182p7
authorRick Bird <nveid@bender.theari.com>
Sun, 27 Mar 2011 05:05:57 +0000 (01:05 -0400)
committerRick Bird <nveid@bender.theari.com>
Sun, 27 Mar 2011 05:12:09 +0000 (01:12 -0400)
Minor changes:
  * nwho() now takes an optional viewer argument like lwho(). By Sketch.

Fixes:
  * Clarified the behavior of eval() and get_eval() in help. Suggested by
    Talvo and Javelin.
  * A failed db save no longer broadcasts a success message in additionto a
    failure one. Reported by Cooee.
  * The open database file wasn't getting closed on a failed save.
  * Crash bug in sortkey(). Fix by Nathan Baum.
  * 'help @desc' brings up @describe instead of @descformat.
    Suggested by Nymeria.
  * Removed mention of Win32 requiring a particular attribute
    compression algorithm. Any will work, and always have.
    Reported by Andrew Klein.
  * Crash bug in @purge. Javelin.

13 files changed:
game/txt/hlp/cobra_cmd.hlp
game/txt/hlp/cobra_flag.hlp
game/txt/hlp/cobra_func.hlp
options.h.dist
src/bsd.c
src/extmail.c
src/function.c
src/funlist.c
src/game.c
src/htab.c
src/malias.c
src/utils.c
src/warnings.c

index 53c95a50c17ae4eced4ce79436370799e39a5e1e..b51713d1c5d1b9945813eefe29a521a8cb48c6ca 100644 (file)
@@ -910,6 +910,7 @@ See also: give, @quota, MONEY
 
 See also: CLIENTS, ATTRIBUTES, WILDCARDS, MUSHCODE
 & @describe
+& @desc
   @describe <object> [=<description>]
 
   This command sets the description of the object, which will be seen 
index d0a2f439455f6a1ccdc56ff6925d630fe6508f53..81529add3cfcba015ec1e711eaf23c85cc5688b2 100644 (file)
@@ -49,11 +49,12 @@ Flag  Title           Flag  Title              Flag  Title
   a - Audible           b - Debug               c - Connected
   d - Destroy_Ok        e - Enter_Ok            g - Gagged
   h - Halt              i - Orphan              j - Jury_Ok             
-  l - Light             m - Myopic, Mistrust    n - No_Command          
-  o - On-Vacation       p - Puppet, Paranoid    s - Suspect           
-  t - Transparent       u - Uninspected         v - Verbose   
-  w - No_Warn           x - Terse, Cloudy       ? - Unregistered      
-  ^ - Listen_Parent     ~ - Noaccents           " - NoSpoof
+  k - Keepalive         l - Light               m - Myopic, Mistrust
+  n - No_Command        o - On-Vacation         p - Puppet, Paranoid
+  r - Royalty           s - Suspect             t - Transparent
+  u - Uninspected       v - Verbose             w - No_Warn
+  x - Terse, Cloudy     ? - Unregistered        ^ - Listen_Parent
+  ~ - Noaccents         " - NoSpoof
 
  Additional Flags:
   Auth_Parent           WeirdPrompts
index 12c1c71826bd2deaa427233ec51ead20ffe3ef27..71dc1408e346c8e6171cb8b3649eb81745db5c0d 100644 (file)
@@ -1187,11 +1187,13 @@ See also: decompose(), secure()
   eval(<object>, <attribute>)
   get_eval(<object>/<attribute>)
  
