/*
   Copyright R.M.A.Lucock 1991
*/

#define RDES_VER "1.1"

#include <stdio.h>
#include <fcntl.h>
#ifndef AMIGA
#include <termio.h>
#endif

#define UCHAR unsigned char

int dofile(int, int, int, int, int, int) , parsekey(UCHAR *, UCHAR *);

void setup_key(UCHAR *,int);

UCHAR *promptkey(void);


int main(int argc, char *argv[])
{
int ftime0 , ftime1;

#ifndef AMIGA
int ctime0 , ctime1;
#endif

long size;

int in_fh , out_fh;

UCHAR key[17];

UCHAR *kptr;

int argindx;

int edflag = 0 , nmode = 0 , cbcflag = 1 , xbflag = 0;

int option , keyset = 0;


   fprintf(stderr,"RDES Version %s\n",RDES_VER);

   if(argc < 2)
      {
      fprintf(
              stderr,
"\nusage:\n%s [-e | -d] [-x] [-b] [-m mode] [-k key] [in_file [out_file]]\n",
             argv[0]
             );
      return(0);
      }


/* Parse the options given */

   for(argindx = 1; argindx < argc; argindx++)
      {
      if(argv[argindx][0] != '-')
         break;

      option = toupper(argv[argindx][1]);

      switch(option)
         {
         case 'E':
            edflag = 0;
            break;
         case 'D':
            edflag = 1;
            break;
         case 'B':
            cbcflag = 0;
            break;
         case 'X':
            xbflag = 1;
            break;
         case 'M':
            if(strlen(argv[argindx]) > 2)
               kptr = (UCHAR *)(&argv[argindx][2]);
            else
               {
               ++argindx;
               if(argindx >= argc)
                  {
                  fprintf(stderr,"syntax error\n");
                  return(0);
                  }
               kptr = (UCHAR *)(argv[argindx]);
               }

            if(sscanf(kptr,"%x",&nmode) != 1)
               {
               fprintf(stderr,"Invalid mode switch %s\n",kptr);
               return(0);
               }
            break;
         case 'K':
            if(strlen(argv[argindx]) > 2)
               kptr = (UCHAR *)(&argv[argindx][2]);
            else
               {
               ++argindx;
               if(argindx >= argc)
                  {
                  fprintf(stderr,"syntax error\n");
                  return(0);
                  }
               kptr = (UCHAR *)(argv[argindx]);
               }

            if( parsekey(kptr,key) == 0)
               return(0);

            keyset = 1;

            break;
         default:
            fprintf(stderr,"option -%c ignored\n", option);
            break;
         }
      }


   argv += argindx; argc -= argindx;

/*
   Check that a key was given. If not, and if we are not reading from
   standard input, nor writing to standard output, prompt for the key.
*/

   if(keyset == 0)
      {
      if(argc > 1)
         {
         if( (kptr = promptkey()) == (UCHAR *)-1)
            return(0);

         if(parsekey(kptr,key) == 0)
            return(0);

         keyset = 1;
         }
      else
         {
         fprintf(stderr,"The key must be given on the command line if the file is\n");
         fprintf(stderr,"being read from standard input\n");
         return(0);
         }
      }

/*
   If no input file is given, read from standard input; if no
   output file is given, write to standard output.
*/

   if(argc > 0)
      {
      if((in_fh = open(argv[0], O_RDONLY)) < 0)
         {
         fprintf(stderr,"Error opening input file\n");
         return(0);
         }
      }
   else
      in_fh = 0;


   if(argc > 1)
      {
#ifdef AMIGA
      if((out_fh = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT)) < 0)
#else
      if((out_fh = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT,S_IRUSR|S_IWUSR)) < 0)
#endif
         {
         fprintf(stderr,"Error opening output file\n");
         return(0);
         }
      }
   else
      out_fh = 1;


/* set up key array */

   setup_key(key,edflag);


   ftime0 = time(NULL);
#ifndef AMIGA
   ctime0 = clock(NULL);
#endif
   size = rwdata(in_fh,out_fh,edflag, nmode, cbcflag, xbflag);
   ftime1 = time(NULL);
#ifndef AMIGA
   ctime1 = clock(NULL);
#endif

   if(size >= 0)
#ifdef AMIGA
      fprintf(stderr,"%d bytes; elapsed time: %d\n",size,ftime1-ftime0);
#else
      fprintf(stderr,"%d bytes; elapsed time: %d (real) %d (cpu mS)\n",size,ftime1-ftime0,(ctime1-ctime0)/1000);
#endif

   if(argc > 0)
      close(in_fh);
   if(argc > 1)
      close(out_fh);

   return(1);
}


int parsekey(UCHAR *kptr, UCHAR *dptr)
{
unsigned long tkey[8];

int ncon , slen;


   if( (slen = strlen(kptr)) <= 8)
      {
      memset(dptr,'\0',8);
      strncpy(dptr,kptr,slen);
      strncpy(kptr,"        ",slen);
      return(1);
      }
   else if(strlen(kptr) == 16)
      {
      ncon = sscanf(
                    kptr,
                    "%02x%02x%02x%02x%02x%02x%02x%02x",
                    &tkey[0],
                    &tkey[1],
                    &tkey[2],
                    &tkey[3],
                    &tkey[4],
                    &tkey[5],
                    &tkey[6],
                    &tkey[7]
                   );

      strncpy(kptr,"                ",16);

      if(ncon != 8)
         {
         fprintf(stderr,"Error scanning hex key string\n");
         return(0);
         }

      for(ncon=0; ncon < 8; ++ncon)
         dptr[ncon] = (UCHAR)tkey[ncon];

      return(1);
      }
   else
      {
      fprintf(stderr,"Invalid key length - must be <= 8 (ascii) or 16 (hex)\n");
      return(0);
      }
}


UCHAR *promptkey(void)
{
static UCHAR instr[17];

int ret;

#ifndef AMIGA
short val;

struct termio tbuf;

   if(ioctl(0,TCGETA,&tbuf) == -1)
      {
      fprintf(stderr,"Error reading terminal control block\n");
      return((UCHAR *)-1);
      }

   val = tbuf.c_lflag;

   tbuf.c_lflag &= (unsigned short)(0xFFFF^ECHO);
   if(ioctl(0,TCSETAW,&tbuf) == -1)
      {
      fprintf(stderr,"Error setting terminal control block\n");
      return((UCHAR *)-1);
      }
#endif

   printf("Enter key: ");

#ifdef AMIGA
   ret = scanf("%s",instr);
#else
   ret = scanf("%[^\n]",instr);

   tbuf.c_lflag = val;

   if(ioctl(0,TCSETAW,&tbuf) == -1)
      fprintf(stderr,"Error re-setting terminal control block\n");
#endif

   if(ret == 1)
      return(instr);
   else
      {
      fprintf(stderr,"Error reading key input\n");
      return((UCHAR *)-1);
      }

}
