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