Exemple #1
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(char* key, char* cert)
{
	SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
	if(!ctx) print_exit("out of memory");
	(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
	(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
	if(!SSL_CTX_use_certificate_chain_file(ctx, cert))
		print_exit("cannot read cert");
	if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
		print_exit("cannot read key");
	if(!SSL_CTX_check_private_key(ctx))
		print_exit("private key is not correct");
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
	if (!SSL_CTX_set_ecdh_auto(ctx,1))
		if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
#elif defined(USE_ECDSA)
	if(1) {
		EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
		if (!ecdh) {
			if(verb>=1) printf("could not find p256, not enabling ECDHE\n");
		} else {
			if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) {
				if(verb>=1) printf("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE\n");
			}
			EC_KEY_free(ecdh);
		}
	}
#endif
	if(!SSL_CTX_load_verify_locations(ctx, cert, NULL))
		print_exit("cannot load cert verify locations");
	return ctx;
}
Exemple #2
0
/** setup SSL context */
static SSL_CTX*
setup_ctx(char* key, char* cert)
{
	SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
	if(!ctx) print_exit("out of memory");
	(void)SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
	if(!SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM))
		print_exit("cannot read cert");
	if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
		print_exit("cannot read key");
	if(!SSL_CTX_check_private_key(ctx))
		print_exit("private key is not correct");
	if(!SSL_CTX_load_verify_locations(ctx, cert, NULL))
		print_exit("cannot load cert verify locations");
	return ctx;
}
Exemple #3
0
/** provide ssl service */
static void
do_service(char* addr, int port, char* key, char* cert)
{
	SSL_CTX* sslctx = setup_ctx(key, cert);
	int fd = setup_fd(addr, port);
	int go = 1;
	if(fd == -1) print_exit("could not setup sockets");
	if(verb) {printf("petal start\n"); fflush(stdout);}
	while(go) {
		struct sockaddr_storage from;
		socklen_t flen = (socklen_t)sizeof(from);
		int s = accept(fd, (struct sockaddr*)&from, &flen);
		if(verb) fflush(stdout);
		if(s != -1) {
			SSL* ssl = setup_ssl(s, sslctx);
			if(verb) fflush(stdout);
			if(ssl) {
				service_ssl(ssl, &from, flen);
				if(verb) fflush(stdout);
				SSL_shutdown(ssl);
				SSL_free(ssl);
			}
			fd_close(s);
		} else if (verb >=2) log_errno("accept");
		if(verb) fflush(stdout);
	}
	/* if we get a kill signal, the process dies and the OS reaps us */
	if(verb) printf("petal end\n");
	fd_close(fd);
	SSL_CTX_free(sslctx);
}
Exemple #4
0
/** parse a text IP address into a sockaddr */
static int
parse_ip_addr(char* str, int port, struct sockaddr_storage* ret, socklen_t* l)
{
	socklen_t len = 0;
	struct sockaddr_storage* addr = NULL;
	struct sockaddr_in6 a6;
	struct sockaddr_in a;
	uint16_t p = (uint16_t)port;
	int fam = 0;
	memset(&a6, 0, sizeof(a6));
	memset(&a, 0, sizeof(a));

	if(inet_pton(AF_INET6, str, &a6.sin6_addr) > 0) {
		/* it is an IPv6 */
		fam = AF_INET6;
		a6.sin6_family = AF_INET6;
		a6.sin6_port = (in_port_t)htons(p);
		addr = (struct sockaddr_storage*)&a6;
		len = (socklen_t)sizeof(struct sockaddr_in6);
	}
	if(inet_pton(AF_INET, str, &a.sin_addr) > 0) {
		/* it is an IPv4 */
		fam = AF_INET;
		a.sin_family = AF_INET;
		a.sin_port = (in_port_t)htons(p);
		addr = (struct sockaddr_storage*)&a;
		len = (socklen_t)sizeof(struct sockaddr_in);
	}
	if(!len) print_exit("cannot parse addr");
	*l = len;
	memmove(ret, addr, len);
	return fam;
}
Exemple #5
0
unsigned char *gen_frbl_from_node(struct s_link *sl_node)
{
    int idx;
    struct btree_node *bt_node;
    static unsigned char path[MAZEMAX + 2];

    bt_node = sl_node->bt_node;
    idx = MAZEMAX;

    /*
     * Generate FRBL pattern and save it to array
     */

    /* diagonal path has to go 1 more block in the goal */
    path[idx--] = 0xff; /* end of path */
#if defined(CONFIG_16X16)
    path[idx--] = FD;
#endif
    while (bt_node->parent) {
        if (bt_node->dir <= LD)
            path[idx--] = bt_node->dir;
        else
            print_exit("Invalid direction in bt_node!\n");
        bt_node = bt_node->parent;
    }
    return &path[++idx];
}
Exemple #6
0
void free_top_node_contour_tree(void)
{
    if (!contour_tree)
        print_exit("%s:Do not call this before generating tree.\n",
                   __func__);
    free_bt_node_list(contour_tree);
    contour_tree = NULL;
}
Exemple #7
0
/* Find fastest path from known maze information
 * and return the FRBL turn array to the caller.
 * if first turn is one of RBL, it means that the
 * mouse has to make back turn or smooth L/R turn.
 * In that case, no diagonal turns.
 *
 * fast_path_type: 0 find all possible pathes
 *                 1 find from only known blocks
 */
