/modules/database/db_old.cpp
C++ | 1360 lines | 1162 code | 182 blank | 16 comment | 243 complexity | 7946871e32c177c82a5c02332178f5db MD5 | raw file
Possible License(s): GPL-2.0
- /*
- *
- * (C) 2003-2018 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.
- */
- #include "module.h"
- #include "modules/os_session.h"
- #include "modules/bs_kick.h"
- #include "modules/cs_mode.h"
- #include "modules/bs_badwords.h"
- #include "modules/os_news.h"
- #include "modules/suspend.h"
- #include "modules/os_forbid.h"
- #include "modules/cs_entrymsg.h"
- #define READ(x) \
- if (true) \
- { \
- if ((x) < 0) \
- printf("Error, the database is broken, line %d, trying to continue... no guarantee.\n", __LINE__); \
- } \
- else \
- static_cast<void>(0)
- #define getc_db(f) (fgetc((f)->fp))
- #define read_db(f, buf, len) (fread((buf), 1, (len), (f)->fp))
- #define read_buffer(buf, f) ((read_db((f), (buf), sizeof(buf)) == sizeof(buf)) ? 0 : -1)
- #define OLD_BI_PRIVATE 0x0001
- #define OLD_NI_KILLPROTECT 0x00000001 /* Kill others who take this nick */
- #define OLD_NI_SECURE 0x00000002 /* Don't recognize unless IDENTIFY'd */
- #define OLD_NI_MSG 0x00000004 /* Use PRIVMSGs instead of NOTICEs */
- #define OLD_NI_MEMO_HARDMAX 0x00000008 /* Don't allow user to change memo limit */
- #define OLD_NI_MEMO_SIGNON 0x00000010 /* Notify of memos at signon and un-away */
- #define OLD_NI_MEMO_RECEIVE 0x00000020 /* Notify of new memos when sent */
- #define OLD_NI_PRIVATE 0x00000040 /* Don't show in LIST to non-servadmins */
- #define OLD_NI_HIDE_EMAIL 0x00000080 /* Don't show E-mail in INFO */
- #define OLD_NI_HIDE_MASK 0x00000100 /* Don't show last seen address in INFO */
- #define OLD_NI_HIDE_QUIT 0x00000200 /* Don't show last quit message in INFO */
- #define OLD_NI_KILL_QUICK 0x00000400 /* Kill in 20 seconds instead of 60 */
- #define OLD_NI_KILL_IMMED 0x00000800 /* Kill immediately instead of in 60 sec */
- #define OLD_NI_MEMO_MAIL 0x00010000 /* User gets email on memo */
- #define OLD_NI_HIDE_STATUS 0x00020000 /* Don't show services access status */
- #define OLD_NI_SUSPENDED 0x00040000 /* Nickname is suspended */
- #define OLD_NI_AUTOOP 0x00080000 /* Autoop nickname in channels */
- #define OLD_NS_NO_EXPIRE 0x0004 /* nick won't expire */
- #define OLD_NS_VERBOTEN 0x0002
- #define OLD_CI_KEEPTOPIC 0x00000001
- #define OLD_CI_SECUREOPS 0x00000002
- #define OLD_CI_PRIVATE 0x00000004
- #define OLD_CI_TOPICLOCK 0x00000008
- #define OLD_CI_RESTRICTED 0x00000010
- #define OLD_CI_PEACE 0x00000020
- #define OLD_CI_SECURE 0x00000040
- #define OLD_CI_VERBOTEN 0x00000080
- #define OLD_CI_ENCRYPTEDPW 0x00000100
- #define OLD_CI_NO_EXPIRE 0x00000200
- #define OLD_CI_MEMO_HARDMAX 0x00000400
- #define OLD_CI_OPNOTICE 0x00000800
- #define OLD_CI_SECUREFOUNDER 0x00001000
- #define OLD_CI_SIGNKICK 0x00002000
- #define OLD_CI_SIGNKICK_LEVEL 0x00004000
- #define OLD_CI_XOP 0x00008000
- #define OLD_CI_SUSPENDED 0x00010000
- /* BotServ SET flags */
- #define OLD_BS_DONTKICKOPS 0x00000001
- #define OLD_BS_DONTKICKVOICES 0x00000002
- #define OLD_BS_FANTASY 0x00000004
- #define OLD_BS_SYMBIOSIS 0x00000008
- #define OLD_BS_GREET 0x00000010
- #define OLD_BS_NOBOT 0x00000020
- /* BotServ Kickers flags */
- #define OLD_BS_KICK_BOLDS 0x80000000
- #define OLD_BS_KICK_COLORS 0x40000000
- #define OLD_BS_KICK_REVERSES 0x20000000
- #define OLD_BS_KICK_UNDERLINES 0x10000000
- #define OLD_BS_KICK_BADWORDS 0x08000000
- #define OLD_BS_KICK_CAPS 0x04000000
- #define OLD_BS_KICK_FLOOD 0x02000000
- #define OLD_BS_KICK_REPEAT 0x01000000
- #define OLD_NEWS_LOGON 0
- #define OLD_NEWS_OPER 1
- #define OLD_NEWS_RANDOM 2
- static struct mlock_info
- {
- char c;
- uint32_t m;
- } mlock_infos[] = {
- {'i', 0x00000001},
- {'m', 0x00000002},
- {'n', 0x00000004},
- {'p', 0x00000008},
- {'s', 0x00000010},
- {'t', 0x00000020},
- {'R', 0x00000100},
- {'r', 0x00000200},
- {'c', 0x00000400},
- {'A', 0x00000800},
- {'K', 0x00002000},
- {'O', 0x00008000},
- {'Q', 0x00010000},
- {'S', 0x00020000},
- {'G', 0x00100000},
- {'C', 0x00200000},
- {'u', 0x00400000},
- {'z', 0x00800000},
- {'N', 0x01000000},
- {'M', 0x04000000}
- };
- static Anope::string hashm;
- enum
- {
- LANG_EN_US, /* United States English */
- LANG_JA_JIS, /* Japanese (JIS encoding) */
- LANG_JA_EUC, /* Japanese (EUC encoding) */
- LANG_JA_SJIS, /* Japanese (SJIS encoding) */
- LANG_ES, /* Spanish */
- LANG_PT, /* Portugese */
- LANG_FR, /* French */
- LANG_TR, /* Turkish */
- LANG_IT, /* Italian */
- LANG_DE, /* German */
- LANG_CAT, /* Catalan */
- LANG_GR, /* Greek */
- LANG_NL, /* Dutch */
- LANG_RU, /* Russian */
- LANG_HUN, /* Hungarian */
- LANG_PL /* Polish */
- };
- static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status, uint32_t *limit, Anope::string *key)
- {
- ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
- for (unsigned i = 0; i < (sizeof(mlock_infos) / sizeof(mlock_info)); ++i)
- if (lock & mlock_infos[i].m)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock_infos[i].c);
- if (cm && ml)
- {
- if (limit && mlock_infos[i].c == 'l')
- ml->SetMLock(cm, status, stringify(*limit));
- else if (key && mlock_infos[i].c == 'k')
- ml->SetMLock(cm, status, *key);
- else
- ml->SetMLock(cm, status);
- }
- }
- }
- static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- static const char Pad64 = '=';
- static void my_b64_encode(const Anope::string &src, Anope::string &target)
- {
- size_t src_pos = 0, src_len = src.length();
- unsigned char input[3];
- target.clear();
- while (src_len - src_pos > 2)
- {
- input[0] = src[src_pos++];
- input[1] = src[src_pos++];
- input[2] = src[src_pos++];
- target += Base64[input[0] >> 2];
- target += Base64[((input[0] & 0x03) << 4) + (input[1] >> 4)];
- target += Base64[((input[1] & 0x0f) << 2) + (input[2] >> 6)];
- target += Base64[input[2] & 0x3f];
- }
- /* Now we worry about padding */
- if (src_pos != src_len)
- {
- input[0] = input[1] = input[2] = 0;
- for (size_t i = 0; i < src_len - src_pos; ++i)
- input[i] = src[src_pos + i];
- target += Base64[input[0] >> 2];
- target += Base64[((input[0] & 0x03) << 4) + (input[1] >> 4)];
- if (src_pos == src_len - 1)
- target += Pad64;
- else
- target += Base64[((input[1] & 0x0f) << 2) + (input[2] >> 6)];
- target += Pad64;
- }
- }
- static Anope::string Hex(const char *data, size_t l)
- {
- const char hextable[] = "0123456789abcdef";
- std::string rv;
- for (size_t i = 0; i < l; ++i)
- {
- unsigned char c = data[i];
- rv += hextable[c >> 4];
- rv += hextable[c & 0xF];
- }
- return rv;
- }
- static Anope::string GetLevelName(int level)
- {
- switch (level)
- {
- case 0:
- return "INVITE";
- case 1:
- return "AKICK";
- case 2:
- return "SET";
- case 3:
- return "UNBAN";
- case 4:
- return "AUTOOP";
- case 5:
- return "AUTODEOP";
- case 6:
- return "AUTOVOICE";
- case 7:
- return "OP";
- case 8:
- return "ACCESS_LIST";
- case 9:
- return "CLEAR";
- case 10:
- return "NOJOIN";
- case 11:
- return "ACCESS_CHANGE";
- case 12:
- return "MEMO";
- case 13:
- return "ASSIGN";
- case 14:
- return "BADWORDS";
- case 15:
- return "NOKICK";
- case 16:
- return "FANTASIA";
- case 17:
- return "SAY";
- case 18:
- return "GREET";
- case 19:
- return "VOICEME";
- case 20:
- return "VOICE";
- case 21:
- return "GETKEY";
- case 22:
- return "AUTOHALFOP";
- case 23:
- return "AUTOPROTECT";
- case 24:
- return "OPME";
- case 25:
- return "HALFOPME";
- case 26:
- return "HALFOP";
- case 27:
- return "PROTECTME";
- case 28:
- return "PROTECT";
- case 29:
- return "KICKME";
- case 30:
- return "KICK";
- case 31:
- return "SIGNKICK";
- case 32:
- return "BANME";
- case 33:
- return "BAN";
- case 34:
- return "TOPIC";
- case 35:
- return "INFO";
- default:
- return "INVALID";
- }
- }
- static char *strscpy(char *d, const char *s, size_t len)
- {
- char *d_orig = d;
- if (!len)
- return d;
- while (--len && (*d++ = *s++));
- *d = '\0';
- return d_orig;
- }
- struct dbFILE
- {
- int mode; /* 'r' for reading, 'w' for writing */
- FILE *fp; /* The normal file descriptor */
- char filename[1024]; /* Name of the database file */
- };
- static dbFILE *open_db_read(const char *service, const char *filename, int version)
- {
- dbFILE *f;
- FILE *fp;
- int myversion;
- f = new dbFILE;
- strscpy(f->filename, (Anope::DataDir + "/" + filename).c_str(), sizeof(f->filename));
- f->mode = 'r';
- fp = fopen(f->filename, "rb");
- if (!fp)
- {
- Log() << "Can't read " << service << " database " << f->filename;
- delete f;
- return NULL;
- }
- f->fp = fp;
- myversion = fgetc(fp) << 24 | fgetc(fp) << 16 | fgetc(fp) << 8 | fgetc(fp);
- if (feof(fp))
- {
- Log() << "Error reading version number on " << f->filename << ": End of file detected.";
- delete f;
- return NULL;
- }
- else if (myversion < version)
- {
- Log() << "Unsuported database version (" << myversion << ") on " << f->filename << ".";
- delete f;
- return NULL;
- }
- return f;
- }
- void close_db(dbFILE *f)
- {
- fclose(f->fp);
- delete f;
- }
- static int read_int16(int16_t *ret, dbFILE *f)
- {
- int c1, c2;
- *ret = 0;
- c1 = fgetc(f->fp);
- c2 = fgetc(f->fp);
- if (c1 == EOF || c2 == EOF)
- return -1;
- *ret = c1 << 8 | c2;
- return 0;
- }
- static int read_uint16(uint16_t *ret, dbFILE *f)
- {
- int c1, c2;
- *ret = 0;
- c1 = fgetc(f->fp);
- c2 = fgetc(f->fp);
- if (c1 == EOF || c2 == EOF)
- return -1;
- *ret = c1 << 8 | c2;
- return 0;
- }
- static int read_string(Anope::string &str, dbFILE *f)
- {
- str.clear();
- uint16_t len;
- if (read_uint16(&len, f) < 0)
- return -1;
- if (len == 0)
- return 0;
- char *s = new char[len];
- if (len != fread(s, 1, len, f->fp))
- {
- delete [] s;
- return -1;
- }
- str = s;
- delete [] s;
- return 0;
- }
- static int read_uint32(uint32_t *ret, dbFILE *f)
- {
- int c1, c2, c3, c4;
- *ret = 0;
- c1 = fgetc(f->fp);
- c2 = fgetc(f->fp);
- c3 = fgetc(f->fp);
- c4 = fgetc(f->fp);
- if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
- return -1;
- *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
- return 0;
- }
- int read_int32(int32_t *ret, dbFILE *f)
- {
- int c1, c2, c3, c4;
- *ret = 0;
- c1 = fgetc(f->fp);
- c2 = fgetc(f->fp);
- c3 = fgetc(f->fp);
- c4 = fgetc(f->fp);
- if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF)
- return -1;
- *ret = c1 << 24 | c2 << 16 | c3 << 8 | c4;
- return 0;
- }
- static void LoadNicks()
- {
- ServiceReference<ForbidService> forbid("ForbidService", "forbid");
- dbFILE *f = open_db_read("NickServ", "nick.db", 14);
- if (f == NULL)
- return;
- for (int i = 0; i < 1024; ++i)
- for (int c; (c = getc_db(f)) == 1;)
- {
- Anope::string buffer;
- READ(read_string(buffer, f));
- NickCore *nc = new NickCore(buffer);
- const Anope::string settings[] = { "killprotect", "kill_quick", "ns_secure", "ns_private", "hide_email",
- "hide_mask", "hide_quit", "memo_signon", "memo_receive", "autoop", "msg", "ns_keepmodes" };
- for (unsigned j = 0; j < sizeof(settings) / sizeof(Anope::string); ++j)
- nc->Shrink<bool>(settings[j].upper());
- char pwbuf[32];
- READ(read_buffer(pwbuf, f));
- if (hashm == "plain")
- my_b64_encode(pwbuf, nc->pass);
- else if (hashm == "md5" || hashm == "oldmd5")
- nc->pass = Hex(pwbuf, 16);
- else if (hashm == "sha1")
- nc->pass = Hex(pwbuf, 20);
- else
- nc->pass = Hex(pwbuf, strlen(pwbuf));
- nc->pass = hashm + ":" + nc->pass;
- READ(read_string(buffer, f));
- nc->email = buffer;
- READ(read_string(buffer, f));
- if (!buffer.empty())
- nc->Extend<Anope::string>("greet", buffer);
- uint32_t u32;
- READ(read_uint32(&u32, f));
- //nc->icq = u32;
- READ(read_string(buffer, f));
- //nc->url = buffer;
- READ(read_uint32(&u32, f));
- if (u32 & OLD_NI_KILLPROTECT)
- nc->Extend<bool>("KILLPROTECT");
- if (u32 & OLD_NI_SECURE)
- nc->Extend<bool>("NS_SECURE");
- if (u32 & OLD_NI_MSG)
- nc->Extend<bool>("MSG");
- if (u32 & OLD_NI_MEMO_HARDMAX)
- nc->Extend<bool>("MEMO_HARDMAX");
- if (u32 & OLD_NI_MEMO_SIGNON)
- nc->Extend<bool>("MEMO_SIGNON");
- if (u32 & OLD_NI_MEMO_RECEIVE)
- nc->Extend<bool>("MEMO_RECEIVE");
- if (u32 & OLD_NI_PRIVATE)
- nc->Extend<bool>("NS_PRIVATE");
- if (u32 & OLD_NI_HIDE_EMAIL)
- nc->Extend<bool>("HIDE_EMAIL");
- if (u32 & OLD_NI_HIDE_MASK)
- nc->Extend<bool>("HIDE_MASK");
- if (u32 & OLD_NI_HIDE_QUIT)
- nc->Extend<bool>("HIDE_QUIT");
- if (u32 & OLD_NI_KILL_QUICK)
- nc->Extend<bool>("KILL_QUICK");
- if (u32 & OLD_NI_KILL_IMMED)
- nc->Extend<bool>("KILL_IMMED");
- if (u32 & OLD_NI_MEMO_MAIL)
- nc->Extend<bool>("MEMO_MAIL");
- if (u32 & OLD_NI_HIDE_STATUS)
- nc->Extend<bool>("HIDE_STATUS");
- if (u32 & OLD_NI_SUSPENDED)
- {
- SuspendInfo si;
- si.what = nc->display;
- si.when = si.expires = 0;
- nc->Extend("NS_SUSPENDED", si);
- }
- if (!(u32 & OLD_NI_AUTOOP))
- nc->Extend<bool>("AUTOOP");
- uint16_t u16;
- READ(read_uint16(&u16, f));
- switch (u16)
- {
- case LANG_ES:
- nc->language = "es_ES.UTF-8";
- break;
- case LANG_PT:
- nc->language = "pt_PT.UTF-8";
- break;
- case LANG_FR:
- nc->language = "fr_FR.UTF-8";
- break;
- case LANG_TR:
- nc->language = "tr_TR.UTF-8";
- break;
- case LANG_IT:
- nc->language = "it_IT.UTF-8";
- break;
- case LANG_DE:
- nc->language = "de_DE.UTF-8";
- break;
- case LANG_CAT:
- nc->language = "ca_ES.UTF-8"; // yes, iso639 defines catalan as CA
- break;
- case LANG_GR:
- nc->language = "el_GR.UTF-8";
- break;
- case LANG_NL:
- nc->language = "nl_NL.UTF-8";
- break;
- case LANG_RU:
- nc->language = "ru_RU.UTF-8";
- break;
- case LANG_HUN:
- nc->language = "hu_HU.UTF-8";
- break;
- case LANG_PL:
- nc->language = "pl_PL.UTF-8";
- break;
- case LANG_EN_US:
- case LANG_JA_JIS:
- case LANG_JA_EUC:
- case LANG_JA_SJIS: // these seem to be unused
- default:
- nc->language = "en";
- }
- READ(read_uint16(&u16, f));
- for (uint16_t j = 0; j < u16; ++j)
- {
- READ(read_string(buffer, f));
- nc->access.push_back(buffer);
- }
- int16_t i16;
- READ(read_int16(&i16, f));
- READ(read_int16(&nc->memos.memomax, f));
- for (int16_t j = 0; j < i16; ++j)
- {
- Memo *m = new Memo;
- READ(read_uint32(&u32, f));
- uint16_t flags;
- READ(read_uint16(&flags, f));
- int32_t tmp32;
- READ(read_int32(&tmp32, f));
- m->time = tmp32;
- char sbuf[32];
- READ(read_buffer(sbuf, f));
- m->sender = sbuf;
- READ(read_string(m->text, f));
- m->owner = nc->display;
- nc->memos.memos->push_back(m);
- m->mi = &nc->memos;
- }
- READ(read_uint16(&u16, f));
- READ(read_int16(&i16, f));
- Log(LOG_DEBUG) << "Loaded NickCore " << nc->display;
- }
- for (int i = 0; i < 1024; ++i)
- for (int c; (c = getc_db(f)) == 1;)
- {
- Anope::string nick, last_usermask, last_realname, last_quit;
- time_t time_registered, last_seen;
- READ(read_string(nick, f));
- READ(read_string(last_usermask, f));
- READ(read_string(last_realname, f));
- READ(read_string(last_quit, f));
- int32_t tmp32;
- READ(read_int32(&tmp32, f));
- time_registered = tmp32;
- READ(read_int32(&tmp32, f));
- last_seen = tmp32;
- uint16_t tmpu16;
- READ(read_uint16(&tmpu16, f));
- Anope::string core;
- READ(read_string(core, f));
- NickCore *nc = NickCore::Find(core);
- if (nc == NULL)
- {
- Log() << "Skipping coreless nick " << nick << " with core " << core;
- continue;
- }
- if (tmpu16 & OLD_NS_VERBOTEN)
- {
- if (!forbid)
- {
- delete nc;
- continue;
- }
- if (nc->display.find_first_of("?*") != Anope::string::npos)
- {
- delete nc;
- continue;
- }
- ForbidData *d = forbid->CreateForbid();
- d->mask = nc->display;
- d->creator = last_usermask;
- d->reason = last_realname;
- d->expires = 0;
- d->created = 0;
- d->type = FT_NICK;
- delete nc;
- forbid->AddForbid(d);
- continue;
- }
- NickAlias *na = new NickAlias(nick, nc);
- na->last_usermask = last_usermask;
- na->last_realname = last_realname;
- na->last_quit = last_quit;
- na->time_registered = time_registered;
- na->last_seen = last_seen;
- if (tmpu16 & OLD_NS_NO_EXPIRE)
- na->Extend<bool>("NS_NO_EXPIRE");
- Log(LOG_DEBUG) << "Loaded NickAlias " << na->nick;
- }
- close_db(f); /* End of section Ia */
- }
- static void LoadVHosts()
- {
- dbFILE *f = open_db_read("HostServ", "hosts.db", 3);
- if (f == NULL)
- return;
- for (int c; (c = getc_db(f)) == 1;)
- {
- Anope::string nick, ident, host, creator;
- int32_t vtime;
- READ(read_string(nick, f));
- READ(read_string(ident, f));
- READ(read_string(host, f));
- READ(read_string(creator, f));
- READ(read_int32(&vtime, f));
- NickAlias *na = NickAlias::Find(nick);
- if (na == NULL)
- {
- Log() << "Removing vhost for nonexistent nick " << nick;
- continue;
- }
- na->SetVhost(ident, host, creator, vtime);
- Log() << "Loaded vhost for " << na->nick;
- }
- close_db(f);
- }
- static void LoadBots()
- {
- dbFILE *f = open_db_read("Botserv", "bot.db", 10);
- if (f == NULL)
- return;
- for (int c; (c = getc_db(f)) == 1;)
- {
- Anope::string nick, user, host, real;
- int16_t flags, chancount;
- int32_t created;
- READ(read_string(nick, f));
- READ(read_string(user, f));
- READ(read_string(host, f));
- READ(read_string(real, f));
- READ(read_int16(&flags, f));
- READ(read_int32(&created, f));
- READ(read_int16(&chancount, f));
- BotInfo *bi = BotInfo::Find(nick, true);
- if (!bi)
- bi = new BotInfo(nick, user, host, real);
- bi->created = created;
- if (flags & OLD_BI_PRIVATE)
- bi->oper_only = true;
- Log(LOG_DEBUG) << "Loaded bot " << bi->nick;
- }
- close_db(f);
- }
- static void LoadChannels()
- {
- ServiceReference<ForbidService> forbid("ForbidService", "forbid");
- dbFILE *f = open_db_read("ChanServ", "chan.db", 16);
- if (f == NULL)
- return;
- for (int i = 0; i < 256; ++i)
- for (int c; (c = getc_db(f)) == 1;)
- {
- Anope::string buffer;
- char namebuf[64];
- READ(read_buffer(namebuf, f));
- ChannelInfo *ci = new ChannelInfo(namebuf);
- const Anope::string settings[] = { "keeptopic", "peace", "cs_private", "restricted", "cs_secure", "secureops", "securefounder",
- "signkick", "signkick_level", "topiclock", "persist", "noautoop", "cs_keepmodes" };
- for (unsigned j = 0; j < sizeof(settings) / sizeof(Anope::string); ++j)
- ci->Shrink<bool>(settings[j].upper());
- READ(read_string(buffer, f));
- ci->SetFounder(NickCore::Find(buffer));
- READ(read_string(buffer, f));
- ci->SetSuccessor(NickCore::Find(buffer));
- char pwbuf[32];
- READ(read_buffer(pwbuf, f));
- READ(read_string(ci->desc, f));
- READ(read_string(buffer, f));
- READ(read_string(buffer, f));
- int32_t tmp32;
- READ(read_int32(&tmp32, f));
- ci->time_registered = tmp32;
- READ(read_int32(&tmp32, f));
- ci->last_used = tmp32;
- READ(read_string(ci->last_topic, f));
- READ(read_buffer(pwbuf, f));
- ci->last_topic_setter = pwbuf;
- READ(read_int32(&tmp32, f));
- ci->last_topic_time = tmp32;
- uint32_t tmpu32;
- READ(read_uint32(&tmpu32, f));
- // Temporary flags cleanup
- tmpu32 &= ~0x80000000;
- if (tmpu32 & OLD_CI_KEEPTOPIC)
- ci->Extend<bool>("KEEPTOPIC");
- if (tmpu32 & OLD_CI_SECUREOPS)
- ci->Extend<bool>("SECUREOPS");
- if (tmpu32 & OLD_CI_PRIVATE)
- ci->Extend<bool>("CS_PRIVATE");
- if (tmpu32 & OLD_CI_TOPICLOCK)
- ci->Extend<bool>("TOPICLOCK");
- if (tmpu32 & OLD_CI_RESTRICTED)
- ci->Extend<bool>("RESTRICTED");
- if (tmpu32 & OLD_CI_PEACE)
- ci->Extend<bool>("PEACE");
- if (tmpu32 & OLD_CI_SECURE)
- ci->Extend<bool>("CS_SECURE");
- if (tmpu32 & OLD_CI_NO_EXPIRE)
- ci->Extend<bool>("CS_NO_EXPIRE");
- if (tmpu32 & OLD_CI_MEMO_HARDMAX)
- ci->Extend<bool>("MEMO_HARDMAX");
- if (tmpu32 & OLD_CI_SECUREFOUNDER)
- ci->Extend<bool>("SECUREFOUNDER");
- if (tmpu32 & OLD_CI_SIGNKICK)
- ci->Extend<bool>("SIGNKICK");
- if (tmpu32 & OLD_CI_SIGNKICK_LEVEL)
- ci->Extend<bool>("SIGNKICK_LEVEL");
- Anope::string forbidby, forbidreason;
- READ(read_string(forbidby, f));
- READ(read_string(forbidreason, f));
- if (tmpu32 & OLD_CI_SUSPENDED)
- {
- SuspendInfo si;
- si.what = ci->name;
- si.by = forbidby;
- si.reason = forbidreason;
- si.when = si.expires = 0;
- ci->Extend("CS_SUSPENDED", si);
- }
- bool forbid_chan = tmpu32 & OLD_CI_VERBOTEN;
- int16_t tmp16;
- READ(read_int16(&tmp16, f));
- ci->bantype = tmp16;
- READ(read_int16(&tmp16, f));
- if (tmp16 > 36)
- tmp16 = 36;
- for (int16_t j = 0; j < tmp16; ++j)
- {
- int16_t level;
- READ(read_int16(&level, f));
- if (level == ACCESS_INVALID)
- level = ACCESS_FOUNDER;
- if (j == 10 && level < 0) // NOJOIN
- ci->Shrink<bool>("RESTRICTED"); // If CSDefRestricted was enabled this can happen
- ci->SetLevel(GetLevelName(j), level);
- }
- bool xop = tmpu32 & OLD_CI_XOP;
- ServiceReference<AccessProvider> provider_access("AccessProvider", "access/access"), provider_xop("AccessProvider", "access/xop");
- uint16_t tmpu16;
- READ(read_uint16(&tmpu16, f));
- for (uint16_t j = 0; j < tmpu16; ++j)
- {
- uint16_t in_use;
- READ(read_uint16(&in_use, f));
- if (in_use)
- {
- ChanAccess *access = NULL;
- if (xop)
- {
- if (provider_xop)
- access = provider_xop->Create();
- }
- else
- if (provider_access)
- access = provider_access->Create();
- if (access)
- access->ci = ci;
- int16_t level;
- READ(read_int16(&level, f));
- if (access)
- {
- if (xop)
- {
- switch (level)
- {
- case 3:
- access->AccessUnserialize("VOP");
- break;
- case 4:
- access->AccessUnserialize("HOP");
- break;
- case 5:
- access->AccessUnserialize("AOP");
- break;
- case 10:
- access->AccessUnserialize("SOP");
- break;
- }
- }
- else
- access->AccessUnserialize(stringify(level));
- }
- Anope::string mask;
- READ(read_string(mask, f));
- if (access)
- access->SetMask(mask, ci);
- READ(read_int32(&tmp32, f));
- if (access)
- {
- access->last_seen = tmp32;
- access->creator = "Unknown";
- access->created = Anope::CurTime;
- ci->AddAccess(access);
- }
- }
- }
- READ(read_uint16(&tmpu16, f));
- for (uint16_t j = 0; j < tmpu16; ++j)
- {
- uint16_t flags;
- READ(read_uint16(&flags, f));
- if (flags & 0x0001)
- {
- Anope::string mask, reason, creator;
- READ(read_string(mask, f));
- READ(read_string(reason, f));
- READ(read_string(creator, f));
- READ(read_int32(&tmp32, f));
- ci->AddAkick(creator, mask, reason, tmp32);
- }
- }
- READ(read_uint32(&tmpu32, f)); // mlock on
- ci->Extend<uint32_t>("mlock_on", tmpu32);
- READ(read_uint32(&tmpu32, f)); // mlock off
- ci->Extend<uint32_t>("mlock_off", tmpu32);
- READ(read_uint32(&tmpu32, f)); // mlock limit
- ci->Extend<uint32_t>("mlock_limit", tmpu32);
- READ(read_string(buffer, f)); // key
- ci->Extend<Anope::string>("mlock_key", buffer);
- READ(read_string(buffer, f)); // +f
- READ(read_string(buffer, f)); // +L
- READ(read_int16(&tmp16, f));
- READ(read_int16(&ci->memos.memomax, f));
- for (int16_t j = 0; j < tmp16; ++j)
- {
- READ(read_uint32(&tmpu32, f));
- READ(read_uint16(&tmpu16, f));
- Memo *m = new Memo;
- READ(read_int32(&tmp32, f));
- m->time = tmp32;
- char sbuf[32];
- READ(read_buffer(sbuf, f));
- m->sender = sbuf;
- READ(read_string(m->text, f));
- m->owner = ci->name;
- ci->memos.memos->push_back(m);
- m->mi = &ci->memos;
- }
- READ(read_string(buffer, f));
- if (!buffer.empty())
- {
- EntryMessageList *eml = ci->Require<EntryMessageList>("entrymsg");
- if (eml)
- {
- EntryMsg *e = eml->Create();
- e->chan = ci->name;
- e->creator = "Unknown";
- e->message = buffer;
- e->when = Anope::CurTime;
- (*eml)->push_back(e);
- }
- }
- READ(read_string(buffer, f));
- ci->bi = BotInfo::Find(buffer, true);
- READ(read_int32(&tmp32, f));
- if (tmp32 & OLD_BS_DONTKICKOPS)
- ci->Extend<bool>("BS_DONTKICKOPS");
- if (tmp32 & OLD_BS_DONTKICKVOICES)
- ci->Extend<bool>("BS_DONTKICKVOICES");
- if (tmp32 & OLD_BS_FANTASY)
- ci->Extend<bool>("BS_FANTASY");
- if (tmp32 & OLD_BS_GREET)
- ci->Extend<bool>("BS_GREET");
- if (tmp32 & OLD_BS_NOBOT)
- ci->Extend<bool>("BS_NOBOT");
- KickerData *kd = ci->Require<KickerData>("kickerdata");
- if (kd)
- {
- if (tmp32 & OLD_BS_KICK_BOLDS)
- kd->bolds = true;
- if (tmp32 & OLD_BS_KICK_COLORS)
- kd->colors = true;
- if (tmp32 & OLD_BS_KICK_REVERSES)
- kd->reverses = true;
- if (tmp32 & OLD_BS_KICK_UNDERLINES)
- kd->underlines = true;
- if (tmp32 & OLD_BS_KICK_BADWORDS)
- kd->badwords = true;
- if (tmp32 & OLD_BS_KICK_CAPS)
- kd->caps = true;
- if (tmp32 & OLD_BS_KICK_FLOOD)
- kd->flood = true;
- if (tmp32 & OLD_BS_KICK_REPEAT)
- kd->repeat = true;
- }
- READ(read_int16(&tmp16, f));
- for (int16_t j = 0; j < tmp16; ++j)
- {
- int16_t ttb;
- READ(read_int16(&ttb, f));
- if (j < TTB_SIZE && kd)
- kd->ttb[j] = ttb;
- }
- READ(read_int16(&tmp16, f));
- if (kd)
- kd->capsmin = tmp16;
- READ(read_int16(&tmp16, f));
- if (kd)
- kd->capspercent = tmp16;
- READ(read_int16(&tmp16, f));
- if (kd)
- kd->floodlines = tmp16;
- READ(read_int16(&tmp16, f));
- if (kd)
- kd->floodsecs = tmp16;
- READ(read_int16(&tmp16, f));
- if (kd)
- kd->repeattimes = tmp16;
- BadWords *bw = ci->Require<BadWords>("badwords");
- READ(read_uint16(&tmpu16, f));
- for (uint16_t j = 0; j < tmpu16; ++j)
- {
- uint16_t in_use;
- READ(read_uint16(&in_use, f));
- if (in_use)
- {
- READ(read_string(buffer, f));
- uint16_t type;
- READ(read_uint16(&type, f));
- BadWordType bwtype = BW_ANY;
- if (type == 1)
- bwtype = BW_SINGLE;
- else if (type == 2)
- bwtype = BW_START;
- else if (type == 3)
- bwtype = BW_END;
- if (bw)
- bw->AddBadWord(buffer, bwtype);
- }
- }
- if (forbid_chan)
- {
- if (!forbid)
- {
- delete ci;
- continue;
- }
- if (ci->name.find_first_of("?*") != Anope::string::npos)
- {
- delete ci;
- continue;
- }
- ForbidData *d = forbid->CreateForbid();
- d->mask = ci->name;
- d->creator = forbidby;
- d->reason = forbidreason;
- d->expires = 0;
- d->created = 0;
- d->type = FT_CHAN;
- delete ci;
- forbid->AddForbid(d);
- continue;
- }
- Log(LOG_DEBUG) << "Loaded channel " << ci->name;
- }
- close_db(f);
- }
- static void LoadOper()
- {
- dbFILE *f = open_db_read("OperServ", "oper.db", 13);
- if (f == NULL)
- return;
- XLineManager *akill, *sqline, *snline, *szline;
- akill = sqline = snline = szline = NULL;
- for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(), it_end = XLineManager::XLineManagers.end(); it != it_end; ++it)
- {
- XLineManager *xl = *it;
- if (xl->Type() == 'G')
- akill = xl;
- else if (xl->Type() == 'Q')
- sqline = xl;
- else if (xl->Type() == 'N')
- snline = xl;
- else if (xl->Type() == 'Z')
- szline = xl;
- }
- int32_t tmp32;
- READ(read_int32(&tmp32, f));
- READ(read_int32(&tmp32, f));
- int16_t capacity;
- read_int16(&capacity, f); // AKill count
- for (int16_t i = 0; i < capacity; ++i)
- {
- Anope::string user, host, by, reason;
- int32_t seton, expires;
- READ(read_string(user, f));
- READ(read_string(host, f));
- READ(read_string(by, f));
- READ(read_string(reason, f));
- READ(read_int32(&seton, f));
- READ(read_int32(&expires, f));
- if (!akill)
- continue;
- XLine *x = new XLine(user + "@" + host, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
- akill->AddXLine(x);
- }
- read_int16(&capacity, f); // SNLines
- for (int16_t i = 0; i < capacity; ++i)
- {
- Anope::string mask, by, reason;
- int32_t seton, expires;
- READ(read_string(mask, f));
- READ(read_string(by, f));
- READ(read_string(reason, f));
- READ(read_int32(&seton, f));
- READ(read_int32(&expires, f));
- if (!snline)
- continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
- snline->AddXLine(x);
- }
- read_int16(&capacity, f); // SQLines
- for (int16_t i = 0; i < capacity; ++i)
- {
- Anope::string mask, by, reason;
- int32_t seton, expires;
- READ(read_string(mask, f));
- READ(read_string(by, f));
- READ(read_string(reason, f));
- READ(read_int32(&seton, f));
- READ(read_int32(&expires, f));
- if (!sqline)
- continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
- sqline->AddXLine(x);
- }
- read_int16(&capacity, f); // SZLines
- for (int16_t i = 0; i < capacity; ++i)
- {
- Anope::string mask, by, reason;
- int32_t seton, expires;
- READ(read_string(mask, f));
- READ(read_string(by, f));
- READ(read_string(reason, f));
- READ(read_int32(&seton, f));
- READ(read_int32(&expires, f));
- if (!szline)
- continue;
- XLine *x = new XLine(mask, by, expires, reason, XLineManager::GenerateUID());
- x->created = seton;
- szline->AddXLine(x);
- }
- close_db(f);
- }
- static void LoadExceptions()
- {
- if (!session_service)
- return;
- dbFILE *f = open_db_read("OperServ", "exception.db", 9);
- if (f == NULL)
- return;
- int16_t num;
- READ(read_int16(&num, f));
- for (int i = 0; i < num; ++i)
- {
- Anope::string mask, reason;
- int16_t limit;
- char who[32];
- int32_t time, expires;
- READ(read_string(mask, f));
- READ(read_int16(&limit, f));
- READ(read_buffer(who, f));
- READ(read_string(reason, f));
- READ(read_int32(&time, f));
- READ(read_int32(&expires, f));
- Exception *exception = session_service->CreateException();
- exception->mask = mask;
- exception->limit = limit;
- exception->who = who;
- exception->time = time;
- exception->expires = expires;
- exception->reason = reason;
- session_service->AddException(exception);
- }
- close_db(f);
- }
- static void LoadNews()
- {
- if (!news_service)
- return;
- dbFILE *f = open_db_read("OperServ", "news.db", 9);
- if (f == NULL)
- return;
- int16_t n;
- READ(read_int16(&n, f));
- for (int16_t i = 0; i < n; i++)
- {
- int16_t type;
- NewsItem *ni = news_service->CreateNewsItem();
- READ(read_int16(&type, f));
- switch (type)
- {
- case OLD_NEWS_LOGON:
- ni->type = NEWS_LOGON;
- break;
- case OLD_NEWS_OPER:
- ni->type = NEWS_OPER;
- break;
- case OLD_NEWS_RANDOM:
- ni->type = NEWS_RANDOM;
- break;
- }
- int32_t unused;
- READ(read_int32(&unused, f));
- READ(read_string(ni->text, f));
- char who[32];
- READ(read_buffer(who, f));
- ni->who = who;
- int32_t tmp;
- READ(read_int32(&tmp, f));
- ni->time = tmp;
- news_service->AddNewsItem(ni);
- }
- close_db(f);
- }
- class DBOld : public Module
- {
- PrimitiveExtensibleItem<uint32_t> mlock_on, mlock_off, mlock_limit;
- PrimitiveExtensibleItem<Anope::string> mlock_key;
- public:
- DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR),
- mlock_on(this, "mlock_on"), mlock_off(this, "mlock_off"), mlock_limit(this, "mlock_limit"), mlock_key(this, "mlock_key")
- {
- hashm = Config->GetModule(this)->Get<const Anope::string>("hash");
- if (hashm != "md5" && hashm != "oldmd5" && hashm != "sha1" && hashm != "plain" && hashm != "sha256")
- throw ModuleException("Invalid hash method");
- }
- EventReturn OnLoadDatabase() anope_override
- {
- LoadNicks();
- LoadVHosts();
- LoadBots();
- LoadChannels();
- LoadOper();
- LoadExceptions();
- LoadNews();
- return EVENT_STOP;
- }
- void OnUplinkSync(Server *s) anope_override
- {
- for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
- {
- ChannelInfo *ci = it->second;
- uint32_t *limit = mlock_limit.Get(ci);
- Anope::string *key = mlock_key.Get(ci);
- uint32_t *u = mlock_on.Get(ci);
- if (u)
- {
- process_mlock(ci, *u, true, limit, key);
- mlock_on.Unset(ci);
- }
- u = mlock_off.Get(ci);
- if (u)
- {
- process_mlock(ci, *u, false, limit, key);
- mlock_off.Unset(ci);
- }
- mlock_limit.Unset(ci);
- mlock_key.Unset(ci);
- if (ci->c)
- ci->c->CheckModes();
- }
- }
- };
- MODULE_INIT(DBOld)