X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fchannels.cpp;h=f067646d3358656ff94647e8846d1bf2ee7058e5;hb=0a58b25ad736e7cec4944eb89e10f617d74225a0;hp=c51321a64348031d1950652a123db2d5cb479aa6;hpb=6f009062aa0dc1df7c5d24a7f321d1e75bca3f34;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/channels.cpp b/src/channels.cpp index c51321a64..f067646d3 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * Inspire is copyright (C) 2002-2005 ChatSpike-Dev. + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. * E-mail: * * @@ -94,7 +94,7 @@ void chanrec::SetCustomMode(char mode,bool mode_on) std::string a = this->custom_modes; int pos = a.find(mode); a.erase(pos,1); - strncpy(this->custom_modes,a.c_str(),MAXMODES); + strlcpy(this->custom_modes,a.c_str(),MAXMODES); log(DEBUG,"Custom mode %c removed: modelist='%s'",mode,this->custom_modes); this->SetCustomModeParam(mode,"",false); @@ -160,29 +160,96 @@ long chanrec::GetUserCounter() void chanrec::AddUser(char* castuser) { - internal_userlist.push_back(castuser); + internal_userlist[castuser] = castuser; log(DEBUG,"Added casted user to channel's internal list"); } void chanrec::DelUser(char* castuser) { - for (std::vector::iterator a = internal_userlist.begin(); a < internal_userlist.end(); a++) + std::map::iterator a = internal_userlist.find(castuser); + if (a != internal_userlist.end()) { - if (*a == castuser) - { - log(DEBUG,"Removed casted user from channel's internal list"); - internal_userlist.erase(a); - return; - } + log(DEBUG,"Removed casted user from channel's internal list"); + internal_userlist.erase(a); + return; } - log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name); + /* Tidy up any others */ + DelOppedUser(castuser); + DelHalfoppedUser(castuser); + DelVoicedUser(castuser); +} + +void chanrec::AddOppedUser(char* castuser) +{ + internal_op_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelOppedUser(char* castuser) +{ + std::map::iterator a = internal_op_userlist.find(castuser); + if (a != internal_op_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_op_userlist.erase(a); + return; + } +} + +void chanrec::AddHalfoppedUser(char* castuser) +{ + internal_halfop_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelHalfoppedUser(char* castuser) +{ + std::map::iterator a = internal_halfop_userlist.find(castuser); + if (a != internal_halfop_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_halfop_userlist.erase(a); + return; + } +} + +void chanrec::AddVoicedUser(char* castuser) +{ + internal_voice_userlist[castuser] = castuser; + log(DEBUG,"Added casted user to channel's internal list"); +} + +void chanrec::DelVoicedUser(char* castuser) +{ + std::map::iterator a = internal_voice_userlist.find(castuser); + if (a != internal_voice_userlist.end()) + { + log(DEBUG,"Removed casted user from channel's internal list"); + internal_voice_userlist.erase(a); + return; + } } -std::vector *chanrec::GetUsers() +std::map *chanrec::GetUsers() { return &internal_userlist; } +std::map *chanrec::GetOppedUsers() +{ + return &internal_op_userlist; +} + +std::map *chanrec::GetHalfoppedUsers() +{ + return &internal_halfop_userlist; +} + +std::map *chanrec::GetVoicedUsers() +{ + return &internal_voice_userlist; +} + /* add a channel to a user, creating the record for it if needed and linking * it to the user record */ @@ -197,7 +264,8 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri int created = 0; char cname[MAXBUF]; int MOD_RESULT = 0; - strncpy(cname,cn,CHANMAX); + strlcpy(cname,cn,CHANMAX); + log(DEBUG,"cname='%s' cn='%s'",cname,cn); log(DEBUG,"add_channel: %s %s",user->nick,cname); @@ -218,7 +286,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri chanlist[cname]->binarymodes = CM_TOPICLOCK | CM_NOEXTERNAL; chanlist[cname]->created = TIME; *chanlist[cname]->topic = 0; - strncpy(chanlist[cname]->setby, user->nick,NICKMAX); + strlcpy(chanlist[cname]->setby, user->nick,NICKMAX); chanlist[cname]->topicset = 0; Ptr = chanlist[cname]; log(DEBUG,"add_channel: created: %s",cname); @@ -311,7 +379,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri { for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++) { - if (match(user->GetFullHost(),i->data)) + if ((match(user->GetFullHost(),i->data)) || (match(user->GetFullRealHost(),i->data))) { WriteServ(user->fd,"474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name); return NULL; @@ -370,6 +438,7 @@ chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created) { /* first user in is given ops */ a.uc_modes = UCMODE_OP; + Ptr->AddOppedUser((char*)user); } else { @@ -406,7 +475,6 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool if (!Ptr) return NULL; - FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr)); log(DEBUG,"del_channel: removing: %s %s",user->nick,Ptr->name); for (unsigned int i =0; i < user->chans.size(); i++) @@ -416,10 +484,12 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool { if (reason) { + FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr,reason)); WriteChannel(Ptr,user,"PART %s :%s",Ptr->name, reason); } else { + FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr,"")); WriteChannel(Ptr,user,"PART :%s",Ptr->name); } user->chans[i].uc_modes = 0; @@ -442,6 +512,7 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool if (iter != chanlist.end()) { log(DEBUG,"del_channel: destroyed: %s",Ptr->name); + FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr)); delete Ptr; chanlist.erase(iter); } @@ -450,58 +521,103 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool return NULL; } - -void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) +void server_kick_channel(userrec* user, chanrec* Ptr, char* reason, bool triggerevents) { - if ((!src) || (!user) || (!Ptr) || (!reason)) - { - log(DEFAULT,"*** BUG *** kick_channel was given an invalid parameter"); - return; - } - - if ((!Ptr) || (!user) || (!src)) - { - return; - } + if ((!user) || (!Ptr) || (!reason)) + { + return; + } - log(DEBUG,"kick_channel: removing: %s %s %s",user->nick,Ptr->name,src->nick); + if (IS_LOCAL(user)) + { + if (!has_channel(user,Ptr)) + { + /* Not on channel */ + return; + } + } + + if (triggerevents) + { + FOREACH_MOD(I_OnUserKick,OnUserKick(NULL,user,Ptr,reason)); + } - if (!has_channel(user,Ptr)) - { - WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name); - return; - } + for (unsigned int i =0; i < user->chans.size(); i++) + { + if (user->chans[i].channel) + if (!strcasecmp(user->chans[i].channel->name,Ptr->name)) + { + WriteChannelWithServ(Config->ServerName,Ptr,"KICK %s %s :%s",Ptr->name, user->nick, reason); + user->chans[i].uc_modes = 0; + user->chans[i].channel = NULL; + break; + } + } - int MOD_RESULT = 0; - FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(src,user,Ptr,AC_KICK)); - if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server))) - return; + Ptr->DelUser((char*)user); - if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server))) + if (!usercount(Ptr)) { - if ((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) + chan_hash::iterator iter = chanlist.find(Ptr->name); + log(DEBUG,"del_channel: destroying channel: %s",Ptr->name); + /* kill the record */ + if (iter != chanlist.end()) { - if (cstatus(src,Ptr) == STATUS_HOP) - { - WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name); - } - else - { - WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name); - } - - return; + log(DEBUG,"del_channel: destroyed: %s",Ptr->name); + FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr)); + delete Ptr; + chanlist.erase(iter); } } +} - if (!is_uline(src->server)) +void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) +{ + if ((!src) || (!user) || (!Ptr) || (!reason)) { - MOD_RESULT = 0; - FOREACH_RESULT(I_OnUserPreKick,OnUserPreKick(src,user,Ptr,reason)); - if (MOD_RESULT) - return; + log(DEFAULT,"*** BUG *** kick_channel was given an invalid parameter"); + return; } + log(DEBUG,"kick_channel: removing: %s %s %s",user->nick,Ptr->name,src->nick); + + if (IS_LOCAL(user)) + { + if (!has_channel(user,Ptr)) + { + WriteServ(src->fd,"441 %s %s %s :They are not on that channel",src->nick, user->nick, Ptr->name); + return; + } + int MOD_RESULT = 0; + FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(src,user,Ptr,AC_KICK)); + if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server))) + return; + + if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server))) + { + if ((cstatus(src,Ptr) < STATUS_HOP) || (cstatus(src,Ptr) < cstatus(user,Ptr))) + { + if (cstatus(src,Ptr) == STATUS_HOP) + { + WriteServ(src->fd,"482 %s %s :You must be a channel operator",src->nick, Ptr->name); + } + else + { + WriteServ(src->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",src->nick, Ptr->name); + } + + return; + } + } + if (!is_uline(src->server)) + { + MOD_RESULT = 0; + FOREACH_RESULT(I_OnUserPreKick,OnUserPreKick(src,user,Ptr,reason)); + if (MOD_RESULT) + return; + } + } + FOREACH_MOD(I_OnUserKick,OnUserKick(src,user,Ptr,reason)); for (unsigned int i =0; i < user->chans.size(); i++) @@ -531,6 +647,7 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason) if (iter != chanlist.end()) { log(DEBUG,"del_channel: destroyed: %s",Ptr->name); + FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr)); delete Ptr; chanlist.erase(iter); }