this->SetNoticeMask(*c, adding);
output += *c;
+ oldadding = adding;
}
}
else
this->WriteNumeric(ERR_UNKNOWNSNOMASK, "%s %c :is unknown snomask char to me", this->nick.c_str(), *c);
- oldadding = adding;
break;
}
LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr)
: User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this),
+ localuseriter(ServerInstance->Users->local_users.end()),
bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0),
already_sent(0)
{
ServerInstance->Users->QuitUser(user, "RecvQ exceeded");
ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",
user->nick.c_str(), (unsigned long)recvq.length(), user->MyClass->GetRecvqMax());
+ return;
}
unsigned long sendqmax = ULONG_MAX;
if (!user->HasPrivPermission("users/flood/increased-buffers"))
CullResult LocalUser::cull()
{
- LocalUserList::iterator x = find(ServerInstance->Users->local_users.begin(),ServerInstance->Users->local_users.end(),this);
- if (x != ServerInstance->Users->local_users.end())
- ServerInstance->Users->local_users.erase(x);
+ // The iterator is initialized to local_users.end() in the constructor. It is
+ // overwritten in UserManager::AddUser() with the real iterator so this check
+ // is only a precaution currently.
+ if (localuseriter != ServerInstance->Users->local_users.end())
+ {
+ ServerInstance->Users->local_count--;
+ ServerInstance->Users->local_users.erase(localuseriter);
+ }
else
- ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector");
+ ServerInstance->Logs->Log("USERS", DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick);
ClearInvites();
eh.cull();
bool User::ChangeNick(const std::string& newnick, bool force)
{
+ if (quitting)
+ {
+ ServerInstance->Logs->Log("USERS", DEFAULT, "ERROR: Attempted to change nick of a quitting user: " + this->nick);
+ return false;
+ }
+
ModResult MOD_RESULT;
if (force)
return irc::sockets::cidr_mask(client_sa, range);
}
-bool User::SetClientIP(const char* sip)
+bool User::SetClientIP(const char* sip, bool recheck_eline)
{
cachedip.clear();
cached_hostip.clear();
return irc::sockets::aptosa(sip, 0, client_sa);
}
-void User::SetClientIP(const irc::sockets::sockaddrs& sa)
+void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline)
{
cachedip.clear();
cached_hostip.clear();
memcpy(&client_sa, &sa, sizeof(irc::sockets::sockaddrs));
}
-bool LocalUser::SetClientIP(const char* sip)
+bool LocalUser::SetClientIP(const char* sip, bool recheck_eline)
{
irc::sockets::sockaddrs sa;
if (!irc::sockets::aptosa(sip, 0, sa))
// Invalid
return false;
- LocalUser::SetClientIP(sa);
+ LocalUser::SetClientIP(sa, recheck_eline);
return true;
}
-void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa)
+void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline)
{
if (sa != client_sa)
{
User::SetClientIP(sa);
+ if (recheck_eline)
+ this->exempt = (ServerInstance->XLines->MatchesLine("E", this) != NULL);
+
FOREACH_MOD(I_OnSetUserIP,OnSetUserIP(this));
}
}
std::string quitstr = ":" + GetFullHost() + " QUIT :Changing ident";
- this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax + 1);
+ this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax);
this->InvalidateCache();