If a core Wireshark developer repeatedly can't remember that the
[metze/wireshark/wip.git] / echld_test.c
1 /* echld-test.c
2  *  basic test framework for echld
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copyright (c) 2013 by Luis Ontanon <luis@ontanon.org>
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25  */
26
27 #include "config.h"
28
29 #ifdef HAVE_FCNTL_H
30 #include <fcntl.h>
31 #endif
32
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
35 #endif
36
37 #include <sys/time.h>
38 #include <sys/uio.h>
39
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43
44 #include <signal.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include <glib.h>
50 #include <glib/gprintf.h>
51
52 #include "echld/echld.h"
53 #include "echld/echld-util.h"
54
55 #include "epan/epan.h"
56 #include "wsutil/str_util.h"
57
58 typedef char* (*cmd_cb_t)(char** params, char** err);
59
60 typedef struct _cmd_t {
61         const char* txt;
62         cmd_cb_t cb;
63         int args_taken;
64         const char* help;
65 } cmd_t;
66
67
68 #define MAX_PARAMSETS 16
69
70 static enc_msg_t* paramsets[MAX_PARAMSETS] = {
71         NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,
72         NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL
73 };
74
75 static int nps = 0;
76
77 static char* ps_cmd(char** pars _U_, char** err _U_) {
78         int n_id = nps++;
79
80         if (n_id >= MAX_PARAMSETS) {
81                 *err = g_strdup("Max Num of Paramsets reached");
82                 return NULL;
83         }
84
85         paramsets[n_id] = echld_new_child_params();
86
87         return g_strdup_printf("New Paramset ps_id=%d",n_id);
88 }
89
90 static char* psadd_cmd(char** params _U_, char** err) {
91         int ps_id = (int) strtol(params[1], NULL, 10);
92
93         if (ps_id >= nps) {
94                 *err = g_strdup_printf("No paramset pd_is=%d",ps_id);
95                 return NULL;
96         }
97
98         echld_new_child_params_add_params(paramsets[ps_id], params[2], params[3], NULL);
99
100         return g_strdup_printf("PSAdd ps_id=%d %s='%s'", ps_id, params[2], params[3]);
101
102
103 static char* psmerge_cmd(char** params, char** err) {
104         int ps1_id = (int) strtol(params[1], NULL, 10);
105         int ps2_id = (int) strtol(params[2], NULL, 10);
106         int n_id;
107
108         if (ps1_id >= nps) {
109                 *err = g_strdup_printf("No paramset pd_is=%d",ps1_id);
110                 return NULL;
111         }
112
113         if (ps2_id >= nps) {
114                 *err = g_strdup_printf("No paramset pd_is=%d",ps2_id);
115                 return NULL;
116         }
117
118         n_id = nps++;
119
120         if (n_id >= MAX_PARAMSETS) {
121                 *err = g_strdup_printf("Max Num of Paramsets reached");
122                 return NULL;
123         }
124
125         paramsets[n_id] = echld_new_child_params_merge(paramsets[ps1_id],paramsets[ps2_id]);
126
127         return g_strdup_printf("Merged Paramset ps1_id=%d ps2_id=%d ps_id=%d",ps1_id, ps2_id, n_id);
128 }
129
130 static char* new_child_cmd(char** params, char** err) {
131         int ps_id = (int) strtol(params[1], NULL, 10);
132         int child;
133
134         if (ps_id >= nps) {
135                 *err = g_strdup_printf("No paramset pd_is=%d",ps_id);
136                 return NULL;
137         }
138
139         child = echld_new(paramsets[ps_id],NULL);
140
141         if (child <= 0) {
142                 *err = g_strdup("No child\n");
143                 return NULL;
144         }
145
146         return g_strdup_printf("New chld_id=%d\n",child);;
147 }
148
149
150 void ping_cb(long usec, void* data) {
151         int ping_id = *((int*)data);
152
153         if (usec >= 0) {
154                 fprintf(stdout, "Ping ping_id=%d returned in %dus\n",ping_id,(int)usec);
155         } else {
156                 fprintf(stdout, "Ping ping_id=%d erored\n",ping_id);
157         }
158
159         g_free(data);
160 }
161
162
163 static char* ping_cmd(char** params, char** err) {
164         int child = (int) strtol(params[1], NULL, 10);
165         static int ping_id = 0;
166         int* ping_data = g_new(int,1);
167
168         *ping_data = ping_id++;
169
170         if (!echld_ping(child,ping_cb,ping_data)) {
171                 *err = g_strdup_printf("Could not send ping child=%d",child);
172                 return NULL;
173         } else {
174                 return g_strdup_printf("Ping sent child=%d",child);
175         }
176 }
177
178 void param_cb(const char* param, const char* value, const char* error, void* data _U_) {
179         if (error) {
180                 fprintf(stdout, "Param Set Error msg=%s\n", error );
181         } else {
182                 fprintf(stdout, "Param: param='%s' val='%s'\n", param, value );
183         }
184 }
185
186 static char* set_cmd(char** params, char** err) {
187         int child = (int) strtol(params[1], NULL, 10);
188         char* param = params[2];
189         char* value = params[3];
190
191         if ( ! echld_set_param(child,param,value,param_cb,NULL) ) {
192                 *err = g_strdup_printf("Failed to SET child=%d param='%s' value='%s'",child,param,value);
193                 return NULL;
194         } else {
195                 return g_strdup_printf("Set command sent child=%d param='%s' value='%s'",child,param,value);
196         }
197 }
198
199 static char* get_cmd(char** params, char** err) {
200         int child = (int) strtol(params[1], NULL, 10);
201         char* param = params[2];
202
203         if ( ! echld_get_param(child,param,param_cb,NULL) ) {
204                 *err = g_strdup_printf("Failed to GET child=%d param='%s'",child,param);
205                 return NULL;
206         } else {
207                 return g_strdup_printf("Get command sent child=%d param='%s'",child,param);
208         }
209 }
210
211 static void close_cb(const char* error, void* data) {
212         if (error) {
213                 fprintf(stdout, "Close Error msg=%s\n", error );
214         } else {
215                 fprintf(stdout, "Closed: child=%d\n", *((int*)data) );
216         }
217 }
218
219 static char* close_cmd(char** params, char** err) {
220         int child = (int) strtol(params[1], NULL, 10);
221         int* cmdp = g_new(int,1);
222         *cmdp = child;
223         if ( ! echld_close(child,close_cb,cmdp) ) {
224                 *err = g_strdup_printf("Could not close child=%d",child);
225                 return NULL;
226         } else {
227                 return g_strdup_printf("CLose command sent child=%d",child);
228         }
229 }
230 int keep_going = 1;
231
232 static char* quit_cmd(char** params _U_, char** err _U_) {
233         keep_going = 0;
234         return g_strdup("Quitting");
235 }
236
237 static char* help_cmd(char**, char**);
238
239 static char* open_file_cmd(char** pars _U_, char** err _U_) {
240         *err = g_strdup("Not Implemented");
241         return NULL;
242 }
243
244 static char* prepare_capture_cmd(char** pars _U_, char** err _U_) {
245         *err = g_strdup("Not Implemented");
246         return NULL;
247 }
248
249 static char* start_capture_cmd(char** pars _U_, char** err _U_) {
250         *err = g_strdup("Not Implemented");
251         return NULL;
252 }
253
254 static char* get_sum_cmd(char** pars _U_, char** err _U_) {
255         *err = g_strdup("Not Implemented");
256         return NULL;
257 }
258
259 static char* get_tree_cmd(char** pars _U_, char** err _U_) {
260         *err = g_strdup("Not Implemented");
261         return NULL;
262 }
263
264 static char* get_buf_cmd(char** pars _U_, char** err _U_) {
265         *err = g_strdup("Not Implemented");
266         return NULL;
267 }
268
269 static char* stop_cmd(char** pars _U_, char** err _U_) {
270         *err = g_strdup("Not Implemented");
271         return NULL;
272 }
273
274 static char* note_cmd(char** pars _U_, char** err _U_) {
275         *err = g_strdup("Not Implemented");
276         return NULL;
277 }
278
279 static char* apply_cmd(char** pars _U_, char** err _U_) {
280         *err = g_strdup("Not Implemented");
281         return NULL;
282 }
283
284 static char* save_cmd(char** pars _U_, char** err _U_) {
285         *err = g_strdup("Not Implemented");
286         return NULL;
287 }
288
289 static char* run_cmd(char** pars, char** err _U_);
290
291
292
293
294 cmd_t commands[] = {
295         { "QUIT", quit_cmd, 0, "QUIT"},
296         { "HELP", help_cmd, 0, "HELP"},
297         { "RUN", run_cmd, 1, "RUN filename"},
298         { "PS", ps_cmd, 1, "PS [dummy]"},
299         { "PSADD", psadd_cmd, 4, "PSADD ps_id param value"},
300         { "PSMERGE", psmerge_cmd, 4, "PSMERGE ps_id ps_id"},
301         { "NEW", new_child_cmd, 1, "NEW ps_id"},
302         { "PING", ping_cmd, 1, "PING child_id"},
303         { "SET", set_cmd, 3, "SET child_id param_name param_val"},
304         { "GET", get_cmd, 2, "GET child_id param_name"},
305         { "CLOSE", close_cmd, 1, "CLOSE child_id"},
306         { "FILE", open_file_cmd, 2, "FILE child_id filename"},
307         { "PREP", prepare_capture_cmd, 2, "PREP child_id intfname params"},
308         { "START",start_capture_cmd,1,"START child_id"},
309         { "SUM", get_sum_cmd,2,"SUM child_id packet_range"},
310         { "TREE", get_tree_cmd,2,"TREE child_id packet_range"},
311         { "BUFF", get_buf_cmd,2,"BUFF child_id buffer_name"},
312         { "STOP", stop_cmd,1,"STOP child_id"},
313         { "NOTE", note_cmd,1,"NOTE child_id framenum note..."},
314         { "APPLY", apply_cmd,1,"APPLY child_id dfilter"},
315         { "SAVE", save_cmd,1,"SAVE child_id filename params"},
316         { NULL, NULL, 0, NULL }
317 };
318
319 static char* help_cmd(char** params _U_, char** err _U_) {
320         GString* out = g_string_new("Commands:\n");
321         cmd_t* c = commands;
322         char* s;
323
324         for (;c->txt;c++) {
325                 g_string_append_printf(out,"%s\n",c->help);
326         }
327         s = out->str;
328         g_string_free(out,FALSE);
329         return s;
330 }
331
332
333 static int invoke_cmd(FILE* in_fp) {
334         size_t len;
335         char* cmd_line;
336
337         if(( cmd_line = fgetln(in_fp,&len) )) {
338                 cmd_t* c = commands;
339                 cmd_line[len] = 0;
340                 g_strchomp(cmd_line);
341
342                 for (;c->txt;c++) {
343                         if ( strcasestr(cmd_line, c->txt) == cmd_line ) {
344                                 char** params = g_strsplit(cmd_line, " ", c->args_taken+1);
345                                 char* err = NULL;
346                                 char* str = c->cb(params,&err);
347
348                                 if (err) {
349                                         fprintf(stdout, "Error: %s\n", err);
350                                         g_free(err);
351                                 } else {
352                                         fprintf(stdout, "%s\n", str);
353                                         g_free(str);
354                                 }
355                                 
356                                 g_strfreev(params);
357                                 return TRUE;
358                         }
359                 }
360                 
361                 fprintf(stdout, "Error: no such command %s\n", cmd_line);
362                 return TRUE;
363         } else {
364                 return FALSE;
365         }
366 }
367
368 static char* run_cmd(char** pars, char** err _U_) {
369         FILE* fp = fopen(pars[1],"r");
370         while(invoke_cmd(fp)) { ; }
371         fclose(fp);
372         return NULL;
373 }
374
375
376 int got_param = 0;
377
378
379 int main(int argc _U_, char** argv _U_) {
380         struct timeval tv;
381         int tot_cycles = 0;
382         echld_init_t init = {ECHLD_ENCODING_JSON,argv[0],main,NULL,NULL,NULL,NULL};
383         
384
385         tv.tv_sec = 5;
386         tv.tv_usec = 0;
387
388         echld_set_parent_dbg_level(5);
389
390         echld_initialize(&init);
391
392         do {
393                 fd_set rfds;
394                 fd_set efds;
395                 int nfds;
396
397                 FD_ZERO(&rfds);
398                 FD_ZERO(&efds);
399                 FD_SET(0,&rfds);
400                 FD_SET(0,&efds);
401
402                 nfds = echld_select(FD_SETSIZE, &rfds, NULL, &efds, &tv);
403
404                 if (FD_ISSET(0,&rfds)) {
405                         invoke_cmd(stdin);
406                 }
407
408                 tot_cycles++;
409         } while( keep_going );
410
411         fprintf(stderr, "Done: tot_cycles=%d\n", tot_cycles );
412
413         echld_terminate();
414         return 0;
415 }