|
|
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.