ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/commandtree.C
Revision: 1.9
Committed: Sun Sep 9 20:05:52 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.8: +5 -7 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

File Contents

# User Rev Content
1 pippijn 1.9 /**
2     * commandtree.C: Commandtree manipulation routines.
3 pippijn 1.8 * Rights to this code are as documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.9 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team (http://ermyth.schmorp.de)
6 pippijn 1.1 */
7    
8 pippijn 1.9 static char const rcsid[] = "$Id: commandtree.C,v 1.8 2007-09-05 11:23:15 pippijn Exp $";
9    
10 pippijn 1.1 #include <algorithm>
11    
12     #include "atheme.h"
13 pippijn 1.8 #include <common/string.h>
14 pippijn 1.1 #include "users.h"
15     #include "privs.h"
16    
17     cmdvec null_cmdvec;
18    
19     struct cmd_eq
20     {
21 pippijn 1.3 cmd_eq () : cmd (0) { }
22     cmd_eq (char const * const command) : cmd (command) { }
23     cmd_eq (command_t const &command) : cmd (command.name) { }
24 pippijn 1.1
25     bool operator () (command_t const *c)
26     {
27     return !strcasecmp (c->name, cmd);
28     }
29    
30     /******/
31    
32     bool operator () (char const *c1, command_t const *c2)
33     {
34     return !strcasecmp (c1, c2->name);
35     }
36    
37     bool operator () (command_t const *c1, char const *c2)
38     {
39     return !strcasecmp (c1->name, c2);
40     }
41    
42     bool operator () (command_t const *c1, command_t const *c2)
43     {
44     return !strcasecmp (c1->name, c2->name);
45     }
46    
47     private:
48 pippijn 1.3 char const * const cmd;
49 pippijn 1.1 } cmd_compare;
50    
51     /*
52     * command_add_many()
53     *
54     * Inputs:
55     * array of commands to add, list to add them to.
56     *
57     * Output:
58     * none
59     *
60     * Side Effects:
61     * adds an array of commands to a command list,
62     * via command_add().
63     */
64     void
65 pippijn 1.3 operator << (cmdvec &commandlist, command_t const &cmd)
66 pippijn 1.1 {
67 pippijn 1.3 if (std::find_if (commandlist.begin (), commandlist.end (), cmd_eq (cmd)) != commandlist.end ())
68 pippijn 1.1 {
69     slog (LG_INFO, "command_add(): command %s already in the list", cmd.name);
70     return;
71     }
72    
73 pippijn 1.3 commandlist.push_back (&cmd);
74 pippijn 1.1 }
75    
76     void
77     operator << (cmdvec &commandlist, command_t const *cmd[])
78     {
79     unsigned int i;
80    
81     for (i = 0; cmd[i] != NULL; i++)
82 pippijn 1.3 commandlist << *cmd[i];
83 pippijn 1.1 }
84    
85     /*
86     * command_delete_many()
87     *
88     * Inputs:
89     * array of commands to delete, list to delete them from.
90     *
91     * Output:
92     * none
93     *
94     * Side Effects:
95     * deletes an array of commands from a command list,
96     * via command_delete().
97     */
98     void
99 pippijn 1.3 operator >> (cmdvec &commandlist, command_t const &cmd)
100 pippijn 1.1 {
101 pippijn 1.3 commandlist.erase (std::find_if (commandlist.begin (), commandlist.end (), cmd_eq (cmd)));
102 pippijn 1.1 }
103    
104     void
105     operator >> (cmdvec &commandlist, command_t const *cmd[])
106     {
107     unsigned int i;
108    
109     for (i = 0; cmd[i] != NULL; i++)
110 pippijn 1.3 commandlist >> *cmd[i];
111 pippijn 1.1 }
112    
113     command_t const *
114     cmdvec::find (char const *command)
115     {
116 pippijn 1.3 cmdvec::iterator et = end ();
117     cmdvec::iterator it = std::find_if (begin (), et, cmd_eq (command));
118 pippijn 1.1
119 pippijn 1.3 if (it != et)
120 pippijn 1.1 return *it;
121    
122     return NULL;
123     }
124    
125     void
126     command_t::exec (service_t *svs, sourceinfo_t *si, int parc, char *parv[]) const
127     {
128     if (has_priv (si, access))
129     {
130     cmd (si, parc, parv);
131     return;
132     }
133    
134     if (has_any_privs (si))
135 pippijn 1.7 command_fail (si, fault::noprivs, _("You do not have %s privilege."), access);
136 pippijn 1.1 else
137 pippijn 1.7 command_fail (si, fault::noprivs, _("You are not authorized to perform this operation."));
138 pippijn 1.1 /*snoop(_("DENIED CMD: \2%s\2 used %s %s"), origin, svs->name, cmd); */
139     }
140    
141     void
142 pippijn 1.3 command_exec_split (service_t *svs, sourceinfo_t *si, char const * const cmd, char const * const text, cmdvec &commandlist)
143 pippijn 1.1 {
144 pippijn 1.5 char *parv[20] = { 0 };
145 pippijn 1.1 command_t const *c;
146    
147 pippijn 1.3 if ((c = commandlist.find (cmd)))
148 pippijn 1.1 {
149 pippijn 1.4 unsigned const parc = sjtoken (text, ' ', parv, c->maxparc);
150 pippijn 1.1 c->exec (svs, si, parc, parv);
151     }
152     else
153     notice (svs->name, si->su->nick, _("Invalid command. Use \2/%s%s help\2 for a command listing."), (ircd->uses_rcommand == false) ? "msg " : "", svs->disp);
154     }
155    
156     /*
157     * command_help
158     * Iterates the command tree and lists available commands.
159     *
160     * inputs -
161     * si: The origin of the request.
162     * commandtree: The command tree being listed.
163     *
164     * outputs -
165     * A list of available commands.
166     */
167     struct render_help
168     {
169 pippijn 1.3 render_help (sourceinfo_t *info)
170     : si (info)
171 pippijn 1.1 {
172     }
173    
174     void operator () (command_t const *c)
175     {
176     /* show only the commands we have access to
177     * (taken from command_exec())
178     */
179     if (has_priv (si, c->access))
180     command_success_nodata (si, "\2%-15s\2 %s", c->name, c->desc);
181     }
182    
183     sourceinfo_t *si;
184     };
185    
186     void
187 pippijn 1.3 command_help (sourceinfo_t *si, cmdvec &commandlist)
188 pippijn 1.1 {
189 pippijn 1.3 if (si->service == NULL || si->service->cmdtree == &commandlist)
190 pippijn 1.1 command_success_nodata (si, _("The following commands are available:"));
191     else
192     command_success_nodata (si, _("The following subcommands are available:"));
193    
194 pippijn 1.3 std::for_each (commandlist.begin (), commandlist.end (), render_help (si));
195 pippijn 1.1 }
196    
197     /* name1 name2 name3... */
198     static bool
199     string_in_list (char const *str, char const *name)
200     {
201     char *p;
202     int l;
203    
204     if (str == NULL)
205     return false;
206     l = strlen (name);
207     while (*str != '\0')
208     {
209     p = strchr (str, ' ');
210     if (p != NULL ? p - str == l && !strncasecmp (str, name, p - str) : !strcasecmp (str, name))
211     return true;
212     if (p == NULL)
213     return false;
214     str = p;
215     while (*str == ' ')
216     str++;
217     }
218     return false;
219     }
220    
221     /*
222     * command_help_short
223     * Iterates over the command tree and lists available commands.
224     *
225     * inputs -
226     * mynick: The nick of the services bot sending out the notices.
227     * origin: The origin of the request.
228     * commandtree: The command tree being listed.
229     * maincmds: The commands to list verbosely.
230     *
231     * outputs -
232     * A list of available commands.
233     */
234     struct render_help_short
235     {
236 pippijn 1.3 render_help_short (sourceinfo_t *info, char const * const cmdlist)
237     : si (info), maincmds (cmdlist)
238 pippijn 1.1 {
239     }
240    
241     void operator () (command_t const *c)
242     {
243     /* show only the commands we have access to
244     * (taken from command_exec())
245     */
246     if (string_in_list (maincmds, c->name) && has_priv (si, c->access))
247     command_success_nodata (si, "\2%-15s\2 %s", c->name, c->desc);
248     }
249    
250     private:
251     sourceinfo_t *si;
252 pippijn 1.3 char const * const maincmds;
253 pippijn 1.1 };
254    
255     struct render_list
256     {
257 pippijn 1.3 render_list (sourceinfo_t *info, dynstr &str, char const * const cmdlist, size_t length)
258     : si (info), buf (str), maincmds (cmdlist), indent (length)
259 pippijn 1.1 {
260     }
261    
262     void operator () (command_t const *c)
263     {
264     /* show only the commands we have access to
265     * (taken from command_exec())
266     */
267     size_t l = indent;
268     if (!string_in_list (maincmds, c->name) && has_priv (si, c->access))
269     {
270 pippijn 1.7 if (buf.size () > l)
271     buf.add (", ", 2);
272     if (buf.size () > 55)
273 pippijn 1.1 {
274 pippijn 1.3 command_success_nodata (si, "%s", buf.c_str ());
275 pippijn 1.7 buf.clear ();
276 pippijn 1.1 while (--l > 0)
277 pippijn 1.7 buf.add (' ');
278     buf.add (' ');
279 pippijn 1.1 l = indent;
280     }
281 pippijn 1.7 buf.add (c->name, strlen (c->name));
282 pippijn 1.1 }
283     }
284    
285     private:
286     sourceinfo_t *si;
287 pippijn 1.3 dynstr &buf;
288     char const * const maincmds;
289 pippijn 1.1 size_t indent;
290     };
291    
292     void
293 pippijn 1.3 command_help_short (sourceinfo_t *si, cmdvec &commandlist, char const * const maincmds)
294 pippijn 1.1 {
295     size_t l;
296     char *lbuf;
297 pippijn 1.3 dynstr buf (256);
298 pippijn 1.1
299 pippijn 1.3 if (si->service == NULL || si->service->cmdtree == &commandlist)
300 pippijn 1.1 command_success_nodata (si, _("The following commands are available:"));
301     else
302     command_success_nodata (si, _("The following subcommands are available:"));
303    
304 pippijn 1.3 std::for_each (commandlist.begin (), commandlist.end (), render_help_short (si, maincmds));
305 pippijn 1.1
306     command_success_nodata (si, " ");
307     lbuf = _("Other commands: ");
308 pippijn 1.7 buf.add (lbuf, l = strlen (lbuf));
309 pippijn 1.1
310 pippijn 1.3 std::for_each (commandlist.begin (), commandlist.end (), render_list (si, buf, maincmds, l));
311 pippijn 1.1
312 pippijn 1.7 if (buf.size () > l)
313 pippijn 1.1 command_success_nodata (si, "%s", buf.c_str ());
314     }