summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-02 16:47:25 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-02 16:47:25 +0000
commitf2256deeefe9a9f57f6f6b902604c01138ad16cc (patch)
tree2180cffd6bec0487e3d8b5a7d5894b258782e39c
parentf288993a85681c09e3d92d8c3ab9742826923e99 (diff)
Executable include for MOTD and more
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
-rw-r--r--include/configparser.h4
-rw-r--r--include/configreader.h17
-rw-r--r--include/typedefs.h4
-rw-r--r--src/commands/cmd_motd.cpp7
-rw-r--r--src/commands/cmd_rules.cpp5
-rw-r--r--src/configparser.cpp37
-rw-r--r--src/configreader.cpp30
-rw-r--r--src/modules.cpp23
8 files changed, 75 insertions, 52 deletions
diff --git a/include/configparser.h b/include/configparser.h
index 3240ff5f9..1054b1f7f 100644
--- a/include/configparser.h
+++ b/include/configparser.h
@@ -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 */
diff --git a/include/configreader.h b/include/configreader.h
index 3d01d7e91..112736439 100644
--- a/include/configreader.h
+++ b/include/configreader.h
@@ -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);
diff --git a/include/typedefs.h b/include/typedefs.h
index bea8e33ef..5ca49493b 100644
--- a/include/typedefs.h
+++ b/include/typedefs.h
@@ -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;
diff --git a/src/commands/cmd_motd.cpp b/src/commands/cmd_motd.cpp
index 9468eb2f3..b48c1c951 100644
--- a/src/commands/cmd_motd.cpp
+++ b/src/commands/cmd_motd.cpp
@@ -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());
diff --git a/src/commands/cmd_rules.cpp b/src/commands/cmd_rules.cpp
index 78b3235fb..e1e44d51f 100644
--- a/src/commands/cmd_rules.cpp
+++ b/src/commands/cmd_rules.cpp
@@ -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());
diff --git a/src/configparser.cpp b/src/configparser.cpp
index 0e77cbb36..558c49117 100644
--- a/src/configparser.cpp
+++ b/src/configparser.cpp
@@ -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());
diff --git a/src/configreader.cpp b/src/configreader.cpp
index b34c3ecca..9db1f2665 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -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;
diff --git a/src/modules.cpp b/src/modules.cpp
index 558923332..d4ba9145a 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -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();
}