1 1.34 christos /* $NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $ */ 2 1.3 cgd 3 1.1 cgd /* 4 1.3 cgd * Copyright (c) 1983, 1993 5 1.3 cgd * The Regents of the University of California. All rights reserved. 6 1.1 cgd * 7 1.1 cgd * Redistribution and use in source and binary forms, with or without 8 1.1 cgd * modification, are permitted provided that the following conditions 9 1.1 cgd * are met: 10 1.1 cgd * 1. Redistributions of source code must retain the above copyright 11 1.1 cgd * notice, this list of conditions and the following disclaimer. 12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 cgd * notice, this list of conditions and the following disclaimer in the 14 1.1 cgd * documentation and/or other materials provided with the distribution. 15 1.21 agc * 3. Neither the name of the University nor the names of its contributors 16 1.1 cgd * may be used to endorse or promote products derived from this software 17 1.1 cgd * without specific prior written permission. 18 1.1 cgd * 19 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 cgd * SUCH DAMAGE. 30 1.1 cgd */ 31 1.1 cgd 32 1.6 christos #include <sys/cdefs.h> 33 1.1 cgd #ifndef lint 34 1.3 cgd #if 0 35 1.5 tls static char sccsid[] = "@(#)sync.c 8.2 (Berkeley) 4/28/95"; 36 1.3 cgd #else 37 1.34 christos __RCSID("$NetBSD: sync.c,v 1.34 2013/10/19 17:23:08 christos Exp $"); 38 1.3 cgd #endif 39 1.1 cgd #endif /* not lint */ 40 1.1 cgd 41 1.22 jsm #include <sys/stat.h> 42 1.22 jsm 43 1.6 christos #include <fcntl.h> 44 1.5 tls #include <errno.h> 45 1.33 dholland #include <limits.h> 46 1.18 jwise #include <signal.h> 47 1.6 christos #include <stdarg.h> 48 1.17 jwise #include <stdio.h> 49 1.6 christos #include <stdlib.h> 50 1.18 jwise #include <string.h> 51 1.17 jwise #include <time.h> 52 1.6 christos #include <unistd.h> 53 1.5 tls #include "extern.h" 54 1.14 jsm #include "pathnames.h" 55 1.1 cgd 56 1.1 cgd #define BUFSIZE 4096 57 1.1 cgd 58 1.30 dholland /* Message types */ 59 1.30 dholland #define W_CAPTAIN 1 60 1.30 dholland #define W_CAPTURED 2 61 1.30 dholland #define W_CLASS 3 62 1.30 dholland #define W_CREW 4 63 1.30 dholland #define W_DBP 5 64 1.30 dholland #define W_DRIFT 6 65 1.30 dholland #define W_EXPLODE 7 66 1.31 dholland /* W_FILE 8 not used */ 67 1.30 dholland #define W_FOUL 9 68 1.30 dholland #define W_GUNL 10 69 1.30 dholland #define W_GUNR 11 70 1.30 dholland #define W_HULL 12 71 1.30 dholland #define W_MOVE 13 72 1.30 dholland #define W_OBP 14 73 1.30 dholland #define W_PCREW 15 74 1.30 dholland #define W_UNFOUL 16 75 1.30 dholland #define W_POINTS 17 76 1.30 dholland #define W_QUAL 18 77 1.30 dholland #define W_UNGRAP 19 78 1.30 dholland #define W_RIGG 20 79 1.30 dholland #define W_COL 21 80 1.30 dholland #define W_DIR 22 81 1.30 dholland #define W_ROW 23 82 1.30 dholland #define W_SIGNAL 24 83 1.30 dholland #define W_SINK 25 84 1.30 dholland #define W_STRUCK 26 85 1.30 dholland #define W_TA 27 86 1.30 dholland #define W_ALIVE 28 87 1.30 dholland #define W_TURN 29 88 1.30 dholland #define W_WIND 30 89 1.30 dholland #define W_FS 31 90 1.30 dholland #define W_GRAP 32 91 1.30 dholland #define W_RIG1 33 92 1.30 dholland #define W_RIG2 34 93 1.30 dholland #define W_RIG3 35 94 1.30 dholland #define W_RIG4 36 95 1.30 dholland #define W_BEGIN 37 96 1.30 dholland #define W_END 38 97 1.30 dholland #define W_DDEAD 39 98 1.30 dholland 99 1.30 dholland 100 1.30 dholland static void recv_captain(struct ship *ship, const char *astr); 101 1.30 dholland static void recv_captured(struct ship *ship, long a); 102 1.30 dholland static void recv_class(struct ship *ship, long a); 103 1.30 dholland static void recv_crew(struct ship *ship, long a, long b, long c); 104 1.30 dholland static void recv_dbp(struct ship *ship, long a, long b, long c, long d); 105 1.30 dholland static void recv_drift(struct ship *ship, long a); 106 1.30 dholland static void recv_explode(struct ship *ship, long a); 107 1.30 dholland static void recv_foul(struct ship *ship, long a); 108 1.30 dholland static void recv_gunl(struct ship *ship, long a, long b); 109 1.30 dholland static void recv_gunr(struct ship *ship, long a, long b); 110 1.30 dholland static void recv_hull(struct ship *ship, long a); 111 1.30 dholland static void recv_move(struct ship *ship, const char *astr); 112 1.30 dholland static void recv_obp(struct ship *ship, long a, long b, long c, long d); 113 1.30 dholland static void recv_pcrew(struct ship *ship, long a); 114 1.30 dholland static void recv_unfoul(struct ship *ship, long a, long b); 115 1.30 dholland static void recv_points(struct ship *ship, long a); 116 1.30 dholland static void recv_qual(struct ship *ship, long a); 117 1.30 dholland static void recv_ungrap(struct ship *ship, long a, long b); 118 1.30 dholland static void recv_rigg(struct ship *ship, long a, long b, long c, long d); 119 1.30 dholland static void recv_col(struct ship *ship, long a); 120 1.30 dholland static void recv_dir(struct ship *ship, long a); 121 1.30 dholland static void recv_row(struct ship *ship, long a); 122 1.30 dholland static void recv_signal(struct ship *ship, const char *astr); 123 1.30 dholland static void recv_sink(struct ship *ship, long a); 124 1.30 dholland static void recv_struck(struct ship *ship, long a); 125 1.30 dholland static void recv_ta(struct ship *ship, long a); 126 1.30 dholland static void recv_alive(void); 127 1.30 dholland static void recv_turn(long a); 128 1.30 dholland static void recv_wind(long a, long b); 129 1.30 dholland static void recv_fs(struct ship *ship, long a); 130 1.30 dholland static void recv_grap(struct ship *ship, long a); 131 1.30 dholland static void recv_rig1(struct ship *ship, long a); 132 1.30 dholland static void recv_rig2(struct ship *ship, long a); 133 1.30 dholland static void recv_rig3(struct ship *ship, long a); 134 1.30 dholland static void recv_rig4(struct ship *ship, long a); 135 1.30 dholland static void recv_begin(struct ship *ship); 136 1.30 dholland static void recv_end(struct ship *ship); 137 1.30 dholland static void recv_ddead(void); 138 1.30 dholland 139 1.30 dholland static void Write(int, struct ship *, long, long, long, long); 140 1.30 dholland static void Writestr(int, struct ship *, const char *); 141 1.30 dholland 142 1.28 dholland static int sync_update(int, struct ship *, const char *, 143 1.28 dholland long, long, long, long); 144 1.16 jwise 145 1.1 cgd static char sync_buf[BUFSIZE]; 146 1.1 cgd static char *sync_bp = sync_buf; 147 1.1 cgd static long sync_seek; 148 1.1 cgd static FILE *sync_fp; 149 1.1 cgd 150 1.33 dholland static const char * 151 1.33 dholland get_sync_file(int scenario_number) 152 1.33 dholland { 153 1.33 dholland static char sync_file[NAME_MAX]; 154 1.33 dholland 155 1.33 dholland snprintf(sync_file, sizeof(sync_file), _FILE_SYNC, scenario_number); 156 1.33 dholland return sync_file; 157 1.33 dholland } 158 1.33 dholland 159 1.33 dholland static const char * 160 1.33 dholland get_lock_file(int scenario_number) 161 1.33 dholland { 162 1.33 dholland static char sync_lock[NAME_MAX]; 163 1.33 dholland 164 1.33 dholland snprintf(sync_lock, sizeof(sync_lock), _FILE_LOCK, scenario_number); 165 1.33 dholland return sync_lock; 166 1.33 dholland } 167 1.33 dholland 168 1.6 christos void 169 1.15 jwise fmtship(char *buf, size_t len, const char *fmt, struct ship *ship) 170 1.6 christos { 171 1.6 christos while (*fmt) { 172 1.6 christos if (len-- == 0) { 173 1.6 christos *buf = '\0'; 174 1.6 christos return; 175 1.6 christos } 176 1.7 christos if (*fmt == '$' && fmt[1] == '$') { 177 1.6 christos size_t l = snprintf(buf, len, "%s (%c%c)", 178 1.6 christos ship->shipname, colours(ship), sterncolour(ship)); 179 1.6 christos buf += l; 180 1.6 christos len -= l - 1; 181 1.6 christos fmt += 2; 182 1.6 christos } 183 1.6 christos else 184 1.6 christos *buf++ = *fmt++; 185 1.6 christos } 186 1.6 christos 187 1.6 christos if (len > 0) 188 1.6 christos *buf = '\0'; 189 1.6 christos } 190 1.6 christos 191 1.6 christos 192 1.1 cgd /*VARARGS3*/ 193 1.6 christos void 194 1.6 christos makesignal(struct ship *from, const char *fmt, struct ship *ship, ...) 195 1.6 christos { 196 1.6 christos char message[BUFSIZ]; 197 1.6 christos char format[BUFSIZ]; 198 1.6 christos va_list ap; 199 1.15 jwise 200 1.6 christos va_start(ap, ship); 201 1.6 christos fmtship(format, sizeof(format), fmt, ship); 202 1.26 dholland vsnprintf(message, sizeof(message), format, ap); 203 1.6 christos va_end(ap); 204 1.30 dholland send_signal(from, message); 205 1.1 cgd } 206 1.1 cgd 207 1.15 jwise /*VARARGS2*/ 208 1.7 christos void 209 1.7 christos makemsg(struct ship *from, const char *fmt, ...) 210 1.7 christos { 211 1.7 christos char message[BUFSIZ]; 212 1.7 christos va_list ap; 213 1.15 jwise 214 1.7 christos va_start(ap, fmt); 215 1.26 dholland vsnprintf(message, sizeof(message), fmt, ap); 216 1.7 christos va_end(ap); 217 1.30 dholland send_signal(from, message); 218 1.7 christos } 219 1.11 hubertf 220 1.6 christos int 221 1.25 dholland sync_exists(int gamenum) 222 1.1 cgd { 223 1.33 dholland const char *path; 224 1.1 cgd struct stat s; 225 1.1 cgd time_t t; 226 1.1 cgd 227 1.33 dholland path = get_sync_file(gamenum); 228 1.15 jwise time(&t); 229 1.14 jsm setegid(egid); 230 1.33 dholland if (stat(path, &s) < 0) { 231 1.14 jsm setegid(gid); 232 1.1 cgd return 0; 233 1.14 jsm } 234 1.1 cgd if (s.st_mtime < t - 60*60*2) { /* 2 hours */ 235 1.33 dholland unlink(path); 236 1.33 dholland path = get_lock_file(gamenum); 237 1.33 dholland unlink(path); 238 1.14 jsm setegid(gid); 239 1.1 cgd return 0; 240 1.14 jsm } else { 241 1.14 jsm setegid(gid); 242 1.1 cgd return 1; 243 1.14 jsm } 244 1.1 cgd } 245 1.1 cgd 246 1.6 christos int 247 1.15 jwise sync_open(void) 248 1.1 cgd { 249 1.33 dholland const char *sync_file; 250 1.14 jsm struct stat tmp; 251 1.33 dholland 252 1.1 cgd if (sync_fp != NULL) 253 1.15 jwise fclose(sync_fp); 254 1.33 dholland sync_file = get_sync_file(game); 255 1.34 christos (void)get_lock_file(game); 256 1.14 jsm setegid(egid); 257 1.14 jsm if (stat(sync_file, &tmp) < 0) { 258 1.14 jsm mode_t omask = umask(002); 259 1.1 cgd sync_fp = fopen(sync_file, "w+"); 260 1.15 jwise umask(omask); 261 1.1 cgd } else 262 1.1 cgd sync_fp = fopen(sync_file, "r+"); 263 1.14 jsm setegid(gid); 264 1.1 cgd if (sync_fp == NULL) 265 1.1 cgd return -1; 266 1.1 cgd sync_seek = 0; 267 1.1 cgd return 0; 268 1.1 cgd } 269 1.1 cgd 270 1.6 christos void 271 1.25 dholland sync_close(int doremove) 272 1.1 cgd { 273 1.33 dholland const char *sync_file; 274 1.33 dholland 275 1.1 cgd if (sync_fp != 0) 276 1.15 jwise fclose(sync_fp); 277 1.25 dholland if (doremove) { 278 1.33 dholland sync_file = get_sync_file(game); 279 1.14 jsm setegid(egid); 280 1.15 jwise unlink(sync_file); 281 1.14 jsm setegid(gid); 282 1.14 jsm } 283 1.1 cgd } 284 1.1 cgd 285 1.30 dholland static void 286 1.15 jwise Write(int type, struct ship *ship, long a, long b, long c, long d) 287 1.1 cgd { 288 1.26 dholland size_t max = sizeof(sync_buf) - (sync_bp - sync_buf); 289 1.30 dholland int shipindex = (ship == NULL) ? 0 : ship->file->index; 290 1.6 christos 291 1.26 dholland snprintf(sync_bp, max, "%d %d 0 %ld %ld %ld %ld\n", 292 1.30 dholland type, shipindex, a, b, c, d); 293 1.11 hubertf while (*sync_bp++) 294 1.11 hubertf ; 295 1.11 hubertf sync_bp--; 296 1.11 hubertf if (sync_bp >= &sync_buf[sizeof sync_buf]) 297 1.11 hubertf abort(); 298 1.15 jwise sync_update(type, ship, NULL, a, b, c, d); 299 1.11 hubertf } 300 1.11 hubertf 301 1.30 dholland static void 302 1.15 jwise Writestr(int type, struct ship *ship, const char *a) 303 1.11 hubertf { 304 1.26 dholland size_t max = sizeof(sync_buf) - (sync_bp - sync_buf); 305 1.30 dholland int shipindex = (ship == NULL) ? 0 : ship->file->index; 306 1.26 dholland 307 1.30 dholland snprintf(sync_bp, max, "%d %d 1 %s\n", type, shipindex, a); 308 1.1 cgd while (*sync_bp++) 309 1.1 cgd ; 310 1.1 cgd sync_bp--; 311 1.1 cgd if (sync_bp >= &sync_buf[sizeof sync_buf]) 312 1.1 cgd abort(); 313 1.15 jwise sync_update(type, ship, a, 0, 0, 0, 0); 314 1.1 cgd } 315 1.1 cgd 316 1.6 christos int 317 1.15 jwise Sync(void) 318 1.1 cgd { 319 1.1 cgd sig_t sighup, sigint; 320 1.6 christos int n; 321 1.4 cgd int type, shipnum, isstr; 322 1.11 hubertf char *astr; 323 1.4 cgd long a, b, c, d; 324 1.1 cgd char buf[80]; 325 1.1 cgd char erred = 0; 326 1.33 dholland #ifndef LOCK_EX 327 1.33 dholland const char *sync_file; 328 1.33 dholland const char *sync_lock; 329 1.33 dholland #endif 330 1.1 cgd 331 1.1 cgd sighup = signal(SIGHUP, SIG_IGN); 332 1.1 cgd sigint = signal(SIGINT, SIG_IGN); 333 1.1 cgd for (n = TIMEOUT; --n >= 0;) { 334 1.1 cgd #ifdef LOCK_EX 335 1.1 cgd if (flock(fileno(sync_fp), LOCK_EX|LOCK_NB) >= 0) 336 1.1 cgd break; 337 1.1 cgd if (errno != EWOULDBLOCK) 338 1.1 cgd return -1; 339 1.1 cgd #else 340 1.33 dholland sync_file = get_sync_file(game); 341 1.33 dholland sync_lock = get_lock_file(game); 342 1.14 jsm setegid(egid); 343 1.14 jsm if (link(sync_file, sync_lock) >= 0) { 344 1.14 jsm setegid(gid); 345 1.1 cgd break; 346 1.14 jsm } 347 1.14 jsm setegid(gid); 348 1.1 cgd if (errno != EEXIST) 349 1.1 cgd return -1; 350 1.1 cgd #endif 351 1.1 cgd sleep(1); 352 1.1 cgd } 353 1.1 cgd if (n <= 0) 354 1.1 cgd return -1; 355 1.15 jwise fseek(sync_fp, sync_seek, SEEK_SET); 356 1.1 cgd for (;;) { 357 1.1 cgd switch (fscanf(sync_fp, "%d%d%d", &type, &shipnum, &isstr)) { 358 1.1 cgd case 3: 359 1.1 cgd break; 360 1.1 cgd case EOF: 361 1.1 cgd goto out; 362 1.1 cgd default: 363 1.1 cgd goto bad; 364 1.1 cgd } 365 1.1 cgd if (shipnum < 0 || shipnum >= cc->vessels) 366 1.1 cgd goto bad; 367 1.1 cgd if (isstr != 0 && isstr != 1) 368 1.1 cgd goto bad; 369 1.1 cgd if (isstr) { 370 1.25 dholland int ch; 371 1.6 christos char *p; 372 1.24 mrg 373 1.1 cgd for (p = buf;;) { 374 1.25 dholland ch = getc(sync_fp); 375 1.27 dholland *p++ = ch; 376 1.25 dholland switch (ch) { 377 1.1 cgd case '\n': 378 1.1 cgd p--; 379 1.1 cgd case EOF: 380 1.1 cgd break; 381 1.1 cgd default: 382 1.1 cgd if (p >= buf + sizeof buf) 383 1.1 cgd p--; 384 1.1 cgd continue; 385 1.1 cgd } 386 1.1 cgd break; 387 1.1 cgd } 388 1.1 cgd *p = 0; 389 1.1 cgd for (p = buf; *p == ' '; p++) 390 1.1 cgd ; 391 1.11 hubertf astr = p; 392 1.11 hubertf a = b = c = d = 0; 393 1.11 hubertf } else { 394 1.28 dholland if (fscanf(sync_fp, "%ld%ld%ld%ld", &a, &b, &c, &d) 395 1.28 dholland != 4) 396 1.1 cgd goto bad; 397 1.11 hubertf astr = NULL; 398 1.11 hubertf } 399 1.11 hubertf if (sync_update(type, SHIP(shipnum), astr, a, b, c, d) < 0) 400 1.1 cgd goto bad; 401 1.1 cgd } 402 1.1 cgd bad: 403 1.1 cgd erred++; 404 1.1 cgd out: 405 1.1 cgd if (!erred && sync_bp != sync_buf) { 406 1.15 jwise fseek(sync_fp, 0L, SEEK_END); 407 1.15 jwise fwrite(sync_buf, sizeof *sync_buf, sync_bp - sync_buf, 408 1.1 cgd sync_fp); 409 1.15 jwise fflush(sync_fp); 410 1.1 cgd sync_bp = sync_buf; 411 1.1 cgd } 412 1.1 cgd sync_seek = ftell(sync_fp); 413 1.1 cgd #ifdef LOCK_EX 414 1.15 jwise flock(fileno(sync_fp), LOCK_UN); 415 1.1 cgd #else 416 1.14 jsm setegid(egid); 417 1.15 jwise unlink(sync_lock); 418 1.14 jsm setegid(gid); 419 1.1 cgd #endif 420 1.15 jwise signal(SIGHUP, sighup); 421 1.15 jwise signal(SIGINT, sigint); 422 1.1 cgd return erred ? -1 : 0; 423 1.1 cgd } 424 1.1 cgd 425 1.16 jwise static int 426 1.28 dholland sync_update(int type, struct ship *ship, const char *astr, 427 1.28 dholland long a, long b, long c, long d) 428 1.1 cgd { 429 1.1 cgd switch (type) { 430 1.30 dholland case W_CAPTAIN: recv_captain(ship, astr); break; 431 1.30 dholland case W_CAPTURED: recv_captured(ship, a); break; 432 1.30 dholland case W_CLASS: recv_class(ship, a); break; 433 1.30 dholland case W_CREW: recv_crew(ship, a, b, c); break; 434 1.30 dholland case W_DBP: recv_dbp(ship, a, b, c, d); break; 435 1.30 dholland case W_DRIFT: recv_drift(ship, a); break; 436 1.30 dholland case W_EXPLODE: recv_explode(ship, a); break; 437 1.30 dholland case W_FOUL: recv_foul(ship, a); break; 438 1.30 dholland case W_GUNL: recv_gunl(ship, a, b); break; 439 1.30 dholland case W_GUNR: recv_gunr(ship, a, b); break; 440 1.30 dholland case W_HULL: recv_hull(ship, a); break; 441 1.30 dholland case W_MOVE: recv_move(ship, astr); break; 442 1.30 dholland case W_OBP: recv_obp(ship, a, b, c, d); break; 443 1.30 dholland case W_PCREW: recv_pcrew(ship, a); break; 444 1.30 dholland case W_UNFOUL: recv_unfoul(ship, a, b); break; 445 1.30 dholland case W_POINTS: recv_points(ship, a); break; 446 1.30 dholland case W_QUAL: recv_qual(ship, a); break; 447 1.30 dholland case W_UNGRAP: recv_ungrap(ship, a, b); break; 448 1.30 dholland case W_RIGG: recv_rigg(ship, a, b, c, d); break; 449 1.30 dholland case W_COL: recv_col(ship, a); break; 450 1.30 dholland case W_DIR: recv_dir(ship, a); break; 451 1.30 dholland case W_ROW: recv_row(ship, a); break; 452 1.30 dholland case W_SIGNAL: recv_signal(ship, astr); break; 453 1.30 dholland case W_SINK: recv_sink(ship, a); break; 454 1.30 dholland case W_STRUCK: recv_struck(ship, a); break; 455 1.30 dholland case W_TA: recv_ta(ship, a); break; 456 1.30 dholland case W_ALIVE: recv_alive(); break; 457 1.30 dholland case W_TURN: recv_turn(a); break; 458 1.30 dholland case W_WIND: recv_wind(a, b); break; 459 1.30 dholland case W_FS: recv_fs(ship, a); break; 460 1.30 dholland case W_GRAP: recv_grap(ship, a); break; 461 1.30 dholland case W_RIG1: recv_rig1(ship, a); break; 462 1.30 dholland case W_RIG2: recv_rig2(ship, a); break; 463 1.30 dholland case W_RIG3: recv_rig3(ship, a); break; 464 1.30 dholland case W_RIG4: recv_rig4(ship, a); break; 465 1.30 dholland case W_BEGIN: recv_begin(ship); break; 466 1.30 dholland case W_END: recv_end(ship); break; 467 1.30 dholland case W_DDEAD: recv_ddead(); break; 468 1.1 cgd default: 469 1.1 cgd fprintf(stderr, "sync_update: unknown type %d\r\n", type); 470 1.1 cgd return -1; 471 1.1 cgd } 472 1.1 cgd return 0; 473 1.1 cgd } 474 1.30 dholland 475 1.30 dholland /* 476 1.30 dholland * Messages to send 477 1.30 dholland */ 478 1.30 dholland 479 1.30 dholland void 480 1.30 dholland send_captain(struct ship *ship, const char *astr) 481 1.30 dholland { 482 1.30 dholland Writestr(W_CAPTAIN, ship, astr); 483 1.30 dholland } 484 1.30 dholland 485 1.30 dholland void 486 1.30 dholland send_captured(struct ship *ship, long a) 487 1.30 dholland { 488 1.30 dholland Write(W_CAPTURED, ship, a, 0, 0, 0); 489 1.30 dholland } 490 1.30 dholland 491 1.30 dholland void 492 1.30 dholland send_class(struct ship *ship, long a) 493 1.30 dholland { 494 1.30 dholland Write(W_CLASS, ship, a, 0, 0, 0); 495 1.30 dholland } 496 1.30 dholland 497 1.30 dholland void 498 1.30 dholland send_crew(struct ship *ship, long a, long b, long c) 499 1.30 dholland { 500 1.30 dholland Write(W_CREW, ship, a, b, c, 0); 501 1.30 dholland } 502 1.30 dholland 503 1.30 dholland void 504 1.30 dholland send_dbp(struct ship *ship, long a, long b, long c, long d) 505 1.30 dholland { 506 1.30 dholland Write(W_DBP, ship, a, b, c, d); 507 1.30 dholland } 508 1.30 dholland 509 1.30 dholland void 510 1.30 dholland send_drift(struct ship *ship, long a) 511 1.30 dholland { 512 1.30 dholland Write(W_DRIFT, ship, a, 0, 0, 0); 513 1.30 dholland } 514 1.30 dholland 515 1.30 dholland void 516 1.30 dholland send_explode(struct ship *ship, long a) 517 1.30 dholland { 518 1.30 dholland Write(W_EXPLODE, ship, a, 0, 0, 0); 519 1.30 dholland } 520 1.30 dholland 521 1.30 dholland void 522 1.30 dholland send_foul(struct ship *ship, long a) 523 1.30 dholland { 524 1.30 dholland Write(W_FOUL, ship, a, 0, 0, 0); 525 1.30 dholland } 526 1.30 dholland 527 1.30 dholland void 528 1.30 dholland send_gunl(struct ship *ship, long a, long b) 529 1.30 dholland { 530 1.30 dholland Write(W_GUNL, ship, a, b, 0, 0); 531 1.30 dholland } 532 1.30 dholland 533 1.30 dholland void 534 1.30 dholland send_gunr(struct ship *ship, long a, long b) 535 1.30 dholland { 536 1.30 dholland Write(W_GUNR, ship, a, b, 0, 0); 537 1.30 dholland } 538 1.30 dholland 539 1.30 dholland void 540 1.30 dholland send_hull(struct ship *ship, long a) 541 1.30 dholland { 542 1.30 dholland Write(W_HULL, ship, a, 0, 0, 0); 543 1.30 dholland } 544 1.30 dholland 545 1.30 dholland void 546 1.30 dholland send_move(struct ship *ship, const char *astr) 547 1.30 dholland { 548 1.30 dholland Writestr(W_MOVE, ship, astr); 549 1.30 dholland } 550 1.30 dholland 551 1.30 dholland void 552 1.30 dholland send_obp(struct ship *ship, long a, long b, long c, long d) 553 1.30 dholland { 554 1.30 dholland Write(W_OBP, ship, a, b, c, d); 555 1.30 dholland } 556 1.30 dholland 557 1.30 dholland void 558 1.30 dholland send_pcrew(struct ship *ship, long a) 559 1.30 dholland { 560 1.30 dholland Write(W_PCREW, ship, a, 0, 0, 0); 561 1.30 dholland } 562 1.30 dholland 563 1.30 dholland void 564 1.30 dholland send_unfoul(struct ship *ship, long a, long b) 565 1.30 dholland { 566 1.30 dholland Write(W_UNFOUL, ship, a, b, 0, 0); 567 1.30 dholland } 568 1.30 dholland 569 1.30 dholland void 570 1.30 dholland send_points(struct ship *ship, long a) 571 1.30 dholland { 572 1.30 dholland Write(W_POINTS, ship, a, 0, 0, 0); 573 1.30 dholland } 574 1.30 dholland 575 1.30 dholland void 576 1.30 dholland send_qual(struct ship *ship, long a) 577 1.30 dholland { 578 1.30 dholland Write(W_QUAL, ship, a, 0, 0, 0); 579 1.30 dholland } 580 1.30 dholland 581 1.30 dholland void 582 1.30 dholland send_ungrap(struct ship *ship, long a, long b) 583 1.30 dholland { 584 1.30 dholland Write(W_UNGRAP, ship, a, b, 0, 0); 585 1.30 dholland } 586 1.30 dholland 587 1.30 dholland void 588 1.30 dholland send_rigg(struct ship *ship, long a, long b, long c, long d) 589 1.30 dholland { 590 1.30 dholland Write(W_RIGG, ship, a, b, c, d); 591 1.30 dholland } 592 1.30 dholland 593 1.30 dholland void 594 1.30 dholland send_col(struct ship *ship, long a) 595 1.30 dholland { 596 1.30 dholland Write(W_COL, ship, a, 0, 0, 0); 597 1.30 dholland } 598 1.30 dholland 599 1.30 dholland void 600 1.30 dholland send_dir(struct ship *ship, long a) 601 1.30 dholland { 602 1.30 dholland Write(W_DIR, ship, a, 0, 0, 0); 603 1.30 dholland } 604 1.30 dholland 605 1.30 dholland void 606 1.30 dholland send_row(struct ship *ship, long a) 607 1.30 dholland { 608 1.30 dholland Write(W_ROW, ship, a, 0, 0, 0); 609 1.30 dholland } 610 1.30 dholland 611 1.30 dholland void 612 1.30 dholland send_signal(struct ship *ship, const char *astr) 613 1.30 dholland { 614 1.30 dholland Writestr(W_SIGNAL, ship, astr); 615 1.30 dholland } 616 1.30 dholland 617 1.30 dholland void 618 1.30 dholland send_sink(struct ship *ship, long a) 619 1.30 dholland { 620 1.30 dholland Write(W_SINK, ship, a, 0, 0, 0); 621 1.30 dholland } 622 1.30 dholland 623 1.30 dholland void 624 1.30 dholland send_struck(struct ship *ship, long a) 625 1.30 dholland { 626 1.30 dholland Write(W_STRUCK, ship, a, 0, 0, 0); 627 1.30 dholland } 628 1.30 dholland 629 1.30 dholland void 630 1.30 dholland send_ta(struct ship *ship, long a) 631 1.30 dholland { 632 1.30 dholland Write(W_TA, ship, a, 0, 0, 0); 633 1.30 dholland } 634 1.30 dholland 635 1.30 dholland void 636 1.30 dholland send_alive(void) 637 1.30 dholland { 638 1.30 dholland Write(W_ALIVE, NULL, 0, 0, 0, 0); 639 1.30 dholland } 640 1.30 dholland 641 1.30 dholland void 642 1.30 dholland send_turn(long a) 643 1.30 dholland { 644 1.30 dholland Write(W_TURN, NULL, a, 0, 0, 0); 645 1.30 dholland } 646 1.30 dholland 647 1.30 dholland void 648 1.30 dholland send_wind(long a, long b) 649 1.30 dholland { 650 1.30 dholland Write(W_WIND, NULL, a, b, 0, 0); 651 1.30 dholland } 652 1.30 dholland 653 1.30 dholland void 654 1.30 dholland send_fs(struct ship *ship, long a) 655 1.30 dholland { 656 1.30 dholland Write(W_FS, ship, a, 0, 0, 0); 657 1.30 dholland } 658 1.30 dholland 659 1.30 dholland void 660 1.30 dholland send_grap(struct ship *ship, long a) 661 1.30 dholland { 662 1.30 dholland Write(W_GRAP, ship, a, 0, 0, 0); 663 1.30 dholland } 664 1.30 dholland 665 1.30 dholland void 666 1.30 dholland send_rig1(struct ship *ship, long a) 667 1.30 dholland { 668 1.30 dholland Write(W_RIG1, ship, a, 0, 0, 0); 669 1.30 dholland } 670 1.30 dholland 671 1.30 dholland void 672 1.30 dholland send_rig2(struct ship *ship, long a) 673 1.30 dholland { 674 1.30 dholland Write(W_RIG2, ship, a, 0, 0, 0); 675 1.30 dholland } 676 1.30 dholland 677 1.30 dholland void 678 1.30 dholland send_rig3(struct ship *ship, long a) 679 1.30 dholland { 680 1.30 dholland Write(W_RIG3, ship, a, 0, 0, 0); 681 1.30 dholland } 682 1.30 dholland 683 1.30 dholland void 684 1.30 dholland send_rig4(struct ship *ship, long a) 685 1.30 dholland { 686 1.30 dholland Write(W_RIG4, ship, a, 0, 0, 0); 687 1.30 dholland } 688 1.30 dholland 689 1.30 dholland void 690 1.30 dholland send_begin(struct ship *ship) 691 1.30 dholland { 692 1.30 dholland Write(W_BEGIN, ship, 0, 0, 0, 0); 693 1.30 dholland } 694 1.30 dholland 695 1.30 dholland void 696 1.30 dholland send_end(struct ship *ship) 697 1.30 dholland { 698 1.30 dholland Write(W_END, ship, 0, 0, 0, 0); 699 1.30 dholland } 700 1.30 dholland 701 1.30 dholland void 702 1.30 dholland send_ddead(void) 703 1.30 dholland { 704 1.30 dholland Write(W_DDEAD, NULL, 0, 0, 0, 0); 705 1.30 dholland } 706 1.30 dholland 707 1.30 dholland 708 1.30 dholland /* 709 1.30 dholland * Actions upon message receipt 710 1.30 dholland */ 711 1.30 dholland 712 1.30 dholland static void 713 1.30 dholland recv_captain(struct ship *ship, const char *astr) 714 1.30 dholland { 715 1.30 dholland strlcpy(ship->file->captain, astr, sizeof ship->file->captain); 716 1.30 dholland } 717 1.30 dholland 718 1.30 dholland static void 719 1.30 dholland recv_captured(struct ship *ship, long a) 720 1.30 dholland { 721 1.30 dholland if (a < 0) 722 1.30 dholland ship->file->captured = 0; 723 1.30 dholland else 724 1.30 dholland ship->file->captured = SHIP(a); 725 1.30 dholland } 726 1.30 dholland 727 1.30 dholland static void 728 1.30 dholland recv_class(struct ship *ship, long a) 729 1.30 dholland { 730 1.30 dholland ship->specs->class = a; 731 1.30 dholland } 732 1.30 dholland 733 1.30 dholland static void 734 1.30 dholland recv_crew(struct ship *ship, long a, long b, long c) 735 1.30 dholland { 736 1.30 dholland struct shipspecs *s = ship->specs; 737 1.30 dholland 738 1.30 dholland s->crew1 = a; 739 1.30 dholland s->crew2 = b; 740 1.30 dholland s->crew3 = c; 741 1.30 dholland } 742 1.30 dholland 743 1.30 dholland static void 744 1.30 dholland recv_dbp(struct ship *ship, long a, long b, long c, long d) 745 1.30 dholland { 746 1.30 dholland struct BP *p = &ship->file->DBP[a]; 747 1.30 dholland 748 1.30 dholland p->turnsent = b; 749 1.30 dholland p->toship = SHIP(c); 750 1.30 dholland p->mensent = d; 751 1.30 dholland } 752 1.30 dholland 753 1.30 dholland static void 754 1.30 dholland recv_drift(struct ship *ship, long a) 755 1.30 dholland { 756 1.30 dholland ship->file->drift = a; 757 1.30 dholland } 758 1.30 dholland 759 1.30 dholland static void 760 1.30 dholland recv_explode(struct ship *ship, long a) 761 1.30 dholland { 762 1.30 dholland if ((ship->file->explode = a) == 2) 763 1.30 dholland ship->file->dir = 0; 764 1.30 dholland } 765 1.30 dholland 766 1.30 dholland static void 767 1.30 dholland recv_foul(struct ship *ship, long a) 768 1.30 dholland { 769 1.30 dholland struct snag *p = &ship->file->foul[a]; 770 1.30 dholland 771 1.30 dholland if (SHIP(a)->file->dir == 0) 772 1.30 dholland return; 773 1.30 dholland if (p->sn_count++ == 0) 774 1.30 dholland p->sn_turn = turn; 775 1.30 dholland ship->file->nfoul++; 776 1.30 dholland } 777 1.30 dholland 778 1.30 dholland static void 779 1.30 dholland recv_gunl(struct ship *ship, long a, long b) 780 1.30 dholland { 781 1.30 dholland struct shipspecs *s = ship->specs; 782 1.30 dholland 783 1.30 dholland s->gunL = a; 784 1.30 dholland s->carL = b; 785 1.30 dholland } 786 1.30 dholland 787 1.30 dholland static void 788 1.30 dholland recv_gunr(struct ship *ship, long a, long b) 789 1.30 dholland { 790 1.30 dholland struct shipspecs *s = ship->specs; 791 1.30 dholland 792 1.30 dholland s->gunR = a; 793 1.30 dholland s->carR = b; 794 1.30 dholland } 795 1.30 dholland 796 1.30 dholland static void 797 1.30 dholland recv_hull(struct ship *ship, long a) 798 1.30 dholland { 799 1.30 dholland ship->specs->hull = a; 800 1.30 dholland } 801 1.30 dholland 802 1.30 dholland static void 803 1.30 dholland recv_move(struct ship *ship, const char *astr) 804 1.30 dholland { 805 1.30 dholland strlcpy(ship->file->movebuf, astr, sizeof ship->file->movebuf); 806 1.30 dholland } 807 1.30 dholland 808 1.30 dholland static void 809 1.30 dholland recv_obp(struct ship *ship, long a, long b, long c, long d) 810 1.30 dholland { 811 1.30 dholland struct BP *p = &ship->file->OBP[a]; 812 1.30 dholland 813 1.30 dholland p->turnsent = b; 814 1.30 dholland p->toship = SHIP(c); 815 1.30 dholland p->mensent = d; 816 1.30 dholland } 817 1.30 dholland 818 1.30 dholland static void 819 1.30 dholland recv_pcrew(struct ship *ship, long a) 820 1.30 dholland { 821 1.30 dholland ship->file->pcrew = a; 822 1.30 dholland } 823 1.30 dholland 824 1.30 dholland static void 825 1.30 dholland recv_unfoul(struct ship *ship, long a, long b) 826 1.30 dholland { 827 1.30 dholland struct snag *p = &ship->file->foul[a]; 828 1.30 dholland 829 1.30 dholland if (p->sn_count > 0) { 830 1.30 dholland if (b) { 831 1.30 dholland ship->file->nfoul -= p->sn_count; 832 1.30 dholland p->sn_count = 0; 833 1.30 dholland } else { 834 1.30 dholland ship->file->nfoul--; 835 1.30 dholland p->sn_count--; 836 1.30 dholland } 837 1.30 dholland } 838 1.30 dholland } 839 1.30 dholland 840 1.30 dholland static void 841 1.30 dholland recv_points(struct ship *ship, long a) 842 1.30 dholland { 843 1.30 dholland ship->file->points = a; 844 1.30 dholland } 845 1.30 dholland 846 1.30 dholland static void 847 1.30 dholland recv_qual(struct ship *ship, long a) 848 1.30 dholland { 849 1.30 dholland ship->specs->qual = a; 850 1.30 dholland } 851 1.30 dholland 852 1.30 dholland static void 853 1.30 dholland recv_ungrap(struct ship *ship, long a, long b) 854 1.30 dholland { 855 1.30 dholland struct snag *p = &ship->file->grap[a]; 856 1.30 dholland 857 1.30 dholland if (p->sn_count > 0) { 858 1.30 dholland if (b) { 859 1.30 dholland ship->file->ngrap -= p->sn_count; 860 1.30 dholland p->sn_count = 0; 861 1.30 dholland } else { 862 1.30 dholland ship->file->ngrap--; 863 1.30 dholland p->sn_count--; 864 1.30 dholland } 865 1.30 dholland } 866 1.30 dholland } 867 1.30 dholland 868 1.30 dholland static void 869 1.30 dholland recv_rigg(struct ship *ship, long a, long b, long c, long d) 870 1.30 dholland { 871 1.30 dholland struct shipspecs *s = ship->specs; 872 1.30 dholland 873 1.30 dholland s->rig1 = a; 874 1.30 dholland s->rig2 = b; 875 1.30 dholland s->rig3 = c; 876 1.30 dholland s->rig4 = d; 877 1.30 dholland } 878 1.30 dholland 879 1.30 dholland static void 880 1.30 dholland recv_col(struct ship *ship, long a) 881 1.30 dholland { 882 1.30 dholland ship->file->col = a; 883 1.30 dholland } 884 1.30 dholland 885 1.30 dholland static void 886 1.30 dholland recv_dir(struct ship *ship, long a) 887 1.30 dholland { 888 1.30 dholland ship->file->dir = a; 889 1.30 dholland } 890 1.30 dholland 891 1.30 dholland static void 892 1.30 dholland recv_row(struct ship *ship, long a) 893 1.30 dholland { 894 1.30 dholland ship->file->row = a; 895 1.30 dholland } 896 1.30 dholland 897 1.30 dholland static void 898 1.30 dholland recv_signal(struct ship *ship, const char *astr) 899 1.30 dholland { 900 1.30 dholland if (mode == MODE_PLAYER) { 901 1.30 dholland if (nobells) 902 1.30 dholland Signal("$$: %s", ship, astr); 903 1.30 dholland else 904 1.30 dholland Signal("\a$$: %s", ship, astr); 905 1.30 dholland } 906 1.30 dholland } 907 1.30 dholland 908 1.30 dholland static void 909 1.30 dholland recv_sink(struct ship *ship, long a) 910 1.30 dholland { 911 1.30 dholland if ((ship->file->sink = a) == 2) 912 1.30 dholland ship->file->dir = 0; 913 1.30 dholland } 914 1.30 dholland 915 1.30 dholland static void 916 1.30 dholland recv_struck(struct ship *ship, long a) 917 1.30 dholland { 918 1.30 dholland ship->file->struck = a; 919 1.30 dholland } 920 1.30 dholland 921 1.30 dholland static void 922 1.30 dholland recv_ta(struct ship *ship, long a) 923 1.30 dholland { 924 1.30 dholland ship->specs->ta = a; 925 1.30 dholland } 926 1.30 dholland 927 1.30 dholland static void 928 1.30 dholland recv_alive(void) 929 1.30 dholland { 930 1.30 dholland alive = 1; 931 1.30 dholland } 932 1.30 dholland 933 1.30 dholland static void 934 1.30 dholland recv_turn(long a) 935 1.30 dholland { 936 1.30 dholland turn = a; 937 1.30 dholland } 938 1.30 dholland 939 1.30 dholland static void 940 1.30 dholland recv_wind(long a, long b) 941 1.30 dholland { 942 1.30 dholland winddir = a; 943 1.30 dholland windspeed = b; 944 1.30 dholland } 945 1.30 dholland 946 1.30 dholland static void 947 1.30 dholland recv_fs(struct ship *ship, long a) 948 1.30 dholland { 949 1.30 dholland ship->file->FS = a; 950 1.30 dholland } 951 1.30 dholland 952 1.30 dholland static void 953 1.30 dholland recv_grap(struct ship *ship, long a) 954 1.30 dholland { 955 1.30 dholland struct snag *p = &ship->file->grap[a]; 956 1.30 dholland 957 1.30 dholland if (SHIP(a)->file->dir == 0) 958 1.30 dholland return; 959 1.30 dholland if (p->sn_count++ == 0) 960 1.30 dholland p->sn_turn = turn; 961 1.30 dholland ship->file->ngrap++; 962 1.30 dholland } 963 1.30 dholland 964 1.30 dholland static void 965 1.30 dholland recv_rig1(struct ship *ship, long a) 966 1.30 dholland { 967 1.30 dholland ship->specs->rig1 = a; 968 1.30 dholland } 969 1.30 dholland 970 1.30 dholland static void 971 1.30 dholland recv_rig2(struct ship *ship, long a) 972 1.30 dholland { 973 1.30 dholland ship->specs->rig2 = a; 974 1.30 dholland } 975 1.30 dholland 976 1.30 dholland static void 977 1.30 dholland recv_rig3(struct ship *ship, long a) 978 1.30 dholland { 979 1.30 dholland ship->specs->rig3 = a; 980 1.30 dholland } 981 1.30 dholland 982 1.30 dholland static void 983 1.30 dholland recv_rig4(struct ship *ship, long a) 984 1.30 dholland { 985 1.30 dholland ship->specs->rig4 = a; 986 1.30 dholland } 987 1.30 dholland 988 1.30 dholland static void 989 1.30 dholland recv_begin(struct ship *ship) 990 1.30 dholland { 991 1.30 dholland strcpy(ship->file->captain, "begin"); 992 1.30 dholland people++; 993 1.30 dholland } 994 1.30 dholland 995 1.30 dholland static void 996 1.30 dholland recv_end(struct ship *ship) 997 1.30 dholland { 998 1.30 dholland *ship->file->captain = 0; 999 1.30 dholland ship->file->points = 0; 1000 1.30 dholland people--; 1001 1.30 dholland } 1002 1.30 dholland 1003 1.30 dholland static void 1004 1.30 dholland recv_ddead(void) 1005 1.30 dholland { 1006 1.30 dholland hasdriver = 0; 1007 1.30 dholland } 1008