TinyMUSH 3.3
TinyMUSH Server
Loading...
Searching...
No Matches
Functions | Variables
command.c File Reference

Command parser and support routines. More...

#include "config.h"
#include "constants.h"
#include "typedefs.h"
#include "macros.h"
#include "externs.h"
#include "prototypes.h"
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
#include <pcre.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <dlfcn.h>
#include <unistd.h>
#include <libgen.h>
Include dependency graph for command.c:

Functions

void init_cmdtab (void)
 Initialize the command table. More...
 
void reset_prefix_cmds (void)
 Reset prefix's commands. More...
 
bool check_access (dbref player, int mask)
 Check if player has access to function. Note that the calling function may also give permission denied messages on failure. More...
 
bool check_mod_access (dbref player, EXTFUNCS *xperms)
 Go through sequence of module call-outs, treating all of them like permission checks. More...
 
bool check_userdef_access (dbref player, HOOKENT *hookp, char *cargs[], int ncargs)
 Check if user has access to command with user-def'd permissions. More...
 
void process_hook (HOOKENT *hp, int save_globs, dbref player, dbref cause __attribute__((unused)), char *cargs[], int ncargs)
 Evaluate a hook. More...
 
void call_move_hook (dbref player, dbref cause, bool state)
 Call the hooks before and after leaving a room. More...
 
bool check_cmd_access (dbref player, CMDENT *cmdp, char *cargs[], int ncargs)
 Check if user has access to command. More...
 
void process_cmdent (CMDENT *cmdp, char *switchp, dbref player, dbref cause, bool interactive, char *arg, char *unp_command, char *cargs[], int ncargs)
 Perform indicated command with passed args. More...
 
char * process_command (dbref player, dbref cause, int interactive, char *command, char *args[], int nargs)
 Execute a command. More...
 
void process_cmdline (dbref player, dbref cause, char *cmdline, char *args[], int nargs, BQUE *qent)
 Execute a semicolon/pipe-delimited series of commands. More...
 
void list_cmdtable (dbref player)
 List internal commands. Note that user-defined command permissions are ignored in this context. More...
 
void list_attrtable (dbref player)
 List available attributes. More...
 
void helper_list_cmdaccess (dbref player, CMDENT *ctab)
 Helper for the list access commands. More...
 
void list_cmdaccess (dbref player)
 List access commands. More...
 
void list_cmdswitches (dbref player)
 List switches for commands. More...
 
void list_attraccess (dbref player)
 List access to attributes. More...
 
void list_attrtypes (dbref player)
 List attribute "types" (wildcards and permissions) More...
 
int cf_access (int *vp __attribute__((unused)), char *str, long extra, dbref player, char *cmd)
 Change command or switch permissions. More...
 
int cf_acmd_access (int *vp __attribute__((unused)), char *str, long extra, dbref player, char *cmd)
 Change command permissions for all attr-setting cmds. More...
 
int cf_attr_access (int *vp __attribute__((unused)), char *str, long extra, dbref player, char *cmd)
 Change access on an attribute. More...
 
int cf_attr_type (int *vp __attribute__((unused)), char *str, long extra, dbref player, char *cmd)
 Define attribute flags for new user-named attributes whose names match a certain pattern. More...
 
int cf_cmd_alias (int *vp, char *str, long extra __attribute__((unused)), dbref player, char *cmd)
 Add a command alias. More...
 
void list_df_flags (dbref player)
 List default flags at create time. More...
 
void list_costs (dbref player)
 List the costs of things. More...
 
void list_params (dbref player)
 List boolean game options from mushconf. list_config: List non-boolean game options. More...
 
void list_vattrs (dbref player)
 List user-defined attributes. More...
 
void list_hashstat (dbref player, const char *tab_name, HASHTAB *htab)
 Helper for listing information from an hash table. More...
 
void list_nhashstat (dbref player, const char *tab_name, HASHTAB *htab)
 Helper for listing information from an nhash table. More...
 
void list_hashstats (dbref player)
 List informations from Hash/NHash tables. More...
 
void list_textfiles (dbref player)
 List textfiles. More...
 
