PennMUSH Enhancements 1.8.3p10
authorRick L Bird <nveid@yahoo.com>
Sat, 23 Apr 2011 05:18:37 +0000 (01:18 -0400)
committerRick L Bird <nveid@yahoo.com>
Sat, 23 Apr 2011 05:18:37 +0000 (01:18 -0400)
Commit Refs: #97 to #123

31 files changed:
configure.ac
hdrs/SFMT.h
hdrs/lock.h
hdrs/mushdb.h
hdrs/parse.h
src/atr_tab.c
src/attrib.c
src/bsd.c
src/cmds.c
src/command.c
src/cque.c
src/create.c
src/db.c
src/function.c
src/fundb.c
src/funlist.c
src/funmath.c
src/funmisc.c
src/funstr.c
src/game.c
src/lock.c
src/markup.c
src/mysocket.c
src/notify.c
src/parse.c
src/pcre.c
src/predicat.c
src/set.c
src/wild.c
src/wiz.c
test/testrand.pl

index 455906c4250901d89341d3d1b3392c18cdba59dd..6a3ae142ff2c6da2296d7e33a440757f73082249 100644 (file)
@@ -205,7 +205,13 @@ AC_CHECK_LIB(intl, gettext)
 AC_CHECK_LIB(crypt, crypt)
 LIB_SOCKET_NSL
 AC_CHECK_LIB(fam, FAMOpen)