-  Eval() works the same way as xget(), except that it performs %-substitutions
-  and function evaluation on the attribute before returning the value. eval()
-  does not modify the stack (%0-%9), so the attribute being evaled sees the
-  same values for them that the calling code does. Unless you need this behavior,
-  it is better to use u() instead, which hides the caller's stack.
+  Eval() works the same way as xget(), except that it performs
+  %-substitutions and function evaluation on the attribute before
+  returning the value. eval() changes the enactor (%#) to the object
+  executing the eval (%!). It does not modify the stack (%0-%9), so
+  the attribute being evaled sees the same values for them that the
+  calling code does. Unless you need this behavior, it is better to
+  use u() instead, which hides the caller's stack.
 
     Example:
       &TEST me=%B%B%B-[name(me)]
@@ -2729,15 +2731,6 @@ See also: lcon(), lexits(), con(), exit()
   object is @created (or @dug, or @opened, or @pcreated, etc.), it
   will have this dbref.
 
-& NMWHO()
-  nmwho()
-
-  This returns a count of all currently connected, non-hidden players.
-  It's exactly the same as nwho() used by a mortal, and is suitable
-  for use on privileged global objects who need an unprivileged count
-  of who's online.
-
-See also: nwho(), mwho(), xmwho()
 & NOR()
   nor(<boolean>[, ... , <booleanN>])
 
@@ -2806,13 +2799,25 @@ See also: ncon(), nexits(), xplayers(), lplayers(), lvplayers()
   nvthings(<object>) is identical to words(lvthings(<object>))
 
 See also: ncon(), nexits(), xthings(), lthings(), lvthings()
+& NMWHO()
 & NWHO()
   nwho()
+  nwho(<viewer>)
+  nmwho()
 
-  This returns a count of all currently-connected players. When
+  nwho() returns a count of all currently-connected players. When
   mortals use this function, DARK wizards or royalty are NOT counted.
 
-See also: lwho(), nmwho(), xwho()
+  nmwho() returns a count of all currently connected, non-hidden players.
+  It's exactly the same as nwho() used by a mortal, and is suitable
+  for use on privileged global objects that always need an unprivileged
+  count of who is online.
+
+  If nwho() is given an argument, and is used by an object that can see
+  DARK and Hidden players, nwho() returns the count of online players
+  based on what <viewer> can see.
+
+See also: lwho(), mwho(), xwho(), xmwho()
 & OBJ()
   obj(<object>)
 
index 4e01b875404cc9801f9e900302123412529ec17f..80f8b7cd305e63c157e19d4bd7fea3d4c2284c76 100644 (file)
@@ -65,7 +65,7 @@
  *     when decompressing, and considerably slower when compressing.
  *     (But you decompress a lot more often). Compression ratio
  *     is worse than Huffman for small dbs (<1.5Mb of text), but
- *     better for larger dbs. Win32 systems must use this.
+ *     better for larger dbs. 
  * 4 - Raevnos's almost 8-bit clean version of the word-based algorithm.
  *     Prefer 3 unless you need extended characters. This algorithm
  *     can encode all characters except 0x06.
index 01ab285b66a51f8f28948eb14ff0482143927837..b75be8b8154ff6a3998ffb2c8f51e5857e68f0d3 100644 (file)
--- a/src/bsd.c
+++ b/src/bsd.c
@@ -4141,16 +4141,35 @@ visible_short_page(dbref player, const char *match)
 /* ARGSUSED */
 FUNCTION(fun_nwho) {
   DESC *d;
+  dbref victim;
   int count = 0;
   int powered = (*(called_as + 1) != 'M') && Priv_Who(executor);
 
+  if (nargs && args[0] && *args[0]) {
+    /* An argument was given. Find the victim and choose the lowest
+     * perms possible */
+    if (!powered) {
+      safe_str(T(e_perm), buff, bp);
+      return;
+    }
+    if ((victim = noisy_match_result(executor, args[0], NOTYPE,
+                                     MAT_EVERYTHING)) == 0) {
+      safe_str(T(e_notvis), buff, bp);
+      return;
+    }
+    if (!Priv_Who(victim))
+      powered = 0;
+  }
+
   DESC_ITER_CONN(d) {
-    if (!Hidden(d) || (powered && CanSee(executor, d->player)))
+    if (!Hidden(d) || powered) {
       count++;
-  }
+    }
+  } 
   safe_integer(count, buff, bp);
 }
 
