Exemplo n.º 1
0
 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);
 }
Exemplo n.º 2
0
/**
 * 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;
}
Exemplo n.º 3
0
	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 ) );

	}
Exemplo n.º 4
0
/*==========================================================
 * 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;
}
Exemplo n.º 5
0
/*---------------------------------------------------------------------------------------------
 * (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;
}
Exemplo n.º 6
0
/*---------------------------------------------------------------------------------------------
 * (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;
}
Exemplo n.º 7
0
/*---------------------------------------------------------------------------------------------
 * (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");
        }
    }
}
Exemplo n.º 8
0
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;
}