/[svn]/ircd-hybrid-7.2/contrib/m_force.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/contrib/m_force.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 632 - (show annotations)
Thu Jun 1 10:53:00 2006 UTC (13 years, 4 months ago) by michael
File MIME type: text/x-chdr
File size: 10817 byte(s)
- 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

1 /* 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 * $Id$
29 */
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 const char *_version = "$Revision$";
79 #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 dlink_node *ptr = NULL;
97
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 if ((target_p = find_client(parv[1])) == NULL || !IsClient(target_p))
106 {
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 {
180 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 }
193 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 if (!check_channel_name(newch, 1))
224 {
225 sendto_one(source_p, form_str(ERR_BADCHANNAME),
226 me.name, source_p->name, newch);
227 return;
228 }
229
230 /*
231 * it would be interesting here to allow an oper
232 * 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 chptr = make_channel(newch);
245 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 if ((target_p = find_client(parv[1])) == NULL || !IsClient(target_p))
298 {
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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26