ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/contrib/m_clearchan.c
Revision: 812
Committed: Thu Sep 7 09:41:54 2006 UTC (19 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 7904 byte(s)
Log Message:
- Imported contrib/

File Contents

# User Rev Content
1 michael 812 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_clearchan.c: Performs a channel takeover
4     *
5     * Copyright (C) 2002 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22     * $Id: m_clearchan.c 801 2006-08-30 16:54:25Z adx $
23     */
24    
25     #include "stdinc.h"
26     #include "handlers.h"
27     #include "channel.h"
28     #include "channel_mode.h"
29     #include "client.h"
30     #include "ircd.h"
31     #include "numeric.h"
32     #include "server.h"
33     #include "send.h"
34     #include "hash.h"
35     #include "msg.h"
36     #include "parse.h"
37     #include "conf/modules.h"
38     #include "common.h"
39     #include "user.h"
40    
41     static void mo_clearchan(struct Client *, struct Client *, int, char *[]);
42     static void kick_list(struct Client *, struct Channel *);
43     static void remove_our_modes(struct Channel *);
44     static void remove_a_mode(struct Channel *, int, char);
45    
46     struct Message clearchan_msgtab = {
47     "CLEARCHAN", 0, 0, 2, 0, MFLG_SLOW, 0,
48     { m_unregistered, m_not_oper, m_ignore, m_ignore, mo_clearchan, m_ignore }
49     };
50    
51     INIT_MODULE(m_clearchan, "$Revision: 801 $")
52     {
53     mod_add_cmd(&clearchan_msgtab);
54     }
55    
56     CLEANUP_MODULE
57     {
58     mod_del_cmd(&clearchan_msgtab);
59     }
60    
61    
62     /*! \brief CLEARCHAN command handler (called for operators only)
63     *
64     * \param client_p Pointer to allocated Client struct with physical connection
65     * to this server, i.e. with an open socket connected.
66     * \param source_p Pointer to allocated Client struct from which the message
67     * originally comes from. This can be a local or remote client.
68     * \param parc Integer holding the number of supplied arguments.
69     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
70     * pointers.
71     * \note Valid arguments for this command are:
72     * - parv[0] = sender prefix
73     * - parv[1] = channel name
74     */
75     static void
76     mo_clearchan(struct Client *client_p, struct Client *source_p,
77     int parc, char *parv[])
78     {
79     struct Channel *chptr = NULL;
80    
81     if (!IsAdmin(source_p))
82     {
83     sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
84     me.name, source_p->name);
85     return;
86     }
87    
88     if ((chptr = hash_find_channel(parv[1])) == NULL)
89     {
90     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
91     me.name, source_p->name, parv[1]);
92     return;
93     }
94    
95     if (IsMember(source_p, chptr))
96     {
97     sendto_one(source_p, ":%s NOTICE %s :*** Please part %s before using CLEARCHAN",
98     me.name, source_p->name, chptr->chname);
99     return;
100     }
101    
102     sendto_wallops_flags(UMODE_WALLOP, &me, "CLEARCHAN called for [%s] by %s",
103     chptr->chname, get_oper_name(source_p));
104     sendto_server(NULL, source_p, NULL, NOCAPS, NOCAPS,
105     ":%s WALLOPS :CLEARCHAN called for [%s] by %s",
106     me.name, chptr->chname, get_oper_name(source_p));
107     ilog(L_NOTICE, "CLEARCHAN called for [%s] by %s",
108     chptr->chname, get_oper_name(source_p));
109    
110     /*
111     * Kill all the modes we have about the channel..
112     * making everyone a peon
113     */
114     remove_our_modes(chptr);
115    
116     /* SJOIN the user to give them ops, and lock the channel */
117     sendto_server(client_p, source_p, chptr, CAP_TS6, NOCAPS,
118     ":%s JOIN %lu %s +ntsi",
119     source_p->id, (unsigned long)(chptr->channelts - 1),
120     chptr->chname);
121     sendto_server(client_p, source_p, chptr, NOCAPS, CAP_TS6,
122     ":%s SJOIN %lu %s +ntsi :@%s",
123     me.name, (unsigned long)(chptr->channelts - 1),
124     chptr->chname, source_p->name);
125     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN %s",
126     source_p->name, source_p->username,
127     source_p->host, chptr->chname);
128     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +o %s",
129     me.name, chptr->chname, source_p->name);
130    
131     /*
132     * Take the TS down by 1, so we don't see the channel taken over
133     * again.
134     */
135     if (chptr->channelts)
136     --chptr->channelts;
137    
138     chptr->mode.mode = MODE_SECRET | MODE_TOPICLIMIT |
139     MODE_INVITEONLY | MODE_NOPRIVMSGS;
140     free_topic(chptr);
141     chptr->mode.key[0] = '\0';
142    
143     /* Kick the users out and join the oper */
144     kick_list(source_p, chptr);
145     }
146    
147     static void
148     kick_list(struct Client *source_p, struct Channel *chptr)
149     {
150     dlink_node *ptr = NULL, *ptr_next = NULL;
151     struct Membership *ms = NULL;
152    
153     DLINK_FOREACH(ptr, chptr->members.head)
154     {
155     ms = ptr->data;
156    
157     sendto_channel_local(ALL_MEMBERS, NO, chptr,
158     ":%s!%s@%s KICK %s %s CLEARCHAN",
159     source_p->name, source_p->username,
160     source_p->host, chptr->chname, ms->client_p->name);
161     sendto_server(NULL, source_p, chptr, NOCAPS, NOCAPS,
162     ":%s KICK %s %s :CLEARCHAN", source_p->name,
163     chptr->chname, ms->client_p->name);
164     }
165    
166     add_user_to_channel(chptr, source_p, CHFL_CHANOP, NO);
167    
168     DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
169     {
170     ms = ptr->data;
171    
172     if (ms->client_p != source_p)
173     remove_user_from_channel(ms);
174     }
175    
176     /*
177     * Join the user themselves to the channel down here, so they dont see a nicklist
178     * or people being kicked
179     */
180     sendto_one(source_p, ":%s!%s@%s JOIN %s",
181     source_p->name, source_p->username,
182     source_p->host, chptr->chname);
183     channel_member_names(source_p, chptr, 1);
184     }
185    
186     /* remove_our_modes()
187     *
188     * inputs - hide from ops or not int flag
189     * - pointer to channel to remove modes from
190     * - client pointer
191     * output - NONE
192     * side effects - Go through the local members, remove all their
193     * chanop modes etc., this side lost the TS.
194     */
195     static void
196     remove_our_modes(struct Channel *chptr)
197     {
198     remove_a_mode(chptr, CHFL_CHANOP, 'o');
199     #ifdef HALFOPS
200     remove_a_mode(chptr, CHFL_HALFOP, 'h');
201     #endif
202     remove_a_mode(chptr, CHFL_VOICE, 'v');
203    
204     /* Clear all +beI modes */
205     free_channel_list(&chptr->banlist);
206     free_channel_list(&chptr->exceptlist);
207     free_channel_list(&chptr->invexlist);
208     }
209    
210     /* remove_a_mode()
211     *
212     * inputs -
213     * output - NONE
214     * side effects - remove ONE mode from a channel
215     */
216     static void
217     remove_a_mode(struct Channel *chptr, int mask, char flag)
218     {
219     const dlink_node *ptr = NULL;
220     char lmodebuf[MODEBUFLEN];
221     const char *lpara[4] = { "", "", "", "" };
222     char *mbuf = lmodebuf;
223     int count = 0;
224    
225     *mbuf++ = '-';
226    
227     DLINK_FOREACH(ptr, chptr->members.head)
228     {
229     struct Membership *ms = ptr->data;
230     if ((ms->flags & mask) == 0)
231     continue;
232    
233     ms->flags &= ~mask;
234    
235     lpara[count++] = ms->client_p->name;
236    
237     *mbuf++ = flag;
238    
239     if (count == 4)
240     {
241     *mbuf = '\0';
242     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s %s %s %s %s",
243     me.name, chptr->chname, lmodebuf, lpara[0],
244     lpara[1], lpara[2], lpara[3]);
245    
246     mbuf = lmodebuf;
247     *mbuf++ = '-';
248     count = 0;
249     lpara[0] = lpara[1] = lpara[2] = lpara[3] = "";
250     }
251     }
252    
253     if (count != 0)
254     {
255     *mbuf = '\0';
256     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s %s %s %s %s",
257     me.name, chptr->chname, lmodebuf, lpara[0],
258     lpara[1], lpara[2], lpara[3]);
259     }
260     }

Properties

Name Value
svn:eol-style native
svn:keywords "Id Revision"