summaryrefslogtreecommitdiffstats
path: root/hunt
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2014-03-30 02:46:57 +0000
committerdholland <dholland@NetBSD.org>2014-03-30 02:46:57 +0000
commitcd13042d23065cae90a02dae4f7602a2b4eb7ce0 (patch)
tree98d62ea76406c929cd5d73485e639c7eca6829f0 /hunt
parent1f6302b1815a3f7936f23ba89822b55e4705d6e7 (diff)
downloadbsdgames-darwin-cd13042d23065cae90a02dae4f7602a2b4eb7ce0.tar.gz
bsdgames-darwin-cd13042d23065cae90a02dae4f7602a2b4eb7ce0.tar.zst
bsdgames-darwin-cd13042d23065cae90a02dae4f7602a2b4eb7ce0.zip
goto considered harmful
Diffstat (limited to 'hunt')
-rw-r--r--hunt/hunt/server.c206
1 files changed, 111 insertions, 95 deletions
diff --git a/hunt/hunt/server.c b/hunt/hunt/server.c
index da7f14d2..9d9ab30b 100644
--- a/hunt/hunt/server.c
+++ b/hunt/hunt/server.c
@@ -1,4 +1,4 @@
-/* $NetBSD: server.c,v 1.1 2014/03/30 02:26:09 dholland Exp $ */
+/* $NetBSD: server.c,v 1.2 2014/03/30 02:46:57 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
* All rights reserved.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: server.c,v 1.1 2014/03/30 02:26:09 dholland Exp $");
+__RCSID("$NetBSD: server.c,v 1.2 2014/03/30 02:46:57 dholland Exp $");
#include <sys/param.h>
#include <sys/stat.h>
@@ -53,8 +53,43 @@ __RCSID("$NetBSD: server.c,v 1.1 2014/03/30 02:26:09 dholland Exp $");
#ifdef INTERNET
+/*
+ * Code for finding and talking to hunt daemons.
+ */
+
+static SOCKET *listv;
+static unsigned int listmax;
+
+static SOCKET test;
+static bool initial = true;
+static struct in_addr local_address;
+struct hostent *hp;
+static int brdc;
+static SOCKET *brdv;
+
+static void
+serverlist_setup(void)
+{
+ char local_name[MAXHOSTNAMELEN + 1];
+
+ if (gethostname(local_name, sizeof(local_name)) < 0) {
+ leavex(1, "Sorry, I have no hostname.");
+ }
+ local_name[sizeof(local_name) - 1] = '\0';
+ if ((hp = gethostbyname(local_name)) == NULL) {
+ leavex(1, "Can't find myself.");
+ }
+ memcpy(&local_address, hp->h_addr, sizeof(local_address));
+
+ listmax = 20;
+ listv = malloc(listmax * sizeof(listv[0]));
+ if (listv == NULL) {
+ leavex(1, "Out of memory.");
+ }
+}
+
static int
-broadcast_vec(int s /*socket*/, struct sockaddr_in **vector)
+getbroadcastaddrs(int s /*socket*/, struct sockaddr_in **vector)
{
int vec_cnt;
struct ifaddrs *ifp, *ip;
@@ -82,53 +117,83 @@ broadcast_vec(int s /*socket*/, struct sockaddr_in **vector)
return vec_cnt;
}
-SOCKET *
-list_drivers(void)
+static void
+get_responses(int contactsock)
{
- 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];
+ socklen_t namelen;
- if (initial) { /* do one time initialization */
- if (gethostname(local_name, sizeof local_name) < 0) {
- leavex(1, "Sorry, I have no name.");
- /* NOTREACHED */
+ listc = 0;
+ namelen = sizeof(test);
+ errno = 0;
+ set[0].fd = contactsock;
+ 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;
}
- local_name[sizeof(local_name) - 1] = '\0';
- if ((hp = gethostbyname(local_name)) == NULL) {
- leavex(1, "Can't find myself.");
- /* NOTREACHED */
+
+ if (poll(set, 1, 1000) == 1 &&
+ recvfrom(contactsock, &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;
}
- local_address = * ((struct in_addr *) hp->h_addr);
- listmax = 20;
- listv = (SOCKET *) malloc(listmax * sizeof (SOCKET));
+ if (errno != 0 && errno != EINTR) {
+ leave(1, "poll/recvfrom");
+ }
+
+ /* 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(contactsock);
+ initial = false;
+ break;
+ }
+}
+
+SOCKET *
+list_drivers(void)
+{
+ int option;
+ u_short msg;
+ int contactsock;
+ int i;
+
+ if (initial) {
+ /* do one time initialization */
+ serverlist_setup();
} else if (Sock_host != NULL)
return listv; /* address already valid */
- test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
- if (test_socket < 0) {
+ contactsock = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
+ if (contactsock < 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) {
@@ -136,24 +201,28 @@ list_drivers(void)
/* NOTREACHED */
}
test.sin_addr = *((struct in_addr *) hp->h_addr);
- goto test_one_host;
+ msg = htons(C_TESTMSG());
+ (void) sendto(contactsock, &msg, sizeof msg, 0,
+ (struct sockaddr *) &test, sizeof(test));
+ get_responses(contactsock);
+ return listv;
}
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,
+ (void) sendto(contactsock, &msg, sizeof msg, 0,
(struct sockaddr *) &test, sizeof(test));
}
if (initial)
- brdc = broadcast_vec(test_socket, &brdv);
+ brdc = getbroadcastaddrs(contactsock, &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,
+ if (setsockopt(contactsock, SOL_SOCKET, SO_BROADCAST,
&option, sizeof option) < 0) {
leave(1, "setsockopt broadcast");
/* NOTREACHED */
@@ -164,72 +233,19 @@ list_drivers(void)
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,
+ if (sendto(contactsock, &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,
+ if (sendto(contactsock, &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;
+ get_responses(contactsock);
+ return listv;
}
#endif /* INTERNET */