/*****************************************************************************
  TCPtt_s  : TCP Typewriter Example Server

  Copyright (C) 1996, Michael J. Andrews
  ALL RIGHTS RESERVED
*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include "netinfo.h"

void main(void)
{
  int                  fdSocket;      /* Holds the socket file descriptor
					 number that the server will
					 bind itself to and use to
					 listen for incoming connections */
  int                  fdNewSocket;   /* The socket file descriptor
					 that the server will accept
					 and use to communicate with
					 clients */
  struct sockaddr_in   AddrServ;      /* Address information structure
					 for us */
  struct sockaddr_in   AddrClient;    /* Address information structure
					 for the client we're
					 currently in communication
					 with */
  int                  clilen;        /* Will hold the length of the
					 address structure AddrClient */
  int                  childpid;      /* Becomes the process id number
					 of our forked off child */
  struct hostent       *clientdata;   /* Will point to data returned by a
					 gethostbyaddr() call */
  char                 buffer[255];   /* A character buffer */
  
                         /* Print out a header */
  printf("\nTCP Typewriter Server v1.0\n");
  printf("Setting up Server...");

  if ( (fdSocket=socket(AF_INET, SOCK_STREAM, 0)) <0)
    perror("TCPtt_s - Trying to initialize server");
                                  /* Opens a socket using the Internet
				     Family addressing scheme (IP) as
				     a stream (TCP). */

                         /* Fill out address structure for server */

  bzero((char *)&AddrServ, sizeof(AddrServ)); /* Erase anything that
		                                 might be hanging out
						 in our address
						 structure */
  AddrServ.sin_family=AF_INET;         /* AF_INET is the Internet
					  Protocol Family.  */
  AddrServ.sin_addr.s_addr=htonl(INADDR_ANY); /* Will accept incoming
						 connections from any
						 address */
  AddrServ.sin_port=htons(PORT_SERVER);       /* Server port number */
  
  if (bind(fdSocket, (struct sockaddr *)&AddrServ,
	    sizeof(AddrServ))<0 )
    perror("TCPtt_s - trying to bind server");  /* We "bind" the
						   server to the
						   information in
						   AddrServ */ 

  listen(fdSocket, 5);                          /* Listen for clients,
						   holding at most 5
						   in the queue */

  clilen=sizeof(AddrClient);
  printf("Okay.  Waiting for clients.\n\n");

  /******************** MAIN LOOP ***********************************/

  while(1)
    {
      fdNewSocket=accept(fdSocket,(struct sockaddr *)&AddrClient, &clilen);
                              /* Block until we accept (or we error
				 out) on an incoming TCP connection.
				 The addressing information for the
				 client will be stored in AddrClient */
      if (fdNewSocket<0) perror("TCPtt_s - Trying to accept connection");
                              /* Check for errors */

      /****** FORK BELOW ************/
      if ((childpid=fork())<0) perror("TCPtt_s - Trying to fork");
                              /* Fork off a child process to deal with
				 the new client */
      else if (childpid == 0) /* If childpid is 0, we're the child
				 process */
	{
	  if ((clientdata=malloc(sizeof(struct hostent)))==NULL)
	    perror("TCPtt_s - Trying to allocate RAM"); /* Allocate
							   some memory */
	  clientdata=gethostbyaddr((char *)&AddrClient.sin_addr,
				   sizeof(AddrClient.sin_addr), 
				   AF_INET);
	                      /* Retrieves useful information about
				 the client we just connected with,
				 including the official hostname */
	  while(1)
	    {
	      read(fdNewSocket, buffer, 80); /* Blocks further
						execution until 80
						characters are read,
						or EOF is reached */
	      printf("%s: %s\n", clientdata->h_name, buffer);
                    	      /* Print out "hostname: message */
	      if (!strcmp(buffer, "quit")) break; /* Exit out on
						     "quit" */
	    }
	  close(fdNewSocket);      /* Close the client's socket */
	  free(clientdata);        /* Free up the memory we allocated
				      earlier */
	  exit(0);
	}
    }
  close(fdSocket); /* I guess we never get here.  Too bad. */
}



