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