-/* $NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $ */
+/* $NetBSD: driver.c,v 1.16 2009/07/04 02:37:20 dholland Exp $ */
/*
- * Hunt
- * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- * San Francisco, California
+ * 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>
#ifndef lint
-__RCSID("$NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $");
+__RCSID("$NetBSD: driver.c,v 1.16 2009/07/04 02:37:20 dholland Exp $");
#endif /* not lint */
# include <sys/ioctl.h>
# define DAEMON_SIZE (sizeof Daemon - 1)
# endif
-static void clear_scores __P((void));
-static int havechar __P((PLAYER *));
-static void init __P((void));
- int main __P((int, char *[], char *[]));
-static void makeboots __P((void));
-static void send_stats __P((void));
-static void zap __P((PLAYER *, FLAG));
+static void clear_scores(void);
+static int havechar(PLAYER *, int);
+static void init(void);
+ int main(int, char *[], char *[]);
+static void makeboots(void);
+static void send_stats(void);
+static void zap(PLAYER *, FLAG, int);
/*
* The main program.
*/
int
-main(ac, av, ep)
- int ac;
- char **av, **ep;
+main(int ac, char **av, char **ep)
{
PLAYER *pp;
- int had_char;
# ifdef INTERNET
u_short msg;
short port_num, reply;
- int namelen;
+ socklen_t namelen;
SOCKET test;
# endif
- static fd_set read_fds;
static FLAG first = TRUE;
static FLAG server = FALSE;
- extern int optind;
- extern char *optarg;
- int c;
- static struct timeval linger = { 90, 0 };
+ int c, i;
+ const int linger = 90 * 1000;
First_arg = av[0];
if (ep == NULL || *ep == NULL)
again:
do {
- read_fds = Fds_mask;
errno = 0;
- while (select(Num_fds, &read_fds, NULL, NULL, NULL) < 0)
+ while (poll(fdset, 3+MAXPL+MAXMON, INFTIM) < 0)
{
if (errno != EINTR)
# ifdef LOG
- syslog(LOG_WARNING, "select: %m");
+ syslog(LOG_WARNING, "poll: %m");
# else
- warn("select");
+ warn("poll");
# endif
errno = 0;
}
- Have_inp = read_fds;
# ifdef INTERNET
- if (FD_ISSET(Test_socket, &read_fds)) {
+ if (fdset[2].revents & POLLIN) {
namelen = DAEMON_SIZE;
port_num = htons(sock_port);
- (void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
+ (void) recvfrom(Test_socket, &msg, sizeof msg,
0, (struct sockaddr *) &test, &namelen);
switch (ntohs(msg)) {
case C_MESSAGE:
if (Nplayer <= 0)
break;
reply = htons((u_short) Nplayer);
- (void) sendto(Test_socket, (char *) &reply,
+ (void) sendto(Test_socket, &reply,
sizeof reply, 0,
(struct sockaddr *) &test, DAEMON_SIZE);
break;
case C_SCORES:
reply = htons(stat_port);
- (void) sendto(Test_socket, (char *) &reply,
+ (void) sendto(Test_socket, &reply,
sizeof reply, 0,
(struct sockaddr *) &test, DAEMON_SIZE);
break;
if (msg == C_MONITOR && Nplayer <= 0)
break;
reply = htons(sock_port);
- (void) sendto(Test_socket, (char *) &reply,
+ (void) sendto(Test_socket, &reply,
sizeof reply, 0,
(struct sockaddr *) &test, DAEMON_SIZE);
break;
}
}
# endif
- for (;;) {
- had_char = FALSE;
- for (pp = Player; pp < End_player; pp++)
- if (havechar(pp)) {
+ {
+ for (pp = Player, i = 0; pp < End_player; pp++, i++)
+ if (havechar(pp, i + 3)) {
execute(pp);
pp->p_nexec++;
- had_char++;
}
# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; pp++)
- if (havechar(pp)) {
+ for (pp = Monitor, i = 0; pp < End_monitor; pp++, i++)
+ if (havechar(pp, i + MAXPL + 3)) {
mon_execute(pp);
pp->p_nexec++;
- had_char++;
}
# endif
- if (!had_char)
- break;
moveshots();
- for (pp = Player; pp < End_player; )
+ for (pp = Player, i = 0; pp < End_player; )
if (pp->p_death[0] != '\0')
- zap(pp, TRUE);
+ zap(pp, TRUE, i + 3);
else
- pp++;
+ pp++, i++;
# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; )
+ for (pp = Monitor, i = 0; pp < End_monitor; )
if (pp->p_death[0] != '\0')
- zap(pp, FALSE);
+ zap(pp, FALSE, i + MAXPL + 3);
else
- pp++;
+ pp++, i++;
# endif
}
- if (FD_ISSET(Socket, &read_fds))
+ if (fdset[0].revents & POLLIN)
if (answer()) {
# ifdef INTERNET
if (first && standard_port)
# endif
first = FALSE;
}
- if (FD_ISSET(Status, &read_fds))
+ if (fdset[1].revents & POLLIN)
send_stats();
- for (pp = Player; pp < End_player; pp++) {
- if (FD_ISSET(pp->p_fd, &read_fds))
+ for (pp = Player, i = 0; pp < End_player; pp++, i++) {
+ if (fdset[i + 3].revents & POLLIN)
sendcom(pp, READY, pp->p_nexec);
pp->p_nexec = 0;
(void) fflush(pp->p_output);
}
# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; pp++) {
- if (FD_ISSET(pp->p_fd, &read_fds))
+ for (pp = Monitor, i = 0; pp < End_monitor; pp++, i++) {
+ if (fdset[i + MAXPL + 3].revents & POLLIN)
sendcom(pp, READY, pp->p_nexec);
pp->p_nexec = 0;
(void) fflush(pp->p_output);
# endif
} while (Nplayer > 0);
- read_fds = Fds_mask;
- if (select(Num_fds, &read_fds, NULL, NULL, &linger) > 0) {
+ if (poll(fdset, 3+MAXPL+MAXMON, linger) > 0) {
goto again;
}
if (server) {
}
# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; )
- zap(pp, FALSE);
+ for (pp = Monitor, i = 0; pp < End_monitor; i++)
+ zap(pp, FALSE, i + MAXPL + 3);
# endif
cleanup(0);
/* NOTREACHED */
* Initialize the global parameters.
*/
static void
-init()
+init(void)
{
int i;
# ifdef INTERNET
SOCKET test_port;
int msg;
- int len;
+ socklen_t len;
# endif
# ifndef DEBUG
# ifdef LOG
# ifdef SYSLOG_43
- openlog("HUNT", LOG_PID, LOG_DAEMON);
+ openlog("huntd", LOG_PID, LOG_DAEMON);
# endif
# ifdef SYSLOG_42
- openlog("HUNT", LOG_PID);
+ openlog("huntd", LOG_PID);
# endif
# endif
# endif
/*
- * Initialize minimal select mask
+ * Initialize minimal poll mask
*/
- FD_ZERO(&Fds_mask);
- FD_SET(Socket, &Fds_mask);
- FD_SET(Status, &Fds_mask);
- Num_fds = ((Socket > Status) ? Socket : Status) + 1;
+ fdset[0].fd = Socket;
+ fdset[0].events = POLLIN;
+ fdset[1].fd = Status;
+ fdset[1].events = POLLIN;
# ifdef INTERNET
len = sizeof (SOCKET);
(void) listen(Test_socket, 5);
}
- FD_SET(Test_socket, &Fds_mask);
- if (Test_socket + 1 > Num_fds)
- Num_fds = Test_socket + 1;
+ fdset[2].fd = Test_socket;
+ fdset[2].events = POLLIN;
+# else
+ fdset[2].fd = -1;
# endif
Seed = getpid() + time((time_t *) NULL);
* Put the boots in the maze
*/
static void
-makeboots()
+makeboots(void)
{
int x, y;
PLAYER *pp;
* Check the damage to the given player, and see if s/he is killed
*/
void
-checkdam(ouch, gotcha, credit, amt, shot_type)
- PLAYER *ouch, *gotcha;
- IDENT *credit;
- int amt;
- char shot_type;
+checkdam(PLAYER *ouch, PLAYER *gotcha, IDENT *credit, int amt,
+ char this_shot_type)
{
- char *cp;
+ const char *cp;
if (ouch->p_death[0] != '\0')
return;
# ifdef BOOTS
- if (shot_type == SLIME)
+ if (this_shot_type == SLIME)
switch (ouch->p_nboots) {
default:
break;
# endif
ouch->p_damage += amt;
if (ouch->p_damage <= ouch->p_damcap) {
- (void) sprintf(Buf, "%2d", ouch->p_damage);
+ (void) snprintf(Buf, sizeof(Buf), "%2d", ouch->p_damage);
cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL);
outstr(ouch, Buf, 2);
return;
}
/* Someone DIED */
- switch (shot_type) {
+ switch (this_shot_type) {
default:
cp = "Killed";
break;
# endif
}
if (credit == NULL) {
- (void) sprintf(ouch->p_death, "| %s by %s |", cp,
- (shot_type == MINE || shot_type == GMINE) ?
+ (void) snprintf(ouch->p_death, sizeof(ouch->p_death),
+ "| %s by %s |", cp,
+ (this_shot_type == MINE || this_shot_type == GMINE) ?
"a mine" : "act of God");
return;
}
- (void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
+ (void) snprintf(ouch->p_death, sizeof(ouch->p_death),
+ "| %s by %s |", cp, credit->i_name);
if (ouch == gotcha) { /* No use killing yourself */
credit->i_kills--;
gotcha->p_damage -= STABDAM;
if (gotcha->p_damage < 0)
gotcha->p_damage = 0;
- (void) sprintf(Buf, "%2d/%2d", gotcha->p_damage, gotcha->p_damcap);
+ (void) snprintf(Buf, sizeof(Buf), "%2d/%2d", gotcha->p_damage,
+ gotcha->p_damcap);
cgoto(gotcha, STAT_DAM_ROW, STAT_VALUE_COL);
outstr(gotcha, Buf, 5);
- (void) sprintf(Buf, "%3d", (gotcha->p_damcap - MAXDAM) / 2);
+ (void) snprintf(Buf, sizeof(Buf), "%3d",
+ (gotcha->p_damcap - MAXDAM) / 2);
cgoto(gotcha, STAT_KILL_ROW, STAT_VALUE_COL);
outstr(gotcha, Buf, 3);
- (void) sprintf(Buf, "%5.2f", gotcha->p_ident->i_score);
+ (void) snprintf(Buf, sizeof(Buf), "%5.2f", gotcha->p_ident->i_score);
for (ouch = Player; ouch < End_player; ouch++) {
cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
STAT_NAME_COL);
* Kill off a player and take him out of the game.
*/
static void
-zap(pp, was_player)
- PLAYER *pp;
- FLAG was_player;
+zap(PLAYER *pp, FLAG was_player, int i)
{
- int i, len;
+ int n, len;
BULLET *bp;
PLAYER *np;
int x, y;
x = (WIDTH - len) / 2;
cgoto(pp, HEIGHT / 2, x);
outstr(pp, pp->p_death, len);
- for (i = 1; i < len; i++)
- pp->p_death[i] = '-';
+ for (n = 1; n < len; n++)
+ pp->p_death[n] = '-';
pp->p_death[0] = '+';
pp->p_death[len - 1] = '+';
cgoto(pp, HEIGHT / 2 - 1, x);
bp->b_over = SPACE;
}
- i = rand_num(pp->p_ammo);
+ n = rand_num(pp->p_ammo);
x = rand_num(pp->p_ammo);
- if (x > i)
- i = x;
+ if (x > n)
+ n = x;
if (pp->p_ammo == 0)
x = 0;
- else if (i == pp->p_ammo - 1) {
+ else if (n == pp->p_ammo - 1) {
x = pp->p_ammo;
len = SLIME;
}
else {
for (x = MAXBOMB - 1; x > 0; x--)
- if (i >= shot_req[x])
+ if (n >= shot_req[x])
break;
for (y = MAXSLIME - 1; y > 0; y--)
- if (i >= slime_req[y])
+ if (n >= slime_req[y])
break;
if (y >= 0 && slime_req[y] > shot_req[x]) {
x = slime_req[y];
if (x > 0) {
(void) add_shot(len, pp->p_y, pp->p_x, pp->p_face, x,
(PLAYER *) NULL, TRUE, SPACE);
- (void) sprintf(Buf, "%s detonated.",
+ (void) snprintf(Buf, sizeof(Buf), "%s detonated.",
pp->p_ident->i_name);
for (np = Player; np < End_player; np++)
message(np, Buf);
End_player--;
if (pp != End_player) {
memcpy(pp, End_player, sizeof (PLAYER));
- (void) sprintf(Buf, "%5.2f%c%-10.10s %c",
+ fdset[i] = fdset[End_player - Player + 3];
+ fdset[End_player - Player + 3].fd = -1;
+ (void) snprintf(Buf, sizeof(Buf), "%5.2f%c%-10.10s %c",
pp->p_ident->i_score, stat_char(pp),
pp->p_ident->i_name, pp->p_ident->i_team);
- i = STAT_PLAY_ROW + 1 + (pp - Player);
+ n = STAT_PLAY_ROW + 1 + (pp - Player);
for (np = Player; np < End_player; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
outstr(np, Buf, STAT_NAME_LEN);
}
# ifdef MONITOR
for (np = Monitor; np < End_monitor; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
outstr(np, Buf, STAT_NAME_LEN);
}
# endif
- }
+ } else
+ fdset[i].fd = -1;
/* Erase the last player */
- i = STAT_PLAY_ROW + 1 + Nplayer;
+ n = STAT_PLAY_ROW + 1 + Nplayer;
for (np = Player; np < End_player; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
ce(np);
}
# ifdef MONITOR
for (np = Monitor; np < End_monitor; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
ce(np);
}
}
End_monitor--;
if (pp != End_monitor) {
memcpy(pp, End_monitor, sizeof (PLAYER));
- (void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
+ fdset[i] = fdset[End_monitor - Monitor + MAXPL + 3];
+ fdset[End_monitor - Monitor + MAXPL + 3].fd = -1;
+ (void) snprintf(Buf, sizeof(Buf), "%5.5s %-10.10s %c",
+ " ",
pp->p_ident->i_name, pp->p_ident->i_team);
- i = STAT_MON_ROW + 1 + (pp - Player);
+ n = STAT_MON_ROW + 1 + (pp - Player);
for (np = Player; np < End_player; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
outstr(np, Buf, STAT_NAME_LEN);
}
for (np = Monitor; np < End_monitor; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
outstr(np, Buf, STAT_NAME_LEN);
}
- }
+ } else
+ fdset[i].fd = -1;
/* Erase the last monitor */
- i = STAT_MON_ROW + 1 + (End_monitor - Monitor);
+ n = STAT_MON_ROW + 1 + (End_monitor - Monitor);
for (np = Player; np < End_player; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
ce(np);
}
for (np = Monitor; np < End_monitor; np++) {
- cgoto(np, i, STAT_NAME_COL);
+ cgoto(np, n, STAT_NAME_COL);
ce(np);
}
-
}
# endif
-
- FD_CLR(savefd, &Fds_mask);
- if (Num_fds == savefd + 1) {
- Num_fds = Socket;
-# ifdef INTERNET
- if (Test_socket > Socket)
- Num_fds = Test_socket;
-# endif
- for (np = Player; np < End_player; np++)
- if (np->p_fd > Num_fds)
- Num_fds = np->p_fd;
-# ifdef MONITOR
- for (np = Monitor; np < End_monitor; np++)
- if (np->p_fd > Num_fds)
- Num_fds = np->p_fd;
-# endif
- Num_fds++;
- }
}
/*
* Return a random number in a given range.
*/
int
-rand_num(range)
- int range;
+rand_num(int range)
{
return (range == 0 ? 0 : RN % range);
}
* FALSE.
*/
static int
-havechar(pp)
- PLAYER *pp;
+havechar(PLAYER *pp, int i)
{
if (pp->p_ncount < pp->p_nchar)
return TRUE;
- if (!FD_ISSET(pp->p_fd, &Have_inp))
+ if (!(fdset[i].revents & POLLIN))
return FALSE;
- FD_CLR(pp->p_fd, &Have_inp);
check_again:
errno = 0;
if ((pp->p_nchar = read(pp->p_fd, pp->p_cbuf, sizeof pp->p_cbuf)) <= 0)
* Exit with the given value, cleaning up any droppings lying around
*/
SIGNAL_TYPE
-cleanup(eval)
- int eval;
+cleanup(int eval)
{
PLAYER *pp;
* Print stats to requestor
*/
static void
-send_stats()
+send_stats(void)
{
IDENT *ip;
FILE *fp;
int s;
SOCKET sockstruct;
- int socklen;
+ socklen_t socklen;
/*
* Get the output stream ready
if (errno == EINTR)
return;
# ifdef LOG
- syslog(LOG_ERR, "accept: %m");
+ syslog(LOG_WARNING, "accept: %m");
# else
warn("accept");
# endif
fp = fdopen(s, "w");
if (fp == NULL) {
# ifdef LOG
- syslog(LOG_ERR, "fdopen: %m");
+ syslog(LOG_WARNING, "fdopen: %m");
# else
warn("fdopen");
# endif
* Clear out the scores so the next session start clean
*/
static void
-clear_scores()
+clear_scores(void)
{
IDENT *ip, *nextip;
for (ip = Scores; ip != NULL; ip = nextip) {
nextip = ip->i_next;
- (void) free((char *) ip);
+ (void) free(ip);
}
Scores = NULL;
}