]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Allow for skipping clone checking before DNS is complete.
[user/henk/code/inspircd.git] / src / users.cpp
index 9f4060968e61792847619598e76c1e586445db8f..0dc9cea573ced77a3893978e7e66986058b6dbb8 100644 (file)
@@ -122,18 +122,16 @@ void User::SetNoticeMask(unsigned char sm, bool value)
        snomasks[sm-65] = value;
 }
 
-const char* User::FormatNoticeMasks()
+std::string User::FormatNoticeMasks()
 {
-       static char data[MAXBUF];
-       int offset = 0;
+       std::string data;
 
-       for (int n = 0; n < 64; n++)
+       for (unsigned char n = 0; n < 64; n++)
        {
                if (snomasks[n])
-                       data[offset++] = n+65;
+                       data.push_back(n + 65); 
        }
 
-       data[offset] = 0;
        return data;
 }
 
@@ -153,15 +151,15 @@ void User::SetMode(unsigned char m, bool value)
 
 const char* User::FormatModes(bool showparameters)
 {
-       static char data[MAXBUF];
+       static std::string data;
        std::string params;
-       int offset = 0;
+       data.clear();
 
        for (unsigned char n = 0; n < 64; n++)
        {
                if (modes[n])
                {
-                       data[offset++] = n + 65;
+                       data.push_back(n + 65);
                        ModeHandler* mh = ServerInstance->Modes->FindMode(n + 65, MODETYPE_USER);
                        if (showparameters && mh && mh->GetNumParams(true))
                        {
@@ -171,9 +169,8 @@ const char* User::FormatModes(bool showparameters)
                        }
                }
        }
-       data[offset] = 0;
-       strlcat(data, params.c_str(), MAXBUF);
-       return data;
+       data += params;
+       return data.c_str();
 }
 
 User::User(const std::string &uid, const std::string& sid, int type)
@@ -221,18 +218,8 @@ const std::string& User::MakeHost()
        if (!this->cached_makehost.empty())
                return this->cached_makehost;
 
-       char nhost[MAXBUF];
-       /* This is much faster than snprintf */
-       char* t = nhost;
-       for(const char* n = ident.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '@';
-       for(const char* n = host.c_str(); *n; n++)
-               *t++ = *n;
-       *t = 0;
-
-       this->cached_makehost.assign(nhost);
-
+       // XXX: Is there really a need to cache this?
+       this->cached_makehost = ident + "@" + host;
        return this->cached_makehost;
 }
 
@@ -241,18 +228,8 @@ const std::string& User::MakeHostIP()
        if (!this->cached_hostip.empty())
                return this->cached_hostip;
 
-       char ihost[MAXBUF];
-       /* This is much faster than snprintf */
-       char* t = ihost;
-       for(const char* n = ident.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '@';
-       for(const char* n = this->GetIPString().c_str(); *n; n++)
-               *t++ = *n;
-       *t = 0;
-
-       this->cached_hostip = ihost;
-
+       // XXX: Is there really a need to cache this?
+       this->cached_hostip = ident + "@" + this->GetIPString();
        return this->cached_hostip;
 }
 
@@ -261,54 +238,18 @@ const std::string& User::GetFullHost()
        if (!this->cached_fullhost.empty())
                return this->cached_fullhost;
 
-       char result[MAXBUF];
-       char* t = result;
-       for(const char* n = nick.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '!';
-       for(const char* n = ident.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '@';
-       for(const char* n = dhost.c_str(); *n; n++)
-               *t++ = *n;
-       *t = 0;
-
-       this->cached_fullhost = result;
-
+       // XXX: Is there really a need to cache this?
+       this->cached_fullhost = nick + "!" + ident + "@" + dhost;
        return this->cached_fullhost;
 }
 
-char* User::MakeWildHost()
-{
-       static char nresult[MAXBUF];
-       char* t = nresult;
-       *t++ = '*';     *t++ = '!';
-       *t++ = '*';     *t++ = '@';
-       for(const char* n = dhost.c_str(); *n; n++)
-               *t++ = *n;
-       *t = 0;
-       return nresult;
-}
-
 const std::string& User::GetFullRealHost()
 {
        if (!this->cached_fullrealhost.empty())
                return this->cached_fullrealhost;
 
-       char fresult[MAXBUF];
-       char* t = fresult;
-       for(const char* n = nick.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '!';
-       for(const char* n = ident.c_str(); *n; n++)
-               *t++ = *n;
-       *t++ = '@';
-       for(const char* n = host.c_str(); *n; n++)
-               *t++ = *n;
-       *t = 0;
-
-       this->cached_fullrealhost = fresult;
-
+       // XXX: Is there really a need to cache this?
+       this->cached_fullrealhost = nick + "!" + ident + "@" + host;
        return this->cached_fullrealhost;
 }
 
@@ -402,7 +343,7 @@ bool LocalUser::HasPrivPermission(const std::string &privstr, bool noisy)
        }
 
        if (noisy)
-               this->WriteNotice("Oper type " + std::string(oper->NameStr()) + " does not have access to priv " + privstr);
+               this->WriteNotice("Oper type " + oper->name + " does not have access to priv " + privstr);
 
        return false;
 }
