ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/contrib/m_force.c
Revision: 30
Committed: Sun Oct 2 20:03:27 2005 UTC (18 years, 5 months ago) by adx
Content type: text/x-csrc
File size: 11250 byte(s)
Log Message:
- imported sources
- can be moved later according to the directory/branching scheme,
  but we need the svn up

File Contents

# Content
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: m_force.c,v 1.43 2005/10/01 14:29:47 michael Exp $
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: 1.43 $";
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
97 if (!IsAdmin(source_p))
98 {
99 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
100 me.name, source_p->name);
101 return;
102 }
103
104 if ((target_p = find_client(parv[1])) == NULL)
105 {
106 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
107 me.name, source_p->name, parv[1]);
108 return;
109 }
110
111 if (!MyConnect(target_p))
112 {
113 if (target_p->from != client_p)
114 {
115 if (IsCapable(target_p->from, CAP_ENCAP))
116 sendto_one(target_p, ":%s ENCAP %s FORCEJOIN %s %s",
117 source_p->name, target_p->from->name,
118 target_p->name, parv[2]);
119 else
120 sendto_one(target_p, ":%s FORCEJOIN %s %s",
121 source_p->name, target_p->name, parv[2]);
122 }
123
124 return;
125 }
126
127 /* select our modes from parv[2] if they exist... (chanop)*/
128 switch (*parv[2])
129 {
130 case '@':
131 type = CHFL_CHANOP;
132 mode = 'o';
133 sjmode = '@';
134 parv[2]++;
135 break;
136 #ifdef HALFOPS
137 case '%':
138 type = CHFL_HALFOP;
139 mode = 'h';
140 sjmode = '%';
141 parv[2]++;
142 break;
143 #endif
144 case '+':
145 type = CHFL_VOICE;
146 mode = 'v';
147 sjmode = '+';
148 parv[2]++;
149 break;
150 default:
151 type = 0;
152 mode = sjmode = '\0'; /* make sure sjmode is 0. sjoin depends on it */
153 break;
154 }
155
156 if ((chptr = hash_find_channel(parv[2])) != NULL)
157 {
158 if (IsMember(target_p, chptr))
159 {
160 sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s",
161 me.name, source_p->name, target_p->name, chptr->chname);
162 return;
163 }
164
165 add_user_to_channel(chptr, target_p, type, NO);
166
167 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
168 target_p->name, target_p->username,
169 target_p->host, chptr->chname);
170
171 if (sjmode)
172 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +%c %s",
173 me.name, chptr->chname, mode, target_p->name);
174
175 if (chptr->chname[0] == '#')
176 {
177 if (sjmode)
178 {
179 sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
180 ":%s SJOIN %lu %s + :%c%s",
181 me.id, (unsigned long)chptr->channelts,
182 chptr->chname, sjmode, target_p->id);
183 sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
184 ":%s SJOIN %lu %s + :%c%s",
185 me.name, (unsigned long)chptr->channelts,
186 chptr->chname, sjmode, target_p->name);
187 }
188 else
189 {
190 sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
191 ":%s SJOIN %lu %s + :%s",
192 me.id, (unsigned long)chptr->channelts,
193 chptr->chname, target_p->id);
194 sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
195 ":%s SJOIN %lu %s + :%s",
196 me.name, (unsigned long)chptr->channelts,
197 chptr->chname, target_p->name);
198 }
199 }
200
201 if (chptr->topic != NULL)
202 {
203 sendto_one(target_p, form_str(RPL_TOPIC),
204 me.name, target_p->name,
205 chptr->chname, chptr->topic);
206 sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
207 me.name, source_p->name, chptr->chname,
208 chptr->topic_info, chptr->topic_time);
209 }
210
211 target_p->localClient->last_join_time = CurrentTime;
212 channel_member_names(target_p, chptr, 1);
213 }
214 else
215 {
216 newch = parv[2];
217
218 if (check_channel_name(newch) == 0)
219 {
220 sendto_one(source_p, form_str(ERR_BADCHANNAME),
221 me.name, source_p->name, newch);
222 return;
223 }
224
225 /* channel name must begin with & or # */
226 if (!IsChanPrefix(*newch))
227 {
228 sendto_one(source_p, form_str(ERR_BADCHANNAME),
229 me.name, source_p->name, newch);
230 return;
231 }
232
233 /* it would be interesting here to allow an oper
234 * to force target_p into a channel that doesn't exist
235 * even more so, into a local channel when we disable
236 * local channels... but...
237 * I don't want to break anything - scuzzy
238 */
239 if (ConfigChannel.disable_local_channels && (*newch == '&'))
240 {
241 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
242 me.name, source_p->name, newch);
243 return;
244 }
245
246 /* newch can't be longer than CHANNELLEN */
247 if (strlen(newch) > CHANNELLEN)
248 {
249 sendto_one(source_p, form_str(ERR_BADCHANNAME),
250 me.name, source_p->name, newch);
251 return;
252 }
253
254 chptr = get_or_create_channel(target_p, newch, NULL);
255 add_user_to_channel(chptr, target_p, CHFL_CHANOP, NO);
256
257 /* send out a join, make target_p join chptr */
258 if (chptr->chname[0] == '#')
259 {
260 sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
261 ":%s SJOIN %lu %s +nt :@%s",
262 me.id, (unsigned long)chptr->channelts,
263 chptr->chname, ID(target_p));
264 sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
265 ":%s SJOIN %lu %s +nt :@%s",
266 me.name, (unsigned long)chptr->channelts,
267 chptr->chname, target_p->name);
268 }
269
270 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
271 target_p->name, target_p->username,
272 target_p->host, chptr->chname);
273
274 chptr->mode.mode |= MODE_TOPICLIMIT | MODE_NOPRIVMSGS;
275
276 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +nt",
277 me.name, chptr->chname);
278
279 target_p->localClient->last_join_time = CurrentTime;
280 channel_member_names(target_p, chptr, 1);
281
282 /* we do this to let the oper know that a channel was created, this will be
283 * seen from the server handling the command instead of the server that
284 * the oper is on.
285 */
286 sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s",
287 me.name, source_p->name, chptr->chname);
288 }
289 }
290
291 static void
292 mo_forcepart(struct Client *client_p, struct Client *source_p,
293 int parc, char *parv[])
294 {
295 struct Client *target_p = NULL;
296 struct Channel *chptr = NULL;
297 struct Membership *member = NULL;
298
299 if (!IsAdmin(source_p))
300 {
301 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
302 me.name, source_p->name);
303 return;
304 }
305
306 /* if target_p == NULL then let the oper know */
307 if ((target_p = find_client(parv[1])) == NULL)
308 {
309 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
310 me.name, source_p->name, parv[1]);
311 return;
312 }
313
314 if (!MyConnect(target_p))
315 {
316 if (target_p->from != client_p)
317 {
318 if (IsCapable(target_p->from, CAP_ENCAP))
319 sendto_one(target_p, ":%s ENCAP %s FORCEPART %s %s",
320 source_p->name, target_p->from->name,
321 target_p->name, parv[2]);
322 else
323 sendto_one(target_p, ":%s FORCEPART %s %s",
324 source_p->name, target_p->name, parv[2]);
325 }
326
327 return;
328 }
329
330 if ((chptr = hash_find_channel(parv[2])) == NULL)
331 {
332 sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
333 me.name, source_p->name, parv[2]);
334 return;
335 }
336
337 if ((member = find_channel_link(target_p, chptr)) == NULL)
338 {
339 sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
340 me.name, source_p->name, chptr->chname, target_p->name);
341 return;
342 }
343
344 if (chptr->chname[0] == '#')
345 {
346 sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
347 ":%s PART %s :%s", ID(target_p),
348 chptr->chname, target_p->name);
349 sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
350 ":%s PART %s :%s", target_p->name,
351 chptr->chname, target_p->name);
352 }
353
354 sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s :%s",
355 target_p->name, target_p->username,
356 target_p->host, chptr->chname,
357 target_p->name);
358 remove_user_from_channel(member);
359 }

Properties

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