
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>

#include <unistd.h>

#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <limits.h>
#include <iostream.h>
#include <fstream.h>
#include <strings.h>
#include <string.h>
#include <new>
#include "system.h"
#include "server.h"
#include "support.h"

int do_shutdown;
int server_reboot;


void sig_term_handler(int signo)
{
   if( (signo != SIGSEGV) && (signo != SIGBUS) && (signo != SIGIOT) )
   {
      cerr << "Got signal: " << signo << " NOT setting to default handler." << endl;
      signal( signo, (&sig_term_handler) );
   }
   else
   {
      cerr << "Got signal: " << signo << " setting to default handler." << endl;
      signal( signo, SIG_DFL );
   }

   if( signo == SIGTERM )
   {
      do_shutdown = TRUE;
   }
   else if( signo == SIGALRM );
   else if( signo == SIGHUP );
   else if( signo == SIGIO );
   else if( signo == SIGPIPE );
   else if( signo == SIGSTOP )
      do_shutdown = TRUE;
   else if( signo == SIGINT )
      do_shutdown = TRUE;
   else if( signo == SIGTTIN );
   else if( signo == SIGTTOU );
   else if( ( signo == SIGUSR1 ) || ( signo == SIGUSR2 ) );
   else if( signo == SIGVTALRM );
   else if( signo == SIGXCPU )
      do_shutdown = TRUE;
   else if( signo == SIGXFSZ )
      do_shutdown = TRUE;
   else if( ( signo == SIGSEGV ) || ( signo == SIGIOT ) )
      abort();
   else if( signo == SIGBUS )
      abort();
   else
      do_shutdown = FALSE;
}


struct timeval timediff( struct timeval *a, struct timeval *b )
{
   struct timeval rslt, tmp;
   tmp = *a;
   if( ( rslt.tv_usec = tmp.tv_usec - b->tv_usec ) < 0 )
   {
      rslt.tv_usec += 1000000;
      --(tmp.tv_sec);
   }
   if( ( rslt.tv_sec = tmp.tv_sec - b->tv_sec) < 0)
   {
      rslt.tv_usec = 0;
      rslt.tv_sec = 0;
   }
   return(rslt);
}


int init_socket(int port)
{
   int  s;
   char *opt;
   char hostname[ MAX_HOSTNAME + 1 ];
   struct sockaddr_in sa;
   struct hostent *hp;
   memset( (char*)(&sa), 0, sizeof( struct sockaddr_in ) );

   if( gethostname( hostname, MAX_HOSTNAME ) < 0 );

   hp = gethostbyname(hostname);
   if(hp == NULL)
   {
      do_shutdown = TRUE;
      exit(100);
   }
   sa.sin_family = hp->h_addrtype;
   sa.sin_port   = htons(port);

   if((s = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0)
   {
      do_shutdown = TRUE;
      exit( 100 );
   }

   if( setsockopt( s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof (opt) ) < 0)
   {
      do_shutdown = TRUE;
      exit(100);
   }

   int sanity = 0;
   bool loop = true;
   while( loop )
   {
      if (sanity++ > 25)
      {
         close(s);
         do_shutdown = true;
         exit(0);
      }

      if( bind( s, (struct sockaddr*)&sa, sizeof( sa ) ) < 0 )
         sleep(10);
      else
         loop = false;
   }

   listen( s, 5 );
   return( s );
}

int new_connection( int s )

   struct sockaddr_in isa;
#if defined(_LINUX_)
   unsigned int  i;
#else
   int i;
#endif
   int t;

   i = sizeof(isa);
   if (getsockname(s, (struct sockaddr *) & isa, &i) < 0)
      return (-1);

   if((t = accept(s, (struct sockaddr *)(&isa), &i)) < 0)
      return(-1);

#if !defined(FNDELAY)
#define FNDELAY O_NDELAY
#endif
   if( fcntl( t, F_SETFL, FNDELAY ) == -1 )
   {
      cerr << "New_descriptor: fcntl: FNDELAY\n";
      return -1;
   }
//   nonblock(t);
   return(t);
}


void nonblock(int s)
{
   int  flags;

   flags = fcntl( s, F_GETFL );
   flags |= O_NONBLOCK;
   if (fcntl(s, F_SETFL, flags) < 0)
   {
      do_shutdown = TRUE;
      exit( 100 );
   }
}

void close_sockets(int mother)
{
   close( mother );
}

