ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/chanserv/akick.C
Revision: 1.10
Committed: Sat Sep 22 14:27:27 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +4 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * akick.C: This file contains code for the ChanServ AKICK functions.
3 *
4 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team
5 * Rights to this code are as documented in COPYING.
6 *
7 *
8 * Portions of this file were derived from sources bearing the following license:
9 * Copyright © 2005 William Pitcock, et al.
10 * Rights to this code are as documented in doc/pod/license.pod.
11 *
12 * $Id: akick.C,v 1.9 2007-09-16 18:54:42 pippijn Exp $
13 */
14
15 #include "atheme.h"
16 #include <util/time.h>
17 #include <ermyth/module.h>
18 #include <account/myuser.h>
19 #include <account/mychan.h>
20 #include <account/chanacs.h>
21
22 static void cs_cmd_akick (sourceinfo_t *si, int parc, char *parv[]);
23
24 static char const rcsid[] = "$Id: akick.C,v 1.9 2007-09-16 18:54:42 pippijn Exp $";
25
26 REGISTER_MODULE ("chanserv/akick", false, "The Ermyth Team <http://ermyth.xinutec.org>");
27
28 command_t const cs_akick = { "AKICK", N_("Manipulates a channel's AKICK list."), AC_NONE, 4, cs_cmd_akick };
29
30 E cmdvec cs_cmdtree;
31 E helpvec cs_helptree;
32
33 void
34 cs_cmd_akick (sourceinfo_t *si, int parc, char *parv[])
35 {
36 myuser_t *mu;
37 mychan_t *mc;
38 chanacs_t *ca, *ca2;
39 metadata *md;
40 node_t *n;
41 int operoverride = 0;
42 char *chan;
43 char *cmd;
44 char *uname = parv[2];
45 char *reason = parv[3];
46
47 if (parc < 2)
48 {
49 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "AKICK");
50 command_fail (si, fault::needmoreparams, _("Syntax: AKICK <#channel> ADD|DEL|LIST <nickname|hostmask> [reason]"));
51 return;
52 }
53
54 if (parv[0][0] == '#')
55 chan = parv[0], cmd = parv[1];
56 else if (parv[1][0] == '#')
57 cmd = parv[0], chan = parv[1];
58 else
59 {
60 command_fail (si, fault::badparams, STR_INVALID_PARAMS, "AKICK");
61 command_fail (si, fault::badparams, _("Syntax: AKICK <#channel> ADD|DEL|LIST <nickname|hostmask> [reason]"));
62 return;
63 }
64
65 if ((strcasecmp ("LIST", cmd)) && (!uname))
66 {
67 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "AKICK");
68 command_fail (si, fault::needmoreparams, _("Syntax: AKICK <#channel> ADD|DEL|LIST <nickname|hostmask> [reason]"));
69 return;
70 }
71
72 /* make sure they're registered, logged in
73 * and the founder of the channel before
74 * we go any further.
75 */
76 if (!si->smu)
77 {
78 /* if they're opers and just want to LIST, they don't have to log in */
79 if (!(has_priv (si, PRIV_CHAN_AUSPEX) && !strcasecmp ("LIST", cmd)))
80 {
81 command_fail (si, fault::noprivs, _("You are not logged in."));
82 return;
83 }
84 }
85
86 mc = mychan_t::find (chan);
87 if (!mc)
88 {
89 command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), chan);
90 return;
91 }
92
93 if (mc->find_metadata ("private:close:closer"))
94 {
95 command_fail (si, fault::noprivs, _("\2%s\2 is closed."), chan);
96 return;
97 }
98
99 /* ADD */
100 if (!strcasecmp ("ADD", cmd))
101 {
102 if ((chanacs_source_flags (mc, si) & (CA_FLAGS | CA_REMOVE)) != (CA_FLAGS | CA_REMOVE))
103 {
104 command_fail (si, fault::noprivs, _("You are not authorized to perform this operation."));
105 return;
106 }
107
108 mu = myuser_t::find_ext (uname);
109 if (!mu)
110 {
111 /* we might be adding a hostmask */
112 if (!validhostmask (uname))
113 {
114 command_fail (si, fault::badparams, _("\2%s\2 is neither a nickname nor a hostmask."), uname);
115 return;
116 }
117
118 uname = collapse (uname);
119
120 ca = chanacs_find_host_literal (mc, uname, 0);
121 if (ca != NULL)
122 {
123 if (ca->level & CA_AKICK)
124 command_fail (si, fault::nochange, _("\2%s\2 is already on the AKICK list for \2%s\2"), uname, mc->name);
125 else
126 command_fail (si, fault::alreadyexists, _("\2%s\2 already has flags \2%s\2 on \2%s\2"), uname, bitmask_to_flags (ca->level, chanacs_flags), mc->name);
127 return;
128 }
129
130 ca = chanacs_find_host (mc, uname, CA_AKICK);
131 if (ca != NULL)
132 {
133 command_fail (si, fault::nochange, _("The more general mask \2%s\2 is already on the AKICK list for \2%s\2"), ca->host, mc->name);
134 return;
135 }
136
137 /* new entry */
138 ca2 = chanacs_open (mc, NULL, uname, true);
139 if (chanacs_is_table_full (ca2))
140 {
141 command_fail (si, fault::toomany, _("Channel %s access list is full."), mc->name);
142 chanacs_close (ca2);
143 return;
144 }
145 chanacs_modify_simple (ca2, CA_AKICK, 0);
146 if (reason != NULL)
147 ca2->add_metadata ("reason", reason);
148
149 ca2->callback.akick_add (ca2);
150 chanacs_close (ca2);
151
152 verbose (mc, "\2%s\2 added \2%s\2 to the AKICK list.", get_source_name (si), uname);
153 logcommand (si, CMDLOG_SET, "%s AKICK ADD %s", mc->name, uname);
154
155 command_success_nodata (si, _("\2%s\2 has been added to the AKICK list for \2%s\2."), uname, mc->name);
156
157 return;
158 }
159 else
160 {
161 if ((ca = chanacs_find (mc, mu, 0x0)))
162 {
163 if (ca->level & CA_AKICK)
164 command_fail (si, fault::nochange, _("\2%s\2 is already on the AKICK list for \2%s\2"), mu->name, mc->name);
165 else
166 command_fail (si, fault::alreadyexists, _("\2%s\2 already has flags \2%s\2 on \2%s\2"), mu->name, bitmask_to_flags (ca->level, chanacs_flags), mc->name);
167 return;
168 }
169
170 /* new entry */
171 ca2 = chanacs_open (mc, mu, NULL, true);
172 if (chanacs_is_table_full (ca2))
173 {
174 command_fail (si, fault::toomany, _("Channel %s access list is full."), mc->name);
175 chanacs_close (ca2);
176 return;
177 }
178 chanacs_modify_simple (ca2, CA_AKICK, 0);
179 if (reason != NULL)
180 ca2->add_metadata ("reason", reason);
181
182 ca2->callback.akick_add (ca2);
183 chanacs_close (ca2);
184
185 command_success_nodata (si, _("\2%s\2 has been added to the AKICK list for \2%s\2."), mu->name, mc->name);
186
187 verbose (mc, "\2%s\2 added \2%s\2 to the AKICK list.", get_source_name (si), mu->name);
188 logcommand (si, CMDLOG_SET, "%s AKICK ADD %s", mc->name, mu->name);
189
190 return;
191 }
192 }
193 else if (!strcasecmp ("DEL", cmd))
194 {
195 if ((chanacs_source_flags (mc, si) & (CA_FLAGS | CA_REMOVE)) != (CA_FLAGS | CA_REMOVE))
196 {
197 command_fail (si, fault::noprivs, _("You are not authorized to perform this operation."));
198 return;
199 }
200
201 mu = myuser_t::find_ext (uname);
202 if (!mu)
203 {
204 /* we might be deleting a hostmask */
205 ca = chanacs_find_host_literal (mc, uname, CA_AKICK);
206 if (ca == NULL)
207 {
208 ca = chanacs_find_host (mc, uname, CA_AKICK);
209 if (ca != NULL)
210 command_fail (si, fault::nosuch_key, _("\2%s\2 is not on the AKICK list for \2%s\2, however \2%s\2 is."), uname, mc->name, ca->host);
211 else
212 command_fail (si, fault::nosuch_key, _("\2%s\2 is not on the AKICK list for \2%s\2."), uname, mc->name);
213 return;
214 }
215
216 chanacs_modify_simple (ca, 0, CA_AKICK);
217 chanacs_close (ca);
218
219 verbose (mc, "\2%s\2 removed \2%s\2 from the AKICK list.", get_source_name (si), uname);
220 logcommand (si, CMDLOG_SET, "%s AKICK DEL %s", mc->name, uname);
221
222 command_success_nodata (si, _("\2%s\2 has been removed from the AKICK list for \2%s\2."), uname, mc->name);
223
224 return;
225 }
226
227 if (!(ca = chanacs_find (mc, mu, CA_AKICK)))
228 {
229 command_fail (si, fault::nosuch_key, _("\2%s\2 is not on the AKICK list for \2%s\2."), mu->name, mc->name);
230 return;
231 }
232
233 chanacs_modify_simple (ca, 0, CA_AKICK);
234 chanacs_close (ca);
235
236 command_success_nodata (si, _("\2%s\2 has been removed from the AKICK list for \2%s\2."), mu->name, mc->name);
237 logcommand (si, CMDLOG_SET, "%s AKICK DEL %s", mc->name, mu->name);
238
239 verbose (mc, "\2%s\2 removed \2%s\2 from the AKICK list.", get_source_name (si), mu->name);
240
241 return;
242 }
243 else if (!strcasecmp ("LIST", cmd))
244 {
245 int i = 0;
246
247 if (!chanacs_source_has_flag (mc, si, CA_ACLVIEW))
248 {
249 if (has_priv (si, PRIV_CHAN_AUSPEX))
250 operoverride = 1;
251 else
252 {
253 command_fail (si, fault::noprivs, _("You are not authorized to perform this operation."));
254 return;
255 }
256 }
257 command_success_nodata (si, _("AKICK list for \2%s\2:"), mc->name);
258
259 LIST_FOREACH (n, mc->chanacs.head)
260 {
261 ca = (chanacs_t *) n->data;
262
263 if (ca->level == CA_AKICK)
264 {
265 md = ca->find_metadata ("reason");
266 if (ca->myuser == NULL)
267 command_success_nodata (si, _("%d: \2%s\2 %s [modified: %s ago]"), ++i, ca->host, md ? md->value : "", time_ago (ca->ts));
268 else if (!ca->myuser->logins.empty ())
269 command_success_nodata (si, _("%d: \2%s\2 (logged in) %s [modified: %s ago]"), ++i, ca->myuser->name, md ? md->value : "", time_ago (ca->ts));
270 else
271 command_success_nodata (si, _("%d: \2%s\2 (not logged in) %s [modified: %s ago]"), ++i, ca->myuser->name, md ? md->value : "", time_ago (ca->ts));
272 }
273
274 }
275
276 command_success_nodata (si, _("Total of \2%d\2 %s in \2%s\2's AKICK list."), i, (i == 1) ? "entry" : "entries", mc->name);
277 if (operoverride)
278 logcommand (si, CMDLOG_ADMIN, "%s AKICK LIST (oper override)", mc->name);
279 else
280 logcommand (si, CMDLOG_GET, "%s AKICK LIST", mc->name);
281 }
282 else
283 command_fail (si, fault::badparams, _("Invalid command. Use \2/%s%s help\2 for a command listing."), (ircd->uses_rcommand == false) ? "msg " : "", si->service->disp);
284 }
285
286 bool
287 _modinit (module *m)
288 {
289 cs_cmdtree << cs_akick;
290 help_addentry (cs_helptree, "AKICK", "help/chanserv/akick", NULL);
291
292 return true;
293 }
294
295 void
296 _moddeinit ()
297 {
298 help_delentry (cs_helptree, "AKICK");
299 cs_cmdtree >> cs_akick;
300 }