 value the difference in technical superiority and brand recognition of BEL Valves products and service versus competition through.<reponame>610t/retrobsd<filename>src/games/hunt/driver.c
/*
 *  Hunt
 *  Copyright (c) 1985 <NAME>, <NAME>, <NAME>
 *  San Francisco, California
 *
 *  Copyright (c) 1985 Regents of the University of California.
 *  All rights reserved.  The Berkeley software License Agreement
 *  specifies the terms and conditions for redistribution.
 *
 * 1997/9/9 - updated to use sigprocmask (and compute the alarm mask correctly)
 */

# include	"hunt.h"
# include	<signal.h>
# include	<errno.h>
# include	<sys/ioctl.h>
# include	<sys/time.h>

# ifndef pdp11
# define	RN	(((Seed = Seed * 11109 + 13849) >> 16) & 0xffff)
# else pdp11
# define	RN	((Seed = Seed * 11109 + 13849) & 0x7fff)
# endif pdp11

int	Seed = 0;

# ifdef CONSTANT_MOVE
static struct itimerval	Timing;
# endif CONSTANT_MOVE

SOCKET	Daemon;
# ifdef	INTERNET
int	Test_socket;		/* test socket to answer datagrams */
# define	DAEMON_SIZE	(sizeof Daemon)
# else INTERNET
# define	DAEMON_SIZE	(sizeof Daemon - 1)
# endif	INTERNET

/*
 * main:
 *	The main program.
 */
main()
{
	register PLAYER	*pp;
	register int	had_char;
# ifdef INTERNET
	register long	test_mask;
	int		msg;
	int		namelen;
	SOCKET		test;
# endif INTERNET
# ifdef CONSTANT_MOVE
	sigset_t	alarm_sigset;
# endif CONSTANT_MOVE
	static long	read_fds;

	init();
	Sock_mask = (1 << Socket);
# ifdef INTERNET
	test_mask = (1 << Test_socket);
# endif INTERNET

# ifdef CONSTANT_MOVE
	sigemptyset(&alarm_sigset);
	sigaddset(&alarm_sigset, SIGALRM);
	(void) sigprocmask(SIG_BLOCK, &alarm_sigset, NULL);
	(void) signal(SIGALRM, moveshots);
# endif CONSTANT_MOVE

	while (Nplayer > 0) {
# ifdef CONSTANT_MOVE
		(void) sigprocmask(SIG_UNBLOCK, &alarm_sigset, NULL);
# endif CONSTANT_MOVE
		read_fds = Fds_mask;
		errno = 0;
# ifndef OLDIPC
		while (select(Num_fds, &read_fds, (int *) NULL,
		    (int *) NULL, (struct timeval *) NULL) < 0)
# else OLDIPC
		while (select(20, &read_fds, NULL, 32767) < 0)
# endif OLDIPC
		{
			if (errno!= EINTR)
				perror("select");
			if (Nplayer == 0)
				goto out;
			errno = 0;
		}
		Have_inp = read_fds;
# ifdef CONSTANT_MOVE
		(void) sigprocmask(SIG_BLOCK, &alarm_sigset, NULL);
# endif CONSTANT_MOVE
# ifdef INTERNET
		if (read_fds & test_mask) {
			namelen = DAEMON_SIZE;
# ifndef OLDIPC
			(void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
				0, (struct sockaddr *) &test, &namelen);
			(void) sendto(Test_socket, (char *) &msg, sizeof msg,
				0, (struct sockaddr *) &test, DAEMON_SIZE);
# else OLDIPC
			(void) receive(Test_socket, (struct sockaddr *) &test,
				(char *) &msg, sizeof msg);
			(void) send(Test_socket, (struct sockaddr *) &test,
				(char *) &msg, sizeof msg);
# endif OLDIPC
		}
# endif INTERNET
		for (;;) {
			had_char = FALSE;
			for (pp = Player; pp < End_player; pp++)
				if (havechar(pp)) {
					execute(pp);
					pp->p_nexec++;
					had_char++;
				}
# ifdef MONITOR
			for (pp = Monitor; pp < End_monitor; pp++)
				if (havechar(pp)) {
					mon_execute(pp);
					pp->p_nexec++;
					had_char++;
				}
# endif MONITOR
			if (!had_char)
				break;
# ifdef CONSTANT_MOVE
			for (pp = Player; pp < End_player; pp++) {
				look(pp);
				sendcom(pp, REFRESH);
			}
# ifdef MONITOR
			for (pp = Monitor; pp < End_monitor; pp++)
				sendcom(pp, REFRESH);
# endif MONITOR
# else CONSTANT_MOVE
			moveshots();
# endif CONSTANT_MOVE
			for (pp = Player; pp < End_player; )
				if (pp->p_death[0]!= '\0')
					zap(pp, TRUE);
				else
					pp++;
# ifdef MONITOR
			for (pp = Monitor; pp < End_monitor; )
				if (pp->p_death[0]!= '\0')
					zap(pp, FALSE);
				else
					pp++;
# endif MONITOR
		}
		if (read_fds & Sock_mask)
			answer();
		for (pp = Player; pp < End_player; pp++) {
			if (read_fds & pp->p_mask)
				sendcom(pp, READY, pp->p_nexec);
			pp->p_nexec = 0;
			(void) fflush(pp->p_output);
		}
# ifdef MONITOR
		for (pp = Monitor; pp < End_monitor; pp++) {
			if (read_fds & pp->p_mask)
				sendcom(pp, READY, pp->p_nexec);
			pp->p_nexec = 0;
			(void) fflush(pp->p_output);
		}
# endif MONITOR
	}
out:
# ifdef	CONSTANT_MOVE
	bul_alarm(0);
# endif	CONSTANT_MOVE

# ifdef MONITOR
	for (pp = Monitor; pp < End_monitor; )
		zap(pp, FALSE);
# endif MONITOR
	cleanup(0);
}

/*
 * init:
 *	Initialize the global parameters.
 */
init()
{
	register int	i;
# ifdef	INTERNET
	SOCKET		test_port;
	auto int	msg;
# endif	INTERNET
	int cleanup();

# ifndef DEBUG
	(void) ioctl(fileno(stdout), TIOCNOTTY, NULL);
	(void) setpgrp(getpid(), getpid());
	(void) signal(SIGHUP, SIG_IGN);
	(void) signal(SIGINT, SIG_IGN);
	(void) signal(SIGQUIT, SIG_IGN);
	(void) signal(SIGTERM, cleanup);
# endif DEBUG

	(void) chdir("/usr/tmp");	/* just in case it core dumps */
	(void) signal(SIGPIPE, SIG_IGN);

# ifdef	INTERNET
	Daemon.sin_family = SOCK_FAMILY;
# ifdef OLD
	if (gethostname(local_name, sizeof local_name) < 0) {
		perror("gethostname");
		exit(1);
	}
	if ((hp = gethostbyname(local_name)) == NULL) {
		fprintf(stderr, "Unknown host %s\n", local_name);
		exit(1);
	}
	bcopy(hp->h_addr, &(Daemon.sin