/* MySQL functions.
*
* (C) 2003-2005 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 */
/*************************************************************************/
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);
}
}
/*************************************************************************/
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;
}
/*************************************************************************/
int db_mysql_open()
{
/* If MySQL is disabled, return 0 */
if (!do_mysql)
return 0;
mysql = mysql_init(NULL);
if (mysql == NULL)
db_mysql_error(MYSQL_WARNING, "Unable to create mysql object");
if (!MysqlPort)
MysqlPort = 3306;
if (MysqlSock) {
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;
}
} else {
if ((!mysql_real_connect
(mysql, MysqlHost, MysqlUser, MysqlPass, MysqlName, MysqlPort,
NULL, 0))) {
log_perror("MySQL Error: Cant connect to MySQL: %s\n", mysql_error(mysql));
return 0;
}
}
return 1;
}
/*************************************************************************/
int db_mysql_query(char *sql)
{
int result, lcv;
char *s;
if (!do_mysql) {
return -1;
}
if (debug) {
s = db_mysql_quote(sql);
alog("debug: %s", s);
free(s);
}
result = mysql_query(mysql, sql);
if (result) {
switch (mysql_errno(mysql)) {
case CR_SERVER_GONE_ERROR:
case CR_SERVER_LOST:
for (lcv = 0; lcv < MysqlRetries; lcv++) {
if (db_mysql_open()) {
result = mysql_query(mysql, sql);
return (result);
}
sleep(MysqlRetryGap);
}
/* If we get here, we could not connect. */
log_perror("Unable to reconnect to database: %s\n",
mysql_error(mysql));
db_mysql_error(MYSQL_ERROR, "connect");
/* Never reached. */
break;
default:
/* Unhandled error. */
return (result);
}
}
return (0);
}
/*************************************************************************/
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;
}
/*************************************************************************/
/* I don't like using res here, maybe we can pass it as a param? */
int db_mysql_close()
{
if (mysql_res)
mysql_free_result(mysql_res);
mysql_close(mysql);
return 1;
}
/*************************************************************************/
/*
* NickServ Specific Secion
*/
/*************************************************************************/
void db_mysql_save_ns_req(NickRequest * nr)
{
char *qnick, *qpasscode, *qpassword, *qemail;
char sqlcmd[MAX_SQL_BUF];
qnick = db_mysql_quote(nr->nick);
qpasscode = db_mysql_quote(nr->passcode);
qpassword = db_mysql_quote(nr->password);
qemail = db_mysql_quote(nr->email);
snprintf(sqlcmd, MAX_SQL_BUF,
"REPLACE anope_ns_request (nick,passcode,password,email,requested,active)"
" VALUES ('%s','%s','%s','%s','%d','1')",
qnick, qpasscode, qpassword, qemail, (int) nr->requested);
if (db_mysql_query(sqlcmd)) {
log_perror("Can't create sql query: %s", sqlcmd);
db_mysql_error(MYSQL_WARNING, "query");
}
free(qnick);
free(qpasscode);
free(qpassword);
free(qemail);
}
char *db_mysql_secure(char *pass)
{
char epass[BUFSIZE];
/* Initialize the buffer. Bug #86 */
memset(epass, '\0', BUFSIZE);
#ifdef USE_ENCRYPTION
if (pass) {
/* If we use the builtin encryption don't double encrypt! */
snprintf(epass, sizeof(epass), "'%s'", pass);
}
#else
if (!pass) {
snprintf(epass, sizeof(epass), "''");
} else if ((!MysqlSecure) || (strcmp(MysqlSecure, "") == 0)) {
snprintf(epass, sizeof(epass), "'%s'", pass);
} else if (strcmp(MysqlSecure, "des") == 0) {
snprintf(epass, sizeof(epass), "ENCRYPT('%s')", pass);
} else if (strcmp(MysqlSecure, "md5") == 0) {
sn
|