X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=9fef906d16d83de783acfe89e93de293563443bf;hb=08f6f056667df63d1673bea959c73b75393113c6;hp=db5f8a74d2751b7fd6e64bfc822227dfe6677e84;hpb=78044f849b63c71fb9c741c648415a298c0ed617;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index db5f8a74d..9fef906d1 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -33,43 +33,45 @@ bool User::IsNoticeMaskSet(unsigned char sm) return (snomasks[sm-65]); } -bool User::IsModeSet(unsigned char m) +bool User::IsModeSet(unsigned char m) const { ModeHandler* mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER); return (mh && modes[mh->GetId()]); } -const char* User::FormatModes(bool showparameters) +std::string User::GetModeLetters(bool includeparams) const { - static std::string data; + std::string ret(1, '+'); std::string params; - data.clear(); - for (unsigned char n = 0; n < 64; n++) + for (unsigned char i = 'A'; i < 'z'; i++) { - ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER); - if (mh && IsModeSet(mh)) + const ModeHandler* const mh = ServerInstance->Modes.FindMode(i, MODETYPE_USER); + if ((!mh) || (!IsModeSet(mh))) + continue; + + ret.push_back(mh->GetModeChar()); + if ((includeparams) && (mh->NeedsParam(true))) { - data.push_back(n + 65); - if (showparameters && mh->GetNumParams(true)) - { - std::string p = mh->GetUserParameter(this); - if (p.length()) - params.append(" ").append(p); - } + const std::string val = mh->GetUserParameter(this); + if (!val.empty()) + params.append(1, ' ').append(val); } } - data += params; - return data.c_str(); + + ret += params; + return ret; } User::User(const std::string& uid, Server* srv, int type) - : uuid(uid), server(srv), usertype(type) + : age(ServerInstance->Time()) + , signon(0) + , uuid(uid) + , server(srv) + , registered(REG_NONE) + , quitting(false) + , usertype(type) { - age = ServerInstance->Time(); - signon = 0; - registered = 0; - quitting = false; client_sa.sa.sa_family = AF_UNSPEC; ServerInstance->Logs->Log("USERS", LOG_DEBUG, "New UUID for user: %s", uuid.c_str()); @@ -83,14 +85,24 @@ User::User(const std::string& uid, Server* srv, int type) } LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr) - : User(ServerInstance->UIDGen.GetUID(), ServerInstance->FakeClient->server, USERTYPE_LOCAL), eh(this), - bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0), - already_sent(0) -{ - exempt = quitting_sendq = false; - idle_lastmsg = 0; + : User(ServerInstance->UIDGen.GetUID(), ServerInstance->FakeClient->server, USERTYPE_LOCAL) + , eh(this) + , bytes_in(0) + , bytes_out(0) + , cmds_in(0) + , cmds_out(0) + , quitting_sendq(false) + , lastping(true) + , exempt(false) + , nping(0) + , idle_lastmsg(0) + , CommandFloodPenalty(0) + , already_sent(0) +{ + signon = ServerInstance->Time(); + // The user's default nick is their UUID + nick = uuid; ident = "unknown"; - lastping = 0; eh.SetFd(myfd); memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs)); memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs)); @@ -141,19 +153,20 @@ const std::string& User::GetFullRealHost() return this->cached_fullrealhost; } -bool User::HasModePermission(unsigned char, ModeType) +bool User::HasModePermission(const ModeHandler* mh) const { return true; } -bool LocalUser::HasModePermission(unsigned char mode, ModeType type) +bool LocalUser::HasModePermission(const ModeHandler* mh) const { if (!this->IsOper()) return false; + const unsigned char mode = mh->GetModeChar(); if (mode < 'A' || mode > ('A' + 64)) return false; - return ((type == MODETYPE_USER ? oper->AllowedUserModes : oper->AllowedChanModes))[(mode - 'A')]; + return ((mh->GetModeType() == MODETYPE_USER ? oper->AllowedUserModes : oper->AllowedChanModes))[(mode - 'A')]; } /* @@ -481,7 +494,7 @@ void LocalUser::CheckClass(bool clone_count) } } - this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout; + this->nping = ServerInstance->Time() + a->GetPingTime(); } bool LocalUser::CheckLines(bool doZline) @@ -526,10 +539,10 @@ void LocalUser::FullConnect() this->WriteNumeric(RPL_WELCOME, InspIRCd::Format("Welcome to the %s IRC Network %s", ServerInstance->Config->Network.c_str(), GetFullRealHost().c_str())); this->WriteNumeric(RPL_YOURHOSTIS, InspIRCd::Format("Your host is %s, running version %s", ServerInstance->Config->ServerName.c_str(), INSPIRCD_BRANCH)); - this->WriteNumeric(RPL_SERVERCREATED, InspIRCd::Format("This server was created %s %s", __TIME__, __DATE__)); + this->WriteNumeric(RPL_SERVERCREATED, InspIRCd::TimeString(ServerInstance->startup_time, "This server was created %H:%M:%S %b %d %Y")); - const std::string& modelist = ServerInstance->Modes->GetModeListFor004Numeric(); - this->WriteNumeric(RPL_SERVERVERSION, ServerInstance->Config->ServerName, INSPIRCD_BRANCH, modelist); + const TR1NS::array& modelist = ServerInstance->Modes->GetModeListFor004Numeric(); + this->WriteNumeric(RPL_SERVERVERSION, ServerInstance->Config->ServerName, INSPIRCD_BRANCH, modelist[0], modelist[1], modelist[2]); ServerInstance->ISupport.SendTo(this); @@ -575,6 +588,7 @@ void LocalUser::FullConnect() void User::InvalidateCache() { /* Invalidate cache */ + cachedip.clear(); cached_fullhost.clear(); cached_hostip.clear(); cached_makehost.clear(); @@ -614,11 +628,8 @@ bool User::ChangeNick(const std::string& newnick, time_t newts) if (InUse->registered != REG_ALL) { /* force the camper to their UUID, and ask them to re-send a NICK. */ - InUse->WriteFrom(InUse, "NICK %s", InUse->uuid.c_str()); - InUse->WriteNumeric(ERR_NICKNAMEINUSE, InUse->nick, "Nickname overruled."); - - InUse->registered &= ~REG_NICK; - InUse->ChangeNick(InUse->uuid); + LocalUser* const localuser = static_cast(InUse); + localuser->OverruleNick(); } else { @@ -646,6 +657,16 @@ bool User::ChangeNick(const std::string& newnick, time_t newts) return true; } +void LocalUser::OverruleNick() +{ + this->WriteFrom(this, "NICK %s", this->uuid.c_str()); + this->WriteNumeric(ERR_NICKNAMEINUSE, this->nick, "Nickname overruled."); + + // Clear the bit before calling ChangeNick() to make it NOT run the OnUserPostNick() hook + this->registered &= ~REG_NICK; + this->ChangeNick(this->uuid); +} + int LocalUser::GetServerPort() { switch (this->server_sa.sa.sa_family) @@ -660,10 +681,9 @@ int LocalUser::GetServerPort() const std::string& User::GetIPString() { - int port; if (cachedip.empty()) { - irc::sockets::satoap(client_sa, cachedip, port); + cachedip = client_sa.addr(); /* IP addresses starting with a : on irc are a Bad Thing (tm) */ if (cachedip[0] == ':') cachedip.insert(cachedip.begin(),1,'0'); @@ -687,11 +707,10 @@ irc::sockets::cidr_mask User::GetCIDRMask() return irc::sockets::cidr_mask(client_sa, range); } -bool User::SetClientIP(const char* sip, bool recheck_eline) +bool User::SetClientIP(const std::string& address, bool recheck_eline) { - cachedip.clear(); - cached_hostip.clear(); - return irc::sockets::aptosa(sip, 0, client_sa); + this->InvalidateCache(); + return irc::sockets::aptosa(address, 0, client_sa); } void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) @@ -701,10 +720,10 @@ void User::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_eline) memcpy(&client_sa, &sa, sizeof(irc::sockets::sockaddrs)); } -bool LocalUser::SetClientIP(const char* sip, bool recheck_eline) +bool LocalUser::SetClientIP(const std::string& address, bool recheck_eline) { irc::sockets::sockaddrs sa; - if (!irc::sockets::aptosa(sip, 0, sa)) + if (!irc::sockets::aptosa(address, 0, sa)) // Invalid return false; @@ -811,7 +830,8 @@ void User::WriteNumeric(const Numeric::Numeric& numeric) if (MOD_RESULT == MOD_RES_DENY) return; - this->Write(BuildNumeric(ServerInstance->Config->ServerName, this, numeric.GetNumeric(), numeric.GetParams())); + const std::string& servername = (numeric.GetServer() ? numeric.GetServer()->GetName() : ServerInstance->Config->ServerName); + this->Write(BuildNumeric(servername, this, numeric.GetNumeric(), numeric.GetParams())); } void User::WriteFrom(User *user, const std::string &text) @@ -926,48 +946,9 @@ void User::ForEachNeighbor(ForEachNeighborHandler& handler, bool include_self) } } -void LocalUser::SendText(const std::string& line) -{ - Write(line); -} - -void RemoteUser::SendText(const std::string& line) -{ - ServerInstance->PI->PushToClient(this, line); -} - -void FakeUser::SendText(const std::string& line) -{ -} - -void User::SendText(const char *text, ...) -{ - std::string line; - VAFORMAT(line, text, text); - SendText(line); -} - -void User::SendText(const std::string& linePrefix, std::stringstream& textStream) -{ - std::string line; - std::string word; - while (textStream >> word) - { - size_t lineLength = linePrefix.length() + line.length() + word.length() + 3; // "\s\n\r" - if (lineLength > ServerInstance->Config->Limits.MaxLine) - { - SendText(linePrefix + line); - line.clear(); - } - line += " " + word; - } - SendText(linePrefix + line); -} - void User::WriteRemoteNumeric(const Numeric::Numeric& numeric) { - const std::string& servername = (numeric.GetServer() ? numeric.GetServer()->GetName() : ServerInstance->Config->ServerName); - SendText(BuildNumeric(servername, this, numeric.GetNumeric(), numeric.GetParams())); + WriteNumeric(numeric); } /* return 0 or 1 depending if users u and u2 share one or more common channels @@ -1121,14 +1102,14 @@ void LocalUser::SetClass(const std::string &explicit_name) } /* if it requires a port ... */ - int port = c->config->getInt("port"); - if (port) + if (!c->ports.empty()) { - ServerInstance->Logs->Log("CONNECTCLASS", LOG_DEBUG, "Requires port (%d)", port); - /* and our port doesn't match, fail. */ - if (this->GetServerPort() != port) + if (!c->ports.count(this->GetServerPort())) + { + ServerInstance->Logs->Log("CONNECTCLASS", LOG_DEBUG, "Requires a different port, skipping"); continue; + } } if (regdone && !c->config->getString("password").empty()) @@ -1191,13 +1172,11 @@ ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask) } ConnectClass::ConnectClass(ConfigTag* tag, char t, const std::string& mask, const ConnectClass& parent) - : config(tag), type(t), fakelag(parent.fakelag), name("unnamed"), - registration_timeout(parent.registration_timeout), host(mask), pingtime(parent.pingtime), - softsendqmax(parent.softsendqmax), hardsendqmax(parent.hardsendqmax), recvqmax(parent.recvqmax), - penaltythreshold(parent.penaltythreshold), commandrate(parent.commandrate), - maxlocal(parent.maxlocal), maxglobal(parent.maxglobal), maxconnwarn(parent.maxconnwarn), maxchans(parent.maxchans), - limit(parent.limit), resolvehostnames(parent.resolvehostnames) { + Update(&parent); + name = "unnamed"; + type = t; + config = tag; } void ConnectClass::Update(const ConnectClass* src) @@ -1220,4 +1199,5 @@ void ConnectClass::Update(const ConnectClass* src) maxchans = src->maxchans; limit = src->limit; resolvehostnames = src->resolvehostnames; + ports = src->ports; }