diff options
-rw-r--r-- | Changes | 1 | ||||
-rw-r--r-- | Changes.conf | 8 | ||||
-rw-r--r-- | botserv.c | 4 | ||||
-rw-r--r-- | chanserv.c | 12 | ||||
-rw-r--r-- | config.c | 2 | ||||
-rw-r--r-- | data/example.conf | 7 | ||||
-rw-r--r-- | docs/MYSQL | 6 | ||||
-rw-r--r-- | extern.h | 29 | ||||
-rw-r--r-- | init.c | 26 | ||||
-rw-r--r-- | mysql.c | 669 | ||||
-rw-r--r-- | news.c | 6 | ||||
-rw-r--r-- | nickserv.c | 13 | ||||
-rw-r--r-- | proxy.c | 4 | ||||
-rw-r--r-- | rdb.c | 113 | ||||
-rw-r--r-- | sessions.c | 4 | ||||
-rw-r--r-- | version.log | 6 |
16 files changed, 879 insertions, 31 deletions
@@ -1,6 +1,7 @@ Anope Version 1.7.0 -------------------- Provided by Anope Dev. <dev@anope.org> +2004/03/31 Implemented MySQL Phase2 (see docs/MYSQL file) 2004/03/31 Modules can now add Commands/Messages from outside of AnopeInit 2004/03/31 Fixed a bug with recersive module callbacks. 2004/03/30 Added channelname to entrymsg diff --git a/Changes.conf b/Changes.conf index d5a04b70f..c0d663dab 100644 --- a/Changes.conf +++ b/Changes.conf @@ -1,5 +1,13 @@ Anope Version 1.7.0 -------------------- ** ADDED CONFIGURATION DIRECTIVES ** + +# UseRDB [OPTIONAL] +# +# Enable this if you want anope to load its data from a remote database. +# (e.g. MySQL) +# +#UseRDB + ** MODIFIED CONFIGURATION DIRECTIVES ** ** DELETED CONFIGURATION DIRECTIVES ** @@ -34,7 +34,7 @@ int nbots = 0; /*************************************************************************/ -static BotInfo *makebot(char *nick); +BotInfo *makebot(char *nick); static UserData *get_user_data(Channel * c, User * u); static void unassign(User * u, ChannelInfo * ci); @@ -709,7 +709,7 @@ static void insert_bot(BotInfo * bi) /*************************************************************************/ -static BotInfo *makebot(char *nick) +BotInfo *makebot(char *nick) { BotInfo *bi; diff --git a/chanserv.c b/chanserv.c index d3fe142a9..4e0a0cae7 100644 --- a/chanserv.c +++ b/chanserv.c @@ -226,10 +226,10 @@ int xop_msgs[4][14] = { /* *INDENT-ON* */ /*************************************************************************/ -static void alpha_insert_chan(ChannelInfo * ci); +void alpha_insert_chan(ChannelInfo * ci); static ChannelInfo *makechan(const char *chan); -static int delchan(ChannelInfo * ci); -static void reset_levels(ChannelInfo * ci); +int delchan(ChannelInfo * ci); +void reset_levels(ChannelInfo * ci); static int is_real_founder(User * user, ChannelInfo * ci); static int is_identified(User * user, ChannelInfo * ci); static void make_unidentified(User * u, ChannelInfo * ci); @@ -2075,7 +2075,7 @@ int check_access(User * user, ChannelInfo * ci, int what) /* Insert a channel alphabetically into the database. */ -static void alpha_insert_chan(ChannelInfo * ci) +void alpha_insert_chan(ChannelInfo * ci) { ChannelInfo *ptr, *prev; char *chan = ci->name; @@ -2120,7 +2120,7 @@ static ChannelInfo *makechan(const char *chan) /* Remove a channel from the ChanServ database. Return 1 on success, 0 * otherwise. */ -static int delchan(ChannelInfo * ci) +int delchan(ChannelInfo * ci) { int i; NickCore *nc = ci->founder; @@ -2204,7 +2204,7 @@ static int delchan(ChannelInfo * ci) /* Reset channel access level values to their default state. */ -static void reset_levels(ChannelInfo * ci) +void reset_levels(ChannelInfo * ci) { int i; @@ -292,6 +292,7 @@ char *MysqlSecure; char *MysqlSock; int MysqlRetries = 0; int MysqlRetryGap = 0; +int UseRDB = 0; int DefConLevel; int DefCon1; @@ -485,6 +486,7 @@ Directive directives[] = { {"MysqlSock", {{PARAM_STRING, PARAM_RELOAD, &MysqlSock}}}, {"MysqlRetries", {{PARAM_POSINT, PARAM_RELOAD, &MysqlRetries}}}, {"MysqlRetryGap", {{PARAM_POSINT, PARAM_RELOAD, &MysqlRetryGap}}}, + {"UseRDB", {{PARAM_SET, PARAM_RELOAD, &UseRDB}}}, {"ModuleAutoload", {{PARAM_STRING, PARAM_RELOAD, &Modules}}}, {"ModuleDelayedAutoload", {{PARAM_STRING, PARAM_RELOAD, &ModulesDelayed}}}, diff --git a/data/example.conf b/data/example.conf index 1b7e39f15..4aa0688cf 100644 --- a/data/example.conf +++ b/data/example.conf @@ -1426,6 +1426,13 @@ AddAkiller #MysqlRetries 10 #MysqlRetryGap 1 +# UseRDB [OPTIONAL] +# +# Enable this if you want anope to load its data from a remote database. +# (e.g. MySQL) +# +#UseRDB + ########################################################################### # # Module configuration diff --git a/docs/MYSQL b/docs/MYSQL index 088b5c07a..1d5bcce3f 100644 --- a/docs/MYSQL +++ b/docs/MYSQL @@ -17,6 +17,12 @@ Introduction: replace the FFF completely as an archive method (since all changes to the mysql db would be lost on the next Services save). All, while keeping FFF intact. This is still not the final goal, but it's a milestone. + (COMPLETED) + + UPDATE: Anope 1.7.0 (Revision 11 and above) finally supports phase 2! + A new config directive called 'UseRDB' has been added. + If you enable this, anope will automatically try to load its + data from MySQL (if configured and compiled with). PHASE 3:The next step, and most convoluted of all (since we'll need to modify pretty much all the source) is to load/save (SELECT/INSERT) data @@ -43,6 +43,7 @@ E void load_bs_dbase(void); E void save_bs_dbase(void); E void save_bs_rdb_dbase(void); +E BotInfo *makebot(char *nick); E BotInfo *findbot(char *nick); E void bot_join(ChannelInfo *ci); E void bot_rejoin_all(BotInfo *bi); @@ -91,6 +92,9 @@ E CSModeUtil csmodeutils[]; E void listchans(int count_only, const char *chan); E void get_chanserv_stats(long *nrec, long *memuse); +E int delchan(ChannelInfo * ci); +E void alpha_insert_chan(ChannelInfo * ci); +E void reset_levels(ChannelInfo * ci); E void cs_init(void); E void chanserv(User *u, char *buf); E void load_cs_dbase(void); @@ -436,6 +440,10 @@ E void rdb_save_os_db(unsigned int maxucnt, unsigned int maxutime, HostCache * hc); E void rdb_save_news(NewsItem * ni); E void rdb_save_exceptions(Exception * e); +E void rdb_load_bs_dbase(void); +E void rdb_load_hs_dbase(void); +E void rdb_load_ns_dbase(void); +E void rdb_load_dbases(void); #endif #ifdef USE_MYSQL @@ -448,6 +456,7 @@ E char *MysqlSock; E char *MysqlSecure; E int MysqlRetries; E int MysqlRetryGap; +E int UseRDB; #endif E int read_config(int reload); @@ -595,6 +604,9 @@ E void doCleanBuffer(char *str); /**** news.c ****/ +E int32 nnews, news_size; +E NewsItem *news; + E void get_news_stats(long *nrec, long *memuse); E void load_news(void); E void save_news(void); @@ -611,6 +623,9 @@ E NickAlias *nalists[1024]; E NickCore *nclists[1024]; E NickRequest *nrlists[1024]; +E void insert_requestnick(NickRequest * nr); +E void alpha_insert_alias(NickAlias * na); +E void insert_core(NickCore * nc); E void listnicks(int count_only, const char *nick); E void get_aliases_stats(long *nrec, long *memuse); E void get_core_stats(long *nrec, long *memuse); @@ -642,9 +657,11 @@ E void helpserv_init(void); /**** hostserv.c ****/ E void hostserv_init(void); +E void addHostCore(char *nick, char *vIdent, char *vhost, char *creator, int32 tmp_time); /**** operserv.c ****/ +E SList akills, sglines, sqlines, szlines; E SList servadmins; E SList servopers; @@ -714,6 +731,7 @@ E void s_unszline(char *mask); E HostCache *hcache[1024]; +E HostCache *proxy_cache_add(char *host); E void get_proxy_stats(long *nrec, long *memuse); E void ntoa(struct in_addr addr, char *ipaddr, int len); E int proxy_check(char *nick, char *host, uint32 ip); @@ -746,6 +764,9 @@ E void privmsg(const char *source, const char *dest, const char *fmt, ...) /**** sessions.c ****/ +E Exception *exceptions; +E int16 nexceptions; + E void get_session_stats(long *nrec, long *memuse); E void get_exception_stats(long *nrec, long *memuse); @@ -832,6 +853,14 @@ E void db_mysql_save_news(NewsItem * ni); E void db_mysql_save_exceptions(Exception * e); E void db_mysql_save_hs_core(HostCore * hc); E void db_mysql_save_bs_core(BotInfo * bi); +E void db_mysql_load_bs_dbase(void); +E void db_mysql_load_hs_dbase(void); +E void db_mysql_load_ns_dbase(void); +E void db_mysql_load_ns_req_dbase(void); +E void db_mysql_load_cs_dbase(void); +E void db_mysql_load_os_dbase(void); +E void db_mysql_load_exceptions(void); +E void db_mysql_load_news(void); #endif @@ -616,7 +616,7 @@ int init(int ac, char **av) helpserv_init(); #ifdef USE_RDB - db_mysql_init(); + rdb_init(); #endif /* Initialize proxy detection */ @@ -641,6 +641,11 @@ int init(int ac, char **av) #endif /* Load up databases */ +#ifdef USE_RDB + if (UseRDB) + rdb_load_dbases(); + if (!UseRDB) { +#endif if (!skeleton) { load_ns_dbase(); if (debug) @@ -651,7 +656,6 @@ int init(int ac, char **av) alog("debug: Loaded %s database (2/9)", s_HostServ); } if (s_BotServ) { - load_bs_dbase(); if (debug) alog("debug: Loaded %s database (3/9)", s_BotServ); } else if (debug) @@ -674,12 +678,24 @@ int init(int ac, char **av) if (debug) alog("debug: Loaded PreNick database (9/9)"); } - + } alog("Databases loaded"); /* Save the databases back to file/mysql to reflect any changes */ - save_databases(); - +#ifdef USE_RDB + if (!UseRDB) /* Only save if we are not using remote databases + * to avoid floods. As a side effects our nice + * FFF databases won't get overwritten if the + * mysql db is broken (empty etc.) */ + { +#endif + alog("Info: Reflecting database records."); + save_databases(); +#ifdef USE_RDB + } else { + alog("Info: Not reflecting database records."); + } +#endif /* Connect to the remote server */ servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort); if (servsock < 0 && RemoteServer2) { @@ -58,8 +58,10 @@ int db_mysql_init() do_mysql = 1; alog("MySQL has been enabled."); } + if (!db_mysql_open()) + do_mysql = 0; + return 1; - } /*************************************************************************/ @@ -103,6 +105,10 @@ int db_mysql_query(char *sql) { int result, lcv; + char *s = db_mysql_quote(sql); + + if(debug) alog(s); + free(s); result = mysql_query(mysql, sql); @@ -867,3 +873,664 @@ void db_mysql_save_bs_core(BotInfo * bi) } /*************************************************************************/ + +void db_mysql_load_bs_dbase(void) +{ + BotInfo *bi; + char sqlcmd[MAX_SQL_BUF]; + + if (!do_mysql) return; + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `nick`,`user`,`host`,`rname`,`flags`,`created`,`chancount` FROM `anope_bs_core`"); + + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + 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 = atoi(mysql_row[4]); + bi->created = atoi(mysql_row[5]); + bi->chancount = atoi(mysql_row[6]); + } + mysql_free_result(mysql_res); +} + +void db_mysql_load_hs_dbase(void) +{ + char sqlcmd[MAX_SQL_BUF]; + char *nick; + char *vHost; + char *creator; + char *vIdent; + int32 time; + + if (!do_mysql) return; + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `nick`,`vident`,`vhost`,`creator`,`time` FROM `anope_hs_core`"); + + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + while((mysql_row = mysql_fetch_row(mysql_res))) { + nick = sstrdup(mysql_row[0]); + vIdent = sstrdup(mysql_row[1]); + vHost = sstrdup(mysql_row[2]); + creator = sstrdup(mysql_row[3]); + time = atoi(mysql_row[4]); + addHostCore(nick, vIdent, vHost, creator, time); + free(nick); + free(vHost); + free(creator); + free(vIdent); + } + mysql_free_result(mysql_res); +} + +void db_mysql_load_news(void) +{ + char sqlcmd[MAX_SQL_BUF]; + int j; + + if (!do_mysql) return; + + snprintf(sqlcmd, MAX_SQL_BUF,"SELECT `type`,`num`,`ntext`,`who`,`time` FROM `anope_os_news`"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + nnews = mysql_num_rows(mysql_res); + if (nnews < 8) news_size = 16; + else if (nnews >= 16384) news_size = 32767; + else news_size = 2 * nnews; + news = scalloc(sizeof(*news) * news_size, 1); + if (!nnews) { + mysql_free_result(mysql_res); + return; + } + j = 0; + while((mysql_row = mysql_fetch_row(mysql_res))) { + news[j].type = atoi(mysql_row[0]); + news[j].num = atoi(mysql_row[1]); + news[j].text = sstrdup(mysql_row[2]); + snprintf(news[j].who, NICKMAX, "%s",mysql_row[3]); + news[j].time = atoi(mysql_row[4]); + j++; + } + mysql_free_result(mysql_res); +} + +void db_mysql_load_exceptions(void) +{ + char sqlcmd[MAX_SQL_BUF]; + int j; + + if (!do_mysql) return; + + snprintf(sqlcmd, MAX_SQL_BUF,"SELECT `mask`,`lim`,`who`,`reason`,`time`,`expires` FROM `anope_os_exceptions`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + nexceptions = mysql_num_rows(mysql_res); + exceptions = scalloc(sizeof(Exception) * nexceptions, 1); + j = 0; + while((mysql_row = mysql_fetch_row(mysql_res))) { + exceptions[j].mask = sstrdup(mysql_row[0]); + exceptions[j].limit = atoi(mysql_row[1]); + snprintf(exceptions[j].who, NICKMAX, "%s",mysql_row[2]); + exceptions[j].reason = sstrdup(mysql_row[3]); + exceptions[j].time = atoi(mysql_row[4]); + exceptions[j].expires = atoi(mysql_row[5]); + j++; + } + mysql_free_result(mysql_res); +} + +#define HASH(host) ((tolower((host)[0])&31)<<5 | (tolower((host)[1])&31)) + +void db_mysql_load_os_dbase(void) +{ + char sqlcmd[MAX_SQL_BUF]; + Akill *ak; + SXLine *sx; + HostCache *hc; + int akc,sgc,sqc,szc,j; + + if (!do_mysql) return; + + snprintf(sqlcmd, MAX_SQL_BUF,"SELECT `maxusercnt`,`maxusertime`,`akills_count`,`sglines_count`,`sqlines_count`,`szlines_count` FROM `anope_os_core`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + if ((mysql_row = mysql_fetch_row(mysql_res))) { + maxusercnt = atoi(mysql_row[0]); + maxusertime = atoi(mysql_row[1]); + akc = atoi(mysql_row[2]); + sgc = atoi(mysql_row[3]); + sqc = atoi(mysql_row[4]); + szc = atoi(mysql_row[5]); + } else { + maxusercnt = 0; + maxusertime = time(NULL); + akc = sgc = sqc = szc = 0; + } + mysql_free_result(mysql_res); + + snprintf(sqlcmd, MAX_SQL_BUF, "SELECT `user`,`host`,`xby`,`reason`,`seton`,`expire` FROM `anope_os_akills`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + slist_setcapacity(&akills,akc); + while((mysql_row = mysql_fetch_row(mysql_res))) { + ak = scalloc(sizeof(Akill), 1); + 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 = atoi(mysql_row[4]); + ak->expires = atoi(mysql_row[5]); + slist_add(&akills, ak); + } + mysql_free_result(mysql_res); + + slist_setcapacity(&sglines,sgc); + slist_setcapacity(&sqlines,sqc); + slist_setcapacity(&szlines,szc); + + snprintf(sqlcmd, MAX_SQL_BUF, "SELECT `mask`,`xby`,`reason`,`seton`,`expire` FROM `anope_os_sglines`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql statement: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + while ((mysql_row = mysql_fetch_row(mysql_res))) { + sx = scalloc(sizeof(SXLine), 1); + sx->mask = sstrdup(mysql_row[0]); + sx->by = sstrdup(mysql_row[1]); + sx->reason = sstrdup(mysql_row[2]); + sx->seton = atoi(mysql_row[3]); + sx->expires = atoi(mysql_row[4]); + slist_add(&sglines, sx); + } + mysql_free_result(mysql_res); + + snprintf(sqlcmd, MAX_SQL_BUF, "SELECT `mask`,`xby`,`reason`,`seton`,`expire` FROM `anope_os_sqlines`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql statement: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + while ((mysql_row = mysql_fetch_row(mysql_res))) { + sx = scalloc(sizeof(SXLine), 1); + sx->mask = sstrdup(mysql_row[0]); + sx->by = sstrdup(mysql_row[1]); + sx->reason = sstrdup(mysql_row[2]); + sx->seton = atoi(mysql_row[3]); + sx->expires = atoi(mysql_row[4]); + slist_add(&sqlines, sx); + } + mysql_free_result(mysql_res); + + snprintf(sqlcmd, MAX_SQL_BUF, "SELECT `mask`,`xby`,`reason`,`seton`,`expire` FROM `anope_os_szlines`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql statement: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + while ((mysql_row = mysql_fetch_row(mysql_res))) { + sx = scalloc(sizeof(SXLine), 1); + sx->mask = sstrdup(mysql_row[0]); + sx->by = sstrdup(mysql_row[1]); + sx->reason = sstrdup(mysql_row[2]); + sx->seton = atoi(mysql_row[3]); + sx->expires = atoi(mysql_row[4]); + slist_add(&szlines, sx); + } + mysql_free_result(mysql_res); + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `mask`,`status`,`used` FROM `anope_os_hcache`"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + while ((mysql_row = mysql_fetch_row(mysql_res))) { + j = HASH(mysql_row[0]); + hc = scalloc(1, sizeof(HostCache)); + hc->host = sstrdup(mysql_row[0]); + hc->status = atoi(mysql_row[1]); + hc->used = atoi(mysql_row[2]); + + hc->prev = NULL; + hc->next = hcache[j]; + if (hc->next) + hc->next->prev = hc; + hcache[j] = hc; + } + mysql_free_result(mysql_res); +} + +#undef HASH + +void db_mysql_load_cs_dbase(void) +{ + char sqlcmd[MAX_SQL_BUF], *tempstr; + ChannelInfo *ci; + int n_levels, j; + MYSQL_RES *res; + MYSQL_ROW row; + + if (!do_mysql) return; + + snprintf(sqlcmd,MAX_SQL_BUF,"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`,`ttb`,`bwcount`,`capsmin`,`capspercent`,`floodlines`,`floodsecs`,`repeattimes` FROM `anope_cs_info`"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + while((mysql_row = mysql_fetch_row(mysql_res))) { + ci = scalloc(sizeof(ChannelInfo),1); + snprintf(ci->name,CHANMAX,"%s",mysql_row[0]); + ci->founder = findcore(mysql_row[1]); + ci->successor = findcore(mysql_row[2]); + snprintf(ci->founderpass,PASSMAX,"%s",mysql_row[3]); + ci->desc = sstrdup(mysql_row[4]); + ci->url = sstrdup(mysql_row[5]); + if (strlen(ci->url) == 0) { free(ci->url); ci->url = NULL; } + ci->email = sstrdup(mysql_row[6]); + if (strlen(ci->email) == 0) { free(ci->email); ci->email = NULL; } + ci->time_registered = atoi(mysql_row[7]); + ci->last_used = atoi(mysql_row[8]); + ci->last_topic = sstrdup(mysql_row[9]); + snprintf(ci->last_topic_setter,NICKMAX,"%s",mysql_row[10]); + ci->last_topic_time = atoi(mysql_row[11]); + ci->flags = atoi(mysql_row[12]); +#ifdef USE_ENCRYPTION + if (!(ci->flags & (CI_ENCRYPTEDPW | CI_VERBOTEN))) { + if (debug) + alog("debug: %s: encrypting password for %s on load",s_ChanServ,ci->name); + if (encrypt_in_place(ci->founderpass, PASSMAX) < 0) + fatal("%s: load database: Can't encrypt %s password!",s_ChanServ,ci->name); + ci->flags |= CI_ENCRYPTEDPW; + } +#else + if (ci->flags & CI_ENCRYPTEDPW) { + fatal("%s: load database: password for %s encrypted but encryption disabled, aborting",s_ChanServ,ci->name); + } +#endif + ci->flags &= ~CI_INHABIT; + + ci->forbidby = sstrdup(mysql_row[13]); + ci->forbidreason = sstrdup(mysql_row[14]); + ci->bantype = atoi(mysql_row[15]); + + tempstr = db_mysql_quote(ci->name); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `position`,`level` FROM `anope_cs_levels` WHERE `channel` = '%s'",tempstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + res = mysql_store_result(mysql); + n_levels = mysql_num_rows(res); + ci->levels = scalloc(2 * CA_SIZE, 1); + reset_levels(ci); + while((row = mysql_fetch_row(res))) { + ci->levels[atoi(row[0])] = atoi(row[1]); + } + mysql_free_result(res); + ci->accesscount = atoi(mysql_row[16]); + if (ci->accesscount) { + ci->access = scalloc(ci->accesscount, sizeof(ChanAccess)); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `in_use`,`level`,`display`,`last_seen` FROM `anope_cs_access` WHERE `channel` = '%s'",tempstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + res = mysql_store_result(mysql); + j = 0; + while((row = mysql_fetch_row(res))) { + ci->access[j].in_use = atoi(row[0]); + if (ci->access[j].in_use) { + ci->access[j].level = atoi(row[1]); + ci->access[j].nc = findcore(row[2]); + if (ci->access[j].nc == NULL) ci->access[j].in_use = 0; + ci->access[j].last_seen = atoi(row[3]); + } + j++; + } + mysql_free_result(res); + } else { + ci->access = NULL; + } + ci->akickcount = atoi(mysql_row[17]); + if (ci->akickcount) { + ci->akick = scalloc(ci->akickcount,sizeof(AutoKick)); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `flags`,`dmask`,`reason`,`creator`,`addtime` FROM `anope_cs_akicks` WHERE `channel` = '%s'",tempstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + res = mysql_store_result(mysql); + j = 0; + while((row = mysql_fetch_row(res))) { + ci->akick[j].flags = atoi(row[0]); + if (ci->akick[j].flags & AK_USED) { + if (ci->akick[j].flags & AK_ISNICK) { + ci->akick[j].u.nc = findcore(row[1]); + if (!ci->akick[j].u.nc) ci->akick[j].flags &= ~AK_USED; + } else { + ci->akick[j].u.mask = sstrdup(row[1]); + } + ci->akick[j].reason = sstrdup(row[2]); + ci->akick[j].creator = sstrdup(row[3]); + ci->akick[j].addtime = atoi(row[4]); + } + j++; + } + mysql_free_result(res); + } else { + ci->akick = NULL; + } + ci->mlock_on = atoi(mysql_row[18]); + ci->mlock_off = atoi(mysql_row[19]); + ci->mlock_limit = atoi(mysql_row[20]); + ci->mlock_key = sstrdup(mysql_row[21]); +#ifdef HAS_FMODE + ci->mlock_flood = sstrdup(mysql_row[22]); +#endif + +#ifdef HAS_LMODE + ci->mlock_redirect = sstrdup(mysql_row[23]); +#endif + ci->memos.memomax = atoi(mysql_row[25]); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `number`,`flags`,`time`,`sender`,`text` FROM `anope_ms_info` WHERE `receiver` = '%s'",tempstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + res = mysql_store_result(mysql); + ci->memos.memocount = mysql_num_rows(res); + if (ci->memos.memocount) { + Memo *memos; + memos = scalloc(sizeof(Memo) * ci->memos.memocount, 1); + ci->memos.memos = memos; + while((row = mysql_fetch_row(res))) { + memos->number = atoi(row[0]); + memos->flags = atoi(row[1]); + memos->time = atoi(row[2]); + snprintf(memos->sender,NICKMAX,"%s",row[3]); + memos->text = sstrdup(row[4]); + memos++; + } + } + mysql_free_result(res); + ci->entry_message = sstrdup(mysql_row[24]); + if (strlen(ci->entry_message) == 0) { free(ci->entry_message); ci->entry_message = NULL; } + ci->c = NULL; + + ci->bi = findbot(mysql_row[26]); + ci->botflags = atoi(mysql_row[27]); + ci->ttb = scalloc(2 * TTB_SIZE, 1); + for (j = 0; j < TTB_SIZE; j++) { + ci->ttb[j] = 0; + } + ci->capsmin = atoi(mysql_row[30]); + ci->capspercent = atoi(mysql_row[31]); + ci->floodlines = atoi(mysql_row[32]); + ci->floodsecs = atoi(mysql_row[33]); + ci->repeattimes = atoi(mysql_row[34]); + + ci->bwcount = atoi(mysql_row[29]); + if (ci->bwcount) { + ci->badwords = scalloc(ci->bwcount, sizeof(BadWord)); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `word`,`type` FROM `anope_cs_badwords` WHERE `channel` = '%s'",tempstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + res = mysql_store_result(mysql); + j = 0; + while((row = mysql_fetch_row(res))) { + ci->badwords[j].in_use = 1; + if (ci->badwords[j].in_use) { /* I know... but for later */ + ci->badwords[j].word = sstrdup(row[0]); + ci->badwords[j].type = atoi(row[1]); + } + j++; + } + mysql_free_result(res); + } else { + ci->badwords = NULL; + } + alpha_insert_chan(ci); + free(tempstr); + } + mysql_free_result(mysql_res); + + for (j = 0; j < 256; j++) { + ChannelInfo *next; + for (ci = chanlists[j]; 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); + } + } + } +} + +void db_mysql_load_ns_req_dbase(void) +{ + char sqlcmd[MAX_SQL_BUF]; + NickRequest *nr; + + if (!do_mysql) return; + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `nick`,`passcode`,`password`,`email`,`requested`,`active` FROM `anope_ns_req`;"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s",sqlcmd); + db_mysql_error(MYSQL_WARNING,"query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + 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 = atoi(mysql_row[4]); + insert_requestnick(nr); + } + mysql_free_result(mysql_res); +} + +void db_mysql_load_ns_dbase(void) +{ + char sqlcmd[MAX_SQL_BUF], *tmpstr; + NickCore *nc; + NickAlias *na; + MYSQL_RES *res; + MYSQL_ROW row; + int i,j; + + if (!do_mysql) return; + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `display`,`pass`,`email`,`icq`,`url`,`flags`,`language`,`accesscount`,`memocount`,`memomax`,`channelcount`,`channelmax`,`greet`,`active` FROM `anope_ns_core`"); + + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + if (mysql_num_rows(mysql_res) == 0) { + mysql_free_result(mysql_res); + return; + } + + while((mysql_row = mysql_fetch_row(mysql_res))) { + nc = scalloc(1, sizeof(NickCore)); + + nc->display = sstrdup(mysql_row[0]); + nc->pass = sstrdup(mysql_row[1]); + nc->email = sstrdup(mysql_row[2]); + nc->icq = atoi(mysql_row[3]); + nc->url = sstrdup(mysql_row[4]); + nc->flags = atoi(mysql_row[5]); + nc->language = atoi(mysql_row[6]); + nc->accesscount = atoi(mysql_row[7]); + nc->memos.memocount = atoi(mysql_row[8]); + nc->memos.memomax = atoi(mysql_row[9]); + nc->channelcount = atoi(mysql_row[10]); + nc->channelmax = atoi(mysql_row[11]); + nc->greet = sstrdup(mysql_row[12]); + + if (!NSAllowKillImmed) + nc->flags &= ~NI_KILL_IMMED; + +#ifdef USE_ENCRYPTION + if (nc->pass && !(nc->flags & NI_ENCRYPTEDPW)) { + if (debug) + alog("debug: %s: encrypting password for `%s' on load", s_NickServ, nc->display); + if(encrypt_in_place(nc->pass, PASSMAX) < 0) + fatal("%s: Can't encrypt `%s' nickname password!", s_NickServ, nc->display); + + nc->flags |= NI_ENCRYPTEDPW; + } +#else + if (nc->flags & NI_ENCRYPTEDPW) + fatal("%s: load database: password for %s encrypted but encryption disabled, aborting", s_NickServ, nc->display); +#endif + + if (nc->flags & NI_SERVICES_ADMIN) + slist_add(&servadmins, nc); + if (nc->flags & NI_SERVICES_OPER) + slist_add(&servopers, nc); + + if (nc->accesscount) { + char **access; + access = scalloc(sizeof(char *) * nc->accesscount, 1); + nc->access = access; + tmpstr = db_mysql_quote(nc->display); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `access` FROM `anope_ns_access` WHERE `display` = '%s'",tmpstr); + free(tmpstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + res = mysql_store_result(mysql); + while((row = mysql_fetch_row(res))) { + *access = sstrdup(row[0]); + access++; + } + mysql_free_result(res); + } + + if (nc->memos.memocount) { + Memo *memos; + memos = scalloc(sizeof(Memo) * nc->memos.memocount, 1); + nc->memos.memos = memos; + tmpstr = db_mysql_quote(nc->display); + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `number`,`flags`,`time`,`sender`,`text` FROM `anope_ms_info` WHERE `receiver` = '%s' ORDER BY `number` ASC",tmpstr); + free(tmpstr); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + res = mysql_store_result(mysql); + while((row = mysql_fetch_row(res))) { + memos->number = atoi(row[0]); + memos->flags = atoi(row[1]); + memos->time = atoi(row[2]); + snprintf(memos->sender,NICKMAX,"%s",row[3]); + memos->text = sstrdup(row[4]); + memos++; + } + mysql_free_result(res); + } + insert_core(nc); + } + mysql_free_result(mysql_res); + + snprintf(sqlcmd,MAX_SQL_BUF,"SELECT `display`,`nick`,`time_registered`,`last_seen`,`status`,`last_usermask`,`last_realname`,`last_quit` FROM `anope_ns_alias`"); + if (db_mysql_query(sqlcmd)) { + log_perror("Can't create sql query: %s", sqlcmd); + db_mysql_error(MYSQL_WARNING, "query"); + } + mysql_res = mysql_store_result(mysql); + while((mysql_row = mysql_fetch_row(mysql_res))) { + na = scalloc(1, sizeof(NickAlias)); + na->nick = sstrdup(mysql_row[1]); + + na->last_usermask = sstrdup(mysql_row[5]); + na->last_realname = sstrdup(mysql_row[6]); + na->last_quit = sstrdup(mysql_row[7]); + na->time_registered = atoi(mysql_row[2]); + na->last_seen = atoi(mysql_row[3]); + na->status = atoi(mysql_row[4]); + na->status &= ~NS_TEMPORARY; + tmpstr = sstrdup(mysql_row[0]); + na->nc = findcore(tmpstr); + free(tmpstr); + + slist_add(&na->nc->aliases, na); + + if(!(na->status & NS_VERBOTEN)) { + if (!na->last_usermask) na->last_usermask = sstrdup(""); + if (!na->last_realname) na->last_realname = sstrdup(""); + } + + na->nc->flags &= ~NI_SERVICES_ROOT; + alpha_insert_alias(na); + } + mysql_free_result(mysql_res); + + for (j = 0; j < 1024; j++) { + NickAlias *next; + for (na = nalists[j]; na; na = next) { + next = na->next; + if (!na->nc) { + alog("%s: while loading database: %s has no core! We delete it.",s_NickServ, na->nick); + delnick(na); + continue; + } + for (i = 0; i < RootNumber; i++) { + if (!stricmp(ServicesRoots[i], na->nick)) + na->nc->flags |= NI_SERVICES_ROOT; + } + } + } +} + @@ -17,9 +17,9 @@ /*************************************************************************/ -static int32 nnews = 0; -static int32 news_size = 0; -static NewsItem *news = NULL; +int32 nnews = 0; +int32 news_size = 0; +NewsItem *news = NULL; /*************************************************************************/ diff --git a/nickserv.c b/nickserv.c index f71aeb37b..0890494ac 100644 --- a/nickserv.c +++ b/nickserv.c @@ -33,9 +33,9 @@ static int guestnum; /* Current guest number */ extern char *getvHost(char *nick); static int is_on_access(User * u, NickCore * nc); -static void alpha_insert_alias(NickAlias * na); -static void insert_core(NickCore * nc); -static void insert_requestnick(NickRequest * nr); +void alpha_insert_alias(NickAlias * na); +void insert_core(NickCore * nc); +void insert_requestnick(NickRequest * nr); static NickAlias *makenick(const char *nick); static NickRequest *makerequest(const char *nick); static NickAlias *makealias(const char *nick, NickCore * nc); @@ -696,7 +696,6 @@ void load_ns_dbase(void) SAFE(read_string(&nc->display, f)); SAFE(read_string(&nc->pass, f)); - SAFE(read_string(&nc->email, f)); SAFE(read_string(&nc->greet, f)); SAFE(read_int32(&nc->icq, f)); @@ -1300,7 +1299,7 @@ static int is_on_access(User * u, NickCore * nc) /* Insert a nick alias alphabetically into the database. */ -static void alpha_insert_alias(NickAlias * na) +void alpha_insert_alias(NickAlias * na) { NickAlias *ptr, *prev; char *nick = na->nick; @@ -1322,7 +1321,7 @@ static void alpha_insert_alias(NickAlias * na) /* Insert a nick core into the database. */ -static void insert_core(NickCore * nc) +void insert_core(NickCore * nc) { int index = HASH(nc->display); @@ -1334,7 +1333,7 @@ static void insert_core(NickCore * nc) } /*************************************************************************/ -static void insert_requestnick(NickRequest * nr) +void insert_requestnick(NickRequest * nr) { int index = HASH(nr->nick); @@ -50,7 +50,7 @@ pthread_mutex_t resmut = PTHREAD_MUTEX_INITIALIZER; static uint32 aton(char *ipaddr); static void proxy_akill(char *host); -static HostCache *proxy_cache_add(char *host); +HostCache *proxy_cache_add(char *host); static void proxy_cache_del(HostCache * hc); static HostCache *proxy_cache_find(char *host); static int proxy_connect(unsigned long ip, unsigned short port); @@ -134,7 +134,7 @@ static void proxy_akill(char *host) /* Adds a cache entry after having it allocated */ -static HostCache *proxy_cache_add(char *host) +HostCache *proxy_cache_add(char *host) { HostCache *hc; int index = HASH(host); @@ -30,7 +30,7 @@ int rdb_open() { #ifdef USE_MYSQL - return db_mysql_open(); + return 1; // db_mysql_open(); #endif } @@ -41,7 +41,7 @@ int rdb_close() { #ifdef USE_MYSQL - return db_mysql_close(); + return 1; // db_mysql_close(); #endif } @@ -337,6 +337,115 @@ void rdb_save_news(NewsItem * ni) /*************************************************************************/ +void rdb_load_bs_dbase(void) +{ + +#ifdef USE_MYSQL + return db_mysql_load_bs_dbase(); +#endif + +} + +/*************************************************************************/ + +void rdb_load_hs_dbase(void) +{ + +#ifdef USE_MYSQL + return db_mysql_load_hs_dbase(); +#endif + +} + +/*************************************************************************/ + +void rdb_load_ns_dbase(void) +{ + +#ifdef USE_MYSQL + return db_mysql_load_ns_dbase(); +#endif +} + +/*************************************************************************/ + +void rdb_load_news(void) +{ +#ifdef USE_MYSQL + return db_mysql_load_news(); +#endif +} + +/*************************************************************************/ + +void rdb_load_exceptions(void) +{ +#ifdef USE_MYSQL + return db_mysql_load_exceptions(); +#endif +} + +/*************************************************************************/ + +void rdb_load_cs_dbase(void) +{ +#ifdef USE_MYSQL + return db_mysql_load_cs_dbase(); +#endif +} + +/*************************************************************************/ + +void rdb_load_os_dbase(void) +{ +#ifdef USE_MYSQL + return db_mysql_load_os_dbase(); +#endif +} + +/*************************************************************************/ + +void rdb_load_ns_req_dbase(void) +{ +#ifdef USE_MYSQL + return db_mysql_load_ns_req_dbase(); +#endif +} + +/*************************************************************************/ + +void rdb_load_dbases(void) +{ + if (!skeleton) { + rdb_load_ns_dbase(); + if (debug) alog("RDB: Loaded NickServ DataBase (1/8)"); + if (s_HostServ) { + rdb_load_hs_dbase(); + if (debug) alog("RDB: Loaded HostServ DataBase (2/8)"); + } + if (s_BotServ) { + rdb_load_bs_dbase(); + if (debug) alog("RDB: Loaded BotServ DataBase (3/8)"); + } + rdb_load_cs_dbase(); + if (debug) alog("RDB: Loaded ChanServ DataBase (4/8)"); + } + rdb_load_os_dbase(); + if (debug) alog("RDB: Loaded OperServ DataBase (5/8)"); + rdb_load_news(); + if (debug) alog("RDB: Loaded News DataBase (6/8)"); + rdb_load_exceptions(); + if (debug) alog("RDB: Loaded Exception Database (7/8)"); + if (PreNickDBName) { + rdb_load_ns_req_dbase(); + if (debug) alog("RDB: Loaded PreNick DataBase (8/8)"); + } else { + if (debug) alog("RDB: No need to load PreNickDB (8/8)"); + } + alog("RDB: All DataBases loaded."); +} +/*************************************************************************/ + void rdb_save_exceptions(Exception * e) { diff --git a/sessions.c b/sessions.c index 876bf5bcd..1620a2e15 100644 --- a/sessions.c +++ b/sessions.c @@ -68,8 +68,8 @@ struct session_ { static Session *sessionlist[1024]; static int32 nsessions = 0; -static Exception *exceptions = NULL; -static int16 nexceptions = 0; +Exception *exceptions = NULL; +int16 nexceptions = 0; /*************************************************************************/ diff --git a/version.log b/version.log index bb00ef88c..68afc4c03 100644 --- a/version.log +++ b/version.log @@ -8,11 +8,15 @@ VERSION_MAJOR="1" VERSION_MINOR="7" VERSION_PATCH="0" -VERSION_BUILD="15" +VERSION_BUILD="17" VERSION_EXTRA="" # $Log$ # +# BUILD : 1.7.0 (17) +# BUGS : +# NOTES : Implemented MySQL Phase 2, see Changes and docs/MYSQL file for information. +# # BUILD : 1.7.0 (15) # BUGS : N/A # NOTES : Added the ability for modules to add Commands and Messages outside of AnopeInit() |