xref: /csrg-svn/games/sail/sync.c (revision 69068)
118706Sedward /*
260848Sbostic  * Copyright (c) 1983, 1993
360848Sbostic  *	The Regents of the University of California.  All rights reserved.
433695Sbostic  *
542605Sbostic  * %sccs.include.redist.c%
618706Sedward  */
718706Sedward 
815207Sedward #ifndef lint
9*69068Sbostic static char sccsid[] = "@(#)sync.c	8.2 (Berkeley) 04/28/95";
1033695Sbostic #endif /* not lint */
1115207Sedward 
1216081Sedward #include <sys/file.h>
13*69068Sbostic #include <errno.h>
14*69068Sbostic #include "extern.h"
1515207Sedward 
1618249Sedward #define BUFSIZE 4096
1718249Sedward 
1815207Sedward static char sync_buf[BUFSIZE];
1915901Sedward static char *sync_bp = sync_buf;
2015207Sedward static char sync_lock[25];
2115207Sedward static char sync_file[25];
2215207Sedward static long sync_seek;
2315207Sedward static FILE *sync_fp;
2415207Sedward #define SF "/tmp/#sailsink.%d"
2515207Sedward #define LF "/tmp/#saillock.%d"
2615207Sedward 
2715207Sedward /*VARARGS3*/
2815207Sedward makesignal(from, fmt, ship, a, b, c)
2918249Sedward 	struct ship *from;
3018249Sedward 	char *fmt;
3118249Sedward 	register struct ship *ship;
3215207Sedward {
3315207Sedward 	char message[80];
3415207Sedward 
3515207Sedward 	if (ship == 0)
3615207Sedward 		(void) sprintf(message, fmt, a, b, c);
3715207Sedward 	else
3815207Sedward 		(void) sprintf(message, fmt,
3915207Sedward 			ship->shipname, colours(ship),
4015207Sedward 			sterncolour(ship), a, b, c);
4115207Sedward 	Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
4215207Sedward }
4315207Sedward 
4415312Sedward #include <sys/types.h>
4515312Sedward #include <sys/stat.h>
sync_exists(game)4615207Sedward sync_exists(game)
4715207Sedward {
4815207Sedward 	char buf[sizeof sync_file];
4915312Sedward 	struct stat s;
5015312Sedward 	time_t t;
5115207Sedward 
5215207Sedward 	(void) sprintf(buf, SF, game);
5315723Sedward 	(void) time(&t);
5415312Sedward 	if (stat(buf, &s) < 0)
5515312Sedward 		return 0;
5615312Sedward 	if (s.st_mtime < t - 60*60*2) {		/* 2 hours */
5715723Sedward 		(void) unlink(buf);
5816081Sedward 		(void) sprintf(buf, LF, game);
5916081Sedward 		(void) unlink(buf);
6015312Sedward 		return 0;
6115312Sedward 	} else
6215312Sedward 		return 1;
6315207Sedward }
6415207Sedward 
sync_open()6515207Sedward sync_open()
6615207Sedward {
6718590Sedward 	if (sync_fp != NULL)
6818590Sedward 		(void) fclose(sync_fp);
6918590Sedward 	(void) sprintf(sync_lock, LF, game);
7018590Sedward 	(void) sprintf(sync_file, SF, game);
7118590Sedward 	if (access(sync_file, 0) < 0) {
7218590Sedward 		int omask = umask(issetuid ? 077 : 011);
7318590Sedward 		sync_fp = fopen(sync_file, "w+");
7418590Sedward 		(void) umask(omask);
7518590Sedward 	} else
7618590Sedward 		sync_fp = fopen(sync_file, "r+");
7718590Sedward 	if (sync_fp == NULL)
7818590Sedward 		return -1;
7925934Sedward 	sync_seek = 0;
8015249Sedward 	return 0;
8115207Sedward }
8215207Sedward 
sync_close(remove)8315207Sedward sync_close(remove)
8418249Sedward 	char remove;
8515207Sedward {
8615352Sedward 	if (sync_fp != 0)
8715352Sedward 		(void) fclose(sync_fp);
8815207Sedward 	if (remove)
8915207Sedward 		(void) unlink(sync_file);
9015207Sedward }
9115207Sedward 
Write(type,ship,isstr,a,b,c,d)9215207Sedward Write(type, ship, isstr, a, b, c, d)
9318249Sedward 	int type;
9418249Sedward 	struct ship *ship;
9518249Sedward 	char isstr;
9618249Sedward 	int a, b, c, d;
9715207Sedward {
9815207Sedward 	if (isstr)
9915901Sedward 		(void) sprintf(sync_bp, "%d %d %d %s\n",
10015723Sedward 			type, ship->file->index, isstr, a);
10115207Sedward 	else
10215901Sedward 		(void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
10315723Sedward 			type, ship->file->index, isstr, a, b, c, d);
10415901Sedward 	while (*sync_bp++)
10515207Sedward 		;
10615901Sedward 	sync_bp--;
10715901Sedward 	if (sync_bp >= &sync_buf[sizeof sync_buf])
10815207Sedward 		abort();
10916081Sedward 	(void) sync_update(type, ship, a, b, c, d);
11015207Sedward }
11115207Sedward 
Sync()11215207Sedward Sync()
11315207Sedward {
11439835Sbostic 	sig_t sighup, sigint;
11516425Sedward 	register n;
11615207Sedward 	int type, shipnum, isstr, a, b, c, d;
11716081Sedward 	char buf[80];
11816081Sedward 	char erred = 0;
11916081Sedward 	extern errno;
12015207Sedward 
12125934Sedward 	sighup = signal(SIGHUP, SIG_IGN);
12225934Sedward 	sigint = signal(SIGINT, SIG_IGN);
12316425Sedward 	for (n = TIMEOUT; --n >= 0;) {
12416081Sedward #ifdef LOCK_EX
12516081Sedward 		if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
12616081Sedward 			break;
12716081Sedward 		if (errno != EWOULDBLOCK)
12816081Sedward 			return -1;
12916081Sedward #else
13016081Sedward 		if (link(sync_file, sync_lock) >= 0)
13116081Sedward 			break;
13216081Sedward 		if (errno != EEXIST)
13316081Sedward 			return -1;
13416081Sedward #endif
13516425Sedward 		sleep(1);
13616081Sedward 	}
13716425Sedward 	if (n <= 0)
13816081Sedward 		return -1;
13915207Sedward 	(void) fseek(sync_fp, sync_seek, 0);
14016081Sedward 	for (;;) {
14116081Sedward 		switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
14216081Sedward 		case 3:
14316081Sedward 			break;
14416081Sedward 		case EOF:
14516081Sedward 			goto out;
14616081Sedward 		default:
14716081Sedward 			goto bad;
14816081Sedward 		}
14916081Sedward 		if (shipnum < 0 || shipnum >= cc->vessels)
15016081Sedward 			goto bad;
15116081Sedward 		if (isstr != 0 && isstr != 1)
15216081Sedward 			goto bad;
15315207Sedward 		if (isstr) {
15416081Sedward 			register char *p;
15515207Sedward 			for (p = buf;;) {
15615207Sedward 				switch (*p++ = getc(sync_fp)) {
15715207Sedward 				case '\n':
15815207Sedward 					p--;
15915207Sedward 				case EOF:
16015207Sedward 					break;
16115207Sedward 				default:
16216081Sedward 					if (p >= buf + sizeof buf)
16316081Sedward 						p--;
16415207Sedward 					continue;
16515207Sedward 				}
16615207Sedward 				break;
16715207Sedward 			}
16815207Sedward 			*p = 0;
16915207Sedward 			for (p = buf; *p == ' '; p++)
17015207Sedward 				;
17115207Sedward 			a = (int)p;
17215207Sedward 			b = c = d = 0;
17315207Sedward 		} else
17416081Sedward 			if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
17516081Sedward 				goto bad;
17616081Sedward 		if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
17716081Sedward 			goto bad;
17815207Sedward 	}
17916081Sedward bad:
18016081Sedward 	erred++;
18116081Sedward out:
18216081Sedward 	if (!erred && sync_bp != sync_buf) {
18315207Sedward 		(void) fseek(sync_fp, 0L, 2);
18425934Sedward 		(void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
18525934Sedward 			sync_fp);
18615207Sedward 		(void) fflush(sync_fp);
18715901Sedward 		sync_bp = sync_buf;
18815207Sedward 	}
18915207Sedward 	sync_seek = ftell(sync_fp);
19016081Sedward #ifdef LOCK_EX
19116081Sedward 	(void) flock(fileno(sync_fp), LOCK_UN);
19216081Sedward #else
19315207Sedward 	(void) unlink(sync_lock);
19416081Sedward #endif
19525934Sedward 	(void) signal(SIGHUP, sighup);
19625934Sedward 	(void) signal(SIGINT, sigint);
19716081Sedward 	return erred ? -1 : 0;
19815207Sedward }
19915207Sedward 
sync_update(type,ship,a,b,c,d)20015207Sedward sync_update(type, ship, a, b, c, d)
20118249Sedward 	int type;
20218249Sedward 	register struct ship *ship;
20318249Sedward 	int a, b, c, d;
20415207Sedward {
20515207Sedward 	switch (type) {
20615207Sedward 	case W_DBP: {
20715207Sedward 		register struct BP *p = &ship->file->DBP[a];
20815207Sedward 		p->turnsent = b;
20915207Sedward 		p->toship = SHIP(c);
21015207Sedward 		p->mensent = d;
21115207Sedward 		break;
21215207Sedward 		}
21315207Sedward 	case W_OBP: {
21415207Sedward 		register struct BP *p = &ship->file->OBP[a];
21515207Sedward 		p->turnsent = b;
21615207Sedward 		p->toship = SHIP(c);
21715207Sedward 		p->mensent = d;
21815207Sedward 		break;
21915207Sedward 		}
22015207Sedward 	case W_FOUL: {
22115723Sedward 		register struct snag *p = &ship->file->foul[a];
22215723Sedward 		if (SHIP(a)->file->dir == 0)
22315723Sedward 			break;
22415723Sedward 		if (p->sn_count++ == 0)
22515723Sedward 			p->sn_turn = turn;
22615723Sedward 		ship->file->nfoul++;
22715207Sedward 		break;
22815207Sedward 		}
22915207Sedward 	case W_GRAP: {
23015723Sedward 		register struct snag *p = &ship->file->grap[a];
23115723Sedward 		if (SHIP(a)->file->dir == 0)
23215723Sedward 			break;
23315723Sedward 		if (p->sn_count++ == 0)
23415723Sedward 			p->sn_turn = turn;
23515723Sedward 		ship->file->ngrap++;
23615207Sedward 		break;
23715207Sedward 		}
23815723Sedward 	case W_UNFOUL: {
23915723Sedward 		register struct snag *p = &ship->file->foul[a];
24015723Sedward 		if (p->sn_count > 0)
24115723Sedward 			if (b) {
24215723Sedward 				ship->file->nfoul -= p->sn_count;
24315723Sedward 				p->sn_count = 0;
24415723Sedward 			} else {
24515723Sedward 				ship->file->nfoul--;
24615723Sedward 				p->sn_count--;
24715723Sedward 			}
24815723Sedward 		break;
24915723Sedward 		}
25015723Sedward 	case W_UNGRAP: {
25115723Sedward 		register struct snag *p = &ship->file->grap[a];
25215723Sedward 		if (p->sn_count > 0)
25315723Sedward 			if (b) {
25415723Sedward 				ship->file->ngrap -= p->sn_count;
25515723Sedward 				p->sn_count = 0;
25615723Sedward 			} else {
25715723Sedward 				ship->file->ngrap--;
25815723Sedward 				p->sn_count--;
25915723Sedward 			}
26015723Sedward 		break;
26115723Sedward 		}
26215207Sedward 	case W_SIGNAL:
26318249Sedward 		if (mode == MODE_PLAYER)
26418670Sedward 			if (nobells)
26518670Sedward 				Signal("%s (%c%c): %s", ship, a);
26618670Sedward 			else
26718670Sedward 				Signal("\7%s (%c%c): %s", ship, a);
26815207Sedward 		break;
26915207Sedward 	case W_CREW: {
27015207Sedward 		register struct shipspecs *s = ship->specs;
27115207Sedward 		s->crew1 = a;
27215207Sedward 		s->crew2 = b;
27315207Sedward 		s->crew3 = c;
27415207Sedward 		break;
27515207Sedward 		}
27615207Sedward 	case W_CAPTAIN:
27715207Sedward 		(void) strncpy(ship->file->captain, (char *)a,
27815207Sedward 			sizeof ship->file->captain - 1);
27915207Sedward 		ship->file->captain[sizeof ship->file->captain - 1] = 0;
28015207Sedward 		break;
28115207Sedward 	case W_CAPTURED:
28215315Sedward 		if (a < 0)
28315315Sedward 			ship->file->captured = 0;
28415315Sedward 		else
28515315Sedward 			ship->file->captured = SHIP(a);
28615207Sedward 		break;
28715207Sedward 	case W_CLASS:
28815207Sedward 		ship->specs->class = a;
28915207Sedward 		break;
29015207Sedward 	case W_DRIFT:
29115207Sedward 		ship->file->drift = a;
29215207Sedward 		break;
29315207Sedward 	case W_EXPLODE:
29415207Sedward 		if ((ship->file->explode = a) == 2)
29515207Sedward 			ship->file->dir = 0;
29615207Sedward 		break;
29715207Sedward 	case W_FS:
29815207Sedward 		ship->file->FS = a;
29915207Sedward 		break;
30015207Sedward 	case W_GUNL: {
30115207Sedward 		register struct shipspecs *s = ship->specs;
30215207Sedward 		s->gunL = a;
30315207Sedward 		s->carL = b;
30415207Sedward 		break;
30515207Sedward 		}
30615207Sedward 	case W_GUNR: {
30715207Sedward 		register struct shipspecs *s = ship->specs;
30815207Sedward 		s->gunR = a;
30915207Sedward 		s->carR = b;
31015207Sedward 		break;
31115207Sedward 		}
31215207Sedward 	case W_HULL:
31315207Sedward 		ship->specs->hull = a;
31415207Sedward 		break;
31515723Sedward 	case W_MOVE:
31615723Sedward 		(void) strncpy(ship->file->movebuf, (char *)a,
31715723Sedward 			sizeof ship->file->movebuf - 1);
31815723Sedward 		ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
31915207Sedward 		break;
32015207Sedward 	case W_PCREW:
32115207Sedward 		ship->file->pcrew = a;
32215207Sedward 		break;
32315207Sedward 	case W_POINTS:
32415207Sedward 		ship->file->points = a;
32515207Sedward 		break;
32615207Sedward 	case W_QUAL:
32715207Sedward 		ship->specs->qual = a;
32815207Sedward 		break;
32915207Sedward 	case W_RIGG: {
33015207Sedward 		register struct shipspecs *s = ship->specs;
33115207Sedward 		s->rig1 = a;
33215207Sedward 		s->rig2 = b;
33315207Sedward 		s->rig3 = c;
33415207Sedward 		s->rig4 = d;
33515207Sedward 		break;
33615207Sedward 		}
33715207Sedward 	case W_RIG1:
33815207Sedward 		ship->specs->rig1 = a;
33915207Sedward 		break;
34015207Sedward 	case W_RIG2:
34115207Sedward 		ship->specs->rig2 = a;
34215207Sedward 		break;
34315207Sedward 	case W_RIG3:
34415207Sedward 		ship->specs->rig3 = a;
34515207Sedward 		break;
34615207Sedward 	case W_RIG4:
34715207Sedward 		ship->specs->rig4 = a;
34815207Sedward 		break;
34915723Sedward 	case W_COL:
35015207Sedward 		ship->file->col = a;
35115207Sedward 		break;
35215723Sedward 	case W_DIR:
35315207Sedward 		ship->file->dir = a;
35415207Sedward 		break;
35515723Sedward 	case W_ROW:
35615207Sedward 		ship->file->row = a;
35715207Sedward 		break;
35815207Sedward 	case W_SINK:
35915207Sedward 		if ((ship->file->sink = a) == 2)
36015207Sedward 			ship->file->dir = 0;
36115207Sedward 		break;
36215207Sedward 	case W_STRUCK:
36315207Sedward 		ship->file->struck = a;
36415207Sedward 		break;
36515207Sedward 	case W_TA:
36615207Sedward 		ship->specs->ta = a;
36715207Sedward 		break;
36815207Sedward 	case W_ALIVE:
36915207Sedward 		alive = 1;
37015207Sedward 		break;
37115207Sedward 	case W_TURN:
37215207Sedward 		turn = a;
37315207Sedward 		break;
37415207Sedward 	case W_WIND:
37515207Sedward 		winddir = a;
37615207Sedward 		windspeed = b;
37715207Sedward 		break;
37815207Sedward 	case W_BEGIN:
37915207Sedward 		(void) strcpy(ship->file->captain, "begin");
38015207Sedward 		people++;
38115207Sedward 		break;
38215207Sedward 	case W_END:
38316081Sedward 		*ship->file->captain = 0;
38416081Sedward 		ship->file->points = 0;
38515207Sedward 		people--;
38615207Sedward 		break;
38716081Sedward 	case W_DDEAD:
38816081Sedward 		hasdriver = 0;
38916081Sedward 		break;
39015207Sedward 	default:
39116081Sedward 		fprintf(stderr, "sync_update: unknown type %d\r\n", type);
39216081Sedward 		return -1;
39315207Sedward 	}
39416081Sedward 	return 0;
39515207Sedward }
396