summaryrefslogtreecommitdiffstats
path: root/hunt
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2014-03-30 01:44:37 +0000
committerdholland <dholland@NetBSD.org>2014-03-30 01:44:37 +0000
commit49c27d0ce015c82ce7d2e4c36edf731592406617 (patch)
tree0247b30075082387a28d534890b2b8518cbdb308 /hunt
parenta91067b8ba82b43d07c7888f04b5d641a509561c (diff)
downloadbsdgames-darwin-49c27d0ce015c82ce7d2e4c36edf731592406617.tar.gz
bsdgames-darwin-49c27d0ce015c82ce7d2e4c36edf731592406617.tar.zst
bsdgames-darwin-49c27d0ce015c82ce7d2e4c36edf731592406617.zip
Remove all the conditional compilation for INTERNET. Now you can run
this on either a local or internet socket (including via inetd on either) and it will, or is supposed to, DTRT. Does not really support ipv6 yet, but in a number of places will no longer vomit or exhibit UB if it encounters an ipv6 address.
Diffstat (limited to 'hunt')
-rw-r--r--hunt/huntd/answer.c53
-rw-r--r--hunt/huntd/driver.c317
-rw-r--r--hunt/huntd/hunt.h11
-rw-r--r--hunt/huntd/huntd.610
4 files changed, 224 insertions, 167 deletions
diff --git a/hunt/huntd/answer.c b/hunt/huntd/answer.c
index 8b4c789d..5f42abe4 100644
--- a/hunt/huntd/answer.c
+++ b/hunt/huntd/answer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: answer.c,v 1.20 2014/03/30 00:26:58 dholland Exp $ */
+/* $NetBSD: answer.c,v 1.21 2014/03/30 01:44:37 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
* All rights reserved.
@@ -32,16 +32,18 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: answer.c,v 1.20 2014/03/30 00:26:58 dholland Exp $");
+__RCSID("$NetBSD: answer.c,v 1.21 2014/03/30 01:44:37 dholland Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
+#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
+#include <assert.h>
#include "hunt.h"
#define SCOREDECAY 15
@@ -64,33 +66,48 @@ answer(void)
static socklen_t socklen;
static uint32_t machine;
static uint32_t uid;
- static SOCKET sockstruct;
+ static struct sockaddr_storage newaddr;
char *cp1, *cp2;
int flags;
uint32_t version;
int i;
-#ifdef INTERNET
- socklen = sizeof sockstruct;
-#else
- socklen = sizeof sockstruct - 1;
-#endif
- errno = 0;
- newsock = accept(huntsock, (struct sockaddr *) &sockstruct, &socklen);
- if (newsock < 0)
- {
+ socklen = sizeof(newaddr);
+ newsock = accept(huntsock, (struct sockaddr *)&newaddr, &socklen);
+ if (newsock < 0) {
if (errno == EINTR)
return false;
complain(LOG_ERR, "accept");
cleanup(1);
}
-#ifdef INTERNET
- machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
-#else
- if (machine == 0)
+ /*
+ * XXX this is pretty bollocks
+ */
+ switch (newaddr.ss_family) {
+ case AF_INET:
+ machine = ((struct sockaddr_in *)&newaddr)->sin_addr.s_addr;
+ machine = ntohl(machine);
+ break;
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)&newaddr;
+ assert(sizeof(sin6->sin6_addr.s6_addr) >
+ sizeof(machine));
+ memcpy(&machine, sin6->sin6_addr.s6_addr,
+ sizeof(machine));
+ }
+ break;
+ case AF_UNIX:
machine = gethostid();
-#endif
+ break;
+ default:
+ machine = 0; /* ? */
+ break;
+ }
+
version = htonl((uint32_t) HUNT_VERSION);
(void) write(newsock, &version, LONGLEN);
(void) read(newsock, &uid, LONGLEN);
@@ -127,7 +144,6 @@ answer(void)
*cp2++ = *cp1;
*cp2 = '\0';
-#ifdef INTERNET
if (mode == C_MESSAGE) {
char buf[BUFSIZ + 1];
int n;
@@ -155,7 +171,6 @@ answer(void)
return false;
}
else
-#endif
#ifdef MONITOR
if (mode == C_MONITOR)
if (End_monitor < &Monitor[MAXMON]) {
diff --git a/hunt/huntd/driver.c b/hunt/huntd/driver.c
index dce7c4b1..55dad68f 100644
--- a/hunt/huntd/driver.c
+++ b/hunt/huntd/driver.c
@@ -1,4 +1,4 @@
-/* $NetBSD: driver.c,v 1.34 2014/03/30 00:26:58 dholland Exp $ */
+/* $NetBSD: driver.c,v 1.35 2014/03/30 01:44:37 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
* All rights reserved.
@@ -32,18 +32,25 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: driver.c,v 1.34 2014/03/30 00:26:58 dholland Exp $");
+__RCSID("$NetBSD: driver.c,v 1.35 2014/03/30 01:44:37 dholland Exp $");
#endif /* not lint */
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <err.h>
-#include <errno.h>
-#include <signal.h>
+#include <sys/un.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+
#include <stdlib.h>
#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <err.h>
#include "hunt.h"
#include "pathnames.h"
@@ -94,31 +101,25 @@ __RCSID("$NetBSD: driver.c,v 1.34 2014/03/30 00:26:58 dholland Exp $");
* ".stats")
*/
-#ifdef INTERNET
-static struct sockaddr_in huntaddr;
-static struct sockaddr_in stataddr;
+static bool localmode; /* true -> AF_UNIX; false -> AF_INET */
+static bool inetd_spawned; /* invoked via inetd? */
+static bool standard_port = true; /* listening on standard port? */
+
+static struct sockaddr_storage huntaddr;
+static struct sockaddr_storage stataddr;
+static socklen_t huntaddrlen;
+static socklen_t stataddrlen;
+
static uint16_t contactport = TEST_PORT;
static uint16_t huntport; /* port # of tcp listen socket */
static uint16_t statport; /* port # of statistics tcp socket */
-static int contactsock; /* socket to answer datagrams */
-#define STATSOCKADDR_SIZE (sizeof statsockaddr)
-#else
-static struct sockaddr_un huntaddr;
-static struct sockaddr_un stataddr;
-static const char huntsockpath[] = PATH_HUNTSOCKET;
-static const char statsockpath[] = PATH_STATSOCKET;
-#define STATSOCKADDR_SIZE (sizeof statsockaddr - 1)
-#endif
+static const char *huntsockpath = PATH_HUNTSOCKET;
+static char *statsockpath;
+
+static int contactsock; /* socket to answer datagrams */
int huntsock; /* main socket */
static int statsock; /* stat socket */
-static socklen_t huntaddrlen;
-static socklen_t stataddrlen;
-
-#ifdef INTERNET
-static bool inetd_spawned; /* invoked via inetd */
-static bool standard_port = true; /* true if listening on standard port */
-#endif
#ifdef VOLCANO
static int volcano = 0; /* Explosion size */
@@ -131,6 +132,68 @@ static void makeboots(void);
static void send_stats(void);
static void zap(PLAYER *, bool, int);
+static int
+getnum(const char *s, unsigned long *ret)
+{
+ char *t;
+
+ errno = 0;
+ *ret = strtoul(s, &t, 0);
+ if (errno || *t != '\0') {
+ return -1;
+ }
+ return 0;
+}
+
+static __dead void
+usage(const char *av0)
+{
+ fprintf(stderr, "Usage: %s [-s] [-p portnumber|socketpath]\n", av0);
+ exit(1);
+}
+
+static void
+makeaddr(const char *path, uint16_t port,
+ struct sockaddr_storage *ss, socklen_t *len)
+{
+ struct sockaddr_in *sin;
+ struct sockaddr_un *sun;
+
+ if (path == NULL) {
+ sin = (struct sockaddr_in *)ss;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ sin->sin_port = htons(port);
+ *len = sizeof(*sin);
+ } else {
+ sun = (struct sockaddr_un *)ss;
+ sun->sun_family = AF_UNIX;
+ strlcpy(sun->sun_path, path, sizeof(sun->sun_path));
+ *len = SUN_LEN(sun);
+ }
+}
+
+static uint16_t
+getsockport(int sock)
+{
+ struct sockaddr_storage addr;
+ socklen_t len;
+
+ len = sizeof(addr);
+ if (getsockname(sock, (struct sockaddr *)&addr, &len) < 0) {
+ complain(LOG_ERR, "getsockname");
+ exit(1);
+ }
+ switch (addr.ss_family) {
+ case AF_INET:
+ return ntohs(((struct sockaddr_in *)&addr)->sin_port);
+ case AF_INET6:
+ return ntohs(((struct sockaddr_in6 *)&addr)->sin6_port);
+ default:
+ break;
+ }
+ return 0;
+}
/*
* main:
@@ -140,12 +203,10 @@ int
main(int ac, char **av)
{
PLAYER *pp;
-#ifdef INTERNET
- u_short msg;
- short reply;
- socklen_t namelen;
- SOCKET test;
-#endif
+ unsigned long optargnum;
+ uint16_t msg, reply;
+ struct sockaddr_storage msgaddr;
+ socklen_t msgaddrlen;
static bool first = true;
static bool server = false;
int c, i;
@@ -156,21 +217,26 @@ main(int ac, char **av)
case 's':
server = true;
break;
-#ifdef INTERNET
case 'p':
standard_port = false;
- contactport = atoi(optarg);
+ if (getnum(optarg, &optargnum) < 0) {
+ localmode = true;
+ huntsockpath = optarg;
+ } else if (optargnum < 0xffff) {
+ localmode = false;
+ contactport = optargnum;
+ } else {
+ usage(av[0]);
+ }
break;
-#endif
default:
-erred:
- fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]);
- exit(1);
+ usage(av[0]);
}
}
if (optind < ac)
- goto erred;
+ usage(av[0]);
+ asprintf(&statsockpath, "%s.stats", huntsockpath);
init();
@@ -183,11 +249,10 @@ again:
complain(LOG_WARNING, "poll");
errno = 0;
}
-#ifdef INTERNET
- if (fdset[2].revents & POLLIN) {
- namelen = sizeof(test);
+ if (!localmode && fdset[2].revents & POLLIN) {
+ msgaddrlen = sizeof(msgaddr);
(void) recvfrom(contactsock, &msg, sizeof msg,
- 0, (struct sockaddr *) &test, &namelen);
+ 0, (struct sockaddr *)&msgaddr, &msgaddrlen);
switch (ntohs(msg)) {
case C_MESSAGE:
if (Nplayer <= 0)
@@ -195,13 +260,15 @@ again:
reply = htons((u_short) Nplayer);
(void) sendto(contactsock, &reply,
sizeof reply, 0,
- (struct sockaddr *) &test, sizeof(test));
+ (struct sockaddr *)&msgaddr,
+ msgaddrlen);
break;
case C_SCORES:
reply = htons(statport);
(void) sendto(contactsock, &reply,
sizeof reply, 0,
- (struct sockaddr *) &test, sizeof(test));
+ (struct sockaddr *)&msgaddr,
+ msgaddrlen);
break;
case C_PLAYER:
case C_MONITOR:
@@ -210,11 +277,12 @@ again:
reply = htons(huntport);
(void) sendto(contactsock, &reply,
sizeof reply, 0,
- (struct sockaddr *) &test, sizeof(test));
+ (struct sockaddr *)&msgaddr,
+ msgaddrlen);
break;
}
}
-#endif
+
{
for (pp = Player, i = 0; pp < End_player; pp++, i++)
if (havechar(pp, i + 3)) {
@@ -298,11 +366,10 @@ static void
init(void)
{
int i;
-#ifdef INTERNET
- struct sockaddr_in contactaddr;
- int msg;
+ struct sockaddr_storage stdinaddr;
+ struct sockaddr_storage contactaddr;
+ socklen_t contactaddrlen;
socklen_t len;
-#endif
#ifndef DEBUG
#ifdef TIOCNOTTY
@@ -324,60 +391,68 @@ init(void)
#endif
/*
- * Initialize statistics socket
+ * check for inetd
*/
-#ifdef INTERNET
- stataddr.sin_family = AF_INET;
- stataddr.sin_addr.s_addr = INADDR_ANY;
- stataddr.sin_port = 0;
- stataddrlen = sizeof(stataddr);
-#else
- stataddr.sun_family = AF_UNIX;
- (void) strcpy(stataddr.sun_path, statsockpath);
- stataddrlen = SUN_LEN(&stataddr);
-#endif
-
- statsock = socket(SOCK_FAMILY, SOCK_STREAM, 0);
- if (bind(statsock, (struct sockaddr *) &stataddr, stataddrlen) < 0) {
- if (errno == EADDRINUSE)
- exit(0);
+ len = sizeof(stdinaddr);
+ if (getsockname(STDIN_FILENO, (struct sockaddr *)&stdinaddr,
+ &len) >= 0) {
+ inetd_spawned = true;
+ /* force localmode, assimilate stdin as appropriate */
+ if (stdinaddr.ss_family == AF_UNIX) {
+ localmode = true;
+ contactsock = -1;
+ huntsock = STDIN_FILENO;
+ }
else {
- complain(LOG_ERR, "bind");
- cleanup(1);
+ localmode = false;
+ contactsock = STDIN_FILENO;
+ huntsock = -1;
}
+ } else {
+ /* keep value of localmode; no sockets yet */
+ contactsock = -1;
+ huntsock = -1;
}
- (void) listen(statsock, 5);
-#ifdef INTERNET
- len = sizeof(stataddr);
- if (getsockname(statsock, (struct sockaddr *) &stataddr, &len) < 0) {
- complain(LOG_ERR, "getsockname");
- exit(1);
+ /*
+ * initialize contact socket
+ */
+ if (!localmode && contactsock < 0) {
+ makeaddr(NULL, contactport, &contactaddr, &contactaddrlen);
+ contactsock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (bind(contactsock, (struct sockaddr *) &contactaddr,
+ contactaddrlen) < 0) {
+ complain(LOG_ERR, "bind");
+ exit(1);
+ }
+ (void) listen(contactsock, 5);
}
- statport = ntohs(stataddr.sin_port);
-#endif
/*
* Initialize main socket
*/
-#ifdef INTERNET
- huntaddr.sin_family = AF_INET;
- huntaddr.sin_addr.s_addr = INADDR_ANY;
- huntaddr.sin_port = 0;
- huntaddrlen = sizeof(huntaddr);
-#else
- huntaddr.sun_family = AF_UNIX;
- (void) strcpy(huntaddr.sun_path, huntsockpath);
- huntaddrlen = SUN_LEN(&huntaddr);
-#endif
+ if (huntsock < 0) {
+ makeaddr(localmode ? huntsockpath : NULL, 0, &huntaddr,
+ &huntaddrlen);
+ huntsock = socket(huntaddr.ss_family, SOCK_STREAM, 0);
+ if (bind(huntsock, (struct sockaddr *)&huntaddr,
+ huntaddrlen) < 0) {
+ if (errno == EADDRINUSE)
+ exit(0);
+ else {
+ complain(LOG_ERR, "bind");
+ cleanup(1);
+ }
+ }
+ (void) listen(huntsock, 5);
+ }
- huntsock = socket(SOCK_FAMILY, SOCK_STREAM, 0);
-#if defined(INTERNET)
- msg = 1;
- if (setsockopt(huntsock, SOL_SOCKET, SO_USELOOPBACK, &msg, sizeof msg)<0)
- complain(LOG_WARNING, "setsockopt loopback");
-#endif
- if (bind(huntsock, (struct sockaddr *) &huntaddr, huntaddrlen) < 0) {
+ /*
+ * Initialize statistics socket
+ */
+ makeaddr(localmode ? statsockpath : NULL, 0, &stataddr, &stataddrlen);
+ statsock = socket(stataddr.ss_family, SOCK_STREAM, 0);
+ if (bind(statsock, (struct sockaddr *)&stataddr, stataddrlen) < 0) {
if (errno == EADDRINUSE)
exit(0);
else {
@@ -385,16 +460,16 @@ init(void)
cleanup(1);
}
}
- (void) listen(huntsock, 5);
+ (void) listen(statsock, 5);
-#ifdef INTERNET
- len = sizeof(huntaddr);
- if (getsockname(huntsock, (struct sockaddr *) &huntaddr, &len) < 0) {
- complain(LOG_ERR, "getsockname");
- exit(1);
+ if (!localmode) {
+ contactport = getsockport(contactsock);
+ statport = getsockport(statsock);
+ huntport = getsockport(huntsock);
+ if (contactport != TEST_PORT) {
+ standard_port = false;
+ }
}
- huntport = ntohs(huntaddr.sin_port);
-#endif
/*
* Initialize minimal poll mask
@@ -403,36 +478,14 @@ init(void)
fdset[0].events = POLLIN;
fdset[1].fd = statsock;
fdset[1].events = POLLIN;
-
-#ifdef INTERNET
- len = sizeof(contactaddr);
- if (getsockname(STDIN_FILENO, (struct sockaddr *) &contactaddr, &len) >= 0
- && contactaddr.sin_family == AF_INET) {
- inetd_spawned = true;
- contactsock = STDIN_FILENO;
- if (ntohs(contactaddr.sin_port) != contactport) {
- standard_port = false;
- contactport = ntohs(contactaddr.sin_port);
- }
+ if (localmode) {
+ fdset[2].fd = -1;
+ fdset[2].events = 0;
} else {
- contactaddr = huntaddr;
- contactaddr.sin_port = htons(contactport);
-
- contactsock = socket(AF_INET, SOCK_DGRAM, 0);
- if (bind(contactsock, (struct sockaddr *) &contactaddr,
- sizeof(contactaddr)) < 0) {
- complain(LOG_ERR, "bind");
- exit(1);
- }
- (void) listen(contactsock, 5);
+ fdset[2].fd = contactsock;
+ fdset[2].events = POLLIN;
}
- fdset[2].fd = contactsock;
- fdset[2].events = POLLIN;
-#else
- fdset[2].fd = -1;
-#endif
-
srandom(time(NULL));
makemaze();
#ifdef BOOTS
@@ -902,18 +955,14 @@ send_stats(void)
IDENT *ip;
FILE *fp;
int s;
- SOCKET sockstruct;
+ struct sockaddr_storage newaddr;
socklen_t socklen;
/*
* Get the output stream ready
*/
-#ifdef INTERNET
- socklen = sizeof sockstruct;
-#else
- socklen = sizeof sockstruct - 1;
-#endif
- s = accept(statsock, (struct sockaddr *) &sockstruct, &socklen);
+ socklen = sizeof(newaddr);
+ s = accept(statsock, (struct sockaddr *)&newaddr, &socklen);
if (s < 0) {
if (errno == EINTR)
return;
diff --git a/hunt/huntd/hunt.h b/hunt/huntd/hunt.h
index ab2dd56e..daff100b 100644
--- a/hunt/huntd/hunt.h
+++ b/hunt/huntd/hunt.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hunt.h,v 1.28 2014/03/30 00:26:58 dholland Exp $ */
+/* $NetBSD: hunt.h,v 1.29 2014/03/30 01:44:37 dholland Exp $ */
/*
* Copyright (c) 1983-2003, Regents of the University of California.
@@ -41,15 +41,6 @@
#include <sys/uio.h>
#include <sys/poll.h>
-#ifdef INTERNET
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#else
-#include <sys/un.h>
-#endif
-
#include "hunt_common.h"
extern const int shot_req[];
diff --git a/hunt/huntd/huntd.6 b/hunt/huntd/huntd.6
index 51e646b8..32206e4d 100644
--- a/hunt/huntd/huntd.6
+++ b/hunt/huntd/huntd.6
@@ -1,4 +1,4 @@
-.\" $NetBSD: huntd.6,v 1.11 2014/03/29 20:32:04 dholland Exp $
+.\" $NetBSD: huntd.6,v 1.12 2014/03/30 01:44:37 dholland Exp $
.\"
.\" huntd
.\"
@@ -40,7 +40,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl s
-.Op Fl p Ar port
+.Op Fl p Ar address
.Sh DESCRIPTION
.Nm
controls the multi-player
@@ -58,8 +58,10 @@ This is similar to running it under the control of
.Pp
The
.Fl p
-option changes the UDP port number used to rendezvous with the player
-process and thus allows for private games of hunt.
+option can be either a pathname, in which case a local socket by that
+name is used for the game, or a number, in which case it selects an
+alternate port number for the internet socket used for the game.
+This allows for private games of hunt.
.Ss INETD
To run
.Nm