circlemud_squared_0.5.153/cnf/
circlemud_squared_0.5.153/etc/
circlemud_squared_0.5.153/etc/etc/
circlemud_squared_0.5.153/etc/house/
circlemud_squared_0.5.153/etc/misc/
circlemud_squared_0.5.153/etc/plralias/A-E/
circlemud_squared_0.5.153/etc/plralias/F-J/
circlemud_squared_0.5.153/etc/plralias/K-O/
circlemud_squared_0.5.153/etc/plralias/P-T/
circlemud_squared_0.5.153/etc/plralias/U-Z/
circlemud_squared_0.5.153/etc/plralias/ZZZ/
circlemud_squared_0.5.153/etc/plrobjs/
circlemud_squared_0.5.153/etc/plrobjs/A-E/
circlemud_squared_0.5.153/etc/plrobjs/F-J/
circlemud_squared_0.5.153/etc/plrobjs/K-O/
circlemud_squared_0.5.153/etc/plrobjs/P-T/
circlemud_squared_0.5.153/etc/plrobjs/U-Z/
circlemud_squared_0.5.153/etc/plrobjs/ZZZ/
circlemud_squared_0.5.153/etc/text/
circlemud_squared_0.5.153/etc/text/help/
circlemud_squared_0.5.153/src/util/
circlemud_squared_0.5.153/src/util/worldconv/
/**
 * @file command.c
 *
 * Command types, function prototypes, and maintenence routines.
 *
 * @author Geoff Davis <geoff@circlemudsquared.org>
 * @ingroup command
 * @license All rights reserved.  See license.doc for complete information.
 * @package cs
 * @since v1.0
 *
 * Copyright (C) 2006 Geoff Davis <geoff@circlemudsquared.org>
 *                    Greg Buxton <greg@circlemudsquared.org>
 *
 * Copyright (C) 1993, 94 by the Trustees of the Johns Hopkins University
 * CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991.
 */

#define __COMMAND_C__

#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "command.h"
#include "constants.h"
#include "dao.h"
#include "db.h"
#include "interpreter.h"
#include "log.h"

/*
 * External variables.
 */
extern int no_specials;

/*
 * External functions.
 */
socialData_t *find_action(const commandData_t *cmd);
int special(charData_t *ch, const commandData_t *cmd, char *arg);

/**
 * The ACMD table.
 * @ingroup command
 * @var const acmdData_t[]
 */
BEGIN_ACMD_REGISTRY(acmd_registry)
  REGISTER_ACMD(do_action)
  REGISTER_ACMD(do_advance)
  REGISTER_ACMD(do_alias)
  REGISTER_ACMD(do_appraise)
  REGISTER_ACMD(do_assist)
  REGISTER_ACMD(do_at)
  REGISTER_ACMD(do_authorize)
  REGISTER_ACMD(do_backstab)
  REGISTER_ACMD(do_ban)
  REGISTER_ACMD(do_bash)
  REGISTER_ACMD(do_buy)
  REGISTER_ACMD(do_cast)
  REGISTER_ACMD(do_color)
  REGISTER_ACMD(do_commands)
  REGISTER_ACMD(do_consider)
  REGISTER_ACMD(do_date)
  REGISTER_ACMD(do_dc)
  REGISTER_ACMD(do_diagnose)
  REGISTER_ACMD(do_display)
  REGISTER_ACMD(do_drink)
  REGISTER_ACMD(do_drop)
  REGISTER_ACMD(do_eat)
  REGISTER_ACMD(do_echo)
  REGISTER_ACMD(do_enter)
  REGISTER_ACMD(do_equipment)
  REGISTER_ACMD(do_examine)
  REGISTER_ACMD(do_exits)
  REGISTER_ACMD(do_flee)
  REGISTER_ACMD(do_follow)
  REGISTER_ACMD(do_force)
  REGISTER_ACMD(do_gecho)
  REGISTER_ACMD(do_gen_comm)
  REGISTER_ACMD(do_gen_door)
  REGISTER_ACMD(do_gen_ps)
  REGISTER_ACMD(do_gen_write)
  REGISTER_ACMD(do_get)
  REGISTER_ACMD(do_give)
  REGISTER_ACMD(do_gold)
  REGISTER_ACMD(do_goto)
  REGISTER_ACMD(do_grab)
  REGISTER_ACMD(do_group)
  REGISTER_ACMD(do_gsay)
  REGISTER_ACMD(do_hcontrol)
  REGISTER_ACMD(do_help)
  REGISTER_ACMD(do_hide)
  REGISTER_ACMD(do_hit)
  REGISTER_ACMD(do_house)
  REGISTER_ACMD(do_insult)
  REGISTER_ACMD(do_inventory)
  REGISTER_ACMD(do_invis)
  REGISTER_ACMD(do_kick)
  REGISTER_ACMD(do_kill)
  REGISTER_ACMD(do_last)
  REGISTER_ACMD(do_leave)
  REGISTER_ACMD(do_levels)
  REGISTER_ACMD(do_list)
  REGISTER_ACMD(do_load)
  REGISTER_ACMD(do_look)
  REGISTER_ACMD(do_move)
  REGISTER_ACMD(do_not_here)
