PennMUSH patch 1.8.1-patch08 applied. untested
authorRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 08:28:04 +0000 (04:28 -0400)
committerRick Bird <nveid@bender.theari.com>
Fri, 25 Mar 2011 08:28:04 +0000 (04:28 -0400)
14 files changed:
hdrs/copyrite.h
hdrs/lock.h
src/attrib.c
src/bsd.c
src/command.c
src/funlist.c
src/funtime.c
src/game.c
src/lock.c
src/look.c
src/move.c
src/notify.c
src/parse.c
src/wiz.c

index 982503db17ab0ddff768e392e17c7d70b6b33779..5c623fc3b34871c0c22ff4cb62fc649fe7a6a213 100644 (file)
  *
  * Past and present PennMUSH development team members:
  *  T. Alexander Popiel, Ralph Melton, Thorvald Natvig, Luuk de Waard,
- *  Shawn Wagner, Ervin Hearn III, Alan "Javelin" Schwartz
+ *  Shawn Wagner, Ervin Hearn III, Alan "Javelin" Schwartz, Greg Millam
  * Past and present PennMUSH porters:
  *  Nick Gammon, Sylvia, Dan Williams, Ervin Hearn III
  * TinyMUSH 2.2, TinyMUSH 3.0, TinyMUX 2, and RhostMUSH developers
index 494c660e0940a253ce33feddce639bb7640e43c4..70f901e2a4fb21ead3c37be8253b5ebe4536ec4c 100644 (file)
@@ -60,6 +60,8 @@ int add_lock_raw(dbref player, dbref thing, lock_type type,
                 boolexp key, int flags);
 void free_locks(lock_list *ll);
 int eval_lock(dbref player, dbref thing, lock_type ltype);
+int eval_lock_with(dbref player, dbref thing, lock_type ltype, dbref env0,
+                  dbref env1);
 int fail_lock(dbref player, dbref thing, lock_type ltype, const char *def,
              dbref loc);
 void do_unlock(dbref player, const char *name, lock_type type);
index 84a3a85e7ae026d09389e65b321844c90d6f9e86..ddb7ffcc76e4572f1c2f71c4769c01419497a9b4 100644 (file)
@@ -1448,6 +1448,11 @@ atr_comm_divmatch(dbref thing, dbref player, int type, int end,
     if (!s)
       continue;
     *s++ = '\0';
+    if (type == '^' && !AF_Ahear(ptr)) {
+      if ((thing == player && !AF_Mhear(ptr))
+         || (thing != player && AF_Mhear(ptr)))
+       continue;
+    }
 
     if (AF_Regexp(ptr)) {
       /* Turn \: into : */
index 6ac6c9616b1c243963c797eb95490898b00d98c3..1eebb3433117bc7bc55e21778d7595e4f8c7a5c3 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -4137,7 +4137,7 @@ FUNCTION(fun_lwho)
   int start, count;
   int powered = !(strchr(called_as, 'M') != NULL) && Priv_Who(executor);
   int xwho = *called_as == 'X';
-  int objid = strchr(called_as, 'D') != NULL;
+  int objid = (index(called_as, 'D') != NULL);
 
   first = 1;
   if(!xwho && nargs && args[0] && *args[0]) {
@@ -4379,6 +4379,7 @@ FUNCTION(fun_zwho)
   dbref zone, victim;
   int first;
   int powered = (strcmp(called_as, "ZMWHO") && Priv_Who(executor));
+  int objid = (index(called_as, 'D') != NULL);
   first = 1;
 
   zone = match_thing(executor, args[0]);
@@ -4395,7 +4396,7 @@ FUNCTION(fun_zwho)
     return;
   }
 
-  if (!GoodObject(zone) || !(eval_lock(victim, zone, Zone_Lock) || CanSee(victim,zone))) {
+  if (!GoodObject(zone) || (!Priv_Who(executor) && !(eval_lock(victim, zone, Zone_Lock) || CanSee(victim,zone)))) {
     safe_str(T(e_perm), buff, bp);
     return;
   }
@@ -4418,6 +4419,10 @@ FUNCTION(fun_zwho)
          safe_chr(' ', buff, bp);
        }
        safe_dbref(d->player, buff, bp);
+       if (objid) {
+         safe_chr(':', buff, bp);
+         safe_integer(CreTime(d->player), buff, bp);
+       }
       }
   }
 }