-AC_CHECK_LIB(z, gzungetc)
+
+
+AC_ARG_ENABLE(zlib, AS_HELP_STRING([--disable-zlib], [Don't use zlib for database compression.]),
+                   enable_zlib=$enableval, enable_zlib=yes)
+if test "$enable_zlib" = "yes"; then
+ AC_CHECK_LIB(z, gzungetc)
+fi
 
 # with_ssl=set
 CHECK_SSL
index 8729b62aac08808155bb31549ff1efd1b10595ae..4e78ce30c1c218194c30f29a6288bcf2e32294c8 100644 (file)
@@ -36,8 +36,6 @@
 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
 #include <inttypes.h>
 #elif defined(_MSC_VER) || defined(__BORLANDC__)
-typedef unsigned int uint32_t;
-typedef unsigned __int64 uint64_t;
 #define inline __inline
 #else
 #include <inttypes.h>
index af1c67156cc9ab93ea28b3b6639925b6deb2b08c..9e3f313c23cb221773b3893ebd57b623b4371d69 100644 (file)
@@ -76,6 +76,9 @@ void do_list_locks(dbref player, const char *arg, int lc, const char *label);
 void list_locks(char *buff, char **bp, const char *name);
 const char *lock_flags(lock_list *ll);
 const char *lock_flags_long(lock_list *ll);
+void list_lock_flags(char *buff, char **bp);
+void list_lock_flags_long(char *buff, char **bp);
+lock_list *getlockstruct(dbref thing, lock_type type);
 void check_zone_lock(dbref player, dbref zone, int noisy);
 void define_lock(lock_type name, privbits flags);
 #define L_FLAGS(lock) ((lock)->flags)
index 56ac5531730a385846cd2134037ed227c7fcfc72..227bea48cbe4d70db933e5342050da93b7f20472 100644 (file)
@@ -222,7 +222,7 @@ bool unfindable(dbref);
 #define DBF_DIVISIONS           0x40000
 #define DBF_LABELS              0x100000
 #define DBF_SPIFFY_AF_ANSI      0x200000
-
+#define DBF_HEAR_CONNECT        0x400000
 
 /* CobraMUSH Specific DBF Flags */
 #define DBF_NEW_ATR_LOCK        0x200000
index 6dd83bd55c8358366c543466145bd94fd8ceeea2..4eb7715042ca8793c83505a58f8872391ba404e4 100644 (file)
@@ -79,6 +79,7 @@ bool is_objid(char const *str);
 
 bool is_integer(char const *str);
 bool is_uinteger(char const *str);
+bool is_strict_uinteger(const char *str);
 bool is_boolean(char const *str);
 
 /* Split a sep-delimited string into individual elements */
index 033072627980fb75980636f54911f59ae21794c8..d893f974b3c355037b707476784f139f789451a2 100644 (file)
@@ -534,6 +534,7 @@ list_attribs(void)
   int nptrs = 0, i;
 
   ap = (ATTR *) ptab_firstentry(&ptab_attrib);
+  ptrs[0] = "";
   while (ap) {
     ptrs[nptrs++] = AL_NAME(ap);
     ap = (ATTR *) ptab_nextentry(&ptab_attrib);
index b459356309af7f82dcc824d99e0333c62f814955..aa9375a7b7c7d9631328632db67ac21dfd4cde3c 100644 (file)
@@ -1258,7 +1258,8 @@ atr_comm_match(dbref thing, dbref player, int type, int end,
     parent_depth = GoodObject(Parent(thing));
   } else {
     flag_mask = AF_LISTEN;
-    if (ThingInhearit(thing) || RoomInhearit(thing)) {
+    if (has_flag_by_name
+        (thing, "LISTEN_PARENT", TYPE_PLAYER | TYPE_THING | TYPE_ROOM)) {
       parent_depth = GoodObject(Parent(thing));
     } else {
       parent_depth = 0;
index a2bb918ce38748e7582df1a72a62ac53d776c8b5..a12a2b10c131b6307b50262b93a6243971c8c229 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -782,9 +782,8 @@ main(int argc, char **argv)
   shutdown_checkpoint();
 #endif
   WSACleanup();                 /* clean up */
-#else
-  exit(0);
 #endif
+  exit(0);
 }
 #endif                          /* BOOLEXP_DEBUGGING */
 
@@ -3952,6 +3951,32 @@ FUNCTION(fun_lwho)
   }
 }
 
+#ifdef WIN32
+#pragma warning( disable : 4761)        /* Disable bogus conversion warning */
+#endif
+/* ARGSUSED */
+FUNCTION(fun_hidden)
+{
+  dbref it = match_thing(executor, args[0]);
+  if (CanSee(executor, it) && ((Admin(executor) ||
+                                  Location(executor) == Location(it) || Location(it) == executor))) {
+  if ((it == NOTHING) || (!IsPlayer(it))) {
+    notify(executor, T("Couldn't find that player."));
+    safe_str("#-1", buff, bp);
+    return;
+  }
+  safe_boolean(hidden(it), buff, bp);
+  return;
+  } else { 
+          notify(executor, T("Permission denied.")); 
+          safe_str("#-1", buff, bp); 
+          return;
+  }
+}
+
+#ifdef WIN32
+#pragma warning( default : 4761)        /* Re-enable conversion warning */
+#endif
 
 /** Look up a DESC by character name or file descriptor.
  * \param executor the dbref of the object calling the function calling this.
index c66766121916e2f21bdc54f0d6feb6c46afdc35c..548818546454219ebeb5bbdd75d29a0064811d69 100644 (file)
@@ -76,7 +76,9 @@ COMMAND (cmd_atrlock) {
 }
 
 COMMAND (cmd_attribute) {
-  if (SW_ISSET(sw, SWITCH_ACCESS))
+  if(SW_ISSET(sw, SWITCH_INFO) || !has_power(player, "GFUNCS")) {
+    do_attribute_info(player, arg_left);
+  } else if (SW_ISSET(sw, SWITCH_ACCESS))
     do_attribute_access(player, arg_left, arg_right,            
         SW_ISSET(sw, SWITCH_RETROACTIVE));
   else if(SW_ISSET(sw, SWITCH_LOCK)) {
@@ -87,10 +89,9 @@ COMMAND (cmd_attribute) {
   }
   else if (SW_ISSET(sw, SWITCH_DELETE))
     do_attribute_delete(player, arg_left, SW_ISSET(sw, SWITCH_DEFAULTS));
-  else if (SW_ISSET(sw, SWITCH_RENAME))
-    do_attribute_rename(player, arg_left, arg_right);
-  else
-    do_attribute_info(player, arg_left);
+  else if (SW_ISSET(sw, SWITCH_RENAME)) {
+      do_attribute_rename(player, arg_left, arg_right);
+  } else notify(player, "You lost me..."); 
 }
 
 COMMAND(cmd_atrchown)
@@ -195,11 +196,11 @@ COMMAND(cmd_config)
     {
       int source = SW_ISSET(sw, SWITCH_SAVE) ? 2 : 1;
       if (source == 2) {
-       if (!God(player)) {
-       /* Only god can alter the original config file. */
-         notify(player, T("You can't remake the world in your image."));
-         return;
-       }     
+        if (!God(player)) {
+          /* Only god can alter the original config file. */
+          notify(player, T("You can't remake the world in your image."));
+          return;
+        }
       }
       if (!config_set(arg_left, arg_right, source, 0)
           && !config_set(arg_left, arg_right, source, 1))
index 30b0f4f1203805c993997e0c61b5cc3282016908..a6b1716f6e077aa6d9acfe9c371644fe0d611dd5 100644 (file)
@@ -87,7 +87,7 @@ COMLIST commands[] = {
   {"@ATRLOCK", "READ WRITE", cmd_atrlock, CMD_T_ANY | CMD_T_EQSPLIT, NULL},
   {"@ATRCHOWN", NULL, cmd_atrchown, CMD_T_EQSPLIT, NULL},
   {"@ATTRIBUTE", "ACCESS DEFAULTS LOCK WRITE READ DELETE RENAME RETROACTIVE", cmd_attribute,
-   CMD_T_ANY | CMD_T_EQSPLIT, "POWER^GFUNCS"},
+   CMD_T_ANY | CMD_T_EQSPLIT, NULL},
   {"@BOOT", "PORT ME", cmd_boot, CMD_T_ANY, NULL},
   {"@BREAK", NULL, cmd_break, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE, NULL},
 #ifdef CHAT_SYSTEM
@@ -1040,7 +1040,8 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from
     noevtoken = 1;
     p = string + 1;
     string = p;
-    memmove(global_eval_context.ccom, (char *) global_eval_context.ccom + 1, BUFFER_LEN - 1);
+    memmove(global_eval_context.ccom, (char *) global_eval_context.ccom + 1, 
+       BUFFER_LEN - 1);
   }
   if (*p == '[') {
     if ((cmd = command_find("WARN_ON_MISSING"))) {
@@ -1201,7 +1202,7 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from
     command_parse_free_args;
     return commandraw;
   }
-
  /* Parse out any switches */
   sw = SW_ALLOC();
   swp = switches;
@@ -1290,54 +1291,56 @@ command_parse(dbref player, dbref cause, dbref realcause, char *string, int from
   }
 
 
-  /* Finish setting up commandraw, if we may need it for hooks */
-  if (has_hook(&cmd->hooks.ignore) || has_hook(&cmd->hooks.override)) {
-    p = command2;
-    if (*p && (*p == ' ')) {
-      safe_chr(' ', commandraw, &c2);
-      p++;
-    }
-    if (cmd->type & CMD_T_ARGS) {
-      int lsa_index;
-      if (lsa[1]) {
-        safe_str(lsa[1], commandraw, &c2);
-        for (lsa_index = 2; lsa[lsa_index]; lsa_index++) {
-          safe_chr(',', commandraw, &c2);
-          safe_str(lsa[lsa_index], commandraw, &c2);
-        }
-      }
-    } else {
-      safe_str(ls, commandraw, &c2);
+  /* Finish setting up commandraw, for hooks and %u */
+  p = command2;
+  if (attrib) {
+    safe_chr('/', commandraw, &c2);
+    safe_str(swp, commandraw, &c2);
+  }
+  if (*p && (*p == ' ')) {
+   safe_chr(' ', commandraw, &c2);
+    p++;
+  }
+  if (cmd->type & CMD_T_ARGS) {
+    int lsa_index;
+    if (lsa[1]) {
+      safe_str(lsa[1], commandraw, &c2);
+      for (lsa_index = 2; lsa[lsa_index]; lsa_index++) {
+        safe_chr(',', commandraw, &c2);
+        safe_str(lsa[lsa_index], 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;
-         /* This is counterintuitive, but rsa[]
-          * starts at 1. */
-         if (rsa[1]) {
-           safe_str(rsa[1], commandraw, &c2);
-           for (rsa_index = 2; rsa[rsa_index]; rsa_index++) {
-             safe_chr(',', commandraw, &c2);
-             safe_str(rsa[rsa_index], commandraw, &c2);
-           }
-         }
+  } else {
+    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;
+        /* This is counterintuitive, but rsa[]
+         * starts at 1. */
+        if (rsa[1]) {
+         safe_str(rsa[1], commandraw, &c2);
+          for (rsa_index = 2; rsa[rsa_index]; rsa_index++) {
+            safe_chr(',', commandraw, &c2);
+            safe_str(rsa[rsa_index], commandraw, &c2);
+         } 
+       } } else {
+           safe_str(rs, commandraw, &c2);
        }
-      } else {
-        safe_str(rs, commandraw, &c2);
       }
+  }
 #ifdef NEVER
-      /* We used to do this, but we're not sure why */
-      process_expression(commandraw, &c2, (const char **) &p, player, realcause,
-                         cause, noevtoken ? PE_NOTHING :
-                         ((PE_DEFAULT & ~PE_FUNCTION_CHECK) |
-                          PE_COMMAND_BRACES), PT_DEFAULT, NULL);
+  /* We used to do this, but we're not sure why */
+  process_expression(commandraw, &c2, (const char **) &p, player, cause,
+                     cause, noevtoken ? PE_NOTHING :
+                    ((PE_DEFAULT & ~PE_EVALUATE) |
+                      PE_COMMAND_BRACES), PT_DEFAULT, NULL);
 #endif
-    }
-    *c2 = '\0';
-  }
-
+  *c2 = '\0';
+  mush_strncpy(global_eval_context.ucom, commandraw, BUFFER_LEN);
   retval = NULL;
   if (cmd->func == NULL) {
     do_rawlog(LT_ERR, T("No command vector on command %s."), cmd->name);
index 94ee972bde9140a2f9637da9753e793644d50dcc..ed57eb7ce41d7e8eaec3c2c3b11afa9ba6d3fa96 100644 (file)
@@ -39,6 +39,8 @@
 #include "game.h"
 #include "attrib.h"
 #include "flags.h"
+#include "function.h"
+#include "case.h"
 #include "dbdefs.h"
 #include "log.h"
 #include "intmap.h"
@@ -1212,6 +1214,166 @@ do_waitpid(dbref player, const char *pidstr, const char *timestr,
   notify_format(player, T("Queue entry with qid %u updated."), pid);
 }
 
+FUNCTION(fun_pidinfo)
+{
+  char *r, *s;
+  char *osep, osepd[2] = { ' ', '\0' };
+  char *fields, field[80] = "queue player time object attribute command";
+  uint32_t pid;
+  BQUE *q;
+  bool first = true;
+
+  if (!is_uinteger(args[0])) {
+    safe_str(T(e_num), buff, bp);
+    return;
+  }
+
+  pid = parse_uint32(args[0], NULL, 10);
+  q = im_find(queue_map, pid);
+
+  if (!q) {
+    safe_str(T("#-1 INVALID PID"), buff, bp);
+    return;
+  }
+
+  if (!controls(executor, q->player) && !LookQueue(executor)) {
+    safe_str(T(e_perm), buff, bp);
+    return;
+  }
+
+  if ((nargs > 1) && args[1] && *args[1]) {
+    fields = args[1];
+  } else {
+    fields = field;
+  }
+
+  if (nargs == 3)
+    osep = args[2];
+  else {
+    osep = osepd;
+  }
+
+  s = trim_space_sep(fields, ' ');
+  do {
+    r = split_token(&s, ' ');
+    if (string_prefix("queue", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      if (GoodObject(q->sem))
+        safe_str("semaphore", buff, bp);
+      else
+        safe_str("wait", buff, bp);
+    } else if (string_prefix("player", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      safe_dbref(q->player, buff, bp);
+    } else if (string_prefix("time", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      if (q->left == 0)
+        safe_integer(-1, buff, bp);
+      else
+        safe_integer(difftime(q->left, mudtime), buff, bp);
+    } else if (string_prefix("object", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      safe_dbref(q->sem, buff, bp);
+    } else if (string_prefix("attribute", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      if (GoodObject(q->sem)) {
+        safe_str(q->semattr, buff, bp);
+      } else {
+        safe_dbref(NOTHING, buff, bp);
+      }
+    } else if (string_prefix("command", r)) {
+      if (!first)
+        safe_str(osep, buff, bp);
+      first = false;
+      safe_str(q->comm, buff, bp);
+    }
+  } while (s);
+}
+
+FUNCTION(fun_lpids)
+{
+  /* Can be called as LPIDS or GETPIDS */
+  BQUE *tmp;
+  int qmask = 3;
+  dbref thing = -1;
+  dbref player = -1;
+  char *attr = NULL;
+  bool first = true;
+  if (string_prefix(called_as, "LPIDS")) {
+    /* lpids(player[,type]) */
+    if (args[0] && *args[0]) {
+      player = match_thing(executor, args[0]);
+      if (!GoodObject(player)) {
+        safe_str(T(e_notvis), buff, bp);
+        return;
+      }
+      if (!(LookQueue(executor) || (Owner(player) == executor))) {
+        safe_str(T(e_perm), buff, bp);
+        return;
+      }
+    } else if (!LookQueue(executor)) {
+      player = executor;
+    }
+    if ((nargs == 2) && args[1] && *args[1]) {
+      if (*args[1] == 'W' || *args[1] == 'w')
+        qmask = 1;
+      else if (*args[1] == 'S' || *args[1] == 's')
+        qmask = 2;
+    }
+  } else {
+    /* getpids(obj[/attrib]) */
+    qmask = 2;                  /* semaphores only */
+    attr = strchr(args[0], '/');
+    if (attr)
+      *attr++ = '\0';
+    thing = match_thing(executor, args[0]);
+    if (!GoodObject(thing)) {
+      safe_str(T(e_notvis), buff, bp);
+      return;
+    }
+    if (!(LookQueue(executor) || (controls(executor, thing)))) {
+      safe_str(T(e_perm), buff, bp);
+      return;
+    }
+  }
+
+  if (qmask & 1) {
+    for (tmp = qwait; tmp; tmp = tmp->next) {
+      if (GoodObject(player) && (!Owns(tmp->player, player)))
+        continue;
+      if (!first)
+        safe_chr(' ', buff, bp);
+      safe_integer(tmp->qid, buff, bp);
+      first = false;
+    }
+  }
+  if (qmask & 2) {
+    for (tmp = qsemfirst; tmp; tmp = tmp->next) {
+      if (GoodObject(player) && (!Owns(tmp->player, player)))
+        continue;
+      if (GoodObject(thing) && (tmp->sem != thing))
+        continue;
+      if (attr && *attr && strcasecmp(tmp->semattr, attr))
+        continue;
+      if (!first)
+        safe_chr(' ', buff, bp);
+      safe_integer(tmp->qid, buff, bp);
+      first = false;
+    }
+  }
+}
+
+
 static void
 show_queue(dbref player, dbref victim, int q_type, int q_quiet, int q_all,
            BQUE * q_ptr, int *tot, int *self, int *del)
@@ -1508,7 +1670,6 @@ do_halt(dbref owner, const char *ncom, dbref victim)
   }
 
   add_to(QUEUE_PER_OWNER ? Owner(player) : player, num);
-
   if (ncom && *ncom) {
     int j;
     for (j = 0; j < 10; j++)
@@ -1603,20 +1764,16 @@ do_haltqid(dbref player, uint32_t qid)
      turn comes up (Or show it in @ps, etc.).  Exception is for
      semaphores, which otherwise might wait forever. */
   q->player = NOTHING;
-
   if (q->semattr) {
     BQUE *last = NULL, *tmp;
-
     for (tmp = qsemfirst; tmp; last = tmp, tmp = tmp->next) {
       if (tmp == q) {
         if (last)
           last->next = tmp->next;
         else
           qsemfirst = tmp->next;
-
         if (qsemlast == tmp)
           qsemlast = last;
-
         break;
       }
     }
@@ -1654,7 +1811,6 @@ do_haltpid(dbref player, const char *arg1)
 }
 
 
-
 /** Halt all objects in the database.
  * \param player the enactor.
  */
@@ -1687,7 +1843,6 @@ void
 do_allrestart(dbref player)
 {
   dbref thing;
-
   if (!HaltAny(player)) {
     notify(player, T("You do not have the power to restart the world."));
     return;
@@ -1700,7 +1855,8 @@ do_allrestart(dbref player)
     }
     if (IsPlayer(thing)) {
       notify_format(thing,
-                    T("Your objects are being globally restarted by %s"),
+                    T
+                    ("Your objects are being globally restarted by %s"),
                     Name(player));
     }
   }
@@ -1711,7 +1867,6 @@ do_raw_restart(victim)
 dbref victim;
 {
   dbref thing;
-
   if (IsPlayer(victim)) {
     for (thing = 0; thing < db_top; thing++) {
       if ((Owner(thing) == victim) && !IsGarbage(thing)
index cb0cbfe3d9358f38393c4ad654f0f14fece39b44..b793b2b2178607db1ced4e28157f707b1f2c8256 100644 (file)
@@ -103,7 +103,9 @@ do_real_open(dbref player, const char *direction, const char *linkto,
 
   dbref loc =
     (pseudo !=
-     NOTHING) ? pseudo : (IsExit(player) ? Source(player) : Location(player));
+     NOTHING) ? pseudo : (IsExit(player) ? Source(player) : (IsRoom(player) ?
+                                                             player :
+                                                             Location(player)));
   dbref new_exit;
   if (!command_check_byname(player, "@dig")) {
     notify(player, "Permission denied.");
@@ -551,8 +553,10 @@ clone_object(dbref player, dbref thing, const char *newname, int preserve)
 
   clone = new_object();
 
+  /* Need to figure out why this is here. */
   memcpy(REFDB(clone), REFDB(thing), sizeof(struct object));
   Owner(clone) = Owner(player);
+  Name(clone) = NULL;
   if (newname && *newname)
     set_name(clone, newname);
   else
index 7d114a1dec4a7e0ea27cb53006a5357e087fa36b..ddaa65315d44b0c9c5457537ba79bbfcda04eaff 100644 (file)
--- a/src/db.c
+++ b/src/db.c
@@ -1017,6 +1017,7 @@ db_paranoid_write(PENNFILE *f, int flag)
   dbflag += DBF_DIVISIONS;
   dbflag += DBF_LABELS;
   dbflag += DBF_SPIFFY_AF_ANSI;
+  dbflag += DBF_HEAR_CONNECT;
 
   do_rawlog(LT_CHECK, "PARANOID WRITE BEGINNING...\n");
 
@@ -1750,6 +1751,12 @@ db_read_oldstyle(PENNFILE *f)
       if (IsPlayer(i)) {
         add_player(i);
         clear_flag_internal(i, "CONNECTED");
+        /* If it has the MONITOR flag and the db predates HEAR_CONNECT, swap them over */
+        if (!(globals.indb_flags & DBF_HEAR_CONNECT) &&
+            has_flag_by_name(i, "MONITOR", NOTYPE)) {
+          clear_flag_internal(i, "MONITOR");
+          set_flag_internal(i, "HEAR_CONNECT");
+        }
       }
       break;
 
@@ -2102,6 +2109,12 @@ db_read(PENNFILE *f)
         if (IsPlayer(i)) {
           add_player(i);
           clear_flag_internal(i, "CONNECTED");
+          /* If it has the MONITOR flag and the db predates HEAR_CONNECT, swap them over */
+          if (!(globals.indb_flags & DBF_HEAR_CONNECT) &&
+              has_flag_by_name(i, "MONITOR", NOTYPE)) {
+            clear_flag_internal(i, "MONITOR");
+            set_flag_internal(i, "HEAR_CONNECT");
+          }
         }
       }
       break;
index 070330cf8c22730b2cf9bf8361adaf2e327667a2..f8e7db309181d260ed90bac5ee106c214fda34d6 100644 (file)
@@ -499,6 +499,8 @@ FUNTAB flist[] = {
   {"LIST", fun_list, 1, 1, FN_REG},
   {"LIT", fun_lit, 1, -1, FN_LITERAL},
   {"LJUST", fun_ljust, 2, 3, FN_REG},
+  {"LLOCKFLAGS", fun_lockflags, 0, 1, FN_REG},
+  {"LLOCKS", fun_locks, 1, 1, FN_REG},
   {"LMATH", fun_lmath, 2, 3, FN_REG},
   {"LNUM", fun_lnum, 1, 3, FN_REG},
   {"LOC", fun_loc, 1, 1, FN_REG},
@@ -506,6 +508,9 @@ FUNTAB flist[] = {
   {"LOCALIZE", fun_localize, 1, 1, FN_NOPARSE},
   {"LOCATE", fun_locate, 3, 3, FN_REG},
   {"LOCK", fun_lock, 1, 2, FN_REG},
+  {"LOCKFLAGS", fun_lockflags, 0, 1, FN_REG},
+  {"LOCKOWNER", fun_lockowner, 1, 1, FN_REG},
+  {"LOCKS", fun_locks, 1, 1, FN_REG},
   {"LPARENT", fun_lparent, 1, 1, FN_REG},
   {"LPLAYERS", fun_dbwalker, 1, 1, FN_REG},
   {"LPORTS", fun_lports, 0, 1, FN_REG},
index ac603cfe971fc932921ba0f6090bdcfdffd15c24..5d83b51b06ac955521187358ab2c8bd4f4003875 100644 (file)
@@ -451,8 +451,6 @@ FUNCTION(fun_flags)
       return;
     }
     safe_str(privs_to_letters(attr_privs_view, AL_FLAGS(a)), buff, bp);
-    if (atr_sub_branch(a))
-      safe_chr('`', buff, bp);
   } else {
     /* Object flags, visible to all */
     safe_str(unparse_flags(thing, executor), buff, bp);
@@ -1130,6 +1128,121 @@ get_locktype(str)
   return upcasestr(str);
 }
 
+/* ARGSUSED */
+FUNCTION(fun_locks)
+{
+  dbref thing = match_thing(executor, args[0]);
+  lock_list *ll;
+  const lock_list *p;
+  int first = 1;
+
+  if (!GoodObject(thing)) {
+    safe_str(T(e_notvis), buff, bp);
+    return;
+  }
+
+  for (ll = Locks(thing); ll; ll = ll->next) {
+    p = get_lockproto(L_TYPE(ll));
+    if (!first) {
+      safe_chr(' ', buff, bp);
+    }
+    first = 0;
+    if (!p)
+      safe_str("USER:", buff, bp);
+    safe_str(L_TYPE(ll), buff, bp);
+  }
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lockflags)
+{
+  dbref it;
+  char *p;
+  int fullname = 0;
+  lock_list *ll;
+  lock_type ltype;
+
+  if (called_as[1] == 'L')      /* LLOCKFLAGS */
+    fullname = 1;
+
+  if (nargs == 0) {
+    if (fullname)
+      list_lock_flags_long(buff, bp);
+    else
+      list_lock_flags(buff, bp);
+    return;
+  }
+
+  if ((p = strchr(args[0], '/')))
+    *(p++) = '\0';
+
+  it = match_thing(executor, args[0]);
+  if (!GoodObject(it)) {
+    safe_str(T(e_notvis), buff, bp);
+    return;
+  }
+  ltype = get_locktype(p);
+
+  if (GoodObject(it) && (ltype !=NULL)
+      &&Can_Read_Lock(executor, it, ltype)) {
+    ll = getlockstruct(it, ltype);
+    if (ll) {
+      if (fullname)
+        safe_str(lock_flags_long(ll), buff, bp);
+      else
+        safe_str(lock_flags(ll), buff, bp);
+      return;
+    } else {
+      safe_str("#-1 NO SUCH LOCK", buff, bp);
+      return;
+    }
+  }
+  safe_str("#-1 NO SUCH LOCK", buff, bp);
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lockowner)
+{
+  dbref it;
+  char *p;
+  lock_type ltype;
+  lock_list *ll;
+
+  if ((p = strchr(args[0], '/')))
+    *(p++) = '\0';
+
+  it = match_thing(executor, args[0]);
+  if (!GoodObject(it)) {
+    safe_str(T(e_notvis), buff, bp);
+    return;
+  }
+  ltype = get_locktype(p);
+  if (ltype == NULL || !Can_Read_Lock(executor, it, ltype)) {
+    safe_str(T("#-1 NO SUCH LOCK"), buff, bp);
+    return;
+  }
+  ll = getlockstruct(it, ltype);
+  if (ll)
+    safe_dbref(L_CREATOR(ll), buff, bp);
+  else
+    safe_str(T("#-1 NO SUCH LOCK"), buff, bp);
+
+}
+
+/* ARGSUSED */
+FUNCTION(fun_lset)
+{
+  if (!FUNCTION_SIDE_EFFECTS) {
+    safe_str(T(e_disabled), buff, bp);
+    return;
+  }
+  if (!command_check_byname(executor, "@lset") || fun->flags & FN_NOSIDEFX) {
+    safe_str(T(e_perm), buff, bp);
+    return;
+  }
+  do_lset(executor, args[0], args[1]);
+}
+
 /* ARGSUSED */
 FUNCTION(fun_lock)
 {
index 56c8c3f2c8107625e6a29df8a369cca23bd9a039..6798d328248491a5fb7f5ff793bcc2f1bb0fced1 100644 (file)
@@ -1404,6 +1404,14 @@ FUNCTION(fun_randword)
 
   s = trim_space_sep(args[0], sep);
   word_count = do_wordcount(s, sep);
+
+  if (word_count == 0)
+    return;
+  else if (word_count == 1) {
+    safe_strl(args[0], arglens[0], buff, bp);
+    return;
+  }
+
   word_index = get_random32(0, word_count - 1);
 
   /* Go to the start of the token we're interested in. */
@@ -2080,6 +2088,7 @@ FUNCTION(fun_member)
   char *s, *t;
   char sep;
   int el;
+  char needle[BUFFER_LEN], haystack[BUFFER_LEN];
 
   if (!delim_check(buff, bp, nargs, args, 3, &sep))
     return;
@@ -2088,12 +2097,16 @@ FUNCTION(fun_member)
     safe_str(T("#-1 CAN ONLY TEST ONE ELEMENT"), buff, bp);
     return;
   }
-  s = trim_space_sep(args[0], sep);
+
+  strncpy(haystack, remove_markup(args[0], NULL), BUFFER_LEN);
+  strncpy(needle, remove_markup(args[1], NULL), BUFFER_LEN);
+
+  s = trim_space_sep(haystack, sep);
   el = 1;
 
   do {
     t = split_token(&s, sep);
-    if (!strcmp(args[1], t)) {
+    if (!strcmp(needle, t)) {
       safe_integer(el, buff, bp);
       return;
     }
index 7405edcbbe2ed34ed6b95e6a5e0745ce4aa6e202..1179aa9593d957f0050b0416108e3fd2316e62c2 100644 (file)
@@ -1918,6 +1918,7 @@ FUNCTION(fun_baseconv)
   while (ptr && *ptr) {
     if (*ptr == '-') {
       isnegative = 1;
+      ptr++;
       continue;
     }
     n *= from;
index 1b4c886c5675ad58545e295aa567020844fecfd3..3770caf4a5c4728117b85948cf4dcd55bbabf3ce 100644 (file)
@@ -305,25 +305,26 @@ FUNCTION(fun_r)
 /* ARGSUSED */
 FUNCTION(fun_rand)
 {
-  /*
-   * Uses Sh'dow's random number generator, found in utils.c.  Better
-   * distribution than original, w/ minimal speed losses.
-   */
-  int low, high;
-  if (!is_integer(args[0])) {
-    safe_str(T(e_int), buff, bp);
+  uint32_t low, high;
+  if (!is_strict_uinteger(args[0])) {
+    safe_str(T(e_uint), buff, bp);
     return;
   }
   if (nargs == 1) {
     low = 0;
-    high = parse_integer(args[0]) - 1;
+    high = parse_uinteger(args[0]);
+    if (high == 0) {
+      safe_str(T(e_range), buff, bp);
+      return;
+    }
+    high -= 1;
   } else {
-    if (!is_integer(args[1])) {
-      safe_str(T(e_ints), buff, bp);
+    if (!is_strict_uinteger(args[1])) {
+      safe_str(T(e_uints), buff, bp);
       return;
     }
-    low = parse_integer(args[0]);
-    high = parse_integer(args[1]);
+    low = parse_uinteger(args[0]);
+    high = parse_uinteger(args[1]);
   }
 
   if (low > high) {
@@ -331,7 +332,7 @@ FUNCTION(fun_rand)
     return;
   }
 
-  safe_integer(get_random32(low, high), buff, bp);
+  safe_uinteger(get_random32(low, high), buff, bp);
 }
 
 /* ARGSUSED */
index ba6ba26ac33fa62642578ac916ceb4a11bb26f99..8604afc9da392313f785a7d9397debe521bd799e 100644 (file)
@@ -1866,7 +1866,6 @@ align_one_line(char *buff, char **bp, int ncols,
   return 1;
 }
 
-
 FUNCTION(fun_align)
 {
   int nline;
@@ -1954,35 +1953,71 @@ FUNCTION(fun_align)
     safe_str(T("#-1 TOO MANY COLUMNS FOR ALIGN"), buff, bp);
     return;
   }
-  if (nargs < (ncols + 1) || nargs > (ncols + 4)) {
-    safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
-    return;
-  }
-  if (nargs >= (ncols + 2)) {
-    if (!args[ncols + 1] || strlen(args[ncols + 1]) > 1) {
-      safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+  if (strcmp(called_as, "LALIGN")) {
+    /* each column is a separate arg */
+    if (nargs < (ncols + 1) || nargs > (ncols + 4)) {
+      safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
       return;
     }
-    if (*args[ncols + 1]) {
-      filler = *(args[ncols + 1]);
+    if (nargs >= (ncols + 2)) {
+      if (!args[ncols + 1] || strlen(args[ncols + 1]) > 1) {
+        safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+        return;
+      }
+      if (*args[ncols + 1]) {
+        filler = *(args[ncols + 1]);
+      }
+    }
+    if (nargs >= (ncols + 3)) {
+      fieldsep = args[ncols + 2];
+    }
+    if (nargs >= (ncols + 4)) {
+      linesep = args[ncols + 3];
     }
-  }
-  if (nargs >= (ncols + 3)) {
-    fieldsep = args[ncols + 2];
-  }
-  if (nargs >= (ncols + 4)) {
-    linesep = args[ncols + 3];
-  }
 
-  fslen = strlen(fieldsep);
-  lslen = strlen(linesep);
+    fslen = strlen(fieldsep);
+    lslen = strlen(linesep);
 
-  for (i = 0; i < MAX_COLS; i++) {
-    as[i] = NULL;
-  }
-  for (i = 0; i < ncols; i++) {
-    as[i] = parse_ansi_string(args[i + 1]);
-    ptrs[i] = as[i]->text;
+    for (i = 0; i < MAX_COLS; i++) {
+      as[i] = NULL;
+    }
+    for (i = 0; i < ncols; i++) {
+      as[i] = parse_ansi_string(args[i + 1]);
+      ptrs[i] = as[i]->text;
+    }
+  } else {
+    /* columns are in args[1] as an args[2]-separated list */
+    char delim, *s;
+    if (!delim_check(buff, bp, nargs, args, 3, &delim))
+      return;
+    if (do_wordcount(args[1], delim) != ncols) {
+      safe_str(T("#-1 INVALID NUMBER OF ARGUMENTS TO ALIGN"), buff, bp);
+      return;
+    }
+    if (nargs > 3) {
+      if (!args[3] || strlen(args[3]) > 1) {
+        safe_str(T("#-1 FILLER MUST BE ONE CHARACTER"), buff, bp);
+        return;
+      }
+      if (*args[3])
+        filler = *(args[3]);
+    }
+    if (nargs > 4)
+      fieldsep = args[4];
+    if (nargs > 5)
+      linesep = args[5];
+
+    fslen = strlen(fieldsep);
+    lslen = strlen(linesep);
+
+    for (i = 0; i < MAX_COLS; i++) {
+      as[i] = NULL;
+    }
+    s = trim_space_sep(args[1], delim);
+    for (i = 0; i < ncols; i++) {
+      as[i] = parse_ansi_string(split_token(&s, delim));
+      ptrs[i] = as[i]->text;
+    }
   }
 
   nline = 0;
index 80f6644a783e28ea615b63be06ebdb1e7c8d0b13..ef31f49bb25b474428f5700b93f5f0c0cb9aa85f 100644 (file)
@@ -1246,8 +1246,8 @@ process_command(dbref player, char *command, dbref cause, dbref realcause,  int
   strcpy(unp, command);
 
   cptr = command_parse(player, cause, realcause, command, from_port);
-  strcpy(global_eval_context.ucom, (cptr ? cptr : ""));
   if (cptr) {
+    mush_strncpy(global_eval_context.ucom, cptr, BUFFER_LEN);
     a = 0;
     if (!Gagged(player)) {
       if (Mobile(player)) {
@@ -1566,7 +1566,7 @@ Listener(dbref thing)
   /* If a monitor flag is set on a room or thing, it's a listener.
    * Otherwise not (even if ^patterns are present)
    */
-  return (ThingListen(thing) || RoomListen(thing));
+  return has_flag_by_name(thing, "MONITOR", NOTYPE);
 }
 
 /** Reset all players' money.
@@ -2320,7 +2320,8 @@ db_open(const char *fname)
     pf->type = PFT_GZFILE;
     pf->handle.g = gzopen(filename, "rb");
     if (!pf->handle.g) {
-      do_rawlog(LT_ERR, "Unable to open %s with libz: %s\n", filename, strerror(errno));
+      do_rawlog(LT_ERR, "Unable to open %s with libz: %s\n", filename,
+                strerror(errno));
       mush_free(pf, "pennfile");
       longjmp(db_err, 1);
     }
index 552443e6ca1d0405f464bbf10c093340ce1bb5d1..54fc71f553c899b698e3c7709f4176aebdc66fb2 100644 (file)
@@ -144,7 +144,6 @@ static void free_one_lock_list(lock_list *ll);
 static lock_type check_lock_type(dbref player, dbref thing, lock_type name);
 static int delete_lock(dbref player, dbref thing, lock_type type);
 static int can_write_lock(dbref player, dbref thing, lock_list *lock);
-static lock_list *getlockstruct(dbref thing, lock_type type);
 static lock_list *getlockstruct_noparent(dbref thing, lock_type type);
 
 slab *lock_slab = NULL;
@@ -153,6 +152,8 @@ static void free_lock(lock_list *ll);
 
 extern int unparsing_boolexp;
 
+lock_list *getlockstruct(dbref thing, lock_type type);
+
 /** Return a list of all available locks
  * \param buff the buffer
  * \param bp a pointer to the current position in the buffer
@@ -212,6 +213,39 @@ lock_flags(lock_list *ll)
   return privs_to_letters(lock_privs, L_FLAGS(ll));
 }
 
+/** List all lock flag characters on a buffer
+ * \param buff The buffer
+ * \param bp Pointer to a position in the buffer.
+ */
+
+void
+list_lock_flags(char *buff, char **bp)
+{
+  int i;
+  for (i = 0; lock_privs[i].name; i++) {
+    if (lock_privs[i].letter)
+      safe_chr(lock_privs[i].letter, buff, bp);
+  }
+}
+
+/** List all lock flag names on a buffer
+ * \param buff The buffer
+ * \param bp Pointer to a position in the buffer.
+ */
+
+void
+list_lock_flags_long(char *buff, char **bp)
+{
+  int i;
+  int first = 1;
+  for (i = 0; lock_privs[i].name; i++) {
+    if (!first)
+      safe_chr(' ', buff, bp);
+    first = 0;
+    safe_str(lock_privs[i].name, buff, bp);
+  }
+}
+
 /** Return a list of lock flag names.
  * \param ll pointer to a lock.
  * \return string of lock flag names, space-separated.
@@ -335,7 +369,7 @@ getlock_noparent(dbref thing, lock_type type)
     return L_KEY(ll);
 }
 
-static lock_list *
+lock_list *
 getlockstruct(dbref thing, lock_type type)
 {
   lock_list *ll;
index 9710c24daae60a55ca4e19de1d5e47266b1958ea..a52a599e29036a3d4299f0491d4bcebf5060da68 100644 (file)
@@ -2102,6 +2102,7 @@ real_decompose_str(char *orig, char *buff, char **bp)
  * \param ovector the offset vectors
  * \param stringcount the number of subpatterns
  * \param stringnumber the number of the desired subpattern
+ * \param nonempty if true, copy empty registers as well.
  * \param buff buffer to copy the subpattern to
  * \param bp pointer to the end of buffer
  * \return size of subpattern, or -1 if unknown pattern
@@ -2130,6 +2131,7 @@ ansi_pcre_copy_substring(ansi_string *as, int *ovector,
  * \param ovector the offset vectors
  * \param stringcount the number of subpatterns
  * \param stringname the name of the desired subpattern
+ * \param nonempty if true, copy empty registers as well.
  * \param buff buffer to copy the subpattern to
  * \param bp pointer to the end of buffer
  * \return size of subpattern, or -1 if unknown pattern
index d73c48fb729b65caf5a31c3b7404fb563aebc3cc..ccdf9a2c6d5daf977bef11a9abf6bfbb7c6dbb52 100644 (file)
@@ -318,6 +318,17 @@ make_socket(Port_t port, int socktype, union sockaddr_u *addr, socklen_t * len,
     if (bind(s, server->ai_addr, server->ai_addrlen) == 0)
       break;                    /* Success */
 
+#ifdef WIN32
+    if (WSAGetLastError() == WSAEADDRINUSE) {
+#else
+    if (errno == EADDRINUSE) {
+#endif
+      fprintf(stderr,
+              "Another process (Possibly another copy of this mush?) appears to be using port %hu. Aborting.\n",
+              port);
+      exit(1);
+    }
+
     penn_perror("binding stream socket (Possibly ignorable)");
     closesocket(s);
   } while ((server = server->ai_next) != NULL);
index 487d44489dbdf92f832c52ad3dd90ddcdcd12bfd..866571651ab5bc7329f3bd917d1f47a073c155db 100644 (file)
@@ -953,7 +953,7 @@ notify_anything_loc(dbref speaker, na_lookup func,
      *    * unlike normal @listen, don't pass the message on.
      *    */
 
-    if ((ThingListen(target) || RoomListen(target))
+    if ((has_flag_by_name(target, "MONITOR", NOTYPE))
        && eval_lock(speaker, target, Listen_Lock)
       )
       atr_comm_match(target, speaker, '^', ':',
index 6b25ca18c429c0d50bf708461a38b6c88f79185e..e3334bc6d1e7396c17b48f4e96a463c13536280f 100644 (file)
@@ -334,6 +334,32 @@ is_uinteger(char const *str)
   return 1;
 }
 
+/** Is string really an unsigned integer?
+ * \param str string to check.
+ * \retval 1 string is an uinteger.
+ * \retval 0 string is not an uinteger.
+ */
+bool
+is_strict_uinteger(const char *str)
+{
+  char *end;
+
+  if (!str)
+    return 0;
+  /* strtoul() accepts negative numbers, so we still have to do this check */
+  while (isspace((unsigned char) *str))
+    str++;
+  if (*str == '\0')
+    return 0;
+  if (!(isdigit((unsigned char) *str) || *str == '+'))
+    return 0;
+  errno = 0;
+  parse_uint(str, &end, 10);
+  if (errno == ERANGE || *end != '\0')
+    return 0;
+  return 1;
+}
+
 /** Is string a number by the strict definition?
  * A strict number is a non-null string that passes strtod.
  * \param str string to check.
index f9d5f230c0315ce1eaf10a947d263b88cda10919..854c3687a7f4c2f3dc2def6179f59080646e4e6a 100644 (file)
@@ -1257,6 +1257,7 @@ int
 
 
 
+
 pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
                         const char ***listptr);
 
@@ -1347,6 +1348,7 @@ int
 
 
 
+
 pcre_get_substring(const char *subject, int *ovector, int stringcount,
                    int stringnumber, const char **stringptr);
 
@@ -1404,6 +1406,7 @@ int
 
 
 
+
 pcre_get_named_substring(const pcre * code, const char *subject, int *ovector,
                          int stringcount, const char *stringname,
                          const char **stringptr);
@@ -2291,6 +2294,7 @@ static BOOL
 
 
 
+
 compile_regex(int, int, int *, uschar **, const uschar **, int *, BOOL, int,
               int *, int *, branch_chain *, compile_data *);
 
index 4ef128efe42599fefbf3beca5f2116bf929e8f3a..02e4efe1a10724a962b1a9b86f319b2fd4ea99f7 100644 (file)
@@ -883,6 +883,9 @@ int
 ok_password(const char *password)
 {
   const unsigned char *scan;
+  if (password == NULL)
+    return 0;
+
   if (*password == '\0')
     return 0;
 
index d1d13dcce97ccbb68ea38f3411716c69490d9b83..cea38ae2c36b9b19a02e9462f3483601d63694b3 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -59,55 +59,61 @@ static void copy_attrib_flags(dbref player, dbref target, ATTR *atr, int flags);
  * \param newname new name for object.
  */
 void
-do_name(dbref player, const char *name, char *newname)
+do_name(dbref player, const char *name, char *newname_)
 {
   dbref thing;
   char *eon;                    /* End Of Name */
+  char *bon;                   /* Beginning of name*/
   char *myenv[10];
   int i;
-
-  newname = trim_space_sep(newname, ' ');
+  char *newname;
 
   if ((thing = match_controlled(player, name)) != NOTHING) {
+    newname = mush_strdup(trim_space_sep(newname_, ' '), "name.newname");
+    bon = newname;
     /* check for bad name */
     if ((*newname == '\0') || strchr(newname, '[')) {
       notify(player, T("Give it what new name?"));
+      mush_free(newname, "name.newname");
       return;
     }
     /* check for renaming a player */
     if (IsPlayer(thing)) {
-      if (*newname == '"') {
-        for (; *newname && ((*newname == '"')
-                            || isspace((unsigned char) *newname)); newname++) ;
-        eon = newname;
-        while (*eon && (*eon != '"')) {
-          while (*eon && (*eon != '"'))
-            eon++;
-          if (*eon == '"') {
-            *eon++ = '\0';
-            while (*eon && isspace((unsigned char) *eon))
-              eon++;
-            break;
-          }
+      // If it has "s, it's surrounding a spaced name, likely. So bon
+      // is beginning of name.
+      // I'm going to cheat here and make it so
+      // @name me="foo"bar names somebody foo, since " is an invalid name.
+      if (*bon == '"') {
+        bon++;
+        eon = bon;
+        while (*eon && *eon != '"') {
+          eon++;
+        }
+        if (*eon) {
+          *eon = '\0';
         }
       } else {
-        eon = newname;
+        eon = bon;
         while (*eon && !isspace((unsigned char) *eon))
           eon++;
         if (*eon)
-          *eon++ = '\0';
+          *(eon++) = '\0';
       }
-      if (!ok_player_name(newname, player, thing)) {
+      if (!ok_player_name(bon, player, thing)) {
         notify(player, T("You can't give a player that name."));
+       mush_free(newname, "name.newname");
         return;
       }
       /* everything ok, notify */
       do_log(LT_CONN, 0, 0, T("Name change by %s(#%d) to %s"),
-             Name(thing), thing, newname);
+             Name(thing), thing, bon);
       /* everything ok, we can fall through to change the name */
     } else {
+      bon = newname;
       if (!ok_name(newname)) {
         notify(player, T("That is not a reasonable name."));
+       mush_free(newname, "name.newname");
         return;
       }
     }
@@ -116,13 +122,13 @@ do_name(dbref player, const char *name, char *newname)
     myenv[0] = (char *) mush_malloc(BUFFER_LEN, "string");
     myenv[1] = (char *) mush_malloc(BUFFER_LEN, "string");
     mush_strncpy(myenv[0], Name(thing), BUFFER_LEN);
-    strcpy(myenv[1], newname);
+    strcpy(myenv[1], bon);
     for (i = 2; i < 10; i++)
       myenv[i] = NULL;
 
     if (IsPlayer(thing))
-      reset_player_list(thing, Name(thing), NULL, newname, NULL);
-    set_name(thing, newname);
+      reset_player_list(thing, Name(thing), NULL, bon, NULL);
+    set_name(thing, bon);
     if(!IsPlayer(thing)) {
           char lmbuf[1024];
           ModTime(thing) = mudtime;
@@ -137,6 +143,7 @@ do_name(dbref player, const char *name, char *newname)
       notify(player, T("Name set."));
     real_did_it(player, thing, NULL, NULL, "ONAME", NULL, "ANAME", NOTHING,
                 myenv, NA_INTER_PRESENCE);
+    mush_free(newname, "name.newname");
     mush_free(myenv[0], "string");
     mush_free(myenv[1], "string");
   }
@@ -981,7 +988,7 @@ do_use(dbref player, const char *what)
 
   if ((thing =
        noisy_match_result(player, what, TYPE_THING,
-                          MAT_NEAR_THINGS)) != NOTHING) {
+                          MAT_NEAR_THINGS | MAT_ENGLISH)) != NOTHING) {
     if (!eval_lock(player, thing, Use_Lock)) {
       fail_lock(player, thing, Use_Lock, T("Permission denied."), NOTHING);
       return;
index 0dea11d18cd9f00a4af427f908d9c211f00f8042..dac70c9d566cfc858f8c1be42f05269c36734d71 100644 (file)
@@ -544,11 +544,13 @@ regexp_match_case_r(const char *restrict s, const char *restrict val, bool cs,
   pcre_extra *extra;
   size_t i;
   const char *errptr;
+  ansi_string *as;
   const char *d;
   size_t delenn;
   int erroffset;
   int offsets[99];
   int subpatterns;
+  int totallen = 0;
 
   for (i = 0; i < nmatches; i++)
     matches[i] = NULL;
@@ -563,14 +565,20 @@ regexp_match_case_r(const char *restrict s, const char *restrict val, bool cs,
     return 0;
   }
   add_check("pcre");
-  d = remove_markup(val, &delenn);
+
+  /* The ansi string */
+  as = parse_ansi_string(val);
+  delenn = as->len;
+  d = as->text;
+
   extra = default_match_limit();
   /*
    * Now we try to match the pattern. The relevant fields will
    * automatically be filled in by this.
    */
-  if ((subpatterns = pcre_exec(re, extra, d, delenn - 1, 0, 0, offsets, 99))
+  if ((subpatterns = pcre_exec(re, extra, d, delenn, 0, 0, offsets, 99))
       < 0) {
+    free_ansi_string(as);
     mush_free(re, "pcre");
     return 0;
   }
@@ -586,20 +594,26 @@ regexp_match_case_r(const char *restrict s, const char *restrict val, bool cs,
    * go from 1 to 9. We DO PRESERVE THIS PARADIGM, for consistency
    * with other languages.
    */
-
-  for (i = 0; i < nmatches && (int) i < subpatterns && (size_t) len > i; i++) {
-    ssize_t sublen;
-
-    sublen = pcre_copy_substring(d, offsets, subpatterns, (int) i, data, len);
-
-    if (sublen < 0)
-      break;
-
-    matches[i] = data;
-    data += sublen + 2;
-    len -= sublen + 2;
+  for (i = 0; i < nmatches && (int) i < subpatterns && totallen < len; i++) {
+    // Current data match.
+    /* This is more annoying than a jumping flea up the nose. Since 
+     * ansi_pcre_copy_substring() uses buff, bp instead of char *, len,
+     * we have to mangle bp and 'buff' by hand. Sound easy? We also
+     * have to make sure that 'buff' + len < BUFFER_LEN. Particularly since
+     * matchspace is 2*BUFFER_LEN
+     */
+    char *buff = data + totallen;
+    char *bp = buff;
+    matches[i] = bp;
+    if ((len - totallen) < BUFFER_LEN) {
+      buff = data + len - BUFFER_LEN;
+    }
+    ansi_pcre_copy_substring(as, offsets, subpatterns, (int) i, 1, buff, &bp);
+    *(bp++) = '\0';
+    totallen = bp - data;
   }
 
+  free_ansi_string(as);
   mush_free(re, "pcre");
   return 1;
 }
index 6470e5cf794e3d29d1fd4a8ff2c2d32ae2ccbc8a..0077df999ff081fa77cbc5bb329d0ae03d358b31 100644 (file)
--- a/src/wiz.c
+++ b/src/wiz.c
@@ -1368,34 +1368,6 @@ FUNCTION(fun_lsearch)
     mush_free(results, "search_results");
 }
 
-
-#ifdef WIN32
-#pragma warning( disable : 4761)        /* Disable bogus conversion warning */
-#endif
-/* ARGSUSED */
-FUNCTION(fun_hidden)
-{
-  dbref it = match_thing(executor, args[0]);
-  if (CanSee(executor, it) && ((Admin(executor) ||
-                                  Location(executor) == Location(it) || Location(it) == executor))) {
-  if ((it == NOTHING) || (!IsPlayer(it))) {
-    notify(executor, T("Couldn't find that player."));
-    safe_str("#-1", buff, bp);
-    return;
-  }
-  safe_boolean(hidden(it), buff, bp);
-  return;
-  } else { 
-          notify(executor, T("Permission denied.")); 
-          safe_str("#-1", buff, bp); 
-          return;
-  }
-}
-
-#ifdef WIN32
-#pragma warning( default : 4761)        /* Re-enable conversion warning */
-#endif
-
 /* ARGSUSED */
 FUNCTION(fun_quota)
 {
@@ -2016,13 +1988,6 @@ raw_search(dbref player, const char *owner, int nargs, const char **args,
   ATTR *a;
   char lbuff[BUFFER_LEN];
 
-  /* make sure player has money to do the search */
-  if (!payfor(player, FIND_COST)) {
-    notify_format(player, T("Searches cost %d %s."), FIND_COST,
-                  ((FIND_COST == 1) ? MONEY : MONIES));
-    return -1;
-  }
-
   if (fill_search_spec(player, owner, nargs, args, &spec) < 0) {
     giveto(player, FIND_COST);
     if (spec.lock != TRUE_BOOLEXP)
@@ -2030,6 +1995,17 @@ raw_search(dbref player, const char *owner, int nargs, const char **args,
     return -1;
   }
 
+  /* make sure player has money to do the search -
+   * But only if this does an eval or lock search. */
+  if ((spec.lock != TRUE_BOOLEXP) ||
+      spec.cmdstring[0] || spec.listenstring[0] || spec.eval[0]) {
+    if (!payfor(player, FIND_COST)) {
+      notify_format(player, T("Searches cost %d %s."), FIND_COST,
+                    ((FIND_COST == 1) ? MONEY : MONIES));
+      return -1;
+    }
+  }
+
   if ((spec.owner != ANY_OWNER &&
        spec.owner != Owner(player) && 
        (!(CanSearch(player, spec.owner) || (spec.type == TYPE_PLAYER)) 
index fdeefddfc0b67fcef65620d2e07d0397a34e836f..f40a9614a3e37211d7dc362d3ab1ce5e38e7d1b8 100644 (file)
@@ -7,4 +7,9 @@ test('rand.5', $god, 'think rand(0,0)', '0');
 test('rand.6', $god, 'think rand(1,1)', '1');
 test('rand.7', $god, 'think rand(2,1)', '#-1');
 test('rand.8', $god, 'think rand(0,9)', '^\d\s*$');
+test('rand.9', $god, 'think rand(-5, 10)', '#-1');
+test('rand.10', $god, 'think rand(-5, -10)', '#-1');
 
+test('randword.1', $god, 'think randword(%b%b%b)', '^$');
+test('randword.2', $god, 'think randword(foo)', 'foo');
+test('randword.3', $god, 'think randword(foo bar)', '(?:foo|bar)');