#ifndef lint
static char *RCSid = "$Header: main.c,v 1.23 90/03/19 10:50:14 mr-frog Exp $";
#endif /* not lint */

/*
 * main.c
 *
 * main command loop for Empire
 *
 * from PSL Empire, 1985
 */

#include "gamesdef.h"
#include "misc.h"
#include "proto.h"
#include "var.h"
#include "com.h"
#include "nat.h"
#include "sect.h"
#include "deity.h"
#include "file.h"
#include "proto.h"
#include "io.h"

#include <stdio.h>
#include <sys/time.h>
#include <fcntl.h>

extern	int m_m_p_d;

char	combuf[512];
char	*argp[64];
char	*condarg;
time_t	lasttime;
iop_t	playerio;
iop_t	iop;

char	*program = "player";
int	execmode;

extern	int pr();
int	(*leprfunc)() = pr;

natid	cnum;
int	nstat, ncomstat, minleft, btused;
int	visitor, god, broke;
int	owner;
time_t	curup;                   /* used in calc of minutes used */
double  dolcost;

#ifdef BLITZ
	time_t blitz_time;
#endif /* BLITZ */

main(argc, argv)
	int	argc;
	char	**argv;
{
#ifdef BAN
        FILE *banfile, *authfile;
        int  match;
        char hostname[257];
        char username[257];
#endif
	extern	int aborted;
	struct	natstr *natp;
	int	hour[2];
	int	clen;
	int	flags;

	flags = IO_READ|IO_WRITE;
	if (isatty(0)) {
		/* XXX for debugging */
		close(0);
		close(1);
		close(2);
		if (open("/dev/tty", O_RDWR, 0) < 0)
			return -1;
	} else
		flags |= IO_NBLOCK;
	io_init();
	playerio = io_open(0, flags, IO_BUFSIZE, 0, 0);
	if (playerio == 0)
		return -1;
	time(&lasttime);
	(void) time(&curup);
	(void) srandom(curup >> 16);
	sigsetup();
	showvers(CLIENTPROTO);
#ifdef BAN
	if (argc < 2) {
#else
	if (argc != 2) {
#endif /* BAN */
		pr("Empire problems!  Need country #\n");
		tm_exit(1);
	}
	cnum = atoi(argv[1]);
	if (cnum < 0 || cnum >= MAXNOC) {
		pr(fmt("cnum %d invalid\n", cnum));
		tm_exit(2);
	}
#ifdef BAN
        if((banfile = fopen(BANFILE,"r")) == NULL) {
                logerror("Cannot find ban file");
                }
        else {
                match = 0;
                fgets(hostname,256,banfile);
                fgets(username,256,banfile);
                while(!feof(banfile)) {
                        hostname[strlen(hostname)-1] = NULL;
                        username[strlen(username)-1] = NULL;
                        if(strstr(argv[3],hostname) == NULL) {
                                fgets(hostname,256,banfile);
                                fgets(username,256,banfile);
                        }
                        else {
                                if(strstr(argv[2],username) == NULL) {
                                        fgets(hostname,256,banfile);
                                        fgets(username,256,banfile);
                                } else {
                                        match++;
                                        fgets(hostname,256,banfile);
                                        fgets(username,256,banfile);
                                }
                        }
                }
                fclose(banfile);
                        if(match > 0) {
                                logerror("Attempted login by BANNED host %s@%s",
                                        argv[2],argv[3]);
                                pr("You Have been BANNED FROM THIS GAME!!!");
                                tm_exit(0);
                        }
        }
#endif
	/*
	 * get rid of the country number
	 */
	clen = strlen(argv[1]);
	while (clen-- > 0)
		argv[1][clen] = ' ';
	if (!tm_connect()) {
		logerror("Can't connect to the transaction manager!");
		(void) fflush(stdout);
		tm_exit(0);
	}
	init_files();
#if	defined(BMAP) || defined(AUTONAV)
	/* JNP 12/15/89   Open the bigmap file */
	openbigmap(cnum);
#endif
	init_nats();
	natp = getnatp(cnum);
#ifdef BAN
        if (god) {
                if((authfile = fopen(AUTHFILE,"r")) == NULL) {
                        logerror("Cannot find auth file");
                        }
                else {
                        match = 0;
                        fgets(hostname,256,authfile);
                        fgets(username,256,authfile);
                        while(!feof(authfile)) {
                                hostname[strlen(hostname)-1] = NULL;
                                username[strlen(username)-1] = NULL;
                                if(strstr(argv[3],hostname) == NULL) {
                                        fgets(hostname,256,authfile);
                                        fgets(username,256,authfile);
                                }
                                else {
                                        if(strstr(argv[2],username) == NULL)
                                        {
                                                fgets(hostname,256,authfile);
                                                fgets(username,256,authfile);
                                        } else {
                                                match++;
                                                fgets(hostname,256,authfile);
                                                fgets(username,256,authfile);
                                        }
                                }
                        }
                        fclose(authfile);
                        if(match == 0) {
                                logerror("NON-AUTHed Login attempted by %s@%s",
                                          argv[2],argv[3]);
                                pr("Unauthorized Login!\n");
                                tm_exit(0);
                        }
                }
        }
#endif
	if (!gamehours(curup, hour)) {
		pr("Empire hours restriction in force\n");
		if ((natp->nat_stat & STAT_GOD) == 0) {
			fflush(stdout);
			tm_exit(0);
		}
	}
	getconstants();
	daychange(curup);
	if ((minleft = getminleft(curup, hour, &m_m_p_d)) <= 0) {
		pr("Time exceeded today\n");
		tm_exit(0);
	}
	NAT_DELTA(nat_login, cnum, 1);
	while (status()) {
		if (command() == 0 && !aborted)
			break;
		aborted = 0;
	}
	quit();
	/*NOTREACHED*/
}

int
command()
{
	char	*redir;

	if (getcommand(combuf) < 0)
		return 0;
	if (parse(combuf, argp, &condarg, 0, &redir) < 0) {
		pr("See \"info syntax\"?\n");
	} else if (dispatch(combuf, redir) < 0)
		pr("Try \"list of commands\", \"info commands\" or \"info\"\n");
	return 1;
}

/*
 * empire main loop; plenty of system calls per iteration!
 * time(&curup), getsect(0,0), read(tm), read(gamedown),
 * read(stdin, cmdbuf).
 */
int
status()
{
	extern	int locks;
	extern	int btused;
	struct	natstr *natp;
	int	minute;
	struct	sctstr sect;
	int	hour[2];

	if (io_error(playerio) || io_eof(playerio))
		return 0;
	if (io_error(iop) || io_eof(iop)) {
		io_close(iop);
		pr("Transaction manager died!\n");
		return 0;
	}
	natp = getnatp(cnum);
	visitor = (natp->nat_stat & (STAT_NORM|STAT_GOD)) == 0;
	if (dolcost != 0.0) {
		if (dolcost > 100.0)
			pr(fmt("That just cost you $%.2f\n", dolcost));
		else if (dolcost < -100.0)
			pr(fmt("You just made $%.2f\n", -dolcost));
		if (natp->nat_money < dolcost && !broke) {
			broke = 1;
			nstat &= ~MONEY;
			pr("You are now broke; industries are on strike.\n");
		} else if (broke && natp->nat_money - dolcost > 0) {
			broke = 0;
			nstat |= MONEY;
			pr(fmt("You are	no longer broke!\n"));
		}
		NAT_DELTA(nat_money, cnum, -(int)(dolcost+0.5));
		dolcost = 0.0;
	}
	getsect(natp->nat_xcap, natp->nat_ycap, &sect);
	if ((sect.sct_type == SCT_CAPIT || sect.sct_type == SCT_SANCT) &&
	    sect.sct_own == cnum)
		nstat |= CAP;
	else
		nstat &= ~CAP;
	ncomstat = nstat;
	(void) time(&curup);
	minute = (curup - lasttime) / 60;
	if (minute > 0) {
		minleft -= minute;
		if (minleft <= 0) {
			/*
			 * countdown timer "minleft" has expired.
			 * either day change, or hours restriction
			 */
			daychange(curup);
			if (!gamehours(curup, hour)) {
				pr("Empire hours restriction in force\n");
				if ((natp->nat_stat & STAT_GOD) == 0)
					return 0;
			}
			minleft = getminleft(curup, hour, &m_m_p_d);
		}
		lasttime += minute * 60;
		NAT_DELTA(nat_minused, cnum, minute);
	}
	if ((nstat & NORM) && natp->nat_minused > m_m_p_d) {
		pr("Max minutes per day limit exceeded.\n");
		ncomstat = VIS;
	}
	if (btused) {
		NAT_DELTA(nat_btu, cnum, -btused);
		btused = 0;
	}
	if (natp->nat_tgms > 0) {
		if (natp->nat_tgms == 1)
			pr("You have a new telegram waiting ...\n");
		else
			pr(fmt("You have %s new telegrams waiting ...\n",
				numstr(natp->nat_tgms)));
		NAT_DELTA(nat_tgms, cnum, -natp->nat_tgms);
	}
#ifdef WIRE
	if (natp->nat_ann > 0) {
		if (natp->nat_ann == 1)
			pr("You have a new announcement waiting ...\n");
		else
			pr(fmt("You have %s new announcements waiting ...\n",
				numstr(natp->nat_ann)));
		NAT_DELTA(nat_ann, cnum, -natp->nat_ann);
	}
#endif /* WIRE */
	if (!visitor && !god && (nstat & CAP) == 0)
		pr("You lost your capital... better designate one\n");
	if (locks) {
		tm_unlock(locks);
		locks = 0;
	}
	if (gamedown() && !god) {
		pr("gamedown\n");
		return 0;
	}
	return 1;
}

/*
 * actually a command; redirection and piping ignored.
 * XXX This whole mess should be redone; execute block should
 * start with "exec start", and should end with "exec end".
 * We'll wait until 1.2 I guess.
 */
int
execute()
{
	char	buf[512];
	int	abort;
	char	*redir;

	abort = 0;
	redir = 0;
	prexec(argp[1]);
	while (!abort && status()) {
		if (recvclient(buf, sizeof(buf)) < 0)
			break;
		if (parse(buf, argp, &condarg, 0, &redir) < 0) {
			abort = 1;
			continue;
		}
		if (redir == 0)
			pr(fmt("\nExecute : %s\n", buf));
		if (dispatch(buf, redir) < 0)
			abort = 1;
	}
	if (redir == 0)
		pr(fmt("Execute : %s\n", abort ? "aborted" : "terminated"));
	return RET_OK;
}
