summaryrefslogtreecommitdiffstats
path: root/hunt
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2014-03-30 02:26:09 +0000
committerdholland <dholland@NetBSD.org>2014-03-30 02:26:09 +0000
commit1f6302b1815a3f7936f23ba89822b55e4705d6e7 (patch)
tree6faa4fb042006f48bfeaec569572354d5498f801 /hunt
parentacab9d9e10a833b800e8722c81c902a170f427bf (diff)
downloadbsdgames-darwin-1f6302b1815a3f7936f23ba89822b55e4705d6e7.tar.gz
bsdgames-darwin-1f6302b1815a3f7936f23ba89822b55e4705d6e7.tar.zst
bsdgames-darwin-1f6302b1815a3f7936f23ba89822b55e4705d6e7.zip
split off a bunch of the nastier network code into its own file
Diffstat (limited to 'hunt')
-rw-r--r--hunt/hunt/Makefile4
-rw-r--r--hunt/hunt/hunt.c203
-rw-r--r--hunt/hunt/hunt_private.h18
-rw-r--r--hunt/hunt/server.c235
4 files changed, 263 insertions, 197 deletions
diff --git a/hunt/hunt/Makefile b/hunt/hunt/Makefile
index 2279cc19..602b31fd 100644
--- a/hunt/hunt/Makefile
+++ b/hunt/hunt/Makefile
@@ -1,7 +1,7 @@
-# $NetBSD: Makefile,v 1.8 2014/03/29 21:24:26 dholland Exp $
+# $NetBSD: Makefile,v 1.9 2014/03/30 02:26:09 dholland Exp $
PROG= hunt
-SRCS= connect.c hunt.c otto.c playit.c
+SRCS= connect.c hunt.c otto.c playit.c server.c
MAN= hunt.6
LDADD= -lcurses -lterminfo
DPADD= ${LIBCURSES} ${LIBTERMINFO}
diff --git a/hunt/hunt/hunt.c b/hunt/hunt/hunt.c
index 4cd9d7a5..8f577b27 100644
--- a/hunt/hunt/hunt.c
+++ b/hunt/hunt/hunt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hunt.c,v 1.47 2014/03/29 22:15:13 dholland Exp $ */
+/* $NetBSD: hunt.c,v 1.48 2014/03/30 02:26:09 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
* All rights reserved.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: hunt.c,v 1.47 2014/03/29 22:15:13 dholland Exp $");
+__RCSID("$NetBSD: hunt.c,v 1.48 2014/03/30 02:26:09 dholland Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -64,7 +64,7 @@ static const char Driver[] = PATH_HUNTD;
#endif
#ifdef INTERNET
-static uint16_t Test_port = TEST_PORT;
+uint16_t Test_port = TEST_PORT;
#else
static const char Sock_name[] = PATH_HUNTSOCKET;
#endif
@@ -79,14 +79,14 @@ char Buf[BUFSIZ];
/*static*/ int Socket;
#ifdef INTERNET
-static char *Sock_host;
+char *Sock_host;
static char *use_port;
-static bool Query_driver = false;
+bool Query_driver = false;
char *Send_message = NULL;
-static bool Show_scores = false;
+bool Show_scores = false;
#endif
-static SOCKET Daemon;
+SOCKET Daemon;
#ifdef INTERNET
#define DAEMON_SIZE (sizeof Daemon)
#else
@@ -106,18 +106,12 @@ extern int cur_row, cur_col;
static void dump_scores(SOCKET);
static long env_init(long);
static void fill_in_blanks(void);
-static void leave(int, const char *) __dead;
-static void leavex(int, const char *) __dead;
static void fincurs(void);
static void rmnl(char *);
static void sigterm(int) __dead;
static void sigusr1(int) __dead;
static void find_driver(bool);
static void start_driver(void);
-static int broadcast_vec(int, struct sockaddr_in **);
-#ifdef INTERNET
-static SOCKET *list_drivers(void);
-#endif
extern int Otto_mode;
/*
@@ -351,185 +345,6 @@ main(int ac, char **av)
}
#ifdef INTERNET
-static int
-broadcast_vec(int s /*socket*/, struct sockaddr_in **vector)
-{
- int vec_cnt;
- struct ifaddrs *ifp, *ip;
-
- *vector = NULL;
- if (getifaddrs(&ifp) < 0)
- return 0;
-
- vec_cnt = 0;
- for (ip = ifp; ip; ip = ip->ifa_next)
- if ((ip->ifa_addr->sa_family == AF_INET) &&
- (ip->ifa_flags & IFF_BROADCAST))
- vec_cnt++;
-
- *vector = malloc(vec_cnt * sizeof(struct sockaddr_in));
-
- vec_cnt = 0;
- for (ip = ifp; ip; ip = ip->ifa_next)
- if ((ip->ifa_addr->sa_family == AF_INET) &&
- (ip->ifa_flags & IFF_BROADCAST))
- memcpy(&(*vector)[vec_cnt++], ip->ifa_broadaddr,
- sizeof(struct sockaddr_in));
-
- freeifaddrs(ifp);
- return vec_cnt;
-}
-
-static SOCKET *
-list_drivers(void)
-{
- int option;
- u_short msg;
- u_short port_num;
- static SOCKET test;
- int test_socket;
- socklen_t namelen;
- char local_name[MAXHOSTNAMELEN + 1];
- static bool initial = true;
- static struct in_addr local_address;
- struct hostent *hp;
- static int brdc;
- static SOCKET *brdv;
- int i;
- unsigned j;
- static SOCKET *listv;
- static unsigned int listmax;
- unsigned int listc;
- struct pollfd set[1];
-
- if (initial) { /* do one time initialization */
- if (gethostname(local_name, sizeof local_name) < 0) {
- leavex(1, "Sorry, I have no name.");
- /* NOTREACHED */
- }
- local_name[sizeof(local_name) - 1] = '\0';
- if ((hp = gethostbyname(local_name)) == NULL) {
- leavex(1, "Can't find myself.");
- /* NOTREACHED */
- }
- local_address = * ((struct in_addr *) hp->h_addr);
-
- listmax = 20;
- listv = (SOCKET *) malloc(listmax * sizeof (SOCKET));
- } else if (Sock_host != NULL)
- return listv; /* address already valid */
-
- test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
- if (test_socket < 0) {
- leave(1, "socket system call failed");
- /* NOTREACHED */
- }
- test.sin_family = SOCK_FAMILY;
- test.sin_port = htons(Test_port);
- listc = 0;
-
- if (Sock_host != NULL) { /* explicit host given */
- if ((hp = gethostbyname(Sock_host)) == NULL) {
- leavex(1, "Unknown host");
- /* NOTREACHED */
- }
- test.sin_addr = *((struct in_addr *) hp->h_addr);
- goto test_one_host;
- }
-
- if (!initial) {
- /* favor host of previous session by broadcasting to it first */
- test.sin_addr = Daemon.sin_addr;
- msg = htons(C_PLAYER); /* Must be playing! */
- (void) sendto(test_socket, &msg, sizeof msg, 0,
- (struct sockaddr *) &test, DAEMON_SIZE);
- }
-
- if (initial)
- brdc = broadcast_vec(test_socket, &brdv);
-
-#ifdef SO_BROADCAST
- /* Sun's will broadcast even though this option can't be set */
- option = 1;
- if (setsockopt(test_socket, SOL_SOCKET, SO_BROADCAST,
- &option, sizeof option) < 0) {
- leave(1, "setsockopt broadcast");
- /* NOTREACHED */
- }
-#endif
-
- /* send broadcast packets on all interfaces */
- msg = htons(C_TESTMSG());
- for (i = 0; i < brdc; i++) {
- test.sin_addr = brdv[i].sin_addr;
- if (sendto(test_socket, &msg, sizeof msg, 0,
- (struct sockaddr *) &test, DAEMON_SIZE) < 0) {
- leave(1, "sendto");
- /* NOTREACHED */
- }
- }
- test.sin_addr = local_address;
- if (sendto(test_socket, &msg, sizeof msg, 0,
- (struct sockaddr *) &test, DAEMON_SIZE) < 0) {
- leave(1, "sendto");
- /* NOTREACHED */
- }
-
-get_response:
- namelen = DAEMON_SIZE;
- errno = 0;
- set[0].fd = test_socket;
- set[0].events = POLLIN;
- for (;;) {
- if (listc + 1 >= listmax) {
- SOCKET *newlistv;
-
- listmax += 20;
- newlistv = realloc(listv, listmax * sizeof(*listv));
- if (newlistv == NULL)
- leave(1, "realloc");
- listv = newlistv;
- }
-
- if (poll(set, 1, 1000) == 1 &&
- recvfrom(test_socket, &port_num, sizeof(port_num),
- 0, (struct sockaddr *) &listv[listc], &namelen) > 0) {
- /*
- * Note that we do *not* convert from network to host
- * order since the port number *should* be in network
- * order:
- */
- for (j = 0; j < listc; j += 1)
- if (listv[listc].sin_addr.s_addr
- == listv[j].sin_addr.s_addr)
- break;
- if (j == listc)
- listv[listc++].sin_port = port_num;
- continue;
- }
-
- if (errno != 0 && errno != EINTR) {
- leave(1, "poll/recvfrom");
- /* NOTREACHED */
- }
-
- /* terminate list with local address */
- listv[listc].sin_family = SOCK_FAMILY;
- listv[listc].sin_addr = local_address;
- listv[listc].sin_port = htons(0);
-
- (void) close(test_socket);
- initial = false;
- return listv;
- }
-
-test_one_host:
- msg = htons(C_TESTMSG());
- (void) sendto(test_socket, &msg, sizeof msg, 0,
- (struct sockaddr *) &test, DAEMON_SIZE);
- goto get_response;
-}
-
static void
find_driver(bool do_startup)
{
@@ -772,7 +587,7 @@ fincurs(void)
* Leave the game somewhat gracefully, restoring all current
* tty stats, and print errno.
*/
-static void
+void
leave(int eval, const char *mesg)
{
int serrno = errno;
@@ -786,7 +601,7 @@ leave(int eval, const char *mesg)
* Leave the game somewhat gracefully, restoring all current
* tty stats.
*/
-static void
+void
leavex(int eval, const char *mesg)
{
fincurs();
diff --git a/hunt/hunt/hunt_private.h b/hunt/hunt/hunt_private.h
index c84f486b..4f7b8693 100644
--- a/hunt/hunt/hunt_private.h
+++ b/hunt/hunt/hunt_private.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hunt_private.h,v 1.3 2014/03/29 22:15:26 dholland Exp $ */
+/* $NetBSD: hunt_private.h,v 1.4 2014/03/30 02:26:09 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
@@ -74,6 +74,15 @@ extern bool Am_monitor;
extern char map_key[256];
extern bool no_beep;
+#ifdef INTERNET
+/* XXX this pile had to be made public to split off server.c; fix them up */
+extern SOCKET Daemon;
+extern uint16_t Test_port;
+extern char *Sock_host;
+extern bool Query_driver;
+extern bool Show_scores;
+#endif
+
/*
* function types
*/
@@ -84,6 +93,8 @@ void do_connect(char *, char, long);
/* in hunt.c */
__dead void bad_con(void);
__dead void bad_ver(void);
+__dead void leave(int, const char *);
+__dead void leavex(int, const char *);
void intr(int);
/* in otto.c */
@@ -94,3 +105,8 @@ void playit(void);
int quit(int);
void clear_the_screen(void);
void do_message(void);
+
+/* in server.c */
+#ifdef INTERNET
+SOCKET *list_drivers(void);
+#endif
diff --git a/hunt/hunt/server.c b/hunt/hunt/server.c
new file mode 100644
index 00000000..da7f14d2
--- /dev/null
+++ b/hunt/hunt/server.c
@@ -0,0 +1,235 @@
+/* $NetBSD: server.c,v 1.1 2014/03/30 02:26:09 dholland Exp $ */
+/*
+ * Copyright (c) 1983-2003, Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * + Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * + Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * + Neither the name of the University of California, San Francisco nor
+ * the names of its contributors may be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: server.c,v 1.1 2014/03/30 02:26:09 dholland Exp $");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <curses.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ifaddrs.h>
+
+#include "hunt_common.h"
+#include "pathnames.h"
+#include "hunt_private.h"
+
+#ifdef INTERNET
+
+static int
+broadcast_vec(int s /*socket*/, struct sockaddr_in **vector)
+{
+ int vec_cnt;
+ struct ifaddrs *ifp, *ip;
+
+ *vector = NULL;
+ if (getifaddrs(&ifp) < 0)
+ return 0;
+
+ vec_cnt = 0;
+ for (ip = ifp; ip; ip = ip->ifa_next)
+ if ((ip->ifa_addr->sa_family == AF_INET) &&
+ (ip->ifa_flags & IFF_BROADCAST))
+ vec_cnt++;
+
+ *vector = malloc(vec_cnt * sizeof(struct sockaddr_in));
+
+ vec_cnt = 0;
+ for (ip = ifp; ip; ip = ip->ifa_next)
+ if ((ip->ifa_addr->sa_family == AF_INET) &&
+ (ip->ifa_flags & IFF_BROADCAST))
+ memcpy(&(*vector)[vec_cnt++], ip->ifa_broadaddr,
+ sizeof(struct sockaddr_in));
+
+ freeifaddrs(ifp);
+ return vec_cnt;
+}
+
+SOCKET *
+list_drivers(void)
+{
+ int option;
+ u_short msg;
+ u_short port_num;
+ static SOCKET test;
+ int test_socket;
+ socklen_t namelen;
+ char local_name[MAXHOSTNAMELEN + 1];
+ static bool initial = true;
+ static struct in_addr local_address;
+ struct hostent *hp;
+ static int brdc;
+ static SOCKET *brdv;
+ int i;
+ unsigned j;
+ static SOCKET *listv;
+ static unsigned int listmax;
+ unsigned int listc;
+ struct pollfd set[1];
+
+ if (initial) { /* do one time initialization */
+ if (gethostname(local_name, sizeof local_name) < 0) {
+ leavex(1, "Sorry, I have no name.");
+ /* NOTREACHED */
+ }
+ local_name[sizeof(local_name) - 1] = '\0';
+ if ((hp = gethostbyname(local_name)) == NULL) {
+ leavex(1, "Can't find myself.");
+ /* NOTREACHED */
+ }
+ local_address = * ((struct in_addr *) hp->h_addr);
+
+ listmax = 20;
+ listv = (SOCKET *) malloc(listmax * sizeof (SOCKET));
+ } else if (Sock_host != NULL)
+ return listv; /* address already valid */
+
+ test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
+ if (test_socket < 0) {
+ leave(1, "socket system call failed");
+ /* NOTREACHED */
+ }
+ test.sin_family = SOCK_FAMILY;
+ test.sin_port = htons(Test_port);
+ listc = 0;
+
+ if (Sock_host != NULL) { /* explicit host given */
+ if ((hp = gethostbyname(Sock_host)) == NULL) {
+ leavex(1, "Unknown host");
+ /* NOTREACHED */
+ }
+ test.sin_addr = *((struct in_addr *) hp->h_addr);
+ goto test_one_host;
+ }
+
+ if (!initial) {
+ /* favor host of previous session by broadcasting to it first */
+ test.sin_addr = Daemon.sin_addr;
+ msg = htons(C_PLAYER); /* Must be playing! */
+ (void) sendto(test_socket, &msg, sizeof msg, 0,
+ (struct sockaddr *) &test, sizeof(test));
+ }
+
+ if (initial)
+ brdc = broadcast_vec(test_socket, &brdv);
+
+#ifdef SO_BROADCAST
+ /* Sun's will broadcast even though this option can't be set */
+ option = 1;
+ if (setsockopt(test_socket, SOL_SOCKET, SO_BROADCAST,
+ &option, sizeof option) < 0) {
+ leave(1, "setsockopt broadcast");
+ /* NOTREACHED */
+ }
+#endif
+
+ /* send broadcast packets on all interfaces */
+ msg = htons(C_TESTMSG());
+ for (i = 0; i < brdc; i++) {
+ test.sin_addr = brdv[i].sin_addr;
+ if (sendto(test_socket, &msg, sizeof msg, 0,
+ (struct sockaddr *) &test, sizeof(test)) < 0) {
+ leave(1, "sendto");
+ /* NOTREACHED */
+ }
+ }
+ test.sin_addr = local_address;
+ if (sendto(test_socket, &msg, sizeof msg, 0,
+ (struct sockaddr *) &test, sizeof(test)) < 0) {
+ leave(1, "sendto");
+ /* NOTREACHED */
+ }
+
+get_response:
+ namelen = sizeof(test);
+ errno = 0;
+ set[0].fd = test_socket;
+ set[0].events = POLLIN;
+ for (;;) {
+ if (listc + 1 >= listmax) {
+ SOCKET *newlistv;
+
+ listmax += 20;
+ newlistv = realloc(listv, listmax * sizeof(*listv));
+ if (newlistv == NULL)
+ leave(1, "realloc");
+ listv = newlistv;
+ }
+
+ if (poll(set, 1, 1000) == 1 &&
+ recvfrom(test_socket, &port_num, sizeof(port_num),
+ 0, (struct sockaddr *) &listv[listc], &namelen) > 0) {
+ /*
+ * Note that we do *not* convert from network to host
+ * order since the port number *should* be in network
+ * order:
+ */
+ for (j = 0; j < listc; j += 1)
+ if (listv[listc].sin_addr.s_addr
+ == listv[j].sin_addr.s_addr)
+ break;
+ if (j == listc)
+ listv[listc++].sin_port = port_num;
+ continue;
+ }
+
+ if (errno != 0 && errno != EINTR) {
+ leave(1, "poll/recvfrom");
+ /* NOTREACHED */
+ }
+
+ /* terminate list with local address */
+ listv[listc].sin_family = SOCK_FAMILY;
+ listv[listc].sin_addr = local_address;
+ listv[listc].sin_port = htons(0);
+
+ (void) close(test_socket);
+ initial = false;
+ return listv;
+ }
+
+test_one_host:
+ msg = htons(C_TESTMSG());
+ (void) sendto(test_socket, &msg, sizeof msg, 0,
+ (struct sockaddr *) &test, sizeof(test));
+ goto get_response;
+}
+
+#endif /* INTERNET */