split off a bunch of the nastier network code into its own file
This commit is contained in:
parent
38f4986ae9
commit
082c40f53a
@ -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}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
235
games/hunt/hunt/server.c
Normal file
235
games/hunt/hunt/server.c
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user