typedef std::map<std::string, reference<ConfigTag> > TagIndex;
typedef std::map<std::string, reference<OperInfo> > OperIndex;
+typedef ConfigDataHash::iterator ConfigIter;
+typedef std::pair<ConfigDataHash::iterator, ConfigDataHash::iterator> ConfigTagList;
/** This class holds the bulk of the runtime configuration for the ircd.
* It allows for reading new config values, accessing configuration files,
* @param tag The name of the tag to get
* @param offset get the Nth occurance of the tag
*/
- ConfigTag* ConfValue(const std::string& tag, int offset = 0);
+ ConfigTag* ConfValue(const std::string& tag);
+
+ ConfigTagList ConfTags(const std::string& tag);
/** Error stream, contains error output from any failed configuration parsing.
*/
bool InvBypassModes;
};
+
#endif
/** Holds a complete list of all channels to which a user has been invited and has not yet joined, and the time at which they'll expire.
*/
-CoreExport typedef std::vector< std::pair<irc::string, time_t> > InvitedList;
+typedef std::vector< std::pair<irc::string, time_t> > InvitedList;
/** Holds a complete list of all allow and deny tags from the configuration file (connection classes)
*/
-CoreExport typedef std::vector<reference<ConnectClass> > ClassVector;
+typedef std::vector<reference<ConnectClass> > ClassVector;
/** Typedef for the list of user-channel records for a user
*/
-CoreExport typedef std::set<Channel*> UserChanList;
+typedef std::set<Channel*> UserChanList;
/** Shorthand for an iterator into a UserChanList
*/
-CoreExport typedef UserChanList::iterator UCListIter;
+typedef UserChanList::iterator UCListIter;
/* Required forward declaration
*/
time_t idle_lastmsg;
/** Client address that the user is connected from.
- * Do not modify this value directly, use SetClientIP() to change it
+ * Do not modify this value directly, use SetClientIP() to change it.
* Port is not valid for remote users.
*/
irc::sockets::sockaddrs client_sa;
static void ReadXLine(ServerConfig* conf, const std::string& tag, const std::string& key, XLineFactory* make)
{
- for(int i=0;; ++i)
+ ConfigTagList tags = conf->ConfTags(tag);
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* ctag = conf->ConfValue(tag, i);
- if (!ctag)
- break;
+ ConfigTag* ctag = i->second;
std::string mask;
if (!ctag->readString(key, mask))
throw CoreException("<"+tag+":"+key+"> missing at " + ctag->getTagLocation());
void ServerConfig::CrossCheckOperClassType()
{
LocalIndex operclass;
- for (int i = 0;; ++i)
+ ConfigTagList tags = ConfTags("class");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("class", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string name = tag->getString("name");
if (name.empty())
throw CoreException("<class:name> missing from tag at " + tag->getTagLocation());
operclass[name] = tag;
}
- for (int i = 0;; ++i)
+ tags = ConfTags("type");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("type", i);
- if (!tag)
- break;
-
+ ConfigTag* tag = i->second;
std::string name = tag->getString("name");
if (name.empty())
throw CoreException("<type:name> is missing from tag at " + tag->getTagLocation());
}
}
- for (int i = 0;; ++i)
+ tags = ConfTags("oper");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("oper", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string name = tag->getString("name");
if (name.empty())
}
ClassMap newBlocksByMask;
+ Classes.resize(config_data.count("type"));
std::map<std::string, int> names;
bool try_again = true;
for(int tries=0; try_again; tries++)
{
try_again = false;
- for(unsigned int i=0;; i++)
+ ConfigTagList tags = ConfTags("type");
+ int i=0;
+ for(ConfigIter it = tags.first; it != tags.second; ++it, ++i)
{
- ConfigTag* tag = ConfValue("connect", i);
- if (!tag)
- break;
- if (Classes.size() <= i)
- Classes.resize(i+1);
+ ConfigTag* tag = it->second;
if (Classes[i])
continue;
if (!sid.empty() && !ServerInstance->IsSID(sid))
throw CoreException(sid + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter.");
- for (int i = 0;; ++i)
+ ConfigTagList tags = ConfTags("uline");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("uline", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string server;
if (!tag->readString("server", server))
throw CoreException("<uline> tag missing server at " + tag->getTagLocation());
ulines[assign(server)] = tag->getBool("silent");
}
- for(int i=0;; ++i)
+ tags = ConfTags("banlist");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("banlist", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string chan;
if (!tag->readString("chan", chan))
throw CoreException("<banlist> tag missing chan at " + tag->getTagLocation());
std::string tag = Once[Index];
if (!ConfValue(tag))
throw CoreException("You have not defined a <"+tag+"> tag, this is required.");
- if (ConfValue(tag, 1))
+ ConfigTagList tags = ConfTags(tag);
+ if (tags.first != tags.second)
{
+ tags.first++;
errstr << "You have more than one <" << tag << "> tag.\n"
- << "First occurrence at " << ConfValue(tag, 0)->getTagLocation()
- << "; second occurrence at " << ConfValue(tag, 1)->getTagLocation() << std::endl;
+ << "First occurrence at " << ConfValue(tag)->getTagLocation()
+ << "; second occurrence at " << tags.first->second->getTagLocation() << std::endl;
}
}
std::vector<std::string> added_modules;
std::set<std::string> removed_modules(v.begin(), v.end());
- for(int i=0; ; i++)
+ ConfigTagList tags = ConfTags("module");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ConfValue("module", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string name;
if (tag->readString("name", name))
{
return (path.length() > 2 && isalpha(path[0]) && path[1] == ':');
}
-ConfigTag* ServerConfig::ConfValue(const std::string &tag, int offset)
+ConfigTag* ServerConfig::ConfValue(const std::string &tag)
{
- ConfigDataHash::size_type pos = offset;
- if (pos >= config_data.count(tag))
- return NULL;
-
ConfigDataHash::iterator iter = config_data.find(tag);
-
- for(int i = 0; i < offset; i++)
- iter++;
-
+ if (iter == config_data.end())
+ return NULL;
return iter->second;
}
+ConfigTagList ServerConfig::ConfTags(const std::string& tag)
+{
+ return config_data.equal_range(tag);
+}
+
bool ConfigTag::readString(const std::string& key, std::string& value, bool allow_lf)
{
if (!this)
}
ConfigReader Conf;
std::map<std::string, FileWriter*> logmap;
- std::map<std::string, FileWriter*>::iterator i;
- for (int index = 0;; ++index)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("log");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("log", index);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string method = tag->getString("method");
if (method != "file")
{
loglevel = NONE;
}
FileWriter* fw;
- std::string target = Conf.ReadValue("log", "target", index);
- if ((i = logmap.find(target)) == logmap.end())
+ std::string target = tag->getString("target");
+ std::map<std::string, FileWriter*>::iterator fwi = logmap.find(target);
+ if (fwi == logmap.end())
{
FILE* f = fopen(target.c_str(), "a");
fw = new FileWriter(f);
}
else
{
- fw = i->second;
+ fw = fwi->second;
}
FileLogStream* fls = new FileLogStream(loglevel, fw);
AddLogTypes(type, fls, true);
printf("\n");
}
- for(int count = 0;; count++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("module");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("module", count);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string name = tag->getString("name");
printf_c("[\033[1;32m*\033[0m] Loading module:\t\033[1;32m%s\033[0m\n",name.c_str());
{
}
+static ConfigTag* SlowGetTag(const std::string &tag, int index)
+{
+ ConfigTagList tags = ServerInstance->Config->ConfTags(tag);
+ while (tags.first != tags.second)
+ {
+ if (!index)
+ return tags.first->second;
+ tags.first++;
+ index--;
+ }
+ return NULL;
+}
std::string ConfigReader::ReadValue(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool allow_linefeeds)
{
- /* Don't need to strlcpy() tag and name anymore, ReadConf() takes const char* */
std::string result = default_value;
- if (!ServerInstance->Config->ConfValue(tag, index)->readString(name, result, allow_linefeeds))
+ if (!SlowGetTag(tag, index)->readString(name, result, allow_linefeeds))
{
this->error = CONF_VALUE_NOT_FOUND;
}
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, const std::string &default_value, int index)
{
bool def = (default_value == "yes");
- return ServerInstance->Config->ConfValue(tag, index)->getBool(name, def);
+ return SlowGetTag(tag, index)->getBool(name, def);
}
bool ConfigReader::ReadFlag(const std::string &tag, const std::string &name, int index)
int ConfigReader::ReadInteger(const std::string &tag, const std::string &name, const std::string &default_value, int index, bool need_positive)
{
int v = atoi(default_value.c_str());
- int result = ServerInstance->Config->ConfValue(tag, index)->getInt(name, v);
+ int result = SlowGetTag(tag, index)->getInt(name, v);
if ((need_positive) && (result < 0))
{
ServerInstance->Logs->Log("MODULE", DEBUG, "Module is using ConfigReader::Enumerate on %s; this is slow!",
tag.c_str());
int i=0;
- while (ServerInstance->Config->ConfValue(tag, i)) i++;
+ while (SlowGetTag(tag, i)) i++;
return i;
}
fprefix = fpre.empty() ? '!' : fpre[0];
Aliases.clear();
- for (int i = 0;; i++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("alias");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("alias", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
Alias a;
a.AliasedCommand = tag->getString("text").c_str();
tag->readString("replace", a.ReplaceFormat, true);
helpop_map.clear();
- for (int i = 0;; i++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("helpop", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
irc::string key = assign(tag->getString("key"));
std::string value;
tag->readString("value", value, true); /* Linefeeds allowed */
ApplyModes(user, ThisOpersModes);
}
- if (!opername.empty()) // if user is local ..
+ ThisOpersModes = user->oper->getConfig("modes");
+ if (!ThisOpersModes.empty())
{
- for (int i = 0;; i++)
- {
- ConfigTag* tag = ServerInstance->Config->ConfValue("oper", i);
- if (!tag)
- break;
- if (tag->getString("name") != opername)
- continue;
- ThisOpersModes = tag->getString("modes");
- if (!ThisOpersModes.empty())
- {
- ApplyModes(user, ThisOpersModes);
- }
- break;
- }
+ ApplyModes(user, ThisOpersModes);
}
}
void ReadConfig()
{
allowchans.clear();
- for (int i = 0;; i++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("allowchannel");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("allowchannel", i);
- if (!tag)
- return;
+ ConfigTag* tag = i->second;
std::string txt = tag->getString("name");
allowchans.insert(txt.c_str());
}
if (rebind)
{
- for (int j = 0; ; j++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("bind");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("bind", j);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string Type = tag->getString("type");
std::string IP = tag->getString("address");
std::string Port = tag->getString("port");
AutoconnectBlocks.clear();
LinkBlocks.clear();
ValidIPs.clear();
- for (int j = 0;; ++j)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("link");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("link", j);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
reference<Link> L = new Link(tag);
L->Name = tag->getString("name").c_str();
L->AllowMask = tag->getString("allowmask");
LinkBlocks.push_back(L);
}
- for (int j = 0;; ++j)
+ tags = ServerInstance->Config->ConfTags("autoconnect");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("autoconnect", j);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
reference<Autoconnect> A = new Autoconnect(tag);
A->Period = tag->getInt("period");
A->NextConnectTime = ServerInstance->Time() + A->Period;
CmdResult Handle (const std::vector<std::string> ¶meters, User *user)
{
- for (int index = 0;; index++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("vhost");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("vhost", index);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string mask = tag->getString("host");
std::string username = tag->getString("user");
std::string pass = tag->getString("pass");
int bound = 0;
std::vector<ListenSocketBase*> old_ports(ports.begin(), ports.end());
- for (int count = 0;; count++)
+ ConfigTagList tags = ServerInstance->Config->ConfTags("bind");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = ServerInstance->Config->ConfValue("bind", count);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
std::string porttag = tag->getString("port");
std::string Addr = tag->getString("address");
std::string Type = tag->getString("type");
/* stats o */
case 'o':
- for (int i = 0;; i++)
+ {
+ ConfigTagList tags = ServerInstance->Config->ConfTags("oper");
+ for(ConfigIter i = tags.first; i != tags.second; ++i)
{
- ConfigTag* tag = Config->ConfValue("oper", i);
- if (!tag)
- break;
+ ConfigTag* tag = i->second;
results.push_back(sn+" 243 "+user->nick+" O "+tag->getString("host")+" * "+
tag->getString("name") + " " + tag->getString("type")+" 0");
}
+ }
break;
/* stats l (show user I/O stats) */