]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Started work on /UNLOADMODULE, resource tracking and flags in Version class
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Thu, 7 Apr 2005 17:04:04 +0000 (17:04 +0000)
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>
Thu, 7 Apr 2005 17:04:04 +0000 (17:04 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@999 e03df62e-2008-0410-955e-edbf42e46eb7

23 files changed:
include/commands.h
include/ctables.h
include/inspircd.h
include/modules.h
src/commands.cpp
src/inspircd.cpp
src/modules.cpp
src/modules/m_chghost.cpp
src/modules/m_globops.cpp
src/modules/m_helpop.cpp
src/modules/m_knock.cpp
src/modules/m_opermotd.cpp
src/modules/m_randquote.cpp
src/modules/m_remove.cpp
src/modules/m_sajoin.cpp
src/modules/m_samode.cpp
src/modules/m_sanick.cpp
src/modules/m_sapart.cpp
src/modules/m_saquit.cpp
src/modules/m_sethost.cpp
src/modules/m_setname.cpp
src/modules/m_silence.cpp
src/modules/m_testcommand.cpp

index aa6fcf206067556747271c5ba9e396335c179d80..589168409741323b0a997427a19f5b11fcdfd173 100644 (file)
@@ -80,6 +80,7 @@ void handle_qline(char **parameters, int pcnt, userrec *user);
 void handle_eline(char **parameters, int pcnt, userrec *user);
 void handle_server(char **parameters, int pcnt, userrec *user);
 void handle_loadmodule(char **parameters, int pcnt, userrec *user);
+void handle_unloadmodule(char **parameters, int pcnt, userrec *user);
 
 /** Special functions for processing server to server traffic
  */
index fb96b9ef69e5a5ad7a2e242386c96c2970e0af06..5926f3a2a2f76c2926555503f205a564b690d817 100644 (file)
@@ -44,6 +44,9 @@ class command_t : public Extensible
        /** used by /stats m
         */
        long total_bytes;
+       /** used for resource tracking between modules
+        */
+       char source[MAXBUF];
 };
 
 #endif
index e54da779b7ad9b94267657662341b8932c66534f..b7a5b71045c72c658b029751ebf41e50a35556b2 100644 (file)
@@ -159,6 +159,7 @@ long map_count(const char* s);
 userrec* ReHashNick(char* Old, char* New);
 long GetMaxBans(char* name);
 bool LoadModule(const char* filename);
+bool UnloadModule(const char* filename);
 char* ModuleError();
 
 // mesh network functions
index 9b2118472b15307c689a8d0e7c66da6a6905c4eb..b1f505e295bc1ef5fe135ff7fe09b1c328eb2e8b 100644 (file)
@@ -96,7 +96,7 @@ typedef std::deque<userrec*> chanuserlist;
    
 // *********************************************************************************************
 
-extern void createcommand(char* cmd, handlerfunc f, char flags, int minparams);
+extern void createcommand(char* cmd, handlerfunc f, char flags, int minparams, char* source);
 extern void server_mode(char **parameters, int pcnt, userrec *user);
 
 // class Version holds the version information of a Module, returned
@@ -109,8 +109,8 @@ extern void server_mode(char **parameters, int pcnt, userrec *user);
 class Version : public classbase
 {
  public:
-        const int Major, Minor, Revision, Build;
-        Version(int major, int minor, int revision, int build);
+        const int Major, Minor, Revision, Build, Flags;
+        Version(int major, int minor, int revision, int build, int flags);
 };
 
 /** Holds /ADMIN data
@@ -545,8 +545,11 @@ class Server : public classbase
         * than the 'minparams' value you specified when creating the command. The *user parameter is the class of
         * the user which caused the command to trigger, who will always have the flag you specified in 'flags' when
         * creating the initial command. For example to create an oper only command create the commands with flags='o'.
+        * The source parameter is used for resource tracking, and should contain the name of your module (with file
+        * extension) e.g. "m_blarp.so". If you place the wrong identifier here, you can cause crashes if your module
+        * is unloaded.
         */
