summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/command_parse.cpp75
-rw-r--r--src/userprocess.cpp43
-rw-r--r--src/users.cpp3
3 files changed, 74 insertions, 47 deletions
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index f07a4ffd7..f3ff69c96 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -6,7 +6,7 @@
* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
@@ -214,7 +214,45 @@ CmdResult CommandParser::CallHandler(const std::string &commandname,const char**
return CMD_INVALID;
}
-void CommandParser::ProcessCommand(User *user, std::string &cmd)
+void CommandParser::DoLines(User* current, bool one_only)
+{
+ // while there are complete lines to process...
+ int floodlines = 0;
+
+ while (current->BufferIsReady())
+ {
+ if (ServerInstance->Time() > current->reset_due)
+ {
+ current->reset_due = ServerInstance->Time() + current->threshold;
+ current->lines_in = 0;
+ }
+
+ if (++current->lines_in > current->flood && current->flood)
+ {
+ ServerInstance->FloodQuitUser(current);
+ return;
+ }
+
+ if ((++floodlines > current->flood) && (current->flood != 0))
+ {
+ ServerInstance->FloodQuitUser(current);
+ return;
+ }
+
+ // use GetBuffer to copy single lines into the sanitized string
+ std::string single_line = current->GetBuffer();
+ current->bytes_in += single_line.length();
+ current->cmds_in++;
+ if (single_line.length() > MAXBUF - 2) // MAXBUF is 514 to allow for neccessary line terminators
+ single_line.resize(MAXBUF - 2); // So to trim to 512 here, we use MAXBUF - 2
+
+ // ProcessBuffer returns false if the user has gone over penalty
+ if (!ServerInstance->Parser->ProcessBuffer(single_line, current) || one_only)
+ break;
+ }
+}
+
+bool CommandParser::ProcessCommand(User *user, std::string &cmd)
{
const char *command_p[MAXPARAMETERS];
int items = 0;
@@ -241,7 +279,7 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
int MOD_RESULT = 0;
FOREACH_RESULT(I_OnPreCommand,OnPreCommand(command,command_p,items,user,false,cmd));
if (MOD_RESULT == 1) {
- return;
+ return true;
}
if (!user)
@@ -251,7 +289,7 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
* I'm not entirely sure when we would be passed NULL, but let's handle it
* anyway, by dropping it like a hot potato. -- w00t
*/
- return;
+ return true;
}
/* find the command, check it exists */
@@ -261,9 +299,15 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
{
ServerInstance->stats->statsUnknown++;
user->WriteServ("421 %s %s :Unknown command",user->nick,command.c_str());
- return;
+ return true;
}
+ /* Modify the user's penalty */
+ user->Penalty += cm->second->Penalty;
+ bool do_more = (user->Penalty < 10);
+ if (do_more)
+ user->OverPenalty = true;
+
/* activity resets the ping pending timer */
user->nping = ServerInstance->Time() + user->pingmax;
if (cm->second->flags_needed)
@@ -271,12 +315,12 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
if (!user->IsModeSet(cm->second->flags_needed))
{
user->WriteServ("481 %s :Permission Denied - You do not have the required operator privileges",user->nick);
- return;
+ return do_more;
}
if (!user->HasPermission(command))
{
user->WriteServ("481 %s :Permission Denied - Oper type %s does not have access to command %s",user->nick,user->oper,command.c_str());
- return;
+ return do_more;
}
}
if ((user->registered == REG_ALL) && (!IS_OPER(user)) && (cm->second->IsDisabled()))
@@ -285,19 +329,19 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
user->WriteServ("421 %s %s :This command has been disabled.",user->nick,command.c_str());
ServerInstance->SNO->WriteToSnoMask('d', "%s denied for %s (%s@%s)",
command.c_str(), user->nick, user->ident, user->host);
- return;
+ return do_more;
}
if (items < cm->second->min_params)
{
user->WriteServ("461 %s %s :Not enough parameters.", user->nick, command.c_str());
if ((ServerInstance->Config->SyntaxHints) && (user->registered == REG_ALL) && (cm->second->syntax.length()))
user->WriteServ("304 %s :SYNTAX %s %s", user->nick, cm->second->command.c_str(), cm->second->syntax.c_str());
- return;
+ return do_more;
}
if ((user->registered != REG_ALL) && (!cm->second->WorksBeforeReg()))
{
user->WriteServ("451 %s :You have not registered",command.c_str());
- return;
+ return do_more;
}
else
{
@@ -309,7 +353,7 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
int MOD_RESULT = 0;
FOREACH_RESULT(I_OnPreCommand,OnPreCommand(command,command_p,items,user,true,cmd));
if (MOD_RESULT == 1)
- return;
+ return do_more;
/*
* WARNING: be careful, the user may be deleted soon
@@ -317,7 +361,7 @@ void CommandParser::ProcessCommand(User *user, std::string &cmd)
CmdResult result = cm->second->Handle(command_p,items,user);
FOREACH_MOD(I_OnPostCommand,OnPostCommand(command, command_p, items, user, result,cmd));
- return;
+ return do_more;
}
}
@@ -351,12 +395,12 @@ void CommandParser::RemoveCommand(Commandable::iterator safei, const char* sourc
}
}
-void CommandParser::ProcessBuffer(std::string &buffer,User *user)
+bool CommandParser::ProcessBuffer(std::string &buffer,User *user)
{
std::string::size_type a;
if (!user)
- return;
+ return true;
while ((a = buffer.rfind("\n")) != std::string::npos)
buffer.erase(a);
@@ -368,9 +412,10 @@ void CommandParser::ProcessBuffer(std::string &buffer,User *user)
if (!user->muted)
{
ServerInstance->Log(DEBUG,"C[%d] I :%s %s",user->GetFd(), user->nick, buffer.c_str());
- this->ProcessCommand(user,buffer);
+ return this->ProcessCommand(user,buffer);
}
}
+ return true;
}
bool CommandParser::CreateCommand(Command *f, void* so_handle)
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 9009cf061..75f0da0ee 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -72,7 +72,6 @@ void ProcessUserHandler::Call(User* cu)
{
User *current;
int currfd;
- int floodlines = 0;
Server->stats->statsRecv += result;
/*
@@ -123,36 +122,7 @@ void ProcessUserHandler::Call(User* cu)
return;
}
- // while there are complete lines to process...
- while (current->BufferIsReady())
- {
- if (Server->Time() > current->reset_due)
- {
- current->reset_due = Server->Time() + current->threshold;
- current->lines_in = 0;
- }
-
- if (++current->lines_in > current->flood && current->flood)
- {
- Server->FloodQuitUser(current);
- return;
- }
-
- if ((++floodlines > current->flood) && (current->flood != 0))
- {
- Server->FloodQuitUser(current);
- return;
- }
-
- // use GetBuffer to copy single lines into the sanitized string
- std::string single_line = current->GetBuffer();
- current->bytes_in += single_line.length();
- current->cmds_in++;
- if (single_line.length() > MAXBUF - 2) /* MAXBUF is 514 to allow for neccessary line terminators */
- single_line.resize(MAXBUF - 2); /* So to trim to 512 here, we use MAXBUF - 2 */
-
- Server->Parser->ProcessBuffer(single_line, current);
- }
+ Server->Parser->DoLines(current);
return;
}
@@ -190,6 +160,17 @@ void InspIRCd::DoBackgroundUserStuff()
{
User *curr = *count2;
+ if (curr->OverPenalty)
+ Parser->DoLines(curr, true);
+
+ /* Knock a second off */
+ if (curr->Penalty)
+ {
+ curr->Penalty--;
+ if (!curr->Penalty)
+ curr->OverPenalty = false;
+ }
+
if ((curr->registered != REG_ALL) && (TIME > curr->timeout))
{
/*
diff --git a/src/users.cpp b/src/users.cpp
index f978fc441..060e90782 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -175,9 +175,10 @@ User::User(InspIRCd* Instance, const std::string &uid) : ServerInstance(Instance
server = (char*)Instance->FindServerNamePtr(Instance->Config->ServerName);
reset_due = ServerInstance->Time();
age = ServerInstance->Time(true);
+ Penalty = 0;
lines_in = lastping = signon = idle_lastmsg = nping = registered = 0;
ChannelCount = timeout = flood = bytes_in = bytes_out = cmds_in = cmds_out = 0;
- ExemptFromPenalty = UnderPenalty = muted = exempt = haspassed = dns_done = false;
+ OverPenalty = ExemptFromPenalty = muted = exempt = haspassed = dns_done = false;
fd = -1;
recvq.clear();
sendq.clear();