unsigned char *find_maze_fastest_path(
    unsigned char cur_mouse_pos, char cur_mouse_dir,
    unsigned int search_type, struct s_link *f_node,
    int fast_path_type)
{
    unsigned char *path;
    struct s_link *mouse_path;
    struct s_link *sl_fast_path;
#ifdef DEBUG
    int i;
#endif

    if (!f_node)
        print_exit("f_node NULL\n");
    print_dbg(DEBUG_SEARCH, "mouse pos:%d,%d mouse_dir:%d "
              "search_type:%d\n", pos_x(cur_mouse_pos),
              pos_y(cur_mouse_pos), cur_mouse_dir,
              search_type);
    /* draw contour map from the goal */
    draw_contour(maze_search, contour_map,
                 search_type, cur_mouse_pos);
    /* generate full binary tree with all pathes */
    mouse_path = gen_bin_tree(maze_search,
                              contour_map, cur_mouse_pos, cur_mouse_dir);
    /* find the fastest path and get the node */
    sl_fast_path = find_fastest_path(mouse_path, fast_path_type);

    if (sl_fast_path) {

        memcpy(f_node, sl_fast_path, sizeof(struct s_link));

        /* Free sl_nodes after searching the fastest path */
        sl_node_free(mouse_path);
    } else {
        sl_node_free(mouse_path);
        return NULL;
    }

    /* generate FRBL array for the fastest path */
    path = gen_frbl_from_node(f_node);

#ifdef DEBUG
    printf("%s\n", __func__);
    for (i = 0; path[i] != 0xff; i++)
        printf("%C",
               (path[i] == FD) ? 'F' : \
               ((path[i] == RD) ? 'R' : \
                ((path[i] == BD) ? 'B' : \
                 ((path[i] == LD) ? 'L' : 'X'))));
    printf("\n");
#endif

    return path;
}
Exemple #8
0
/* wall bits are filled by absolute direction.
 * index : current mouse location to save the wall information.
 */
