mirror of
https://github.com/anope/anope.git
synced 2026-06-26 03:46:39 +02:00
2000 lines
66 KiB
C
2000 lines
66 KiB
C
|
|
/* MySQL functions.
|
|
*
|
|
* (C) 2003-2012 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 "services.h"
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Database Global Variables */
|
|
MYSQL *mysql; /* MySQL Handler */
|
|
MYSQL_RES *mysql_res; /* MySQL Result */
|
|
MYSQL_FIELD *mysql_fields; /* MySQL Fields */
|
|
MYSQL_ROW mysql_row; /* MySQL Row */
|
|
|
|
int mysql_is_connected = 0; /* Are we currently connected? */
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Throw a mysql error into the logs. If severity is MYSQL_ERROR, we
|
|
* also exit Anope...
|
|
*/
|
|
void db_mysql_error(int severity, char *msg)
|
|
{
|
|
static char buf[512];
|
|
|
|
if (mysql_error(mysql)) {
|
|
snprintf(buf, sizeof(buf), "MySQL %s %s: %s", msg,
|
|
severity == MYSQL_WARNING ? "warning" : "error",
|
|
mysql_error(mysql));
|
|
} else {
|
|
snprintf(buf, sizeof(buf), "MySQL %s %s", msg,
|
|
severity == MYSQL_WARNING ? "warning" : "error");
|
|
}
|
|
|
|
log_perror(buf);
|
|
|
|
if (severity == MYSQL_ERROR) {
|
|
log_perror("MySQL FATAL error... aborting.");
|
|
exit(0);
|
|
}
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Initialize the MySQL code */
|
|
int db_mysql_init()
|
|
{
|
|
|
|
/* If the host is not defined, assume we don't want MySQL */
|
|
if (!MysqlHost) {
|
|
do_mysql = 0;
|
|
alog("MySQL: has been disabled.");
|
|
return 0;
|
|
} else {
|
|
do_mysql = 1;
|
|
alog("MySQL: has been enabled.");
|
|
alog("MySQL: client version %s.", mysql_get_client_info());
|
|
}
|
|
|
|
/* The following configuration options are required.
|
|
* If missing disable MySQL to avoid any problems.
|
|
*/
|
|
|
|
if ((do_mysql) && (!MysqlName || !MysqlUser)) {
|
|
do_mysql = 0;
|
|
alog("MySQL Error: Set all required configuration options.");
|
|
return 0;
|
|
}
|
|
|
|
if (!db_mysql_open()) {
|
|
do_mysql = 0;
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Open a connection to the mysql database. Return 0 on failure, or
|
|
* 1 on success. If this succeeds, we're guaranteed of a working
|
|
* mysql connection (unless something unexpected happens ofcourse...)
|
|
*/
|
|
int db_mysql_open()
|
|
{
|
|
/* If MySQL is disabled, return 0 */
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
/* If we are reported to be connected, ping MySQL to see if we really are
|
|
* still connected. (yes mysql_ping() returns 0 on success)
|
|
*/
|
|
if (mysql_is_connected && !mysql_ping(mysql))
|
|
return 1;
|
|
|
|
mysql_is_connected = 0;
|
|
|
|
mysql = mysql_init(NULL);
|
|
if (mysql == NULL) {
|
|
db_mysql_error(MYSQL_WARNING, "Unable to create mysql object");
|
|
return 0;
|
|
}
|
|
|
|
if (!MysqlPort)
|
|
MysqlPort = MYSQL_DEFAULT_PORT;
|
|
|
|
if (!mysql_real_connect(mysql, MysqlHost, MysqlUser, MysqlPass, MysqlName, MysqlPort, MysqlSock, 0)) {
|
|
log_perror("MySQL Error: Cant connect to MySQL: %s\n", mysql_error(mysql));
|
|
return 0;
|
|
}
|
|
|
|
mysql_is_connected = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Perform a MySQL query. Return 1 if the query succeeded and 0 if the
|
|
* query failed. Before returning failure, re-try the query a few times
|
|
* and die if it still fails.
|
|
*/
|
|
int db_mysql_query(char *sql)
|
|
{
|
|
int lcv;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
if (debug)
|
|
alog("debug: MySQL: %s", sql);
|
|
|
|
/* Try as many times as configured in MysqlRetries */
|
|
for (lcv = 0; lcv < MysqlRetries; lcv++) {
|
|
if (db_mysql_open() && (mysql_query(mysql, sql) == 0))
|
|
return 1;
|
|
|
|
/* If we get here, we could not run the query */
|
|
log_perror("Unable to run query: %s\n", mysql_error(mysql));
|
|
|
|
/* Wait for MysqlRetryGap seconds and try again */
|
|
sleep(MysqlRetryGap);
|
|
}
|
|
|
|
/* Unable to run the query even after MysqlRetries tries */
|
|
db_mysql_error(MYSQL_WARNING, "query");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Quote a string to be safely included in a query. The result of this
|
|
* function is allocated; it MUST be freed by the caller.
|
|
*/
|
|
char *db_mysql_quote(char *sql)
|
|
{
|
|
int slen;
|
|
char *quoted;
|
|
|
|
|
|
if (!sql)
|
|
return sstrdup("");
|
|
|
|
slen = strlen(sql);
|
|
quoted = malloc((1 + (slen * 2)) * sizeof(char));
|
|
|
|
mysql_real_escape_string(mysql, quoted, sql, slen);
|
|
|
|
return quoted;
|
|
|
|
}
|
|
|
|
/**
|
|
* Quote a buffer to be safely included in a query.
|
|
* The result is allocated and needs to be freed by caller.
|
|
**/
|
|
char *db_mysql_quote_buffer(char *sql, int size)
|
|
{
|
|
char *ret;
|
|
ret = scalloc((1 + 2 * size), sizeof(char));
|
|
|
|
mysql_real_escape_string(mysql, ret, sql, size);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Close the MySQL database connection. */
|
|
int db_mysql_close()
|
|
{
|
|
mysql_close(mysql);
|
|
|
|
mysql_is_connected = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Try to execute a query and issue a warning when failed. Return 1 on
|
|
* success and 0 on failure.
|
|
*/
|
|
int db_mysql_try(const char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
static char sql[MAX_SQL_BUF];
|
|
|
|
va_start(args, fmt);
|
|
vsnprintf(sql, MAX_SQL_BUF, fmt, args);
|
|
va_end(args);
|
|
|
|
if (!db_mysql_query(sql)) {
|
|
log_perror("Can't create sql query: %s", sql);
|
|
db_mysql_error(MYSQL_WARNING, "query");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/**
|
|
* Returns a string (buffer) to insert into a SQL query.
|
|
* The string will, once evaluated by MySQL, result in the given pass
|
|
* encoded in the encryption type selected for MysqlSecure
|
|
* The result of this function is an allocated MySQL safe string.
|
|
*
|
|
* @param pass The buffer containing the password to secure.
|
|
* @param size The size of the password-to-secure buffer.
|
|
* @return Returns a MySQL safe string containing the password, hash or SQL instruction to encrypt the password. Needs to be free'd.
|
|
**/
|
|
char *db_mysql_secure(char *pass, int size)
|
|
{
|
|
char tmp_pass[PASSMAX];
|
|
char *str, *tmp;
|
|
unsigned bufsize = (2 * PASSMAX + 15);
|
|
|
|
if (MysqlSecure)
|
|
bufsize += strlen(MysqlSecure);
|
|
|
|
/* Initialize the buffer. Bug #86 */
|
|
memset(tmp_pass, 0, PASSMAX);
|
|
|
|
/* Return all zeros if no pass is set. */
|
|
if (!pass)
|
|
return NULL;
|
|
|
|
str = scalloc(bufsize, sizeof(char));
|
|
if (enc_decrypt(pass, tmp_pass, PASSMAX - 1) != 1) {
|
|
/* We couldnt decrypt the pass... */
|
|
/* Make sure the hash is MySQL safe.. */
|
|
tmp = db_mysql_quote_buffer(pass, size);
|
|
snprintf(str, bufsize, "'%s'", tmp);
|
|
free(tmp);
|
|
} else { /* if we could decrypt the pass */
|
|
/* Make sure the pass itself pass is MySQL safe.. */
|
|
tmp = db_mysql_quote_buffer(tmp_pass, strlen(tmp_pass));
|
|
if ((!MysqlSecure) || (strcmp(MysqlSecure, "") == 0)) {
|
|
snprintf(str, bufsize, "'%s'", tmp);
|
|
} else if (strcmp(MysqlSecure, "des") == 0) {
|
|
snprintf(str, bufsize, "ENCRYPT('%s')", tmp);
|
|
} else if (strcmp(MysqlSecure, "md5") == 0) {
|
|
snprintf(str, bufsize, "MD5('%s')", tmp);
|
|
} else if (strcmp(MysqlSecure, "sha") == 0) {
|
|
snprintf(str, bufsize, "SHA('%s')", tmp);
|
|
} else {
|
|
snprintf(str, bufsize, "ENCODE('%s','%s')", tmp, MysqlSecure);
|
|
}
|
|
free(tmp);
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/*
|
|
* NickServ Specific Secion
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given NickRequest into the database
|
|
* Return 1 on success, 0 on failure
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_ns_request
|
|
*/
|
|
int db_mysql_save_ns_req(NickRequest * nr)
|
|
{
|
|
int ret;
|
|
char *q_nick, *q_passcode, *q_password, *q_email;
|
|
|
|
q_nick = db_mysql_quote(nr->nick);
|
|
q_passcode = db_mysql_quote(nr->passcode);
|
|
q_password = db_mysql_quote_buffer(nr->password, PASSMAX);
|
|
q_email = db_mysql_quote(nr->email);
|
|
|
|
ret = db_mysql_try("UPDATE anope_ns_request "
|
|
"SET passcode = '%s', password = '%s', email = '%s', requested = %d, active = 1 "
|
|
"WHERE nick = '%s'",
|
|
q_passcode, q_password, q_email, (int) nr->requested,
|
|
q_nick);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_ns_request "
|
|
"(nick, passcode, password, email, requested, active) "
|
|
"VALUES ('%s', '%s', '%s', '%s', %d, 1)",
|
|
q_nick, q_passcode, q_password, q_email,
|
|
(int) nr->requested);
|
|
}
|
|
|
|
free(q_nick);
|
|
free(q_passcode);
|
|
free(q_password);
|
|
free(q_email);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given NickCore into the database
|
|
* Also save the access list and memo's for this user
|
|
* Return 1 on success, 0 on failure
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_ns_core
|
|
* - anope_ns_alias
|
|
* - anope_ns_access
|
|
* - anope_ms_info (serv='NICK')
|
|
*/
|
|
int db_mysql_save_ns_core(NickCore * nc)
|
|
{
|
|
int ret;
|
|
int i;
|
|
char *q_display, *q_pass, *q_email, *q_greet, *q_url,
|
|
*q_access, *q_sender, *q_text;
|
|
|
|
q_display = db_mysql_quote(nc->display);
|
|
q_email = db_mysql_quote(nc->email);
|
|
q_greet = db_mysql_quote(nc->greet);
|
|
q_url = db_mysql_quote(nc->url);
|
|
|
|
/* First secure the pass, then make it MySQL safe.. - Viper */
|
|
q_pass = db_mysql_secure(nc->pass, PASSMAX);
|
|
if (!q_pass)
|
|
fatal("Unable to encrypt password for MySQL");
|
|
|
|
/* Let's take care of the core itself */
|
|
/* Update the existing records */
|
|
ret = db_mysql_try("UPDATE anope_ns_core "
|
|
"SET pass = %s, email = '%s', greet = '%s', icq = %d, url = '%s', flags = %d, language = %d, "
|
|
"accesscount = %d, memocount = %d, memomax = %d, channelcount = %d, channelmax = %d, active = 1 "
|
|
"WHERE display = '%s'",
|
|
q_pass, q_email, q_greet, nc->icq, q_url, nc->flags,
|
|
nc->language, nc->accesscount, nc->memos.memocount,
|
|
nc->memos.memomax, nc->channelcount, nc->channelmax,
|
|
q_display);
|
|
|
|
/* Our previous UPDATE affected no rows, therefore this is a new record */
|
|
if (ret && (mysql_affected_rows(mysql) == 0))
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_ns_core "
|
|
"(display, pass, email, greet, icq, url, flags, language, accesscount, memocount, memomax, channelcount, channelmax, active) "
|
|
"VALUES ('%s', %s, '%s', '%s', %d, '%s', %d, %d, %d, %d, %d, %d, %d, 1)",
|
|
q_display, q_pass, q_email, q_greet, nc->icq, q_url,
|
|
nc->flags, nc->language, nc->accesscount,
|
|
nc->memos.memocount, nc->memos.memomax,
|
|
nc->channelcount, nc->channelmax);
|
|
|
|
/* Now let's do the access */
|
|
for (i = 0; ret && (i < nc->accesscount); i++) {
|
|
q_access = db_mysql_quote(nc->access[i]);
|
|
/**
|
|
ret = db_mysql_try("UPDATE anope_ns_access "
|
|
"SET access = '%s' "
|
|
"WHERE display = '%s'",
|
|
q_access, q_display);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {**/
|
|
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_ns_access "
|
|
"(display, access) "
|
|
"VALUES ('%s','%s')",
|
|
q_display, q_access);
|
|
/* } */
|
|
|
|
free(q_access);
|
|
}
|
|
|
|
/* Memos */
|
|
for (i = 0; ret && (i < nc->memos.memocount); i++) {
|
|
q_sender = db_mysql_quote(nc->memos.memos[i].sender);
|
|
q_text = db_mysql_quote(nc->memos.memos[i].text);
|
|
|
|
if (nc->memos.memos[i].id != 0)
|
|
{
|
|
ret = db_mysql_try("UPDATE anope_ms_info "
|
|
"SET receiver = '%s', number = %d, flags = %d, time = %d, sender = '%s', text = '%s', active = 1 "
|
|
"WHERE nm_id = %d AND serv = 'NICK'",
|
|
q_display, nc->memos.memos[i].number,
|
|
nc->memos.memos[i].flags,
|
|
(int) nc->memos.memos[i].time, q_sender, q_text,
|
|
nc->memos.memos[i].id);
|
|
}
|
|
if (nc->memos.memos[i].id == 0 || (ret && (mysql_affected_rows(mysql) == 0))) {
|
|
ret = db_mysql_try("INSERT INTO anope_ms_info "
|
|
"(receiver, number, flags, time, sender, text, serv, active) "
|
|
"VALUES ('%s', %d, %d, %d, '%s', '%s', 'NICK', 1)",
|
|
q_display, nc->memos.memos[i].number,
|
|
nc->memos.memos[i].flags,
|
|
(int) nc->memos.memos[i].time, q_sender,
|
|
q_text);
|
|
|
|
/* This is to make sure we can UPDATE memos instead of TRUNCATE
|
|
* the table each time and then INSERT them all again. Ideally
|
|
* everything in core would have it's dbase-id stored, but that's
|
|
* something for phase 3. -GD
|
|
*/
|
|
if (ret)
|
|
nc->memos.memos[i].id = mysql_insert_id(mysql);
|
|
}
|
|
|
|
free(q_sender);
|
|
free(q_text);
|
|
}
|
|
|
|
free(q_display);
|
|
free(q_pass);
|
|
free(q_email);
|
|
free(q_greet);
|
|
free(q_url);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given NickAlias into the database
|
|
* Return 1 on success, 0 on failure
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_ns_core
|
|
* - anope_ns_alias
|
|
* - anope_ns_access
|
|
* - anope_ms_info (serv='NICK')
|
|
*/
|
|
int db_mysql_save_ns_alias(NickAlias * na)
|
|
{
|
|
int ret;
|
|
char *q_nick, *q_lastmask, *q_lastrname, *q_lastquit, *q_display;
|
|
|
|
q_nick = db_mysql_quote(na->nick);
|
|
q_lastmask = db_mysql_quote(na->last_usermask);
|
|
q_lastrname = db_mysql_quote(na->last_realname);
|
|
q_lastquit = db_mysql_quote(na->last_quit);
|
|
q_display = db_mysql_quote(na->nc->display);
|
|
|
|
ret = db_mysql_try("UPDATE anope_ns_alias "
|
|
"SET last_usermask = '%s', last_realname = '%s', last_quit = '%s', time_registered = %d, last_seen = %d, status = %d, "
|
|
" display = '%s', active = 1 "
|
|
"WHERE nick = '%s'",
|
|
q_lastmask, q_lastrname, q_lastquit,
|
|
(int) na->time_registered, (int) na->last_seen,
|
|
(int) na->status, q_display, q_nick);
|
|
|
|
/* Our previous UPDATE affected no rows, therefore this is a new record */
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_ns_alias "
|
|
"(nick, last_usermask, last_realname, last_quit, time_registered, last_seen, status, display, active) "
|
|
"VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, '%s', 1)",
|
|
q_nick, q_lastmask, q_lastrname, q_lastquit,
|
|
(int) na->time_registered, (int) na->last_seen,
|
|
(int) na->status, q_display);
|
|
}
|
|
|
|
free(q_nick);
|
|
free(q_lastmask);
|
|
free(q_lastrname);
|
|
free(q_lastquit);
|
|
free(q_display);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/*
|
|
* ChanServ Specific Secion
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given ChannelInfo into the database
|
|
* Also save the access list, levels, akicks, badwords, ttb, and memo's for this channel
|
|
* Return 1 on success, 0 on failure
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_cs_info
|
|
* - anope_cs_access
|
|
* - anope_cs_levels
|
|
* - anope_cs_akicks
|
|
* - anope_cs_badwords
|
|
* - anope_cs_ttb
|
|
* - anope_ms_info (serv='CHAN')
|
|
*/
|
|
int db_mysql_save_cs_info(ChannelInfo * ci)
|
|
{
|
|
int ret, i;
|
|
char *q_name;
|
|
char *q_founder;
|
|
char *q_successor;
|
|
char *q_pass;
|
|
char *q_desc;
|
|
char *q_url;
|
|
char *q_email;
|
|
char *q_lasttopic;
|
|
char *q_lasttopicsetter;
|
|
char *q_forbidby;
|
|
char *q_forbidreason;
|
|
char *q_mlock_key;
|
|
char *q_mlock_flood;
|
|
char *q_mlock_redirect;
|
|
char *q_entrymsg;
|
|
char *q_botnick;
|
|
char *q_sender;
|
|
char *q_text;
|
|
char *q_accessdisp;
|
|
char *q_akickdisp;
|
|
char *q_akickreason;
|
|
char *q_akickcreator;
|
|
char *q_badwords;
|
|
|
|
q_name = db_mysql_quote(ci->name);
|
|
if (ci->founder) {
|
|
q_founder = db_mysql_quote(ci->founder->display);
|
|
} else {
|
|
q_founder = db_mysql_quote("");
|
|
}
|
|
if (ci->successor) {
|
|
q_successor = db_mysql_quote(ci->successor->display);
|
|
} else {
|
|
q_successor = db_mysql_quote("");
|
|
}
|
|
q_desc = db_mysql_quote(ci->desc);
|
|
q_url = db_mysql_quote(ci->url);
|
|
q_email = db_mysql_quote(ci->email);
|
|
q_lasttopic = db_mysql_quote(ci->last_topic);
|
|
q_lasttopicsetter = db_mysql_quote(ci->last_topic_setter);
|
|
q_forbidby = db_mysql_quote(ci->forbidby);
|
|
q_forbidreason = db_mysql_quote(ci->forbidreason);
|
|
q_mlock_key = db_mysql_quote(ci->mlock_key);
|
|
q_mlock_flood = db_mysql_quote(ci->mlock_flood);
|
|
q_mlock_redirect = db_mysql_quote(ci->mlock_redirect);
|
|
q_entrymsg = db_mysql_quote(ci->entry_message);
|
|
if (ci->bi) {
|
|
q_botnick = db_mysql_quote(ci->bi->nick);
|
|
} else {
|
|
q_botnick = db_mysql_quote("");
|
|
}
|
|
|
|
/* First secure the pass, then make it MySQL safe.. - Viper */
|
|
q_pass = db_mysql_secure(ci->founderpass, PASSMAX);
|
|
if (!q_pass)
|
|
fatal("Unable to encrypt password for MySQL");
|
|
|
|
/* Let's take care of the core itself */
|
|
ret = db_mysql_try("UPDATE anope_cs_info "
|
|
"SET founder = '%s', successor = '%s', founderpass = %s, descr = '%s', url = '%s', email = '%s', time_registered = %d, "
|
|
" last_used = %d, last_topic = '%s', last_topic_setter = '%s', last_topic_time = %d, flags = %d, forbidby = '%s', "
|
|
" forbidreason = '%s', bantype = %d, accesscount = %d, akickcount = %d, mlock_on = %d, mlock_off = %d, mlock_limit = %d, "
|
|
" mlock_key = '%s', mlock_flood = '%s', mlock_redirect = '%s', entry_message = '%s', memomax = %d, botnick = '%s', botflags = %d, "
|
|
" bwcount = %d, capsmin = %d, capspercent = %d, floodlines = %d, floodsecs = %d, repeattimes = %d, active = 1 "
|
|
"WHERE name = '%s'",
|
|
q_founder, q_successor, q_pass, q_desc, q_url, q_email,
|
|
(int) ci->time_registered, (int) ci->last_used,
|
|
q_lasttopic, q_lasttopicsetter,
|
|
(int) ci->last_topic_time, (int) ci->flags, q_forbidby,
|
|
q_forbidreason, (int) ci->bantype,
|
|
(int) ci->accesscount, (int) ci->akickcount,
|
|
(int) ci->mlock_on, (int) ci->mlock_off,
|
|
(int) ci->mlock_limit, q_mlock_key, q_mlock_flood,
|
|
q_mlock_redirect, q_entrymsg, (int) ci->memos.memomax,
|
|
q_botnick, (int) ci->botflags, (int) ci->bwcount,
|
|
(int) ci->capsmin, (int) ci->capspercent,
|
|
(int) ci->floodlines, (int) ci->floodsecs,
|
|
(int) ci->repeattimes, q_name);
|
|
|
|
/* Our previous UPDATE affected no rows, therefore this is a new record */
|
|
if (ret && (mysql_affected_rows(mysql) == 0))
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_info "
|
|
"(name, founder, successor, founderpass, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, "
|
|
" last_topic_time, flags, forbidby, forbidreason, bantype, accesscount, akickcount, mlock_on, mlock_off, mlock_limit, "
|
|
" mlock_key, mlock_flood, mlock_redirect, entry_message, botnick, botflags, bwcount, capsmin, capspercent, floodlines, "
|
|
" floodsecs, repeattimes, active) "
|
|
"VALUES ('%s', '%s', '%s', %s, '%s', '%s', '%s', %d, %d, '%s', '%s', %d, %d, '%s', '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', "
|
|
" '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d, 1)",
|
|
q_name, q_founder, q_successor, q_pass, q_desc,
|
|
q_url, q_email, (int) ci->time_registered,
|
|
(int) ci->last_used, q_lasttopic,
|
|
q_lasttopicsetter, (int) ci->last_topic_time,
|
|
(int) ci->flags, q_forbidby, q_forbidreason,
|
|
(int) ci->bantype, (int) ci->accesscount,
|
|
(int) ci->akickcount, (int) ci->mlock_on,
|
|
(int) ci->mlock_off, (int) ci->mlock_limit,
|
|
q_mlock_key, q_mlock_flood, q_mlock_redirect,
|
|
q_entrymsg, q_botnick, (int) ci->botflags,
|
|
(int) ci->bwcount, (int) ci->capsmin,
|
|
(int) ci->capspercent, (int) ci->floodlines,
|
|
(int) ci->floodsecs, (int) ci->repeattimes);
|
|
|
|
/* Memos */
|
|
for (i = 0; ret && (i < ci->memos.memocount); i++) {
|
|
q_sender = db_mysql_quote(ci->memos.memos[i].sender);
|
|
q_text = db_mysql_quote(ci->memos.memos[i].text);
|
|
|
|
if (ci->memos.memos[i].id != 0)
|
|
{
|
|
ret = db_mysql_try("UPDATE anope_ms_info "
|
|
"SET receiver = '%s', number = %d, flags = %d, time = %d, sender = '%s', text = '%s', active = 1 "
|
|
"WHERE nm_id = %d AND serv = 'CHAN'",
|
|
q_name, ci->memos.memos[i].number,
|
|
ci->memos.memos[i].flags,
|
|
(int) ci->memos.memos[i].time, q_sender, q_text,
|
|
ci->memos.memos[i].id);
|
|
}
|
|
if (ci->memos.memos[i].id == 0 || (ret && (mysql_affected_rows(mysql) == 0))) {
|
|
ret = db_mysql_try("INSERT INTO anope_ms_info "
|
|
"(receiver, number,flags, time, sender, text, serv, active) "
|
|
"VALUES ('%s', %d, %d, %d, '%s', '%s', 'CHAN', 1)",
|
|
q_name, ci->memos.memos[i].number,
|
|
ci->memos.memos[i].flags,
|
|
(int) ci->memos.memos[i].time, q_sender,
|
|
q_text);
|
|
|
|
/* See comment at db_mysql_save_ns_core */
|
|
if (ret)
|
|
ci->memos.memos[i].id = mysql_insert_id(mysql);
|
|
}
|
|
|
|
free(q_sender);
|
|
free(q_text);
|
|
}
|
|
|
|
/* Access */
|
|
for (i = 0; ret && (i < ci->accesscount); i++) {
|
|
if (ci->access[i].in_use) {
|
|
q_accessdisp = db_mysql_quote(ci->access[i].nc->display);
|
|
|
|
ret = db_mysql_try("UPDATE anope_cs_access "
|
|
"SET in_use = %d, level = %d, last_seen = %d, active = 1 "
|
|
"WHERE channel = '%s' AND display = '%s'",
|
|
(int) ci->access[i].in_use,
|
|
(int) ci->access[i].level,
|
|
(int) ci->access[i].last_seen,
|
|
q_name, q_accessdisp);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_access "
|
|
"(channel, display, in_use, level, last_seen, active) "
|
|
"VALUES ('%s', '%s', %d, %d, %d, 1)",
|
|
q_name, q_accessdisp,
|
|
(int) ci->access[i].in_use,
|
|
(int) ci->access[i].level,
|
|
(int) ci->access[i].last_seen);
|
|
}
|
|
|
|
free(q_accessdisp);
|
|
}
|
|
}
|
|
|
|
/* Levels */
|
|
for (i = 0; ret && (i < CA_SIZE); i++) {
|
|
ret = db_mysql_try("UPDATE anope_cs_levels "
|
|
"SET level = %d, active = 1 "
|
|
"WHERE channel = '%s' AND position = %d",
|
|
(int) ci->levels[i], q_name, i);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_levels "
|
|
"(channel, position, level, active) "
|
|
"VALUES ('%s', %d, %d, 1)",
|
|
q_name, i, (int) ci->levels[i]);
|
|
}
|
|
}
|
|
|
|
/* Akicks */
|
|
for (i = 0; ret && (i < ci->akickcount); i++) {
|
|
if (ci->akick[i].flags & AK_USED) {
|
|
if (ci->akick[i].flags & AK_ISNICK)
|
|
q_akickdisp = db_mysql_quote(ci->akick[i].u.nc->display);
|
|
else
|
|
q_akickdisp = db_mysql_quote(ci->akick[i].u.mask);
|
|
|
|
q_akickreason = db_mysql_quote(ci->akick[i].reason);
|
|
q_akickcreator = db_mysql_quote(ci->akick[i].creator);
|
|
} else {
|
|
q_akickdisp = "";
|
|
q_akickreason = "";
|
|
q_akickcreator = "";
|
|
}
|
|
|
|
ret = db_mysql_try("UPDATE anope_cs_akicks "
|
|
"SET flags = %d, reason = '%s', creator = '%s', addtime = %d, active = 1 "
|
|
"WHERE channel = '%s' AND dmask = '%s'",
|
|
(int) ci->akick[i].flags, q_akickreason,
|
|
q_akickcreator, (ci->akick[i].flags & AK_USED ?
|
|
(int) ci->akick[i].addtime : 0),
|
|
q_name, q_akickdisp);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_akicks "
|
|
"(channel, dmask, flags, reason, creator, addtime, active) "
|
|
"VALUES ('%s', '%s', %d, '%s', '%s', %d, 1)",
|
|
q_name, q_akickdisp, (int) ci->akick[i].flags,
|
|
q_akickreason, q_akickcreator,
|
|
(ci->akick[i].flags & AK_USED ?
|
|
(int) ci->akick[i].addtime : 0));
|
|
}
|
|
|
|
if (ci->akick[i].flags & AK_USED) {
|
|
free(q_akickdisp);
|
|
free(q_akickreason);
|
|
free(q_akickcreator);
|
|
}
|
|
}
|
|
|
|
/* Bad Words */
|
|
for (i = 0; ret && (i < ci->bwcount); i++) {
|
|
if (ci->badwords[i].in_use) {
|
|
q_badwords = db_mysql_quote(ci->badwords[i].word);
|
|
|
|
ret = db_mysql_try("UPDATE anope_cs_badwords "
|
|
"SET type = %d, active = 1 "
|
|
"WHERE channel = '%s' AND word = '%s'",
|
|
(int) ci->badwords[i].type, q_name,
|
|
q_badwords);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_badwords "
|
|
"(channel, word, type, active) "
|
|
"VALUES ('%s', '%s', %d, 1)",
|
|
q_name, q_badwords,
|
|
(int) ci->badwords[i].type);
|
|
}
|
|
|
|
free(q_badwords);
|
|
}
|
|
}
|
|
|
|
/* TTB's */
|
|
for (i = 0; ret && (i < TTB_SIZE); i++) {
|
|
ret = db_mysql_try("UPDATE anope_cs_ttb "
|
|
"SET value = %d, active = 1 "
|
|
"WHERE channel = '%s' AND ttb_id = %d",
|
|
ci->ttb[i], q_name, i);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_cs_ttb "
|
|
"(channel, ttb_id, value, active) "
|
|
"VALUES ('%s', %d, %d, 1)",
|
|
q_name, i, ci->ttb[i]);
|
|
}
|
|
}
|
|
|
|
free(q_name);
|
|
free(q_founder);
|
|
free(q_successor);
|
|
free(q_pass);
|
|
free(q_desc);
|
|
free(q_url);
|
|
free(q_email);
|
|
free(q_lasttopic);
|
|
free(q_lasttopicsetter);
|
|
free(q_mlock_key);
|
|
free(q_mlock_flood);
|
|
free(q_mlock_redirect);
|
|
free(q_entrymsg);
|
|
free(q_botnick);
|
|
free(q_forbidby);
|
|
free(q_forbidreason);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
/*
|
|
* OperServ Specific Section
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the OperServ database into MySQL
|
|
* Return 1 on success, 0 on failure
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_os_akills
|
|
* - anope_os_sglines
|
|
* - anope_os_sqlines
|
|
* - anope_os_szlines
|
|
* These tables are emptied:
|
|
* - anope_os_core
|
|
*/
|
|
|
|
int db_mysql_save_os_db(unsigned int maxucnt, unsigned int maxutime,
|
|
SList * ak, SList * sgl, SList * sql, SList * szl)
|
|
{
|
|
int ret;
|
|
int i;
|
|
Akill *akl;
|
|
SXLine *sl;
|
|
char *q_user;
|
|
char *q_host;
|
|
char *q_mask;
|
|
char *q_by;
|
|
char *q_reason;
|
|
|
|
|
|
/* First save the core info */
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_core "
|
|
"(maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count) "
|
|
"VALUES (%d, %d, %d, %d, %d, %d)",
|
|
maxucnt, maxutime, ak->count, sgl->count, sql->count,
|
|
szl->count);
|
|
|
|
/* Next save all AKILLs */
|
|
for (i = 0; ret && (i < ak->count); i++) {
|
|
akl = ak->list[i];
|
|
q_user = db_mysql_quote(akl->user);
|
|
q_host = db_mysql_quote(akl->host);
|
|
q_by = db_mysql_quote(akl->by);
|
|
q_reason = db_mysql_quote(akl->reason);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_akills "
|
|
"SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
|
|
"WHERE user = '%s' AND host = '%s'",
|
|
q_by, q_reason, (int) akl->seton,
|
|
(int) akl->expires, q_user, q_host);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_akills "
|
|
"(user, host, xby, reason, seton, expire, active) "
|
|
"VALUES ('%s', '%s', '%s', '%s', %d, %d, 1)",
|
|
q_user, q_host, q_by, q_reason,
|
|
(int) akl->seton, (int) akl->expires);
|
|
}
|
|
|
|
free(q_user);
|
|
free(q_host);
|
|
free(q_by);
|
|
free(q_reason);
|
|
}
|
|
|
|
/* Time to save the SGLINEs */
|
|
for (i = 0; ret && (i < sgl->count); i++) {
|
|
sl = sgl->list[i];
|
|
q_mask = db_mysql_quote(sl->mask);
|
|
q_by = db_mysql_quote(sl->by);
|
|
q_reason = db_mysql_quote(sl->reason);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_sglines "
|
|
"SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
|
|
"WHERE mask = '%s'",
|
|
q_by, q_reason, (int) sl->seton, (int) sl->expires,
|
|
q_mask);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_sglines "
|
|
"(mask, xby, reason, seton, expire, active) "
|
|
"VALUES ('%s', '%s', '%s', %d, %d, 1)",
|
|
q_mask, q_by, q_reason, (int) sl->seton,
|
|
(int) sl->expires);
|
|
}
|
|
|
|
free(q_mask);
|
|
free(q_by);
|
|
free(q_reason);
|
|
}
|
|
|
|
/* Save the SQLINEs */
|
|
for (i = 0; ret && (i < sql->count); i++) {
|
|
sl = sql->list[i];
|
|
|
|
q_mask = db_mysql_quote(sl->mask);
|
|
q_by = db_mysql_quote(sl->by);
|
|
q_reason = db_mysql_quote(sl->reason);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_sqlines "
|
|
"SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
|
|
"WHERE mask = '%s'",
|
|
q_by, q_reason, (int) sl->seton, (int) sl->expires,
|
|
q_mask);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_sqlines "
|
|
"(mask, xby, reason, seton, expire, active) "
|
|
"VALUES ('%s', '%s', '%s', %d, %d, 1)",
|
|
q_mask, q_by, q_reason, (int) sl->seton,
|
|
(int) sl->expires);
|
|
}
|
|
|
|
free(q_mask);
|
|
free(q_by);
|
|
free(q_reason);
|
|
}
|
|
|
|
/* Now save the SZLINEs */
|
|
for (i = 0; ret && (i < szl->count); i++) {
|
|
sl = szl->list[i];
|
|
|
|
q_mask = db_mysql_quote(sl->mask);
|
|
q_by = db_mysql_quote(sl->by);
|
|
q_reason = db_mysql_quote(sl->reason);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_szlines "
|
|
"SET xby = '%s', reason = '%s', seton = %d, expire = %d, active = 1 "
|
|
"WHERE mask = '%s'",
|
|
q_by, q_reason, (int) sl->seton, (int) sl->expires,
|
|
q_mask);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_szlines "
|
|
"(mask, xby, reason, seton, expire, active) "
|
|
"VALUES ('%s', '%s', '%s', %d, %d, 1)",
|
|
q_mask, q_by, q_reason, (int) sl->seton,
|
|
(int) sl->expires);
|
|
}
|
|
|
|
free(q_mask);
|
|
free(q_by);
|
|
free(q_reason);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given NewsItem
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_os_news
|
|
*/
|
|
int db_mysql_save_news(NewsItem * ni)
|
|
{
|
|
int ret;
|
|
char *q_text;
|
|
char *q_who;
|
|
|
|
q_text = db_mysql_quote(ni->text);
|
|
q_who = db_mysql_quote(ni->who);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_news "
|
|
"SET ntext = '%s', who = '%s', active = 1 "
|
|
"WHERE type = %d AND num = %d AND `time` = %d",
|
|
q_text, q_who, ni->type, ni->num, (int) ni->time);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_news "
|
|
"(type, num, ntext, who, `time`, active) "
|
|
"VALUES (%d, %d, '%s', '%s', %d, 1)",
|
|
ni->type, ni->num, q_text, q_who, (int) ni->time);
|
|
}
|
|
|
|
free(q_text);
|
|
free(q_who);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given Exception
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_os_exceptions
|
|
*/
|
|
|
|
int db_mysql_save_exceptions(Exception * e)
|
|
{
|
|
int ret;
|
|
char *q_mask;
|
|
char *q_who;
|
|
char *q_reason;
|
|
|
|
q_mask = db_mysql_quote(e->mask);
|
|
q_who = db_mysql_quote(e->who);
|
|
q_reason = db_mysql_quote(e->reason);
|
|
|
|
ret = db_mysql_try("UPDATE anope_os_exceptions "
|
|
"SET lim = %d, who = '%s', reason = '%s', `time` = %d, expires = %d, active = 1 "
|
|
"WHERE mask = '%s'",
|
|
e->limit, q_who, q_reason, (int) e->time,
|
|
(int) e->expires, q_mask);
|
|
|
|
if (ret && (mysql_affected_rows(mysql)) == 0) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_os_exceptions "
|
|
"(mask, lim, who, reason, `time`, expires, active) "
|
|
"VALUES ('%s', %d, '%s', '%s', %d, %d, 1)",
|
|
q_mask, e->limit, q_who, q_reason, (int) e->time,
|
|
(int) e->expires);
|
|
}
|
|
|
|
free(q_mask);
|
|
free(q_who);
|
|
free(q_reason);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
/*
|
|
* HostServ Specific Section
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
|
|
/* Save the given HostCore
|
|
* These tables are tagged and will be cleaned:
|
|
* - anope_hs_core
|
|
*/
|
|
|
|
int db_mysql_save_hs_core(HostCore * hc)
|
|
{
|
|
int ret;
|
|
char *q_nick;
|
|
char *q_ident;
|
|
char *q_host;
|
|
char *q_creator;
|
|
|
|
q_nick = db_mysql_quote(hc->nick);
|
|
q_ident = db_mysql_quote(hc->vIdent);
|
|
q_host = db_mysql_quote(hc->vHost);
|
|
q_creator = db_mysql_quote(hc->creator);
|
|
|
|
ret = db_mysql_try("UPDATE anope_hs_core "
|
|
"SET vident = '%s', vhost = '%s', creator = '%s', `time` = %d, active = 1 "
|
|
"WHERE nick = '%s'",
|
|
q_ident, q_host, q_creator, (int) hc->time, q_nick);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_hs_core "
|
|
"(nick, vident, vhost, creator, `time`, active) "
|
|
"VALUES ('%s', '%s', '%s', '%s', %d, 1)",
|
|
q_nick, q_ident, q_host, q_creator,
|
|
(int) hc->time);
|
|
}
|
|
|
|
free(q_nick);
|
|
free(q_ident);
|
|
free(q_host);
|
|
free(q_creator);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/*
|
|
* BotServ Specific Section
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
|
|
int db_mysql_save_bs_core(BotInfo * bi)
|
|
{
|
|
int ret;
|
|
char *q_nick;
|
|
char *q_user;
|
|
char *q_host;
|
|
char *q_real;
|
|
|
|
q_nick = db_mysql_quote(bi->nick);
|
|
q_user = db_mysql_quote(bi->user);
|
|
q_host = db_mysql_quote(bi->host);
|
|
q_real = db_mysql_quote(bi->real);
|
|
|
|
ret = db_mysql_try("UPDATE anope_bs_core "
|
|
"SET user = '%s', host = '%s', rname = '%s', flags = %d, created = %d, chancount = %d, active = 1 "
|
|
"WHERE nick = '%s'",
|
|
q_user, q_host, q_real, bi->flags, (int) bi->created,
|
|
bi->chancount, q_nick);
|
|
|
|
if (ret && (mysql_affected_rows(mysql) == 0)) {
|
|
ret = db_mysql_try("INSERT DELAYED INTO anope_bs_core "
|
|
"(nick, user, host, rname, flags, created, chancount, active) "
|
|
"VALUES ('%s', '%s', '%s', '%s', %d, %d, %d, 1)",
|
|
q_nick, q_user, q_host, q_real, bi->flags,
|
|
(int) bi->created, bi->chancount);
|
|
}
|
|
|
|
free(q_nick);
|
|
free(q_user);
|
|
free(q_host);
|
|
free(q_real);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
|
|
/* Some loading code! */
|
|
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
|
|
int db_mysql_load_bs_dbase(void)
|
|
{
|
|
int ret;
|
|
BotInfo *bi;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT nick, user, host, rname, flags, created, chancount "
|
|
"FROM anope_bs_core "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
bi = makebot(mysql_row[0]);
|
|
bi->user = sstrdup(mysql_row[1]);
|
|
bi->host = sstrdup(mysql_row[2]);
|
|
bi->real = sstrdup(mysql_row[3]);
|
|
bi->flags = strtol(mysql_row[4], (char **) NULL, 10);
|
|
bi->created = strtol(mysql_row[5], (char **) NULL, 10);
|
|
bi->chancount = strtol(mysql_row[6], (char **) NULL, 10);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int db_mysql_load_hs_dbase(void)
|
|
{
|
|
int ret;
|
|
char *vident = NULL;
|
|
int32 time;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT nick, vident, vhost, creator, `time` "
|
|
"FROM anope_hs_core "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res)))
|
|
{
|
|
/* FIX: we can never allow an empty vident, it must *always* be NULL. */
|
|
vident = mysql_row[1];
|
|
if (!strcmp(vident, ""))
|
|
{
|
|
vident = NULL;
|
|
}
|
|
|
|
time = strtol(mysql_row[4], (char **) NULL, 10);
|
|
addHostCore(mysql_row[0], NULL, mysql_row[2], mysql_row[3], time);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int db_mysql_load_news(void)
|
|
{
|
|
int ret;
|
|
int i;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT type, num, ntext, who, `time` "
|
|
"FROM anope_os_news "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_store_result(mysql);
|
|
|
|
nnews = mysql_num_rows(mysql_res);
|
|
if (nnews < 8) /* 2^3 */
|
|
news_size = 16; /* 2^4 */
|
|
else if (nnews >= 16384) /* 2^14 */
|
|
news_size = 32767; /* 2^15 - 1 */
|
|
else
|
|
news_size = 2 * nnews;
|
|
|
|
news = scalloc(news_size, sizeof(*news));
|
|
|
|
i = 0;
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
news[i].type = strtol(mysql_row[0], (char **) NULL, 10);
|
|
news[i].num = strtol(mysql_row[1], (char **) NULL, 10);
|
|
news[i].text = sstrdup(mysql_row[2]);
|
|
snprintf(news[i].who, NICKMAX, "%s", mysql_row[3]);
|
|
news[i].time = strtol(mysql_row[4], (char **) NULL, 10);
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int db_mysql_load_exceptions(void)
|
|
{
|
|
int ret;
|
|
int i;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT mask, lim, who, reason, `time`, expires "
|
|
"FROM anope_os_exceptions "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_store_result(mysql);
|
|
nexceptions = mysql_num_rows(mysql_res);
|
|
exceptions = scalloc(nexceptions, sizeof(Exception));
|
|
|
|
i = 0;
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
exceptions[i].mask = sstrdup(mysql_row[0]);
|
|
exceptions[i].limit = strtol(mysql_row[1], (char **) NULL, 10);
|
|
snprintf(exceptions[i].who, NICKMAX, "%s", mysql_row[2]);
|
|
exceptions[i].reason = sstrdup(mysql_row[3]);
|
|
exceptions[i].time = strtol(mysql_row[4], (char **) NULL, 10);
|
|
exceptions[i].expires = strtol(mysql_row[5], (char **) NULL, 10);
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int db_mysql_load_os_dbase(void)
|
|
{
|
|
int ret;
|
|
Akill *ak;
|
|
SXLine *sl;
|
|
int akc, sglc, sqlc, szlc;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT maxusercnt, maxusertime, akills_count, sglines_count, sqlines_count, szlines_count "
|
|
"FROM anope_os_core");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
|
|
if ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
maxusercnt = strtol(mysql_row[0], (char **) NULL, 10);
|
|
maxusertime = strtol(mysql_row[1], (char **) NULL, 10);
|
|
/* I'm not too happy with the idea of storing thse counts in a field
|
|
* instead of just using mysql_num_rows on the actual tables when
|
|
* filling the data. For now this will do, but it's bound to give
|
|
* problems sooner or later... (it probably does if you are looking
|
|
* at this) -GD
|
|
*/
|
|
akc = strtol(mysql_row[2], (char **) NULL, 10);
|
|
sglc = strtol(mysql_row[3], (char **) NULL, 10);
|
|
sqlc = strtol(mysql_row[4], (char **) NULL, 10);
|
|
szlc = strtol(mysql_row[5], (char **) NULL, 10);
|
|
} else {
|
|
maxusercnt = 0;
|
|
maxusertime = time(NULL);
|
|
akc = 0;
|
|
sglc = 0;
|
|
sqlc = 0;
|
|
szlc = 0;
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
|
|
/* Load the AKILLs */
|
|
|
|
ret = db_mysql_try("SELECT user, host, xby, reason, seton, expire "
|
|
"FROM anope_os_akills "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
slist_setcapacity(&akills, akc);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
ak = scalloc(1, sizeof(Akill));
|
|
ak->user = sstrdup(mysql_row[0]);
|
|
ak->host = sstrdup(mysql_row[1]);
|
|
ak->by = sstrdup(mysql_row[2]);
|
|
ak->reason = sstrdup(mysql_row[3]);
|
|
ak->seton = strtol(mysql_row[4], (char **) NULL, 10);
|
|
ak->expires = strtol(mysql_row[5], (char **) NULL, 10);
|
|
slist_add(&akills, ak);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
|
|
/* Load the SGLINEs */
|
|
|
|
ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
|
|
"FROM anope_os_sglines "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
slist_setcapacity(&sglines, sglc);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
sl = scalloc(1, sizeof(SXLine));
|
|
sl->mask = sstrdup(mysql_row[0]);
|
|
sl->by = sstrdup(mysql_row[1]);
|
|
sl->reason = sstrdup(mysql_row[2]);
|
|
sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
|
|
sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
|
|
slist_add(&sglines, sl);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
|
|
/* Load the SQLINEs */
|
|
|
|
ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
|
|
"FROM anope_os_sqlines "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
slist_setcapacity(&sqlines, sqlc);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
sl = scalloc(1, sizeof(SXLine));
|
|
sl->mask = sstrdup(mysql_row[0]);
|
|
sl->by = sstrdup(mysql_row[1]);
|
|
sl->reason = sstrdup(mysql_row[2]);
|
|
sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
|
|
sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
|
|
slist_add(&sqlines, sl);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
|
|
/* Load the SZLINEs */
|
|
|
|
ret = db_mysql_try("SELECT mask, xby, reason, seton, expire "
|
|
"FROM anope_os_szlines "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
slist_setcapacity(&szlines, szlc);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
sl = scalloc(1, sizeof(SXLine));
|
|
sl->mask = sstrdup(mysql_row[0]);
|
|
sl->by = sstrdup(mysql_row[1]);
|
|
sl->reason = sstrdup(mysql_row[2]);
|
|
sl->seton = strtol(mysql_row[3], (char **) NULL, 10);
|
|
sl->expires = strtol(mysql_row[4], (char **) NULL, 10);
|
|
slist_add(&szlines, sl);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int db_mysql_load_cs_dbase(void)
|
|
{
|
|
int ret;
|
|
char *q_name;
|
|
ChannelInfo *ci;
|
|
int i;
|
|
MYSQL_RES *res;
|
|
MYSQL_ROW row;
|
|
unsigned long *lengths;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT name, founder, successor, founderpass, descr, url, email, time_registered, last_used, last_topic, last_topic_setter, "
|
|
" last_topic_time, flags, forbidby, forbidreason, bantype, accesscount, akickcount, mlock_on, mlock_off, mlock_limit, "
|
|
" mlock_key, mlock_flood, mlock_redirect, entry_message, memomax, botnick, botflags, bwcount, capsmin, capspercent, floodlines, "
|
|
" floodsecs, repeattimes "
|
|
"FROM anope_cs_info "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
/* I'd really like to use mysql_use_result here, but it'd tie up with
|
|
* all the queries being run inside each iteration... -GD
|
|
*/
|
|
mysql_res = mysql_store_result(mysql);
|
|
|
|
while (ret && (mysql_row = mysql_fetch_row(mysql_res))) {
|
|
/* We need to get the length of the password.. - Viper */
|
|
lengths = mysql_fetch_lengths(mysql_res);
|
|
ci = scalloc(1, sizeof(ChannelInfo));
|
|
|
|
/* Name, founder, successor, password */
|
|
snprintf(ci->name, CHANMAX, "%s", mysql_row[0]);
|
|
ci->founder = findcore(mysql_row[1]);
|
|
if (mysql_row[2] && *(mysql_row[2]))
|
|
ci->successor = findcore(mysql_row[2]);
|
|
else
|
|
ci->successor = NULL;
|
|
|
|
/* Copy the password from what we got back from the DB and
|
|
* keep in mind that lengths may vary. We should never
|
|
* use more than we have. - Viper */
|
|
memset(ci->founderpass, 0, PASSMAX);
|
|
if (lengths[3] >= PASSMAX)
|
|
memcpy(ci->founderpass, mysql_row[3], PASSMAX - 1);
|
|
else
|
|
memcpy(ci->founderpass, mysql_row[3], lengths[3]);
|
|
|
|
/* Description, URL, email -- scalloc() initializes to 0/NULL */
|
|
ci->desc = sstrdup(mysql_row[4]);
|
|
if (mysql_row[5] && *(mysql_row[5]))
|
|
ci->url = sstrdup(mysql_row[5]);
|
|
if (mysql_row[6] && *(mysql_row[6]))
|
|
ci->email = sstrdup(mysql_row[6]);
|
|
|
|
/* Time registered, last used, last topic, last topic setter + time */
|
|
ci->time_registered = strtol(mysql_row[7], (char **) NULL, 10);
|
|
ci->last_used = strtol(mysql_row[8], (char **) NULL, 10);
|
|
if (mysql_row[9] && *(mysql_row[9])) {
|
|
ci->last_topic = sstrdup(mysql_row[9]);
|
|
snprintf(ci->last_topic_setter, NICKMAX, "%s", mysql_row[10]);
|
|
ci->last_topic_time = strtol(mysql_row[11], (char **) NULL, 10);
|
|
}
|
|
|
|
/* Flags, forbidden by, forbid reason, bantype
|
|
* NOTE: CI_INHABIT will be disabled in flags!!
|
|
*/
|
|
ci->flags =
|
|
strtol(mysql_row[12], (char **) NULL, 10) & ~CI_INHABIT;
|
|
|
|
if (mysql_row[13] && *(mysql_row[13])) {
|
|
ci->forbidby = sstrdup(mysql_row[13]);
|
|
if (mysql_row[14] && *(mysql_row[14]))
|
|
ci->forbidreason = sstrdup(mysql_row[14]);
|
|
}
|
|
|
|
ci->bantype = strtol(mysql_row[15], (char **) NULL, 10);
|
|
|
|
/* Accesscount, akickcount */
|
|
ci->accesscount = strtol(mysql_row[16], (char **) NULL, 10);
|
|
ci->akickcount = strtol(mysql_row[17], (char **) NULL, 10);
|
|
|
|
/* Mlock: on, off, limit, key, flood, redirect */
|
|
ci->mlock_on = strtol(mysql_row[18], (char **) NULL, 10);
|
|
ci->mlock_off = strtol(mysql_row[19], (char **) NULL, 10);
|
|
ci->mlock_limit = strtol(mysql_row[20], (char **) NULL, 10);
|
|
if (mysql_row[21] && *(mysql_row[21])) {
|
|
ci->mlock_key = sstrdup(mysql_row[21]);
|
|
if (mysql_row[22] && *(mysql_row[22])) {
|
|
ci->mlock_flood = sstrdup(mysql_row[22]);
|
|
}
|
|
if (mysql_row[23] && *(mysql_row[23])) {
|
|
ci->mlock_redirect = sstrdup(mysql_row[23]);
|
|
}
|
|
}
|
|
|
|
/* MemoMax, entrymessage, botinfo, botflags, badwordcount */
|
|
ci->memos.memomax = strtol(mysql_row[25], (char **) NULL, 10);
|
|
if (mysql_row[24] && *(mysql_row[24]))
|
|
ci->entry_message = sstrdup(mysql_row[24]);
|
|
ci->bi = findbot(mysql_row[26]);
|
|
ci->botflags = strtol(mysql_row[27], (char **) NULL, 10);
|
|
ci->bwcount = strtol(mysql_row[28], (char **) NULL, 10);
|
|
|
|
/* Capsmin, capspercent, floodlines, floodsecs, repeattimes */
|
|
ci->capsmin = strtol(mysql_row[29], (char **) NULL, 10);
|
|
ci->capspercent = strtol(mysql_row[30], (char **) NULL, 10);
|
|
ci->floodlines = strtol(mysql_row[31], (char **) NULL, 10);
|
|
ci->floodsecs = strtol(mysql_row[32], (char **) NULL, 10);
|
|
ci->repeattimes = strtol(mysql_row[33], (char **) NULL, 10);
|
|
|
|
|
|
/* Get info from other tables; we'll need the channel name */
|
|
q_name = db_mysql_quote(ci->name);
|
|
|
|
/* Get the LEVELS list */
|
|
ret = db_mysql_try("SELECT position, level "
|
|
"FROM anope_cs_levels "
|
|
"WHERE channel = '%s' AND active = 1",
|
|
q_name);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
ci->levels = scalloc(CA_SIZE, sizeof(*ci->levels));
|
|
reset_levels(ci);
|
|
|
|
while ((row = mysql_fetch_row(res))) {
|
|
i = strtol(row[0], (char **) NULL, 10);
|
|
ci->levels[i] = strtol(row[1], (char **) NULL, 10);
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
|
|
/* Get the channel ACCESS list */
|
|
if (ret && (ci->accesscount > 0)) {
|
|
ci->access = scalloc(ci->accesscount, sizeof(ChanAccess));
|
|
|
|
ret = db_mysql_try("SELECT level, display, last_seen "
|
|
"FROM anope_cs_access "
|
|
"WHERE channel = '%s' AND in_use = 1 AND active = 1",
|
|
q_name);
|
|
|
|
if (ret) {
|
|
res = mysql_store_result(mysql);
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
ci->access[i].in_use = 1;
|
|
ci->access[i].level = strtol(row[0], (char **) NULL, 10);
|
|
ci->access[i].nc = findcore(row[1]);
|
|
if (!(ci->access[i].nc))
|
|
ci->access[i].in_use = 0;
|
|
ci->access[i].last_seen =
|
|
strtol(row[2], (char **) NULL, 10);
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* Get the channel AKICK list */
|
|
if (ret && (ci->akickcount > 0)) {
|
|
ci->akick = scalloc(ci->akickcount, sizeof(AutoKick));
|
|
|
|
ret = db_mysql_try("SELECT flags, dmask, reason, creator, addtime "
|
|
"FROM anope_cs_akicks "
|
|
"WHERE channel = '%s' AND active = 1 AND (flags & %d) <> 0",
|
|
q_name, AK_USED);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
ci->akick[i].flags = strtol(row[0], (char **) NULL, 10);
|
|
if (ci->akick[i].flags & AK_ISNICK) {
|
|
ci->akick[i].u.nc = findcore(row[1]);
|
|
if (!(ci->akick[i].u.nc))
|
|
ci->akick[i].flags &= ~AK_USED;
|
|
} else {
|
|
ci->akick[i].u.mask = sstrdup(row[1]);
|
|
}
|
|
if (row[2] && *(row[2])) {
|
|
ci->akick[i].reason = sstrdup(row[2]);
|
|
}
|
|
ci->akick[i].creator = sstrdup(row[3]);
|
|
ci->akick[i].addtime = strtol(row[4], (char **) NULL, 10);
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
if (ret) {
|
|
/* Get the channel memos */
|
|
ret = db_mysql_try("SELECT nm_id, number, flags, time, sender, text "
|
|
"FROM anope_ms_info "
|
|
"WHERE receiver = '%s' AND serv = 'CHAN' AND active = 1",
|
|
q_name);
|
|
|
|
if (ret) {
|
|
res = mysql_store_result(mysql);
|
|
ci->memos.memocount = mysql_num_rows(res);
|
|
|
|
if (ci->memos.memocount > 0) {
|
|
Memo *memos;
|
|
|
|
memos = scalloc(ci->memos.memocount, sizeof(Memo));
|
|
ci->memos.memos = memos;
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
memos[i].id = strtol(row[0], (char **) NULL, 10);
|
|
memos[i].number = strtol(row[1], (char **) NULL, 10);
|
|
memos[i].flags = strtol(row[2], (char **) NULL, 10);
|
|
memos[i].time = strtol(row[3], (char **) NULL, 10);
|
|
snprintf(memos[i].sender, NICKMAX, "%s", row[4]);
|
|
memos[i].text = sstrdup(row[5]);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* Get the TTB data */
|
|
if (ret) {
|
|
ci->ttb = scalloc(TTB_SIZE, sizeof(*ci->ttb));
|
|
|
|
ret = db_mysql_try("SELECT ttb_id, value "
|
|
"FROM anope_cs_ttb "
|
|
"WHERE channel = '%s' AND active = 1",
|
|
q_name);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
|
|
while ((row = mysql_fetch_row(res))) {
|
|
i = strtol(row[0], (char **) NULL, 10);
|
|
/* Should we do a sanity check on the value of i? -GD */
|
|
ci->ttb[i] = strtol(row[1], (char **) NULL, 10);
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* Get the badwords */
|
|
if (ret && (ci->bwcount > 0)) {
|
|
ci->badwords = scalloc(ci->bwcount, sizeof(BadWord));
|
|
|
|
ret = db_mysql_try("SELECT word, type "
|
|
"FROM anope_cs_badwords "
|
|
"WHERE channel = '%s' AND active = 1",
|
|
q_name);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
ci->badwords[i].in_use = 1;
|
|
ci->badwords[i].word = sstrdup(row[0]);
|
|
ci->badwords[i].type = strtol(row[1], (char **) NULL, 10);
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* YAY! all done; free q_name and insert the channel */
|
|
free(q_name);
|
|
alpha_insert_chan(ci);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
/* Check to be sure that all channels still have a founder. If not,
|
|
* delete them. This code seems to be required in the old mysql code
|
|
* so i'll leave it in just to be sure. I also wonder why they didn't
|
|
* do that check up above immediately when it was known there was no
|
|
* founder... -GD
|
|
*/
|
|
for (i = 0; i < 256; i++) {
|
|
ChannelInfo *next;
|
|
for (ci = chanlists[i]; ci; ci = next) {
|
|
next = ci->next;
|
|
if (!(ci->flags & CI_VERBOTEN) && !ci->founder) {
|
|
alog("%s: database load: Deleting founderless channel %s",
|
|
s_ChanServ, ci->name);
|
|
delchan(ci);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int db_mysql_load_ns_req_dbase(void)
|
|
{
|
|
int ret;
|
|
NickRequest *nr;
|
|
unsigned long *lengths;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT nick, passcode, password, email, requested "
|
|
"FROM anope_ns_request "
|
|
"WHERE active = 1");
|
|
|
|
if (ret) {
|
|
mysql_res = mysql_use_result(mysql);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
/* We need to get the length of the password.. - Viper */
|
|
lengths = mysql_fetch_lengths(mysql_res);
|
|
nr = scalloc(1, sizeof(NickRequest));
|
|
|
|
nr->nick = sstrdup(mysql_row[0]);
|
|
nr->passcode = sstrdup(mysql_row[1]);
|
|
nr->email = sstrdup(mysql_row[3]);
|
|
nr->requested = strtol(mysql_row[4], (char **) NULL, 10);
|
|
|
|
/* Copy the password from what we got back from the DB and
|
|
* keep in mind that lengths may vary. We should never
|
|
* use more than we have. - Viper */
|
|
memset(nr->password, 0, PASSMAX);
|
|
if (lengths[2] >= PASSMAX)
|
|
memcpy(nr->password, mysql_row[2], PASSMAX - 1);
|
|
else
|
|
memcpy(nr->password, mysql_row[2], lengths[2]);
|
|
|
|
|
|
insert_requestnick(nr);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int db_mysql_load_ns_dbase(void)
|
|
{
|
|
int ret;
|
|
char *q_display;
|
|
NickCore *nc;
|
|
NickAlias *na;
|
|
MYSQL_RES *res;
|
|
MYSQL_ROW row;
|
|
int i;
|
|
unsigned long *lengths;
|
|
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
ret = db_mysql_try("SELECT display, pass, email, icq, url, flags, language, accesscount, memocount, memomax, channelcount, channelmax, greet "
|
|
"FROM anope_ns_core "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
/* I'd really like to use mysql_use_result here, but it'd tie up with
|
|
* all the queries being run inside each iteration... -GD
|
|
*/
|
|
mysql_res = mysql_store_result(mysql);
|
|
|
|
while (ret && (mysql_row = mysql_fetch_row(mysql_res))) {
|
|
/* We need to get the length of the password.. - Viper */
|
|
lengths = mysql_fetch_lengths(mysql_res);
|
|
|
|
nc = scalloc(1, sizeof(NickCore));
|
|
|
|
/* Display, password, email, ICQ, URL, flags */
|
|
nc->display = sstrdup(mysql_row[0]);
|
|
if (mysql_row[2] && *(mysql_row[2])) {
|
|
nc->email = sstrdup(mysql_row[2]);
|
|
}
|
|
nc->icq = strtol(mysql_row[3], (char **) NULL, 10);
|
|
if (mysql_row[4] && *(mysql_row[4])) {
|
|
nc->url = sstrdup(mysql_row[4]);
|
|
}
|
|
nc->flags = strtol(mysql_row[5], (char **) NULL, 10);
|
|
|
|
/* Copy the password from what we got back from the DB and
|
|
* keep in mind that lengths may vary. We should never
|
|
* use more than we have. - Viper */
|
|
memset(nc->pass, 0, PASSMAX);
|
|
if (lengths[1] >= PASSMAX)
|
|
memcpy(nc->pass, mysql_row[1], PASSMAX - 1);
|
|
else
|
|
memcpy(nc->pass, mysql_row[1], lengths[1]);
|
|
|
|
/* Language, accesscount, memocount, memomax */
|
|
nc->language = strtol(mysql_row[6], (char **) NULL, 10);
|
|
nc->accesscount = strtol(mysql_row[7], (char **) NULL, 10);
|
|
nc->memos.memocount = strtol(mysql_row[8], (char **) NULL, 10);
|
|
nc->memos.memomax = strtol(mysql_row[9], (char **) NULL, 10);
|
|
|
|
/* Channelcount, channelmax, greet */
|
|
nc->channelcount = strtol(mysql_row[10], (char **) NULL, 10);
|
|
nc->channelmax = strtol(mysql_row[11], (char **) NULL, 10);
|
|
if (mysql_row[12] && *(mysql_row[12]))
|
|
nc->greet = sstrdup(mysql_row[12]);
|
|
|
|
/* Don't allow KILL_IMMED if the config doesn't allow it */
|
|
if (!NSAllowKillImmed)
|
|
nc->flags &= ~NI_KILL_IMMED;
|
|
|
|
/* Check if the current user is important enough to be added to
|
|
* services admin or services oper lists
|
|
*/
|
|
if (nc->flags & NI_SERVICES_ADMIN)
|
|
slist_add(&servadmins, nc);
|
|
if (nc->flags & NI_SERVICES_OPER)
|
|
slist_add(&servopers, nc);
|
|
|
|
/* Unset the SERVICES_ROOT flag; we will set it again later if this
|
|
* user is really a services root (checked per NickAlias) -GD
|
|
*/
|
|
nc->flags &= ~NI_SERVICES_ROOT;
|
|
|
|
/* Get info from other tables; we'll need the display */
|
|
q_display = db_mysql_quote(nc->display);
|
|
|
|
/* Fill the accesslist */
|
|
if (ret && (nc->accesscount > 0)) {
|
|
nc->access = scalloc(nc->accesscount, sizeof(char *));
|
|
|
|
ret = db_mysql_try("SELECT access "
|
|
"FROM anope_ns_access "
|
|
"WHERE display = '%s' AND active = 1",
|
|
q_display);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
if (row[0] && *(row[0])) {
|
|
nc->access[i] = sstrdup(row[0]);
|
|
i++;
|
|
}
|
|
}
|
|
|
|
/* Versions previous to 1.8.3 have a problem with saving nick access lists to sql
|
|
* because of the way the table is set up, causing nc->accesscount to be higher
|
|
* than what is in the database, which causes numerious problems including crashes. - Adam
|
|
*/
|
|
if (nc->accesscount > i)
|
|
{
|
|
nc->accesscount = i;
|
|
nc->access = srealloc(nc->access, sizeof(char *) * nc->accesscount);
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* Load the memos */
|
|
if (ret && (nc->memos.memocount > 0)) {
|
|
nc->memos.memos = scalloc(nc->memos.memocount, sizeof(Memo));
|
|
|
|
ret = db_mysql_try("SELECT nm_id, number, flags, time, sender, text "
|
|
"FROM anope_ms_info "
|
|
"WHERE receiver = '%s' AND active = 1 AND serv = 'NICK' "
|
|
"ORDER BY number ASC",
|
|
q_display);
|
|
|
|
if (ret) {
|
|
res = mysql_use_result(mysql);
|
|
|
|
i = 0;
|
|
while ((row = mysql_fetch_row(res))) {
|
|
nc->memos.memos[i].id = strtol(row[0], (char **) NULL, 10);
|
|
nc->memos.memos[i].number = strtol(row[1], (char **) NULL, 10);
|
|
nc->memos.memos[i].flags = strtol(row[2], (char **) NULL, 10);
|
|
nc->memos.memos[i].time = strtol(row[3], (char **) NULL, 10);
|
|
snprintf(nc->memos.memos[i].sender, NICKMAX, "%s", row[4]);
|
|
nc->memos.memos[i].text = sstrdup(row[5]);
|
|
|
|
i++;
|
|
}
|
|
|
|
mysql_free_result(res);
|
|
}
|
|
}
|
|
|
|
/* Done with the core; insert it */
|
|
insert_core(nc);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
/* Load the nickaliases */
|
|
ret = db_mysql_try("SELECT nick, display, time_registered, last_seen, status, last_usermask, last_realname, last_quit "
|
|
"FROM anope_ns_alias "
|
|
"WHERE active = 1");
|
|
|
|
if (!ret)
|
|
return 0;
|
|
|
|
mysql_res = mysql_use_result(mysql);
|
|
|
|
while ((mysql_row = mysql_fetch_row(mysql_res))) {
|
|
/* First make sure this NickAlias has a NickCore; else we don't even
|
|
* bother adding it to the aliases at all...
|
|
*/
|
|
NickCore *nc;
|
|
|
|
if (!(nc = findcore(mysql_row[1])))
|
|
continue;
|
|
|
|
na = scalloc(1, sizeof(NickAlias));
|
|
|
|
/* nick, time_registered, last_seen, status
|
|
* NOTE: remove NS_TEMPORARY from status on load
|
|
*/
|
|
na->nick = sstrdup(mysql_row[0]);
|
|
na->nc = nc;
|
|
na->time_registered = strtol(mysql_row[2], (char **) NULL, 10);
|
|
na->last_seen = strtol(mysql_row[3], (char **) NULL, 10);
|
|
na->status =
|
|
strtol(mysql_row[4], (char **) NULL, 10) & ~NS_TEMPORARY;
|
|
|
|
/* last_usermask, last_realname, last_quit */
|
|
na->last_usermask = sstrdup(mysql_row[5]);
|
|
na->last_realname = sstrdup(mysql_row[6]);
|
|
|
|
if (mysql_row[7] && *(mysql_row[7])) {
|
|
na->last_quit = sstrdup(mysql_row[7]);
|
|
}
|
|
|
|
/* Assign to the nickcore aliases */
|
|
slist_add(&na->nc->aliases, na);
|
|
|
|
/* Check if this user is a services root */
|
|
for (i = 0; i < RootNumber; i++) {
|
|
if (stricmp(ServicesRoots[i], na->nick) == 0)
|
|
na->nc->flags |= NI_SERVICES_ROOT;
|
|
}
|
|
|
|
/* Last, but not least: insert the alias! */
|
|
alpha_insert_alias(na);
|
|
}
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* get random mysql number for the generator */
|
|
unsigned int mysql_rand(void)
|
|
{
|
|
unsigned int num = 0;
|
|
|
|
if (!do_mysql)
|
|
return 0;
|
|
|
|
db_mysql_try("SELECT RAND()");
|
|
|
|
mysql_res = mysql_store_result(mysql);
|
|
|
|
if (!(mysql_row = mysql_fetch_row(mysql_res))) {
|
|
mysql_free_result(mysql_res);
|
|
return 0;
|
|
}
|
|
|
|
num = UserKey3 * strtol(mysql_row[0], (char **) NULL, 10);
|
|
|
|
mysql_free_result(mysql_res);
|
|
|
|
return num;
|
|
}
|