Dev:Command API

Registering a new command
Syntax: Command *CommandAdd(Module *module, char *cmd, int (*func), unsigned char params, int flags) flags available:
 * module - The module this command is associated with
 * cmd - The text of the command
 * func - A function pointer to be called when this function is executed
 * params - The number of parameters this command accepts, use MAXPARA to accept up to maximum.
 * flags - The flags for this new command decide who may execute the command. Multiple flags are OR'ed together.

Example: CMD_FUNC(mymod_test); /* Forward declaration */

DLLFUNC int MOD_INIT(mymod)(ModuleInfo *modinfo) {   CommandAdd(modinfo->handle, "TEST", mymod_test, MAXPARA, M_USER|M_SERVER); }

You should always add all your commands in MOD_INIT and never in MOD_LOAD.

The actual command function
Example: DLLFUNC CMD_FUNC(mymod_test) {   sendnotice(sptr, "Thanks for testing"); return 0; }

The CMD_FUNC macro of UnrealIRCd will provide the following parameters:

Client information
For more information on the contents of sptr and cptr see Client, User and Server structs.

Parameter checking
Safe operation on parc and parv is important and may be slightly confusing if you're new. If you, for example, execute "TEST lalala" then parc will be 2 and parv[1] will contain the string lalala.

Most code in UnrealIRCd checks such things as follows: DLLFUNC CMD_FUNC(mymod_test) {   if ((parc < 3) || BadPtr(parv[2])) {       sendnotice(sptr, "Error: Two parameter required"); }   sendnotice(sptr, "Thanks for testing with the following two parameter: '%s' and '%s'", parv[1], parv[2]); return 0; }

Return values & killing clients
Normally you return 0 from the command. If you, however, decided to kill the client then you should be very careful to communicate this back. This is done by returning FLUSH_BUFFER. In most cases the kill function you call takes care of this, for example exit_client will return FLUSH_BUFFER if necessary and the same is true for place_host_ban.

Example (GOOD): DLLFUNC CMD_FUNC(mymod_test) {   if (!MyClient(sptr)) return 0; return exit_client(sptr, sptr, sptr, "You are dead"); }

Example (BAD): DLLFUNC CMD_FUNC(mymod_test) {   if (!MyClient(sptr)) return 0; exit_client(sptr, sptr, sptr, "You are dead"); return 0; /* BAD: upper layer does not know 'sptr' has been freed, so this will cause read-after-free memory errors which may result in a crash */ }