/*  REGISTER_ACMD(do_olc) */
  REGISTER_ACMD(do_order)
  REGISTER_ACMD(do_page)
  REGISTER_ACMD(do_poofset)
  REGISTER_ACMD(do_pour)
  REGISTER_ACMD(do_practice)
  REGISTER_ACMD(do_purge)
  REGISTER_ACMD(do_put)
  REGISTER_ACMD(do_qcomm)
  REGISTER_ACMD(do_quit)
  REGISTER_ACMD(do_reboot)
  REGISTER_ACMD(do_remove)
  REGISTER_ACMD(do_reply)
  REGISTER_ACMD(do_report)
  REGISTER_ACMD(do_rescue)
  REGISTER_ACMD(do_rest)
  REGISTER_ACMD(do_restore)
  REGISTER_ACMD(do_return)
  REGISTER_ACMD(do_save)
  REGISTER_ACMD(do_savecommands)
  REGISTER_ACMD(do_savezone)
  REGISTER_ACMD(do_say)
  REGISTER_ACMD(do_score)
  REGISTER_ACMD(do_sell)
  REGISTER_ACMD(do_send)
  REGISTER_ACMD(do_set)
  REGISTER_ACMD(do_show)
  REGISTER_ACMD(do_shutdown)
  REGISTER_ACMD(do_sit)
  REGISTER_ACMD(do_skillset)
  REGISTER_ACMD(do_sleep)
  REGISTER_ACMD(do_slowns)
  REGISTER_ACMD(do_sneak)
  REGISTER_ACMD(do_snoop)
  REGISTER_ACMD(do_spec_comm)
  REGISTER_ACMD(do_split)
  REGISTER_ACMD(do_stand)
  REGISTER_ACMD(do_stat)
  REGISTER_ACMD(do_steal)
  REGISTER_ACMD(do_switch)
  REGISTER_ACMD(do_syslog)
  REGISTER_ACMD(do_teleport)
  REGISTER_ACMD(do_tell)
  REGISTER_ACMD(do_time)
  REGISTER_ACMD(do_title)
  REGISTER_ACMD(do_toggle)
  REGISTER_ACMD(do_track)
  REGISTER_ACMD(do_trackthru)
  REGISTER_ACMD(do_trans)
  REGISTER_ACMD(do_unban)
  REGISTER_ACMD(do_ungroup)
  REGISTER_ACMD(do_use)
  REGISTER_ACMD(do_users)
  REGISTER_ACMD(do_visible)
  REGISTER_ACMD(do_vnum)
  REGISTER_ACMD(do_vstat)
  REGISTER_ACMD(do_wake)
  REGISTER_ACMD(do_wear)
  REGISTER_ACMD(do_weather)
  REGISTER_ACMD(do_where)
  REGISTER_ACMD(do_who)
  REGISTER_ACMD(do_wield)
  REGISTER_ACMD(do_wimpy)
  REGISTER_ACMD(do_wizlock)
  REGISTER_ACMD(do_wiznet)
  REGISTER_ACMD(do_wizutil)
  REGISTER_ACMD(do_write)
  REGISTER_ACMD(do_zreset)
END_ACMD_REGISTRY();

/**
 * The master command table.
 * @ingroup command
 * @var const commandData_t[]
 */
