/* $CopyInstall: conf/modules.conf.example $(CONPATH) */
/* $CopyInstall: conf/opers.conf.example $(CONPATH) */
/* $CopyInstall: conf/links.conf.example $(CONPATH) */
-/* $CopyInstall: .gdbargs $(BASE) */
+/* $CopyInstall: tools/gdbargs $(BASE)/.gdbargs */
#include "inspircd.h"
#include <fstream>
struct ParseStack
{
std::vector<std::string> reading;
+ std::map<std::string, std::string> vars;
ConfigDataHash& output;
std::stringstream& errstr;
ParseStack(ServerConfig* conf)
: output(conf->config_data), errstr(conf->errstr)
- { }
+ {
+ vars["amp"] = "&";
+ vars["quot"] = "\"";
+ vars["newline"] = vars["nl"] = "\n";
+ }
bool ParseFile(const std::string& name, int flags);
bool ParseExec(const std::string& name, int flags);
void DoInclude(ConfigTag* includeTag, int flags);
while (1)
{
ch = next();
- if (ch == '\\')
+ if (ch == '&')
{
- ch = next();
- if (ch == 'n')
- ch = '\n';
- else if (ch == 'r')
- ch = '\r';
+ std::string varname;
+ while (1)
+ {
+ ch = next();
+ if (isalnum(ch))
+ varname.push_back(ch);
+ else if (ch == ';')
+ break;
+ else
+ {
+ stack.errstr << "Invalid XML entity name in value of <" + tag->tag + ":" + key + ">\n"
+ << "To include an ampersand or quote, use & or "\n";
+ throw CoreException("Parse error");
+ }
+ }
+ std::map<std::string, std::string>::iterator var = stack.vars.find(varname);
+ if (var == stack.vars.end())
+ throw CoreException("Undefined XML entity reference '&" + varname + ";'");
+ value.append(var->second);
}
else if (ch == '"')
break;
nextword(name);
int spc = next();
- if (!isspace(spc))
+ if (spc == '>')
+ unget(spc);
+ else if (!isspace(spc))
throw CoreException("Invalid character in tag name");
if (name.empty())
while (kv());
- if (tag->tag == "include")
+ if (name == "include")
{
stack.DoInclude(tag, flags);
}
+ else if (name == "define")
+ {
+ std::string varname = tag->getString("name");
+ std::string value = tag->getString("value");
+ if (varname.empty())
+ throw CoreException("Variable definition must include variable name");
+ stack.vars[varname] = value;
+ }
else
{
- stack.output.insert(std::make_pair(tag->tag, tag));
+ stack.output.insert(std::make_pair(name, tag));
}
// this is not a leak; reference<> takes care of the delete
tag = NULL;
}
}
+/** RAII wrapper on FILE* to close files on exceptions */
+struct FileWrapper
+{
+ FILE* const f;
+ FileWrapper(FILE* file) : f(file) {}
+ operator bool() { return f; }
+ operator FILE*() { return f; }
+ ~FileWrapper()
+ {
+ if (f)
+ fclose(f);
+ }
+};
+
bool ParseStack::ParseFile(const std::string& name, int flags)
{
ServerInstance->Logs->Log("CONFIG", DEBUG, "Reading file %s", name.c_str());
/* It's not already included, add it to the list of files we've loaded */
- FILE* file = fopen(name.c_str(), "r");
+ FileWrapper file(fopen(name.c_str(), "r"));
if (!file)
throw CoreException("Could not read \"" + name + "\" for include");
/* It's not already included, add it to the list of files we've loaded */
- FILE* file = popen(name.c_str(), "r");
+ FileWrapper file(popen(name.c_str(), "r"));
if (!file)
throw CoreException("Could not open executable \"" + name + "\" for include");
me->softsendqmax = tag->getInt("softsendq", me->softsendqmax);
me->hardsendqmax = tag->getInt("hardsendq", me->hardsendqmax);
me->recvqmax = tag->getInt("recvq", me->recvqmax);
+ me->penaltythreshold = tag->getInt("threshold", me->penaltythreshold);
me->maxlocal = tag->getInt("localmax", me->maxlocal);
me->maxglobal = tag->getInt("globalmax", me->maxglobal);
me->port = tag->getInt("port", me->port);
AdminName = ConfValue("admin")->getString("name", "");
AdminEmail = ConfValue("admin")->getString("email", "null@example.com");
AdminNick = ConfValue("admin")->getString("nick", "admin");
- ModPath = options->getString("moduledir", MOD_PATH);
+ ModPath = ConfValue("path")->getString("moduledir", MOD_PATH);
NetBufferSize = ConfValue("performance")->getInt("netbuffersize", 10240);
MaxWhoResults = ConfValue("performance")->getInt("maxwho", 1024);
dns_timeout = ConfValue("dns")->getInt("timeout", 5);
if (fname.empty())
return false;
- FILE* file = NULL;
char linebuf[MAXBUF];
F.clear();
- if (!FileExists(fname.c_str()))
- return false;
- file = fopen(fname.c_str(), "r");
+ FileWrapper file(fopen(fname.c_str(), "r"));
- if (file)
+ if (!file)
+ return false;
+ while (!feof(file))
{
- while (!feof(file))
- {
- if (fgets(linebuf, sizeof(linebuf), file))
- linebuf[strlen(linebuf)-1] = 0;
- else
- *linebuf = 0;
-
- F.push_back(*linebuf ? linebuf : " ");
- }
+ if (fgets(linebuf, sizeof(linebuf), file))
+ linebuf[strlen(linebuf)-1] = 0;
+ else
+ *linebuf = 0;
- fclose(file);
+ F.push_back(*linebuf ? linebuf : " ");
}
- else
- return false;
return true;
}