
/* Placed in the public domain by the author David Kinzer */

#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/ports.h"
#include "exec/libraries.h"
#include "exec/devices.h"
#include "exec/io.h"
#include "devices/serial.h"

#include <stdio.h>

#define BUFLEN 256
#define LOGNAMELENGTH 30
#define PASSWORDLENGTH 30

main(ac,av)
int ac;
char *av[];
{
FILE *pwfile, *banfile;
char buf[BUFLEN],logname[LOGNAMELENGTH],password[PASSWORDLENGTH];
char *pwptr,*comptr;
int commandflag = 0;
int earlyend = 0;  /* error exit flag, not yet used */

   if (ac < 2) return;   /* no password file given, error */
   
   pwfile = fopen(av[1],"r");
   if (pwfile) {
      /* password file opened */
      if (!openamigaserial()) {
         /* serial port is available, prompt user */
         
         /* send out banner file, if requested */
         if (ac > 2) {
            banfile = fopen(av[2],"r");
            if (banfile) {
               while (fgets(buf,BUFLEN,banfile)) 
                  writeamigaserial(buf);
               fclose(banfile);
            }
         }

         /* send out login prompt */

         while(pwfile && !commandflag && !earlyend) {  

            /* Prompt for ID */
            writeamigaserial("login: ");
            readamigaserial(logname,LOGNAMELENGTH,1);
            writeamigaserial("password: ");
            readamigaserial(password,PASSWORDLENGTH,0);
                /* change to -1 for asterisk echo   ^ */

            /* check for appropriate response */
            while (fgets(buf,BUFLEN,pwfile)) {
               if (buf[0] == ' ') continue;
               if (buf[0] == '*') continue;
               if (buf[0] == '\0') continue;
               if (buf[0] == '\n') continue;
               
               /* get rid of newline at end of line (borrow unused pointer) */
               pwptr = buf;
               while (*pwptr) {
                  if (*pwptr == '\n')
                     *pwptr = '\0';
                  else
                     pwptr++;
               }
               /* break up line into fields */
               pwptr = buf;
               while (*pwptr) {
                  if (*pwptr == ':') {
                     *pwptr = '\0';
                     pwptr++;
                     break;  /* out of while loop */
                  } else
                     pwptr++;
                }
               comptr = pwptr;
               while (*comptr) {
                  if (*comptr == ':') {
                     *comptr = '\0';
                     comptr++;
                     break;  /* out of while loop */
                  } else
                     comptr++;
               }
               if (!strcmp(buf,logname) && !strcmp(pwptr,password)) {
                  /* the names match, set up command for exit */
                  commandflag = 1;
                  break;  /* out of file reading while loop */
               }  
            }
            if (!commandflag && !earlyend) {
               /* none of the logins matched, restart process if possible */
               fclose(pwfile);
               pwfile = fopen(av[1],"r");

               /* slow down direct key space search for security */
               Delay(150L);

               /* inform user of error */
               writeamigaserial("Login incorrect\n");
            }


         }
    
         closeamigaserial();
      }

      if (pwfile) fclose(pwfile);
   }

   if (commandflag && *comptr) Execute(comptr,0L,0L);
      
   
}
      




/* Standard Amiga Serial Port Routines */

static struct Port *mySerPort;
struct IOExtSer *mySerReq;

int openamigaserial()
{
int gotport = 0;
int gotextio = 0;
long error;
long OpenDevice();
VOID *CreateExtIO();
struct Port *CreatePort();


   mySerPort = CreatePort("mySerial",0L);
   if (mySerPort == NULL) 
      goto errorexit;
   gotport = 1;

   mySerReq = (struct IOExtSer *)CreateExtIO(mySerPort,
              (long)sizeof(struct IOExtSer));
   if (mySerReq == NULL) 
      goto errorexit;
   gotextio = 1;

   error = OpenDevice("serial.device",0L,mySerReq,0L);
   if (error) 
      goto errorexit;

   return 0;  /* return success */


errorexit:
   if (gotextio) 
      DeleteExtIO(mySerReq,sizeof(struct IOExtSer));
   if (gotport)
      DeletePort(mySerPort);

   return 1;  /* return error */

}

closeamigaserial()
{
   CloseDevice(mySerReq);
   DeleteExtIO(mySerReq,sizeof(struct IOExtSer));
   DeletePort(mySerPort);
}



readamigaserial(buf,max,echo)
char *buf;
int max,echo;
{
int i = 0;
int temp;
char c;
char *index();

   while (i < max-1) {
      temp = get1();
      if (temp < 0) {
         *buf = '\0';
         return;
      } else
         c = temp;
      if (!c) continue;
      if (index("\r\n\004",c)) {
         *buf = '\0';
         send1('\r');
         send1('\n');
         return;
      } else if (index("\b\377",c)) {
         if (i) {
            i--;
            buf--;
            if (echo) {
               send1('\b');
               send1(' ');
               send1('\b');
            }
         }
      } else {
         *buf++ = c;
         i++;
         if (echo > 0) send1(c);
         if (echo < 0) send1('*');
      }
   }
   /* ran out of room */
   *buf = '\0';
}




writeamigaserial(buf)
char *buf;
{
   while (*buf) {
      if (*buf == '\n') 
         send1('\r');
      send1(*buf++);
   }

}




send1(chr)
char chr;
{
char temp;

   temp = chr;   


   mySerReq->IOSer.io_Data = (APTR)&temp;
   mySerReq->IOSer.io_Length = 1;
   mySerReq->IOSer.io_Command = CMD_WRITE;
   return DoIO(mySerReq);

}

int get1()
{
   unsigned char temp;

   mySerReq->IOSer.io_Data = (APTR)&temp;
   mySerReq->IOSer.io_Length = 1;
   mySerReq->IOSer.io_Command = CMD_READ;
   if (DoIO(mySerReq)) {
      return -1;                   /* error occured, flag with -1 */
   } 
   return temp;

}

