/************************************************************************/
/*                                                                      */
/* Programm: Krypt            Version: 2.0   vom 10.09.89               */
/*                                                                      */
/* läuft mit Kickstart und WB 1.2 und 1.3                               */
/*                                                                      */
/* Autor: A.S.                © 1989 by Arthur Rat Software             */
/* ---------------------------------------------------------------------*/
/* Das Programm verschlüsselt beliebige Files durch rotieren der Bits   */
/* von jeweils zwei Bytes. Die Anzahl der Rotationsschritte wird durch  */
/* einen Zufallszahlengenerator bestimmt dessen Startwert durch eine    */
/* Schlüsselzahl festgelegt wird.                                       */
/*                                                                      */
/************************************************************************/
/* Version       Datum       Bemerkung                                  */
/*---------     -------     -----------                                 */
/*   1.00      30.08.88      funktionsfähig vom CLI aus                 */
/*   2.00      10.09.89      mit Requester und Mausbedienung            */
/************************************************************************/

/*****************************************************************/
/* !! ACHTUNG !! Damit dieses Programm funktioniert, muß nach dem */
/* Compilieren und ! vor ! dem Assemblieren das Assemblerlisting  */
/* verändert werden. Der Befehl asl.w muß in rol.w und der Befehl */
/* asr.w in ror.w geändert werden.                                */
/* Danach kann normal assembliert und gelinkt werden.             */
/******************************************************************/

/******************************************************************/
/* Mit Aztec-C 3.6 übersetzt.                                     */
/* Aufrufe wie folgt:                                             */
/* cc Krypt.c -a             nicht automatisch assemblieren       */
/* Mit ed das File Krypt.asm wie oben beschrieben bearbeiten.     */
/* as Krypt.asm              assemblieren                         */
/* ln Krypt.o -lm -lc        linken                               */
/* fertig                                                         */
/******************************************************************/

#define CR  13
#define MODE_OLDFILE 1005L
#define MODE_NEWFILE 1006L

#include <stdio.h>
#include <exec/types.h>
#include <intuition/intuition.h>
#include <functions.h>

struct Library *IntuitionBase;
struct Library *GfxBase;


char Fehlertext[45];
char Loeschen[45] = "                                           ";

struct IntuiText Fehlermeldung =
{
  1, 0,
  JAM2,
  9, 78,
  NULL,
  (UBYTE *)Fehlertext,
  NULL
};

/* Aktueller Zeichensatz ist Topaz 80 */

struct TextAttr MyFont={(UBYTE *)"topaz.font",
                        TOPAZ_EIGHTY,
                        FS_NORMAL,
                        FPF_ROMFONT};

#include "kryptgadgets.h"

/* Window Definitionen */

struct NewWindow NewWindow={130,78,380,100,0,1,
                            CLOSEWINDOW | GADGETUP,
                            WINDOWCLOSE | SIMPLE_REFRESH | ACTIVATE |
                            WINDOWDRAG | WINDOWDEPTH | NOCAREREFRESH,
                            &SchlZahlGadget,
                            NULL,
                            (UBYTE *)"Ver-/Entschlüsseln",NULL,NULL,
                            0,0,0,0,
                            WBENCHSCREEN};
struct Window *Window;

long handle;
float start;

buchstabe(z)
register char z;
{
  if((z >= 'a' && z <= 'z') || (z >= 'A' && z <= 'Z')) return(TRUE);
  return(FALSE);
}



strchback(s,c)
register char s[];
register char c;
{
  register int i = strlen(s);
  while((i >= 0) && !(s[i] == c))
    i--;
  return(i);   /* Fehler = -1 */
}



float Zufall()
{
  float prim = 7417.0;
  float temp;

  temp = start * prim;
  start = temp - (int)temp;
  temp = (int)(15.0 * start) + 1.0;
  return temp;
}



void verschluesseln(w)
struct Window *w;
{
  long count;
  struct FileHandle *fhandle1, *fhandle2;
  short temp;
  float Zahl;

  fhandle1 = Open(QuellfileBuffer, MODE_OLDFILE);
  if(fhandle1 != NULL)
  {
    start = (float)(SchlZahlInfo.LongInt);
    while(start > 1.0) start = start / 10.0;
    fhandle2 = Open(ZielfileBuffer, MODE_NEWFILE);
    Write(fhandle2, &(SchlZahlInfo.LongInt), 4L);
    count = Read(fhandle1, &temp, 2L);     /* Zeichen lesen, jeweils 2 */
    do
    {
      Zahl = Zufall();                    /* Zufallszahl ermitteln    */
      if(count == 2L)                     /* bei ungerader Anzahl Bytes in
                                             der Datei wird das letzte Byte
                                             nicht verschlüsselt           */
        temp = (temp << (int)Zahl);/* die zwei Zeichen nach links rotieren */
      Write(fhandle2, &temp, count);   /* verschlüsselte Zeichen speichern */
      count = Read(fhandle1, &temp, 2L);  /* Zeichen lesen, jeweils 2 */
    }while(count > 0L);                   /* bis Dateiende */
    Close(fhandle2);
    Close(fhandle1);
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    strcpy(Fehlertext, "Fertig.");
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
  }
  else
  {
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    strcpy(Fehlertext, "Fehler: Datei nicht gefunden!");
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
  }
}   /* End of verschluesseln */


void entschluesseln(w)
struct Window *w;
{
  long count;
  long nix;
  struct FileHandle *fhandle1, *fhandle2;
  short temp;
  float Zahl;

