X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/7cd3d9ac5b00ff858d349bf508d6d3ef8e811563..fd88f5c5678c80ff5e338adc372d28a52ad20530:/usr/src/games/sail/sync.c diff --git a/usr/src/games/sail/sync.c b/usr/src/games/sail/sync.c index 3cde4d1868..8f8dc7dbb9 100644 --- a/usr/src/games/sail/sync.c +++ b/usr/src/games/sail/sync.c @@ -1,11 +1,48 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + #ifndef lint -static char *sccsid = "@(#)sync.c 2.2 83/11/01"; -#endif +static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95"; +#endif /* not lint */ -#include "externs.h" +#include +#include +#include "extern.h" + +#define BUFSIZE 4096 static char sync_buf[BUFSIZE]; -static char *sync_bufp = sync_buf; +static char *sync_bp = sync_buf; static char sync_lock[25]; static char sync_file[25]; static long sync_seek; @@ -15,9 +52,9 @@ static FILE *sync_fp; /*VARARGS3*/ makesignal(from, fmt, ship, a, b, c) -struct ship *from; -char *fmt; -register struct ship *ship; + struct ship *from; + char *fmt; + register struct ship *ship; { char message[80]; @@ -39,11 +76,13 @@ sync_exists(game) time_t t; (void) sprintf(buf, SF, game); - time(&t); + (void) time(&t); if (stat(buf, &s) < 0) return 0; if (s.st_mtime < t - 60*60*2) { /* 2 hours */ - unlink(buf); + (void) unlink(buf); + (void) sprintf(buf, LF, game); + (void) unlink(buf); return 0; } else return 1; @@ -51,27 +90,24 @@ sync_exists(game) sync_open() { + if (sync_fp != NULL) + (void) fclose(sync_fp); (void) sprintf(sync_lock, LF, game); (void) sprintf(sync_file, SF, game); if (access(sync_file, 0) < 0) { - int omask; -#ifdef SETUID - omask = umask(077); -#else - omask = umask(011); -#endif + int omask = umask(issetuid ? 077 : 011); sync_fp = fopen(sync_file, "w+"); (void) umask(omask); } else sync_fp = fopen(sync_file, "r+"); - if (sync_fp == 0) + if (sync_fp == NULL) return -1; - sync_seek == 0; + sync_seek = 0; return 0; } sync_close(remove) -char remove; + char remove; { if (sync_fp != 0) (void) fclose(sync_fp); @@ -80,40 +116,68 @@ char remove; } Write(type, ship, isstr, a, b, c, d) -int type; -struct ship *ship; -char isstr; -int a, b, c, d; + int type; + struct ship *ship; + char isstr; + int a, b, c, d; { if (isstr) - (void) sprintf(sync_bufp, "%d %d %d %s\n", - type, ship-SHIP(0), isstr, a); + (void) sprintf(sync_bp, "%d %d %d %s\n", + type, ship->file->index, isstr, a); else - (void) sprintf(sync_bufp, "%d %d %d %d %d %d %d\n", - type, ship-SHIP(0), isstr, a, b, c, d); - while (*sync_bufp++) + (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n", + type, ship->file->index, isstr, a, b, c, d); + while (*sync_bp++) ; - sync_bufp--; - if (sync_bufp >= &sync_buf[sizeof sync_buf]) + sync_bp--; + if (sync_bp >= &sync_buf[sizeof sync_buf]) abort(); - sync_update(type, ship, a, b, c, d); + (void) sync_update(type, ship, a, b, c, d); } Sync() { - int (*sig1)(), (*sig2)(); + sig_t sighup, sigint; + register n; int type, shipnum, isstr, a, b, c, d; - char buf[60]; - register char *p = buf; - int n; + char buf[80]; + char erred = 0; + extern errno; - sig1 = signal(SIGHUP, SIG_IGN); - sig2 = signal(SIGINT, SIG_IGN); - for (n = 0; link(sync_file, sync_lock) < 0 && n < 30; n++) - sleep(2); + sighup = signal(SIGHUP, SIG_IGN); + sigint = signal(SIGINT, SIG_IGN); + for (n = TIMEOUT; --n >= 0;) { +#ifdef LOCK_EX + if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0) + break; + if (errno != EWOULDBLOCK) + return -1; +#else + if (link(sync_file, sync_lock) >= 0) + break; + if (errno != EEXIST) + return -1; +#endif + sleep(1); + } + if (n <= 0) + return -1; (void) fseek(sync_fp, sync_seek, 0); - while (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr) != EOF) { + for (;;) { + switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) { + case 3: + break; + case EOF: + goto out; + default: + goto bad; + } + if (shipnum < 0 || shipnum >= cc->vessels) + goto bad; + if (isstr != 0 && isstr != 1) + goto bad; if (isstr) { + register char *p; for (p = buf;;) { switch (*p++ = getc(sync_fp)) { case '\n': @@ -121,6 +185,8 @@ Sync() case EOF: break; default: + if (p >= buf + sizeof buf) + p--; continue; } break; @@ -131,25 +197,36 @@ Sync() a = (int)p; b = c = d = 0; } else - (void) fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d); - sync_update(type, SHIP(shipnum), a, b, c, d); + if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4) + goto bad; + if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0) + goto bad; } - if (sync_bufp != sync_buf) { +bad: + erred++; +out: + if (!erred && sync_bp != sync_buf) { (void) fseek(sync_fp, 0L, 2); - (void) fputs(sync_buf, sync_fp); + (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf, + sync_fp); (void) fflush(sync_fp); - sync_bufp = sync_buf; + sync_bp = sync_buf; } sync_seek = ftell(sync_fp); +#ifdef LOCK_EX + (void) flock(fileno(sync_fp), LOCK_UN); +#else (void) unlink(sync_lock); - (void) signal(SIGHUP, sig1); - (void) signal(SIGINT, sig2); +#endif + (void) signal(SIGHUP, sighup); + (void) signal(SIGINT, sigint); + return erred ? -1 : 0; } sync_update(type, ship, a, b, c, d) -int type; -register struct ship *ship; -int a, b, c, d; + int type; + register struct ship *ship; + int a, b, c, d; { switch (type) { case W_DBP: { @@ -167,21 +244,53 @@ int a, b, c, d; break; } case W_FOUL: { - register struct snag *p = &ship->file->fouls[a]; - p->turnfoul = b; - p->toship = SHIP(c); + register struct snag *p = &ship->file->foul[a]; + if (SHIP(a)->file->dir == 0) + break; + if (p->sn_count++ == 0) + p->sn_turn = turn; + ship->file->nfoul++; break; } case W_GRAP: { - register struct snag *p = &ship->file->grapples[a]; - p->turnfoul = b; - p->toship = SHIP(c); + register struct snag *p = &ship->file->grap[a]; + if (SHIP(a)->file->dir == 0) + break; + if (p->sn_count++ == 0) + p->sn_turn = turn; + ship->file->ngrap++; break; } - case W_SIGNAL: - if (isplayer) { - Signal("\7%s (%c%c): %s", ship, a); + case W_UNFOUL: { + register struct snag *p = &ship->file->foul[a]; + if (p->sn_count > 0) + if (b) { + ship->file->nfoul -= p->sn_count; + p->sn_count = 0; + } else { + ship->file->nfoul--; + p->sn_count--; + } + break; } + case W_UNGRAP: { + register struct snag *p = &ship->file->grap[a]; + if (p->sn_count > 0) + if (b) { + ship->file->ngrap -= p->sn_count; + p->sn_count = 0; + } else { + ship->file->ngrap--; + p->sn_count--; + } + break; + } + case W_SIGNAL: + if (mode == MODE_PLAYER) + if (nobells) + Signal("%s (%c%c): %s", ship, a); + else + Signal("\7%s (%c%c): %s", ship, a); break; case W_CREW: { register struct shipspecs *s = ship->specs; @@ -229,10 +338,10 @@ int a, b, c, d; case W_HULL: ship->specs->hull = a; break; - case W_LAST: - (void) strncpy(ship->file->last, (char *)a, - sizeof ship->file->last - 1); - ship->file->last[sizeof ship->file->last - 1] = 0; + case W_MOVE: + (void) strncpy(ship->file->movebuf, (char *)a, + sizeof ship->file->movebuf - 1); + ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0; break; case W_PCREW: ship->file->pcrew = a; @@ -263,13 +372,13 @@ int a, b, c, d; case W_RIG4: ship->specs->rig4 = a; break; - case W_SHIPCOL: + case W_COL: ship->file->col = a; break; - case W_SHIPDIR: + case W_DIR: ship->file->dir = a; break; - case W_SHIPROW: + case W_ROW: ship->file->row = a; break; case W_SINK: @@ -297,11 +406,16 @@ int a, b, c, d; people++; break; case W_END: - (void) strcpy(ship->file->captain, ""); + *ship->file->captain = 0; + ship->file->points = 0; people--; break; - default: - fprintf(stderr, "sync_update: unknown type %d\n", type); + case W_DDEAD: + hasdriver = 0; break; + default: + fprintf(stderr, "sync_update: unknown type %d\r\n", type); + return -1; } + return 0; }