ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/m_force.c
Revision: 632
Committed: Thu Jun 1 10:53:00 2006 UTC (20 years, 1 month ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/contrib/m_force.c
File size: 10817 byte(s)
Log Message:
- Added channel::disable_fake_channels which disallows creation of channels
  that have ascii 2, 3, 31 and 160 in their names.
- Minor improvements and cleanups to channel name validation routines
  backported from 7.3

File Contents

# User Rev Content
1 adx 30 /* contrib/m_force.c
2     * Copyright (C) 2002, 2003, 2004, 2005 Hybrid Development Team
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are
6     * met:
7     *
8     * 1.Redistributions of source code must retain the above copyright notice,
9     * this list of conditions and the following disclaimer.
10     * 2.Redistributions in binary form must reproduce the above copyright
11     * notice, this list of conditions and the following disclaimer in the
12     * documentation and/or other materials provided with the distribution.
13     * 3.The name of the author may not be used to endorse or promote products
14     * derived from this software without specific prior written permission.
15     *
16     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19     * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20     * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22     * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24     * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25     * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26     * POSSIBILITY OF SUCH DAMAGE.
27     *
28 knight 31 * $Id$
29 adx 30 */
30    
31     #include "stdinc.h"
32     #include "handlers.h"
33     #include "client.h"
34     #include "common.h" /* FALSE bleah */
35     #include "ircd.h"
36     #include "irc_string.h"
37     #include "numeric.h"
38     #include "fdlist.h"
39     #include "hash.h"
40     #include "s_bsd.h"
41     #include "s_conf.h"
42     #include "s_serv.h"
43     #include "send.h"
44     #include "msg.h"
45     #include "parse.h"
46     #include "modules.h"
47     #include "channel.h"
48     #include "channel_mode.h"
49    
50     static void mo_forcejoin(struct Client *, struct Client *, int parc, char *[]);
51     static void mo_forcepart(struct Client *, struct Client *, int parc, char *[]);
52    
53     struct Message forcejoin_msgtab = {
54     "FORCEJOIN", 0, 0, 3, 0, MFLG_SLOW, 0,
55     { m_ignore, m_not_oper, mo_forcejoin, mo_forcejoin, mo_forcejoin, m_ignore }
56     };
57    
58     struct Message forcepart_msgtab = {
59     "FORCEPART", 0, 0, 3, 0, MFLG_SLOW, 0,
60     { m_ignore, m_not_oper, mo_forcepart, mo_forcepart, mo_forcepart, m_ignore }
61     };
62    
63     #ifndef STATIC_MODULES
64     void
65     _modinit(void)
66     {
67     mod_add_cmd(&forcejoin_msgtab);
68     mod_add_cmd(&forcepart_msgtab);
69     }
70    
71     void
72     _moddeinit(void)
73     {
74     mod_del_cmd(&forcejoin_msgtab);
75     mod_del_cmd(&forcepart_msgtab);
76     }
77    
78 knight 31 const char *_version = "$Revision$";
79 adx 30 #endif
80    
81     /* m_forcejoin()
82     * parv[0] = sender prefix
83     * parv[1] = user to force
84     * parv[2] = channel to force them into
85     */
86     static void
87     mo_forcejoin(struct Client *client_p, struct Client *source_p,
88     int parc, char *parv[])
89     {
90     struct Client *target_p = NULL;
91     struct Channel *chptr = NULL;
92     unsigned int type = 0;
93     char mode = '\0';
94     char sjmode = '\0';
95     char *newch = NULL;
96 michael 632 dlink_node *ptr = NULL;
97 adx 30
98     if (!IsAdmin(source_p))
99     {
100     sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
101     me.name, source_p->name);
102     return;
103     }
104    
105 michael 545 if ((target_p = find_client(parv[1])) == NULL || !IsClient(target_p))
106 adx 30 {
107     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
108     me.name, source_p->name, parv[1]);
109     return;
110     }
111    
112     if (!MyConnect(target_p))
113     {
114     if (target_p->from != client_p)
115     {
116     if (IsCapable(target_p->from, CAP_ENCAP))
117     sendto_one(target_p, ":%s ENCAP %s FORCEJOIN %s %s",
118     source_p->name, target_p->from->name,
119     target_p->name, parv[2]);
120     else
121     sendto_one(target_p, ":%s FORCEJOIN %s %s",
122     source_p->name, target_p->name, parv[2]);
123     }
124    
125     return;
126     }
127    
128     /* select our modes from parv[2] if they exist... (chanop)*/
129     switch (*parv[2])
130     {
131     case '@':
132     type = CHFL_CHANOP;
133     mode = 'o';
134     sjmode = '@';
135     parv[2]++;
136     break;
137     #ifdef HALFOPS
138     case '%':
139     type = CHFL_HALFOP;
140     mode = 'h';
141     sjmode = '%';
142     parv[2]++;
143     break;
144     #endif
145     case '+':
146     type = CHFL_VOICE;
147     mode = 'v';
148     sjmode = '+';
149     parv[2]++;
150     break;
151     default:
152     type = 0;
153     mode = sjmode = '\0'; /* make sure sjmode is 0. sjoin depends on it */
154     break;
155     }
156    
157     if ((chptr = hash_find_channel(parv[2])) != NULL)
158     {
159     if (IsMember(target_p, chptr))
160     {
161     sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s",
162     me.name, source_p->name, target_p->name, chptr->chname);
163     return;
164     }
165    
166     add_user_to_channel(chptr, target_p, type, NO);
167    
168     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
169     target_p->name, target_p->username,
170     target_p->host, chptr->chname);
171    
172     if (sjmode)
173     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +%c %s",
174     me.name, chptr->chname, mode, target_p->name);
175    
176     if (chptr->chname[0] == '#')
177     {
178     if (sjmode)
179 michael 632 {
180 adx 356 DLINK_FOREACH (ptr, serv_list.head)
181     {
182     struct Client *serv_p = ptr->data;
183     if (serv_p == target_p->from || IsDead(serv_p))
184     continue;
185    
186     sendto_one(serv_p, ":%s SJOIN %lu %s + :%c%s",
187     ID_or_name(&me, serv_p), (unsigned long)chptr->channelts,
188     chptr->chname, (sjmode == '%' &&
189     !IsCapable(serv_p, CAP_HOPS)) ? '@' : sjmode,
190     ID_or_name(target_p, serv_p));
191     }
192 michael 632 }
193 adx 30 else
194     {
195     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
196     ":%s SJOIN %lu %s + :%s",
197     me.id, (unsigned long)chptr->channelts,
198     chptr->chname, target_p->id);
199     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
200     ":%s SJOIN %lu %s + :%s",
201     me.name, (unsigned long)chptr->channelts,
202     chptr->chname, target_p->name);
203     }
204     }
205    
206     if (chptr->topic != NULL)
207     {
208     sendto_one(target_p, form_str(RPL_TOPIC),
209     me.name, target_p->name,
210     chptr->chname, chptr->topic);
211     sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
212     me.name, source_p->name, chptr->chname,
213     chptr->topic_info, chptr->topic_time);
214     }
215    
216     target_p->localClient->last_join_time = CurrentTime;
217     channel_member_names(target_p, chptr, 1);
218     }
219     else
220     {
221     newch = parv[2];
222    
223 michael 632 if (!check_channel_name(newch, 1))
224 adx 30 {
225     sendto_one(source_p, form_str(ERR_BADCHANNAME),
226     me.name, source_p->name, newch);
227     return;
228     }
229    
230 michael 632 /*
231     * it would be interesting here to allow an oper
232 adx 30 * to force target_p into a channel that doesn't exist
233     * even more so, into a local channel when we disable
234     * local channels... but...
235     * I don't want to break anything - scuzzy
236     */
237     if (ConfigChannel.disable_local_channels && (*newch == '&'))
238     {
239     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
240     me.name, source_p->name, newch);
241     return;
242     }
243    
244 michael 632 chptr = make_channel(newch);
245 adx 30 add_user_to_channel(chptr, target_p, CHFL_CHANOP, NO);
246    
247     /* send out a join, make target_p join chptr */
248     if (chptr->chname[0] == '#')
249     {
250     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
251     ":%s SJOIN %lu %s +nt :@%s",
252     me.id, (unsigned long)chptr->channelts,
253     chptr->chname, ID(target_p));
254     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
255     ":%s SJOIN %lu %s +nt :@%s",
256     me.name, (unsigned long)chptr->channelts,
257     chptr->chname, target_p->name);
258     }
259    
260     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
261     target_p->name, target_p->username,
262     target_p->host, chptr->chname);
263    
264     chptr->mode.mode |= MODE_TOPICLIMIT | MODE_NOPRIVMSGS;
265    
266     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +nt",
267     me.name, chptr->chname);
268    
269     target_p->localClient->last_join_time = CurrentTime;
270     channel_member_names(target_p, chptr, 1);
271    
272     /* we do this to let the oper know that a channel was created, this will be
273     * seen from the server handling the command instead of the server that
274     * the oper is on.
275     */
276     sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s",
277     me.name, source_p->name, chptr->chname);
278     }
279     }
280    
281     static void
282     mo_forcepart(struct Client *client_p, struct Client *source_p,
283     int parc, char *parv[])
284     {
285     struct Client *target_p = NULL;
286     struct Channel *chptr = NULL;
287     struct Membership *member = NULL;
288    
289     if (!IsAdmin(source_p))
290     {
291     sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
292     me.name, source_p->name);
293     return;
294     }
295    
296     /* if target_p == NULL then let the oper know */
297 michael 490 if ((target_p = find_client(parv[1])) == NULL || !IsClient(target_p))
298 adx 30 {
299     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
300     me.name, source_p->name, parv[1]);
301     return;
302     }
303    
304     if (!MyConnect(target_p))
305     {
306     if (target_p->from != client_p)
307     {
308     if (IsCapable(target_p->from, CAP_ENCAP))
309     sendto_one(target_p, ":%s ENCAP %s FORCEPART %s %s",
310     source_p->name, target_p->from->name,
311     target_p->name, parv[2]);
312     else
313     sendto_one(target_p, ":%s FORCEPART %s %s",
314     source_p->name, target_p->name, parv[2]);
315     }
316    
317     return;
318     }
319    
320     if ((chptr = hash_find_channel(parv[2])) == NULL)
321     {
322     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
323     me.name, source_p->name, parv[2]);
324     return;
325     }
326    
327     if ((member = find_channel_link(target_p, chptr)) == NULL)
328     {
329     sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
330     me.name, source_p->name, chptr->chname, target_p->name);
331     return;
332     }
333    
334     if (chptr->chname[0] == '#')
335     {
336     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
337     ":%s PART %s :%s", ID(target_p),
338     chptr->chname, target_p->name);
339     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
340     ":%s PART %s :%s", target_p->name,
341     chptr->chname, target_p->name);
342     }
343    
344     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s :%s",
345     target_p->name, target_p->username,
346     target_p->host, chptr->chname,
347     target_p->name);
348     remove_user_from_channel(member);
349     }

Properties

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