@@ -429,7 +370,7 @@ void UserIOHandler::OnDataReady()
        while (user->CommandFloodPenalty < penaltymax && getSendQSize() < sendqmax)
        {
                std::string line;
-               line.reserve(MAXBUF);
+               line.reserve(ServerInstance->Config->Limits.MaxLine);
                std::string::size_type qpos = 0;
                while (qpos < recvq.length())
                {
@@ -444,7 +385,7 @@ void UserIOHandler::OnDataReady()
                        case '\n':
                                goto eol_found;
                        }
-                       if (line.length() < MAXBUF - 2)
+                       if (line.length() < ServerInstance->Config->Limits.MaxLine - 2)
                                line.push_back(c);
                }
                // if we got here, the recvq ran out before we found a newline
@@ -507,7 +448,10 @@ CullResult LocalUser::cull()
        // 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", LOG_DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick);
 
@@ -551,10 +495,10 @@ void User::Oper(OperInfo* info)
        }
 
        ServerInstance->SNO->WriteToSnoMask('o',"%s (%s@%s) is now an IRC operator of type %s (using oper '%s')",
-               nick.c_str(), ident.c_str(), host.c_str(), oper->NameStr(), opername.c_str());
-       this->WriteNumeric(381, "%s :You are now %s %s", nick.c_str(), strchr("aeiouAEIOU", oper->name[0]) ? "an" : "a", oper->NameStr());
+               nick.c_str(), ident.c_str(), host.c_str(), oper->name.c_str(), opername.c_str());
+       this->WriteNumeric(381, "%s :You are now %s %s", nick.c_str(), strchr("aeiouAEIOU", oper->name[0]) ? "an" : "a", oper->name.c_str());
 
-       ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "%s opered as type: %s", GetFullRealHost().c_str(), oper->NameStr());
+       ServerInstance->Logs->Log("OPER", LOG_DEFAULT, "%s opered as type: %s", GetFullRealHost().c_str(), oper->name.c_str());
        ServerInstance->Users->all_opers.push_back(this);
 
        // Expand permissions from config for faster lookup
@@ -656,7 +600,7 @@ void User::UnOper()
 /*
  * Check class restrictions
  */
-void LocalUser::CheckClass()
+void LocalUser::CheckClass(bool clone_count)
 {
        ConnectClass* a = this->MyClass;
 
@@ -670,19 +614,22 @@ void LocalUser::CheckClass()
                ServerInstance->Users->QuitUser(this, a->config->getString("reason", "Unauthorised connection"));
                return;
        }
-       else if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal()))
+       else if (clone_count)
        {
-               ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)");
-               if (a->maxconnwarn)
-                       ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString().c_str());
-               return;
-       }
-       else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal()))
-       {
-               ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)");
-               if (a->maxconnwarn)
-                       ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString().c_str());
-               return;
+               if ((a->GetMaxLocal()) && (ServerInstance->Users->LocalCloneCount(this) > a->GetMaxLocal()))
+               {
+                       ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (local)");
+                       if (a->maxconnwarn)
+                               ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum LOCAL connections (%ld) exceeded for IP %s", a->GetMaxLocal(), this->GetIPString().c_str());
+                       return;
+               }
+               else if ((a->GetMaxGlobal()) && (ServerInstance->Users->GlobalCloneCount(this) > a->GetMaxGlobal()))
+               {
+                       ServerInstance->Users->QuitUser(this, "No more connections allowed from your host via this connect class (global)");
+                       if (a->maxconnwarn)
+                               ServerInstance->SNO->WriteToSnoMask('a', "WARNING: maximum GLOBAL connections (%ld) exceeded for IP %s", a->GetMaxGlobal(), this->GetIPString().c_str());
+                       return;
+               }
        }
 
        this->nping = ServerInstance->Time() + a->GetPingTime() + ServerInstance->Config->dns_timeout;