index d71f3a5d1e5739a70200b734e177e6084f738f57..c6eb77eddd0cc4d4d013a50cf27dacc5f7f3c4f5 100644 (file)
@@ -1158,6 +1158,7 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from
       safe_str(ls, commandraw, &c2);
     }
     if (cmd->type & CMD_T_EQSPLIT) {
+      if(rhs_present) {
       safe_chr('=', commandraw, &c2);
       if (cmd->type & CMD_T_RS_ARGS) {
        int rsa_index;
@@ -1170,6 +1171,7 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from
            safe_str(rsa[rsa_index], commandraw, &c2);
          }
        }
+      }
       } else {
         safe_str(rs, commandraw, &c2);
       }
@@ -1370,7 +1372,7 @@ int command_lock(const char *name, const char *lock) {
  * This does nothing more than notify the player
  * with "This command has not been implemented"
  */
-COMMAND (cmd_unimplemented) {
+COMMAND(cmd_unimplemented) {
   char *saveregs[NUMQ];
 
   if (strcmp(cmd->name, "UNIMPLEMENTED_COMMAND") != 0 &&
index 455501b34312b336fb12c92ad922e205f99a4f0f..046c7768143a57abaf2b5907343462c0d572dfa0 100644 (file)
@@ -42,8 +42,9 @@ static int regrep_helper(dbref who, dbref what, dbref parent,
 /** Type definition for a qsort comparison function */
 typedef int (*comp_func) (const void *, const void *);
 static void sane_qsort(void **array, int left, int right, comp_func compare);
+enum itemfun_op { IF_DELETE, IF_REPLACE, IF_INSERT };
 static void do_itemfuns(char *buff, char **bp, char *str, char *num,
-                       char *word, char *sep, int flag);
+                       char *word, char *sep, enum itemfun_op flag);
 
 char *iter_rep[MAX_ITERS];  /**< itext values */
 int iter_place[MAX_ITERS];  /**< inum numbers */
@@ -2335,11 +2336,11 @@ FUNCTION(fun_index)
  * \param num string containing the element number to operate on.
  * \param word string to insert/delete/replace.
  * \param sep separator string.
- * \param flag operation to perform: 0 - delete, 1 - replace, 2 - insert
+ * \param flag operation to perform: IF_DELETE, IF_REPLACE, IF_INSERT
  */
 static void
 do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
-           char *sep, int flag)
+           char *sep, enum itemfun_op flag)
 {
   char c;
   int el, count, len = -1;
@@ -2358,7 +2359,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
     c = ' ';
 
   /* we can't remove anything before the first position */
-  if ((el < 1 && flag != 2) || el == 0) {
+  if ((el < 1 && flag != IF_INSERT) || el == 0) {
     safe_str(str, buff, bp);
     return;
   }
@@ -2408,7 +2409,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
     sptr[-1] = '\0';
 
   switch (flag) {
-  case 0:
+  case IF_DELETE:
     /* deletion */
     if (!eptr) {               /* last element in the string */
       if (el != 1)
@@ -2421,7 +2422,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
       safe_str(eptr, buff, bp);
     }
     break;
-  case 1:
+  case IF_REPLACE:
     /* replacing */
     if (!eptr) {               /* last element in string */
       if (el != 1) {
@@ -2439,7 +2440,7 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
       safe_str(eptr, buff, bp);
     }
     break;
-  case 2:
+  case IF_INSERT:
     /* insertion */
     if (sptr == str) {         /* first element in string */
       safe_str(word, buff, bp);
@@ -2449,8 +2450,10 @@ do_itemfuns(char *buff, char **bp, char *str, char *num, char *word,
       safe_str(str, buff, bp);
       safe_chr(c, buff, bp);
       safe_str(word, buff, bp);
-      safe_chr(c, buff, bp);
-      safe_str(sptr, buff, bp);
+      if (sptr && *sptr) {     /* Don't add an osep to the end of the list */
+       safe_chr(c, buff, bp);
+       safe_str(sptr, buff, bp);
+      }
     }
     break;
   }
@@ -2462,7 +2465,7 @@ FUNCTION(fun_ldelete)
 {
   /* delete a word at position X of a list */
 
-  do_itemfuns(buff, bp, args[0], args[1], NULL, args[2], 0);
+  do_itemfuns(buff, bp, args[0], args[1], NULL, args[2], IF_DELETE);
 }
 
 /* ARGSUSED */
@@ -2470,7 +2473,7 @@ FUNCTION(fun_replace)
 {
   /* replace a word at position X of a list */
 
-  do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], 1);
+  do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], IF_REPLACE);
 }
 
 /* ARGSUSED */
@@ -2478,7 +2481,7 @@ FUNCTION(fun_insert)
 {
   /* insert a word at position X of a list */
 
-  do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], 2);
+  do_itemfuns(buff, bp, args[0], args[1], args[2], args[3], IF_INSERT);
 }
 
 /* ARGSUSED */
