static void update_progress_bar() { #ifdef FAKE_PROGRESS_BAR int total = 100000; int remaining = total - progress_bar_level; int addme = 0; addme = (5*100*remaining)/total; progress_bar_level += addme; comm_send_status(Globals, arg_get_value(Hostinfos, "NAME"), "portscan", progress_bar_level, total); signal(SIGALRM, update_progress_bar); /* * Update the alarm time */ alarm((progress_bar_level/(total))+4); #else fprintf(stderr, "T =%d/%d\tU=%d/%d\n", scanned_tcp_ports, total_tcp_ports, scanned_udp_ports, total_udp_ports); comm_send_status(Globals, arg_get_value(Hostinfos, "NAME"), "portscan", scanned_tcp_ports + scanned_udp_ports, total_tcp_ports + total_udp_ports); #endif }
/* Restarts the scanner by reloading the configuration. */ static void reload_openvassd () { struct arglist *preferences = NULL, *plugins; nvticache_t *nvti_cache; char *config_file; pid_t handler_pid; log_write ("Reloading the scanner.\n"); /* Ignore SIGHUP while reloading. */ openvas_signal (SIGHUP, SIG_IGN); handler_pid = loading_handler_start (); /* Free the nvti cache. */ nvti_cache = arg_get_value (global_preferences, "nvticache"); nvticache_free (nvti_cache); /* Reload config file. */ config_file = arg_get_value (global_preferences, "config_file"); preferences_init (config_file, &preferences); /* Reload the plugins */ plugins = plugins_init (preferences); set_globals_from_preferences (preferences); plugins_free (global_plugins); global_plugins = plugins; loading_handler_stop (handler_pid); log_write ("Finished reloading the scanner.\n"); reload = 0; openvas_signal (SIGHUP, sighup); }
tree_cell * nasl_get_preference(lex_ctxt * lexic) { tree_cell *retc; char *name, *value; struct arglist *script_infos, *prefs; script_infos = lexic->script_infos; prefs = arg_get_value(script_infos, "preferences"); if (prefs == NULL) { nasl_perror(lexic, "get_preference: not preferences\n"); return NULL; } name = get_str_var_by_num(lexic, 0); if (name == NULL) { nasl_perror(lexic, "get_preference: no name\n"); return NULL; } value = arg_get_value(prefs, name); if (value == NULL) return NULL; retc = alloc_typed_cell(CONST_DATA); retc->x.str_val = strdup(value); retc->size = strlen(value); return retc; }
tree_cell * nasl_scanner_status(lex_ctxt * lexic) { int current = get_int_local_var_by_name(lexic, "current", -1); int total = get_int_local_var_by_name(lexic, "total", -1); struct arglist * script_infos = lexic->script_infos; struct arglist * hostdata = arg_get_value(script_infos, "HOSTNAME"); if(current != -1 && total != -1) { struct arglist * globs = arg_get_value(script_infos, "globals"); if (globs == NULL) return NULL; comm_send_status(globs, arg_get_value(hostdata, "NAME"), "portscan", current, total); } return FAKE_CELL; }
tree_cell * nasl_end_denial(lex_ctxt * lexic) { int port = (int)arg_get_value(lexic->script_infos, "denial_port"); int soc; int to = lexic->recv_timeout; struct arglist * script_infos = lexic->script_infos; tree_cell * retc = NULL; /* * We must wait the time the DoS does its effect */ Sleep(10); if(!port) { int ping = (int)arg_get_value(script_infos, "tcp_ping_result"); if(ping) return nasl_tcp_ping(lexic); else { retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = 1; return retc; } } else { retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; soc = open_stream_connection(script_infos, port, NESSUS_ENCAPS_IP, to); if(soc > 0) { /* Send some data */ #define BOGUS "are you dead ?" if((nsend(soc, BOGUS, sizeof(BOGUS)-1, 0))>=0) { retc->x.i_val = 1; close_stream_connection(soc); return retc; } } } retc->x.i_val = 0; return retc; }
void nasl_trace(lex_ctxt * lexic, char * msg, ...) { va_list param; char debug_message[4096]; char *script_name = "", *p; if(nasl_trace_fp == NULL) return; va_start(param, msg); if( lexic != NULL ) { script_name = arg_get_value(lexic->script_infos, "script_name"); if(script_name == NULL) script_name = ""; } vsnprintf(debug_message, sizeof(debug_message), msg, param); for (p = debug_message; *p != '\0'; p ++) ; if (p == debug_message || p[-1] != '\n') fprintf(nasl_trace_fp, "[%d](%s) %s\n",getpid(), script_name, debug_message); else fprintf(nasl_trace_fp, "[%d](%s) %s",getpid(), script_name, debug_message); va_end(param); }
struct arglist * plug_get_oldstyle_kb(struct arglist * desc ) { struct kb_item ** kb = arg_get_value(desc, "key"); struct arglist * ret; struct kb_item * k; int i; if ( kb == NULL ) return NULL; ret = emalloc ( sizeof(struct arglist) ); for ( i = 0 ; i < HASH_MAX ; i ++ ) { k = kb[i]; while ( k != NULL ) { if ( k->type == KB_TYPE_INT ) arg_add_value(ret, k->name, ARG_INT, -1, (void*)k->v.v_int); else if ( k->type == KB_TYPE_STR ) arg_add_value(ret, k->name, ARG_STRING, strlen(k->v.v_str), estrdup(k->v.v_str)); k = k->next; } } return ret; }
char *xscan_get_desc(struct arglist *desc, char *key) { #ifdef _XSCAN_PLUG char lang[MAX_PATH] = {0}; char line[MAX_PATH] = {0}; char buf[10240] = {0}; char *fname = NULL; char *ptr = NULL; ptr = arg_get_value(desc, "script_name"); if (!ptr) return NULL; fname = strrchr(ptr, '\\'); if (fname) fname++; else fname = ptr; sprintf(line, ".\\dat\\language.ini"); GetPrivateProfileString("LANGUAGE", "SELECTED", "\0", lang, sizeof(lang)-1, line); sprintf(line, ".\\scripts\\desc\\%s.desc", fname); GetPrivateProfileString(lang, key, "\0", buf, sizeof(buf)-1, line); if (strlen(buf)) return strdup(buf); else return NULL; #else return NULL; #endif }
/** * @brief Determine if the plugin requirements are met. * * @return Returns NULL is everything is ok, else an error message. */ char * requirements_plugin (kb_t kb, struct scheduler_plugin *plugin, struct arglist *preferences) { static char error[64]; char *missing; char *present; struct arglist *tcp, *udp, *rkeys, *ekeys; char *opti = arg_get_value (preferences, "optimization_level"); /* * Check wether the good ports are open */ error[sizeof (error) - 1] = '\0'; tcp = plugin->required_ports; if (tcp != NULL && (get_closed_ports (kb, tcp, preferences)) == 0) { strncpy (error, "none of the required tcp ports are open", sizeof (error) - 1); return error; } udp = plugin->required_udp_ports; if (udp != NULL && (get_closed_udp_ports (kb, udp, preferences)) == 0) { strncpy (error, "none of the required udp ports are open", sizeof (error) - 1); return error; } if (opti != NULL && (strcmp (opti, "open_ports") == 0 || atoi (opti) == 1)) return NULL; /* * Check wether a key we wanted is missing */ rkeys = plugin->required_keys; if ((missing = key_missing (kb, rkeys))) { snprintf (error, sizeof (error), "because the key %s is missing", missing); return error; } if (opti != NULL && (strcmp (opti, "required_keys") == 0 || atoi (opti) == 2)) return NULL; /* * Check wether a key we do not want is present */ ekeys = plugin->excluded_keys; if ((present = key_present (kb, ekeys))) { snprintf (error, sizeof (error), "because the key %s is present", present); return error; } return NULL; }
/* remove the udp data for socket <soc> */ static void rm_udp_data (struct arglist *script_infos, int soc) { GHashTable * udp_data = arg_get_value (script_infos, "udp_data"); if (udp_data) g_hash_table_remove (udp_data, (gconstpointer)&soc); }
/* Are safe checks enabled ? */ tree_cell * safe_checks(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; struct arglist * prefs = arg_get_value(script_infos, "preferences"); char * value; tree_cell * retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; value = arg_get_value(prefs, "safe_checks"); if((value && !strcmp(value, "yes"))) { retc->x.i_val = 1; } else retc->x.i_val = 0; return retc; }
void add_socket(struct arglist *script_infos, int socket) { struct arglist *socket_list = NULL; struct arglist *temp_list = NULL; char line[10] = {0}; if (socket <= 0) return; socket_list = (struct arglist *)arg_get_value(script_infos, "socket_list"); if (!socket_list) { socket_list = emalloc(sizeof(struct arglist)); if (!socket_list) return; arg_add_value(script_infos, "socket_list", ARG_PTR, -1, socket_list); } sprintf(line, "%d", socket); if (arg_get_value(socket_list, line) <= 0) arg_add_value(socket_list, line, ARG_INT, -1, (void *)socket); }
void plugin_set_running_state(struct arglist * plugin, int state) { if(plugin == NULL) return; if(arg_get_value(plugin, "RUNNING_STATE") != NULL) arg_set_value(plugin, "RUNNING_STATE", sizeof(state), (void*)state); else arg_add_value(plugin, "RUNNING_STATE", ARG_INT, sizeof(state), (void*)state); }
static void handle_client (struct arglist *globals) { struct arglist *prefs = arg_get_value (globals, "preferences"); /* Become process group leader and the like ... */ start_daemon_mode (); wait: comm_wait_order (globals); preferences_reset_cache (); ntp_timestamp_scan_starts (globals); attack_network (globals); ntp_timestamp_scan_ends (globals); comm_terminate (globals); if (arg_get_value (prefs, "ntp_keep_communication_alive")) { log_write ("Kept alive connection"); goto wait; } }
/* remove the udp data for socket <soc> */ static void rm_udp_data(struct arglist * script_infos, int soc) { harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12] = {0}; if(udp_data == NULL) return; snprintf(name, sizeof(name)-1, "%d", soc); harg_remove(udp_data, name); }
/* get the udp data for socket <soc> */ static char * get_udp_data (struct arglist *script_infos, int soc, int *len) { GHashTable * udp_data = arg_get_value (script_infos, "udp_data"); struct udp_record * data_record = g_hash_table_lookup (udp_data, (gconstpointer)&soc); if (!data_record) return NULL; *len = data_record->len; return data_record->data; }
static void init_plugins (struct arglist *options) { struct arglist *preferences, *plugins; preferences = arg_get_value (options, "preferences"); plugins = plugins_init (preferences); arg_replace_value (options, "plugins", ARG_ARGLIST, -1, plugins); plugins_free (global_plugins); global_plugins = plugins; }
tree_cell * nasl_this_host(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; tree_cell * retc; struct in_addr addr; char hostname[255]; char * ret; struct in_addr * ia = plug_get_host_ip(script_infos); struct in_addr src; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; addr = socket_get_next_source_addr(arg_get_value(script_infos, "globals")); if ( addr.s_addr != INADDR_ANY ) { retc->x.str_val = estrdup(inet_ntoa(addr)); retc->size = strlen(retc->x.str_val); return retc; } src.s_addr = 0; if(ia) { if(islocalhost(ia)) src.s_addr = ia->s_addr; else (void)routethrough(ia, &src); if(src.s_addr) { char * ret; ret = estrdup(inet_ntoa(src)); retc->x.str_val = ret; retc->size = strlen(ret); return retc; } hostname[sizeof(hostname) - 1] = '\0'; gethostname(hostname, sizeof(hostname) - 1); addr = nn_resolve(hostname); ret = estrdup(inet_ntoa(addr)); retc->x.str_val = ret; retc->size = strlen(ret); } return retc; }
static tree_cell * security_something(lex_ctxt * lexic, proto_post_something_t proto_post_func, post_something_t post_func) { struct arglist * script_infos = lexic->script_infos; char* proto = get_str_local_var_by_name(lexic, "protocol"); char* data = get_str_local_var_by_name(lexic, "data"); int port = get_int_local_var_by_name(lexic, "port", -1); char * dup = NULL; if(data != NULL) { int len = get_local_var_size_by_name(lexic, "data"); int i; dup = strndup(data, len); for(i=0; i<len; i++) if(dup[i] == 0)dup[i]=' '; } if((arg_get_value(script_infos, "standalone")) != NULL) { if( data != NULL ) fprintf(stdout, "%s\n", dup); else fprintf(stdout, "Success\n"); } if(proto == NULL) proto = get_str_local_var_by_name(lexic, "proto"); if(port < 0) port = get_int_var_by_num(lexic, 0, -1); if(dup != NULL) { if(proto == NULL) post_func(script_infos, port, dup); else proto_post_func(script_infos, port, proto, dup); efree(&dup); return FAKE_CELL; } if(proto == NULL) post_func(script_infos, port, NULL); else proto_post_func(script_infos, port, proto, NULL); return FAKE_CELL; }
static void start_daemon_mode (void) { char *s; int fd; /* do not block the listener port for subsequent scanners */ close (global_iana_socket); /* become process group leader */ if (setsid () < 0) { log_write ("Warning: Cannot set process group leader (%s)\n", strerror (errno)); } if ((fd = open ("/dev/tty", O_RDWR)) >= 0) close (fd); /* no input, anymore: provide an empty-file substitute */ if ((fd = open ("/dev/null", O_RDONLY)) < 0) { log_write ("Cannot open /dev/null (%s) -- aborting\n", strerror (errno)); exit (0); } dup2 (fd, 0); close (fd); /* provide a dump file to collect stdout and stderr */ if ((s = arg_get_value (global_preferences, "dumpfile")) == 0) s = OPENVASSD_DEBUGMSG; /* setting "-" denotes terminal mode */ if (strcmp (s, "-") == 0) return; fflush (stdout); fflush (stderr); if ((fd = open (s, O_WRONLY | O_CREAT | O_APPEND, 0600)) < 0) { log_write ("Cannot create a new dumpfile %s (%s)-- aborting\n", s, strerror (errno)); exit (2); } dup2 (fd, 1); dup2 (fd, 2); close (fd); setlinebuf (stdout); setlinebuf (stderr); }
tree_cell * nasl_scanner_get_port(lex_ctxt * lexic) { tree_cell * retc; int idx = get_int_var_by_num(lexic, 0, -1); struct arglist * script_infos = lexic->script_infos; struct arglist * prefs = arg_get_value(script_infos, "preferences"); char *prange = arg_get_value(prefs, "port_range"); static int num = 0; static u_short * ports = NULL; if (prange == NULL) return NULL; if(idx < 0) { nasl_perror(lexic, "Argument error in scanner_get_port()\n"); nasl_perror(lexic, "Correct usage is : num = scanner_get_port(<num>)\n"); nasl_perror(lexic, "Where <num> should be 0 the first time you call it\n"); return NULL; } if (ports == NULL) { ports = (u_short*)getpts(prange, &num); if (ports == NULL) { return NULL; } } if(idx >= num) { return NULL; } retc = alloc_tree_cell(0, NULL); retc->type = CONST_INT; retc->x.i_val = ports[idx]; return retc; }
/** * @brief Initialize everything. * * @param stop_early 0: do some initialization, 1: no initialization. */ static int init_openvassd (struct arglist *options, int first_pass, int stop_early, int dont_fork) { int isck = -1; struct arglist *preferences = NULL; int scanner_port = GPOINTER_TO_SIZE (arg_get_value (options, "scanner_port")); char *config_file = arg_get_value (options, "config_file"); struct addrinfo *addr = arg_get_value (options, "addr"); preferences_init (config_file, &preferences); log_init (arg_get_value (preferences, "logfile")); if (dont_fork == FALSE) setup_legacy_log_handler (log_vwrite); if (!stop_early) { if (first_pass != 0) init_network (scanner_port, &isck, *addr); } if (first_pass && !stop_early) { openvas_signal (SIGSEGV, sighandler); openvas_signal (SIGCHLD, sighand_chld); openvas_signal (SIGTERM, sighandler); openvas_signal (SIGINT, sighandler); openvas_signal (SIGHUP, sighup); openvas_signal (SIGUSR1, sighandler); /* openvassd dies, not its sons */ openvas_signal (SIGPIPE, SIG_IGN); } arg_replace_value (options, "isck", ARG_INT, sizeof (gpointer), GSIZE_TO_POINTER (isck)); arg_replace_value (options, "preferences", ARG_ARGLIST, -1, preferences); set_globals_from_preferences (preferences); return 0; }
static void set_globals_from_preferences (struct arglist *prefs) { char *str; if ((str = arg_get_value (prefs, "max_hosts")) != NULL) { global_max_hosts = atoi (str); if (global_max_hosts <= 0) global_max_hosts = 15; } if ((str = arg_get_value (prefs, "max_checks")) != NULL) { global_max_checks = atoi (str); if (global_max_checks <= 0) global_max_checks = 10; } arg_free (global_preferences); global_preferences = prefs; }
static void main_loop () { log_write ("openvassd %s started\n", OPENVASSD_VERSION); proctitle_set ("openvassd: Waiting for incoming connections"); for (;;) { int soc; int family; unsigned int lg_address; struct sockaddr_in6 address6; struct sockaddr_in6 *p_addr; struct arglist *globals; struct addrinfo *ai; check_and_reload (); wait_for_children1 (); ai = arg_get_value (g_options, "addr"); lg_address = sizeof (struct sockaddr_in6); soc = accept (global_iana_socket, (struct sockaddr *) (&address6), &lg_address); if (soc == -1) continue; /* * MA: you cannot share an open SSL connection through fork/multithread * The SSL connection shall be open _after_ the fork */ globals = emalloc (sizeof (struct arglist)); arg_add_value (globals, "global_socket", ARG_INT, -1, GSIZE_TO_POINTER (soc)); arg_add_value (globals, "plugins", ARG_ARGLIST, -1, global_plugins); arg_add_value (globals, "preferences", ARG_ARGLIST, -1, global_preferences); p_addr = emalloc (sizeof (struct sockaddr_in6)); family = ai->ai_family; memcpy (p_addr, &address6, sizeof (address6)); arg_add_value (globals, "client_address", ARG_PTR, -1, p_addr); arg_add_value (globals, "family", ARG_INT, -1, GSIZE_TO_POINTER (family)); /* we do not want to create an io thread, yet so the last argument is -1 */ if (create_process ((process_func_t) scanner_thread, globals) < 0) { log_write ("Could not fork - client won't be served"); sleep (2); } close (soc); arg_free (globals); } }
tree_cell * nasl_start_denial(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; int to = lexic->recv_timeout; int port = plug_get_host_open_port(script_infos); int soc; int alive = 0; tree_cell * p; if(port) { soc = open_stream_connection(script_infos, port, NESSUS_ENCAPS_IP, to); if(soc>=0) { if(arg_get_value(script_infos, "denial_port") != 0) arg_set_value(script_infos, "denial_port", sizeof(int), (void*)port); else arg_add_value(script_infos, "denial_port", ARG_INT, sizeof(int), (void*)port); close_stream_connection(soc); return FAKE_CELL; } } p = nasl_tcp_ping(lexic); if (p != NULL) alive = p->x.i_val; if(arg_get_value(script_infos, "tcp_ping_result") != 0) arg_set_value(script_infos, "tcp_ping_result", sizeof(int), (void*)alive); else arg_add_value(script_infos, "tcp_ping_result", ARG_INT, sizeof(int), (void*)alive); deref_cell(p); return FAKE_CELL; }
/* add udp data in our cache */ static int add_udp_data(struct arglist * script_infos, int soc, char * data, int len) { harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12] = {0}; if(udp_data == NULL) { udp_data = harg_create(123); arg_add_value(script_infos, "udp_data", ARG_PTR, -1, udp_data); } snprintf(name, sizeof(name)-1, "%d", soc); if(harg_get_blob(udp_data, name) != NULL) harg_set_blob(udp_data, name, len, data); else harg_add_blob( udp_data, name, len, data); return 0; }
/* get the udp data for socket <soc> */ static char * get_udp_data(struct arglist * script_infos, int soc, int * len) { harglst * udp_data = arg_get_value(script_infos, "udp_data"); char name[12] = {0}; char * ret; if(udp_data == NULL) return NULL; snprintf(name, sizeof(name)-1, "%d", soc); ret = harg_get_blob(udp_data, name); if(ret == NULL) return NULL; *len = harg_get_size(udp_data, name); return ret; }
/* add udp data in our cache */ static int add_udp_data (struct arglist *script_infos, int soc, char *data, int len) { GHashTable * udp_data = arg_get_value (script_infos, "udp_data"); struct udp_record * data_record = g_malloc0 (sizeof(struct udp_record)); int * key = g_memdup (&soc, sizeof(int)); data_record->len = len; data_record->data = g_memdup ((gconstpointer)data, (guint)len); if (udp_data == NULL) { udp_data = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, g_free); arg_add_value (script_infos, "udp_data", ARG_PTR, -1, udp_data); } g_hash_table_replace (udp_data, (gpointer)key, (gpointer)data_record); return 0; }
int plugin_get_running_state(struct arglist * plugin) { return (int)arg_get_value(plugin, "RUNNING_STATE"); }
struct arglist * store_plugin(struct arglist * plugin, char * file) { char desc_file[PATH_MAX+1]; char path[PATH_MAX+1]; struct plugin plug; struct pprefs pp[MAX_PREFS+1]; char * str; char * dir; struct arglist * arglist, * ret, *prefs; int e; int fd; int num_plugin_prefs = 0; if( current_mode == MODE_SYS ) dir = sys_store_dir; else dir = usr_store_dir; if(strlen(file) + 2 > sizeof(path)) return NULL; strncpy(path, dir, sizeof(path) - 2 - strlen(file)); str = strrchr(path, '/'); if(str != NULL) { str[0] = '\0'; } strcat(path, "/"); strcat(path, file); snprintf(desc_file, sizeof(desc_file), "%s/%s", dir, file); str = strrchr(desc_file, '.'); if( str != NULL ) { str[0] = '\0'; if(strlen(desc_file) + 6 < sizeof(desc_file) ) strcat(desc_file, ".desc"); } bzero(&plug, sizeof(plug)); bzero(pp, sizeof(pp)); plug.magic = MAGIC; plug.id = _plug_get_id(plugin); e = safe_copy(path, plug.path, sizeof(plug.path), path, "path"); if(e < 0)return NULL; plug.timeout = _plug_get_timeout(plugin); plug.category = _plug_get_category(plugin); str = _plug_get_name(plugin); e = safe_copy(str, plug.name, sizeof(plug.name), path, "name"); if(e < 0)return NULL; str = _plug_get_version(plugin); e = safe_copy(str, plug.version, sizeof(plug.version), path, "version"); if(e < 0)return NULL; str = _plug_get_summary(plugin); e = safe_copy(str, plug.summary, sizeof(plug.summary), path, "summary"); if(e < 0)return NULL; str = _plug_get_description(plugin); e = safe_copy(str, plug.description, sizeof(plug.description), path, "description"); if(e < 0)return NULL; str = _plug_get_copyright(plugin); e = safe_copy(str, plug.copyright, sizeof(plug.copyright), path, "copyright"); if(e < 0)return NULL; str = _plug_get_family(plugin); e = safe_copy(str, plug.family, sizeof(plug.family), path, "family"); if(e < 0)return NULL; str = _plug_get_cve_id(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_CVE_SZ ) fprintf(stderr, "WARNING! CVE size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.cve_id, sizeof(plug.cve_id), path, "cve_id"); if(e < 0)return NULL; str = _plug_get_bugtraq_id(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_BID_SZ) fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.bid, sizeof(plug.bid), path, "bugtraq id"); if(e < 0)return NULL; str = _plug_get_xref(plugin); #ifdef DEBUG_STORE if ( str != NULL && strlen(str) > OLD_XREF_SZ) fprintf(stderr, "WARNING! BID size will be too long for older versions of Nessus!\n"); #endif e = safe_copy(str, plug.xref, sizeof(plug.xref), path, "xref id"); if(e < 0)return NULL; arglist = _plug_get_deps(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.dependencies, sizeof(plug.dependencies), path, "dependencies"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_keys(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_keys, sizeof(plug.required_keys), path, "required keys"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_excluded_keys(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.excluded_keys, sizeof(plug.excluded_keys), path, "excluded_keys"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_ports(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_ports, sizeof(plug.required_ports), path, "required ports"); efree(&str); if(e < 0)return NULL; arglist = _plug_get_required_udp_ports(plugin); str = arglist2str(arglist); e = safe_copy(str, plug.required_udp_ports, sizeof(plug.required_udp_ports), path, "required udp ports"); efree(&str); if(e < 0)return NULL; prefs = arg_get_value(plugin, "preferences"); arglist = arg_get_value(plugin, "PLUGIN_PREFS"); if( arglist != NULL ) { char * p_name = _plug_get_name(plugin); while(arglist->next != NULL) { char * name = arglist->name; char * dfl = arglist->value; char * type, * str; type = arglist->name; str = strchr(type, '/'); str[0] = '\0'; name = str + 1; e = safe_copy(type, pp[num_plugin_prefs].type, sizeof(pp[num_plugin_prefs].type), path, "preference-type"); if(e < 0)return NULL; e = safe_copy(name, pp[num_plugin_prefs].name, sizeof(pp[num_plugin_prefs].name), path, "preference-name"); if(e < 0)return NULL; e = safe_copy(dfl, pp[num_plugin_prefs].dfl, sizeof(pp[num_plugin_prefs].dfl), path, "preference-default"); if(e < 0)return NULL; num_plugin_prefs ++; if(num_plugin_prefs >= MAX_PREFS) { fprintf(stderr, "%s: too many preferences\n", path); return NULL; } _add_plugin_preference(prefs, p_name, name, type, dfl); str[0] = '/'; arglist = arglist->next; } } if(num_plugin_prefs > 0) plug.has_prefs = 1; fd = open(desc_file, O_RDWR|O_CREAT|O_TRUNC, 0644); if(fd < 0) { return NULL; } if(write(fd, &plug, sizeof(plug)) < 0) { perror("write "); } if(num_plugin_prefs > 0) { write(fd, pp, sizeof(pp)); } close(fd); arg_set_value(plugin, "preferences", -1, NULL); arg_free_all(plugin); return NULL; }