static void dump_scores(const struct sockaddr_storage *host, socklen_t hostlen) { int s; char buf[BUFSIZ]; ssize_t cnt; printf("\n%s:\n", lookuphost(host, hostlen)); fflush(stdout); s = socket(host->ss_family, SOCK_STREAM, 0); if (s < 0) err(1, "socket"); if (connect(s, (const struct sockaddr *)host, hostlen) < 0) err(1, "connect"); while ((cnt = read(s, buf, BUFSIZ)) > 0) write(fileno(stdout), buf, cnt); (void) close(s); }
long cswrite(Chan *c, void *a, long n, vlong offset) { char *f[4]; char *s, *ns; ulong ip; int nf, port; s = malloc(n+1); if(s == nil) error(Enomem); if(waserror()){ free(s); nexterror(); } memmove(s, a, n); s[n] = 0; nf = getfields(s, f, nelem(f), 0, "!"); if(nf != 3) error("can't translate"); port = lookupport(f[2]); if(port <= 0) error("no translation for port found"); ip = lookuphost(f[1]); if(ip == 0) error("no translation for host found"); ns = smprint("/net/%s/clone %I!%d", f[0], ip, port); if(ns == nil) error(Enomem); free(c->aux); c->aux = ns; poperror(); free(s); return n; }
static void find_driver(void) { u_short msg; const struct sockaddr_storage *host; socklen_t hostlen; unsigned num; int i, c; msg = C_PLAYER; #ifdef MONITOR if (Am_monitor) { msg = C_MONITOR; } #endif serverlist_query(msg); num = serverlist_num(); if (num == 0) { start_driver(); sleep(2); /* try again */ serverlist_query(msg); num = serverlist_num(); if (num == 0) { /* give up */ return; } } if (num == 1) { host = serverlist_gethost(0, &hostlen); } else { clear_the_screen(); move(1, 0); addstr("Pick one:"); for (i = 0; i < HEIGHT - 4 && i < (int)num; i++) { move(3 + i, 0); host = serverlist_gethost(i, &hostlen); printw("%8c %.64s", 'a' + i, lookuphost(host, hostlen)); } move(4 + i, 0); addstr("Enter letter: "); refresh(); while (1) { c = getchar(); if (c == EOF) { leavex(1, "EOF on stdin"); } if (islower((unsigned char)c) && c - 'a' < i) { break; } beep(); refresh(); } clear_the_screen(); host = serverlist_gethost(c - 'a', &hostlen); } /* XXX fix this (won't work in ipv6) */ assert(hostlen == sizeof(Daemon)); memcpy(&Daemon, host, sizeof(Daemon)); }
/* * main: * Main program for local process */ int main(int ac, char **av) { char *term; int c; int enter_status; bool Query_driver = false; bool Show_scores = false; enter_status = env_init(Q_CLOAK); while ((c = getopt(ac, av, "Sbcfh:l:mn:op:qst:w:")) != -1) { switch (c) { case 'l': /* rsh compatibility */ case 'n': (void) strncpy(name, optarg, sizeof(name)); break; case 't': team = *optarg; if (!isdigit((unsigned char)team)) { warnx("Team names must be numeric"); team = ' '; } break; case 'o': #ifndef OTTO warnx("The -o flag is reserved for future use."); goto usage; #else Otto_mode = true; break; #endif case 'm': #ifdef MONITOR Am_monitor = true; #else warnx("The monitor was not compiled in."); #endif break; #ifdef INTERNET case 'S': Show_scores = true; break; case 'q': /* query whether hunt is running */ Query_driver = true; break; case 'w': Send_message = optarg; break; case 'h': contacthost = optarg; break; case 'p': contactportstr = optarg; contactport = atoi(contactportstr); break; #else case 'S': case 'q': case 'w': case 'h': case 'p': wanrx("Need TCP/IP for S, q, w, h, and p options."); break; #endif case 'c': enter_status = Q_CLOAK; break; case 'f': #ifdef FLY enter_status = Q_FLY; #else warnx("The flying code was not compiled in."); #endif break; case 's': enter_status = Q_SCAN; break; case 'b': no_beep = !no_beep; break; default: usage: fputs( "usage:\thunt [-qmcsfS] [-n name] [-t team] [-p port] [-w message] [host]\n", stderr); exit(1); } } #ifdef INTERNET if (optind + 1 < ac) goto usage; else if (optind + 1 == ac) contacthost = av[ac - 1]; #else if (optind < ac) goto usage; #endif #ifdef INTERNET serverlist_setup(contacthost, contactport); if (Show_scores) { const struct sockaddr_storage *host; socklen_t hostlen; u_short msg = C_SCORES; unsigned i; serverlist_query(msg); for (i = 0; i < serverlist_num(); i++) { host = serverlist_gethost(i, &hostlen); dump_scores(host, hostlen); } exit(0); } if (Query_driver) { const struct sockaddr_storage *host; socklen_t hostlen; u_short msg = C_MESSAGE; u_short num_players; unsigned i; serverlist_query(msg); for (i = 0; i < serverlist_num(); i++) { host = serverlist_gethost(i, &hostlen); num_players = ntohs(serverlist_getresponse(i)); printf("%d player%s hunting on %s!\n", num_players, (num_players == 1) ? "" : "s", lookuphost(host, hostlen)); } exit(0); } #endif #ifdef OTTO if (Otto_mode) (void) strncpy(name, "otto", sizeof(name)); else #endif fill_in_blanks(); (void) fflush(stdout); if (!isatty(0) || (term = getenv("TERM")) == NULL) errx(1, "no terminal type"); if (!initscr()) errx(0, "couldn't initialize screen"); (void) noecho(); (void) cbreak(); in_visual = true; if (LINES < SCREEN_HEIGHT || COLS < SCREEN_WIDTH) leavex(1, "Need a larger window"); clear_the_screen(); (void) signal(SIGINT, intr); (void) signal(SIGTERM, sigterm); (void) signal(SIGUSR1, sigusr1); (void) signal(SIGPIPE, SIG_IGN); for (;;) { #ifdef INTERNET find_driver(); if (Daemon.sin_port == 0) leavex(1, "Game not found, try again"); jump_in: do { int option; huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0); if (huntsocket < 0) err(1, "socket"); option = 1; if (setsockopt(huntsocket, SOL_SOCKET, SO_USELOOPBACK, &option, sizeof option) < 0) warn("setsockopt loopback"); errno = 0; if (connect(huntsocket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) { if (errno != ECONNREFUSED) { leave(1, "connect"); } } else break; sleep(1); } while (close(huntsocket) == 0); #else /* !INTERNET */ /* * set up a socket */ if ((huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) err(1, "socket"); /* * attempt to connect the socket to a name; if it fails that * usually means that the driver isn't running, so we start * up the driver. */ Daemon.sun_family = SOCK_FAMILY; (void) strcpy(Daemon.sun_path, huntsockpath); if (connect(huntsocket, &Daemon, DAEMON_SIZE) < 0) { if (errno != ENOENT) { leavex(1, "connect2"); } start_driver(); do { (void) close(huntsocket); if ((huntsocket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) err(1, "socket"); sleep(2); } while (connect(huntsocket, &Daemon, DAEMON_SIZE) < 0); } #endif do_connect(name, sizeof(name), team, enter_status); #ifdef INTERNET if (Send_message != NULL) { do_message(); if (enter_status == Q_MESSAGE) break; Send_message = NULL; /* don't continue as that will call find_driver */ goto jump_in; } #endif playit(); if ((enter_status = quit(enter_status)) == Q_QUIT) break; } leavex(0, NULL); /* NOTREACHED */ return(0); }
TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) { TCPSTREAM *stream = NIL; struct sockaddr_in sin; int sock; char *s,tmp[MAILTMPLEN]; port &= 0xffff; /* erase flags */ /* The domain literal form is used (rather than simply the dotted decimal as with other Unix programs) because it has to be a valid "host name" in mailsystem terminology. */ sin.sin_family = AF_INET; /* family is always Internet */ /* look like domain literal? */ if (host[0] == '[' && host[(strlen (host))-1] == ']') { strcpy (tmp,host+1); /* yes, copy number part */ tmp[strlen (tmp)-1] = '\0'; if ((sin.sin_addr.s_addr = inet_addr (tmp)) == -1) { sprintf (tmp,"Bad format domain-literal: %.80s",host); mm_log (tmp,ERROR); return NIL; } } /* look up host name */ else if (!lookuphost (&host,&sin)) { sprintf (tmp,"Host not found: %s",host); mm_log (tmp,ERROR); return NIL; } /* copy port number in network format */ if (!(sin.sin_port = htons (port))) fatal ("Bad port argument to tcp_open"); /* get a TCP stream */ if ((sock = socket (sin.sin_family,SOCK_STREAM,0)) < 0) { sprintf (tmp,"Unable to create TCP socket (%d)",errno); mm_log (tmp,ERROR); fs_give ((void **) &host); return NIL; } #if 0 /* needed? */ else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */ sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)", sock,FD_SETSIZE); close (sock); errno = ENOBUFS; /* just in case */ return NIL; } #endif /* open connection */ if (connect (sock,(struct sockaddr *) &sin,sizeof (sin)) < 0) { switch (errno) { /* analyze error */ case ECONNREFUSED: s = "Refused"; break; case ENOBUFS: s = "Insufficient system resources"; break; case ETIMEDOUT: s = "Timed out"; break; default: s = "Unknown error"; break; } sprintf (tmp,"Can't connect to %.80s,%ld: %s (%d)",host,port,s,errno); mm_log (tmp,ERROR); close (sock); fs_give ((void **) &host); return NIL; } /* create TCP/IP stream */ stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM)); stream->host = host; /* official host name */ stream->localhost = cpystr (mylocalhost ()); stream->port = port; /* port number */ stream->tcps = sock; /* init socket */ stream->ictr = 0; /* init input counter */ return stream; /* return success */ }