PennMUSH Incorp 182p4
authorRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 21:16:27 +0000 (17:16 -0400)
committerRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 21:16:27 +0000 (17:16 -0400)
  * 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

12 files changed:
hdrs/log.h
hdrs/mushtype.h
src/Makefile.SH
src/bsd.c
src/cque.c
src/funlist.c
src/funstr.c
src/game.c
src/log.c
src/parse.c
src/portmsg.c
src/timer.c

index ea202501a0a69d1b39f94c98b0e18379a318f1ce..43fa90ba1b0176ae78ee08232064af69b69d3e55 100644 (file)
@@ -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)));
index 6f0e67b639cf471e91d42aada7511210adb516e3..c0ed6017c493a99767d472625e5a3d403066b4c6 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef MUSH_TYPES_H
 #define MUSH_TYPES_H
 #include "copyrite.h"
-#include "options.h"
-#include <stdio.h>
-#ifdef WIN32
-#include <windows.h>
-#endif
 #ifdef HAS_OPENSSL
 #include <openssl/ssl.h>
 #endif
index 8b4128ceaf2cec9e3b6d236b666bea2c182ed604..d86b7d2864e1da7838bf1407fda24c9f362b176e 100644 (file)
@@ -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
index 085fa0190e20315672a31567e72a5a9eaecb2b0f..4f623d14f13a3ba99c210ccbed7de9d41a4bfc91 100644 (file)
--- 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) {
index c60d19379c44447d619af042866403c363afd169..cc628a6c5843d9104649fe787b636b22fe9dbb45 100644 (file)
@@ -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);
index 33e010a0de14a31e9ed56cf38fce1984e45a304f..d1420558b8370652d6ff1a8966c10bf6f5c9b688 100644 (file)
@@ -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");
   }
index c4efed05099c6cd67034c263a6e75cbe931c1f0d..8daf98e5bc07c3711c0b904dda458a7b513db2f3 100644 (file)
@@ -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) {
index 005a52db7ac92b54ddeceb739938e593e1ea7706..5b02bbcd9022f2c5450bf6bab891a3e3d8a16e88 100644 (file)
@@ -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)
index 06afea1b0327790e1acf50366884f02a22f9f52b..7242970cab479ea5a874885bcef706c6dbd9696f 100644 (file)
--- 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);
 }
 
 
index b92ea5cfc4573ea89bf36a3a22f815b3b9292ed9..63ff7fd1c67bab1f28700df1d13b8787c0d9d8eb 100644 (file)
@@ -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;
          }
index 238f9e503750b588c8aae2bc8e7e8bb5f386c83d..161b3a0e5ab3bf64b1accfb1616ac8656f1686e8 100644 (file)
@@ -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,
 #include <sys/wait.h>
 #endif
 #include <fcntl.h>
+#include <string.h>
 
 #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;
 }
index dd2bca8a2e6d58478289eb1e88682b6679f05fb4..f552e6d6a6d8e8d61532b6e57b261c0ceef58b28 100644 (file)
@@ -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 */
   }