]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Executable include for MOTD and more
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Tue, 2 Feb 2010 16:47:25 +0000 (16:47 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Tue, 2 Feb 2010 16:47:25 +0000 (16:47 +0000)
This introduces an <execfiles> tag that reads files from the output of
a command, in the same way as executable includes. The files specified
here can also be used anywhere a file is used (opermotd, randquote, etc)

git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12354 e03df62e-2008-0410-955e-edbf42e46eb7

include/configparser.h
include/configreader.h
include/typedefs.h
src/commands/cmd_motd.cpp
src/commands/cmd_rules.cpp
src/configparser.cpp
src/configreader.cpp
src/modules.cpp

index 3240ff5f9360874afffff7d2ae79f18d66693460..1054b1f7f8a0086ae058ccd67e1120108835ace5 100644 (file)
@@ -22,10 +22,11 @@ struct ParseStack
        std::vector<std::string> reading;
        std::map<std::string, std::string> vars;
        ConfigDataHash& output;
+       ConfigFileCache& FilesOutput;
        std::stringstream& errstr;
 
        ParseStack(ServerConfig* conf)
-               : output(conf->config_data), errstr(conf->errstr)
+               : output(conf->config_data), FilesOutput(conf->Files), errstr(conf->errstr)
        {
                vars["amp"] = "&";
                vars["quot"] = "\"";
@@ -34,6 +35,7 @@ struct ParseStack
        bool ParseFile(const std::string& name, int flags);
        bool ParseExec(const std::string& name, int flags);
        void DoInclude(ConfigTag* includeTag, int flags);
+       void DoReadFile(const std::string& key, const std::string& file, int flags, bool exec);
 };
 
 /** RAII wrapper on FILE* to close files on exceptions */
index 3d01d7e9168ec01ec7a41e653cff71cf6b4971c6..1127364399f1f5be4f01e8c29ac876fe3e23ae2b 100644 (file)
@@ -219,6 +219,11 @@ class CoreExport ServerConfig
         */
        ConfigDataHash config_data;
 
+       /** This holds all extra files that have been read in the configuration
+        * (for example, MOTD and RULES files are stored here)
+        */
+       ConfigFileCache Files;
+
        /** Length limits, see definition of ServerLimits class
         */
        ServerLimits Limits;
@@ -435,14 +440,6 @@ class CoreExport ServerConfig
         */
        std::string HideKillsServer;
 
-       /** The MOTD file, cached in a file_cache type.
-        */
-       file_cache MOTD;
-
-       /** The RULES file, cached in a file_cache type.
-        */
-       file_cache RULES;
-
        /** The full pathname and filename of the PID
         * file as defined in the configuration.
         */
@@ -555,10 +552,6 @@ class CoreExport ServerConfig
 
        void Fill();
 
-       /** Read a file into a file_cache object
-        */
-       bool ReadFile(file_cache &F, const std::string& fname);
-
        /* Returns true if the given string starts with a windows drive letter
         */
        bool StartsWithWindowsDriveLetter(const std::string &path);
index bea8e33efa3df7e8702b84f7a49b41205dd2f04f..5ca49493bff0121db9c5515af758055099e9822f 100644 (file)
@@ -97,6 +97,7 @@ typedef std::pair<std::string, std::string> KeyVal;
 /** The entire configuration
  */
 typedef std::multimap<std::string, reference<ConfigTag> > ConfigDataHash;
+
 /** Iterator of ConfigDataHash */
 typedef ConfigDataHash::const_iterator ConfigIter;
 /** Iterator pair, used for tag-name ranges */
@@ -105,6 +106,9 @@ typedef std::pair<ConfigIter,ConfigIter> ConfigTagList;
 /** Index of valid oper blocks and types */
 typedef std::map<std::string, reference<OperInfo> > OperIndex;
 
+/** Files read by the configuration */
+typedef std::map<std::string, file_cache> ConfigFileCache;
+
 /** A hash of commands used by the core
  */
 typedef nspace::hash_map<std::string,Command*> Commandtable;
index 9468eb2f3500282a7c1900470854157d447ee279..b48c1c951a87c0ad5986cb545e74ebd8086e8314 100644 (file)
@@ -45,16 +45,19 @@ CmdResult CommandMotd::Handle (const std::vector<std::string>& parameters, User
 {
        if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
                return CMD_SUCCESS;
-       if (!ServerInstance->Config->MOTD.size())
+
+       ConfigFileCache::iterator motd = ServerInstance->Config->Files.find("motd");
+       if (motd == ServerInstance->Config->Files.end())
        {
                user->SendText(":%s %03d %s :Message of the day file is missing.",
                        ServerInstance->Config->ServerName.c_str(), ERR_NOMOTD, user->nick.c_str());
                return CMD_SUCCESS;
        }
+
        user->SendText(":%s %03d %s :%s message of the day", ServerInstance->Config->ServerName.c_str(),
                RPL_MOTDSTART, user->nick.c_str(), ServerInstance->Config->ServerName.c_str());
 
-       for (file_cache::iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); i++)
+       for (file_cache::iterator i = motd->second.begin(); i != motd->second.end(); i++)
                user->SendText(":%s %03d %s :- %s", ServerInstance->Config->ServerName.c_str(), RPL_MOTD, user->nick.c_str(),i->c_str());
 
        user->SendText(":%s %03d %s :End of message of the day.", ServerInstance->Config->ServerName.c_str(), RPL_ENDOFMOTD, user->nick.c_str());
index 78b3235fb3b69f9dcf4f8cb82a4fee37601d5be9..e1e44d51f7ff17040a6e4c0e415fc293ff5357ef 100644 (file)
@@ -44,7 +44,8 @@ CmdResult CommandRules::Handle (const std::vector<std::string>& parameters, User
        if (parameters.size() > 0 && parameters[0] != ServerInstance->Config->ServerName)
                return CMD_SUCCESS;
 
-       if (!ServerInstance->Config->RULES.size())
+       ConfigFileCache::iterator rules = ServerInstance->Config->Files.find("rules");
+       if (rules == ServerInstance->Config->Files.end())
        {
                user->SendText(":%s %03d %s :RULES file is missing.",
                        ServerInstance->Config->ServerName.c_str(), ERR_NORULES, user->nick.c_str());
@@ -53,7 +54,7 @@ CmdResult CommandRules::Handle (const std::vector<std::string>& parameters, User
        user->SendText(":%s %03d %s :%s server rules:", ServerInstance->Config->ServerName.c_str(),
                RPL_RULESTART, user->nick.c_str(), ServerInstance->Config->ServerName.c_str());
 
-       for (file_cache::iterator i = ServerInstance->Config->RULES.begin(); i != ServerInstance->Config->RULES.end(); i++)
+       for (file_cache::iterator i = rules->second.begin(); i != rules->second.end(); i++)
                user->SendText(":%s %03d %s :- %s", ServerInstance->Config->ServerName.c_str(), RPL_RULES, user->nick.c_str(),i->c_str());
 
        user->SendText(":%s %03d %s :End of RULES command.", ServerInstance->Config->ServerName.c_str(), RPL_RULESEND, user->nick.c_str());
index 0e77cbb3679deaf445bf9e4dd2c1fe29745ed8a0..558c49117dd69ff6343015205c354c8a27e04af2 100644 (file)
@@ -177,6 +177,20 @@ struct Parser
                {
                        stack.DoInclude(tag, flags);
                }
+               else if (name == "files")
+               {
+                       for(std::vector<KeyVal>::iterator i = items->begin(); i != items->end(); i++)
+                       {
+                               stack.DoReadFile(i->first, i->second, flags, false);
+                       }
+               }
+               else if (name == "execfiles")
+               {
+                       for(std::vector<KeyVal>::iterator i = items->begin(); i != items->end(); i++)
+                       {
+                               stack.DoReadFile(i->first, i->second, flags, true);
+                       }
+               }
                else if (name == "define")
                {
                        if (!(flags & FLAG_USE_XML))
@@ -275,6 +289,29 @@ void ParseStack::DoInclude(ConfigTag* tag, int flags)
        }
 }
 
+void ParseStack::DoReadFile(const std::string& key, const std::string& name, int flags, bool exec)
+{
+       if (flags & FLAG_NO_INC)
+               throw CoreException("Invalid <files> tag in file included with noinclude=\"yes\"");
+       if (exec && (flags & FLAG_NO_EXEC))
+               throw CoreException("Invalid <execfiles> tag in file included with noexec=\"yes\"");
+
+       FileWrapper file(exec ? popen(name.c_str(), "r") : fopen(name.c_str(), "r"));
+       if (!file)
+               throw CoreException("Could not read \"" + name + "\" for \"" + key + "\" file");
+
+       file_cache& cache = FilesOutput[key];
+       cache.clear();
+
+       char linebuf[MAXBUF*10];
+       while (fgets(linebuf, sizeof(linebuf), file))
+       {
+               int len = strlen(linebuf);
+               if (len)
+                       cache.push_back(std::string(linebuf, len - 1));
+       }
+}
+
 bool ParseStack::ParseFile(const std::string& name, int flags)
 {
        ServerInstance->Logs->Log("CONFIG", DEBUG, "Reading file %s", name.c_str());
index b34c3eccaf346c5490e111a57a9cc6a537b75313..9db1f2665499d4828026f50305321c7cbbbd4606 100644 (file)
@@ -588,8 +588,6 @@ void ServerConfig::Read()
        }
        if (valid)
        {
-               ReadFile(MOTD, ConfValue("files")->getString("motd"));
-               ReadFile(RULES, ConfValue("files")->getString("rules"));
                DNSServer = ConfValue("dns")->getString("server");
                FindDNS(DNSServer);
        }
@@ -792,34 +790,6 @@ ConfigTagList ServerConfig::ConfTags(const std::string& tag)
        return config_data.equal_range(tag);
 }
 
-/** Read the contents of a file located by `fname' into a file_cache pointed at by `F'.
- */
-bool ServerConfig::ReadFile(file_cache &F, const std::string& fname)
-{
-       if (fname.empty())
-               return false;
-
-       char linebuf[MAXBUF];
-
-       F.clear();
-
-       FileWrapper file(fopen(fname.c_str(), "r"));
-
-       if (!file)
-               return false;
-       while (!feof(file))
-       {
-               if (fgets(linebuf, sizeof(linebuf), file))
-                       linebuf[strlen(linebuf)-1] = 0;
-               else
-                       *linebuf = 0;
-
-               F.push_back(*linebuf ? linebuf : " ");
-       }
-
-       return true;
-}
-
 bool ServerConfig::FileExists(const char* file)
 {
        struct stat sb;
index 558923332982cc0a5b30e44743f2922beb9e2e4c..d4ba9145a6b527491d86cb805d4a47a1cce94c85 100644 (file)
@@ -686,13 +686,26 @@ void FileReader::CalcSize()
 
 void FileReader::LoadFile(const std::string &filename)
 {
-       file_cache c;
-       c.clear();
-       if (ServerInstance->Config->ReadFile(c,filename.c_str()))
+       std::map<std::string, file_cache>::iterator file = ServerInstance->Config->Files.find(filename);
+       if (file != ServerInstance->Config->Files.end())
        {
-               this->fc = c;
-               this->CalcSize();
+               this->fc = file->second;
        }
+       else
+       {
+               FILE* f = fopen(filename.c_str(), "r");
+               if (!f)
+                       return;
+               char linebuf[MAXBUF*10];
+               while (fgets(linebuf, sizeof(linebuf), f))
+               {
+                       int len = strlen(linebuf);
+                       if (len)
+                               fc.push_back(std::string(linebuf, len - 1));
+               }
+               fclose(f);
+       }
+       CalcSize();
 }