/* This contains functions to send and receive data from the server */
/* ---------------------------------------------------------------- */

#include "headers.h" /* has all important stuff */

/* This file has the server I/O functions.. to communicate with server */

/* send data to server */
void send_data(int fd, char *fmt, ...)
{
   int res;
   int ch = 0;
   int size = 2;

#  ifndef NOSSL
   int sslerr = 0;
   int dobreak = 0;
#  endif

   va_list args;

   char *lnptr, *cmdptr;
   char writebuf[MAXWRITESIZE];
   
   errors = 0;

   memset(writebuf, 0, sizeof(writebuf));
   memset(clients[curClient].logmsg.cmdmsg, 0, MAXSEGSIZE);

   va_start(args, fmt);
   (void)vsnprintf(writebuf, sizeof(writebuf) - 1, fmt, args);
   va_end(args);
    
   (void)strncpy(clients[curClient].logmsg.cmdmsg, writebuf, MAXSEGSIZE - 1);
   clients[curClient].logmsg.cmdlen = strlen(clients[curClient].logmsg.cmdmsg);

   if (child == 1)
   {
      if (getpid() == clients[curClient].pidstats[0].pid) ch = 0;
      else ch = 1;
   }

   if (((writebuf[0] == '\n') || (writebuf[0] == '\0')) && 
       (isprint(writebuf[1]) == 0))
   {
#     ifdef NOSSL
      if (silent != 1)
      {
         if (child == 1)
            debug("[in recv_data] (in %s)\n"
                  "the data received is bad.. returning\n\n",
                  (ch == 1 ? "child" : "parent"));

         else
            debug("(in recv_data) the data received is bad.. "
                  "returning\n\n");

         debug("bad data is:\n%s\n", readbuf);
      }

#     else
      error("client possibly disconnected.. aborting\n\n");

      if (mainpid != getpid()) quit(ERROR);
      else 
      {
         errors = 1;
         longjmp(newconn, 1);
      }
#     endif

      return;
   }

   if (silent != 1)
   {
      if (strlen(writebuf) <= 12)
         debug("sending the following to the client: %s%c", 
               writebuf, (strchr(writebuf, '\n') == NULL ? '\n' : '\0'));

      else
         debug("sending the following to the client:\n%s\n%c", 
               writebuf, (strchr(writebuf, '\n') == NULL ? '\n' : '\0'));
   }

   errno = errors = 0;

   cmdptr = clients[curClient].logmsg.cmdmsg;
   lnptr = exportInt(clients[curClient].logmsg.cmdlen);

   size = 2;
   while(1) 
   {
      errno = 0, res = 0;

#     ifndef NOSSL
      res = SSL_write(clients[curClient].sslconn, lnptr, (u_int)size);
#     else
      res = write(clients[curClient].sockfd, lnptr, size);
#     endif

      /* ---------------------- */

#     ifndef NOSSL /* SSL error handling */
      sslerr = SSL_get_error(clients[curClient].sslconn, res);
      switch(sslerr)
      {
         case SSL_ERROR_NONE:
            if (size == res) 
            {
               dobreak = 1;
               break;
            }

            lnptr += res, size -= res;
            break;

         case SSL_ERROR_WANT_WRITE:
         case SSL_ERROR_WANT_READ:
         case SSL_ERROR_WANT_X509_LOOKUP:
            errors = 1, dobreak = 1;
            break;

         case SSL_ERROR_SYSCALL:
         case SSL_ERROR_SSL:
            errors = 1, dobreak = 1;
            break;

         case SSL_ERROR_ZERO_RETURN:
            errors = 1, dobreak = 1;
            break;         
      }

      if (dobreak == 1)
      {
         dobreak = 0;
         break;
      }

#     else /* normal error handling */
      if (res <= 0)
      {
         if ((res == ERROR) && (errno == EINTR)) continue;

         errors = 1;
         break;
      }

      else if (res < size)
      {
         lnptr += res, size -= res;
         continue;
      }

      else break;
#     endif /* SSL/NOSSL error handling part */
   }

   if (errors != 1)
   {
      size = clients[curClient].logmsg.cmdlen;

      while(1)
      {
         errno = 0, res = 0;

#        ifndef NOSSL
         SSL_write(clients[curClient].sslconn, cmdptr, (u_int)size);
#        else
         res = write(clients[curClient].sockfd, cmdptr, size);
#        endif

         /* ---------------------- */

#        ifndef NOSSL /* SSL error handling */
         sslerr = SSL_get_error(clients[curClient].sslconn, res);
         switch(sslerr)
         {
            case SSL_ERROR_NONE:
               if (size == res) 
               {
                  dobreak = 1;
                  break;
               }

               cmdptr += res, size -= res;
               break;

            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_X509_LOOKUP:
               errors = 1, dobreak = 1;
               break;

            case SSL_ERROR_SYSCALL:
            case SSL_ERROR_SSL:
               errors = 1, dobreak = 1;
               break;

            case SSL_ERROR_ZERO_RETURN:
               errors = 1, dobreak = 1;
               break;         
         }

         if (dobreak == 1)
         {
            dobreak = 0;
            break;
         }

#        else /* normal error handling */
         if (res <= 0)
         {
            if ((res == ERROR) && (errno == EINTR)) continue;

            errors = 1;
            break;
         }

         else if (res < size)
         {
            cmdptr += res, size -= res;
            continue;
         }

         else break;
#        endif /* SSL/NOSSL error handling */
      }
   }

#  ifndef NOSSL /* SSL error handling part */
   switch(sslerr)
   {
      case SSL_ERROR_NONE:
         /* we don't need to do anything for this */
         break;

      case SSL_ERROR_WANT_WRITE:
      case SSL_ERROR_WANT_READ:
      case SSL_ERROR_WANT_X509_LOOKUP:
         error("got SSL_ERROR_WANT_(WRITE/READ/X509_LOOKUP).. ignoring\n\n");
         errors = 0;

         break;

      case SSL_ERROR_SYSCALL:
      case SSL_ERROR_SSL:
         if (errno <= 0)
         { 
            errors = 0;
            break;
         }

         error("error with SSL_write: %s\n\n", strerror(errno));

         ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
         if (debugging == 1) ERR_print_errors_fp(dblogfd1);

         if (mainpid != getpid()) quit(ERROR);
         else
         {
            errors = 1, timeout = 0;
            longjmp(newconn, 1);
         }

      case SSL_ERROR_ZERO_RETURN:
         if (mainpid != getpid())
         {
            error("client dropped connection.. aborting\n\n");
            quit(ERROR);
         }

         else
         {
            error("client dropped connection.. restarting\n\n");

            errors = 1, timeout = 0;
            longjmp(newconn, 1);
         }
   }

#  else /* no SSL normal error handling */

   if (res <= 0)
   {
      if (res == 0)
      {
         if (getpid() != mainpid) 
         {
            error("the client disconnected.. aborting\n\n");
            quit(ERROR);
         }

         else
         {
            errors = 1;
            error("the client disconnected.. restarting\n\n");

            longjmp(newconn, 1);
         }
      }

      else if (errno > 0)
      {
         if (child == 1)
         {
#           ifndef NOSSL
            ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
            if (debugging == 1) ERR_print_errors_fp(dblogfd1);

            else
               error("(in %s) error sending data to client:\n%s\n\n",
                     (ch == 1 ? "child" : "parent"), strerror(errno));

#           else
            error("(in %s) error sending data to client:\n%s\n\n",
                  (ch == 1 ? "child" : "parent"), strerror(errno));
#           endif
         }

         else
         {
#           ifndef NOSSL
            ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
            if (debugging == 1) ERR_print_errors_fp(dblogfd1);

#           else
            error("error sending data to client:\n%s\n\n", strerror(errno));
#           endif

         }

         if (mainpid != getpid()) quit(ERROR);
         else
         {
            errors = 1;
/*
            if (errno != EPIPE) 
               send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
*/

            longjmp(newconn, 1);
         }
      }

      else if ((timeout == 1) || (errors == 1))
      {
         if (silent != 1)
         {
#           ifndef NOSSL
            ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
            if (debugging == 1) ERR_print_errors_fp(dblogfd1);

#           else
            debug("(in send_data) error or timeout occured sending data\n");
#           endif
         }

         errors = 1, timeout = 0;

         if (getpid() != mainpid) quit(ERROR);
         else
         {
            send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);
            longjmp(newconn, 1);
         }
      }
   }
