[net.sources.games] search for SVR2 part 3

lars@myab.UUCP (lars) (03/13/86)

#--------CUT---------CUT---------CUT---------CUT--------#
#########################################################
#                                                       #
# This is a shell archive file.  To extract files:      #
#                                                       #
#    1)	Make a directory for the files.                 #
#    2) Write a file, such as "file.shar", containing   #
#       this archive file into the directory.           #
#    3) Type "sh file.shar".  Do not use csh.           #
#                                                       #
#########################################################
#
#
echo x - scab.c
sed 's/^Z//' >scab.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: scab.c,v 2.1 85/04/10 17:31:37 matt Stab $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Greg Ordy	1979
Z * Rewrite by Sam Leffler	1981
Z * Socket code by Dave Pare	1983
Z * Ported & improved
Z *      by Matt Crawford	1985
Z *
Z * routines that handle scabs - players deserving of 
Z * "special" attention.
Z *
Z * Copyright (c) 1979
Z *
Z */
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Z
Zvoid makescab(p)
Zregister t_player *p;
Z{
Z	extern	t_alien alien[NALIEN];
Z	extern	t_player *whoscab;
Z	void	enterscab();
Z	register t_alien *pa;
Z
Z	p->scabcount++;
Z	if (p->scabcount > 2)
Z		enterscab(p);
Z	for (pa = alien; pa < &alien[NALIEN]; pa++) {
Z		if (pa->type != SHANK)
Z			continue;
Z		pa->aname = NAMESH;
Z		pa->whotoget = (thing *)p;
Z	}
Z	whoscab = p;
Z}
Z
Zvoid seescab(p)
Zregister t_player *p;
Z{
Z	extern	t_player *whoscab;
Z	extern	void pstatus();
Z
Z	if (whoscab == NOBODY)
Z		pstatus(p, "Currently no SCAB.");
Z	else
Z		pstatus(p, "Current SCAB-- %s", p->plname);
Z}
Z
Zstatic void enterscab(p)
Zregister t_player *p;
Z{}
STUNKYFLUFF
set `sum < scab.c`
if test 19833 != $1
then
echo scab.c: Error. number of characters is: $1, should be: 19833.
fi
#
#
echo x - score.c
sed 's/^Z//' >score.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: score.c,v 2.1 85/04/10 17:31:40 matt Stab $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Dave Pare	1983
Z * Ported & improved
Z *      by Matt Crawford	1985
Z *
Z * routine to update player scores, formerly handled in
Z * search.c, but now moved to the daemon's care.
Z *
Z * Copyright (c) 1983
Z *
Z * $Log:	score.c,v $
Z * Revision 2.1  85/04/10  17:31:40  matt
Z * Major de-linting and minor restructuring.
Z * 
Z */
Z
Z#include <stdio.h>
Z#include <sys/types.h>
Z#include <sys/file.h>
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Zvoid putplayer(p)
Zregister t_player *p;
Z{
Z	extern	long	lseek();
Z	extern	char	*strcpy();
Z	extern	int	pfd;
Z	int	index;
Z	int	found;
Z	t_totals	entry;
Z
Z	found = 0;
Z	(void)lseek(pfd, 0L, 0);
Z	for (index=0; read(pfd, (char *)&entry, sizeof(t_totals)) > 0; index++)
Z		if (!strcmp(p->plname, entry.ptname)) {
Z			found++;
Z			break;
Z		}
Z	if (!found) {
Z		bzero((char *)&entry, sizeof(entry));
Z		strcpy(entry.ptname, p->plname);
Z	} else
Z		(void)lseek(pfd, (long)(index * sizeof(t_totals)), 0);
Z	if (p->status.killed == TRUE)
Z		entry.ptkilled++;
Z	if (entry.ptbest < p->points)
Z		entry.ptbest = p->points;
Z	entry.ptpoints += p->points;
Z	entry.ptgames++;
Z	entry.pthits += p->phits;
Z	entry.ptkills += p->pkills;
Z	entry.ptahits += p->ahits;
Z	entry.ptlast = p->points;
Z	write(pfd, (char *)&entry, sizeof(t_totals));
Z}
STUNKYFLUFF
set `sum < score.c`
if test 47665 != $1
then
echo score.c: Error. number of characters is: $1, should be: 47665.
fi
#
#
echo x - search.c
sed 's/^Z//' >search.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: search.c,v 2.4 85/08/06 19:20:08 matt Exp $";
Z#endif
Z/*
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original          by Dave Pare	1983
Z * Ported & improved by Matt Crawford	1985
Z * Ported            by Lars Pensjo	1985
Z * Ported & improved by Tore Fahlstrom	1985
Z *
Z * The player process.  Search tries to connect to the daemon via a message
Z * queue. It gathers data about the player and sends it along to the daemon.
Z * Termcap routines taken from the original SVR2 source.
Z *
Z * Copyright (c) 1983
Z */
Z
Z#include <fcntl.h>
Z#include <stdio.h>
Z#include <sys/types.h>
Z#include <sys/stat.h>
Z#include <sys/file.h>
Z#include <ctype.h>
Z#include <signal.h>
Z#include <time.h>
Z#include <sys/ipc.h>
Z#include <sys/msg.h>
Z#include <pwd.h>
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Z#define XQZERO	0		/* flag value: Nothing dangerous done */
Z#define XQINIT	1		/* flag value: done savetty */
Z#define XQCONN	2		/* flag value: deamon servs this player */
Z#define XQDISC	3		/* flag value: deamon ignore this player */
Zint	xqstat = XQZERO;	/* Make it possible to close down all shit */
Z
Zstruct message omesg;		/* buffer for outgoing messages */
Zstruct message imesg;		/* buffer for incoming messages */
Zstruct message amesg;		/* buffer for ack messages */
Z
Zint	fd;			/* the terminal - opened from "/dev/tty" */
Zt_file	player;			/* who are we, what does our term look like */
Zint	sock;			/* socket to daemon */
Zint	uid;			/* user id -- well, not the real one */
Zint	owner = 0;		/* True if owner is playing */
Z
Z
Zmain(argc, argv)
Zint argc;
Zchar *argv[];
Z{
Z	extern	catchsignal ();
Z	char	*strcpy(), *strncpy();
Z	int pid;
Z	int apa;
Z
Z	register int n;			/* read count register */
Z		 int sendok = TRUE;	/* did we get away the last message */
Z		 int acknok = TRUE;	/* did a rcve before send */
Z
Z	if (geteuid() == OWNERID) {
Z	    owner = 1;
Z	    setuid(OWNERID);
Z	    goto skip;	/* Skip boring things */
Z	}
Z	/*
Z	 * Start up daemon if not running
Z	 */
Z	if (!excl("/tmp/SEARCH")) {
Z	    printf("Starting daemon...\n");
Z	    system("/usr/games/lib/search/searchd");
Z	    printf("Done\n");
Z	}
Z
Z	if (!isatty(0) || !isatty(1))
Z		fatal("You must have a terminal to play search!\n");
Z	
Zskip:
Z	/*
Z	 * Set all the signals
Z	 */
Z	if (owner) {
Z	    (void) signal(SIGINT,  SIG_IGN);
Z	    (void) signal(SIGTERM, SIG_IGN);
Z	    (void) signal(SIGHUP,  SIG_IGN);
Z	    (void) signal(SIGPIPE, SIG_IGN);
Z	} else {
Z	    (void) signal(SIGINT,  catchsignal);
Z	    (void) signal(SIGTERM, SIG_IGN);
Z	    (void) signal(SIGHUP,  catchsignal);
Z	    (void) signal(SIGPIPE, catchsignal);
Z	}
Z
Z	/*
Z	 *  Compute a search-user-id. It must be larger than 1 because 0
Z	 *  and 1 are special. 0 is notused. 1 is used for new players and
Z	 *  therefore used only once in the game. 
Z	 *  Uid is also a multiple of 3, because the messages sent to the
Z	 *  deamon have an even type (uid) and the messages recieved have an
Z	 *  odd type (uid+1).
Z	 */
Z	uid = 3 * getpid() + 3;
Z
Z	/*
Z	 *  Try to open a channel to the deamon (if it is up and running)
Z	 */
Z	for (apa = 0; (sock = getid()) < 0; apa++) {
Z	    if (apa == 5) {
Z		if (!owner) printf("Can't start daemon\n");
Z		exit(1);
Z	    }
Z	    sleep(3);
Z	}
Z
Z	/*
Z	 *  Call initscr() to make use of handy functions.  Save the old term
Z	 *  characteristics.  It is also advisable to do all terminal dependent
Z	 *  operations here in search and not in the deamon.
Z	 *  Set up terminal modes for game
Z	 */
Z	savetty ();
Z	xqstat = XQINIT;
Z	cbreak();
Z	noecho();
Z
Z
Z	/*
Z	 *  Open our own tty for both reading & writing - makes it
Z	 *  much easier to do ioctls since we only have to do them on
Z	 *  the one fd now.
Z	 */
Z	if (!owner)
Z	    if ((fd=open("/dev/tty", O_RDWR , 0)) < 0)
Z		fatal("Cannot open your tty\n");
Z
Z	/*
Z	 *  Now set up the player structure for transmission to the daemon.
Z	 */
Z	if (owner) (void) strcpy(player.p_name, "search");
Z	else (void) strcpy(player.p_name, (getpwuid (getuid ()))->pw_name);
Z	player.uid = uid;
Z	if (termcap(&player))
Z		fatal("Terminal unsuitable for play!\n");
Z
Z	/*
Z	 * Transmit all the info we've gathered to the daemon
Z	 */
Z	omesg.mtype = 1;	/* special type used only here */
Z	omesg.ident = uid;	/* to tell the deamon who I am */
Z	if (sizeof(player) > (sizeof(omesg) - 8))
Z		fatal("Prog. error: player struct > sizeof omesg.\n");
Z	bcopy(omesg.text, &player, sizeof(player));
Z	if (msgsnd(sock, &omesg, (sizeof(player) + 8), 0) == -1)
Z		fatal("Startup request failed!\n");
Z	xqstat = XQCONN;
Z
Z	omesg.mtype = uid;
Z	imesg.mtype = uid + 1;
Z	amesg.mtype = uid + 2;
Z	if (!owner) pid = fork();
Z	/* When owner is playing, don't read from keyboard */
Z	if(!owner && !pid){
Z	    /* child */
Z	    (void) signal(SIGINT,  SIG_DFL);
Z	    (void) signal(SIGTERM, SIG_IGN);
Z	    (void) signal(SIGHUP,  SIG_DFL);
Z	    (void) signal(SIGPIPE, SIG_DFL);
Z	    /*
Z	    ** just read from the keyboard, send to deamon and wait for ack.
Z	    */
Z	    for (;;) {
Z
Z		/*  No use of reading more than QSIZE characters because
Z		 *  the deamon input queue cannot take more than that.
Z		 */
Z		if ((n=read(fd, omesg.text, QSIZE)) == -1)
Z		    fatal("Terminal read failed!\n");
Z		omesg.text[n] = '\0'; /* remove in the future */
Z		if (msgsnd(sock,&omesg,8+n,0) == -1) {
Z		    fatal("msgsnd failed!\n");
Z		}
Z		/*
Z		 *  Wait for ack.
Z		 */
Z		if (msgrcv(sock,&amesg,sizeof amesg,uid+2,0)!= -1) {
Z			switch (amesg.text[0]) {
Z			default:
Z				fatal("ack gets funny!\n");
Z				break;
Z			case 1:
Z				/* Acknowledge -- ok to send next message */
Z				break;
Z			}
Z		} else
Z			fatal("msgrcv ack failed!\n");
Z	    }
Z	} else {
Z	    /* parent */	
Z	    /*
Z	    ** read from deamon and write it on the screen
Z	    */
Z	    for(;;){
Z		if (msgrcv(sock,&imesg,sizeof imesg,uid+1,0)!= -1) {
Z			switch (imesg.text[0]) {
Z			default:
Z				/* Output for your screen */
Z				if (owner) update(imesg.text);
Z				else write(fd, imesg.text, strlen(imesg.text));
Z				break;
Z			case 0:
Z				/* The deamon is finished with you */
Z				xqstat = XQDISC;
Z				if (owner) fatal("");
Z				/* Kill child */
Z				kill(pid,SIGINT);
Z				fatal("Welcome back to search!\n");
Z			}
Z		} else
Z			fatal("msgrcv failed!\n");
Z	    }
Z	}
Z}
Z
Zcatchsignal ()
Z{
Z	if (getuid() == OWNERID || geteuid() == OWNERID) {
Z	    printf("PID %d, uid %d, euid %d, owner %d\n",
Z		getpid(), getuid(), geteuid(), owner);
Z	    abort();
Z	}
Z	fatal("Signal caught -- execution terminated.\n");
Z}
Z
Zfatal (godbye)
Z	char *godbye;
Z{
Z	/*
Z	 *  Do the tty reset right away, no need to wait...
Z	 */
Z	if (xqstat != XQZERO)
Z		resetty ();
Z	if (xqstat == XQCONN || xqstat == XQDISC) {
Z		/*
Z		 *  Read back all output not yet read by deamon
Z		 *  Got to fix in the future so I know if I have sent any
Z		 *  messages that need to get acknowledge, or shall that
Z		 *  be done in the deamon. Maybe the deamon should read
Z		 *  back both channels.
Z		 */
Z		while(msgrcv(sock,&imesg,sizeof imesg,uid+2,IPC_NOWAIT) != -1);
Z		while(msgrcv(sock,&imesg,sizeof imesg,uid+1,IPC_NOWAIT) != -1);
Z		while(msgrcv(sock,&imesg,sizeof imesg,uid,IPC_NOWAIT) != -1);
Z	}
Z	if (!owner) write (fd, godbye, strlen (godbye));
Z	if (xqstat == XQCONN) {
Z		/* Need a nl -- the game was running */
Z		if (!owner) write (fd, "\n", 1);
Z		/*
Z		 *  Tell deamon that we are leaving now
Z		 */
Z		omesg.text[0] = '\0';	/* remove in the future */
Z		if (msgsnd (sock, &omesg, 8+1, 0) == -1) {
Z			char *tellem =
Z				"Failed to tell deamon that I'm leaving!\n";
Z			if (!owner) write (fd, tellem, sizeof (tellem));
Z			exit(xqstat == XQDISC ? 0 : 10 + xqstat);
Z		}
Z		for(;;)
Z		    if (msgrcv(sock,&imesg,sizeof imesg,uid+1,0)!= -1) {
Z			switch (imesg.text[0]) {
Z			default:
Z			    /* Output for your screen */
Z			    if (!owner)
Z			    write(fd, imesg.text, strlen(imesg.text));
Z			    break;
Z			case 0:
Z			    exit(xqstat == XQDISC ? 0 : 10 + xqstat);
Z			}
Z		    } else break;
Z	}
Z	exit(xqstat == XQDISC ? 0 : 10 + xqstat);
Z}
Z
Z
Zstatic	char	buf[1024], *bp = buf;
Zstruct	init {
Z	char	*i_name;	/* termcap name */
Z	char	*i_dest;	/* where to put the result */
Z	short	i_size;		/* sizeof associated buffer */
Z	short	i_pad;		/* padding flag: 0=no, 1=P, 2=P* */
Z} list[] = {
Z	{ "bc", player.p_BC, sizeof(player.p_BC), 0 },
Z	{ "up", player.p_UP, sizeof(player.p_UP), 0 },
Z	{ "cm", player.p_CM, sizeof(player.p_CM), 1 },
Z	{ "ce", player.p_CE, sizeof(player.p_CE), 1 },
Z	{ "cl", player.p_CL, sizeof(player.p_CL), 2 },
Z	{ NULLCH, NULLCH, 0, 0 }
Z};
Z
Z/*
Z * Build up the termcap description needed by searchd
Z */
Zint termcap(p)
Zregister t_file *p;
Z{
Z	register char	*cp;
Z	register int	lines,	cols;
Z	register struct init *pi = list;
Z	char	*term,	tbuf[BUFSIZ];
Z	extern	char	*getenv(),	*tgetstr();
Z	int getstring();
Z
Z	p->p_speed = 9600;
Z	if ((term = getenv("TERM")) != NULL && tgetent(tbuf, term) > 0) {
Z		if (cp = tgetstr("pc", &bp))
Z			p->p_PC = *cp;
Z		cols = tgetnum("co", &bp);
Z		lines = tgetnum("li", &bp);
Z		while (pi->i_size != 0) {
Z			getstring(pi);
Z			pi++;
Z		}
Z		return(*p->p_CM == '\0' || *p->p_CL == '\0' || cols < 80 ||
Z		       lines < 24);
Z	}
Z	return(1);
Z}
Z
Z/*
Z * Termcap support routine
Z */
Zgetstring(pi)
Zregister struct	init	*pi;
Z{
Z	register char	*cp = tgetstr(pi->i_name, &bp);
Z
Z	if (cp == NULL)
Z		return;
Z	if ( pi->i_pad ) {
Z		while ( strchr( "0123456789.", *cp ) )
Z			cp++;
Z		if ( pi->i_pad == 2 && *cp == '*' )
Z			cp++;
Z	}
Z	if ( strlen(cp) >= pi->i_size )
Z		fatal("Prog. error: Long termcap entry found!\n");
Z	(void) strncpy(pi->i_dest, cp , pi->i_size);
Z}
Z
Zgetid() {
Z    int key;
Z
Z    if ((key = ftok("/tmp/SEARCH", 0)) == -1) {
Z	return -1;
Z    }
Z    return msgget(key, 0);
Z}
Z
Zbcopy(to, from, n)
Zregister char *to, *from;
Z{
Z    while (n--) *to++ = *from++;
Z}
Z#include <termio.h>
Ztypedef struct termio SGTTY;
Z#include <term.h>
Z#include <stdio.h>
Z
Z/*
Z------------------------------------------------------------------------------
Z *	There are a few problems in conection with the use of curses,
Z *	I don't know why, but the routines below does exactly what you
Z *	want them do. The same routines in curses does not.
Z------------------------------------------------------------------------------
Z */
Z
Zstatic struct termio oldti, newti;
Zcbreak () { newti.c_lflag    &= ~ICANON; newti.c_cc[VMIN]  = 1;
Z	newti.c_cc[VTIME] = 1; ioctl (1, TCSETA, &newti); }
Znocbreak () { newti.c_lflag |= ICANON; newti.c_cc[VEOF] = oldti.c_cc[VEOF];
Z	newti.c_cc[VEOL] = oldti.c_cc[VEOL]; ioctl (1, TCSETA, &newti); }
Zecho () { newti. c_lflag |= ECHO; ioctl (1, TCSETA, &newti); }
Znoecho () { newti.c_lflag &= ~ECHO; ioctl (1, TCSETA, &newti); }
Zresetty () { newti = oldti; ioctl (1, TCSETA, &newti); }
Zsavetty () { ioctl (1, TCGETA, &oldti); newti = oldti; }
Z
Zupdate(str)
Zchar *str;
Z{
Z}
STUNKYFLUFF
set `sum < search.c`
if test 18423 != $1
then
echo search.c: Error. number of characters is: $1, should be: 18423.
fi
#
#
echo x - searchwho.c
sed 's/^Z//' >searchwho.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: searchwho.c,v 2.2 85/08/15 13:37:49 matt Exp $";
Z#endif
Z/*
Z *
Z * searchwho
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original by Dave Pare	1983
Z * Ported & improved
Z *      by Matt Crawford	1985
Z *
Z * who is playing search
Z *
Z * Copyright (c) 1983
Z *
Z * $Log:	searchwho.c,v $
Z * Revision 2.2  85/08/15  13:37:49  matt
Z * Limit dtabsiz to an int's worth of bits.
Z * 
Z * Revision 2.1  85/04/10  17:31:55  matt
Z * Major de-linting and minor restructuring.
Z * 
Z * Revision 1.3  85/02/10  02:06:33  matt
Z * Allow a port to be specified, as for search itself.
Z * 
Z * Revision 1.2  85/02/09  23:50:40  matt
Z * Eliminated the dependence on the value of the mask after
Z * select() times out.  Use the return value to distinguish
Z * a timeout!!
Z * 
Z */
Z
Z#include <stdio.h>
Z#include <sys/param.h>		/* includes <sys/types.h> and <signal.h> */
Z#include <sys/stat.h>
Z#include <sys/file.h>
Z#include <sgtty.h>
Z#include <ctype.h>
Z#include <pwd.h>
Z#include <sys/time.h>
Z#include <errno.h>
Z#include <sys/socket.h>
Z#include <sys/un.h>
Z
Z#include "defines.h"
Z#include "structs.h"
Z
Z
Zextern	int errno;
Zint	dtabsiz;			/* how many fd's here? */
Zint	sock;				/* socket to daemon */
Z
Zmain(argc, argv)
Zint argc;
Zchar *argv[];
Z{
Z	void reset();
Z	register int    cc;	/* returned from all sorts of calls */
Z	register int    i;	/* general purpose register */
Z	register int    sockmask;
Z	register char   buf[4096];/* misc buffer for i/o */
Z	int     mask;		/* masks used in select() calls */
Z	struct timeval  timeout;/* time outs for select calls */
Z	int     save_mask;	/* don't calculate mask each time */
Z	int     first_time;	/* for printing header */
Z	int     junk;
Z	struct sockaddr loc_addr;/* local socket address */
Z
Z	dtabsiz = getdtablesize();
Z /* 
Z  * set all the signals
Z  */
Z	(void) signal(SIGINT, SIG_IGN);
Z	(void) signal(SIGTERM, SIG_IGN);
Z	(void) signal(SIGQUIT, reset);
Z	(void) signal(SIGHUP, reset);
Z	(void) signal(SIGPIPE, reset);
Z	(void) signal(SIGALRM, reset);
Z	(void) signal(SIGTSTP, SIG_IGN);
Z	(void) signal(SIGSTOP, SIG_IGN);
Z	sock = socket(AF_UNIX, SOCK_STREAM, 0);
Z	if (sock < 0) {
Z		perror("search, socket");
Z		exit(1);
Z	}
Z /* 
Z  * connect to the local search daemon thru the lock
Z  * file (usually /tmp/slock for historical reasons)
Z  */
Z	if (connect(sock, &loc_addr, sizeof(loc_addr))) {
Z		printf("no local search daemon running\n");
Z		exit(1);
Z	}
Z /* 
Z  * daemon knows that a 1 byte message 'w' is from "searchwho".
Z  */
Z	if (write(sock, "w", 1) != 1) {
Z		perror("write");
Z		printf("searchwho: bad connect on socket\n");
Z		exit(1);
Z	}
Z /* 
Z  * set up all the stuff for the select loop
Z  */
Z	sockmask = 1 << sock;
Z	save_mask = sockmask;
Z	timeout.tv_usec = 0L;
Z	timeout.tv_sec = 3L;
Z /* 
Z  * just in case nobody's there
Z  */
Z	alarm(20);
Z	first_time = 1;
Z	for (;;) {
Z		mask = save_mask;
Z		i = select(dtabsiz, &mask, 0, 0, &timeout);
Z		if (i < 0) {
Z			if (errno = EINTR)
Z				continue;
Z			perror("select");
Z		}
Z	/* 
Z	 * nope - no data waiting.  select() timed out.
Z	 */
Z		if (!i) {
Z			printf("no data yet, we'll wait a bit longer...\n");
Z			fflush(stdout);
Z			continue;
Z		}
Z		if (!(sockmask & mask))
Z			continue;
Z	/* 
Z	 * input waiting from the daemon - read it in and
Z	 * write it to the screen (stdout).
Z	 */
Z		alarm (3);
Z		if (fgets(buf, 80, &_iob[sock]) != NULL) {
Z		/* 
Z		 * when you get zero characters from a socket that
Z		 * had input waiting, it means that the socket was
Z		 * closed down (from the other side)
Z		 */
Z			if (first_time) {
Z				if (strncmp(buf, "nobody", 6) != 0) {
Z					printf("    username   points \n");
Z					first_time = 0;
Z				} else
Z					puts(buf);
Z			} else
Z				puts(buf);
Z			fflush(stdout);
Z		} else
Z			reset(0);
Z		alarm(0);
Z	}
Z}
Z
Z/*
Z * reset disconnects us from any sockets we've connected to,
Z * and shuts everything down nicely.
Z */
Zvoid reset(signal)
Zint signal;
Z{
Z	char	buf[1024];
Z	struct	timeval delay;
Z	int	mask;
Z	int	i;
Z
Z	/*
Z	 * disconnect from our socket (getting rid of the
Z	 * gunk possibly leftover)
Z	 */
Z	mask = 1 << sock;
Z	delay.tv_sec = 0L;
Z	delay.tv_usec = 500L;
Z	shutdown(sock, 1);
Z	i = select(dtabsiz, &mask, 0, 0, &delay);
Z	if (i > 0) {
Z		i = read(sock, buf, sizeof(buf));
Z		write(1, buf, i);
Z	}
Z	shutdown(sock, 2);
Z	(void) close(sock);
Z	putchar('\n');
Z	exit(0);
Z}
STUNKYFLUFF
set `sum < searchwho.c`
if test 2102 != $1
then
echo searchwho.c: Error. number of characters is: $1, should be: 2102.
fi
#
#
echo x - signal.c
sed 's/^Z//' >signal.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: signal.c,v 2.1 85/04/10 17:32:00 matt Stab $";
Z#endif
Z/*
Z *
Z * search
Z *
Z * multi-player and multi-system search and destroy.
Z *
Z * Original code by Dave Pare	1984
Z * Ported & improved
Z *      by Matt Crawford	1985
Z *
Z * signal handlers for the daemon
Z *
Z * Copyright (c) 1984
Z *
Z * $Log:	signal.c,v $
Z * Revision 2.1  85/04/10  17:32:00  matt
Z * Major de-linting and minor restructuring.
Z * 
Z */
Z
Z#include <stdio.h>
Z#include <sys/types.h>
Z#include <time.h>
Z#include <sys/file.h>
Z#include <signal.h>
Z#include <nlist.h>
Z#include "defines.h"
Z#include "structs.h"
Z
Z
Ztrap(sig)
Zint sig;
Z{
Z	extern	void	done();
Z	extern	t_player player[NPLAYER];
Z	extern	int pfd;
Z	extern	int errfile;
Z	t_player *p;
Z	char	buf[80];
Z
Z
Z	for (p = player; p < &player[NPLAYER]; p++)
Z		if (p->status.alive == TRUE)
Z			done(p);
Z	close(pfd);
Z	sprintf(buf, "trapped interrupt %d\n", sig);
Z	errlog(buf);
Z	close(errfile);
Z	exit(sig);
Z	/*NOTREACHED*/
Z}
Z
Zcore_dump()
Z{
Z	extern	void	done();
Z	extern	t_player	player[NPLAYER];
Z	t_player	*p;
Z
Z	errlog("dumping core...\n");
Z	signal(SIGQUIT, SIG_IGN);
Z	for (p = player; p < &player[NPLAYER]; p++)
Z		if (p->status.alive == TRUE)
Z			done(p);
Z	signal(SIGQUIT, SIG_DFL);
Z	kill(getpid(), SIGQUIT);
Z	/*NOTREACHED*/
Z}
Z
Z
Z/*
Z *  Put the delay in the game.  tune to taste.
Z *  There is not much one can do here, because SVR2 doesn't make
Z *
Z */
Zvoid
Zset_delay() {
Z	static long lasttime = 0;
Z
Z	if (time (0L) == lasttime)
Z		sleep (1);
Z	lasttime = time (0L);
Z/*
Z	extern	int nplayer;
Z	long usecs;
Z	usecs = 100000L - (nplayer * 15000L);
Z	if (usecs < 10000L)
Z		return;
Z*/
Z}
STUNKYFLUFF
set `sum < signal.c`
if test 58360 != $1
then
echo signal.c: Error. number of characters is: $1, should be: 58360.
fi
#
#
echo x - sscore.c
sed 's/^Z//' >sscore.c <<\STUNKYFLUFF
Z#ifndef lint
Zstatic char rcsid[] = "$Header: sscore.c,v 1.4 85/07/08 17:22:57 matt Exp $";
Z#endif
Z/*
Z *
Z * Original by Dave Pare	1983
Z * Ported & improved
Z *      by Matt Crawford	1985
Z *
Z * program to sort and print the player scoreboard.
Z */
Z
Z
Z#include <stdio.h>
Z#include <ctype.h>
Z#include <sys/types.h>
Z#include <sys/file.h>
Z#include "defines.h"
Z#include "structs.h"
Z
Z
Zstruct totals {
Z	char	ptname[20];	/* player name */
Z	int	ptpoints;	/* total points */
Z	int	pthits;		/* total player hits */
Z	int	ptahits;	/* total alien hits */
Z	int	ptkills;	/* total player kills */
Z	int	ptkilled;	/* total times killed */
Z	int	ptlast;		/* last game's score */
Z	int	ptbest;		/* best score */
Z	int	ptgames;	/* # games played */
Z	int	average;	/* average score */
Z} ;
Z
Zstruct totals *malloc();
Z
Zmain() {
Z	register int i,
Z		j,
Z		found,
Z		next;
Z	register struct totals *lp;
Z	int	pointfd;
Z	struct	totals *list[2000];
Z	long	number;
Z
Z	for (i=0; i<2000; i++)
Z		list[i] = NULL;
Z	if ((pointfd = open(POINTFILE, 0)) < 0)
Z		fatal("can't open points file %s", POINTFILE);
Z	printf("%-17s %-5s %-8s %-7s %-7s %-5s %-6s %-5s %-5s %-4s\n",
Z		"Player", "Games", "Total", "Hits(p)", "Hits(a)",
Z		"Kills", "Killed", "Best", "Last", "Avg");
Z	for (number=0; number<2000; number++) {
Z		lp = malloc(sizeof(struct totals));
Z		if (lp == NULL)
Z			fatal("out of memory\n");
Z		if (read(pointfd, lp, sizeof(t_totals)) <= 0) {
Z			free(lp);
Z			break;
Z		}
Z		if (lp->ptgames > 0)
Z			lp->average = lp->ptpoints/lp->ptgames;
Z		else
Z			lp->average = 0;
Z		list[number] = lp;
Z	}
Z	if ( number == 0 )
Z	        exit(0);
Z	found = 1;
Z	for (i=number-1; i && found; i--) {
Z		found = 0;
Z		for (j=0, next=1; j<i; j++, next++) {
Z			if (list[j]->ptbest < list[next]->ptbest) {
Z				lp = list[j];
Z				list[j] = list[next];
Z				list[next] = lp;
Z				found++;
Z			}
Z		}
Z	}
Z	for (i=0; i<2000; i++) {
Z		lp = list[i];
Z		if (lp == NULL || lp->ptpoints == 0)
Z			continue;
Z		printf("%-17s %-5d %-8d %-7d %-7d %-5d %-6d %-5d %-5d %-4d\n",
Z			lp->ptname, lp->ptgames, lp->ptpoints, lp->pthits,
Z			lp->ptahits, lp->ptkills, lp->ptkilled, lp->ptbest,
Z			lp->ptlast, lp->average);
Z	}
Z}
Z
Zfatal(fmt, arg)
Zchar *fmt;
Z{
Z	fprintf(stderr, "sscore:");
Z	fprintf(stderr, fmt, arg);
Z	fputc('\n', stderr);
Z	exit(1);
Z}
STUNKYFLUFF
set `sum < sscore.c`
if test 36604 != $1
then
echo sscore.c: Error. number of characters is: $1, should be: 36604.
fi
echo All done
exit 0
-- 
    ______________________________________________________
	Lars Pensjo
	{decvax,philabs}!mcvax!enea!chalmers!myab!lars