#include "bancache.h"
#include "commands/cmd_whowas.h"
-typedef unsigned int uniq_id_t;
-class sent
-{
- uniq_id_t uniq_id;
- uniq_id_t* array;
- void init()
- {
- if (!array)
- array = new uniq_id_t[ServerInstance->SE->GetMaxFds()];
- memset(array, 0, ServerInstance->SE->GetMaxFds() * sizeof(uniq_id_t));
- uniq_id++;
- }
- public:
- sent() : uniq_id(static_cast<uniq_id_t>(-1)), array(NULL) {}
- inline uniq_id_t operator++()
- {
- if (++uniq_id == 0)
- init();
- return uniq_id;
- }
- inline uniq_id_t& operator[](int i)
- {
- return array[i];
- }
- ~sent()
- {
- delete[] array;
- }
-};
-
-static sent already_sent;
+already_sent_t LocalUser::already_sent_id = 0;
std::string User::ProcessNoticeMasks(const char *sm)
{
adding = false;
break;
case '*':
- for (unsigned char d = 'A'; d <= 'z'; d++)
+ for (unsigned char d = 'a'; d <= 'z'; d++)
{
- if (ServerInstance->SNO->IsEnabled(d))
+ if (!ServerInstance->SNO->masks[d - 'a'].Description.empty())
{
if ((!IsNoticeMaskSet(d) && adding) || (IsNoticeMaskSet(d) && !adding))
{
output += d;
}
+ oldadding = adding;
+ char u = toupper(d);
+ if ((!IsNoticeMaskSet(u) && adding) || (IsNoticeMaskSet(u) && !adding))
+ {
+ if ((oldadding != adding) || (!output.length()))
+ output += (adding ? '+' : '-');
+
+ this->SetNoticeMask(u, adding);
+
+ output += u;
+ }
+ oldadding = adding;
}
- oldadding = adding;
}
break;
default:
- if ((*c >= 'A') && (*c <= 'z') && (ServerInstance->SNO->IsEnabled(*c)))
+ if (isalpha(*c))
{
if ((!IsNoticeMaskSet(*c) && adding) || (IsNoticeMaskSet(*c) && !adding))
{
}
LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr)
- : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this)
+ : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this),
+ bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0),
+ already_sent(0)
{
- bytes_in = bytes_out = cmds_in = cmds_out = 0;
- server_sa.sa.sa_family = AF_UNSPEC;
- CommandFloodPenalty = 0;
- lastping = nping = 0;
+ lastping = 0;
eh.SetFd(myfd);
memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs));
memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs));
}
else if (a->type == CC_DENY)
{
- ServerInstance->Users->QuitUser(this, "Unauthorised connection");
+ ServerInstance->Users->QuitUser(this, a->config->getString("reason", "Unauthorised connection"));
return;
}
else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal()))
* may put the user into a totally seperate class with different restrictions! so we *must* check again.
* Don't remove this! -- w00t
*/
- this->SetClass();
-
- /* Check the password, if one is required by the user's connect class.
- * This CANNOT be in CheckClass(), because that is called prior to PASS as well!
- */
- if (!MyClass->config->getString("pass").empty())
- {
- if (ServerInstance->PassCompare(this, MyClass->config->getString("pass"), password, MyClass->config->getString("hash")))
- {
- ServerInstance->Users->QuitUser(this, "Invalid password");
- return;
- }
- }
+ SetClass();
CheckClass();
CheckLines();
* Also don't check Q:Lines for remote nickchanges, they should have our Q:Lines anyway to enforce themselves.
* -- w00t
*/
- if (IS_LOCAL(this))
+ if (IS_LOCAL(this) && !force)
{
XLine* mq = ServerInstance->XLines->MatchesLine("Q",newnick);
if (mq)
if (this->registered != REG_ALL || quitting)
return;
- uniq_id_t uniq_id = ++already_sent;
+ LocalUser::already_sent_id++;
UserChanList include_c(chans);
std::map<User*,bool> exceptions;
LocalUser* u = IS_LOCAL(i->first);
if (u && !u->quitting)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = LocalUser::already_sent_id;
if (i->second)
u->Write(line);
}
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && already_sent[u->GetFd()] != uniq_id)
+ if (u && !u->quitting && u->already_sent != LocalUser::already_sent_id)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = LocalUser::already_sent_id;
u->Write(line);
}
}
if (this->registered != REG_ALL)
return;
- uniq_id_t uniq_id = ++already_sent;
+ already_sent_t uniq_id = ++LocalUser::already_sent_id;
snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str());
snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str());
LocalUser* u = IS_LOCAL(i->first);
if (u && !u->quitting)
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = uniq_id;
if (i->second)
u->Write(IS_OPER(u) ? out2 : out1);
}
for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++)
{
LocalUser* u = IS_LOCAL(i->first);
- if (u && !u->quitting && (already_sent[u->GetFd()] != uniq_id))
+ if (u && !u->quitting && (u->already_sent != uniq_id))
{
- already_sent[u->GetFd()] = uniq_id;
+ u->already_sent = uniq_id;
u->Write(IS_OPER(u) ? out2 : out1);
}
}
if (!ServerInstance->Config->CycleHosts)
return;
- uniq_id_t silent_id = ++already_sent;
- uniq_id_t seen_id = ++already_sent;
+ already_sent_t silent_id = ++LocalUser::already_sent_id;
+ already_sent_t seen_id = ++LocalUser::already_sent_id;
UserChanList include_c(chans);
std::map<User*,bool> exceptions;
{
if (i->second)
{
- already_sent[u->GetFd()] = seen_id;
+ u->already_sent = seen_id;
u->Write(quitline);
}
else
{
- already_sent[u->GetFd()] = silent_id;
+ u->already_sent = silent_id;
}
}
}
LocalUser* u = IS_LOCAL(i->first);
if (u == NULL || u == this)
continue;
- if (already_sent[u->GetFd()] == silent_id)
+ if (u->already_sent == silent_id)
continue;
- if (already_sent[u->GetFd()] != seen_id)
+ if (u->already_sent != seen_id)
{
u->Write(quitline);
- already_sent[u->GetFd()] = seen_id;
+ u->already_sent = seen_id;
}
u->Write(joinline);
if (modeline.length() > 0)
for (ClassVector::iterator i = ServerInstance->Config->Classes.begin(); i != ServerInstance->Config->Classes.end(); i++)
{
ConnectClass* c = *i;
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Checking %s", c->GetName().c_str());
ModResult MOD_RESULT;
FIRST_MOD_RESULT(OnSetConnectClass, MOD_RESULT, (this,c));
if (c->type == CC_NAMED)
continue;
+ bool regdone = (registered != REG_NONE);
+ if (c->config->getBool("registered", regdone) != regdone)
+ continue;
+
/* check if host matches.. */
if (c->GetHost().length() && !InspIRCd::MatchCIDR(this->GetIPString(), c->GetHost(), NULL) &&
!InspIRCd::MatchCIDR(this->host, c->GetHost(), NULL))
continue;
}
- bool regdone = (registered != REG_NONE);
- if (c->config->getBool("registered", regdone) != regdone)
- continue;
+ if (!c->config->getString("pass").empty())
+ {
+ if (ServerInstance->PassCompare(this, c->config->getString("pass"), password, c->config->getString("hash")))
+ {
+ ServerInstance->Logs->Log("CONNECTCLASS", DEBUG, "Bad password, skipping");
+ continue;
+ }
+ }
/* we stop at the first class that meets ALL critera. */
found = c;