void save_wallinfo_to_maze(unsigned char index, unsigned char wall)
{
    int x, y;

    print_dbg(DEBUG_SEARCH, "%02X, %02X\n", index, wall&0xf);
    /* trying to save know wall to maze_search? */
    if ((maze_search[index]&0xF0) == 0xF0)
        print_exit("%s: %d,%d is already known block!\n",
                   __func__, pos_x(index), pos_y(index));

    /* save wall info to current index */
    maze_search[index] |= (wall&0xf);
    maze_search[index] |= 0xF0;

    /* save wall information the wall of other blocks */
    x = pos_x(index);
    y = pos_y(index);

    /* north (it's south wall of next block) */
    if (y+1 < MAX_Y) {
        maze_search[get_index(x, y+1)] |= KNOWN_SOUTH;
        if (wall & NORTH)
            maze_search[get_index(x, y+1)] |= SOUTH;
    }
    /* east (it's west wall of next block) */
    if (x+1 < MAX_X) {
        maze_search[get_index(x+1, y)] |= KNOWN_WEST;
        if (wall & EAST)
            maze_search[get_index(x+1, y)] |= WEST;
    }
    /* south (it's north wall of next block) */
    if (y > 0) {
        maze_search[get_index(x, y-1)] |= KNOWN_NORTH;
        if (wall & SOUTH)
            maze_search[get_index(x, y-1)] |= NORTH;
    }
    /* west (it's east wall of next block) */
    if (x > 0) {
        maze_search[get_index(x-1, y)] |= KNOWN_EAST;
        if (wall & WEST)
            maze_search[get_index(x-1, y)] |= EAST;
    }
    print_dbg(DEBUG_SEARCH, "%s: index:%02X maze_search[index]=%02X\n",
              __func__, index, (unsigned char)maze_search[index]);
}
Exemple #9
0
int test_all_permutations(void)
{
    int p, w;
    bool has_failure = false;

    for (p = 0; p <= 5; p++) {
        for (w = 0; w <= 3; w++) {
            int testpid;
            int ret;

            testpid = fork();
            if (testpid == 0) {
                logline("-------------------------------------------------------");
                logline("*** Executing self-test: %s -p %d -w %d",
                        getprogname(), p, w);
                test((parent_exit_t)p,
                     (debugger_exit_t)w);
                _exit(1); /* never reached */
            } else if (testpid == -1) {
                err(1, "failed to fork test pid");
            } else {
                int stat_loc;

                ret = waitpid(testpid, &stat_loc, 0);
                if (ret == -1)
                    err(1, "waitpid(%d) by test harness failed", testpid);

                logline("test process: %s", print_exit(testpid, stat_loc));
                if (!WIFEXITED(stat_loc) || (0 != WEXITSTATUS(stat_loc))) {
                    logline("FAILED TEST");
                    has_failure = true;
                }
            }
        }
    }

    if (has_failure) {
        logline("test failures found");
        return 1;
    }

    return 0;
}
Exemple #10
0
void run_timer(unsigned char *maze_file)
{
#ifdef DEBUG
	time_t t1, t2;
	double elapsed;
#endif

	if (maze_file == NULL)
		print_exit("%s: maze_file is NULL.\n", __func__);

	g_timeout_add(TIMER_MS, timer_handler, maze_file);

#ifdef DEBUG
	t1 = clock();
	t2 = clock();

	elapsed = ((double)(t2 - t1)/(double)CLOCKS_PER_SEC)*
		1000.0;      /* sec to ms */
	printf("elapsed time:%fmS\n", elapsed);
#endif
}
Exemple #11
0
static void interpret(char *name, char *val, int comma, int rtype)
{
	int type;

	while (*name == ' '||*name == '(')
		name++;


	/* Do some fixups */
	if (rtype == AUDIT_EXECVE && name[0] == 'a')
		type = T_ESCAPED;
	else if (rtype == AUDIT_AVC && strcmp(name, "saddr") == 0)
		type = -1;
	else if (strcmp(name, "acct") == 0) {
		// Remove trailing punctuation
		int len = strlen(val);
		if (val[len-1] == ':')
			val[len-1] = 0;

		if (val[0] == '"')
			type = T_ESCAPED;
		else if (is_hex_string(val))
			type = T_ESCAPED;
		else
			type = -1;
	} else
		type = audit_lookup_type(name);

	switch(type) {
		case T_UID:
			print_uid(val);
			break;
		case T_GID:
			print_gid(val);
			break;
		case T_SYSCALL:
			print_syscall(val);
			break;
		case T_ARCH:
			print_arch(val);
			break;
		case T_EXIT:
			print_exit(val);
			break;
		case T_ESCAPED:
			print_escaped(val);
			break;
		case T_PERM:
			print_perm(val);
			break;
		case T_MODE:
			print_mode(val);
			break;
		case T_SOCKADDR:
			print_sockaddr(val);
			break;
		case T_FLAGS:
			print_flags(val);
			break;
		case T_PROMISC:
			print_promiscuous(val);
			break;
		case T_CAPABILITY:
			print_capabilities(val);
			break;
		case T_SIGNAL:
			print_signals(val);
			break;
		case T_KEY:
			print_key(val);
			break;
		case T_LIST:
			print_list(val);
			break;
		case T_TTY_DATA:
			print_tty_data(val);
			break;
		default:
			printf("%s%c", val, comma ? ',' : ' ');
	}
}
Exemple #12
0
int
main(int argc, char **argv)
{
	int ch;
	const char *conffile;

	conffile = CONFFILE;

	while ((ch = getopt(argc, argv, "f:v")) != -1) {
		switch (ch) {
			case 'f':
				conffile = optarg;
				break;
			case 'v':
				verbose++;
				break;
			default:
				usage();
				/* NOTREACHED */
		}
	}

	bzero(&config, sizeof(config));
	config.print.feedlines = -1;
	config.print.cchide_customer = 1;
	config.print.ccsig_customer = 1;
	bzero(&header, sizeof(header));
	if (parse_config(conffile))
		exit(1);

	/* set database files */
	if (config.database.custdb == NULL)
		if ((config.database.custdb = strdup(config.database.alldb
				? config.database.alldb : CUSTDBFILE)) == NULL)
			err(1, "cannot set customer database file");
	if (config.database.menudb == NULL)
		if ((config.database.menudb = strdup(config.database.alldb
				? config.database.alldb : MENUDBFILE)) == NULL)
			err(1, "cannot set menu database file");
	if (config.database.orderdb == NULL)
		if ((config.database.orderdb = strdup(config.database.alldb
				? config.database.alldb : ORDERDBFILE)) == NULL)
			err(1, "cannot set order database file");
	if (config.print.feedlines < 0)
		config.print.feedlines = PRINT_FEED_LINES;

	if (licence_init() == -1)
		errx(1, "cannot proceed without licence");

	event_init();

	module_init();
	rule_init();

	input_init();
	print_init();
	form_init();
	display_init();
	status_init();
	menu_init();
	customer_init();
	special_init();
	payment_init();
	window_init();
	order_init();

	display_refresh();

	signal(SIGPIPE, SIG_IGN);
	if (event_dispatch() == -1)
		err(1, "terminated abnormally");

	if (exitcode != 0 && exitmsg == NULL)
		exitmsg = strdup(status.status);

	order_exit();
	window_exit();
	payment_exit();
	special_exit();
	customer_exit();
	menu_exit();
	status_exit();
	display_exit();
	form_exit();
	print_exit();
	input_exit();

	rule_exit();
	module_exit();

	if (exitcode && exitmsg != NULL)
		errx(exitcode, "%s", exitmsg);
	else
		fprintf(stdout, "exiting normally\n");

	exit(0);
}
Exemple #13
0
/* Add the transaction represented by user_name and amount to the appropriate
 * transaction list, and update the balances of the corresponding user and group.
 * Note that updating a user's balance might require the user to be moved to a
 * different position in the list to keep the list in sorted order. Returns 0 on
 * success, and -1 if the specified user does not exist.
 */
