Annotation of 43BSDReno/games/hunt/NEW/hunt.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.