void list_db_stats (dbref player)
 Get useful info from the DB layer about hash stats, etc. More...
 
void list_process (dbref player)
 List local resource usage stats of the MUSH process. Adapted from code by Claudius@PythonMUCK, posted to the net by Howard/Dark_Lord. More...
 
void print_memory (dbref player, const char *item, size_t size)
 
void list_memory (dbref player)
 Breaks down memory usage of the process. More...
 
void do_list (dbref player, dbref cause __attribute__((unused)), int extra __attribute__((unused)), char *arg)
 List information stored in internal structures. More...
 

Variables

void(* handler_cs_no_args )(dbref, dbref, int)
 
void(* handler_cs_one_args )(dbref, dbref, int, char *)
 
void(* handler_cs_one_args_unparse )(dbref, char *)
 
void(* handler_cs_one_args_cmdargs )(dbref, dbref, int, char *, char *[], int)
 
void(* handler_cs_two_args )(dbref, dbref, int, char *, char *)
 
void(* handler_cs_two_args_cmdargs )(dbref, dbref, int, char *, char *, char *[], int)
 
void(* handler_cs_two_args_argv )(dbref, dbref, int, char *, char *[], int)
 
void(* handler_cs_two_args_cmdargs_argv )(dbref, dbref, int, char *, char *[], int, char *[], int)
 
CMDENTprefix_cmds [256]
 
CMDENTgoto_cmdp
 
CMDENTenter_cmdp
 
CMDENTleave_cmdp
 
CMDENTinternalgoto_cmdp
 

Detailed Description

Command parser and support routines.

Author
TinyMUSH development team (https://github.com/TinyMUSH)
Version
3.3
Date
2020-12-25

Function Documentation

◆ call_move_hook()

void call_move_hook ( dbref  player,
dbref  cause,
bool  state 
)

Call the hooks before and after leaving a room.

Parameters
playerDBref of Player leaving
causeDBref of what caused the action
stateTrue: before, False: after

◆ cf_access()

int cf_access ( int *vp   __attribute__(unused),
char *  str,
long  extra,
dbref  player,
char *  cmd 
)

Change command or switch permissions.

Parameters
vp
str
extra
player
cmd
Returns
int

◆ cf_acmd_access()

int cf_acmd_access ( int *vp   __attribute__(unused),
char *  str,
long  extra,
dbref  player,
char *  cmd 
)

Change command permissions for all attr-setting cmds.

Parameters
vp
str
extra
player
cmd
Returns
int

◆ cf_attr_access()

int cf_attr_access ( int *vp   __attribute__(unused),
char *  str,
long  extra,
dbref  player,
char *  cmd 
)

Change access on an attribute.

Parameters
vp
str
extra
player
cmd
Returns
int

◆ cf_attr_type()

int cf_attr_type ( int *vp   __attribute__(unused),
char *  str,
long  extra,
dbref  player,
char *  cmd 
)

Define attribute flags for new user-named attributes whose names match a certain pattern.

Parameters
vp
str
extra
player
cmd
Returns
int

Split our string into the attribute pattern and privileges. Also uppercase it, while we're at it. Make sure it's not longer than an attribute name can be.

Create our new data blob. Make sure that we're setting the privs to something reasonable before trying to link it in. (If we're not, an error will have been logged; we don't need to do it.)

◆ cf_cmd_alias()

int cf_cmd_alias ( int *  vp,
char *  str,
long extra   __attribute__(unused),
dbref  player,
char *  cmd 
)

Add a command alias.

Parameters
vp
str
extra
player
cmd
Returns
int

we only got one argument to @alias. Bad.

Switch form of command aliasing: create an alias for a command + a switch

Look up the command

Look up the switch

Got it, create the new command table entry

KNOWN PROBLEM: We are not inheriting the hook that the 'original' command had – we will have to add it manually (whereas an alias of a non-switched command is just another hashtable entry for the same command pointer and therefore gets the hook). This is preferable to having to search the hashtable for hooks when a hook is deleted, though.

A normal (non-switch) alias

◆ check_access()

bool check_access ( dbref  player,
int  mask 
)

Check if player has access to function. Note that the calling function may also give permission denied messages on failure.

Parameters
playerPlayer doing the command
maskPermission's mask
Returns
bool Permission granted or not

Check if we have permission to execute

Check for bits that we have to have. Since we know that we're not God at this point, if it is God-only, it fails. (God in combination with other stuff is implicitly checked, since we return false if we don't find the other bits.)

