/*******************************\
* ACCOUNTS.C			*
* (c)1986-87, Patrick E. Hughes	*
\*******************************/

#include <exec/types.h>
#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include "System.h"
#include "Defines.h"

/***********************\
* GLOBAL VARIABLE LIST	*
\***********************/

extern struct System System;

extern struct User User;
extern long lseek();

static char string[133];

/***********************\
* LOAD_ACCOUNT()	*
\***********************/
int Load_Account(slot,hoozer)
	int slot;
	struct User *hoozer;
{
int stat, fd;
long seekstat;
long size, final;

--slot;
size=(long)sizeof(struct User);
final=size*(long)slot;

strcpy(string,System.Location);
strcat(string,"User.Data");
fd=open(string,O_RDONLY);
if(fd==(-1)) { return(FAILURE); }

seekstat=lseek(fd,final,0);
if(seekstat!=final)
	{
	close(fd);
	return(FAILURE);
	}

stat=read(fd,hoozer,sizeof(struct User));
if(stat!=sizeof(struct User))
	{
	close(fd);
	return(FAILURE);
	}

close(fd);

return(SUCCESS);
}

/***********************\
* SAVE_ACCOUNT()	*
\***********************/
int Save_Account(hoozer)
	struct User *hoozer;
{
int stat, fd, slot;
long seekstat;
long size, final;

if(hoozer->Slot_Number==0) { return(FAILURE); }

slot=hoozer->Slot_Number-1;

size=(long)sizeof(struct User);
final=size*(long)slot;

strcpy(string,System.Location);
strcat(string,"User.Data");
fd=open(string,O_WRONLY);
if(fd==(-1)) { return(FAILURE); }

seekstat=lseek(fd,final,0);
if(seekstat!=final)
	{
	close(fd);
	return(FAILURE);
	}

stat=write(fd,hoozer,sizeof(struct User));
if(stat!=sizeof(struct User))
	{
	close(fd);
	return(FAILURE);
	}

close(fd);

return(SUCCESS);
}

/***********************\
* FORCESAVE_ACCOUNT()	*
\***********************/
int ForceSave_Account(hoozer,slot)
	struct User *hoozer;
	int slot;
{
int stat, fd;
long seekstat;
long size, final;

slot-=1;

size=(long)sizeof(struct User);
final=size*(long)slot;

strcpy(string,System.Location);
strcat(string,"User.Data");
fd=open(string,O_WRONLY);
if(fd==(-1)) { return(FAILURE); }

seekstat=lseek(fd,final,0);
if(seekstat!=final)
	{
	close(fd);
	return(FAILURE);
	}

stat=write(fd,hoozer,sizeof(struct User));
if(stat!=sizeof(struct User))
	{
	close(fd);
	return(FAILURE);
	}

close(fd);

return(SUCCESS);
}

/***********************\
* FIND_OPEN_ACCOUNT()	*
\***********************/
int Find_Open_Account(hoozer)
	struct User *hoozer;
{
struct User *user, the_struct;
int count, flag, stat;

user=&the_struct;

flag=FAILURE;
for(count=1;count<=System.User_Defaults.Maximum;++count)
	{
	stat=Load_Account(count,user);
	if(stat==SUCCESS && user->Slot_Number==0)
		{
		hoozer->Slot_Number=count;
		return(SUCCESS);
		}
	SendChar('.');
	}

return(FAILURE);
}

