Sample internet server

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <errno.h>
#include <ctype.h>

void subprocess_ended(int xxx)
{ int process_id,exit_status;
  process_id=wait(&exit_status); }

void control_c(int xxx)
{ signal(SIGINT, SIG_DFL);
  printf("[Received halt signal, waiting for subprocesses]\n");
  while (1)
  { int r=wait(NULL);
    if (r<0) break; }
  printf("[Server terminated]\n");
  exit(2); }

void serve(FILE *reader, FILE *writer)
{ char line[1028];
  while (1)
  { fprintf(writer, "go ahead: ");
    fflush(writer);
    printf("sent: go ahead: \n");
    char *s=fgets(line, sizeof(line), reader);
    if (s==NULL) break;
    printf("received: %s", line);
    int fn=0, answer;
    s=strtok(line, " \r\n");
    if (s!=NULL)
    { if (strcasecmp(s, "add")==0) { fn='+'; answer=0; }
      else if (strcasecmp(s, "multiply")==0) { fn='*'; answer=1; }
      else if (strcasecmp(s, "exit")==0) return; }
    if (fn!=0)
    { while (1)
      { s=strtok(NULL, " \r\n");
        if (s==NULL) break;
        int n=atol(s);
        if (fn=='+') answer+=n;
        else if (fn=='*') answer*=n; }
      fprintf(writer, "answer = %d\n", answer);
      fflush(writer);
      printf("sent: answer = %d\n", answer); }
    else
    { fprintf(writer, "not understood\n");
      fflush(writer);
      printf("sent: not understood\n"); } } }

int socket_connected_to_random_port(int & portnum)
{ struct sockaddr_in connection_info;
  int sock=socket(AF_INET, SOCK_STREAM, 0);
  if (sock<0) { perror("socket creation"); exit(1); }
  while (1)
  { portnum=1024+(random() & 0x1FFF);
    bzero(&connection_info, sizeof(connection_info));
    connection_info.sin_family=AF_INET;
    connection_info.sin_addr.s_addr=htonl(INADDR_ANY);
    connection_info.sin_port=htons(portnum);
    int r=bind(sock, (sockaddr *)&connection_info, sizeof(connection_info));
    if (r>=0) break; }
  return sock; }

void main(void)
{ srandomdev();
  int portnum;
  int main_socket=socket_connected_to_random_port(portnum);
  printf("[server established on port %d]\n", portnum);

  signal(SIGCHLD, subprocess_ended);
  signal(SIGINT, control_c);

  int r=listen(main_socket, 3);
  if (r<0)
  { perror("listen");
    exit(1); }

  while (1)
  { struct sockaddr_in client_info;
    unsigned int ci_size=sizeof(client_info);
    int session_socket=accept(main_socket, (sockaddr *)&client_info, &ci_size);
    if (session_socket<0)
    { if (errno==EINTR) continue;
      perror("accept");
      sleep(1);
      continue; }
    int pid=fork();
    if (pid==0)
    { char clientname[100];
      struct in_addr client_addr;

      client_addr.s_addr=client_info.sin_addr.s_addr;
      strcpy(clientname,inet_ntoa(client_addr));
      printf("[connection accepted from %s]\n", clientname);

      FILE * r_connection=fdopen(session_socket,"r");
      FILE * w_connection=fdopen(session_socket,"w");
      if (w_connection==NULL || r_connection==NULL)
      { printf("[bad connection, session terminated]\n");
        exit(1); }

      serve(r_connection, w_connection);

      printf("[disconnecting from %s]\n", clientname);
      exit(0); }

    close(session_socket); } }