|
|
1.1 ! root 1: /* ! 2: * Hunt ! 3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold ! 4: * San Francisco, California ! 5: * ! 6: * Copyright (c) 1985 Regents of the University of California. ! 7: * All rights reserved. The Berkeley software License Agreement ! 8: * specifies the terms and conditions for redistribution. ! 9: */ ! 10: ! 11: # include <errno.h> ! 12: # include <curses.h> ! 13: # include "hunt.h" ! 14: # include <signal.h> ! 15: # include <ctype.h> ! 16: # include <sys/stat.h> ! 17: # ifndef HPUX ! 18: # include <sys/time.h> ! 19: # else ! 20: # include <time.h> ! 21: # endif ! 22: # ifdef TERMINFO ! 23: # include <term.h> ! 24: ! 25: # define CM cursor_address ! 26: ! 27: # else ! 28: ! 29: /* ! 30: * Some old versions of curses don't have these defined ! 31: */ ! 32: # ifndef cbreak ! 33: # define cbreak() crmode() ! 34: # endif ! 35: # endif ! 36: ! 37: /* ! 38: * these numbers are contrived to allow 3 users on a VAX 11/750 ! 39: * i.e. an spin loop of 10000 iterations in 30 milliseconds. ! 40: */ ! 41: # define LOOP_COUNT 10000 ! 42: # define FUDGE_FACTOR 30 ! 43: ! 44: FLAG Last_player = FALSE; ! 45: # ifdef MONITOR ! 46: FLAG Am_monitor = FALSE; ! 47: # endif MONITOR ! 48: ! 49: char Buf[BUFSIZ]; ! 50: ! 51: int Socket; ! 52: # ifdef INTERNET ! 53: char *Sock_host; ! 54: char *use_port; ! 55: FLAG Query_driver = FALSE; ! 56: char *Send_message = NULL; ! 57: FLAG Show_scores = FALSE; ! 58: # endif INTERNET ! 59: ! 60: SOCKET Daemon; ! 61: # ifdef INTERNET ! 62: # define DAEMON_SIZE (sizeof Daemon) ! 63: # else INTERNET ! 64: # define DAEMON_SIZE (sizeof Daemon - 1) ! 65: # endif INTERNET ! 66: ! 67: char map_key[256]; /* what to map keys to */ ! 68: FLAG no_beep; ! 69: ! 70: static char name[NAMELEN]; ! 71: static char team = ' '; ! 72: ! 73: static int in_visual; ! 74: ! 75: extern int cur_row, cur_col, _putchar(); ! 76: extern char *tgoto(); ! 77: ! 78: # ifdef INTERNET ! 79: extern SOCKET *list_drivers(); ! 80: # endif ! 81: ! 82: /* ! 83: * main: ! 84: * Main program for local process ! 85: */ ! 86: main(ac, av) ! 87: int ac; ! 88: char **av; ! 89: { ! 90: char *term; ! 91: int c; ! 92: extern int errno; ! 93: extern int Otto_mode; ! 94: extern int optind; ! 95: extern char *optarg; ! 96: long enter_status; ! 97: int intr(), sigterm(), sigemt(), tstp(); ! 98: long env_init(), quit(); ! 99: ! 100: enter_status = env_init((long) Q_CLOAK); ! 101: while ((c = getopt(ac, av, "Sbcfh:l:mn:op:qst:w:")) != EOF) { ! 102: switch (c) { ! 103: ! 104: # ifdef INTERNET ! 105: case 'S': ! 106: Show_scores = TRUE; ! 107: break; ! 108: # endif ! 109: ! 110: case 'l': /* rsh compatibility */ ! 111: case 'n': ! 112: (void) strncpy(name, optarg, NAMELEN); ! 113: break; ! 114: case 't': ! 115: team = *optarg; ! 116: if (!isdigit(team)) { ! 117: fprintf(stderr, "Team names must be numeric\n"); ! 118: team = ' '; ! 119: } ! 120: break; ! 121: case 'o': ! 122: # ifndef OTTO ! 123: fputs("The -o flag is reserved for future use.\n", ! 124: stderr); ! 125: goto usage; ! 126: # else OTTO ! 127: Otto_mode = TRUE; ! 128: break; ! 129: # endif OTTO ! 130: # ifdef MONITOR ! 131: case 'm': ! 132: Am_monitor = TRUE; ! 133: break; ! 134: # endif MONITOR ! 135: # ifdef INTERNET ! 136: case 'q': /* query whether hunt is running */ ! 137: Query_driver = TRUE; ! 138: break; ! 139: case 'w': ! 140: Send_message = optarg; ! 141: break; ! 142: case 'h': ! 143: Sock_host = optarg; ! 144: break; ! 145: case 'p': ! 146: use_port = optarg; ! 147: Test_port = atoi(use_port); ! 148: break; ! 149: # endif INTERNET ! 150: case 'c': ! 151: enter_status = Q_CLOAK; ! 152: break; ! 153: # ifdef FLY ! 154: case 'f': ! 155: enter_status = Q_FLY; ! 156: break; ! 157: # endif FLY ! 158: case 's': ! 159: enter_status = Q_SCAN; ! 160: break; ! 161: case 'b': ! 162: no_beep = !no_beep; ! 163: break; ! 164: default: ! 165: usage: ! 166: # ifdef INTERNET ! 167: # ifdef MONITOR ! 168: # define USAGE "usage:\thunt [-qmcsfS] [-n name] [-t team]\n\t[-p port] [-w message] [host]\n" ! 169: # else MONITOR ! 170: # define USAGE "usage:\thunt [-qcsfS] [-n name] [-t team]\n\t[-p port] [-w message] [host]\n" ! 171: # endif MONITOR ! 172: # else INTERNET ! 173: # ifdef MONITOR ! 174: # define USAGE "usage:\thunt [-mcsf] [-n name] [-t team]\n" ! 175: # else MONITOR ! 176: # define USAGE "usage:\thunt [-csf] [-n name] [-t team]\n" ! 177: # endif MONITOR ! 178: # endif INTERNET ! 179: fputs(USAGE, stderr); ! 180: # undef USAGE ! 181: exit(1); ! 182: } ! 183: } ! 184: # ifdef INTERNET ! 185: if (optind + 1 < ac) ! 186: goto usage; ! 187: else if (optind + 1 == ac) ! 188: Sock_host = av[ac - 1]; ! 189: # else INTERNET ! 190: if (optind > ac) ! 191: goto usage; ! 192: # endif INTERNET ! 193: ! 194: # ifdef INTERNET ! 195: if (Show_scores) { ! 196: SOCKET *hosts; ! 197: ! 198: for (hosts = list_drivers(); hosts->sin_port != 0; hosts += 1) ! 199: dump_scores(*hosts); ! 200: exit(0); ! 201: } ! 202: if (Query_driver) { ! 203: SOCKET *hosts; ! 204: ! 205: for (hosts = list_drivers(); hosts->sin_port != 0; hosts += 1) { ! 206: struct hostent *hp; ! 207: int num_players; ! 208: ! 209: hp = gethostbyaddr((char *) &hosts->sin_addr, ! 210: sizeof hosts->sin_addr, AF_INET); ! 211: num_players = ntohs(hosts->sin_port); ! 212: printf("%d player%s hunting on %s!\n", ! 213: num_players, (num_players == 1) ? "" : "s", ! 214: hp != NULL ? hp->h_name : ! 215: inet_ntoa(hosts->sin_addr)); ! 216: } ! 217: exit(0); ! 218: } ! 219: # endif INTERNET ! 220: # ifdef OTTO ! 221: if (Otto_mode) ! 222: (void) strncpy(name, "otto", NAMELEN); ! 223: else ! 224: # endif OTTO ! 225: fill_in_blanks(); ! 226: ! 227: (void) fflush(stdout); ! 228: if (!isatty(0) || (term = getenv("TERM")) == NULL) { ! 229: fprintf(stderr, "no terminal type\n"); ! 230: exit(1); ! 231: } ! 232: # ifdef TERMINFO ! 233: initscr(); ! 234: (void) noecho(); ! 235: (void) cbreak(); ! 236: # else ! 237: _tty_ch = 0; ! 238: gettmode(); ! 239: (void) setterm(term); ! 240: (void) noecho(); ! 241: (void) cbreak(); ! 242: _puts(TI); ! 243: _puts(VS); ! 244: # endif ! 245: in_visual = TRUE; ! 246: if (LINES < SCREEN_HEIGHT || COLS < SCREEN_WIDTH) ! 247: leave(1, "Need a larger window"); ! 248: clear_the_screen(); ! 249: (void) signal(SIGINT, intr); ! 250: (void) signal(SIGTERM, sigterm); ! 251: (void) signal(SIGEMT, sigemt); ! 252: (void) signal(SIGPIPE, SIG_IGN); ! 253: #ifdef SIGTSTP ! 254: (void) signal(SIGTSTP, tstp); ! 255: #endif ! 256: ! 257: for (;;) { ! 258: { ! 259: register int loop; ! 260: struct timeval start, stop; ! 261: int elapsed_time; ! 262: ! 263: (void) gettimeofday(&start, (struct timezone *) NULL); ! 264: for (loop = 0; loop < LOOP_COUNT; loop++) ! 265: continue; ! 266: (void) gettimeofday(&stop, (struct timezone *) NULL); ! 267: elapsed_time = (stop.tv_sec - start.tv_sec) * 1000000 ! 268: + stop.tv_usec - start.tv_usec; ! 269: if (elapsed_time > LOOP_COUNT * FUDGE_FACTOR) ! 270: leave(1, "Response time too slow"); ! 271: } ! 272: ! 273: # ifdef INTERNET ! 274: find_driver(TRUE); ! 275: ! 276: if (Daemon.sin_port == 0) ! 277: leave(1, "Game not found, try again"); ! 278: ! 279: jump_in: ! 280: do { ! 281: int option; ! 282: ! 283: Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0); ! 284: if (Socket < 0) { ! 285: perror("socket"); ! 286: exit(1); ! 287: } ! 288: option = 1; ! 289: if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK, ! 290: &option, sizeof option) < 0) ! 291: perror("setsockopt loopback"); ! 292: errno = 0; ! 293: if (connect(Socket, (struct sockaddr *) &Daemon, ! 294: DAEMON_SIZE) < 0) { ! 295: if (errno != ECONNREFUSED) { ! 296: perror("connect"); ! 297: leave(1, "connect"); ! 298: } ! 299: } ! 300: else ! 301: break; ! 302: sleep(1); ! 303: } while (close(Socket) == 0); ! 304: # else INTERNET ! 305: /* ! 306: * set up a socket ! 307: */ ! 308: ! 309: if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) { ! 310: perror("socket"); ! 311: exit(1); ! 312: } ! 313: ! 314: /* ! 315: * attempt to connect the socket to a name; if it fails that ! 316: * usually means that the driver isn't running, so we start ! 317: * up the driver. ! 318: */ ! 319: ! 320: Daemon.sun_family = SOCK_FAMILY; ! 321: (void) strcpy(Daemon.sun_path, Sock_name); ! 322: if (connect(Socket, &Daemon, DAEMON_SIZE) < 0) { ! 323: if (errno != ENOENT) { ! 324: perror("connect"); ! 325: leave(1, "connect2"); ! 326: } ! 327: start_driver(); ! 328: ! 329: do { ! 330: (void) close(Socket); ! 331: if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) { ! 332: perror("socket"); ! 333: exit(1); ! 334: } ! 335: sleep(2); ! 336: } while (connect(Socket, &Daemon, DAEMON_SIZE) < 0); ! 337: } ! 338: # endif INTERNET ! 339: ! 340: do_connect(name, team, enter_status); ! 341: # ifdef INTERNET ! 342: if (Send_message != NULL) { ! 343: do_message(); ! 344: if (enter_status == Q_MESSAGE) ! 345: break; ! 346: Send_message = NULL; ! 347: /* don't continue as that will call find_driver */ ! 348: goto jump_in; ! 349: } ! 350: # endif ! 351: playit(); ! 352: if ((enter_status = quit(enter_status)) == Q_QUIT) ! 353: break; ! 354: } ! 355: leave(0, (char *) NULL); ! 356: /* NOTREACHED */ ! 357: } ! 358: ! 359: # ifdef INTERNET ! 360: # ifdef BROADCAST ! 361: broadcast_vec(s, vector) ! 362: int s; /* socket */ ! 363: struct sockaddr **vector; ! 364: { ! 365: char if_buf[BUFSIZ]; ! 366: struct ifconf ifc; ! 367: struct ifreq *ifr; ! 368: unsigned int n; ! 369: int vec_cnt; ! 370: ! 371: *vector = NULL; ! 372: ifc.ifc_len = sizeof if_buf; ! 373: ifc.ifc_buf = if_buf; ! 374: if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) ! 375: return 0; ! 376: vec_cnt = 0; ! 377: n = ifc.ifc_len / sizeof (struct ifreq); ! 378: *vector = (struct sockaddr *) malloc(n * sizeof (struct sockaddr)); ! 379: for (ifr = ifc.ifc_req; n != 0; n--, ifr++) ! 380: if (ioctl(s, SIOCGIFBRDADDR, ifr) >= 0) ! 381: bcopy((char *) &ifr->ifr_addr, ! 382: (char *) &(*vector)[vec_cnt++], ! 383: sizeof (struct sockaddr)); ! 384: return vec_cnt; ! 385: } ! 386: # endif BROADCAST ! 387: ! 388: SOCKET * ! 389: list_drivers() ! 390: { ! 391: int option; ! 392: u_short msg; ! 393: u_short port_num; ! 394: static SOCKET test; ! 395: int test_socket; ! 396: int namelen; ! 397: char local_name[256]; ! 398: static initial = TRUE; ! 399: static struct in_addr local_address; ! 400: register struct hostent *hp; ! 401: extern int errno; ! 402: # ifdef BROADCAST ! 403: static int brdc; ! 404: static SOCKET *brdv; ! 405: # else ! 406: u_long local_net; ! 407: # endif BROADCAST ! 408: int i; ! 409: static SOCKET *listv; ! 410: static unsigned int listmax; ! 411: unsigned int listc; ! 412: int mask; ! 413: struct timeval wait; ! 414: ! 415: if (initial) { /* do one time initialization */ ! 416: # ifndef BROADCAST ! 417: sethostent(1); /* don't bother to close host file */ ! 418: # endif BROADCAST ! 419: if (gethostname(local_name, sizeof local_name) < 0) { ! 420: leave(1, "Sorry, I have no name."); ! 421: /* NOTREACHED */ ! 422: } ! 423: if ((hp = gethostbyname(local_name)) == NULL) { ! 424: leave(1, "Can't find myself."); ! 425: /* NOTREACHED */ ! 426: } ! 427: local_address = * ((struct in_addr *) hp->h_addr); ! 428: ! 429: listmax = 20; ! 430: listv = (SOCKET *) malloc(listmax * sizeof (SOCKET)); ! 431: } else if (Sock_host != NULL) ! 432: return listv; /* address already valid */ ! 433: ! 434: test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0); ! 435: if (test_socket < 0) { ! 436: perror("socket"); ! 437: leave(1, "socket system call failed"); ! 438: /* NOTREACHED */ ! 439: } ! 440: test.sin_family = SOCK_FAMILY; ! 441: test.sin_port = htons(Test_port); ! 442: listc = 0; ! 443: ! 444: if (Sock_host != NULL) { /* explicit host given */ ! 445: if ((hp = gethostbyname(Sock_host)) == NULL) { ! 446: leave(1, "Unknown host"); ! 447: /* NOTREACHED */ ! 448: } ! 449: test.sin_addr = *((struct in_addr *) hp->h_addr); ! 450: goto test_one_host; ! 451: } ! 452: ! 453: if (!initial) { ! 454: /* favor host of previous session by broadcasting to it first */ ! 455: test.sin_addr = Daemon.sin_addr; ! 456: msg = htons(C_PLAYER); /* Must be playing! */ ! 457: (void) sendto(test_socket, (char *) &msg, sizeof msg, 0, ! 458: (struct sockaddr *) &test, DAEMON_SIZE); ! 459: } ! 460: ! 461: # ifdef BROADCAST ! 462: if (initial) ! 463: brdc = broadcast_vec(test_socket, (struct sockaddr **) &brdv); ! 464: ! 465: if (brdc <= 0) { ! 466: initial = FALSE; ! 467: test.sin_addr = local_address; ! 468: goto test_one_host; ! 469: } ! 470: ! 471: # ifdef SO_BROADCAST ! 472: /* Sun's will broadcast even though this option can't be set */ ! 473: option = 1; ! 474: if (setsockopt(test_socket, SOL_SOCKET, SO_BROADCAST, ! 475: (int) &option, sizeof option) < 0) { ! 476: perror("setsockopt broadcast"); ! 477: leave(1, "setsockopt broadcast"); ! 478: /* NOTREACHED */ ! 479: } ! 480: # endif ! 481: ! 482: /* send broadcast packets on all interfaces */ ! 483: msg = htons(C_TESTMSG()); ! 484: for (i = 0; i < brdc; i++) { ! 485: test.sin_addr = brdv[i].sin_addr; ! 486: if (sendto(test_socket, (char *) &msg, sizeof msg, 0, ! 487: (struct sockaddr *) &test, DAEMON_SIZE) < 0) { ! 488: perror("sendto"); ! 489: leave(1, "sendto"); ! 490: /* NOTREACHED */ ! 491: } ! 492: } ! 493: # else BROADCAST ! 494: /* loop thru all hosts on local net and send msg to them. */ ! 495: msg = htons(C_TESTMSG()); ! 496: local_net = inet_netof(local_address); ! 497: sethostent(0); /* rewind host file */ ! 498: while (hp = gethostent()) { ! 499: if (local_net == inet_netof(* ((struct in_addr *) hp->h_addr))){ ! 500: test.sin_addr = * ((struct in_addr *) hp->h_addr); ! 501: (void) sendto(test_socket, (char *) &msg, sizeof msg, 0, ! 502: (struct sockaddr *) &test, DAEMON_SIZE); ! 503: } ! 504: } ! 505: # endif BROADCAST ! 506: ! 507: get_response: ! 508: namelen = DAEMON_SIZE; ! 509: errno = 0; ! 510: wait.tv_sec = 1; ! 511: wait.tv_usec = 0; ! 512: for (;;) { ! 513: if (listc + 1 >= listmax) { ! 514: listmax += 20; ! 515: listv = (SOCKET *) realloc((char *) listv, ! 516: listmax * sizeof(SOCKET)); ! 517: } ! 518: ! 519: mask = 1 << test_socket; ! 520: if (select(test_socket + 1, &mask, NULL, NULL, &wait) == 1 ! 521: && recvfrom(test_socket, (char *) &port_num, sizeof port_num, ! 522: 0, (struct sockaddr *) &listv[listc], &namelen) > 0) { ! 523: /* ! 524: * Note that we do *not* convert from network to host ! 525: * order since the port number *should* be in network ! 526: * order: ! 527: */ ! 528: for (i = 0; i < listc; i += 1) ! 529: if (listv[listc].sin_addr.s_addr ! 530: == listv[i].sin_addr.s_addr) ! 531: break; ! 532: if (i == listc) ! 533: listv[listc++].sin_port = port_num; ! 534: continue; ! 535: } ! 536: ! 537: if (errno != 0 && errno != EINTR) { ! 538: perror("select/recvfrom"); ! 539: leave(1, "select/recvfrom"); ! 540: /* NOTREACHED */ ! 541: } ! 542: ! 543: /* terminate list with local address */ ! 544: listv[listc].sin_family = SOCK_FAMILY; ! 545: listv[listc].sin_addr = local_address; ! 546: listv[listc].sin_port = htons(0); ! 547: ! 548: (void) close(test_socket); ! 549: initial = FALSE; ! 550: return listv; ! 551: } ! 552: ! 553: test_one_host: ! 554: msg = htons(C_TESTMSG()); ! 555: (void) sendto(test_socket, (char *) &msg, sizeof msg, 0, ! 556: (struct sockaddr *) &test, DAEMON_SIZE); ! 557: goto get_response; ! 558: } ! 559: ! 560: find_driver(do_startup) ! 561: FLAG do_startup; ! 562: { ! 563: SOCKET *hosts; ! 564: ! 565: hosts = list_drivers(); ! 566: if (hosts[0].sin_port != htons(0)) { ! 567: int i, c; ! 568: ! 569: if (hosts[1].sin_port == htons(0)) { ! 570: Daemon = hosts[0]; ! 571: return; ! 572: } ! 573: /* go thru list and return host that matches daemon */ ! 574: clear_the_screen(); ! 575: mvcur(cur_row, cur_col, 1, 0); ! 576: cur_row = 1; ! 577: cur_col = 0; ! 578: put_str("Pick one:"); ! 579: for (i = 0; i < HEIGHT - 4 && hosts[i].sin_port != htons(0); ! 580: i += 1) { ! 581: struct hostent *hp; ! 582: char buf[80]; ! 583: ! 584: mvcur(cur_row, cur_col, 3 + i, 0); ! 585: cur_row = 3 + i; ! 586: cur_col = 0; ! 587: hp = gethostbyaddr((char *) &hosts[i].sin_addr, ! 588: sizeof hosts[i].sin_addr, AF_INET); ! 589: (void) sprintf(buf, "%8c %.64s", 'a' + i, ! 590: hp != NULL ? hp->h_name ! 591: : inet_ntoa(hosts->sin_addr)); ! 592: put_str(buf); ! 593: } ! 594: mvcur(cur_row, cur_col, 4 + i, 0); ! 595: cur_row = 4 + i; ! 596: cur_col = 0; ! 597: put_str("Enter letter: "); ! 598: (void) fflush(stdout); ! 599: while (!islower(c = getchar()) || (c -= 'a') >= i) { ! 600: (void) putchar(CTRL(G)); ! 601: (void) fflush(stdout); ! 602: } ! 603: Daemon = hosts[c]; ! 604: clear_the_screen(); ! 605: return; ! 606: } ! 607: if (!do_startup) ! 608: return; ! 609: ! 610: start_driver(); ! 611: sleep(2); ! 612: find_driver(FALSE); ! 613: } ! 614: ! 615: dump_scores(host) ! 616: SOCKET host; ! 617: { ! 618: struct hostent *hp; ! 619: int s; ! 620: char buf[BUFSIZ]; ! 621: int cnt; ! 622: ! 623: hp = gethostbyaddr((char *) &host.sin_addr, sizeof host.sin_addr, ! 624: AF_INET); ! 625: printf("\n%s:\n", hp != NULL ? hp->h_name : inet_ntoa(host.sin_addr)); ! 626: fflush(stdout); ! 627: ! 628: s = socket(SOCK_FAMILY, SOCK_STREAM, 0); ! 629: if (s < 0) { ! 630: perror("socket"); ! 631: exit(1); ! 632: } ! 633: if (connect(s, (struct sockaddr *) &host, sizeof host) < 0) { ! 634: perror("connect"); ! 635: exit(1); ! 636: } ! 637: while ((cnt = read(s, buf, BUFSIZ)) > 0) ! 638: write(fileno(stdout), buf, cnt); ! 639: (void) close(s); ! 640: } ! 641: ! 642: # endif INTERNET ! 643: ! 644: start_driver() ! 645: { ! 646: register int procid; ! 647: ! 648: # ifdef MONITOR ! 649: if (Am_monitor) { ! 650: leave(1, "No one playing."); ! 651: /* NOTREACHED */ ! 652: } ! 653: # endif MONITOR ! 654: ! 655: # ifdef INTERNET ! 656: if (Sock_host != NULL) { ! 657: sleep(3); ! 658: return; ! 659: } ! 660: # endif INTERNET ! 661: ! 662: mvcur(cur_row, cur_col, 23, 0); ! 663: cur_row = 23; ! 664: cur_col = 0; ! 665: put_str("Starting..."); ! 666: (void) fflush(stdout); ! 667: # ifndef BSD_RELEASE ! 668: procid = fork(); ! 669: # else ! 670: procid = vfork(); ! 671: # endif ! 672: if (procid == -1) { ! 673: perror("fork"); ! 674: leave(1, "fork failed."); ! 675: } ! 676: if (procid == 0) { ! 677: (void) signal(SIGINT, SIG_IGN); ! 678: # ifndef INTERNET ! 679: (void) close(Socket); ! 680: # else ! 681: if (use_port == NULL) ! 682: # endif ! 683: execl(Driver, "HUNT", (char *) NULL); ! 684: # ifdef INTERNET ! 685: else ! 686: execl(Driver, "HUNT", "-p", use_port, (char *) NULL); ! 687: # endif ! 688: /* only get here if exec failed */ ! 689: (void) kill(getppid(), SIGEMT); /* tell mom */ ! 690: _exit(1); ! 691: } ! 692: mvcur(cur_row, cur_col, 23, 0); ! 693: cur_row = 23; ! 694: cur_col = 0; ! 695: put_str("Connecting..."); ! 696: (void) fflush(stdout); ! 697: } ! 698: ! 699: /* ! 700: * bad_con: ! 701: * We had a bad connection. For the moment we assume that this ! 702: * means the game is full. ! 703: */ ! 704: bad_con() ! 705: { ! 706: leave(1, "The game is full. Sorry."); ! 707: /* NOTREACHED */ ! 708: } ! 709: ! 710: /* ! 711: * bad_ver: ! 712: * version number mismatch. ! 713: */ ! 714: bad_ver() ! 715: { ! 716: leave(1, "Version number mismatch. No go."); ! 717: /* NOTREACHED */ ! 718: } ! 719: ! 720: /* ! 721: * sigterm: ! 722: * Handle a terminate signal ! 723: */ ! 724: sigterm() ! 725: { ! 726: leave(0, (char *) NULL); ! 727: /* NOTREACHED */ ! 728: } ! 729: ! 730: ! 731: /* ! 732: * sigemt: ! 733: * Handle a emt signal - shouldn't happen on vaxes(?) ! 734: */ ! 735: sigemt() ! 736: { ! 737: leave(1, "Unable to start driver. Try again."); ! 738: /* NOTREACHED */ ! 739: } ! 740: ! 741: # ifdef INTERNET ! 742: /* ! 743: * sigalrm: ! 744: * Handle an alarm signal ! 745: */ ! 746: sigalrm() ! 747: { ! 748: return; ! 749: } ! 750: # endif INTERNET ! 751: ! 752: /* ! 753: * rmnl: ! 754: * Remove a '\n' at the end of a string if there is one ! 755: */ ! 756: rmnl(s) ! 757: char *s; ! 758: { ! 759: register char *cp; ! 760: char *rindex(); ! 761: ! 762: cp = rindex(s, '\n'); ! 763: if (cp != NULL) ! 764: *cp = '\0'; ! 765: } ! 766: ! 767: /* ! 768: * intr: ! 769: * Handle a interrupt signal ! 770: */ ! 771: intr() ! 772: { ! 773: register int ch; ! 774: register int explained; ! 775: register int y, x; ! 776: ! 777: (void) signal(SIGINT, SIG_IGN); ! 778: y = cur_row; ! 779: x = cur_col; ! 780: mvcur(cur_row, cur_col, 23, 0); ! 781: cur_row = 23; ! 782: cur_col = 0; ! 783: put_str("Really quit? "); ! 784: clear_eol(); ! 785: (void) fflush(stdout); ! 786: explained = FALSE; ! 787: for (;;) { ! 788: ch = getchar(); ! 789: if (isupper(ch)) ! 790: ch = tolower(ch); ! 791: if (ch == 'y') { ! 792: if (Socket != 0) { ! 793: (void) write(Socket, "q", 1); ! 794: (void) close(Socket); ! 795: } ! 796: leave(0, (char *) NULL); ! 797: } ! 798: else if (ch == 'n') { ! 799: (void) signal(SIGINT, intr); ! 800: mvcur(cur_row, cur_col, y, x); ! 801: cur_row = y; ! 802: cur_col = x; ! 803: (void) fflush(stdout); ! 804: return; ! 805: } ! 806: if (!explained) { ! 807: put_str("(Yes or No) "); ! 808: (void) fflush(stdout); ! 809: explained = TRUE; ! 810: } ! 811: (void) putchar(CTRL(G)); ! 812: (void) fflush(stdout); ! 813: } ! 814: } ! 815: ! 816: /* ! 817: * leave: ! 818: * Leave the game somewhat gracefully, restoring all current ! 819: * tty stats. ! 820: */ ! 821: leave(eval, mesg) ! 822: int eval; ! 823: char *mesg; ! 824: { ! 825: if (in_visual) { ! 826: mvcur(cur_row, cur_col, 23, 0); ! 827: (void) fflush(stdout); /* flush in case VE changes pages */ ! 828: # ifdef TERMINFO ! 829: putp(cursor_normal); ! 830: putp(exit_ca_mode); ! 831: reset_shell_mode(); ! 832: # else ! 833: resetty(); ! 834: _puts(VE); ! 835: _puts(TE); ! 836: # endif ! 837: } ! 838: if (mesg != NULL) ! 839: puts(mesg); ! 840: exit(eval); ! 841: } ! 842: ! 843: #ifdef SIGTSTP ! 844: /* ! 845: * tstp: ! 846: * Handle stop and start signals ! 847: */ ! 848: tstp() ! 849: { ! 850: # ifndef TERMINFO ! 851: static struct sgttyb tty; ! 852: # endif ! 853: int y, x; ! 854: ! 855: y = cur_row; ! 856: x = cur_col; ! 857: mvcur(cur_row, cur_col, 23, 0); ! 858: cur_row = 23; ! 859: cur_col = 0; ! 860: # ifdef TERMINFO ! 861: putp(cursor_normal); ! 862: putp(exit_ca_mode); ! 863: reset_shell_mode(); ! 864: # else ! 865: tty = _tty; ! 866: _puts(VE); ! 867: _puts(TE); ! 868: (void) fflush(stdout); ! 869: resetty(); ! 870: # endif ! 871: (void) kill(getpid(), SIGSTOP); ! 872: (void) signal(SIGTSTP, tstp); ! 873: # ifdef TERMINFO ! 874: reset_prog_mode(); ! 875: putp(enter_ca_mode); ! 876: putp(cursor_visible); ! 877: # else ! 878: _tty = tty; ! 879: ioctl(_tty_ch, TIOCSETP, &_tty); ! 880: _puts(TI); ! 881: _puts(VS); ! 882: # endif ! 883: cur_row = y; ! 884: cur_col = x; ! 885: # ifdef TERMINFO ! 886: putp(tgoto(CM, cur_row, cur_col)); ! 887: # else ! 888: _puts(tgoto(CM, cur_row, cur_col)); ! 889: # endif ! 890: redraw_screen(); ! 891: (void) fflush(stdout); ! 892: } ! 893: #endif ! 894: ! 895: long ! 896: env_init(enter_status) ! 897: long enter_status; ! 898: { ! 899: register int i; ! 900: char *envp, *envname, *s, *index(), *strpbrk(); ! 901: ! 902: for (i = 0; i < 256; i++) ! 903: map_key[i] = (char) i; ! 904: ! 905: envname = NULL; ! 906: if ((envp = getenv("HUNT")) != NULL) { ! 907: while ((s = strpbrk(envp, "=,")) != NULL) { ! 908: if (strncmp(envp, "cloak,", s - envp + 1) == 0) { ! 909: enter_status = Q_CLOAK; ! 910: envp = s + 1; ! 911: } ! 912: else if (strncmp(envp, "scan,", s - envp + 1) == 0) { ! 913: enter_status = Q_SCAN; ! 914: envp = s + 1; ! 915: } ! 916: else if (strncmp(envp, "fly,", s - envp + 1) == 0) { ! 917: enter_status = Q_FLY; ! 918: envp = s + 1; ! 919: } ! 920: else if (strncmp(envp, "nobeep,", s - envp + 1) == 0) { ! 921: no_beep = TRUE; ! 922: envp = s + 1; ! 923: } ! 924: else if (strncmp(envp, "name=", s - envp + 1) == 0) { ! 925: envname = s + 1; ! 926: if ((s = index(envp, ',')) == NULL) { ! 927: *envp = '\0'; ! 928: strncpy(name, envname, NAMELEN); ! 929: break; ! 930: } ! 931: *s = '\0'; ! 932: strncpy(name, envname, NAMELEN); ! 933: envp = s + 1; ! 934: } ! 935: # ifdef INTERNET ! 936: else if (strncmp(envp, "port=", s - envp + 1) == 0) { ! 937: use_port = s + 1; ! 938: Test_port = atoi(use_port); ! 939: if ((s = index(envp, ',')) == NULL) { ! 940: *envp = '\0'; ! 941: break; ! 942: } ! 943: *s = '\0'; ! 944: envp = s + 1; ! 945: } ! 946: else if (strncmp(envp, "host=", s - envp + 1) == 0) { ! 947: Sock_host = s + 1; ! 948: if ((s = index(envp, ',')) == NULL) { ! 949: *envp = '\0'; ! 950: break; ! 951: } ! 952: *s = '\0'; ! 953: envp = s + 1; ! 954: } ! 955: else if (strncmp(envp, "message=", s - envp + 1) == 0) { ! 956: Send_message = s + 1; ! 957: if ((s = index(envp, ',')) == NULL) { ! 958: *envp = '\0'; ! 959: break; ! 960: } ! 961: *s = '\0'; ! 962: envp = s + 1; ! 963: } ! 964: # endif ! 965: else if (strncmp(envp, "team=", s - envp + 1) == 0) { ! 966: team = *(s + 1); ! 967: if (!isdigit(team)) ! 968: team = ' '; ! 969: if ((s = index(envp, ',')) == NULL) { ! 970: *envp = '\0'; ! 971: break; ! 972: } ! 973: *s = '\0'; ! 974: envp = s + 1; ! 975: } /* must be last option */ ! 976: else if (strncmp(envp, "mapkey=", s - envp + 1) == 0) { ! 977: for (s = s + 1; *s != '\0'; s += 2) { ! 978: map_key[(unsigned int) *s] = *(s + 1); ! 979: if (*(s + 1) == '\0') { ! 980: break; ! 981: } ! 982: } ! 983: *envp = '\0'; ! 984: break; ! 985: } else { ! 986: *s = '\0'; ! 987: printf("unknown option %s\n", envp); ! 988: if ((s = index(envp, ',')) == NULL) { ! 989: *envp = '\0'; ! 990: break; ! 991: } ! 992: envp = s + 1; ! 993: } ! 994: } ! 995: if (*envp != '\0') ! 996: if (envname == NULL) ! 997: strncpy(name, envp, NAMELEN); ! 998: else ! 999: printf("unknown option %s\n", envp); ! 1000: } ! 1001: return enter_status; ! 1002: } ! 1003: ! 1004: fill_in_blanks() ! 1005: { ! 1006: register int i; ! 1007: register char *cp; ! 1008: ! 1009: again: ! 1010: if (name[0] != '\0') { ! 1011: printf("Entering as '%s'", name); ! 1012: if (team != ' ') ! 1013: printf(" on team %c.\n", team); ! 1014: else ! 1015: putchar('\n'); ! 1016: } else { ! 1017: printf("Enter your code name: "); ! 1018: if (fgets(name, NAMELEN, stdin) == NULL) ! 1019: exit(1); ! 1020: } ! 1021: rmnl(name); ! 1022: if (name[0] == '\0') { ! 1023: name[0] = '\0'; ! 1024: printf("You have to have a code name!\n"); ! 1025: goto again; ! 1026: } ! 1027: for (cp = name; *cp != '\0'; cp++) ! 1028: if (!isprint(*cp)) { ! 1029: name[0] = '\0'; ! 1030: printf("Illegal character in your code name.\n"); ! 1031: goto again; ! 1032: } ! 1033: if (team == ' ') { ! 1034: printf("Enter your team (0-9 or nothing): "); ! 1035: i = getchar(); ! 1036: if (isdigit(i)) ! 1037: team = i; ! 1038: while (i != '\n' && i != EOF) ! 1039: i = getchar(); ! 1040: } ! 1041: } ! 1042: ! 1043: # ifdef BSD_RELEASE ! 1044: # if BSD_RELEASE < 43 ! 1045: char * ! 1046: strpbrk(s, brk) ! 1047: register char *s, *brk; ! 1048: { ! 1049: register char *p; ! 1050: register c; ! 1051: ! 1052: while (c = *s) { ! 1053: for (p = brk; *p; p++) ! 1054: if (c == *p) ! 1055: return (s); ! 1056: s++; ! 1057: } ! 1058: return (0); ! 1059: } ! 1060: # endif ! 1061: # endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.