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"] = "\"";
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 */
*/
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;
*/
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.
*/
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);
/** 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 */
/** 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;
{
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());
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());
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());
{
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))
}
}
+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());
}
if (valid)
{
- ReadFile(MOTD, ConfValue("files")->getString("motd"));
- ReadFile(RULES, ConfValue("files")->getString("rules"));
DNSServer = ConfValue("dns")->getString("server");
FindDNS(DNSServer);
}
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;
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();
}