safey: sorry...please check the file...this makefile does not work if I don't comment...
[oweals/gnunet.git] / src / monkey / gnunet-monkey.c
1 /**[txh]********************************************************************
2
3   Copyright (c) 2004 by Salvador E. Tropea.
4   Covered by the GPL license.
5
6   Comment:
7   X11 example/test of the libmigdb.
8   Run it from an X11 terminal (xterm, Eterm, etc.).
9   
10 ***************************************************************************/
11
12 #include <stdio.h>
13 #include <unistd.h> //usleep
14 #include <libesmtp.h>
15 #include "gdbmi.h"
16 #include "platform.h"
17 #include "gnunet_common.h"
18
19 extern void sendMail (const char *messageContents);
20 static const char* mode;
21 static const char* dumpFileName;
22
23 void cb_console(const char *str, void *data)
24 {
25  printf("CONSOLE> %s\n",str);
26 }
27
28 /* Note that unlike what's documented in gdb docs it isn't usable. */
29 void cb_target(const char *str, void *data)
30 {
31  printf("TARGET> %s\n",str);
32 }
33
34 void cb_log(const char *str, void *data)
35 {
36  printf("LOG> %s\n",str);
37 }
38
39 void cb_to(const char *str, void *data)
40 {
41  printf(">> %s",str);
42 }
43
44 void cb_from(const char *str, void *data)
45 {
46  printf("<< %s\n",str);
47 }
48
49 static int async_c=0;
50
51 void cb_async(mi_output *o, void *data)
52 {
53  printf("ASYNC\n");
54  async_c++;
55 }
56
57
58 static void dumpText(const char* message)
59 {
60         FILE* file = fopen(dumpFileName, "w");
61         GNUNET_assert(NULL != file);
62         /* FIXME: fprintf(file, message); */
63         fclose(file);
64 }
65
66
67 void send_bug_mail(mi_stop* sr, mi_frames* f)
68 {
69         char *message;
70         GNUNET_asprintf(&message, 
71                         "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n",
72                         f->file, f->func, f->line, mi_reason_enum_to_str(sr->reason), sr->signal_name, sr->signal_meaning);
73         if (strcasecmp(mode, "mail") == 0)
74                 sendMail(message);
75         else
76                 dumpText(message);
77         
78         GNUNET_free (message);
79 }
80
81
82 int wait_for_stop(mi_h *h)
83 {
84  int res=1;
85  mi_stop *sr;
86  mi_frames *f;
87
88  while (!mi_get_response(h))
89     usleep(1000);
90  /* The end of the async. */
91  sr=mi_res_stop(h);
92  if (sr)
93    {
94     f = gmi_stack_info_frame(h);
95     send_bug_mail(sr, f);
96     mi_free_stop(sr);
97     res = 0;
98    }
99  else
100    {
101     printf("Error while waiting\n");
102     printf("mi_error: %d\nmi_error_from_gdb: %s\n",mi_error,mi_error_from_gdb);
103     res=0;
104    }
105  return res;
106 }
107
108 int main(int argc, char *argv[])
109 {
110  mi_aux_term *xterm_tty=NULL;
111  const char* binaryName;
112  const char* argument;
113  int i = 1;
114  
115  argument = argv[i];
116  GNUNET_assert(NULL != argument);
117  do {
118          if (strcasecmp(argument, "--mode") == 0) {
119                  argument = argv[++i];
120                  GNUNET_assert(NULL != argument);
121                  mode = argument;
122          }
123          else if (strcasecmp(argument, "--binary") == 0) {
124                  argument = argv[++i];
125                  GNUNET_assert(NULL != argument);
126                  binaryName = argument;
127          }
128          else if (strcasecmp(argument, "--output") == 0) {
129                  argument = argv[++i];
130                  GNUNET_assert(NULL != argument);
131                  dumpFileName = argument;
132          }
133          else 
134                  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Monkey: Error: Unexpected argument\n"));
135  } while (NULL != (argument = argv[++i]));
136  GNUNET_assert((NULL != binaryName) || (NULL != mode));
137  GNUNET_assert(!((strcasecmp(mode, "text") == 0) && (NULL == dumpFileName)));
138  
139  
140  /* This is like a file-handle for fopen.
141     Here we have all the state of gdb "connection". */
142  mi_h *h;
143
144  /* Connect to gdb child. */
145  h=mi_connect_local();
146  if (!h)
147    {
148     printf("Connect failed\n");
149     return 1;
150    }
151  printf("Connected to gdb!\n");
152
153  /* Set all callbacks. */
154  mi_set_console_cb(h,cb_console,NULL);
155  mi_set_target_cb(h,cb_target,NULL);
156  mi_set_log_cb(h,cb_log,NULL);
157  mi_set_async_cb(h,cb_async,NULL);
158  mi_set_to_gdb_cb(h,cb_to,NULL);
159  mi_set_from_gdb_cb(h,cb_from,NULL);
160
161  /* Set the name of the child and the command line aguments. */
162  if (!gmi_set_exec(h, binaryName, NULL))
163    {
164     printf("Error setting exec y args\n");
165     mi_disconnect(h);
166     return 1;
167    }
168
169  /* Tell gdb to attach the child to a terminal. */
170  if (!gmi_target_terminal(h, ttyname(STDIN_FILENO)))
171    {
172     printf("Error selecting target terminal\n");
173     mi_disconnect(h);
174     return 1;
175    }
176
177  /* Run the program. */
178  if (!gmi_exec_run(h))
179    {
180     printf("Error in run!\n");
181     mi_disconnect(h);
182     return 1;
183    }
184  /* Here we should be stopped when the program crashes */
185  if (!wait_for_stop(h))
186    {
187     mi_disconnect(h);
188     return 1;
189    }
190
191  /* Continue execution. */
192  if (!gmi_exec_continue(h))
193    {
194     printf("Error in continue!\n");
195     mi_disconnect(h);
196     return 1;
197    }
198  /* Here we should be terminated. */
199  if (!wait_for_stop(h))
200    {
201     mi_disconnect(h);
202     return 1;
203    }
204
205  /* Exit from gdb. */
206  gmi_gdb_exit(h);
207  /* Close the connection. */
208  mi_disconnect(h);
209  /* Wait 5 seconds and close the auxiliar terminal. */
210  printf("Waiting 5 seconds\n");
211  sleep(5);
212  gmi_end_aux_term(xterm_tty);
213
214  return 0;
215 }