summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-31 01:25:10 +0000
committerAdam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864>2009-12-31 01:25:10 +0000
commit657e1deb590eaba38ea3e9a9fb353dc0e23c1a41 (patch)
tree49f2c00ae2cd99cd72ae0b7afe9174848bf3041b /src
parentc595e6755de6ecfd1fec58c48ec28c926478da01 (diff)
Added in new plaintext databases. Note: This currently has no automatic backup feature. Big thanks to Phil on this for mass scale testing
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2722 5417fbe8-f217-4b02-8779-1006273d7864
Diffstat (limited to 'src')
-rw-r--r--src/Makefile5
-rw-r--r--src/chanserv.c7
-rw-r--r--src/config.c34
-rw-r--r--src/core/db_plain.cpp1148
-rw-r--r--src/core/ns_forbid.c4
-rw-r--r--src/core/ns_identify.c3
-rw-r--r--src/core/os_ignore.c58
-rw-r--r--src/core/os_modlist.c25
-rw-r--r--src/core/os_news.c42
-rw-r--r--src/datafiles.c203
-rw-r--r--src/init.c12
-rw-r--r--src/main.c4
-rw-r--r--src/modulemanager.cpp6
-rw-r--r--src/modules/hs_request.c150
-rw-r--r--src/modules/os_ignore_db.c490
-rw-r--r--src/modules/os_info.c193
-rw-r--r--src/regchannel.cpp11
-rw-r--r--src/tools/db-convert.c110
-rw-r--r--src/tools/db-convert.h19
-rw-r--r--src/users.c6
20 files changed, 1441 insertions, 1089 deletions
diff --git a/src/Makefile b/src/Makefile
index 8257d8cdf..90705ce29 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o commands.o compat.o \
- config.o datafiles.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
+ config.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
memory.o memoserv.o messages.o misc.o modules.o nickserv.o operserv.o \
process.o protocol.o send.o servers.o sessions.o slist.o sockutil.o opertype.o users.o module.o modulemanager.o configreader.o \
wildcard.o nickcore.o nickalias.o timers.o modes.o regchannel.o
@@ -7,7 +7,7 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o comm
INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \
../include/pseudo.h ../include/sysconf.h ../include/config.h \
../include/messages.h ../include/services.h \
- ../include/timers.h ../include/datafiles.h ../include/extern.h \
+ ../include/timers.h ../include/extern.h \
../include/modules.h ../include/slist.h ../include/hashcomp.h
MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
@@ -47,7 +47,6 @@ command.o: command.cpp $(INCLUDES)
commands.o: commands.c $(INCLUDES)
compat.o: compat.c $(INCLUDES)
config.o: config.c $(INCLUDES)
-datafiles.o: datafiles.c $(INCLUDES)
encrypt.o: encrypt.c $(INCLUDES)
init.o: init.c $(INCLUDES)
ircd.o: ircd.c $(INCLUDES)
diff --git a/src/chanserv.c b/src/chanserv.c
index dc5345ed6..c0f8ac9bb 100644
--- a/src/chanserv.c
+++ b/src/chanserv.c
@@ -719,12 +719,9 @@ int check_kick(User * user, const char *chan, time_t chants)
if (c)
{
- c->RemoveMode(NULL, CMODE_BAN, mask);
- }
-
- c->SetMode(NULL, CMODE_BAN, mask);
- if (c)
+ c->SetMode(NULL, CMODE_BAN, mask);
ircdproto->SendKick(whosends(ci), c, user, "%s", reason);
+ }
return 1;
}
diff --git a/src/config.c b/src/config.c
index aa7577cbf..85eeed357 100644
--- a/src/config.c
+++ b/src/config.c
@@ -22,6 +22,7 @@ ServerConfig Config;
static std::string Modules;
static std::string EncModules;
+static std::string DBModules;
static std::string HostCoreModules;
static std::string MemoCoreModules;
static std::string BotCoreModules;
@@ -180,12 +181,7 @@ bool ValidateEmailReg(ServerConfig *, const char *tag, const char *value, ValueI
{
if (Config.NSEmailReg)
{
- if (std::string(value) == "prenickdatabase")
- {
- if (data.GetValue().empty())
- throw ConfigException(std::string("The value for <") + tag + ":" + value + "> cannot be empty when e-mail registrations are enabled!");
- }
- else if (std::string(value) == "preregexpire")
+ if (std::string(value) == "preregexpire")
{
if (!data.GetInteger())
throw ConfigException(std::string("The value for <") + tag + ":" + value + "> must be non-zero when e-mail registration are enabled!");
@@ -240,7 +236,7 @@ bool ValidateBotServ(ServerConfig *, const char *tag, const char *value, ValueIt
{
if (Config.s_BotServ)
{
- if (std::string(value) == "description" || std::string(value) == "database")
+ if (std::string(value) == "description")
{
if (data.GetValue().empty())
throw ConfigException(std::string("The value for <") + tag + ":" + value + "> cannot be empty when BotServ is enabled!");
@@ -258,7 +254,7 @@ bool ValidateHostServ(ServerConfig *, const char *tag, const char *value, ValueI
{
if (Config.s_HostServ)
{
- if (std::string(value) == "description" || std::string(value) == "database")
+ if (std::string(value) == "description")
{
if (data.GetValue().empty())
throw ConfigException(std::string("The value for <") + tag + ":" + value + "> cannot be empty when HostServ is enabled!");
@@ -613,6 +609,7 @@ int ServerConfig::Read(bool bail)
{"networkinfo", "networkname", "", new ValueContainerChar(&Config.NetworkName), DT_CHARPTR, ValidateNotEmpty},
{"networkinfo", "nicklen", "0", new ValueContainerUInt(&Config.NickLen), DT_UINTEGER | DT_NORELOAD, ValidateNickLen},
{"options", "encryption", "", new ValueContainerString(&EncModules), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
+ {"options", "database", "", new ValueContainerString(&DBModules), DT_STRING | DT_NORELOAD, ValidateNotEmpty},
{"options", "userkey1", "0", new ValueContainerLUInt(&Config.UserKey1), DT_LUINTEGER, NoValidation},
{"options", "userkey2", "0", new ValueContainerLUInt(&Config.UserKey2), DT_LUINTEGER, NoValidation},
{"options", "userkey3", "0", new ValueContainerLUInt(&Config.UserKey3), DT_LUINTEGER, NoValidation},
@@ -645,9 +642,7 @@ int ServerConfig::Read(bool bail)
{"options", "mlock", "+nrt", new ValueContainerString(&Config.MLock), DT_STRING, NoValidation},
{"nickserv", "nick", "NickServ", new ValueContainerChar(&Config.s_NickServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"nickserv", "description", "Nickname Registration Service", new ValueContainerChar(&Config.desc_NickServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
- {"nickserv", "database", "nick.db", new ValueContainerChar(&Config.NickDBName), DT_CHARPTR, ValidateNotEmpty},
{"nickserv", "emailregistration", "no", new ValueContainerBool(&Config.NSEmailReg), DT_BOOLEAN, NoValidation},
- {"nickserv", "prenickdatabase", "", new ValueContainerChar(&Config.PreNickDBName), DT_CHARPTR, ValidateEmailReg},
{"nickserv", "modules", "", new ValueContainerString(&NickCoreModules), DT_STRING, NoValidation},
{"nickserv", "forceemail", "no", new ValueContainerBool(&Config.NSForceEmail), DT_BOOLEAN, ValidateEmailReg},
{"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation},
@@ -677,7 +672,6 @@ int ServerConfig::Read(bool bail)
{"mail", "dontquoteaddresses", "no", new ValueContainerBool(&Config.DontQuoteAddresses), DT_BOOLEAN, NoValidation},
{"chanserv", "nick", "ChanServ", new ValueContainerChar(&Config.s_ChanServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"chanserv", "description", "Channel Registration Service", new ValueContainerChar(&Config.desc_ChanServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
- {"chanserv", "database", "chan.db", new ValueContainerChar(&Config.ChanDBName), DT_CHARPTR, ValidateNotEmpty},
{"chanserv", "modules", "", new ValueContainerString(&ChanCoreModules), DT_STRING, NoValidation},
{"chanserv", "defaults", "keeptopic secure securefounder signkick", new ValueContainerString(&CSDefaults), DT_STRING, NoValidation},
{"chanserv", "maxregistered", "0", new ValueContainerUInt(&Config.CSMaxReg), DT_UINTEGER, NoValidation},
@@ -699,7 +693,6 @@ int ServerConfig::Read(bool bail)
{"memoserv", "memoreceipt", "0", new ValueContainerUInt(&Config.MSMemoReceipt), DT_UINTEGER, NoValidation},
{"botserv", "nick", "", new ValueContainerChar(&Config.s_BotServ), DT_CHARPTR | DT_NORELOAD, NoValidation},
{"botserv", "description", "Bot Service", new ValueContainerChar(&Config.desc_BotServ), DT_CHARPTR | DT_NORELOAD, ValidateBotServ},
- {"botserv", "database", "bot.db", new ValueContainerChar(&Config.BotDBName), DT_CHARPTR, ValidateBotServ},
{"botserv", "modules", "", new ValueContainerString(&BotCoreModules), DT_STRING, NoValidation},
{"botserv", "defaults", "", new ValueContainerString(&BSDefaults), DT_STRING, NoValidation},
{"botserv", "minusers", "0", new ValueContainerUInt(&Config.BSMinUsers), DT_UINTEGER, ValidateBotServ},
@@ -711,15 +704,11 @@ int ServerConfig::Read(bool bail)
{"botserv", "fantasycharacter", "!", new ValueContainerChar(&Config.BSFantasyCharacter), DT_CHARPTR, NoValidation},
{"hostserv", "nick", "", new ValueContainerChar(&Config.s_HostServ), DT_CHARPTR | DT_NORELOAD, NoValidation},
{"hostserv", "description", "vHost Service", new ValueContainerChar(&Config.desc_HostServ), DT_CHARPTR | DT_NORELOAD, ValidateHostServ},
- {"hostserv", "database", "hosts.db", new ValueContainerChar(&Config.HostDBName), DT_CHARPTR, ValidateHostServ},
{"hostserv", "modules", "", new ValueContainerString(&HostCoreModules), DT_STRING, NoValidation},
{"operserv", "nick", "OperServ", new ValueContainerChar(&Config.s_OperServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"operserv", "description", "Operator Service", new ValueContainerChar(&Config.desc_OperServ), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"operserv", "globalnick", "Global", new ValueContainerChar(&Config.s_GlobalNoticer), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
{"operserv", "globaldescription", "Global Noticer", new ValueContainerChar(&Config.desc_GlobalNoticer), DT_CHARPTR | DT_NORELOAD, ValidateNotEmpty},
- {"operserv", "database", "oper.db", new ValueContainerChar(&Config.OperDBName), DT_CHARPTR, ValidateNotEmpty},
- {"operserv", "newsdatabase", "news.db", new ValueContainerChar(&Config.NewsDBName), DT_CHARPTR, ValidateNotEmpty},
- {"operserv", "exceptiondatabase", "exception.db", new ValueContainerChar(&Config.ExceptionDBName), DT_CHARPTR, ValidateNotEmpty},
{"operserv", "modules", "", new ValueContainerString(&OperCoreModules), DT_STRING, NoValidation},
{"operserv", "superadmin", "no", new ValueContainerBool(&Config.SuperAdmin), DT_BOOLEAN, NoValidation},
{"operserv", "logmaxusers", "no", new ValueContainerBool(&Config.LogMaxUsers), DT_BOOLEAN, NoValidation},
@@ -1689,6 +1678,7 @@ int read_config(int reload)
/* Modules Autoload building... :P */
Config.ModulesAutoLoad = BuildStringList(!Modules.empty() ? Modules : "");
Config.EncModuleList = BuildStringList(!EncModules.empty() ? EncModules : "");
+ Config.DBModuleList = BuildStringList(!DBModules.empty() ? DBModules : "");
Config.HostServCoreModules = BuildStringList(!HostCoreModules.empty() ? HostCoreModules : "");
Config.MemoServCoreModules = BuildStringList(!MemoCoreModules.empty() ? MemoCoreModules : "");
Config.BotServCoreModules = BuildStringList(!BotCoreModules.empty() ? BotCoreModules : "");
@@ -1775,18 +1765,6 @@ int read_config(int reload)
}
}
- /**
- * If they try to enable any email registration option,
- * make sure they have everything else they need too...
- *
- * rob
- **/
- if (!Config.NSEmailReg) {
- delete [] Config.PreNickDBName;
- Config.PreNickDBName = NULL;
- Config.NSRExpire = 0;
- }
-
SetDefaultMLock();
if (!retval) {
diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp
new file mode 100644
index 000000000..b551d0b5c
--- /dev/null
+++ b/src/core/db_plain.cpp
@@ -0,0 +1,1148 @@
+/*
+ *
+ * (C) 2003-2009 Anope Team
+ * Contact us at team@anope.org
+ *
+ * Please read COPYING and README for further details.
+ *
+ * Based on the original code of Epona by Lara.
+ * Based on the original code of Services by Andy Church.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+std::fstream db;
+
+/** Enum used for what METADATA type we are reading
+ */
+enum MDType
+{
+ MD_NONE,
+ MD_NC,
+ MD_NA,
+ MD_BI,
+ MD_CH
+};
+
+/* Character for newlines, in my research I have concluded it is significantly faster
+ * to use \n instead of std::endl because std::endl also flushes the buffer, which
+ * is not necessary here
+ */
+static const char endl = '\n';
+
+/** Read from the database and call the events
+ * @param m If specified it only calls the read events for the specific module
+ */
+static void ReadDatabase(Module *m = NULL)
+{
+ std::string buf;
+ EventReturn MOD_RESULT;
+ MDType Type = MD_NONE;
+
+ db.open(DATABASE_FILE, std::ios_base::in);
+
+ if (!db.is_open())
+ {
+ ircdproto->SendGlobops(NULL, "Unable to open %s for reading!", DATABASE_FILE);
+ return;
+ }
+
+ while (std::getline(db, buf))
+ {
+ if (buf.empty())
+ continue;
+
+ spacesepstream sep(buf);
+ std::vector<std::string> params;
+ while (sep.GetToken(buf))
+ {
+ if (buf[0] == ':')
+ {
+ buf.erase(buf.begin());
+ if (!buf.empty())
+ params.push_back(buf + " " + sep.GetRemaining());
+ }
+ else
+ params.push_back(buf);
+ }
+
+ if (m)
+ MOD_RESULT = m->OnDatabaseRead(params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseRead, OnDatabaseRead(params));
+ }
+ if (MOD_RESULT == EVENT_STOP)
+ continue;
+
+ std::string mdbuf;
+ NickCore *nc;
+ NickAlias *na;
+ BotInfo *bi;
+ ChannelInfo *ci;
+ if (!params.empty())
+ {
+ if (params[0] == "NC")
+ {
+ nc = findcore(params[1].c_str());
+ Type = MD_NC;
+ }
+ else if (params[0] == "NA")
+ {
+ na = findnick(params[2].c_str());
+ Type = MD_NA;
+ }
+ else if (params[0] == "BI")
+ {
+ bi = findbot(params[1].c_str());
+ Type = MD_BI;
+ }
+ else if (params[0] == "CH")
+ {
+ ci = cs_findchan(params[1].c_str());
+ Type = MD_CH;
+ }
+ else if (params[0] == "MD")
+ {
+ std::string key = params[1];
+ params.erase(params.begin());
+ params.erase(params.begin());
+
+ if (nc && Type == MD_NC)
+ {
+ try
+ {
+ if (m)
+ MOD_RESULT = m->OnDatabaseReadMetadata(nc, key, params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(nc, key, params));
+ }
+ }
+ catch (const char *err)
+ {
+ alog("[db_plain}: %s", err);
+ }
+ }
+ else if (na && Type == MD_NA)
+ {
+ try
+ {
+ if (m)
+ MOD_RESULT = m->OnDatabaseReadMetadata(na, key, params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(na, key, params));
+ }
+ }
+ catch (const char *err)
+ {
+ alog("[db_plain}: %s", err);
+ }
+ }
+ else if (bi && Type == MD_BI)
+ {
+ try
+ {
+ if (m)
+ MOD_RESULT = m->OnDatabaseReadMetadata(bi, key, params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(bi, key, params));
+ }
+ }
+ catch (const char *err)
+ {
+ alog("[db_plain}: %s", err);
+ }
+ }
+ else if (ci && Type == MD_CH)
+ {
+ try
+ {
+ if (m)
+ MOD_RESULT = m->OnDatabaseReadMetadata(ci, key, params);
+ else
+ {
+ FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(ci, key, params));
+ }
+ }
+ catch (const char *err)
+ {
+ alog("[db_plain}: %s", err);
+ }
+ }
+ }
+ }
+ }
+
+ db.close();
+}
+
+struct LangInfo
+{
+ std::string Name;
+ int LanguageId;
+};
+
+struct ChannelModeInfo
+{
+ std::string Name;
+ ChannelModeName Value;
+};
+
+struct ChannelFlagInfo
+{
+ std::string Name;
+ ChannelInfoFlag Flag;
+};
+
+struct ChannelLevel
+{
+ std::string Name;
+ int Level;
+};
+
+struct BotFlagInfo
+{
+ std::string Name;
+ BotServFlag Flag;
+};
+
+struct NickCoreFlagInfo
+{
+ std::string Name;
+ NickCoreFlag Flag;
+};
+
+LangInfo LangInfos[] = {
+ {"en", LANG_EN_US},
+ {"es", LANG_ES},
+ {"pt", LANG_PT},
+ {"fr", LANG_FR},
+ {"tr", LANG_TR},
+ {"it", LANG_IT},
+ {"de", LANG_DE},
+ {"ca", LANG_CAT},
+ {"gr", LANG_GR},
+ {"nl", LANG_NL},
+ {"ru", LANG_RU},
+ {"hu", LANG_HUN},
+ {"pl", LANG_PL},
+ {"", -1}
+};
+
+ChannelModeInfo ChannelModes[] = {
+ {"BLOCKCOLOR", CMODE_BLOCKCOLOR},
+ {"FLOOD", CMODE_FLOOD},
+ {"INVITE", CMODE_INVITE},
+ {"KEY", CMODE_KEY},
+ {"LIMIT", CMODE_LIMIT},
+ {"MODERATED", CMODE_MODERATED},
+ {"NOEXTERNAL", CMODE_NOEXTERNAL},
+ {"PRIVATE", CMODE_PRIVATE},
+ {"REGISTERED", CMODE_REGISTERED},
+ {"SECRET", CMODE_SECRET},
+ {"TOPIC", CMODE_TOPIC},
+ {"AUDITORIUM", CMODE_AUDITORIUM},
+ {"SSL", CMODE_SSL},
+ {"ADMINONLY", CMODE_ADMINONLY},
+ {"NOCTCP", CMODE_NOCTCP},
+ {"FILTER", CMODE_FILTER},
+ {"NOKNOCK", CMODE_NOKNOCK},
+ {"REDIRECT", CMODE_REDIRECT},
+ {"REGMODERATED", CMODE_REGMODERATED},
+ {"NONICK", CMODE_NONICK},
+ {"OPERONLY", CMODE_OPERONLY},
+ {"NONICK", CMODE_NONICK},
+ {"REGISTEREDONLY", CMODE_REGISTEREDONLY},
+ {"STRIPCOLOR", CMODE_STRIPCOLOR},
+ {"NONOTICE", CMODE_NONOTICE},
+ {"NOINVITE", CMODE_NOINVITE},
+ {"ALLINVITE", CMODE_ALLINVITE},
+ {"BLOCKCAPS", CMODE_BLOCKCAPS},
+ {"PERM", CMODE_PERM},
+ {"NICKFLOOD", CMODE_NICKFLOOD},
+ {"JOINFLOOD", CMODE_JOINFLOOD},
+ {"", static_cast<ChannelModeName>(-1)}
+};
+
+ChannelFlagInfo ChannelInfoFlags[] = {
+ {"KEEPTOPIC", CI_KEEPTOPIC},
+ {"SECUREOPS", CI_SECUREOPS},
+ {"PRIVATE", CI_PRIVATE},
+ {"TOPICLOCK", CI_TOPICLOCK},
+ {"RESTRICTED", CI_RESTRICTED},
+ {"PEACE", CI_PEACE},
+ {"SECURE", CI_SECURE},
+ {"FORBIDDEN", CI_FORBIDDEN},
+ {"NO_EXPIRE", CI_NO_EXPIRE},
+ {"MEMO_HARDMAX", CI_MEMO_HARDMAX},
+ {"OPNOTICE", CI_OPNOTICE},
+ {"SECUREFOUNDER", CI_SECUREFOUNDER},
+ {"SIGNKICK", CI_SIGNKICK},
+ {"SIGNKICK_LEVEL", CI_SIGNKICK_LEVEL},
+ {"XOP", CI_XOP},
+ {"SUSPENDED", CI_SUSPENDED},
+ {"PERSIST", CI_PERSIST},
+ {"", static_cast<ChannelInfoFlag>(-1)}
+};
+
+ChannelLevel ChannelLevels[] = {
+ {"INVITE", CA_INVITE},
+ {"AKICK", CA_AKICK},
+ {"SET", CA_SET},
+ {"UNBAN", CA_UNBAN},
+ {"AUTOOP", CA_AUTOOP},
+ {"AUTODEOP", CA_AUTODEOP},
+ {"AUTOVOICE", CA_AUTOVOICE},
+ {"OPDEOP", CA_OPDEOP},
+ {"ACCESS_LIST", CA_ACCESS_LIST},
+ {"CLEAR", CA_CLEAR},
+ {"NOJOIN", CA_NOJOIN},
+ {"ACCESS_CHANGE", CA_ACCESS_CHANGE},
+ {"MEMO", CA_MEMO},
+ {"ASSIGN", CA_ASSIGN},
+ {"BADWORDS", CA_BADWORDS},
+ {"NOKICK", CA_NOKICK},
+ {"FANTASIA", CA_FANTASIA},
+ {"SAY", CA_SAY},
+ {"GREET", CA_GREET},
+ {"VOICEME", CA_VOICEME},
+ {"VOICE", CA_VOICE},
+ {"GETKEY", CA_GETKEY},
+ {"AUTOHALFOP", CA_AUTOHALFOP},
+ {"AUTOPROTECT", CA_AUTOPROTECT},
+ {"OPDEOPME", CA_OPDEOPME},
+ {"HALFOPME", CA_HALFOPME},
+ {"HALFOP", CA_HALFOP},
+ {"PROTECTME", CA_PROTECTME},
+ {"PROTECT", CA_PROTECT},
+ {"KICKME", CA_KICKME},
+ {"KICK", CA_KICK},
+ {"SIGNKICK", CA_SIGNKICK},
+ {"BANME", CA_BANME},
+ {"BAN", CA_BAN},
+ {"TOPIC", CA_TOPIC},
+ {"INFO", CA_INFO},
+ {"AUTOOWNER", CA_AUTOOWNER},
+ {"OWNER", CA_OWNER},
+ {"OWNERME", CA_OWNERME},
+ {"", -1}
+};
+
+BotFlagInfo BotFlags[] = {
+ {"DONTKICKOPS", BS_DONTKICKOPS},
+ {"DONTKICKVOICES", BS_DONTKICKVOICES},
+ {"FANTASY", BS_FANTASY},
+ {"SYMBIOSIS", BS_SYMBIOSIS},
+ {"GREET", BS_GREET},
+ {"NOBOT", BS_NOBOT},
+ {"KICK_BOLDS", BS_KICK_BOLDS},
+ {"KICK_COLORS", BS_KICK_COLORS},
+ {"KICK_REVERSES", BS_KICK_REVERSES},
+ {"KICK_UNDERLINES", BS_KICK_UNDERLINES},
+ {"KICK_BADWORDS", BS_KICK_BADWORDS},
+ {"KICK_CAPS", BS_KICK_CAPS},
+ {"KICK_FLOOD", BS_KICK_FLOOD},
+ {"KICK_REPEAT", BS_KICK_REPEAT},
+ {"", static_cast<BotServFlag>(-1)}
+};
+
+NickCoreFlagInfo NickCoreFlags[] = {
+ {"KILLPROTECT", NI_KILLPROTECT},
+ {"SECURE", NI_SECURE},
+ {"MSG", NI_MSG},
+ {"MEMO_HARDMAX", NI_MEMO_HARDMAX},
+ {"MEMO_SIGNON", NI_MEMO_SIGNON},
+ {"MEMO_RECEIVE", NI_MEMO_RECEIVE},
+ {"PRIVATE", NI_PRIVATE},
+ {"HIDE_EMAIL", NI_HIDE_EMAIL},
+ {"HIDE_MASK", NI_HIDE_MASK},
+ {"HIDE_QUIT", NI_HIDE_QUIT},
+ {"KILL_QUICK", NI_KILL_QUICK},
+ {"KILL_IMMED", NI_KILL_IMMED},
+ {"MEMO_MAIL", NI_MEMO_MAIL},
+ {"HIDE_STATUS", NI_HIDE_STATUS},
+ {"SUSPENDED", NI_SUSPENDED},
+ {"AUTOOP", NI_AUTOOP},
+ {"FORBIDDEN", NI_FORBIDDEN},
+ {"", static_cast<NickCoreFlag>(-1)}
+};
+
+static void LoadNickCore(const std::vector<std::string> &params)
+{
+ NickCore *nc = new NickCore(params[0]);
+ /* Clear default flags */
+ nc->ClearFlags();
+
+ if (params.size() <= 2)
+ {
+ /* This is a forbidden nick */
+ return;
+ }
+
+ size_t tmp = params[1].find(':'); // XXX till we store the hash method internally with the nickcore
+ const char *pass = params[1].c_str() + tmp + 1;
+ char passbuf[PASSMAX];
+ memset(&passbuf, 0, sizeof(passbuf));
+ b64_decode(pass, passbuf, PASSMAX);
+ strscpy(nc->pass, passbuf, PASSMAX);
+
+ for (int i = 0; LangInfos[i].LanguageId != -1; ++i)
+ if (params[2] == LangInfos[i].Name)
+ nc->language = LangInfos[i].LanguageId;
+
+ nc->memos.memomax = atoi(params[3].c_str());
+ nc->channelcount = atoi(params[4].c_str());
+
+ if (debug > 1)
+ alog("[db_plain]: Loaded NickCore %s", nc->display);
+}
+
+static void LoadNickAlias(const std::vector<std::string> &params)
+{
+ NickCore *nc = findcore(params[0].c_str());
+ if (!nc)
+ {
+ alog("[db_plain]: Unable to find core %s", params[0].c_str());
+ return;
+ }
+
+ NickAlias *na = new NickAlias(params[1], nc);
+
+ na->time_registered = strtol(params[2].c_str(), NULL, 10);
+
+ na->last_seen = strtol(params[3].c_str(), NULL, 10);
+
+ if (debug > 1)
+ alog("[db_plain}: Loaded nickalias for %s", na->nick);
+}
+
+static void LoadBotInfo(const std::vector<std::string> &params)
+{
+ BotInfo *bi = new BotInfo(params[0].c_str());
+ bi->user = sstrdup(params[1].c_str());
+ bi->host = sstrdup(params[2].c_str());
+ bi->created = strtol(params[4].c_str(), NULL, 10);
+ bi->chancount = atol(params[5].c_str());
+ bi->real = sstrdup(params[6].c_str());
+
+ if (debug > 1)
+ alog("[db_plain]: Loaded botinfo for %s", bi->nick);
+}
+
+static void LoadChanInfo(const std::vector<std::string> &params)
+{
+ ChannelInfo *ci = new ChannelInfo(params[0]);
+ /* CLear default mlock */
+ ci->ClearMLock();
+ /* Remove default channel flags */
+ ci->ClearFlags();
+ ci->botflags.ClearFlags();
+
+ ci->time_registered = strtol(params[1].c_str(), NULL, 10);
+
+ ci->last_used = strtol(params[2].c_str(), NULL, 10);
+
+ ci->bantype = atoi(params[3].c_str());
+
+ ci->memos.memomax = atoi(params[4].c_str());
+
+ if (debug > 1)
+ alog("[db_plain]: loaded channel %s", ci->name);
+}
+
+static void LoadHostInfo(const std::vector<std::string> &params)
+{
+ if (!findnick(params[0].c_str()))
+ return;
+ addHostCore(params[0].c_str(), params[4].empty() ? NULL : const_cast<char *>(params[4].c_str()), const_cast<char *>(params[3].c_str()), params[1].c_str(), strtol(params[2].c_str(), NULL, 10)); // XXX
+ if (debug > 1)
+ alog("[db_plain]: loaded vhost for %s", params[0].c_str());
+}
+
+static void LoadOperInfo(const std::vector<std::string> &params)
+{
+ if (params[0] == "STATS")
+ {
+ maxusercnt = atol(params[1].c_str());
+ maxusertime = strtol(params[2].c_str(), NULL, 10);
+ }
+ else if (params[0] == "AKILL" || params[0] == "SGLINE" || params[0] == "SQLINE" || params[0] == "SZLINE")
+ {
+ int (*add_sxline)(User *, const char *, const char *, time_t, const char *);
+ if (params[0] == "AKILL")
+ add_sxline = add_akill;
+ else if (params[0] == "SGLINE")
+ add_sxline = add_sgline;
+ else if (params[0] == "SQLINE")
+ add_sxline = add_sqline;
+ else if (params[0] == "SZLINE")
+ add_sxline = add_szline;
+
+ add_sxline(NULL, (params[1] + "@" + params[2]).c_str(), params[3].c_str(), strtol(params[5].c_str(), NULL, 10), params[6].c_str());
+ }
+ else if (params[0] == "EXCEPTION")
+ {
+ nexceptions++;
+ exceptions = static_cast<Exception *>(srealloc(exceptions, sizeof(Exception) * nexceptions));
+ exceptions[nexceptions - 1].mask = sstrdup(params[1].c_str());
+ exceptions[nexceptions - 1].limit = atol(params[2].c_str());
+ strscpy(exceptions[nexceptions - 1].who, params[3].c_str(), NICKMAX);
+ exceptions[nexceptions - 1].time = strtol(params[4].c_str(), NULL, 10);
+ exceptions[nexceptions - 1].expires = strtol(params[5].c_str(), NULL, 10);
+ exceptions[nexceptions - 1].reason = sstrdup(params[6].c_str());
+ exceptions[nexceptions - 1].num = nexceptions - 1;
+ }
+}
+
+void Write(const std::string &buf)
+{
+ db << buf << endl;
+}
+
+void WriteMetadata(const std::string &key, const std::string &data)
+{
+ Write("MD " + key + " " + data);
+}
+
+class DBPlain : public Module
+{
+ public:
+ DBPlain(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(DATABASE);
+
+ Implementation i[] = { I_OnDatabaseRead, I_OnLoadDatabase, I_OnDatabaseReadMetadata, I_OnSaveDatabase, I_OnModuleLoad };
+ ModuleManager::Attach(i, this, 5);
+ }
+
+ EventReturn OnDatabaseRead(const std::vector<std::string> &params)
+ {
+ std::string key = params[0];
+ std::vector<std::string> otherparams = params;
+ otherparams.erase(otherparams.begin());
+
+ if (key == "NC")
+ LoadNickCore(otherparams);
+ else if (key == "NA")
+ LoadNickAlias(otherparams);
+ else if (key == "BI")
+ LoadBotInfo(otherparams);
+ else if (key == "CH")
+ LoadChanInfo(otherparams);
+ else if (key == "HI")
+ LoadHostInfo(otherparams);
+ else if (key == "OS")
+ LoadOperInfo(otherparams);
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnLoadDatabase()
+ {
+ ReadDatabase();
+
+ /* No need to ever reload this again, although this should never be trigged again */
+ ModuleManager::Detach(I_OnLoadDatabase, this);
+ ModuleManager::Detach(I_OnDatabaseReadMetadata, this);
+
+ return EVENT_STOP;
+ }
+
+ EventReturn OnDatabaseReadMetadata(NickCore *nc, const std::string &key, const std::vector<std::string> &params)
+ {
+ if (key == "EMAIL")
+ nc->email = sstrdup(params[0].c_str());
+ else if (key == "GREET")
+ nc->greet = sstrdup(params[0].c_str());
+ else if (key == "ICQ")
+ nc->icq = atoi(params[0].c_str());
+ else if (key == "URL")
+ nc->url = sstrdup(params[0].c_str());
+ else if (key == "ACCESS")
+ nc->AddAccess(params[0]);
+ else if (key == "FLAGS")
+ {
+ for (unsigned j = 0; j < params.size(); ++j)
+ for (int i = 0; NickCoreFlags[i].Flag != -1; ++i)
+ if (NickCoreFlags[i].Name == params[j])
+ nc->SetFlag(NickCoreFlags[i].Flag);
+ }
+ else if (key == "MI")
+ {
+ Memo *m = new Memo;
+ m->number = atoi(params[0].c_str());
+ m->time = strtol(params[1].c_str(), NULL, 10);
+ strscpy(m->sender, params[2].c_str(), NICKMAX);
+ unsigned j;
+ for (j = 3; (params[j] == "UNREAD" || params[j] == "RECEIPT" || params[j] == "NOTIFYS"); ++j)
+ {
+ if (params[j] == "UNREAD")
+ m->SetFlag(MF_UNREAD);
+ else if (params[j] == "RECEIPT")
+ m->SetFlag(MF_RECEIPT);
+ else if (params[j] == "NOTIFYS")
+ m->SetFlag(MF_NOTIFYS);
+ }
+ m->text = sstrdup(params[j + 1].c_str());
+ nc->memos.memos.push_back(m);
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnDatabaseReadMetadata(NickAlias *na, const std::string &key, const std::vector<std::string> &params)
+ {
+ if (key == "LAST_USERMASK")
+ na->last_usermask = sstrdup(params[0].c_str());
+ else if (key == "LAST_REALNAME")
+ na->last_realname = sstrdup(params[0].c_str());
+ else if (key == "LAST_QUIT")
+ na->last_quit = sstrdup(params[0].c_str());
+ else if (key == "FLAGS")
+ {
+ for (unsigned j = 0; j < params.size(); ++j)
+ {
+ if (params[j] == "FORBIDDEN")
+ na->SetFlag(NS_FORBIDDEN);
+ else if (params[j] == "NOEXPIRE")
+ na->SetFlag(NS_NO_EXPIRE);
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnDatabaseReadMetadata(BotInfo *bi, const std::string &key, const std::vector<std::string> &params)
+ {
+ std::string buf;
+
+ if (key == "FLAGS")
+ {
+ for (unsigned j = 0; j < params.size(); ++j)
+ {
+ if (params[j] == "PRIVATE")
+ bi->SetFlag(BI_PRIVATE);
+ else if (params[j] == "CHANSERV")
+ bi->SetFlag(BI_CHANSERV);
+ else if (params[j] == "BOTSERV")
+ bi->SetFlag(BI_BOTSERV);
+ else if (params[j] == "HOSTSERV")
+ bi->SetFlag(BI_HOSTSERV);
+ else if (params[j] == "OPERSERV")
+ bi->SetFlag(BI_OPERSERV);
+ else if (params[j] == "MEMOSERV")
+ bi->SetFlag(BI_MEMOSERV);
+ else if (params[j] == "NICKSERV")
+ bi->SetFlag(BI_NICKSERV);
+ else if (params[j] == "GLOBAL")
+ bi->SetFlag(BI_GLOBAL);
+ }
+ }
+
+ return EVENT_CONTINUE;
+ }
+
+ EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const std::string &key, const std::vector<std::string> &params)
+ {
+ std::string buf;
+ int i;
+
+ if (key == "FOUNDER")
+ {
+ ci->founder = findcore(params[0].c_str());
+ if (!ci->founder)
+ {
+ alog("[db_plain]: Deleting founderless channel %s", ci->name);
+ delete ci;
+ ci = NULL;
+ throw "no founder";
+ }
+ }
+ else if (key == "SUCCESSOR")
+ ci->successor = findcore(params[0].c_str());
+ else if (key == "LEVELS")
+ {
+ for (unsigned j = 0; j < params.size(); ++j, ++j)
+ for (i = 0; ChannelLevels[i].Level != -1; ++i)
+ if (ChannelLevels[i].Name == params[j])
+ ci->levels[ChannelLevels[i].Level] = atoi(params[j + 1].c_str());
+ }
+ else if (key == "FLAGS")
+ {
+ for (unsigned j = 0; j < params.size(); ++j)
+ for (i = 0; ChannelInfoFlags[i].Flag != -1; ++i)
+ if (ChannelInfoFlags[i].Name == params[j])
+ ci->SetFlag(ChannelInfoFlags[i].Flag);
+ }
+ else if (key == "DESC")
+ ci->desc = sstrdup(params[0].c_str());
+ else if (key == "URL")
+ ci->url = sstrdup(params[0].c_str());
+ else if (key == "EMAIL")
+ ci->email = sstrdup(params[0].c_str());
+ else if (key == "TOPIC")
+ {
+ strscpy(ci->last_topic_setter, params[0].c_str(), NICKMAX);
+ ci->last_topic_time = strtol(params[1].c_str(), NULL, 10);
+ ci->last_topic = sstrdup(params[2].c_str());
+ }
+ else if (key == "FORBID")
+ {
+ ci->forbidby = sstrdup(params[0].c_str());
+ ci->forbidreason = sstrdup(params[1].c_str());
+ }
+ else if (key == "ACCESS")
+ {
+ NickCore *nc = findcore(params[0].c_str());
+ if (!nc)
+ throw "access entry for nonexistant core";
+ int level = atoi(params[1].c_str());
+ time_t last_seen = strtol(params[2].c_str(), NULL, 10);
+ ci->AddAccess(nc, level, buf, last_seen);
+ }
+ else if (key == "AKICK")
+ {
+ bool Stuck = params[0] == "STUCK" ? true : false;
+ bool Nick = params[1] == "NICK" ? true : false;
+ NickCore *nc = NULL;
+ if (Nick)
+ {
+ nc = findcore(params[2].c_str());
+ if (!nc)
+ {
+ throw "akick for nonexistant core";
+ }
+ }
+ AutoKick *ak;
+ if (Nick)
+ ak = ci->AddAkick(params[3], nc, params.size() > 5 ? params[5] : "", strtol(params[4].c_str(), NULL, 10));
+ else
+ ak = ci->AddAkick(params[3], params[2], params.size() > 5 ? params[5] : "", strtol(params[4].c_str(