118706Sedward /*
260848Sbostic * Copyright (c) 1983, 1993
360848Sbostic * The Regents of the University of California. All rights reserved.
433695Sbostic *
542605Sbostic * %sccs.include.redist.c%
618706Sedward */
718706Sedward
815207Sedward #ifndef lint
9*69068Sbostic static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 04/28/95";
1033695Sbostic #endif /* not lint */
1115207Sedward
1216081Sedward #include <sys/file.h>
13*69068Sbostic #include <errno.h>
14*69068Sbostic #include "extern.h"
1515207Sedward
1618249Sedward #define BUFSIZE 4096
1718249Sedward
1815207Sedward static char sync_buf[BUFSIZE];
1915901Sedward static char *sync_bp = sync_buf;
2015207Sedward static char sync_lock[25];
2115207Sedward static char sync_file[25];
2215207Sedward static long sync_seek;
2315207Sedward static FILE *sync_fp;
2415207Sedward #define SF "/tmp/#sailsink.%d"
2515207Sedward #define LF "/tmp/#saillock.%d"
2615207Sedward
2715207Sedward /*VARARGS3*/
2815207Sedward makesignal(from, fmt, ship, a, b, c)
2918249Sedward struct ship *from;
3018249Sedward char *fmt;
3118249Sedward register struct ship *ship;
3215207Sedward {
3315207Sedward char message[80];
3415207Sedward
3515207Sedward if (ship == 0)
3615207Sedward (void) sprintf(message, fmt, a, b, c);
3715207Sedward else
3815207Sedward (void) sprintf(message, fmt,
3915207Sedward ship->shipname, colours(ship),
4015207Sedward sterncolour(ship), a, b, c);
4115207Sedward Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
4215207Sedward }
4315207Sedward
4415312Sedward #include <sys/types.h>
4515312Sedward #include <sys/stat.h>
sync_exists(game)4615207Sedward sync_exists(game)
4715207Sedward {
4815207Sedward char buf[sizeof sync_file];
4915312Sedward struct stat s;
5015312Sedward time_t t;
5115207Sedward
5215207Sedward (void) sprintf(buf, SF, game);
5315723Sedward (void) time(&t);
5415312Sedward if (stat(buf, &s) < 0)
5515312Sedward return 0;
5615312Sedward if (s.st_mtime < t - 60*60*2) { /* 2 hours */
5715723Sedward (void) unlink(buf);
5816081Sedward (void) sprintf(buf, LF, game);
5916081Sedward (void) unlink(buf);
6015312Sedward return 0;
6115312Sedward } else
6215312Sedward return 1;
6315207Sedward }
6415207Sedward
sync_open()6515207Sedward sync_open()
6615207Sedward {
6718590Sedward if (sync_fp != NULL)
6818590Sedward (void) fclose(sync_fp);
6918590Sedward (void) sprintf(sync_lock, LF, game);
7018590Sedward (void) sprintf(sync_file, SF, game);
7118590Sedward if (access(sync_file, 0) < 0) {
7218590Sedward int omask = umask(issetuid ? 077 : 011);
7318590Sedward sync_fp = fopen(sync_file, "w+");
7418590Sedward (void) umask(omask);
7518590Sedward } else
7618590Sedward sync_fp = fopen(sync_file, "r+");
7718590Sedward if (sync_fp == NULL)
7818590Sedward return -1;
7925934Sedward sync_seek = 0;
8015249Sedward return 0;
8115207Sedward }
8215207Sedward
sync_close(remove)8315207Sedward sync_close(remove)
8418249Sedward char remove;
8515207Sedward {
8615352Sedward if (sync_fp != 0)
8715352Sedward (void) fclose(sync_fp);
8815207Sedward if (remove)
8915207Sedward (void) unlink(sync_file);
9015207Sedward }
9115207Sedward
Write(type,ship,isstr,a,b,c,d)9215207Sedward Write(type, ship, isstr, a, b, c, d)
9318249Sedward int type;
9418249Sedward struct ship *ship;
9518249Sedward char isstr;
9618249Sedward int a, b, c, d;
9715207Sedward {
9815207Sedward if (isstr)
9915901Sedward (void) sprintf(sync_bp, "%d %d %d %s\n",
10015723Sedward type, ship->file->index, isstr, a);
10115207Sedward else
10215901Sedward (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
10315723Sedward type, ship->file->index, isstr, a, b, c, d);
10415901Sedward while (*sync_bp++)
10515207Sedward ;
10615901Sedward sync_bp--;
10715901Sedward if (sync_bp >= &sync_buf[sizeof sync_buf])
10815207Sedward abort();
10916081Sedward (void) sync_update(type, ship, a, b, c, d);
11015207Sedward }
11115207Sedward
Sync()11215207Sedward Sync()
11315207Sedward {
11439835Sbostic sig_t sighup, sigint;
11516425Sedward register n;
11615207Sedward int type, shipnum, isstr, a, b, c, d;
11716081Sedward char buf[80];
11816081Sedward char erred = 0;
11916081Sedward extern errno;
12015207Sedward
12125934Sedward sighup = signal(SIGHUP, SIG_IGN);
12225934Sedward sigint = signal(SIGINT, SIG_IGN);
12316425Sedward for (n = TIMEOUT; --n >= 0;) {
12416081Sedward #ifdef LOCK_EX
12516081Sedward if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
12616081Sedward break;
12716081Sedward if (errno != EWOULDBLOCK)
12816081Sedward return -1;
12916081Sedward #else
13016081Sedward if (link(sync_file, sync_lock) >= 0)
13116081Sedward break;
13216081Sedward if (errno != EEXIST)
13316081Sedward return -1;
13416081Sedward #endif
13516425Sedward sleep(1);
13616081Sedward }
13716425Sedward if (n <= 0)
13816081Sedward return -1;
13915207Sedward (void) fseek(sync_fp, sync_seek, 0);
14016081Sedward for (;;) {
14116081Sedward switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
14216081Sedward case 3:
14316081Sedward break;
14416081Sedward case EOF:
14516081Sedward goto out;
14616081Sedward default:
14716081Sedward goto bad;
14816081Sedward }
14916081Sedward if (shipnum < 0 || shipnum >= cc->vessels)
15016081Sedward goto bad;
15116081Sedward if (isstr != 0 && isstr != 1)
15216081Sedward goto bad;
15315207Sedward if (isstr) {
15416081Sedward register char *p;
15515207Sedward for (p = buf;;) {
15615207Sedward switch (*p++ = getc(sync_fp)) {
15715207Sedward case '\n':
15815207Sedward p--;
15915207Sedward case EOF:
16015207Sedward break;
16115207Sedward default:
16216081Sedward if (p >= buf + sizeof buf)
16316081Sedward p--;
16415207Sedward continue;
16515207Sedward }
16615207Sedward break;
16715207Sedward }
16815207Sedward *p = 0;
16915207Sedward for (p = buf; *p == ' '; p++)
17015207Sedward ;
17115207Sedward a = (int)p;
17215207Sedward b = c = d = 0;
17315207Sedward } else
17416081Sedward if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
17516081Sedward goto bad;
17616081Sedward if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
17716081Sedward goto bad;
17815207Sedward }
17916081Sedward bad:
18016081Sedward erred++;
18116081Sedward out:
18216081Sedward if (!erred && sync_bp != sync_buf) {
18315207Sedward (void) fseek(sync_fp, 0L, 2);
18425934Sedward (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
18525934Sedward sync_fp);
18615207Sedward (void) fflush(sync_fp);
18715901Sedward sync_bp = sync_buf;
18815207Sedward }
18915207Sedward sync_seek = ftell(sync_fp);
19016081Sedward #ifdef LOCK_EX
19116081Sedward (void) flock(fileno(sync_fp), LOCK_UN);
19216081Sedward #else
19315207Sedward (void) unlink(sync_lock);
19416081Sedward #endif
19525934Sedward (void) signal(SIGHUP, sighup);
19625934Sedward (void) signal(SIGINT, sigint);
19716081Sedward return erred ? -1 : 0;
19815207Sedward }
19915207Sedward
sync_update(type,ship,a,b,c,d)20015207Sedward sync_update(type, ship, a, b, c, d)
20118249Sedward int type;
20218249Sedward register struct ship *ship;
20318249Sedward int a, b, c, d;
20415207Sedward {
20515207Sedward switch (type) {
20615207Sedward case W_DBP: {
20715207Sedward register struct BP *p = &ship->file->DBP[a];
20815207Sedward p->turnsent = b;
20915207Sedward p->toship = SHIP(c);
21015207Sedward p->mensent = d;
21115207Sedward break;
21215207Sedward }
21315207Sedward case W_OBP: {
21415207Sedward register struct BP *p = &ship->file->OBP[a];
21515207Sedward p->turnsent = b;
21615207Sedward p->toship = SHIP(c);
21715207Sedward p->mensent = d;
21815207Sedward break;
21915207Sedward }
22015207Sedward case W_FOUL: {
22115723Sedward register struct snag *p = &ship->file->foul[a];
22215723Sedward if (SHIP(a)->file->dir == 0)
22315723Sedward break;
22415723Sedward if (p->sn_count++ == 0)
22515723Sedward p->sn_turn = turn;
22615723Sedward ship->file->nfoul++;
22715207Sedward break;
22815207Sedward }
22915207Sedward case W_GRAP: {
23015723Sedward register struct snag *p = &ship->file->grap[a];
23115723Sedward if (SHIP(a)->file->dir == 0)
23215723Sedward break;
23315723Sedward if (p->sn_count++ == 0)
23415723Sedward p->sn_turn = turn;
23515723Sedward ship->file->ngrap++;
23615207Sedward break;
23715207Sedward }
23815723Sedward case W_UNFOUL: {
23915723Sedward register struct snag *p = &ship->file->foul[a];
24015723Sedward if (p->sn_count > 0)
24115723Sedward if (b) {
24215723Sedward ship->file->nfoul -= p->sn_count;
24315723Sedward p->sn_count = 0;
24415723Sedward } else {
24515723Sedward ship->file->nfoul--;
24615723Sedward p->sn_count--;
24715723Sedward }
24815723Sedward break;
24915723Sedward }
25015723Sedward case W_UNGRAP: {
25115723Sedward register struct snag *p = &ship->file->grap[a];
25215723Sedward if (p->sn_count > 0)
25315723Sedward if (b) {
25415723Sedward ship->file->ngrap -= p->sn_count;
25515723Sedward p->sn_count = 0;
25615723Sedward } else {
25715723Sedward ship->file->ngrap--;
25815723Sedward p->sn_count--;
25915723Sedward }
26015723Sedward break;
26115723Sedward }
26215207Sedward case W_SIGNAL:
26318249Sedward if (mode == MODE_PLAYER)
26418670Sedward if (nobells)
26518670Sedward Signal("%s (%c%c): %s", ship, a);
26618670Sedward else
26718670Sedward Signal("\7%s (%c%c): %s", ship, a);
26815207Sedward break;
26915207Sedward case W_CREW: {
27015207Sedward register struct shipspecs *s = ship->specs;
27115207Sedward s->crew1 = a;
27215207Sedward s->crew2 = b;
27315207Sedward s->crew3 = c;
27415207Sedward break;
27515207Sedward }
27615207Sedward case W_CAPTAIN:
27715207Sedward (void) strncpy(ship->file->captain, (char *)a,
27815207Sedward sizeof ship->file->captain - 1);
27915207Sedward ship->file->captain[sizeof ship->file->captain - 1] = 0;
28015207Sedward break;
28115207Sedward case W_CAPTURED:
28215315Sedward if (a < 0)
28315315Sedward ship->file->captured = 0;
28415315Sedward else
28515315Sedward ship->file->captured = SHIP(a);
28615207Sedward break;
28715207Sedward case W_CLASS:
28815207Sedward ship->specs->class = a;
28915207Sedward break;
29015207Sedward case W_DRIFT:
29115207Sedward ship->file->drift = a;
29215207Sedward break;
29315207Sedward case W_EXPLODE:
29415207Sedward if ((ship->file->explode = a) == 2)
29515207Sedward ship->file->dir = 0;
29615207Sedward break;
29715207Sedward case W_FS:
29815207Sedward ship->file->FS = a;
29915207Sedward break;
30015207Sedward case W_GUNL: {
30115207Sedward register struct shipspecs *s = ship->specs;
30215207Sedward s->gunL = a;
30315207Sedward s->carL = b;
30415207Sedward break;
30515207Sedward }
30615207Sedward case W_GUNR: {
30715207Sedward register struct shipspecs *s = ship->specs;
30815207Sedward s->gunR = a;
30915207Sedward s->carR = b;
31015207Sedward break;
31115207Sedward }
31215207Sedward case W_HULL:
31315207Sedward ship->specs->hull = a;
31415207Sedward break;
31515723Sedward case W_MOVE:
31615723Sedward (void) strncpy(ship->file->movebuf, (char *)a,
31715723Sedward sizeof ship->file->movebuf - 1);
31815723Sedward ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
31915207Sedward break;
32015207Sedward case W_PCREW:
32115207Sedward ship->file->pcrew = a;
32215207Sedward break;
32315207Sedward case W_POINTS:
32415207Sedward ship->file->points = a;
32515207Sedward break;
32615207Sedward case W_QUAL:
32715207Sedward ship->specs->qual = a;
32815207Sedward break;
32915207Sedward case W_RIGG: {
33015207Sedward register struct shipspecs *s = ship->specs;
33115207Sedward s->rig1 = a;
33215207Sedward s->rig2 = b;
33315207Sedward s->rig3 = c;
33415207Sedward s->rig4 = d;
33515207Sedward break;
33615207Sedward }
33715207Sedward case W_RIG1:
33815207Sedward ship->specs->rig1 = a;
33915207Sedward break;
34015207Sedward case W_RIG2:
34115207Sedward ship->specs->rig2 = a;
34215207Sedward break;
34315207Sedward case W_RIG3:
34415207Sedward ship->specs->rig3 = a;
34515207Sedward break;
34615207Sedward case W_RIG4:
34715207Sedward ship->specs->rig4 = a;
34815207Sedward break;
34915723Sedward case W_COL:
35015207Sedward ship->file->col = a;
35115207Sedward break;
35215723Sedward case W_DIR:
35315207Sedward ship->file->dir = a;
35415207Sedward break;
35515723Sedward case W_ROW:
35615207Sedward ship->file->row = a;
35715207Sedward break;
35815207Sedward case W_SINK:
35915207Sedward if ((ship->file->sink = a) == 2)
36015207Sedward ship->file->dir = 0;
36115207Sedward break;
36215207Sedward case W_STRUCK:
36315207Sedward ship->file->struck = a;
36415207Sedward break;
36515207Sedward case W_TA:
36615207Sedward ship->specs->ta = a;
36715207Sedward break;
36815207Sedward case W_ALIVE:
36915207Sedward alive = 1;
37015207Sedward break;
37115207Sedward case W_TURN:
37215207Sedward turn = a;
37315207Sedward break;
37415207Sedward case W_WIND:
37515207Sedward winddir = a;
37615207Sedward windspeed = b;
37715207Sedward break;
37815207Sedward case W_BEGIN:
37915207Sedward (void) strcpy(ship->file->captain, "begin");
38015207Sedward people++;
38115207Sedward break;
38215207Sedward case W_END:
38316081Sedward *ship->file->captain = 0;
38416081Sedward ship->file->points = 0;
38515207Sedward people--;
38615207Sedward break;
38716081Sedward case W_DDEAD:
38816081Sedward hasdriver = 0;
38916081Sedward break;
39015207Sedward default:
39116081Sedward fprintf(stderr, "sync_update: unknown type %d\r\n", type);
39216081Sedward return -1;
39315207Sedward }
39416081Sedward return 0;
39515207Sedward }
396