X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fusers.cpp;h=455bb74ec6ba5329845e5eb8333b592557478666;hb=b03ec6a4eaa19c9e8acbe99ffc8c55fddcbf2384;hp=d75016f2f7498de32a80a0642d53e12769440a0b;hpb=3a9cee1356d0e46ced89826c9433fd1ecac3a9e7;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/users.cpp b/src/users.cpp index d75016f2f..455bb74ec 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -11,7 +11,7 @@ * --------------------------------------------------- */ -/* $Core: libIRCDusers */ +/* $Core */ #include "inspircd.h" #include @@ -98,7 +98,7 @@ void User::StartDNSLookup() { try { - bool cached; + bool cached = false; const char* sip = this->GetIPString(false); /* Special case for 4in6 (Have i mentioned i HATE 4in6?) */ @@ -190,12 +190,11 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance age = ServerInstance->Time(); Penalty = 0; lines_in = lastping = signon = idle_lastmsg = nping = registered = 0; - ChannelCount = timeout = bytes_in = bytes_out = cmds_in = cmds_out = 0; + bytes_in = bytes_out = cmds_in = cmds_out = 0; quietquit = OverPenalty = ExemptFromPenalty = quitting = exempt = haspassed = dns_done = false; fd = -1; recvq.clear(); sendq.clear(); - WriteError.clear(); res_forward = res_reverse = NULL; Visibility = NULL; ip = NULL; @@ -206,8 +205,6 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance AllowedOperCommands = NULL; chans.clear(); invites.clear(); - memset(modes,0,sizeof(modes)); - memset(snomasks,0,sizeof(snomasks)); if (uid.empty()) uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1); @@ -560,7 +557,7 @@ bool User::AddBuffer(const std::string &a) if (this->MyClass && (recvq.length() > this->MyClass->GetRecvqMax())) { - this->SetWriteError("RecvQ exceeded"); + ServerInstance->Users->QuitUser(this, "RecvQ exceeded"); ServerInstance->SNO->WriteToSnoMask('A', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax()); return false; } @@ -620,7 +617,7 @@ std::string User::GetBuffer() void User::AddWriteBuf(const std::string &data) { - if (*this->GetWriteError()) + if (this->quitting) return; if (this->MyClass && (sendq.length() + data.length() > this->MyClass->GetSendqMax())) @@ -630,7 +627,7 @@ void User::AddWriteBuf(const std::string &data) * if we dont it'll recursively call here over and over again trying * to repeatedly add the text to the sendq! */ - this->SetWriteError("SendQ exceeded"); + ServerInstance->Users->QuitUser(this, "SendQ exceeded"); ServerInstance->SNO->WriteToSnoMask('A', "User %s SendQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)sendq.length() + data.length(),this->MyClass->GetSendqMax()); return; } @@ -644,71 +641,53 @@ void User::AddWriteBuf(const std::string &data) // send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it) void User::FlushWriteBuf() { - try + if (this->fd == FD_MAGIC_NUMBER) { - if ((this->fd == FD_MAGIC_NUMBER) || (*this->GetWriteError())) - { - sendq.clear(); - } - if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER)) - { - int old_sendq_length = sendq.length(); - int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0); + sendq.clear(); + return; + } - if (n_sent == -1) + if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER)) + { + int old_sendq_length = sendq.length(); + int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0); + + if (n_sent == -1) + { + if (errno == EAGAIN) { - if (errno == EAGAIN) - { - /* The socket buffer is full. This isnt fatal, - * try again later. - */ - this->ServerInstance->SE->WantWrite(this); - } - else - { - /* Fatal error, set write error and bail - */ - this->SetWriteError(errno ? strerror(errno) : "EOF from client"); - return; - } + /* The socket buffer is full. This isnt fatal, + * try again later. + */ + ServerInstance->SE->WantWrite(this); } else { - /* advance the queue */ - if (n_sent) - this->sendq = this->sendq.substr(n_sent); - /* update the user's stats counters */ - this->bytes_out += n_sent; - this->cmds_out++; - if (n_sent != old_sendq_length) - this->ServerInstance->SE->WantWrite(this); + /* Fatal error, set write error and bail */ + ServerInstance->Users->QuitUser(this, errno ? strerror(errno) : "Write error"); + return; } } + else + { + /* advance the queue */ + if (n_sent) + this->sendq = this->sendq.substr(n_sent); + /* update the user's stats counters */ + this->bytes_out += n_sent; + this->cmds_out++; + if (n_sent != old_sendq_length) + this->ServerInstance->SE->WantWrite(this); + } } - catch (...) - { - ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::FlushWriteBuf()"); - } - + /* note: NOT else if! */ if (this->sendq.empty()) { FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(this)); } } -void User::SetWriteError(const std::string &error) -{ - // don't try to set the error twice, its already set take the first string. - if (this->WriteError.empty()) - this->WriteError = error; -} - -const char* User::GetWriteError() -{ - return this->WriteError.c_str(); -} - void User::Oper(const std::string &opertype, const std::string &opername) { char* mycmd; @@ -882,8 +861,6 @@ void User::CheckClass() } this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout; - this->timeout = ServerInstance->Time() + a->GetRegTimeout(); - this->MaxChans = a->GetMaxChans(); } bool User::CheckLines() @@ -1171,7 +1148,6 @@ const char* User::GetCIDRMask(int range) { struct in_addr v4; sockaddr_in* sin; - uint32_t temp; char buffer[16]; if (range > 32) @@ -1187,9 +1163,9 @@ const char* User::GetCIDRMask(int range) */ if(range > 0) { - temp = ntohl(v4.s_addr); - temp = (temp >> (32 - range)) << (32 - range); - v4.s_addr = htonl(temp); + v4.s_addr = ntohl(v4.s_addr); + v4.s_addr = (v4.s_addr >> (32 - range)) << (32 - range); + v4.s_addr = htonl(v4.s_addr); } else { @@ -1671,7 +1647,7 @@ bool User::ChangeDisplayedHost(const char* shost) } if (IS_LOCAL(this)) - this->WriteNumeric(396, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str()); + this->WriteNumeric(RPL_YOURDISPLAYEDHOST, "%s %s :is now your displayed host",this->nick.c_str(),this->dhost.c_str()); return true; } @@ -1778,12 +1754,6 @@ void User::SplitChanList(User* dest, const std::string &cl) } } -unsigned int User::GetMaxChans() -{ - return this->MaxChans; -} - - /* * Sets a user's connection class. * If the class name is provided, it will be used. Otherwise, the class will be guessed using host/ip/ident/etc. @@ -1948,31 +1918,31 @@ void User::ShowMOTD() { if (!ServerInstance->Config->MOTD.size()) { - this->WriteNumeric(422, "%s :Message of the day file is missing.",this->nick.c_str()); + this->WriteNumeric(ERR_NOMOTD, "%s :Message of the day file is missing.",this->nick.c_str()); return; } - this->WriteNumeric(375, "%s :%s message of the day", this->nick.c_str(), ServerInstance->Config->ServerName); + this->WriteNumeric(RPL_MOTDSTART, "%s :%s message of the day", this->nick.c_str(), ServerInstance->Config->ServerName); for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++) - this->WriteNumeric(372, "%s :- %s",this->nick.c_str(),i->c_str()); + this->WriteNumeric(RPL_MOTD, "%s :- %s",this->nick.c_str(),i->c_str()); - this->WriteNumeric(376, "%s :End of message of the day.", this->nick.c_str()); + this->WriteNumeric(RPL_ENDOFMOTD, "%s :End of message of the day.", this->nick.c_str()); } void User::ShowRULES() { if (!ServerInstance->Config->RULES.size()) { - this->WriteNumeric(434, "%s :RULES File is missing",this->nick.c_str()); + this->WriteNumeric(ERR_NORULES, "%s :RULES File is missing",this->nick.c_str()); return; } - this->WriteNumeric(308, "%s :- %s Server Rules -",this->nick.c_str(),ServerInstance->Config->ServerName); + this->WriteNumeric(RPL_RULESTART, "%s :- %s Server Rules -",this->nick.c_str(),ServerInstance->Config->ServerName); for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++) - this->WriteNumeric(232, "%s :- %s",this->nick.c_str(),i->c_str()); + this->WriteNumeric(RPL_RULES, "%s :- %s",this->nick.c_str(),i->c_str()); - this->WriteNumeric(309, "%s :End of RULES command.",this->nick.c_str()); + this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str()); } void User::HandleEvent(EventType et, int errornum) @@ -1980,37 +1950,17 @@ void User::HandleEvent(EventType et, int errornum) if (this->quitting) // drop everything, user is due to be quit return; - /* WARNING: May delete this user! */ - int thisfd = this->GetFd(); - - try + switch (et) { - switch (et) - { - case EVENT_READ: - ServerInstance->ProcessUser(this); - break; - case EVENT_WRITE: - this->FlushWriteBuf(); - break; - case EVENT_ERROR: - /** This should be safe, but dont DARE do anything after it -- Brain */ - this->SetWriteError(errornum ? strerror(errornum) : "EOF from client"); - break; - } - } - catch (...) - { - ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::HandleEvent intercepted"); - } - - /* If the user has raised an error whilst being processed, quit them now we're safe to */ - if ((ServerInstance->SE->GetRef(thisfd) == this)) - { - if (!WriteError.empty()) - { - ServerInstance->Users->QuitUser(this, GetWriteError()); - } + case EVENT_READ: + ServerInstance->ProcessUser(this); + break; + case EVENT_WRITE: + this->FlushWriteBuf(); + break; + case EVENT_ERROR: + ServerInstance->Users->QuitUser(this, errornum ? strerror(errornum) : "Client closed the connection"); + break; } }