/* Password.c */
/* written by Nathan Bolstad.                      */
/* This is the final flow for the password program */

/* Include all the needed include files */
#include <stdio.h>
#include <intuition/intuition.h>
#include <string.h>
	

/* set up all the defines that are used in this program */
#define back    8
#define enter  13
#define setword 2
#define b 170

/* set up any global structures that are required in the program */
struct IntuitionBase *IntuitionBase;
struct Window *Wind;
struct IntuiMessage *message = NULL;
struct RastPort *raster;
struct NewWindow Window =
{
   184, 115,
   272, 26,
   1, 3,
   VANILLAKEY,
   ACTIVATE | SMART_REFRESH | WINDOWDRAG,
   NULL, NULL,
   NULL, /* TITLE STRING */
   NULL, NULL,
   30, 20,
   300, 100,
   WBENCHSCREEN
};

struct IntuiText star =
{
   1, 0,
   JAM1,
   9, 0,
   NULL,
   (UBYTE *) "*",
   NULL
};
	
struct IntuiText line =
{
   1, 0,
   JAM2,
   9, 0,
   NULL,
   (UBYTE *) "_",
   NULL
};
		
struct IntuiText correct =
{
   1, 0,
   JAM2,
   9, 0,
   NULL,
   (UBYTE *) "     ****** CORRECT! ******     ",
   NULL
};
	
struct IntuiText write_error =
{
   1, 0,
   JAM2,
   9, 0,
   NULL,
   (UBYTE *) "Error Writing S:Password.cfg    ",
   NULL
};
	
struct IntuiText wrong_verify =
{
   1, 0,
   JAM2,
   9, 0,
   NULL,
   (UBYTE *) "Incorrect Verification: Aborting",
   NULL
};
		
FILE *file = NULL;
char password[33];
char entered[33];
char *name = "S:Password.cfg";
char *ent = "Please Enter Your Password.";
char *old = "Please Enter Your OLD Password.";
char *new = "Please Enter Your NEW Password.";
char *ver = "Please Verify Your NEW Password.";
char input;
	
UBYTE done = 0;
ULONG signalmask, signals, flag;
	
short location = 0, count = 0;
	
/* all the required routines */

void exitall();
void openmywindow();
void setpassword();
void getpassword();
void cleanstring();
void xor();

void clearstring() /* clears the entered string */
{
   location = 0;
   for(count = 0; count < 32; count ++)
	{
	   PrintIText(raster, &line, (SHORT) (8 * count), (SHORT) 14);
	   entered[count] = 0;
	}
  /*  return(0); */
}
	
void openmywindow() /* open the window after the heading has been set */
{
   Wind = (struct Window *) OpenWindow(&Window);
   if(Wind == NULL)
	   exit(0);
   raster = Wind -> RPort;
   signalmask = 1L << Wind -> UserPort -> mp_SigBit;
   /* return(0); */
}

getstring()  /* used for all the input into password */
{
   for(;;)
	{
	   signals = Wait(signalmask);
	   if(signals & signalmask)
		{
		   message = (struct IntuiMessage *) GetMsg(Wind -> UserPort);
		   flag = message -> Class;
		   input = message -> Code;
		   ReplyMsg(message);
		   if(location > 32)
			   location = 32;
		   entered[location] = (char) input;
		   location ++;
		   switch(input)
			{
			case back:
				entered[location - 2] = 0;
				entered[location - 1] = 0;
				location -= 2;
				if(location < 0)
					location = 0;
				PrintIText(raster, &line, (SHORT) (8 * location), (SHORT) 14);
				break;
			case enter:
				entered[location - 1] = 0;
            if(location == 1)
               return(setword);
				if(!strcmp(password, entered))
					return(TRUE); /* correct password */
				else
					return(FALSE); /* incorrect password */				
			default:
				if(location >= 32)
					location = 32;
				PrintIText(raster, &star, (SHORT) (8 * (location - 1)), (SHORT) 14);
			}
		   while(message)
			   message = (struct IntuiMessage *) GetMsg(Wind -> UserPort);
		}
	}
}
	
void exitall()    /* close all open things and exit() */
{
   if(file) fclose(file);
   if(Wind) CloseWindow(Wind);
   if(IntuitionBase) CloseLibrary(IntuitionBase);
      exit(0);
}
	
void getpassword() /* we use this most of time to get the correct input */
{
   int ret = 0;
   for(;;)
	{
	   clearstring();
	   ret = getstring();
	   switch(ret)
      {
         case TRUE:
		      break;
         case setword:
            setpassword();
            exitall();
      }
      if(ret == TRUE)
         break;
	}
}
   
void setpassword() /* used if password is to be set */
{
   int ret = 0;
   if(file)
	{
	   SetWindowTitles(Wind, old, -1);
	   for(;;)
		{
         clearstring();
         if(getstring())
         {
            if(!strcmp(password, entered))
            break;
         }
		}
	}
   SetWindowTitles(Wind, new, -1);
   clearstring();
   ret = getstring();
   strcpy(password, entered);
   SetWindowTitles(Wind, ver, -1);
   clearstring();
   ret = getstring();
   switch(ret)
	{
	case TRUE:
      xor();
		file = fopen(name, "w+");
      count = 0;
		while(password[count] != 0)
      {
		   fputc(password[count], file);
         count ++;
      }
		exitall();
	case FALSE:
		PrintIText(raster, &wrong_verify, (SHORT) 0, (SHORT) 14);
		Delay(200);
		exitall();
   default:
      PrintIText(raster, &wrong_verify, (SHORT) 0, (SHORT) 14);
      Delay(200);
      exitall();
	}
   CloseWindow(Wind);
}

void xor()
{
   char a;
   count = 0;
   while(password[count])
   {
      a = password[count];
      password[count] ^= b;
      count++;
   }
}

/* The main part of the program */

void _main()
{
   int ret = 1;

   IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
   if(!IntuitionBase)
	   exitall();
   file = fopen(name, "r");
   if(file)
	{
	   while(ret)
		{
		   password[count] = fgetc(file);
		   if(password[count] == EOF)
			{
			   ret = 0;
			   password[count] = NULL;
			}
		   else
			   count ++;
		}
      fclose(file);
      xor();
	}
   else
   {
      openmywindow();
      setpassword();
   }

   /* set up our window */
   Window.Title = ent;
   openmywindow();
   getpassword();
   PrintIText(raster, &correct, (SHORT) 0, (SHORT) 14);
	Delay(150);
	exitall();
}
