Remove extraneous semicolons from end of macro uses.
[srvx.git] / src / modcmd.h
1 /* modcmd.h - Generalized module command support
2  * Copyright 2002-2006 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, const 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 /* 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
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);
171
172 /* Send help for a command to a user. */
173 int svccmd_send_help(struct userNode *user, struct userNode *bot, struct svccmd *cmd);
174 /* .. and if somebody doesn't have a modcmd handy .. */
175 int svccmd_send_help_2(struct userNode *user, struct service *service, const char *topic);
176 /* Check whether a user may invoke a command or not.  If they can,
177  * return non-zero.  If they cannot (and noisy is non-zero), tell them
178  * why not and return 0.
179  */
180 int svccmd_can_invoke(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int flags);
181 /* Execute a command.  Returns non-zero on success. */
182 int svccmd_invoke_argv(struct userNode *user, struct service *service, struct chanNode *channel, unsigned int argc, char *argv[], unsigned int server_qualified);
183 /* Get notification when a command is being unbound.  This lets
184  * services which cache svccmd references remove them.
185  */
186 typedef void (*svccmd_unbind_func_t)(struct svccmd *target);
187 void reg_svccmd_unbind_func(svccmd_unbind_func_t handler);
188
189 /* Initialize the module command subsystem. */
190 void modcmd_init(void);
191 /* Finalize the command mappings, read aliases, etc.  Do this after
192  * all other modules have registered their commands.
193  */
194 void modcmd_finalize(void);
195
196 #endif /* !defined(MODCMDS_H) */