ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hybrid-ircservices-1/commands.c
Revision: 1209
Committed: Thu Aug 25 19:05:49 2011 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 6459 byte(s)
Log Message:
- run everything thru indent
  "-bli0 -di1 -npcs -nut -cdw -bls -nbbo -bap"

File Contents

# Content
1 /* Routines for looking up commands in a *Serv command list.
2 *
3 * IRC Services is copyright (c) 1996-2009 Andrew Church.
4 * E-mail: <achurch@achurch.org>
5 * Parts written by Andrew Kempe and others.
6 * This program is free but copyrighted software; see the file GPL.txt for
7 * details.
8 */
9
10 #include "services.h"
11 #include "modules.h"
12 #include "commands.h"
13 #include "language.h"
14
15 /*************************************************************************/
16
17 typedef struct commandlist_ CommandList;
18 typedef struct commandarray_ CommandArray;
19
20 struct commandlist_
21 {
22 CommandList *next, *prev;
23 Module *id;
24 CommandArray *first_array;
25 };
26
27 struct commandarray_
28 {
29 CommandArray *next, *prev;
30 Command *commands;
31 };
32
33 /*************************************************************************/
34
35 /* List of all commands registered. */
36 static CommandList *cmdlist;
37
38 /*************************************************************************/
39 /*************************************************************************/
40
41 /* Set up a new command list using the given module pointer as an ID value.
42 * Fails if a command list associated with `id' already exists.
43 */
44
45 int
46 new_commandlist(Module * id)
47 {
48 CommandList *cl;
49
50 LIST_SEARCH_SCALAR(cmdlist, id, id, cl);
51 if (cl)
52 return 0;
53 cl = smalloc(sizeof(*cl));
54 cl->id = id;
55 cl->first_array = NULL;
56 LIST_INSERT(cl, cmdlist);
57 return 1;
58 }
59
60 /*************************************************************************/
61
62 /* Register a command array under the given ID. Fails if there is no
63 * command list associated with `id', `array' is NULL, `array' has already
64 * been added to the list, or there are multiple command entries in `array'
65 * with the same name (case-insensitive). If an entry in `array' has the
66 * same name as a previously-registered entry, the entry in `array' will
67 * take precendence, and a pointer to the previous entry will be stored in
68 * the `next' field of the entry.
69 */
70
71 int
72 register_commands(Module * id, Command * array)
73 {
74 CommandList *cl;
75 CommandArray *ca;
76 Command *c, *c2;
77
78 /* Basic sanity checking */
79 if (!array)
80 return 0;
81 LIST_SEARCH_SCALAR(cmdlist, id, id, cl);
82 if (!cl)
83 return 0;
84 LIST_SEARCH_SCALAR(cl->first_array, commands, array, ca);
85 if (ca)
86 return 0;
87 /* Check for duplicate commands and set `next' pointers */
88 for (c = array; c->name; c++)
89 {
90 for (c2 = c + 1; c2->name; c2++)
91 {
92 if (stricmp(c->name, c2->name) == 0)
93 return 0;
94 }
95 c->next = lookup_cmd(id, c->name);
96 }
97 /* All's well, insert it in the list and return success */
98 ca = smalloc(sizeof(*ca));
99 ca->commands = array;
100 LIST_INSERT(ca, cl->first_array);
101 return 1;
102 }
103
104 /*************************************************************************/
105
106 /* Unregister a command array from the given ID. Fails if there is no
107 * command list associated with `id' or `array' was not in the list in the
108 * first place.
109 */
110
111 int
112 unregister_commands(Module * id, Command * array)
113 {
114 CommandList *cl;
115 CommandArray *ca;
116
117 LIST_SEARCH_SCALAR(cmdlist, id, id, cl);
118 if (!cl)
119 return 0;
120 LIST_SEARCH_SCALAR(cl->first_array, commands, array, ca);
121 if (!ca)
122 return 0;
123 LIST_REMOVE(ca, cl->first_array);
124 free(ca);
125 return 1;
126 }
127
128 /*************************************************************************/
129
130 /* Delete the command list associated with the given ID. Fails if there is
131 * no command list associated with `id' or the command list is not empty.
132 */
133
134 int
135 del_commandlist(Module * id)
136 {
137 CommandList *cl;
138
139 LIST_SEARCH_SCALAR(cmdlist, id, id, cl);
140 if (!cl || cl->first_array)
141 return 0;
142 LIST_REMOVE(cl, cmdlist);
143 free(cl);
144 return 1;
145 }
146
147 /*************************************************************************/
148 /*************************************************************************/
149
150 /* Returns the Command structure associated with the given command for the
151 * given command list (`id'), or NULL if no such command exists.
152 */
153
154 Command *
155 lookup_cmd(Module * id, const char *name)
156 {
157 CommandList *cl;
158 CommandArray *ca;
159 Command *c;
160
161 LIST_SEARCH_SCALAR(cmdlist, id, id, cl);
162 if (!cl)
163 return NULL;
164 LIST_FOREACH(ca, cl->first_array)
165 {
166 for (c = ca->commands; c->name; c++)
167 {
168 if (stricmp(c->name, name) == 0)
169 return c;
170 }
171 }
172 return NULL;
173 }
174
175 /*************************************************************************/
176
177 /* Run the routine for the given command, if it exists and the user has
178 * privilege to do so; if not, print an appropriate error message.
179 */
180
181 void
182 run_cmd(const char *service, User * u, Module * id, const char *cmd)
183 {
184 Command *c = lookup_cmd(id, cmd);
185
186 if (c && c->routine)
187 {
188 if ((c->has_priv == NULL) || c->has_priv(u))
189 c->routine(u);
190 else
191 notice_lang(service, u, ACCESS_DENIED);
192 }
193 else
194 {
195 notice_lang(service, u, UNKNOWN_COMMAND_HELP, cmd, service);
196 }
197 }
198
199 /*************************************************************************/
200
201 /* Print a help message for the given command. Multiple spaces between
202 * words are compressed to a single space before looking up the command
203 * (this will cause `cmd' to be modified).
204 */
205
206 void
207 help_cmd(const char *service, User * u, Module * id, char *cmd)
208 {
209 Command *c;
210 char *s;
211
212 s = cmd - 1;
213 while ((s = strpbrk(s + 1, " \t")) != NULL)
214 {
215 char *t = s + strspn(s, " \t");
216 if (t > s + 1)
217 memmove(s + 1, t, strlen(t) + 1);
218 }
219
220 c = lookup_cmd(id, cmd);
221 if (c)
222 {
223 const char *p1 = c->help_param1,
224 *p2 = c->help_param2, *p3 = c->help_param3, *p4 = c->help_param4;
225
226 if (c->helpmsg_all >= 0)
227 notice_help(service, u, c->helpmsg_all, p1, p2, p3, p4);
228
229 if (is_oper(u))
230 {
231 if (c->helpmsg_oper >= 0)
232 notice_help(service, u, c->helpmsg_oper, p1, p2, p3, p4);
233 else if (c->helpmsg_all < 0)
234 notice_lang(service, u, NO_HELP_AVAILABLE, cmd);
235 }
236 else
237 {
238 if (c->helpmsg_reg >= 0)
239 notice_help(service, u, c->helpmsg_reg, p1, p2, p3, p4);
240 else if (c->helpmsg_all < 0)
241 notice_lang(service, u, NO_HELP_AVAILABLE, cmd);
242 }
243
244 }
245 else
246 {
247
248 notice_lang(service, u, NO_HELP_AVAILABLE, cmd);
249
250 }
251 }
252
253 /*************************************************************************/
254
255 /*
256 * Local variables:
257 * c-file-style: "stroustrup"
258 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
259 * indent-tabs-mode: nil
260 * End:
261 *
262 * vim: expandtab shiftwidth=4:
263 */