]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/command_parse.h
This was never supposed to be invoked on /rehash, only startup.. so move it to startu...
[user/henk/code/inspircd.git] / include / command_parse.h
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #ifndef __COMMAND_PARSE_H
15 #define __COMMAND_PARSE_H
16
17 /** A list of dll/so files containing the command handlers for the core
18  */
19 typedef std::map<std::string, void*> SharedObjectList;
20
21 /** This class handles command management and parsing.
22  * It allows you to add and remove commands from the map,
23  * call command handlers by name, and chop up comma seperated
24  * parameters into multiple calls.
25  */
26 class CoreExport CommandParser : public classbase
27 {
28  private:
29         /** The creator of this class
30          */
31         InspIRCd* ServerInstance;
32
33         /** Parameter buffer
34          */
35         std::vector<std::string> para;
36
37         /** Process a parameter string into a list of items
38          * @param command_p The output list of items
39          * @param parameters The input string
40          * @return The number of parameters parsed into command_p
41          */
42         int ProcessParameters(std::vector<std::string>& command_p, char* parameters);
43
44         /** Process a command from a user.
45          * @param user The user to parse the command for
46          * @param cmd The command string to process
47          */
48         bool ProcessCommand(User *user, std::string &cmd);
49
50         /** Finds the init_command symbol in a .so file
51          * @param v A function pointer to be initialized
52          * @param h A valid shared object handle
53          * @param name The filename being loaded, used for error reporting
54          * @return True if the symbol could be found
55          */
56         bool FindSym(void** v, void* h, const std::string &name);
57
58         /** A list of core-implemented modes and their shared object handles
59          */
60         SharedObjectList RFCCommands;
61
62         /** Load a command from a shared object on disk.
63          * @param name The shared object to load (without path)
64          * @return NULL on success, pointer to dlerrr() error message on failure
65          */
66         const char* LoadCommand(const char* name);
67
68         /** Removes a command if the sources match. Used as a helper for
69          *  safe hash_map delete while iter in RemoveCommands(const char* source).
70          */
71         void RemoveCommand(nspace::hash_map<std::string,Command*>::iterator safei, const char* source);
72
73
74  public:
75         /** Command list, a hash_map of command names to Command*
76          */
77         Commandtable cmdlist;
78
79         /** Reload a core command.
80          * This will only reload commands implemented by the core,
81          * to reload a modular command, you must reload that module.
82          * @param cmd The command to reload. This will cause the shared
83          * object which implements this command to be closed, and then reloaded.
84          * @return True if the command was reloaded, false if it could not be found
85          * or another error occured
86          */
87         bool ReloadCommand(std::string cmd, User* user);
88
89         /** Default constructor.
90          * @param Instance The creator of this class
91          */
92         CommandParser(InspIRCd* Instance);
93
94         /** Calls the handler for a given command.
95          * @param commandname The command to find. This should be in uppercase.
96          * @param parameters Parameter list
97          * @param user The user to call the handler on behalf of
98          * @return This method will return CMD_SUCCESS if the command handler was found and called,
99          * and the command completeld successfully. It will return CMD_FAILURE if the command handler was found
100          * and called, but the command did not complete successfully, and it will return CMD_INVALID if the
101          * command simply did not exist at all or the wrong number of parameters were given, or the user
102          * was not privilaged enough to execute the command.
103          */
104         CmdResult CallHandler(const std::string &commandname, const std::vector<std::string>& parameters, User *user);
105
106         /** Get the handler function for a command.
107          * @param commandname The command required. Always use uppercase for this parameter.
108          * @return a pointer to the command handler, or NULL
109          */
110         Command* GetHandler(const std::string &commandname);
111
112         /** This function returns true if a command is valid with the given number of parameters and user.
113          * @param commandname The command name to check
114          * @param pcnt The parameter count
115          * @param user The user to check against
116          * @return If the user given has permission to execute the command, and the parameter count is
117          * equal to or greater than the minimum number of parameters to the given command, then this
118          * function will return true, otherwise it will return false.
119          */
120         bool IsValidCommand(const std::string &commandname, unsigned int pcnt, User * user);
121         
122         /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
123          * There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
124          * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
125          * the channel names and their keys as follows:
126          *
127          * JOIN #chan1,#chan2,#chan3 key1,,key3
128          *
129          * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
130          * two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
131          * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
132          * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
133          *
134          * @param user The user who sent the command
135          * @param CommandObj the command object to call for each parameter in the list
136          * @param parameters Parameter list as an array of array of char (that's not a typo).
137          * @param The number of items in the parameters list
138          * @param splithere The first parameter index to split as a comma seperated list
139          * @param extra The second parameter index to split as a comma seperated list
140          * @return This function will return 1 when there are no more parameters to process. When this occurs, its
141          * caller should return without doing anything, otherwise it should continue into its main section of code.
142          */
143         int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere, unsigned int extra);
144
145         /** LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
146          * There are two overriden versions of this method, one of which takes two potential lists and the other takes one.
147          * We need a version which takes two potential lists for JOIN, because a JOIN may contain two lists of items at once,
148          * the channel names and their keys as follows:
149          *
150          * JOIN #chan1,#chan2,#chan3 key1,,key3
151          *
152          * Therefore, we need to deal with both lists concurrently. The first instance of this method does that by creating
153          * two instances of irc::commasepstream and reading them both together until the first runs out of tokens.
154          * The second version is much simpler and just has the one stream to read, and is used in NAMES, WHOIS, PRIVMSG etc.
155          * Both will only parse until they reach ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
156          *
157          * @param user The user who sent the command
158          * @param CommandObj the command object to call for each parameter in the list
159          * @param parameters Parameter list as an array of array of char (that's not a typo).
160          * @param The number of items in the parameters list
161          * @param splithere The first parameter index to split as a comma seperated list
162          * @param extra The second parameter index to split as a comma seperated list
163          * @return This function will return 1 when there are no more parameters to process. When this occurs, its
164          * caller should return without doing anything, otherwise it should continue into its main section of code.
165          */
166         int LoopCall(User* user, Command* CommandObj, const std::vector<std::string>& parameters, unsigned int splithere);
167
168         /** Take a raw input buffer from a recvq, and process it on behalf of a user.
169          * @param buffer The buffer line to process
170          * @param user The user to whom this line belongs
171          */
172         bool ProcessBuffer(std::string &buffer,User *user);
173
174         /** Process lines in a users sendq.
175          * @param current The user to process
176          * @param one_only if one_only is set only one command is processed from the sendq.
177          */
178         void DoLines(User* current, bool one_only = false);
179
180         /** Remove all commands relating to module 'source'.
181          * @param source A module name which has introduced new commands
182          */
183         void RemoveCommands(const char* source);
184
185         /** Add a new command to the commands hash
186          * @param f The new Command to add to the list
187          * @param so_handle The handle to the shared object where the command can be found.
188          * Only core commands loaded via cmd_*.so files should set this parameter to anything
189          * meaningful. Module authors should leave this parameter at its default of NULL.
190          * @return True if the command was added
191          */
192         bool CreateCommand(Command *f, void* so_handle = NULL);
193
194         /** Insert the default RFC1459 commands into the command hash.
195          */
196         void SetupCommandTable();
197
198         /** Translate nicknames in a string into UIDs, based on the TranslationType given.
199          * @param to The translation type to use for the process.
200          * @param source The input string
201          * @param dest The output string, it is safe to pass source and dest as the same variable only for translation type TR_TEXT.
202          * @return returns the number of substitutions made. Will always be 0 or 1 for TR_TEXT and 0..n for other types.
203          */
204         int TranslateUIDs(TranslateType to, const std::string &source, std::string &dest);
205 };
206
207 /** Command handler class for the RELOAD command.
208  * A command cant really reload itself, so this has to be in here.
209  */
210 class cmd_reload : public Command
211 {
212  public:
213         /** Standard constructor
214          */
215         cmd_reload (InspIRCd* Instance) : Command(Instance,"RELOAD","o",1) { syntax = "<core-command>"; }
216         /** Handle RELOAD
217          */
218         CmdResult Handle(const std::vector<std::string>& parameters, User *user);
219 };
220
221 /** A lookup table of values for multiplier characters used by
222  * InspIRCd::Duration(). In this lookup table, the indexes for
223  * the ascii values 'm' and 'M' have the value '60', the indexes
224  * for the ascii values 'D' and 'd' have a value of '86400', etc.
225  */
226 const int duration_multi[] =
227 {
228         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
229         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
230         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
231         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
232         1, 1, 1, 1, 1, 1, 1, 1, 86400, 1, 1, 1, 3600,
233         1, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1,
234         604800, 1, 31557600, 1, 1, 1, 1, 1, 1, 1, 1,
235         1, 1, 86400, 1, 1, 1, 3600, 1, 1, 1, 1, 60,
236         1, 1, 1, 1, 1, 1, 1, 1, 1, 604800, 1, 31557600,
237         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
238         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
239         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
240         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
241         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
242         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
243         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
244         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
245         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
246 };
247
248 #endif
249