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