Yet another iteration:
- improve the parameter api - Add a parameter set message to the NEW child message to set parameters in bulk in the child - some more harvestig from tshark svn path=/trunk/; revision=50393
This commit is contained in:
parent
34cd52a8e5
commit
880e19ac3d
163
echld/child.c
163
echld/child.c
|
@ -61,6 +61,7 @@ typedef struct _child {
|
|||
|
||||
} echld_child_t;
|
||||
|
||||
static echld_epan_stuff_t* stuff = NULL;
|
||||
|
||||
static echld_child_t child;
|
||||
|
||||
|
@ -143,8 +144,8 @@ static void sig_term(int sig _U_) {
|
|||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id) {
|
||||
extern void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id, echld_epan_stuff_t* es) {
|
||||
stuff = es;
|
||||
|
||||
close_sleep_time.tv_sec = CHILD_CLOSE_SLEEP_TIME / 1000000;
|
||||
close_sleep_time.tv_usec = CHILD_CLOSE_SLEEP_TIME % 1000000;
|
||||
|
@ -298,11 +299,48 @@ static char* param_get_file_list(char** err) {
|
|||
return s;
|
||||
}
|
||||
|
||||
#ifdef PCAP_NG_DEFAULT
|
||||
static int out_file_type = WTAP_FILE_PCAPNG;
|
||||
#else
|
||||
static int out_file_type = WTAP_FILE_PCAP;
|
||||
#endif
|
||||
|
||||
static echld_bool_t param_set_out_file_type(char* val, char** err) {
|
||||
int oft = wtap_short_string_to_file_type(val);
|
||||
|
||||
if (oft < 0) {
|
||||
*err = g_strdup_printf("\"%s\" isn't a valid capture file type", val);
|
||||
return FALSE;
|
||||
} else {
|
||||
out_file_type = oft;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static char* param_get_out_file_type(char** err _U_) {
|
||||
return g_strdup_printf("%s(%d): %s",
|
||||
wtap_file_type_short_string(out_file_type),
|
||||
out_file_type, wtap_file_type_string(out_file_type));
|
||||
}
|
||||
|
||||
|
||||
static echld_bool_t param_set_add_hosts_file(char* val, char** err) {
|
||||
if (add_hosts_file(val)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
*err = g_strdup_printf("Can't read host entries from \"%s\"",val);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PARAM_BOOL(quiet,FALSE);
|
||||
PARAM_BOOL(start_capture,FALSE);
|
||||
PARAM_BOOL(push_details,FALSE);
|
||||
PARAM_BOOL(print_hex,FALSE);
|
||||
|
||||
static char* param_get_params(char** err _U_);
|
||||
|
||||
static param_t params[] = {
|
||||
static param_t child_params[] = {
|
||||
#ifdef DEBUG_CHILD
|
||||
PARAM(dbg_level,"Debug Level (0<int<5)"),
|
||||
# endif
|
||||
|
@ -311,40 +349,21 @@ static param_t params[] = {
|
|||
PARAM(dfilter,"Dispay Filter (str)"),
|
||||
RO_PARAM(packet_count,"Packets Read/Captured So Far (str)"),
|
||||
RO_PARAM(file_list,"List of Files in the Current Dir"),
|
||||
PARAM(start_capture,"Automatically start capture"),
|
||||
PARAM(quiet,"Quiet Mode"),
|
||||
PARAM(push_details,"Whether details of dissection should be passed"),
|
||||
PARAM(print_hex,"Output in hex"),
|
||||
PARAM(out_file_type,"Output File Type"),
|
||||
WO_PARAM(add_hosts_file,"Add a Hosts File"),
|
||||
RO_PARAM(params,"This List"),
|
||||
{NULL,NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
|
||||
static char* param_get_params(char** err _U_) {
|
||||
param_t* p = params;
|
||||
GString* str = g_string_new("");
|
||||
char* s;
|
||||
|
||||
for (;p->name;p++) {
|
||||
g_string_append_printf(str,"%s(%s): %s\n",
|
||||
p->name,((p->get && p->set)?"rw":(p->get?"ro":"wo")),p->desc);
|
||||
}
|
||||
|
||||
s = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return s;
|
||||
return paramset_get_params_list(child_params,PARAM_LIST_FMT);
|
||||
}
|
||||
|
||||
static param_t* get_paramset(char* name) {
|
||||
int i;
|
||||
for (i = 0; params[i].name != NULL;i++) {
|
||||
if (strcmp(name,params[i].name) == 0 ) return &(params[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void child_open_file(char* filename) {
|
||||
CHILD_DBG((2,"CMD open file filename='%s'",filename));
|
||||
child_err(ECHLD_ERR_UNIMPLEMENTED,child.reqh_id,"open file not implemented yet!");
|
||||
|
@ -402,6 +421,7 @@ static void child_save_file(char* filename, char* pars) {
|
|||
static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_msg_type_t type, echld_reqh_id_t reqh_id, void* data _U_) {
|
||||
GByteArray ba;
|
||||
GByteArray* gba;
|
||||
char* err = NULL;
|
||||
|
||||
child.reqh_id = reqh_id;
|
||||
|
||||
|
@ -415,15 +435,22 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
|
|||
return 0;
|
||||
}
|
||||
|
||||
ba.data = b;
|
||||
ba.len = (guint)len;
|
||||
|
||||
switch(type) {
|
||||
case ECHLD_NEW_CHILD: {
|
||||
child.state = IDLE;
|
||||
CHILD_RESP(NULL,ECHLD_HELLO);
|
||||
child.state = CREATING;
|
||||
if ( !paramset_apply_em(child_params,(enc_msg_t*)&ba, &err) ) {
|
||||
child_err(ECHLD_ERR_CRASHED_CHILD,reqh_id,
|
||||
"Initial Paramset Error '%s'",err);
|
||||
} else {
|
||||
child.state = IDLE;
|
||||
CHILD_RESP(NULL,ECHLD_HELLO);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECHLD_PING:
|
||||
ba.data = b;
|
||||
ba.len = (guint)len;
|
||||
CHILD_DBG((1,"PONG"));
|
||||
CHILD_RESP(&ba,ECHLD_PONG);
|
||||
break;
|
||||
|
@ -432,23 +459,10 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
|
|||
char* value;
|
||||
|
||||
if ( child.dec->set_param && child.dec->set_param(b,len,¶m,&value) ) {
|
||||
param_t* p = get_paramset(param);
|
||||
char* err;
|
||||
|
||||
if (!p) {
|
||||
child_err(ECHLD_CANNOT_SET_PARAM,reqh_id,"no such param='%s'",param);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p->set) {
|
||||
child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"reason='read only'");
|
||||
break;
|
||||
}
|
||||
|
||||
if (! p->set(value,&err) ) {
|
||||
child_err(ECHLD_CANNOT_SET_PARAM,reqh_id,"reason='%s'",err);
|
||||
if (! paramset_apply_set (child_params, param, value, &err) ) {
|
||||
child_err(ECHLD_CANNOT_SET_PARAM,reqh_id,"%s",err);
|
||||
g_free(err);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gba = child.enc->param(param,value);
|
||||
|
@ -464,27 +478,14 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
|
|||
case ECHLD_GET_PARAM: {
|
||||
char* param;
|
||||
if ( child.dec->get_param && child.dec->get_param(b,len,¶m) ) {
|
||||
char* err;
|
||||
char* val;
|
||||
|
||||
param_t* p = get_paramset(param);
|
||||
|
||||
if (!p) {
|
||||
child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"no such param='%s'",param);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p->get) {
|
||||
child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"reason='write only'");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(val = p->get(&err))) {
|
||||
child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"reason='%s'",err);
|
||||
if (! (val = paramset_apply_get (child_params, param, &err)) ) {
|
||||
child_err(ECHLD_CANNOT_GET_PARAM,reqh_id,"%s",err);
|
||||
g_free(err);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
gba = child.enc->param(param,val);
|
||||
CHILD_RESP(gba,ECHLD_PARAM);
|
||||
g_byte_array_free(gba,TRUE);
|
||||
|
@ -627,11 +628,16 @@ static long child_receive(guint8* b, size_t len, echld_chld_id_t chld_id, echld_
|
|||
|
||||
}
|
||||
|
||||
static void child_dumpcap_read(void) {
|
||||
static int child_dumpcap_read(void) {
|
||||
// this folk manages the reading of dumpcap's pipe
|
||||
// it has to read interface descriptions when doing so
|
||||
// and managing capture during capture
|
||||
CHILD_DBG((2,"child_dumpcap_read"));
|
||||
CHILD_DBG((2,"child_dumpcap_read"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void child_file_read(void) {
|
||||
|
||||
}
|
||||
|
||||
int echld_child_loop(void) {
|
||||
|
@ -650,6 +656,7 @@ int echld_child_loop(void) {
|
|||
fd_set efds;
|
||||
struct timeval timeout;
|
||||
int nfds;
|
||||
gboolean captured = FALSE;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_ZERO(&wfds);
|
||||
|
@ -664,16 +671,15 @@ int echld_child_loop(void) {
|
|||
FD_SET(child.fds.pipe_from_dumpcap,&rfds);
|
||||
}
|
||||
|
||||
if (child.fds.file_being_read > 0) {
|
||||
FD_SET(child.fds.file_being_read,&rfds);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CHILD
|
||||
if (step >= 100) CHILD_DBG((4,"child_loop: select()ing step=%d",step++));
|
||||
if (step <= 20) CHILD_DBG((4,"child_loop: select()ing step=%d",step++));
|
||||
#endif
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 999999;
|
||||
|
||||
nfds = select(FD_SETSIZE, &rfds, &wfds, &efds, &timeout);
|
||||
#ifdef DEBUG_CHILD
|
||||
if (step >= 100) CHILD_DBG((4,"child_loop: select()ed nfds=%d",nfds));
|
||||
if (step <= 20) CHILD_DBG((4,"child_loop: select()ed nfds=%d",nfds));
|
||||
#endif
|
||||
|
||||
if ( FD_ISSET(disp_from,&efds) ) {
|
||||
|
@ -691,11 +697,6 @@ int echld_child_loop(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (child.fds.file_being_read > 0 && FD_ISSET(child.fds.file_being_read,&efds) ) {
|
||||
CHILD_DBG((0,"Broken Readfile Pipe step=%d",step));
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(disp_from, &rfds)) {
|
||||
long st = echld_read_frame(&(child.parent), child_receive, &child);
|
||||
|
||||
|
@ -714,7 +715,11 @@ int echld_child_loop(void) {
|
|||
#ifdef DEBUG_CHILD
|
||||
step = 0;
|
||||
#endif
|
||||
child_dumpcap_read();
|
||||
captured = child_dumpcap_read();
|
||||
}
|
||||
|
||||
if ( child.state == READING || captured ) {
|
||||
child_file_read();
|
||||
}
|
||||
} while(1);
|
||||
|
||||
|
|
|
@ -338,7 +338,96 @@ long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t
|
|||
return (long) writev(fd, iov, iov_cnt);
|
||||
}
|
||||
|
||||
/* paramset management */
|
||||
|
||||
param_t* paramset_find (param_t* paramsets, char* name, char** err) {
|
||||
int i;
|
||||
for (i = 0; paramsets[i].name != NULL;i++) {
|
||||
if (strcmp(name,paramsets[i].name) == 0 ) return &(paramsets[i]);
|
||||
}
|
||||
|
||||
*err = g_strdup_printf("Could not find param='%s'",name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
echld_bool_t paramset_apply_set (param_t* paramsets, char* name, char* val, char** err) {
|
||||
param_t* p = paramset_find(paramsets,name,err);
|
||||
|
||||
if ( !p ) return FALSE;
|
||||
if ( ! p->set ) {
|
||||
*err = g_strdup_printf("Cannot set RO param='%s'",name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return p->set(val,err);
|
||||
}
|
||||
|
||||
char* paramset_apply_get (param_t* paramsets, char* name, char** err) {
|
||||
param_t* p = paramset_find(paramsets,name,err);
|
||||
|
||||
if ( !p ) return NULL;
|
||||
|
||||
if ( ! p->get ) {
|
||||
*err = g_strdup_printf("Cannot get WO param='%s'",name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return p->get(err);
|
||||
}
|
||||
|
||||
echld_bool_t paramset_apply_em(param_t* paramset, enc_msg_t* em, char** err) {
|
||||
GByteArray* ba = (GByteArray*)em;
|
||||
char* p = (char*) ba->data;
|
||||
int tot_len = ba->len;
|
||||
long rem = tot_len;
|
||||
p[rem-1] = '\0'; /* make sure last char is null */
|
||||
|
||||
while(rem > 2) {
|
||||
char* param = p;
|
||||
long param_len = strlen(param)+1;
|
||||
char* value = p + param_len;
|
||||
long value_len;
|
||||
|
||||
rem -= param_len;
|
||||
|
||||
if (rem < 0) {
|
||||
*err = g_strdup_printf("Malformed msg param len invalid");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
value_len = strlen(value)+1;
|
||||
|
||||
rem -= value_len;
|
||||
p = value + value_len;
|
||||
|
||||
if (rem < 0) {
|
||||
*err = g_strdup_printf("Malformed msg value len invalid");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! paramset_apply_set(paramset,param,value,err))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char* paramset_get_params_list(param_t* paramsets,const char* fmt) {
|
||||
param_t* p = paramsets;
|
||||
GString* str = g_string_new("");
|
||||
char* s;
|
||||
|
||||
for (;p->name;p++) {
|
||||
g_string_append_printf(str,fmt,
|
||||
p->name,
|
||||
((p->get && p->set)?"rw":(p->get?"ro":"wo")),
|
||||
p->desc);
|
||||
}
|
||||
|
||||
s = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* encoders and decoders */
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ struct dispatcher {
|
|||
|
||||
struct dispatcher* dispatcher;
|
||||
|
||||
|
||||
#ifdef DEBUG_DISPATCHER
|
||||
static int debug_lvl = DEBUG_DISPATCHER;
|
||||
static FILE* debug_fp = NULL;
|
||||
|
@ -135,6 +134,17 @@ static long dbg_r = 0;
|
|||
#define DISP_RESP(B,T) (DISP_WRITE( dispatcher->parent_out, (B), 0, (T), dispatcher->reqh_id))
|
||||
|
||||
|
||||
|
||||
static echld_epan_stuff_t stuff;
|
||||
|
||||
static void init_stuff(void) {
|
||||
#ifdef HAVE_LIBPCAP
|
||||
capture_opts_init(&stuff.cap_opts);
|
||||
capture_session_init(&stuff.cap_sess, (void *)&stuff.cfile);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void children_massacre(void) {
|
||||
int i;
|
||||
struct dispatcher_child* cc = dispatcher->children;
|
||||
|
@ -314,7 +324,7 @@ static char* intflist2json(GList* if_list, char** if_cap_err) {
|
|||
return s;
|
||||
}
|
||||
|
||||
static char* intf_list;
|
||||
static char* intf_list = NULL;
|
||||
|
||||
static void get_interfaces(char** err) {
|
||||
int err_no = 0;
|
||||
|
@ -342,11 +352,11 @@ static char* param_get_interfaces(char** err _U_) {
|
|||
|
||||
static long disp_loop_timeout_usec = DISPATCHER_WAIT_INITIAL;
|
||||
|
||||
static char* param_get_loop_to(char** err _U_) {
|
||||
static char* param_get_loop_timeout(char** err _U_) {
|
||||
return g_strdup_printf("%fs", (((float)disp_loop_timeout_usec)/1000000.0) );
|
||||
}
|
||||
|
||||
static echld_bool_t param_set_loop_to(char* val , char** err ) {
|
||||
static echld_bool_t param_set_loop_timeout(char* val , char** err ) {
|
||||
char* p;
|
||||
int usec = (int)strtol(val, &p, 10); /*XXX: "10ms" or "500us" or "1s" */
|
||||
|
||||
|
@ -360,67 +370,79 @@ static echld_bool_t param_set_loop_to(char* val , char** err ) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GString *comp_info_str;
|
||||
GString *runtime_info_str;
|
||||
static GString *comp_info_str;
|
||||
static GString *runtime_info_str;
|
||||
static const char* version_str = "Echld " VERSION;
|
||||
static char* version_long_str = NULL;
|
||||
|
||||
|
||||
static char* param_get_long_version(char** err _U_) {
|
||||
return g_strdup(version_long_str);
|
||||
}
|
||||
|
||||
static char* param_get_version(char** err _U_) {
|
||||
char* str;
|
||||
|
||||
str = g_strdup_printf("Echld " VERSION "%s\n"
|
||||
"\n"
|
||||
"%s"
|
||||
"\n"
|
||||
"%s"
|
||||
"\n"
|
||||
"%s",
|
||||
wireshark_svnversion, get_copyright_info(), comp_info_str->str,
|
||||
runtime_info_str->str);
|
||||
|
||||
g_string_free(runtime_info_str,TRUE);
|
||||
g_string_free(comp_info_str,TRUE);
|
||||
|
||||
return str;
|
||||
return g_strdup(version_str);
|
||||
}
|
||||
|
||||
static char* param_get_capture_types(char** err _U_) {
|
||||
GString* str = g_string_new("");
|
||||
char* s;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WTAP_NUM_FILE_TYPES; i++) {
|
||||
if (wtap_dump_can_open(i)) {
|
||||
g_string_append_printf(str,"%s: %s\n",
|
||||
wtap_file_type_short_string(i), wtap_file_type_string(i));
|
||||
}
|
||||
}
|
||||
|
||||
s = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return s;
|
||||
}
|
||||
|
||||
static echld_bool_t param_set_add_hosts_file(char* val, char** err) {
|
||||
if (add_hosts_file(val)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
*err = g_strdup_printf("Can't read host entries from \"%s\"",val);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static echld_bool_t param_set_x_opt(char* val, char** err) {
|
||||
if (ex_opt_add(val)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
*err = g_strdup_printf("Cannot set X opt '%s'",val);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static char* param_get_params(char** err _U_);
|
||||
|
||||
static param_t disp_params[] = {
|
||||
#ifdef DEBUG_DISPATCHER
|
||||
{"dbg_level", param_get_dbg_level, param_set_dbg_level,"0>int>5"},
|
||||
PARAM(dbg_level,"0>int>5"),
|
||||
# endif
|
||||
{"version",param_get_version,NULL,"version string"},
|
||||
{"loop_timeout",param_get_loop_to,param_set_loop_to,"main loop step timeout"},
|
||||
{"interfaces",param_get_interfaces,NULL,"interface information"},
|
||||
{"params",param_get_params,NULL,"this list"},
|
||||
RO_PARAM(long_version,"long version string"),
|
||||
RO_PARAM(version,"version string"),
|
||||
PARAM(loop_timeout,"main loop step timeout"),
|
||||
RO_PARAM(interfaces,"interface information"),
|
||||
RO_PARAM(capture_types,"the available capture types"),
|
||||
WO_PARAM(add_hosts_file,"Add a hosts file"),
|
||||
WO_PARAM(x_opt,"Set a -X option"),
|
||||
RO_PARAM(params,"This List"),
|
||||
{NULL,NULL,NULL,NULL}
|
||||
};
|
||||
|
||||
static char* param_get_params(char** err _U_) {
|
||||
param_t* p = disp_params;
|
||||
GString* str = g_string_new("");
|
||||
char* s;
|
||||
|
||||
for (;p->name;p++) {
|
||||
g_string_append_printf(str,"%s(%s): %s\n",
|
||||
p->name,((p->get && p->set)?"rw":(p->get?"ro":"wo")),p->desc);
|
||||
}
|
||||
|
||||
s = str->str;
|
||||
g_string_free(str,FALSE);
|
||||
return s;
|
||||
return paramset_get_params_list(disp_params,PARAM_LIST_FMT);
|
||||
}
|
||||
|
||||
|
||||
static param_t* get_paramset(char* name) {
|
||||
int i;
|
||||
for (i = 0; disp_params[i].name != NULL;i++) {
|
||||
if (strcmp(name,disp_params[i].name) == 0 ) return &(disp_params[i]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct dispatcher_child* dispatcher_get_child(struct dispatcher* d, int chld_id) {
|
||||
int i;
|
||||
struct dispatcher_child* cc = d->children;
|
||||
|
@ -451,6 +473,12 @@ static void set_dumpcap_pid(int pid) {
|
|||
}
|
||||
|
||||
static void preinit_epan(char* argv0, int (*main)(int, char **)) {
|
||||
char *gpf_path, *pf_path;
|
||||
char *gdp_path, *dp_path;
|
||||
int gpf_open_errno, gpf_read_errno;
|
||||
int pf_open_errno, pf_read_errno;
|
||||
int gdp_open_errno, gdp_read_errno;
|
||||
int dp_open_errno, dp_read_errno;
|
||||
char* error;
|
||||
|
||||
error = init_progfile_dir(argv0, main);
|
||||
|
@ -461,7 +489,9 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) {
|
|||
runtime_info_str = g_string_new("Running ");
|
||||
get_runtime_version_info(runtime_info_str, NULL);
|
||||
|
||||
capture_opts_init(&dispatcher->capture_opts);
|
||||
version_long_str = g_strdup_printf("%s%s\n%s\n%s\n%s",
|
||||
version_str, wireshark_svnversion, get_copyright_info(),
|
||||
comp_info_str->str, runtime_info_str->str);
|
||||
|
||||
if (error) {
|
||||
DISP_FATAL((CANNOT_PREINIT_EPAN,"Failed epan_preinit: msg='%s'",error));
|
||||
|
@ -470,6 +500,8 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) {
|
|||
/* Add it to the information to be reported on a crash. */
|
||||
ws_add_crash_info("Echld " VERSION "%s\n%s\n%s",
|
||||
wireshark_svnversion, comp_info_str->str, runtime_info_str->str);
|
||||
|
||||
init_stuff();
|
||||
|
||||
capture_sync_set_fetch_dumpcap_pid_cb(set_dumpcap_pid);
|
||||
|
||||
|
@ -481,28 +513,38 @@ static void preinit_epan(char* argv0, int (*main)(int, char **)) {
|
|||
DISP_FATAL((CANNOT_PREINIT_EPAN,"Error getting interfaces: %s", error));
|
||||
}
|
||||
|
||||
|
||||
prefs_apply_all();
|
||||
|
||||
/* disabled protocols as per configuration file */
|
||||
set_disabled_protos_list();
|
||||
|
||||
/* Here we do initialization of parts of epan that will be the same for every child we fork */
|
||||
initialize_funnel_ops();
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
stuff.prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, &pf_open_errno, &pf_read_errno, &pf_path);
|
||||
// check 4 errors
|
||||
|
||||
read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno, &dp_path, &dp_open_errno, &dp_read_errno);
|
||||
// check 4 errors
|
||||
|
||||
cap_file_init(&stuff.cfile);
|
||||
|
||||
timestamp_set_precision(TS_PREC_AUTO_USEC);
|
||||
|
||||
DISP_DBG((2,"epan preinit done"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void dispatcher_clear(void) {
|
||||
DISP_DBG((2,"dispatcher_clear"));
|
||||
/* remove unnecessary stuff for the working child */
|
||||
/* remove signal handlers */
|
||||
}
|
||||
|
||||
void dispatcher_sig(int sig) {
|
||||
DISP_FATAL((TERMINATED,"SIG sig=%d",sig));
|
||||
exit(1);
|
||||
|
||||
}
|
||||
|
||||
void dispatcher_reaper(int sig) {
|
||||
|
@ -701,7 +743,7 @@ static void detach_new_child(enc_msg_t* em, echld_chld_id_t chld_id) {
|
|||
close(pipe_to_child);
|
||||
close(pipe_from_child);
|
||||
|
||||
echld_child_initialize(chld_id, pipe_from_disp,pipe_to_disp,reqh_id);
|
||||
echld_child_initialize(chld_id, pipe_from_disp,pipe_to_disp,reqh_id,&stuff);
|
||||
|
||||
exit( echld_child_loop() );
|
||||
|
||||
|
@ -768,20 +810,9 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
|
|||
char* value;
|
||||
if ( dispatcher->dec.from_parent->set_param(b,len,¶m,&value) ) {
|
||||
GByteArray* ba;
|
||||
param_t* p = get_paramset(param);
|
||||
char* err;
|
||||
if (!p) {
|
||||
dispatcher_err(ECHLD_CANNOT_SET_PARAM,"no such param='%s'",param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! p->set ) {
|
||||
dispatcher_err(ECHLD_CANNOT_SET_PARAM,"reason='read only'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! p->set(value,&err) ) {
|
||||
dispatcher_err(ECHLD_CANNOT_SET_PARAM,"reason='%s'",err);
|
||||
if (! paramset_apply_set (disp_params, param, value, &err) ) {
|
||||
dispatcher_err(ECHLD_CANNOT_SET_PARAM,"%s",err);
|
||||
g_free(err);
|
||||
return 0;
|
||||
}
|
||||
|
@ -804,20 +835,8 @@ static long dispatch_to_child(guint8* b, size_t len, echld_chld_id_t chld_id, ec
|
|||
char* err;
|
||||
char* val;
|
||||
|
||||
param_t* p = get_paramset(param);
|
||||
|
||||
if (!p) {
|
||||
dispatcher_err(ECHLD_CANNOT_GET_PARAM,"no such param='%s'",param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (! p->get ) {
|
||||
dispatcher_err(ECHLD_CANNOT_SET_PARAM,"reason='write only'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(val = p->get(&err))) {
|
||||
dispatcher_err(ECHLD_CANNOT_GET_PARAM,"reason='%s'",err);
|
||||
if (! (val = paramset_apply_get (disp_params, param, &err)) ) {
|
||||
dispatcher_err(ECHLD_CANNOT_GET_PARAM,"%s",err);
|
||||
g_free(err);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1021,7 +1040,6 @@ void echld_dispatcher_start(int* in_pipe_fds, int* out_pipe_fds, char* argv0, in
|
|||
|
||||
dispatcher = &d;
|
||||
|
||||
|
||||
echld_init_reader(&(d.parent_in),in_pipe_fds[0],4096);
|
||||
d.parent_out = out_pipe_fds[1];
|
||||
d.children = g_new0(struct dispatcher_child,ECHLD_MAX_CHILDREN);
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
@ -62,11 +63,16 @@
|
|||
#include "capture_ifinfo.h"
|
||||
#include "capture_sync.h"
|
||||
#include "version_info.h"
|
||||
#include "cfile.h"
|
||||
#include "wsutil/crash_info.h"
|
||||
#include "wsutil/privileges.h"
|
||||
#include "epan/filesystem.h"
|
||||
#include "epan/epan.h"
|
||||
#include "epan/prefs.h"
|
||||
#include "epan/ex-opt.h"
|
||||
#include "epan/funnel.h"
|
||||
#include "epan/prefs.h"
|
||||
#include "epan/timestamp.h"
|
||||
#include "disabled_protos.h"
|
||||
#include "echld.h"
|
||||
|
||||
|
@ -149,6 +155,15 @@ typedef struct _param {
|
|||
const char* desc;
|
||||
} param_t;
|
||||
|
||||
extern param_t* paramset_find (param_t* paramsets, char* name, char** err);
|
||||
|
||||
extern char* paramset_apply_get (param_t* paramsets, char* name, char** err);
|
||||
extern echld_bool_t paramset_apply_set (param_t* paramsets, char* name, char* val, char** err);
|
||||
extern echld_bool_t paramset_apply_em(param_t* paramset, enc_msg_t* em, char** err);
|
||||
|
||||
#define PARAM_LIST_FMT "%s(%s): %s\n" /* name, rw|ro|wo, desc */
|
||||
char* paramset_get_params_list(param_t* paramsets,const char* fmt);
|
||||
|
||||
#define PARAM_STR(Name, Default) static char* param_ ## Name = Default; \
|
||||
static char* param_get_ ## Name (char** err _U_ ) { return (param_ ## Name) ? g_strdup(param_ ## Name) : (*err = g_strdup( #Name " not set"), NULL); } \
|
||||
static echld_bool_t param_set_ ## Name (char* val , char** err _U_) { if (param_ ## Name) g_free(param_ ## Name); param_ ## Name = g_strdup(val); return TRUE; } \
|
||||
|
@ -165,6 +180,15 @@ typedef struct _param {
|
|||
#define RO_PARAM(Name,Desc) {#Name, param_get_ ## Name, NULL, Desc}
|
||||
#define WO_PARAM(Name,Desc) {#Name, NULL, param_set_ ## Name, Desc}
|
||||
|
||||
typedef struct _echld_epan_stuff_t {
|
||||
#ifdef HAVE_LIBPCAP
|
||||
capture_session cap_sess;
|
||||
capture_options cap_opts;
|
||||
capture_file cfile;
|
||||
#endif
|
||||
e_prefs* prefs;
|
||||
} echld_epan_stuff_t;
|
||||
|
||||
/* the call_back used by read_frame() */
|
||||
typedef long (*read_cb_t)(guint8*, size_t, echld_chld_id_t, echld_msg_type_t, echld_reqh_id_t, void*);
|
||||
|
||||
|
@ -216,7 +240,7 @@ extern long echld_read_frame(echld_reader_t* r, read_cb_t cb, void* cb_data);
|
|||
extern long echld_write_frame(int fd, GByteArray* ba, guint16 chld_id, echld_msg_type_t type, guint16 reqh_id, void* data);
|
||||
|
||||
|
||||
extern void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id);
|
||||
extern void echld_child_initialize(echld_chld_id_t chld_id, int pipe_from_parent, int pipe_to_parent, int reqh_id, echld_epan_stuff_t* es);
|
||||
extern int echld_child_loop(void);
|
||||
|
||||
/* never returns*/
|
||||
|
@ -242,21 +266,25 @@ extern void echld_unused(void);
|
|||
#define DISP_KILLED_CHILD_WAIT 100000 /* 0.1s */
|
||||
|
||||
/* fatalities */
|
||||
#define BROKEN_PARENT_PIPE 123
|
||||
#define BROKEN_DUMPCAP_PIPE 124
|
||||
#define BROKEN_READFILE 125
|
||||
#define DISPATCHER_DEAD 126
|
||||
#define UNIMPLEMENTED 127
|
||||
#define CANNOT_FORK 128
|
||||
#define SHOULD_HAVE_EXITED_BEFORE 129
|
||||
#define DISPATCHER_PIPE_FAILED 130
|
||||
#define TERMINATED 140
|
||||
#define CANNOT_PREINIT_EPAN 141
|
||||
#define BROKEN_PARENT_PIPE 9
|
||||
#define BROKEN_DUMPCAP_PIPE 10
|
||||
#define BROKEN_READFILE 11
|
||||
#define DISPATCHER_DEAD 12
|
||||
#define UNIMPLEMENTED 13
|
||||
#define CANNOT_FORK 14
|
||||
#define SHOULD_HAVE_EXITED_BEFORE 15
|
||||
#define DISPATCHER_PIPE_FAILED 16
|
||||
#define TERMINATED 17
|
||||
#define CANNOT_PREINIT_EPAN 18
|
||||
#define NO_INITIALIZER 19
|
||||
|
||||
#ifndef DEBUG_BASE
|
||||
#define echld_common_set_dbg(a,b,c)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* echld_child.h
|
||||
/* echld.h
|
||||
* epan working child API
|
||||
*
|
||||
* $Id$
|
||||
|
@ -65,6 +65,9 @@ typedef int echld_reqh_id_t;
|
|||
/* id of message handlers, a negative value is an error */
|
||||
typedef int echld_msgh_id_t;
|
||||
|
||||
/* enc_msg_t is an obscure object for an encoded message (a GbyteArray for now)*/
|
||||
typedef struct _GByteArray enc_msg_t;
|
||||
|
||||
/* sets the codec set by name */
|
||||
typedef enum _echld_encoding {
|
||||
ECHLD_ENCODING_TEXT = 'T',
|
||||
|
@ -77,12 +80,29 @@ typedef int echld_bool_t;
|
|||
/* typedef for a timeval so that sys/time.h is not required in the client */
|
||||
typedef struct timeval tv_t;
|
||||
|
||||
/* will initialize epan registering protocols and taps */
|
||||
WS_DLL_PUBLIC void echld_initialize(echld_encoding_t, char* argv0, int (*main)(int, char **));
|
||||
typedef void (*cleanup_cb_t)(void*);
|
||||
typedef int (*main_t)(int, char**); /* a pointer to main() */
|
||||
|
||||
/* cleans up (?) echld and kills the server process(es) */
|
||||
/* I will be passed to echld_initialize() */
|
||||
typedef struct _echld_init {
|
||||
echld_encoding_t encoding; /* only JSON for now */
|
||||
char* argv0; /* the value of argv[0] */
|
||||
main_t main;
|
||||
cleanup_cb_t after_fork_cb; /* to be called after fork to free the
|
||||
child processes from entities of the parent */
|
||||
void* after_fork_cb_data;
|
||||
|
||||
cleanup_cb_t at_term_cb; /* to be called after echld_terminate() is done */
|
||||
void* at_term_cb_data;
|
||||
} echld_init_t;
|
||||
|
||||
/* will initialize echld forking the dispatcher and registering protocols and taps */
|
||||
WS_DLL_PUBLIC void echld_initialize(echld_init_t*);
|
||||
|
||||
/* cleans up echld and kills the server process(es) */
|
||||
WS_DLL_PUBLIC echld_state_t echld_terminate(void);
|
||||
|
||||
|
||||
/*
|
||||
* returning ECHLD_NO_ERROR means there has being no error
|
||||
*
|
||||
|
@ -94,25 +114,6 @@ WS_DLL_PUBLIC echld_state_t echld_terminate(void);
|
|||
*/
|
||||
WS_DLL_PUBLIC echld_error_t echld_get_error(const char** errstr_ptr);
|
||||
|
||||
/*
|
||||
* Children Management Operations
|
||||
*/
|
||||
|
||||
/* create a new worker process */
|
||||
WS_DLL_PUBLIC echld_chld_id_t echld_new(void* child_data);
|
||||
|
||||
/* will return NULL on error, if NULL is also ok for you use echld_get_error() */
|
||||
WS_DLL_PUBLIC void* echld_get_data(echld_chld_id_t);
|
||||
|
||||
WS_DLL_PUBLIC echld_state_t echld_set_data(echld_chld_id_t id, void* child_data);
|
||||
|
||||
/* for each child call cb(id,child_data,cb_data) */
|
||||
typedef echld_bool_t (*echld_iter_cb_t)(echld_chld_id_t, void* child_data, void* cb_data);
|
||||
WS_DLL_PUBLIC void echld_foreach_child(echld_iter_cb_t cb, void* cb_data);
|
||||
|
||||
/* enc_msg_t is an obscure object for an encoded message */
|
||||
typedef struct _GByteArray enc_msg_t;
|
||||
|
||||
|
||||
/*
|
||||
* prototype of message callbacks passed to echld_reqh() and echld_msgh()
|
||||
|
@ -127,7 +128,6 @@ typedef struct _GByteArray enc_msg_t;
|
|||
typedef echld_bool_t (*echld_msg_cb_t)(echld_msg_type_t type, enc_msg_t* msg_buff, void* cb_data);
|
||||
|
||||
|
||||
|
||||
/* encoding and decoding */
|
||||
|
||||
|
||||
|
@ -152,8 +152,10 @@ typedef struct _parent_out {
|
|||
enc_msg_t* (*save_file)(const char* filename, const char* params);
|
||||
} echld_parent_encoder_t;
|
||||
|
||||
|
||||
WS_DLL_PUBLIC echld_parent_encoder_t* echld_get_encoder(void);
|
||||
|
||||
|
||||
/*
|
||||
* decoder
|
||||
* it returns an allocated string with the decoded response of the message, you free it.
|
||||
|
@ -161,6 +163,31 @@ WS_DLL_PUBLIC echld_parent_encoder_t* echld_get_encoder(void);
|
|||
*/
|
||||
WS_DLL_PUBLIC char* echld_decode(echld_msg_type_t, enc_msg_t*);
|
||||
|
||||
/*
|
||||
* Children Management Operations
|
||||
*/
|
||||
|
||||
WS_DLL_PUBLIC enc_msg_t* echld_new_child_params(void);
|
||||
|
||||
/* takes the em, and param=value pairs of strings, NULL to end.
|
||||
echld_new_child_params_add_params(em,param1_str,val1_str,param2_str,val2_str,NULL); */
|
||||
WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t*, ...);
|
||||
|
||||
WS_DLL_PUBLIC enc_msg_t* echld_new_child_params_merge(enc_msg_t*, enc_msg_t*);
|
||||
|
||||
|
||||
/* create a new worker process */
|
||||
WS_DLL_PUBLIC echld_chld_id_t echld_new(enc_msg_t* new_child_parameters, void* child_data);
|
||||
|
||||
/* will return NULL on error, if NULL is also ok for you use echld_get_error() */
|
||||
WS_DLL_PUBLIC void* echld_get_data(echld_chld_id_t);
|
||||
|
||||
WS_DLL_PUBLIC echld_state_t echld_set_data(echld_chld_id_t id, void* child_data);
|
||||
|
||||
/* for each child call cb(id,child_data,cb_data) */
|
||||
typedef echld_bool_t (*echld_iter_cb_t)(echld_chld_id_t, void* child_data, void* cb_data);
|
||||
WS_DLL_PUBLIC void echld_foreach_child(echld_iter_cb_t cb, void* cb_data);
|
||||
|
||||
/*
|
||||
* Request Handlers
|
||||
*
|
||||
|
|
|
@ -183,13 +183,16 @@ void parent_reaper(int sig) {
|
|||
}
|
||||
|
||||
/* will initialize epan registering protocols and taps */
|
||||
void echld_initialize(echld_encoding_t enc, char* argv0, int (*main)(int, char **)) {
|
||||
void echld_initialize(echld_init_t* init) {
|
||||
int from_disp[2];
|
||||
int to_disp[2];
|
||||
|
||||
PARENT_DBG((1,"Echld Starting"));
|
||||
|
||||
if (enc != ECHLD_ENCODING_JSON) {
|
||||
if (!init) {
|
||||
PARENT_FATAL((NO_INITIALIZER,"Missing Initializer"));
|
||||
}
|
||||
|
||||
if (init->encoding != ECHLD_ENCODING_JSON) {
|
||||
PARENT_FATAL((UNIMPLEMENTED,"Only JSON implemented"));
|
||||
}
|
||||
|
||||
|
@ -213,7 +216,12 @@ void echld_initialize(echld_encoding_t enc, char* argv0, int (*main)(int, char *
|
|||
#endif
|
||||
/* child code */
|
||||
echld_cleanup();
|
||||
echld_dispatcher_start(to_disp,from_disp,argv0,main);
|
||||
|
||||
if (init->after_fork_cb)
|
||||
init->after_fork_cb(init->after_fork_cb_data);
|
||||
|
||||
echld_dispatcher_start(to_disp,from_disp,init->argv0,init->main);
|
||||
|
||||
PARENT_FATAL((SHOULD_HAVE_EXITED_BEFORE,"This shoudln't happen"));
|
||||
} else {
|
||||
/* parent code */
|
||||
|
@ -468,7 +476,7 @@ static int msgh_attach(echld_t* c, echld_msg_type_t t, echld_msg_cb_t resp_cb, v
|
|||
|
||||
static int next_chld_id = 1;
|
||||
|
||||
extern int echld_new(void* child_data) {
|
||||
extern int echld_new(enc_msg_t* new_child_em, void* child_data) {
|
||||
echld_t* c = get_child(-1);
|
||||
|
||||
if (!c) return -1;
|
||||
|
@ -477,12 +485,10 @@ extern int echld_new(void* child_data) {
|
|||
c->data = child_data;
|
||||
c->state = CREATING;
|
||||
|
||||
g_byte_array_set_size(parent.snd,0);
|
||||
|
||||
PARENT_DBG((1,"Child[%d]: =>CREATING",c->chld_id));
|
||||
|
||||
msgh_attach(c,ECHLD_CHILD_DEAD, parent_dead_child , c);
|
||||
reqh_snd(c, ECHLD_NEW_CHILD, parent.snd, parent_get_hello, c);
|
||||
reqh_snd(c, ECHLD_NEW_CHILD, (GByteArray*)new_child_em, parent_get_hello, c);
|
||||
|
||||
return c->chld_id;
|
||||
}
|
||||
|
@ -806,3 +812,40 @@ extern echld_state_t echld_wait(struct timeval* timeout) {
|
|||
return ECHLD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
enc_msg_t* echld_new_child_params(void) {
|
||||
return (enc_msg_t*)g_byte_array_new();
|
||||
}
|
||||
|
||||
enc_msg_t* echld_new_child_params_merge(enc_msg_t* em1, enc_msg_t* em2) {
|
||||
GByteArray* ba = g_byte_array_new();
|
||||
GByteArray* b1 = (GByteArray*)em1;
|
||||
GByteArray* b2 = (GByteArray*)em2;
|
||||
|
||||
g_byte_array_append(ba,b1->data,b1->len);
|
||||
g_byte_array_append(ba,b2->data,b2->len);
|
||||
|
||||
return (enc_msg_t*)ba;
|
||||
}
|
||||
|
||||
WS_DLL_PUBLIC void echld_new_child_params_add_params(enc_msg_t* em, ...) {
|
||||
GByteArray* ba = (GByteArray*) em;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap,em);
|
||||
do {
|
||||
char* param_str = va_arg(ap, char*);
|
||||
|
||||
if (param_str) {
|
||||
char* val_str = va_arg(ap, char*);
|
||||
|
||||
g_byte_array_append(ba, (guint8*) param_str, (guint)strlen(param_str)+1);
|
||||
g_byte_array_append(ba, (guint8*) val_str, (guint)strlen(val_str)+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
} while(1);
|
||||
va_end(ap);
|
||||
|
||||
}
|
||||
|
|
160
echld_test.c
160
echld_test.c
|
@ -64,8 +64,79 @@ typedef struct _cmd_t {
|
|||
const char* help;
|
||||
} cmd_t;
|
||||
|
||||
static char* new_child_cmd(char** params _U_, char** err) {
|
||||
int child = echld_new(NULL);
|
||||
|
||||
#define MAX_PARAMSETS 16
|
||||
|
||||
static enc_msg_t* paramsets[MAX_PARAMSETS] = {
|
||||
NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,
|
||||
NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL
|
||||
};
|
||||
|
||||
static int nps = 0;
|
||||
|
||||
static char* ps_cmd(char** pars _U_, char** err _U_) {
|
||||
int n_id = nps++;
|
||||
|
||||
if (n_id >= MAX_PARAMSETS) {
|
||||
*err = g_strdup("Max Num of Paramsets reached");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
paramsets[n_id] = echld_new_child_params();
|
||||
|
||||
return g_strdup_printf("New Paramset ps_id=%d",n_id);
|
||||
}
|
||||
|
||||
static char* psadd_cmd(char** params _U_, char** err) {
|
||||
int ps_id = (int) strtol(params[1], NULL, 10);
|
||||
|
||||
if (ps_id >= nps) {
|
||||
*err = g_strdup_printf("No paramset pd_is=%d",ps_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
echld_new_child_params_add_params(paramsets[ps_id], params[2], params[3], NULL);
|
||||
|
||||
return g_strdup_printf("PSAdd ps_id=%d %s='%s'", ps_id, params[2], params[3]);
|
||||
}
|
||||
|
||||
static char* psmerge_cmd(char** params, char** err) {
|
||||
int ps1_id = (int) strtol(params[1], NULL, 10);
|
||||
int ps2_id = (int) strtol(params[2], NULL, 10);
|
||||
int n_id;
|
||||
|
||||
if (ps1_id >= nps) {
|
||||
*err = g_strdup_printf("No paramset pd_is=%d",ps1_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ps2_id >= nps) {
|
||||
*err = g_strdup_printf("No paramset pd_is=%d",ps2_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
n_id = nps++;
|
||||
|
||||
if (n_id >= MAX_PARAMSETS) {
|
||||
*err = g_strdup_printf("Max Num of Paramsets reached");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
paramsets[n_id] = echld_new_child_params_merge(paramsets[ps1_id],paramsets[ps2_id]);
|
||||
|
||||
return g_strdup_printf("Merged Paramset ps1_id=%d ps2_id=%d ps_id=%d",ps1_id, ps2_id, n_id);
|
||||
}
|
||||
|
||||
static char* new_child_cmd(char** params, char** err) {
|
||||
int ps_id = (int) strtol(params[1], NULL, 10);
|
||||
int child;
|
||||
|
||||
if (ps_id >= nps) {
|
||||
*err = g_strdup_printf("No paramset pd_is=%d",ps_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
child = echld_new(paramsets[ps_id],NULL);
|
||||
|
||||
if (child <= 0) {
|
||||
*err = g_strdup("No child\n");
|
||||
|
@ -215,11 +286,19 @@ static char* save_cmd(char** pars _U_, char** err _U_) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static char* run_cmd(char** pars, char** err _U_);
|
||||
|
||||
|
||||
|
||||
|
||||
cmd_t commands[] = {
|
||||
{ "QUIT", quit_cmd, 0, "QUIT"},
|
||||
{ "HELP", help_cmd, 0, "HELP"},
|
||||
{ "NEW", new_child_cmd, 0, "NEW"},
|
||||
{ "RUN", run_cmd, 1, "RUN filename"},
|
||||
{ "PS", ps_cmd, 1, "PS [dummy]"},
|
||||
{ "PSADD", psadd_cmd, 4, "PSADD ps_id param value"},
|
||||
{ "PSMERGE", psmerge_cmd, 4, "PSMERGE ps_id ps_id"},
|
||||
{ "NEW", new_child_cmd, 1, "NEW ps_id"},
|
||||
{ "PING", ping_cmd, 1, "PING child_id"},
|
||||
{ "SET", set_cmd, 3, "SET child_id param_name param_val"},
|
||||
{ "GET", get_cmd, 2, "GET child_id param_name"},
|
||||
|
@ -251,7 +330,47 @@ static char* help_cmd(char** params _U_, char** err _U_) {
|
|||
}
|
||||
|
||||
|
||||
static int invoke_cmd(FILE* in_fp) {
|
||||
size_t len;
|
||||
char* cmd_line;
|
||||
|
||||
if(( cmd_line = fgetln(in_fp,&len) )) {
|
||||
cmd_t* c = commands;
|
||||
cmd_line[len] = 0;
|
||||
g_strchomp(cmd_line);
|
||||
|
||||
for (;c->txt;c++) {
|
||||
if ( strcasestr(cmd_line, c->txt) == cmd_line ) {
|
||||
char** params = g_strsplit(cmd_line, " ", c->args_taken+1);
|
||||
char* err = NULL;
|
||||
char* str = c->cb(params,&err);
|
||||
|
||||
if (err) {
|
||||
fprintf(stdout, "Error: %s\n", err);
|
||||
g_free(err);
|
||||
} else {
|
||||
fprintf(stdout, "%s\n", str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
g_strfreev(params);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "Error: no such command %s\n", cmd_line);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static char* run_cmd(char** pars, char** err _U_) {
|
||||
FILE* fp = fopen(pars[1],"r");
|
||||
while(invoke_cmd(fp)) { ; }
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int got_param = 0;
|
||||
|
@ -260,13 +379,15 @@ int got_param = 0;
|
|||
int main(int argc _U_, char** argv _U_) {
|
||||
struct timeval tv;
|
||||
int tot_cycles = 0;
|
||||
echld_init_t init = {ECHLD_ENCODING_JSON,argv[0],main,NULL,NULL,NULL,NULL};
|
||||
|
||||
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
echld_set_parent_dbg_level(5);
|
||||
|
||||
echld_initialize(ECHLD_ENCODING_JSON,argv[0],main);
|
||||
echld_initialize(&init);
|
||||
|
||||
do {
|
||||
fd_set rfds;
|
||||
|
@ -281,38 +402,9 @@ int main(int argc _U_, char** argv _U_) {
|
|||
nfds = echld_select(FD_SETSIZE, &rfds, NULL, &efds, &tv);
|
||||
|
||||
if (FD_ISSET(0,&rfds)) {
|
||||
size_t len;
|
||||
char* cmd_line;
|
||||
|
||||
if(( cmd_line = fgetln(stdin,&len) )) {
|
||||
cmd_t* c = commands;
|
||||
cmd_line[len] = 0;
|
||||
g_strchomp(cmd_line);
|
||||
|
||||
for (;c->txt;c++) {
|
||||
if ( strcasestr(cmd_line, c->txt) == cmd_line ) {
|
||||
char** params = g_strsplit(cmd_line, " ", c->args_taken+1);
|
||||
char* err = NULL;
|
||||
char* str = c->cb(params,&err);
|
||||
|
||||
if (err) {
|
||||
fprintf(stdout, "Error: %s\n", err);
|
||||
g_free(err);
|
||||
} else {
|
||||
fprintf(stdout, "%s\n", str);
|
||||
g_free(str);
|
||||
}
|
||||
|
||||
g_strfreev(params);
|
||||
goto cmd_executed;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stdout, "Error: no such command %s\n", cmd_line);
|
||||
}
|
||||
invoke_cmd(stdin);
|
||||
}
|
||||
|
||||
cmd_executed:
|
||||
tot_cycles++;
|
||||
} while( keep_going );
|
||||
|
||||
|
|
Loading…
Reference in New Issue