@@ -732,10 +679,8 @@ void LocalUser::FullConnect()
        this->WriteNumeric(RPL_YOURHOSTIS, "%s :Your host is %s, running version %s",this->nick.c_str(),ServerInstance->Config->ServerName.c_str(),BRANCH);
        this->WriteNumeric(RPL_SERVERCREATED, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__);
 
-       std::string umlist = ServerInstance->Modes->UserModeList();
-       std::string cmlist = ServerInstance->Modes->ChannelModeList();
-       std::string pmlist = ServerInstance->Modes->ParaModeList();
-       this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, umlist.c_str(), cmlist.c_str(), pmlist.c_str());
+       const std::string& modelist = ServerInstance->Modes->GetModeListFor004Numeric();
+       this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, modelist.c_str());
 
        ServerInstance->ISupport.SendTo(this);
        this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str());
@@ -796,17 +741,16 @@ bool User::ChangeNick(const std::string& newnick, bool force)
                return false;
        }
 
-       ModResult MOD_RESULT;
-
-       if (force)
-               ServerInstance->NICKForced.set(this, 1);
-       FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick));
-       ServerInstance->NICKForced.set(this, 0);
-
-       if (MOD_RESULT == MOD_RES_DENY)
+       if (!force)
        {
-               ServerInstance->stats->statsCollisions++;
-               return false;
+               ModResult MOD_RESULT;
+               FIRST_MOD_RESULT(OnUserPreNick, MOD_RESULT, (this, newnick));
+
+               if (MOD_RESULT == MOD_RES_DENY)
+               {
+                       ServerInstance->stats->statsCollisions++;
+                       return false;
+               }
        }
 
        if (assign(newnick) == assign(nick))
@@ -996,10 +940,10 @@ void LocalUser::Write(const std::string& text)
        if (!ServerInstance->SE->BoundsCheckFd(&eh))
                return;
 
-       if (text.length() > MAXBUF - 2)
+       if (text.length() > ServerInstance->Config->Limits.MaxLine - 2)
        {
                // this should happen rarely or never. Crop the string at 512 and try again.
-               std::string try_again = text.substr(0, MAXBUF - 2);
+               std::string try_again = text.substr(0, ServerInstance->Config->Limits.MaxLine - 2);
                Write(try_again);
                return;
        }
@@ -1018,14 +962,9 @@ void LocalUser::Write(const std::string& text)
  */
 void LocalUser::Write(const char *text, ...)
 {
-       va_list argsPtr;
-       char textbuffer[MAXBUF];
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
-       this->Write(std::string(textbuffer));
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       this->Write(textbuffer);
 }
 
 void User::WriteServ(const std::string& text)
@@ -1038,14 +977,9 @@ void User::WriteServ(const std::string& text)
  */
 void User::WriteServ(const char* text, ...)
 {
-       va_list argsPtr;
-       char textbuffer[MAXBUF];
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteServ(std::string(textbuffer));
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       this->WriteServ(textbuffer);
 }
 
 void User::WriteNotice(const std::string& text)
@@ -1055,28 +989,23 @@ void User::WriteNotice(const std::string& text)
 
 void User::WriteNumeric(unsigned int numeric, const char* text, ...)
 {
-       va_list argsPtr;
-       char textbuffer[MAXBUF];
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteNumeric(numeric, std::string(textbuffer));
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       this->WriteNumeric(numeric, textbuffer);
 }
 
 void User::WriteNumeric(unsigned int numeric, const std::string &text)
 {
-       char textbuffer[MAXBUF];
        ModResult MOD_RESULT;
 
        FIRST_MOD_RESULT(OnNumeric, MOD_RESULT, (this, numeric, text));
 
        if (MOD_RESULT == MOD_RES_DENY)
                return;
-
-       snprintf(textbuffer,MAXBUF,":%s %03u %s",ServerInstance->Config->ServerName.c_str(), numeric, text.c_str());
-       this->Write(std::string(textbuffer));
+       
+       const std::string message = InspIRCd::Format(":%s %03u %s", ServerInstance->Config->ServerName.c_str(),
+               numeric, text.c_str());
+       this->Write(message);
 }
 
 void User::WriteFrom(User *user, const std::string &text)
