int fw_perform_return( gchar *action, GHashTable *conf, peer *p, gchar *result, int size) { GHashTable *data; gchar *cmd; FILE * fd; int ret=0; gchar dummy_result[30]; if ( !result ) { result = dummy_result; size = sizeof(dummy_result); } data = g_hash_dup( conf ); // // Than add specifics about this particular client, if any if (p != NULL) { g_hash_set( data, "IP", p->ip ); g_hash_set( data, "MAC", p->hw ); g_hash_set( data, "Class", "Public" ); } cmd = conf_string( conf, action ); cmd = parse_template( cmd, data ); g_warning("Got command %s from action %s", cmd, action ); // add data to the environment g_hash_table_foreach( data, (GHFunc) fw_popen_set_env, NULL ); fd = popen(cmd, "r"); if(fd == NULL) { g_warning( "popen %s failed: %m", cmd ); ret=1; } else if ( fgets(result, size, fd) == NULL ) { g_warning( "fgets %s failed: %m", cmd ); ret=1; } if ( fd && pclose(fd) != 0 ) { g_warning( "pclose %s failed: %m", cmd ); ret=1; } g_hash_free(data); g_free(cmd); return ret; }
static int fw_exec( fw_action *act, GHashTable *conf ) { GHashTable *data; GPtrArray *env; gchar *cmd, **arg, **n; data = g_hash_dup( conf ); // // Than add specifics about this particular client, if any if (act->p != NULL) { g_hash_set( data, "IP", act->p->ip ); g_hash_set( data, "MAC", act->p->hw ); g_hash_set( data, "Class", "Public" ); } cmd = conf_string( conf, act->cmd ); cmd = parse_template( cmd, data ); g_message("Got command %s from action %s", cmd, act->cmd ); arg = g_strsplit( cmd, " ", 0 ); // prime the environment with our existing environment env = g_ptr_array_new(); for ( n = environ; *n != NULL; n++ ) g_ptr_array_add( env, *n ); // Then add everything from the conf file g_hash_table_foreach( data, (GHFunc) fw_exec_add_env, env ); // Add a closing NULL so execve knows where to lay off. g_ptr_array_add( env, NULL ); /* We're not cleaning up memory references because * hopefully the exec won't fail... */ execve( *arg, arg, (char **)env->pdata ); g_error( "execve %s failed: %m", cmd ); // Shouldn't happen. return -1; }