Initial import
[ratbox-ambernet.git] / contrib / m_force.c
blobf696b5014772135d6575bb3b5500ddc20412e07b
1 /* contrib/m_force.c
2 * Copyright (C) 1996-2002 Hybrid Development Team
3 * Copyright (C) 2004 ircd-ratbox Development Team
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
9 * 1.Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2.Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3.The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * $Id: m_force.c 16480 2004-04-05 02:38:04Z leeh $
32 #include "stdinc.h"
33 #include "tools.h"
34 #include "channel.h"
35 #include "class.h"
36 #include "client.h"
37 #include "common.h"
38 #include "irc_string.h"
39 #include "sprintf_irc.h"
40 #include "ircd.h"
41 #include "hostmask.h"
42 #include "numeric.h"
43 #include "commio.h"
44 #include "s_conf.h"
45 #include "s_newconf.h"
46 #include "s_log.h"
47 #include "send.h"
48 #include "hash.h"
49 #include "s_serv.h"
50 #include "msg.h"
51 #include "parse.h"
52 #include "modules.h"
53 #include "event.h"
56 static int mo_forcejoin(struct Client *client_p, struct Client *source_p,
57 int parc, const char *parv[]);
58 static int mo_forcepart(struct Client *client_p, struct Client *source_p,
59 int parc, const char *parv[]);
61 struct Message forcejoin_msgtab = {
62 "FORCEJOIN", 0, 0, 0, MFLG_SLOW,
63 {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_forcejoin, 3}}
66 struct Message forcepart_msgtab = {
67 "FORCEPART", 0, 0, 0, MFLG_SLOW,
68 {mg_unreg, mg_not_oper, mg_ignore, mg_ignore, mg_ignore, {mo_forcepart, 3}}
71 mapi_clist_av1 force_clist[] = { &forcejoin_msgtab, &forcepart_msgtab, NULL };
73 DECLARE_MODULE_AV1(force, NULL, NULL, force_clist, NULL, NULL, "$Revision: 16480 $");
76 * m_forcejoin
77 * parv[0] = sender prefix
78 * parv[1] = user to force
79 * parv[2] = channel to force them into
81 static int
82 mo_forcejoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
84 struct Client *target_p;
85 struct Channel *chptr;
86 int type;
87 char mode;
88 char sjmode;
89 char *newch;
91 if(!IsOperAdmin(source_p))
93 sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcejoin");
94 return 0;
97 if((hunt_server(client_p, source_p, ":%s FORCEJOIN %s %s", 1, parc, parv)) != HUNTED_ISME)
98 return 0;
100 /* if target_p is not existant, print message
101 * to source_p and bail - scuzzy
103 if((target_p = find_client(parv[1])) == NULL)
105 sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]);
106 return 0;
109 if(!IsPerson(target_p))
110 return 0;
112 /* select our modes from parv[2] if they exist... (chanop) */
113 if(*parv[2] == '@')
115 type = CHFL_CHANOP;
116 mode = 'o';
117 sjmode = '@';
119 else if(*parv[2] == '+')
121 type = CHFL_VOICE;
122 mode = 'v';
123 sjmode = '+';
125 else
127 type = CHFL_PEON;
128 mode = sjmode = '\0';
131 if(mode != '\0')
132 parv[2]++;
134 if((chptr = find_channel(parv[2])) != NULL)
136 if(IsMember(target_p, chptr))
138 /* debugging is fun... */
139 sendto_one(source_p, ":%s NOTICE %s :*** Notice -- %s is already in %s",
140 me.name, source_p->name, target_p->name, chptr->chname);
141 return 0;
144 add_user_to_channel(chptr, target_p, type);
146 sendto_server(target_p, chptr, NOCAPS, NOCAPS,
147 ":%s SJOIN %ld %s + :%c%s",
148 me.name, (long) chptr->channelts,
149 chptr->chname, type ? sjmode : ' ', target_p->name);
151 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
152 target_p->name, target_p->username,
153 target_p->host, chptr->chname);
155 if(type)
156 sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +%c %s",
157 me.name, chptr->chname, mode, target_p->name);
159 if(chptr->topic != NULL)
161 sendto_one(target_p, form_str(RPL_TOPIC), me.name,
162 target_p->name, chptr->chname, chptr->topic);
163 sendto_one(target_p, form_str(RPL_TOPICWHOTIME),
164 me.name, source_p->name, chptr->chname,
165 chptr->topic_info, chptr->topic_time);
168 channel_member_names(chptr, target_p, 1);
170 else
172 newch = LOCAL_COPY(parv[2]);
173 if(!check_channel_name(newch))
175 sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
176 source_p->name, (unsigned char *) newch);
177 return 0;
180 /* channel name must begin with & or # */
181 if(!IsChannelName(newch))
183 sendto_one(source_p, form_str(ERR_BADCHANNAME), me.name,
184 source_p->name, (unsigned char *) newch);
185 return 0;
188 /* newch can't be longer than CHANNELLEN */
189 if(strlen(newch) > CHANNELLEN)
191 sendto_one(source_p, ":%s NOTICE %s :Channel name is too long", me.name,
192 source_p->name);
193 return 0;
196 chptr = get_or_create_channel(target_p, newch, NULL);
197 add_user_to_channel(chptr, target_p, CHFL_CHANOP);
199 /* send out a join, make target_p join chptr */
200 sendto_server(target_p, chptr, NOCAPS, NOCAPS,
201 ":%s SJOIN %ld %s +nt :@%s", me.name,
202 (long) chptr->channelts, chptr->chname, target_p->name);
204 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
205 target_p->name, target_p->username,
206 target_p->host, chptr->chname);
208 chptr->mode.mode |= MODE_TOPICLIMIT;
209 chptr->mode.mode |= MODE_NOPRIVMSGS;
211 sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s +nt", me.name, chptr->chname);
213 target_p->localClient->last_join_time = CurrentTime;
214 channel_member_names(chptr, target_p, 1);
216 /* we do this to let the oper know that a channel was created, this will be
217 * seen from the server handling the command instead of the server that
218 * the oper is on.
220 sendto_one(source_p, ":%s NOTICE %s :*** Notice -- Creating channel %s", me.name,
221 source_p->name, chptr->chname);
223 return 0;
227 static int
228 mo_forcepart(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
230 struct Client *target_p;
231 struct Channel *chptr;
232 struct membership *msptr;
234 if(!IsOperAdmin(source_p))
236 sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, source_p->name, "forcepart");
237 return 0;
240 if((hunt_server(client_p, source_p, ":%s FORCEPART %s %s", 1, parc, parv)) != HUNTED_ISME)
241 return 0;
243 /* if target_p == NULL then let the oper know */
244 if((target_p = find_client(parv[1])) == NULL)
246 sendto_one(source_p, form_str(ERR_NOSUCHNICK), me.name, source_p->name, parv[1]);
247 return 0;
250 if(!IsClient(target_p))
251 return 0;
254 if((chptr = find_channel(parv[2])) == NULL)
256 sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
257 form_str(ERR_NOSUCHCHANNEL), parv[1]);
258 return 0;
261 if((msptr = find_channel_membership(chptr, target_p)) == NULL)
263 sendto_one(source_p, form_str(ERR_USERNOTINCHANNEL),
264 me.name, parv[0], parv[1], parv[2]);
265 return 0;
268 sendto_server(target_p, chptr, NOCAPS, NOCAPS,
269 ":%s PART %s :%s", target_p->name, chptr->chname, target_p->name);
271 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s :%s",
272 target_p->name, target_p->username,
273 target_p->host, chptr->chname, target_p->name);
276 remove_user_from_channel(msptr);
278 return 0;