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