index 67c8625a119b5614d215d8a9a32bb91d524fcf39..518cf624f7439665a6861d490f499a7c10f33dc9 100644 (file)
@@ -133,7 +133,7 @@ FUNCTION(fun_time)
          if(is_strict_number(ptr)) {
            utc = 1;
            tz = strtod(ptr, NULL);
-           if (tz >= -24.0 || tz <= 24.0) {
+           if (tz >= -24.0 && tz <= 24.0) {
              mytime += (int) (tz * 3600);
            }
          } else setenv("TZ", ptr, 1);
@@ -205,16 +205,6 @@ FUNCTION(fun_etimefmt)
 
 }
 
-/* ARGSUSED */
-FUNCTION(fun_stringsecs)
-{
-  int secs;
-  if (etime_to_secs(args[0], &secs))
-    safe_integer(secs, buff, bp);
-  else
-    safe_str(T("#-1 INVALID TIMESTRING"), buff, bp);
-}
-
 /** Convert an elapsed time string (3d 2h 1m 10s) to seconds.
  * \param str1 a time string.
  * \param secs pointer to an int to fill with number of seconds.
@@ -273,6 +263,61 @@ etime_to_secs(char *str1, int *secs)
 }
 
 
+/* ARGSUSED */
+FUNCTION(fun_stringsecs)
+{
+  /* parse the result from timestring() back into a number of seconds */
+
+  int secs = 0;
+  char *str1 = args[0];
+  char str2[BUFFER_LEN];
+  int i;
+
+  while (str1 && *str1) {
+    while (*str1 == ' ')
+      str1++;
+    i = 0;
+    while (isdigit((unsigned char) *str1)) {
+      str2[i] = *str1;
+      str1++;
+      i++;
+    }
+    if (i == 0) {
+      safe_str(T("#-1 INVALID TIMESTRING"), buff, bp); // no numbers
+      return;
+    }
+    str2[i] = '\0';
+    if (!*str1) {
+      secs += parse_integer(str2);     // no more chars, just add seconds and stop
+      break;
+    }
+    switch (*str1) {
+    case 'd':
+    case 'D':
+      secs += (parse_integer(str2) * 86400);   // days
+      break;
+    case 'h':
+    case 'H':
+      secs += (parse_integer(str2) * 3600);    // hours
+      break;
+    case 'm':
+    case 'M':
+      secs += (parse_integer(str2) * 60);      // minutes
+      break;
+    case 's':
+    case 'S':
+    case ' ':
+      secs += parse_integer(str2);     // seconds
+      break;
+    default:
+      safe_str(T("#-1 INVALID TIMESTRING"), buff, bp);
+      return;
+    }
+    str1++;                    // move past the time char
+  }
+  safe_integer(secs, buff, bp);
+}
+
 /* ARGSUSED */
 FUNCTION(fun_timestring)
 {
index 7df66d81e8d85867e78bdb2954f3ab90b7b4e7e3..37d3db2f163e8d264c1446b6a3c973cc8ed52d19 100644 (file)
@@ -1994,7 +1994,7 @@ linux_uptime(dbref player __attribute__ ((__unused__)))
   {
     struct tm *t;
     t = localtime(&mudtime);
-    strftime(tbuf1, sizeof tbuf1, "%I:%M%p ", t);
+    strftime(tbuf1, sizeof tbuf1, "Server uptime: %I:%M%p ", t);
     nl = tbuf1 + strlen(tbuf1);
   }
   /* System uptime */
@@ -2252,6 +2252,14 @@ do_uptime(dbref player, int mortal)
                  (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);
+
   /* Mortals, go no further! */
   if (!Site(player) || mortal)
     return;
index c22d76e77eb6786e80071d1e15f12b27d55d0f42..8d45c46c79f424acc68b6c9717c57fd0cbe911c8 100644 (file)
@@ -806,6 +806,47 @@ eval_lock(dbref player, dbref thing, lock_type ltype)
   return eval_boolexp(player, getlock(thing, ltype), thing, NULL);
 }
 