-       virtual void AddCommand(char* cmd, handlerfunc f, char flags, int minparams);
+       virtual void AddCommand(char* cmd, handlerfunc f, char flags, int minparams, char* source);
         
        /** Sends a servermode.
         * you must format the parameters array with the target, modes and parameters for those modes.
index 5d8f9431696616eb22bb3bdc262cbc78cd175491..19dd9f200a070cf9be2106efa08a6229fd31c377 100644 (file)
@@ -283,6 +283,19 @@ void handle_loadmodule(char **parameters, int pcnt, userrec *user)
        }
 }
 
+void handle_unloadmodule(char **parameters, int pcnt, userrec *user)
+{
+        if (UnloadModule(parameters[0]))
+        {
+                WriteOpers("*** MODULE UNLOADED: %s",parameters[0]);
+                WriteServ(user->fd,"973 %s %s :Module successfully unloaded.",user->nick, parameters[0]);
+        }
+        else
+        {
+                WriteServ(user->fd,"972 %s %s :Failed to unload module: %s",user->nick, parameters[0],ModuleError());
+        }
+}
+
 void handle_die(char **parameters, int pcnt, userrec *user)
 {
        log(DEBUG,"die: %s",user->nick);
index d3c9e9ed4b3def66f9a64750d736afa804c91705..f0d007cb949a7df723dcf5a2009c0d1c0ba10456 100644 (file)
@@ -2920,11 +2920,12 @@ void process_command(userrec *user, char* cmd)
 }
 
 
-void createcommand(char* cmd, handlerfunc f, char flags, int minparams)
+void createcommand(char* cmd, handlerfunc f, char flags, int minparams,char* source)
 {
        command_t comm;
        /* create the command and push it onto the table */     
        strlcpy(comm.command,cmd,MAXBUF);
+       strlcpy(comm.source,source,MAXBUF);
        comm.handler_function = f;
        comm.flags_needed = flags;
        comm.min_params = minparams;
@@ -2934,59 +2935,80 @@ void createcommand(char* cmd, handlerfunc f, char flags, int minparams)
        log(DEBUG,"Added command %s (%d parameters)",cmd,minparams);
 }
 