int add_xct(Group *group, const char *user_name, double amount) {
    /* Allocate space for the new xct that is to be added to the list of
     * xcts.
     */
    Xct *new_xct = (Xct*) malloc (sizeof(Xct));

    /* Checks if malloc failed, if malloc failed, a error message is printed to
     * standard output and exit code of 256.
     */
    if (new_xct == NULL) {
        print_exit("ERROR: Malloc failed", 256);

    /* If malloc didn't fail, the user name and the amount is assigned to the new
     * xct and the next pointer is set to NULL temporarily.
     */
    } else {
        int size_to_malloc = (strlen(user_name)+1)*sizeof(char);
        new_xct->name = (char*) malloc (size_to_malloc);

        /* Checks if the current malloc failed, if it failed a message is printed
         * to standard output and exit code of 256 is set.
         */
        if (new_xct->name == NULL) {
            print_exit("ERROR: Malloc failed", 256);
        }
        strncpy(new_xct->name, user_name, size_to_malloc);
        new_xct->name[size_to_malloc] = '\0';
        new_xct->amount = amount;
        new_xct->next = NULL;
    }

    /* Finds the previous user to the user that added a xct in order to change
     * the user's balance and re-organize the list.
     */
    User *prev_user = find_prev_user(group, user_name);

    /* If no user was found with the same user name in the list of users, -1 is
     * returned.
     */
    if (prev_user == NULL) {
        free_dp(new_xct->name);
        free_dp(new_xct);
        return -1;

    /* Checks if the user returned is the head of the list of users, if it is, 
     * the head is changed so that the user can be moved to its correct location.
     */
    } else if (strcmp(prev_user->name, user_name) == 0) {
        push_xct(group, new_xct);
        prev_user->balance += amount;
        sort_user(group, prev_user, user_name);
        return 0;

    /* Checks if the user returned is in the middle of the list of users, the 
     * user is remvoed from its current position and placed in the correct
     * position in the users of list.
     */
    } else {
        push_xct(group, new_xct);
        prev_user->next->balance += amount;
        sort_user(group, prev_user, user_name);
        return 0;
    }
}
Exemple #14
0
/* Add a group with name group_name to the group_list referred to by
 * group_list_ptr. The groups are ordered by the time that the group was
 * added to the list with new groups added to the end of the list.
 *
 * Returns 0 on success and -1 if a group with this name already exists.
 *
 * (I.e, allocate and initialize a Group struct, and insert it
 * into the group_list. Note that the head of the group list might change
 * which is why the first argument is a double pointer.)
 */
int add_group(Group **group_list_ptr, const char *group_name) {
    /* Allocates space in memory for new_group in order to add the group the
     * group_list
     */
    Group *new_group = (Group*) malloc (sizeof(Group));

    /* Checks if malloc have allocated space.
     *     1) If it didn't, print out error message and exit with code 256
     */
    if (new_group == NULL) {
        print_exit("ERROR: Malloc failed", 256);

    /*     2) If it did, set the new group_name, set users, xcts and next pointers
     *        to NULL
     */
    } else {
        int size_to_malloc = (strlen(group_name) + 1) * sizeof(char);
        new_group->name = (char*) malloc (size_to_malloc);

        /* Checks if malloc completed successfully, if it didn't complete 
         * successfully it will print out an error message to standard output.
         */
        if (new_group->name == NULL) {
            print_exit("ERROR: Malloc failed", 256);
        }
        strncpy(new_group->name, group_name, size_to_malloc);
        new_group->name[size_to_malloc] = '\0';

        /* All other pointers are set NULL until the embedded linked list are 
         * declared and initialized. 
         */
        new_group->users = NULL;
        new_group->xcts = NULL;
        new_group->next = NULL;
    }

    /* Checks if the list is empty.
     * If it is, it sets the new_group to the head of the list and 0 is returned
     */
    if (*group_list_ptr == NULL) {
        *group_list_ptr = new_group;
        return 0;

    /* If it is not an empty list, it will traverse the list to detect if a group
     * with the same name already exists.
     */
    } else {
        Group *curr = *group_list_ptr;
        while (curr != NULL) {

            /* Compares the current group name with the group_name (user wants
             * to add). 
             *     1) If a group with the same name exists, -1 is returned
             */
            if (strcmp(curr->name, group_name) == 0) {
                free_dp(new_group->name);
                free_dp(new_group);
                return -1;
            } else if (curr->next == NULL) {
                curr->next = new_group;
                return 0;
            } else {
                curr = curr->next;
            }
        }
        return 0;
    }
}
Exemple #15
0
/* Add a new user with the specified user name to the specified group. Return zero
 * on success and -1 if the group already has a user with that name.
 * (allocate and initialize a User data structure and insert it into the
 * appropriate group list)
 */
int add_user(Group *group, const char *user_name) {
    /* Allocates space in memory for the user, and checks if malloc has been
     * completed successfully.
     */
    User *new_user = (User*) malloc (sizeof(User));

    /* If malloc is not completed succesfully, an error message will be printed
     * out to standard output and program will exit with 256 exit code
     */
    if (new_user == NULL) {
        print_exit("ERROR: Malloc failed", 256);

    /* If malloc has been completed successfully, the user name is set to user_name
     * and set initial balance to 0
     */
    } else {
        int size_to_malloc = (strlen(user_name)+1)*sizeof(char);
        new_user->name = (char*) malloc (size_to_malloc);

        /* Checks if malloc is completed succesfully, if it is not completed
         * successfully, and error message will be printed out the screen and exit
         * code of 256.
         */
        if (new_user->name == NULL) {
            print_exit("ERROR: Malloc failed", 256);
        }

        /* Copies the user_name given to the user name got the newly created
         * user.
         */
        strncpy(new_user->name, user_name, size_to_malloc);
        new_user->name[size_to_malloc] = '\0';

        /* Sets all other values to either 0.0 if it is double, or NULL if it is
         * a pointer to another linked list.
         */
        new_user->balance = 0.0;
        new_user->next = NULL;
    }

    // Returns the user if the user already exists in the group.
    User *prev_user = find_prev_user(group, user_name);

    /* If prev_user is NULL, meaning no user in the group exists with the same
     * name. We can add the new user in this case to the specified group.
     */
    if (prev_user == NULL) {
        prev_user = new_user;
        User *tmp = group->users;
        group->users = prev_user;
        group->users->next = tmp;
        return 0;

    /* If prev_user is not NULL, this means that a user with the same name already
     * exists, so we don't add the new user and just return -1. Free space for 
     * the user name and the user, also points the user to NULL to avoid dangling 
     * pointers
     */
    } else {
        free_dp(new_user->name);
        free_dp(new_user);
        return -1;
    }
}
Exemple #16
0
/*
 * debugger will register kevents, wait for quorum on events, then exit
 */
