1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)sync.c	5.2 (Berkeley) 1/21/86";
   9: #endif not lint
  10: 
  11: #include "externs.h"
  12: #include <sys/file.h>
  13: #include <sys/errno.h>
  14: 
  15: #define BUFSIZE 4096
  16: 
  17: static char sync_buf[BUFSIZE];
  18: static char *sync_bp = sync_buf;
  19: static char sync_lock[25];
  20: static char sync_file[25];
  21: static long sync_seek;
  22: static FILE *sync_fp;
  23: #define SF "/tmp/#sailsink.%d"
  24: #define LF "/tmp/#saillock.%d"
  25: 
  26: /*VARARGS3*/
  27: makesignal(from, fmt, ship, a, b, c)
  28:     struct ship *from;
  29:     char *fmt;
  30:     register struct ship *ship;
  31: {
  32:     char message[80];
  33: 
  34:     if (ship == 0)
  35:         (void) sprintf(message, fmt, a, b, c);
  36:     else
  37:         (void) sprintf(message, fmt,
  38:             ship->shipname, colours(ship),
  39:             sterncolour(ship), a, b, c);
  40:     Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
  41: }
  42: 
  43: #include <sys/types.h>
  44: #include <sys/stat.h>
  45: sync_exists(game)
  46: {
  47:     char buf[sizeof sync_file];
  48:     struct stat s;
  49:     time_t t;
  50: 
  51:     (void) sprintf(buf, SF, game);
  52:     (void) time(&t);
  53:     if (stat(buf, &s) < 0)
  54:         return 0;
  55:     if (s.st_mtime < t - 60*60*2) {     /* 2 hours */
  56:         (void) unlink(buf);
  57:         (void) sprintf(buf, LF, game);
  58:         (void) unlink(buf);
  59:         return 0;
  60:     } else
  61:         return 1;
  62: }
  63: 
  64: sync_open()
  65: {
  66:     if (sync_fp != NULL)
  67:         (void) fclose(sync_fp);
  68:     (void) sprintf(sync_lock, LF, game);
  69:     (void) sprintf(sync_file, SF, game);
  70:     if (access(sync_file, 0) < 0) {
  71:         int omask = umask(issetuid ? 077 : 011);
  72:         sync_fp = fopen(sync_file, "w+");
  73:         (void) umask(omask);
  74:     } else
  75:         sync_fp = fopen(sync_file, "r+");
  76:     if (sync_fp == NULL)
  77:         return -1;
  78:     sync_seek = 0;
  79:     return 0;
  80: }
  81: 
  82: sync_close(remove)
  83:     char remove;
  84: {
  85:     if (sync_fp != 0)
  86:         (void) fclose(sync_fp);
  87:     if (remove)
  88:         (void) unlink(sync_file);
  89: }
  90: 
  91: Write(type, ship, isstr, a, b, c, d)
  92:     int type;
  93:     struct ship *ship;
  94:     char isstr;
  95:     int a, b, c, d;
  96: {
  97:     if (isstr)
  98:         (void) sprintf(sync_bp, "%d %d %d %s\n",
  99:             type, ship->file->index, isstr, a);
 100:     else
 101:         (void) sprintf(sync_bp, "%d %d %d %d %d %d %d\n",
 102:             type, ship->file->index, isstr, a, b, c, d);
 103:     while (*sync_bp++)
 104:         ;
 105:     sync_bp--;
 106:     if (sync_bp >= &sync_buf[sizeof sync_buf])
 107:         abort();
 108:     (void) sync_update(type, ship, a, b, c, d);
 109: }
 110: 
 111: Sync()
 112: {
 113:     int (*sighup)(), (*sigint)();
 114:     register n;
 115:     int type, shipnum, isstr, a, b, c, d;
 116:     char buf[80];
 117:     char erred = 0;
 118:     extern errno;
 119: 
 120:     sighup = signal(SIGHUP, SIG_IGN);
 121:     sigint = signal(SIGINT, SIG_IGN);
 122:     for (n = TIMEOUT; --n >= 0;) {
 123: #ifdef LOCK_EX
 124:         if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
 125:             break;
 126:         if (errno != EWOULDBLOCK)
 127:             return -1;
 128: #else
 129:         if (link(sync_file, sync_lock) >= 0)
 130:             break;
 131:         if (errno != EEXIST)
 132:             return -1;
 133: #endif
 134:         sleep(1);
 135:     }
 136:     if (n <= 0)
 137:         return -1;
 138:     (void) fseek(sync_fp, sync_seek, 0);
 139:     for (;;) {
 140:         switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
 141:         case 3:
 142:             break;
 143:         case EOF:
 144:             goto out;
 145:         default:
 146:             goto bad;
 147:         }
 148:         if (shipnum < 0 || shipnum >= cc->vessels)
 149:             goto bad;
 150:         if (isstr != 0 && isstr != 1)
 151:             goto bad;
 152:         if (isstr) {
 153:             register char *p;
 154:             for (p = buf;;) {
 155:                 switch (*p++ = getc(sync_fp)) {
 156:                 case '\n':
 157:                     p--;
 158:                 case EOF:
 159:                     break;
 160:                 default:
 161:                     if (p >= buf + sizeof buf)
 162:                         p--;
 163:                     continue;
 164:                 }
 165:                 break;
 166:             }
 167:             *p = 0;
 168:             for (p = buf; *p == ' '; p++)
 169:                 ;
 170:             a = (int)p;
 171:             b = c = d = 0;
 172:         } else
 173:             if (fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d) != 4)
 174:                 goto bad;
 175:         if (sync_update(type, SHIP(shipnum), a, b, c, d) < 0)
 176:             goto bad;
 177:     }
 178: bad:
 179:     erred++;
 180: out:
 181:     if (!erred && sync_bp != sync_buf) {
 182:         (void) fseek(sync_fp, 0L, 2);
 183:         (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
 184:             sync_fp);
 185:         (void) fflush(sync_fp);
 186:         sync_bp = sync_buf;
 187:     }
 188:     sync_seek = ftell(sync_fp);
 189: #ifdef LOCK_EX
 190:     (void) flock(fileno(sync_fp), LOCK_UN);
 191: #else
 192:     (void) unlink(sync_lock);
 193: #endif
 194:     (void) signal(SIGHUP, sighup);
 195:     (void) signal(SIGINT, sigint);
 196:     return erred ? -1 : 0;
 197: }
 198: 
 199: sync_update(type, ship, a, b, c, d)
 200:     int type;
 201:     register struct ship *ship;
 202:     int a, b, c, d;
 203: {
 204:     switch (type) {
 205:     case W_DBP: {
 206:         register struct BP *p = &ship->file->DBP[a];
 207:         p->turnsent = b;
 208:         p->toship = SHIP(c);
 209:         p->mensent = d;
 210:         break;
 211:         }
 212:     case W_OBP: {
 213:         register struct BP *p = &ship->file->OBP[a];
 214:         p->turnsent = b;
 215:         p->toship = SHIP(c);
 216:         p->mensent = d;
 217:         break;
 218:         }
 219:     case W_FOUL: {
 220:         register struct snag *p = &ship->file->foul[a];
 221:         if (SHIP(a)->file->dir == 0)
 222:             break;
 223:         if (p->sn_count++ == 0)
 224:             p->sn_turn = turn;
 225:         ship->file->nfoul++;
 226:         break;
 227:         }
 228:     case W_GRAP: {
 229:         register struct snag *p = &ship->file->grap[a];
 230:         if (SHIP(a)->file->dir == 0)
 231:             break;
 232:         if (p->sn_count++ == 0)
 233:             p->sn_turn = turn;
 234:         ship->file->ngrap++;
 235:         break;
 236:         }
 237:     case W_UNFOUL: {
 238:         register struct snag *p = &ship->file->foul[a];
 239:         if (p->sn_count > 0)
 240:             if (b) {
 241:                 ship->file->nfoul -= p->sn_count;
 242:                 p->sn_count = 0;
 243:             } else {
 244:                 ship->file->nfoul--;
 245:                 p->sn_count--;
 246:             }
 247:         break;
 248:         }
 249:     case W_UNGRAP: {
 250:         register struct snag *p = &ship->file->grap[a];
 251:         if (p->sn_count > 0)
 252:             if (b) {
 253:                 ship->file->ngrap -= p->sn_count;
 254:                 p->sn_count = 0;
 255:             } else {
 256:                 ship->file->ngrap--;
 257:                 p->sn_count--;
 258:             }
 259:         break;
 260:         }
 261:     case W_SIGNAL:
 262:         if (mode == MODE_PLAYER)
 263:             if (nobells)
 264:                 Signal("%s (%c%c): %s", ship, a);
 265:             else
 266:                 Signal("\7%s (%c%c): %s", ship, a);
 267:         break;
 268:     case W_CREW: {
 269:         register struct shipspecs *s = ship->specs;
 270:         s->crew1 = a;
 271:         s->crew2 = b;
 272:         s->crew3 = c;
 273:         break;
 274:         }
 275:     case W_CAPTAIN:
 276:         (void) strncpy(ship->file->captain, (char *)a,
 277:             sizeof ship->file->captain - 1);
 278:         ship->file->captain[sizeof ship->file->captain - 1] = 0;
 279:         break;
 280:     case W_CAPTURED:
 281:         if (a < 0)
 282:             ship->file->captured = 0;
 283:         else
 284:             ship->file->captured = SHIP(a);
 285:         break;
 286:     case W_CLASS:
 287:         ship->specs->class = a;
 288:         break;
 289:     case W_DRIFT:
 290:         ship->file->drift = a;
 291:         break;
 292:     case W_EXPLODE:
 293:         if ((ship->file->explode = a) == 2)
 294:             ship->file->dir = 0;
 295:         break;
 296:     case W_FS:
 297:         ship->file->FS = a;
 298:         break;
 299:     case W_GUNL: {
 300:         register struct shipspecs *s = ship->specs;
 301:         s->gunL = a;
 302:         s->carL = b;
 303:         break;
 304:         }
 305:     case W_GUNR: {
 306:         register struct shipspecs *s = ship->specs;
 307:         s->gunR = a;
 308:         s->carR = b;
 309:         break;
 310:         }
 311:     case W_HULL:
 312:         ship->specs->hull = a;
 313:         break;
 314:     case W_MOVE:
 315:         (void) strncpy(ship->file->movebuf, (char *)a,
 316:             sizeof ship->file->movebuf - 1);
 317:         ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
 318:         break;
 319:     case W_PCREW:
 320:         ship->file->pcrew = a;
 321:         break;
 322:     case W_POINTS:
 323:         ship->file->points = a;
 324:         break;
 325:     case W_QUAL:
 326:         ship->specs->qual = a;
 327:         break;
 328:     case W_RIGG: {
 329:         register struct shipspecs *s = ship->specs;
 330:         s->rig1 = a;
 331:         s->rig2 = b;
 332:         s->rig3 = c;
 333:         s->rig4 = d;
 334:         break;
 335:         }
 336:     case W_RIG1:
 337:         ship->specs->rig1 = a;
 338:         break;
 339:     case W_RIG2:
 340:         ship->specs->rig2 = a;
 341:         break;
 342:     case W_RIG3:
 343:         ship->specs->rig3 = a;
 344:         break;
 345:     case W_RIG4:
 346:         ship->specs->rig4 = a;
 347:         break;
 348:     case W_COL:
 349:         ship->file->col = a;
 350:         break;
 351:     case W_DIR:
 352:         ship->file->dir = a;
 353:         break;
 354:     case W_ROW:
 355:         ship->file->row = a;
 356:         break;
 357:     case W_SINK:
 358:         if ((ship->file->sink = a) == 2)
 359:             ship->file->dir = 0;
 360:         break;
 361:     case W_STRUCK:
 362:         ship->file->struck = a;
 363:         break;
 364:     case W_TA:
 365:         ship->specs->ta = a;
 366:         break;
 367:     case W_ALIVE:
 368:         alive = 1;
 369:         break;
 370:     case W_TURN:
 371:         turn = a;
 372:         break;
 373:     case W_WIND:
 374:         winddir = a;
 375:         windspeed = b;
 376:         break;
 377:     case W_BEGIN:
 378:         (void) strcpy(ship->file->captain, "begin");
 379:         people++;
 380:         break;
 381:     case W_END:
 382:         *ship->file->captain = 0;
 383:         ship->file->points = 0;
 384:         people--;
 385:         break;
 386:     case W_DDEAD:
 387:         hasdriver = 0;
 388:         break;
 389:     default:
 390:         fprintf(stderr, "sync_update: unknown type %d\r\n", type);
 391:         return -1;
 392:     }
 393:     return 0;
 394: }

Defined functions

sync_exists defined in line 45; used 2 times
sync_open defined in line 64; used 2 times
sync_update defined in line 199; used 2 times

Defined variables

sccsid defined in line 8; never used
sync_bp defined in line 18; used 8 times
sync_buf defined in line 17; used 8 times
sync_file defined in line 20; used 7 times
sync_lock defined in line 19; used 3 times
sync_seek defined in line 21; used 3 times

Defined macros

BUFSIZE defined in line 15; used 1 times
  • in line 17
LF defined in line 24; used 2 times
SF defined in line 23; used 2 times
Last modified: 1986-01-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3947
Valid CSS Valid XHTML 1.0 Strict