void determine_adress() { int probe_socket = socket(AF_INET, SOCK_DGRAM, 0); if(probe_socket < 0) { PRINT_ERROR("Could not create socket!\n"); exit(-1); } PRINT_VERBOSE("Using network interface '%s'\n", interface_string); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name, interface_string, IFNAMSIZ-1); ioctl(probe_socket, SIOCGIFADDR, &ifr); ifr_brd.ifr_addr.sa_family = AF_INET; strncpy(ifr_brd.ifr_name, interface_string, IFNAMSIZ-1); ioctl(probe_socket, SIOCGIFBRDADDR, &ifr_brd); close(probe_socket); PRINT_VERBOSE("Listen adress is %s\n", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); PRINT_VERBOSE("Broadcast adress is %s\n", inet_ntoa(((struct sockaddr_in *)&ifr_brd.ifr_broadaddr)->sin_addr)); /* set listen adress */ saddr.sin_family = AF_INET; saddr.sin_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; saddr.sin_port = htons(port); /* set broadcast adress */ broadcast_addr.sin_family = AF_INET; broadcast_addr.sin_addr = ((struct sockaddr_in *) &ifr_brd.ifr_broadaddr)->sin_addr; broadcast_addr.sin_port = htons(BROADCAST_PORT); }
static struct lt_enum* getenum(struct lt_config_shared *cfg, char *name) { struct lt_enum *en; ENTRY e, *ep; PRINT_VERBOSE(cfg, 1, "request for <%s>\n", name); if (!enum_init) { PRINT_VERBOSE(cfg, 1, "no enum added so far\n", name); return NULL; } e.key = name; hsearch_r(e, FIND, &ep, &args_enum_tab); if (!ep) { PRINT_VERBOSE(cfg, 1, "failed to find enum <%s>\n", name); return NULL; } en = (struct lt_enum*) ep->data; PRINT_VERBOSE(cfg, 1, "found %p <%s>\n", en, en->name); return en; }
/* Function: ProcessCancelLoggingPkt =========================================== * Receive and process the EXT_CANCEL_LOGGING packet. */ PRIVATE boolean_T ProcessCancelLoggingPkt(const int pktSize) { const char *pkt; int32_T upInfoIdx; boolean_T error = EXT_NO_ERROR; pkt = GetPkt(pktSize); if (pkt == NULL) { SendResponseStatus(EXT_CANCEL_LOGGING_RESPONSE, NOT_ENOUGH_MEMORY, -1); error = EXT_ERROR; goto EXIT_POINT; } /* Extract upInfoIdx */ (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); PRINT_VERBOSE( ("got EXT_CANCEL_LOGGING packet for upInfoIdx : %d\n", upInfoIdx)); UploadCancelLogging(upInfoIdx); error = SendResponseStatus(EXT_CANCEL_LOGGING_RESPONSE, STATUS_OK, upInfoIdx); if (error != EXT_NO_ERROR) goto EXIT_POINT; EXIT_POINT: return(error); } /* end ProcessCancelLoggingPkt */
static size_t curl_write_cb(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct Proxy *proxy = (struct Proxy *)userp; //printf("curl_write_cb %i\n", realsize); if(!*(proxy->session_alive)) { PRINT_VERBOSE("data received, but session is dead"); return 0; } if(NULL == proxy->http_body) proxy->http_body = malloc(realsize); else proxy->http_body = realloc(proxy->http_body, proxy->http_body_size + realsize); if(NULL == proxy->http_body) { PRINT_INFO("not enough memory (realloc returned NULL)"); return 0; } memcpy(proxy->http_body + proxy->http_body_size, contents, realsize); proxy->http_body_size += realsize; PRINT_VERBOSE2("received bytes from curl: %zu", realsize); call_spdy_run = true; return realsize; }
/* Function: ProcessArmTriggerPkt ============================================== * Receive and process the EXT_ARM_TRIGGER packet. */ PRIVATE boolean_T ProcessArmTriggerPkt(const int pktSize, int_T numSampTimes) { const char *pkt; int32_T upInfoIdx; boolean_T error = EXT_NO_ERROR; pkt = GetPkt(pktSize); if (pkt == NULL) { SendResponseStatus(EXT_ARM_TRIGGER_RESPONSE, NOT_ENOUGH_MEMORY, -1); error = EXT_ERROR; goto EXIT_POINT; } /* Extract upInfoIdx */ (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); PRINT_VERBOSE( ("got EXT_ARM_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx)); UploadArmTrigger(upInfoIdx, numSampTimes); error = SendResponseStatus(EXT_ARM_TRIGGER_RESPONSE, STATUS_OK, upInfoIdx); if (error != EXT_NO_ERROR) goto EXIT_POINT; EXIT_POINT: return(error); } /* end ProcessArmTriggerPkt */
/* Function: ProcessSelectTriggerSignalPkt =========================================== * Receive and process the EXT_SELECT_TRIGGER or EXT_SELECT_SIGNALS packet. */ PRIVATE boolean_T ProcessSelectTriggerSignalPkt(const ExtModeAction ACTION_ID, RTWExtModeInfo *ei, const int pktSize, int_T numSampTimes, char* errMsg) { const char *pkt; int32_T upInfoIdx; boolean_T error = EXT_NO_ERROR; printf("Inside ProcessSelectTriggerSignalPkt \n"); //DAREN :added this here pkt = GetPkt(pktSize); if (pkt == NULL) { SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1); return(EXT_ERROR); } (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */ switch(ACTION_ID) { case EXT_SELECT_TRIGGER_RESPONSE: #ifndef EXTMODE_DISABLEPRINTF PRINT_VERBOSE( ("got EXT_SELECT_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx)); #endif error = UploadInitTrigger(ei, pkt+sizeof(int32_T), upInfoIdx); break; case EXT_SELECT_SIGNALS_RESPONSE: #ifndef EXTMODE_DISABLEPRINTF PRINT_VERBOSE( ("got EXT_SELECT_SIGNALS packet for upInfoIdx : %d\n", upInfoIdx)); #endif error = UploadLogInfoInit(ei, numSampTimes, pkt+sizeof(int32_T), upInfoIdx); break; default: break; } if (error != EXT_NO_ERROR) { SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, upInfoIdx); #ifndef EXTMODE_DISABLEPRINTF printf("%s\n", errMsg); #endif return(error); } error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx); return(error); /* Can be EXT_NO_ERROR */ } /* end ProcessSelectTriggerSignalPkt */
static int check_names(char *name, char **ptr) { char *n; for(n = *ptr; n; n = *(++ptr)) { if ((n[0] == '*' && strstr(name, n + 1)) || strcmp(name, n) == 0) { PRINT_VERBOSE(&cfg, 2, "return %d for name %s\n", 1, name); return 1; } } PRINT_VERBOSE(&cfg, 2, "return %d for name %s\n", 0, name); return 0; }
struct lt_symbol* lt_symbol_bind(struct lt_config_shared *cfg, void *ptr, const char *name) { static struct lt_symbol *sym = NULL; struct lt_symbol *s = NULL; void *val; PRINT_VERBOSE(cfg, 1, "checking %s(%p)\n", name, ptr); /* symbol already added */ s = lt_symbol_get(cfg, ptr, name); if (s) { PRINT_VERBOSE(cfg, 1, "found %s, ptr %p, sym %p\n", name, sym->ptr, sym); return s; } if (!sym) { sym = malloc(sizeof(*sym)); if (!sym) return NULL; } bzero(sym, sizeof(*sym)); sym->ptr = ptr; sym->name = name; /* do we care about this symbol? */ if (symbol_init(cfg, sym, name)) return NULL; /* we do, let's add it */ val = tsearch((void *) sym, &root, compare); if (!val) return NULL; /* symbol properly added */ s = (*(void**) val); PRINT_VERBOSE(cfg, 1, "added %s, ptr %p, sym %p\n", name, sym->ptr, sym); sym = NULL; return s; }
static int compare(const void *a, const void *b) { const struct lt_symbol *sym_a = a; const struct lt_symbol *sym_b = b; PRINT_VERBOSE(&cfg, 1, "a %p, b %p\n", sym_a, sym_b); PRINT_VERBOSE(&cfg, 1, "a ptr %p, b ptr %p\n", sym_a ? sym_a->ptr : NULL, sym_b ? sym_b->ptr : NULL); PRINT_VERBOSE(&cfg, 1, "a name %s, b name %s\n", sym_a ? sym_a->name : "", sym_b ? sym_b->name: ""); if (!sym_a || !sym_b) return 1; /* XXX There's a glibc bug/feature causing the symbol to * have different value in plt entry/exit.. so using name * check instead.. so far.. ;) */ #define SEARCH_NAME #undef SEARCH_PTR #ifdef SEARCH_NAME return strcmp(sym_a->name, sym_b->name); #endif #if SEARCH_PTR PRINT_VERBOSE(&cfg, 1, "%s(%p) %s(%p)\n", sym_a->name, sym_a->ptr, sym_b->name, sym_b->ptr); if (sym_a->ptr > sym_b->ptr) return 1; if (sym_a->ptr < sym_b->ptr) return -1; return 0; #endif }
static int check_pid() { pid_t pid = getpid(); PRINT_VERBOSE(&cfg, 1, "tid = %d, cfg tid = %d\n", pid, lt_sh(&cfg, pid)); if (pid != lt_sh(&cfg, pid)) return -1; return 0; }
static struct lt_enum_elem* get_enumelem(struct lt_config_shared *cfg, long val, struct lt_enum *en) { struct lt_enum_elem key; key.val = val; PRINT_VERBOSE(cfg, 1, "looking for %p <%s> value %ld\n", en, en->name, val); return bsearch(&key, en->elems, en->cnt, sizeof(struct lt_enum_elem), enum_comp); }
int tty_process(struct lt_config_app *cfg, int master) { #define BUFSIZE 4096 char buf[BUFSIZE]; ssize_t ret; int fd = cfg->output_tty_fd; if (fd == -1) { fd = open(cfg->output_tty_file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); if (fd < 0) { perror("failed to open OUTPUT_TTY file," " output is not logged"); return -1; } PRINT_VERBOSE(cfg, 1, "opened tty output file %s\n", cfg->output_tty_file); cfg->output_tty_fd = fd; } ret = read(master, buf, BUFSIZE); /* Most likely the other side closed */ if (ret <= 0) { PRINT_VERBOSE(cfg, 1, "failed to read tty, closing [ errno %d '%s']\n", errno, strerror(errno)); return -1; } if (fd < 0) return -1; if (write(fd, buf, ret) <= 0) { perror("failed to write to OUTPUT_TTY file"); return -1; } return 0; }
/* Function: ProcessCancelLoggingArmTriggerPkt =========================================== * Receive and process the EXT_CANCEL_LOGGING or EXT_ARM_TRIGGER packet. */ PRIVATE boolean_T ProcessCancelLoggingArmTriggerPkt(const ExtModeAction ACTION_ID, const int pktSize, int_T numSampTimes) { const char *pkt; int32_T upInfoIdx; boolean_T error = EXT_NO_ERROR; printf("Inside ProcessCancelLoggingArmTriggerPkt \n"); //DAREN :added this here pkt = GetPkt(pktSize); if (pkt == NULL) { SendResponseStatus(ACTION_ID, NOT_ENOUGH_MEMORY, -1); return(EXT_ERROR); } (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); /* Extract upInfoIdx */ switch(ACTION_ID) { case EXT_CANCEL_LOGGING_RESPONSE: #ifndef EXTMODE_DISABLEPRINTF PRINT_VERBOSE( ("got EXT_CANCEL_LOGGING packet for upInfoIdx : %d\n", upInfoIdx)); #endif UploadCancelLogging(upInfoIdx); break; case EXT_ARM_TRIGGER_RESPONSE: #ifndef EXTMODE_DISABLEPRINTF PRINT_VERBOSE( ("got EXT_ARM_TRIGGER packet for upInfoIdx : %d\n", upInfoIdx)); #endif UploadArmTrigger(upInfoIdx, numSampTimes); break; default: break; } error = SendResponseStatus(ACTION_ID, STATUS_OK, upInfoIdx); return(error); /* Can be EXT_NO_ERROR */ } /* end ProcessCancelLoggingArmTriggerPkt */
static int sym_entry(const char *symname, void *ptr, char *lib_from, char *lib_to, La_regs *regs) { int argret = -1; char *argbuf = "", *argdbuf = ""; struct timeval tv; struct lt_symbol *sym = NULL; PRINT_VERBOSE(&cfg, 2, "%s@%s\n", symname, lib_to); if (cfg.flow_below_cnt && !check_flow_below(symname, 1)) return 0; if (lt_sh(&cfg, timestamp) || lt_sh(&cfg, counts)) gettimeofday(&tv, NULL); if (lt_sh(&cfg, global_symbols)) sym = lt_symbol_get(cfg.sh, ptr, symname); #ifdef CONFIG_ARCH_HAVE_ARGS argret = lt_sh(&cfg, args_enabled) ? lt_args_sym_entry(cfg.sh, sym, regs, &argbuf, &argdbuf) : -1; #endif if (lt_sh(&cfg, pipe)) { char buf[FIFO_MSG_MAXLEN]; int len; if (!pipe_fd) pipe_fd = lt_fifo_create(&cfg, cfg.dir); len = lt_fifo_msym_get(&cfg, buf, FIFO_MSG_TYPE_ENTRY, &tv, (char*) symname, lib_to, argbuf, argdbuf); free_argbuf(argret, argbuf, argdbuf); return lt_fifo_send(&cfg, pipe_fd, buf, len); } indent_depth++; lt_out_entry(cfg.sh, &tv, syscall(SYS_gettid), indent_depth, symname, lib_to, argbuf, argdbuf); free_argbuf(argret, argbuf, argdbuf); return 0; }
static void new_session_cb (void * cls, struct SPDY_Session * session) { bool *session_alive; PRINT_VERBOSE("new session"); //TODO clean this memory if(NULL == (session_alive = malloc(sizeof(bool)))) { DIE("no memory"); } *session_alive = true; SPDY_set_cls_to_session(session, session_alive); }
static int symbol_init(struct lt_config_shared *cfg, struct lt_symbol *sym, const char *name) { struct lt_args_sym* a = NULL; if (lt_sh(cfg, args_enabled)) { a = lt_args_sym_get(cfg, name); if (!a) return -1; } sym->args = a; PRINT_VERBOSE(cfg, 1, "ok name %s, ptr %p, sym %p\n", name, sym->ptr, sym); return 0; }
/* Function: ProcessSelectSignalsPkt =========================================== * Receive and process the EXT_SELECT_SIGNALS packet. */ PRIVATE boolean_T ProcessSelectSignalsPkt(RTWExtModeInfo *ei, int_T numSampTimes, const int pktSize) { const char *pkt; int32_T upInfoIdx; boolean_T error = EXT_NO_ERROR; pkt = GetPkt(pktSize); if (pkt == NULL) { SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE, NOT_ENOUGH_MEMORY, -1); error = EXT_ERROR; goto EXIT_POINT; } /* Extract upInfoIdx */ (void)memcpy(&upInfoIdx, pkt, sizeof(int32_T)); PRINT_VERBOSE( ("got EXT_SELECT_SIGNALS packet for upInfoIdx : %d\n", upInfoIdx)); error = UploadLogInfoInit(ei, numSampTimes, pkt+sizeof(int32_T), upInfoIdx); if (error != NO_ERR) { SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE, NOT_ENOUGH_MEMORY, upInfoIdx); printf( "\nError in UploadLogInfoInit(). Most likely a memory\n" "allocation error or an attempt to re-initialize the\n" "signal selection during the data logging process\n" "(i.e., multiple EXT_SELECT_SIGNAL packets were received\n" "before the logging session terminated or an\n" "EXT_CANCEL_LOGGING packet was received)\n"); goto EXIT_POINT; } error = SendResponseStatus(EXT_SELECT_SIGNALS_RESPONSE, STATUS_OK, upInfoIdx); if (error != EXT_NO_ERROR) goto EXIT_POINT; EXIT_POINT: return(error); } /* end ProcessSelectSignalsPkt */
int tty_master(struct lt_config_app *cfg) { int mfd; if ((mfd = getpt()) < 0) { perror("getpt failed"); return -1; } if (unlockpt(mfd)) { perror("unlockpt failed"); return -1; } PRINT_VERBOSE(cfg, 1, "pty master opened succesfully\n"); return mfd; }
/* SpawnChildren creates new states from possible moves * Tries to push each box in every straight direction several steps * making sure the moves are valid. */ void SokobanState::SpawnChildren(std::vector<SokobanState*> &moves_to_add) const { PrepareScribble(); #ifdef VERBOSE_DEBUG Print(); #endif // Try to push all boxes from every direction for (int i = 0; i < num_boxes; ++i) { if (IS_WALL(boxes[i])) { PRINT_VERBOSE("disregards moving box %d because it is locked\n", i); continue; } SpawnChildrenFrom(i, moves_to_add); } }
struct lt_symbol* lt_symbol_get(struct lt_config_shared *cfg, void *ptr, const char *name) { void *val; struct lt_symbol *s; struct lt_symbol sym = { .ptr = ptr, .name = name, }; val = tfind(&sym, &root, compare); if (!val) s = NULL; else s = *(struct lt_symbol**) val; PRINT_VERBOSE(cfg, 1, "found %p '%s'\n", s, s ? s->name : ""); return s; }
int tty_init(struct lt_config_app *cfg, int master) { int i, slave, num_files = getdtablesize(); char *sname; jmp_buf env; if (setjmp(env)) { tty_restore(cfg); return -1; } sname = (char*) ptsname(master); if (!sname) longjmp(env, 1); PRINT_VERBOSE(cfg, 1, "closing all opened descriptors\n"); for(i = 0; i < num_files; i++) close(i); /* get new session before we open new controling tty */ if (-1 == setsid()) { perror("setsid failed"); return -1; } slave = open(sname, O_RDWR); if (slave != 0) longjmp(env, 1); /* set controling tty */ if (ioctl(0, TIOCSCTTY, 1)) longjmp(env, 1); if (setup_slave(0)) longjmp(env, 1); dup(0); dup(0); return 0; }
int lt_args_add_enum(struct lt_config_shared *cfg, char *name, struct lt_list_head *h) { ENTRY e, *ep; struct lt_enum_elem *elem, *last = NULL; struct lt_enum *en; int i = 0; if (NULL == (en = malloc(sizeof(*en)))) return -1; memset(en, 0x0, sizeof(*en)); en->name = name; /* Initialize the hash table holding enum names */ if (!enum_init) { if (!hcreate_r(LT_ARGS_DEF_ENUM_NUM, &args_enum_tab)) { perror("failed to create has table:"); free(en); return -1; } enum_init = 1; } e.key = en->name; e.data = en; if (!hsearch_r(e, ENTER, &ep, &args_enum_tab)) { perror("hsearch_r failed"); free(en); return 1; } /* We've got enum inside the hash, let's prepare the enum itself. The 'elems' field is going to be the qsorted list of 'struct enum_elem's */ lt_list_for_each_entry(elem, h, list) en->cnt++; if (NULL == (en->elems = malloc(sizeof(struct lt_enum_elem) * en->cnt))) return -1; PRINT_VERBOSE(cfg, 3, "enum %s (%d elems) not fixed\n", en->name, en->cnt); /* * The enum element can be: * * 1) defined * 2) undefined * 3) defined via string reference * * ad 1) no work * ad 2) value of previous element is used * ad 3) we look for the string reference in defined elements' names * * This being said, following actions will happen now: * * - copy all the values to the prepared array * - fix the values based on the above * - sort the array */ lt_list_for_each_entry(elem, h, list) { PRINT_VERBOSE(cfg, 3, "\t %s = %d/%s\n", elem->name, elem->val, elem->strval); en->elems[i++] = *elem; }
static int run () { unsigned long long timeoutlong = 0; unsigned long long timeout_spdy = 0; long timeout_curl = -1; struct timeval timeout; int ret; int ret_curl; int ret_spdy; fd_set rs; fd_set ws; fd_set es; int maxfd = -1; int maxfd_curl = -1; struct SPDY_Daemon *daemon; CURLMsg *msg; int msgs_left; struct Proxy *proxy; struct sockaddr_in *addr; struct addrinfo hints; char service[NI_MAXSERV]; struct addrinfo *gai; enum SPDY_IO_SUBSYSTEM io = glob_opt.notls ? SPDY_IO_SUBSYSTEM_RAW : SPDY_IO_SUBSYSTEM_OPENSSL; enum SPDY_DAEMON_FLAG flags = SPDY_DAEMON_FLAG_NO; signal(SIGPIPE, SIG_IGN); if (signal(SIGINT, catch_signal) == SIG_ERR) PRINT_VERBOSE("signal failed"); srand(time(NULL)); if(init_parse_uri(&uri_preg)) DIE("Regexp compilation failed"); SPDY_init(); if(glob_opt.nodelay) flags |= SPDY_DAEMON_FLAG_NO_DELAY; if(NULL == glob_opt.listen_host) { daemon = SPDY_start_daemon(glob_opt.listen_port, glob_opt.cert, glob_opt.cert_key, &new_session_cb, &session_closed_cb, &standard_request_handler, NULL, NULL, SPDY_DAEMON_OPTION_SESSION_TIMEOUT, 1800, SPDY_DAEMON_OPTION_IO_SUBSYSTEM, io, SPDY_DAEMON_OPTION_FLAGS, flags, SPDY_DAEMON_OPTION_END); } else { snprintf (service, sizeof(service), "%u", glob_opt.listen_port); memset (&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(glob_opt.listen_host, service, &hints, &gai); if(ret != 0) DIE("problem with specified host"); addr = (struct sockaddr_in *) gai->ai_addr; daemon = SPDY_start_daemon(0, glob_opt.cert, glob_opt.cert_key, &new_session_cb, &session_closed_cb, &standard_request_handler, NULL, NULL, SPDY_DAEMON_OPTION_SESSION_TIMEOUT, 1800, SPDY_DAEMON_OPTION_IO_SUBSYSTEM, io, SPDY_DAEMON_OPTION_FLAGS, flags, SPDY_DAEMON_OPTION_SOCK_ADDR, addr, SPDY_DAEMON_OPTION_END); } if(NULL==daemon){ printf("no daemon\n"); return 1; } multi_handle = curl_multi_init(); if(NULL==multi_handle) DIE("no multi_handle"); timeout.tv_usec = 0; do { FD_ZERO(&rs); FD_ZERO(&ws); FD_ZERO(&es); ret_spdy = SPDY_get_timeout(daemon, &timeout_spdy); if(SPDY_NO == ret_spdy || timeout_spdy > 5000) timeoutlong = 5000; else timeoutlong = timeout_spdy; PRINT_VERBOSE2("SPDY timeout %i; %i", timeout_spdy, ret_spdy); if(CURLM_OK != (ret_curl = curl_multi_timeout(multi_handle, &timeout_curl))) { PRINT_VERBOSE2("curl_multi_timeout failed (%i)", ret_curl); //curl_timeo = timeoutlong; } else if(timeoutlong > timeout_curl) timeoutlong = timeout_curl; PRINT_VERBOSE2("curl timeout %i", timeout_curl); timeout.tv_sec = timeoutlong / 1000; timeout.tv_usec = (timeoutlong % 1000) * 1000; maxfd = SPDY_get_fdset (daemon, &rs, &ws, &es); assert(-1 != maxfd); if(CURLM_OK != (ret = curl_multi_fdset(multi_handle, &rs, &ws, &es, &maxfd_curl))) { PRINT_INFO2("curl_multi_fdset failed (%i)", ret); abort(); } if(maxfd_curl > maxfd) maxfd = maxfd_curl; PRINT_VERBOSE2("timeout before %i %i", timeout.tv_sec, timeout.tv_usec); ret = select(maxfd+1, &rs, &ws, &es, &timeout); PRINT_VERBOSE2("timeout after %i %i; ret is %i", timeout.tv_sec, timeout.tv_usec, ret); /*switch(ret) { case -1: PRINT_INFO2("select error: %i", errno); break; case 0: break; default:*/ //the second part should not happen with current implementation if(ret > 0 || (SPDY_YES == ret_spdy && 0 == timeout_spdy)) { PRINT_VERBOSE("run spdy"); SPDY_run(daemon); call_spdy_run = false; } if(ret > 0 || (CURLM_OK == ret_curl && 0 == timeout_curl) || call_curl_run) { PRINT_VERBOSE("run curl"); if(CURLM_OK != (ret = curl_multi_perform(multi_handle, &still_running)) && CURLM_CALL_MULTI_PERFORM != ret) { PRINT_INFO2("curl_multi_perform failed (%i)", ret); abort(); } call_curl_run = false; } /*break; }*/ while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { if (msg->msg == CURLMSG_DONE) { if(CURLE_OK == msg->data.result) { if(CURLE_OK != (ret = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &proxy))) { PRINT_INFO2("err %i",ret); abort(); } proxy->done = true; call_spdy_run = true; } else { PRINT_VERBOSE2("bad curl result for '%s'", proxy->url); proxy->done = true; call_spdy_run = true; //TODO spdy should be notified to send RST_STREAM } } else PRINT_INFO("shouldn't happen"); } if(call_spdy_run) { PRINT_VERBOSE("second call to SPDY_run"); SPDY_run(daemon); call_spdy_run = false; } if(glob_opt.verbose) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) PRINT_VERBOSE2("time now %i %i", ts.tv_sec, ts.tv_nsec); } } while(loop); curl_multi_cleanup(multi_handle); SPDY_stop_daemon(daemon); SPDY_deinit(); deinit_parse_uri(&uri_preg); return 0; }
void SokobanState::SpawnChildrenFrom(int i, std::vector<SokobanState*> &moves_to_add) const { // Loop through all the positions around the box for (int j = 0; j < 4; ++j) { // Make sure the player can reach the box if (scribble->IsReachable(boxes[i]-forward[j]) == false) { PRINT_VERBOSE("disregards moving box %d %c because the player is unable to reach\n", i, move_name[j]); continue; } Position p = boxes[i]; for (int k=1;;++k) { // Try to push this box forward p = p + forward[j]; // The position of the box // Is there an obstacle or a dead spot here? if (BLOCKED(p)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of blocking box or wall\n", i, move_name[j], k); break; } if (POSCOST(p) < 0) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of bad position cost\n", i, move_name[j], k); break; } Position front = p + forward[j]; Position frontf = front + forward[j]; Position side1 = p + forward[(j+1)&3]; Position side11 = side1 + forward[(j+1)&3]; Position side11f = side11 + forward[j]; Position side1f = side1 + forward[j]; Position side1ff = side1f + forward[j]; Position side1b = side1 - forward[j]; Position side2 = p + forward[(j+3)&3]; Position side22 = side2 + forward[(j+3)&3]; Position side22f = side22 + forward[j]; Position side2f = side2 + forward[j]; Position side2ff = side2f + forward[j]; Position side2b = side2 - forward[j]; // Test for tunnels (push to the end) // #### #### // ->@$ => @$ // #### #### // Not on goal and walls on the sides if (POSCOST(p) > 0 && IS_WALL(side1) && IS_WALL(side2) && IS_WALL(side1f) && IS_WALL(side2f)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of tunnel\n", i, move_name[j], k); continue; // keep searching forwards } if (BLOCKED(front)) { // Check for box-box deadlock // Check for 4 boxes with at least one not standing on a goal // Wall or box not on goal // ** // *$ if ( BLOCKED(side1) && BLOCKED(side1f) && (POSCOST(p) > 0 || POSCOST(side1) > 0 || POSCOST(side1f) > 0 || POSCOST(front) > 0 ) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of 4box-deadlock\n", i, move_name[j], k); break; } if ( BLOCKED(side2) && BLOCKED(side2f) && (POSCOST(p) > 0 || POSCOST(side2) > 0 || POSCOST(side2f) > 0 || POSCOST(front) > 0 ) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of 4box-deadlock\n", i, move_name[j], k); break; } // Check for S-deadlock // # // @$$ // # if ( (POSCOST(p) > 0 || POSCOST(front) > 0) && ((IS_WALL(side1) && IS_WALL(side2f)) || (IS_WALL(side2) && IS_WALL(side1f))) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } // Check for S-deadlock // # // $$ // @# if (IS_WALL(front)) { if ( BLOCKED(side1) && IS_WALL(side1b) && (POSCOST(p) > 0 || POSCOST(side1) > 0) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } if ( BLOCKED(side2) && IS_WALL(side2b) && (POSCOST(p) > 0 || POSCOST(side2) > 0) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of S-deadlock\n", i, move_name[j], k); break; } } } // Check for "elliptic" deadlock // Corner deadlock is a special case of elliptic deadlock // $$ ### // $ $ # $ // $$ #$ if (BLOCKED(front)) { // Test for corner position // @$$ // $ $ // $$ if (level.ValidPosition(side1f+(side1f-p)) && !BLOCKED(side1f) && BLOCKED(side1) && BLOCKED(side1f+(side1-p)) && BLOCKED(side1f+(side1f-p)) && BLOCKED(side1f+(front-p)) && (!EllipseOK(side1f) || (POSCOST(p) != 0 && POSCOST(side1f) != 0))) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (level.ValidPosition(side2f+(side2f-p)) && !BLOCKED(side2f) && BLOCKED(side2) && BLOCKED(side2f+(side2-p)) && BLOCKED(side2f+(side2f-p)) && BLOCKED(side2f+(front-p)) && (!EllipseOK(side2f) || (POSCOST(side2f) != 0 && POSCOST(p) != 0))) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } // Test for // $$ // $ $ //->@$$ if (level.ValidPosition(side1+(side1f-p)) && !BLOCKED(side1) && BLOCKED(side1-(front-p)) && BLOCKED(side1f) && BLOCKED(side1+(side1-p)) && BLOCKED(side1+(side1-p)-(front-p)) && (!EllipseOK(side1) )) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (level.ValidPosition(side2+(side2f-p)) && !BLOCKED(side2) && BLOCKED(side2-(front-p)) && BLOCKED(side2f) && BLOCKED(side2+(side2-p)) && BLOCKED(side2+(side2-p)-(front-p)) && (!EllipseOK(side2) )) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } } // Test for center position // $$ // @$ $ // $$ if (level.ValidPosition(front+(front-p)) && !BLOCKED(front) && BLOCKED(front+(front-p)) && BLOCKED(side1f) && BLOCKED(side2f) ) { if (BLOCKED(side1) && BLOCKED(side2f+(front-p)) && !EllipseOK(front)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } if (BLOCKED(side2) && BLOCKED(side1f+(front-p)) && !EllipseOK(front)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of elliptic deadlock\n", i, move_name[j], k); break; } } // Check for diamond deadlock // # // #-# // -$- if (POSCOST(p) != 0 && POSCOST(front) < 0 && POSCOST(side1) < 0 && POSCOST(side2) < 0 && IS_WALL(frontf) && IS_WALL(side1f) && IS_WALL(side2f) ) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of diamond deadlock\n", i, move_name[j], k); break; } int new_free_goals = free_goals; if (POSCOST(p) == 0) // On goal { // If this box is immobilized over a goal // Make sure that every free box can reach a free goal // @*# // # if ( IS_WALL(front) && (IS_WALL(side1) || IS_WALL(side2))) new_free_goals &= ~(1<<level.GetGoalAt(p)); // @** // ** if ( BLOCKED(front) && POSCOST(front) <= 0 && ((BLOCKED(side1) && POSCOST(side1) <= 0 && BLOCKED(side1f) && POSCOST(side1f) <= 0) || (BLOCKED(side2) && POSCOST(side2) <= 0 && BLOCKED(side2f) && POSCOST(side2f) <= 0)) ) { new_free_goals &= ~(1<<level.GetGoalAt(p)) & ~(1<<level.GetGoalAt(front)); if (BLOCKED(side1) && POSCOST(side1) <= 0 && BLOCKED(side1f) && POSCOST(side1f) <= 0) { new_free_goals &= ~(1<<level.GetGoalAt(side1)); new_free_goals &= ~(1<<level.GetGoalAt(side1f)); if (level.ValidPosition(frontf) && BLOCKED(frontf) && POSCOST(frontf) <= 0 && level.ValidPosition(side1ff) && BLOCKED(side1ff) && POSCOST(side1ff) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(frontf)) & ~(1<<level.GetGoalAt(side1ff)); if (level.ValidPosition(side11) && BLOCKED(side11) && POSCOST(side11) <= 0 && level.ValidPosition(side11f) && BLOCKED(side11f) && POSCOST(side11f) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(side11)) & ~(1<<level.GetGoalAt(side11f)); } if (BLOCKED(side2) && POSCOST(side2) <= 0 && BLOCKED(side2f) && POSCOST(side2f) <= 0) { new_free_goals &= ~(1<<level.GetGoalAt(side2)); new_free_goals &= ~(1<<level.GetGoalAt(side2f)); if (level.ValidPosition(frontf) && BLOCKED(frontf) && POSCOST(frontf) <= 0 && level.ValidPosition(side2ff) && BLOCKED(side2ff) && POSCOST(side2ff) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(frontf)) & ~(1<<level.GetGoalAt(side2ff)); if (level.ValidPosition(side22) && BLOCKED(side22) && POSCOST(side22) <= 0 && level.ValidPosition(side22f) && BLOCKED(side22f) && POSCOST(side22f) <= 0) new_free_goals &= ~(1<<level.GetGoalAt(side22)) & ~(1<<level.GetGoalAt(side22f)); } bool bad_move = false; for (int b=0; b < num_boxes; ++b) { if (b==i) continue; if ( POSCOST(boxes[b]) != 0 && (scribble->GoalsReachable(boxes[b]) & new_free_goals) == 0 ) { Position delta = p-boxes[i]; PRINT_VERBOSE("box %d will be unable to reach any goal if box %d is moved (%d,%d)\n", b, i, delta.x, delta.y); // this is not an ok move bad_move = true; break; } } if (bad_move) break; } } SokobanState *s = new SokobanState(*this, i, move_name[j], k, new_free_goals); if (s->Cost() == unsigned(-1)) { PRINT_VERBOSE("disregards moving box %d %c %d steps because of negative cost of new state\n", i, move_name[j], k); delete s; s = NULL; break; } moves_to_add.push_back(s); PRINT_VERBOSE("added move of box %d %c %d steps\n", i, move_name[j], k); } } }
int main(int argc, char **argv) { int i, found; struct sockaddr_in clientaddr; socklen_t sin_size = sizeof(clientaddr); struct sigaction signalaction, sigint_action; sigset_t sigset; char buf[MAXLEN]; int c; char* busses_string; #ifdef HAVE_LIBCONFIG config_t config; #endif /* set default config settings */ port = PORT; description = malloc(sizeof(BEACON_DESCRIPTION)); strcpy(description, BEACON_DESCRIPTION); interface_string = malloc(strlen("eth0")+ 1); strcpy(interface_string, "eth0"); busses_string = malloc(strlen("vcan0")+ 1); strcpy(busses_string, "vcan0"); #ifdef HAVE_LIBCONFIG /* Read config file before parsing commandline arguments */ config_init(&config); if(CONFIG_TRUE == config_read_file(&config, "/etc/socketcand.conf")) { config_lookup_int(&config, "port", (long int*) &port); config_lookup_string(&config, "description", (const char**) &description); config_lookup_string(&config, "busses", (const char**) &busses_string); config_lookup_string(&config, "listen", (const char**) &interface_string); } #endif /* Parse commandline arguments */ while (1) { /* getopt_long stores the option index here. */ int option_index = 0; static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"interfaces", required_argument, 0, 'i'}, {"port", required_argument, 0, 'p'}, {"listen", required_argument, 0, 'l'}, {"daemon", no_argument, 0, 'd'}, {"version", no_argument, 0, 'z'}, {"no-beacon", no_argument, 0, 'n'}, {0, 0, 0, 0} }; c = getopt_long (argc, argv, "vhni:p:l:d", long_options, &option_index); if (c == -1) break; switch (c) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; break; case 'v': puts ("Verbose output activated\n"); verbose_flag = 1; break; case 'p': port = atoi(optarg); break; case 'i': busses_string = realloc(busses_string,strlen(optarg)); strcpy(busses_string, optarg); break; case 'l': interface_string = realloc(interface_string, strlen(optarg)); strcpy(interface_string, optarg); break; case 'h': print_usage(); return 0; case 'd': daemon_flag=1; break; case 'z': printf("socketcand version '%s'\n", PACKAGE_VERSION); return 0; case 'n': disable_beacon=1; break; case '?': print_usage(); return 0; default: print_usage(); return -1; } } /* parse busses */ for(i=0;;i++) { if(busses_string[i] == '\0') break; if(busses_string[i] == ',') interface_count++; } interface_count++; interface_names = malloc(sizeof(char *) * interface_count); interface_names[0] = strtok(busses_string, ","); for(i=1;i<interface_count;i++) { interface_names[i] = strtok(NULL, ","); } /* if daemon mode was activated the syslog must be opened */ if(daemon_flag) { openlog("socketcand", 0, LOG_DAEMON); } sigemptyset(&sigset); signalaction.sa_handler = &childdied; signalaction.sa_mask = sigset; signalaction.sa_flags = 0; sigaction(SIGCHLD, &signalaction, NULL); /* signal for dying child */ sigint_action.sa_handler = &sigint; sigint_action.sa_mask = sigset; sigint_action.sa_flags = 0; sigaction(SIGINT, &sigint_action, NULL); if((sl = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("inetsocket"); exit(1); } #ifdef DEBUG if(verbose_flag) printf("setting SO_REUSEADDR\n"); i = 1; if(setsockopt(sl, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) <0) { perror("setting SO_REUSEADDR failed"); } #endif determine_adress(); if(!disable_beacon) { PRINT_VERBOSE("creating broadcast thread...\n") i = pthread_create(&beacon_thread, NULL, &beacon_loop, NULL); if(i) PRINT_ERROR("could not create broadcast thread.\n"); } else { PRINT_VERBOSE("Discovery beacon disabled\n"); } PRINT_VERBOSE("binding socket to %s:%d\n", inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)) if(bind(sl,(struct sockaddr*)&saddr, sizeof(saddr)) < 0) { perror("bind"); exit(-1); } if (listen(sl,3) != 0) { perror("listen"); exit(1); } while (1) { client_socket = accept(sl,(struct sockaddr *)&clientaddr, &sin_size); if (client_socket > 0 ){ int flag; flag = 1; setsockopt(client_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag)); if (fork()) close(client_socket); else break; } else { if (errno != EINTR) { /* * If the cause for the error was NOT the * signal from a dying child => give an error */ perror("accept"); exit(1); } } } PRINT_VERBOSE("client connected\n") #ifdef DEBUG PRINT_VERBOSE("setting SO_REUSEADDR\n") i = 1; if(setsockopt(client_socket, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)) <0) { perror("setting SO_REUSEADDR failed"); } #endif /* main loop with state machine */ while(1) { switch(state) { case STATE_NO_BUS: if(previous_state != STATE_NO_BUS) { strcpy(buf, "< hi >"); send(client_socket, buf, strlen(buf), 0); previous_state = STATE_NO_BUS; } /* client has to start with a command */ i = receive_command(client_socket, (char *) &buf); if(i != 0) { PRINT_ERROR("Connection terminated while waiting for command.\n"); state = STATE_SHUTDOWN; break; } if(!strncmp("< open ", buf, 7)) { sscanf(buf, "< open %s>", bus_name); /* check if access to this bus is allowed */ found = 0; for(i=0;i<interface_count;i++) { if(!strcmp(interface_names[i], bus_name)) found = 1; } if(found) { strcpy(buf, "< ok >"); send(client_socket, buf, strlen(buf), 0); state = STATE_BCM; break; } else { PRINT_INFO("client tried to access unauthorized bus.\n"); strcpy(buf, "< error could not open bus >"); send(client_socket, buf, strlen(buf), 0); state = STATE_SHUTDOWN; } } else { PRINT_ERROR("unknown command '%s'.\n", buf) strcpy(buf, "< error unknown command >"); send(client_socket, buf, strlen(buf), 0); } break; case STATE_BCM: state_bcm(); break; case STATE_RAW: state_raw(); break; case STATE_CONTROL: state_control(); break; case STATE_SHUTDOWN: PRINT_VERBOSE("Closing client connection.\n"); close(client_socket); return 0; } } return 0; }
/* reads all available data from the socket into the command buffer. * returns '-1' if no command could be received. */ int receive_command(int socket, char *buffer) { int i, start, stop; /* if there are no more elements in the buffer read more data from the * socket. */ if(!more_elements) { cmd_index += read(socket, cmd_buffer+cmd_index, MAXLEN-cmd_index); #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tRead from socket\n"); #endif } #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tcmd_index now %d\n", cmd_index); #endif more_elements = 0; /* find first '<' in string */ start = -1; for(i=0;i<cmd_index;i++) { if(cmd_buffer[i] == '<') { start = i; break; } } /* * if there is no '<' in string it makes no sense to keep data because * we will never be able to construct a command of it */ if(start == -1) { cmd_index = 0; #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tBad data. No element found\n"); #endif return -1; } /* check whether the command is completely in the buffer */ stop = -1; for(i=1;i<cmd_index;i++) { if(cmd_buffer[i] == '>') { stop = i; break; } } /* if no '>' is in the string we have to wait for more data */ if(stop == -1) { #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tNo full element in the buffer\n"); #endif return -1; } #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tElement between %d and %d\n", start, stop); #endif /* copy string to new destination and correct cmd_buffer */ for(i=start;i<=stop;i++) { buffer[i-start] = cmd_buffer[i]; } buffer[i-start] = '\0'; #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tElement is '%s'\n", buffer); #endif /* if only this message was in the buffer we're done */ if(stop == cmd_index-1) { cmd_index = 0; } else { /* check if there is a '<' after the stop */ start = -1; for(i=stop;i<cmd_index;i++) { if(cmd_buffer[i] == '<') { start = i; break; } } /* if there is none it is only garbage we can remove */ if(start == -1) { cmd_index = 0; #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tGarbage after the first element in the buffer\n"); #endif return 0; /* otherwise we copy the valid data to the beginning of the buffer */ } else { for(i=start;i<cmd_index;i++) { cmd_buffer[i-start] = cmd_buffer[i]; } cmd_index -= start; /* check if there is at least one full element in the buffer */ stop = -1; for(i=1;i<cmd_index;i++) { if(cmd_buffer[i] == '>') { stop = i; break; } } if(stop != -1) { more_elements = 1; #ifdef DEBUG_RECEPTION PRINT_VERBOSE("\tMore than one full element in the buffer.\n"); #endif } } } return 0; }
static size_t curl_header_cb(void *ptr, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; struct Proxy *proxy = (struct Proxy *)userp; char *line = (char *)ptr; char *name; char *value; char *status; int i; int pos; int ret; int num_values; const char * const * values; bool abort_it; //printf("curl_header_cb %s\n", line); if(!*(proxy->session_alive)) { PRINT_VERBOSE("headers received, but session is dead"); return 0; } //trailer if(NULL != proxy->response) return 0; if('\r' == line[0]) { //all headers were already handled; prepare spdy frames if(NULL == (proxy->response = SPDY_build_response_with_callback(proxy->status, proxy->status_msg, proxy->version, proxy->headers, &response_callback, proxy, 0))) DIE("no response"); SPDY_name_value_destroy(proxy->headers); free(proxy->status_msg); free(proxy->version); if(SPDY_YES != SPDY_queue_response(proxy->request, proxy->response, true, false, &response_done_callback, proxy)) DIE("no queue"); call_spdy_run = true; return realsize; } pos = 0; if(NULL == proxy->version) { //first line from headers //version for(i=pos; i<realsize && ' '!=line[i]; ++i); if(i == realsize) DIE("error on parsing headers"); if(NULL == (proxy->version = strndup(line, i - pos))) DIE("No memory"); pos = i+1; //status (number) for(i=pos; i<realsize && ' '!=line[i] && '\r'!=line[i]; ++i); if(NULL == (status = strndup(&(line[pos]), i - pos))) DIE("No memory"); proxy->status = atoi(status); free(status); if(i<realsize && '\r'!=line[i]) { //status (message) pos = i+1; for(i=pos; i<realsize && '\r'!=line[i]; ++i); if(NULL == (proxy->status_msg = strndup(&(line[pos]), i - pos))) DIE("No memory"); } PRINT_VERBOSE2("Header line received '%s' '%i' '%s' ", proxy->version, proxy->status, proxy->status_msg); return realsize; } //other lines //header name for(i=pos; i<realsize && ':'!=line[i] && '\r'!=line[i]; ++i) line[i] = tolower(line[i]); //spdy requires lower case if(NULL == (name = strndup(line, i - pos))) DIE("No memory"); if(0 == strcmp(SPDY_HTTP_HEADER_CONNECTION, name) || 0 == strcmp(SPDY_HTTP_HEADER_KEEP_ALIVE, name) || 0 == strcmp(SPDY_HTTP_HEADER_TRANSFER_ENCODING, name) ) { //forbidden in spdy, ignore free(name); return realsize; } if(i == realsize || '\r'==line[i]) { //no value. is it possible? if(SPDY_YES != SPDY_name_value_add(proxy->headers, name, "")) DIE("SPDY_name_value_add failed"); return realsize; } //header value pos = i+1; while(pos<realsize && isspace(line[pos])) ++pos; //remove leading space for(i=pos; i<realsize && '\r'!=line[i]; ++i); if(NULL == (value = strndup(&(line[pos]), i - pos))) DIE("No memory"); PRINT_VERBOSE2("Adding header: '%s': '%s'", name, value); if(SPDY_YES != (ret = SPDY_name_value_add(proxy->headers, name, value))) { abort_it=true; if(NULL != (values = SPDY_name_value_lookup(proxy->headers, name, &num_values))) for(i=0; i<num_values; ++i) if(0 == strcasecmp(value, values[i])) { abort_it=false; PRINT_INFO2("header appears more than once with same value '%s: %s'", name, value); break; } if(abort_it) { PRINT_INFO2("SPDY_name_value_add failed (%i) for '%s'", ret, name); abort(); } } free(name); free(value); return realsize; }
/* Function: rt_PktServerWork ================================================== * Abstract: * If not connected, establish communication of the packet line and the * data upload line. If connected, send/receive packets and parameters * on the packet line. */ PUBLIC void rt_PktServerWork( RTWExtModeInfo *ei, int_T numSampTimes, boolean_T *stopReq) { PktHeader pktHdr; boolean_T hdrAvail; boolean_T error = EXT_NO_ERROR; boolean_T disconnectOnError = FALSE; pktServerArgT *pktServerArg; /* * If not connected, attempt to make connection to host. */ if (!connected) { rtExtModeTestingKillIfOrphaned(FALSE); error = ExtOpenConnection(extUD,&connected); if (error != EXT_NO_ERROR) goto EXIT_POINT; } /* * If ExtOpenConnection is not blocking and there are no pending * requests to open a connection, we'll still be unconnected. */ if (!connected) goto EXIT_POINT; /* nothing to do */ /* * Process packets. */ /* Wait for a packet. */ error = GetPktHdr(&pktHdr, &hdrAvail); if (error != EXT_NO_ERROR) { fprintf(stderr, "\nError occurred getting packet header.\n"); disconnectOnError = TRUE; goto EXIT_POINT; } rtExtModeTestingKillIfOrphaned(hdrAvail); if (!hdrAvail) goto EXIT_POINT; /* nothing to do */ /* * This is the first packet. Should contain the string: * 'ext-mode'. Its contents are not important to us. * It is used as a flag to start the handshaking process. */ if (!commInitialized) { pktHdr.type = EXT_CONNECT; } /* * At this point we know that we have a packet: process it. */ #ifdef QNX_OS //taskSafe(); #endif switch(pktHdr.type) { case EXT_GET_TIME: { /* Skip verbosity print out - we get too many of these */ /*PRINT_VERBOSE(("got EXT_GET_TIME packet.\n"));*/ time_T t = rteiGetT(ei); error = SendPktToHost( EXT_GET_TIME_RESPONSE,sizeof(time_T), (char_T *)&t); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_ARM_TRIGGER: { error = ProcessArmTriggerPkt(pktHdr.size,numSampTimes); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_SELECT_SIGNALS: { error = ProcessSelectSignalsPkt(ei,numSampTimes,pktHdr.size); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_SELECT_TRIGGER: { error = ProcessSelectTriggerPkt(ei,pktHdr.size); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_CONNECT: { PRINT_VERBOSE(("got EXT_CONNECT packet.\n")); error = ProcessConnectPkt(ei); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_SETPARAM: { PRINT_VERBOSE(("got EXT_SETPARAM packet.\n")); error = ProcessSetParamPkt(ei, pktHdr.size); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_GETPARAMS: { PRINT_VERBOSE(("got EXT_GETPARAMS packet.\n")); error = ProcessGetParamsPkt(ei); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_DISCONNECT_REQUEST: { PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST packet.\n")); /* * Note that from the target's point of view this is * more a "notify" than a "request". The host needs to * have this acknowledged before it can begin closing * the connection. */ error = SendPktToHost(EXT_DISCONNECT_REQUEST_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; DisconnectFromHost(numSampTimes); break; } case EXT_DISCONNECT_REQUEST_NO_FINAL_UPLOAD: { PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST_NO_FINAL_UPLOAD packet.\n")); /* * The target receives this packet when the host is * immediately terminating the extmode communication due * to some error. The target should not send back a * response or a final upload of data because the host is * expecting neither. The target must be disconnected and * returned to a state where it is running and can be * re-connected to by the host. */ ForceDisconnectFromHost(numSampTimes); break; } case EXT_MODEL_START: PRINT_VERBOSE(("got EXT_MODEL_START packet.\n")); #ifdef QNX_OS { extern sem_t* startStopSem; sem_post(startStopSem); } #endif startModel = TRUE; error = SendPktToHost(EXT_MODEL_START_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_STOP: PRINT_VERBOSE(("got EXT_MODEL_STOP packet.\n")); *stopReq = TRUE; break; case EXT_MODEL_PAUSE: PRINT_VERBOSE(("got EXT_MODEL_PAUSE packet.\n")); modelStatus = TARGET_STATUS_PAUSED; startModel = FALSE; error = SendPktToHost(EXT_MODEL_PAUSE_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_STEP: PRINT_VERBOSE(("got EXT_MODEL_STEP packet.\n")); if ((modelStatus == TARGET_STATUS_PAUSED) && !startModel) { startModel = TRUE; } error = SendPktToHost(EXT_MODEL_STEP_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_CONTINUE: PRINT_VERBOSE(("got EXT_MODEL_CONTINUE packet.\n")); if (modelStatus == TARGET_STATUS_PAUSED) { modelStatus = TARGET_STATUS_RUNNING; startModel = FALSE; } error = SendPktToHost(EXT_MODEL_CONTINUE_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_CANCEL_LOGGING: { error = ProcessCancelLoggingPkt(pktHdr.size); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } default: fprintf(stderr,"received invalid packet.\n"); break; } /* end switch */ EXIT_POINT: if (error != EXT_NO_ERROR) { if (disconnectOnError) { fprintf(stderr, "Error occurred in rt_PktServerWork.\n" "Disconnecting from host!\n"); /* An error in this function which causes disconnectOnError to be * set to true is caused by a physical failure in the external mode * connection. We assume this failure caused the host to disconnect. * The target must be disconnected and returned to a state * where it is running and can be re-connected to by the host. */ ForceDisconnectFromHost(numSampTimes); } } #ifdef VXWORKS //taskUnsafe(); #endif } /* end rt_PktServerWork */
/* Function: rt_MsgServerWork ================================================== * Abstract: * If not connected, establish communication of the message line and the * data upload line. If connected, send/receive messages and parameters * on the message line. */ PUBLIC boolean_T rt_MsgServerWork(SimStruct *S) { MsgHeader msgHdr; boolean_T hdrAvail; boolean_T error = EXT_NO_ERROR; boolean_T disconnectOnError = FALSE; /* * If not connected, attempt to make connection to host. */ if (!connected) { error = ExtOpenConnection(extUD,&connected); if (error != EXT_NO_ERROR) goto EXIT_POINT; } /* * If ExtOpenConnection is not blocking and there are no pending * requests to open a connection, we'll still be unconnected. */ if (!connected) goto EXIT_POINT; /* nothing do do */ /* * Process messages. */ /* Wait for a message. */ error = GetMsgHdr(&msgHdr, &hdrAvail); if (error != EXT_NO_ERROR) { printf("\nError occured getting message header.\n"); disconnectOnError = TRUE; goto EXIT_POINT; } if (!hdrAvail) goto EXIT_POINT; /* nothing to do */ /* * This is the first message. Should contain the string: * 'ext-mode'. Its contents are not important to us. * It is used as a flag to start the handshaking process. */ if (!commInitialized) { msgHdr.type = EXT_CONNECT; } /* * At this point we know that we have a message: process it. */ switch(msgHdr.type) { case EXT_GET_TIME: { time_T t = ssGetT(S); /* Skip verbosity print out - we get too many of these */ /*PRINT_VERBOSE(("got EXT_GET_TIME message.\n"));*/ error = SendMsgToHost( EXT_GET_TIME_RESPONSE,sizeof(time_T),(char_T *)&t); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_ARM_TRIGGER: { PRINT_VERBOSE(("got EXT_ARM_TRIGGER message.\n")); UploadArmTrigger(); break; } case EXT_SELECT_SIGNALS: { const char *msg; PRINT_VERBOSE(("got EXT_SELECT_SIGNALS message.\n")); msg = GetMsg(msgHdr.size); if (msg == NULL) { error = EXT_ERROR; goto EXIT_POINT; } error = UploadLogInfoInit(S, msg); if (error != NO_ERR) { printf( "\nError in UploadLogInfoInit(). Most likely a memory\n" "allocation error or an attempt to re-initialize the\n" "signal selection during the data logging process\n" "(i.e., multiple EXT_SELECT_SIGNAL messages were received\n" "before the logging session terminated or an\n" "EXT_CANCEL_LOGGING message was received)"); goto EXIT_POINT; } break; } case EXT_SELECT_TRIGGER: { const char *msg; PRINT_VERBOSE(("got EXT_SELECT_TRIGGER message.\n")); msg = GetMsg(msgHdr.size); if (msg == NULL) { error = EXT_ERROR; goto EXIT_POINT; } error = UploadInitTrigger(S, msg); if (error != EXT_NO_ERROR) { printf("\nError in UploadInitTrigger\n"); goto EXIT_POINT; } break; } case EXT_CONNECT: { PRINT_VERBOSE(("got EXT_CONNECT message.\n")); error = ProcessConnectMsg(S); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_SETPARAM: { PRINT_VERBOSE(("got EXT_SETPARAM message.\n")); error = ProcessSetParamMsg(S, msgHdr.size); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_GETPARAMS: { PRINT_VERBOSE(("got EXT_GETPARAMS message.\n")); error = ProcessGetParamsMsg(S); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; } case EXT_DISCONNECT_REQUEST: { PRINT_VERBOSE(("got EXT_DISCONNECT_REQUEST message.\n")); /* * Note that from the target's point of view this is * more a "notify" than a "request". The host needs to * have this acknowledged before it can begin closing * the connection. */ error = SendMsgToHost(EXT_DISCONNECT_REQUEST_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; DisconnectFromHost(S); break; } case EXT_MODEL_START: PRINT_VERBOSE(("got EXT_MODEL_START message.\n")); #ifdef VXWORKS { extern SEM_ID startStopSem; semGive(startStopSem); } #endif startModel = TRUE; error = SendMsgToHost(EXT_MODEL_START_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_STOP: PRINT_VERBOSE(("got EXT_MODEL_STOP message.\n")); ssSetStopRequested(S, TRUE); break; case EXT_MODEL_PAUSE: PRINT_VERBOSE(("got EXT_MODEL_PAUSE message.\n")); modelStatus = TARGET_STATUS_PAUSED; startModel = FALSE; error = SendMsgToHost(EXT_MODEL_PAUSE_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_STEP: PRINT_VERBOSE(("got EXT_MODEL_STEP message.\n")); if ((modelStatus == TARGET_STATUS_PAUSED) && !startModel) { startModel = TRUE; } error = SendMsgToHost(EXT_MODEL_STEP_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_MODEL_CONTINUE: PRINT_VERBOSE(("got EXT_MODEL_CONTINUE message.\n")); if (modelStatus == TARGET_STATUS_PAUSED) { modelStatus = TARGET_STATUS_RUNNING; startModel = FALSE; } error = SendMsgToHost(EXT_MODEL_CONTINUE_RESPONSE, 0, NULL); if (error != EXT_NO_ERROR) goto EXIT_POINT; break; case EXT_CANCEL_LOGGING: PRINT_VERBOSE(("got EXT_CANCEL_LOGGING message.\n")); UploadCancelLogging(); break; default: fprintf(stderr,"received invalid message.\n"); break; } /* end switch */ EXIT_POINT: if (error != EXT_NO_ERROR) { if (disconnectOnError) { fprintf(stderr, "Error occured in rt_MsgServerWork.\n" "Disconnecting from host!\n"); DisconnectFromHost(S); /* * Patch by Gopal Santhanam 5/25/2002 (for VXWORKS) * If there there was a problem and we have already disconnected * from the host, there is no point in returning that error * back to rt_MsgServer. That would cause the task servicing * external messages to quit. Once disconnected, we could * just as easily resume by waiting for a new connection. */ #ifdef VXWORKS error = EXT_NO_ERROR; #endif } } return(error); } /* end rt_MsgServerWork */