dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
/*  -*- LPC -*-  */
/**
 * The finger object, this handles all the finger and refer information
 * for the players.
 * @author Pinkfish
 * @started way back in 1991 sometime
 */
/*
 * $Locker:  $
 * $Id: finger.c,v 1.114 2003/07/16 18:40:28 pinkfish Exp $
 * 
 */
#include <config.h>
#include <mail.h>
#include <finger.h>
#include <player_handler.h>
#include <player.h>
#include <access.h>
#include <login.h>
#include <clubs.h>
#include <alias.h>
#include <library.h>
#include <nomic_system.h>

inherit "/std/basic/club_listing";
inherit "/global/family";

// 7776000 == 90 days.
#define NO_EMAIL_TIME 7776000
#define WWW_REPLACEMENTS (["%^BOLD%^" : "<b>", \
                           "%^EBOLD%^" : "</b>", \
                           "%^RESET%^" : "", \
                           "\n" : "<br>\n" ])
#define REPLACEMENTS (["%^EBOLD%^" : "%^RESET%^", \
                       "<br>" : ""])

void create() {
   seteuid("Root");
}                               /* create() */

/**
 * This method fixes up the output for html.
 * @param str the string to check
 * @return the htmlised string
 */
string htmlise(string str) {
   return replace_string(str, "<", "&lt;");
} /* htmlise() */

/**
 * This method returns the infomation printed when a banished person is
 * fingered;
 * @param name the name of the banished person
 * @return the banished information
 */
string banish_finger(string name, int caller) {
  string retval;
  string *file;
  
  file = explode(read_file("/banish/" + name[0..0] + "/" + name + ".o"), "\n");
  retval = sprintf("%35-s%35-s\n", "Login name : " + name,
                   "Real name : Banished");
  retval += "Not really many seconds old.\n";
  retval += "No mail ever.\n";
  retval += "No plan.\nNo future.\n";
  if (caller) {
    if (sizeof(file) == 3) {
      retval += implode(file, "\n") + "\n";
    } else {
      retval += "Banish info not in the correct format.\n";
    }
  }
  
  if (CLUB_HANDLER->is_club(name)) {
    retval += "\nThere is also a club of this name, try: 'refer club " +
      name + "' for information on the club.\n";
  }
  
  return replace(retval, "@@", "@ @ ");
}

/**
 * This method turns a time elapsed into a string.  Like: ten minutes
 * and one second
 * @param time_elapsed the amount of time elapsed
 * @return a nice time elapsed string
 */
string time_elapsed_string(int time_elapsed) {
   return query_time_string(time_elapsed, -1);
}                               /* time_elapsed_string() */

/**
 * This method returns additional information about the player.  This is
 * stuff like, are they a playtester, are they a trustee etc.
 * @param name the name of the player to get addional information about
 * @param user_colour if it should user colour codes
 * @param caller the grade of the caller
 *        (player, creator, director : 0, 1, 2)
 * @return the additional information
 */
