PennMUSH Community

root/1.8.3/trunk/src/command.c

Revision 1278, 66.6 kB (checked in by shawnw, 2 months ago)

Prep for 1.8.3p7

Line 
1 /**
2  * \file command.c
3  *
4  * \brief Parsing of commands.
5  *
6  * Sets up a hash table for the commands, and parses input for commands.
7  * This implementation is almost totally by Thorvald Natvig, with
8  * various mods by Javelin and others over time.
9  *
10  */
11
12 #include "copyrite.h"
13 #include "config.h"
14
15 #include <string.h>
16 #include <assert.h>
17 #include <stdlib.h>
18
19 #include "conf.h"
20 #include "externs.h"
21 #include "dbdefs.h"
22 #include "mushdb.h"
23 #include "game.h"
24 #include "match.h"
25 #include "attrib.h"
26 #include "extmail.h"
27 #include "parse.h"
28 #include "access.h"
29 #include "version.h"
30 #include "ptab.h"
31 #include "htab.h"
32 #include "strtree.h"
33 #include "function.h"
34 #include "command.h"
35 #include "mymalloc.h"
36 #include "flags.h"
37 #include "log.h"
38 #include "sort.h"
39 #include "cmds.h"
40 #include "confmagic.h"
41
42 PTAB ptab_command;      /**< Prefix table for command names. */
43 PTAB ptab_command_perms;        /**< Prefix table for command permissions */
44
45 HASHTAB htab_reserved_aliases;  /**< Hash table for reserved command aliases */
46
47 slab *command_slab = NULL; /**< slab for command_info structs */
48
49 static const char *command_isattr(char *command);
50 static int command_check(dbref player, COMMAND_INFO *cmd);
51 static int switch_find(COMMAND_INFO *cmd, const char *sw);
52 static void strccat(char *buff, char **bp, const char *from);
53 static int has_hook(struct hook_data *hook);
54 extern int global_fun_invocations;       /**< Counter for function invocations */
55 extern int global_fun_recursions;       /**< Counter for function recursion */
56
57 SWITCH_VALUE *dyn_switch_list = NULL;
58 int switch_bytes = 0;
59 size_t num_switches = 0;
60
61 enum command_load_state { CMD_LOAD_BUILTIN,
62   CMD_LOAD_LOCAL,
63   CMD_LOAD_DONE
64 };
65 static enum command_load_state command_state = CMD_LOAD_BUILTIN;
66 static StrTree switch_names;
67
68 int run_hook(dbref player, dbref cause, struct hook_data *hook,
69              char *saveregs[], int save);
70
71 int run_hook_override(COMMAND_INFO *cmd, dbref player, const char *commandraw);
72
73
74 /** The list of standard commands. Additional commands can be added
75  * at runtime with add_command().
76  */
77 COMLIST commands[] = {
78
79   {"@COMMAND",
80    "ADD ALIAS DELETE EQSPLIT LSARGS RSARGS NOEVAL ON OFF QUIET ENABLE DISABLE RESTRICT NOPARSE",
81    cmd_command,
82    CMD_T_PLAYER | CMD_T_EQSPLIT, 0, 0},
83   {"@@", NULL, cmd_null, CMD_T_ANY | CMD_T_NOPARSE, 0, 0},
84   {"@ALLHALT", NULL, cmd_allhalt, CMD_T_ANY, "WIZARD", "HALT"},
85   {"@ALLQUOTA", "QUIET", cmd_allquota, CMD_T_ANY, "WIZARD", "QUOTA"},
86   {"@ASSERT", NULL, cmd_assert, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE, 0,
87    0},
88   {"@ATRLOCK", NULL, cmd_atrlock, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
89   {"@ATRCHOWN", NULL, cmd_atrchown, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
90
91   {"@ATTRIBUTE", "ACCESS DELETE RENAME RETROACTIVE", cmd_attribute,
92    CMD_T_ANY | CMD_T_EQSPLIT, "WIZARD", 0},
93   {"@BOOT", "PORT ME SILENT", cmd_boot, CMD_T_ANY, 0, 0},
94   {"@BREAK", NULL, cmd_break, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE, 0,
95    0},
96   {"@CEMIT", "NOEVAL NOISY SILENT SPOOF", cmd_cemit,
97    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
98   {"@CHANNEL",
99    "LIST ADD DELETE RENAME NAME PRIVS QUIET NOISY DECOMPILE DESCRIBE CHOWN WIPE MUTE UNMUTE GAG UNGAG HIDE UNHIDE WHAT TITLE BRIEF RECALL BUFFER SET",
100    cmd_channel,
101    CMD_T_ANY | CMD_T_SWITCHES | CMD_T_EQSPLIT | CMD_T_NOGAGGED | CMD_T_RS_ARGS,
102    0, 0},
103   {"@CHAT", NULL, cmd_chat, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
104   {"@CHOWNALL", "PRESERVE", cmd_chownall, CMD_T_ANY | CMD_T_EQSPLIT, "WIZARD",
105    0},
106
107   {"@CHOWN", "PRESERVE", cmd_chown,
108    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
109   {"@CHZONEALL", NULL, cmd_chzoneall, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
110
111   {"@CHZONE", NULL, cmd_chzone,
112    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
113   {"@CONFIG",
114    "SET LOWERCASE LIST GLOBALS DEFAULTS COSTS FLAGS FUNCTIONS COMMANDS ATTRIBS",
115    cmd_config, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
116   {"@CPATTR", "CONVERT NOFLAGCOPY", cmd_cpattr,
117    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS,
118    0, 0},
119   {"@CREATE", NULL, cmd_create, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
120    0, 0},
121   {"@CLONE", "PRESERVE", cmd_clone, CMD_T_ANY | CMD_T_NOGAGGED | CMD_T_EQSPLIT,
122    0, 0},
123
124   {"@CLOCK", "JOIN SPEAK MOD SEE HIDE", cmd_clock,
125    CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
126   {"@DBCK", NULL, cmd_dbck, CMD_T_ANY, "WIZARD", 0},
127
128   {"@DECOMPILE", "DB PREFIX TF FLAGS ATTRIBS SKIPDEFAULTS", cmd_decompile,
129    CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
130   {"@DESTROY", "OVERRIDE", cmd_destroy, CMD_T_ANY, 0, 0},
131
132   {"@DIG", "TELEPORT", cmd_dig,
133    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
134   {"@DISABLE", NULL, cmd_disable, CMD_T_ANY, "WIZARD", 0},
135
136   {"@DOING", "HEADER", cmd_doing,
137    CMD_T_ANY | CMD_T_NOPARSE | CMD_T_NOGAGGED, 0, 0},
138   {"@DOLIST", "NOTIFY DELIMIT", cmd_dolist,
139    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE, 0, 0},
140   {"@DRAIN", "ALL ANY", cmd_notify_drain, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
141   {"@DUMP", "PARANOID DEBUG", cmd_dump, CMD_T_ANY, "WIZARD", 0},
142
143   {"@EDIT", "FIRST CHECK", cmd_edit,
144    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_RS_NOPARSE |
145    CMD_T_NOGAGGED, 0, 0},
146   {"@ELOCK", NULL, cmd_elock, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
147    0, 0},
148   {"@EMIT", "ROOM NOEVAL SILENT SPOOF", cmd_emit, CMD_T_ANY | CMD_T_NOGAGGED, 0,
149    0},
150   {"@ENABLE", NULL, cmd_enable, CMD_T_ANY | CMD_T_NOGAGGED, "WIZARD", 0},
151
152   {"@ENTRANCES", "EXITS THINGS PLAYERS ROOMS", cmd_entrances,
153    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
154   {"@EUNLOCK", NULL, cmd_eunlock, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
155
156   {"@FIND", NULL, cmd_find,
157    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
158   {"@FIRSTEXIT", NULL, cmd_firstexit, CMD_T_ANY, 0, 0},
159   {"@FLAG", "ADD TYPE LETTER LIST RESTRICT DELETE ALIAS DISABLE ENABLE",
160    cmd_flag,
161    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
162
163   {"@FORCE", "NOEVAL", cmd_force, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
164    0, 0},
165   {"@FUNCTION", "BUILTIN DELETE ENABLE DISABLE PRESERVE RESTORE RESTRICT",
166    cmd_function,
167    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
168   {"@GREP", "LIST PRINT ILIST IPRINT", cmd_grep,
169    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE | CMD_T_NOGAGGED, 0, 0},
170   {"@HALT", "ALL PID", cmd_halt, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
171   {"@HIDE", "NO OFF YES ON", cmd_hide, CMD_T_ANY, 0, 0},
172   {"@HOOK", "LIST AFTER BEFORE IGNORE OVERRIDE", cmd_hook,
173    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS,
174    "WIZARD", "hook"},
175   {"@KICK", NULL, cmd_kick, CMD_T_ANY, "WIZARD", 0},
176
177   {"@LEMIT", "NOEVAL SILENT SPOOF", cmd_lemit,
178    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
179   {"@LINK", "PRESERVE", cmd_link, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0,
180    0},
181   {"@LISTMOTD", NULL, cmd_listmotd, CMD_T_ANY, 0, 0},
182
183   {"@LIST", "LOWERCASE MOTD LOCKS FLAGS FUNCTIONS POWERS COMMANDS ATTRIBS",
184    cmd_list,
185    CMD_T_ANY, 0, 0},
186   {"@LOCK", NULL, cmd_lock,
187    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_SWITCHES | CMD_T_NOGAGGED, 0, 0},
188   {"@LOG", "CHECK CMD CONN ERR TRACE WIZ", cmd_log,
189    CMD_T_ANY | CMD_T_NOGAGGED, "WIZARD", 0},
190   {"@LOGWIPE", "CHECK CMD CONN ERR TRACE WIZ", cmd_logwipe,
191    CMD_T_ANY | CMD_T_NOGAGGED | CMD_T_GOD, 0, 0},
192   {"@LSET", NULL, cmd_lset,
193    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
194   {"@MAIL",
195    "NOEVAL NOSIG STATS DSTATS FSTATS DEBUG NUKE FOLDERS UNFOLDER LIST READ CLEAR UNCLEAR PURGE FILE TAG UNTAG FWD FORWARD SEND SILENT URGENT",
196    cmd_mail, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
197
198   {"@MALIAS",
199    "SET CREATE DESTROY DESCRIBE RENAME STATS CHOWN NUKE ADD REMOVE LIST ALL WHO MEMBERS USEFLAG SEEFLAG",
200    cmd_malias, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
201
202   {"@MAP", "DELIMIT", cmd_map, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE,
203    0, 0},
204   {"@MESSAGE", "NOEVAL SPOOF", cmd_message,
205    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, 0, 0},
206   {"@MOTD", "CONNECT LIST WIZARD DOWN FULL", cmd_motd,
207    CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
208   {"@MVATTR", "CONVERT NOFLAGCOPY", cmd_mvattr,
209    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS,
210    0, 0},
211   {"@NAME", NULL, cmd_name, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED
212    | CMD_T_NOGUEST, 0, 0},
213   {"@NEWPASSWORD", NULL, cmd_newpassword, CMD_T_ANY | CMD_T_EQSPLIT
214    | CMD_T_RS_NOPARSE, "WIZARD", 0},
215   {"@NOTIFY", "ALL ANY", cmd_notify_drain, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
216   {"@NSCEMIT", "NOEVAL NOISY SPOOF", cmd_cemit,
217    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, "WIZARD", "CAN_NSPEMIT"},
218   {"@NSEMIT", "ROOM NOEVAL SILENT SPOOF", cmd_emit, CMD_T_ANY | CMD_T_NOGAGGED,
219    "WIZARD", "CAN_NSPEMIT"},
220   {"@NSLEMIT", "NOEVAL SILENT SPOOF", cmd_lemit,
221    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, "WIZARD", "CAN_NSPEMIT"},
222   {"@NSOEMIT", "NOEVAL SPOOF", cmd_oemit,
223    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, "WIZARD", "CAN_NSPEMIT"},
224   {"@NSPEMIT", "LIST SILENT NOISY NOEVAL", cmd_pemit,
225    CMD_T_ANY | CMD_T_EQSPLIT, "WIZARD", "CAN_NSPEMIT"},
226   {"@NSPROMPT", "SILENT NOISY NOEVAL", cmd_prompt,
227    CMD_T_ANY | CMD_T_EQSPLIT, "WIZARD", "CAN_NSPEMIT"},
228   {"@NSREMIT", "LIST NOEVAL NOISY SILENT SPOOF", cmd_remit,
229    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, "WIZARD", "CAN_NSPEMIT"},
230   {"@NSZEMIT", NULL, cmd_zemit, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
231    "WIZARD", "CAN_NSPEMIT"},
232   {"@NUKE", NULL, cmd_nuke, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
233
234   {"@OEMIT", "NOEVAL SPOOF", cmd_oemit,
235    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
236   {"@OPEN", NULL, cmd_open,
237    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
238   {"@PARENT", NULL, cmd_parent, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
239   {"@PASSWORD", NULL, cmd_password, CMD_T_PLAYER | CMD_T_EQSPLIT
240    | CMD_T_NOPARSE | CMD_T_RS_NOPARSE | CMD_T_NOGUEST, 0, 0},
241   {"@PCREATE", NULL, cmd_pcreate, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
242
243   {"@PEMIT", "LIST CONTENTS SILENT NOISY NOEVAL SPOOF", cmd_pemit,
244    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
245   {"@POLL", "CLEAR", cmd_poll, CMD_T_ANY, 0, 0},
246   {"@POOR", NULL, cmd_poor, CMD_T_ANY, 0, 0},
247   {"@POWER", "ADD TYPE LETTER LIST RESTRICT DELETE ALIAS DISABLE ENABLE",
248    cmd_power, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, 0, 0},
249   {"@PROMPT", "SILENT NOISY NOEVAL SPOOF", cmd_prompt,
250    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
251   {"@PS", "ALL SUMMARY COUNT QUICK", cmd_ps, CMD_T_ANY, 0, 0},
252   {"@PURGE", NULL, cmd_purge, CMD_T_ANY, 0, 0},
253   {"@QUOTA", "ALL SET", cmd_quota, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
254   {"@READCACHE", NULL, cmd_readcache, CMD_T_ANY, "WIZARD", 0},
255   {"@RECYCLE", "OVERRIDE", cmd_destroy, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
256
257   {"@REMIT", "LIST NOEVAL NOISY SILENT SPOOF", cmd_remit,
258    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
259   {"@REJECTMOTD", NULL, cmd_rejectmotd, CMD_T_ANY, "WIZARD", 0},
260   {"@RESTART", "ALL", cmd_restart, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
261   {"@RWALL", "NOEVAL EMIT", cmd_rwall, CMD_T_ANY, "WIZARD ROYALTY", 0},
262   {"@SCAN", "ROOM SELF ZONE GLOBALS", cmd_scan,
263    CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
264   {"@SEARCH", NULL, cmd_search,
265    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_RS_NOPARSE, 0, 0},
266   {"@SELECT", "NOTIFY REGEXP", cmd_select,
267    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_RS_NOPARSE, 0, 0},
268   {"@SET", NULL, cmd_set, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
269   {"@SHUTDOWN", "PANIC REBOOT PARANOID", cmd_shutdown, CMD_T_ANY, "WIZARD", 0},
270 #if defined(HAVE_MYSQL) || defined(HAVE_POSTGRESQL) || defined(HAVE_SQLITE3)
271   {"@SQL", NULL, cmd_sql, CMD_T_ANY, "WIZARD", "SQL_OK"},
272 #else
273   {"@SQL", NULL, cmd_unimplemented, CMD_T_ANY, "WIZARD", "SQL_OK"},
274 #endif
275   {"@SITELOCK", "BAN CHECK REGISTER REMOVE NAME", cmd_sitelock,
276    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, "WIZARD", 0},
277   {"@STATS", "CHUNKS FREESPACE PAGING REGIONS TABLES", cmd_stats,
278    CMD_T_ANY, 0, 0},
279
280   {"@SWEEP", "CONNECTED HERE INVENTORY EXITS", cmd_sweep, CMD_T_ANY, 0, 0},
281   {"@SWITCH", "NOTIFY FIRST ALL REGEXP", cmd_switch,
282    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_RS_NOPARSE |
283    CMD_T_NOGAGGED, 0, 0},
284   {"@SQUOTA", NULL, cmd_squota, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
285
286   {"@TELEPORT", "SILENT INSIDE", cmd_teleport,
287    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
288   {"@TRIGGER", NULL, cmd_trigger,
289    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS | CMD_T_NOGAGGED, 0, 0},
290   {"@ULOCK", NULL, cmd_ulock, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
291    0, 0},
292   {"@UNDESTROY", NULL, cmd_undestroy, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
293   {"@UNLINK", NULL, cmd_unlink, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
294
295   {"@UNLOCK", NULL, cmd_unlock,
296    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_SWITCHES | CMD_T_NOGAGGED, 0, 0},
297   {"@UNRECYCLE", NULL, cmd_undestroy, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
298   {"@UPTIME", "MORTAL", cmd_uptime, CMD_T_ANY, 0, 0},
299   {"@UUNLOCK", NULL, cmd_uunlock, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
300   {"@VERB", NULL, cmd_verb, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_ARGS, 0, 0},
301   {"@VERSION", NULL, cmd_version, CMD_T_ANY, 0, 0},
302   {"@WAIT", "PID UNTIL", cmd_wait, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_RS_NOPARSE,
303    0, 0},
304   {"@WALL", "NOEVAL EMIT", cmd_wall, CMD_T_ANY, "WIZARD ROYALTY", "ANNOUNCE"},
305
306   {"@WARNINGS", NULL, cmd_warnings, CMD_T_ANY | CMD_T_EQSPLIT, 0, 0},
307   {"@WCHECK", "ALL ME", cmd_wcheck, CMD_T_ANY, 0, 0},
308   {"@WHEREIS", NULL, cmd_whereis, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
309   {"@WIPE", NULL, cmd_wipe, CMD_T_ANY, 0, 0},
310   {"@WIZWALL", "NOEVAL EMIT", cmd_wizwall, CMD_T_ANY, "WIZARD", 0},
311   {"@WIZMOTD", NULL, cmd_wizmotd, CMD_T_ANY, "WIZARD", 0},
312   {"@ZEMIT", NULL, cmd_zemit, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED,
313    0, 0},
314
315   {"BUY", NULL, cmd_buy, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
316   {"BRIEF", NULL, cmd_brief, CMD_T_ANY, 0, 0},
317   {"DESERT", NULL, cmd_desert, CMD_T_PLAYER | CMD_T_THING, 0, 0},
318   {"DISMISS", NULL, cmd_dismiss, CMD_T_PLAYER | CMD_T_THING, 0, 0},
319   {"DROP", NULL, cmd_drop, CMD_T_PLAYER | CMD_T_THING, 0, 0},
320   {"EXAMINE", "ALL BRIEF DEBUG MORTAL PARENT", cmd_examine, CMD_T_ANY, 0, 0},
321   {"EMPTY", NULL, cmd_empty, CMD_T_PLAYER | CMD_T_THING | CMD_T_NOGAGGED, 0, 0},
322   {"ENTER", NULL, cmd_enter, CMD_T_ANY, 0, 0},
323
324   {"FOLLOW", NULL, cmd_follow,
325    CMD_T_PLAYER | CMD_T_THING | CMD_T_NOGAGGED, 0, 0},
326
327   {"GET", NULL, cmd_get, CMD_T_PLAYER | CMD_T_THING | CMD_T_NOGAGGED, 0, 0},
328   {"GIVE", "SILENT", cmd_give, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0,
329    0},
330   {"GOTO", NULL, cmd_goto, CMD_T_PLAYER | CMD_T_THING, 0, 0},
331   {"HOME", NULL, cmd_home, CMD_T_PLAYER | CMD_T_THING, 0, 0},
332   {"INVENTORY", NULL, cmd_inventory, CMD_T_ANY, 0, 0},
333
334   {"KILL", NULL, cmd_kill, CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
335   {"LOOK", "OUTSIDE", cmd_look, CMD_T_ANY, 0, 0},
336   {"LEAVE", NULL, cmd_leave, CMD_T_PLAYER | CMD_T_THING, 0, 0},
337
338   {"PAGE", "BLIND NOEVAL LIST PORT OVERRIDE", cmd_page,
339    CMD_T_ANY | CMD_T_RS_NOPARSE | CMD_T_NOPARSE | CMD_T_EQSPLIT |
340    CMD_T_NOGAGGED, 0, 0},
341   {"POSE", "NOEVAL NOSPACE", cmd_pose, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
342   {"SCORE", NULL, cmd_score, CMD_T_ANY, 0, 0},
343   {"SAY", "NOEVAL", cmd_say, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
344   {"SEMIPOSE", "NOEVAL", cmd_semipose, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
345   {"SLAY", NULL, cmd_slay, CMD_T_ANY, 0, 0},
346
347   {"TAKE", NULL, cmd_take, CMD_T_PLAYER | CMD_T_THING | CMD_T_NOGAGGED,
348    0, 0},
349   {"TEACH", NULL, cmd_teach, CMD_T_ANY | CMD_T_NOPARSE, 0, 0},
350   {"THINK", "NOEVAL", cmd_think, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
351
352   {"UNFOLLOW", NULL, cmd_unfollow,
353    CMD_T_PLAYER | CMD_T_THING | CMD_T_NOGAGGED, 0, 0},
354   {"USE", NULL, cmd_use, CMD_T_ANY | CMD_T_NOGAGGED, 0, 0},
355
356   {"WHISPER", "LIST NOISY SILENT NOEVAL", cmd_whisper,
357    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED, 0, 0},
358   {"WITH", "NOEVAL ROOM", cmd_with, CMD_T_PLAYER | CMD_T_THING | CMD_T_EQSPLIT,
359    0, 0},
360
361 /* ATTRIB_SET is an undocumented command - it's sugar to make it possible
362  * enable/disable attribute setting with &XX or @XX
363  */
364   {"ATTRIB_SET", NULL, command_atrset,
365    CMD_T_ANY | CMD_T_EQSPLIT | CMD_T_NOGAGGED | CMD_T_INTERNAL, 0, 0},
366
367 /* A way to stop people starting commands with functions */
368   {"WARN_ON_MISSING", NULL, cmd_warn_on_missing,
369    CMD_T_ANY | CMD_T_NOPARSE | CMD_T_INTERNAL, 0, 0},
370
371 /* A way to let people override the Huh? message */
372   {"HUH_COMMAND", NULL, cmd_huh_command,