void do_parent(pid_t child, pid_t debugger, parent_exit_t parent_exit_time, debugger_exit_t debugger_exit_time)
{
    int kq;
    int ret;
    struct kevent64_s kev;
    int deathcount = 0;
    int childsignalcount = 0;
    int stat_loc;

    setprogname("PARENT");

    logline("parent pid %d has child pid %d and debugger pid %d. waiting for processes to exit...", getpid(), child, debugger);

    kq = kqueue();
    if (kq < 0)
        err(1, "kqueue");

    EV_SET64(&kev, child, EVFILT_PROC, EV_ADD|EV_ENABLE,
             NOTE_EXIT|NOTE_EXITSTATUS|NOTE_EXIT_DETAIL|NOTE_FORK|NOTE_EXEC|NOTE_SIGNAL,
             0, child, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_PROC");

    EV_SET64(&kev, SIGCHLD, EVFILT_SIGNAL, EV_ADD|EV_ENABLE,
             0, 0, child, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_SIGNAL");

    EV_SET64(&kev, 7, EVFILT_TIMER, EV_ADD|EV_ENABLE|EV_ONESHOT,
             NOTE_SECONDS, 7, 0, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_TIMER");

    while(1) {
        ret = kevent64(kq, NULL, 0, &kev, 1, 0, NULL);
        if (ret == -1) {
            if (errno == EINTR)
                continue;
            err(1, "kevent64");
        } else if (ret == 0) {
            break;
        }

        logline("kevent64 returned ident %llu filter %s fflags %s data %s",
                kev.ident, str_kev_filter(kev.filter),
                str_kev_fflags(kev.filter, kev.fflags),
                str_kev_data(kev.filter, kev.fflags, kev.data, kev.udata));
        if (kev.filter == EVFILT_SIGNAL) {
            /* must be SIGCHLD */
            deathcount++;
        } else if (kev.filter == EVFILT_PROC) {
            if (child == kev.udata) {
                if ((kev.fflags & (NOTE_EXIT|NOTE_EXITSTATUS)) == (NOTE_EXIT|NOTE_EXITSTATUS)) {
                    deathcount++;
                } else if (kev.fflags & NOTE_SIGNAL) {
                    childsignalcount++;
                    if ((parent_exit_time == eParentExitAfterDebuggerAttach) && (childsignalcount >= 2)) {
                        /* second signal is attach */
                        logline("exiting because of eParentExitAfterDebuggerAttach");
                        exit(0);
                    }
                } else if (kev.fflags & NOTE_FORK) {
                    if (parent_exit_time == eParentExitBeforeDebuggerAttach) {
                        logline("exiting because of eParentExitBeforeDebuggerAttach");
                        exit(0);
                    }
                }
            }
        } else if (kev.filter == EVFILT_TIMER) {
            errx(1, "timed out waiting for NOTE_EXIT");
        }

        if (deathcount >= (parent_exit_time == eParentExitAfterWaitpidAndSIGCHLD ? 2 : 1)) {
            break;
        }
    }

    if (parent_exit_time == eParentExitBeforeWaitpid) {
        logline("exiting because of eParentExitBeforeWaitpid");
        exit(0);
    }

    ret = waitpid(child, &stat_loc, 0);
    if (ret == -1)
        err(1, "waitpid(%d) by parent failed", child);

    logline("child process: %s", print_exit(child, stat_loc));
    if (!WIFSIGNALED(stat_loc) || (SIGKILL != WTERMSIG(stat_loc)))
        errx(1, "child did not exit as expected");

    ret = waitpid(debugger, &stat_loc, 0);
    if (ret == -1)
        err(1, "waitpid(%d) by parent failed", debugger);

    logline("debugger process: %s", print_exit(debugger, stat_loc));
    if (!WIFEXITED(stat_loc) || (0 != WEXITSTATUS(stat_loc)))
        errx(1, "debugger did not exit as expected");

    /* Received both SIGCHLD and NOTE_EXIT, as needed */
    logline("exiting beacuse of eParentExitAfterWaitpid/eParentExitAfterWaitpidAndSIGCHLD");
    exit(0);
}
Exemple #17
0
/*
 * debugger will register kevents, attach+kill child, wait for quorum on events,
 * then exit.
 */
void do_debugger(pid_t child, debugger_exit_t debugger_exit_time)
{
    int kq;
    int ret;
    struct kevent64_s kev;
    int deathcount = 0;
    int stat_loc;

    setprogname("DEBUGGER");

    logline("debugger pid %d has child pid %d. waiting for process exit...", getpid(), child);

    sleep(1);
    fprintf(stderr, "\n");
    ret = ptrace(PT_ATTACH, child, 0, 0);
    if (ret == -1)
        err(1, "ptrace(PT_ATTACH)");

    ret = waitpid(child, &stat_loc, WUNTRACED);
    if (ret == -1)
        err(1, "waitpid(child, WUNTRACED)");

    logline("child process stopped: %s", print_exit(child, stat_loc));

    if (debugger_exit_time == eDebuggerExitWithoutDetach) {
        logline("exiting because of eDebuggerExitWithoutDetach");
        exit(0);
    } else if (debugger_exit_time == eDebuggerExitAfterDetach) {
        ret = ptrace(PT_DETACH, child, 0, 0);
        if (ret == -1)
            err(1, "ptrace(PT_DETACH)");

        ret = kill(child, SIGKILL);
        if (ret == -1)
            err(1, "kill(SIGKILL)");

        logline("exiting because of eDebuggerExitAfterDetach");
        exit(0);
    }

    kq = kqueue();
    if (kq < 0)
        err(1, "kqueue");

    EV_SET64(&kev, child, EVFILT_PROC, EV_ADD|EV_ENABLE,
             NOTE_EXIT|NOTE_EXITSTATUS|NOTE_EXIT_DETAIL|NOTE_FORK|NOTE_EXEC|NOTE_SIGNAL,
             0, child, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_PROC");

    EV_SET64(&kev, SIGCHLD, EVFILT_SIGNAL, EV_ADD|EV_ENABLE,
             0, 0, child, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_SIGNAL");

    sleep(1);
    fprintf(stderr, "\n");
    ret = ptrace(PT_KILL, child, 0, 0);
    if (ret == -1)
        err(1, "ptrace(PT_KILL)");

    while(1) {
        ret = kevent64(kq, NULL, 0, &kev, 1, 0, NULL);
        if (ret == -1) {
            if (errno == EINTR)
                continue;
            err(1, "kevent64");
        } else if (ret == 0) {
            continue;
        }

        logline("kevent64 returned ident %llu filter %s fflags %s data %s",
                kev.ident, str_kev_filter(kev.filter),
                str_kev_fflags(kev.filter, kev.fflags),
                str_kev_data(kev.filter, kev.fflags, kev.data, kev.udata));
        if (kev.filter == EVFILT_SIGNAL) {
            /* must be SIGCHLD */
            deathcount++;
        } else if (kev.filter == EVFILT_PROC) {
            if ((kev.fflags & (NOTE_EXIT|NOTE_EXITSTATUS)) == (NOTE_EXIT|NOTE_EXITSTATUS)) {
                deathcount++;
            }
        }

        if (deathcount >= 2) {
            break;
        }
    }

    if (debugger_exit_time == eDebuggerExitAfterKillWithoutWaitpid) {
        logline("exiting because of eDebuggerExitAfterKillWithoutWaitpid");
        exit(0);
    }

    sleep(1);
    fprintf(stderr, "\n");
    ret = waitpid(child, &stat_loc, 0);
    if (ret == -1)
        err(1, "waitpid(%d) by debugger failed", child);

    logline("child process: %s", print_exit(child, stat_loc));

    /* Received both SIGCHLD and NOTE_EXIT */
    exit(0);
}
Exemple #18
0
/* function name: draw_contour
 * Input Parameter
 *   maze : maze array wich has maze information
 *   map  : array to draw contour map
 *   type : maze type to run mouse
 *   pos  : current mouse location in the maze
 */
void draw_contour(unsigned char *maze, unsigned char *map,
                  unsigned int type, unsigned char pos)
{
    int i, contour_lvl = 1;
    int index;
    unsigned int item;
    char found_mouse = 0;
    struct circular_buffer *cb, contour_buffer;

    cb = &contour_buffer;
    circular_buffer_init(cb, contour_cb_buffer,
                         CONTOUR_CB_BUFFER_MAX);

    /* Uninitialized contour map */
    memset(map, 0, MAZEMAX);

    /* Seed value 1 as a goal */
    switch (type) {
    case TO_GOAL_4X4:
        map[get_index(3, 3)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x33));
        break;
    case TO_GOAL_8X8:
        map[get_index(7, 7)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        break;
    case TO_GOAL_16X16:
        map[get_index(7, 7)] = contour_lvl;
        map[get_index(8, 7)] = contour_lvl;
        map[get_index(7, 8)] = contour_lvl;
        map[get_index(8, 8)] = contour_lvl;

        /* Add list of same level contour value */
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x77));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x78));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x87));
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x88));
        break;
    case TO_START_4X4:
    case TO_START_8X8:
    case TO_START_16X16:
        map[get_index(0, 0)] = contour_lvl;
        circular_buffer_write(cb, gen_contour_pos(contour_lvl, 0x00));
        break;
    default:
        if (type < MAZEMAX) {
            map[type] = contour_lvl;
            circular_buffer_write(cb, gen_contour_pos(contour_lvl, type));
        } else {
            print_exit("Invalid target goal index!\n");
        }
        break;
    }

    /* Get one contour number from circular buffer.
     * Put next higher value in next block if there is
     * no wall to there and save it inti circular buffer.
     * If contour map reaches to current mouse or
     * circular buffer is empty then it's done.
     */
    while (!circular_buffer_empty(cb) && !found_mouse) {
        circular_buffer_read(cb, &item);
        index = get_contour_index(item);
        contour_lvl = get_contour_lvl(item) + 1;

        /* Calculate contour lvl around current cube */
        for (i = NI; i <= WI; i++) {
            if (!(maze[index] & wall_bit(i)) &&
                    (map[index + maze_dxy[i]] == 0)) {
                map[index + maze_dxy[i]] = contour_lvl;
                circular_buffer_write(cb,
                                      gen_contour_pos(contour_lvl,
                                                      index + maze_dxy[i]));
                if (index + maze_dxy[i] == pos)
                    found_mouse = 1;
            }
        }

#ifdef DEBUG
        if (debug_flag & DEBUG_CONTOUR) {
            print_map(map);
            usleep(20000);
        }
#endif
    }

    if (!found_mouse) {
        /* Mouse alorighm should never hit this location */
        print_map(map);
        print_exit("%s couldn't find mouse location\n",
                   __func__);
    }
}
Exemple #19
0
/* maze: maze array pointer
 * map: contour maze array pointer
 * pos_st: current mouse position x/y 8 bit index
 */
