static void esif_ws_cgi_redirect_output ( char *script, int fd ) { int current_out; char buffer[BUFFER_LENGTH]; int ret; FILE *dataFile = NULL; #define MAX_SIZE 100 printf("esif_ws_cgi_redirect_output-> full_script_name: %s\n", script); current_out = esif_ccb_dup(1); if (current_out == -1) { perror("_dup( 1 ) failure"); exit(1); } esif_ccb_fopen(&dataFile, "data", "w"); if (NULL == dataFile) { printf("failed to open file in writing mode \n"); return; } if (-1 == esif_ccb_dup2(dataFile, 1)) { perror("Can't _dup2 stdout"); exit(1); } printf("Execute the script\n"); system(script); fflush(stdout); fclose(dataFile); esif_ccb_dup3(current_out, 1); esif_ccb_flushall(); esif_ccb_fopen(&dataFile, "data", "r"); if (NULL == dataFile) { printf("failed to open file in readig mode: \n"); return; } (long)fseek(dataFile, (off_t)0, SEEK_END); (void)fseek(dataFile, (off_t)0, SEEK_SET); (void)esif_ccb_sprintf(BUFFER_LENGTH, buffer, (char*)"HTTP/1.1 200 OK\n"); (void)send(fd, buffer, (int)esif_ccb_strlen(buffer, MAX_SIZE), 0); while ((ret = (int)fread(buffer, 1, BUFFER_LENGTH, dataFile)) > 0) (void)send(fd, buffer, ret, 0); fclose(dataFile); esif_ws_server_initialize_clients(); esif_ws_http_set_login_requested(1); esif_ws_http_set_authenticated(1); }
int esif_ws_init(void) { int index=0; int retVal=0; char *ipaddr = (char*)g_ws_ipaddr; char *portPtr = g_ws_port; struct sockaddr_in addrSrvr = {0}; struct sockaddr_in addrClient = {0}; socklen_t len_inet = 0; esif_ccb_socket_t client_socket = INVALID_SOCKET; int option = 1; eEsifError req_results = ESIF_OK; ClientRecordPtr clientPtr = NULL; int selRetVal = 0; int maxfd = 0; int setsize = 0; struct timeval tv={0}; /* Timeout value */ fd_set workingSet = {0}; esif_ccb_mutex_init(&g_web_socket_lock); atomic_inc(&g_ws_threads); atomic_set(&g_ws_quit, 0); CMD_OUT("Starting WebServer %s %s\n", ipaddr, portPtr); esif_ccb_socket_init(); // Allocate pool of Client Records and HTTP input buffer g_clients = (ClientRecordPtr )esif_ccb_malloc(MAX_CLIENTS * sizeof(*g_clients)); g_ws_http_buffer = (char *)esif_ccb_malloc(WS_BUFFER_LENGTH); if (NULL == g_clients || NULL == g_ws_http_buffer) { ESIF_TRACE_DEBUG("Out of memory"); goto exit; } esif_ws_server_initialize_clients(); len_inet = sizeof(addrSrvr); retVal = esif_ws_server_create_inet_addr(&addrSrvr, &len_inet, ipaddr, portPtr, (char*)"top"); if (retVal < 0 && !addrSrvr.sin_port) { ESIF_TRACE_DEBUG("Invalid server address/port number"); goto exit; } g_listen = socket(PF_INET, SOCK_STREAM, 0); if (g_listen == SOCKET_ERROR) { ESIF_TRACE_DEBUG("open socket error"); goto exit; } retVal = setsockopt(g_listen, SOL_SOCKET, SO_REUSEADDR, (char*)&option, sizeof(option)); if (retVal < 0) { esif_ccb_socket_close(g_listen); g_listen = INVALID_SOCKET; ESIF_TRACE_DEBUG("setsockopt failed"); goto exit; } retVal = bind(g_listen, (struct sockaddr*)&addrSrvr, len_inet); if (retVal < -1) { esif_ccb_socket_close(g_listen); g_listen = INVALID_SOCKET; ESIF_TRACE_DEBUG("bind sysem call failed"); goto exit; } retVal = listen(g_listen, MAX_CLIENTS); if (retVal < 0) { ESIF_TRACE_DEBUG("listen system call failed"); goto exit; } /* Accept client requests and new connections until told to quit */ while (!atomic_read(&g_ws_quit)) { /* Build file descriptor set of active sockets */ maxfd = 0; setsize = 0; /* Clear the FD set we will check after each iteration */ FD_ZERO(&workingSet); /* Add our listner to the FD set to check */ if (g_listen != INVALID_SOCKET) { FD_SET((u_int)g_listen, &workingSet); maxfd = (int)g_listen + 1; setsize++; } /* Add our current clients to the FD set to check */ for (index = 0; index < MAX_CLIENTS && setsize < FD_SETSIZE; index++) { if (g_clients[index].socket != INVALID_SOCKET) { FD_SET((u_int)g_clients[index].socket, &workingSet); maxfd = esif_ccb_max(maxfd, (int)g_clients[index].socket + 1); setsize++; } } /* If we have nothing functional in te FD set to check; break */ if (maxfd == 0) { break; } /* * timeout of N + 0.05 secs */ tv.tv_sec = 2; tv.tv_usec = 50000; /* Check our FD set for sockets ready to be accepted (listener) or read (others already accepted) */ selRetVal = select(maxfd, &workingSet, NULL, NULL, &tv); if (selRetVal == SOCKET_ERROR) { break; } else if (!selRetVal) { continue; } /* Accept any new connections on the listening socket */ if (FD_ISSET(g_listen, &workingSet)) { int sockets = (g_listen == INVALID_SOCKET ? 0 : 1); len_inet = sizeof addrClient; client_socket = (int)accept(g_listen, (struct sockaddr*)&addrClient, &len_inet); if (client_socket == SOCKET_ERROR) { ESIF_TRACE_DEBUG("accept(2)"); goto exit; } /* Find the first empty client in our list */ for (index = 0; index < MAX_CLIENTS && sockets < FD_SETSIZE; index++) { if (g_clients[index].socket == INVALID_SOCKET) { esif_ws_client_initialize_client(&g_clients[index]); g_clients[index].socket = client_socket; break; } sockets++; } /* If all clients are in use, close the new client */ if (index >= MAX_CLIENTS || sockets >= FD_SETSIZE) { ESIF_TRACE_DEBUG("Connection Limit Exceeded (%d)", MAX_CLIENTS); esif_ccb_socket_close(client_socket); client_socket = INVALID_SOCKET; continue; } } /* Go through our client list and check if the FD set indicates any have activity */ for (index = 0; index < MAX_CLIENTS; index++) { client_socket = g_clients[index].socket; if (client_socket == INVALID_SOCKET || client_socket == g_listen) { continue; } /* Process client if it is in the set of active file descriptors */ if (FD_ISSET(client_socket, &workingSet)) { ESIF_TRACE_DEBUG("Client %d connected\n", client_socket); /******************** Process the client request ********************/ clientPtr = &g_clients[index]; req_results = esif_ws_client_process_request(clientPtr); if (req_results == ESIF_E_WS_DISC) { ESIF_TRACE_DEBUG("Client %d disconnected\n", client_socket); esif_ws_client_initialize_client(clientPtr); /* reset */ } else if (req_results == ESIF_E_NO_MEMORY) { ESIF_TRACE_DEBUG("Out of memory\n"); esif_ws_client_initialize_client(clientPtr); /* reset */ } /* Clear everything after use */ esif_ws_protocol_initialize(&clientPtr->prot); } } } exit: /* cleanup */ if (g_listen != INVALID_SOCKET) { esif_ccb_socket_close(g_listen); g_listen = INVALID_SOCKET; } if (g_clients) { for (index = 0; index < MAX_CLIENTS; index++) { esif_ws_client_close_client(&g_clients[index]); } esif_ccb_free(g_clients); g_clients = NULL; } esif_ccb_free(g_rest_out); esif_ccb_free(g_ws_http_buffer); g_rest_out = NULL; g_ws_http_buffer = NULL; esif_ccb_socket_exit(); atomic_dec(&g_ws_threads); return 0; }