private string get_additional_info(string name, int no_colour,
                                   int user_colour, int width, int caller) {
  string retval, tmp, tmp_leader;
   string *bing;
   int i, used_colour, need_new, domain_leader, domain_deputy,
     domain_developer;
   object ob;

   retval = "%^BOLD%^";

   if (PLAYER_HANDLER->test_creator(name)) {
      if (master()->query_trustee(name))
         retval += capitalize(name) + " is a Trustee.\n";
      else if (master()->query_director(name))
         retval += capitalize(name) + " is a Director.\n";
      else if (master()->query_senior(name))
         retval += capitalize(name) + " is a Senior Creator.\n";
      else
         retval += capitalize(name) + " is a Creator.\n";

      bing = "/secure/master"->query_domains();
      
      tmp = "";
      tmp_leader = "";
      for (i = 0; i < sizeof(bing); i++) {
         if ((string) ("/d/" + bing[i] + "/master")->query_lord() == name) {          
            bing[i] = capitalize(bing[i]);
            tmp_leader += "Leader of the " + bing[i] + " domain.\n";
            domain_leader = 1;
            continue;
         } else if (("/d/" + bing[i] + "/master")->query_deputy(name)) {
            tmp += "Deputy of the " + capitalize(bing[i]) + " domain.\n";
            domain_deputy = 1;
         } else if (!("/d/" + bing[i] + "/master")->query_member(name)) {
           if(bing[i] != "fluffy" && bing[i] != "liaison")
             domain_developer = 1;
           continue;
         }
         tmp += "Project in the " + capitalize(bing[i]) + " domain: " + 
           ("/d/" + bing[i] + "/master")->query_project(name) + "\n";
         bing[i] = capitalize(bing[i]);
      }
      
      tmp = tmp_leader + tmp;
      
      if (!sizeof(bing) && !domain_leader && !domain_deputy &&
          !domain_developer)
          tmp += "Not a member of any domain.\n";

      bing = ({ });
      if("/d/admin/master"->query_member(name))
        bing += ({ "Administrator" });
      if(domain_leader)
        bing += ({ "Domain Leader" });
      if(domain_deputy)
        bing += ({ "Domain Deputy" });
      
      if("/d/liaison/master"->query_member(name))
        bing += ({ "Liaison" });
      else if(domain_developer)
        bing += ({ "Developer" });
      
      if(sizeof(bing))
        retval += "Roles : " + query_multiple_short(bing) + ".\n";

      if(tmp)
        retval += sprintf("Domains : %-=*s", width - 10, tmp);
      
   } else if (PLAYTESTER_HAND->query_playtester(name)) {
      bing = ({"Playtester"});
      if (PLAYTESTER_HAND->query_pt_exec (name)) {
        bing += ({"Playtesting Executive"});        
      }
      
      if (PLAYTESTER_HAND->query_senior_playtester(name)) {
         retval += capitalize(name) + " is a Senior Playtester.\n";
      } else {
         retval += capitalize(name) + " is a Playtester.\n";
      }
      
        retval += "Roles : " + query_multiple_short(bing) + ".\n";
   }
   retval += "%^EBOLD%^";
   
   i = PLAYER_HANDLER->test_start_time(name);
   if (i)
      retval += "First logged on " + ctime(i) + ".\n";

   retval += capitalize(time_elapsed_string(-PLAYER_HANDLER->test_age(name))) + " old.\n";

   // On since or last logged on info.
   if (find_player(name) &&
       (caller >= find_player(name)->query_invis() ||
        (this_player() &&
         reference_allowed(find_player(name), this_player())))) {
      retval += "On since " + ctime(PLAYER_HANDLER->test_last(name)) + " (" +
         capitalize(time_elapsed_string(time() - PLAYER_HANDLER->test_last(name))) +
         ").\n";
   } else {
      /* Should be a nice number.... */
      i = time() - PLAYER_HANDLER->test_last(name);
      retval += "Last logged off " + time_elapsed_string(i) + " ago.\n";
   }

   if (caller > 1) {
      if (!find_player(name)) {
         retval += PLAYER_HANDLER->test_last_on_from(name) + "  ";
         need_new = 1;
      } else {
         retval += query_ip_name(find_player(name)) + " (" +
            query_ip_number(find_player(name)) + ")\n";
      }
   }

   
   ob = find_player(name);
   if (ob && (caller >= ob->query_invis() ||
                      (this_player() &&
                       reference_allowed (ob, this_player())))) {
      if (interactive(ob)) {
         retval += "Idle for " + time_elapsed_string(query_idle(ob)) + ".\n";
         need_new = 0;
      } else {
         retval += "Net dead.\n";
         need_new = 0;
      }
   }

   if (need_new)
      retval += "\n";

   retval += (string) MAILER->finger_mail(name);
   tmp = PLAYER_HANDLER->query_project(name);
   if(no_colour || !user_colour) {
     tmp = strip_colours(tmp);
     tmp = replace(tmp, "%^", " ");
   }
   
   if (tmp && tmp != "") {
      if (strsrch(tmp, "%^") != -1)
         used_colour = 1;
      retval += "%^BOLD%^Project:%^EBOLD%^\n" + tmp + "\n%^RESET%^";
   } else
      retval += "No project.\n";

   tmp = PLAYER_HANDLER->query_plan(name);
   if(no_colour || !user_colour) {
     tmp = strip_colours(tmp);
     tmp = replace(tmp, "%^", " ");
   }
   
   if (tmp && tmp != "") {
      if (strsrch(tmp, "%^") != -1)
         used_colour = 1;

      retval += "%^BOLD%^Plan:%^EBOLD%^\n" + tmp + "\n%^RESET%^";
   } else
      retval += "No plan.\n";

   if (used_colour)
      retval += "%^RESET%^%^BOLD%^---  End of finger ---%^EBOLD%^\n";

   return retval;
}

