Channel::Channel(InspIRCd* Instance, const std::string &cname, time_t ts) : ServerInstance(Instance)
{
- chan_hash::iterator findchan = ServerInstance->chanlist->find(name);
+ chan_hash::iterator findchan = ServerInstance->chanlist->find(cname);
if (findchan != Instance->chanlist->end())
throw CoreException("Cannot create duplicate channel " + cname);
void Channel::SetDefaultModes()
{
+ ServerInstance->Logs->Log("CHANNELS", DEBUG, "SetDefaultModes %s", ServerInstance->Config->DefaultModes);
irc::spacesepstream list(ServerInstance->Config->DefaultModes);
std::string modeseq;
std::string parameter;
if (IS_LOCAL(user) && override == false)
{
MOD_RESULT = 0;
- FOREACH_RESULT_I(Instance,I_OnUserPreJoin,OnUserPreJoin(user,NULL,cname,privs));
+ FOREACH_RESULT_I(Instance,I_OnUserPreJoin, OnUserPreJoin(user, NULL, cname, privs, key ? key : ""));
if (MOD_RESULT == 1)
return NULL;
}
if (IS_LOCAL(user) && override == false)
{
MOD_RESULT = 0;
- FOREACH_RESULT_I(Instance,I_OnUserPreJoin,OnUserPreJoin(user,Ptr,cname,privs));
+ FOREACH_RESULT_I(Instance,I_OnUserPreJoin, OnUserPreJoin(user, Ptr, cname, privs, key ? key : ""));
if (MOD_RESULT == 1)
{
return NULL;
}
/* As spotted by jilles, dont bother to set this on remote users */
- if (IS_LOCAL(user) && Ptr->GetUserCounter() == 1)
+ if (IS_LOCAL(user) && Ptr->GetUserCounter() == 0)
Ptr->SetDefaultModes();
return Channel::ForceChan(Instance, Ptr, user, privs, bursting);
char mask[MAXBUF];
int MOD_RESULT = 0;
FOREACH_RESULT(I_OnCheckBan,OnCheckBan(user, this));
- if (!MOD_RESULT)
+
+ if (MOD_RESULT == -1)
+ return true;
+ else if (MOD_RESULT == 0)
{
snprintf(mask, MAXBUF, "%s!%s@%s", user->nick, user->ident, user->GetIPString());
for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++)
return false;
}
+bool Channel::IsExtBanned(User *user, char type)
+{
+ // XXX. do we need events?
+ char mask[MAXBUF];
+ char *maskptr;
+
+ snprintf(mask, MAXBUF, "%s!%s@%s", user->nick, user->ident, user->GetIPString());
+
+ for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++)
+ {
+ if (i->data[0] != type || i->data[1] != ':')
+ continue;
+
+ // Iterate past char and : to get to the mask without doing a data copy(!)
+ maskptr = i->data;
+ maskptr++; // past the char
+ maskptr++; // past the :
+
+ /* This allows CIDR ban matching
+ *
+ * Full masked host Full unmasked host IP with/without CIDR
+ */
+ if ((match(user->GetFullHost(), maskptr)) || (match(user->GetFullRealHost(), maskptr)) || (match(mask, maskptr, true)))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Channel::PartUser
* remove a channel from a users record, and return the number of users left.
* Therefore, if this function returns 0 the caller should delete the Channel.
return this->GetUserCounter();
}
-long Channel::ServerKickUser(User* user, const char* reason, bool triggerevents)
+long Channel::ServerKickUser(User* user, const char* reason, bool triggerevents, const char* servername)
{
bool silent = false;
}
}
+ if (servername == NULL || *ServerInstance->Config->HideWhoisServer)
+ servername = ServerInstance->Config->ServerName;
+
if (triggerevents)
{
FOREACH_MOD(I_OnUserKick,OnUserKick(NULL, user, this, reason, silent));
if (i != user->chans.end())
{
if (!silent)
- this->WriteChannelWithServ(ServerInstance->Config->ServerName, "KICK %s %s :%s", this->name, user->nick, reason);
+ this->WriteChannelWithServ(servername, "KICK %s %s :%s", this->name, user->nick, reason);
user->chans.erase(i);
this->RemoveAllPrefixes(user);
void Channel::WriteAllExcept(User* user, bool serversource, char status, CUList &except_list, const std::string &text)
{
- CUList *ulist;
+ CUList *ulist = this->GetUsers();
char tb[MAXBUF];
- switch (status)
- {
- case '@':
- ulist = this->GetOppedUsers();
- break;
- case '%':
- ulist = this->GetHalfoppedUsers();
- break;
- case '+':
- ulist = this->GetVoicedUsers();
- break;
- default:
- ulist = this->GetUsers();
- break;
- }
-
snprintf(tb,MAXBUF,":%s %s",user->GetFullHost(),text.c_str());
std::string out = tb;
{
if ((IS_LOCAL(i->first)) && (except_list.find(i->first) == except_list.end()))
{
+ /* User doesnt have the status we're after */
+ if (status && !strchr(this->GetAllPrefixChars(i->first), status))
+ continue;
+
if (serversource)
i->first->WriteServ(text);
else
}
}
- dlen = curlen = snprintf(list,MAXBUF,"353 %s %c %s :", user->nick, this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name);
+ dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick, this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name);
int numusers = 0;
char* ptr = list + dlen;
continue;
}
- size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str());
-
- curlen += ptrlen;
- ptr += ptrlen;
-
- numusers++;
+ size_t ptrlen = 0;
if (curlen > (480-NICKMAX))
{
user->WriteServ(std::string(list));
/* reset our lengths */
- dlen = curlen = snprintf(list,MAXBUF,"353 %s %c %s :", user->nick, this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name);
+ dlen = curlen = snprintf(list,MAXBUF,"%s %c %s :", user->nick, this->IsModeSet('s') ? '@' : this->IsModeSet('p') ? '*' : '=', this->name);
ptr = list + dlen;
ptrlen = 0;
numusers = 0;
}
+
+ ptrlen = snprintf(ptr, MAXBUF, "%s%s ", prefixlist.c_str(), nick.c_str());
+
+ curlen += ptrlen;
+ ptr += ptrlen;
+
+ numusers++;
}
/* if whats left in the list isnt empty, send it */
if (numusers)
{
- user->WriteServ(std::string(list));
+ user->WriteNumeric(353,std::string(list));
}
user->WriteNumeric(366, "%s %s :End of /NAMES list.", user->nick, this->name);
return pf;
}
+
const char* Channel::GetAllPrefixChars(User* user)
{
static char prefix[MAXBUF];