#include "ufk.h"
#include <signal.h>
#include <stat.h>

/*
 *      s e r v e r
 */

server()
{
   char num, i;
   int len;
   extern char rec_filnam[];
   char filename[50];
   struct stat statbuf;

   if (!open_port(TRUE,FALSE))         /* Setup communication port */
      prterr(ER_POPNERR);
   else
   {
      n = 0;                           /* initialize message number */
      numtry = 0;                      /* say no tries yet */
      sflg = 0;
      set_frame();
      posit(0,21);
      if (!nooutput)
      {
         if (remote)
         {
            fputs("Server running... Type your kermit 'BYE' or 'FINISH'\n\l",
                  stdout);
            fputs("commands, or ctrl-X to quit the server.\n\l",stdout);
         }
         else
           fputs("Type ctrl-X to quit the server.\n\l",stdout);
      }
      set_default_comm();              /* Set default communication */
      if (alloc_pkt(RECEIVE))          /* Setup packet buffers */
         while(TRUE)
         {
            aborted = FALSE;           /* Reset eventual abort condition */
            switch(rpack(&len,&num,recpkt,1))/* do this as long as necessary */
            {
               case 'S':
                     rflg++;           /* Flag receive file */
                     set_frame();
                     n = num;
                     rpar(recpkt,len);  /* setup receive parameters */
                     spar(sndpkt,&len); /* setup transmit parameters */
                     spack('Y',n,len,sndpkt,0,1);
                     alloc_pkt(RECEIVE);/* Define correct buffers */
                     numtry = 0;
                     rec_filnam[0] = '\0'; /* Use default name */
                     n = (n + 1) % 64;
                     recsw('F');        /* switch to 'F' state */
                     break;

               case 'I':
                     set_frame();
                     n = num;
                     rpar(recpkt,len);   /* setup receive parameters */
                     spar(sndpkt,&len);  /* setup transmit parameters */
                     spack('Y',n,len,sndpkt,0,1);
                     break;

               case 'R':
                     i = 0;
                     do
                        filename[i] = recpkt[i]; /* copy filename */
                     while((recpkt[i++] != '\0') && (i < len));
                     filename[i] = '\0';   /* Mark end of string */
                     numprm = 2;
                     params[1] = filename; /* Setup pointer to filename */
                     if (get_file_spec(TRUE))/* Parse filespec */
                     {
                        sflg = 2;          /* Flag send file */
                        set_frame();
                        alloc_pkt(SEND);   /* Define correct buffers */
                        sendsw();          /* Send file */
                        n = 0;
                     }
                     else
                        error(PER_OPEN,"%s",filename); /* Cannot open file */
                     break;

               case 'G':                   /* 'general' command */
                     set_frame();
                     switch(*recpkt)
                     {
                        case 'L':          /* logout */
                                 spack('Y',num,0,0,0,1);  /* acknowledge */
                                 kdelay(1); /* Give him time for response */
                                 close_port(TRUE,TRUE);
                                 stat("/act/utmp",&statbuf);
                                 if (statbuf.st_size != 0)/* su mode if not 0*/
                                    kill(0,SIGKILL);/* stop if successful */
                                 else
                                    exit(0);  /* Normal exit in su mode */

                        case 'F':          /* finish */
                                 spack('Y',num,0,0,0,1);  /* acknowledge */
                                 close_port(TRUE,FALSE);
                                 return;

                        default:
                                 error(PER_UNIMPL); /* Not implemented */
                     }
                     break;

               case 'T':                   /* timeout */
                     if (aborted)
                     {
                        close_port(TRUE,FALSE);
                        return;            /* aborted by user */
                     }
                     spack('N',n,0,0,0,1); /* send NAK */
                     break;

               case 'N':
               case 'E':
                     break;                /* Eat NAK and error packet */

               case FALSE:
                     error(PER_PACKET);    /* Packet error */
                     break;

               default:
                     if (aborted)
                     {
                        close_port(TRUE,FALSE);
                        return;
                     }
                     error(PER_UNIMPL);    /* Not implemented */
            }
            rflg = sflg = 0;
            set_default_comm();            /* Set default communication */
         }
      close_port(TRUE,FALSE);
   }
}

/*
 * stop remote server
 */

finish()
{
   if (remote)
      prterr(ER_ILLREMOT);
   else
   {
      if (!do_generic('F'))
      {
         disp(0,18,"Finish failed\n");
         beep();
      }
      close_port(TRUE,FALSE);
   }
}

/*
 * log out remote server and local kermit
 */

bye()
{
   if (remote)
      prterr(ER_ILLREMOT);
   else
   {
      if (!do_generic('L'))
      {
         disp(0,18,"Bye failed\n");
         beep();
      }
      else
      {
         close_port(TRUE,FALSE);
         kerm_exit();
      }
      close_port(TRUE,FALSE);
   }
}

/*
 * send server function
 */

do_generic(function)
char function;
{
   char num;
   int len;

   n = 0;                                 /* initialize message number */
   numtry = 0;                            /* say no tries yet */

   if (!open_port(TRUE,FALSE))            /* Setup communication port */
      prterr(ER_POPNERR);
   else
   {
      if (alloc_pkt(SEND))                /* Setup buffers */
      {
         set_frame();
         set_default_comm();              /* setup default communication */
         *sndpkt = function;              /* insert GENERIC command */
         *(sndpkt+sizeof(char)) = '\0';   /* For debug printout */

         while(TRUE)
         {
            num = 0;
            spack('G',num,1,sndpkt,0,1);  /* send GENERIC packet */
            switch(rpack(&len,&num,recpkt,1))
            {
               case 'Y':
                        return(TRUE);     /* valid response */

               case 'E':
                        prerrpkt(recpkt);
                        return(FALSE);    /* received an error */

               case 'T':
                        if (aborted)
                           return(FALSE); /* aborted by user */

               default:
                        if (numtry++ > maxtry)
                           return(FALSE); /* too many errors */
            }
         }
      }
   }
   return (FALSE);                     /* failure */
}