const commandData_t cmd_info[] = {
  /* directions must come before other commands but after RESERVED */
  { "north",    POS_STANDING,   do_move,        AUTH_NONE },
  { "east",     POS_STANDING,   do_move,        AUTH_NONE },
  { "south",    POS_STANDING,   do_move,        AUTH_NONE },
  { "west",     POS_STANDING,   do_move,        AUTH_NONE },
  { "up",       POS_STANDING,   do_move,        AUTH_NONE },
  { "down",     POS_STANDING,   do_move,        AUTH_NONE },

  /* A */
  { "at",       POS_DEAD,       do_at,          AUTH_WIZARD },
  { "accuse",   POS_SITTING,    do_action,      AUTH_NONE },
  { "advance",  POS_DEAD,       do_advance,     AUTH_OWNER },
  { "alias",    POS_DEAD,       do_alias,       AUTH_GUEST },
  { "applaud",  POS_RESTING,    do_action,      AUTH_NONE },
  { "appraise", POS_STANDING,   do_appraise,    AUTH_GUEST },
  { "ask",      POS_RESTING,    do_spec_comm,   AUTH_NONE },
  { "assist",   POS_FIGHTING,   do_assist,      AUTH_PLAYER },
  { "auction",  POS_SLEEPING,   do_gen_comm,    AUTH_GUEST },
  { "authorize",POS_DEAD,       do_authorize,   AUTH_OWNER },

  /* B */
  { "bounce",   POS_STANDING,   do_action,      AUTH_NONE },
  { "backstab", POS_STANDING,   do_backstab,    AUTH_PLAYER },
  { "ban",      POS_DEAD,       do_ban,         AUTH_OWNER },
  { "balance",  POS_STANDING,   do_not_here,    AUTH_PLAYER },
  { "bash",     POS_FIGHTING,   do_bash,        AUTH_PLAYER },
  { "beg",      POS_RESTING,    do_action,      AUTH_NONE },
  { "bleed",    POS_RESTING,    do_action,      AUTH_NONE },
  { "blush",    POS_RESTING,    do_action,      AUTH_NONE },
  { "bow",      POS_STANDING,   do_action,      AUTH_NONE },
  { "brb",      POS_RESTING,    do_action,      AUTH_NONE },
  { "burp",     POS_RESTING,    do_action,      AUTH_NONE },
  { "buy",      POS_STANDING,   do_buy,         AUTH_GUEST },
  { "bug",      POS_DEAD,       do_gen_write,   AUTH_GUEST },

  /* C */
  { "cast",     POS_SITTING,    do_cast,        AUTH_PLAYER },
  { "cackle",   POS_RESTING,    do_action,      AUTH_NONE },
  { "check",    POS_STANDING,   do_not_here,    AUTH_PLAYER },
  { "chuckle",  POS_RESTING,    do_action,      AUTH_NONE },
  { "clap",     POS_RESTING,    do_action,      AUTH_NONE },
  { "clear",    POS_DEAD,       do_gen_ps,      AUTH_NONE },
  { "close",    POS_SITTING,    do_gen_door,    AUTH_NONE },
  { "cls",      POS_DEAD,       do_gen_ps,      AUTH_NONE },
  { "consider", POS_RESTING,    do_consider,    AUTH_NONE },
  { "color",    POS_DEAD,       do_color,       AUTH_NONE },
  { "comfort",  POS_RESTING,    do_action,      AUTH_NONE },
  { "comb",     POS_RESTING,    do_action,      AUTH_NONE },
  { "commands", POS_DEAD,       do_commands,    AUTH_NONE },
  { "cough",    POS_RESTING,    do_action,      AUTH_NONE },
  { "credits",  POS_DEAD,       do_gen_ps,      AUTH_NONE },
  { "cringe",   POS_RESTING,    do_action,      AUTH_NONE },
  { "cry",      POS_RESTING,    do_action,      AUTH_NONE },
  { "cuddle",   POS_RESTING,    do_action,      AUTH_NONE },
  { "curse",    POS_RESTING,    do_action,      AUTH_NONE },
  { "curtsey",  POS_STANDING,   do_action,      AUTH_NONE },

  /* D */
  { "dance",    POS_STANDING,   do_action,      AUTH_NONE },
  { "date",     POS_DEAD,       do_date,        AUTH_WIZARD },
  { "daydream", POS_SLEEPING,   do_action,      AUTH_NONE },
  { "dc",       POS_DEAD,       do_dc,          AUTH_WIZARD },
  { "deposit",  POS_STANDING,   do_not_here,    AUTH_PLAYER },
  { "diagnose", POS_RESTING,    do_diagnose,    AUTH_NONE },
  { "display",  POS_DEAD,       do_display,     AUTH_NONE },
  { "donate",   POS_RESTING,    do_drop,        AUTH_NONE },
  { "drink",    POS_RESTING,    do_drink,       AUTH_NONE },
  { "drop",     POS_RESTING,    do_drop,        AUTH_NONE },
  { "drool",    POS_RESTING,    do_action,      AUTH_NONE },

  /* E */
  { "eat",      POS_RESTING,    do_eat,         AUTH_NONE },
  { "echo",     POS_SLEEPING,   do_echo,        AUTH_WIZARD },
  { "emote",    POS_RESTING,    do_echo,        AUTH_PLAYER },
  { ":",        POS_RESTING,    do_echo,        AUTH_PLAYER },
  { "embrace",  POS_STANDING,   do_action,      AUTH_NONE },
  { "enter",    POS_STANDING,   do_enter,       AUTH_NONE },
  { "equipment",POS_SLEEPING,   do_equipment,   AUTH_NONE },
  { "exits",    POS_RESTING,    do_exits,       AUTH_NONE },
  { "examine",  POS_SITTING,    do_examine,     AUTH_NONE },

  /* F */
  { "force",    POS_SLEEPING,   do_force,       AUTH_WIZARD },
  { "fart",     POS_RESTING,    do_action,      AUTH_NONE },
  { "fill",     POS_STANDING,   do_pour,        AUTH_NONE },
  { "flee",     POS_FIGHTING,   do_flee,        AUTH_PLAYER },
  { "flip",     POS_STANDING,   do_action,      AUTH_NONE },
  { "flirt",    POS_RESTING,    do_action,      AUTH_NONE },
  { "follow",   POS_RESTING,    do_follow,      AUTH_NONE },
  { "fondle",   POS_RESTING,    do_action,      AUTH_NONE },
  { "freeze",   POS_DEAD,       do_wizutil,     AUTH_FREEZE },
  { "french",   POS_RESTING,    do_action,      AUTH_NONE },
  { "frown",    POS_RESTING,    do_action,      AUTH_NONE },
  { "fume",     POS_RESTING,    do_action,      AUTH_NONE },

  /* G */
  { "get"      , POS_RESTING , do_get      , AUTH_NONE },
  { "gasp"     , POS_RESTING , do_action   , AUTH_NONE },
  { "gecho"    , POS_DEAD    , do_gecho    , AUTH_WIZARD },
  { "give"     , POS_RESTING , do_give     , AUTH_NONE },
  { "giggle"   , POS_RESTING , do_action   , AUTH_NONE },
  { "glare"    , POS_RESTING , do_action   , AUTH_NONE },
  { "goto"     , POS_SLEEPING, do_goto     , AUTH_WIZARD },
  { "gold"     , POS_RESTING , do_gold     , AUTH_NONE },
  { "gossip"   , POS_SLEEPING, do_gen_comm , AUTH_NONE },
  { "group"    , POS_RESTING , do_group    , AUTH_PLAYER },
  { "grab"     , POS_RESTING , do_grab     , AUTH_NONE },
  { "grats"    , POS_SLEEPING, do_gen_comm , AUTH_NONE },
  { "greet"    , POS_RESTING , do_action   , AUTH_NONE },
  { "grin"     , POS_RESTING , do_action   , AUTH_NONE },
  { "groan"    , POS_RESTING , do_action   , AUTH_NONE },
  { "grope"    , POS_RESTING , do_action   , AUTH_NONE },
  { "grovel"   , POS_RESTING , do_action   , AUTH_NONE },
  { "growl"    , POS_RESTING , do_action   , AUTH_NONE },
  { "gsay"     , POS_SLEEPING, do_gsay     , AUTH_NONE },
  { "gtell"    , POS_SLEEPING, do_gsay     , AUTH_NONE },

  { "help"     , POS_DEAD    , do_help     , AUTH_NONE },
  { "handbook" , POS_DEAD    , do_gen_ps   , AUTH_WIZARD },
  { "hcontrol" , POS_DEAD    , do_hcontrol , AUTH_OWNER },
  { "hiccup"   , POS_RESTING , do_action   , AUTH_NONE },
  { "hide"     , POS_RESTING , do_hide     , AUTH_PLAYER },
  { "hit"      , POS_FIGHTING, do_hit      , AUTH_NONE },
  { "hold"     , POS_RESTING , do_grab     , AUTH_PLAYER },
  { "holler"   , POS_RESTING , do_gen_comm , AUTH_PLAYER },
  { "hop"      , POS_RESTING , do_action   , AUTH_NONE },
  { "house"    , POS_RESTING , do_house    , AUTH_NONE },
  { "hug"      , POS_RESTING , do_action   , AUTH_NONE },

  { "inventory", POS_DEAD    , do_inventory, AUTH_NONE },
  { "idea"     , POS_DEAD    , do_gen_write, AUTH_NONE },
  { "imotd"    , POS_DEAD    , do_gen_ps   , AUTH_WIZARD },
  { "immlist"  , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "info"     , POS_SLEEPING, do_gen_ps   , AUTH_NONE },
  { "insult"   , POS_RESTING , do_insult   , AUTH_NONE },
  { "invis"    , POS_DEAD    , do_invis    , AUTH_WIZARD },

  { "junk"     , POS_RESTING , do_drop     , AUTH_NONE },

  { "kill"     , POS_FIGHTING, do_kill     , AUTH_NONE },
  { "kick"     , POS_FIGHTING, do_kick     , AUTH_PLAYER },
  { "kiss"     , POS_RESTING , do_action   , AUTH_NONE },

  { "look"     , POS_RESTING , do_look     , AUTH_NONE },
  { "laugh"    , POS_RESTING , do_action   , AUTH_NONE },
  { "last"     , POS_DEAD    , do_last     , AUTH_WIZARD },
  { "leave"    , POS_STANDING, do_leave    , AUTH_NONE },
  { "levels"   , POS_DEAD    , do_levels   , AUTH_NONE },
  { "list"     , POS_SITTING , do_list     , AUTH_NONE },
  { "lick"     , POS_RESTING , do_action   , AUTH_NONE },
  { "lock"     , POS_SITTING , do_gen_door , AUTH_NONE },
  { "load"     , POS_DEAD    , do_load     , AUTH_WIZARD },
  { "love"     , POS_RESTING , do_action   , AUTH_NONE },

  { "moan"     , POS_RESTING , do_action   , AUTH_NONE },
  { "motd"     , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "mail"     , POS_STANDING, do_not_here , AUTH_PLAYER },
  { "massage"  , POS_RESTING , do_action   , AUTH_NONE },
  { "mute"     , POS_DEAD    , do_wizutil  , AUTH_WIZARD },
  { "murder"   , POS_FIGHTING, do_hit      , AUTH_NONE },

  { "news"     , POS_SLEEPING, do_gen_ps   , AUTH_NONE },
  { "nibble"   , POS_RESTING , do_action   , AUTH_NONE },
  { "nod"      , POS_RESTING , do_action   , AUTH_NONE },
  { "notitle"  , POS_DEAD    , do_wizutil  , AUTH_WIZARD },
  { "nudge"    , POS_RESTING , do_action   , AUTH_NONE },
  { "nuzzle"   , POS_RESTING , do_action   , AUTH_NONE },

  { "order"    , POS_RESTING , do_order    , AUTH_PLAYER },
  { "offer"    , POS_STANDING, do_not_here , AUTH_PLAYER },
  { "open"     , POS_SITTING , do_gen_door , AUTH_NONE },

  { "put"      , POS_RESTING , do_put      , AUTH_NONE },
  { "pat"      , POS_RESTING , do_action   , AUTH_NONE },
  { "page"     , POS_DEAD    , do_page     , AUTH_WIZARD },
  { "pardon"   , POS_DEAD    , do_wizutil  , AUTH_WIZARD },
  { "peer"     , POS_RESTING , do_action   , AUTH_NONE },
  { "pick"     , POS_STANDING, do_gen_door , AUTH_PLAYER },
  { "point"    , POS_RESTING , do_action   , AUTH_NONE },
  { "poke"     , POS_RESTING , do_action   , AUTH_NONE },
  { "policy"   , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "ponder"   , POS_RESTING , do_action   , AUTH_NONE },
  { "poofin"   , POS_DEAD    , do_poofset  , AUTH_WIZARD },
  { "poofout"  , POS_DEAD    , do_poofset  , AUTH_WIZARD },
  { "pour"     , POS_STANDING, do_pour     , AUTH_NONE },
  { "pout"     , POS_RESTING , do_action   , AUTH_NONE },
  { "prompt"   , POS_DEAD    , do_display  , AUTH_NONE },
  { "practice" , POS_RESTING , do_practice , AUTH_PLAYER },
  { "pray"     , POS_SITTING , do_action   , AUTH_NONE },
  { "puke"     , POS_RESTING , do_action   , AUTH_NONE },
  { "punch"    , POS_RESTING , do_action   , AUTH_NONE },
  { "purr"     , POS_RESTING , do_action   , AUTH_NONE },
  { "purge"    , POS_DEAD    , do_purge    , AUTH_WIZARD },

  { "quaff"    , POS_RESTING , do_use      , AUTH_NONE },
  { "qecho"    , POS_DEAD    , do_qcomm    , AUTH_WIZARD },
  { "qui"      , POS_DEAD    , do_quit     , AUTH_NONE },
  { "quit"     , POS_DEAD    , do_quit     , AUTH_NONE },
  { "qsay"     , POS_RESTING , do_qcomm    , AUTH_NONE },

  { "reply"    , POS_SLEEPING, do_reply    , AUTH_NONE },
  { "rest"     , POS_RESTING , do_rest     , AUTH_NONE },
  { "read"     , POS_RESTING , do_look     , AUTH_NONE },
  { "reload"   , POS_DEAD    , do_reboot   , AUTH_OWNER },
  { "recite"   , POS_RESTING , do_use      , AUTH_NONE },
  { "receive"  , POS_STANDING, do_not_here , AUTH_PLAYER },
  { "remove"   , POS_RESTING , do_remove   , AUTH_NONE },
  { "rent"     , POS_STANDING, do_not_here , AUTH_PLAYER },
  { "report"   , POS_RESTING , do_report   , AUTH_NONE },
  { "reroll"   , POS_DEAD    , do_wizutil  , AUTH_OWNER },
  { "rescue"   , POS_FIGHTING, do_rescue   , AUTH_PLAYER },
  { "restore"  , POS_DEAD    , do_restore  , AUTH_WIZARD },
  { "return"   , POS_DEAD    , do_return   , AUTH_NONE },
  { "roll"     , POS_RESTING , do_action   , AUTH_NONE },
  { "ruffle"   , POS_STANDING, do_action   , AUTH_NONE },

  { "say"      , POS_RESTING , do_say      , AUTH_NONE },
  { "'"        , POS_RESTING , do_say      , AUTH_NONE },
  { "save"     , POS_SLEEPING, do_save     , AUTH_NONE },
  { "savecommands", POS_DEAD , do_savecommands, AUTH_WIZARD },
  { "savezone" , POS_DEAD    , do_savezone , AUTH_WIZARD },
  { "score"    , POS_DEAD    , do_score    , AUTH_NONE },
  { "scream"   , POS_RESTING , do_action   , AUTH_NONE },
  { "sell"     , POS_SITTING , do_sell     , AUTH_GUEST },
  { "send"     , POS_SLEEPING, do_send     , AUTH_WIZARD },
  { "set"      , POS_DEAD    , do_set      , AUTH_WIZARD },
  { "shout"    , POS_RESTING , do_gen_comm , AUTH_NONE },
  { "shake"    , POS_RESTING , do_action   , AUTH_NONE },
  { "shiver"   , POS_RESTING , do_action   , AUTH_NONE },
  { "show"     , POS_DEAD    , do_show     , AUTH_WIZARD },
  { "shrug"    , POS_RESTING , do_action   , AUTH_NONE },
  { "shutdow"  , POS_DEAD    , do_shutdown , AUTH_OWNER },
  { "shutdown" , POS_DEAD    , do_shutdown , AUTH_OWNER },
  { "sigh"     , POS_RESTING , do_action   , AUTH_NONE },
  { "sing"     , POS_RESTING , do_action   , AUTH_NONE },
  { "sip"      , POS_RESTING , do_drink    , AUTH_NONE },
  { "sit"      , POS_RESTING , do_sit      , AUTH_NONE },
  { "skillset" , POS_SLEEPING, do_skillset , AUTH_OWNER },
  { "sleep"    , POS_SLEEPING, do_sleep    , AUTH_NONE },
  { "slap"     , POS_RESTING , do_action   , AUTH_NONE },
  { "slowns"   , POS_DEAD    , do_slowns   , AUTH_OWNER },
  { "smile"    , POS_RESTING , do_action   , AUTH_NONE },
  { "smirk"    , POS_RESTING , do_action   , AUTH_NONE },
  { "snicker"  , POS_RESTING , do_action   , AUTH_NONE },
  { "snap"     , POS_RESTING , do_action   , AUTH_NONE },
  { "snarl"    , POS_RESTING , do_action   , AUTH_NONE },
  { "sneeze"   , POS_RESTING , do_action   , AUTH_NONE },
  { "sneak"    , POS_STANDING, do_sneak    , AUTH_PLAYER },
  { "sniff"    , POS_RESTING , do_action   , AUTH_NONE },
  { "snore"    , POS_SLEEPING, do_action   , AUTH_NONE },
  { "snowball" , POS_STANDING, do_action   , AUTH_WIZARD },
  { "snoop"    , POS_DEAD    , do_snoop    , AUTH_WIZARD },
  { "snuggle"  , POS_RESTING , do_action   , AUTH_NONE },
  { "socials"  , POS_DEAD    , do_commands , AUTH_NONE },
  { "split"    , POS_SITTING , do_split    , AUTH_PLAYER },
  { "spank"    , POS_RESTING , do_action   , AUTH_NONE },
  { "spit"     , POS_STANDING, do_action   , AUTH_NONE },
  { "squeeze"  , POS_RESTING , do_action   , AUTH_NONE },
  { "stand"    , POS_RESTING , do_stand    , AUTH_NONE },
  { "stare"    , POS_RESTING , do_action   , AUTH_NONE },
  { "stat"     , POS_DEAD    , do_stat     , AUTH_WIZARD },
  { "steal"    , POS_STANDING, do_steal    , AUTH_PLAYER },
  { "steam"    , POS_RESTING , do_action   , AUTH_NONE },
  { "stroke"   , POS_RESTING , do_action   , AUTH_NONE },
  { "strut"    , POS_STANDING, do_action   , AUTH_NONE },
  { "sulk"     , POS_RESTING , do_action   , AUTH_NONE },
  { "switch"   , POS_DEAD    , do_switch   , AUTH_OWNER },
  { "syslog"   , POS_DEAD    , do_syslog   , AUTH_WIZARD },

  { "tell"     , POS_DEAD    , do_tell     , AUTH_NONE },
  { "tackle"   , POS_RESTING , do_action   , AUTH_NONE },
  { "take"     , POS_RESTING , do_get      , AUTH_NONE },
  { "tango"    , POS_STANDING, do_action   , AUTH_NONE },
  { "taunt"    , POS_RESTING , do_action   , AUTH_NONE },
  { "taste"    , POS_RESTING , do_eat      , AUTH_NONE },
  { "teleport" , POS_DEAD    , do_teleport , AUTH_WIZARD },
  { "thank"    , POS_RESTING , do_action   , AUTH_NONE },
  { "think"    , POS_RESTING , do_action   , AUTH_NONE },
  { "thaw"     , POS_DEAD    , do_wizutil  , AUTH_FREEZE },
  { "title"    , POS_DEAD    , do_title    , AUTH_NONE },
  { "tickle"   , POS_RESTING , do_action   , AUTH_NONE },
  { "time"     , POS_DEAD    , do_time     , AUTH_NONE },
  { "toggle"   , POS_DEAD    , do_toggle   , AUTH_NONE },
  { "track"    , POS_STANDING, do_track    , AUTH_NONE },
  { "trackthru", POS_DEAD    , do_trackthru, AUTH_OWNER },
  { "transfer" , POS_SLEEPING, do_trans    , AUTH_WIZARD },
  { "twiddle"  , POS_RESTING , do_action   , AUTH_NONE },
  { "typo"     , POS_DEAD    , do_gen_write, AUTH_NONE },

  { "unlock"   , POS_SITTING , do_gen_door , AUTH_NONE },
  { "ungroup"  , POS_DEAD    , do_ungroup  , AUTH_NONE },
  { "unban"    , POS_DEAD    , do_unban    , AUTH_OWNER },
  { "unaffect" , POS_DEAD    , do_wizutil  , AUTH_WIZARD },
  { "uptime"   , POS_DEAD    , do_date     , AUTH_WIZARD },
  { "use"      , POS_SITTING , do_use      , AUTH_PLAYER },
  { "users"    , POS_DEAD    , do_users    , AUTH_WIZARD },

  { "value"    , POS_STANDING, do_not_here , AUTH_NONE },
  { "version"  , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "visible"  , POS_RESTING , do_visible  , AUTH_PLAYER },
  { "vnum"     , POS_DEAD    , do_vnum     , AUTH_WIZARD },
  { "vstat"    , POS_DEAD    , do_vstat    , AUTH_WIZARD },

  { "wake"     , POS_SLEEPING, do_wake     , AUTH_NONE },
  { "wave"     , POS_RESTING , do_action   , AUTH_NONE },
  { "wear"     , POS_RESTING , do_wear     , AUTH_NONE },
  { "weather"  , POS_RESTING , do_weather  , AUTH_NONE },
  { "who"      , POS_DEAD    , do_who      , AUTH_NONE },
  { "whoami"   , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "where"    , POS_RESTING , do_where    , AUTH_PLAYER },
  { "whisper"  , POS_RESTING , do_spec_comm, AUTH_NONE },
  { "whine"    , POS_RESTING , do_action   , AUTH_NONE },
  { "whistle"  , POS_RESTING , do_action   , AUTH_NONE },
  { "wield"    , POS_RESTING , do_wield    , AUTH_NONE },
  { "wiggle"   , POS_STANDING, do_action   , AUTH_NONE },
  { "wimpy"    , POS_DEAD    , do_wimpy    , AUTH_NONE },
  { "wink"     , POS_RESTING , do_action   , AUTH_NONE },
  { "withdraw" , POS_STANDING, do_not_here , AUTH_PLAYER },
  { "wiznet"   , POS_DEAD    , do_wiznet   , AUTH_WIZARD },
  { ";"        , POS_DEAD    , do_wiznet   , AUTH_WIZARD },
  { "wizhelp"  , POS_SLEEPING, do_commands , AUTH_WIZARD },
  { "wizlist"  , POS_DEAD    , do_gen_ps   , AUTH_NONE },
  { "wizlock"  , POS_DEAD    , do_wizlock  , AUTH_OWNER },
  { "worship"  , POS_RESTING , do_action   , AUTH_NONE },
  { "write"    , POS_STANDING, do_write    , AUTH_GUEST },

  { "yawn"     , POS_RESTING , do_action   , AUTH_NONE },
  { "yodel"    , POS_RESTING , do_action   , AUTH_NONE },

  { "zreset"   , POS_DEAD    , do_zreset   , AUTH_OWNER },

  { "\n", 0, 0, 0 } /* this must be last */
};

