]>
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 AS |
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); | |
2187a4e3 | 165 | struct svccmd *svccmd_resolve_name(struct svccmd *origin, const char *name); |
d76ed9a9 AS |
166 | |
167 | /* Send help for a command to a user. */ | |
b1bf690d | 168 | int svccmd_send_help(struct userNode *user, struct service *service, const char *topic); |
d76ed9a9 AS |
169 | /* .. and if somebody doesn't have a modcmd handy .. */ |
170 | int svccmd_send_help_2(struct userNode *user, struct service *service, const char *topic); | |
567a5f26 AS |
171 | /* Send brief help for a command to a user. */ |
172 | int svccmd_send_help_brief(struct userNode *user, struct userNode *bot, struct svccmd *cmd); | |
d76ed9a9 AS |
173 | /* Check whether a user may invoke a command or not. If they can, |
174 | * return non-zero. If they cannot (and noisy is non-zero), tell them | |
175 | * why not and return 0. | |
176 | */ | |
177 | int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int flags); | |
178 | /* Execute a command. Returns non-zero on success. */ | |
179 | int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, char *argv[], unsigned int server_qualified); | |
180 | /* Get notification when a command is being unbound. This lets | |
181 | * services which cache svccmd references remove them. | |
182 | */ | |
183 | typedef void (*svccmd_unbind_func_t)(struct svccmd *target); | |
184 | void reg_svccmd_unbind_func(svccmd_unbind_func_t handler); | |
185 | ||
186 | /* Initialize the module command subsystem. */ | |
187 | void modcmd_init(void); | |
188 | /* Finalize the command mappings, read aliases, etc. Do this after | |
189 | * all other modules have registered their commands. | |
190 | */ | |
191 | void modcmd_finalize(void); | |
192 | ||
193 | #endif /* !defined(MODCMDS_H) */ |