/******************************************
*               K_R_Y_P_T                 *
*                                         *
* Created by THOMAS BECKER in HÖXTER      *
*                                         *
* Aufruf: KRYPT quelldatei[.k] [ziel[.k]] *
* !!! Dateien mit [.k] werden codiert !!! *
* !!! Dateien ohne [.k] decodiert     !!! *
*                                         *
* Options: cc krypt.c -s +l               *
*          ln krypt.o -lc32 -lm           *
******************************************/

#include <exec/types.h>
#include <stdio.h>
#include <exec/memory.h>
#include <libraries/dosextens.h>
#include <libraries/dos.h>

#define PASSWORD /* wenn definiert dann Passwortabfrage */
#define TYPE eintrag->fib_DirEntryType
#define NAME eintrag->fib_FileName
#define SIZE eintrag->fib_Size
#define MAX_BUFF_SIZE 200*512L /* Max-Buffer-Konstante */
#define KEYS sizeof(key)/sizeof(UBYTE)
#define CODIERE 1
#define DECODIERE 0

static struct FileInfoBlock *eintrag;
UBYTE key [] = {9,3,0,8,5,7,2,4,1,9,8,6}; /* veränderbar */
/* Schlüssel zum Vertauschen, gültig wenn undef PASSWORD */

VOID hilfe (), make_it ();
BYTE endezeichen [3] = ".k"; /* veränderbar */

main (argc,argv)
int argc;
char *argv [];
{
BYTE ziel [232];
BOOL flag=TRUE;
LONG buff_size;

if ((argc<2)||(argc>3)) hilfe ();

if (*(argv[1])=='?') hilfe ();

ziel[0]='\0';

if (argc==3)
   {
   strcpy (ziel,argv[2]);
   if ((check_datei(ziel))&&(TYPE))
      {
      if (((ziel[strlen(ziel)-1])!=':')&&
         ((ziel[strlen(ziel)-1])!='/')) strcat (ziel,"/");
      }
   else flag=FALSE;
   }

if (check_datei(argv[1]))
   {
   if (flag) strcat (ziel,NAME);
   make_it (argv[1],ziel,SIZE); /* zum (De)Codieren */
   }
else printf ("%s nicht gefunden!\n",argv[1]);

FreeMem (eintrag,sizeof (struct FileInfoBlock));
} /* end of main */

int check_datei (name)
char *name;
{
struct FileLock *lock;

eintrag=AllocMem (sizeof(struct FileInfoBlock),0);
if (!eintrag)
   {
   printf ("Brauche CHIP-Memory für FileInfoBlock!\n");
   return (FALSE);
   }

if (!(lock=Lock (name,ACCESS_READ)))
   return (FALSE);

if (!(Examine(lock,eintrag)))
   {
   UnLock(lock);
   return (FALSE);
   }

UnLock(lock);
return (TRUE);
} /* end of check_datei */

VOID hilfe ()
{
   printf ("\n\033[4mUsage:\033[0m\tquelldatei[%s] [ziel[%s]]...\n",endezeichen,endezeichen);
   printf ("\tDateien mit '%s' werden dekodiert\n",endezeichen);
   printf ("\tDateien ohne '%s' werden kodiert\n",endezeichen);
   exit ();
} /* end of hilf
e */

VOID make_it(quelldatei,zieldatei,buff_size) /*(De)Codierung*/
char *quelldatei,*zieldatei;
LONG buff_size;
{
UBYTE *buffer,password[81];
VOID kill_endung(),umrechnen(),codiere(),decodiere();
BOOL verschluesseln;
LONG number,handle1,handle2;

if ((handle1 = open (quelldatei,0,0))==-1)
   {
   printf ("%s kann nicht geöffnet werden!\n",quelldatei);
   goto WEITER;
   }

if (buff_size > MAX_BUFF_SIZE) buff_size = MAX_BUFF_SIZE;

if (!(buffer =(UBYTE *)AllocMem (buff_size,MEMF_PUBLIC)))
   {
   printf ("Ich brauche mehr MEMORY\n");
   close (handle1);
   goto WEITER;
   }

if (!(endung(quelldatei))) /*Test auf Codieren bzw Decodieren*/
   {
   strcat (zieldatei,endezeichen);
   verschluesseln = CODIERE;
   }
   else
   {
   if (endung(zieldatei)) kill_endung (zieldatei);
   verschluesseln = DECODIERE;
   }

if ((handle2 = creat (zieldatei,0))==-1)
   if ((handle2 = open (zieldatei,1,0))==-1)
      {
      printf ("%s kann nicht geöffnet werden!\n",zieldatei);
      FreeMem (buffer,buff_size);
      close (handle1);
      goto WEITER;
      }

#ifdef PASSWORD /* wird nur bei Zeile 20 compiliert */

printf ("\n\033[1mEnter Password: \033[0m");
scanf ("%80s",password);
umrechnen (password);

#endif PASSWORD

printf ("\n");
if (!verschluesseln) printf ("DE"); /*Kontrollausgabe*/
printf ("CODIERE \033[3m%s\033[0m to \033[3m%s\033[0m\n"
   ,quelldatei,zieldatei);

do
   {
   number =read (handle1,buffer,buff_size);
   if (verschluesseln) codiere (buffer,number);
                  else decodiere (buffer,number);
   write (handle2,buffer,number);
   } while (number==buff_size);

FreeMem (buffer,buff_size);

close (handle1);
close (handle2);

WEITER:;
} /* end of make_it */

endung (s) /* Mal 2 eigene Routinchen, kann auch kurz program-*/
register char *s; /*miert mit strlen in make_it gesetzt werden*/
{
while (*s) s++;
if (((*(--s)) == endezeichen[1]) && ((*(--s)) == endezeichen[0])) return (1);
return (0);
} /* end of endung */

VOID kill_endung (s)
register char *s;
{
while (*s) s++;
*(s-2) = 0;
} /* end of kill_endung */

VOID decodiere (reihe,number)
UBYTE reihe [];
LONG number;
{
register UBYTE zeichen;
register long i,j;

for (j=0;j<number-9;j+=10)
   {
   for (i=KEYS-2;i>=0;i--)
      {
      zeichen = reihe [key[i]+j];
      reihe [key[i]+j] = reihe [key[i+1]+j];
      reihe [key[i+1]+j] = zeichen;
      }
   }
} /* end of decodiere */

VOID codiere (reihe,number)
UBYTE reihe [];
long number;
{
register UBYTE zeichen;
register long i,j;

for (j=0;j<number-9;j+=10)
   {
   for (i=0;i<KEYS-1;i++)
      {
      zeichen = reihe [key[i]+j];
      reihe [key[i]+j] = reihe [key[i+1]+j];
      reihe [key[i+1]+j] = zeichen;
      }
   }
} /* end of codiere */

#ifdef PASSWORD /* wird nur bei Zeile 20 compiliert */

VOID umrechnen (password) /* Passwort als Schlüssel */
UBYTE password [];
{
unsigned int i,zahl=0;
double kommazahl;

for (i=0;i<strlen(password);i++) zahl += password [i];
kommazahl = (password [i-1]-1) / (double)zahl;
for (i=0;i<KEYS;i++)
   {
   key [i] = (UBYTE) (kommazahl*=10);
   kommazahl -= key[i];
   }
} /* end of umrechnen */

#endif PASSWORD

