home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / sail / part02 / sync.c < prev   
C/C++ Source or Header  |  1988-04-13  |  8KB  |  401 lines

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