118706Sedward /* 221248Sdist * Copyright (c) 1983 Regents of the University of California. 3*33695Sbostic * All rights reserved. 4*33695Sbostic * 5*33695Sbostic * Redistribution and use in source and binary forms are permitted 6*33695Sbostic * provided that this notice is preserved and that due credit is given 7*33695Sbostic * to the University of California at Berkeley. The name of the University 8*33695Sbostic * may not be used to endorse or promote products derived from this 9*33695Sbostic * software without specific prior written permission. This software 10*33695Sbostic * is provided ``as is'' without express or implied warranty. 1118706Sedward */ 1218706Sedward 1315207Sedward #ifndef lint 14*33695Sbostic static char sccsid[] = "@(#)sync.c 5.3 (Berkeley) 03/09/88"; 15*33695Sbostic #endif /* not lint */ 1615207Sedward 1715207Sedward #include "externs.h" 1816081Sedward #include <sys/file.h> 1916081Sedward #include <sys/errno.h> 2015207Sedward 2118249Sedward #define BUFSIZE 4096 2218249Sedward 2315207Sedward static char sync_buf[BUFSIZE]; 2415901Sedward static char *sync_bp = sync_buf; 2515207Sedward static char sync_lock[25]; 2615207Sedward static char sync_file[25]; 2715207Sedward static long sync_seek; 2815207Sedward static FILE *sync_fp; 2915207Sedward #define SF "/tmp/#sailsink.%d" 3015207Sedward #define LF "/tmp/#saillock.%d" 3115207Sedward 3215207Sedward /*VARARGS3*/ 3315207Sedward makesignal(from, fmt, ship, a, b, c) 3418249Sedward struct ship *from; 3518249Sedward char *fmt; 3618249Sedward register struct ship *ship; 3715207Sedward { 3815207Sedward char message[80]; 3915207Sedward 4015207Sedward if (ship == 0) 4115207Sedward (void) sprintf(message, fmt, a, b, c); 4215207Sedward else 4315207Sedward (void) sprintf(message, fmt, 4415207Sedward ship->shipname, colours(ship), 4515207Sedward sterncolour(ship), a, b, c); 4615207Sedward Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0); 4715207Sedward } 4815207Sedward 4915312Sedward #include <sys/types.h> 5015312Sedward #include <sys/stat.h> 5115207Sedward sync_exists(game) 5215207Sedward { 5315207Sedward char buf[sizeof sync_file]; 5415312Sedward struct stat s; 5515312Sedward time_t t; 5615207Sedward 5715207Sedward (void) sprintf(buf, SF, game); 5815723Sedward (void) time(&t); 5915312Sedward if (stat(buf, &s) < 0) 6015312Sedward return 0; 6115312Sedward if (s.st_mtime < t - 60*60*2) { /* 2 hours */ 6215723Sedward (void) unlink(buf); 6316081Sedward (void) sprintf(buf, LF, game); 6416081Sedward (void) unlink(buf); 6515312Sedward return 0; 6615312Sedward } else 6715312Sedward return 1; 6815207Sedward } 6915207Sedward 7015207Sedward sync_open() 7115207Sedward { 7218590Sedward if (sync_fp != NULL) 7318590Sedward (void) fclose(sync_fp); 7418590Sedward (void) sprintf(sync_lock, LF, game); 7518590Sedward (void) sprintf(sync_file, SF, game); 7618590Sedward if (access(sync_file, 0) < 0) { 7718590Sedward int omask = umask(issetuid ? 077 : 011); 7818590Sedward sync_fp = fopen(sync_file, "w+"); 7918590Sedward (void) umask(omask); 8018590Sedward } else 8118590Sedward sync_fp = fopen(sync_file, "r+"); 8218590Sedward if (sync_fp == NULL) 8318590Sedward return -1; 8425934Sedward sync_seek = 0; 8515249Sedward return 0; 8615207Sedward } 8715207Sedward 8815207Sedward sync_close(remove) 8918249Sedward char remove; 9015207Sedward { 9115352Sedward if (sync_fp != 0) 9215352Sedward (void) fclose(sync_fp); 9315207Sedward if (remove) 9415207Sedward (void) unlink(sync_file); 9515207Sedward } 9615207Sedward 9715207Sedward Write(type, ship, isstr, a, b, c, d) 9818249Sedward int type; 9918249Sedward struct ship *ship; 10018249Sedward char isstr; 10118249Sedward int a, b, c, d; 10215207Sedward { 10315207Sedward if (isstr) 10415901Sedward (void) sprintf(sync_bp, "%d %d %d %s\n", 10515723Sedward type, ship->file->index, isstr, a); 10615207Sedward else 10715901Sedward (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n", 10815723Sedward type, ship->file->index, isstr, a, b, c, d); 10915901Sedward while (*sync_bp++) 11015207Sedward ; 11115901Sedward sync_bp--; 11215901Sedward if (sync_bp >= &sync_buf[sizeof sync_buf]) 11315207Sedward abort(); 11416081Sedward (void) sync_update(type, ship, a, b, c, d); 11515207Sedward } 11615207Sedward 11715207Sedward Sync() 11815207Sedward { 11925934Sedward int (*sighup)(), (*sigint)(); 12016425Sedward register n; 12115207Sedward int type, shipnum, isstr, a, b, c, d; 12216081Sedward char buf[80]; 12316081Sedward char erred = 0; 12416081Sedward extern errno; 12515207Sedward 12625934Sedward sighup = signal(SIGHUP, SIG_IGN); 12725934Sedward sigint = signal(SIGINT, SIG_IGN); 12816425Sedward for (n = TIMEOUT; --n >= 0;) { 12916081Sedward #ifdef LOCK_EX 13016081Sedward if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0) 13116081Sedward break; 13216081Sedward if (errno != EWOULDBLOCK) 13316081Sedward return -1; 13416081Sedward #else 13516081Sedward if (link(sync_file, sync_lock) >= 0) 13616081Sedward break; 13716081Sedward if (errno != EEXIST) 13816081Sedward return -1; 13916081Sedward #endif 14016425Sedward sleep(1); 14116081Sedward } 14216425Sedward if (n <= 0) 14316081Sedward return -1; 14415207Sedward (void) fseek(sync_fp, sync_seek, 0); 14516081Sedward for (;;) { 14616081Sedward switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) { 14716081Sedward case 3: 14816081Sedward break; 14916081Sedward case EOF: 15016081Sedward goto out; 15116081Sedward default: 15216081Sedward goto bad; 15316081Sedward } 15416081Sedward if (shipnum < 0 || shipnum >= cc->vessels) 15516081Sedward goto bad; 15616081Sedward if (isstr != 0 && isstr != 1) 15716081Sedward goto bad; 15815207Sedward if (isstr) { 15916081Sedward register char *p; 16015207Sedward for (p = buf;;) { 16115207Sedward switch (*p++ = getc(sync_fp)) { 16215207Sedward case '\n': 16315207Sedward p--; 16415207Sedward case EOF: 16515207Sedward break; 16615207Sedward default: 16716081Sedward if (p >= buf + sizeof buf) 16816081Sedward p--; 16915207Sedward continue; 17015207Sedward } 17115207Sedward break; 17215207Sedward } 17315207Sedward *p = 0; 17415207Sedward for (p = buf; *p == ' '; p++) 17515207Sedward ; 17615207Sedward a = (int)p; 17715207Sedward b = c = d = 0; 17815207Sedward } else 17916081Sedward if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4) 18016081Sedward goto bad; 18116081Sedward if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0) 18216081Sedward goto bad; 18315207Sedward } 18416081Sedward bad: 18516081Sedward erred++; 18616081Sedward out: 18716081Sedward if (!erred && sync_bp != sync_buf) { 18815207Sedward (void) fseek(sync_fp, 0L, 2); 18925934Sedward (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf, 19025934Sedward sync_fp); 19115207Sedward (void) fflush(sync_fp); 19215901Sedward sync_bp = sync_buf; 19315207Sedward } 19415207Sedward sync_seek = ftell(sync_fp); 19516081Sedward #ifdef LOCK_EX 19616081Sedward (void) flock(fileno(sync_fp), LOCK_UN); 19716081Sedward #else 19815207Sedward (void) unlink(sync_lock); 19916081Sedward #endif 20025934Sedward (void) signal(SIGHUP, sighup); 20125934Sedward (void) signal(SIGINT, sigint); 20216081Sedward return erred ? -1 : 0; 20315207Sedward } 20415207Sedward 20515207Sedward sync_update(type, ship, a, b, c, d) 20618249Sedward int type; 20718249Sedward register struct ship *ship; 20818249Sedward int a, b, c, d; 20915207Sedward { 21015207Sedward switch (type) { 21115207Sedward case W_DBP: { 21215207Sedward register struct BP *p = &ship->file->DBP[a]; 21315207Sedward p->turnsent = b; 21415207Sedward p->toship = SHIP(c); 21515207Sedward p->mensent = d; 21615207Sedward break; 21715207Sedward } 21815207Sedward case W_OBP: { 21915207Sedward register struct BP *p = &ship->file->OBP[a]; 22015207Sedward p->turnsent = b; 22115207Sedward p->toship = SHIP(c); 22215207Sedward p->mensent = d; 22315207Sedward break; 22415207Sedward } 22515207Sedward case W_FOUL: { 22615723Sedward register struct snag *p = &ship->file->foul[a]; 22715723Sedward if (SHIP(a)->file->dir == 0) 22815723Sedward break; 22915723Sedward if (p->sn_count++ == 0) 23015723Sedward p->sn_turn = turn; 23115723Sedward ship->file->nfoul++; 23215207Sedward break; 23315207Sedward } 23415207Sedward case W_GRAP: { 23515723Sedward register struct snag *p = &ship->file->grap[a]; 23615723Sedward if (SHIP(a)->file->dir == 0) 23715723Sedward break; 23815723Sedward if (p->sn_count++ == 0) 23915723Sedward p->sn_turn = turn; 24015723Sedward ship->file->ngrap++; 24115207Sedward break; 24215207Sedward } 24315723Sedward case W_UNFOUL: { 24415723Sedward register struct snag *p = &ship->file->foul[a]; 24515723Sedward if (p->sn_count > 0) 24615723Sedward if (b) { 24715723Sedward ship->file->nfoul -= p->sn_count; 24815723Sedward p->sn_count = 0; 24915723Sedward } else { 25015723Sedward ship->file->nfoul--; 25115723Sedward p->sn_count--; 25215723Sedward } 25315723Sedward break; 25415723Sedward } 25515723Sedward case W_UNGRAP: { 25615723Sedward register struct snag *p = &ship->file->grap[a]; 25715723Sedward if (p->sn_count > 0) 25815723Sedward if (b) { 25915723Sedward ship->file->ngrap -= p->sn_count; 26015723Sedward p->sn_count = 0; 26115723Sedward } else { 26215723Sedward ship->file->ngrap--; 26315723Sedward p->sn_count--; 26415723Sedward } 26515723Sedward break; 26615723Sedward } 26715207Sedward case W_SIGNAL: 26818249Sedward if (mode == MODE_PLAYER) 26918670Sedward if (nobells) 27018670Sedward Signal("%s (%c%c): %s", ship, a); 27118670Sedward else 27218670Sedward Signal("\7%s (%c%c): %s", ship, a); 27315207Sedward break; 27415207Sedward case W_CREW: { 27515207Sedward register struct shipspecs *s = ship->specs; 27615207Sedward s->crew1 = a; 27715207Sedward s->crew2 = b; 27815207Sedward s->crew3 = c; 27915207Sedward break; 28015207Sedward } 28115207Sedward case W_CAPTAIN: 28215207Sedward (void) strncpy(ship->file->captain, (char *)a, 28315207Sedward sizeof ship->file->captain - 1); 28415207Sedward ship->file->captain[sizeof ship->file->captain - 1] = 0; 28515207Sedward break; 28615207Sedward case W_CAPTURED: 28715315Sedward if (a < 0) 28815315Sedward ship->file->captured = 0; 28915315Sedward else 29015315Sedward ship->file->captured = SHIP(a); 29115207Sedward break; 29215207Sedward case W_CLASS: 29315207Sedward ship->specs->class = a; 29415207Sedward break; 29515207Sedward case W_DRIFT: 29615207Sedward ship->file->drift = a; 29715207Sedward break; 29815207Sedward case W_EXPLODE: 29915207Sedward if ((ship->file->explode = a) == 2) 30015207Sedward ship->file->dir = 0; 30115207Sedward break; 30215207Sedward case W_FS: 30315207Sedward ship->file->FS = a; 30415207Sedward break; 30515207Sedward case W_GUNL: { 30615207Sedward register struct shipspecs *s = ship->specs; 30715207Sedward s->gunL = a; 30815207Sedward s->carL = b; 30915207Sedward break; 31015207Sedward } 31115207Sedward case W_GUNR: { 31215207Sedward register struct shipspecs *s = ship->specs; 31315207Sedward s->gunR = a; 31415207Sedward s->carR = b; 31515207Sedward break; 31615207Sedward } 31715207Sedward case W_HULL: 31815207Sedward ship->specs->hull = a; 31915207Sedward break; 32015723Sedward case W_MOVE: 32115723Sedward (void) strncpy(ship->file->movebuf, (char *)a, 32215723Sedward sizeof ship->file->movebuf - 1); 32315723Sedward ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0; 32415207Sedward break; 32515207Sedward case W_PCREW: 32615207Sedward ship->file->pcrew = a; 32715207Sedward break; 32815207Sedward case W_POINTS: 32915207Sedward ship->file->points = a; 33015207Sedward break; 33115207Sedward case W_QUAL: 33215207Sedward ship->specs->qual = a; 33315207Sedward break; 33415207Sedward case W_RIGG: { 33515207Sedward register struct shipspecs *s = ship->specs; 33615207Sedward s->rig1 = a; 33715207Sedward s->rig2 = b; 33815207Sedward s->rig3 = c; 33915207Sedward s->rig4 = d; 34015207Sedward break; 34115207Sedward } 34215207Sedward case W_RIG1: 34315207Sedward ship->specs->rig1 = a; 34415207Sedward break; 34515207Sedward case W_RIG2: 34615207Sedward ship->specs->rig2 = a; 34715207Sedward break; 34815207Sedward case W_RIG3: 34915207Sedward ship->specs->rig3 = a; 35015207Sedward break; 35115207Sedward case W_RIG4: 35215207Sedward ship->specs->rig4 = a; 35315207Sedward break; 35415723Sedward case W_COL: 35515207Sedward ship->file->col = a; 35615207Sedward break; 35715723Sedward case W_DIR: 35815207Sedward ship->file->dir = a; 35915207Sedward break; 36015723Sedward case W_ROW: 36115207Sedward ship->file->row = a; 36215207Sedward break; 36315207Sedward case W_SINK: 36415207Sedward if ((ship->file->sink = a) == 2) 36515207Sedward ship->file->dir = 0; 36615207Sedward break; 36715207Sedward case W_STRUCK: 36815207Sedward ship->file->struck = a; 36915207Sedward break; 37015207Sedward case W_TA: 37115207Sedward ship->specs->ta = a; 37215207Sedward break; 37315207Sedward case W_ALIVE: 37415207Sedward alive = 1; 37515207Sedward break; 37615207Sedward case W_TURN: 37715207Sedward turn = a; 37815207Sedward break; 37915207Sedward case W_WIND: 38015207Sedward winddir = a; 38115207Sedward windspeed = b; 38215207Sedward break; 38315207Sedward case W_BEGIN: 38415207Sedward (void) strcpy(ship->file->captain, "begin"); 38515207Sedward people++; 38615207Sedward break; 38715207Sedward case W_END: 38816081Sedward *ship->file->captain = 0; 38916081Sedward ship->file->points = 0; 39015207Sedward people--; 39115207Sedward break; 39216081Sedward case W_DDEAD: 39316081Sedward hasdriver = 0; 39416081Sedward break; 39515207Sedward default: 39616081Sedward fprintf(stderr, "sync_update: unknown type %d\r\n", type); 39716081Sedward return -1; 39815207Sedward } 39916081Sedward return 0; 40015207Sedward } 401