ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/chanserv/close.C
Revision: 1.8
Committed: Sat Sep 22 14:27:27 2007 UTC (19 years, 1 month 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

# User Rev Content
1 pippijn 1.7 /**
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 pippijn 1.5 * Copyright © 2005-2006 Atheme Development Group
10 pippijn 1.2 * Rights to this code are as documented in doc/pod/license.pod.
11 pippijn 1.1 *
12 pippijn 1.8 * $Id: close.C,v 1.7 2007-09-16 18:54:42 pippijn Exp $
13 pippijn 1.1 */
14    
15     #include "atheme.h"
16 pippijn 1.8 #include <util/numeric.h>
17     #include <libermyth.h>
18 pippijn 1.5 #include <ermyth/module.h>
19 pippijn 1.1 #include <account/mychan.h>
20    
21 pippijn 1.8 static char const rcsid[] = "$Id: close.C,v 1.7 2007-09-16 18:54:42 pippijn Exp $";
22 pippijn 1.1
23 pippijn 1.8 REGISTER_MODULE ("chanserv/close", false, "The Ermyth Team <http://ermyth.xinutec.org>");
24 pippijn 1.1
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 pippijn 1.5 command_t const cs_close = { "CLOSE", N_("Closes a channel."), PRIV_CHAN_ADMIN, 3, cs_cmd_close };
29 pippijn 1.1
30 pippijn 1.5 E cmdvec cs_cmdtree;
31     E helpvec cs_helptree;
32 pippijn 1.1
33 pippijn 1.5 static bool
34     close_check_join (chanuser_t *cu)
35 pippijn 1.1 {
36     mychan_t *mc;
37    
38     if (cu == NULL || is_internal_client (cu->user))
39 pippijn 1.5 return true;
40 pippijn 1.6 mc = mychan_t::find (cu->chan->name);
41 pippijn 1.1 if (mc == NULL)
42 pippijn 1.5 return true;
43 pippijn 1.1
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 pippijn 1.5 phandler->kick (chansvs.nick, cu->chan->name, cu->user->nick, "This channel has been closed");
58     return false;
59 pippijn 1.1 }
60 pippijn 1.5
61     return true;
62 pippijn 1.1 }
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 pippijn 1.6 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "CLOSE");
78     command_fail (si, fault::needmoreparams, _("Usage: CLOSE <#channel> <ON|OFF> [reason]"));
79 pippijn 1.1 return;
80     }
81    
82 pippijn 1.6 if (!(mc = mychan_t::find (target)))
83 pippijn 1.1 {
84 pippijn 1.6 command_fail (si, fault::nosuch_target, _("\2%s\2 is not registered."), target);
85 pippijn 1.1 return;
86     }
87    
88     if (!strcasecmp (action, "ON"))
89     {
90     if (!reason)
91     {
92 pippijn 1.6 command_fail (si, fault::needmoreparams, STR_INSUFFICIENT_PARAMS, "CLOSE");
93     command_fail (si, fault::needmoreparams, _("Usage: CLOSE <#channel> ON <reason>"));
94 pippijn 1.1 return;
95     }
96    
97     if (config_options.chan && !irccasecmp (config_options.chan, target))
98     {
99 pippijn 1.6 command_fail (si, fault::noprivs, _("\2%s\2 cannot be closed."), target);
100 pippijn 1.1 return;
101     }
102    
103     if (mc->find_metadata ("private:close:closer"))
104     {
105 pippijn 1.6 command_fail (si, fault::nochange, _("\2%s\2 is already closed."), target);
106 pippijn 1.1 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 pippijn 1.5 phandler->kick (chansvs.nick, target, cu->user->nick, "This channel has been closed");
131 pippijn 1.1 }
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 pippijn 1.6 command_fail (si, fault::nochange, _("\2%s\2 is not closed."), target);
144 pippijn 1.1 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 pippijn 1.6 command_fail (si, fault::badparams, STR_INVALID_PARAMS, "CLOSE");
171     command_fail (si, fault::badparams, _("Usage: CLOSE <#channel> <ON|OFF> [reason]"));
172 pippijn 1.1 }
173     }
174    
175 pippijn 1.5 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 pippijn 1.8 help_delentry (cs_helptree, "CLOSE");
191 pippijn 1.5 }