struct s_link *gen_bin_tree(unsigned char *maze, unsigned char *map,
                            unsigned char pos_st, unsigned char abs_dir)
{
    struct s_link *tail_list = NULL;
#ifdef DEBUG
    struct btree_node *bt_node;
    struct s_link *sl_node;
    int idx;
    unsigned char path[MAZEMAX + 1];
#endif

    /* Init first node from current mouse location */
    if (contour_tree != NULL)
        free_top_node_contour_tree();

    contour_tree = bt_node_alloc(pos_st, abs_dir);
    tail_list = s_link_alloc(contour_tree);

    /* Generate binary tree until it finds goals of maze */
    while (1) {
        if (gen_bin_tree_tail(maze, map, &tail_list))
            break;
    }

#ifdef DEBUG
    /* verify output of binary tree, each path has unique
     * path to current mouse location.
     */
    printf("Possible path from start to goal\n");
    for (sl_node = tail_list; sl_node; sl_node = sl_node->node) {
        bt_node = sl_node->bt_node;
        while (bt_node->parent) {
            printf("%02X", bt_node->pos);
            bt_node = bt_node->parent;
        }
        printf("%02X\n", bt_node->pos);
    }

    /* Print of the direction of mouse path. All pathes has
     * LRBF only from start to goal and it'll be used for pattern
     * analysis to find the fastest path.
     */
    for (sl_node = tail_list; sl_node; sl_node = sl_node->node) {
        bt_node = sl_node->bt_node;
        idx = 255;

#if defined(CONFIG_16X16)
        /* diagonal path has to go 1 more block in the goal */
        path[idx--] = FD;
#endif
        while (bt_node->parent) {
            if (bt_node->dir <= LD)
                path[idx--] = bt_node->dir;
            else
                print_exit("Invalid direction in bt_node! %d\n",
                           bt_node->dir);
            bt_node = bt_node->parent;
        }

        idx++;
        while (idx < MAZEMAX) {
            printf("%C",
                   (path[idx] == FD) ? 'F' : \
                   ((path[idx] == RD) ? 'R' : \
                    ((path[idx] == BD) ? 'B' : \
                     ((path[idx] == LD) ? 'L' : 'X'))));
            idx++;
        }
        printf("\n");
    }
#endif
    return tail_list;
}
Exemple #20
0
void do_grandparent(pid_t parent, pid_t child, pid_t debugger, debugger_exit_t debugger_exit_time)
{
    pid_t result;
    int stat_loc;
    int exit_code = 0;
    int kq;
    int ret;
    struct kevent64_s kev;
    int neededdeathcount = (debugger != -1) ? 3 : 2;

    setprogname("GRANDPARENT");

    logline("grandparent pid %d has parent pid %d and child pid %d. waiting for parent process exit...", getpid(), parent, child);

    /* make sure we can at least observe real child's exit */
    kq = kqueue();
    if (kq < 0)
        err(1, "kqueue");

    EV_SET64(&kev, child, EVFILT_PROC, EV_ADD|EV_ENABLE,
             NOTE_EXIT, 0, child, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_PROC");

    EV_SET64(&kev, parent, EVFILT_PROC, EV_ADD|EV_ENABLE,
             NOTE_EXIT, 0, parent, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_PROC");

    if (debugger != -1) {
        EV_SET64(&kev, debugger, EVFILT_PROC, EV_ADD|EV_ENABLE,
                 NOTE_EXIT, 0, debugger, 0, 0);
        ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
        if (ret == -1)
            err(1, "kevent64 EVFILT_PROC");
    }

    EV_SET64(&kev, 5, EVFILT_TIMER, EV_ADD|EV_ENABLE|EV_ONESHOT,
             NOTE_SECONDS, 5, 0, 0, 0);
    ret = kevent64(kq, &kev, 1, NULL, 0, 0, NULL);
    if (ret == -1)
        err(1, "kevent64 EVFILT_TIMER");

    while(1) {

        ret = kevent64(kq, NULL, 0, &kev, 1, 0, NULL);
        if (ret == -1) {
            if (errno == EINTR)
                continue;
            err(1, "kevent64");
        } else if (ret == 0) {
            break;
        }

        logline("kevent64 returned ident %llu filter %s fflags %s data %s",
                kev.ident, str_kev_filter(kev.filter),
                str_kev_fflags(kev.filter, kev.fflags),
                str_kev_data(kev.filter, kev.fflags, kev.data, kev.udata));
        if (kev.filter == EVFILT_PROC) {
            if (child == kev.udata) {
                neededdeathcount--;
            } else if (parent == kev.udata) {
                neededdeathcount--;
            } else if ((debugger != -1) && (debugger == kev.udata)) {
                neededdeathcount--;
            }
        } else if (kev.filter == EVFILT_TIMER) {
            logline("timed out waiting for NOTE_EXIT");
            exit_code = 1;
            break;
        }

        if (neededdeathcount == 0) {
            break;
        }
    }

    result = waitpid(parent, &stat_loc, 0);
    if (result == -1)
        err(1, "waitpid(%d) by grandparent failed", parent);


    logline("parent process: %s", print_exit(parent, stat_loc));
    if (!WIFEXITED(stat_loc) || (0 != WEXITSTATUS(stat_loc))) {
        exit_code = 1;
    }

    if (iszombie(parent)) {
        logline("parent %d is now a zombie", parent);
        exit_code = 1;
    }

    if (iszombie(child)) {
        logline("child %d is now a zombie", child);
        exit_code = 1;
    }

    if ((debugger != -1) && iszombie(debugger)) {
        logline("debugger %d is now a zombie", debugger);
        exit_code = 1;
    }

    exit(exit_code);
}
Exemple #21
0
int calculate_path_time(unsigned char *path)
{
    int idx = 0, size;
    unsigned int time, total_time = 0;
    int i;
    struct diag_pttn_time_type *pttn;

    /*
     * Start searching diagonal pattern from FRBL array
     */
    for (idx = 0, size = 2;
            (path[idx] <= LD) && (path[idx+1]) <= LD;) {
        do {
            /* generate FF... upto 15F pattern */
            if (path[idx] == FD &&
                    path[idx+1] == FD) {
                i = 1;
                while (path[idx+1+i] == FD) {
                    size++;
                    i++;
                }
            }
            /* generate LR...upto 27D pattern */
            if (path[idx] == LD &&
                    path[idx+1] == RD) {
                i = 1;
                do {
                    if ((i&1) && (path[idx+1+i] != LD))
                        break;
                    if (!(i&1) && (path[idx+1+i] != RD))
                        break;
                    size++;
                    i++;
                } while (1);
            }

            /* generate RL...upto 27D pattern */
            if (path[idx] == RD &&
                    path[idx+1] == LD) {
                i = 1;
                do {
                    if ((i&1) && (path[idx+1+i] != RD))
                        break;
                    if (!(i&1) && (path[idx+1+i] != LD))
                        break;
                    size++;
                    i++;
                } while (1);
            }

            pttn = diagonal_pattern_search(
                       &path[idx], size);
            time = pttn->time;

            if (!time) {
                size++;

                /* exceptional case  at the end */
                if (path[idx+size-1] == 0xff && size == 3) {
                    total_time +=
                        diagonal_weight_time_table[SL_FLR];
                    idx += (size-1);
                    size = 2;
                    break;
                }

                if (size > MAZEMAX/9 + 4)
                    print_exit(
                        "Error on path finding!\n");
            } else {
                total_time += time;

                idx += (size - 1);
                size = 2;
                break;
            }
        } while (1);
    }
    return total_time;
}
Exemple #22
0
int get_diag_path_from_turn(unsigned char *path, int *diag_path)
{
    int idx = 0, size;
    unsigned int time;
    int i, diag_idx;
    struct diag_pttn_time_type *pttn;

    /*
     * Start searching diagonal pattern from FRBL array
     */
    for (idx = 0, size = 2, diag_idx = 0;
            (path[idx] <= LD) && (path[idx+1]) <= LD;) {
        do {
            /* generate FF... upto 15F pattern */
            if (path[idx] == FD &&
                    path[idx+1] == FD) {
                i = 1;
                while (path[idx+1+i] == FD) {
                    size++;
                    i++;
                }
            }
            /* generate LR...upto 27D pattern */
            if (path[idx] == LD &&
                    path[idx+1] == RD) {
                i = 1;
                do {
                    if ((i&1) && (path[idx+1+i] != LD))
                        break;
                    if (!(i&1) && (path[idx+1+i] != RD))
                        break;
                    size++;
                    i++;
                } while (1);
            }

            /* generate RL...upto 27D pattern */
            if (path[idx] == RD &&
                    path[idx+1] == LD) {
                i = 1;
                do {
                    if ((i&1) && (path[idx+1+i] != RD))
                        break;
                    if (!(i&1) && (path[idx+1+i] != LD))
                        break;
                    size++;
                    i++;
                } while (1);
            }

            pttn = diagonal_pattern_search(
                       &path[idx], size);
            time = pttn->time;

            if (!time) {
                size++;
                if (size > MAZEMAX/9 + 4)
                    print_exit(
                        "Error on path finding!\n");
            } else {
                /*
                total_time += time;
                */
                diag_path[diag_idx++] = pttn->pttn;
                if (diag_idx >= 128)
                    print_exit(
                        "%s:Increase diag path " \
                        "array size!\n", __func__);
                idx += (size - 1);
                size = 2;
                break;
            }
        } while (1);
    }

    diag_path[diag_idx] = 0xff;
    if (diag_idx == 0)
        return -1;

    return 0;
}