freebsd-dev/games/sail/sync.c
Bruce Evans 5d34c3e0f1 Fixed printf format errors. Didn't fix gross homemade varargs function
Write().  Pointers are passed to it as longs, but it expects them to
be passed as ints.  The alpha non-fixes made this worse.
1998-06-30 18:58:28 +00:00

422 lines
9.1 KiB
C

/*
* 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, (long)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, (char *)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 = (long)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;
long 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;
}