+bool removecommands(const char* source)
+{
+       bool go_again = true;
+       while (go_again)
+       {
+               go_again = false;
+               for (std::deque<command_t>::iterator i = cmdlist.begin(); i != cmdlist.end(); i++)
+               {
+                       if (!strcmp(i->source,source))
+                       {
+                               log(DEBUG,"removecommands(%s) Removing dependent command: %s",i->source,i->command);
+                               cmdlist.erase(i);
+                               go_again = true;
+                               break;
+                       }
+               }
+       }
+       return true;
+}
+
 void SetupCommandTable(void)
 {
-       createcommand("USER",handle_user,0,4);
-       createcommand("NICK",handle_nick,0,1);
-       createcommand("QUIT",handle_quit,0,0);
-       createcommand("VERSION",handle_version,0,0);
-       createcommand("PING",handle_ping,0,1);
-       createcommand("PONG",handle_pong,0,1);
-       createcommand("ADMIN",handle_admin,0,0);
-       createcommand("PRIVMSG",handle_privmsg,0,2);
-       createcommand("INFO",handle_info,0,0);
-       createcommand("TIME",handle_time,0,0);
-       createcommand("WHOIS",handle_whois,0,1);
-       createcommand("WALLOPS",handle_wallops,'o',1);
-       createcommand("NOTICE",handle_notice,0,2);
-       createcommand("JOIN",handle_join,0,1);
-       createcommand("NAMES",handle_names,0,1);
-       createcommand("PART",handle_part,0,1);
-       createcommand("KICK",handle_kick,0,2);
-       createcommand("MODE",handle_mode,0,1);
-       createcommand("TOPIC",handle_topic,0,1);
-       createcommand("WHO",handle_who,0,1);
-       createcommand("MOTD",handle_motd,0,0);
-       createcommand("RULES",handle_rules,0,0);
-       createcommand("OPER",handle_oper,0,2);
-       createcommand("LIST",handle_list,0,0);
-       createcommand("DIE",handle_die,'o',1);
-       createcommand("RESTART",handle_restart,'o',1);
-       createcommand("KILL",handle_kill,'o',2);
-       createcommand("REHASH",handle_rehash,'o',0);
-       createcommand("LUSERS",handle_lusers,0,0);
-       createcommand("STATS",handle_stats,0,1);
-       createcommand("USERHOST",handle_userhost,0,1);
-       createcommand("AWAY",handle_away,0,0);
-       createcommand("ISON",handle_ison,0,0);
-       createcommand("SUMMON",handle_summon,0,0);
-       createcommand("USERS",handle_users,0,0);
-       createcommand("INVITE",handle_invite,0,2);
-       createcommand("PASS",handle_pass,0,1);
-       createcommand("TRACE",handle_trace,'o',0);
-       createcommand("WHOWAS",handle_whowas,0,1);
-       createcommand("CONNECT",handle_connect,'o',1);
-       createcommand("SQUIT",handle_squit,'o',0);
-       createcommand("MODULES",handle_modules,'o',0);
-       createcommand("LINKS",handle_links,0,0);
-       createcommand("MAP",handle_map,0,0);
-       createcommand("KLINE",handle_kline,'o',1);
-       createcommand("GLINE",handle_gline,'o',1);
-       createcommand("ZLINE",handle_zline,'o',1);
-       createcommand("QLINE",handle_qline,'o',1);
-       createcommand("ELINE",handle_eline,'o',1);
-       createcommand("LOADMODULE",handle_loadmodule,'o',1);
-       createcommand("SERVER",handle_server,0,0);
+       createcommand("USER",handle_user,0,4,"<core>");
+       createcommand("NICK",handle_nick,0,1,"<core>");
+       createcommand("QUIT",handle_quit,0,0,"<core>");
+       createcommand("VERSION",handle_version,0,0,"<core>");
+       createcommand("PING",handle_ping,0,1,"<core>");
+       createcommand("PONG",handle_pong,0,1,"<core>");
+       createcommand("ADMIN",handle_admin,0,0,"<core>");
+       createcommand("PRIVMSG",handle_privmsg,0,2,"<core>");
+       createcommand("INFO",handle_info,0,0,"<core>");
+       createcommand("TIME",handle_time,0,0,"<core>");
+       createcommand("WHOIS",handle_whois,0,1,"<core>");
+       createcommand("WALLOPS",handle_wallops,'o',1,"<core>");
+       createcommand("NOTICE",handle_notice,0,2,"<core>");
+       createcommand("JOIN",handle_join,0,1,"<core>");
+       createcommand("NAMES",handle_names,0,1,"<core>");
+       createcommand("PART",handle_part,0,1,"<core>");
+       createcommand("KICK",handle_kick,0,2,"<core>");
+       createcommand("MODE",handle_mode,0,1,"<core>");
+       createcommand("TOPIC",handle_topic,0,1,"<core>");
+       createcommand("WHO",handle_who,0,1,"<core>");
+       createcommand("MOTD",handle_motd,0,0,"<core>");
+       createcommand("RULES",handle_rules,0,0,"<core>");
+       createcommand("OPER",handle_oper,0,2,"<core>");
+       createcommand("LIST",handle_list,0,0,"<core>");
+       createcommand("DIE",handle_die,'o',1,"<core>");
+       createcommand("RESTART",handle_restart,'o',1,"<core>");
+       createcommand("KILL",handle_kill,'o',2,"<core>");
+       createcommand("REHASH",handle_rehash,'o',0,"<core>");
+       createcommand("LUSERS",handle_lusers,0,0,"<core>");
+       createcommand("STATS",handle_stats,0,1,"<core>");
+       createcommand("USERHOST",handle_userhost,0,1,"<core>");
+       createcommand("AWAY",handle_away,0,0,"<core>");
+       createcommand("ISON",handle_ison,0,0,"<core>");
+       createcommand("SUMMON",handle_summon,0,0,"<core>");
+       createcommand("USERS",handle_users,0,0,"<core>");
+       createcommand("INVITE",handle_invite,0,2,"<core>");
+       createcommand("PASS",handle_pass,0,1,"<core>");
+       createcommand("TRACE",handle_trace,'o',0,"<core>");
+       createcommand("WHOWAS",handle_whowas,0,1,"<core>");
+       createcommand("CONNECT",handle_connect,'o',1,"<core>");
+       createcommand("SQUIT",handle_squit,'o',0,"<core>");
+       createcommand("MODULES",handle_modules,'o',0,"<core>");
+       createcommand("LINKS",handle_links,0,0,"<core>");
+       createcommand("MAP",handle_map,0,0,"<core>");
+       createcommand("KLINE",handle_kline,'o',1,"<core>");
+       createcommand("GLINE",handle_gline,'o',1,"<core>");
+       createcommand("ZLINE",handle_zline,'o',1,"<core>");
+       createcommand("QLINE",handle_qline,'o',1,"<core>");
+       createcommand("ELINE",handle_eline,'o',1,"<core>");
+       createcommand("LOADMODULE",handle_loadmodule,'o',1,"<core>");
+       createcommand("UNLOADMODULE",handle_unloadmodule,'o',1,"<core>");
+       createcommand("SERVER",handle_server,0,0,"<core>");
 }
 
 void process_buffer(const char* cmdbuf,userrec *user)
