/*
A quick and dirty webserver that does almost nothing.
23 feb 2001 Junichi Uekawa


*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define MAXHOSTNAMELEN 256	/* max hostname len per manpage  */
#define BACKLOG 256		/* max backlog to listen to */

#define TMPBUFSIZE 2048		/* length of incoming command to accept */


void openanddump(int sock, char * filename)
{
  FILE * f = fopen ( filename , "r");
  int readbytes;
  char buf [ TMPBUFSIZE + 1 ] ;
  static char * message = 
    "HTTP/1.1 200 OK\n" 
    "Server: Upaccho\n"
    "Content-Type: text/html\n\n";
    
  if (f)
    {
      write (sock, message, strlen(message));
      
      while (0!=( readbytes = fread ( buf, 1, TMPBUFSIZE, f )))
	{
	  write ( sock, buf, readbytes);	  
	}
      
      fclose(f);
    } 
}


void handle_incoming(int sock)
{
  static char buf [ TMPBUFSIZE + 1 ] ;	/* incoming buffer */
  static char buf_processed [TMPBUFSIZE + 1 ];
  static char filename [ TMPBUFSIZE + 1024 ]; /* using this to handle work */
  static char htmlversion [TMPBUFSIZE + 1 ];
  
  int i;
  int strlength ;
  
  
  if ((i = read (sock, buf, TMPBUFSIZE))<= 0)
    return ;
  buf [i] = 0;
  printf ("DEBUG:\n"
	  "==============================================\n"
	  "%s\n"
	  "==============================================\n\n", buf);
  

  if (strlen (buf) > 4)
    {
      sscanf (buf, "GET %s %s", buf_processed, htmlversion);
      strlength = strlen (buf_processed);
      if (buf_processed[strlength - 1 ] == '/')
	sprintf(filename, ".%sindex.html", buf_processed);
      else
	sprintf(filename, ".%s", buf_processed);
      
      openanddump(sock, filename);      
    }
}


int main (int ac, char** av)
{
  char localhostname [MAXHOSTNAMELEN + 1] ;
  struct sockaddr_in sa, tmpisa;
  int incoming_socket;		/* the main waiting socket */
  int t;			/* new incoming calls */
  struct hostent *hp;
  int i;
  
  
  
  puts ("Upaccho web server version 0.0.0\n"
	"copyright 2001 Junichi Uekawa\n");
  if (ac != 2)
    {
      fprintf(stderr, "Please specify the port as the command-line parameter\n");
      exit(1);
    }
   
  
  gethostname (localhostname, MAXHOSTNAMELEN) ;
  if ((hp = gethostbyname(localhostname)) == NULL)
    {
      fprintf(stderr, "%s: cannot get localhost info\n", av[0]);
      exit (1);
    }
  if ((incoming_socket = socket (hp->h_addrtype, SOCK_STREAM, 0 )) == -1 )
    {
      perror  ("socket");
      exit (1);      
    }

  sa.sin_port = htons(atoi(av[1]));	/* this should hopefully be portable */
  memcpy((char*)&sa.sin_addr, (char*)hp->h_addr, hp->h_length);
  sa.sin_family = hp->h_addrtype;
  
  if (bind(incoming_socket, &sa, sizeof(sa)) < 0  ) 
    {
      perror ("bind");
      exit (1);
    }

  listen (incoming_socket, BACKLOG);

    while (1)
    {
      i = sizeof (tmpisa);
      if ((t = accept (incoming_socket, &tmpisa, &i )) == -1)
	{
	  perror ("accept");
	  exit (1);
	}
      handle_incoming( t );
      close(t);
    }

    //  close (incoming_socket);    
}
