static void* connection_handler(void* data) { socket_info_t* socket_info = (socket_info_t*)data; thread_t ctod; debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); /* spawn client to device thread */ socket_info->stop_ctod = 0; if (thread_create(&ctod, thread_client_to_device, data) != 0) { fprintf(stderr, "Failed to start client to device thread...\n"); } /* join the fun */ thread_join(ctod); /* shutdown client socket */ socket_shutdown(socket_info->client_fd, SHUT_RDWR); socket_close(socket_info->client_fd); /* shutdown server socket if we have to terminate to unblock the server loop */ if (quit_flag) { socket_shutdown(socket_info->server_fd, SHUT_RDWR); socket_close(socket_info->server_fd); } return NULL; }
/** Terminate sources. * * Close listening Sockets and shutdown() others * * XXX: This function is not very efficient (going through the linked list of * channels and repeatedly calling functions which do the same), but it's only * used for cleanup, so it should be fine. * * \see eventloop_stop */ static void terminate_fds(void) { Channel *ch = self.channels, *next; while (ch != NULL) { next = ch->next; o_log(O_LOG_DEBUG4, "EventLoop: Terminating channel %s\n", ch->name); if (!ch->is_active || socket_is_disconnected(ch->socket) || socket_is_listening(ch->socket)) { o_log(O_LOG_DEBUG3, "EventLoop: Releasing listening channel %s\n", ch->name); eventloop_socket_release((SockEvtSource*)ch); } else if (self.force_stop) { o_log(O_LOG_DEBUG3, "EventLoop: Closing down %s\n", ch->name); eventloop_socket_release((SockEvtSource*)ch); socket_close(ch->socket); } else { o_log(O_LOG_DEBUG3, "EventLoop: Shutting down %s\n", ch->name); socket_shutdown(ch->socket); ch->is_shutting_down = 1; } ch = next; } update_fds(); }
/* UNIX local-domain socket module invocation ********************************/ unsigned cvm_xfer_local_packets(const char* path, const struct cvm_packet* request, struct cvm_packet* response) { int sock; int result; unsigned io; unsigned done; unsigned len; result = CVME_IO; response->length = 0; if ((sock = socket_unixstr()) != -1 && socket_connectu(sock, path)) { for (done = 0, len = request->length; done < len; done += io) { if ((io = write(sock, request->data+done, len-done)) == 0) break; if (io == (unsigned)-1) break; } socket_shutdown(sock, 0, 1); if (done >= len) { for (done = 0; done < CVM_BUFSIZE; done += io) { if ((io = read(sock, response->data+done, CVM_BUFSIZE-done)) == 0) break; if (io == (unsigned)-1) done = CVM_BUFSIZE+1; } if (done <= CVM_BUFSIZE) { response->length = done; result = 0; } } } close(sock); return result; }
static int STDCALL http_server_thread(void* param) { char req[1024] = {0}; bool* running = (bool*)param; socket_t socket = tcpserver_create(NULL, PORT, 32); while(*running) { int r = socket_select_read(socket, 1000); if(1 == r) { struct sockaddr_in in4; socklen_t len = sizeof(in4); socket_t client = socket_accept(socket, (sockaddr*)&in4, &len); if(client != socket_invalid) { r = socket_recv_by_time(client, req, sizeof(req), 0, 5000); r = socket_send_all_by_time(client, s_reply, strlen(s_reply), 0, 5000); r = socket_shutdown(client, SHUT_RDWR); r = socket_close(client); printf("server side close socket\n"); } } } return 0; }
// socket-shutdown scm_obj_t subr_socket_shutdown(VM* vm, int argc, scm_obj_t argv[]) { if (argc == 2) { if (SOCKETP(argv[0])) { if (FIXNUMP(argv[1])) { intptr_t how = FIXNUM(argv[1]); if (how >= 0 && how <= 2) { try { socket_shutdown((scm_socket_t)argv[0], FIXNUM(argv[1])); return scm_unspecified; } catch (io_exception_t& e) { raise_io_error(vm, "socket-shutdown", e.m_operation, e.m_message, e.m_err, argv[0], scm_false); return scm_undef; } } } wrong_type_argument_violation(vm, "socket-shutdown", 1, "0, 1, or 2", argv[1], argc, argv); return scm_undef; } wrong_type_argument_violation(vm, "socket-shutdown", 0, "socket", argv[0], argc, argv); return scm_undef; } wrong_number_of_arguments_violation(vm, "socket-shutdown", 2, 2, argc, argv); return scm_undef; }
void JNL_Connection::close(int quick) { if (quick || m_state == STATE_RESOLVING || m_state == STATE_CONNECTING) { m_state=STATE_CLOSED; /* ** Joshua Teitelbaum 1/27/2006 ** virualization for ssl */ socket_shutdown(); m_socket=-1; memset(m_recv_buffer,0,m_recv_buffer_len); memset(m_send_buffer,0,m_send_buffer_len); m_remote_port=0; m_recv_len=m_recv_pos=0; m_send_len=m_send_pos=0; m_host[0]=0; memset(m_saddr,0,sizeof(m_saddr)); } else { if (m_state == STATE_CONNECTED) m_state=STATE_CLOSING; } }
/* ** err = sock.shutdown(fd, shut=sock.SHUT_RDWR) */ static int lsocket_shutdown(lua_State *L) { int fd = luaL_checkint(L, 1); int how = luaL_optint(L, 2, SHUT_RDWR); int err = socket_shutdown(fd, how); lua_pushinteger(L, err); return 1; }
/*-------------------------------------------------------------------------*\ * Shuts the connection down partially \*-------------------------------------------------------------------------*/ static int meth_shutdown(lua_State *L) { /* SHUT_RD, SHUT_WR, SHUT_RDWR have the value 0, 1, 2, so we can use method index directly */ static const char* methods[] = { "receive", "send", "both", NULL }; p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); int how = luaL_checkoption(L, 2, "both", methods); socket_shutdown(&tcp->sock, how); lua_pushnumber(L, 1); return 1; }
static void *thread_device_to_client(void *data) { socket_info_t* socket_info = (socket_info_t*)data; idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR; int recv_len; int sent; char buffer[131072]; debug("%s: started thread...\n", __func__); debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); debug("%s: server fd = %d\n", __func__, socket_info->server_fd); while (!quit_flag && !socket_info->stop_dtoc && socket_info->client_fd > 0 && socket_info->server_fd > 0) { debug("%s: receiving data from device...\n", __func__); res = idevice_connection_receive_timeout(socket_info->device_connection, buffer, sizeof(buffer), (uint32_t*)&recv_len, 5000); if (recv_len <= 0) { if (recv_len == 0 && res == IDEVICE_E_SUCCESS) { // try again continue; } else { fprintf(stderr, "recv failed: %s\n", strerror(errno)); break; } } else { /* send to device */ debug("%s: sending data to client...\n", __func__); sent = socket_send(socket_info->client_fd, buffer, recv_len); if (sent < recv_len) { if (sent <= 0) { fprintf(stderr, "send failed: %s\n", strerror(errno)); break; } else { fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len); } } else { // sending succeeded, receive from device debug("%s: pushed %d bytes to client\n", __func__, sent); } } } debug("%s: shutting down...\n", __func__); socket_shutdown(socket_info->client_fd, SHUT_RDWR); socket_close(socket_info->client_fd); socket_info->client_fd = -1; socket_info->stop_ctod = 1; return NULL; }
void ExitClient(int errcode) { if (socket_shutdown(mypid) == -1) printf("PANIC: unable to shutdown socket\n"); unlink(cpath); fflush(stdout); fflush(stdin); if (pbuff) free(pbuff); exit(errcode); }
int ksocket_shutdown(ksocket_t ks, int how, struct cred *cr) { struct sonode *so; /* All Solaris components should pass a cred for this operation. */ ASSERT(cr != NULL); if (!KSOCKET_VALID(ks)) return (ENOTSOCK); so = KSTOSO(ks); return (socket_shutdown(so, how, cr)); }
/*-------------------------------------------------------------------------*\ * Shuts the connection down partially \*-------------------------------------------------------------------------*/ static int meth_shutdown(lua_State *L) { p_tcp tcp = (p_tcp) auxiliar_checkclass(L, "tcp{client}", 1); const char *how = luaL_optstring(L, 2, "both"); switch (how[0]) { case 'b': if (strcmp(how, "both")) goto error; socket_shutdown(&tcp->sock, 2); break; case 's': if (strcmp(how, "send")) goto error; socket_shutdown(&tcp->sock, 1); break; case 'r': if (strcmp(how, "receive")) goto error; socket_shutdown(&tcp->sock, 0); break; } lua_pushnumber(L, 1); return 1; error: luaL_argerror(L, 2, "invalid shutdown method"); return 0; }
void gwlib_shutdown(void) { gwlib_assert_init(); charset_shutdown(); http_shutdown(); socket_shutdown(); gwthread_shutdown(); octstr_shutdown(); gwlib_protected_shutdown(); uuid_shutdown(); cfg_shutdown(); gw_check_leaks(); log_shutdown(); gwmem_shutdown(); init = 0; }
JNL_Connection::~JNL_Connection() { /* ** Joshua Teitelbaum 1/27/2006 ** virtualization for ssl, calling socket_shtudown() */ socket_shutdown(); free(m_recv_buffer); free(m_send_buffer); if (m_dns_owned) { delete m_dns; } delete m_saddr; }
int main() { if (!socket_init()) return -1; ncurses_init(); ncurses_print("Welcome to the bedrock console.\n"); ncurses_print("To exit type \"quit\"\n"); while (console_running) socket_process(); ncurses_shutdown(); socket_shutdown(); return 0; }
int zsp_listener_stop(zsp_listener_t *listener) { if (listener == NULL) return SSS_ERROR; if (listener->sock != NULL) { socket_shutdown(listener->sock); socket_delete(listener->sock); listener->sock = NULL; } if (listener->thread != NULL) { thread_stop(listener->thread); thread_delete(listener->thread); listener->thread = NULL; } listener->port = 0; return SSS_OK; }
void Quick_Bye(int onsig) { char *temp; int i; temp = calloc(PATH_MAX, sizeof(char)); Syslog('+', "Quick_Bye"); socket_shutdown(mypid); snprintf(temp, PATH_MAX, "%s/tmp/ftnd%d", getenv("FTND_ROOT"), getpid()); unlink(temp); free(temp); colour(LIGHTGRAY, BLACK); sleep(3); if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) { cookedport(); } /* * Ignore SIGHUP during hangup */ signal(SIGHUP, SIG_IGN); hangup(); /* * Prevent that we call die() if something goes wrong next */ for (i = 0; i < NSIG; i++) if ((i == SIGHUP) || (i == SIGPIPE) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM)) signal(i, SIG_DFL); free(pTTY); if (StartTime) free(StartTime); exit(FTNERR_OK); }
/* * Main routine. Parse the arguments, open the remctl connection, send the * command, and then call process_response. */ int main(int argc, char *argv[]) { int option, status; char *server_host; struct addrinfo hints, *ai; const char *source = NULL; const char *service_name = NULL; unsigned short port = 0; struct remctl *r; int errorcode = 0; /* Set up logging and identity. */ message_program_name = "remctl"; if (!socket_init()) die("failed to initialize socket library"); /* * Parse options. The + tells GNU getopt to stop option parsing at the * first non-argument rather than proceeding on to find options anywhere. * Without this, it's hard to call remote programs that take options. * Non-GNU getopt will treat the + as a supported option, which is handled * below. */ while ((option = getopt(argc, argv, "+b:dhp:s:v")) != EOF) { switch (option) { case 'b': source = optarg; break; case 'd': message_handlers_debug(1, message_log_stderr); break; case 'h': usage(0); break; case 'p': port = atoi(optarg); break; case 's': service_name = optarg; break; case 'v': printf("%s\n", PACKAGE_STRING); exit(0); break; case '+': fprintf(stderr, "%s: invalid option -- +\n", argv[0]); default: usage(1); break; } } argc -= optind; argv += optind; if (argc < 2) usage(1); server_host = *argv++; argc--; /* * If service_name isn't set, the remctl library uses host/<server> * (host@<server> in GSS-API parlance). However, if the server to which * we're connecting is a DNS-load-balanced name, we have to be careful * what principal name we use. * * Ideally, we would let the GSS-API library handle this and choose * whether to canonicalize the <server> in the principal name based on the * krb5.conf rdns setting and similar configuration. However, with DNS * load balancing, this still may fail. At the time of network * connection, we will connect to whatever the name resolves to then. * After we connect, we authenticate, and the GSS-API library will then * separately canonicalize the hostname. It could get a different answer * than we got for our network connection, leading to an authentication * failure. * * Therefore, if the principal isn't specified, we canonicalize the * hostname to which we're connecting before we connect. Then, the * additional canonicalization possibly done by the GSS-API library should * return the same results and be consistent. * * Note that this opens the possibility of a subtle attack through DNS * spoofing, since both the principal used and the host to which we're * connecting can be changed by varying the DNS response. * * If the principal is specified explicitly, assume the user knows what * they're doing and don't do any of this. */ if (service_name == NULL) { memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; status = getaddrinfo(server_host, NULL, &hints, &ai); if (status != 0) die("cannot resolve host %s: %s", server_host, gai_strerror(status)); server_host = xstrdup(ai->ai_canonname); freeaddrinfo(ai); } /* Open connection. */ r = remctl_new(); if (r == NULL) sysdie("cannot initialize remctl connection"); if (source != NULL) if (!remctl_set_source_ip(r, source)) die("%s", remctl_error(r)); if (!remctl_open(r, server_host, port, service_name)) die("%s", remctl_error(r)); /* Do the work. */ if (!remctl_command(r, (const char **) argv)) die("%s", remctl_error(r)); if (!process_response(r, &errorcode)) die("%s", remctl_error(r)); /* Shut down cleanly. */ remctl_close(r); socket_shutdown(); return errorcode; }
void Good_Bye(int onsig) { FILE *pUsrConfig, *pExitinfo; char *temp; int offset; time_t t_end; int i; IsDoing("Hangup"); temp = calloc(PATH_MAX, sizeof(char)); Syslog('+', "Good_Bye(%d)", onsig); /* * Don't display goodbye screen on SIGHUP and idle timeout. * With idle timeout this will go into a loop. */ if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) DisplayFile((char *)"goodbye"); SaveLastCallers(); /* * Update the users database record. */ snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("FTND_ROOT")); if ((pUsrConfig = fopen(temp,"r+")) != NULL) { snprintf(temp, PATH_MAX, "%s/%s/exitinfo", CFG.bbs_usersdir, exitinfo.Name); if ((pExitinfo = fopen(temp,"rb")) != NULL) { fread(&usrconfighdr, sizeof(usrconfighdr), 1, pUsrConfig); fread(&exitinfo, sizeof(exitinfo), 1, pExitinfo); usrconfig = exitinfo; fclose(pExitinfo); usrconfig.iLastFileArea = iAreaNumber; /* If time expired, do not say say successful logoff */ if (!iExpired && !hanged_up) Syslog('+', "User successfully logged off BBS"); usrconfig.iLastMsgArea = iMsgAreaNumber; offset = usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize); if (fseek(pUsrConfig, offset, SEEK_SET) != 0) { WriteError("$Can't move pointer in file %s/etc/users.data", getenv("FTND_ROOT")); } else { fwrite(&usrconfig, sizeof(usrconfig), 1, pUsrConfig); } fclose(pUsrConfig); } } /* * Update mib counters */ t_end = time(NULL); mib_minutes = (unsigned int) ((t_end - t_start) / 60); mib_sessions++; sendmibs(); /* * Flush all data to the user, wait 5 seconds to * be sure the user received all data. */ if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) { colour(LIGHTGRAY, BLACK); sleep(4); } for (i = 0; i < NSIG; i++) { if (i == SIGCHLD) signal(i, SIG_DFL); else if ((i != SIGKILL) && (i != SIGSTOP)) signal(i, SIG_DFL); } if ((onsig != SIGALRM) && (onsig != FTNERR_TIMEOUT) && (hanged_up == 0)) { cookedport(); } /* * Ignore SIGHUP during hangup. */ signal(SIGHUP, SIG_IGN); hangup(); for (i = 0; i < NSIG; i++) { if ((i == SIGHUP) || (i == SIGPIPE) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM)) signal(i, SIG_DFL); } if (do_mailout) CreateSema((char *)"mailout"); t_end = time(NULL); Syslog(' ', "FTNDBBS finished in %s", t_elapsed(t_start, t_end)); sleep(1); /* * Start shutting down this session, cleanup some files. */ socket_shutdown(mypid); snprintf(temp, PATH_MAX, "%s/tmp/ftnd%d", getenv("FTND_ROOT"), getpid()); unlink(temp); snprintf(temp, PATH_MAX, "%s/%s/.quote", CFG.bbs_usersdir, exitinfo.Name); unlink(temp); snprintf(temp, PATH_MAX, "%s/%s/data.msg", CFG.bbs_usersdir, exitinfo.Name); unlink(temp); snprintf(temp, PATH_MAX, "%s/%s/door.sys", CFG.bbs_usersdir, exitinfo.Name); unlink(temp); snprintf(temp, PATH_MAX, "%s/%s/door32.sys", CFG.bbs_usersdir, exitinfo.Name); unlink(temp); snprintf(temp, PATH_MAX, "%s/%s/exitinfo", CFG.bbs_usersdir, exitinfo.Name); unlink(temp); free(temp); unlink("taglist"); Free_Language(); free(pTTY); if (StartTime) free(StartTime); deinitnl(); exit(onsig); }
int main(int argc, char *argv[]) { lockdownd_client_t lockdown = NULL; idevice_t device = NULL; idevice_connection_t connection = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; thread_t th; const char* udid = NULL; lockdownd_service_descriptor_t service = NULL; uint16_t local_port = 0; int result = EXIT_SUCCESS; int i; /* bind signals */ signal(SIGINT, clean_exit); signal(SIGTERM, clean_exit); #ifndef WIN32 signal(SIGQUIT, clean_exit); signal(SIGPIPE, SIG_IGN); #endif /* parse cmdline arguments */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { debug_mode = 1; idevice_set_debug_level(1); socket_set_verbose(3); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } udid = argv[i]; continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return EXIT_SUCCESS; } else if (atoi(argv[i]) > 0) { local_port = atoi(argv[i]); continue; } else { print_usage(argc, argv); return EXIT_SUCCESS; } } /* a PORT is mandatory */ if (!local_port) { fprintf(stderr, "Please specify a PORT.\n"); print_usage(argc, argv); goto leave_cleanup; } /* start services and connect to device */ ret = idevice_new(&device, udid); if (ret != IDEVICE_E_SUCCESS) { if (udid) { fprintf(stderr, "No device found with udid %s, is it plugged in?\n", udid); } else { fprintf(stderr, "No device found, is it plugged in?\n"); } result = EXIT_FAILURE; goto leave_cleanup; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lockdown, "idevicedebugserverproxy")) { fprintf(stderr, "Could not connect to lockdownd. Exiting.\n"); result = EXIT_FAILURE; goto leave_cleanup; } if ((lockdownd_start_service(lockdown, "com.apple.debugserver", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) { fprintf(stderr, "Could not start com.apple.debugserver!\nPlease make sure to mount the developer disk image first.\n"); result = EXIT_FAILURE; goto leave_cleanup; } if (idevice_connect(device, service->port, &connection) != IDEVICE_E_SUCCESS) { fprintf(stderr, "Connection to debugserver port %d failed!\n", (int)service->port); result = EXIT_FAILURE; goto leave_cleanup; } /* free lockdown connection if running as it is not needed anymore */ if (lockdown) { lockdownd_client_free(lockdown); lockdown = NULL; } /* setup and create socket endpoint */ socket_info_t socket_info; socket_info.device_connection = connection; socket_info.local_port = local_port; socket_info.remote_port = service->port; if (service) { lockdownd_service_descriptor_free(service); service = NULL; } /* create local socket */ socket_info.server_fd = socket_create(socket_info.local_port); if (socket_info.server_fd < 0) { fprintf(stderr, "Could not create socket\n"); result = EXIT_FAILURE; goto leave_cleanup; } while (!quit_flag) { debug("%s: Waiting for connection on local port %d\n", __func__, socket_info.local_port); /* wait for client */ socket_info.client_fd = socket_accept(socket_info.server_fd, socket_info.local_port); if (socket_info.client_fd < 0) { debug("%s: Continuing...\n", __func__); continue; } debug("%s: Handling new client connection...\n", __func__); if (thread_create(&th, connection_handler, (void*)&socket_info) != 0) { fprintf(stderr, "Could not start connection handler.\n"); socket_shutdown(socket_info.server_fd, SHUT_RDWR); socket_close(socket_info.server_fd); } } debug("%s: Shutting down debugserver proxy...\n", __func__); leave_cleanup: if (connection) { idevice_disconnect(connection); } if (lockdown) { lockdownd_client_free(lockdown); } if (device) { idevice_free(device); } return result; }
URL url_http_open(char *name) { URL_http *url; SOCKET fd; char *host, *path = NULL, *p; unsigned short port; char buff[BUFSIZ]; char wwwserver[256]; int n; #ifdef DEBUG printf("url_http_open(%s)\n", name); #endif /* DEBUG */ url = (URL_http *)alloc_url(sizeof(URL_http)); if(url == NULL) { url_errno = errno; return NULL; } /* common members */ URLm(url, type) = URL_http_t; URLm(url, url_read) = url_http_read; URLm(url, url_gets) = url_http_gets; URLm(url, url_fgetc) = url_http_fgetc; URLm(url, url_seek) = NULL; URLm(url, url_tell) = NULL; URLm(url, url_close) = url_http_close; /* private members */ url->fp = NULL; if(url_http_proxy_host) { char *q; int len; host = url_http_proxy_host; port = url_http_proxy_port; p = name; if(strncmp(p, "http://", 7) == 0) p += 7; for(q = p; *q && *q != ':' && *q != '/'; q++) ; len = q - p; if(len >= sizeof(wwwserver) - 1) { /* What?? */ strcpy(wwwserver, "localhost"); } else { strncpy(wwwserver, p, len); } } else { if(strncmp(name, "http://", 7) == 0) name += 7; n = strlen(name); if(n + REQUEST_OFFSET >= BUFSIZ) { url_http_close((URL)url); url_errno = URLERR_URLTOOLONG; errno = ENOENT; return NULL; } memcpy(buff, name, n + 1); host = buff; for(p = host; *p && *p != ':' && *p != '/'; p++) ; if(*p == ':') { char *pp; *p++ = '\0'; /* terminate `host' string */ port = atoi(p); pp = strchr(p, '/'); if(pp == NULL) p[0] = '\0'; else p = pp; } else port = 80; path = p; if(*path == '\0') *(path + 1) = '\0'; *path = '\0'; /* terminate `host' string */ strncpy(wwwserver, host, sizeof(wwwserver)); } #ifdef DEBUG printf("open(host=`%s', port=`%d')\n", host, port); #endif /* DEBUG */ #ifdef __W32__ timeout_flag = 0; fd = open_socket(host, port); #else timeout_flag = 0; signal(SIGALRM, timeout); alarm(ALARM_TIMEOUT); fd = open_socket(host, port); alarm(0); signal(SIGALRM, SIG_DFL); #endif /* __W32__ */ if(fd == (SOCKET)-1) { VOLATILE_TOUCH(timeout_flag); #ifdef ETIMEDOUT if(timeout_flag) errno = ETIMEDOUT; #endif /* ETIMEDOUT */ if(errno) url_errno = errno; else { url_errno = URLERR_CANTOPEN; errno = ENOENT; } url_http_close((URL)url); return NULL; } if((url->fp = socket_fdopen(fd, "rb")) == NULL) { url_errno = errno; closesocket(fd); url_http_close((URL)url); errno = url_errno; return NULL; } if(url_http_proxy_host) sprintf(buff, "GET %s HTTP/1.0\r\n", name); else { *path = '/'; sprintf(buff, "GET %s HTTP/1.0\r\n", path); } socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ if(url_user_agent) { sprintf(buff, "User-Agent: %s\r\n", url_user_agent); socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ } /* Host field */ sprintf(buff, "Host: %s\r\n", wwwserver); socket_write(fd, buff, (long)strlen(buff)); #ifdef DEBUG printf("HTTP<%s", buff); #endif /* DEBUG */ /* End of header */ socket_write(fd, "\r\n", 2); socket_shutdown(fd, 1); if(socket_fgets(buff, BUFSIZ, url->fp) == NULL) { if(errno) url_errno = errno; else { url_errno = URLERR_CANTOPEN; errno = ENOENT; } url_http_close((URL)url); return NULL; } #ifdef DEBUG printf("HTTP>%s", buff); #endif /* DEBUG */ p = buff; if(strncmp(p, "HTTP/1.0 ", 9) == 0 || strncmp(p, "HTTP/1.1 ", 9) == 0) p += 9; if(strncmp(p, "200", 3) != 0) /* Not success */ { url_http_close((URL)url); url_errno = errno = ENOENT; return NULL; } /* Skip mime header */ while(socket_fgets(buff, BUFSIZ, url->fp) != NULL) { if(buff[0] == '\n' || (buff[0] == '\r' && buff[1] == '\n')) break; /* end of heaer */ #ifdef DEBUG printf("HTTP>%s", buff); #endif /* DEBUG */ } #ifdef __W32__ return url_buff_open((URL)url, 1); #else return (URL)url; #endif /* __W32__ */ }
static void *thread_client_to_device(void *data) { socket_info_t* socket_info = (socket_info_t*)data; idevice_error_t res = IDEVICE_E_UNKNOWN_ERROR; int recv_len; int sent; char buffer[131072]; thread_t dtoc; debug("%s: started thread...\n", __func__); debug("%s: client_fd = %d\n", __func__, socket_info->client_fd); debug("%s: server_fd = %d\n", __func__, socket_info->server_fd); /* spawn server to client thread */ socket_info->stop_dtoc = 0; if (thread_create(&dtoc, thread_device_to_client, data) != 0) { fprintf(stderr, "Failed to start device to client thread...\n"); } while (!quit_flag && !socket_info->stop_ctod && socket_info->client_fd > 0 && socket_info->server_fd > 0) { debug("%s: receiving data from client...\n", __func__); /* attempt to read incoming data from client */ recv_len = socket_receive_timeout(socket_info->client_fd, buffer, sizeof(buffer), 0, 5000); /* any data received? */ if (recv_len <= 0) { if (recv_len == 0) { /* try again */ continue; } else { fprintf(stderr, "Receive failed: %s\n", strerror(errno)); break; } } else { /* forward data to device */ debug("%s: sending data to device...\n", __func__); res = idevice_connection_send(socket_info->device_connection, buffer, recv_len, (uint32_t*)&sent); if (sent < recv_len || res != IDEVICE_E_SUCCESS) { if (sent <= 0) { fprintf(stderr, "send failed: %s\n", strerror(errno)); break; } else { fprintf(stderr, "only sent %d from %d bytes\n", sent, recv_len); } } else { // sending succeeded, receive from device debug("%s: sent %d bytes to device\n", __func__, sent); } } } debug("%s: shutting down...\n", __func__); socket_shutdown(socket_info->client_fd, SHUT_RDWR); socket_close(socket_info->client_fd); socket_info->client_fd = -1; socket_info->stop_dtoc = 1; /* join other thread to allow it to stop */ thread_join(dtoc); return NULL; }
void do_tcp_tests(int timeout, int concurrency) { int selres; fd_set readfds, writefds; struct timespec timestamp; int absmaxconcurrency; int activesockets = 0; /* Number of allocated sockets */ int pending = 0; /* Total number of tests */ tcptest_t *nextinqueue; /* Points to the next item to start testing */ tcptest_t *firstactive; /* Points to the first item currently being tested */ /* Thus, active connections are between firstactive..nextinqueue */ tcptest_t *item; int sockok; int maxfd; int res; socklen_t connressize; char msgbuf[4096]; struct rlimit lim; /* If timeout or concurrency are 0, set them to reasonable defaults */ if (timeout == 0) timeout = 10; /* seconds */ /* * Decide how many tests to run in parallel. * If no --concurrency set by user, default to (FD_SETSIZE / 4) - typically 256. * But never go above the ressource limit that is set, or above FD_SETSIZE. * And we save 10 fd's for stdio, libs etc. */ absmaxconcurrency = (FD_SETSIZE - 10); getrlimit(RLIMIT_NOFILE, &lim); if ((lim.rlim_cur > 10) && ((lim.rlim_cur - 10) < absmaxconcurrency)) absmaxconcurrency = (lim.rlim_cur - 10); if (concurrency == 0) concurrency = (FD_SETSIZE / 4); if (concurrency > absmaxconcurrency) concurrency = absmaxconcurrency; dbgprintf("Concurrency evaluation: rlim_cur=%lu, FD_SETSIZE=%d, absmax=%d, initial=%d\n", lim.rlim_cur, FD_SETSIZE, absmaxconcurrency, concurrency); if (shuffletests) { struct timeval tv; struct timezone tz; gettimeofday(&tv, &tz); srandom(tv.tv_usec); } /* How many tests to do ? */ for (item = thead; (item); item = item->next) { if (shuffletests) item->randomizer = random(); pending++; } if (shuffletests) thead = msort(thead, tcptest_compare, tcptest_getnext, tcptest_setnext); firstactive = nextinqueue = thead; dbgprintf("About to do %d TCP tests running %d in parallel, abs.max %d\n", pending, concurrency, absmaxconcurrency); while (pending > 0) { int slowrunning, cclimit; time_t slowtimestamp = gettimer() - SLOWLIMSECS; /* * First, see if we need to allocate new sockets and initiate connections. */ /* * We start by counting the number of tests where the latest activity * happened more than SLOWLIMSECS seconds ago. These are ignored when counting * how many more tests we can start concurrenly. But never exceed the absolute * max. number of concurrently open sockets possible. */ for (item=firstactive, slowrunning = 0; (item != nextinqueue); item=item->next) { if ((item->fd > -1) && (item->lastactive < slowtimestamp)) slowrunning++; } cclimit = concurrency + slowrunning; if (cclimit > absmaxconcurrency) cclimit = absmaxconcurrency; sockok = 1; while (sockok && nextinqueue && (activesockets < cclimit)) { /* * We need to allocate a new socket that has O_NONBLOCK set. */ nextinqueue->fd = socket(PF_INET, SOCK_STREAM, 0); sockok = (nextinqueue->fd != -1); if (sockok) { /* Set the source address */ if (nextinqueue->srcaddr) { struct sockaddr_in src; int isip; memset(&src, 0, sizeof(src)); src.sin_family = PF_INET; src.sin_port = 0; isip = (inet_aton(nextinqueue->srcaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0); if (!isip) { char *envaddr = getenv(nextinqueue->srcaddr); isip = (envaddr && (inet_aton(envaddr, (struct in_addr *) &src.sin_addr.s_addr) != 0)); } if (isip) { res = bind(nextinqueue->fd, (struct sockaddr *)&src, sizeof(src)); if (res != 0) errprintf("WARNING: Could not bind to source IP %s for test %s: %s\n", nextinqueue->srcaddr, nextinqueue->tspec, strerror(errno)); } else { errprintf("WARNING: Invalid source IP %s for test %s, using default\n", nextinqueue->srcaddr, nextinqueue->tspec); } } res = fcntl(nextinqueue->fd, F_SETFL, O_NONBLOCK); if (res == 0) { /* * Initiate the connection attempt ... */ getntimer(&nextinqueue->timestart); nextinqueue->lastactive = nextinqueue->timestart.tv_sec; nextinqueue->cutoff = nextinqueue->timestart.tv_sec + timeout + 1; res = connect(nextinqueue->fd, (struct sockaddr *)&nextinqueue->addr, sizeof(nextinqueue->addr)); /* * Did it work ? */ if ((res == 0) || ((res == -1) && (errno == EINPROGRESS))) { /* This is OK - EINPROGRES and res=0 pick up status in select() */ activesockets++; tcp_stats_connects++; } else if (res == -1) { /* connect() failed. Flag the item as "not open" */ nextinqueue->connres = errno; nextinqueue->open = 0; nextinqueue->errcode = CONTEST_ENOCONN; close(nextinqueue->fd); nextinqueue->fd = -1; pending--; switch (nextinqueue->connres) { /* These may happen if connection is refused immediately */ case ECONNREFUSED : break; case EHOSTUNREACH : break; case ENETUNREACH : break; case EHOSTDOWN : break; /* Not likely ... */ case ETIMEDOUT : break; /* These should not happen. */ case EBADF : errprintf("connect returned EBADF!\n"); break; case ENOTSOCK : errprintf("connect returned ENOTSOCK!\n"); break; case EADDRNOTAVAIL: errprintf("connect returned EADDRNOTAVAIL!\n"); break; case EAFNOSUPPORT : errprintf("connect returned EAFNOSUPPORT!\n"); break; case EISCONN : errprintf("connect returned EISCONN!\n"); break; case EADDRINUSE : errprintf("connect returned EADDRINUSE!\n"); break; case EFAULT : errprintf("connect returned EFAULT!\n"); break; case EALREADY : errprintf("connect returned EALREADY!\n"); break; default : errprintf("connect returned %d, errno=%d\n", res, errno); } } else { /* Should NEVER happen. connect returns 0 or -1 */ errprintf("Strange result from connect: %d, errno=%d\n", res, errno); } } else { /* Could net set to non-blocking mode! Hmmm ... */ sockok = 0; errprintf("Cannot set O_NONBLOCK\n"); } nextinqueue=nextinqueue->next; } else { int newconcurrency = ((activesockets > 5) ? (activesockets-1) : 5); /* Could not get a socket */ switch (errno) { case EPROTONOSUPPORT: errprintf("Cannot get socket - EPROTONOSUPPORT\n"); break; case EAFNOSUPPORT : errprintf("Cannot get socket - EAFNOSUPPORT\n"); break; case EMFILE : errprintf("Cannot get socket - EMFILE\n"); break; case ENFILE : errprintf("Cannot get socket - ENFILE\n"); break; case EACCES : errprintf("Cannot get socket - EACCESS\n"); break; case ENOBUFS : errprintf("Cannot get socket - ENOBUFS\n"); break; case ENOMEM : errprintf("Cannot get socket - ENOMEM\n"); break; case EINVAL : errprintf("Cannot get socket - EINVAL\n"); break; default : errprintf("Cannot get socket - errno=%d\n", errno); break; } if (newconcurrency != concurrency) { errprintf("Reducing --concurrency setting from %d to %d\n", concurrency, newconcurrency); concurrency = newconcurrency; } } } /* Ready to go - we have a bunch of connections being established */ dbgprintf("%d tests pending - %d active tests, %d slow tests\n", pending, activesockets, slowrunning); restartselect: /* * Setup the FDSET's */ FD_ZERO(&readfds); FD_ZERO(&writefds); maxfd = -1; for (item=firstactive; (item != nextinqueue); item=item->next) { if (item->fd > -1) { /* * WRITE events are used to signal that a * connection is ready, or it has been refused. * READ events are only interesting for sockets * that have already been found to be open, and * thus have the "readpending" flag set. * * So: On any given socket, we want either a * write-event or a read-event - never both. */ if (item->readpending) FD_SET(item->fd, &readfds); else FD_SET(item->fd, &writefds); if (item->fd > maxfd) maxfd = item->fd; } } if (maxfd == -1) { /* No active connections */ if (activesockets == 0) { /* This can happen, if we get an immediate CONNREFUSED on all connections. */ continue; } else { errprintf("contest logic error: No FD's, active=%d, pending=%d\n", activesockets, pending); continue; } } /* * Wait for something to happen: connect, timeout, banner arrives ... */ if (maxfd < 0) { errprintf("select - no active fd's found, but pending is %d\n", pending); selres = 0; } else { struct timeval tmo = { 1, 0 }; dbgprintf("Doing select with maxfd=%d\n", maxfd); selres = select((maxfd+1), &readfds, &writefds, NULL, &tmo); dbgprintf("select returned %d\n", selres); } if (selres == -1) { int selerr = errno; /* * select() failed - this is BAD! */ switch (selerr) { case EINTR : errprintf("select failed - EINTR\n"); goto restartselect; case EBADF : errprintf("select failed - EBADF\n"); break; case EINVAL: errprintf("select failed - EINVAL\n"); break; case ENOMEM: errprintf("select failed - ENOMEM\n"); break; default : errprintf("Unknown select() error %d\n", selerr); break; } /* Leave this mess ... */ errprintf("Aborting TCP tests with %d tests pending\n", pending); return; } /* selres == 0 (timeout) isn't special - just go through the list of active tests */ /* Fetch the timestamp so we can tell how long the connect took */ getntimer(×tamp); /* Now find out which connections had something happen to them */ for (item=firstactive; (item != nextinqueue); item=item->next) { if (item->fd > -1) { /* Only active sockets have this */ if (timestamp.tv_sec > item->cutoff) { /* * Request timed out. */ if (item->readpending) { /* Final read timeout - just shut this socket */ socket_shutdown(item); item->errcode = CONTEST_ETIMEOUT; } else { /* Connection timeout */ item->open = 0; item->errcode = CONTEST_ETIMEOUT; } get_totaltime(item, ×tamp); close(item->fd); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } else { if (FD_ISSET(item->fd, &writefds)) { int do_talk = 1; unsigned char *outbuf = NULL; unsigned int outlen = 0; item->lastactive = timestamp.tv_sec; if (!item->open) { /* * First time here. * * Active response on this socket - either OK, or * connection refused. * We determine what happened by getting the SO_ERROR status. * (cf. select_tut(2) manpage). */ connressize = sizeof(item->connres); res = getsockopt(item->fd, SOL_SOCKET, SO_ERROR, &item->connres, &connressize); item->open = (item->connres == 0); if (!item->open) item->errcode = CONTEST_ENOCONN; do_talk = item->open; get_connectiontime(item, ×tamp); } if (item->open && (item->svcinfo->flags & TCP_SSL)) { /* * Setup the SSL connection, if not done already. * * NB: This can be triggered many times, as setup_ssl() * may need more data from the remote and return with * item->sslrunning == SSLSETUP_PENDING */ if (item->sslrunning == SSLSETUP_PENDING) { setup_ssl(item); if (item->sslrunning == 1) { /* * Update connectiontime to include * time for SSL handshake. */ get_connectiontime(item, ×tamp); } } do_talk = (item->sslrunning == 1); } /* * Connection succeeded - port is open, if SSL then the * SSL handshake is complete. * * If we have anything to send then send it. * If we want the banner, set the "readpending" flag to initiate * select() for read()'s. * NB: We want the banner EITHER if the GET_BANNER flag is set, * OR if we need it to match the expect string in the servicedef. */ item->readpending = (do_talk && !item->silenttest && ( (item->svcinfo->flags & TCP_GET_BANNER) || item->svcinfo->exptext )); if (do_talk) { if (item->telnetnegotiate && item->telnetbuflen) { /* * Return the telnet negotiate data response */ outbuf = item->telnetbuf; outlen = item->telnetbuflen; } else if (item->sendtxt && !item->silenttest) { outbuf = item->sendtxt; outlen = (item->sendlen ? item->sendlen : strlen(outbuf)); } if (outbuf && outlen) { /* * It may be that we cannot write all of the * data we want to. Tough ... */ res = socket_write(item, outbuf, outlen); tcp_stats_written += res; if (res == -1) { /* Write failed - this socket is done. */ dbgprintf("write failed\n"); item->readpending = 0; item->errcode = CONTEST_EIO; } else if (item->svcinfo->flags & TCP_HTTP) { /* * HTTP tests require us to send the full buffer. * So adjust sendtxt/sendlen accordingly. * If no more to send, switch to read-mode. */ item->sendtxt += res; item->sendlen -= res; item->readpending = (item->sendlen == 0); } } } /* If closed and/or no bannergrabbing, shut down socket */ if (item->sslrunning != SSLSETUP_PENDING) { if (!item->open || !item->readpending) { if (item->open) { socket_shutdown(item); } close(item->fd); get_totaltime(item, ×tamp); if (item->finalcallback) item->finalcallback(item->priv); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } } } else if (FD_ISSET(item->fd, &readfds)) { /* * Data ready to read on this socket. Grab the * banner - we only do one read (need the socket * for other tests), so if the banner takes more * than one cycle to arrive, too bad! */ int wantmoredata = 0; int datadone = 0; item->lastactive = timestamp.tv_sec; /* * We may be in the process of setting up an SSL connection */ if (item->sslrunning == SSLSETUP_PENDING) setup_ssl(item); if (item->sslrunning == SSLSETUP_PENDING) break; /* Loop again waiting for more data */ /* * Connection is ready - plain or SSL. Read data. */ res = socket_read(item, msgbuf, sizeof(msgbuf)-1); tcp_stats_read += res; dbgprintf("read %d bytes from socket\n", res); if ((res > 0) && item->datacallback) { datadone = item->datacallback(msgbuf, res, item->priv); } if ((res > 0) && item->telnetnegotiate) { /* * telnet data has telnet options first. * We must negotiate the session before we * get the banner. */ item->telnetbuf = item->banner; item->telnetbuflen = res; /* * Safety measure: Dont loop forever doing * telnet options. * This puts a maximum on how many times * we go here. */ item->telnetnegotiate--; if (!item->telnetnegotiate) { dbgprintf("Max. telnet negotiation (%d) reached for host %s\n", MAX_TELNET_CYCLES, inet_ntoa(item->addr.sin_addr)); } if (do_telnet_options(item)) { /* Still havent seen the session banner */ item->banner = NULL; item->bannerbytes = 0; item->readpending = 0; wantmoredata = 1; } else { /* No more options - we have the banner */ item->telnetnegotiate = 0; } } if ((item->svcinfo->flags & TCP_HTTP) && ((res > 0) || item->sslagain) && (!datadone) ) { /* * HTTP : Grab the entire response. */ wantmoredata = 1; } if (!wantmoredata) { if (item->open) { socket_shutdown(item); } item->readpending = 0; close(item->fd); get_totaltime(item, ×tamp); if (item->finalcallback) item->finalcallback(item->priv); item->fd = -1; activesockets--; pending--; if (item == firstactive) firstactive = item->next; } } } } } /* end for loop */ } /* end while (pending) */ dbgprintf("TCP tests completed normally\n"); }
int start_server (int argc, char *argv[]) { int i; int threadCount = 0; int thread_id; HANDLE g_hThread[MAX_THREAD]; char doers_number[MAXDOER][SPACE_FOR_THREAD_ID]; char movers_number[MAXMOVER][SPACE_FOR_THREAD_ID]; #ifdef INFORMIX MI_CONNECTION_INFO conn_info; // This works around a bug in Informix's isqlt09a.dll that causes memory // access violation when our program exits. memset (&conn_info, '\0', sizeof (conn_info)); mi_server_connect (&conn_info); #endif // Don't let the user start the middleware server as a standalone program. // Check whether the argument matches the magic string. if ((argc != 2) || (stricmp(argv[1], SERVER_MAGIC_STR) != 0)) { puts("Vigilert Middleware Server cannot be started as a standalone program."); puts("Start the Velara Vigilert service.\n"); Sleep (4000); exit(EXIT_FAILURE); } // Assign IDs to the multiple movers and doers for (i = 0; i < MAXDOER; i++) { sprintf (doers_number[i], "%d", i + 1); } for (i = 0; i < MAXMOVER; i++) { sprintf (movers_number[i], "%d", i + 1); } /* Initialize the global variables */ num_doer = 0; num_mover = 0; g_fTerminate = FALSE; num_doers_accessing_global_SPI = 0; puts ("\n.:. Vigilert Server .:."); // Save the memory state so we can diff against it in vl_gather_stats. _CrtMemCheckpoint (&s1); // Initialize the mutexes InitializeCriticalSection(&suspend_mutex); InitializeCriticalSection(&mover_cleaner_mutex); InitializeCriticalSection(&doer_num_mutex); InitializeCriticalSection(&mover_num_mutex); InitializeCriticalSection(&num_doers_accessing_global_SPI_mutex); InitializeCriticalSection(&Global_SPI_mutex); #ifdef _MIDDLE init_named_mem(); #endif load_keys(); #ifdef _MIDDLE InitializeCriticalSection(&logwrite_mutex); InitializeCriticalSection(&begin_udr_mutex); tm_init_conn_pool(); #endif // Initialize the semaphores that wakeup the movers and the doers // Doers can be woken up by doer dispatcher, mover (that moves the database tokens // to the database task queue) and the TCP-IP server thread that builds and moves the stream // tokens to the stream task queue. wakeup_doer_by_doer_dispatcher_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL); // Semaphore for doer-dispatcher wakeup_doer_by_mover_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL); // Semaphore for mover wakeup_doer_by_tcpip_server_sem = CreateSemaphore(NULL, 0, MAXDOER, NULL); // Semahpore for TCP-IP server // Mover can be wpken up by mover dispatcher. wakeup_mover_by_mover_dispatcher_sem = CreateSemaphore(NULL, 0, MAXMOVER, NULL); // Semaphore for mover-dispatcher // Initialize the array of semaphore handles that can wake up the doers wakeup_doer_array[0] = wakeup_doer_by_doer_dispatcher_sem; wakeup_doer_array[1] = wakeup_doer_by_mover_sem; wakeup_doer_array[2] = wakeup_doer_by_tcpip_server_sem; // Initialize the event variable to say whether a command execute thread is waiting to access global SPI. command_execute_waiting_event = CreateEvent(NULL, TRUE, TRUE, NULL); /* start threads */ g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, wait_end, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover_dispatcher, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer_dispatcher, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, TCPIPserver, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, cleaner, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; #ifdef _DEBUG g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, GatherStatsServer, NULL, CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; #endif for (i = 0; i < MAXDOER; i++) { g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, doer,(LPVOID)doers_number[i], CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; } for (i = 0; i < MAXMOVER; i++) { g_hThread[threadCount] = chBEGINTHREADEX(NULL, 0, mover,(LPVOID)movers_number[i], CREATE_SUSPENDED, &thread_id); tm_associate_thread_id_to_connection(threadCount, thread_id); threadCount++; } // Before starting the various threads, let the main thread run the initializing routine // to initialize all main memory data structures tm_associate_thread_id_to_connection(threadCount, tm_get_thread_id()); tman_init(); // Resume the various suspended threads one by one for (i = 0; i < threadCount; i++) { int result; result = ResumeThread(g_hThread[i]); if (result == -1) { #ifdef _MIDDLE printf ("Error: unable to start thread %d.\n", tm_own_connpool_1[i].thread_id); #endif exit (EXIT_FAILURE); } } // Wait for all the currently active threads to die or terminate before performing the cleanup // of all main memory objects and exiting the middleware server WaitForMultipleObjects(threadCount, g_hThread, TRUE, INFINITE); for (i = 0; i< threadCount; i++) CloseHandle(g_hThread[i]); DeleteCriticalSection(&mover_num_mutex); DeleteCriticalSection(&doer_num_mutex); DeleteCriticalSection(&mover_cleaner_mutex); DeleteCriticalSection(&suspend_mutex); DeleteCriticalSection(&num_doers_accessing_global_SPI_mutex); DeleteCriticalSection(&Global_SPI_mutex); CloseHandle(wakeup_mover_by_mover_dispatcher_sem); CloseHandle(wakeup_doer_by_doer_dispatcher_sem); CloseHandle(wakeup_doer_by_tcpip_server_sem); CloseHandle(wakeup_doer_by_mover_sem); CloseHandle(command_execute_waiting_event); #ifdef _MIDDLE { tm_close_conn_pool(); close_named_mem(); DeleteCriticalSection(&begin_udr_mutex); DeleteCriticalSection(&logwrite_mutex); socket_shutdown(); } #endif puts ("Vigilert run complete."); return EXIT_SUCCESS; }