Check the things that we can't be.

◆ check_cmd_access()

bool check_cmd_access ( dbref  player,
CMDENT cmdp,
char *  cargs[],
int  ncargs 
)

Check if user has access to command.

Parameters
playerDBref of playuer
cmdpCommand entry
cargsCommand Arguments
ncargsNumber of arguments
Returns
Bool User has access or not

◆ check_mod_access()

bool check_mod_access ( dbref  player,
EXTFUNCS xperms 
)

Go through sequence of module call-outs, treating all of them like permission checks.

Parameters
playerPlayer doing the command
xpermsExtended functions list
Returns
bool Permission granted or not

◆ check_userdef_access()

bool check_userdef_access ( dbref  player,
HOOKENT hookp,
char *  cargs[],
int  ncargs 
)

Check if user has access to command with user-def'd permissions.

Parameters
playerPlayer doing the command
hookpHook entry point
cargsCommand argument list
ncargsNumber of arguments
Returns
bool Permission granted or not

We have user-defined command permissions. Go evaluate the obj/attr pair that we've been given. If that result is nonexistent, we consider it a failure. We use boolean truth here.

Note that unlike before and after hooks, we always preserve the registers. (When you get right down to it, this thing isn't really a hook. It's just convenient to re-use the same code that we use with hooks.)

◆ do_list()

void do_list ( dbref  player,
dbref cause   __attribute__(unused),
int extra   __attribute__(unused),
char *  arg 
)

List information stored in internal structures.

Parameters
playerDBref of player
causeDBref of cause
extraNot used.
argArguments

◆ helper_list_cmdaccess()

void helper_list_cmdaccess ( dbref  player,
CMDENT ctab 
)

Helper for the list access commands.

Parameters
playerDBref of the player
ctabCommand table
buffBuffer for the list

◆ init_cmdtab()

void init_cmdtab ( void  )

Initialize the command table.

Load attribute-setting commands

also add the __ alias form

Load the builtin commands, plus __ aliases

Set the builtin prefix commands

◆ list_attraccess()

void list_attraccess ( dbref  player)

List access to attributes.

Parameters
playerDBref of player

◆ list_attrtable()

void list_attrtable ( dbref  player)

List available attributes.

Parameters
player

◆ list_attrtypes()

void list_attrtypes ( dbref  player)

List attribute "types" (wildcards and permissions)

Parameters
playerDBref of player

◆ list_cmdaccess()

void list_cmdaccess ( dbref  player)

List access commands.

Parameters
playerDBref of the player

◆ list_cmdswitches()

void list_cmdswitches ( dbref  player)

List switches for commands.

Parameters
playerDBref of the player

◆ list_cmdtable()

void list_cmdtable ( dbref  player)

List internal commands. Note that user-defined command permissions are ignored in this context.

Parameters
playerDBref of the player

Players get the list of logged-out cmds too

◆ list_costs()

void list_costs ( dbref  player)

List the costs of things.

Parameters
playerDBref of player

◆ list_db_stats()

void list_db_stats ( dbref  player)

Get useful info from the DB layer about hash stats, etc.

Parameters
playerDBref of player

◆ list_df_flags()

void list_df_flags ( dbref  player)

List default flags at create time.

Parameters
playerDBref of player

◆ list_hashstat()

void list_hashstat ( dbref  player,
const char *  tab_name,
HASHTAB htab 
)

Helper for listing information from an hash table.

Parameters
playerDBref of player
tab_nameHash table name
htabHash table

◆ list_hashstats()

void list_hashstats ( dbref  player)

List informations from Hash/NHash tables.

Parameters
playerDBref of player

◆ list_memory()

void list_memory ( dbref  player)

Breaks down memory usage of the process.

