mirror of
https://github.com/anope/anope.git
synced 2026-07-06 15:53:13 +02:00
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
This commit is contained in:
+35
-125
@@ -24,9 +24,6 @@
|
||||
int HSRequestMemoUser = 0;
|
||||
int HSRequestMemoOper = 0;
|
||||
int HSRequestMemoSetters = 0;
|
||||
char *HSRequestDBName = NULL;
|
||||
|
||||
#define HSREQ_DEFAULT_DBNAME "hs_request.db"
|
||||
|
||||
/* Language defines */
|
||||
#define LNG_NUM_STRINGS 21
|
||||
@@ -58,8 +55,6 @@ int my_isvalidchar(const char c);
|
||||
void my_memo_lang(User *u, const char *name, int z, int number, ...);
|
||||
void req_send_memos(User *u, char *vIdent, char *vHost);
|
||||
|
||||
void hsreq_load_db();
|
||||
|
||||
void my_load_config();
|
||||
void my_add_languages();
|
||||
|
||||
@@ -410,10 +405,6 @@ class HSRequest : public Module
|
||||
this->AddCommand(HOSTSERV, new CommandHSReject());
|
||||
this->AddCommand(HOSTSERV, new CommandHSWaiting());
|
||||
|
||||
ModuleManager::Attach(I_OnPreCommand, this);
|
||||
ModuleManager::Attach(I_OnSaveDatabase, this);
|
||||
ModuleManager::Attach(I_OnBackupDatabase, this);
|
||||
|
||||
this->SetAuthor(AUTHOR);
|
||||
this->SetVersion(VERSION);
|
||||
this->SetType(SUPPORTED);
|
||||
@@ -421,8 +412,6 @@ class HSRequest : public Module
|
||||
my_load_config();
|
||||
hs_request_head = NULL;
|
||||
|
||||
hsreq_load_db();
|
||||
|
||||
const char* langtable_en_us[] = {
|
||||
/* LNG_REQUEST_SYNTAX */
|
||||
"Syntax: \002REQUEST \037vhost\037\002",
|
||||
@@ -679,7 +668,8 @@ class HSRequest : public Module
|
||||
this->InsertLanguage(LANG_RU, LNG_NUM_STRINGS, langtable_ru);
|
||||
this->InsertLanguage(LANG_IT, LNG_NUM_STRINGS, langtable_it);
|
||||
|
||||
ModuleManager::Attach(I_OnHostServHelp, this);
|
||||
Implementation i[] = { I_OnHostServHelp, I_OnPreCommand, I_OnDatabaseRead, I_OnDatabaseWrite };
|
||||
ModuleManager::Attach(i, this, 4);
|
||||
}
|
||||
|
||||
~HSRequest()
|
||||
@@ -689,8 +679,6 @@ class HSRequest : public Module
|
||||
/* Clean up all open host requests */
|
||||
while (hs_request_head)
|
||||
hs_request_head = deleteHostCore(hs_request_head, NULL);
|
||||
|
||||
delete [] HSRequestDBName;
|
||||
}
|
||||
|
||||
EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms)
|
||||
@@ -726,52 +714,43 @@ class HSRequest : public Module
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
void OnSaveDatabase()
|
||||
{
|
||||
FILE *fp;
|
||||
const char *db_filename;
|
||||
const char *vident;
|
||||
HostCore *current;
|
||||
|
||||
if (HSRequestDBName)
|
||||
db_filename = HSRequestDBName;
|
||||
else
|
||||
db_filename = HSREQ_DEFAULT_DBNAME;
|
||||
|
||||
fp = fopen(db_filename, "w");
|
||||
if (!fp)
|
||||
{
|
||||
alog("[hs_request] Unable to open database ('%s') for writing", db_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
current = hs_request_head;
|
||||
while (current)
|
||||
{
|
||||
vident = current->vIdent ? current->vIdent : "(null)";
|
||||
fprintf(fp, "%s:%s:%s:%X:%s\n", current->nick, vident, current->vHost, static_cast<uint32>(current->time), current->creator);
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (debug)
|
||||
alog("[hs_request] Successfully saved database");
|
||||
}
|
||||
|
||||
void OnBackupDatabase()
|
||||
{
|
||||
if (HSRequestDBName)
|
||||
ModuleDatabaseBackup(HSRequestDBName);
|
||||
else
|
||||
ModuleDatabaseBackup(HSREQ_DEFAULT_DBNAME);
|
||||
}
|
||||
|
||||
void OnHostServHelp(User *u)
|
||||
{
|
||||
this->NoticeLang(Config.s_HostServ, u, LNG_HELP);
|
||||
this->NoticeLang(Config.s_HostServ, u, LNG_HELP_SETTER);
|
||||
}
|
||||
|
||||
EventReturn OnDatabaseRead(const std::vector<std::string> ¶ms)
|
||||
{
|
||||
if (params[0] == "HS_REQUEST" && params.size() >= 6)
|
||||
{
|
||||
my_add_host_request(const_cast<char *>(params[1].c_str()), const_cast<char *>(params[2].c_str()), const_cast<char *>(params[3].c_str()), const_cast<char *>(params[4].c_str()), strtol(params[5].c_str(), NULL, 10));
|
||||
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
void OnDatabaseWrite(void (*Write)(const std::string &))
|
||||
{
|
||||
for (HostCore *current = hs_request_head; current; current = current->next)
|
||||
{
|
||||
const char *vident = current->vIdent ? current->vIdent : "(null)";
|
||||
std::string buf = "HS_REQUEST ";
|
||||
// We really need a better + operator to make this easier ...
|
||||
buf += current->nick;
|
||||
buf += " ";
|
||||
buf += vident;
|
||||
buf += " ";
|
||||
buf += current->vHost;
|
||||
buf += " ";
|
||||
buf += current->time;
|
||||
buf += " ";
|
||||
buf += current->creator;
|
||||
Write(buf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void my_memo_lang(User *u, const char *name, int z, int number, ...)
|
||||
@@ -872,84 +851,15 @@ int my_isvalidchar(const char c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hsreq_load_db()
|
||||
{
|
||||
FILE *fp;
|
||||
const char *db_filename;
|
||||
char readbuf[1024];
|
||||
char *nick, *vident, *vhost, *creator, *tmp;
|
||||
int32 tmp_time;
|
||||
char *buf;
|
||||
|
||||
if (HSRequestDBName)
|
||||
db_filename = HSRequestDBName;
|
||||
else
|
||||
db_filename = HSREQ_DEFAULT_DBNAME;
|
||||
|
||||
fp = fopen(db_filename, "r");
|
||||
if (!fp)
|
||||
{
|
||||
alog("[hs_request] Unable to open database ('%s') for reading", db_filename);
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(readbuf, 1024, fp))
|
||||
{
|
||||
buf = normalizeBuffer(readbuf);
|
||||
if (buf || *buf)
|
||||
{
|
||||
nick = myStrGetToken(buf, ':', 0);
|
||||
vident = myStrGetToken(buf, ':', 1);
|
||||
vhost = myStrGetToken(buf, ':', 2);
|
||||
tmp = myStrGetToken(buf, ':', 3);
|
||||
if (tmp)
|
||||
{
|
||||
tmp_time = strtol(tmp, NULL, 16);
|
||||
delete [] tmp;
|
||||
}
|
||||
else
|
||||
tmp_time = 0;
|
||||
creator = myStrGetToken(buf, ':', 4);
|
||||
if (!nick || !vident || !vhost || !creator)
|
||||
{
|
||||
alog("[hs_request] Error while reading database, skipping record");
|
||||
continue;
|
||||
}
|
||||
if (!stricmp(vident, "(null)"))
|
||||
{
|
||||
delete [] vident;
|
||||
vident = NULL;
|
||||
}
|
||||
my_add_host_request(nick, vident, vhost, creator, tmp_time);
|
||||
delete [] nick;
|
||||
delete [] vhost;
|
||||
delete [] creator;
|
||||
if (vident)
|
||||
delete [] vident;
|
||||
}
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (debug)
|
||||
alog("[hs_request] Successfully loaded database");
|
||||
}
|
||||
|
||||
void my_load_config()
|
||||
{
|
||||
ConfigReader config;
|
||||
HSRequestMemoUser = config.ReadFlag("hs_request", "memouser", "no", 0);
|
||||
HSRequestMemoOper = config.ReadFlag("hs_request", "memooper", "no", 0);
|
||||
HSRequestMemoSetters = config.ReadFlag("hs_request", "memosetters", "no", 0);
|
||||
std::string tmp = config.ReadValue("hs_request", "database", HSREQ_DEFAULT_DBNAME, 0);
|
||||
|
||||
if (HSRequestDBName)
|
||||
delete [] HSRequestDBName;
|
||||
HSRequestDBName = sstrdup(tmp.c_str());
|
||||
|
||||
if (debug)
|
||||
alog("debug: [hs_request] Set config vars: MemoUser=%d MemoOper=%d MemoSetters=%d DBName='%s'", HSRequestMemoUser, HSRequestMemoOper, HSRequestMemoSetters, HSRequestDBName);
|
||||
alog("debug: [hs_request] Set config vars: MemoUser=%d MemoOper=%d MemoSetters=%d", HSRequestMemoUser, HSRequestMemoOper, HSRequestMemoSetters);
|
||||
}
|
||||
|
||||
MODULE_INIT(HSRequest)
|
||||
|
||||
@@ -1,490 +0,0 @@
|
||||
/* os_ignore_db.c - Provides a database backend for OS IGNORE.
|
||||
*
|
||||
* (C) 2003-2009 Anope Team
|
||||
* Contact us at team@anope.org
|
||||
*
|
||||
* Included in the Anope module pack since Anope 1.7.23
|
||||
* Anope Coder: Viper <viper@anope.org>
|
||||
*
|
||||
* Please read COPYING and README for further details.
|
||||
*
|
||||
*/
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
||||
#include "module.h"
|
||||
|
||||
#define AUTHOR "Viper"
|
||||
#define VERSION "$Id$"
|
||||
|
||||
/* Default database name */
|
||||
#define DefIgnoreDB "os_ignore.db"
|
||||
#define IGNOREDBVERSION 1
|
||||
|
||||
/* Database seperators */
|
||||
#define SEPARATOR '^' /* End of a key, seperates keys from values */
|
||||
#define BLOCKEND '\n' /* End of a block, e.g. a whole ignore */
|
||||
#define VALUEEND '\000' /* End of a value */
|
||||
#define SUBSTART '\010' /* Beginning of a new subblock, closed by a BLOCKEND */
|
||||
|
||||
/* Database reading return values */
|
||||
#define DB_READ_SUCCESS 0
|
||||
#define DB_READ_ERROR 1
|
||||
#define DB_EOF_ERROR 2
|
||||
#define DB_VERSION_ERROR 3
|
||||
#define DB_READ_BLOCKEND 4
|
||||
#define DB_READ_SUBSTART 5
|
||||
|
||||
#define DB_WRITE_SUCCESS 0
|
||||
#define DB_WRITE_ERROR 1
|
||||
#define DB_WRITE_NOVAL 2
|
||||
|
||||
/* Database Key, Value max length */
|
||||
#define MAXKEYLEN 128
|
||||
#define MAXVALLEN 1024
|
||||
|
||||
/* Structs */
|
||||
typedef struct db_file_ DBFile;
|
||||
|
||||
struct db_file_ {
|
||||
FILE *fptr; /* Pointer to the opened file */
|
||||
int db_version; /* The db version of the datafiles (only needed for reading) */
|
||||
int core_db_version; /* The current db version of this anope source */
|
||||
char service[256]; /* StatServ/etc. */
|
||||
char filename[256]; /* Filename of the database */
|
||||
char temp_name[262]; /* Temp filename of the database */
|
||||
};
|
||||
|
||||
|
||||
/* Variables */
|
||||
char *IgnoreDB;
|
||||
|
||||
/* Functions */
|
||||
int new_open_db_read(DBFile *dbptr, char **key, char **value);
|
||||
int new_open_db_write(DBFile *dbptr);
|
||||
void new_close_db(FILE *fptr, char **key, char **value);
|
||||
int new_read_db_entry(char **key, char **value, FILE * fptr);
|
||||
int new_write_db_entry(const char *key, DBFile *dbptr, const char *fmt, ...);
|
||||
int new_write_db_endofblock(DBFile *dbptr);
|
||||
void fill_db_ptr(DBFile *dbptr, int version, int core_version, char service[256], char filename[256]);
|
||||
|
||||
void load_ignore_db();
|
||||
void load_config();
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
||||
class OSIgnoreDB : public Module
|
||||
{
|
||||
public:
|
||||
OSIgnoreDB(const std::string &modname, const std::string &creator) : Module(modname, creator)
|
||||
{
|
||||
IgnoreDB = NULL;
|
||||
|
||||
this->SetAuthor(AUTHOR);
|
||||
this->SetVersion(VERSION);
|
||||
this->SetType(SUPPORTED);
|
||||
|
||||
ModuleManager::Attach(I_OnSaveDatabase, this);
|
||||
ModuleManager::Attach(I_OnBackupDatabase, this);
|
||||
|
||||
load_config();
|
||||
/* Load the ignore database and re-add them to anopes ignorelist. */
|
||||
load_ignore_db();
|
||||
ModuleManager::Attach(I_OnReload, this);
|
||||
}
|
||||
|
||||
~OSIgnoreDB()
|
||||
{
|
||||
/* Save the ignore database before bailing out.. */
|
||||
OnSaveDatabase();
|
||||
|
||||
if (IgnoreDB)
|
||||
delete [] IgnoreDB;
|
||||
}
|
||||
|
||||
void OnReload(bool starting)
|
||||
{
|
||||
load_config();
|
||||
}
|
||||
|
||||
void OnSaveDatabase()
|
||||
{
|
||||
DBFile *dbptr = new DBFile;
|
||||
time_t now;
|
||||
IgnoreData *ign, *next;
|
||||
|
||||
now = time(NULL);
|
||||
fill_db_ptr(dbptr, 0, IGNOREDBVERSION, Config.s_OperServ, IgnoreDB);
|
||||
|
||||
/* time to backup the old db */
|
||||
rename(IgnoreDB, dbptr->temp_name);
|
||||
|
||||
if (new_open_db_write(dbptr)) {
|
||||
rename(dbptr->temp_name, IgnoreDB);
|
||||
delete dbptr;
|
||||
return; /* Bang, an error occurred */
|
||||
}
|
||||
|
||||
/* Store the version of the DB in the DB as well...
|
||||
* This will make stuff a lot easier if the database scheme needs to modified. */
|
||||
new_write_db_entry("IGNORE_DB_VERSION", dbptr, "%d", IGNOREDBVERSION);
|
||||
new_write_db_endofblock(dbptr);
|
||||
|
||||
/* Go over the entire ignorelist, check whether each entry is still valid
|
||||
* and write it to the database if it is.*/
|
||||
for (ign = ignore; ign; ign = next) {
|
||||
next = ign->next;
|
||||
|
||||
if (ign->time != 0 && ign->time <= now) {
|
||||
if (debug)
|
||||
alog("[os_ignore_db] debug: Expiring ignore entry %s", ign->mask);
|
||||
if (ign->prev)
|
||||
ign->prev->next = ign->next;
|
||||
else if (ignore == ign)
|
||||
ignore = ign->next;
|
||||
if (ign->next)
|
||||
ign->next->prev = ign->prev;
|
||||
delete [] ign->mask;
|
||||
delete ign;
|
||||
ign = NULL;
|
||||
} else {
|
||||
new_write_db_entry("m", dbptr, "%s", ign->mask);
|
||||
new_write_db_entry("t", dbptr, "%d", ign->time);
|
||||
new_write_db_endofblock(dbptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbptr) {
|
||||
new_close_db(dbptr->fptr, NULL, NULL); /* close file */
|
||||
remove(dbptr->temp_name); /* saved successfully, no need to keep the old one */
|
||||
delete dbptr; /* free the db struct */
|
||||
}
|
||||
}
|
||||
|
||||
void OnBackupDatabase()
|
||||
{
|
||||
ModuleDatabaseBackup(IgnoreDB);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
||||
void load_config() {
|
||||
ConfigReader config;
|
||||
std::string tmp = config.ReadValue("os_ignore", "database", DefIgnoreDB, 0);
|
||||
|
||||
if (IgnoreDB)
|
||||
delete [] IgnoreDB;
|
||||
IgnoreDB = sstrdup(tmp.c_str());
|
||||
|
||||
if (debug)
|
||||
alog("[os_ignore_db] debug: Set config vars: OSIgnoreDBName='%s'", IgnoreDB);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
||||
/**************************************************************************
|
||||
* DataBase Handling
|
||||
**************************************************************************/
|
||||
|
||||
void load_ignore_db() {
|
||||
DBFile *dbptr = new DBFile;
|
||||
char *key, *value, *mask = NULL;
|
||||
int retval = 0;
|
||||
time_t expiry_time;
|
||||
IgnoreData *ign;
|
||||
|
||||
expiry_time = time(NULL);
|
||||
fill_db_ptr(dbptr, 0, IGNOREDBVERSION, Config.s_OperServ, IgnoreDB);
|
||||
|
||||
/* let's remove existing temp files here, because we only load dbs on startup */
|
||||
remove(dbptr->temp_name);
|
||||
|
||||
/* Open the db, fill the rest of dbptr and allocate memory for key and value */
|
||||
if (new_open_db_read(dbptr, &key, &value)) {
|
||||
delete dbptr;
|
||||
return; /* Bang, an error occurred */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
/* read a new entry and fill key and value with it -Certus */
|
||||
retval = new_read_db_entry(&key, &value, dbptr->fptr);
|
||||
|
||||
if (retval == DB_READ_ERROR) {
|
||||
new_close_db(dbptr->fptr, &key, &value);
|
||||
delete dbptr;
|
||||
return;
|
||||
|
||||
} else if (retval == DB_EOF_ERROR) {
|
||||
new_close_db(dbptr->fptr, &key, &value);
|
||||
delete dbptr;
|
||||
return;
|
||||
} else if (retval == DB_READ_BLOCKEND) { /* DB_READ_BLOCKEND */
|
||||
/* Check if we have everything to add the ignore..
|
||||
* We shouldn't bother with already expired ignores either.. */
|
||||
if (mask && (expiry_time > time(NULL) || expiry_time == 0)) {
|
||||
/* We should check for double entries.. */
|
||||
for (ign = ignore; ign; ign = ign->next)
|
||||
if (!stricmp(ign->mask, mask))
|
||||
break;
|
||||
|
||||
if (!ign) {
|
||||
/* Create a fresh entry.. */
|
||||
ign = new IgnoreData;
|
||||
ign->mask = sstrdup(mask);
|
||||
ign->time = expiry_time;
|
||||
ign->prev = NULL;
|
||||
ign->next = ignore;
|
||||
if (ignore)
|
||||
ignore->prev = ign;
|
||||
ignore = ign;
|
||||
if (debug)
|
||||
alog("[os_ignore_db] debug: Added new ignore entry for %s", mask);
|
||||
} else {
|
||||
/* Update time on existing entry.
|
||||
* The longest expiry time survives.. */
|
||||
if (expiry_time == 0 || ign->time == 0)
|
||||
ign->time = 0;
|
||||
else if (expiry_time > ign->time)
|
||||
ign->time = expiry_time;
|
||||
}
|
||||
}
|
||||
|
||||
if (mask) delete [] mask;
|
||||
mask = NULL;
|
||||
expiry_time = time(NULL);
|
||||
} else { /* DB_READ_SUCCESS */
|
||||
if (!*key || !*value)
|
||||
continue;
|
||||
|
||||
/* mask */
|
||||
if (!stricmp(key, "m")) {
|
||||
if (mask)
|
||||
delete [] mask;
|
||||
mask = sstrdup(value);
|
||||
|
||||
/* expiry time */
|
||||
} else if (!stricmp(key, "t")) {
|
||||
expiry_time = atoi(value);
|
||||
|
||||
} else if (!stricmp(key, "IGNORE_DB_VERSION")) {
|
||||
if (atoi(value) != IGNOREDBVERSION) {
|
||||
alog("[\002os_ignore_db\002] Database version does not match any database versions supported by this module.");
|
||||
alog("[\002os_ignore_db\002] Continuing with clean database...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* else */
|
||||
} /* while */
|
||||
|
||||
delete dbptr;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
|
||||
/**************************************************************************
|
||||
* Generic DataBase Functions (Borrowed this from Trystan :-) )
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
int new_open_db_read(DBFile *dbptr, char **key, char **value) {
|
||||
*key = new char[MAXKEYLEN];
|
||||
*value = new char[MAXVALLEN];
|
||||
|
||||
if (!(dbptr->fptr = fopen(dbptr->filename, "rb"))) {
|
||||
if (debug) {
|
||||
alog("debug: Can't read %s database %s : errno(%d)", dbptr->service,
|
||||
dbptr->filename, errno);
|
||||
}
|
||||
delete [] *key;
|
||||
*key = NULL;
|
||||
delete [] *value;
|
||||
*value = NULL;
|
||||
return DB_READ_ERROR;
|
||||
}
|
||||
dbptr->db_version = fgetc(dbptr->fptr) << 24 | fgetc(dbptr->fptr) << 16
|
||||
| fgetc(dbptr->fptr) << 8 | fgetc(dbptr->fptr);
|
||||
|
||||
if (ferror(dbptr->fptr)) {
|
||||
if (debug) {
|
||||
alog("debug: Error reading version number on %s", dbptr->filename);
|
||||
}
|
||||
delete [] *key;
|
||||
*key = NULL;
|
||||
delete [] *value;
|
||||
*value = NULL;
|
||||
return DB_READ_ERROR;
|
||||
} else if (feof(dbptr->fptr)) {
|
||||
if (debug) {
|
||||
alog("debug: Error reading version number on %s: End of file detected",
|
||||
dbptr->filename);
|
||||
}
|
||||
delete [] *key;
|
||||
*key = NULL;
|
||||
delete [] *value;
|
||||
*value = NULL;
|
||||
return DB_EOF_ERROR;
|
||||
} else if (dbptr->db_version < 1) {
|
||||
if (debug) {
|
||||
alog("debug: Invalid version number (%d) on %s", dbptr->db_version, dbptr->filename);
|
||||
}
|
||||
delete [] *key;
|
||||
*key = NULL;
|
||||
delete [] *value;
|
||||
*value = NULL;
|
||||
return DB_VERSION_ERROR;
|
||||
}
|
||||
return DB_READ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int new_open_db_write(DBFile *dbptr) {
|
||||
if (!(dbptr->fptr = fopen(dbptr->filename, "wb"))) {
|
||||
if (debug) {
|
||||
alog("debug: %s Can't open %s database for writing", dbptr->service, dbptr->filename);
|
||||
}
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
|
||||
if (fputc(dbptr->core_db_version >> 24 & 0xFF, dbptr->fptr) < 0 ||
|
||||
fputc(dbptr->core_db_version >> 16 & 0xFF, dbptr->fptr) < 0 ||
|
||||
fputc(dbptr->core_db_version >> 8 & 0xFF, dbptr->fptr) < 0 ||
|
||||
fputc(dbptr->core_db_version & 0xFF, dbptr->fptr) < 0) {
|
||||
if (debug) {
|
||||
alog("debug: Error writing version number on %s", dbptr->filename);
|
||||
}
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
return DB_WRITE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void new_close_db(FILE *fptr, char **key, char **value) {
|
||||
if (key && *key) {
|
||||
delete [] *key;
|
||||
*key = NULL;
|
||||
}
|
||||
if (value && *value) {
|
||||
delete [] *value;
|
||||
*value = NULL;
|
||||
}
|
||||
|
||||
if (fptr) {
|
||||
fclose(fptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int new_read_db_entry(char **key, char **value, FILE *fptr) {
|
||||
char *string = *key;
|
||||
int character;
|
||||
int i = 0;
|
||||
|
||||
**key = '\0';
|
||||
**value = '\0';
|
||||
|
||||
while (1) {
|
||||
if ((character = fgetc(fptr)) == EOF) { /* a problem occurred reading the file */
|
||||
if (ferror(fptr)) {
|
||||
return DB_READ_ERROR; /* error! */
|
||||
}
|
||||
return DB_EOF_ERROR; /* end of file */
|
||||
} else if (character == BLOCKEND) { /* END OF BLOCK */
|
||||
return DB_READ_BLOCKEND;
|
||||
} else if (character == VALUEEND) { /* END OF VALUE */
|
||||
string[i] = '\0'; /* end of value */
|
||||
return DB_READ_SUCCESS;
|
||||
} else if (character == SEPARATOR) { /* END OF KEY */
|
||||
string[i] = '\0'; /* end of key */
|
||||
string = *value; /* beginning of value */
|
||||
i = 0; /* start with the first character of our value */
|
||||
} else {
|
||||
if ((i == (MAXKEYLEN - 1)) && (string == *key)) { /* max key length reached, continuing with value */
|
||||
string[i] = '\0'; /* end of key */
|
||||
string = *value; /* beginning of value */
|
||||
i = 0; /* start with the first character of our value */
|
||||
} else if ((i == (MAXVALLEN - 1)) && (string == *value)) { /* max value length reached, returning */
|
||||
string[i] = '\0';
|
||||
return DB_READ_SUCCESS;
|
||||
} else {
|
||||
string[i] = character; /* read string (key or value) */
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int new_write_db_entry(const char *key, DBFile *dbptr, const char *fmt, ...) {
|
||||
char string[MAXKEYLEN + MAXVALLEN + 2], value[MAXVALLEN]; /* safety byte :P */
|
||||
va_list ap;
|
||||
unsigned int length;
|
||||
|
||||
if (!dbptr) {
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(value, MAXVALLEN, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (!stricmp(value, "(null)")) {
|
||||
return DB_WRITE_NOVAL;
|
||||
}
|
||||
snprintf(string, MAXKEYLEN + MAXVALLEN + 1, "%s%c%s", key, SEPARATOR, value);
|
||||
length = strlen(string);
|
||||
string[length] = VALUEEND;
|
||||
length++;
|
||||
|
||||
if (fwrite(string, 1, length, dbptr->fptr) < length) {
|
||||
if (debug) {
|
||||
alog("debug: Error writing to %s", dbptr->filename);
|
||||
}
|
||||
new_close_db(dbptr->fptr, NULL, NULL);
|
||||
if (debug) {
|
||||
alog("debug: Restoring backup.");
|
||||
}
|
||||
remove(dbptr->filename);
|
||||
rename(dbptr->temp_name, dbptr->filename);
|
||||
delete dbptr;
|
||||
dbptr = NULL;
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
return DB_WRITE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int new_write_db_endofblock(DBFile *dbptr) {
|
||||
if (!dbptr) {
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
if (fputc(BLOCKEND, dbptr->fptr) == EOF) {
|
||||
if (debug) {
|
||||
alog("debug: Error writing to %s", dbptr->filename);
|
||||
}
|
||||
new_close_db(dbptr->fptr, NULL, NULL);
|
||||
return DB_WRITE_ERROR;
|
||||
}
|
||||
return DB_WRITE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fill_db_ptr(DBFile *dbptr, int version, int core_version,
|
||||
char service[256], char filename[256]) {
|
||||
dbptr->db_version = version;
|
||||
dbptr->core_db_version = core_version;
|
||||
if (!service)
|
||||
strlcpy(dbptr->service, service, sizeof(dbptr->service));
|
||||
else
|
||||
strlcpy(dbptr->service, "", sizeof(dbptr->service));
|
||||
|
||||
strlcpy(dbptr->filename, filename, sizeof(dbptr->filename));
|
||||
snprintf(dbptr->temp_name, sizeof(dbptr->temp_name), "%s.temp", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
MODULE_INIT(OSIgnoreDB)
|
||||
+41
-152
@@ -21,9 +21,6 @@
|
||||
#define AUTHOR "Rob"
|
||||
#define VERSION "$Id$"
|
||||
|
||||
/* Default database name */
|
||||
#define DEFAULT_DB_NAME "os_info.db"
|
||||
|
||||
/* Multi-language stuff */
|
||||
#define LANG_NUM_STRINGS 10
|
||||
|
||||
@@ -40,11 +37,6 @@
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
char *OSInfoDBName = NULL;
|
||||
|
||||
int mLoadData();
|
||||
int mLoadConfig();
|
||||
|
||||
static Module *me;
|
||||
|
||||
/*************************************************************************/
|
||||
@@ -201,19 +193,9 @@ class OSInfo : public Module
|
||||
this->SetVersion(VERSION);
|
||||
this->SetType(SUPPORTED);
|
||||
|
||||
if (mLoadConfig())
|
||||
throw ModuleException("Unable to load config");
|
||||
|
||||
this->AddCommand(NICKSERV, new CommandNSOInfo());
|
||||
this->AddCommand(CHANSERV, new CommandCSOInfo());
|
||||
|
||||
ModuleManager::Attach(I_OnPostCommand, this);
|
||||
ModuleManager::Attach(I_OnSaveDatabase, this);
|
||||
ModuleManager::Attach(I_OnBackupDatabase, this);
|
||||
|
||||
mLoadData();
|
||||
ModuleManager::Attach(I_OnReload, this);
|
||||
|
||||
const char* langtable_en_us[] = {
|
||||
/* OINFO_SYNTAX */
|
||||
"Syntax: OINFO [ADD|DEL] nick <info>",
|
||||
@@ -427,8 +409,8 @@ class OSInfo : public Module
|
||||
this->InsertLanguage(LANG_RU, LANG_NUM_STRINGS, langtable_ru);
|
||||
this->InsertLanguage(LANG_IT, LANG_NUM_STRINGS, langtable_it);
|
||||
|
||||
Implementation i[] = { I_OnNickServHelp, I_OnChanServHelp };
|
||||
ModuleManager::Attach(i, this, 2);
|
||||
Implementation i[] = { I_OnNickServHelp, I_OnChanServHelp, I_OnPostCommand, I_OnDatabaseReadMetadata, I_OnDatabaseWriteMetadata };
|
||||
ModuleManager::Attach(i, this, 5);
|
||||
}
|
||||
|
||||
~OSInfo()
|
||||
@@ -455,18 +437,6 @@ class OSInfo : public Module
|
||||
ci->Shrink("os_info");
|
||||
}
|
||||
}
|
||||
|
||||
if (OSInfoDBName)
|
||||
delete [] OSInfoDBName;
|
||||
}
|
||||
|
||||
void OnReload(bool starting)
|
||||
{
|
||||
alog("os_info: Reloading configuration directives...");
|
||||
int ret = mLoadConfig();
|
||||
|
||||
if (ret)
|
||||
alog("os_info.c: ERROR: An error has occured while reloading the configuration file");
|
||||
}
|
||||
|
||||
void OnPostCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms)
|
||||
@@ -508,52 +478,6 @@ class OSInfo : public Module
|
||||
}
|
||||
}
|
||||
|
||||
void OnSaveDatabase()
|
||||
{
|
||||
ChannelInfo *ci = NULL;
|
||||
NickCore *nc = NULL;
|
||||
int i = 0;
|
||||
int ret = 0;
|
||||
FILE *out;
|
||||
|
||||
if (!(out = fopen(OSInfoDBName, "w")))
|
||||
{
|
||||
alog("os_info: ERROR: can not open the database file!");
|
||||
ircdproto->SendGlobops(findbot(Config.s_OperServ), "os_info: ERROR: can not open the database file!");
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < 1024; ++i)
|
||||
{
|
||||
for (nc = nclists[i]; nc; nc = nc->next)
|
||||
{
|
||||
/* If we have any info on this user */
|
||||
char *c;
|
||||
if (nc->GetExtArray("os_info", c))
|
||||
fprintf(out, "N %s %s\n", nc->display, c);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; ++i)
|
||||
{
|
||||
for (ci = chanlists[i]; ci; ci = ci->next)
|
||||
{
|
||||
/* If we have any info on this channel */
|
||||
char *c;
|
||||
if (ci->GetExtArray("os_info", c))
|
||||
fprintf(out, "C %s %s\n", ci->name, c);
|
||||
}
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
}
|
||||
|
||||
void OnBackupDatabase()
|
||||
{
|
||||
ModuleDatabaseBackup(OSInfoDBName);
|
||||
}
|
||||
|
||||
void OnNickServHelp(User *u)
|
||||
{
|
||||
this->NoticeLang(Config.s_NickServ, u, OINFO_HELP_CMD);
|
||||
@@ -563,91 +487,56 @@ class OSInfo : public Module
|
||||
{
|
||||
this->NoticeLang(Config.s_ChanServ, u, OCINFO_HELP_CMD);
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
/**
|
||||
* Load data from the db file, and populate our OperInfo lines
|
||||
* @return 0 for success
|
||||
**/
|
||||
int mLoadData()
|
||||
{
|
||||
int ret = 0;
|
||||
FILE *in;
|
||||
|
||||
char *type = NULL;
|
||||
char *name = NULL;
|
||||
char *info = NULL;
|
||||
int len = 0;
|
||||
|
||||
ChannelInfo *ci = NULL;
|
||||
NickAlias *na = NULL;
|
||||
|
||||
/* will _never_ be this big thanks to the 512 limit of a message */
|
||||
char buffer[2000];
|
||||
if (!(in = fopen(OSInfoDBName, "r")))
|
||||
void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), NickCore *nc)
|
||||
{
|
||||
alog("os_info: WARNING: can not open the database file! (it might not exist, this is not fatal)");
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (fgets(buffer, 1500, in))
|
||||
char *c;
|
||||
|
||||
if (nc->GetExtArray("os_info", c))
|
||||
{
|
||||
type = myStrGetToken(buffer, ' ', 0);
|
||||
name = myStrGetToken(buffer, ' ', 1);
|
||||
info = myStrGetTokenRemainder(buffer, ' ', 2);
|
||||
if (type)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
if (info)
|
||||
{
|
||||
len = strlen(info);
|
||||
/* Take the \n from the end of the line */
|
||||
info[len - 1] = '\0';
|
||||
if (!stricmp(type, "C"))
|
||||
{
|
||||
if ((ci = cs_findchan(name)))
|
||||
ci->Extend("os_info", new ExtensibleItemPointerArray<char>(sstrdup(info)));
|
||||
}
|
||||
else if (!stricmp(type, "N"))
|
||||
{
|
||||
if ((na = findnick(name)))
|
||||
na->nc->Extend("os_info", new ExtensibleItemPointerArray<char>(sstrdup(info)));
|
||||
}
|
||||
delete [] info;
|
||||
}
|
||||
delete [] name;
|
||||
}
|
||||
delete [] type;
|
||||
}
|
||||
std::string buf = ":";
|
||||
buf += c;
|
||||
WriteMetadata("OS_INFO", buf.c_str());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration directives from Services configuration file.
|
||||
* @return 0 for success
|
||||
**/
|
||||
int mLoadConfig()
|
||||
{
|
||||
ConfigReader config;
|
||||
std::string tmp = config.ReadValue("os_info", "database", DEFAULT_DB_NAME, 0);
|
||||
void OnDatabaseWriteMetadata(void (*WriteMetadata)(const std::string &, const std::string &), ChannelInfo *ci)
|
||||
{
|
||||
char *c;
|
||||
|
||||
if (OSInfoDBName)
|
||||
delete [] OSInfoDBName;
|
||||
if (ci->GetExtArray("os_info", c))
|
||||
{
|
||||
std::string buf = ":";
|
||||
buf += c;
|
||||
WriteMetadata("OS_INFO", buf.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
OSInfoDBName = sstrdup(tmp.c_str());
|
||||
EventReturn OnDatabaseReadMetadata(NickCore *nc, const std::string &key, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
if (key == "OS_INFO")
|
||||
{
|
||||
nc->Shrink("os_info");
|
||||
nc->Extend("os_info", new ExtensibleItemPointerArray<char>(sstrdup(params[0].c_str()))); /// We really should use std::string here...
|
||||
|
||||
alog("os_info: Directive OSInfoDBName loaded (%s)...", OSInfoDBName);
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
|
||||
EventReturn OnDatabaseReadMetadata(ChannelInfo *ci, const std::string &key, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
if (key == "OS_INFO")
|
||||
{
|
||||
ci->Shrink("os_info");
|
||||
ci->Extend("os_info", new ExtensibleItemPointerArray<char>(sstrdup(params[0].c_str())));
|
||||
|
||||
return EVENT_STOP;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
return EVENT_CONTINUE;
|
||||
}
|
||||
};
|
||||
|
||||
MODULE_INIT(OSInfo)
|
||||
|
||||
Reference in New Issue
Block a user