#include <exec/types.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <dos/dos.h>

#include <libraries/gadtools.h>
#include <libraries/reqtools.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/reqtools.h>
#include <proto/dlg.h>

#include <gengui.h>

#include "crypt.h"

#include <pragmas/dlg.h>

#include "Owners.h"

//#define  HANDLERFILE "L:TPT-Handler"
//#define  HANDLERFILE "Test/Don/TPT-Handler"
#define  HANDLERFILE "Test/Tom/TPT-Handler"

static char yyy_version[]="$VER: HandlerConvert 1.1  "__AMIGADATE__"";

struct   Library       *DLGBase = NULL;

UBYTE CRC;

char  SERIAL[10];
char  OWNER[256];

int   decryptowner(char *, ULONG);
int   Decrypt(char *, char *);
BOOL  ProcHandler(void);
void  ShutDown(int);
int   OldDecrypt(char *, char *);
int   decryptowner(char *, ULONG);

extern   BOOL  GenerateKeyFile(void);

/// Main
void main(void)
{
   DLGBase = OpenLibrary("dlg.library",2L);

   if(!DLGBase)            ShutDown(10);
   if(!ProcHandler())      ShutDown(10);
   if(!GenerateKeyFile())  ShutDown(10);

   ShutDown(0);
}
//-
/// ShutDown
void ShutDown(int code)
{
   if(DLGBase) CloseLibrary(DLGBase);
   exit(code);
}
//-
/// ProcHandler
BOOL ProcHandler(void)
{
   BOOL     found = FALSE;
   BOOL     NFound = FALSE;

   BPTR     fh = NULL;

   int      counter = 0;
   int      a = 0;

   UBYTE   *buf = NULL;
   UBYTE   *oldbuf = NULL;

   ULONG    serialnumber = 0;


   if (!(buf=(UBYTE *)calloc(1,5000)))
   {
      printf("Can't allocate buffer!\n");
      return( FALSE );
   }

   if (!(oldbuf=(UBYTE *)calloc(1,5000)))
   {
      printf("Can't allocate second buffer\n");
      free(buf);
      return( FALSE );
   }

   fh = Open(HANDLERFILE,MODE_OLDFILE);

   if (!fh)
   {
      printf("Can't open handler!\n");
      free(buf);
      free(oldbuf);
      return( FALSE );
   }


   /* read in the last part of tpt-handler */
   Seek(fh, -5000, OFFSET_END);

   if (Read(fh, buf, 5000) != 5000)
   {
      printf("Can't read in data from handler!\n");
      Close(fh);
      free(buf);
      free(oldbuf);
      return( FALSE );
   }

   found = FALSE;

   for(counter=4999;counter;counter--)
   {
      if (buf[counter]==')')
      {
         counter--;
         if (buf[counter]=='-')
         {
            counter--;
            if (buf[counter]==':')
            {
               found=TRUE;
               break;
            }
         }
      }
   }

   if (!found)
   {
      printf("Can't find offset marker!\n");
      Close(fh);
      free(buf);
      free(oldbuf);
      return( FALSE );
   }

   /* We have found the smiley on tpt-handler */
   Seek(fh, 134 - (5000 - (long)counter), OFFSET_END);

   Read(fh, buf, 21);
   Close(fh); fh=NULL;
   memcpy(oldbuf,buf,21);
   Decrypt(buf, buf);

   for(a=0; a<21; a++)
   {
      if (buf[a]=='#')
      {
         NFound = TRUE;
         break;
      }
   }

   if(!NFound)
   {
      memcpy(buf,oldbuf,21);
      OldDecrypt(buf,buf);

      for(a=0; a<21; a++)
      {
         if(buf[a]=='#')
         {
            NFound = TRUE;
            break;
         }
      }

      if(!NFound)
      {
         printf("Decryption Error!\n");
         free(buf);
         free(oldbuf);
         return( FALSE );
      }
   }

   free(oldbuf); oldbuf=NULL;
   a++;

   buf[a+6] = 0;

   if (strncmp(buf+a,"PR",2)  &&
       strncmp(buf+a,"DV",2)  &&
       strncmp(buf+a,"BT",2)  &&
       strncmp(buf+a,"RE",2) )
   {
      printf("Can't find prefix, found %s!\n",buf);
      free(buf); buf=NULL;
      return( FALSE );
   }

   if ((!isdigit(buf[a+2])) ||
      (!isdigit(buf[a+3])) ||
      (!isdigit(buf[a+4])) ||
      (!isdigit(buf[a+5])))
   {
      printf("Non-numeric data after prefix!\n");
      free(buf); buf=NULL;
      return( FALSE );
   }

   serialnumber    = atol(buf+a+2);
   sprintf(SERIAL,"%06ld",serialnumber);

   strcpy(OWNER,"");

   if (!decryptowner(OWNER, serialnumber))
   {
      printf("Can't decrypt owner info!\n");
      free(buf); buf=NULL;
      return( FALSE );
   }

   free(buf); buf=NULL;
   return( TRUE );
}
//-
/// Decrypt
// this routine has been modified to update 1.0 handlers only
int Decrypt(char *inbuf,char *outbuf)
{
   UBYTE numchars, shift, i;

   Forbid();
   numchars = inbuf[0];
   shift    = numchars;

   for(i=0;i<numchars;i++)
   {
      outbuf[i] = inbuf[i+1] - shift;
      shift     = inbuf[i+1] - CRYPTOFFSET;
   }

   Permit();
   return((int)numchars);
}
//-
/// OldDecrypt
// This routine retains backwards compatability
OldDecrypt(char *inbuf, char *outbuf)
{
  UBYTE numchars, shift, i;

  numchars=inbuf[0];
  shift=numchars;

  for(i=0;i<numchars;i++)
  {
    outbuf[i] = inbuf[i+1]-shift;
    shift = inbuf[i+1]-shift;
  }

  return(numchars);
}
//-
/// decryptowner
int decryptowner(char *s, ULONG sn)
{
   char  buf[60];
   int   rc = 0;
   int   i,j;
   int   ctr;
   int   cnt;
   int   ssn;

   char *r;
   char *rr;


   cnt = 0;

   for(i = 0;; i++)
   {
      r = (char *)&enc[i];

      if (r[0]==0 && r[1]==0 && r[2]==0)  break;


      for(j = 0; j < 60; j++)
         r[j] ^= encrypt3[cnt];

      cnt++;

      if (cnt >= strlen(encrypt3)) cnt = 0;

      ctr = 0;

      for(j=0;j<60;j++)
      {
         r[j] ^= encrypt2[ctr];
         ctr++;

         if (ctr>=strlen(encrypt2))  ctr = 0;
      }

      ctr = 0;

      for(j=0;j<60;j++)
      {
         r[j] ^= encrypt1[ctr];
         ctr++;
         if (ctr>=strlen(encrypt1))  ctr = 0;
      }
   }

   for(i=0;;i++)
   {
      r = (char *)&enc[i];

      if (r[0]==0)  break;

      rr = r;
      rr = stpblk(r);
      ssn = atoi(rr);

      if (ssn==(int)sn)
      {
         rc = 1;
         strncpy(buf,r+17,60);
         buf[59]=0;
         break;
      }
   }

   for(j=strlen(buf)-1;buf[j]==32;j--)
      buf[j]=0;

   sprintf(OWNER, "%s", buf);
   return(rc);
}
//-
