* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
- * Inspire is copyright (C) 2002-2005 ChatSpike-Dev.
+ * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
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);
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<char*>::iterator a = internal_userlist.begin(); a < internal_userlist.end(); a++)
+ std::map<char*,char*>::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<char*,char*>::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<char*,char*>::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<char*,char*>::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<char*> *chanrec::GetUsers()
+std::map<char*,char*> *chanrec::GetUsers()
{
return &internal_userlist;
}
+std::map<char*,char*> *chanrec::GetOppedUsers()
+{
+ return &internal_op_userlist;
+}
+
+std::map<char*,char*> *chanrec::GetHalfoppedUsers()
+{
+ return &internal_halfop_userlist;
+}
+
+std::map<char*,char*> *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 */
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);
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);
{
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;
{
/* first user in is given ops */
a.uc_modes = UCMODE_OP;
+ Ptr->AddOppedUser((char*)user);
}
else
{
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++)
{
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;
if (iter != chanlist.end())
{
log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr));
delete Ptr;
chanlist.erase(iter);
}
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++)
if (iter != chanlist.end())
{
log(DEBUG,"del_channel: destroyed: %s",Ptr->name);
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(Ptr));
delete Ptr;
chanlist.erase(iter);
}