+/** Evaluate a lock.
+ * Evaluate lock ltype on thing for player, passing dbrefs for %0/%1.
+ * \param player dbref attempting to pass the lock.
+ * \param thing object containing the lock.
+ * \param ltype type of lock to check.
+ * \retval 1 player passes the lock.
+ * \retval 0 player does not pass the lock.
+ */
+int
+eval_lock_with(dbref player, dbref thing, lock_type ltype, dbref env0,
+              dbref env1)
+{
+  char *myenv[10] = { NULL };
+  char e0[SBUF_LEN], e1[SBUF_LEN], *ep;
+  char *preserves[10];
+  int result;
+
+  if (env0 != NOTHING) {
+    ep = e0;
+    safe_dbref(env0, e0, &ep);
+    *ep = '\0';
+    myenv[0] = e0;
+  }
+
+  if (env1 != NOTHING) {
+    ep = e1;
+    safe_dbref(env1, e1, &ep);
+    *ep = '\0';
+    myenv[1] = e1;
+  }
+
+  save_global_env("eval_lock_save", preserves);
+  restore_global_env("eval_lock", myenv);
+
+  boolexp b = getlock(thing, ltype);
+  log_activity(LA_LOCK, thing, unparse_boolexp(player, b, UB_DBREF));
+  result = eval_boolexp(player, b, thing, NULL);
+  restore_global_env("eval_lock_save", preserves);
+  return result;
+}
+
 /** Active a lock's failure attributes.
  * \param player dbref failing to pass the lock.
  * \param thing object containing the lock.
index 41b6795076b0bb3e4444d74d2a1e11217340abff..2c738d0801ffc07c5f7b65cfb131554f1459454f 100644 (file)
@@ -79,13 +79,14 @@ look_exits(dbref player, dbref loc, const char *exit_name)
   a = atr_get(loc, "EXITFORMAT");
   if (a) {
     char *wsave[10], *rsave[NUMQ];
-    char *arg, *buff, *bp, *save;
+    char *arg, *arg2, *buff, *bp, *save;
     char const *sp;
     int j;
 
     arg = (char *) mush_malloc(BUFFER_LEN, "string");
+    arg2 = (char *) mush_malloc(BUFFER_LEN, "string");
     buff = (char *) mush_malloc(BUFFER_LEN, "string");
-    if (!arg || !buff)
+    if (!arg || !buff || !arg2)
       mush_panic("Unable to allocate memory in look_exits");
     save_global_regs("look_exits", rsave);
     for (j = 0; j < 10; j++) {
@@ -126,6 +127,7 @@ look_exits(dbref player, dbref loc, const char *exit_name)
     mush_free((Malloc_t) tbuf2, "string");
     mush_free((Malloc_t) nbuf, "string");
     mush_free((Malloc_t) arg, "string");
+    mush_free((Malloc_t) arg2, "string");
     mush_free((Malloc_t) buff, "string");
     return;
   }
index ea471eb7320bc4bbe20acd8821a94142ba68d737..d58e799152c88bc62e54a034dbf66cb10b97d855 100644 (file)
@@ -303,8 +303,7 @@ can_move(dbref player, const char *direction)
 {
   int ok;
   if (!strcasecmp(direction, "home")) {
-    ok = !Fixed(player);
-    ok = ok && command_check_byname(player, "HOME");
+    ok = command_check_byname(player, "HOME");
   } else {
     /* otherwise match on exits - don't use GoodObject here! */
     ok = (match_result(player, direction, TYPE_EXIT, MAT_ENGLISH | MAT_EXIT) !=
index 387dab0d8981d201cba4f6c674bb9dc6df34cdad..0d49cbbde7bbfd6912d36a7ac6a978e9302aaf36 100644 (file)
@@ -973,11 +973,10 @@ notify_anything_loc(dbref speaker, na_lookup func,
       }
     }
     /* if object is flagged LISTENER, check for ^ listen patterns
-     *    * these are like AHEAR - object cannot trigger itself.
      *    * unlike normal @listen, don't pass the message on.
      *    */
 
