xref: /haiku/src/bin/spybmessage.cpp (revision 02354704729d38c3b078c696adc1bbbd33cbcf72)
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