/**
 * This method returns the intermud finger information.
 * @param name the name to get the intermud info on
 * @return the intermud information
 */
public mixed *remote_finger(string name) {
   mixed *retval;
   object ob;
   string cname;

   if (!strlen(name) || !PLAYER_HANDLER->test_user(name))
      return 0;

   ob = find_player(name);

   cname = PLAYER_HANDLER->query_cap_name(name);
   if (!cname) {
      cname = capitalize(name);
   }
   retval = allocate(9);
   retval[0] = cname;
   retval[1] = cname;
   retval[0] = cname;
   retval[1] = cname;
   retval[2] = (PLAYER_HANDLER->test_real_name(name) ?
                PLAYER_HANDLER->test_real_name(name) : "???");
   retval[3] = "0";
   retval[4] = (ob && !ob->query_invis() ? ctime(ob->query_last_log_on()) :
                capitalize(time_elapsed_string(time() -
                                    PLAYER_HANDLER->test_last(name))));
   retval[5] = (ob && !ob->query_invis() ? query_idle(ob) : -1);
   retval[6] = 0;
   retval[7] = 0;
   retval[8] = get_additional_info(name, 1, 0, 80, 0);

   return retval;
}                               /* remote_finger() */


/* Wraps the name with a link to its www finger info. */
private string link_name(string name) {
   return "<a href=\"finger.c?player="+ name +"\">"+ capitalize(name) + "</a>";
}


/**
 * This method returns the information used to do a domain finger of
 * the domain.
 * @param name the name of the domain to finger
 * @param www 1 if called from www_finger_info()
 * @return the information about the domain
 */
string domain_finger(string name,
                     int width,
                     int www)
{
   string ret;
   string master;
   string *members;
   string *deputies;
   string idle_str;
   int i;
   string projects;

   master = "/d/" + name + "/master";

   if (!stringp(ret = master->generate_string())) {

      ret = "%^BOLD%^The domain of " + capitalize(name) + ".\n";
      ret += "The leader for this domain is " +
         (www?
          link_name((string) master->query_lord()) + ".\n":
          capitalize((string) master->query_lord()) + ".\n");
      members = master->query_members();
      deputies = master->query_deputies();
      if (deputies && sizeof(deputies)) {
         if (sizeof(deputies) > 1) {
            ret += "The deputies for the domain are ";
         } else {
            ret += "The deputy for the domain is ";
         }
         if(www) {
            ret +=
               query_multiple_short(map(deputies, (: link_name($1) :)));
         } else {
            ret +=
               query_multiple_short(map(deputies, (: capitalize($1) :)));
         }
         ret += ".\n";
      }

      ret += "%^EBOLD%^";
      ret += "The current members of this domain are :\n";
      projects = "";
      if(www) {
         // Begin table
         ret +=
            "<table cols=\"2\" rules=\"none\""
            "border=\"0\" width=\"100%\">";
      }
      for (i = 0; i < sizeof(members); i++) {
         if (master->query_deputy(members[i])) {
            projects = "[deputy] " + master->query_project(members[i]) + "\n";
         } else {
            projects = master->query_project(members[i]) + "\n";
         }
         if(www) {
            ret += "<tr> <td>"+ link_name(members[i]) +
               "</td> <td>"+ projects +"</td> <tr>";
         } else {
            ret += sprintf("%-=12s %-=*s",
                           capitalize(members[i]), width - 14, projects);
         }
      }
      if(www) {
         // Close the table
         ret += "</table>";
      }
   }

   if (master->query_info()) {
      ret += sprintf("%-=*s", width, (string) master->query_info());
   }

   if ( ( idle_str = master->query_idle_mess() ) ) {
       ret += idle_str;
   }
   else { 
       ret += "It hasn't been idle, it just hasn't had a lunch break in "
        "years.\n";
   }

   return ret;
}

