]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - sail/sync.c
Include <time.h> in various places in the games where time() or time_t
[bsdgames-darwin.git] / sail / sync.c
1 /* $NetBSD: sync.c,v 1.13 1999/09/09 17:30:20 jsm Exp $ */
2
3 /*
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95";
40 #else
41 __RCSID("$NetBSD: sync.c,v 1.13 1999/09/09 17:30:20 jsm Exp $");
42 #endif
43 #endif /* not lint */
44
45 #include <fcntl.h>
46 #include <errno.h>
47 #ifdef __STDC__
48 #include <stdarg.h>
49 #else
50 #include <varargs.h>
51 #endif
52 #include <stdlib.h>
53 #include <unistd.h>
54 #include <sys/types.h>
55 #include <sys/stat.h>
56 #include <time.h>
57 #include "extern.h"
58
59 #define BUFSIZE 4096
60
61 static char sync_buf[BUFSIZE];
62 static char *sync_bp = sync_buf;
63 static char sync_lock[25];
64 static char sync_file[25];
65 static long sync_seek;
66 static FILE *sync_fp;
67 #define SF "/tmp/#sailsink.%d"
68 #define LF "/tmp/#saillock.%d"
69
70 void
71 fmtship(buf, len, fmt, ship)
72 char *buf;
73 size_t len;
74 const char *fmt;
75 struct ship *ship;
76 {
77 while (*fmt) {
78 if (len-- == 0) {
79 *buf = '\0';
80 return;
81 }
82 if (*fmt == '$' && fmt[1] == '$') {
83 size_t l = snprintf(buf, len, "%s (%c%c)",
84 ship->shipname, colours(ship), sterncolour(ship));
85 buf += l;
86 len -= l - 1;
87 fmt += 2;
88 }
89 else
90 *buf++ = *fmt++;
91 }
92
93 if (len > 0)
94 *buf = '\0';
95 }
96
97
98 /*VARARGS3*/
99 void
100 #ifdef __STDC__
101 makesignal(struct ship *from, const char *fmt, struct ship *ship, ...)
102 #else
103 makesignal(va_alias)
104 va_dcl
105 #endif
106 {
107 char message[BUFSIZ];
108 char format[BUFSIZ];
109 va_list ap;
110 #ifndef __STDC__
111 struct ship *from;
112 const char *fmt;
113 struct ship *ship;
114
115 va_start(ap);
116 from = va_arg(ap, struct ship *);
117 fmt = va_arg(ap, const char *);
118 ship = va_arg(ap, struct ship *);
119 #else
120 va_start(ap, ship);
121 #endif
122 fmtship(format, sizeof(format), fmt, ship);
123 (void) vsprintf(message, format, ap);
124 va_end(ap);
125 Writestr(W_SIGNAL, from, message);
126 }
127
128 void
129 #ifdef __STDC__
130 makemsg(struct ship *from, const char *fmt, ...)
131 #else
132 makemsg(va_alias)
133 va_dcl
134 #endif
135 {
136 char message[BUFSIZ];
137 va_list ap;
138 #ifndef __STDC__
139 struct ship *from;
140 const char *fmt;
141
142 va_start(ap);
143 from = va_arg(ap, struct ship *);
144 fmt = va_arg(ap, const char *);
145 #else
146 va_start(ap, fmt);
147 #endif
148 (void) vsprintf(message, fmt, ap);
149 va_end(ap);
150 Writestr(W_SIGNAL, from, message);
151 }
152
153 int
154 sync_exists(game)
155 int game;
156 {
157 char buf[sizeof sync_file];
158 struct stat s;
159 time_t t;
160
161 (void) sprintf(buf, SF, game);
162 (void) time(&t);
163 if (stat(buf, &s) < 0)
164 return 0;
165 if (s.st_mtime < t - 60*60*2) { /* 2 hours */
166 (void) unlink(buf);
167 (void) sprintf(buf, LF, game);
168 (void) unlink(buf);
169 return 0;
170 } else
171 return 1;
172 }
173
174 int
175 sync_open()
176 {
177 if (sync_fp != NULL)
178 (void) fclose(sync_fp);
179 (void) sprintf(sync_lock, LF, game);
180 (void) sprintf(sync_file, SF, game);
181 if (access(sync_file, 0) < 0) {
182 int omask = umask(issetuid ? 077 : 011);
183 sync_fp = fopen(sync_file, "w+");
184 (void) umask(omask);
185 } else
186 sync_fp = fopen(sync_file, "r+");
187 if (sync_fp == NULL)
188 return -1;
189 sync_seek = 0;
190 return 0;
191 }
192
193 void
194 sync_close(remove)
195 char remove;
196 {
197 if (sync_fp != 0)
198 (void) fclose(sync_fp);
199 if (remove)
200 (void) unlink(sync_file);
201 }
202
203 void
204 Write(type, ship, a, b, c, d)
205 int type;
206 struct ship *ship;
207 long a, b, c, d;
208 {
209
210 (void) sprintf(sync_bp, "%d %d 0 %ld %ld %ld %ld\n",
211 type, ship->file->index, a, b, c, d);
212 while (*sync_bp++)
213 ;
214 sync_bp--;
215 if (sync_bp >= &sync_buf[sizeof sync_buf])
216 abort();
217 (void) sync_update(type, ship, NULL, a, b, c, d);
218 }
219
220 void
221 Writestr(type, ship, a)
222 int type;
223 struct ship *ship;
224 const char *a;
225 {
226
227 (void) sprintf(sync_bp, "%d %d 1 %s\n",
228 type, ship->file->index, a);
229 while (*sync_bp++)
230 ;
231 sync_bp--;
232 if (sync_bp >= &sync_buf[sizeof sync_buf])
233 abort();
234 (void) sync_update(type, ship, a, 0, 0, 0, 0);
235 }
236
237 int
238 Sync()
239 {
240 sig_t sighup, sigint;
241 int n;
242 int type, shipnum, isstr;
243 char *astr;
244 long a, b, c, d;
245 char buf[80];
246 char erred = 0;
247
248 sighup = signal(SIGHUP, SIG_IGN);
249 sigint = signal(SIGINT, SIG_IGN);
250 for (n = TIMEOUT; --n >= 0;) {
251 #ifdef LOCK_EX
252 if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0)
253 break;
254 if (errno != EWOULDBLOCK)
255 return -1;
256 #else
257 if (link(sync_file, sync_lock) >= 0)
258 break;
259 if (errno != EEXIST)
260 return -1;
261 #endif
262 sleep(1);
263 }
264 if (n <= 0)
265 return -1;
266 (void) fseek(sync_fp, sync_seek, SEEK_SET);
267 for (;;) {
268 switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) {
269 case 3:
270 break;
271 case EOF:
272 goto out;
273 default:
274 goto bad;
275 }
276 if (shipnum < 0 || shipnum >= cc->vessels)
277 goto bad;
278 if (isstr != 0 && isstr != 1)
279 goto bad;
280 if (isstr) {
281 char *p;
282 for (p = buf;;) {
283 switch (*p++ = getc(sync_fp)) {
284 case '\n':
285 p--;
286 case EOF:
287 break;
288 default:
289 if (p >= buf + sizeof buf)
290 p--;
291 continue;
292 }
293 break;
294 }
295 *p = 0;
296 for (p = buf; *p == ' '; p++)
297 ;
298 astr = p;
299 a = b = c = d = 0;
300 } else {
301 if (fscanf(sync_fp, "%ld%ld%ld%ld", &a, &b, &c, &d) != 4)
302 goto bad;
303 astr = NULL;
304 }
305 if (sync_update(type, SHIP(shipnum), astr, a, b, c, d) < 0)
306 goto bad;
307 }
308 bad:
309 erred++;
310 out:
311 if (!erred && sync_bp != sync_buf) {
312 (void) fseek(sync_fp, 0L, SEEK_END);
313 (void) fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf,
314 sync_fp);
315 (void) fflush(sync_fp);
316 sync_bp = sync_buf;
317 }
318 sync_seek = ftell(sync_fp);
319 #ifdef LOCK_EX
320 (void) flock(fileno(sync_fp), LOCK_UN);
321 #else
322 (void) unlink(sync_lock);
323 #endif
324 (void) signal(SIGHUP, sighup);
325 (void) signal(SIGINT, sigint);
326 return erred ? -1 : 0;
327 }
328
329 int
330 sync_update(type, ship, astr, a, b, c, d)
331 int type;
332 struct ship *ship;
333 const char *astr;
334 long a, b, c, d;
335 {
336 switch (type) {
337 case W_DBP: {
338 struct BP *p = &ship->file->DBP[a];
339 p->turnsent = b;
340 p->toship = SHIP(c);
341 p->mensent = d;
342 break;
343 }
344 case W_OBP: {
345 struct BP *p = &ship->file->OBP[a];
346 p->turnsent = b;
347 p->toship = SHIP(c);
348 p->mensent = d;
349 break;
350 }
351 case W_FOUL: {
352 struct snag *p = &ship->file->foul[a];
353 if (SHIP(a)->file->dir == 0)
354 break;
355 if (p->sn_count++ == 0)
356 p->sn_turn = turn;
357 ship->file->nfoul++;
358 break;
359 }
360 case W_GRAP: {
361 struct snag *p = &ship->file->grap[a];
362 if (SHIP(a)->file->dir == 0)
363 break;
364 if (p->sn_count++ == 0)
365 p->sn_turn = turn;
366 ship->file->ngrap++;
367 break;
368 }
369 case W_UNFOUL: {
370 struct snag *p = &ship->file->foul[a];
371 if (p->sn_count > 0) {
372 if (b) {
373 ship->file->nfoul -= p->sn_count;
374 p->sn_count = 0;
375 } else {
376 ship->file->nfoul--;
377 p->sn_count--;
378 }
379 }
380 break;
381 }
382 case W_UNGRAP: {
383 struct snag *p = &ship->file->grap[a];
384 if (p->sn_count > 0) {
385 if (b) {
386 ship->file->ngrap -= p->sn_count;
387 p->sn_count = 0;
388 } else {
389 ship->file->ngrap--;
390 p->sn_count--;
391 }
392 }
393 break;
394 }
395 case W_SIGNAL:
396 if (mode == MODE_PLAYER) {
397 if (nobells)
398 Signal("$$: %s", ship, astr);
399 else
400 Signal("\7$$: %s", ship, astr);
401 }
402 break;
403 case W_CREW: {
404 struct shipspecs *s = ship->specs;
405 s->crew1 = a;
406 s->crew2 = b;
407 s->crew3 = c;
408 break;
409 }
410 case W_CAPTAIN:
411 (void) strncpy(ship->file->captain, astr,
412 sizeof ship->file->captain - 1);
413 ship->file->captain[sizeof ship->file->captain - 1] = 0;
414 break;
415 case W_CAPTURED:
416 if (a < 0)
417 ship->file->captured = 0;
418 else
419 ship->file->captured = SHIP(a);
420 break;
421 case W_CLASS:
422 ship->specs->class = a;
423 break;
424 case W_DRIFT:
425 ship->file->drift = a;
426 break;
427 case W_EXPLODE:
428 if ((ship->file->explode = a) == 2)
429 ship->file->dir = 0;
430 break;
431 case W_FS:
432 ship->file->FS = a;
433 break;
434 case W_GUNL: {
435 struct shipspecs *s = ship->specs;
436 s->gunL = a;
437 s->carL = b;
438 break;
439 }
440 case W_GUNR: {
441 struct shipspecs *s = ship->specs;
442 s->gunR = a;
443 s->carR = b;
444 break;
445 }
446 case W_HULL:
447 ship->specs->hull = a;
448 break;
449 case W_MOVE:
450 (void) strncpy(ship->file->movebuf, astr,
451 sizeof ship->file->movebuf - 1);
452 ship->file->movebuf[sizeof ship->file->movebuf - 1] = 0;
453 break;
454 case W_PCREW:
455 ship->file->pcrew = a;
456 break;
457 case W_POINTS:
458 ship->file->points = a;
459 break;
460 case W_QUAL:
461 ship->specs->qual = a;
462 break;
463 case W_RIGG: {
464 struct shipspecs *s = ship->specs;
465 s->rig1 = a;
466 s->rig2 = b;
467 s->rig3 = c;
468 s->rig4 = d;
469 break;
470 }
471 case W_RIG1:
472 ship->specs->rig1 = a;
473 break;
474 case W_RIG2:
475 ship->specs->rig2 = a;
476 break;
477 case W_RIG3:
478 ship->specs->rig3 = a;
479 break;
480 case W_RIG4:
481 ship->specs->rig4 = a;
482 break;
483 case W_COL:
484 ship->file->col = a;
485 break;
486 case W_DIR:
487 ship->file->dir = a;
488 break;
489 case W_ROW:
490 ship->file->row = a;
491 break;
492 case W_SINK:
493 if ((ship->file->sink = a) == 2)
494 ship->file->dir = 0;
495 break;
496 case W_STRUCK:
497 ship->file->struck = a;
498 break;
499 case W_TA:
500 ship->specs->ta = a;
501 break;
502 case W_ALIVE:
503 alive = 1;
504 break;
505 case W_TURN:
506 turn = a;
507 break;
508 case W_WIND:
509 winddir = a;
510 windspeed = b;
511 break;
512 case W_BEGIN:
513 (void) strcpy(ship->file->captain, "begin");
514 people++;
515 break;
516 case W_END:
517 *ship->file->captain = 0;
518 ship->file->points = 0;
519 people--;
520 break;
521 case W_DDEAD:
522 hasdriver = 0;
523 break;
524 default:
525 fprintf(stderr, "sync_update: unknown type %d\r\n", type);
526 return -1;
527 }
528 return 0;
529 }