/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ #ifndef lint static char RCSid[] = "$Header: /home/mjr/hacks/umud/RCS/cmd.c,v 1.8 91/10/22 11:29:33 mjr Exp $"; #endif /* configure all options BEFORE including system stuff. */ #include "config.h" #ifndef VMS #include <sys/param.h> #endif #include "mud.h" #include "cmd.h" #include "vars.h" /* standard commands */ extern int cmd_build(); extern int cmd_do(); extern int cmd_drop(); extern int cmd_go(); extern int cmd_help(); /* in cmd.c (this file) */ extern int cmd__if(); extern int cmd_inv(); extern int cmd_look(); extern int cmd_NEWS(); extern int cmd_QUIT(); extern int cmd_WHO(); /* in tcpio.c (net-specific) */ extern int cmd_page(); extern int cmd_password(); extern int cmd__password(); /* wiz-only */ extern int cmd__rand(); extern int cmd_read(); extern int cmd_say(); extern int cmd_set(); /* in vars.c */ extern int cmd_unset(); /* in vars.c */ extern int cmd_take(); extern int cmd_telep(); extern int cmd_use(); extern int cmd__wall(); extern int cmd_which(); extern int cmd_whisper(); extern int cmd_destroy(); extern int cmd_examine(); /* wiz internal debug functions */ extern int cmd__dump(); extern int cmd__echo(); extern int cmd__force(); extern int cmd__cacheconfig(); /* in cache.c */ #ifdef COMMAND_STATS extern int cmd__cmdstats(); /* in run.c */ #endif extern int cmd__wizard(); #ifdef CMD_LOWLEVEL_LIST extern int cmd__ladd(); extern int cmd__ldel(); #endif extern int cmd__mark(); extern int cmd__cronconfig(); /* in cron.c */ extern int cmd__mudconfig(); /* in mud.c */ extern int cmd__netconfig(); /* in tcpio.c or whatever net module */ #ifdef CMD_LOWLEVEL_SET extern int cmd__set(); extern int cmd__unset(); #endif /* MASTER command table. THIS IS SEARCHED LINEARLY, WHICH IS WHY YOU SHOULD MAKE SURE THAT MOST FREQENTLY USED COMMANDS ARE NEAREST TO THE TOP OF THE TABLE. (linear search is faster in the case of a MUD than a binary search, since we can predict that 90% of ops will fall between emote/say) */ static Cmd ctab[] = { { /* blather something in a TinyMUD-like manner */ "say", 1, CM_EXACT, cmd_say, "say \"string\"" }, { /* emote command - TinyMUD-like emote (do and emote are aliases) */ "do", 1, CM_EXACT, cmd_do, "do \"string\"" }, { /* look around */ "look", 1, CM_NOFLG, cmd_look, "look [thing1] ..." }, { /* go */ "go", 2, CM_FIXARG|CM_EXACT, cmd_go, "go place" }, { /* whisper */ "whisper", 3, CM_FIXARG, cmd_whisper, "whisper player message" }, { /* page */ "page", 2, CM_NOFLG, cmd_page, "page player [message]" }, { /* echo back to user */ "_echo", 2, CM_NOFLG, cmd__echo, "_echo text" }, { /* inventory */ "inventory", 1, CM_NOFLG, cmd_inv, "inventory [thing] ..." }, { /* take */ "take", 2, CM_NOFLG, cmd_take, "take thing [thing2] ..." }, { /* read text off of something */ "read", 2, CM_FIXARG, cmd_read, "read [thing] ..." }, { /* get - an alias for take */ "get", 2, CM_EXACT, cmd_take, "get thing [thing2] ..." }, { /* drop */ "drop", 2, CM_NOFLG, cmd_drop, "drop thing [thing2] ..." }, { /* examine object(s) */ "examine", 1, CM_NOFLG, cmd_examine, "examine [thing1] ..." }, { "set", 2, CM_EXACT, cmd_set, "set thing [type] attribute value (or \"set help\" for help)" }, { "unset", 3, CM_FIXARG, cmd_unset, "unset thing attribute" }, { /* hold */ "hold", 1, CM_EXACT, cmd_use, "hold thing (or nothing to stop holding current object)" }, { /* use */ "use", 1, CM_EXACT, cmd_use, "use thing (or nothing to stop using current object)" }, { /* create a new ?? */ #ifdef BUILD_WIZ_ONLY "build", 2, CM_PRIV, cmd_build, #else "build", 2, CM_NOFLG, cmd_build, #endif "build object-type [object-specific options] (or \"build help\")" }, { /* create a new (alias for build)?? */ #ifdef BUILD_WIZ_ONLY "create", 2, CM_PRIV, cmd_build, #else "create", 2, CM_NOFLG, cmd_build, #endif "create object-type [object-specific options] (or \"create help\")" }, { /* create a new (alias for build)?? */ #ifdef BUILD_WIZ_ONLY "create", 2, CM_PRIV, cmd_build, #else "create", 2, CM_NOFLG, cmd_build, #endif "create object-type [object-specific options] (or \"create help\")" }, { /* which */ "which", 2, CM_NOFLG, cmd_which, "which [object-type] thing-to-match" }, { /* randomly pick a command */ "_rand", 2, CM_NOFLG, cmd__rand, "_rand [cmd1] [cmd2] [...cmdN]" }, { /* conditional (of sorts) */ "_if", 2, CM_NOFLG, cmd__if, "_if boolean-expression cmd [\"else\" cmd]" }, { /* teleport */ "teleport", 3, CM_FIXARG, cmd_telep, "teleport [thing] [destination]" }, { /* destroy an object ; command name must match exactly */ #ifdef BUILD_WIZ_ONLY "destroy", 2, CM_EXACT|CM_PRIV, cmd_destroy, #else "destroy", 2, CM_EXACT, cmd_destroy, #endif "destroy object-type object (or \"destroy help\")" }, { /* NEWS */ "NEWS", 1, CM_NOFLG, cmd_NEWS, "NEWS [action] [article] (or \"NEWS help\")" }, { /* QUIT command */ "QUIT", 1, CM_EXACT|CM_NOWHERE, cmd_QUIT, "QUIT" }, { /* WHO command */ "WHO", 1, CM_NOWHERE, cmd_WHO, "WHO [who] ..." }, { /* dump command list/summary */ "help", 1, CM_NOWHERE, cmd_help, "help [cmd] ..." }, { /* dump object to controlling terminal in OIF format */ "_dump", 2, CM_NOFLG, cmd__dump, "_dump objid" }, { /* submit a command as someone else */ "_force", 3, CM_PRIV, cmd__force, "_force who command" }, { /* shout */ "_wall", 1, CM_PRIV, cmd__wall, "_wall message" }, { /* set a thing's password */ "password", 3, CM_FIXARG, cmd_password, "password oldpassword newpassword" }, { /* wiz set a thing's password */ "_password", 3, CM_FIXARG|CM_PRIV, cmd__password, "_password thing password" }, { /* cache-specific commands [implementation dependent] */ "_cacheconfig", 2, CM_PRIV, cmd__cacheconfig, "_cacheconfig [options] (or \"_cacheconfig help\")" }, { /* permanent database specific commands [implementation dependent] */ "_dbconfig", 2, CM_PRIV, CMD__DBCONFIG, "_dbconfig [options] (or \"_dbconfig help\")" }, { /* output a text mark for 'bots. echo back first arg with an '@' */ "_mark", 1, CM_NOFLG, cmd__mark, "_mark \"string\"" }, #ifdef CMD_LOWLEVEL_LIST { /* add the object id to the named list in the named object */ "_ladd", 4, CM_PRIV|CM_FIXARG, cmd__ladd, "_ladd object listname objectid " }, { /* drop the object id from the named list in the named object */ "_ldel", 4, CM_PRIV|CM_FIXARG, cmd__ldel, "_ldel object listname objectid " }, #endif { /* mud server specific commands [somewhat implementation dependent] */ "_mudconfig", 2, CM_PRIV|CM_NOWHERE, cmd__mudconfig, "_mudconfig [options] (or \"_mudconfig help\")" }, { /* cron execution specific commands [somewhat implementation dependent] */ "_cronconfig", 2, CM_PRIV|CM_NOWHERE, cmd__cronconfig, "_cronconfig [options] (or \"_cronconfig help\")" }, { /* network layer specific commands [somewhat implementation dependent] */ "_netconfig", 2, CM_PRIV, cmd__netconfig, "_netconfig [options] (or \"_netconfig help\")" }, #ifdef CMD_LOWLEVEL_SET { /* set an attribute directly into an object - VERY LOW LEVEL! */ "_set", 5, CM_PRIV|CM_FIXARG, cmd__set, "_set objid vartype varname \"data\"" }, { /* unset an attribute from an object - VERY LOW LEVEL! */ "_unset", 3, CM_PRIV|CM_FIXARG, cmd__unset, "_unset objid varname" }, #endif { /* wizard management */ "_wizard", 2, CM_NOFLG, cmd__wizard, "_wizard [options] (or \"_wizard help\")" }, #ifdef COMMAND_STATS { /* print command statistics */ "_cmdstats", 1, CM_PRIV, cmd__cmdstats, "_cmdstats" }, #endif /* list terminator */ 0,0,0,0,0 }; Cmd * cmdlookup(s) char *s; { Cmd *p = ctab; int x; x = strlen(s); while(p->name != (char *)0) { if((p->flgs & CM_EXACT) && *s == *p->name && !strcmp(s,p->name)) return(p); if(!(p->flgs & CM_EXACT) && *s == *p->name && !strncmp(s,p->name,x)) return(p); p++; } return(0); } /* ARGSUSED */ cmd_help(argc,argv,who,aswho) int argc; char *argv[]; char *who; char *aswho; { Cmd *p = ctab; int x; int wiz; wiz = ut_flagged(who,var_wiz); if(argc <= 1) { while(p->name != (char *)0) { if(wiz || !(p->flgs & CM_PRIV)) say(who,p->usage,"\n",(char *)0); p++; } return(0); } for(x = 1; x < argc; x++) { char fnuf[MAXPATHLEN]; char *jnk; jnk = argv[x]; while((jnk = index(jnk,'.')) != (char *)0) { if(*(jnk + 1) == '.') { say(who, "nice try: \"",argv[x],"\"\n", (char *)0); return(1); } jnk++; } if (strlen(argv[x]) >= MAXPATHLEN) { say(who, "impossible command: \"",argv[x],"\"\n", (char *)0); continue; } sprintf(fnuf,"HELP/%s",argv[x]); if((p = cmdlookup(argv[x])) != (Cmd *)0) { if(wiz || !(p->flgs & CM_PRIV)) { say(who,"usage: ",p->usage,"\n",(char *)0); } if(say_file(who,fnuf)) say(who,"no help file available.\n",(char *)0); } else { if(say_file(who,fnuf)) say(who,"unknown command: \"",argv[x],"\"\n",(char *)0); } } return(0); }