@@ -3241,6 +3263,51 @@ char* ModuleError()
        return MODERR;
 }
 
+bool UnloadModule(const char* filename)
+{
+       for (int j = 0; j != module_names.size(); j++)
+       {
+               if (module_names[j] == std::string(filename))
+               {
+                       // found the module
+                       log(DEBUG,"Deleting module...");
+                       delete factory[j]->factory;
+                       log(DEBUG,"Deleting module factory...");
+                       delete factory[j];
+                       log(DEBUG,"Erasing module entry...");
+                       factory[j] = NULL;
+                       // here we should locate ALL resources claimed by this module... and release them
+                       // for example commands
+                       log(DEBUG,"Erasing module vector...");
+                       for (std::vector<ircd_module*>::iterator t = factory.begin(); t != factory.end(); t++)
+                       {
+                               if (*t == NULL)
+                               {
+                                       factory.erase(t);
+                                       break;
+                               }
+                       }
+                       log(DEBUG,"Erasing module name vector...");
+                       for (std::vector<std::string>::iterator v = module_names.begin(); v != module_names.end(); v++)
+                        {
+                                if (*v == std::string(filename))
+                                {
+                                        module_names.erase(v);
+                                        break;
+                                }
+                        }
+                        log(DEBUG,"Removing dependent commands...");
+                        removecommands(filename);
+                       log(DEFAULT,"Module %s unloaded",filename);
+                       MODCOUNT--;
+                       return true;
+               }
+       }
+       log(DEFAULT,"Module %s is not loaded, cannot unload it!",filename);
+       snprintf(MODERR,MAXBUF,"Module not loaded");
+       return false;
+}
+
 bool LoadModule(const char* filename)
 {
        char modfile[MAXBUF];
index ec1d205605b9cbf2fb924309efc7c51d043be771..7242ae92e79678afee2c693bf2acb1b6fb1db25a 100644 (file)
@@ -297,7 +297,7 @@ void ModeMakeList(char modechar)
 
 // version is a simple class for holding a modules version number
 
-Version::Version(int major, int minor, int revision, int build) : Major(major), Minor(minor), Revision(revision), Build(build) { };
+Version::Version(int major, int minor, int revision, int build, int flags) : Major(major), Minor(minor), Revision(revision), Build(build), Flags(flags) { };
 
 // admin is a simple class for holding a server's administrative info
 
@@ -417,9 +417,9 @@ void Server::Log(int level, std::string s)
        log(level,"%s",s.c_str());
 }
 
-void Server::AddCommand(char* cmd, handlerfunc f, char flags, int minparams)
+void Server::AddCommand(char* cmd, handlerfunc f, char flags, int minparams, char* source)
 {
-       createcommand(cmd,f,flags,minparams);
+       createcommand(cmd,f,flags,minparams,source);
 }
 
 void Server::SendMode(char **parameters, int pcnt, userrec *user)
index c1ba262f143d1c9354a6da4eeefb563004815f18..366166e4c7bd9297cfd420fcf5e48f23d1d80fd9 100644 (file)
@@ -51,7 +51,7 @@ class ModuleChgHost : public Module
        ModuleChgHost()
        {
                Srv = new Server;
-               Srv->AddCommand("CHGHOST",handle_chghost,'o',2);
+               Srv->AddCommand("CHGHOST",handle_chghost,'o',2,"m_chghost.so");
        }
        
        virtual ~ModuleChgHost()
