#ifndef lint
static char *RCSid = "$Header: main.c,v 1.13 90/03/19 11:29:02 mr-frog Exp $";
#endif

/*
 * main.c
 *
 * main command loop and initialization
 * for empire tm server
 *
 * Dave Pare, 1986
 */
#include "misc.h"
#include "tm.h"
#include "user.h"
#include "bit.h"
#include "file.h"
#include "io.h"

#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/un.h>
#include <signal.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <fcntl.h>

#ifndef SIGCHLD
#define SIGCHLD SIGCLD
#endif

extern	s_char serverport[];

extern	user_add();
int	fd_reserve;
static	int expire;
static	int done;

int	(*leprfunc)();		/* logerror pr function, == NULL */

s_char	*program = "tm";

alarmhandler()
{
	expire++;
#ifdef sys5
	(void) signal(SIGALRM, alarmhandler);
#endif
}

child()
{
	done++;
#ifdef sys5
#if defined(hpux) || defined(aix)
	/* HP-UX can't reset signal handler until the wait(2) is done */
#else
	(void) signal(SIGCHLD, child);
#endif
#endif
}

cleanup(code)
	int	code;
{
	(void) unlink(serverport);
	exit(code);
}

readhours(code)
int	code;
{
	long	now;
	int	hour[2];

	time(&now);
	(void) gamehours(now, hour);
}

main()
{
	int	readhours();
	int	child();
	int	catch();
	extern	int errno;
	struct	sockaddr_un un;
	long	now;
	int	s;
	int	hour[2];

#ifndef DEBUG
#ifndef SABER
	disassoc();
#endif
#endif
	time(&now);
	srandom(now);
	setfdtablesize(32, 256);
	initfiles();
	(void) signal(SIGALRM, alarmhandler);
	(void) signal(SIGCHLD, child);
	(void) signal(SIGTERM, cleanup);
	(void) signal(SIGUSR1, readhours);
#ifndef DEBUG
	(void) signal(SIGPIPE, SIG_IGN);
	(void) signal(SIGBUS, catch);
	(void) signal(SIGILL, catch);
	(void) signal(SIGFPE, catch);
	(void) signal(SIGSEGV, catch);
#endif
	(void) gamehours(now, hour);
	initlock();
	schedule_update();
	strcpy(un.sun_path, serverport);
	un.sun_family = AF_UNIX;
	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
		logerror("unix socket create");
		exit(1);
	}
	if (bind(s, (struct sockaddr *) &un, strlen(un.sun_path)+2) < 0) {
		logerror("another %s running?  If not, rm %s and retry",
			program, un.sun_path);
		exit(1);
	}
	if (listen(s, 5) < 0) {
		logerror("unix socket listen");
		cleanup(1);
	}
	user_init();
	io_init();
	(void) io_open(s, IO_READ|IO_NEWSOCK, 0, user_add, 0);
	logerror("tm server started, pid %d", getpid());
	/* squirrel away file descriptors "for later" */
	fd_reserve = getfdtablesize() - 5;
	while (1) {
		if (expire) {
			execute();
			expire = 0;
		} else if (done) {
			exec_done();
			done = 0;
		}
		if (io_select(0) <= 0) {
			if (errno == EINTR) {
				/* a signal! */
				errno = 0;
				continue;
			}
			logerror("PANIC: main loop select");
			cleanup(1);
		}
		io_flush();
		dw_flush();
	}
}

catch(sig)
	int	sig;
{
	logerror("trapped signal %d", sig);
	(void)signal(SIGIOT, SIG_DFL);		/* For Sun */
	(void)signal(SIGILL, SIG_DFL);		/* For VAX */
	(void)abort();
}
