]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/command_parse.cpp
Convert more modules
[user/henk/code/inspircd.git] / src / command_parse.cpp
index 0fa7c05b2783efefe9d9e6a2ebc3c5d19909ff42..d03cb9296054d7ae1033973e1c2d32479898f5cf 100644 (file)
@@ -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.
@@ -224,7 +212,7 @@ int CommandParser::LoopCall(userrec* user, command_t* CommandObj, const char** p
 
 bool CommandParser::IsValidCommand(const std::string &commandname, int pcnt, userrec * user)
 {
-       nspace::hash_map<std::string,command_t*>::iterator n = cmdlist.find(commandname);
+       command_table::iterator n = cmdlist.find(commandname);
 
        if (n != cmdlist.end())
        {
@@ -245,7 +233,7 @@ bool CommandParser::IsValidCommand(const std::string &commandname, int pcnt, use
 
 command_t* CommandParser::GetHandler(const std::string &commandname)
 {
-       nspace::hash_map<std::string,command_t*>::iterator n = cmdlist.find(commandname);
+       command_table::iterator n = cmdlist.find(commandname);
        if (n != cmdlist.end())
                return n->second;
 
@@ -256,7 +244,7 @@ command_t* CommandParser::GetHandler(const std::string &commandname)
 
 CmdResult CommandParser::CallHandler(const std::string &commandname,const char** parameters, int pcnt, userrec *user)
 {
-       nspace::hash_map<std::string,command_t*>::iterator n = cmdlist.find(commandname);
+       command_table::iterator n = cmdlist.find(commandname);
 
        if (n != cmdlist.end())
        {
@@ -311,7 +299,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
                return;
        }
 
-       nspace::hash_map<std::string,command_t*>::iterator cm = cmdlist.find(command);
+       command_table::iterator cm = cmdlist.find(command);
        
        if (cm != cmdlist.end())
        {
@@ -323,16 +311,16 @@ 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;
                                }
                        }
-                       if ((user->registered == REG_ALL) && (!*user->oper) && (cm->second->IsDisabled()))
+                       if ((user->registered == REG_ALL) && (!IS_OPER(user)) && (cm->second->IsDisabled()))
                        {
                                /* command is disabled! */
                                user->WriteServ("421 %s %s :This command has been disabled.",user->nick,command.c_str());
@@ -383,7 +371,7 @@ void CommandParser::ProcessCommand(userrec *user, std::string &cmd)
 
 bool CommandParser::RemoveCommands(const char* source)
 {
-       nspace::hash_map<std::string,command_t*>::iterator i,safei;
+       command_table::iterator i,safei;
        for (i = cmdlist.begin(); i != cmdlist.end(); i++)
        {
                safei = i;
@@ -401,7 +389,7 @@ bool CommandParser::RemoveCommands(const char* source)
        return true;
 }
 
-void CommandParser::RemoveCommand(nspace::hash_map<std::string,command_t*>::iterator safei, const char* source)
+void CommandParser::RemoveCommand(command_table::iterator safei, const char* source)
 {
        command_t* x = safei->second;
        if (x->source == std::string(source))
@@ -426,7 +414,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 +452,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;
@@ -549,6 +537,9 @@ void CommandParser::SetupCommandTable()
 {
        RFCCommands.clear();
 
+       printf("\nLoading core commands");
+       fflush(stdout);
+
        DIR* library = opendir(LIBRARYDIR);
        if (library)
        {
@@ -557,10 +548,13 @@ void CommandParser::SetupCommandTable()
                {
                        if (match(entry->d_name, "cmd_*.so"))
                        {
+                               printf(".");
+                               fflush(stdout);
                                this->LoadCommand(entry->d_name);
                        }
                }
                closedir(library);
+               printf("\n");
        }
 
        this->CreateCommand(new cmd_reload(ServerInstance));