xref: /csrg-svn/games/sail/sync.c (revision 33695)
118706Sedward /*
221248Sdist  * Copyright (c) 1983 Regents of the University of California.
3*33695Sbostic  * All rights reserved.
4*33695Sbostic  *
5*33695Sbostic  * Redistribution and use in source and binary forms are permitted
6*33695Sbostic  * provided that this notice is preserved and that due credit is given
7*33695Sbostic  * to the University of California at Berkeley. The name of the University
8*33695Sbostic  * may not be used to endorse or promote products derived from this
9*33695Sbostic  * software without specific prior written permission. This software
10*33695Sbostic  * is provided ``as is'' without express or implied warranty.
1118706Sedward  */
1218706Sedward 
1315207Sedward #ifndef lint
14*33695Sbostic static char sccsid[] = "@(#)sync.c	5.3 (Berkeley) 03/09/88";
15*33695Sbostic #endif /* not lint */
1615207Sedward 
1715207Sedward #include "externs.h"
1816081Sedward #include <sys/file.h>
1916081Sedward #include <sys/errno.h>
2015207Sedward 
2118249Sedward #define BUFSIZE 4096
2218249Sedward 
2315207Sedward static char sync_buf[BUFSIZE];
2415901Sedward static char *sync_bp = sync_buf;
2515207Sedward static char sync_lock[25];
2615207Sedward static char sync_file[25];
2715207Sedward static long sync_seek;
2815207Sedward static FILE *sync_fp;
2915207Sedward #define SF "/tmp/#sailsink.%d"
3015207Sedward #define LF "/tmp/#saillock.%d"
3115207Sedward 
3215207Sedward /*VARARGS3*/
3315207Sedward makesignal(from, fmt, ship, a, b, c)
3418249Sedward 	struct ship *from;
3518249Sedward 	char *fmt;
3618249Sedward 	register struct ship *ship;
3715207Sedward {
3815207Sedward 	char message[80];
3915207Sedward 
4015207Sedward 	if (ship == 0)
4115207Sedward 		(void) sprintf(message, fmt, a, b, c);
4215207Sedward 	else
4315207Sedward 		(void) sprintf(message, fmt,
4415207Sedward 			ship->shipname, colours(ship),
4515207Sedward 			sterncolour(ship), a, b, c);
4615207Sedward 	Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
4715207Sedward }
4815207Sedward 
4915312Sedward #include <sys/types.h>
5015312Sedward #include <sys/stat.h>
5115207Sedward sync_exists(game)
5215207Sedward {
5315207Sedward 	char buf[sizeof sync_file];
5415312Sedward 	struct stat s;
5515312Sedward 	time_t t;
5615207Sedward 
5715207Sedward 	(void) sprintf(buf, SF, game);
5815723Sedward 	(void) time(&t);
5915312Sedward 	if (stat(buf, &s) < 0)
6015312Sedward 		return 0;
6115312Sedward 	if (s.st_mtime < t - 60*60*2) {		/* 2 hours */
6215723Sedward 		(void) unlink(buf);
6316081Sedward 		(void) sprintf(buf, LF, game);
6416081Sedward 		(void) unlink(buf);
6515312Sedward 		return 0;
6615312Sedward 	} else
6715312Sedward 		return 1;
6815207Sedward }
6915207Sedward 
7015207Sedward sync_open()
7115207Sedward {
7218590Sedward 	if (sync_fp != NULL)
7318590Sedward 		(void) fclose(sync_fp);
7418590Sedward 	(void) sprintf(sync_lock, LF, game);
7518590Sedward 	(void) sprintf(sync_file, SF, game);
7618590Sedward 	if (access(sync_file, 0) < 0) {
7718590Sedward 		int omask = umask(issetuid ? 077 : 011);
7818590Sedward 		sync_fp = fopen(sync_file, "w+");
7918590Sedward 		(void) umask(omask);
8018590Sedward 	} else
8118590Sedward 		sync_fp = fopen(sync_file, "r+");
8218590Sedward 	if (sync_fp == NULL)
8318590Sedward 		return -1;
8425934Sedward 	sync_seek = 0;
8515249Sedward 	return 0;
8615207Sedward }
8715207Sedward 
8815207Sedward sync_close(remove)
8918249Sedward 	char remove;
9015207Sedward {
9115352Sedward 	if (sync_fp != 0)
9215352Sedward 		(void) fclose(sync_fp);
9315207Sedward 	if (remove)
9415207Sedward 		(void) unlink(sync_file);
9515207Sedward }
9615207Sedward 
9715207Sedward Write(type, ship, isstr, a, b, c, d)
9818249Sedward 	int type;
9918249Sedward 	struct ship *ship;
10018249Sedward 	char isstr;
10118249Sedward 	int a, b, c, d;
10215207Sedward {
10315207Sedward 	if (isstr)
10415901Sedward 		(void) sprintf(sync_bp, "%d %d %d %s\n",
10515723Sedward 			type, ship->file->index, isstr, a);
10615207Sedward 	else
10715901Sedward 		(void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
10815723Sedward 			type, ship->file->index, isstr, a, b, c, d);
10915901Sedward 	while (*sync_bp++)
11015207Sedward 		;
11115901Sedward 	sync_bp--;
11215901Sedward 	if (sync_bp >= &sync_buf[sizeof sync_buf])
11315207Sedward 		abort();
11416081Sedward 	(void) sync_update(type, ship, a, b, c, d);
11515207Sedward }
11615207Sedward 
11715207Sedward Sync()
11815207Sedward {
11925934Sedward 	int (*sighup)(), (*sigint)();
12016425Sedward 	register n;
12115207Sedward 	int type, shipnum, isstr, a, b, c, d;
12216081Sedward 	char buf[80];
12316081Sedward 	char erred = 0;
12416081Sedward 	extern errno;
12515207Sedward 
12625934Sedward 	sighup = signal(SIGHUP, SIG_IGN);
12725934Sedward 	sigint = signal(SIGINT, SIG_IGN);
12816425Sedward 	for (n = TIMEOUT; --n >= 0;) {
12916081Sedward #ifdef LOCK_EX
13016081Sedward 		if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
13116081Sedward 			break;
13216081Sedward 		if (errno != EWOULDBLOCK)
13316081Sedward 			return -1;
13416081Sedward #else
13516081Sedward 		if (link(sync_file, sync_lock) >= 0)
13616081Sedward 			break;
13716081Sedward 		if (errno != EEXIST)
13816081Sedward 			return -1;
13916081Sedward #endif
14016425Sedward 		sleep(1);
14116081Sedward 	}
14216425Sedward 	if (n <= 0)
14316081Sedward 		return -1;
14415207Sedward 	(void) fseek(sync_fp, sync_seek, 0);
14516081Sedward 	for (;;) {
14616081Sedward 		switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
14716081Sedward 		case 3:
14816081Sedward 			break;
14916081Sedward 		case EOF:
15016081Sedward 			goto out;
15116081Sedward 		default:
15216081Sedward 			goto bad;
15316081Sedward 		}
15416081Sedward 		if (shipnum < 0 || shipnum >= cc->vessels)
15516081Sedward 			goto bad;
15616081Sedward 		if (isstr != 0 && isstr != 1)
15716081Sedward 			goto bad;
15815207Sedward 		if (isstr) {
15916081Sedward 			register char *p;
16015207Sedward 			for (p = buf;;) {
16115207Sedward 				switch (*p++ = getc(sync_fp)) {
16215207Sedward 				case '\n':
16315207Sedward 					p--;
16415207Sedward 				case EOF:
16515207Sedward 					break;
16615207Sedward 				default:
16716081Sedward 					if (p >= buf + sizeof buf)
16816081Sedward 						p--;
16915207Sedward 					continue;
17015207Sedward 				}
17115207Sedward 				break;
17215207Sedward 			}
17315207Sedward 			*p = 0;
17415207Sedward 			for (p = buf; *p == ' '; p++)
17515207Sedward 				;
17615207Sedward 			a = (int)p;
17715207Sedward 			b = c = d = 0;
17815207Sedward 		} else
17916081Sedward 			if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
18016081Sedward 				goto bad;
18116081Sedward 		if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
18216081Sedward 			goto bad;
18315207Sedward 	}
18416081Sedward bad:
18516081Sedward 	erred++;
18616081Sedward out:
18716081Sedward 	if (!erred && sync_bp != sync_buf) {
18815207Sedward 		(void) fseek(sync_fp, 0L, 2);
18925934Sedward 		(void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
19025934Sedward 			sync_fp);
19115207Sedward 		(void) fflush(sync_fp);
19215901Sedward 		sync_bp = sync_buf;
19315207Sedward 	}
19415207Sedward 	sync_seek = ftell(sync_fp);
19516081Sedward #ifdef LOCK_EX
19616081Sedward 	(void) flock(fileno(sync_fp), LOCK_UN);
19716081Sedward #else
19815207Sedward 	(void) unlink(sync_lock);
19916081Sedward #endif
20025934Sedward 	(void) signal(SIGHUP, sighup);
20125934Sedward 	(void) signal(SIGINT, sigint);
20216081Sedward 	return erred ? -1 : 0;
20315207Sedward }
20415207Sedward 
20515207Sedward sync_update(type, ship, a, b, c, d)
20618249Sedward 	int type;
20718249Sedward 	register struct ship *ship;
20818249Sedward 	int a, b, c, d;
20915207Sedward {
21015207Sedward 	switch (type) {
21115207Sedward 	case W_DBP: {
21215207Sedward 		register struct BP *p = &ship->file->DBP[a];
21315207Sedward 		p->turnsent = b;
21415207Sedward 		p->toship = SHIP(c);
21515207Sedward 		p->mensent = d;
21615207Sedward 		break;
21715207Sedward 		}
21815207Sedward 	case W_OBP: {
21915207Sedward 		register struct BP *p = &ship->file->OBP[a];
22015207Sedward 		p->turnsent = b;
22115207Sedward 		p->toship = SHIP(c);
22215207Sedward 		p->mensent = d;
22315207Sedward 		break;
22415207Sedward 		}
22515207Sedward 	case W_FOUL: {
22615723Sedward 		register struct snag *p = &ship->file->foul[a];
22715723Sedward 		if (SHIP(a)->file->dir == 0)
22815723Sedward 			break;
22915723Sedward 		if (p->sn_count++ == 0)
23015723Sedward 			p->sn_turn = turn;
23115723Sedward 		ship->file->nfoul++;
23215207Sedward 		break;
23315207Sedward 		}
23415207Sedward 	case W_GRAP: {
23515723Sedward 		register struct snag *p = &ship->file->grap[a];
23615723Sedward 		if (SHIP(a)->file->dir == 0)
23715723Sedward 			break;
23815723Sedward 		if (p->sn_count++ == 0)
23915723Sedward 			p->sn_turn = turn;
24015723Sedward 		ship->file->ngrap++;
24115207Sedward 		break;
24215207Sedward 		}
24315723Sedward 	case W_UNFOUL: {
24415723Sedward 		register struct snag *p = &ship->file->foul[a];
24515723Sedward 		if (p->sn_count > 0)
24615723Sedward 			if (b) {
24715723Sedward 				ship->file->nfoul -= p->sn_count;
24815723Sedward 				p->sn_count = 0;
24915723Sedward 			} else {
25015723Sedward 				ship->file->nfoul--;
25115723Sedward 				p->sn_count--;
25215723Sedward 			}
25315723Sedward 		break;
25415723Sedward 		}
25515723Sedward 	case W_UNGRAP: {
25615723Sedward 		register struct snag *p = &ship->file->grap[a];
25715723Sedward 		if (p->sn_count > 0)
25815723Sedward 			if (b) {
25915723Sedward 				ship->file->ngrap -= p->sn_count;
26015723Sedward 				p->sn_count = 0;
26115723Sedward 			} else {
26215723Sedward 				ship->file->ngrap--;
26315723Sedward 				p->sn_count--;
26415723Sedward 			}
26515723Sedward 		break;
26615723Sedward 		}
26715207Sedward 	case W_SIGNAL:
26818249Sedward 		if (mode == MODE_PLAYER)
26918670Sedward 			if (nobells)
27018670Sedward 				Signal("%s (%c%c): %s", ship, a);
27118670Sedward 			else
27218670Sedward 				Signal("\7%s (%c%c): %s", ship, a);
27315207Sedward 		break;
27415207Sedward 	case W_CREW: {
27515207Sedward 		register struct shipspecs *s = ship->specs;
27615207Sedward 		s->crew1 = a;
27715207Sedward 		s->crew2 = b;
27815207Sedward 		s->crew3 = c;
27915207Sedward 		break;
28015207Sedward 		}
28115207Sedward 	case W_CAPTAIN:
28215207Sedward 		(void) strncpy(ship->file->captain, (char *)a,
28315207Sedward 			sizeof ship->file->captain - 1);
28415207Sedward 		ship->file->captain[sizeof ship->file->captain - 1] = 0;
28515207Sedward 		break;
28615207Sedward 	case W_CAPTURED:
28715315Sedward 		if (a < 0)
28815315Sedward 			ship->file->captured = 0;
28915315Sedward 		else
29015315Sedward 			ship->file->captured = SHIP(a);
29115207Sedward 		break;
29215207Sedward 	case W_CLASS:
29315207Sedward 		ship->specs->class = a;
29415207Sedward 		break;
29515207Sedward 	case W_DRIFT:
29615207Sedward 		ship->file->drift = a;
29715207Sedward 		break;
29815207Sedward 	case W_EXPLODE:
29915207Sedward 		if ((ship->file->explode = a) == 2)
30015207Sedward 			ship->file->dir = 0;
30115207Sedward 		break;
30215207Sedward 	case W_FS:
30315207Sedward 		ship->file->FS = a;
30415207Sedward 		break;
30515207Sedward 	case W_GUNL: {
30615207Sedward 		register struct shipspecs *s = ship->specs;
30715207Sedward 		s->gunL = a;
30815207Sedward 		s->carL = b;
30915207Sedward 		break;
31015207Sedward 		}
31115207Sedward 	case W_GUNR: {
31215207Sedward 		register struct shipspecs *s = ship->specs;
31315207Sedward 		s->gunR = a;
31415207Sedward 		s->carR = b;
31515207Sedward 		break;
31615207Sedward 		}
31715207Sedward 	case W_HULL:
31815207Sedward 		ship->specs->hull = a;
31915207Sedward 		break;
32015723Sedward 	case W_MOVE:
32115723Sedward 		(void) strncpy(ship->file->movebuf, (char *)a,
32215723Sedward 			sizeof ship->file->movebuf - 1);
32315723Sedward 		ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
32415207Sedward 		break;
32515207Sedward 	case W_PCREW:
32615207Sedward 		ship->file->pcrew = a;
32715207Sedward 		break;
32815207Sedward 	case W_POINTS:
32915207Sedward 		ship->file->points = a;
33015207Sedward 		break;
33115207Sedward 	case W_QUAL:
33215207Sedward 		ship->specs->qual = a;
33315207Sedward 		break;
33415207Sedward 	case W_RIGG: {
33515207Sedward 		register struct shipspecs *s = ship->specs;
33615207Sedward 		s->rig1 = a;
33715207Sedward 		s->rig2 = b;
33815207Sedward 		s->rig3 = c;
33915207Sedward 		s->rig4 = d;
34015207Sedward 		break;
34115207Sedward 		}
34215207Sedward 	case W_RIG1:
34315207Sedward 		ship->specs->rig1 = a;
34415207Sedward 		break;
34515207Sedward 	case W_RIG2:
34615207Sedward 		ship->specs->rig2 = a;
34715207Sedward 		break;
34815207Sedward 	case W_RIG3:
34915207Sedward 		ship->specs->rig3 = a;
35015207Sedward 		break;
35115207Sedward 	case W_RIG4:
35215207Sedward 		ship->specs->rig4 = a;
35315207Sedward 		break;
35415723Sedward 	case W_COL:
35515207Sedward 		ship->file->col = a;
35615207Sedward 		break;
35715723Sedward 	case W_DIR:
35815207Sedward 		ship->file->dir = a;
35915207Sedward 		break;
36015723Sedward 	case W_ROW:
36115207Sedward 		ship->file->row = a;
36215207Sedward 		break;
36315207Sedward 	case W_SINK:
36415207Sedward 		if ((ship->file->sink = a) == 2)
36515207Sedward 			ship->file->dir = 0;
36615207Sedward 		break;
36715207Sedward 	case W_STRUCK:
36815207Sedward 		ship->file->struck = a;
36915207Sedward 		break;
37015207Sedward 	case W_TA:
37115207Sedward 		ship->specs->ta = a;
37215207Sedward 		break;
37315207Sedward 	case W_ALIVE:
37415207Sedward 		alive = 1;
37515207Sedward 		break;
37615207Sedward 	case W_TURN:
37715207Sedward 		turn = a;
37815207Sedward 		break;
37915207Sedward 	case W_WIND:
38015207Sedward 		winddir = a;
38115207Sedward 		windspeed = b;
38215207Sedward 		break;
38315207Sedward 	case W_BEGIN:
38415207Sedward 		(void) strcpy(ship->file->captain, "begin");
38515207Sedward 		people++;
38615207Sedward 		break;
38715207Sedward 	case W_END:
38816081Sedward 		*ship->file->captain = 0;
38916081Sedward 		ship->file->points = 0;
39015207Sedward 		people--;
39115207Sedward 		break;
39216081Sedward 	case W_DDEAD:
39316081Sedward 		hasdriver = 0;
39416081Sedward 		break;
39515207Sedward 	default:
39616081Sedward 		fprintf(stderr, "sync_update: unknown type %d\r\n", type);
39716081Sedward 		return -1;
39815207Sedward 	}
39916081Sedward 	return 0;
40015207Sedward }
401