/**
 * This method returns the information about the specified club.
 * @param name the name of the club to finger
 * @return the club information
 */
string club_finger(string name)
{
   return club_info_string(name, 0, "gumball lord");
}                               /* club_finger() */

/**
 * This method returns the information about the specified family.
 * @param name the name of the family to finger
 * @return the family information
 */
string family_finger(string name)
{
   return family_info_string(name, "gumball lord");
}                               /* family_finger() */

/**
 * This method returns the information about the specified deity.
 * @param name the name of the deity to finger
 * @return the deity information
 */
string deity_finger(string name)
{
   return 0;
}


/** @ignore yes
 * This handles fingering of things other than players.
 * It currently supports: domains, banished names, clubs and families.
 */
private string other_finger(string name,
                            int no_colour,
                            int user_colour,
                            int width,
                            int caller,
                            int www)
{

   // Im sure I wrote a function for this.
   if (member_array(name, "/secure/master"->query_domains()) != -1) {
      return domain_finger(name, width, www);
   }

   // have to be before test for banish as deities are banished
   if (file_size("/save/deities/" + name + ".o") > 0 ||
       file_size("/save/deities/" + name + ".o.gz") > 0) {
      return deity_finger(name);
   }

   if (name[0..4] == "club ") {
      if (CLUB_HANDLER->is_club(name[5..]) &&
          !CLUB_HANDLER->is_family(name[5..])) {
         return club_finger(name[5..]);
      }
   } else if (name[0..6] == "domain ") {
      if (member_array(name[7..], "/secure/master"->query_domains()) != -1) {
         return domain_finger(name[7..], width, www);
      }
   } else if (name[0..6] == "family ") {
      if (CLUB_HANDLER->is_family(name[7..])) {
         return family_finger(name[7..]);
      }
   } else if (CLUB_HANDLER->is_club(name)) {
      if (CLUB_HANDLER->is_family(name)) {
         return family_finger(name);
      } else {
         return club_finger(name);
      }
   }

   if (file_size("/banish/" + name[0..0] + "/" + name + ".o") > 0) {
      return banish_finger(name, caller);
   }

   return 0;
}

