ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/chanserv/close.C
Revision: 1.7
Committed: Sun Sep 16 18:54:42 2007 UTC (19 years, 1 month ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.6: +10 -5 lines
Log Message:
#defines to enum

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