/**
 * Interprets one command from a character.
 * @param ch the character for whom the command is executed
 * @param argument the command line to be interpreted as a command
 * @return none
 */
void command_interpreter(charData_t *ch, char *argument) {
  int length;
  char *line;
  char arg[MAX_INPUT_LENGTH];
  const commandData_t *cmd = NULL;

  REMOVE_BIT(AFF_FLAGS(ch), AFF_HIDE);

  /* just drop to next line for hitting CR */
  skip_spaces(&argument);
  if (!*argument)
    return;

  /*
   * special case to handle one-character, non-alphanumeric commands;
   * requested by many people so "'hi" or ";godnet test" is possible.
   * Patch sent by Eric Green and Stefan Wasilewski.
   */
  if (!isalpha(*argument)) {
    arg[0] = argument[0];
    arg[1] = '\0';
    line = argument + 1;
  } else
    line = any_one_arg(argument, arg);

  /* otherwise, find the command */
  for (length = strlen(arg), cmd = cmd_info; *(cmd->command) != '\n'; cmd++)
    if (!strncmp(cmd->command, arg, length))
      if (GET_AUTH(ch) >= cmd->minimum_auth)
        break;

  if (strcmp(cmd->command, "\n") == 0)
    send_to_char(ch, "Huh?!?\r\n");
  else if (!IS_NPC(ch) && PLR_FLAGGED(ch, PLR_FROZEN) && GET_AUTH(ch) < AUTH_OWNER)
    send_to_char(ch, "You try, but the mind-numbing cold prevents you...\r\n");
  else if (cmd->command_pointer == NULL)
    send_to_char(ch, "Sorry, that command hasn't been implemented yet.\r\n");
  else if (IS_NPC(ch) && cmd->minimum_auth >= AUTH_WIZARD)
    send_to_char(ch, "You can't use immortal commands while switched.\r\n");
  else if (GET_POS(ch) < cmd->minimum_position)
    switch (GET_POS(ch)) {
    case POS_DEAD:
      send_to_char(ch, "Lie still; you are DEAD!!! :-(\r\n");
      break;
    case POS_INCAP:
    case POS_MORTALLYW:
      send_to_char(ch, "You are in a pretty bad shape, unable to do anything!\r\n");
      break;
    case POS_STUNNED:
      send_to_char(ch, "All you can do right now is think about the stars!\r\n");
      break;
    case POS_SLEEPING:
      send_to_char(ch, "In your dreams, or what?\r\n");
      break;
    case POS_RESTING:
      send_to_char(ch, "Nah... You feel too relaxed to do that..\r\n");
      break;
    case POS_SITTING:
      send_to_char(ch, "Maybe you should get on your feet first?\r\n");
      break;
    case POS_FIGHTING:
      send_to_char(ch, "No way!  You're fighting for your life!\r\n");
      break;
  } else if (no_specials || !special(ch, cmd, line)) {
    cmd->command_pointer(ch, line, cmd);
  }
}

