Consider the following program.
static void
handle_connection(int connection_fd)
{
  char id[4];
  int i, index, n;
  read(connection_fd, id, 3);
  id[3] = '\0';
  
  index = get_index(id);
  if (index < 0)
    {
      write(connection_fd, "No Such Course", 15);
    }
  else
    {
      n = lines[index];
      for (i=0; i<n; i++)
        {
          write(connection_fd, description[index][i], 70);
          write(connection_fd, "\n", 1);
        }
    }
  close(connection_fd);
}
int main(void)
{
  int connection_fd, listening_fd;
  int pid;
  struct sockaddr_in address;
  
  memset(&address, 0, sizeof(address));
  address.sin_family = AF_INET;
  address.sin_port = htons(22801);
  address.sin_addr.s_addr = htonl(INADDR_ANY);
  listening_fd = socket(AF_INET, SOCK_STREAM, 0);
  bind(listening_fd, (struct sockaddr *)&address, sizeof(struct sockaddr));
  listen(listening_fd, 0);
  while (1)
    {
      connection_fd = accept(listening_fd, NULL, NULL);
      handle_connection(connection_fd);
    }
  return 0;
}  
- 
     Is this a client or a server (at the application layer)?
     
 
- 
     Rewrite the above program so that it handles each connection in
     its own process.
     
 
- 
     Rewrite the above program so that it handles each connection in
     its own thread. (Note: You must use a wrapper for the 
     
handle_connection() function. That is, you must not
     change the signature of the handle_connection()
     function.)