ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/contrib/m_force.c
Revision: 76
Committed: Tue Oct 4 19:38:49 2005 UTC (19 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 11129 byte(s)
Log Message:
- fixed contrib #includes

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

Properties

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