+
 /* ARGSUSED */
 FUNCTION(fun_lwho)
 {
index 4281d7f937457a06f51e69693fca3a06f67aa5c6..8ae250bc19e728c9e60aefa189567bc81d1c257e 100644 (file)
@@ -2523,22 +2523,24 @@ status_string(MAIL *mp)
 {
   /* Return a longer description of message flags */
   static char tbuf1[BUFFER_LEN];
+  char *tp;
 
-  tbuf1[0] = '\0';
+  tp = tbuf1;
   if (Read(mp))
-    strcat(tbuf1, T("Read "));
+    safe_str(T("Read "), tbuf1, &tp);
   else
-    strcat(tbuf1, T("Unread "));
+    safe_str(T("Unread "), tbuf1, &tp);
   if (Cleared(mp))
-    strcat(tbuf1, T("Cleared "));
+    safe_str(T("Cleared "), tbuf1, &tp);
   if (Urgent(mp))
-    strcat(tbuf1, T("Urgent "));
+    safe_str(T("Urgent "), tbuf1, &tp);
   if (Mass(mp))
-    strcat(tbuf1, T("Mass "));
+    safe_str(T("Mass "), tbuf1, &tp);
   if (Forward(mp))
-    strcat(tbuf1, T("Fwd "));
+    safe_str(T("Fwd "), tbuf1, &tp);
   if (Tagged(mp))
-    strcat(tbuf1, T("Tagged"));
+    safe_str(T("Tagged"), tbuf1, &tp);
+  *tp = '\0';
   return tbuf1;
 }
 
@@ -2746,18 +2748,19 @@ filter_mail(dbref from, dbref player, char *subject,
     return;
 
   /* Handle this now so it doesn't clutter code */
-  tbuf1[0] = '\0';
+  j = 0;
   if (flags & M_URGENT)
-    strcat(tbuf1, "U");
+    tbuf1[j++] = 'U';
   if (flags & M_FORWARD)
-    strcat(tbuf1, "F");
+    tbuf1[j++] = 'F';
   if (flags & M_REPLY)
-    strcat(tbuf1, "R");
+    tbuf1[j++] = 'R';
+  tbuf1[j] = '\0';
 
-  arg = (char *) mush_malloc(BUFFER_LEN, "string");
-  arg2 = (char *) mush_malloc(BUFFER_LEN, "string");
-  arg3 = (char *) mush_malloc(BUFFER_LEN, "string");
-  arg4 = (char *) mush_malloc(BUFFER_LEN, "string");
+  arg = mush_malloc(BUFFER_LEN, "string");
+  arg2 = mush_malloc(BUFFER_LEN, "string");
+  arg3 = mush_malloc(BUFFER_LEN, "string");
+  arg4 = mush_malloc(BUFFER_LEN, "string");
   if (!arg4)
     mush_panic("Unable to allocate memory in mailfilter");
   save_global_regs("filter_mail", rsave);
@@ -2781,16 +2784,16 @@ filter_mail(dbref from, dbref player, char *subject,
   process_expression(buff, &bp, &ap, player, player, player,
                    PE_DEFAULT, PT_DEFAULT, NULL);
   *bp = '\0';
-  free((Malloc_t) asave);
+  free(asave);
   if (*buff) {
     sprintf(buf, "0:%d", mailnumber);
     do_mail_file(player, buf, buff);
   }
 
-  mush_free((Malloc_t) arg, "string");
-  mush_free((Malloc_t) arg2, "string");
-  mush_free((Malloc_t) arg3, "string");
-  mush_free((Malloc_t) arg4, "string");
+  mush_free(arg, "string");
+  mush_free(arg2, "string");
+  mush_free(arg3, "string");
+  mush_free(arg4, "string");
   restore_global_env("filter_mail", wsave);
   restore_global_regs("filter_mail", rsave);
 }
index 338402d729eabddd135cc3af1b649e0ade14aa26..58811ecb53000399734e8a3b5157d6536758e6d4 100644 (file)
@@ -532,7 +532,7 @@ FUNTAB flist[] = {
   {"NSPEMIT", fun_pemit, 2, -2, FN_REG},
   {"NSREMIT", fun_remit, 2, -2, FN_REG},
   {"NSZEMIT", fun_zemit, 2, -2, FN_REG},
-  {"NWHO", fun_nwho, 0, 0, FN_REG},
+  {"NWHO", fun_nwho, 0, 1, FN_REG},
   {"NMWHO", fun_nwho, 0, 0, FN_REG},
   {"NUM", fun_num, 1, 1, FN_REG},
   {"NULL", fun_null, 1, INT_MAX, FN_REG},
index 9941d5724ecae1bb11cf61a0d43f7437d887bee1..a2f66c470a75edbef3bef04d7d67451c964e4896 100644 (file)
@@ -1289,7 +1289,7 @@ FUNCTION(fun_sortkey)
   for (i = 0; i < nptrs; i++) {
     /* Build our %0 args */
     wenv[0] = (char *) ptrs[i];
-    call_ufun(&ufun, wenv, 2, result, executor, enactor, pe_info);
+    call_ufun(&ufun, wenv, 1, result, executor, enactor, pe_info);
     keys[i] = mush_strdup(result, "sortkey");
   }
 
index d5960072ae394b879d4990586ec367acff8641e0..3b6ea533b66c6761a45129e45a28024b904d79cb 100644 (file)
@@ -343,6 +343,8 @@ dump_database_internal(void)
     /* The dump failed. Disk might be full or something went bad with the
        compression slave. Boo! */
     do_rawlog(LT_ERR, T("ERROR! Database save failed."));
+    if(f)
+      db_close(f);
 #ifndef PROFILING
 #ifdef HAS_ITIMER
     install_sig_handler(SIGPROF, signal_cpu_limit);
@@ -564,8 +566,8 @@ dump_database(void)
   epoch++;
 
   do_rawlog(LT_ERR, "DUMPING: %s.#%d#", globals.dumpfile, epoch);
-  dump_database_internal();
-  do_rawlog(LT_ERR, "DUMPING: %s.#%d# (done)", globals.dumpfile, epoch);
+  if (!dump_database_internal())
+    do_rawlog(LT_ERR, "DUMPING: %s.#%d# (done)", globals.dumpfile, epoch);
 }
 
 /** Dump a database, possibly by forking the process.
@@ -667,7 +669,7 @@ fork_and_dump(int forking)
       _exit(status);            /* !!! */
     } else {
       reserve_fd();
-      if (DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE)
+      if (!status && DUMP_NOFORK_COMPLETE && *DUMP_NOFORK_COMPLETE)
         flag_broadcast(0, 0, "%s", DUMP_NOFORK_COMPLETE);
     }
   }
