ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/m_force.c
Revision: 1219
Committed: Sun Sep 18 09:02:38 2011 UTC (12 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 10700 byte(s)
Log Message:
- Start cleaning up macros in client.h. Replace several ClientHasSomeCoolFlag()
with simple HasFlag/HasUMode macros.

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

Properties

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