/* contrib/m_force.c * Copyright (C) 1996-2002 Hybrid Development Team * Copyright (C) 2004 ircd-ratbox Development Team * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * 1.Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3.The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */#include "stdinc.h"#include "channel.h"#include "class.h"#include "client.h"#include "common.h"#include "match.h"#include "ircd.h"#include "hostmask.h"#include "numeric.h"#include "s_conf.h"#include "s_newconf.h"#include "logger.h"#include "send.h"#include "hash.h"#include "s_serv.h"#include "msg.h"#include "parse.h"#include "modules.h"staticintmo_forcejoin(structClient*client_p,structClient*source_p,intparc,constchar*parv[]);structMessageforcejoin_msgtab={"FORCEJOIN",0,0,0,MFLG_SLOW,{mg_unreg,mg_not_oper,mg_ignore,mg_ignore,mg_ignore,{mo_forcejoin,3}}};mapi_clist_av1force_clist[]={&forcejoin_msgtab,NULL};DECLARE_MODULE_AV1(force,NULL,NULL,force_clist,NULL,NULL,"$Revision: 3297 $");/* * m_forcejoin * parv[1] = user to force * parv[2] = channel to force them into */staticintmo_forcejoin(structClient*client_p,structClient*source_p,intparc,constchar*parv[]){structClient*target_p;structChannel*chptr;inttype;charmode;charsjmode;char*newch;if(!IsOperAdmin(source_p)){sendto_one(source_p,form_str(ERR_NOPRIVS),me.name,source_p->name,"admin");return0;}if((hunt_server(client_p,source_p,":%s FORCEJOIN %s %s",1,parc,parv))!=HUNTED_ISME)return0;/* if target_p is not existant, print message * to source_p and bail - scuzzy */if((target_p=find_client(parv[1]))==NULL){sendto_one(source_p,form_str(ERR_NOSUCHNICK),me.name,source_p->name,parv[1]);return0;}if(!IsPerson(target_p))return0;sendto_wallops_flags(UMODE_WALLOP,&me,"FORCEJOIN called for %s %s by %s!%s@%s",parv[1],parv[2],source_p->name,source_p->username,source_p->host);ilog(L_MAIN,"FORCEJOIN called for %s %s by %s!%s@%s",parv[1],parv[2],source_p->name,source_p->username,source_p->host);sendto_server(NULL,NULL,NOCAPS,NOCAPS,":%s WALLOPS :FORCEJOIN called for %s %s by %s!%s@%s",me.name,parv[1],parv[2],source_p->name,source_p->username,source_p->host);/* select our modes from parv[2] if they exist... (chanop) */if(*parv[2]=='@'){type=CHFL_CHANOP;mode='o';sjmode='@';}elseif(*parv[2]=='+'){type=CHFL_VOICE;mode='v';sjmode='+';}else{type=CHFL_PEON;mode=sjmode='\0';}if(mode!='\0')parv[2]++;if((chptr=find_channel(parv[2]))!=NULL){if(IsMember(target_p,chptr)){/* debugging is fun... */sendto_one_notice(source_p,":*** Notice -- %s is already in %s",target_p->name,chptr->chname);return0;}add_user_to_channel(chptr,target_p,type);sendto_server(target_p,chptr,NOCAPS,NOCAPS,":%s SJOIN %ld %s + :%c%s",me.name,(long)chptr->channelts,chptr->chname,type?sjmode:' ',target_p->name);sendto_channel_local(ALL_MEMBERS,chptr,":%s!%s@%s JOIN :%s",target_p->name,target_p->username,target_p->host,chptr->chname);if(type)sendto_channel_local(ALL_MEMBERS,chptr,":%s MODE %s +%c %s",me.name,chptr->chname,mode,target_p->name);if(chptr->topic!=NULL){sendto_one(target_p,form_str(RPL_TOPIC),me.name,target_p->name,chptr->chname,chptr->topic);sendto_one(target_p,form_str(RPL_TOPICWHOTIME),me.name,source_p->name,chptr->chname,chptr->topic_info,chptr->topic_time);}channel_member_names(chptr,target_p,1);}else{newch=LOCAL_COPY(parv[2]);if(!check_channel_name(newch)){sendto_one(source_p,form_str(ERR_BADCHANNAME),me.name,source_p->name,(unsignedchar*)newch);return0;}/* channel name must begin with & or # */if(!IsChannelName(newch)){sendto_one(source_p,form_str(ERR_BADCHANNAME),me.name,source_p->name,(unsignedchar*)newch);return0;}/* newch can't be longer than CHANNELLEN */if(strlen(newch)>CHANNELLEN){sendto_one_notice(source_p,":Channel name is too long");return0;}chptr=get_or_create_channel(target_p,newch,NULL);add_user_to_channel(chptr,target_p,CHFL_CHANOP);/* send out a join, make target_p join chptr */sendto_server(target_p,chptr,NOCAPS,NOCAPS,":%s SJOIN %ld %s +nt :@%s",me.name,(long)chptr->channelts,chptr->chname,target_p->name);sendto_channel_local(ALL_MEMBERS,chptr,":%s!%s@%s JOIN :%s",target_p->name,target_p->username,target_p->host,chptr->chname);chptr->mode.mode|=MODE_TOPICLIMIT;chptr->mode.mode|=MODE_NOPRIVMSGS;sendto_channel_local(ALL_MEMBERS,chptr,":%s MODE %s +nt",me.name,chptr->chname);target_p->localClient->last_join_time=rb_current_time();channel_member_names(chptr,target_p,1);/* we do this to let the oper know that a channel was created, this will be * seen from the server handling the command instead of the server that * the oper is on. */sendto_one_notice(source_p,":*** Notice -- Creating channel %s",chptr->chname);}return0;}