]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/command_parse.cpp
Set defaults for an enum
[user/henk/code/inspircd.git] / src / command_parse.cpp
index 7529461d098a2064c7461816f92c3fa6b9e933b7..84850a880fb564d7e95895903f0e2c198593d71d 100644 (file)
@@ -1,4 +1,4 @@
-       /*       +------------------------------------+
+/*       +------------------------------------+
  *       | Inspire Internet Relay Chat Daemon |
  *       +------------------------------------+
  *
@@ -14,8 +14,6 @@
 #include "inspircd.h"
 #include "configreader.h"
 #include <algorithm>
-#include <dirent.h>
-#include <dlfcn.h>
 #include "users.h"
 #include "modules.h"
 #include "wildcard.h"
 #include "socket.h"
 #include "command_parse.h"
 
+/* Directory Searching for Unix-Only */
+#ifndef WIN32
+#include <dirent.h>
+#include <dlfcn.h>
+#endif
+
 bool InspIRCd::ULine(const char* server)
 {
        if (!server)
@@ -58,63 +62,47 @@ std::string InspIRCd::TimeString(time_t curtime)
        return std::string(ctime(&curtime),24);
 }
 
-long InspIRCd::Duration(const char* str)
+/** Refactored by Brain, Jun 2007. Much faster with some clever O(1) array
+ * lookups and pointer maths.
+ */
+long InspIRCd::Duration(const std::string &str)
 {
-       char n_field[MAXBUF];
+       unsigned char multiplier = 0;
        long total = 0;
-       n_field[0] = 0;
+       long times = 1;
+       long subtotal = 0;
 
-       if ((!strchr(str,'s')) && (!strchr(str,'m')) && (!strchr(str,'h')) && (!strchr(str,'d')) && (!strchr(str,'w')) && (!strchr(str,'y')))
+       /* Iterate each item in the string, looking for number or multiplier */
+       for (std::string::const_reverse_iterator i = str.rbegin(); i != str.rend(); ++i)
        {
-               std::string n = str;
-               n += 's';
-               return Duration(n.c_str());
-       }
-       
-       for (char* i = (char*)str; *i; i++)
-       {
-               // if we have digits, build up a string for the value in n_field,
-               // up to 10 digits in size.
+               /* Found a number, queue it onto the current number */
                if ((*i >= '0') && (*i <= '9'))
                {
-                       strlcat(n_field,i,10);
+                       subtotal = subtotal + ((*i - '0') * times);
+                       times = times * 10;
                }
                else
                {
-                       // we dont have a digit, check for numeric tokens
-                       switch (tolower(*i))
-                       {
-                               case 's':
-                                       total += atoi(n_field);
-                               break;
-
-                               case 'm':
-                                       total += (atoi(n_field)*duration_m);
-                               break;
-
-                               case 'h':
-                                       total += (atoi(n_field)*duration_h);
-                               break;
-
-                               case 'd':
-                                       total += (atoi(n_field)*duration_d);
-                               break;
-
-                               case 'w':
-                                       total += (atoi(n_field)*duration_w);
-                               break;
+                       /* Found something thats not a number, find out how much
+                        * it multiplies the built up number by, multiply the total
+                        * and reset the built up number.
+                        */
+                       if (subtotal)
+                               total += subtotal * duration_multi[multiplier];
 
-                               case 'y':
-                                       total += (atoi(n_field)*duration_y);
-                               break;
-                       }
-                       n_field[0] = 0;
+                       /* Next subtotal please */
+                       subtotal = 0;
+                       multiplier = *i;
+                       times = 1;
                }
        }
-       // add trailing seconds
-       total += atoi(n_field);
-       
-       return total;
+       if (multiplier)
+       {
+               total += subtotal * duration_multi[multiplier];
+               subtotal = 0;
+       }
+       /* Any trailing values built up are treated as raw seconds */
+       return total + subtotal;
 }
 
 /* LoopCall is used to call a command classes handler repeatedly based on the contents of a comma seperated list.
@@ -145,7 +133,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
         */
        irc::commasepstream items1(parameters[splithere]);
        irc::commasepstream items2(parameters[extra]);
-       std::string item = "*";
+       std::string item("*");
        unsigned int max = 0;
 
        /* Attempt to iterate these lists and call the command objech
@@ -156,9 +144,9 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
        {
                if (dupes.find(item.c_str()) == dupes.end())
                {
-                       const char* new_parameters[127];
+                       const char* new_parameters[MAXPARAMETERS];
 
-                       for (int t = 0; (t < pcnt) && (t < 127); t++)
+                       for (int t = 0; (t < pcnt) && (t < MAXPARAMETERS); t++)
                                new_parameters[t] = parameters[t];
 
                        std::string extrastuff = items2.GetToken();
@@ -186,7 +174,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
 
        /* Only one commasepstream here */
        irc::commasepstream items1(parameters[splithere]);
