]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/users.cpp
Change the syntax of FOREACH macros to be less dumb.
[user/henk/code/inspircd.git] / src / users.cpp
index 9f4060968e61792847619598e76c1e586445db8f..0cd92faefe7bedb4b69df08a76243897cc301dcb 100644 (file)
 
 already_sent_t LocalUser::already_sent_id = 0;
 
-std::string User::ProcessNoticeMasks(const char *sm)
-{
-       bool adding = true, oldadding = false;
-       const char *c = sm;
-       std::string output;
-
-       while (c && *c)
-       {
-               switch (*c)
-               {
-                       case '+':
-                               adding = true;
-                       break;
-                       case '-':
-                               adding = false;
-                       break;
-                       case '*':
-                               for (unsigned char d = 'a'; d <= 'z'; d++)
-                               {
-                                       if (!ServerInstance->SNO->masks[d - 'a'].Description.empty())
-                                       {
-                                               if ((!IsNoticeMaskSet(d) && adding) || (IsNoticeMaskSet(d) && !adding))
-                                               {
-                                                       if ((oldadding != adding) || (!output.length()))
-                                                               output += (adding ? '+' : '-');
-
-                                                       this->SetNoticeMask(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;
-                                       }
-                               }
-                       break;
-                       default:
-                               if (isalpha(*c))
-                               {
-                                       if ((!IsNoticeMaskSet(*c) && adding) || (IsNoticeMaskSet(*c) && !adding))
-                                       {
-                                               if ((oldadding != adding) || (!output.length()))
-                                                       output += (adding ? '+' : '-');
-
-                                               this->SetNoticeMask(*c, adding);
-
-                                               output += *c;
-                                       }
-                               }
-                               else
-                                       this->WriteNumeric(ERR_UNKNOWNSNOMASK, "%s %c :is unknown snomask char to me", this->nick.c_str(), *c);
-
-                               oldadding = adding;
-                       break;
-               }
-
-               c++;
-       }
-
-       std::string s = this->FormatNoticeMasks();
-       if (s.length() == 0)
-       {
-               this->modes[UM_SNOMASK] = false;
-       }
-
-       return output;
-}
-
 bool User::IsNoticeMaskSet(unsigned char sm)
 {
        if (!isalpha(sm))
@@ -115,28 +38,6 @@ bool User::IsNoticeMaskSet(unsigned char sm)
        return (snomasks[sm-65]);
 }
 
-void User::SetNoticeMask(unsigned char sm, bool value)
-{
-       if (!isalpha(sm))
-               return;
-       snomasks[sm-65] = value;
-}
-
-const char* User::FormatNoticeMasks()
-{
-       static char data[MAXBUF];
-       int offset = 0;
-
-       for (int n = 0; n < 64; n++)
-       {
-               if (snomasks[n])
-                       data[offset++] = n+65;
-       }
-
-       data[offset] = 0;
-       return data;
-}
-
 bool User::IsModeSet(unsigned char m)
 {
        if (!isalpha(m))
@@ -144,24 +45,17 @@ bool User::IsModeSet(unsigned char m)
        return (modes[m-65]);
 }
 
-void User::SetMode(unsigned char m, bool value)
-{
-       if (!isalpha(m))
-               return;
-       modes[m-65] = 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 +65,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 +114,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 +124,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 +134,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 +239,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 +266,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 +281,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 +344,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);
 
@@ -527,13 +367,14 @@ CullResult FakeUser::cull()
 
 void User::Oper(OperInfo* info)
 {
-       if (this->IsModeSet('o'))
+       ModeHandler* opermh = ServerInstance->Modes->FindMode('o', MODETYPE_USER);
+       if (this->IsModeSet(opermh))
                this->UnOper();
 
-       this->modes[UM_OPERATOR] = 1;
+       this->SetMode(opermh, true);
        this->oper = info;
        this->WriteServ("MODE %s :+o", this->nick.c_str());
-       FOREACH_MOD(I_OnOper, OnOper(this, info->name));
+       FOREACH_MOD(OnOper, (this, info->name));
 
        std::string opername;
        if (info->oper_block)
@@ -551,17 +392,17 @@ 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
        if (IS_LOCAL(this))
                oper->init();
 
-       FOREACH_MOD(I_OnPostOper,OnPostOper(this, oper->name, opername));
+       FOREACH_MOD(OnPostOper, (this, oper->name, opername));
 }
 
 void OperInfo::init()
@@ -650,13 +491,14 @@ void User::UnOper()
        /* remove the user from the oper list. Will remove multiple entries as a safeguard against bug #404 */
        ServerInstance->Users->all_opers.remove(this);
 
-       this->modes[UM_OPERATOR] = 0;
+       ModeHandler* opermh = ServerInstance->Modes->FindMode('o', MODETYPE_USER);
+       this->SetMode(opermh, false);
 }
 
 /*
  * Check class restrictions
  */
-void LocalUser::CheckClass()
+void LocalUser::CheckClass(bool clone_count)
 {
        ConnectClass* a = this->MyClass;
 
@@ -670,19 +512,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 +577,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());
@@ -765,11 +608,11 @@ void LocalUser::FullConnect()
         * We don't set REG_ALL until triggering OnUserConnect, so some module events don't spew out stuff
         * for a user that doesn't exist yet.
         */
-       FOREACH_MOD(I_OnUserConnect,OnUserConnect(this));
+       FOREACH_MOD(OnUserConnect, (this));
 
        this->registered = REG_ALL;
 
-       FOREACH_MOD(I_OnPostConnect,OnPostConnect(this));
+       FOREACH_MOD(OnPostConnect, (this));
 
        ServerInstance->SNO->WriteToSnoMask('c',"Client connecting on port %d (class %s): %s (%s) [%s]",
                this->GetServerPort(), this->MyClass->name.c_str(), GetFullRealHost().c_str(), this->GetIPString().c_str(), this->fullname.c_str());
@@ -796,17 +639,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))
@@ -898,7 +740,7 @@ bool User::ChangeNick(const std::string& newnick, bool force)
        (*(ServerInstance->Users->clientlist))[newnick] = this;
 
        if (registered == REG_ALL)
