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