diff options
Diffstat (limited to 'games/sail/sync.c')
-rw-r--r-- | games/sail/sync.c | 421 |
1 files changed, 421 insertions, 0 deletions
diff --git a/games/sail/sync.c b/games/sail/sync.c new file mode 100644 index 0000000..ca56e23 --- /dev/null +++ b/games/sail/sync.c @@ -0,0 +1,421 @@ +/* + * 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 8.1 (Berkeley) 5/31/93"; +#endif /* not lint */ + +#include "externs.h" +#include <sys/file.h> +#include <sys/errno.h> + +#define BUFSIZE 4096 + +static char sync_buf[BUFSIZE]; +static char *sync_bp = sync_buf; +static char sync_lock[25]; +static char sync_file[25]; +static long sync_seek; +static FILE *sync_fp; +#define SF "/tmp/#sailsink.%d" +#define LF "/tmp/#saillock.%d" + +/*VARARGS3*/ +makesignal(from, fmt, ship, a, b, c) + struct ship *from; + char *fmt; + register struct ship *ship; +{ + char message[80]; + + if (ship == 0) + (void) sprintf(message, fmt, a, b, c); + else + (void) sprintf(message, fmt, + ship->shipname, colours(ship), + sterncolour(ship), a, b, c); + Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0); +} + +#include <sys/types.h> +#include <sys/stat.h> +sync_exists(game) +{ + char buf[sizeof sync_file]; + struct stat s; + time_t t; + + (void) sprintf(buf, SF, game); + (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 = umask(issetuid ? 077 : 011); + sync_fp = fopen(sync_file, "w+"); + (void) umask(omask); + } else + sync_fp = fopen(sync_file, "r+"); + if (sync_fp == NULL) + return -1; + sync_seek = 0; + return 0; +} + +sync_close(remove) + char remove; +{ + 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; +{ + if (isstr) + (void) sprintf(sync_bp, "%d %d %d %s\n", + type, ship->file->index, isstr, a); + else + (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_bp--; + if (sync_bp >= &sync_buf[sizeof sync_buf]) + abort(); + (void) sync_update(type, ship, a, b, c, d); +} + +Sync() +{ + sig_t sighup, sigint; + register n; + int type, shipnum, isstr, a, b, c, d; + char buf[80]; + char erred = 0; + extern errno; + + 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); + 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': + p--; + case EOF: + break; + default: + if (p >= buf + sizeof buf) + p--; + continue; + } + break; + } + *p = 0; + for (p = buf; *p == ' '; p++) + ; + a = (int)p; + b = c = d = 0; + } else + 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; + } +bad: + erred++; +out: + if (!erred && sync_bp != sync_buf) { + (void) fseek(sync_fp, 0L, 2); + (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf, + sync_fp); + (void) fflush(sync_fp); + sync_bp = sync_buf; + } + sync_seek = ftell(sync_fp); +#ifdef LOCK_EX + (void) flock(fileno(sync_fp), LOCK_UN); +#else + (void) unlink(sync_lock); +#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; +{ + switch (type) { + case W_DBP: { + register struct BP *p = &ship->file->DBP[a]; + p->turnsent = b; + p->toship = SHIP(c); + p->mensent = d; + break; + } + case W_OBP: { + register struct BP *p = &ship->file->OBP[a]; + p->turnsent = b; + p->toship = SHIP(c); + p->mensent = d; + break; + } + case W_FOUL: { + 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->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: + 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; + s->crew1 = a; + s->crew2 = b; + s->crew3 = c; + break; + } + case W_CAPTAIN: + (void) strncpy(ship->file->captain, (char *)a, + sizeof ship->file->captain - 1); + ship->file->captain[sizeof ship->file->captain - 1] = 0; + break; + case W_CAPTURED: + if (a < 0) + ship->file->captured = 0; + else + ship->file->captured = SHIP(a); + break; + case W_CLASS: + ship->specs->class = a; + break; + case W_DRIFT: + ship->file->drift = a; + break; + case W_EXPLODE: + if ((ship->file->explode = a) == 2) + ship->file->dir = 0; + break; + case W_FS: + ship->file->FS = a; + break; + case W_GUNL: { + register struct shipspecs *s = ship->specs; + s->gunL = a; + s->carL = b; + break; + } + case W_GUNR: { + register struct shipspecs *s = ship->specs; + s->gunR = a; + s->carR = b; + break; + } + case W_HULL: + ship->specs->hull = a; + break; + 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; + break; + case W_POINTS: + ship->file->points = a; + break; + case W_QUAL: + ship->specs->qual = a; + break; + case W_RIGG: { + register struct shipspecs *s = ship->specs; + s->rig1 = a; + s->rig2 = b; + s->rig3 = c; + s->rig4 = d; + break; + } + case W_RIG1: + ship->specs->rig1 = a; + break; + case W_RIG2: + ship->specs->rig2 = a; + break; + case W_RIG3: + ship->specs->rig3 = a; + break; + case W_RIG4: + ship->specs->rig4 = a; + break; + case W_COL: + ship->file->col = a; + break; + case W_DIR: + ship->file->dir = a; + break; + case W_ROW: + ship->file->row = a; + break; + case W_SINK: + if ((ship->file->sink = a) == 2) + ship->file->dir = 0; + break; + case W_STRUCK: + ship->file->struck = a; + break; + case W_TA: + ship->specs->ta = a; + break; + case W_ALIVE: + alive = 1; + break; + case W_TURN: + turn = a; + break; + case W_WIND: + winddir = a; + windspeed = b; + break; + case W_BEGIN: + (void) strcpy(ship->file->captain, "begin"); + people++; + break; + case W_END: + *ship->file->captain = 0; + ship->file->points = 0; + people--; + break; + case W_DDEAD: + hasdriver = 0; + break; + default: + fprintf(stderr, "sync_update: unknown type %d\r\n", type); + return -1; + } + return 0; +} |