index 03c49ca104e48b0b1df1b1a5783f5eab85edbd2d..5a1a8f7b31f76b1e72167f305f8635074ab3c3be 100644 (file)
@@ -50,7 +50,7 @@ class ModuleGlobops : public Module
                        printf("Could not claim usermode +g for this module!");
                        exit(0);
                }
-               Srv->AddCommand("GLOBOPS",handle_globops,'o',1);
+               Srv->AddCommand("GLOBOPS",handle_globops,'o',1,"m_globops.so");
        }
        
        virtual ~ModuleGlobops()
index 71b9013e4b16748685187e8b0cb8715d8d6170e1..dc4f6f6148e27bc7a074b138023c374d52d418b9 100644 (file)
@@ -163,7 +163,7 @@ class ModuleHelpop : public Module
                }
 
                // Loads of comments, untill supported properly.
-               Srv->AddCommand("HELPOP",handle_helpop,0,0);
+               Srv->AddCommand("HELPOP",handle_helpop,0,0,"m_helpop.so");
 
        }
 
index fb07bcafc21f3be8652f306e466645a04f5aa915..3940a61a6e50b5e4156e27d99aaf720cb5d576d7 100644 (file)
@@ -62,7 +62,7 @@ class ModuleKnock : public Module
                Srv = new Server;
                
                Srv->AddExtendedMode('K',MT_CHANNEL,false,0,0);
-               Srv->AddCommand("KNOCK",handle_knock,0,2);
+               Srv->AddCommand("KNOCK",handle_knock,0,2,"m_knock.so");
        }
 
         virtual void On005Numeric(std::string &output)
index ef2ad89e7237e487907b14b70f89e17866972b89..06b994c915927a8d97b86d975460a6d01b0dcd6f 100644 (file)
@@ -58,7 +58,7 @@ class ModuleOpermotd : public Module {
 
                        Srv = new Server;
                        
-                       Srv->AddCommand("OPERMOTD",do_opermotd,'o',0);
+                       Srv->AddCommand("OPERMOTD",do_opermotd,'o',0,"m_opermotd.so");
 
                        opermotd = new FileReader();
                        LoadOperMOTD();
index d3dfc5a4575e0999cd2d07b72ce90921813d6901..1a875e52709b5efb058e46f87017e71325481c74 100644 (file)
@@ -80,7 +80,7 @@ class ModuleRandQuote : public Module
                        exit(0);
                }
                /* Hidden Command -- Mode clients assume /quote sends raw data to an IRCd >:D */
-               Srv->AddCommand("QUOTE",handle_randquote,0,0);
+               Srv->AddCommand("QUOTE",handle_randquote,0,0,"m_randquote.so");
        }
        
        virtual ~ModuleRandQuote()
index 873bdb25e4cb69463ff2206a8d57e07d96f68230..d4735081fdcb3574227e10132b6b982039432aaa 100644 (file)
@@ -113,7 +113,7 @@ class ModuleRemove : public Module
        ModuleRemove()
        {
                Srv = new Server;
-               Srv->AddCommand("REMOVE", handle_remove, 0, 3);
+               Srv->AddCommand("REMOVE", handle_remove, 0, 3, "m_remove.so");
        }
 
         virtual void On005Numeric(std::string &output)
index 5b461362b45b6486fc6ad33cba40d483965692b3..b3ca5fef2c7e76bfed5935556fee5de67dd5a26b 100644 (file)
@@ -51,7 +51,7 @@ class ModuleSajoin : public Module
        ModuleSajoin()
        {
                Srv = new Server;
-               Srv->AddCommand("SAJOIN",handle_sajoin,'o',2);
+               Srv->AddCommand("SAJOIN",handle_sajoin,'o',2,"m_sajoin.so");
        }
        
        virtual ~ModuleSajoin()
