ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/contrib/m_force.c
Revision: 356
Committed: Mon Jan 2 22:05:15 2006 UTC (20 years, 9 months ago) by adx
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/contrib/m_force.c
File size: 11190 byte(s)
Log Message:
+ MFC support for halfop->op rewriting.

File Contents

# User Rev Content
1 adx 30 /* 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 knight 31 * $Id$
29 adx 30 */
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 knight 31 const char *_version = "$Revision$";
79 adx 30 #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 adx 356 dlink_node *ptr;
97 adx 30
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)
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 adx 356 DLINK_FOREACH (ptr, serv_list.head)
180     {
181     struct Client *serv_p = ptr->data;
182     if (serv_p == target_p->from || IsDead(serv_p))
183     continue;
184    
185     sendto_one(serv_p, ":%s SJOIN %lu %s + :%c%s",
186     ID_or_name(&me, serv_p), (unsigned long)chptr->channelts,
187     chptr->chname, (sjmode == '%' &&
188     !IsCapable(serv_p, CAP_HOPS)) ? '@' : sjmode,
189     ID_or_name(target_p, serv_p));
190     }
191 adx 30 else
192     {
193     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
194     ":%s SJOIN %lu %s + :%s",
195     me.id, (unsigned long)chptr->channelts,
196     chptr->chname, target_p->id);
197     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
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 != NULL)
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, source_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) == 0)
222     {
223     sendto_one(source_p, form_str(ERR_BADCHANNAME),
224     me.name, source_p->name, newch);
225     return;
226     }
227    
228     /* channel name must begin with & or # */
229     if (!IsChanPrefix(*newch))
230     {
231     sendto_one(source_p, form_str(ERR_BADCHANNAME),
232     me.name, source_p->name, newch);
233     return;
234     }
235    
236     /* it would be interesting here to allow an oper
237     * to force target_p into a channel that doesn't exist
238     * even more so, into a local channel when we disable
239     * local channels... but...
240     * I don't want to break anything - scuzzy
241     */
242     if (ConfigChannel.disable_local_channels && (*newch == '&'))
243     {
244     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
245     me.name, source_p->name, newch);
246     return;
247     }
248    
249     /* newch can't be longer than CHANNELLEN */
250     if (strlen(newch) > CHANNELLEN)
251     {
252     sendto_one(source_p, form_str(ERR_BADCHANNAME),
253     me.name, source_p->name, newch);
254     return;
255     }
256    
257     chptr = get_or_create_channel(target_p, newch, NULL);
258     add_user_to_channel(chptr, target_p, CHFL_CHANOP, NO);
259    
260     /* send out a join, make target_p join chptr */
261     if (chptr->chname[0] == '#')
262     {
263     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
264     ":%s SJOIN %lu %s +nt :@%s",
265     me.id, (unsigned long)chptr->channelts,
266     chptr->chname, ID(target_p));
267     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
268     ":%s SJOIN %lu %s +nt :@%s",
269     me.name, (unsigned long)chptr->channelts,
270     chptr->chname, target_p->name);
271     }
272    
273     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
274     target_p->name, target_p->username,
275     target_p->host, chptr->chname);
276    
277     chptr->mode.mode |= MODE_TOPICLIMIT | MODE_NOPRIVMSGS;
278    
279     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s +nt",
280     me.name, chptr->chname);
281    
282     target_p->localClient->last_join_time = CurrentTime;
283     channel_member_names(target_p, chptr, 1);
284    
285     /* we do this to let the oper know that a channel was created, this will be
286     * seen from the server handling the command instead of the server that
287     * the oper is on.
288     */
289     sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s",
290     me.name, source_p->name, chptr->chname);
291     }
292     }
293    
294     static void
295     mo_forcepart(struct Client *client_p, struct Client *source_p,
296     int parc, char *parv[])
297     {
298     struct Client *target_p = NULL;
299     struct Channel *chptr = NULL;
300     struct Membership *member = NULL;
301    
302     if (!IsAdmin(source_p))
303     {
304     sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
305     me.name, source_p->name);
306     return;
307     }
308    
309     /* if target_p == NULL then let the oper know */
310     if ((target_p = find_client(parv[1])) == NULL)
311     {
312     sendto_one(source_p, form_str(ERR_NOSUCHNICK),
313     me.name, source_p->name, parv[1]);
314     return;
315     }
316    
317     if (!MyConnect(target_p))
318     {
319     if (target_p->from != client_p)
320     {
321     if (IsCapable(target_p->from, CAP_ENCAP))
322     sendto_one(target_p, ":%s ENCAP %s FORCEPART %s %s",
323     source_p->name, target_p->from->name,
324     target_p->name, parv[2]);
325     else
326     sendto_one(target_p, ":%s FORCEPART %s %s",
327     source_p->name, target_p->name, parv[2]);
328     }
329    
330     return;
331     }
332    
333     if ((chptr = hash_find_channel(parv[2])) == NULL)
334     {
335     sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
336     me.name, source_p->name, parv[2]);
337     return;
338     }
339    
340     if ((member = find_channel_link(target_p, chptr)) == NULL)
341     {
342     sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
343     me.name, source_p->name, chptr->chname, target_p->name);
344     return;
345     }
346    
347     if (chptr->chname[0] == '#')
348     {
349     sendto_server(target_p, target_p, chptr, CAP_TS6, NOCAPS, LL_ICLIENT,
350     ":%s PART %s :%s", ID(target_p),
351     chptr->chname, target_p->name);
352     sendto_server(target_p, target_p, chptr, NOCAPS, CAP_TS6, LL_ICLIENT,
353     ":%s PART %s :%s", target_p->name,
354     chptr->chname, target_p->name);
355     }
356    
357     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s PART %s :%s",
358     target_p->name, target_p->username,
359     target_p->host, chptr->chname,
360     target_p->name);
361     remove_user_from_channel(member);
362     }

Properties

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