index f3bf6c526debf1f42dee17868dd36633b106a920..6cafc02a53b4469ccd06cc89c3b66b9b3cd24663 100644 (file)
@@ -527,7 +527,7 @@ void
 hash_stats_header(dbref player)
 {
   notify_format(player,
-                "Table      Buckets Entries LChain  ECh  1Ch  2Ch  3Ch 4+Ch  AvgCh ~Memory");
+                "Table       Buckets Entries LChain  ECh  1Ch  2Ch  3Ch 4+Ch  AvgCh ~Memory");
 }
 
 /** Display stats on a hashtable.
@@ -550,7 +550,6 @@ hash_stats(dbref player, HASHTAB *htab, const char *hname)
   for (n = 0; n < 5; n++)
     lengths[n] = 0;
   bytes += sizeof(HASHTAB);
-  bytes += htab->entry_size * htab->entries;
   if (htab->buckets) {
     bytes += HASHENT_SIZE * htab->hashsize;
     for (n = 0; n < htab->hashsize; n++) {
@@ -572,7 +571,7 @@ hash_stats(dbref player, HASHTAB *htab, const char *hname)
     totchains += lengths[n];
 
   notify_format(player,
-                "%-10s %7d %7d %6d %4d %4d %4d %4d %4d %6.3f %7u", hname,
+                "%-11s %7d %7d %6d %4d %4d %4d %4d %4d %6.3f %7u", hname,
                 htab->hashsize, htab->entries, longest, lengths[0], lengths[1],
                 lengths[2], lengths[3], lengths[4],
                 totchains > 0 ? chainlens / totchains : 0.0, bytes);
index 19ce76dec22dd6b8543cb895d80c3fa8b7ec02db..f01846f078d9a030baff8038b678faac18a544be 100644 (file)
@@ -139,7 +139,7 @@ do_malias_create(dbref player, char *alias, char *tolist)
     return;
   }
   if (!alias || !*alias || !tolist || !*tolist) {
-    notify(player, T("MAIL: What alias do you want to create?."));
+    notify(player, T("MAIL: What alias do you want to create?"));
     return;
   }
   if (*alias != MALIAS_TOKEN) {
index f2de85bd19db73abc8585ecb774bb4b415ec7b73..e135f9be20353ddb986dea90d51bea812826ffc4 100644 (file)
@@ -762,6 +762,8 @@ absolute_room(dbref it)
   if (!GoodObject(room))
     return NOTHING;
   while (!IsRoom(room)) {
+    if (!GoodObject(Location(room)))
+      return room;
     room = Location(room);
     rec++;
     if (rec > 20)
index 70d25473c1d4b8f41cac77abdae49266174069c6..4906b720a718228ef3f8e27616965145eb4c05d9 100644 (file)
@@ -376,9 +376,10 @@ const char *
 unparse_warnings(warn_type warns)
 {
   static char tbuf1[BUFFER_LEN];
+  char *tp;
   int listsize, indexx;
 
-  tbuf1[0] = '\0';
+  tp = tbuf1;
 
   /* Get the # of elements in checklist */
   listsize = sizeof(checklist) / sizeof(tcheck);
@@ -390,8 +391,8 @@ unparse_warnings(warn_type warns)
       /* Which is to say:
        * if the bits set on the_flag is a subset of the bits set on warns
        */
-      strcat(tbuf1, checklist[indexx].name);
-      strcat(tbuf1, " ");
+      safe_str(checklist[indexx].name, tbuf1, &tp);
+      safe_chr(' ', tbuf1, &tp);
       /* If we've got a flag which subsumes smaller ones, don't
        * list the smaller ones
        */