/***********************\
* DISPLAY_ACCOUNT()	*
\***********************/
int Display_Account(who,hoozer)
	int who;
	struct User *hoozer;
{
if(hoozer->Slot_Number==who)
	{
	sprintf(string,"\014\t\t Account [%hu]\r\n",hoozer->Slot_Number);
	PutStr(string);
	}
else
	{
	sprintf(string,"\014\t[33mINACTIVE[0m Account [%hu]\r\n",who);
	PutStr(string);
	}
PutStr("\r\n");

sprintf(string,"A> Name: %-32s",hoozer->Name);
PutStr(string);
sprintf(string,"B> Pass: %s\r\n",hoozer->Pass);
PutStr(string);
PutStr("\r\n");

sprintf(string,"C> Comment1:\r\n%s\r\n",&hoozer->Comments[0][0]);
PutStr(string);
sprintf(string,"D> Comment2:\r\n%s\r\n",&hoozer->Comments[1][0]);
PutStr(string);
sprintf(string,"E> Comment3:\r\n%s\r\n",&hoozer->Comments[2][0]);
PutStr(string);
PutStr("\r\n");

sprintf(string,"F> Sec_Status: %hu  ",hoozer->Sec_Status);
PutStr(string);
if(hoozer->Sec_Status==1) { PutStr("NEW"); }
if(hoozer->Sec_Status==2) { PutStr("VALID"); }
if(hoozer->Sec_Status>=100 && hoozer->Sec_Status<150){PutStr("BOARD-OP");}
if(hoozer->Sec_Status>=150 && hoozer->Sec_Status<255){PutStr("LIBRARY-OP");}
if(hoozer->Sec_Status==255) { PutStr("SYSOP"); }
PutStr("\r\n");

sprintf(string,"G> Sec_Board: %-7hu",hoozer->Sec_Board);
PutStr(string);
sprintf(string,"H> Sec_Library: %-7hu",hoozer->Sec_Library);
PutStr(string);
sprintf(string,"I> Sec_Bulletin: %hu\r\n",hoozer->Sec_Bulletin);
PutStr(string);
PutStr("\r\n");

sprintf(string,"J> Messages_Posted: %-7hu\r\n",hoozer->Messages_Posted);
PutStr(string);
sprintf(string,"K> Mail_Sent: %-7hu",hoozer->Mail_Sent);
PutStr(string);
sprintf(string,"L> Mail_Received: %-9hu\r\n",hoozer->Mail_Received);
PutStr(string);
sprintf(string,"M> Uploads: %-9hu",hoozer->Uploads);
PutStr(string);
sprintf(string,"N> Downloads: %hu\r\n",hoozer->Downloads);
PutStr(string);
PutStr("\r\n");
sprintf(string,"Q> Time_Limit: [%lu] secs    ",hoozer->Time_Limit);
PutStr(string);
sprintf(string,"R> Time_Used: [%lu] secs\r\n",hoozer->Time_Used);
PutStr(string);
PutStr("\r\n");

PutStr("ESC=NO-SAVE  1=SAVE  2=VALIDATE  3=RE-ACTIVATE  DEL=DELETE\r\n\r\n");
}