@@ -1090,14 +1019,9 @@ void User::WriteFrom(User *user, const std::string &text)
 
 void User::WriteFrom(User *user, const char* text, ...)
 {
-       va_list argsPtr;
-       char textbuffer[MAXBUF];
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteFrom(user, std::string(textbuffer));
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       this->WriteFrom(user, textbuffer);
 }
 
 
@@ -1105,14 +1029,9 @@ void User::WriteFrom(User *user, const char* text, ...)
 
 void User::WriteTo(User *dest, const char *data, ...)
 {
-       char textbuffer[MAXBUF];
-       va_list argsPtr;
-
-       va_start(argsPtr, data);
-       vsnprintf(textbuffer, MAXBUF, data, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteTo(dest, std::string(textbuffer));
+       std::string textbuffer;
+       VAFORMAT(textbuffer, data, data);
+       this->WriteTo(dest, textbuffer);
 }
 
 void User::WriteTo(User *dest, const std::string &data)
@@ -1122,36 +1041,24 @@ void User::WriteTo(User *dest, const std::string &data)
 
 void User::WriteCommon(const char* text, ...)
 {
-       char textbuffer[MAXBUF];
-       va_list argsPtr;
-
        if (this->registered != REG_ALL || quitting)
                return;
 
-       int len = snprintf(textbuffer,MAXBUF,":%s ",this->GetFullHost().c_str());
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer + len, MAXBUF - len, text, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteCommonRaw(std::string(textbuffer), true);
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       textbuffer = ":" + this->GetFullHost() + " " + textbuffer;
+       this->WriteCommonRaw(textbuffer, true);
 }
 
 void User::WriteCommonExcept(const char* text, ...)
 {
-       char textbuffer[MAXBUF];
-       va_list argsPtr;
-
        if (this->registered != REG_ALL || quitting)
                return;
 
-       int len = snprintf(textbuffer,MAXBUF,":%s ",this->GetFullHost().c_str());
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer + len, MAXBUF - len, text, argsPtr);
-       va_end(argsPtr);
-
-       this->WriteCommonRaw(std::string(textbuffer), false);
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
+       textbuffer = ":" + this->GetFullHost() + " " + textbuffer;
+       this->WriteCommonRaw(textbuffer, false);
 }
 
 void User::WriteCommonRaw(const std::string &line, bool include_self)
@@ -1250,38 +1157,26 @@ void FakeUser::SendText(const std::string& line)
 
 void User::SendText(const char *text, ...)
 {
-       va_list argsPtr;
-       char line[MAXBUF];
-
-       va_start(argsPtr, text);
-       vsnprintf(line, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
-       SendText(std::string(line));
+       std::string line;
+       VAFORMAT(line, text, text);
+       SendText(line);
 }
 
-void User::SendText(const std::string &LinePrefix, std::stringstream &TextStream)
+void User::SendText(const std::string& linePrefix, std::stringstream& textStream)
 {
-       char line[MAXBUF];
-       int start_pos = LinePrefix.length();
-       int pos = start_pos;
-       memcpy(line, LinePrefix.data(), pos);
-       std::string Word;
-       while (TextStream >> Word)
+       std::string line;
+       std::string word;
+       while (textStream >> word)
        {
-               int len = Word.length();
-               if (pos + len + 12 > MAXBUF)
+               size_t lineLength = linePrefix.length() + line.length() + word.length() + 3; // "\s\n\r"
+               if (lineLength > ServerInstance->Config->Limits.MaxLine)
                {
-                       line[pos] = '\0';
-                       SendText(std::string(line));
-                       pos = start_pos;
+                       SendText(linePrefix + line);
+                       line.clear();
                }
-               line[pos] = ' ';
-               memcpy(line + pos + 1, Word.data(), len);
-               pos += len + 1;
+               line += " " + word;
        }
-       line[pos] = '\0';
-       SendText(std::string(line));
+       SendText(linePrefix + line);
 }
 
 /* return 0 or 1 depending if users u and u2 share one or more common channels
@@ -1447,13 +1342,8 @@ bool User::ChangeIdent(const char* newident)
 
 void User::SendAll(const char* command, const char* text, ...)
 {
-       char textbuffer[MAXBUF];
-       va_list argsPtr;
-
-       va_start(argsPtr, text);
-       vsnprintf(textbuffer, MAXBUF, text, argsPtr);
-       va_end(argsPtr);
-
+       std::string textbuffer;
+       VAFORMAT(textbuffer, text, text);
        const std::string message = ":" + this->GetFullHost() + " " + command + " $* :" + textbuffer;
 
        for (LocalUserList::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)