ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/commandtree.C
Revision: 1.9
Committed: Sun Sep 9 20:05:52 2007 UTC (19 years, 1 month 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

# Content
1 /**
2 * commandtree.C: Commandtree manipulation routines.
3 * Rights to this code are as documented in doc/pod/license.pod.
4 *
5 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team (http://ermyth.schmorp.de)
6 */
7
8 static char const rcsid[] = "$Id: commandtree.C,v 1.8 2007-09-05 11:23:15 pippijn Exp $";
9
10 #include <algorithm>
11
12 #include "atheme.h"
13 #include <common/string.h>
14 #include "users.h"
15 #include "privs.h"
16
17 cmdvec null_cmdvec;
18
19 struct cmd_eq
20 {
21 cmd_eq () : cmd (0) { }
22 cmd_eq (char const * const command) : cmd (command) { }
23 cmd_eq (command_t const &command) : cmd (command.name) { }
24
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 char const * const cmd;
49 } 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 operator << (cmdvec &commandlist, command_t const &cmd)
66 {
67 if (std::find_if (commandlist.begin (), commandlist.end (), cmd_eq (cmd)) != commandlist.end ())
68 {
69 slog (LG_INFO, "command_add(): command %s already in the list", cmd.name);
70 return;
71 }
72
73 commandlist.push_back (&cmd);
74 }
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 commandlist << *cmd[i];
83 }
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 operator >> (cmdvec &commandlist, command_t const &cmd)
100 {
101 commandlist.erase (std::find_if (commandlist.begin (), commandlist.end (), cmd_eq (cmd)));
102 }
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 commandlist >> *cmd[i];
111 }
112
113 command_t const *
114 cmdvec::find (char const *command)
115 {
116 cmdvec::iterator et = end ();
117 cmdvec::iterator it = std::find_if (begin (), et, cmd_eq (command));
118
119 if (it != et)
120 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 command_fail (si, fault::noprivs, _("You do not have %s privilege."), access);
136 else
137 command_fail (si, fault::noprivs, _("You are not authorized to perform this operation."));
138 /*snoop(_("DENIED CMD: \2%s\2 used %s %s"), origin, svs->name, cmd); */
139 }
140
141 void
142 command_exec_split (service_t *svs, sourceinfo_t *si, char const * const cmd, char const * const text, cmdvec &commandlist)
143 {
144 char *parv[20] = { 0 };
145 command_t const *c;
146
147 if ((c = commandlist.find (cmd)))
148 {
149 unsigned const parc = sjtoken (text, ' ', parv, c->maxparc);
150 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 render_help (sourceinfo_t *info)
170 : si (info)
171 {
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 command_help (sourceinfo_t *si, cmdvec &commandlist)
188 {
189 if (si->service == NULL || si->service->cmdtree == &commandlist)
190 command_success_nodata (si, _("The following commands are available:"));
191 else
192 command_success_nodata (si, _("The following subcommands are available:"));
193
194 std::for_each (commandlist.begin (), commandlist.end (), render_help (si));
195 }
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 render_help_short (sourceinfo_t *info, char const * const cmdlist)
237 : si (info), maincmds (cmdlist)
238 {
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 char const * const maincmds;
253 };
254
255 struct render_list
256 {
257 render_list (sourceinfo_t *info, dynstr &str, char const * const cmdlist, size_t length)
258 : si (info), buf (str), maincmds (cmdlist), indent (length)
259 {
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 if (buf.size () > l)
271 buf.add (", ", 2);
272 if (buf.size () > 55)
273 {
274 command_success_nodata (si, "%s", buf.c_str ());
275 buf.clear ();
276 while (--l > 0)
277 buf.add (' ');
278 buf.add (' ');
279 l = indent;
280 }
281 buf.add (c->name, strlen (c->name));
282 }
283 }
284
285 private:
286 sourceinfo_t *si;
287 dynstr &buf;
288 char const * const maincmds;
289 size_t indent;
290 };
291
292 void
293 command_help_short (sourceinfo_t *si, cmdvec &commandlist, char const * const maincmds)
294 {
295 size_t l;
296 char *lbuf;
297 dynstr buf (256);
298
299 if (si->service == NULL || si->service->cmdtree == &commandlist)
300 command_success_nodata (si, _("The following commands are available:"));
301 else
302 command_success_nodata (si, _("The following subcommands are available:"));
303
304 std::for_each (commandlist.begin (), commandlist.end (), render_help_short (si, maincmds));
305
306 command_success_nodata (si, " ");
307 lbuf = _("Other commands: ");
308 buf.add (lbuf, l = strlen (lbuf));
309
310 std::for_each (commandlist.begin (), commandlist.end (), render_list (si, buf, maincmds, l));
311
312 if (buf.size () > l)
313 command_success_nodata (si, "%s", buf.c_str ());
314 }