1
0
mirror of https://github.com/anope/anope.git synced 2026-06-26 10:36:38 +02:00
Files
anope/src/mysql.c
T
viper viper@31f1291d-b8d6-0310-a050-a5561fc1590b 5b9b1acca5 BUILD : 1.7.22 (1450) BUGS : NOTES : Fixed a number of remaining buffer overflows in NS and CS not addressed by previous commit.
git-svn-id: svn://svn.anope.org/anope/trunk@1450 31f1291d-b8d6-0310-a050-a5561fc1590b


git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@1164 5417fbe8-f217-4b02-8779-1006273d7864
2008-09-23 11:14:09 +00:00

1892 lines
63 KiB
C

/* MySQL functions.
*
* (C) 2003-2008 Anope Team
* Contact us at info@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*
* $Id$
*
*/
#include "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;
}
/*************************************************************************/
/* 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;
}
/*************************************************************************/
/* Return a string to insert into a SQL query. The string will, once
* evaluated by MySQL, result in a the given pass encoded in the encryption
* type selected for MysqlSecure
*
* This should be removed since Rob properly did encryption modules... -GD
*/
char *db_mysql_secure(char *pass)
{
char epass[BUFSIZE];
char tmp_pass[PASSMAX];
/* Initialize the buffer. Bug #86 */
memset(epass, '\0', BUFSIZE);
memset(tmp_pass, '\0', PASSMAX);
/* We couldnt decrypt the pass... */
if (enc_decrypt(pass, tmp_pass, PASSMAX - 1) != 1) {
snprintf(epass, sizeof(epass), "'%s'", pass);
} else { /* if we could decrypt the pass */
if (!pass) {
snprintf(epass, sizeof(epass), "''");
} else if ((!MysqlSecure) || (strcmp(MysqlSecure, "") == 0)) {
snprintf(epass, sizeof(epass), "'%s'", tmp_pass);
} else if (strcmp(MysqlSecure, "des") == 0) {
snprintf(epass, sizeof(epass), "ENCRYPT('%s')", tmp_pass);
} else if (strcmp(MysqlSecure, "md5") == 0) {
snprintf(epass, sizeof(epass), "MD5('%s')", tmp_pass);
} else if (strcmp(MysqlSecure, "sha") == 0) {
snprintf(epass, sizeof(epass), "SHA('%s')", tmp_pass);
} else {
snprintf(epass, sizeof(epass), "ENCODE('%s','%s')", tmp_pass,
MysqlSecure);
}
}
return sstrdup(epass);
}
/*************************************************************************/
/*
* 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(nr->password);
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, *epass, *q_email, *q_greet, *q_url,
*q_access, *q_sender, *q_text;
q_display = db_mysql_quote(nc->display);
q_pass = db_mysql_quote(nc->pass);
q_email = db_mysql_quote(nc->email);
q_greet = db_mysql_quote(nc->greet);
q_url = db_mysql_quote(nc->url);
epass = db_mysql_secure(q_pass);
free(q_pass);
/* 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'",
epass, 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, epass, 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);
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 (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(epass);
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;
int i;
char *q_name;
char *q_founder;
char *q_successor;
char *q_pass;
char *e_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_pass = db_mysql_quote(ci->founderpass);
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("");
}
e_pass = db_mysql_secure(q_pass);
free(q_pass);
/* 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, e_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, e_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);
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 (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(e_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 "
"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;
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))) {
time = strtol(mysql_row[4], (char **) NULL, 10);
addHostCore(mysql_row[0], mysql_row[1], 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;
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))) {
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;
snprintf(ci->founderpass, PASSMAX, "%s", mysql_row[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);
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;
ci->forbidby = sstrdup(mysql_row[13]);
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);
ci->mlock_key = sstrdup(mysql_row[21]);
ci->mlock_flood = sstrdup(mysql_row[22]);
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]);
}
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;
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))) {
nr = scalloc(1, sizeof(NickRequest));
nr->nick = sstrdup(mysql_row[0]);
nr->passcode = sstrdup(mysql_row[1]);
nr->password = sstrdup(mysql_row[2]);
nr->email = sstrdup(mysql_row[3]);
nr->requested = strtol(mysql_row[4], (char **) NULL, 10);
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;
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))) {
nc = scalloc(1, sizeof(NickCore));
/* Display, password, email, ICQ, URL, flags */
nc->display = sstrdup(mysql_row[0]);
nc->pass = sstrdup(mysql_row[1]);
nc->email = sstrdup(mysql_row[2]);
nc->icq = strtol(mysql_row[3], (char **) NULL, 10);
nc->url = sstrdup(mysql_row[4]);
nc->flags = strtol(mysql_row[5], (char **) NULL, 10);
/* 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++;
}
}
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]);
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;
}