/**
 * Searches for a command.
 * @param command the cannonical name of the command
 * @return the command, or NULL if the command cannot be found
 */
const commandData_t *find_command(const char *command) {
  /* Declare an iterator variable. */
  register ssize_t cmd = 0;

  /* Iterate over the master command table. */
  for (cmd = 0; strcmp(cmd_info[cmd].command, "\n") != 0; cmd++) {
    /* Test whether the current command is the one we're seeking. */
    if (strcasecmp(cmd_info[cmd].command, command) == 0) {
      return &(cmd_info[cmd]);
    }
  }
  return (NULL);
}


/**
 * The SAVECOMMANDS command.
 * @param ch the character performing the command
 * @param argument the additional text passed after the command
 * @param cmd the command object that was performed
 * @returns none
 */
ACMD(do_savecommands) {
  /* Create the document DAO. */
  daoData_t *rootDao = dao_newDocument();
  /* Create the "Commands" container DAO. */
  daoData_t *commandsDao = dao_newChild(rootDao, "Commands");
  /* Declare an iterator variable. */
  register int i = 0;
  /* Iterate over the command table. */
  for (i = 0; strcmp(cmd_info[i].command, "\n") != 0; i++) {
    /* Declare a temporary string buffer. */
    char buf[MAX_STRING_LENGTH];
    /* Create the "Command#" container DAO. */
    daoData_t *commandDao = dao_newChild(commandsDao, "%d", i);
    /* Look up the corresponding social. */
    socialData_t *social = find_action(cmd_info + i);
    /* Only write non-NULL functions to the DAO. */
    if (cmd_info[i].command_pointer != NULL) {
      /* Declare an iterator variable. */
      register int j = 0;
      /* Iterate over the ACMD function table. */
      for (j = 0; strcmp(acmd_registry[j].name, "\n") != 0; j++) {
        /* Determine if this is the ACMD we're searching for. */
        if (acmd_registry[j].function == cmd_info[i].command_pointer)
          break;
      }
      /* Only write the function name if one was actually found. */
      if (strcmp(acmd_registry[j].name, "\n") != 0) {
        /* Create the "Function" scalar DAO. */
        dao_newScalar(commandDao, "Function", "%s", acmd_registry[j].name);
      }
    }
    /* Print the minimum auth value to the temporary buffer. */
    sprinttype(cmd_info[i].minimum_auth, auth_types, buf, sizeof(buf));
    /* Create the "MinimumAuth" scalar DAO. */
    dao_newScalar(commandDao, "MinimumAuth", "%s", buf);
    /* Print the minimum position value to the temporary buffer. */
    sprinttype(cmd_info[i].minimum_position, position_types, buf, sizeof(buf));
    /* Create the "MinimumPosition" scalar DAO. */
    dao_newScalar(commandDao, "MinimumPosition", "%s", buf);
    /* Create the "Name" scalar DAO. */
    dao_newScalar(commandDao, "Name", cmd_info[i].command);
    /* Only write social information if its available. */
    if (social) {
      /* Create the "Social" container DAO. */
      daoData_t *socialDao = dao_newChild(commandDao, "Social");
      /* Create the "Hidden" scalar DAO. */
      dao_newScalar(socialDao, "Hidden", "%s", YESNO(social->hide));
    }
  }
  /* Save the commands DAO out to disk. */
  dao_saveFile(rootDao, COMMANDS_FILE);
  /* Free the root DAO. */
  dao_free(rootDao);
}