index 6a2499f12f21531d72a8bc5771546ae972b9bf08..624f0483b1bde1d75679bbb8a12e3c39cb85ef4a 100644 (file)
@@ -62,9 +62,7 @@ class ModuleSaMode : public Module
        ModuleSaMode()
        {
                Srv = new Server;
-                Srv->Log(DEBUG,"SAMODE: Pre-add cmd");
-               Srv->AddCommand("SAMODE",handle_samode,'o',2);
-               Srv->Log(DEBUG,"SAMODE: Post-add cmd");
+               Srv->AddCommand("SAMODE",handle_samode,'o',2,"m_samode.so");
        }
        
        virtual ~ModuleSaMode()
index 053f598288ef5e9392dd1ba3432fa32fe0fb0e51..65de142505beeffeb0b7f8ed4f900b36fd8eb8af 100644 (file)
@@ -46,7 +46,7 @@ class ModuleSanick : public Module
        ModuleSanick()
        {
                Srv = new Server;
-               Srv->AddCommand("SANICK",handle_sanick,'o',2);
+               Srv->AddCommand("SANICK",handle_sanick,'o',2,"m_sanick.so");
        }
        
        virtual ~ModuleSanick()
index fb15d2cf8d481cd45254dad188e4a68edd994d22..e4b36b0357961d1fb1412f6eaa22e1b3d7a9376f 100644 (file)
@@ -50,7 +50,7 @@ class ModuleSapart : public Module
        ModuleSapart()
        {
                Srv = new Server;
-               Srv->AddCommand("SAPART",handle_sapart,'o',2);
+               Srv->AddCommand("SAPART",handle_sapart,'o',2,"m_sapart.so");
        }
        
        virtual ~ModuleSapart()
index 9996f204427c738d2a9971bd7e56d5e99d2504b6..5221f38eac04bdc31e0aea9812d01194400697de 100644 (file)
@@ -58,7 +58,7 @@ class ModuleSaquit : public Module
        ModuleSaquit()
        {
                Srv = new Server;
-               Srv->AddCommand("SAQUIT",handle_saquit,'o',2);
+               Srv->AddCommand("SAQUIT",handle_saquit,'o',2,"m_saquit.so");
        }
        
        virtual ~ModuleSaquit()
index ba5e3319bb91908dfb0f95184c4533ed1b35346b..dd60e57669999bf3f180ef098fa1ed75ee517282 100644 (file)
@@ -48,7 +48,7 @@ class ModuleSetHost : public Module
        ModuleSetHost()
        {
                Srv = new Server;
-               Srv->AddCommand("SETHOST",handle_sethost,'o',1);
+               Srv->AddCommand("SETHOST",handle_sethost,'o',1,"m_sethost.so");
        }
        
        virtual ~ModuleSetHost()
index 110afbe518fc4d95a02b06b9c72dce5888106f02..c1489876f1e6a29864111d0576ba64c9df776aa3 100644 (file)
@@ -42,7 +42,7 @@ class ModuleSetName : public Module
        ModuleSetName()
        {
                Srv = new Server;
-               Srv->AddCommand("SETNAME",handle_setname,0,1);
+               Srv->AddCommand("SETNAME",handle_setname,0,1,"m_setname.so");
        }
        
        virtual ~ModuleSetName()
index e6cd730ac48302c10f0d19498c4ad6e567d0b303..a73ec757d02c70b302c431dabea5bf6b3ff93264 100644 (file)
@@ -120,7 +120,7 @@ class ModuleSilence : public Module
        ModuleSilence()
        {
                Srv = new Server;
-               Srv->AddCommand("SILENCE",handle_silence,0,0);
+               Srv->AddCommand("SILENCE",handle_silence,0,0,"m_silence.so");
        }
 
        virtual void OnUserQuit(userrec* user)
index 452160dd0456cfaba6e6ac382b6c0601ebb2fc1c..984283fc3f99d9163ee09738f2cc4cc196f6dbbd 100644 (file)
@@ -55,7 +55,7 @@ class ModuleTestCommand : public Module
                // 0 in the modes parameter signifies that
                // anyone can issue the command, and the
                // command takes only one parameter.
-               Srv->AddCommand("WOOT",handle_woot,0,0);
+               Srv->AddCommand("WOOT",handle_woot,0,0,"m_testcommand.so");
 
                // Add a mode +Z for channels with no parameters                
                Srv->AddExtendedMode('Z',MT_CHANNEL,false,1,0);