  fhandle1 = Open(QuellfileBuffer, MODE_OLDFILE);
  if(fhandle1 != NULL)
  {
    start = (float)(SchlZahlInfo.LongInt);
    while(start > 1.0) start = start / 10.0;
    fhandle2 = Open(ZielfileBuffer, MODE_NEWFILE);
    Read(fhandle1, &nix, 4L);
    count = Read(fhandle1, &temp, 2L);     /* Zeichen lesen, jeweils 2 */
    do
    {
      Zahl = Zufall();                    /* Zufallszahl ermitteln    */
      if(count == 2L)                     /* sh. verschlüsseln        */
        temp = (temp >> (int)Zahl);/*die zwei Zeichen nach rechts rotieren */
      Write(fhandle2, &temp, count);   /* entschlüsselte Zeichen speichern */
      count = Read(fhandle1, &temp, 2L);  /* Zeichen lesen, jeweils 2 */
    }while(count > 0L);           /* bis Dateiende */
    Close(fhandle2);
    Close(fhandle1);
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    strcpy(Fehlertext, "Fertig.");
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
  }
  else
  {
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    strcpy(Fehlertext, "Fehler: Datei nicht gefunden!");
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
  }
}   /* End of entschluesseln */

void main()
{
  int i;
  struct IntuiMessage *Message;
  ULONG class;
  APTR address;

  if((IntuitionBase=OpenLibrary("intuition.library",33L))==NULL)
    Quit();
  if((GfxBase=OpenLibrary("graphics.library",33L))==NULL)
    Quit();
  if((Window=OpenWindow(&NewWindow))==NULL)
    Quit();

  SetDMRequest(Window, &request);
  AlleGadgets(OffGadget, Window);
  ActivateGadget(&QuellfileGadget, Window, NULL);
  FOREVER
  {
    Wait(1L<<Window->UserPort->mp_SigBit);
    while(Message=(struct IntuiMessage *)GetMsg(Window->UserPort))
    {
      class=Message->Class;
      address=Message->IAddress;
      ReplyMsg(Message);
      switch(class)
      {
        case GADGETUP:
          GadgetMessage(address,Window);
          break;
        case CLOSEWINDOW:
          while(Message=(struct IntuiMessage *)GetMsg(Window->UserPort))
            ReplyMsg(Message);
          ClearDMRequest(Window, &request);
          Quit();
      } /* switch */
    } /* while */
  } /* FOREVER */
} /* main */

Quit()
{
  if(Window) CloseWindow(Window);
  if(GfxBase) CloseLibrary(GfxBase);
  if(IntuitionBase) CloseLibrary(IntuitionBase);
  exit(0L);
}

static UBYTE executestr[MAXSTRSIZE];

GadgetMessage(address,w)
APTR address;
struct Window *w;
{
  int i;

  /* Wenn der Quellfilename eingetippt wird und der Zielfilename noch nicht
     definiert ist, erhält dieser den Wert von Quellfilename, genauso ist
     es umgekehrt. */

  if((address == (APTR)&QuellfileGadget) && (QuellfileBuffer[0]))
  {
    strcpy(&ZielfileBuffer,&QuellfileBuffer);
    i = strchback(ZielfileBuffer, '.');
    if(i > 0) ZielfileBuffer[i] = (char)(0);
    else strcat(ZielfileBuffer,".krp");
    RefreshGadgets(&ZielfileGadget,w,NULL);
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    AlleGadgets(OnGadget,w);
  }

  if((address == (APTR)&ZielfileGadget) && (((ZielfileBuffer[0])
     && (!QuellfileBuffer[0])) || (!strcmp(QuellfileBuffer,ZielfileBuffer))))
  {
    strcpy(&QuellfileBuffer,&ZielfileBuffer);
    i = strchback(QuellfileBuffer, '.');
    if(i > 0) QuellfileBuffer[i] = (char)(0);
    else strcat(QuellfileBuffer,".krp");
    RefreshGadgets(&QuellfileGadget,w,NULL);
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    AlleGadgets(OnGadget, w);
  }

  /* Verschlüsseln verschlüsselt das Quellfile und speichert nach Zielfile */

  if(address == (APTR)&VerGadget)
  {
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    if(SchlZahlBuffer[0])
    {
      AlleGadgets(OffGadget,w);
      verschluesseln(w);
      AlleGadgets(OnGadget,w);
    }
    else
    {
      strcpy(Fehlertext, "Erst Schlüsselzahl eingeben.");
      PrintIText(w->RPort, &Fehlermeldung, 0, 0);
      ActivateGadget(&SchlZahlGadget, w, NULL);
    }
  }

  /* Entschlüsseln entschlüsselt das Quellfile und speichert nach Zielfile */

  if(address == (APTR)&EntGadget)
  {
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
    if(SchlZahlBuffer[0])
    {
      AlleGadgets(OffGadget,w);
      entschluesseln(w);
      AlleGadgets(OnGadget,w);
    }
    else
    {
      strcpy(Fehlertext, "Erst Schlüsselzahl eingeben.");
      PrintIText(w->RPort, &Fehlermeldung, 0, 0);
      ActivateGadget(&SchlZahlGadget, w, NULL);
    }     
  }
  if(address == (APTR)&SchlZahlGadget)
  {
    strcpy(Fehlertext, Loeschen);
    PrintIText(w->RPort, &Fehlermeldung, 0, 0);
  }  
}


/* Alle Gadgets an- oder ausschalten */

AlleGadgets(funcp, w)
void (*funcp)();
struct Window *w;
{
  (*funcp)(&VerGadget, w, NULL);
  (*funcp)(&EntGadget, w, NULL);
}

