X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/6f38c952b7128da97a7d4b52b68a82a01d53d242..fd88f5c5678c80ff5e338adc372d28a52ad20530:/usr/src/games/sail/sync.c diff --git a/usr/src/games/sail/sync.c b/usr/src/games/sail/sync.c index 57e4cf070e..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 1.2 83/10/14"; -#endif +static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95"; +#endif /* not lint */ + +#include +#include +#include "extern.h" -#include "externs.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]; @@ -30,77 +67,117 @@ register struct ship *ship; Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0); } +#include +#include sync_exists(game) { char buf[sizeof sync_file]; + struct stat s; + time_t t; (void) sprintf(buf, SF, game); - return access(buf, 0) >= 0; + (void) time(&t); + if (stat(buf, &s) < 0) + return 0; + if (s.st_mtime < t - 60*60*2) { /* 2 hours */ + (void) unlink(buf); + (void) sprintf(buf, LF, game); + (void) unlink(buf); + return 0; + } else + return 1; } 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; { - (void) fclose(sync_fp); + if (sync_fp != 0) + (void) fclose(sync_fp); if (remove) (void) unlink(sync_file); } 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': @@ -108,6 +185,8 @@ Sync() case EOF: break; default: + if (p >= buf + sizeof buf) + p--; continue; } break; @@ -118,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: { @@ -154,27 +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_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: - /* - (void) putchar('\7'); - */ - Signal("%s (%c%c): %s", ship, a); - /* - (void) strncpy(ship->file->signal, (char *)a, - sizeof ship->file->signal - 1); - ship->file->signal[sizeof ship->file->signal - 1] = 0; - */ + 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; @@ -189,7 +305,10 @@ int a, b, c, d; ship->file->captain[sizeof ship->file->captain - 1] = 0; break; case W_CAPTURED: - ship->file->captured = SHIP(a); + if (a < 0) + ship->file->captured = 0; + else + ship->file->captured = SHIP(a); break; case W_CLASS: ship->specs->class = a; @@ -219,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; @@ -253,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: @@ -287,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; }