Parameters
playerDBref of player

Calculate size of object structures

Calculate size of mushstate and mushconf structures

Calculate size of cache

Calculate size of object pipelines

Calculate size of name caches

Calculate size of Raw Memory allocations

Calculate size of command hashtable

Add up all the little bits in the CMDENT.

Calculate size of logged-out commands hashtable

Calculate size of functions hashtable

We don't count func->name because we already got it with htab->target.s

Calculate size of user-defined functions hashtable

Calculate size of flags hashtable

We don't count flag->flagname because we already got it with htab->target.s

Calculate size of powers hashtable

We don't count power->powername because we already got it with htab->target.s

Calculate size of helpfile hashtables

Calculate size of vattr name hashtable

Calculate size of attr name hashtable

Calculate the size of anum_table

After this point, we only report if it's non-zero.

Calculate size of object stacks

Calculate the size of grids

Calculate the size of xvars.

Calculate the size of overhead associated with structures.

Calculate the size of data associated with structures.

Report end total.

◆ list_nhashstat()

void list_nhashstat ( dbref  player,
const char *  tab_name,
HASHTAB htab 
)

Helper for listing information from an nhash table.

Parameters
playerDBref of player
tab_nameNHash table name
htabNHash table

◆ list_params()

void list_params ( dbref  player)

List boolean game options from mushconf. list_config: List non-boolean game options.

Parameters
playerDBref of player

◆ list_process()

void list_process ( dbref  player)

List local resource usage stats of the MUSH process. Adapted from code by Claudius@PythonMUCK, posted to the net by Howard/Dark_Lord.

Parameters
playerDBref of player

Go display everything

◆ list_textfiles()

void list_textfiles ( dbref  player)

List textfiles.

Parameters
playerDBref of player

◆ list_vattrs()

void list_vattrs ( dbref  player)

List user-defined attributes.

Parameters
playerDBref of player

◆ process_cmdent()

void process_cmdent ( CMDENT cmdp,
char *  switchp,
dbref  player,
dbref  cause,
bool  interactive,
char *  arg,
char *  unp_command,
char *  cargs[],
int  ncargs 
)

Perform indicated command with passed args.

Parameters
cmdpCommand
switchpSwitches
playerDBref of player doing the command
causeDBref of what caused the action
interactiveIs the command interractive?
argRaw Arguments
unp_commandRaw Commands
cargsArguments
ncargsNumber of arguments

Perform object type checks.

Check if we have permission to execute the command

Check global flags

Check command switches. Note that there may be more than one, and that we OR all of them together along with the extra value from the command table to produce the key value in the handler call.

At this point we're guaranteed we're going to execute something. Let's check to see if we have a pre-command hook.

If the command normally has interpreted args, but the user specified, /noeval, just do EV_STRIP.

If the command is interpreted, or we're interactive (and the command isn't specified CS_NOINTERP), eval the args.

The others are obvious.

< <cmd> (no args)

< <cmd> <arg>

If an unparsed command, just give it to the handler

Interpret if necessary, but not twice for CS_ADDED

Call the correct handler

Construct the matching buffer.

In the case of a single-letter prefix, we want to just skip past that first letter. want to just skip past that first letter. Otherwise we want to go past the first word.

No args

Now search against the attributes, unless we can't pass the uselock.

Skip the '$' character, and the next

The command the player typed didn't match any of the wildcard patterns we have for that addcommand. We should raise an error. We DO NOT go back into trying to match other stuff – this is a 'Huh?' situation.

Free the buffer if one was allocated

Interpret ARG1

Handle when no '=' was specified

Arg2 is ARGV style. Go get the args

Call the correct command handler

Free the argument buffers

Arg2 is normal style. Interpret if needed

Call the correct command handler

Free the buffer, if needed

Free the buffer obtained by evaluating Arg1

And now we go do the posthook, if we have one.

◆ process_cmdline()

void process_cmdline ( dbref  player,
dbref  cause,
char *  cmdline,
char *  args[],
int  nargs,
BQUE qent 
)

Execute a semicolon/pipe-delimited series of commands.

