EdgeId add_edge (const EdgeType& data, const NodeId& a, const NodeId& b, float cost) { Edge<EdgeType> new_edge (data, a, b, cost); edges.push_back (new_edge); resolve_node(a).next.push_back (static_cast<int>(edges.size())-1); return EdgeId (edges.size ()-1); }
/** * Recursively resolves an IDENTIFIER to a parameter into its actual value, * by looking it up in the global_param_table_sc * Also try and fold any BINARY_OPERATIONs now that an IDENTIFIER has been * resolved */ ast_node_t *resolve_node(char *module_name, ast_node_t *node) { if (node) { long sc_spot; int i; info_ast_visit_t *node_details; STRING_CACHE *local_param_table_sc; ast_node_t *node_copy; node_copy = (ast_node_t *)malloc(sizeof(ast_node_t)); memcpy(node_copy, node, sizeof(ast_node_t)); node_copy->children = malloc(sizeof(ast_node_t*) * node_copy->num_children); for (i = 0; i < node->num_children; i++) { node_copy->children[i] = resolve_node(module_name, node->children[i]); } switch (node->type) { case IDENTIFIERS: oassert(module_name); sc_spot = sc_lookup_string(global_param_table_sc, module_name); oassert(sc_spot != -1); local_param_table_sc = (STRING_CACHE *)global_param_table_sc->data[sc_spot]; sc_spot = sc_lookup_string(local_param_table_sc, node->types.identifier); if (sc_spot != -1) { node = ((ast_node_t *)local_param_table_sc->data[sc_spot]); oassert(node->type == NUMBERS); } break; case BINARY_OPERATION: node_copy->shared_node = TRUE; node_details = constantFold(node_copy); node_copy->shared_node = FALSE; if (node_details && node_details->is_constant_folded == TRUE) { node = node_details->from; free(node_details); oassert(node->type == NUMBERS); } break; default: break; } free(node_copy->children); free(node_copy); } return node; }
nsockaddr::nsockaddr( const char * node, unsigned short port ) throw( sockexception ) { // set the socket address family sin_family = sockaddr::af_inet; // set the port sin_port = htons( port ); // set the address sin_addr.s_addr = resolve_node( node ); // zero out internals memset( sin_zero, 0, sizeof( sin_zero ) ); }
/*========================================================== * resolve_refn_links -- Resolve and check all links in node tree * This converts, eg, "<1850.Census>" to "@S25@" *========================================================*/ INT resolve_refn_links (NODE node) { INT unresolved = 0; BOOLEAN annotate_pointers = (getlloptint("AnnotatePointers", 0) > 0); NODE child=0; CACHEEL cel = node ? node->n_cel: 0; struct tag_node_iter nodeit; if (!node) return 0; if (cel) lock_cache(cel); /* ensure node doesn't fall out of cache */ /* resolve all descendant nodes */ begin_node_it(node, &nodeit); while ((child = next_node_it_ptr(&nodeit)) != NULL) { if (!resolve_node(child, annotate_pointers)) ++unresolved; } if (cel) unlock_cache(cel); return unresolved; }
/*--------------------------------------------------------------------------------------------- * (function: get_name_of_pins * Assume module connections can be one of: Array entry, Concat, Signal, Array range reference * Return a list of strings *-------------------------------------------------------------------------------------------*/ char_list_t *get_name_of_pins(ast_node_t *var_node, char *instance_name_prefix) { char **return_string = NULL; char_list_t *return_list = (char_list_t*)malloc(sizeof(char_list_t)); ast_node_t *rnode[3]; int i; int width = 0; if (var_node->type == ARRAY_REF) { width = 1; return_string = (char**)malloc(sizeof(char*)); rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); oassert(rnode[1]->type == NUMBERS); oassert(var_node->children[0]->type == IDENTIFIERS); return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, rnode[1]->types.number.value); } else if (var_node->type == RANGE_REF) { rnode[0] = resolve_node(instance_name_prefix, var_node->children[0]); rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, var_node->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); width = abs(rnode[1]->types.number.value - rnode[2]->types.number.value) + 1; if (rnode[0]->type == IDENTIFIERS) { return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) return_string[i] = make_full_ref_name(NULL, NULL, NULL, rnode[0]->types.identifier, rnode[2]->types.number.value+i); } else { oassert(rnode[0]->type == NUMBERS); return_string = get_name_of_pins_number(rnode[0], rnode[2]->types.number.value, width); } } else if (var_node->type == IDENTIFIERS) { /* need to look in the symbol table for details about this identifier (i.e. is it a port) */ long sc_spot; ast_node_t *sym_node; // try and resolve var_node sym_node = resolve_node(instance_name_prefix, var_node); if (sym_node == var_node) { char *temp_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) == -1) { error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", temp_string); } free(temp_string); sym_node = (ast_node_t*)local_symbol_table_sc->data[sc_spot]; if (sym_node->children[1] == NULL) { width = 1; return_string = (char**)malloc(sizeof(char*)*width); return_string[0] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); } else if (sym_node->children[3] == NULL) { int index = 0; rnode[1] = resolve_node(instance_name_prefix, sym_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, sym_node->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); width = (rnode[1]->types.number.value - rnode[2]->types.number.value + 1); return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) { return_string[index] = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, i+rnode[2]->types.number.value); index++; } } else if (sym_node->children[3] != NULL) { oassert(FALSE); } else { } } else { oassert(sym_node->type == NUMBERS); width = sym_node->types.number.binary_size; return_string = get_name_of_pins_number(sym_node, 0, width); } } else if (var_node->type == NUMBERS) { width = var_node->types.number.binary_size; return_string = get_name_of_pins_number(var_node, 0, width); } else if (var_node->type == CONCATENATE) { if (var_node->types.concat.num_bit_strings == 0) { oassert(FALSE); } else { if (var_node->types.concat.num_bit_strings == -1) { /* If this hasn't been made into a string list then do it */ make_concat_into_list_of_strings(var_node, instance_name_prefix); } width = var_node->types.concat.num_bit_strings; return_string = (char**)malloc(sizeof(char*)*width); for (i = 0; i < width; i++) // 0th bit is MSB so need to access reverse { return_string[i] = (char*)malloc(sizeof(char)*strlen(var_node->types.concat.bit_strings[var_node->types.concat.num_bit_strings-i-1])+1); sprintf(return_string[i], "%s", var_node->types.concat.bit_strings[var_node->types.concat.num_bit_strings-i-1]); } } } else { oassert(FALSE); } return_list->strings = return_string; return_list->num_strings = width; return return_list; }
/*--------------------------------------------------------------------------------------------- * (function: get_name of_port_at_bit) * Assume module connections can be one of: Array entry, Concat, Signal, Array range reference *-------------------------------------------------------------------------------------------*/ char *get_name_of_pin_at_bit(ast_node_t *var_node, int bit, char *instance_name_prefix) { char *return_string; ast_node_t *rnode[3]; if (var_node->type == ARRAY_REF) { oassert(var_node->children[0]->type == IDENTIFIERS); oassert(var_node->children[1]->type == NUMBERS); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, (int)var_node->children[1]->types.number.value); } else if (var_node->type == RANGE_REF) { rnode[1] = resolve_node(instance_name_prefix, var_node->children[1]); rnode[2] = resolve_node(instance_name_prefix, var_node->children[2]); oassert(var_node->children[0]->type == IDENTIFIERS); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); oassert((rnode[1]->types.number.value >= rnode[2]->types.number.value+bit) && bit >= 0); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->children[0]->types.identifier, rnode[2]->types.number.value+bit); } else if ((var_node->type == IDENTIFIERS) && (bit == -1)) { return_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, -1); } else if (var_node->type == IDENTIFIERS) { long sc_spot; int pin_index; if ((sc_spot = sc_lookup_string(local_symbol_table_sc, var_node->types.identifier)) == -1) { pin_index = 0; error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Missing declaration of this symbol %s\n", var_node->types.identifier); } if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1] == NULL) { pin_index = bit; } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] == NULL) { oassert(((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]->type == NUMBERS); pin_index = ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]->types.number.value + bit; } else oassert(FALSE); return_string = make_full_ref_name(NULL, NULL, NULL, var_node->types.identifier, pin_index); } else if (var_node->type == NUMBERS) { if (bit == -1) bit = 0; oassert(bit < var_node->types.number.binary_size); if (var_node->types.number.binary_string[var_node->types.number.binary_size-bit-1] == '1') { return_string = (char*)malloc(sizeof(char)*11+1); // ONE_VCC_CNS sprintf(return_string, "ONE_VCC_CNS"); } else if (var_node->types.number.binary_string[var_node->types.number.binary_size-bit-1] == '0') { return_string = (char*)malloc(sizeof(char)*13+1); // ZERO_GND_ZERO sprintf(return_string, "ZERO_GND_ZERO"); } else { return_string = NULL; oassert(FALSE); } } else if (var_node->type == CONCATENATE) { if (var_node->types.concat.num_bit_strings == 0) { return_string = NULL; oassert(FALSE); } else { if (var_node->types.concat.num_bit_strings == -1) { /* If this hasn't been made into a string list then do it */ make_concat_into_list_of_strings(var_node, instance_name_prefix); } return_string = (char*)malloc(sizeof(char)*strlen(var_node->types.concat.bit_strings[bit])+1); sprintf(return_string, "%s", var_node->types.concat.bit_strings[bit]); } } else { return_string = NULL; error_message(NETLIST_ERROR, var_node->line_number, var_node->file_number, "Unsupported variable type.\n"); oassert(FALSE); } return return_string; }
/*--------------------------------------------------------------------------------------------- * (function: make_concat_into_list_of_strings) * 0th idx will be the MSbit *-------------------------------------------------------------------------------------------*/ void make_concat_into_list_of_strings(ast_node_t *concat_top, char *instance_name_prefix) { int i, j; ast_node_t *rnode[3]; concat_top->types.concat.num_bit_strings = 0; concat_top->types.concat.bit_strings = NULL; /* recursively do all embedded concats */ for (i = 0; i < concat_top->num_children; i++) { if (concat_top->children[i]->type == CONCATENATE) { make_concat_into_list_of_strings(concat_top->children[i], instance_name_prefix); } } for (i = 0; i < concat_top->num_children; i++) { if (concat_top->children[i]->type == IDENTIFIERS) { char *temp_string = make_full_ref_name(NULL, NULL, NULL, concat_top->children[i]->types.identifier, -1); long sc_spot; if ((sc_spot = sc_lookup_string(local_symbol_table_sc, temp_string)) == -1) { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Missing declaration of this symbol %s\n", temp_string); } free(temp_string); if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1] == NULL) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], -1, instance_name_prefix); } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] == NULL) { /* reverse thorugh the range since highest bit in index will be lower in the string indx */ rnode[1] = resolve_node(instance_name_prefix, ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[1]); rnode[2] = resolve_node(instance_name_prefix, ((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); for (j = rnode[1]->types.number.value - rnode[2]->types.number.value; j >= 0; j--) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else if (((ast_node_t*)local_symbol_table_sc->data[sc_spot])->children[3] != NULL) { oassert(FALSE); } } else if (concat_top->children[i]->type == ARRAY_REF) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], 0, instance_name_prefix); } else if (concat_top->children[i]->type == RANGE_REF) { rnode[1] = resolve_node(instance_name_prefix, concat_top->children[i]->children[1]); rnode[2] = resolve_node(instance_name_prefix, concat_top->children[i]->children[2]); oassert(rnode[1]->type == NUMBERS && rnode[2]->type == NUMBERS); oassert(rnode[1]->types.number.value >= rnode[2]->types.number.value); int width = abs(rnode[1]->types.number.value - rnode[2]->types.number.value) + 1; //for (j = rnode[1]->types.number.value - rnode[2]->types.number.value; j >= 0; j--) // Changed to forward to fix concatenation bug. for (j = 0; j < width; j++) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], ((rnode[1]->types.number.value - rnode[2]->types.number.value))-j, instance_name_prefix); } } else if (concat_top->children[i]->type == NUMBERS) { if(concat_top->children[i]->types.number.base == DEC) { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Concatenation can't include decimal numbers due to conflict on bits\n"); } // Changed to reverse to fix concatenation bug. for (j = concat_top->children[i]->types.number.binary_size-1; j>= 0; j--) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else if (concat_top->children[i]->type == CONCATENATE) { /* forward through list since we build concatenate list in idx order of MSB at index 0 and LSB at index list_size */ for (j = 0; j < concat_top->children[i]->types.concat.num_bit_strings; j++) { concat_top->types.concat.num_bit_strings ++; concat_top->types.concat.bit_strings = (char**)realloc(concat_top->types.concat.bit_strings, sizeof(char*)*(concat_top->types.concat.num_bit_strings)); concat_top->types.concat.bit_strings[concat_top->types.concat.num_bit_strings-1] = get_name_of_pin_at_bit(concat_top->children[i], j, instance_name_prefix); } } else { error_message(NETLIST_ERROR, concat_top->line_number, concat_top->file_number, "Unsupported operation within a concatenation.\n"); } } }
int main(int argc, char *argv[]) { struct sigaction sa; struct rlimit limit; int i, c, rc; int opt_foreground = 0, opt_allow_links = 0; enum startup_state opt_startup = startup_enable; extern char *optarg; extern int optind; struct ev_loop *loop; struct ev_io netlink_watcher; struct ev_signal sigterm_watcher; struct ev_signal sighup_watcher; struct ev_signal sigusr1_watcher; struct ev_signal sigusr2_watcher; struct ev_signal sigchld_watcher; /* Get params && set mode */ while ((c = getopt(argc, argv, "flns:")) != -1) { switch (c) { case 'f': opt_foreground = 1; break; case 'l': opt_allow_links=1; break; case 'n': do_fork = 0; break; case 's': for (i=0; i<startup_INVALID; i++) { if (strncmp(optarg, startup_states[i], strlen(optarg)) == 0) { opt_startup = i; break; } } if (i == startup_INVALID) { fprintf(stderr, "unknown startup mode '%s'\n", optarg); usage(); } break; default: usage(); } } /* check for trailing command line following options */ if (optind < argc) { usage(); } if (opt_allow_links) set_allow_links(1); if (opt_foreground) { config.daemonize = D_FOREGROUND; set_aumessage_mode(MSG_STDERR, DBG_YES); } else { config.daemonize = D_BACKGROUND; set_aumessage_mode(MSG_SYSLOG, DBG_NO); (void) umask( umask( 077 ) | 022 ); } #ifndef DEBUG /* Make sure we are root */ if (getuid() != 0) { fprintf(stderr, "You must be root to run this program.\n"); return 4; } #endif /* Register sighandlers */ sa.sa_flags = 0 ; sigemptyset( &sa.sa_mask ) ; /* Ignore all signals by default */ sa.sa_handler = SIG_IGN; for (i=1; i<NSIG; i++) sigaction( i, &sa, NULL ); atexit(clean_exit); /* Raise the rlimits in case we're being started from a shell * with restrictions. Not a fatal error. */ limit.rlim_cur = RLIM_INFINITY; limit.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_FSIZE, &limit); setrlimit(RLIMIT_CPU, &limit); /* Load the Configuration File */ if (load_config(&config, TEST_AUDITD)) return 6; if (config.priority_boost != 0) { errno = 0; rc = nice((int)-config.priority_boost); if (rc == -1 && errno) { audit_msg(LOG_ERR, "Cannot change priority (%s)", strerror(errno)); return 1; } } /* Daemonize or stay in foreground for debugging */ if (config.daemonize == D_BACKGROUND) { if (become_daemon() != 0) { audit_msg(LOG_ERR, "Cannot daemonize (%s)", strerror(errno)); tell_parent(FAILURE); return 1; } openlog("auditd", LOG_PID, LOG_DAEMON); } /* Init netlink */ if ((fd = audit_open()) < 0) { audit_msg(LOG_ERR, "Cannot open netlink audit socket"); tell_parent(FAILURE); return 1; } /* Init the event handler thread */ write_pid_file(); if (init_event(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (init_dispatcher(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Get machine name ready for use */ if (resolve_node(&config)) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } /* Write message to log that we are alive */ { struct utsname ubuf; char start[DEFAULT_BUF_SZ]; const char *fmt = audit_lookup_format((int)config.log_format); if (fmt == NULL) fmt = "UNKNOWN"; if (uname(&ubuf) != 0) { if (pidfile) unlink(pidfile); tell_parent(FAILURE); return 1; } if (getsubj(subj)) snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d subj=%s res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid(), subj); else snprintf(start, sizeof(start), "auditd start, ver=%s format=%s " "kernel=%.56s auid=%u pid=%d res=success", VERSION, fmt, ubuf.release, audit_getloginuid(), getpid()); if (send_audit_event(AUDIT_DAEMON_START, start)) { audit_msg(LOG_ERR, "Cannot send start message"); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } } /* Tell kernel not to kill us */ avoid_oom_killer(); /* let config manager init */ init_config_manager(); if (opt_startup != startup_nochange && (audit_is_enabled(fd) < 2) && audit_set_enabled(fd, (int)opt_startup) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set initial audit startup state to '%s', exiting", startup_states[opt_startup]); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Tell the kernel we are alive */ if (audit_set_pid(fd, getpid(), WAIT_YES) < 0) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); audit_msg(LOG_ERR, "Unable to set audit pid, exiting"); close_down(); if (pidfile) unlink(pidfile); shutdown_dispatcher(); tell_parent(FAILURE); return 1; } /* Depending on value of opt_startup (-s) set initial audit state */ loop = ev_default_loop (EVFLAG_NOENV); ev_io_init (&netlink_watcher, netlink_handler, fd, EV_READ); ev_io_start (loop, &netlink_watcher); ev_signal_init (&sigterm_watcher, term_handler, SIGTERM); ev_signal_start (loop, &sigterm_watcher); ev_signal_init (&sighup_watcher, hup_handler, SIGHUP); ev_signal_start (loop, &sighup_watcher); ev_signal_init (&sigusr1_watcher, user1_handler, SIGUSR1); ev_signal_start (loop, &sigusr1_watcher); ev_signal_init (&sigusr2_watcher, user2_handler, SIGUSR2); ev_signal_start (loop, &sigusr2_watcher); ev_signal_init (&sigchld_watcher, child_handler, SIGCHLD); ev_signal_start (loop, &sigchld_watcher); if (auditd_tcp_listen_init (loop, &config)) { char emsg[DEFAULT_BUF_SZ]; if (*subj) snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d subj=%s res=failed", audit_getloginuid(), getpid(), subj); else snprintf(emsg, sizeof(emsg), "auditd error halt, auid=%u pid=%d res=failed", audit_getloginuid(), getpid()); stop = 1; send_audit_event(AUDIT_DAEMON_ABORT, emsg); tell_parent(FAILURE); } else { /* Now tell parent that everything went OK */ tell_parent(SUCCESS); audit_msg(LOG_NOTICE, "Init complete, auditd %s listening for events (startup state %s)", VERSION, startup_states[opt_startup]); } /* Parent should be gone by now... */ if (do_fork) close(init_pipe[1]); // Init complete, start event loop if (!stop) ev_loop (loop, 0); auditd_tcp_listen_uninit (loop, &config); // Tear down IO watchers Part 1 ev_signal_stop (loop, &sighup_watcher); ev_signal_stop (loop, &sigusr1_watcher); ev_signal_stop (loop, &sigusr2_watcher); ev_signal_stop (loop, &sigterm_watcher); /* Write message to log that we are going down */ rc = audit_request_signal_info(fd); if (rc > 0) { struct audit_reply trep; rc = get_reply(fd, &trep, rc); if (rc > 0) { char txt[MAX_AUDIT_MESSAGE_LENGTH]; snprintf(txt, sizeof(txt), "auditd normal halt, sending auid=%u " "pid=%d subj=%s res=success", trep.signal_info->uid, trep.signal_info->pid, trep.signal_info->ctx); send_audit_event(AUDIT_DAEMON_END, txt); } } if (rc <= 0) send_audit_event(AUDIT_DAEMON_END, "auditd normal halt, sending auid=? " "pid=? subj=? res=success"); free(rep); // Tear down IO watchers Part 2 ev_io_stop (loop, &netlink_watcher); // Give DAEMON_END event a little time to be sent in case // of remote logging usleep(10000); // 10 milliseconds shutdown_dispatcher(); // Tear down IO watchers Part 3 ev_signal_stop (loop, &sigchld_watcher); close_down(); free_config(&config); ev_default_destroy(); return 0; }