ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/ermyth/modules/chanserv/close.C
Revision: 1.2
Committed: Sat Jul 21 01:29:08 2007 UTC (19 years, 3 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +2 -2 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

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