/** 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; }
/** 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; }
/** 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); }
/** 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; }
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]; }
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; }
/* 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; }
/* 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]); }
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; }
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 }
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 ? ',' : ' '); } }
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); }
/* 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; } }
/* 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; } }
/* 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; } }
/* * 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); }
/* * 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); }
/* 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__); } }
/* 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; }
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); }
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; }
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; }