#  endif /* SSL/NOSSL (error checking part) */

/*
   if (strncmp(writebuf, "OKAY", 4) != 0)
   {
      signal(SIGALRM, okayTimeout);
      (void)alarm(MAXPAUSE);

      * silent = 1, * getOkay(), silent = 0;
      (void)alarm(0);

      if ((errors == 1) || (timeout == 1))
      {
         child = 0;
         send_data(clients[curClient].sockfd, "ERROR: %s\n", CMDACKERROR);

         if (mainpid != getpid()) quit(ERROR);
         else
         {
            errors = 1, timeout = 0;
            longjmp(newconn, 1);
         }
      }
   }
*/
}

   
/* --------------------------------- */
   

/* gets new data from server */
/* [all recv_data() calls must pass sizeof()-1] */
void recv_data(int fd, char *readbuf, int len, int notify)
{
   int res;
   int size = 2;

   int ch = 0;      /* 0 == not child.. parent, 1 == child   */

#  ifndef NOSSL
   int sslerr = 0;
   int dobreak = 0;
#  endif

   int first = 0;
   int newdata = 0; /* indicate new data when oldbuf is null */

   char length[2];
   char *lnptr, *cmdptr;

   if ((notify != 1) || (child != 1) || (clients[curClient].pinging != 1) ||
       (clients[curClient].pidstats[1].pid <= 0)) notify = 0;

   if (notify == 1)
   {
      if (getpid() == clients[curClient].pidstats[0].pid) ch = 0;
      else ch = 1;

      if (silent != 1) 
         debug("(in %s) receiving data...\n", (ch == 1 ? "child" : "parent"));
   }

   else if (silent != 1) debug("receiving data...\n");

   errno = errors = 0;
   memset(readbuf, 0, len);

   if ((ch == 0) || (notify == 0)) /* in parent */
   {
      errno = 0;
      lnptr = length, cmdptr = readbuf;

      size = 2;
      while(1)
      {
#        ifndef NOSSL
         res = SSL_read(clients[curClient].sslconn, lnptr, (u_int)size);
#        else
         res = read(clients[curClient].sockfd, lnptr, size);         
#        endif

         /* ---------------------- */

#        ifndef NOSSL /* SSL error handling */
         sslerr = SSL_get_error(clients[curClient].sslconn, res);
         switch(sslerr)
         {
            case SSL_ERROR_NONE:
               if (size == res) 
               {
                  dobreak = 1;
                  break;
               }

               lnptr += res, size -= res;
               break;

            case SSL_ERROR_WANT_WRITE:
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_X509_LOOKUP:
               errors = 1, dobreak = 1;
               break;

            case SSL_ERROR_SYSCALL:
            case SSL_ERROR_SSL:
               errors = 1, dobreak = 1;
               break;

            case SSL_ERROR_ZERO_RETURN:
               errors = 1, dobreak = 1;
               break;         
         }

         if (dobreak == 1)
         {
            dobreak = 0;
            break;
         }
         
#        else /* no SSL error handling */
         if (res <= 0)
         {
            if ((res == ERROR) && (errno == EINTR)) continue;

            errors = 1;
            break;
         }

         else if (res < size)
         {
            lnptr += res, size -= res;
            continue;
         }

         else break;
#        endif /* SSL/NOSSL error handling */
      }

      if (errors != 1)
      {
         /* clients[curClient].logmsg.cmdlen = importInt(length); */
         clients[curClient].logmsg.cmdlen = importInt(lnptr);

         if (clients[curClient].logmsg.cmdlen > len - 1)
         {
            error("(in recv_data) cmdlen > buflen.. truncating\n\n");
            clients[curClient].logmsg.cmdlen = len - 1;
         }

         size = clients[curClient].logmsg.cmdlen;
         while(1)
         {
#           ifndef NOSSL
            res = SSL_read(clients[curClient].sslconn, cmdptr, (u_int)size);
#           else
            res = read(clients[curClient].sockfd, cmdptr, size);
#           endif

            /* ---------------------- */

#           ifndef NOSSL /* SSL error handling */
            sslerr = SSL_get_error(clients[curClient].sslconn, res);
            switch(sslerr)
            {
               case SSL_ERROR_NONE:
                  if (size == res) 
                  {
                     dobreak = 1;
                     break;
                  }

                  cmdptr += res, size -= res;
                  break;

               case SSL_ERROR_WANT_WRITE:
               case SSL_ERROR_WANT_READ:
               case SSL_ERROR_WANT_X509_LOOKUP:
                  errors = 1, dobreak = 1;
                  break;

               case SSL_ERROR_SYSCALL:
               case SSL_ERROR_SSL:
                  errors = 1, dobreak = 1;
                  break;

               case SSL_ERROR_ZERO_RETURN:
                  errors = 1, dobreak = 1;
                  break;         
            }

            if (dobreak == 1)
            {
               dobreak = 0;
               break;
            }

#           else /* normal error handling */
            if (res <= 0)
            {
               if ((res == ERROR) && (errno == EINTR)) continue;

               errors = 1;
               break;
            }

            else if (res < size)
            {
               cmdptr += res, size -= res;
               continue;
            }

            else break;
#           endif /* SSL/NOSSL error handling */
         }
      }

#     ifndef NOSSL /* SSL error handling */
      switch(sslerr)
      {
         case SSL_ERROR_NONE:
            /* we don't need to do anything for this */
            break;

         case SSL_ERROR_WANT_WRITE:
         case SSL_ERROR_WANT_READ:
         case SSL_ERROR_WANT_X509_LOOKUP:
            error("got SSL_ERROR_WANT_(WRITE/READ/X509_LOOKUP).. "
                  "ignoring\n\n");

            errors = 0;
            break;

         case SSL_ERROR_SYSCALL:
         case SSL_ERROR_SSL:
            if (errno <= 0)
            { 
               errors = 0;
               break;
            }

            error("error with SSL_read: %s\n\n", strerror(errno));

            ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
            if (debugging == 1) ERR_print_errors_fp(dblogfd1);

            if (mainpid != getpid()) quit(ERROR);
            else
            {
               errors = 1, timeout = 0;
               longjmp(newconn, 1);
            }

         case SSL_ERROR_ZERO_RETURN:
            if (mainpid != getpid())
            {
               error("client dropped connection.. aborting\n\n");
               quit(ERROR);
            }

            else
            {
               error("client dropped connection.. restarting\n\n");

               errors = 1, timeout = 0;
               longjmp(newconn, 1);
            }
      }

#     else /* normal SSL error handling */
      if (res <= 0)
      {
         if (res == 0)
         {
            if (getpid() != mainpid) 
            {
               error("the client disconnected.. aborting\n\n");
               quit(ERROR);
            }

            else
            {
               errors = 1;
               error("the client disconnected.. restarting\n\n");
               longjmp(newconn, 1);
            }
         }

         else if (errno > 0)
         {
            if ((debugging == 1) && (silent != 1))
            {
               (void)putchar('\n'); 
               (void)write(dblogfd, "\n", 1);
            }

            if (notify == 1)
            {
#              ifndef NOSSL
               ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
               if (debugging == 1) ERR_print_errors_fp(dblogfd1);

#              else
               error("(in %s) error receiving data from client:\n%s\n\n", 
                     (ch == 1 ? "child" : "parent"), strerror(errno));
#              endif
            }

            else
            {
#              ifndef NOSSL
               ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
               if (debugging == 1) ERR_print_errors_fp(dblogfd1);

#              else
               error("error receiving data from client: %s\n\n", 
                     strerror(errno));
#              endif
            }

            if (mainpid != getpid()) quit(ERROR);
            else
            {
               errors = 1, timeout = 0;
               longjmp(newconn, 1);
            }
         }

         else if ((errors == 1) || (timeout == 1))
         {
            if (silent != 1) 
            {
#              ifndef NOSSL
               ERR_print_errors_fp(stderr), ERR_print_errors_fp(errlogfd1);
               if (debugging == 1) ERR_print_errors_fp(dblogfd1);

#              else
               debug("(in recv_data) error or timeout receiving data\n");
#              endif
            }

            child = 0;
            send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);

            if (mainpid != getpid()) quit(ERROR);
            else
            {
               errors = 1, timeout = 0;
               longjmp(newconn, 1);
            }
         }
      }
#     endif

      if (((readbuf[0] == '\n') || (readbuf[0] == '\0')) && 
          (isprint(readbuf[1]) == 0))
      {
#        ifdef NOSSL
         if (silent != 1)
         {
            if (child == 1)
               debug("[in recv_data] (in %s)\n"
                     "the data received is bad.. returning\n\n",
                     (ch == 1 ? "child" : "parent"));

            else
               debug("(in recv_data) the data received is bad.. "
                     "returning\n\n");

            debug("bad data is:\n%s\n", readbuf);
         }

#        else
         error("client possibly disconnected.. aborting\n\n");

         if (mainpid != getpid()) quit(ERROR);
         else 
         {
            errors = 1;
            longjmp(newconn, 1);
         }
#        endif

         return;
      }

      if (silent != 1)
      {
         if (notify == 1)
         {
            debug("(in %s) data received from the client\n",
                  (ch == 1 ? "child" : "parent"));

            if (strlen(readbuf) > 30)
               debug("(in %s) data is:\n%s\n%c", 
                     (ch == 1 ? "child" : "parent"), readbuf,
                     (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));

            else debug("(in %s) data is: %s%c", 
                       (ch == 1 ? "child" : "parent"), readbuf, 
                       (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
         }

         else
         {
            debug("data received from the client\n");

            if (strlen(readbuf) > 40)
               debug("data is:\n%s\n%c", readbuf, 
                     (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));

            else
               debug("data is: %s%c", readbuf, 
                     (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));
         }
      }
/*
      if (strncmp(readbuf, "OKAY", 4) != 0)
      {
         * (void)sleep(1); *

         * silent = 1, * send_data(clients[curClient].sockfd, "OKAY");
         silent = 0;

         if ((errors == 1) || (timeout == 1))
         {
            child = 0;
            send_data(clients[curClient].sockfd, "ERROR: %s\n", CMDACKERROR);

            if (getpid() != mainpid) quit(ERROR);
            else
            {
               errors = 1, timeout = 0;
               longjmp(newconn, 1);
            }
         }
      }

      else */

      if ((strncmp(readbuf, "QUIT", 4) == 0)  || 
          (strncmp(readbuf, "ERROR", 5) == 0))
      {
         if (mainpid != getpid()) signal(SIGPIPE, SIG_IGN);

         error("QUIT or ERROR received from client..\n"
               "the message was: %s\n%c", readbuf,
               (strchr(readbuf, '\n') == NULL ? '\n' : '\0'));

         child = 0;

         if (mainpid != getpid()) quit(ERROR);
         else 
         {
            errors = 1;
            longjmp(newconn, 1);
         }
      }

      if (notify == 0) return; /* we don't need to do this if there */
                               /* is no child to notify...          */

      if (clients[curClient].oldbuf[0] == '\0')
      {
         if (silent != 1)
            debug("(in %s) no data in oldbuf.. putting data in\n",
                  (ch == 1 ? "child" : "parent"));

         strncpy(clients[curClient].oldbuf, readbuf, 
                 sizeof(clients[curClient].oldbuf));

         newdata = 1, first = 1;
      }

      if (((newdata == 1) || 
          (strcmp(clients[curClient].oldbuf, readbuf) != 0)) && 
          ((strncmp(readbuf, "PONG", 4) == 0) || 
          (strncmp(readbuf, "OKAY", 4) == 0)))
      {
         if ((debugging == 1) && (silent != 1))
         {
            (void)putchar('\n'); 
            (void)write(dblogfd, "\n", 1);
         }

         if (clients[curClient].running == 0)
         {
            if (silent != 1) debug("(in parent) running = 0, now waiting\n");
            while (clients[curClient].running == 0) (void)sleep(1);
         }

         /* new data has been receiveed */
         if (silent != 1) debug("(in parent) sending SIGUSR1 to child\n");

         memset(clients[curClient].segptr, 0, MAXSEGSIZE);

         /* put it in shared mem */
         (void)strncpy(clients[curClient].segptr, readbuf, MAXSEGSIZE-1); 
         
         if (silent != 1) 
            debug("shared segment = %s%c", clients[curClient].segptr,
                  (strchr(clients[curClient].segptr, '\n') == NULL 
                          ? '\n' : '\0'));

         /* FIX - few problems.. first we could have missed any */
         /*     - data we got as SIGUSR2 is on like always...   */

         clients[curClient].running = 0;
         signal(SIGUSR2, startUp);

         res = seteuid(0); 
         if (res == ERROR)
         {
            error("error with seteuid: %s\n\n", strerror(errno)); 
            quit(ERROR);
         }

         /* notify child there is new data */
         res = kill(clients[curClient].pidstats[1].pid, SIGUSR1);
         if (res == ERROR)
         {
            error("error sending SIGUSR1 to child:\n%s\n\n",
                  strerror(errno));

            child = 0;
            send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);

            res = seteuid(pwd->pw_uid);
            if (res == ERROR)
            {
               error("error with seteuid: %s\n\n", strerror(errno)); 
               quit(ERROR);
            }

            if (mainpid != getpid()) quit(ERROR);
            else
            {
               errors = 1;
               longjmp(newconn, 1);
            }
         }

         res = seteuid(pwd->pw_uid);
         if (res == ERROR)
         {
            error("error with seteuid: %s\n\n", strerror(errno)); 
            quit(ERROR);
         }

         if ((debugging == 1) && (silent != 1))
         {
            (void)putchar('\n'); 
            (void)write(dblogfd, "\n", 1);
         }

         /* while (clients[curClient].running == 0) sleep(1); */

         return;
      }

      else
      {
         if ((silent != 1) && (first != 1))
            debug("(in %s) new data was duplicate data.. ignoring\n",
                  (ch == 1 ? "child" : "server"));

         else first = 0;

         return;
      }
   }

   else /* if (ch == 1) */
   {
      if (clients[curClient].newData != 1)
      {
         if (silent != 1) debug("(in child) newData = 0, now waiting\n");
         while (clients[curClient].newData == 0) sleep(NORMPAUSE);
      }

      errno = 0;
      if ((debugging == 1) && (silent != 1))
      {
         (void)putchar('\n'); 
         (void)write(dblogfd, "\n", 1);
      }

      /* make sure buffer is blank */
      memset(readbuf, 0, len);

      if (silent != 1)
         debug("shared segment = %s%c", clients[curClient].segptr,
              (strchr(clients[curClient].segptr, '\n') == NULL ? '\n' : '\0'));

      memcpy(readbuf, clients[curClient].segptr, len), readbuf[len] = '\0';

      if (silent != 1)
         debug("readbuf (after copying seg) = %s%c", readbuf,
              (strchr(clients[curClient].segptr, '\n') == NULL ? '\n' : '\0'));

      clients[curClient].newData = 0; /* reset new data marker */

      res = seteuid(0);
      if (res == ERROR)
      {
         error("error with seteuid: %s\n\n", strerror(errno)); 
         quit(ERROR);
      }

      /* tell parent we got data.. it can continue */
      res = kill(clients[curClient].pidstats[0].pid, SIGUSR2);
      if (res == ERROR)
      {
         child = 0;
         send_data(clients[curClient].sockfd, "ERROR: %s\n", INTERROR);

         res = seteuid(pwd->pw_uid);
         if (res == ERROR)
         {
            error("error with seteuid: %s\n\n", strerror(errno)); 
            quit(ERROR);
         }

         if (mainpid != getpid()) quit(ERROR);
         else
         {
            errors = 1;
            longjmp(newconn, 1);
         }
      }

      res = seteuid(pwd->pw_uid);
      if (res == ERROR)
      {
         error("error with seteuid: %s\n\n", strerror(errno)); 
         quit(ERROR);
      }

      return;
   }
}