Parameters
playerDBref of the player
causeDBref of the cause
cmdlineCommand
argsArguments
nargsNumber of arguments
qentCommand queue.

No lag check on piped commands

Is the queue still linked like we think it is?

Don't use msec_add(), this is more accurate

◆ process_command()

char * process_command ( dbref  player,
dbref  cause,
int  interactive,
char *  command,
char *  args[],
int  nargs 
)

Execute a command.

Parameters
playerDBref of player doing the command
causeDBref of what caused the action
interactiveIs the command interractive?
commandCommand
argsArguments
nargsNumber of arguments
Returns
char*

Robustify player

Make sure player isn't going or halted

Reset recursion and other limits. Baseline the CPU counter.

We have no pointer, we should have no flags.

Warning
NOTE THAT THIS WILL BREAK IF "GOD" IS NOT A DBREF.

Eat leading whitespace, and space-compress if configured

Allow modules to intercept command strings.

Now comes the fun stuff. First check for single-letter leadins. We check these before checking HOME because they are among the most frequently executed commands, and they can never be the HOME command.

Check for the HOME command. You cannot do hooks on this because home is not part of the traditional command table.

Only check for exits if we may use the goto command

Check for an exit name

Exits literally call the 'move' command. Note that, later, when we go to matching master-room and other global-ish exits, that we also need to have move_match_more set to 'yes', or we'll match here only to encounter dead silence when we try to find the exit inside the move routine. We also need to directly find what the pointer for the move (goto) command is, since we could have @addcommand'd it (and probably did, if this conf option is on). Finally, we've got to make this look like we really did type 'goto <exit>', or the @addcommand will just skip over the string.

Execute the pre-hook for the goto command

Execute the post-hook for the goto command

Check for an exit in the master room

Set up a lowercase command and an arg pointer for the hashed command check. Since some types of argument processing destroy the arguments, make a copy so that we keep the original command line intact. Store the edible copy in lcbuf after the lowercased command.

Removed copy of the rest of the command, since it's ok to allow it to be trashed. -dcm

Check for a builtin command (or an alias of a builtin command)

We handle this specially – there is no space compression involved, so we must go back to the preserved command.

Check for enter and leave aliases, user-defined commands on the player, other objects where the player is, on objects in the player's inventory, and on the room that holds the player. We evaluate the command line here to allow chains of $-commands to work.

Idea for enter/leave aliases from R'nice@TinyTIM

Check for a leave alias, if we have permissions to use the 'leave' command.

Check for enter aliases, if we have permissions to use the 'enter' command.

At each of the following stages, we check to make sure that we haven't hit a match on a STOP-set object.

Check for $-command matches on me

Check for $-command matches on nearby things and on my room

Check for $-command matches in my inventory

If we didn't find anything, and we're checking local masters, do those checks. Do it for the zone of the player's location first, and then, if nothing is found, on the player's personal zone. Walking back through the parent tree stops when a match is found. Also note that these matches are done in the style of the master room: parents of the contents of the rooms aren't checked for commands. We try to maintain 2.2/MUX compatibility here, putting both sets of checks together.

2.2 style location

MUX style location

zone of player's location is a parent room

check parent room exits

try matching commands on area zone object

2.2 style player

MUX style player

if nothing matched with parent room/zone object, try matching zone commands on the player's personal zone

If we didn't find anything, try in the master room

Allow modules to intercept, if still no match. This time we pass both the lower-cased evaluated buffer and the preserved command.

If we still didn't find anything, tell how to get help.

◆ process_hook()

void process_hook ( HOOKENT hp,
int  save_globs,
dbref  player,
dbref cause   __attribute__(unused),
char *  cargs[],
int  ncargs 
)

Evaluate a hook.

Parameters
hpHook Entry
save_globsSave globals?
playerPlayer being evaluated
causeCause of the evaluation
cargsCommand arguments
ncargsNumber of arguments

We know we have a non-null hook. We want to evaluate the obj/attr pair of that hook. We consider the enactor to be the player who executed the command that caused this hook to be called.

◆ reset_prefix_cmds()

void reset_prefix_cmds ( void  )

Reset prefix's commands.