mirror of
git://git.acid.vegas/anope.git
synced 2024-11-23 16:16:42 +00:00
1361 lines
31 KiB
C++
1361 lines
31 KiB
C++
/*
|
|
*
|
|
* (C) 2003-2022 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() << "Unsupported 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)
|