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