-       std::string item = "*";
+       std::string item("*");
        unsigned int max = 0;
 
        /* Parse the commasepstream until there are no tokens remaining.
@@ -197,9 +185,9 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
        {
                if (dupes.find(item.c_str()) == dupes.end())
                {
-                       const char* new_parameters[127];
+                       const char* new_parameters[MAXPARAMETERS];
 
-                       for (int t = 0; (t < pcnt) && (t < 127); t++)
+                       for (int t = 0; (t < pcnt) && (t < MAXPARAMETERS); t++)
                                new_parameters[t] = parameters[t];
 
                        new_parameters[splithere] = item.c_str();
@@ -230,7 +218,7 @@ bool CommandParser::IsValidCommand(const std::string &commandname, int pcnt, use
        {
                if ((pcnt>=n->second->min_params) && (n->second->source != "<core>"))
                {
-                       if ((!n->second->flags_needed) || (user->modes[n->second->flags_needed-65]))
+                       if ((!n->second->flags_needed) || (user->IsModeSet(n->second->flags_needed)))
                        {
                                if (n->second->flags_needed)
                                {
@@ -262,7 +250,7 @@ CmdResult CommandParser::CallHandler(const std::string &commandname,const char**
        {
                if (pcnt >= n->second->min_params)
                {
-                       if ((!n->second->flags_needed) || (user->modes[n->second->flags_needed-65]))
+                       if ((!n->second->flags_needed) || (user->IsModeSet(n->second->flags_needed)))
                        {
                                if (n->second->flags_needed)
                                {
@@ -283,7 +271,7 @@ CmdResult CommandParser::CallHandler(const std::string &commandname,const char**
 
 void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
 {
-       const char *command_p[127];
+       const char *command_p[MAXPARAMETERS];
        int items = 0;
        irc::tokenstream tokens(cmd);
        std::string command;
@@ -297,7 +285,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
        if (*command.c_str() == ':')
                tokens.GetToken(command);
 
-       while (tokens.GetToken(para[items]) && (items < 127))
+       while (tokens.GetToken(para[items]) && (items < MAXPARAMETERS))
        {
                command_p[items] = para[items].c_str();
                items++;
@@ -323,12 +311,12 @@ void CommandParser::ProcessCommand(userrec *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);
+                                       user->WriteServ("481 %s :Permission Denied - You do not have the required operator privileges",user->nick);
                                        return;
                                }
                                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());
+                                       user->WriteServ("481 %s :Permission Denied - Oper type %s does not have access to command %s",user->nick,user->oper,command.c_str());
                                        return;
                                }
                        }
@@ -341,7 +329,6 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
                        if (items < cm->second->min_params)
                        {
                                user->WriteServ("461 %s %s :Not enough parameters.", user->nick, command.c_str());
-                               /* If syntax is given, display this as the 461 reply */
                                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;
@@ -358,9 +345,8 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
                                        return;
 
                                /*
-                                * WARNING: nothing may come after the
-                                * command handler call, as the handler
-                                * may free the user structure!
+                                * WARNING: nothing should come after this, as the user may be on a cull list to
+                                * be nuked next loop iteration. be sensible.
                                 */
                                CmdResult result = cm->second->Handle(command_p,items,user);
 
@@ -407,6 +393,7 @@ void CommandParser::RemoveCommand(command_table::iterator safei, const char* sou
        if (x->source == std::string(source))
        {
                cmdlist.erase(safei);
+               delete x;
        }
 }
 
@@ -426,7 +413,7 @@ void CommandParser::ProcessBuffer(std::string &buffer,userrec *user)
        {
                if (!user->muted)
                {
-                       ServerInstance->Log(DEBUG,"-> :%s %s",user->nick,buffer.c_str());
+                       ServerInstance->Log(DEBUG,"C[%d] -> :%s %s",user->GetFd(), user->nick, buffer.c_str());
                        this->ProcessCommand(user,buffer);
                }
        }
@@ -464,7 +451,7 @@ bool CommandParser::FindSym(void** v, void* h)
 {
        *v = dlsym(h, "init_command");
        const char* err = dlerror();
-       if (err)
+       if (err && !(*v))
        {
                ServerInstance->Log(SPARSE, "Error loading core command: %s\n", err);
                return false;