/***********************\
* EDIT_ACCOUNTS()	*
\***********************/
int Edit_Accounts()
{
int which, stat, flag, command, fd;
char str[133], string[133];
struct User hoozer;
long seekstat;

FOREVER
	{
	PutStr("\r\nN>ew-List\r\nEdit which account? ");
	stat=LineInput("",str,5,240L);
	if(toupper(str[0])=='N')
		{
		List_New_Accounts();
		continue;
		}
	if(stat<=0) { return(SUCCESS); }

	which=atoi(str);
	if(which<=0) { return(SUCCESS); }
	if(which>System.User_Defaults.Maximum)
		{
		PutStr("Higher Than Maximum Account\r\n");
		continue;
		}
	stat=Load_Account(which,&hoozer);
	if(stat==FAILURE)
		{
		PutStr("Warning, error while loading account\r\n");
		continue;
		}
	FOREVER
		{
		flag=0;
		Display_Account(which,&hoozer);
		command=ReadChar(240L);
		switch(command)
			{
			case '\033': /* NO-SAVE */
				PutStr("No-Save\r\n");
				flag=1;
				break;
			case '\177': /* DELETE */
				PutStr("Delete\r\n");
				hoozer.Slot_Number=0;
				flag=0;
				break;
			case '1': /* SAVE */
				PutStr("Save\r\n");
				if(hoozer.Slot_Number==0)
					{
					ForceSave_Account(&hoozer,which);
					}
				else	{
					Save_Account(&hoozer);
					flag=1;
					}
				break;
			case '2': /* VALIDATE */
				PutStr("Validate\r\n");
				hoozer.Sec_Status=
					System.User_Defaults.Valid.Sec_Status;
				hoozer.Sec_Board=
					System.User_Defaults.Valid.Sec_Board;
				hoozer.Sec_Library=
					System.User_Defaults.Valid.Sec_Library;
				hoozer.Sec_Bulletin=
					System.User_Defaults.Valid.Sec_Bulletin;
				hoozer.Time_Limit=
					System.User_Defaults.Valid.Time_Limit;
				hoozer.Time_Used=0L;
				hoozer.Time_Total=0L;
				flag=0;
				break;
			case '3': /* RE-ACTIVATE */
				PutStr("Re-Activate\r\n");
				hoozer.Slot_Number=which;
				flag=0;
				break;
			case 'a': /* NAME */
			case 'A':
				PutStr("Name\r\n");
				stat=LineInput(hoozer.Name,hoozer.Name,30,240L);
				flag=0;
				break;
			case 'b': /* PASS */
			case 'B':
				PutStr("Pass\r\n");
				stat=LineInput(hoozer.Pass,hoozer.Pass,8,240L);
				flag=0;
				break;
			case 'c': /* COMMENT 1 */
			case 'C':
				PutStr("Comment 1\r\n");
				stat=LineInput(&hoozer.Comments[0][0],
					&hoozer.Comments[0][0],80,240L);
				flag=0;
				break;
			case 'd': /* COMMENT 2 */
			case 'D':
				PutStr("Comment 2\r\n");
				stat=LineInput(&hoozer.Comments[1][0],
					&hoozer.Comments[1][0],80,240L);
				flag=0;
				break;
			case 'e': /* COMMENT 3 */
			case 'E':
				PutStr("Comment 3\r\n");
				stat=LineInput(&hoozer.Comments[2][0],
					&hoozer.Comments[2][0],80,240L);
				flag=0;
				break;
			case 'f': /* SEC_STATUS */
			case 'F':
				PutStr("Sec_Status\r\n");
				hoozer.Sec_Status=NumberInput();
				flag=0;
				break;
			case 'g': /* SEC_BOARD */
			case 'G':
				PutStr("Sec_Board\r\n");
				hoozer.Sec_Board=NumberInput();
				flag=0;
				break;
			case 'h': /* SEC_LIBRARY */
			case 'H':
				PutStr("Sec_Library\r\n");
				hoozer.Sec_Library=NumberInput();
				flag=0;
				break;
			case 'i': /* SEC_BULLETIN */
			case 'I':
				PutStr("Sec_Bulletin\r\n");
				hoozer.Sec_Bulletin=NumberInput();
				flag=0;
				break;
			case 'j': /* MESSAGES_POSTED */
			case 'J':
				PutStr("Messages_Posted\r\n");
				hoozer.Messages_Posted=NumberInput();
				flag=0;
				break;
			case 'k': /* MAIL_SENT */
			case 'K':
				PutStr("Mail_Sent\r\n");
				hoozer.Mail_Sent=NumberInput();
				flag=0;
				break;
			case 'l': /* MAIL_RECEIVED */
			case 'L':
				PutStr("Mail_Received\r\n");
				hoozer.Mail_Received=NumberInput();
				flag=0;
				break;
			case 'm': /* UPLOADS */
			case 'M':
				PutStr("Uploads\r\n");
				hoozer.Uploads=NumberInput();
				flag=0;
				break;
			case 'n': /* DOWNLOADS */
			case 'N':
				PutStr("Downloads\r\n");
				hoozer.Downloads=NumberInput();
				flag=0;
				break;
			case 'q': /* TIME_LIMIT */
			case 'Q':
				PutStr("Time_Limit\r\n");
				hoozer.Time_Limit=(long)NumberInput();
				flag=0;
				break;
			case 'r': /* TIME_USED */
			case 'R':
				PutStr("Time_Used\r\n");
				hoozer.Time_Used=(long)NumberInput();
				flag=0;
				break;
			default:
				flag=0;
				break;
			}
		if(flag) { break; }
		}
	}
}

/**********************************/
static int List_New_Accounts()
{
int x, stat;
struct User hoozer;

PutStr("New-List\r\n\r\n");

for(x=1;x<=System.User_Defaults.Maximum;++x)
	{
	stat=Load_Account(x,&hoozer);
	if(stat==FAILURE)
		{
		sprintf(string,"FILE-FAULT[%d], ",x);
		PutStr(string);
		}
	else
		{
		if(hoozer.Sec_Status==1)
			{
			sprintf(string,"[%d] ",x);
			PutStr(string);
			}
		}
	SendChar('.');
	Check_Online_Status();
	if(CheckInput())
		{
		stat=ReadChar(120L);
		switch(stat)
			{
			case '\023':
			case 'S':
			case 's':
			case 'P':
			case 'p':
			case ' ':
				PurgeLine();
				PutStr("Any key..");
				stat=ReadChar(120L);
			    if(stat==TIMEOUT||stat==NO_CARRIER){return(stat);}
			PutStr("\b\b\b\b\b\b\b\b\b         \b\b\b\b\b\b\b\b\b");
				break;
			case '\033': /* ESC Abort */
			case '\003': /* ^C */
			case '\020': /* ^P */
			case '\031': /* ^Y */
			case 'Q':
			case 'q':
			case 'X':
			case 'x':
				PutStr("\r\nAbort\r\n");
				goto AcctMark1;
				break;
			default:
				PurgeLine();
				break;
			}
		}
	}
AcctMark1:
PutStr("\r\n\r\n");
}

/**********************************/
int NumberInput()
{
int answer, stat;
char str[6];

PutStr("Enter Number: ");
stat=LineInput("",str,5,240L);
answer=atoi(str);
return(answer);
}
