ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/modules/chanserv/close.C
Revision: 1.8
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.7: +6 -3 lines
Log Message:
split up ermyth into ermyth-modules, libermyth (currently just ermyth-util) and ermyth-core

File Contents

# Content
1 /**
2 * close.C: Closing for channels.
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-2006 Atheme Development Group
10 * Rights to this code are as documented in doc/pod/license.pod.
11 *
12 * $Id: close.C,v 1.7 2007-09-16 18:54:42 pippijn Exp $
13 */
14
15 #include "atheme.h"
16 #include <util/numeric.h>
17 #include <libermyth.h>
18 #include <ermyth/module.h>
19 #include <account/mychan.h>
20
21 static char const rcsid[] = "$Id: close.C,v 1.7 2007-09-16 18:54:42 pippijn Exp $";
22
23 REGISTER_MODULE ("chanserv/close", false, "The Ermyth Team <http://ermyth.xinutec.org>");
24
25 static void cs_cmd_close (sourceinfo_t *si, int parc, char *parv[]);
26
27 /* CLOSE ON|OFF -- don't pollute the root with REOPEN */
28 command_t const cs_close = { "CLOSE", N_("Closes a channel."), PRIV_CHAN_ADMIN, 3, cs_cmd_close };
29
30 E cmdvec cs_cmdtree;
31 E helpvec cs_helptree;
32
33 static bool
34 close_check_join (chanuser_t *cu)
35 {
36 mychan_t *mc;
37
38 if (cu == NULL || is_internal_client (cu->user))
39 return true;
40 mc = mychan_t::find (cu->chan->name);
41 if (mc == NULL)
42 return true;
43
44 if (mc->find_metadata ("private:close:closer"))
45 {
46 /* don't join if we're already in there */
47 if (!chanuser_find (cu->chan, user_find_named (chansvs.nick)))
48 join (cu->chan->name, chansvs.nick);
49
50 /* stay for a bit to stop rejoin floods */
51 mc->flags |= MC_INHABIT;
52
53 /* lock it down */
54 channel_mode_va (chansvs.me->me, cu->chan, 3, "+isbl", "*!*@*", "1");
55
56 /* clear the channel */
57 phandler->kick (chansvs.nick, cu->chan->name, cu->user->nick, "This channel has been closed");
58 return false;
59 }
60
61 return true;
62 }
63
64 static void
65 cs_cmd_close (sourceinfo_t *si, int parc, char *parv[])
66 {
67 char *target = parv[0];
68 char *action = parv[1];
69 char *reason = parv[2];
70 mychan_t *mc;
71 channel_t *c;
72 chanuser_t *cu;
73 node_t *n;
74
75 if (!target || !action)
76 {
77 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "CLOSE");
78 command_fail (si, fault::needmoreparams, _("Usage: CLOSE <#channel> <ON|OFF> [reason]"));
79 return;
80 }
81
82 if (!(mc = mychan_t::find (target)))
83 {
84 command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), target);
85 return;
86 }
87
88 if (!strcasecmp (action, "ON"))
89 {
90 if (!reason)
91 {
92 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "CLOSE");
93 command_fail (si, fault::needmoreparams, _("Usage: CLOSE <#channel> ON <reason>"));
94 return;
95 }
96
97 if (config_options.chan && !irccasecmp (config_options.chan, target))
98 {
99 command_fail (si, fault::noprivs, _("\2%s\2 cannot be closed."), target);
100 return;
101 }
102
103 if (mc->find_metadata ("private:close:closer"))
104 {
105 command_fail (si, fault::nochange, _("\2%s\2 is already closed."), target);
106 return;
107 }
108
109 mc->add_metadata ("private:close:closer", si->su->nick);
110 mc->add_metadata ("private:close:reason", reason);
111 mc->add_metadata ("private:close:timestamp", itoa (NOW));
112
113 if ((c = channel_find (target)))
114 {
115 if (!chanuser_find (c, user_find_named (chansvs.nick)))
116 join (target, chansvs.nick);
117
118 /* stay for a bit to stop rejoin floods */
119 mc->flags |= MC_INHABIT;
120
121 /* lock it down */
122 channel_mode_va (chansvs.me->me, c, 3, "+isbl", "*!*@*", "1");
123
124 /* clear the channel */
125 LIST_FOREACH (n, c->members.head)
126 {
127 cu = (chanuser_t *) n->data;
128
129 if (!is_internal_client (cu->user))
130 phandler->kick (chansvs.nick, target, cu->user->nick, "This channel has been closed");
131 }
132 }
133
134 wallops ("%s closed the channel \2%s\2 (%s).", get_oper_name (si), target, reason);
135 snoop ("CLOSE:ON: \2%s\2 by \2%s\2 (%s)", target, get_oper_name (si), reason);
136 logcommand (si, CMDLOG_ADMIN, "%s CLOSE ON %s", target, reason);
137 command_success_nodata (si, _("\2%s\2 is now closed."), target);
138 }
139 else if (!strcasecmp (action, "OFF"))
140 {
141 if (!mc->find_metadata ("private:close:closer"))
142 {
143 command_fail (si, fault::nochange, _("\2%s\2 is not closed."), target);
144 return;
145 }
146
147 mc->del_metadata ("private:close:closer");
148 mc->del_metadata ("private:close:reason");
149 mc->del_metadata ("private:close:timestamp");
150 mc->flags &= ~MC_INHABIT;
151 c = channel_find (target);
152 if (c != NULL)
153 if (chanuser_find (c, user_find_named (chansvs.nick)))
154 part (c->name, chansvs.nick);
155 c = channel_find (target);
156 if (c != NULL)
157 {
158 /* hmm, channel still exists, probably permanent? */
159 channel_mode_va (chansvs.me->me, c, 2, "-isbl", "*!*@*");
160 check_modes (mc, true);
161 }
162
163 wallops ("%s reopened the channel \2%s\2.", get_oper_name (si), target);
164 snoop ("CLOSE:OFF: \2%s\2 by \2%s\2", target, get_oper_name (si));
165 logcommand (si, CMDLOG_ADMIN, "%s CLOSE OFF", target);
166 command_success_nodata (si, _("\2%s\2 has been reopened."), target);
167 }
168 else
169 {
170 command_fail (si, fault::badparams, STR_INVALID_PARAMS, "CLOSE");
171 command_fail (si, fault::badparams, _("Usage: CLOSE <#channel> <ON|OFF> [reason]"));
172 }
173 }
174
175 bool
176 _modinit (module *m)
177 {
178 cs_cmdtree << cs_close;
179 chanuser_t::callback.join.attach (close_check_join);
180 help_addentry (cs_helptree, "CLOSE", "help/chanserv/close", NULL);
181
182 return true;
183 }
184
185 void
186 _moddeinit ()
187 {
188 cs_cmdtree >> cs_close;
189 chanuser_t::callback.join.detach (close_check_join);
190 help_delentry (cs_helptree, "CLOSE");
191 }