]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - sail/sync.c
1 /* $NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $ */
4 * Copyright (c) 1983, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95";
37 __RCSID("$NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $");
54 #include "pathnames.h"
66 /* W_FILE 8 not used */
100 static void recv_captain(struct ship
*ship
, const char *astr
);
101 static void recv_captured(struct ship
*ship
, long a
);
102 static void recv_class(struct ship
*ship
, long a
);
103 static void recv_crew(struct ship
*ship
, long a
, long b
, long c
);
104 static void recv_dbp(struct ship
*ship
, long a
, long b
, long c
, long d
);
105 static void recv_drift(struct ship
*ship
, long a
);
106 static void recv_explode(struct ship
*ship
, long a
);
107 static void recv_foul(struct ship
*ship
, long a
);
108 static void recv_gunl(struct ship
*ship
, long a
, long b
);
109 static void recv_gunr(struct ship
*ship
, long a
, long b
);
110 static void recv_hull(struct ship
*ship
, long a
);
111 static void recv_move(struct ship
*ship
, const char *astr
);
112 static void recv_obp(struct ship
*ship
, long a
, long b
, long c
, long d
);
113 static void recv_pcrew(struct ship
*ship
, long a
);
114 static void recv_unfoul(struct ship
*ship
, long a
, long b
);
115 static void recv_points(struct ship
*ship
, long a
);
116 static void recv_qual(struct ship
*ship
, long a
);
117 static void recv_ungrap(struct ship
*ship
, long a
, long b
);
118 static void recv_rigg(struct ship
*ship
, long a
, long b
, long c
, long d
);
119 static void recv_col(struct ship
*ship
, long a
);
120 static void recv_dir(struct ship
*ship
, long a
);
121 static void recv_row(struct ship
*ship
, long a
);
122 static void recv_signal(struct ship
*ship
, const char *astr
);
123 static void recv_sink(struct ship
*ship
, long a
);
124 static void recv_struck(struct ship
*ship
, long a
);
125 static void recv_ta(struct ship
*ship
, long a
);
126 static void recv_alive(void);
127 static void recv_turn(long a
);
128 static void recv_wind(long a
, long b
);
129 static void recv_fs(struct ship
*ship
, long a
);
130 static void recv_grap(struct ship
*ship
, long a
);
131 static void recv_rig1(struct ship
*ship
, long a
);
132 static void recv_rig2(struct ship
*ship
, long a
);
133 static void recv_rig3(struct ship
*ship
, long a
);
134 static void recv_rig4(struct ship
*ship
, long a
);
135 static void recv_begin(struct ship
*ship
);
136 static void recv_end(struct ship
*ship
);
137 static void recv_ddead(void);
139 static void Write(int, struct ship
*, long, long, long, long);
140 static void Writestr(int, struct ship
*, const char *);
142 static int sync_update(int, struct ship
*, const char *,
143 long, long, long, long);
145 static char sync_buf
[BUFSIZE
];
146 static char *sync_bp
= sync_buf
;
147 static long sync_seek
;
148 static FILE *sync_fp
;
151 get_sync_file(int scenario_number
)
153 static char sync_file
[NAME_MAX
];
155 snprintf(sync_file
, sizeof(sync_file
), _FILE_SYNC
, scenario_number
);
160 get_lock_file(int scenario_number
)
162 static char sync_lock
[NAME_MAX
];
164 snprintf(sync_lock
, sizeof(sync_lock
), _FILE_LOCK
, scenario_number
);
169 fmtship(char *buf
, size_t len
, const char *fmt
, struct ship
*ship
)
176 if (*fmt
== '$' && fmt
[1] == '$') {
177 size_t l
= snprintf(buf
, len
, "%s (%c%c)",
178 ship
->shipname
, colours(ship
), sterncolour(ship
));
194 makesignal(struct ship
*from
, const char *fmt
, struct ship
*ship
, ...)
196 char message
[BUFSIZ
];
201 fmtship(format
, sizeof(format
), fmt
, ship
);
202 vsnprintf(message
, sizeof(message
), format
, ap
);
204 send_signal(from
, message
);
209 makemsg(struct ship
*from
, const char *fmt
, ...)
211 char message
[BUFSIZ
];
215 vsnprintf(message
, sizeof(message
), fmt
, ap
);
217 send_signal(from
, message
);
221 sync_exists(int gamenum
)
227 path
= get_sync_file(gamenum
);
230 if (stat(path
, &s
) < 0) {
234 if (s
.st_mtime
< t
- 60*60*2) { /* 2 hours */
236 path
= get_lock_file(gamenum
);
249 const char *sync_file
;
254 sync_file
= get_sync_file(game
);
255 (void)get_lock_file(game
);
257 if (stat(sync_file
, &tmp
) < 0) {
258 mode_t omask
= umask(002);
259 sync_fp
= fopen(sync_file
, "w+");
262 sync_fp
= fopen(sync_file
, "r+");
271 sync_close(int doremove
)
273 const char *sync_file
;
278 sync_file
= get_sync_file(game
);
286 Write(int type
, struct ship
*ship
, long a
, long b
, long c
, long d
)
288 size_t max
= sizeof(sync_buf
) - (sync_bp
- sync_buf
);
289 int shipindex
= (ship
== NULL
) ? 0 : ship
->file
->index
;
291 snprintf(sync_bp
, max
, "%d %d 0 %ld %ld %ld %ld\n",
292 type
, shipindex
, a
, b
, c
, d
);
296 if (sync_bp
>= &sync_buf
[sizeof sync_buf
])
298 sync_update(type
, ship
, NULL
, a
, b
, c
, d
);
302 Writestr(int type
, struct ship
*ship
, const char *a
)
304 size_t max
= sizeof(sync_buf
) - (sync_bp
- sync_buf
);
305 int shipindex
= (ship
== NULL
) ? 0 : ship
->file
->index
;
307 snprintf(sync_bp
, max
, "%d %d 1 %s\n", type
, shipindex
, a
);
311 if (sync_bp
>= &sync_buf
[sizeof sync_buf
])
313 sync_update(type
, ship
, a
, 0, 0, 0, 0);
319 sig_t sighup
, sigint
;
321 int type
, shipnum
, isstr
;
327 const char *sync_file
;
328 const char *sync_lock
;
331 sighup
= signal(SIGHUP
, SIG_IGN
);
332 sigint
= signal(SIGINT
, SIG_IGN
);
333 for (n
= TIMEOUT
; --n
>= 0;) {
335 if (flock(fileno(sync_fp
), LOCK_EX
|LOCK_NB
) >= 0)
337 if (errno
!= EWOULDBLOCK
)
340 sync_file
= get_sync_file(game
);
341 sync_lock
= get_lock_file(game
);
343 if (link(sync_file
, sync_lock
) >= 0) {
355 fseek(sync_fp
, sync_seek
, SEEK_SET
);
357 switch (fscanf(sync_fp
, "%d%d%d", &type
, &shipnum
, &isstr
)) {
365 if (shipnum
< 0 || shipnum
>= cc
->vessels
)
367 if (isstr
!= 0 && isstr
!= 1)
382 if (p
>= buf
+ sizeof buf
)
389 for (p
= buf
; *p
== ' '; p
++)
394 if (fscanf(sync_fp
, "%ld%ld%ld%ld", &a
, &b
, &c
, &d
)
399 if (sync_update(type
, SHIP(shipnum
), astr
, a
, b
, c
, d
) < 0)
405 if (!erred
&& sync_bp
!= sync_buf
) {
406 fseek(sync_fp
, 0L, SEEK_END
);
407 fwrite(sync_buf
, sizeof *sync_buf
, sync_bp
- sync_buf
,
412 sync_seek
= ftell(sync_fp
);
414 flock(fileno(sync_fp
), LOCK_UN
);
420 signal(SIGHUP
, sighup
);
421 signal(SIGINT
, sigint
);
422 return erred
? -1 : 0;
426 sync_update(int type
, struct ship
*ship
, const char *astr
,
427 long a
, long b
, long c
, long d
)
430 case W_CAPTAIN
: recv_captain(ship
, astr
); break;
431 case W_CAPTURED
: recv_captured(ship
, a
); break;
432 case W_CLASS
: recv_class(ship
, a
); break;
433 case W_CREW
: recv_crew(ship
, a
, b
, c
); break;
434 case W_DBP
: recv_dbp(ship
, a
, b
, c
, d
); break;
435 case W_DRIFT
: recv_drift(ship
, a
); break;
436 case W_EXPLODE
: recv_explode(ship
, a
); break;
437 case W_FOUL
: recv_foul(ship
, a
); break;
438 case W_GUNL
: recv_gunl(ship
, a
, b
); break;
439 case W_GUNR
: recv_gunr(ship
, a
, b
); break;
440 case W_HULL
: recv_hull(ship
, a
); break;
441 case W_MOVE
: recv_move(ship
, astr
); break;
442 case W_OBP
: recv_obp(ship
, a
, b
, c
, d
); break;
443 case W_PCREW
: recv_pcrew(ship
, a
); break;
444 case W_UNFOUL
: recv_unfoul(ship
, a
, b
); break;
445 case W_POINTS
: recv_points(ship
, a
); break;
446 case W_QUAL
: recv_qual(ship
, a
); break;
447 case W_UNGRAP
: recv_ungrap(ship
, a
, b
); break;
448 case W_RIGG
: recv_rigg(ship
, a
, b
, c
, d
); break;
449 case W_COL
: recv_col(ship
, a
); break;
450 case W_DIR
: recv_dir(ship
, a
); break;
451 case W_ROW
: recv_row(ship
, a
); break;
452 case W_SIGNAL
: recv_signal(ship
, astr
); break;
453 case W_SINK
: recv_sink(ship
, a
); break;
454 case W_STRUCK
: recv_struck(ship
, a
); break;
455 case W_TA
: recv_ta(ship
, a
); break;
456 case W_ALIVE
: recv_alive(); break;
457 case W_TURN
: recv_turn(a
); break;
458 case W_WIND
: recv_wind(a
, b
); break;
459 case W_FS
: recv_fs(ship
, a
); break;
460 case W_GRAP
: recv_grap(ship
, a
); break;
461 case W_RIG1
: recv_rig1(ship
, a
); break;
462 case W_RIG2
: recv_rig2(ship
, a
); break;
463 case W_RIG3
: recv_rig3(ship
, a
); break;
464 case W_RIG4
: recv_rig4(ship
, a
); break;
465 case W_BEGIN
: recv_begin(ship
); break;
466 case W_END
: recv_end(ship
); break;
467 case W_DDEAD
: recv_ddead(); break;
469 fprintf(stderr
, "sync_update: unknown type %d\r\n", type
);
480 send_captain(struct ship
*ship
, const char *astr
)
482 Writestr(W_CAPTAIN
, ship
, astr
);
486 send_captured(struct ship
*ship
, long a
)
488 Write(W_CAPTURED
, ship
, a
, 0, 0, 0);
492 send_class(struct ship
*ship
, long a
)
494 Write(W_CLASS
, ship
, a
, 0, 0, 0);
498 send_crew(struct ship
*ship
, long a
, long b
, long c
)
500 Write(W_CREW
, ship
, a
, b
, c
, 0);
504 send_dbp(struct ship
*ship
, long a
, long b
, long c
, long d
)
506 Write(W_DBP
, ship
, a
, b
, c
, d
);
510 send_drift(struct ship
*ship
, long a
)
512 Write(W_DRIFT
, ship
, a
, 0, 0, 0);
516 send_explode(struct ship
*ship
, long a
)
518 Write(W_EXPLODE
, ship
, a
, 0, 0, 0);
522 send_foul(struct ship
*ship
, long a
)
524 Write(W_FOUL
, ship
, a
, 0, 0, 0);
528 send_gunl(struct ship
*ship
, long a
, long b
)
530 Write(W_GUNL
, ship
, a
, b
, 0, 0);
534 send_gunr(struct ship
*ship
, long a
, long b
)
536 Write(W_GUNR
, ship
, a
, b
, 0, 0);
540 send_hull(struct ship
*ship
, long a
)
542 Write(W_HULL
, ship
, a
, 0, 0, 0);
546 send_move(struct ship
*ship
, const char *astr
)
548 Writestr(W_MOVE
, ship
, astr
);
552 send_obp(struct ship
*ship
, long a
, long b
, long c
, long d
)
554 Write(W_OBP
, ship
, a
, b
, c
, d
);
558 send_pcrew(struct ship
*ship
, long a
)
560 Write(W_PCREW
, ship
, a
, 0, 0, 0);
564 send_unfoul(struct ship
*ship
, long a
, long b
)
566 Write(W_UNFOUL
, ship
, a
, b
, 0, 0);
570 send_points(struct ship
*ship
, long a
)
572 Write(W_POINTS
, ship
, a
, 0, 0, 0);
576 send_qual(struct ship
*ship
, long a
)
578 Write(W_QUAL
, ship
, a
, 0, 0, 0);
582 send_ungrap(struct ship
*ship
, long a
, long b
)
584 Write(W_UNGRAP
, ship
, a
, b
, 0, 0);
588 send_rigg(struct ship
*ship
, long a
, long b
, long c
, long d
)
590 Write(W_RIGG
, ship
, a
, b
, c
, d
);
594 send_col(struct ship
*ship
, long a
)
596 Write(W_COL
, ship
, a
, 0, 0, 0);
600 send_dir(struct ship
*ship
, long a
)
602 Write(W_DIR
, ship
, a
, 0, 0, 0);
606 send_row(struct ship
*ship
, long a
)
608 Write(W_ROW
, ship
, a
, 0, 0, 0);
612 send_signal(struct ship
*ship
, const char *astr
)
614 Writestr(W_SIGNAL
, ship
, astr
);
618 send_sink(struct ship
*ship
, long a
)
620 Write(W_SINK
, ship
, a
, 0, 0, 0);
624 send_struck(struct ship
*ship
, long a
)
626 Write(W_STRUCK
, ship
, a
, 0, 0, 0);
630 send_ta(struct ship
*ship
, long a
)
632 Write(W_TA
, ship
, a
, 0, 0, 0);
638 Write(W_ALIVE
, NULL
, 0, 0, 0, 0);
644 Write(W_TURN
, NULL
, a
, 0, 0, 0);
648 send_wind(long a
, long b
)
650 Write(W_WIND
, NULL
, a
, b
, 0, 0);
654 send_fs(struct ship
*ship
, long a
)
656 Write(W_FS
, ship
, a
, 0, 0, 0);
660 send_grap(struct ship
*ship
, long a
)
662 Write(W_GRAP
, ship
, a
, 0, 0, 0);
666 send_rig1(struct ship
*ship
, long a
)
668 Write(W_RIG1
, ship
, a
, 0, 0, 0);
672 send_rig2(struct ship
*ship
, long a
)
674 Write(W_RIG2
, ship
, a
, 0, 0, 0);
678 send_rig3(struct ship
*ship
, long a
)
680 Write(W_RIG3
, ship
, a
, 0, 0, 0);
684 send_rig4(struct ship
*ship
, long a
)
686 Write(W_RIG4
, ship
, a
, 0, 0, 0);
690 send_begin(struct ship
*ship
)
692 Write(W_BEGIN
, ship
, 0, 0, 0, 0);
696 send_end(struct ship
*ship
)
698 Write(W_END
, ship
, 0, 0, 0, 0);
704 Write(W_DDEAD
, NULL
, 0, 0, 0, 0);
709 * Actions upon message receipt
713 recv_captain(struct ship
*ship
, const char *astr
)
715 strlcpy(ship
->file
->captain
, astr
, sizeof ship
->file
->captain
);
719 recv_captured(struct ship
*ship
, long a
)
722 ship
->file
->captured
= 0;
724 ship
->file
->captured
= SHIP(a
);
728 recv_class(struct ship
*ship
, long a
)
730 ship
->specs
->class = a
;
734 recv_crew(struct ship
*ship
, long a
, long b
, long c
)
736 struct shipspecs
*s
= ship
->specs
;
744 recv_dbp(struct ship
*ship
, long a
, long b
, long c
, long d
)
746 struct BP
*p
= &ship
->file
->DBP
[a
];
754 recv_drift(struct ship
*ship
, long a
)
756 ship
->file
->drift
= a
;
760 recv_explode(struct ship
*ship
, long a
)
762 if ((ship
->file
->explode
= a
) == 2)
767 recv_foul(struct ship
*ship
, long a
)
769 struct snag
*p
= &ship
->file
->foul
[a
];
771 if (SHIP(a
)->file
->dir
== 0)
773 if (p
->sn_count
++ == 0)
779 recv_gunl(struct ship
*ship
, long a
, long b
)
781 struct shipspecs
*s
= ship
->specs
;
788 recv_gunr(struct ship
*ship
, long a
, long b
)
790 struct shipspecs
*s
= ship
->specs
;
797 recv_hull(struct ship
*ship
, long a
)
799 ship
->specs
->hull
= a
;
803 recv_move(struct ship
*ship
, const char *astr
)
805 strlcpy(ship
->file
->movebuf
, astr
, sizeof ship
->file
->movebuf
);
809 recv_obp(struct ship
*ship
, long a
, long b
, long c
, long d
)
811 struct BP
*p
= &ship
->file
->OBP
[a
];
819 recv_pcrew(struct ship
*ship
, long a
)
821 ship
->file
->pcrew
= a
;
825 recv_unfoul(struct ship
*ship
, long a
, long b
)
827 struct snag
*p
= &ship
->file
->foul
[a
];
829 if (p
->sn_count
> 0) {
831 ship
->file
->nfoul
-= p
->sn_count
;
841 recv_points(struct ship
*ship
, long a
)
843 ship
->file
->points
= a
;
847 recv_qual(struct ship
*ship
, long a
)
849 ship
->specs
->qual
= a
;
853 recv_ungrap(struct ship
*ship
, long a
, long b
)
855 struct snag
*p
= &ship
->file
->grap
[a
];
857 if (p
->sn_count
> 0) {
859 ship
->file
->ngrap
-= p
->sn_count
;
869 recv_rigg(struct ship
*ship
, long a
, long b
, long c
, long d
)
871 struct shipspecs
*s
= ship
->specs
;
880 recv_col(struct ship
*ship
, long a
)
886 recv_dir(struct ship
*ship
, long a
)
892 recv_row(struct ship
*ship
, long a
)
898 recv_signal(struct ship
*ship
, const char *astr
)
900 if (mode
== MODE_PLAYER
) {
902 Signal("$$: %s", ship
, astr
);
904 Signal("\a$$: %s", ship
, astr
);
909 recv_sink(struct ship
*ship
, long a
)
911 if ((ship
->file
->sink
= a
) == 2)
916 recv_struck(struct ship
*ship
, long a
)
918 ship
->file
->struck
= a
;
922 recv_ta(struct ship
*ship
, long a
)
940 recv_wind(long a
, long b
)
947 recv_fs(struct ship
*ship
, long a
)
953 recv_grap(struct ship
*ship
, long a
)
955 struct snag
*p
= &ship
->file
->grap
[a
];
957 if (SHIP(a
)->file
->dir
== 0)
959 if (p
->sn_count
++ == 0)
965 recv_rig1(struct ship
*ship
, long a
)
967 ship
->specs
->rig1
= a
;
971 recv_rig2(struct ship
*ship
, long a
)
973 ship
->specs
->rig2
= a
;
977 recv_rig3(struct ship
*ship
, long a
)
979 ship
->specs
->rig3
= a
;
983 recv_rig4(struct ship
*ship
, long a
)
985 ship
->specs
->rig4
= a
;
989 recv_begin(struct ship
*ship
)
991 strcpy(ship
->file
->captain
, "begin");
996 recv_end(struct ship
*ship
)
998 *ship
->file
->captain
= 0;
999 ship
->file
->points
= 0;