private string internal_finger_info(string name,
                                    int no_colour,
                                    int user_colour,
                                    int width,
                                    int caller,
                                    int www) // 1 if webfinger
{
   string retval,
     tmp,
     tmp2;
   int i;
   int days_left;
   mixed *suspended, *lockedout;

   // Call other_finger to handle fingering things that aren't actually players.
   if (!find_player(name) && !PLAYER_HANDLER->test_user(name)) {
   //   if ( !PLAYER_HANDLER->test_user(name) ) {
      return other_finger(name, no_colour, user_colour, width, caller, www);
   }

   // Do the first line of real & login name
   retval = (no_colour ? "" : "%^BOLD%^") +
      sprintf("%*-sReal name : %*-=s\n", (width - 2) / 2,
              "Login name : " +
              strip_colours(PLAYER_HANDLER->query_cap_name(name) + "<br>"),
              (width - 2) / 2 - 12,
              (PLAYER_HANDLER->test_real_name(name) ?
               htmlise(strip_colours(PLAYER_HANDLER->test_real_name(name)[0..30])) :
               "???"));

   // Calculate and show the email & birthday line.
   tmp = PLAYER_HANDLER->test_email(name);
   tmp2 = PLAYER_HANDLER->test_birthday(name);

   // Liaison deputies and above. 
   if ( strlen( tmp ) ) {
     if(tmp[0] == ':' || www ||
        PLAYER_HANDLER->test_last( name ) + NO_EMAIL_TIME < time()) {
       if(caller == 0) {
         tmp = "";
       }
     }
   }
   if (tmp) {
      tmp = htmlise(tmp);
      if (tmp2 && tmp2 != UNKNOWN_BIRTHDAY) {
         tmp2 = htmlise(tmp2);
         retval += sprintf("%*-sEmail : %*-=s\n", (width - 2) / 2,
                           "Birthday : " + tmp2 + "<br>", (width - 2) / 2,
                           tmp);
      } else {
         retval += sprintf("Email : %-*s\n", (width - 2) / 2 - 8, tmp[0..30]);
      }
   } else if (tmp2 && tmp2 != UNKNOWN_BIRTHDAY) {
      tmp2 = htmlise(tmp2);
      retval += sprintf("Birthday : %-*s\n", (width - 2) / 2 - 11, tmp2 +
                        "<br>");
   }

   // Indicate if they're marked for deletion.
   i = PLAYER_HANDLER->test_deleting(name);
   if (i) {
      retval += (no_colour ? "" : "%^RED%^") +
         "This character is marked to be deleted in ";
      if (time() - i > (10 * 60 * 60 * 24)) {
         retval += "1 day.\n";
      } else {
         days_left = (10 - ((time() - i) / (60 * 60 * 24)));
         if (days_left > 1) { 
            retval += days_left + " days.\n";
         } else {
           retval += days_left + " day.\n";
         }
      }
      if (!no_colour)
         retval += "%^RESET%^";
   }

   // Indicate if they're marked for deletion.
   i = PLAYER_HANDLER->test_appealing(name);
   if (i) {
      retval += (no_colour ? "" : "%^RED%^") +
         "This character is marked to be deleted in ";
      if (time() - i > (28 * 60 * 60 * 24)) {
         retval += "1 day";
      } else {
         days_left = (28 - ((time() - i) / (60 * 60 * 24)));
         if (days_left > 1) { 
            retval += days_left + " days";
         } else {
           retval += days_left + " day";
         }
      }
      retval += " pending appeal.\n";
      if (!no_colour)
        retval += "%^RESET%^";
   }
   tmp = PLAYER_HANDLER->test_home_dir(name);
   if (tmp)
      retval +=
         sprintf("%*-s", (width - 2) / 2, "Home directory : " + tmp + "<br>");

   tmp = PLAYER_HANDLER->test_guild(name);
   if (tmp) {
      if (catch(retval += "Member of the " + tmp->query_short() + ".\n"))
         retval += "Member of a very broken guild.\n";
   } else
      retval += "Member of the Adventurers' guild.\n";

   if(!no_colour)
     retval += "%^EBOLD%^";
   
   tmp = PLAYER_HANDLER->test_location(name);
   if (strlen(tmp)) {
      tmp = htmlise(tmp);
      retval += "Location : " + tmp[0..30] + "\n";
   }
   
   tmp = PLAYER_HANDLER->test_homepage(name);
   if (stringp(tmp)) {
      tmp = htmlise(tmp);
      retval += "Home Page: " + tmp + "\n";
   }

   // Show their suspension if they're suspended.
   suspended = "/secure/bastards"->query_suspended(name);
   if (suspended) {
      tmp = capitalize(name) + " has been suspended until " +
         ctime(suspended[SUSPEND_TIME]);
      if (caller) {
         tmp += " for " + suspended[SUSPEND_REASON] + ".\n";
      } else {
         tmp += ".\n";
      }
      retval += "%^YELLOW%^" + sprintf("%s%-=*s", tmp[0..10], width - 11,
                                       tmp[11..]) + "%^RESET%^";
   }
   // Show their suspension if they're suspended.
   lockedout = "/secure/bastards"->query_lockedout(name);
   if (lockedout) {
     tmp = capitalize(name) + " is locked out until " +
       ctime(lockedout[SUSPEND_TIME]);
     if (caller) {
       tmp += " because " + lockedout[SUSPEND_REASON] + ".\n";
     } else {
       tmp += ".\n";
     }
      retval += "%^YELLOW%^" + sprintf("%s%-=*s", tmp[0..10], width - 11,
                                       tmp[11..]) + "%^RESET%^";
   }

   retval += htmlise(get_additional_info(name, no_colour, user_colour, width, caller));

   return retval;
}

