check sync_fp before calling fclose().
[unix-history] / usr / src / games / sail / sync.c
CommitLineData
15e30c53 1#ifndef lint
7cd3d9ac 2static char *sccsid = "@(#)sync.c 2.2 83/11/01";
15e30c53
EW
3#endif
4
5#include "externs.h"
6
7static char sync_buf[BUFSIZE];
8static char *sync_bufp = sync_buf;
9static char sync_lock[25];
10static char sync_file[25];
11static long sync_seek;
12static FILE *sync_fp;
13#define SF "/tmp/#sailsink.%d"
14#define LF "/tmp/#saillock.%d"
15
16/*VARARGS3*/
17makesignal(from, fmt, ship, a, b, c)
18struct ship *from;
19char *fmt;
20register struct ship *ship;
21{
22 char message[80];
23
24 if (ship == 0)
25 (void) sprintf(message, fmt, a, b, c);
26 else
27 (void) sprintf(message, fmt,
28 ship->shipname, colours(ship),
29 sterncolour(ship), a, b, c);
30 Write(W_SIGNAL, from, 1, (int)message, 0, 0, 0);
31}
32
30d1a80b
EW
33#include <sys/types.h>
34#include <sys/stat.h>
15e30c53
EW
35sync_exists(game)
36{
37 char buf[sizeof sync_file];
30d1a80b
EW
38 struct stat s;
39 time_t t;
15e30c53
EW
40
41 (void) sprintf(buf, SF, game);
30d1a80b
EW
42 time(&t);
43 if (stat(buf, &s) < 0)
44 return 0;
45 if (s.st_mtime < t - 60*60*2) { /* 2 hours */
46 unlink(buf);
47 return 0;
48 } else
49 return 1;
15e30c53
EW
50}
51
52sync_open()
53{
54 (void) sprintf(sync_lock, LF, game);
55 (void) sprintf(sync_file, SF, game);
56 if (access(sync_file, 0) < 0) {
57 int omask;
58#ifdef SETUID
59 omask = umask(077);
60#else
61 omask = umask(011);
62#endif
63 sync_fp = fopen(sync_file, "w+");
64 (void) umask(omask);
65 } else
66 sync_fp = fopen(sync_file, "r+");
67 if (sync_fp == 0)
68 return -1;
69 sync_seek == 0;
9224751f 70 return 0;
15e30c53
EW
71}
72
73sync_close(remove)
74char remove;
75{
7cd3d9ac
EW
76 if (sync_fp != 0)
77 (void) fclose(sync_fp);
15e30c53
EW
78 if (remove)
79 (void) unlink(sync_file);
80}
81
82Write(type, ship, isstr, a, b, c, d)
83int type;
84struct ship *ship;
85char isstr;
86int a, b, c, d;
87{
88 if (isstr)
89 (void) sprintf(sync_bufp, "%d %d %d %s\n",
90 type, ship-SHIP(0), isstr, a);
91 else
92 (void) sprintf(sync_bufp, "%d %d %d %d %d %d %d\n",
93 type, ship-SHIP(0), isstr, a, b, c, d);
94 while (*sync_bufp++)
95 ;
96 sync_bufp--;
97 if (sync_bufp >= &sync_buf[sizeof sync_buf])
98 abort();
99 sync_update(type, ship, a, b, c, d);
100}
101
102Sync()
103{
104 int (*sig1)(), (*sig2)();
105 int type, shipnum, isstr, a, b, c, d;
106 char buf[60];
107 register char *p = buf;
108 int n;
109
110 sig1 = signal(SIGHUP, SIG_IGN);
111 sig2 = signal(SIGINT, SIG_IGN);
112 for (n = 0; link(sync_file, sync_lock) < 0 && n < 30; n++)
113 sleep(2);
114 (void) fseek(sync_fp, sync_seek, 0);
115 while (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr) != EOF) {
116 if (isstr) {
117 for (p = buf;;) {
118 switch (*p++ = getc(sync_fp)) {
119 case '\n':
120 p--;
121 case EOF:
122 break;
123 default:
124 continue;
125 }
126 break;
127 }
128 *p = 0;
129 for (p = buf; *p == ' '; p++)
130 ;
131 a = (int)p;
132 b = c = d = 0;
133 } else
134 (void) fscanf(sync_fp, "%d%d%d%d", &a, &b, &c, &d);
135 sync_update(type, SHIP(shipnum), a, b, c, d);
136 }
137 if (sync_bufp != sync_buf) {
138 (void) fseek(sync_fp, 0L, 2);
139 (void) fputs(sync_buf, sync_fp);
140 (void) fflush(sync_fp);
141 sync_bufp = sync_buf;
142 }
143 sync_seek = ftell(sync_fp);
144 (void) unlink(sync_lock);
145 (void) signal(SIGHUP, sig1);
146 (void) signal(SIGINT, sig2);
147}
148
149sync_update(type, ship, a, b, c, d)
150int type;
151register struct ship *ship;
152int a, b, c, d;
153{
154 switch (type) {
155 case W_DBP: {
156 register struct BP *p = &ship->file->DBP[a];
157 p->turnsent = b;
158 p->toship = SHIP(c);
159 p->mensent = d;
160 break;
161 }
162 case W_OBP: {
163 register struct BP *p = &ship->file->OBP[a];
164 p->turnsent = b;
165 p->toship = SHIP(c);
166 p->mensent = d;
167 break;
168 }
169 case W_FOUL: {
170 register struct snag *p = &ship->file->fouls[a];
171 p->turnfoul = b;
172 p->toship = SHIP(c);
173 break;
174 }
175 case W_GRAP: {
176 register struct snag *p = &ship->file->grapples[a];
177 p->turnfoul = b;
178 p->toship = SHIP(c);
179 break;
180 }
181 case W_SIGNAL:
0f5fabce 182 if (isplayer) {
fe0cae24 183 Signal("\7%s (%c%c): %s", ship, a);
0f5fabce 184 }
15e30c53
EW
185 break;
186 case W_CREW: {
187 register struct shipspecs *s = ship->specs;
188 s->crew1 = a;
189 s->crew2 = b;
190 s->crew3 = c;
191 break;
192 }
193 case W_CAPTAIN:
194 (void) strncpy(ship->file->captain, (char *)a,
195 sizeof ship->file->captain - 1);
196 ship->file->captain[sizeof ship->file->captain - 1] = 0;
197 break;
198 case W_CAPTURED:
66e5ed8a
EW
199 if (a < 0)
200 ship->file->captured = 0;
201 else
202 ship->file->captured = SHIP(a);
15e30c53
EW
203 break;
204 case W_CLASS:
205 ship->specs->class = a;
206 break;
207 case W_DRIFT:
208 ship->file->drift = a;
209 break;
210 case W_EXPLODE:
211 if ((ship->file->explode = a) == 2)
212 ship->file->dir = 0;
213 break;
214 case W_FS:
215 ship->file->FS = a;
216 break;
217 case W_GUNL: {
218 register struct shipspecs *s = ship->specs;
219 s->gunL = a;
220 s->carL = b;
221 break;
222 }
223 case W_GUNR: {
224 register struct shipspecs *s = ship->specs;
225 s->gunR = a;
226 s->carR = b;
227 break;
228 }
229 case W_HULL:
230 ship->specs->hull = a;
231 break;
232 case W_LAST:
233 (void) strncpy(ship->file->last, (char *)a,
234 sizeof ship->file->last - 1);
235 ship->file->last[sizeof ship->file->last - 1] = 0;
236 break;
237 case W_PCREW:
238 ship->file->pcrew = a;
239 break;
240 case W_POINTS:
241 ship->file->points = a;
242 break;
243 case W_QUAL:
244 ship->specs->qual = a;
245 break;
246 case W_RIGG: {
247 register struct shipspecs *s = ship->specs;
248 s->rig1 = a;
249 s->rig2 = b;
250 s->rig3 = c;
251 s->rig4 = d;
252 break;
253 }
254 case W_RIG1:
255 ship->specs->rig1 = a;
256 break;
257 case W_RIG2:
258 ship->specs->rig2 = a;
259 break;
260 case W_RIG3:
261 ship->specs->rig3 = a;
262 break;
263 case W_RIG4:
264 ship->specs->rig4 = a;
265 break;
266 case W_SHIPCOL:
267 ship->file->col = a;
268 break;
269 case W_SHIPDIR:
270 ship->file->dir = a;
271 break;
272 case W_SHIPROW:
273 ship->file->row = a;
274 break;
275 case W_SINK:
276 if ((ship->file->sink = a) == 2)
277 ship->file->dir = 0;
278 break;
279 case W_STRUCK:
280 ship->file->struck = a;
281 break;
282 case W_TA:
283 ship->specs->ta = a;
284 break;
285 case W_ALIVE:
286 alive = 1;
287 break;
288 case W_TURN:
289 turn = a;
290 break;
291 case W_WIND:
292 winddir = a;
293 windspeed = b;
294 break;
295 case W_BEGIN:
296 (void) strcpy(ship->file->captain, "begin");
297 people++;
298 break;
299 case W_END:
300 (void) strcpy(ship->file->captain, "");
301 people--;
302 break;
303 default:
304 fprintf(stderr, "sync_update: unknown type %d\n", type);
305 break;
306 }
307}