-               FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(this,oldnick));
+               FOREACH_MOD(OnUserPostNick, (this,oldnick));
 
        return true;
 }
@@ -977,7 +819,7 @@ void LocalUser::SetClientIP(const irc::sockets::sockaddrs& sa, bool recheck_elin
                if (recheck_eline)
                        this->exempt = (ServerInstance->XLines->MatchesLine("E", this) != NULL);
 
-               FOREACH_MOD(I_OnSetUserIP,OnSetUserIP(this));
+               FOREACH_MOD(OnSetUserIP, (this));
        }
 }
 
@@ -996,10 +838,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 +860,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 +875,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 +887,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 +917,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 +927,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 +939,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)
@@ -1166,7 +971,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self)
 
        exceptions[this] = include_self;
 
-       FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));
+       FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));
 
        for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
        {
@@ -1207,7 +1012,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op
        UserChanList include_c(chans);
        std::map<User*,bool> exceptions;
 
-       FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));
+       FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));
 
        for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
        {
@@ -1250,38 +1055,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
@@ -1324,7 +1117,7 @@ bool User::ChangeName(const char* gecos)
                FIRST_MOD_RESULT(OnChangeLocalUserGECOS, MOD_RESULT, (IS_LOCAL(this),gecos));
                if (MOD_RESULT == MOD_RES_DENY)
                        return false;
-               FOREACH_MOD(I_OnChangeName,OnChangeName(this,gecos));
+               FOREACH_MOD(OnChangeName, (this,gecos));
        }
        this->fullname.assign(gecos, 0, ServerInstance->Config->Limits.MaxGecos);
 
@@ -1342,7 +1135,7 @@ void User::DoHostCycle(const std::string &quitline)
        UserChanList include_c(chans);
        std::map<User*,bool> exceptions;
 
-       FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions));
+       FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions));
 
        for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i)
        {
@@ -1410,7 +1203,7 @@ bool User::ChangeDisplayedHost(const char* shost)
                        return false;
        }
 
-       FOREACH_MOD(I_OnChangeHost, OnChangeHost(this,shost));
+       FOREACH_MOD(OnChangeHost, (this,shost));
 
        std::string quitstr = ":" + GetFullHost() + " QUIT :Changing host";
 
@@ -1432,7 +1225,7 @@ bool User::ChangeIdent(const char* newident)
        if (this->ident == newident)
                return true;
 
-       FOREACH_MOD(I_OnChangeIdent, OnChangeIdent(this,newident));
+       FOREACH_MOD(OnChangeIdent, (this,newident));
 
        std::string quitstr = ":" + GetFullHost() + " QUIT :Changing ident";
 
@@ -1447,13 +1240,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++)