ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/m_force.c
Revision: 1243
Committed: Fri Sep 30 10:47:53 2011 UTC (15 years ago) by michael
Content type: text/x-csrc
File size: 10613 byte(s)
Error occurred while calculating annotation data.
Log Message:
- move content of msg.h, ircd_handler.h and handlers.h into parse.h and
  remove headers accordingly
- killed common.h
- remove m_killhost.c and m_flags.c from contrib/
- sort out unused header includes here and there

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

Properties

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