]>
Commit | Line | Data |
---|---|---|
d76ed9a9 AS |
1 | /* modcmd.h - Generalized module command support |
2 | * Copyright 2002-2004 srvx Development Team | |
3 | * | |
83ff05c3 | 4 | * This file is part of x3. |
d76ed9a9 | 5 | * |
d0f04f71 | 6 | * x3 is free software; you can redistribute it and/or modify |
d76ed9a9 | 7 | * it under the terms of the GNU General Public License as published by |
348683aa | 8 | * the Free Software Foundation; either version 3 of the License, or |
d76ed9a9 AS |
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); | |
1136f709 | 35 | #define SVCMSG_HOOK(NAME) int NAME(struct userNode *user, struct userNode *target, const char *text, int server_qualified) |
d76ed9a9 AS |
36 | typedef SVCMSG_HOOK(svcmsg_hook_t); |
37 | ||
38 | DECLARE_LIST(svccmd_list, struct svccmd*); | |
39 | DECLARE_LIST(module_list, struct module*); | |
40 | ||
1136f709 | 41 | #if defined(GCC_VARMACROS) |
42 | # define reply(ARGS...) send_message(user, cmd->parent->bot, ARGS) | |
43 | #elif defined(C99_VARMACROS) | |
44 | # define reply(...) send_message(user, cmd->parent->bot, __VA_ARGS__) | |
d76ed9a9 AS |
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 | ||
1136f709 | 78 | /* We do not use constants for 0 (no logging) and 1 (regular logging) as those |
79 | * are used very often and are intuitive enough. | |
80 | */ | |
81 | #define CMD_LOG_STAFF 0x02 | |
82 | #define CMD_LOG_OVERRIDE 0x04 | |
83 | ||
d76ed9a9 AS |
84 | /* Modularized commands work like this: |
85 | * | |
86 | * Modules define commands. Services contain "bindings" of those | |
87 | * commands to names. | |
88 | * | |
89 | * The module-defined commands (modcmd structs) contain the parameters | |
90 | * fixed by code; for example, assuming a channel was provided, or | |
91 | * that the user has ChanServ access to that channel. | |
92 | * | |
93 | * Service command bindings (svccmd structs) define additional access | |
94 | * controls (and a count of how many times the command has been used) | |
95 | * as well as a link to the modcmd providing the function. | |
96 | * | |
97 | * Aliased commands are special svccmds that have alias expansion | |
98 | * information in an "extra" pointer. In the future, this may be | |
99 | * moved into the svccmd struct if there are no other commands that | |
100 | * need "extra" data. | |
101 | * | |
102 | * The user must meet all the requirements (in flags, access levels, | |
103 | * etc.) before the command is executed. As an exception, for the | |
104 | * "staff" permission checks (oper/network helper/support helper), any | |
105 | * one is sufficient to permit the command usage. | |
106 | */ | |
107 | ||
108 | struct service { | |
109 | struct userNode *bot; | |
110 | struct module_list modules; | |
111 | struct dict *commands; /* contains struct svccmd* */ | |
112 | svcmsg_hook_t *msg_hook; | |
113 | unsigned int privileged : 1; | |
114 | char trigger; | |
115 | }; | |
116 | ||
117 | struct svccmd { | |
118 | char *name; | |
119 | struct service *parent; /* where is this command bound? */ | |
120 | struct modcmd *command; /* what is the implementation? */ | |
121 | struct string_list alias; /* if it's a complicated binding, what is the expansion? */ | |
122 | unsigned int uses; /* how many times was this command used? */ | |
123 | unsigned int flags; | |
124 | unsigned long req_account_flags; | |
125 | unsigned long deny_account_flags; | |
126 | unsigned int min_opserv_level; | |
127 | unsigned int min_channel_access; | |
128 | unsigned int effective_flags; | |
129 | }; | |
130 | ||
131 | struct module { | |
132 | char *name; /* name of module */ | |
133 | struct dict *commands; /* contains struct modcmd* */ | |
134 | struct log_type *clog; /* where to send logged commands */ | |
135 | const char *helpfile_name; /* name to use for helpfile */ | |
136 | expand_func_t expand_help; /* expander function for helpfile */ | |
137 | struct helpfile *helpfile; /* help file to use in case of syntax error */ | |
138 | }; | |
139 | ||
140 | struct modcmd { | |
141 | char *name; | |
142 | struct module *parent; | |
143 | modcmd_func_t *func; | |
144 | struct svccmd *defaults; | |
145 | unsigned int min_argc; | |
146 | unsigned int flags; | |
147 | unsigned int bind_count; | |
148 | }; | |
149 | ||
150 | /* Register a command. The varadic argument section consists of a set | |
151 | * of name/value pairs, where the name and value are strings that give | |
152 | * the default parameters for the command. (The "flags" argument | |
153 | * gives the required parameters.) The set is ended by a null name | |
154 | * pointer (without any value argument). | |
155 | */ | |
156 | struct modcmd *modcmd_register(struct module *module, const char *name, modcmd_func_t func, unsigned int min_argc, unsigned int flags, ...); | |
157 | ||
158 | /* Register a command-providing module. clog is where to log loggable | |
159 | * commands (those without the MODCMD_NO_LOG flag and which succeed). | |
160 | */ | |
161 | struct module *module_register(const char *name, struct log_type *clog, const char *helpfile_name, expand_func_t expand_help); | |
162 | /* Find a module by name. Returns NULL if no such module is registered. */ | |
163 | struct module *module_find(const char *name); | |
164 | ||
165 | /* Register a command-using service. */ | |
166 | struct service *service_register(struct userNode *bot); | |
167 | /* Find a service by name. */ | |
168 | struct service *service_find(const char *name); | |
169 | /* Bind one command to a service. */ | |
170 | struct svccmd *service_bind_modcmd(struct service *service, struct modcmd *cmd, const char *name); | |
2187a4e3 | 171 | struct svccmd *svccmd_resolve_name(struct svccmd *origin, const char *name); |
d76ed9a9 AS |
172 | |
173 | /* Send help for a command to a user. */ | |
b1bf690d | 174 | int svccmd_send_help(struct userNode *user, struct service *service, const char *topic); |
d76ed9a9 AS |
175 | /* .. and if somebody doesn't have a modcmd handy .. */ |
176 | int svccmd_send_help_2(struct userNode *user, struct service *service, const char *topic); | |
567a5f26 AS |
177 | /* Send brief help for a command to a user. */ |
178 | int svccmd_send_help_brief(struct userNode *user, struct userNode *bot, struct svccmd *cmd); | |
d76ed9a9 AS |
179 | /* Check whether a user may invoke a command or not. If they can, |
180 | * return non-zero. If they cannot (and noisy is non-zero), tell them | |
181 | * why not and return 0. | |
182 | */ | |
183 | int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int flags); | |
184 | /* Execute a command. Returns non-zero on success. */ | |
185 | int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, char *argv[], unsigned int server_qualified); | |
186 | /* Get notification when a command is being unbound. This lets | |
187 | * services which cache svccmd references remove them. | |
188 | */ | |
d77556d0 | 189 | typedef void (*svccmd_unbind_func_t)(struct svccmd *target, void *extra); |
190 | void reg_svccmd_unbind_func(svccmd_unbind_func_t handler, void *extra); | |
d76ed9a9 AS |
191 | |
192 | /* Initialize the module command subsystem. */ | |
193 | void modcmd_init(void); | |
194 | /* Finalize the command mappings, read aliases, etc. Do this after | |
195 | * all other modules have registered their commands. | |
196 | */ | |
197 | void modcmd_finalize(void); | |
198 | ||
199 | #endif /* !defined(MODCMDS_H) */ |