-    if ((speaker != target) && (ThingListen(target) || RoomListen(target))
+    if ((ThingListen(target) || RoomListen(target))
        && eval_lock(speaker, target, Listen_Lock)
       )
       atr_comm_match(target, speaker, '^', ':',
index df5be49dc28d6510d1aaba1ab90e315b7ec21415..b92ea5cfc4573ea89bf36a3a22f815b3b9292ed9 100644 (file)
@@ -653,9 +653,11 @@ process_expression(char *buff, char **bp, char const **str,
       break;
     case '$':                  /* Dollar subs for regedit() */
       if ((eflags & (PE_DOLLAR | PE_EVALUATE)) == (PE_DOLLAR | PE_EVALUATE) &&
-         global_eval_context.re_subpatterns >= 0) {
+         global_eval_context.re_subpatterns >= 0 &&
+         global_eval_context.re_offsets != NULL &&
+         global_eval_context.re_from != NULL) {
        char obuf[BUFFER_LEN];
-       int p = 0;
+       int p = -1;
         char subspace[BUFFER_LEN];
         char *named_substring = NULL;
 
@@ -665,24 +667,13 @@ process_expression(char *buff, char **bp, char const **str,
        if (isdigit((unsigned char) **str)) {
          p = **str - '0';
          (*str)++;
-         if (isdigit((unsigned char) **str)) {
-           p *= 10;
-           p += **str - '0';
-           (*str)++;
-           if (isdigit((unsigned char) **str)) {
-             /* More than 100. Treat this as literal. */
-             safe_chr('$', buff, bp);
-             safe_number(p, buff, bp);
-           }
-         }
-         /* Look for a named subexpression */
        } else if (**str == '<') {
          char *nbuf = subspace;
          (*str)++;
-         for (; *str && **str != '>'; (*str)++)
+         for (; *str && **str && **str != '>'; (*str)++)
            safe_chr(**str, subspace, &nbuf);
          *nbuf = '\0';
-         if (*str)
+         if (*str && **str)
            (*str)++;
          if (is_strict_integer(subspace))
            p = abs(parse_integer(subspace));
@@ -693,18 +684,6 @@ process_expression(char *buff, char **bp, char const **str,
          break;
        }
 
-       if ((!named_substring && p >= global_eval_context.re_subpatterns) ||
-           global_eval_context.re_offsets == NULL ||
-           global_eval_context.re_from == NULL) {
-         /* It's out of bounds, return */
-         safe_chr('$', buff, bp);
-         if (named_substring)
-           safe_format(buff, bp, "<%s>", named_substring);
-         else
-           safe_integer(p, buff, bp);
-         break;
-       }
-
        if (named_substring) {
          pcre_copy_named_substring(global_eval_context.re_code,
                                    global_eval_context.re_from,
index 863d868dab7d6df924070189103cc85afb1ecefc..fa19335b0385326e558b327c02564818501feabd 100644 (file)
--- a/src/wiz.c
+++ b/src/wiz.c
@@ -400,7 +400,7 @@ do_teleport(dbref player, const char *arg1, const char *arg2, int silent,
     if (player == victim) {
       if (Fixed(victim) || RPMODE(victim))
        notify(player, T("You can't do that IC!"));
-      else
+      else if(command_check_byname(victim, "HOME"))
        safe_tel(victim, HOME, silent);
       return;
     } else
@@ -1995,7 +1995,8 @@ raw_search(dbref player, const char *owner, int nargs, const char **args,
   }
 
   if ((spec.owner != ANY_OWNER && spec.owner != Owner(player)
-      && !(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER)))) {
+      && !(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER)) ||
+      (ZMaster(spec.owner) && eval_lock(player, spec.owner, Zone_Lock)))) {
     giveto(player, FIND_COST);
     notify(player, T("You need a search warrant to do that."));
     return -1;