private string make_html(string str)
{
   int pos;

   pos = strsrch(str, "http:");
   if (pos == -1) {
      str = "http://" + str;
   } else {
      str = str[pos..];
   }
   pos = strsrch(str, " ");
   if (pos != -1) {
      str = str[0..pos - 1];
   }
   return str;
}                               /* make_html() */

/**
 * This is the main finger method.  It determines the type of finger
 * and prints out the relevant information.
 * @param name the name of the thing being fingered
 * @param no_colour remove all the colour codes
 * @param user_colour show user defined colours
 * @return the shorterned finger information
 */
string finger_info(string name,
                   int no_colour)
{
   int caller,
     width,
     user_colour;
   string retval,
     str;
   string user,
     nick;

   user = this_player()->query_name();
   user_colour = this_player()->query_property(PLAYER_ALLOW_COLOURED_SOULS);
   
   if (this_player()) {
      nick = (string) this_player()->expand_nickname(name);
      if (nick)
         name = nick;
      width = this_player()->query_cols();
   }

   if (!width) {
      width = 80;
   }

   if (master()->query_director(user)) {
      caller = 3;
   } else if (master()->is_liaison_deputy(user)) {
      caller = 2;
   } else if (PLAYER_HANDLER->test_creator(user)) {
      caller = 1;
   } else {
      caller = 0;
   }

   retval = internal_finger_info(name, no_colour, user_colour,
                                 width, caller, 0);
   if (!retval) {
      return 0;
   }

   foreach(str in keys(REPLACEMENTS)) {
      retval = replace_string(retval, str, REPLACEMENTS[str]);
   }

   return retval;
}

/**
 * This method returns the finger information to the web pages.
 * @param name the name of the thing to finger
 * @param user the user who is doing the fingering
 * @return the html code for the finger
 */
string www_finger_info(string name,
                       string user)
{
   int caller;
   string retval,
     str;

   if (!user || user == "")
      caller = 0;
   else if (master()->query_director(user))
      caller = 3;
   else if (master()->is_liaison_deputy(user))
      caller = 2;
   else if (PLAYER_HANDLER->test_creator(user))
      caller = 1;
   else
      caller = 0;

   retval = internal_finger_info(name, 0, 1, 80, caller, 1);
   if (!retval)
      return 0;

   foreach(str in keys(WWW_REPLACEMENTS))
      retval = replace_string(retval, str, WWW_REPLACEMENTS[str]);

   retval = strip_colours(retval);
   return retval;
}

/**
 * This method returns the refer information of the player.
 * @param name the name of the player to get the refer information on
 * @return the refer information
 */
