1*18706Sedward /* 2*18706Sedward * Copyright (c) 1983 Regents of the University of California, 3*18706Sedward * All rights reserved. Redistribution permitted subject to 4*18706Sedward * the terms of the Berkeley Software License Agreement. 5*18706Sedward */ 6*18706Sedward 715207Sedward #ifndef lint 8*18706Sedward static char *sccsid = "@(#)sync.c 2.10 85/04/23"; 915207Sedward #endif 1015207Sedward 1115207Sedward #include "externs.h" 1216081Sedward #include <sys/file.h> 1316081Sedward #include <sys/errno.h> 1415207Sedward 1518249Sedward #define BUFSIZE 4096 1618249Sedward 1715207Sedward static char sync_buf[BUFSIZE]; 1815901Sedward static char *sync_bp = sync_buf; 1915207Sedward static char sync_lock[25]; 2015207Sedward static char sync_file[25]; 2115207Sedward static long sync_seek; 2215207Sedward static FILE *sync_fp; 2315207Sedward #define SF "/tmp/#sailsink.%d" 2415207Sedward #define LF "/tmp/#saillock.%d" 2515207Sedward 2615207Sedward /*VARARGS3*/ 2715207Sedward makesignal(from, fmt, ship, a, b, c) 2818249Sedward struct ship *from; 2918249Sedward char *fmt; 3018249Sedward register struct ship *ship; 3115207Sedward { 3215207Sedward char message[80]; 3315207Sedward 3415207Sedward if (ship == 0) 3515207Sedward (void) sprintf(message, fmt, a, b, c); 3615207Sedward else 3715207Sedward (void) sprintf(message, fmt, 3815207Sedward ship->shipname, colours(ship), 3915207Sedward sterncolour(ship), a, b, c); 4015207Sedward Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0); 4115207Sedward } 4215207Sedward 4315312Sedward #include <sys/types.h> 4415312Sedward #include <sys/stat.h> 4515207Sedward sync_exists(game) 4615207Sedward { 4715207Sedward char buf[sizeof sync_file]; 4815312Sedward struct stat s; 4915312Sedward time_t t; 5015207Sedward 5115207Sedward (void) sprintf(buf, SF, game); 5215723Sedward (void) time(&t); 5315312Sedward if (stat(buf, &s) < 0) 5415312Sedward return 0; 5515312Sedward if (s.st_mtime < t - 60*60*2) { /* 2 hours */ 5615723Sedward (void) unlink(buf); 5716081Sedward (void) sprintf(buf, LF, game); 5816081Sedward (void) unlink(buf); 5915312Sedward return 0; 6015312Sedward } else 6115312Sedward return 1; 6215207Sedward } 6315207Sedward 6415207Sedward sync_open() 6515207Sedward { 6618590Sedward if (sync_fp != NULL) 6718590Sedward (void) fclose(sync_fp); 6818590Sedward (void) sprintf(sync_lock, LF, game); 6918590Sedward (void) sprintf(sync_file, SF, game); 7018590Sedward if (access(sync_file, 0) < 0) { 7118590Sedward int omask = umask(issetuid ? 077 : 011); 7218590Sedward sync_fp = fopen(sync_file, "w+"); 7318590Sedward (void) umask(omask); 7418590Sedward } else 7518590Sedward sync_fp = fopen(sync_file, "r+"); 7618590Sedward if (sync_fp == NULL) 7718590Sedward return -1; 7815207Sedward sync_seek == 0; 7915249Sedward return 0; 8015207Sedward } 8115207Sedward 8215207Sedward sync_close(remove) 8318249Sedward char remove; 8415207Sedward { 8515352Sedward if (sync_fp != 0) 8615352Sedward (void) fclose(sync_fp); 8715207Sedward if (remove) 8815207Sedward (void) unlink(sync_file); 8915207Sedward } 9015207Sedward 9115207Sedward Write(type, ship, isstr, a, b, c, d) 9218249Sedward int type; 9318249Sedward struct ship *ship; 9418249Sedward char isstr; 9518249Sedward int a, b, c, d; 9615207Sedward { 9715207Sedward if (isstr) 9815901Sedward (void) sprintf(sync_bp, "%d %d %d %s\n", 9915723Sedward type, ship->file->index, isstr, a); 10015207Sedward else 10115901Sedward (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n", 10215723Sedward type, ship->file->index, isstr, a, b, c, d); 10315901Sedward while (*sync_bp++) 10415207Sedward ; 10515901Sedward sync_bp--; 10615901Sedward if (sync_bp >= &sync_buf[sizeof sync_buf]) 10715207Sedward abort(); 10816081Sedward (void) sync_update(type, ship, a, b, c, d); 10915207Sedward } 11015207Sedward 11115207Sedward Sync() 11215207Sedward { 11315207Sedward int (*sig1)(), (*sig2)(); 11416425Sedward register n; 11515207Sedward int type, shipnum, isstr, a, b, c, d; 11616081Sedward char buf[80]; 11716081Sedward char erred = 0; 11816081Sedward extern errno; 11915207Sedward 12015207Sedward sig1 = signal(SIGHUP, SIG_IGN); 12115207Sedward sig2 = signal(SIGINT, SIG_IGN); 12216425Sedward for (n = TIMEOUT; --n >= 0;) { 12316081Sedward #ifdef LOCK_EX 12416081Sedward if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0) 12516081Sedward break; 12616081Sedward if (errno != EWOULDBLOCK) 12716081Sedward return -1; 12816081Sedward #else 12916081Sedward if (link(sync_file, sync_lock) >= 0) 13016081Sedward break; 13116081Sedward if (errno != EEXIST) 13216081Sedward return -1; 13316081Sedward #endif 13416425Sedward sleep(1); 13516081Sedward } 13616425Sedward if (n <= 0) 13716081Sedward return -1; 13815207Sedward (void) fseek(sync_fp, sync_seek, 0); 13916081Sedward for (;;) { 14016081Sedward switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) { 14116081Sedward case 3: 14216081Sedward break; 14316081Sedward case EOF: 14416081Sedward goto out; 14516081Sedward default: 14616081Sedward goto bad; 14716081Sedward } 14816081Sedward if (shipnum < 0 || shipnum >= cc->vessels) 14916081Sedward goto bad; 15016081Sedward if (isstr != 0 && isstr != 1) 15116081Sedward goto bad; 15215207Sedward if (isstr) { 15316081Sedward register char *p; 15415207Sedward for (p = buf;;) { 15515207Sedward switch (*p++ = getc(sync_fp)) { 15615207Sedward case '\n': 15715207Sedward p--; 15815207Sedward case EOF: 15915207Sedward break; 16015207Sedward default: 16116081Sedward if (p >= buf + sizeof buf) 16216081Sedward p--; 16315207Sedward continue; 16415207Sedward } 16515207Sedward break; 16615207Sedward } 16715207Sedward *p = 0; 16815207Sedward for (p = buf; *p == ' '; p++) 16915207Sedward ; 17015207Sedward a = (int)p; 17115207Sedward b = c = d = 0; 17215207Sedward } else 17316081Sedward if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4) 17416081Sedward goto bad; 17516081Sedward if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0) 17616081Sedward goto bad; 17715207Sedward } 17816081Sedward bad: 17916081Sedward erred++; 18016081Sedward out: 18116081Sedward if (!erred && sync_bp != sync_buf) { 18215207Sedward (void) fseek(sync_fp, 0L, 2); 18315207Sedward (void) fputs(sync_buf, sync_fp); 18415207Sedward (void) fflush(sync_fp); 18515901Sedward sync_bp = sync_buf; 18615207Sedward } 18715207Sedward sync_seek = ftell(sync_fp); 18816081Sedward #ifdef LOCK_EX 18916081Sedward (void) flock(fileno(sync_fp), LOCK_UN); 19016081Sedward #else 19115207Sedward (void) unlink(sync_lock); 19216081Sedward #endif 19315207Sedward (void) signal(SIGHUP, sig1); 19415207Sedward (void) signal(SIGINT, sig2); 19516081Sedward return erred ? -1 : 0; 19615207Sedward } 19715207Sedward 19815207Sedward sync_update(type, ship, a, b, c, d) 19918249Sedward int type; 20018249Sedward register struct ship *ship; 20118249Sedward int a, b, c, d; 20215207Sedward { 20315207Sedward switch (type) { 20415207Sedward case W_DBP: { 20515207Sedward register struct BP *p = &ship->file->DBP[a]; 20615207Sedward p->turnsent = b; 20715207Sedward p->toship = SHIP(c); 20815207Sedward p->mensent = d; 20915207Sedward break; 21015207Sedward } 21115207Sedward case W_OBP: { 21215207Sedward register struct BP *p = &ship->file->OBP[a]; 21315207Sedward p->turnsent = b; 21415207Sedward p->toship = SHIP(c); 21515207Sedward p->mensent = d; 21615207Sedward break; 21715207Sedward } 21815207Sedward case W_FOUL: { 21915723Sedward register struct snag *p = &ship->file->foul[a]; 22015723Sedward if (SHIP(a)->file->dir == 0) 22115723Sedward break; 22215723Sedward if (p->sn_count++ == 0) 22315723Sedward p->sn_turn = turn; 22415723Sedward ship->file->nfoul++; 22515207Sedward break; 22615207Sedward } 22715207Sedward case W_GRAP: { 22815723Sedward register struct snag *p = &ship->file->grap[a]; 22915723Sedward if (SHIP(a)->file->dir == 0) 23015723Sedward break; 23115723Sedward if (p->sn_count++ == 0) 23215723Sedward p->sn_turn = turn; 23315723Sedward ship->file->ngrap++; 23415207Sedward break; 23515207Sedward } 23615723Sedward case W_UNFOUL: { 23715723Sedward register struct snag *p = &ship->file->foul[a]; 23815723Sedward if (p->sn_count > 0) 23915723Sedward if (b) { 24015723Sedward ship->file->nfoul -= p->sn_count; 24115723Sedward p->sn_count = 0; 24215723Sedward } else { 24315723Sedward ship->file->nfoul--; 24415723Sedward p->sn_count--; 24515723Sedward } 24615723Sedward break; 24715723Sedward } 24815723Sedward case W_UNGRAP: { 24915723Sedward register struct snag *p = &ship->file->grap[a]; 25015723Sedward if (p->sn_count > 0) 25115723Sedward if (b) { 25215723Sedward ship->file->ngrap -= p->sn_count; 25315723Sedward p->sn_count = 0; 25415723Sedward } else { 25515723Sedward ship->file->ngrap--; 25615723Sedward p->sn_count--; 25715723Sedward } 25815723Sedward break; 25915723Sedward } 26015207Sedward case W_SIGNAL: 26118249Sedward if (mode == MODE_PLAYER) 26218670Sedward if (nobells) 26318670Sedward Signal("%s (%c%c): %s", ship, a); 26418670Sedward else 26518670Sedward Signal("\7%s (%c%c): %s", ship, a); 26615207Sedward break; 26715207Sedward case W_CREW: { 26815207Sedward register struct shipspecs *s = ship->specs; 26915207Sedward s->crew1 = a; 27015207Sedward s->crew2 = b; 27115207Sedward s->crew3 = c; 27215207Sedward break; 27315207Sedward } 27415207Sedward case W_CAPTAIN: 27515207Sedward (void) strncpy(ship->file->captain, (char *)a, 27615207Sedward sizeof ship->file->captain - 1); 27715207Sedward ship->file->captain[sizeof ship->file->captain - 1] = 0; 27815207Sedward break; 27915207Sedward case W_CAPTURED: 28015315Sedward if (a < 0) 28115315Sedward ship->file->captured = 0; 28215315Sedward else 28315315Sedward ship->file->captured = SHIP(a); 28415207Sedward break; 28515207Sedward case W_CLASS: 28615207Sedward ship->specs->class = a; 28715207Sedward break; 28815207Sedward case W_DRIFT: 28915207Sedward ship->file->drift = a; 29015207Sedward break; 29115207Sedward case W_EXPLODE: 29215207Sedward if ((ship->file->explode = a) == 2) 29315207Sedward ship->file->dir = 0; 29415207Sedward break; 29515207Sedward case W_FS: 29615207Sedward ship->file->FS = a; 29715207Sedward break; 29815207Sedward case W_GUNL: { 29915207Sedward register struct shipspecs *s = ship->specs; 30015207Sedward s->gunL = a; 30115207Sedward s->carL = b; 30215207Sedward break; 30315207Sedward } 30415207Sedward case W_GUNR: { 30515207Sedward register struct shipspecs *s = ship->specs; 30615207Sedward s->gunR = a; 30715207Sedward s->carR = b; 30815207Sedward break; 30915207Sedward } 31015207Sedward case W_HULL: 31115207Sedward ship->specs->hull = a; 31215207Sedward break; 31315723Sedward case W_MOVE: 31415723Sedward (void) strncpy(ship->file->movebuf, (char *)a, 31515723Sedward sizeof ship->file->movebuf - 1); 31615723Sedward ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0; 31715207Sedward break; 31815207Sedward case W_PCREW: 31915207Sedward ship->file->pcrew = a; 32015207Sedward break; 32115207Sedward case W_POINTS: 32215207Sedward ship->file->points = a; 32315207Sedward break; 32415207Sedward case W_QUAL: 32515207Sedward ship->specs->qual = a; 32615207Sedward break; 32715207Sedward case W_RIGG: { 32815207Sedward register struct shipspecs *s = ship->specs; 32915207Sedward s->rig1 = a; 33015207Sedward s->rig2 = b; 33115207Sedward s->rig3 = c; 33215207Sedward s->rig4 = d; 33315207Sedward break; 33415207Sedward } 33515207Sedward case W_RIG1: 33615207Sedward ship->specs->rig1 = a; 33715207Sedward break; 33815207Sedward case W_RIG2: 33915207Sedward ship->specs->rig2 = a; 34015207Sedward break; 34115207Sedward case W_RIG3: 34215207Sedward ship->specs->rig3 = a; 34315207Sedward break; 34415207Sedward case W_RIG4: 34515207Sedward ship->specs->rig4 = a; 34615207Sedward break; 34715723Sedward case W_COL: 34815207Sedward ship->file->col = a; 34915207Sedward break; 35015723Sedward case W_DIR: 35115207Sedward ship->file->dir = a; 35215207Sedward break; 35315723Sedward case W_ROW: 35415207Sedward ship->file->row = a; 35515207Sedward break; 35615207Sedward case W_SINK: 35715207Sedward if ((ship->file->sink = a) == 2) 35815207Sedward ship->file->dir = 0; 35915207Sedward break; 36015207Sedward case W_STRUCK: 36115207Sedward ship->file->struck = a; 36215207Sedward break; 36315207Sedward case W_TA: 36415207Sedward ship->specs->ta = a; 36515207Sedward break; 36615207Sedward case W_ALIVE: 36715207Sedward alive = 1; 36815207Sedward break; 36915207Sedward case W_TURN: 37015207Sedward turn = a; 37115207Sedward break; 37215207Sedward case W_WIND: 37315207Sedward winddir = a; 37415207Sedward windspeed = b; 37515207Sedward break; 37615207Sedward case W_BEGIN: 37715207Sedward (void) strcpy(ship->file->captain, "begin"); 37815207Sedward people++; 37915207Sedward break; 38015207Sedward case W_END: 38116081Sedward *ship->file->captain = 0; 38216081Sedward ship->file->points = 0; 38315207Sedward people--; 38415207Sedward break; 38516081Sedward case W_DDEAD: 38616081Sedward hasdriver = 0; 38716081Sedward break; 38815207Sedward default: 38916081Sedward fprintf(stderr, "sync_update: unknown type %d\r\n", type); 39016081Sedward return -1; 39115207Sedward } 39216081Sedward return 0; 39315207Sedward } 394