//---------------------------------------------------------------------------
// PASSWORD										(c) Laurence Vanhelsuwe 1994
// --------
// This program is part of a group of 3 complimentary programs to log the
// usage of a stand-alone machine. (LOGIN, LOGOUT, PASSWORD)
//
// This program has been written in ANSI C to make it fully portable across
// different hardware platforms.
//
// Original development and testing was carried out on a Commodore Amiga 3000.
//
// History
// -------
// 03-JAN-94: Initial file creation.
// 06-JAN-94: First useful version (with encoding)
// 11-FEB-94: Fixed users listing bug ( "\r" ending prevented correct listing)
//---------------------------------------------------------------------------

//#define		DEBUG			1

#include	"stdio.h"
#include	"stdlib.h"
#include	"string.h"
#include	"fcntl.h"
#include	"time.h"

#define		MAX_NAME_LEN	(10)
#define		ENTRY_LEN		(1+ MAX_NAME_LEN*2)

#define		SET_FG_0		"[30;40m"

#ifdef	AMIGA
#define		PFILE			"DEVS:PASSWORDS.DAT"
#define		HELP			"?"
#define		SET_FG_1		"[31;40m"
#define		CREAT_MODE		(O_RDWR)
#define		OPEN_MODE		(O_RDWR)

#else

#include	"sys\stat.h"
#define		PFILE			"C:/DOS/PASSWOR.DAT"
#define		HELP			"/?"
#define		SET_FG_1		"[37;40m"
#define		CREAT_MODE		(S_IREAD | S_IWRITE)
#define		OPEN_MODE		(O_RDWR | O_BINARY)

#endif

//---------------------------------------------------------------------------
// Function Prototypes
// -------------------
//---------------------------------------------------------------------------

void get_password		(char *prompt_str, char *passw_str);

//---------------------------------------------------------------------------
// Globals
// -------
//---------------------------------------------------------------------------

char sysop_password[40];
char input[80];
char username[MAX_NAME_LEN+2];
char userpasw[MAX_NAME_LEN+2];

long int file_size, log_pos;
int error, num_entries;

extern int errno;

int logfile, passwfile;			// LEVEL 1 ANSI C File Handles

time_t	systime;
struct tm *tim;

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

main(int argc, char **argv) {

int i,j,len, namelen, passwlen, num;
char *s,*d;

	if(argc > 1 ) {
		printf("PASSWORD V1.0  (Copyright (c) Jan 1994 L. Vanhelsuwe)\n\n");
		printf("Programmed by Laurence Vanhelsuwe in C on an Amiga 3000.\n");
		printf("Ported to IBM PC environment by L. Vanhelsuwe.\n\n");
		printf("USAGE: PASSWORD [%s]\n\n", HELP);
	}

	if ((passwfile = open(PFILE, OPEN_MODE)) == -1) {
#ifdef DEBUG
		printf("open(\"%s\",OPEN_MODE) returned %d...\n", PFILE, passwfile);
		printf("ERROR # : %d \n", errno);
#endif
		printf("Passwords file does not exist ! Attempting to create it...\n");
		passwfile = creat(PFILE, CREAT_MODE);
		if (passwfile == -1) {
			fprintf(stderr, "Couldn't create passwords file! Aborting...\n");
			exit(10);
		}
		printf("Passwords file created OK.\n");
	}

	get_password("Enter System Operator Password:", sysop_password);

// If the SYSOP enters the right PASSWORD immediately followed by 'USERS',
// The programs dumps a list of all the valid users (decoded).

	if(strcmp(sysop_password, "AGRCRGAUSERS") == 0) {
		printf("\nAuthorized Users List:\n\n");
		printf  ("NUMBER\tUSERNAME  PASSWORD\n");
		printf  ("------\t--------  --------\n");

		i = read(passwfile, input, ENTRY_LEN);
		num = 1;
		while (i==ENTRY_LEN) {
			for(j=0;j<MAX_NAME_LEN;j++)
                if (input[j] != ' ') input[j]=input[j]-1;	// decode name
			for(j=MAX_NAME_LEN;j<2*MAX_NAME_LEN;j++)
                if (input[j] != ' ') input[j]=input[j]-2;	// decode password

			printf("%3d\t", num++);
			printf(input);									// print both
			printf("\n");
			i = read(passwfile, input, ENTRY_LEN);
		}
        printf("\n");
		close(passwfile);
		return 0;
	}

// If the password wasn't the special listing password, then you have to enter
// the normal one or you're out !

	if(strcmp(sysop_password, "AGRCRGA") != 0) {
		printf("\nYou are not authorized to add users to this system.\n");
		exit(20);
	}

	lseek(passwfile, 0L, SEEK_END);			// goto the end to APPEND

	do {
		printf("Enter new User's NAME     :");
		scanf("%s", input);
		namelen = strlen(input);
		if (namelen > MAX_NAME_LEN)
			printf("Please enter upto %d characters maximum..\n", MAX_NAME_LEN);
	} while (namelen > MAX_NAME_LEN);
	strcpy(username, input);

	do {
		get_password("Enter new User's PASSWORD :", input);
		passwlen = strlen(input);
		if (passwlen > MAX_NAME_LEN)
			printf("Please enter upto %d characters maximum..\n", MAX_NAME_LEN);
		if (passwlen < 4)
			printf("Please enter at least 4 characters..\n");

	} while (passwlen > MAX_NAME_LEN || passwlen < 4);
	strcpy(userpasw, input);
	
	for(i=0, s=d=username; i<namelen ; i++) *d++ = (*s++) +1;
	write(passwfile, username, namelen);
	len = MAX_NAME_LEN - namelen;
	if (len) write(passwfile, "          ", len);

	for(i=0, s=d=userpasw; i<passwlen; i++) *d++ = (*s++) +2;
	write(passwfile, userpasw, passwlen);
	len = MAX_NAME_LEN - passwlen;
	if (len) write(passwfile, "          ", len);

	write(passwfile, "\r", 1);

	for(i=0, s=d=username; i<namelen ; i++) *d++ = (*s++) -1;
	printf("\nUser '%s' added to list of Authorized Users\n", username);

	close(passwfile);

	return 0;
}

//---------------------------------------------------------------------------
// Get an invisible string in an ANSI compatible, portable way.
//---------------------------------------------------------------------------
void get_password		(char *prompt_str, char *passw_str) {

	printf(prompt_str);				// print the prompt

	printf(SET_FG_0);				// switch to WHITE foreground
	scanf("%s", passw_str);			// get the string (cursor still moves...)
	printf(SET_FG_1);				// switch back to normal foreground color
}

//---------------------------------------------------------------------------
