From 87de65d5e59e292d62ff93a110a94992893f8bd6 Mon Sep 17 00:00:00 2001 From: Rick Bird Date: Fri, 25 Mar 2011 17:16:27 -0400 Subject: [PATCH] PennMUSH Incorp 182p4 * stdin and stdout weren't getting closed, potentially causing problems when trying to log out of a shell after starting a mush. Reported by K Moon. [SW] * Receipt of a SIGUSR1 (Causing a shutdown/reboot) is explictly logged. Suggested by Interloper. [SW] * NetBSD compile and general warning fixes. [SW] * 'make portmsg' works, and portmsg.c rewritten to current * Favor difftime(3) over subtraction of time_t variables. [SW] Penn standards. [SW] * Several references of toloewr changed to DOWNCASE, and toupper to * UPCASE --- hdrs/log.h | 2 +- hdrs/mushtype.h | 5 -- src/Makefile.SH | 7 +- src/bsd.c | 16 ++--- src/cque.c | 8 +-- src/funlist.c | 2 +- src/funstr.c | 4 +- src/game.c | 29 ++++---- src/log.c | 8 ++- src/parse.c | 2 +- src/portmsg.c | 177 +++++++++++++++++------------------------------- src/timer.c | 1 + 12 files changed, 107 insertions(+), 154 deletions(-) diff --git a/hdrs/log.h b/hdrs/log.h index ea20250..43fa90b 100644 --- a/hdrs/log.h +++ b/hdrs/log.h @@ -14,7 +14,7 @@ /* From log.c */ extern void start_all_logs(void); extern void end_all_logs(void); -extern void redirect_stderr(void); +extern void redirect_streams(void); extern void WIN32_CDECL do_log (int logtype, dbref player, dbref object, const char *fmt, ...) __attribute__ ((__format__(__printf__, 4, 5))); diff --git a/hdrs/mushtype.h b/hdrs/mushtype.h index 6f0e67b..c0ed601 100644 --- a/hdrs/mushtype.h +++ b/hdrs/mushtype.h @@ -1,11 +1,6 @@ #ifndef MUSH_TYPES_H #define MUSH_TYPES_H #include "copyrite.h" -#include "options.h" -#include -#ifdef WIN32 -#include -#endif #ifdef HAS_OPENSSL #include #endif diff --git a/src/Makefile.SH b/src/Makefile.SH index 8b4128c..d86b7d2 100644 --- a/src/Makefile.SH +++ b/src/Makefile.SH @@ -207,7 +207,7 @@ indent: (set +e; for file in *.dst *.c ../hdrs/*.h ; do echo $$file; \ /usr/bin/expand $$file > tmpfile; mv -f tmpfile $$file; \ /usr/bin/indent -npro -kr -ci2 -ss -psl -ip4 -i2 -cs -l80 -lc75 \ - -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \ + -T atr_err -T ATRALIAS -T DESC -T CNode -T CONF -T BQUE -T FUN \ -T NVAL -T i_rec -T f_rec -T USERFN_ENTRY -T PRIV -T FLAG \ -T FLAGENT -T FLAG_ALIAS -T tlist -T u -T stat -T tcheck -T ATTR \ -T ALIST -T CHTAB -T FBLKHDR -T FBLOCK -T OPTTAB -T dbref \ @@ -231,8 +231,9 @@ distclean: clean test_compress: comp_h.c $(CC) $(CFLAGS) -o test_compress -DSTANDALONE comp_h.c -portmsg: portmsg.c - $(CC) $(CFLAGS) -o portmsg portmsg.c $(LIBS) +portmsg: portmsg.c mysocket.c sig.o + $(CC) $(CCFLAGS) -DINFOSLAVE -o portmsg portmsg.c mysocket.c sig.o \ + $(LDFLAGS) $(LIBS) # Some dependencies that make depend doesn't handle well compress.o: comp_h.c comp_w.c comp_w8.c diff --git a/src/bsd.c b/src/bsd.c index 085fa01..4f623d1 100644 --- a/src/bsd.c +++ b/src/bsd.c @@ -2904,7 +2904,7 @@ dump_messages(DESC *d, dbref player, int isnew) if (ModTime(player)) notify_format(player, T("%ld failed connections since last login."), - ModTime(player)); + (long) ModTime(player)); ModTime(player) = (time_t) 0; announce_connect(player, isnew, num); /* broadcast connect message */ check_last(player, d->addr, d->ip); /* set Last, Lastsite, give paycheck */ @@ -3124,7 +3124,7 @@ parse_connect(const char *msg1, char *command, char *user, char *pass) msg++; p = (unsigned char *) user; - if (PLAYER_NAME_SPACES && *msg == '\"') { + if (*msg == '\"') { for (; *msg && ((*msg == '\"') || isspace(*msg)); msg++) ; while (*msg && (*msg != '\"')) { while (*msg && !isspace(*msg) && (*msg != '\"')) @@ -3675,15 +3675,15 @@ dump_users(DESC *call_by, char *match, int doing) } static const char * -time_format_1(long dt) +time_format_1(time_t dt) { register struct tm *delta; - time_t holder; /* A hack for 64bit SGI */ + static char buf[64]; if (dt < 0) dt = 0; - holder = (time_t) dt; - delta = gmtime(&holder); + + delta = gmtime(&dt); if (delta->tm_yday > 0) { sprintf(buf, "%dd %02d:%02d", delta->tm_yday, delta->tm_hour, delta->tm_min); @@ -3694,14 +3694,14 @@ time_format_1(long dt) } static const char * -time_format_2(long dt) +time_format_2(time_t dt) { register struct tm *delta; static char buf[64]; if (dt < 0) dt = 0; - delta = gmtime((time_t *) & dt); + delta = gmtime(&dt); if (delta->tm_yday > 0) { sprintf(buf, "%dd", delta->tm_yday); } else if (delta->tm_hour > 0) { diff --git a/src/cque.c b/src/cque.c index c60d193..cc628a6 100644 --- a/src/cque.c +++ b/src/cque.c @@ -58,7 +58,7 @@ typedef struct bque { dbref ooref; /**< Used when doing twin checks */ dbref sem; /**< semaphore object to block on */ char *semattr; /**< semaphore attribute to block on */ - int left; /**< seconds left until execution */ + time_t left; /**< seconds left until execution */ char *env[10]; /**< environment, from wild match */ char *rval[NUMQ]; /**< environment, from setq() */ char *comm; /**< command to be executed */ @@ -791,7 +791,7 @@ que_next(void) /* Wait queue is in sorted order so we only have to look at the first item on it. Anything else is wasted time. */ if (qwait) { - curr = qwait->left - mudtime; + curr = (int) difftime(qwait->left, mudtime); if (curr <= 2) return 1; if (curr < min) @@ -801,7 +801,7 @@ que_next(void) for (point = qsemfirst; point; point = point->next) { if (point->left == 0) /* no timeout */ continue; - curr = point->left - mudtime; + curr = (int) difftime(point->left, mudtime); if (curr <= 2) return 1; if (curr < min) { @@ -1060,7 +1060,7 @@ do_wait(dbref player, dbref cause, char *arg1, char *cmd, int until, char finvoc } /* get timeout, default of -1 */ if (tcount && *tcount) - waitfor = atol(tcount); + waitfor = parse_integer(tcount); else waitfor = -1; add_to_sem(thing, 1, aname); diff --git a/src/funlist.c b/src/funlist.c index 33e010a..d142055 100644 --- a/src/funlist.c +++ b/src/funlist.c @@ -1288,7 +1288,7 @@ FUNCTION(fun_sortkey) /* Now we make a list of keys */ for (i = 0; i < nptrs; i++) { /* Build our %0 args */ - wenv[0] = (char *)ptrs[i]; + wenv[0] = (char *) ptrs[i]; call_ufun(&ufun, wenv, 2, result, executor, enactor, pe_info); keys[i] = mush_strdup(result, "sortkey"); } diff --git a/src/funstr.c b/src/funstr.c index c4efed0..8daf98e 100644 --- a/src/funstr.c +++ b/src/funstr.c @@ -176,7 +176,7 @@ FUNCTION(fun_art) safe_chr('a', buff, bp); return; } - c = tolower(*p); + c = DOWNCASE(*p); if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') safe_str("an", buff, bp); else @@ -487,7 +487,7 @@ FUNCTION(fun_comp) safe_str(T("#-1 INVALID THIRD ARGUMENT"), buff, bp); return; } else if (nargs == 3) { - type = toupper(*args[2]); + type = UPCASE(*args[2]); } switch (type) { diff --git a/src/game.c b/src/game.c index 005a52d..5b02bbc 100644 --- a/src/game.c +++ b/src/game.c @@ -797,7 +797,7 @@ init_game_config(const char *conf) conf_default_set(); config_file_startup(conf, 0); start_all_logs(); - redirect_stderr(); + redirect_streams(); /* Initialize the attribute chunk storage */ chunk_init(); @@ -2223,24 +2223,24 @@ do_uptime(dbref player, int mortal) notify_format(player, T ("Time until next database save: %ld minutes %ld seconds, at %s"), - (options.dump_counter - mudtime) / 60, - (options.dump_counter - mudtime) % 60, tbuf1); + ((long) difftime(options.dump_counter, mudtime)) / 60, + ((long) difftime(options.dump_counter, mudtime)) % 60, tbuf1); when = localtime(&options.dbck_counter); strftime(tbuf1, sizeof tbuf1, "%X", when); notify_format(player, T (" Time until next dbck check: %ld minutes %ld seconds, at %s."), - (options.dbck_counter - mudtime) / 60, - (options.dbck_counter - mudtime) % 60, tbuf1); + ((long) difftime(options.dbck_counter, mudtime)) / 60, + ((long) difftime(options.dbck_counter, mudtime)) % 60, tbuf1); when = localtime(&options.purge_counter); strftime(tbuf1, sizeof tbuf1, "%X", when); notify_format(player, T (" Time until next purge: %ld minutes %ld seconds, at %s."), - (options.purge_counter - mudtime) / 60, - (options.purge_counter - mudtime) % 60, tbuf1); + ((long) difftime(options.purge_counter, mudtime)) / 60, + ((long) difftime(options.purge_counter, mudtime)) % 60, tbuf1); if (options.warn_interval) { when = localtime(&options.warn_counter); @@ -2248,17 +2248,20 @@ do_uptime(dbref player, int mortal) notify_format(player, T (" Time until next @warnings: %ld minutes %ld seconds, at %s."), - (options.warn_counter - mudtime) / 60, - (options.warn_counter - mudtime) % 60, tbuf1); + ((long) difftime(options.warn_counter, mudtime)) / 60, + ((long) difftime(options.warn_counter, mudtime)) % 60, tbuf1); } notify_format(player, T ("PennMUSH Uptime: %ld days %ld hours %ld minutes %ld seconds"), - (mudtime - globals.first_start_time) / 86400, - ((mudtime - globals.first_start_time) % 86400) / 3600, - (((mudtime - globals.first_start_time) % 86400) % 3600) / 60, - (((mudtime - globals.first_start_time) % 86400) % 3600) % 60); + ((long) difftime(mudtime, globals.first_start_time)) / 86400, + ((long) difftime(mudtime, globals.first_start_time) % 86400) / + 3600, + (((long) difftime(mudtime, globals.first_start_time) % 86400) % + 3600) / 60, + (((long) difftime(mudtime, globals.first_start_time) % 86400) % + 3600) % 60); /* Mortals, go no further! */ if (!Site(player) || mortal) diff --git a/src/log.c b/src/log.c index 06afea1..7242970 100644 --- a/src/log.c +++ b/src/log.c @@ -123,12 +123,12 @@ start_all_logs(void) start_log(&cmdlog_fp, CMDLOG); } -/** Redirect stderr to a error log file. +/** Redirect stderr to a error log file and close stdout and stdin. * Should be called after start_all_logs(). * \param log name of logfile to redirect stderr to. */ void -redirect_stderr(void) +redirect_streams(void) { FILE *errlog_fp; @@ -145,6 +145,10 @@ redirect_stderr(void) setvbuf(stderr, NULL, _IOLBF, BUFSIZ); fclose(errlog_fp); } +#ifndef DEBUG_BYTECODE + fclose(stdout); +#endif + fclose(stdin); } diff --git a/src/parse.c b/src/parse.c index b92ea5c..63ff7fd 100644 --- a/src/parse.c +++ b/src/parse.c @@ -847,7 +847,7 @@ process_expression(char *buff, char **bp, char const **str, if (!nextc) goto exit_sequence; (*str)++; - if (!isdigit(nextc)) { + if (!isdigit((unsigned char) nextc)) { safe_str(T(e_int), buff, bp); break; } diff --git a/src/portmsg.c b/src/portmsg.c index 238f9e5..161b3a0 100644 --- a/src/portmsg.c +++ b/src/portmsg.c @@ -42,7 +42,7 @@ * SUCH DAMAGE. * * This version extensively modified by Javelin (Alan Schwartz) - * to conform to PennMUSH autoconfiguration standards. + * and Raevnos (Shawn Wagner) to conform to PennMUSH standards. */ /* If you have multiple IP addresses and want to bind to only one, @@ -74,15 +74,13 @@ #include #endif #include +#include #include "conf.h" #include "externs.h" -#include "mymalloc.h" +#include "mysocket.h" #include "confmagic.h" -/* What htons expects */ -typedef unsigned short Port_t; - #ifdef HAS_WAITPID #define WAIT_TYPE int #else @@ -93,30 +91,39 @@ typedef unsigned short Port_t; #endif #endif -static Signal_t wait_on_child(int sig); -static Signal_t lostconn(int sig); -static int how_many_fds(void); +#ifndef SINGLE_IP_ADDR +const char *host_ip = ""; +#else +const char *host_ip = SINGLE_IP_ADDR +#endif + static void wait_on_child(int sig); +static void +lostconn(int sig) + NORETURN; + + enum { MAX_CONNECTIONS = 15 }; + int connections = 0; -static Signal_t -wait_on_child(int sig __attribute__ ((__unused__))) + static void + wait_on_child(int sig __attribute__ ((__unused__))) { WAIT_TYPE status; #ifdef HAS_WAITPID - while (waitpid(-1, &status, WNOHANG) > 0) ; + while (waitpid(-1, &status, WNOHANG) > 0) + connections--; #else - while (wait3(&status, WNOHANG, 0) > 0) ; + while (wait3(&status, WNOHANG, NULL) > 0) + connections--; #endif -#ifndef SIGNALS_KEPT - signal(SIGCLD, (Sigfunc) wait_on_child); -#endif -#ifndef VOIDSIG - return 0; -#endif + if (connections < 0) + connections = 0; + + reload_sig_handler(SIGCHLD, wait_on_child); } -Signal_t +void lostconn(int sig __attribute__ ((__unused__))) { exit(1); @@ -125,52 +132,49 @@ lostconn(int sig __attribute__ ((__unused__))) int main(int argc, char **argv) { - int msgfd, fd, n; + int msgfd, fd; struct stat statBuf; Port_t port; char *msg; int sockfd, newsockfd; - int addrlen; - int opt; - struct sockaddr_in tcp_srv_addr; - struct sockaddr_in their_addr; - int num_fds; + socklen_t addrlen = 0; + union sockaddr_u their_addr; if (argc != 3) { fprintf(stderr, "Usage: portmsg file port\n"); - exit(1); + return 1; } port = atoi(argv[2]); if (port == 0) { fprintf(stderr, "error: bad port number [%s]\n", argv[2]); - exit(1); + return 1; } if ((msgfd = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "error: cannot open message file [%s]\n", argv[1]); - exit(1); + fprintf(stderr, "error: cannot open message file [%s]: %s\n", argv[1], + strerror(errno)); + return 1; } /* read the message */ fstat(msgfd, &statBuf); if (statBuf.st_size <= 0) { fprintf(stderr, "error: message file [%s] is empty\n", argv[1]); - exit(1); + return 1; } msg = (char *) malloc(statBuf.st_size); if (read(msgfd, msg, statBuf.st_size) != statBuf.st_size) { fprintf(stderr, "error: cannot read message file [%s]\n", argv[1]); - exit(1); + return 1; } - num_fds = how_many_fds(); /* become a daemon */ switch (fork()) { case -1: - fprintf(stderr, "error: can't fork\n"); - exit(1); + perror("can't fork"); + return 1; case 0: break; default: - exit(0); + return 0; } #ifdef HAS_SETPGRP #ifdef USE_BSD_SETPGRP @@ -178,8 +182,8 @@ main(int argc, char **argv) #else if (setpgrp() == -1) { #endif - fprintf(stderr, "error: can't change process group\n"); - exit(1); + perror("can't change process group"); + return 1; } #endif @@ -190,98 +194,43 @@ main(int argc, char **argv) } #endif - signal(SIGCLD, (void *) wait_on_child); - memset((char *) &tcp_srv_addr, 0, sizeof(tcp_srv_addr)); - tcp_srv_addr.sin_family = AF_INET; -#ifdef SINGLE_IP_ADDR - tcp_srv_addr.sin_addr.s_addr = inet_addr(MUSH_IP_ADDR); -#else - tcp_srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); -#endif - tcp_srv_addr.sin_port = htons(port); + install_sig_handler(SIGCHLD, wait_on_child); - if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - fprintf(stderr, "can't create stream socket\n"); - exit(-1); + if ((sockfd = make_socket(port, NULL, NULL, host_ip)) < 0) { + perror("can't make socket"); + return 1; } - opt = 1; - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - (char *) &opt, sizeof(opt)) < 0) { - perror("setsockopt"); - exit(1); - } - if (bind(sockfd, (struct sockaddr *) &tcp_srv_addr, sizeof(tcp_srv_addr)) < 0) { - fprintf(stderr, "can't bind local address\n"); - exit(-1); - } - listen(sockfd, 5); main_again: + if (connections > MAX_CONNECTIONS) { + sleep(1); + goto main_again; + } addrlen = sizeof(their_addr); - newsockfd = accept(sockfd, (struct sockaddr *) &their_addr, &addrlen); + newsockfd = accept(sockfd, &their_addr.addr, &addrlen); if (newsockfd < 0) { if (errno == EINTR) goto main_again; - fprintf(stderr, "accept error\n"); - exit(-1); + perror("Couldn't accept connection"); + return 1; } + connections++; switch (fork()) { case -1: - fprintf(stderr, "server can't fork\n"); - exit(-1); + perror("server can't fork"); + return 1; case 0: - dup2(newsockfd, 0); - dup2(newsockfd, 1); - for (n = 3; n < num_fds; n++) - close(n); + /* child process */ + install_sig_handler(SIGPIPE, lostconn); + ignore_signal(SIGCHLD); + send(newsockfd, msg, statBuf.st_size, 0); + sleep(5); + closesocket(newsockfd); break; default: - close(newsockfd); + closesocket(newsockfd); goto main_again; } - /* daemon child arrives here */ - signal(SIGPIPE, lostconn); - signal(SIGCLD, SIG_IGN); - - fprintf(stdout, msg); - fflush(stdout); - sleep(5); - exit(0); -} - -static int -how_many_fds(void) -{ - /* Determine how many open file descriptors we're allowed - * In order, we'll try: - * 0. OPEN_MAX constant - POSIX.1 limits.h - * 1. sysconf(_SC_OPEN_MAX) - POSIX.1 - * 2. getdtablesize - BSD - * 3. NOFILE - in some sys/param.h - * 4. _NFILE - in some stdio.h - */ -#ifdef OPEN_MAX - static int open_max = OPEN_MAX; -#else - static int open_max = 0; -#endif - - if (open_max) - return open_max; - -#ifdef HAS_SYSCONF - errno = 0; - if ((open_max = sysconf(_SC_OPEN_MAX)) < 0) { - if (errno == 0) /* Value was indeterminate */ - open_max = 0; - } - if (open_max) - return open_max; -#endif - /* Caching getdtablesize is dangerous, since it's affected by - * getrlimit, so we don't. - */ - open_max = 0; - return getdtablesize(); + return 0; } diff --git a/src/timer.c b/src/timer.c index dd2bca8..f552e6d 100644 --- a/src/timer.c +++ b/src/timer.c @@ -220,6 +220,7 @@ dispatch(void) } /* A USR1 does a shutdown/reboot */ if (usr1_triggered) { + do_rawlog(LT_ERR, T("SIGUSR1 received. Rebooting.")); do_reboot(NOTHING, 0); /* We don't return from this */ usr1_triggered = 0; /* But just in case */ } -- 2.30.2