1 /* modcmd.h - Generalized module command support 2 * Copyright 2002-2004 srvx Development Team 3 * 4 * This file is part of srvx. 5 * 6 * srvx is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with srvx; if not, write to the Free Software Foundation, 18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 19 */ 20 21 #if !defined(MODCMDS_H) 22 #define MODCMDS_H 23 24 #include "recdb.h" 25 #include "helpfile.h" 26 #include "log.h" 27 28 struct service; 29 struct svccmd; 30 struct module; 31 struct modcmd; 32 33 #define MODCMD_FUNC(NAME) int NAME(struct userNode *user, UNUSED_ARG(struct chanNode *channel), UNUSED_ARG(unsigned int argc), UNUSED_ARG(char **argv), UNUSED_ARG(struct svccmd *cmd)) 34 typedef MODCMD_FUNC(modcmd_func_t); 35 #define SVCMSG_HOOK(NAME) int NAME(struct userNode *user, struct userNode *target, char *text, int server_qualified); 36 typedef SVCMSG_HOOK(svcmsg_hook_t); 37 38 DECLARE_LIST(svccmd_list, struct svccmd*); 39 DECLARE_LIST(module_list, struct module*); 40 41 #if defined(__GNUC__) && (__GNUC__ < 3) 42 #define reply(FMT...) send_message(user, cmd->parent->bot, FMT) 43 #elif !defined(S_SPLINT_S) /* doesn't recognize C99 variadic macros */ 44 #define reply(...) send_message(user, cmd->parent->bot, __VA_ARGS__) 45 #endif 46 #define modcmd_get_handle_info(USER, NAME) smart_get_handle_info(cmd->parent->bot, USER, NAME) 47 #define modcmd_chanmode_announce(CHANGE) mod_chanmode_announce(cmd->parent->bot, channel, CHANGE) 48 #define modcmd_chanmode(ARGV, ARGC, FLAGS) mod_chanmode(cmd->parent->bot, channel, ARGV, ARGC, FLAGS) 49 50 /* Miscellaneous flags controlling a command */ 51 #define MODCMD_DISABLED 0x001 52 #define MODCMD_NO_LOG 0x002 53 #define MODCMD_KEEP_BOUND 0x004 54 #define MODCMD_ACCEPT_CHANNEL 0x008 55 #define MODCMD_ACCEPT_PCHANNEL 0x010 56 #define MODCMD_NO_DEFAULT_BIND 0x020 57 #define MODCMD_LOG_HOSTMASK 0x040 58 #define MODCMD_IGNORE_CSUSPEND 0x080 59 #define MODCMD_NEVER_CSUSPEND 0x100 60 /* Requirement (access control) flags */ 61 #define MODCMD_REQUIRE_AUTHED 0x001000 62 #define MODCMD_REQUIRE_CHANNEL 0x002000 63 #define MODCMD_REQUIRE_REGCHAN 0x004000 64 #define MODCMD_REQUIRE_CHANUSER 0x008000 65 #define MODCMD_REQUIRE_JOINABLE 0x010000 66 #define MODCMD_REQUIRE_QUALIFIED 0x020000 67 #define MODCMD_REQUIRE_OPER 0x040000 68 #define MODCMD_REQUIRE_NETWORK_HELPER 0x080000 69 #define MODCMD_REQUIRE_SUPPORT_HELPER 0x100000 70 #define MODCMD_REQUIRE_HELPING 0x200000 71 #define MODCMD_TOY 0x400000 72 #define MODCMD_REQUIRE_STAFF (MODCMD_REQUIRE_OPER|MODCMD_REQUIRE_NETWORK_HELPER|MODCMD_REQUIRE_SUPPORT_HELPER) 73 74 #define SVCCMD_QUALIFIED 0x000001 75 #define SVCCMD_DEBIT 0x000002 76 #define SVCCMD_NOISY 0x000004 77 78 /* Modularized commands work like this: 79 * 80 * Modules define commands. Services contain "bindings" of those 81 * commands to names. 82 * 83 * The module-defined commands (modcmd structs) contain the parameters 84 * fixed by code; for example, assuming a channel was provided, or 85 * that the user has ChanServ access to that channel. 86 * 87 * Service command bindings (svccmd structs) define additional access 88 * controls (and a count of how many times the command has been used) 89 * as well as a link to the modcmd providing the function. 90 * 91 * Aliased commands are special svccmds that have alias expansion 92 * information in an "extra" pointer. In the future, this may be 93 * moved into the svccmd struct if there are no other commands that 94 * need "extra" data. 95 * 96 * The user must meet all the requirements (in flags, access levels, 97 * etc.) before the command is executed. As an exception, for the 98 * "staff" permission checks (oper/network helper/support helper), any 99 * one is sufficient to permit the command usage. 100 */ 101 102 struct service { 103 struct userNode *bot; 104 struct module_list modules; 105 struct dict *commands; /* contains struct svccmd* */ 106 svcmsg_hook_t *msg_hook; 107 unsigned int privileged : 1; 108 char trigger; 109 }; 110 111 struct svccmd { 112 char *name; 113 struct service *parent; /* where is this command bound? */ 114 struct modcmd *command; /* what is the implementation? */ 115 struct string_list alias; /* if it's a complicated binding, what is the expansion? */ 116 unsigned int uses; /* how many times was this command used? */ 117 unsigned int flags; 118 unsigned long req_account_flags; 119 unsigned long deny_account_flags; 120 unsigned int min_opserv_level; 121 unsigned int min_channel_access; 122 unsigned int effective_flags; 123 }; 124 125 struct module { 126 char *name; /* name of module */ 127 struct dict *commands; /* contains struct modcmd* */ 128 struct log_type *clog; /* where to send logged commands */ 129 const char *helpfile_name; /* name to use for helpfile */ 130 expand_func_t expand_help; /* expander function for helpfile */ 131 struct helpfile *helpfile; /* help file to use in case of syntax error */ 132 }; 133 134 struct modcmd { 135 char *name; 136 struct module *parent; 137 modcmd_func_t *func; 138 struct svccmd *defaults; 139 unsigned int min_argc; 140 unsigned int flags; 141 unsigned int bind_count; 142 }; 143 144 /* Register a command. The varadic argument section consists of a set 145 * of name/value pairs, where the name and value are strings that give 146 * the default parameters for the command. (The "flags" argument 147 * gives the required parameters.) The set is ended by a null name 148 * pointer (without any value argument). 149 */ 150 struct modcmd *modcmd_register(struct module *module, const char *name, modcmd_func_t func, unsigned int min_argc, unsigned int flags, ...); 151 152 /* Register a command-providing module. clog is where to log loggable 153 * commands (those without the MODCMD_NO_LOG flag and which succeed). 154 */ 155 struct module *module_register(const char *name, struct log_type *clog, const char *helpfile_name, expand_func_t expand_help); 156 /* Find a module by name. Returns NULL if no such module is registered. */ 157 struct module *module_find(const char *name); 158 159 /* Register a command-using service. */ 160 struct service *service_register(struct userNode *bot); 161 /* Find a service by name. */ 162 struct service *service_find(const char *name); 163 /* Bind one command to a service. */ 164 struct svccmd *service_bind_modcmd(struct service *service, struct modcmd *cmd, const char *name); 165 166 /* Send help for a command to a user. */ 167 int svccmd_send_help(struct userNode *user, struct userNode *bot, struct svccmd *cmd); 168 /* .. and if somebody doesn't have a modcmd handy .. */ 169 int svccmd_send_help_2(struct userNode *user, struct service *service, const char *topic); 170 /* Check whether a user may invoke a command or not. If they can, 171 * return non-zero. If they cannot (and noisy is non-zero), tell them 172 * why not and return 0. 173 */ 174 int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int flags); 175 /* Execute a command. Returns non-zero on success. */ 176 int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, char *argv[], unsigned int server_qualified); 177 /* Get notification when a command is being unbound. This lets 178 * services which cache svccmd references remove them. 179 */ 180 typedef void (*svccmd_unbind_func_t)(struct svccmd *target); 181 void reg_svccmd_unbind_func(svccmd_unbind_func_t handler); 182 183 /* Initialize the module command subsystem. */ 184 void modcmd_init(void); 185 /* Finalize the command mappings, read aliases, etc. Do this after 186 * all other modules have registered their commands. 187 */ 188 void modcmd_finalize(void); 189 190 #endif /* !defined(MODCMDS_H) */ 191