/* 
 * getname.c
 *
 * Kevin Smith 09/28/88
 *
 */
#include "copyright2.h"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "defs.h"
#include INC_SYS_FCNTL
#include "struct.h"
#include "data.h"
#include "packets.h"
/*long time();*/
char *crypt();

getname()
/* Let person identify themselves from w */
{
    *(me->p_name)=0;
    while (*(me->p_name)==0) {
	handleLogin();
    }
}

handleLogin()
{
    static struct statentry player;
    static int position= -1;
    int plfd;
    int i;
    int entries;
    off_t file_pos;

    *namePick='\0';
    FD_SET (CP_LOGIN, &inputMask);
    while (*namePick=='\0') {
	/* Been ghostbusted? */
	if (me->p_status==PFREE) exitGame();
	if (isClientDead()) exitGame();
	socketPause();
	readFromClient();
    }

    if ((strcmp(namePick, "Guest")==0 || strcmp(namePick, "guest")==0) &&
	!lockout()) {
	hourratio=5;
	MZERO(&player.stats, sizeof(struct stats));
	player.stats.st_tticks = 1;
	player.stats.st_flags=ST_INITIAL;
	for (i=0; i<95; i++) {
	    player.stats.st_keymap[i]=i+32;
	}
	player.stats.st_keymap[95]=0;
	/* If this is a query on Guest, the client is screwed, but 
	 * I'll send him some crud anyway. 
	 */
	if (passPick[15]!=0) {
	    sendClientLogin(&player.stats);
	    flushSockBuf();
	    return;
	}
	sendClientLogin(&player.stats);
	flushSockBuf();
	strcpy(me->p_name, namePick);
	me->p_pos= -1;
	MCOPY(&player.stats, &(me->p_stats), sizeof(struct stats));
	return;
    }

#ifdef OBSERVERS
    /* mark the observer with special flag */
    if (Observer) {
	int x = strlen (namePick);
	if (namePick[x - 1] != 01) {
	    if (x > 13)
		x = 13;
	    namePick[x] = ' ';
	    namePick[x + 1] = 01;
	    namePick[x + 2] = '\0';
	}
    }
#endif

    hourratio=1;

    /* We look for the guy in the stat file */
    if (strcmp(player.name, namePick) != 0) {
	for (;;) {	/* so I can use break; */
	    plfd = open(PlayerFile, O_RDONLY, 0644);
	    if (plfd < 0) {
		ERROR(1,("I cannot open the player file!\n"));
		strcpy(player.name, namePick);
		position= -1;
		ERROR(1,("Error number: %d\n", errno));
		break;
	    }
	    position=0;
	    while (read(plfd, (char *) &player, sizeof(struct statentry)) ==
		    sizeof(struct statentry)) {
		if (strcmp(namePick, player.name)==0) {
		    close(plfd);
		    break;
		}
		position++;
	    }
	    if (strcmp(namePick, player.name)==0) break;
	    close(plfd);
	    position= -1;
	    strcpy(player.name, namePick);
	    break;
	}
    } 

    /* Was this just a query? */
    if (passPick[15]!=0) {
	if (position== -1) {
	    sendClientLogin(NULL);
	} else {
	    sendClientLogin(&player.stats);
	}
	flushSockBuf();
	return;
    } 

    /* A new guy? */
    if ((position== -1) && !lockout()) {
	strcpy(player.name, namePick);
	strcpy(player.password, crypt(passPick, namePick));
	MZERO(&player.stats, sizeof(struct stats));
	player.stats.st_tticks = 1;
	player.stats.st_flags=ST_INITIAL;
	for (i=0; i<95; i++) {
	    player.stats.st_keymap[i]=i+32;
	}
	plfd = open(PlayerFile, O_RDWR|O_CREAT, 0644);
	if (plfd < 0) {
	    sendClientLogin(NULL);
	} else {
	    if ((file_pos = lseek(plfd, 0, SEEK_END)) < 0) {
		sendClientLogin(NULL);
 	    }	
	    write(plfd, (char *) &player, sizeof(struct statentry));
	    close(plfd);
	    entries = file_pos / sizeof(struct statentry);
	    me->p_pos = entries;
	    MCOPY(&player.stats, &(me->p_stats), sizeof(struct stats));
	    strcpy(me->p_name, namePick);
	    sendClientLogin(&player.stats);
	}
	flushSockBuf();
	return;
    }

    /* An actual login attempt */
    if ((strcmp(player.password, crypt(passPick, player.password)) != 0) ||
	lockout()){
	sendClientLogin(NULL);
    } else {
	sendClientLogin(&player.stats);
	strcpy(me->p_name, namePick);
	me->p_pos=position;
	MCOPY(&player.stats, &(me->p_stats), sizeof(struct stats));
    }
    flushSockBuf();
    return;
}

savestats()
{
    int fd;

    if (me->p_pos < 0) return;
    fd = open(PlayerFile, O_WRONLY, 0644);
    if (fd >= 0) {
	me->p_stats.st_lastlogin = time(NULL);
	lseek(fd, 32 + me->p_pos * sizeof(struct statentry) ,0);
	write(fd, (char *) &me->p_stats, sizeof(struct stats));
	close(fd);
    }
}

/* return true if we want a lockout */
int lockout()
{
    return (
	    (strncmp(login, "bozo", 4) == 0) ||
	    0
	    );
}
