Advertisement
Guest User

Untitled

a guest
Feb 19th, 2018
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.60 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <pthread.h>
  7. #include <signal.h>
  8. #include <arpa/inet.h>
  9. #include <netinet/tcp.h>
  10. #include <netinet/in.h>
  11. #include <sys/time.h>
  12. #include <sys/stat.h>
  13. #include <sys/wait.h>
  14. #include <sys/socket.h>
  15. #include <sys/types.h>
  16.  
  17.  
  18. #define ISspace(x) isspace((int)(x))
  19.  
  20. #define SERVER_PORT 8080
  21. #define SERVER_STRING "Server: wi2me server\r\n"
  22.  
  23. #define MAX_LINE_SIZE 1024
  24. #define MAX_KEY_SIZE 20
  25. #define MAX_VALUE_SIZE 20
  26. #define MAX_DIR_SIZE 200
  27.  
  28.  
  29. #define HTTP_METHOD_GET 1
  30. #define HTTP_METHOD_POST 2
  31. #define HTTP_BAD_REQUEST -1
  32. #define HTTP_METHOD_NOT_IMPLEMENTED -2
  33. #define ERR_SOCKET -3
  34.  
  35.  
  36. struct client_log{
  37.   char dir[MAX_DIR_SIZE];
  38.   char tcp[MAX_DIR_SIZE];
  39.   char info[MAX_DIR_SIZE];
  40.   FILE* s_file;
  41.   pthread_mutex_t file_mutex;
  42. };
  43.  
  44. struct client_list{
  45.   pthread_t pid;
  46.   int  sock;
  47.   struct client_log* c_log;
  48.   struct client_list* next;
  49.   struct client_list* prev;
  50. };
  51.  
  52. void* accept_request(void *);
  53. void  client_bad_request(int);
  54. void  client_unimplemented(int);
  55. void  client_get(int, char*, struct client_log*);
  56. void  client_post(int);
  57. void  cat(int, FILE *);
  58. void  error_die(const char *);
  59. int   get_line(int, char *, int);
  60. void  headers(int);
  61. void  not_found(int);
  62. int   startup(u_short *);
  63. void  server_stop(int);
  64. void remove_from_list(struct client_list*);
  65. void  unimplemented(int);
  66.  
  67. struct client_list *first;
  68. pthread_mutex_t mutex_list = PTHREAD_MUTEX_INITIALIZER;
  69.  
  70. /********************************************************************
  71.  * Split a "key=value" string into key and value
  72.  ********************************************************************/
  73. void split(char* s, char* key, char* value){
  74.   int i=0, j=0;
  75.   while((s[i] != '=') && (s[i] != '\0') && (i < MAX_KEY_SIZE - 1)){
  76.     key[i]=s[i];  
  77.     i++;
  78.   }
  79.   key[i]='\0';
  80.   if(s[i] != '\0'){
  81.     i++;
  82.     do{
  83.       value[j] = s[i];
  84.       i++; j++;
  85.     }while((s[i] != '\0') && (j < MAX_VALUE_SIZE));
  86.   }else value[0]='\0';
  87. }
  88.  
  89. /**********************************************************************/
  90. /* Kill the server and all its instance when catching SIGINT          */
  91. /**********************************************************************/
  92. void server_stop(int sig){
  93.   printf("receive signal %i, shutting down the server\n",sig);
  94. /*  while(first != NULL){
  95.     struct client_list* next;
  96.     next = first->next;
  97.     remove_from_list(first);
  98.     first=next;
  99.   }
  100.   */
  101.   close(first->sock);
  102.   exit(0);
  103. }
  104.  
  105. /**********************************************************************/
  106. /*   print list */
  107. /**********************************************************************/
  108. void print_list(){
  109.   printf ("first : %i - ", first->sock);
  110.   struct client_list* current = first->prev;
  111.   while(current != first){
  112.       if(current == NULL){printf("problem !"); break; }
  113.       printf ("%i - ", current->sock);
  114.       current = current->prev;
  115.   }
  116.   printf("\n");
  117.   return;
  118. }
  119.  
  120. /**********************************************************************/
  121. /* Write TCP Connecshun information                                   */
  122. /**********************************************************************/
  123. void write_tcp_info(int socket, FILE* file, pthread_mutex_t *mutex){  
  124.   if(file == NULL) return;
  125.   struct timeval t_val;
  126.   struct tcp_info tcp_info;
  127.   gettimeofday(&t_val, NULL);
  128.   int tcp_info_length = sizeof(tcp_info);
  129.   if ( getsockopt( socket, SOL_TCP, TCP_INFO, (void *)&tcp_info, (socklen_t *)&tcp_info_length ) == 0 ) {
  130.     pthread_mutex_lock(mutex);
  131.     fprintf(file,"%u.%u %u %u %u %u %u %u %u %u %u %u %u %u\n",
  132.         (unsigned int)t_val.tv_sec,
  133.         (unsigned int)t_val.tv_usec,
  134.         tcp_info.tcpi_last_data_sent,
  135.         tcp_info.tcpi_last_data_recv,
  136.         tcp_info.tcpi_snd_cwnd,
  137.         tcp_info.tcpi_snd_ssthresh,
  138.         tcp_info.tcpi_rcv_ssthresh,
  139.         tcp_info.tcpi_rtt,
  140.         tcp_info.tcpi_rttvar,
  141.         tcp_info.tcpi_unacked,
  142.         tcp_info.tcpi_sacked,
  143.         tcp_info.tcpi_lost,
  144.         tcp_info.tcpi_retrans,
  145.         tcp_info.tcpi_fackets
  146.         );
  147.     pthread_mutex_unlock(mutex);
  148.   }
  149. }
  150.  
  151.  
  152. /**********************************************************************/
  153. /* Initialize the log for the current client                          */
  154. /**********************************************************************/
  155. struct client_log* initialize_log(int socket){
  156.   char c_path[MAX_DIR_SIZE];
  157.   char d_path[MAX_DIR_SIZE];
  158.   char i_path[MAX_DIR_SIZE];
  159.   char t_path[MAX_DIR_SIZE];
  160.   char ipstr[INET6_ADDRSTRLEN];
  161.   struct sockaddr_storage peer;
  162.   struct client_log* c_log;
  163.   FILE *tcp_watch, *info;
  164.   struct timeval t_val;
  165.   socklen_t len;
  166.   int port;
  167.  
  168.   // Write information about the connecshun
  169.   gettimeofday(&t_val, NULL);
  170.   if(getcwd(c_path,MAX_DIR_SIZE) == NULL) return NULL;
  171.   sprintf(d_path,"%s/%u.%02u", c_path, (unsigned int)t_val.tv_sec, (unsigned int)t_val.tv_usec);
  172.   if( mkdir(d_path,S_IRWXU) != 0 ) return NULL;
  173.   sprintf(i_path, "%s/info", d_path);
  174.   info=fopen(i_path,"a+");
  175.   if(info == NULL) return NULL;
  176.  
  177.   len = sizeof(peer);
  178.   getpeername(socket, (struct sockaddr*)&peer, &len);
  179.   if (peer.ss_family == AF_INET) { // IPv4
  180.   struct sockaddr_in *s = (struct sockaddr_in *)&peer;
  181.   port = ntohs(s->sin_port);
  182.   inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
  183.   } else { //IPv6
  184.     struct sockaddr_in6 *s = (struct sockaddr_in6 *)&peer;
  185.     port = ntohs(s->sin6_port);
  186.     inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
  187.   }
  188.   fprintf(info, "timestamp : %u.%u\nhost : %s\nport source : %i\n\n", (unsigned int)t_val.tv_sec, (unsigned int)t_val.tv_usec, ipstr, port);
  189.   fclose(info);
  190.  
  191.   // create tcp file for monitoring TCP connecshun
  192.   sprintf(t_path, "%s/tcp", d_path);
  193.   tcp_watch=fopen(t_path,"a+");
  194.   if(tcp_watch == NULL) return NULL;
  195.  
  196.   // create the structure
  197.   c_log = malloc(sizeof(struct client_log));
  198.   strncpy(c_log->dir, d_path, strlen(d_path));
  199.   strncpy(c_log->tcp, t_path, strlen(t_path));
  200.   strncpy(c_log->info, i_path, strlen(i_path));
  201.   c_log->s_file = tcp_watch;
  202.   pthread_mutex_init(&(c_log->file_mutex), NULL);
  203.  
  204.   fprintf(tcp_watch, "sec.msec last_data_sent last_data_recv snd_cwnd snd_ssthresh rtt rttvar unacked sacked lost retrans fackets\n");
  205.   write_tcp_info(socket, tcp_watch, &(c_log->file_mutex));
  206.  
  207.   return c_log;
  208. }
  209.  
  210.  
  211. /*******************************************************************/
  212. /* Add the client to the double linked list                        */
  213. /*******************************************************************/
  214. void add_client(int sock, struct client_log* c_log){
  215.   pthread_mutex_lock(&mutex_list);
  216.   struct client_list* current = malloc(sizeof(struct client_list));
  217.   current->sock = sock;
  218.   current->c_log = c_log;
  219.   current->next = first;
  220.   current->prev = first->prev;
  221.   first->prev->next = current;
  222.   first->prev = current;
  223.   pthread_mutex_unlock(&mutex_list);
  224. }
  225.  
  226. /*******************************************************************/
  227. /* Remove the client from the double linked list                   */
  228. /*******************************************************************/
  229. void remove_from_list(struct client_list* current){
  230.   if(current == NULL) return;
  231.   pthread_mutex_lock(&mutex_list);
  232.   close(current->sock);
  233.   if(current->c_log != NULL){
  234.     fclose(current->c_log->s_file);
  235.     free(current->c_log);
  236.   }
  237.   if(current->prev != NULL) current->prev->next = current->next;
  238.   if(current->next != NULL) current->next->prev = current->prev;
  239.   free(current);
  240.   pthread_mutex_unlock(&mutex_list);
  241. }
  242.  
  243.  
  244. /*******************************************************************
  245.  * get the method used by the client                              
  246.  * if method is GET, feed "query" with the query string. query
  247.  * should be properly allocated. it will not be fed more than
  248.  * query_size bytes. returns HTTP_METHOD_GET.
  249.  * if method is POST, returns HTTP_METHOD_POST.
  250.  * if method is unknown, returns HTTP_METHOD_UNIMPLEMENTED.
  251.  * throws the error if so
  252.  *******************************************************************/
  253. int retrieve_method(int sock_client, char* query, int query_size){
  254.   char buf[MAX_LINE_SIZE];
  255.   char method[10];
  256.   char *url = malloc(sizeof(char)*MAX_LINE_SIZE);
  257.   char *url_ = url;
  258.   int numchars;
  259.  
  260.   query[0] = '\0';
  261.   numchars = get_line(sock_client, buf, sizeof(buf));
  262.   //printf("%s\n",buf);
  263.   if(numchars < 0) return numchars;
  264.   unsigned int i = 0; unsigned int j = 0;
  265.   while (!ISspace(buf[j]) && (i < sizeof(method) - 1) && (j < numchars))
  266.   {
  267.     method[i] = buf[j];
  268.     i++; j++;
  269.   }
  270.   method[i] = '\0';
  271.   //printf("%s\n",method);
  272.   if( strcasecmp(method, "POST") == 0 ) return HTTP_METHOD_POST;
  273.   if( strcasecmp(method, "GET") != 0  ) return HTTP_METHOD_NOT_IMPLEMENTED;
  274.  
  275.   //the method is GET, feed the query string
  276.   i = 0;
  277.   while (ISspace(buf[j]) && (j < numchars)) j++;
  278.   while (!ISspace(buf[j]) && (i < MAX_LINE_SIZE - 1) && (j < numchars))
  279.   {
  280.     url_[i] = buf[j];
  281.     i++; j++;
  282.   }
  283.   url_[i] = '\0';
  284.  
  285.   while ((*url_ != '?') && (*url_ != '\0')) url_++;
  286.   if (*url_ == '?') url_++;
  287.   strncpy(query, url_, query_size);
  288.   query[query_size - 1] = '\0';
  289.   free(url);
  290.   return HTTP_METHOD_GET;
  291. }
  292.  
  293.  
  294. /**********************************************************************/
  295. /* Inform the client that a request it has made has a problem.
  296.  * Parameters: client socket */
  297. /**********************************************************************/
  298. void client_bad_request(int client)
  299. {
  300.   char buf[1024];
  301.   sprintf(buf, "HTTP/1.0 400 BAD REQUEST\r\n");
  302.   send(client, buf, sizeof(buf), 0);
  303.   sprintf(buf, "Content-type: text/html\r\n");
  304.   send(client, buf, sizeof(buf), 0);
  305.   sprintf(buf, "\r\n");
  306.   send(client, buf, sizeof(buf), 0);
  307.   sprintf(buf, "<P>i couldn't understand your request Dudez !");
  308.   send(client, buf, sizeof(buf), 0);
  309.   sprintf(buf, "<P>check your bro !");
  310.   send(client, buf, sizeof(buf), 0);
  311. }
  312.  
  313. /**********************************************************************/
  314. /* Inform the client that the requested web method has not been
  315.  * implemented.
  316.  * Parameter: the client socket */
  317. /**********************************************************************/
  318. void client_unimplemented(int client)
  319. {
  320.   char buf[1024];
  321.  
  322.   sprintf(buf, "HTTP/1.0 501 Method Not Implemented\r\n");
  323.   send(client, buf, strlen(buf), 0);
  324.   sprintf(buf, SERVER_STRING);
  325.   send(client, buf, strlen(buf), 0);
  326.   sprintf(buf, "Content-Type: text/html\r\n");
  327.   send(client, buf, strlen(buf), 0);
  328.   sprintf(buf, "\r\n");
  329.   send(client, buf, strlen(buf), 0);
  330.   sprintf(buf, "<HTML><HEAD><TITLE>Method Not Implemented\r\n");
  331.   send(client, buf, strlen(buf), 0);
  332.   sprintf(buf, "</TITLE></HEAD>\r\n");
  333.   send(client, buf, strlen(buf), 0);
  334.   sprintf(buf, "<BODY><P>HTTP request method not supported.\r\n");
  335.   send(client, buf, strlen(buf), 0);
  336.   sprintf(buf, "</BODY></HTML>\r\n");
  337.   send(client, buf, strlen(buf), 0);
  338. }
  339.  
  340. /**********************************************************************/
  341. /* Handle the GET method, basically, it just sends out a stream of @
  342.  * Parameter: the client socket and the query string */
  343. /**********************************************************************/
  344. void client_get(int sock_client, char* query_string, struct client_log* c_log){
  345.   char *query = malloc(sizeof(char)*(strlen(query_string)+1));
  346.   char *token = NULL;
  347.   char *id=NULL; char *mac=NULL; char *ssid=NULL;
  348.   unsigned int size=0;
  349.  
  350.   strncpy(query, query_string, strlen(query_string));
  351.   token = strtok(query, "&");
  352.   while (token){
  353.     char *key = malloc(sizeof(char)*MAX_KEY_SIZE);
  354.     char *value = malloc(sizeof(char)*MAX_VALUE_SIZE);
  355.     split(token, key, value);
  356.     if     (strcmp(key,"id")   == 0) id   = value;
  357.     else if(strcmp(key,"mac")  == 0) mac  = value;
  358.     else if(strcmp(key,"ssid") == 0) ssid = value;
  359.     else if(strcmp(key,"size") == 0) size = atoi(value);
  360.     else{ free(key); free(value); }
  361.     free(key);
  362.     token=strtok(NULL, "&");
  363.   }
  364.   free(query);
  365.  
  366.   //printf("%s - %s - %s - %u\n",id, mac, ssid, size);
  367.  
  368.   if((id == NULL) || (mac == NULL) || (ssid == NULL) || (size == 0)) goto bad_argument;
  369.  
  370.   printf("%s\n",c_log->info);
  371.   FILE* info = fopen(c_log->info,"a+");
  372.   if(info == NULL) goto log_error;
  373.   fprintf(info,"access point bssid : %s\naccess point ssid : %s\nstation id : %s\ndata size : %u\n",mac, ssid, id, size);
  374.   fclose(info);
  375.  
  376.   headers(sock_client);
  377.   unsigned int k = 0;
  378.   for(k = 0; k < size; k=k+100){
  379.     if(send(sock_client, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n", 100, 0) < 0)
  380.       break;
  381.     write_tcp_info(sock_client, c_log->s_file, &(c_log->file_mutex));
  382.   }
  383.  
  384.    
  385.  
  386. bad_argument:
  387. log_error:
  388.   if(id != NULL) free(id);
  389.   if(mac != NULL) free(mac);
  390.   if(ssid != NULL) free(ssid);
  391.  
  392.   return;
  393. }
  394.  
  395.  
  396. /**********************************************************************/
  397. /* Handle the POST method, it just receive some data that it doesn't store
  398.  * Parameter: the client socket and the query string                  */
  399. /**********************************************************************/
  400. void client_post(int sock_client){
  401.   sock_client++;
  402. }
  403.  
  404.  
  405. void block_signal(){
  406.   sigset_t set;
  407.   sigemptyset(&set);
  408.   sigaddset(&set, SIGHUP);
  409.   sigaddset(&set, SIGINT);
  410.   sigaddset(&set, SIGUSR1);
  411.   sigaddset(&set, SIGUSR2);
  412.   sigaddset(&set, SIGALRM);
  413.   sigprocmask(SIG_BLOCK, &set, NULL);
  414. }
  415.  
  416. /**********************************************************************/
  417. /* A request has caused a call to accept() on the server port to
  418.  * return.  Process the request appropriately.
  419.  * Parameters: the socket connected to the client */
  420. /**********************************************************************/
  421. void* accept_request(void* p_client)
  422. {
  423.   //block_signal();
  424.   int client = *(int*)(p_client);
  425.   char* query = malloc(sizeof(char)*MAX_LINE_SIZE);
  426.  
  427.  
  428.   unsigned int port;
  429.   char ipstr[INET6_ADDRSTRLEN];
  430.   struct sockaddr_storage peer;
  431.   socklen_t len = sizeof peer;  
  432.   getpeername(client, (struct sockaddr*)&peer, &len);
  433.   if (peer.ss_family == AF_INET) { // IPv4
  434.     struct sockaddr_in *s = (struct sockaddr_in *)&peer;
  435.     port = ntohs(s->sin_port);
  436.     inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
  437.   } else { //IPv6
  438.     struct sockaddr_in6 *s = (struct sockaddr_in6 *)&peer;
  439.     port = ntohs(s->sin6_port);
  440.     inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
  441.   }
  442.   printf("%s connecté depuis le port %u\n", ipstr, port);
  443.   //print_list();
  444.  
  445.  
  446.   struct client_log* c_log = initialize_log(client);
  447.   if(c_log == NULL) goto no_log;
  448.   add_client(client, c_log);
  449.   switch(retrieve_method(client, query, MAX_LINE_SIZE)){
  450.     case HTTP_BAD_REQUEST:
  451.       client_bad_request(client);
  452.       break;
  453.     case ERR_SOCKET:
  454.       break;
  455.     case HTTP_METHOD_NOT_IMPLEMENTED:
  456.       client_unimplemented(client);
  457.       break;
  458.     case HTTP_METHOD_GET:
  459.       client_get(client, query, c_log);
  460.       break;
  461.     case HTTP_METHOD_POST:
  462.       client_post(client);
  463.       break;
  464.   }
  465.  
  466. no_log:
  467.   free(query);
  468.   struct client_list* current = first;
  469.   pthread_mutex_lock(&mutex_list);
  470.   while((current != NULL) && (current->sock != client)) current=current->next;
  471.   pthread_mutex_unlock(&mutex_list);
  472.   if(current != NULL) remove_from_list(current);
  473.   //print_list();
  474.   int retval = 0;
  475.   pthread_exit(&retval);
  476. }
  477.  
  478.  
  479. /**********************************************************************/
  480. /* Print out an error message with perror() (for system errors; based
  481.  * on value of errno, which indicates system call errors) and exit the
  482.  * program indicating an error. */
  483. /**********************************************************************/
  484. void error_die(const char *sc)
  485. {
  486.   perror(sc);
  487.   exit(1);
  488. }
  489.  
  490. /**********************************************************************/
  491. /* Get a line from a socket, whether the line ends in a newline,
  492.  * carriage return, or a CRLF combination.  Terminates the string read
  493.  * with a null character.  If no newline indicator is found before the
  494.  * end of the buffer, the string is terminated with a null.  
  495.  * Parameters: the socket descriptor
  496.  *             the buffer to save the data in
  497.  *             the size of the buffer
  498.  * Returns: the number of bytes stored
  499.  *          ERR_SOCKET if error on the socket
  500.  *          HTTP_BAD_REQUEST if line did not terminate with a CRLF    */
  501. /**********************************************************************/
  502. int get_line(int sock, char *buf, int size)
  503. {
  504.   int i = 0, n;
  505.   char c = '\0';
  506.   //int crlf=0;
  507.  
  508.   while ((i < size - 1) && (c != '\n'))
  509.   {
  510.     n = recv(sock, &c, 1, 0);
  511.     //printf("%02x\n",c);
  512.     /*
  513.     if(n <= 0) return ERR_SOCKET;
  514.     switch(crlf){
  515.       case 0: if(c == '\r') crlf=1;
  516.                 break;
  517.       case 1: if(c == '\n') crlf=2;
  518.                 break;
  519.     }
  520.     */
  521.     buf[i] = c;
  522.     i++;
  523.   }
  524.   buf[i] = '\0';
  525.   //if(crlf != 2) return HTTP_BAD_REQUEST;
  526.   //else return i;
  527.   return i;
  528. }
  529.  
  530. /**********************************************************************/
  531. /* Return the informational HTTP headers about a file. */
  532. /* Parameters: the socket to print the headers on
  533.  *             the name of the file */
  534. /**********************************************************************/
  535. void headers(int client)
  536. {
  537.   char buf[1024];
  538.  
  539.   strcpy(buf, "HTTP/1.0 200 OK\r\n");
  540.   send(client, buf, strlen(buf), 0);
  541.   strcpy(buf, SERVER_STRING);
  542.   send(client, buf, strlen(buf), 0);
  543.   sprintf(buf, "Content-Type: text/html\r\n");
  544.   send(client, buf, strlen(buf), 0);
  545.   strcpy(buf, "\r\n");
  546.   send(client, buf, strlen(buf), 0);
  547. }
  548.  
  549.  
  550. /**********************************************************************/
  551. /* This function starts the process of listening for web connections
  552.  * on a specified port.  If the port is 0, then dynamically allocate a
  553.  * port and modify the original port variable to reflect the actual
  554.  * port.
  555.  * Parameters: pointer to variable containing the port to connect on
  556.  * Returns: the socket */
  557. /**********************************************************************/
  558. int startup(u_short *port)
  559. {
  560.   int httpd = 0;
  561.   struct sockaddr_in name;
  562.  
  563.   httpd = socket(PF_INET, SOCK_STREAM, 0);
  564.   if (httpd == -1)
  565.     error_die("socket");
  566.   memset(&name, 0, sizeof(name));
  567.   name.sin_family = AF_INET;
  568.   name.sin_port = htons(*port);
  569.   name.sin_addr.s_addr = htonl(INADDR_ANY);
  570.   if (bind(httpd, (struct sockaddr *)&name, sizeof(name)) < 0)
  571.     error_die("bind");
  572.   if (*port == 0)  /* if dynamically allocating a port */
  573.   {
  574.     unsigned int namelen = sizeof(name);
  575.     if (getsockname(httpd, (struct sockaddr *)&name, &namelen) == -1)
  576.       error_die("getsockname");
  577.     *port = ntohs(name.sin_port);
  578.   }
  579.   if (listen(httpd, 10) < 0)
  580.     error_die("listen");
  581.   return(httpd);
  582. }
  583.  
  584.  
  585. /**********************************************************************/
  586.  
  587. int main(void)
  588. {
  589.  
  590.   //create core file for crash
  591.  
  592.  
  593.  
  594.   first = malloc(sizeof(struct client_list));
  595.   first->sock = -1;
  596.   first->pid = 0;
  597.   first->c_log = NULL;
  598.   first->next = first;
  599.   first->prev = first;
  600.  
  601.   signal(SIGINT, server_stop);
  602.   u_short port = SERVER_PORT;
  603.   struct sockaddr_in client_name;
  604.   unsigned int client_name_len = sizeof(client_name);
  605.  
  606.   first->sock = startup(&port);
  607.   printf("httpd running on port %d\n", port);
  608.  
  609.   pthread_t newthread;
  610.  
  611.   while (1)
  612.   {
  613.     int client_sock = accept(first->sock,
  614.         (struct sockaddr *)&client_name,
  615.         &client_name_len);
  616.     if (client_sock == -1)
  617.       error_die("accept");
  618.     if (pthread_create(&newthread , NULL, accept_request, &client_sock) != 0)
  619.       perror("pthread_create");
  620.   }
  621.  
  622.   server_stop(0);
  623.  
  624.   return(0);
  625. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement