xref: /openbsd-src/games/sail/sync.c (revision df69c215c7c66baf660f3f65414fd34796c96152)
1*df69c215Sderaadt /*	$OpenBSD: sync.c,v 1.16 2019/06/28 13:32:52 deraadt Exp $	*/
24f095801Spjanzen /*	$NetBSD: sync.c,v 1.9 1998/08/30 09:19:40 veego Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Copyright (c) 1983, 1993
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
167a09557bSmillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  */
32df930be7Sderaadt 
3334278d36Sguenther #include <sys/stat.h>
3434278d36Sguenther 
354f095801Spjanzen #include <errno.h>
36747bd222Smestre #ifdef LOCK_EX
37747bd222Smestre #include <fcntl.h>
38747bd222Smestre #endif
3939ac0be5Smestre #include <signal.h>
404f095801Spjanzen #include <stdlib.h>
4139ac0be5Smestre #include <string.h>
42ee7acb09Stb #include <time.h>
434f095801Spjanzen #include <unistd.h>
4439ac0be5Smestre 
454f095801Spjanzen #include "extern.h"
4639ac0be5Smestre #include "machdep.h"
474f095801Spjanzen #include "pathnames.h"
4839ac0be5Smestre #include "player.h"
49df930be7Sderaadt 
50df930be7Sderaadt #define BUFSIZE 4096
51df930be7Sderaadt 
524f095801Spjanzen static const char SF[] = _PATH_SYNC;
534f095801Spjanzen static const char LF[] = _PATH_LOCK;
54df930be7Sderaadt static char sync_buf[BUFSIZE];
55df930be7Sderaadt static char *sync_bp = sync_buf;
564f095801Spjanzen static char sync_lock[sizeof SF];
574f095801Spjanzen static char sync_file[sizeof LF];
58df930be7Sderaadt static long sync_seek;
59df930be7Sderaadt static FILE *sync_fp;
60df930be7Sderaadt 
614f095801Spjanzen void
fmtship(char * buf,size_t len,const char * fmt,struct ship * ship)62747bd222Smestre fmtship(char *buf, size_t len, const char *fmt, struct ship *ship)
63df930be7Sderaadt {
648c2dad91Smoritz 	if (len == 0)
658c2dad91Smoritz 		abort();	/* XXX */
668c2dad91Smoritz 
678c2dad91Smoritz 	while (*fmt && len > 1) {
684f095801Spjanzen 		if (*fmt == '$' && fmt[1] == '$') {
698c2dad91Smoritz 			size_t l;
708c2dad91Smoritz 			snprintf(buf, len, "%s (%c%c)",
714f095801Spjanzen 			    ship->shipname, colours(ship), sterncolour(ship));
728c2dad91Smoritz 			l = strlen(buf);
734f095801Spjanzen 			buf += l;
748c2dad91Smoritz 			len -= l;
754f095801Spjanzen 			fmt += 2;
768c2dad91Smoritz 		} else {
774f095801Spjanzen 			*buf++ = *fmt++;
788c2dad91Smoritz 			len--;
798c2dad91Smoritz 		}
80df930be7Sderaadt 	}
81df930be7Sderaadt 
824f095801Spjanzen 	*buf = '\0';
834f095801Spjanzen }
844f095801Spjanzen 
854f095801Spjanzen 
864f095801Spjanzen void
makesignal(struct ship * from,const char * fmt,struct ship * ship,...)874f095801Spjanzen makesignal(struct ship *from, const char *fmt, struct ship *ship, ...)
884f095801Spjanzen {
894f095801Spjanzen 	char message[BUFSIZ];
904f095801Spjanzen 	char format[BUFSIZ];
914f095801Spjanzen 	va_list ap;
924f095801Spjanzen 
934f095801Spjanzen 	va_start(ap, ship);
944f095801Spjanzen 	fmtship(format, sizeof(format), fmt, ship);
9542ceebb3Sderaadt 	(void) vsnprintf(message, sizeof message, format, ap);
964f095801Spjanzen 	va_end(ap);
974f095801Spjanzen 	Writestr(W_SIGNAL, from, message);
984f095801Spjanzen }
994f095801Spjanzen 
1004f095801Spjanzen void
makemsg(struct ship * from,const char * fmt,...)1014f095801Spjanzen makemsg(struct ship *from, const char *fmt, ...)
1024f095801Spjanzen {
1034f095801Spjanzen 	char message[BUFSIZ];
1044f095801Spjanzen 	va_list ap;
1054f095801Spjanzen 
1064f095801Spjanzen 	va_start(ap, fmt);
10742ceebb3Sderaadt 	(void) vsnprintf(message, sizeof message, fmt, ap);
1084f095801Spjanzen 	va_end(ap);
1094f095801Spjanzen 	Writestr(W_SIGNAL, from, message);
1104f095801Spjanzen }
1114f095801Spjanzen 
1124f095801Spjanzen int
sync_exists(int game)113747bd222Smestre sync_exists(int game)
114df930be7Sderaadt {
115df930be7Sderaadt 	char buf[sizeof sync_file];
116df930be7Sderaadt 	struct stat s;
117df930be7Sderaadt 	time_t t;
118df930be7Sderaadt 
11942ceebb3Sderaadt 	(void) snprintf(buf, sizeof buf, SF, game);
120df930be7Sderaadt 	(void) time(&t);
1214f095801Spjanzen 	setegid(egid);
122*df69c215Sderaadt 	if (stat(buf, &s) == -1) {
1234f095801Spjanzen 		setegid(gid);
124df930be7Sderaadt 		return 0;
1254f095801Spjanzen 	}
126df930be7Sderaadt 	if (s.st_mtime < t - 60*60*2) {		/* 2 hours */
127df930be7Sderaadt 		(void) unlink(buf);
12842ceebb3Sderaadt 		(void) snprintf(buf, sizeof buf, LF, game);
129df930be7Sderaadt 		(void) unlink(buf);
1304f095801Spjanzen 		setegid(gid);
131df930be7Sderaadt 		return 0;
1324f095801Spjanzen 	}
1334f095801Spjanzen 	setegid(gid);
134df930be7Sderaadt 	return 1;
135df930be7Sderaadt }
136df930be7Sderaadt 
1374f095801Spjanzen int
sync_open(void)138747bd222Smestre sync_open(void)
139df930be7Sderaadt {
1404f095801Spjanzen 	struct stat tmp;
1414f095801Spjanzen 
142df930be7Sderaadt 	if (sync_fp != NULL)
143df930be7Sderaadt 		(void) fclose(sync_fp);
14442ceebb3Sderaadt 	(void) snprintf(sync_lock, sizeof sync_lock, LF, game);
14542ceebb3Sderaadt 	(void) snprintf(sync_file, sizeof sync_file, SF, game);
1464f095801Spjanzen 	setegid(egid);
147*df69c215Sderaadt 	if (stat(sync_file, &tmp) == -1) {
1484f095801Spjanzen 		mode_t omask = umask(002);
149df930be7Sderaadt 		sync_fp = fopen(sync_file, "w+");
150df930be7Sderaadt 		(void) umask(omask);
151df930be7Sderaadt 	} else
152df930be7Sderaadt 		sync_fp = fopen(sync_file, "r+");
1534f095801Spjanzen 	setegid(gid);
154df930be7Sderaadt 	if (sync_fp == NULL)
155df930be7Sderaadt 		return -1;
156df930be7Sderaadt 	sync_seek = 0;
157df930be7Sderaadt 	return 0;
158df930be7Sderaadt }
159df930be7Sderaadt 
1604f095801Spjanzen void
sync_close(int remove)161747bd222Smestre sync_close(int remove)
162df930be7Sderaadt {
163df930be7Sderaadt 	if (sync_fp != 0)
164df930be7Sderaadt 		(void) fclose(sync_fp);
1654f095801Spjanzen 	if (remove) {
1664f095801Spjanzen 		setegid(egid);
167df930be7Sderaadt 		(void) unlink(sync_file);
1684f095801Spjanzen 		setegid(gid);
1694f095801Spjanzen 	}
170df930be7Sderaadt }
171df930be7Sderaadt 
1724f095801Spjanzen void
Write(int type,struct ship * ship,long a,long b,long c,long d)173747bd222Smestre Write(int type, struct ship *ship, long a, long b, long c, long d)
174df930be7Sderaadt {
17542ceebb3Sderaadt 	(void) snprintf(sync_bp, sync_buf + sizeof sync_buf - sync_bp,
17642ceebb3Sderaadt 		"%d %d 0 %ld %ld %ld %ld\n",
1774f095801Spjanzen 	       type, ship->file->index, a, b, c, d);
178df930be7Sderaadt 	while (*sync_bp++)
179df930be7Sderaadt 		;
180df930be7Sderaadt 	sync_bp--;
181df930be7Sderaadt 	if (sync_bp >= &sync_buf[sizeof sync_buf])
182df930be7Sderaadt 		abort();
1834f095801Spjanzen 	(void) sync_update(type, ship, NULL, a, b, c, d);
184df930be7Sderaadt }
185df930be7Sderaadt 
1864f095801Spjanzen void
Writestr(int type,struct ship * ship,const char * a)187747bd222Smestre Writestr(int type, struct ship *ship, const char *a)
1884f095801Spjanzen {
18942ceebb3Sderaadt 	(void) snprintf(sync_bp, sync_buf + sizeof sync_buf - sync_bp,
19042ceebb3Sderaadt 		"%d %d 1 %s\n",
1914f095801Spjanzen 		type, ship->file->index, a);
1924f095801Spjanzen 	while (*sync_bp++)
1934f095801Spjanzen 		;
1944f095801Spjanzen 	sync_bp--;
1954f095801Spjanzen 	if (sync_bp >= &sync_buf[sizeof sync_buf])
1964f095801Spjanzen 		abort();
1974f095801Spjanzen 	(void) sync_update(type, ship, a, 0, 0, 0, 0);
1984f095801Spjanzen }
1994f095801Spjanzen 
2004f095801Spjanzen int
Sync(void)201747bd222Smestre Sync(void)
202df930be7Sderaadt {
203df930be7Sderaadt 	sig_t sighup, sigint;
2044f095801Spjanzen 	int n;
205df930be7Sderaadt 	int type, shipnum, isstr;
2064f095801Spjanzen 	char *astr;
207df930be7Sderaadt 	long a, b, c, d;
208df930be7Sderaadt 	char buf[80];
209df930be7Sderaadt 	char erred = 0;
210df930be7Sderaadt 
211df930be7Sderaadt 	sighup = signal(SIGHUP, SIG_IGN);
212df930be7Sderaadt 	sigint = signal(SIGINT, SIG_IGN);
213df930be7Sderaadt 	for (n = TIMEOUT; --n >= 0;) {
214df930be7Sderaadt #ifdef LOCK_EX
215df930be7Sderaadt 		if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
216df930be7Sderaadt 			break;
217df930be7Sderaadt 		if (errno != EWOULDBLOCK)
218df930be7Sderaadt 			return -1;
219df930be7Sderaadt #else
2204f095801Spjanzen 		setegid(egid);
2214f095801Spjanzen 		if (link(sync_file, sync_lock) >= 0) {
2224f095801Spjanzen 			setegid(gid);
223df930be7Sderaadt 			break;
2244f095801Spjanzen 		}
2254f095801Spjanzen 		setegid(gid);
226df930be7Sderaadt 		if (errno != EEXIST)
227df930be7Sderaadt 			return -1;
228df930be7Sderaadt #endif
229df930be7Sderaadt 		sleep(1);
230df930be7Sderaadt 	}
231df930be7Sderaadt 	if (n <= 0)
232df930be7Sderaadt 		return -1;
2334f095801Spjanzen 	(void) fseek(sync_fp, sync_seek, SEEK_SET);
234df930be7Sderaadt 	for (;;) {
235df930be7Sderaadt 		switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
236df930be7Sderaadt 		case 3:
237df930be7Sderaadt 			break;
238df930be7Sderaadt 		case EOF:
239df930be7Sderaadt 			goto out;
240df930be7Sderaadt 		default:
241df930be7Sderaadt 			goto bad;
242df930be7Sderaadt 		}
243df930be7Sderaadt 		if (shipnum < 0 || shipnum >= cc->vessels)
244df930be7Sderaadt 			goto bad;
245df930be7Sderaadt 		if (isstr != 0 && isstr != 1)
246df930be7Sderaadt 			goto bad;
247df930be7Sderaadt 		if (isstr) {
248c3fc728dSmiod 			int ch;
2494f095801Spjanzen 			char *p;
250c3fc728dSmiod 
251df930be7Sderaadt 			for (p = buf;;) {
252c3fc728dSmiod 				ch = getc(sync_fp);
253c3fc728dSmiod 				switch (ch) {
254df930be7Sderaadt 				case '\n':
255df930be7Sderaadt 				case EOF:
256df930be7Sderaadt 					break;
257df930be7Sderaadt 				default:
258c3fc728dSmiod 					if (p < buf + sizeof buf)
259c3fc728dSmiod 						*p++ = ch;
260df930be7Sderaadt 					continue;
261df930be7Sderaadt 				}
262df930be7Sderaadt 				break;
263df930be7Sderaadt 			}
264df930be7Sderaadt 			*p = 0;
265df930be7Sderaadt 			for (p = buf; *p == ' '; p++)
266df930be7Sderaadt 				;
2674f095801Spjanzen 			astr = p;
2684f095801Spjanzen 			a = b = c = d = 0;
2694f095801Spjanzen 		} else {
2704f095801Spjanzen 			if (fscanf(sync_fp, "%ld%ld%ld%ld", &a, &b, &c, &d) != 4)
271df930be7Sderaadt 				goto bad;
2724f095801Spjanzen 			astr = NULL;
2734f095801Spjanzen 		}
2744f095801Spjanzen 		if (sync_update(type, SHIP(shipnum), astr, a, b, c, d) < 0)
275df930be7Sderaadt 			goto bad;
276df930be7Sderaadt 	}
277df930be7Sderaadt bad:
278df930be7Sderaadt 	erred++;
279df930be7Sderaadt out:
280df930be7Sderaadt 	if (!erred && sync_bp != sync_buf) {
2814f095801Spjanzen 		(void) fseek(sync_fp, 0L, SEEK_END);
282df930be7Sderaadt 		(void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
283df930be7Sderaadt 			sync_fp);
284df930be7Sderaadt 		(void) fflush(sync_fp);
285df930be7Sderaadt 		sync_bp = sync_buf;
286df930be7Sderaadt 	}
287df930be7Sderaadt 	sync_seek = ftell(sync_fp);
288df930be7Sderaadt #ifdef LOCK_EX
289df930be7Sderaadt 	(void) flock(fileno(sync_fp), LOCK_UN);
290df930be7Sderaadt #else
2914f095801Spjanzen 	setegid(egid);
292df930be7Sderaadt 	(void) unlink(sync_lock);
2934f095801Spjanzen 	setegid(gid);
294df930be7Sderaadt #endif
295df930be7Sderaadt 	(void) signal(SIGHUP, sighup);
296df930be7Sderaadt 	(void) signal(SIGINT, sigint);
297df930be7Sderaadt 	return erred ? -1 : 0;
298df930be7Sderaadt }
299df930be7Sderaadt 
3004f095801Spjanzen int
sync_update(int type,struct ship * ship,const char * astr,long a,long b,long c,long d)301747bd222Smestre sync_update(int type, struct ship *ship, const char *astr, long a, long b,
302747bd222Smestre     long c, long d)
303df930be7Sderaadt {
304df930be7Sderaadt 	switch (type) {
305df930be7Sderaadt 	case W_DBP: {
3064f095801Spjanzen 		struct BP *p = &ship->file->DBP[a];
307df930be7Sderaadt 		p->turnsent = b;
308df930be7Sderaadt 		p->toship = SHIP(c);
309df930be7Sderaadt 		p->mensent = d;
310df930be7Sderaadt 		break;
311df930be7Sderaadt 		}
312df930be7Sderaadt 	case W_OBP: {
3134f095801Spjanzen 		struct BP *p = &ship->file->OBP[a];
314df930be7Sderaadt 		p->turnsent = b;
315df930be7Sderaadt 		p->toship = SHIP(c);
316df930be7Sderaadt 		p->mensent = d;
317df930be7Sderaadt 		break;
318df930be7Sderaadt 		}
319df930be7Sderaadt 	case W_FOUL: {
3204f095801Spjanzen 		struct snag *p = &ship->file->foul[a];
321df930be7Sderaadt 		if (SHIP(a)->file->dir == 0)
322df930be7Sderaadt 			break;
323df930be7Sderaadt 		if (p->sn_count++ == 0)
324df930be7Sderaadt 			p->sn_turn = turn;
325df930be7Sderaadt 		ship->file->nfoul++;
326df930be7Sderaadt 		break;
327df930be7Sderaadt 		}
328df930be7Sderaadt 	case W_GRAP: {
3294f095801Spjanzen 		struct snag *p = &ship->file->grap[a];
330df930be7Sderaadt 		if (SHIP(a)->file->dir == 0)
331df930be7Sderaadt 			break;
332df930be7Sderaadt 		if (p->sn_count++ == 0)
333df930be7Sderaadt 			p->sn_turn = turn;
334df930be7Sderaadt 		ship->file->ngrap++;
335df930be7Sderaadt 		break;
336df930be7Sderaadt 		}
337df930be7Sderaadt 	case W_UNFOUL: {
3384f095801Spjanzen 		struct snag *p = &ship->file->foul[a];
3394f095801Spjanzen 		if (p->sn_count > 0) {
340df930be7Sderaadt 			if (b) {
341df930be7Sderaadt 				ship->file->nfoul -= p->sn_count;
342df930be7Sderaadt 				p->sn_count = 0;
343df930be7Sderaadt 			} else {
344df930be7Sderaadt 				ship->file->nfoul--;
345df930be7Sderaadt 				p->sn_count--;
346df930be7Sderaadt 			}
3474f095801Spjanzen 		}
348df930be7Sderaadt 		break;
349df930be7Sderaadt 		}
350df930be7Sderaadt 	case W_UNGRAP: {
3514f095801Spjanzen 		struct snag *p = &ship->file->grap[a];
3524f095801Spjanzen 		if (p->sn_count > 0) {
353df930be7Sderaadt 			if (b) {
354df930be7Sderaadt 				ship->file->ngrap -= p->sn_count;
355df930be7Sderaadt 				p->sn_count = 0;
356df930be7Sderaadt 			} else {
357df930be7Sderaadt 				ship->file->ngrap--;
358df930be7Sderaadt 				p->sn_count--;
359df930be7Sderaadt 			}
3604f095801Spjanzen 		}
361df930be7Sderaadt 		break;
362df930be7Sderaadt 		}
363df930be7Sderaadt 	case W_SIGNAL:
3644f095801Spjanzen 		if (mode == MODE_PLAYER) {
365df930be7Sderaadt 			if (nobells)
3664f095801Spjanzen 				Signal("$$: %s", ship, astr);
367df930be7Sderaadt 			else
3684f095801Spjanzen 				Signal("\7$$: %s", ship, astr);
3694f095801Spjanzen 		}
370df930be7Sderaadt 		break;
371df930be7Sderaadt 	case W_CREW: {
3724f095801Spjanzen 		struct shipspecs *s = ship->specs;
373df930be7Sderaadt 		s->crew1 = a;
374df930be7Sderaadt 		s->crew2 = b;
375df930be7Sderaadt 		s->crew3 = c;
376df930be7Sderaadt 		break;
377df930be7Sderaadt 		}
378df930be7Sderaadt 	case W_CAPTAIN:
37911253235Savsm 		(void) strlcpy(ship->file->captain, astr,
38011253235Savsm 			sizeof ship->file->captain);
381df930be7Sderaadt 		break;
382df930be7Sderaadt 	case W_CAPTURED:
383df930be7Sderaadt 		if (a < 0)
384df930be7Sderaadt 			ship->file->captured = 0;
385df930be7Sderaadt 		else
386df930be7Sderaadt 			ship->file->captured = SHIP(a);
387df930be7Sderaadt 		break;
388df930be7Sderaadt 	case W_CLASS:
389df930be7Sderaadt 		ship->specs->class = a;
390df930be7Sderaadt 		break;
391df930be7Sderaadt 	case W_DRIFT:
392df930be7Sderaadt 		ship->file->drift = a;
393df930be7Sderaadt 		break;
394df930be7Sderaadt 	case W_EXPLODE:
395df930be7Sderaadt 		if ((ship->file->explode = a) == 2)
396df930be7Sderaadt 			ship->file->dir = 0;
397df930be7Sderaadt 		break;
398df930be7Sderaadt 	case W_FS:
399df930be7Sderaadt 		ship->file->FS = a;
400df930be7Sderaadt 		break;
401df930be7Sderaadt 	case W_GUNL: {
4024f095801Spjanzen 		struct shipspecs *s = ship->specs;
403df930be7Sderaadt 		s->gunL = a;
404df930be7Sderaadt 		s->carL = b;
405df930be7Sderaadt 		break;
406df930be7Sderaadt 		}
407df930be7Sderaadt 	case W_GUNR: {
4084f095801Spjanzen 		struct shipspecs *s = ship->specs;
409df930be7Sderaadt 		s->gunR = a;
410df930be7Sderaadt 		s->carR = b;
411df930be7Sderaadt 		break;
412df930be7Sderaadt 		}
413df930be7Sderaadt 	case W_HULL:
414df930be7Sderaadt 		ship->specs->hull = a;
415df930be7Sderaadt 		break;
416df930be7Sderaadt 	case W_MOVE:
41711253235Savsm 		(void) strlcpy(ship->file->movebuf, astr,
41811253235Savsm 			sizeof ship->file->movebuf);
419df930be7Sderaadt 		break;
420df930be7Sderaadt 	case W_PCREW:
421df930be7Sderaadt 		ship->file->pcrew = a;
422df930be7Sderaadt 		break;
423df930be7Sderaadt 	case W_POINTS:
424df930be7Sderaadt 		ship->file->points = a;
425df930be7Sderaadt 		break;
426df930be7Sderaadt 	case W_QUAL:
427df930be7Sderaadt 		ship->specs->qual = a;
428df930be7Sderaadt 		break;
429df930be7Sderaadt 	case W_RIGG: {
4304f095801Spjanzen 		struct shipspecs *s = ship->specs;
431df930be7Sderaadt 		s->rig1 = a;
432df930be7Sderaadt 		s->rig2 = b;
433df930be7Sderaadt 		s->rig3 = c;
434df930be7Sderaadt 		s->rig4 = d;
435df930be7Sderaadt 		break;
436df930be7Sderaadt 		}
437df930be7Sderaadt 	case W_RIG1:
438df930be7Sderaadt 		ship->specs->rig1 = a;
439df930be7Sderaadt 		break;
440df930be7Sderaadt 	case W_RIG2:
441df930be7Sderaadt 		ship->specs->rig2 = a;
442df930be7Sderaadt 		break;
443df930be7Sderaadt 	case W_RIG3:
444df930be7Sderaadt 		ship->specs->rig3 = a;
445df930be7Sderaadt 		break;
446df930be7Sderaadt 	case W_RIG4:
447df930be7Sderaadt 		ship->specs->rig4 = a;
448df930be7Sderaadt 		break;
449df930be7Sderaadt 	case W_COL:
450df930be7Sderaadt 		ship->file->col = a;
451df930be7Sderaadt 		break;
452df930be7Sderaadt 	case W_DIR:
453df930be7Sderaadt 		ship->file->dir = a;
454df930be7Sderaadt 		break;
455df930be7Sderaadt 	case W_ROW:
456df930be7Sderaadt 		ship->file->row = a;
457df930be7Sderaadt 		break;
458df930be7Sderaadt 	case W_SINK:
459df930be7Sderaadt 		if ((ship->file->sink = a) == 2)
460df930be7Sderaadt 			ship->file->dir = 0;
461df930be7Sderaadt 		break;
462df930be7Sderaadt 	case W_STRUCK:
463df930be7Sderaadt 		ship->file->struck = a;
464df930be7Sderaadt 		break;
465df930be7Sderaadt 	case W_TA:
466df930be7Sderaadt 		ship->specs->ta = a;
467df930be7Sderaadt 		break;
468df930be7Sderaadt 	case W_ALIVE:
469df930be7Sderaadt 		alive = 1;
470df930be7Sderaadt 		break;
471df930be7Sderaadt 	case W_TURN:
472df930be7Sderaadt 		turn = a;
473df930be7Sderaadt 		break;
474df930be7Sderaadt 	case W_WIND:
475df930be7Sderaadt 		winddir = a;
476df930be7Sderaadt 		windspeed = b;
477df930be7Sderaadt 		break;
478df930be7Sderaadt 	case W_BEGIN:
4790841e2d4Sderaadt 		(void) strlcpy(ship->file->captain, "begin",
4800841e2d4Sderaadt 		    sizeof ship->file->captain);
481df930be7Sderaadt 		people++;
482df930be7Sderaadt 		break;
483df930be7Sderaadt 	case W_END:
484df930be7Sderaadt 		*ship->file->captain = 0;
485df930be7Sderaadt 		ship->file->points = 0;
486df930be7Sderaadt 		people--;
487df930be7Sderaadt 		break;
488df930be7Sderaadt 	case W_DDEAD:
489df930be7Sderaadt 		hasdriver = 0;
490df930be7Sderaadt 		break;
491df930be7Sderaadt 	default:
492df930be7Sderaadt 		fprintf(stderr, "sync_update: unknown type %d\r\n", type);
493df930be7Sderaadt 		return -1;
494df930be7Sderaadt 	}
495df930be7Sderaadt 	return 0;
496df930be7Sderaadt }
497