string refer_info(string name) {
   string retval, nick, tmp, family, rels, area, str;
   object ob;
   int width, sex;

   retval = "";
   width = 80;

   if (this_player()) {
      nick = (string) this_player()->expand_nickname(name);
      width = this_player()->query_cols();
   }
   if (nick) {
      name = nick;
   }

   if (!PLAYER_HANDLER->test_user(name)) {
     retval = other_finger(name, 0, 0, width, 0, 0);
     if(retval)
       foreach(str in keys(REPLACEMENTS))
         retval = replace_string(retval, str, REPLACEMENTS[str]);
     return retval;
   }


   family = "";

   tmp = PLAYER_HANDLER->test_player_title(name);
   if (tmp) {
      tmp += " ";
   } else {
      tmp = "";
   }

   retval = PLAYER_HANDLER->query_cap_name(name);
   if (!retval) {
      return 0;
   }

   tmp = PLAYER_HANDLER->test_family_name(name);
   if (tmp) {
      retval += " " + tmp;
   }

   if ("/d/liaison/master"->query_member(name)) {
      retval += " (%^YELLOW%^Liaison%^RESET%^)";
   } else if (PLAYER_HANDLER->test_creator(name)) {
      if ("/secure/master"->query_trustee(name)) {
         retval += " (%^RED%^Trustee%^RESET%^)";
      } else if ("/secure/master"->query_director(name)) {
         retval += " (%^RED%^Director%^RESET%^)";
      } else if ("/secure/master"->query_senior(name)) {
         retval += " (%^RED%^Senior%^RESET%^)";
      } else {
         retval += " (%^RED%^Creator%^RESET%^)";
      }
   }

   ob = find_player(name);
   if (ob) {
      if (tmp = (string) ob->query_gtitle()) {
         retval += " " + tmp;
      } else {
         retval += " the Adventurer";
      }
      if (tmp = (string)ob->query_property("player_title")) {
         retval += ", " + tmp;
      }
      tmp = (string) ob->query_title();
      if (tmp && tmp != "") {
         retval += ", " + tmp;
      }
   }

   if (PLAYTESTER_HAND->query_playtester(name)) {
     if (PLAYTESTER_HAND->query_senior_playtester(name)) {
       retval += ", (%^BOLD%^%^CYAN%^Senior Playtester%^RESET%^)";
     } else {
       retval += ", (%^CYAN%^Playtester%^RESET%^)";
     }
   }

   if(ob) {
     retval += ".";
      if(ob->query_nationality_name()) {
        retval += "\n" + capitalize(ob->query_possessive()) +
          " nationality is " + capitalize(ob->query_nationality_name());
        if(ob->query_nationality_region())
          retval += " and " + ob->query_pronoun() + " is from "+
            capitalize(ob->query_nationality_region());
        retval +=  ".\n";
      }
   } else {
      retval += " (not currently logged in)\n";
   }

   tmp = PLAYER_HANDLER->test_desc(name);
   if (tmp && tmp != "") {
     if(!this_player()->query_property(PLAYER_ALLOW_COLOURED_SOULS))
       tmp = strip_colours(tmp);
      sex = PLAYER_HANDLER->test_gender(name);
      if (sex == 1) {
         retval += "He " + tmp + "\n";
      } else if (sex == 2) {
         retval += "She " + tmp + "\n";
      } else {
         retval += "It " + tmp + "\n";
      }
   } else {
      retval += "No description.\n";
   }

   //
   // Do some magistrate and citizen stuff.
   //
   foreach(area in NOMIC_HANDLER->query_citizenship_areas()) {
      if (NOMIC_HANDLER->is_magistrate_of(area, name)) {
         retval += "Magistrate in " + area + ".\n";
      } else if (NOMIC_HANDLER->is_citizen_of(area, name)) {
         retval += "Citizen in " + area + ".\n";
      }
   }

   rels = "/std/basic/club_listing"->player_relationships_string(name);
   if (rels != "") {
      retval += PLAYER_HANDLER->query_cap_name(name) + " " +
         PLAYER_HANDLER->test_family(name) + " is the " + rels + "\n";
   }

   if(PLAYER_HANDLER->test_player_killer(name)) {
     retval += PLAYER_HANDLER->query_cap_name(name) + " is a player killer.\n";
   }

   tmp = PLAYER_HANDLER->query_reference(name);
   if(!this_player()->query_property(PLAYER_ALLOW_COLOURED_SOULS))
     tmp = strip_colours(tmp);
      
   if (tmp && tmp != "") {
      retval += "\n" + tmp + "\n%^RESET%^";
      if (strsrch(tmp, "%^") != -1) {
         retval += "--- End of Reference --\n";
      }
   } else {
      retval += "No reference.\n";
   }

   return retval;
}