1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <unistd.h> 5 #include <OS.h> 6 #include <image.h> 7 #include <Application.h> 8 #include <StorageDefs.h> 9 #include <MessageFilter.h> 10 #include <MessageRunner.h> 11 #include <List.h> 12 #include <Window.h> 13 14 extern char **original_argv; 15 extern char **argv_save; 16 extern char **__libc_argv; 17 extern int original_argc; 18 extern int __libc_argc; 19 20 #define MAX_VIEWS 10 21 22 int gStartWin = 0; 23 char *gMatchViewNames[MAX_VIEWS]; 24 int gNumViewNames = 0; 25 26 char gExePath[B_PATH_NAME_LENGTH]; 27 image_id gExeImg = -1; 28 int (*gExeMainProc)(int argc, char **argv); 29 30 thread_id gWaitForBAppThID = -1; 31 sem_id gStdoutLock; 32 33 //extern "C" EnqueueMessage__Q28BPrivate13BLooperTargetP8BMessage(BLooper *_this, BMessage *message); 34 35 //EnqueueMessage__Q28BPrivate13BLooperTargetP8BMessage(BLooper *_this, BMessage *message); 36 37 BMessageFilter *gAppFilter; 38 bool quitting = false; 39 40 filter_result bapp_filter(BMessage *message, 41 BHandler **target, 42 BMessageFilter *filter) 43 { 44 if (message->what == 'plop') /* our doesn't count */ 45 return B_DISPATCH_MESSAGE; 46 acquire_sem(gStdoutLock); 47 fprintf(stdout, "\033[31mMessage for BApplication:\033[0m\n"); 48 message->PrintToStream(); 49 release_sem(gStdoutLock); 50 return B_DISPATCH_MESSAGE; 51 } 52 53 filter_result bwin_filter(BMessage *message, 54 BHandler **target, 55 BMessageFilter *filter) 56 { 57 BWindow *win; 58 BHandler *hand = NULL; 59 if (target) 60 hand = *target; 61 win = dynamic_cast<BWindow *>(filter->Looper()); 62 acquire_sem(gStdoutLock); 63 fprintf(stdout, 64 "\033[31mMessage for View \"%s\" of Window \"%s\":\033[0m\n", 65 hand?hand->Name():NULL, 66 win?win->Title():NULL); 67 message->PrintToStream(); 68 release_sem(gStdoutLock); 69 return B_DISPATCH_MESSAGE; 70 } 71 72 class MyHandler : public BHandler { 73 public: 74 MyHandler(); 75 ~MyHandler(); 76 void MessageReceived(BMessage *msg); 77 private: 78 BList fWindowList; 79 }; 80 81 MyHandler::MyHandler() 82 :BHandler("spying handler") 83 { 84 fWindowList.MakeEmpty(); 85 } 86 87 MyHandler::~MyHandler() 88 { 89 } 90 91 void MyHandler::MessageReceived(BMessage *msg) 92 { 93 int i; 94 BMessageFilter *afilter; 95 switch (msg->what) { 96 case 'plop': 97 i = be_app->CountWindows(); 98 for (; i; i--) { 99 BWindow *win = be_app->WindowAt(i-1); 100 if (win && !fWindowList.HasItem(win)) { 101 fWindowList.AddItem(win); 102 afilter = new BMessageFilter(B_ANY_DELIVERY, 103 B_ANY_SOURCE, 104 bwin_filter); 105 win->Lock(); 106 win->AddCommonFilter(afilter); 107 win->Unlock(); 108 } 109 } 110 break; 111 } 112 BHandler::MessageReceived(msg); 113 } 114 115 int32 wait_for_loopers(void *arg) 116 { 117 MyHandler *myh; 118 /* wait for BApplication */ 119 while (!be_app) 120 snooze(50000); 121 gAppFilter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, bapp_filter); 122 myh = new MyHandler; 123 be_app->Lock(); 124 be_app->AddCommonFilter(gAppFilter); 125 be_app->AddHandler(myh); 126 be_app->Unlock(); 127 new BMessageRunner(BMessenger(myh), new BMessage('plop'), 100000); 128 129 return 0; 130 } 131 132 static int usage(char *argv0) 133 { 134 printf("usage:\n"); 135 printf("%s app [args...]\n", argv0); 136 return 0; 137 } 138 139 int main(int argc, char **argv) 140 { 141 int i; 142 status_t err; 143 char *trapp_name; 144 if (argc < 2) 145 return usage(argv[0]); 146 trapp_name = argv[0]; 147 148 for (i = 1; i < argc; i++) { 149 if (strncmp(argv[i], "-", 1)) 150 break; 151 else if (!strcmp(argv[i], "-view")) { 152 if (gNumViewNames >= MAX_VIEWS) { 153 printf("too many view names\n"); 154 return 1; 155 } 156 i++; 157 if (i >= argc) { 158 printf("missing arg to -view\n"); 159 return 1; 160 } 161 gMatchViewNames[gNumViewNames] = argv[i]; 162 gNumViewNames++; 163 } else if (!strcmp(argv[i], "-firstw")) { 164 i++; 165 if (i >= argc) { 166 printf("missing arg to -firstw\n"); 167 return 1; 168 } 169 gStartWin = atoi(argv[i]); 170 } else { 171 return usage(argv[0]); 172 } 173 } 174 if (argc - i < 1) 175 return usage(argv[0]); 176 argv += i; 177 argc -= i; 178 179 for (i = 0; i < argc; i++) 180 printf("argv[%d] = %s\n", i, argv[i]); 181 gExePath[0] = '\0'; 182 if (strncmp(argv[0], "/", 1)) { 183 getcwd(gExePath, B_PATH_NAME_LENGTH-10); 184 strcat(gExePath, "/"); 185 } 186 strncat(gExePath, argv[0], B_PATH_NAME_LENGTH-1-strlen(gExePath)); 187 printf("cmd = %s\n", gExePath); 188 gExeImg = load_add_on(gExePath); 189 if (gExeImg < B_OK) { 190 fprintf(stderr, "load_add_on: %s\n", strerror(gExeImg)); 191 return 1; 192 } 193 194 // original are static... 195 //printf("original: %d; %s\n", original_argc, *original_argv); 196 fprintf(stderr, "libc: %d; %s\n", __libc_argc, *__libc_argv); 197 fprintf(stderr, "save: %s\n", *argv_save); 198 199 //argv[0] = trapp_name; 200 __libc_argv = argv; 201 __libc_argc = argc; 202 argv_save = argv; 203 204 gStdoutLock = create_sem(1, "spybmsg_stdout_lock"); 205 206 err = get_image_symbol(gExeImg, "main", B_SYMBOL_TYPE_TEXT, (void **)&gExeMainProc); 207 if (err < B_OK) { 208 fprintf(stderr, "get_image_symbol(main): %s\n", strerror(gExeImg)); 209 return 1; 210 } 211 printf("main @ %p\n", gExeMainProc); 212 213 resume_thread(spawn_thread(wait_for_loopers, 214 "waiting for BLoopers", 215 B_NORMAL_PRIORITY, NULL)); 216 217 i = gExeMainProc(argc, argv); 218 219 return i; 220 } 221 222