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