ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/src/commandtree.C
Revision: 1.6
Committed: Wed Aug 29 21:42:28 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +2 -3 lines
Log Message:
fixed bug in user introduction

File Contents

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