diff options
| author | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2009-12-31 01:25:10 +0000 |
|---|---|---|
| committer | Adam- <Adam-@5417fbe8-f217-4b02-8779-1006273d7864> | 2009-12-31 01:25:10 +0000 |
| commit | 657e1deb590eaba38ea3e9a9fb353dc0e23c1a41 (patch) | |
| tree | 49f2c00ae2cd99cd72ae0b7afe9174848bf3041b /src | |
| parent | c595e6755de6ecfd1fec58c48ec28c926478da01 (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/Makefile | 5 | ||||
| -rw-r--r-- | src/chanserv.c | 7 | ||||
| -rw-r--r-- | src/config.c | 34 | ||||
| -rw-r--r-- | src/core/db_plain.cpp | 1148 | ||||
| -rw-r--r-- | src/core/ns_forbid.c | 4 | ||||
| -rw-r--r-- | src/core/ns_identify.c | 3 | ||||
| -rw-r--r-- | src/core/os_ignore.c | 58 | ||||
| -rw-r--r-- | src/core/os_modlist.c | 25 | ||||
| -rw-r--r-- | src/core/os_news.c | 42 | ||||
| -rw-r--r-- | src/datafiles.c | 203 | ||||
| -rw-r--r-- | src/init.c | 12 | ||||
| -rw-r--r-- | src/main.c | 4 | ||||
| -rw-r--r-- | src/modulemanager.cpp | 6 | ||||
| -rw-r--r-- | src/modules/hs_request.c | 150 | ||||
| -rw-r--r-- | src/modules/os_ignore_db.c | 490 | ||||
| -rw-r--r-- | src/modules/os_info.c | 193 | ||||
| -rw-r--r-- | src/regchannel.cpp | 11 | ||||
| -rw-r--r-- | src/tools/db-convert.c | 110 | ||||
| -rw-r--r-- | src/tools/db-convert.h | 19 | ||||
| -rw-r--r-- | src/users.c | 6 |
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> ¶ms) +{ + 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> ¶ms) +{ + 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> ¶ms) +{ + 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> ¶ms) +{ + 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> ¶ms) +{ + 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> ¶ms) +{ + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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> ¶ms) + { + 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(), NULL, 10)); + if (Stuck) + ak->SetFlag(AK_STUCK); + if (Nick) + ak->SetFlag(AK_ISNICK); + + } + else if (key == "MLOCK_ON" || buf == "MLOCK_OFF") + { + bool Set = key == "MLOCK_ON" ? true : false; + + for (unsigned j = 0; j < params.size(); ++j) + for (i = 0; Channel |
