]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/database/chanservdb.c
Use nsmalloc/nsfree for chanserv.
[irc/quakenet/newserv.git] / chanserv / database / chanservdb.c
CommitLineData
b263aa79 1/*
2 * chanservdb.c:
3 * Handles the SQL stuff for the channel service.
4 */
5
6#include "../chanserv.h"
b263aa79 7#include "../../core/config.h"
8#include "../../lib/sstring.h"
9#include "../../parser/parser.h"
10#include "../../core/events.h"
103521a1 11#include "../../core/nsmalloc.h"
beb29b55 12#include "../../lib/strlfunc.h"
ee8cd7d0 13#include "../../dbapi/dbapi.h"
5857b2db 14#include "../../lib/version.h"
b263aa79 15
16#include <string.h>
b263aa79 17#include <stdio.h>
18#include <sys/poll.h>
19#include <stdarg.h>
20
5857b2db
P
21MODULE_VERSION(QVERSION);
22
b263aa79 23int chanservdb_ready;
24
b263aa79 25regchan **allchans;
97390b65 26maillock *maillocks;
b263aa79 27
28int chanservext;
29int chanservaext;
30
31unsigned int lastchannelID;
32unsigned int lastuserID;
33unsigned int lastbanID;
e3805f60 34unsigned int lastdomainID;
97390b65 35unsigned int lastmaillockID;
b263aa79 36
37/* Local prototypes */
38void csdb_handlestats(int hooknum, void *arg);
ee8cd7d0
CP
39void loadmessages_part1(DBConn *, void *);
40void loadmessages_part2(DBConn *, void *);
41void loadcommandsummary_real(DBConn *, void *);
b263aa79 42
43/* User loading functions */
ee8cd7d0
CP
44void loadsomeusers(DBConn *, void *);
45void loadusersdone(DBConn *, void *);
b263aa79 46
47/* Channel loading functions */
ee8cd7d0
CP
48void loadsomechannels(DBConn *, void *);
49void loadchannelsdone(DBConn *, void *);
b263aa79 50
51/* Chanuser loading functions */
ee8cd7d0
CP
52void loadchanusersinit(DBConn *, void *);
53void loadsomechanusers(DBConn *, void *);
54void loadchanusersdone(DBConn *, void *);
b263aa79 55
56/* Chanban loading functions */
ee8cd7d0
CP
57void loadsomechanbans(DBConn *, void *);
58void loadchanbansdone(DBConn *, void *);
b263aa79 59
e3805f60 60/* Mail Domain loading functions */
ee8cd7d0
CP
61void loadsomemaildomains(DBConn *, void *);
62void loadmaildomainsdone(DBConn *, void *);
e3805f60 63
97390b65 64/* Mail lock loading functions */
ee8cd7d0
CP
65void loadsomemaillocks(DBConn *, void *);
66void loadmaillocksdone(DBConn *, void *);
97390b65 67
b263aa79 68/* Free sstrings in the structures */
69void csdb_freestuff();
70
71static void setuptables() {
72 /* Set up the tables */
73 /* User table */
aa944539 74 dbattach("chanserv");
ee8cd7d0 75 dbcreatequery("CREATE TABLE chanserv.users ("
b263aa79 76 "ID INT NOT NULL,"
77 "username VARCHAR(16) NOT NULL,"
78 "created INT NOT NULL,"
79 "lastauth INT NOT NULL,"
80 "lastemailchng INT NOT NULL,"
81 "flags INT NOT NULL,"
82 "language INT NOT NULL,"
83 "suspendby INT NOT NULL,"
84 "suspendexp INT NOT NULL,"
88d191e3 85 "suspendtime INT NOT NULL,"
b438f642 86 "lockuntil INT NOT NULL,"
b263aa79 87 "password VARCHAR(11) NOT NULL,"
b263aa79 88 "email VARCHAR(100),"
9708f78f 89 "lastemail VARCHAR(100),"
b263aa79 90 "lastuserhost VARCHAR(75),"
91 "suspendreason VARCHAR(250),"
92 "comment VARCHAR(250),"
93 "info VARCHAR(100),"
86d2bc73 94 "lastpasschng INT NOT NULL,"
b263aa79 95 "PRIMARY KEY (ID))");
96
ee8cd7d0 97 dbcreatequery("CREATE INDEX user_username_index ON chanserv.users (username)");
b263aa79 98
99 /* Channel table */
ee8cd7d0 100 dbcreatequery("CREATE TABLE chanserv.channels ("
b263aa79 101 "ID INT NOT NULL,"
102 "name VARCHAR(250) NOT NULL,"
103 "flags INT NOT NULL,"
104 "forcemodes INT NOT NULL,"
105 "denymodes INT NOT NULL,"
106 "chanlimit INT NOT NULL,"
107 "autolimit INT NOT NULL,"
108 "banstyle INT NOT NULL,"
109 "created INT NOT NULL,"
110 "lastactive INT NOT NULL,"
111 "statsreset INT NOT NULL,"
112 "banduration INT NOT NULL,"
113 "founder INT NOT NULL,"
114 "addedby INT NOT NULL,"
115 "suspendby INT NOT NULL,"
88d191e3 116 "suspendtime INT NOT NULL,"
b263aa79 117 "chantype SMALLINT NOT NULL,"
118 "totaljoins INT NOT NULL,"
119 "tripjoins INT NOT NULL,"
120 "maxusers INT NOT NULL,"
121 "tripusers INT NOT NULL,"
122 "welcome VARCHAR(500),"
123 "topic VARCHAR(250),"
124 "chankey VARCHAR(23),"
125 "suspendreason VARCHAR(250),"
126 "comment VARCHAR(250),"
127 "lasttimestamp INT,"
128 "PRIMARY KEY (ID))");
129
130 /* Chanuser table */
ee8cd7d0 131 dbcreatequery("CREATE TABLE chanserv.chanusers ("
b263aa79 132 "userID INT NOT NULL,"
133 "channelID INT NOT NULL,"
134 "flags INT NOT NULL,"
135 "changetime INT NOT NULL,"
136 "usetime INT NOT NULL,"
137 "info VARCHAR(100) NOT NULL,"
138 "PRIMARY KEY (userID, channelID))");
139
ee8cd7d0
CP
140 dbcreatequery("CREATE INDEX chanusers_userID_index on chanserv.chanusers (userID)");
141 dbcreatequery("CREATE INDEX chanusers_channelID_index on chanserv.chanusers (channelID)");
b263aa79 142
ee8cd7d0 143 dbcreatequery("CREATE TABLE chanserv.bans ("
b263aa79 144 "banID INT NOT NULL," /* Unique number for the ban to make
145 DELETEs process in finite time.. */
146 "channelID INT NOT NULL,"
147 "userID INT NOT NULL," /* Who set the ban.. */
148 "hostmask VARCHAR(100) NOT NULL," /* needs to be at least USERLEN+NICKLEN+HOSTLEN+2 */
149 "expiry INT NOT NULL,"
150 "reason VARCHAR(200),"
151 "PRIMARY KEY(banID))");
152
ee8cd7d0 153 dbcreatequery("CREATE INDEX bans_channelID_index on chanserv.bans (channelID)");
b263aa79 154
ee8cd7d0 155 dbcreatequery("CREATE TABLE chanserv.languages ("
b263aa79 156 "languageID INT NOT NULL,"
157 "code VARCHAR(2) NOT NULL,"
158 "name VARCHAR(30) NOT NULL)");
159
ee8cd7d0 160 dbcreatequery("CREATE TABLE chanserv.messages ("
b263aa79 161 "languageID INT NOT NULL,"
162 "messageID INT NOT NULL,"
163 "message VARCHAR(250) NOT NULL,"
164 "PRIMARY KEY (languageID, messageID))");
165
ee8cd7d0 166 dbcreatequery("CREATE TABLE chanserv.help ("
b263aa79 167 "commandID INT NOT NULL,"
168 "command VARCHAR(30) NOT NULL,"
169 "languageID INT NOT NULL,"
170 "summary VARCHAR(200) NOT NULL,"
171 "fullinfo TEXT NOT NULL,"
172 "PRIMARY KEY (commandID, languageID))");
173
ee8cd7d0 174 dbcreatequery("CREATE TABLE chanserv.email ("
b263aa79 175 "userID INT NOT NULL,"
176 "emailtype INT NOT NULL,"
177 "prevEmail VARCHAR(100),"
7713925b
CP
178 "mailID SERIAL,"
179 "PRIMARY KEY (mailID))");
e3805f60 180
ee8cd7d0 181 dbcreatequery("CREATE TABLE chanserv.maildomain ("
e3805f60
P
182 "ID INT NOT NULL,"
183 "name VARCHAR NOT NULL,"
184 "domainlimit INT NOT NULL,"
185 "actlimit INT NOT NULL,"
186 "flags INT NOT NULL,"
187 "PRIMARY KEY (ID))");
188
ee8cd7d0 189 dbcreatequery("CREATE TABLE chanserv.authhistory ("
183b8e2f
P
190 "userID INT NOT NULL,"
191 "nick VARCHAR(15) NOT NULL,"
192 "username VARCHAR(10) NOT NULL,"
193 "host VARCHAR(63) NOT NULL,"
194 "authtime INT NOT NULL,"
49031c0c 195 "disconnecttime INT NOT NULL,"
196 "numeric INT NOT NULL,"
197 "quitreason VARCHAR(100) ,"
183b8e2f
P
198 "PRIMARY KEY (userID, authtime))");
199
ee8cd7d0
CP
200 dbcreatequery("CREATE INDEX authhistory_userID_index on chanserv.authhistory(userID)");
201 dbcreatequery("CREATE TABLE chanserv.chanlevhistory ("
183b8e2f
P
202 "userID INT NOT NULL,"
203 "channelID INT NOT NULL,"
204 "targetID INT NOT NULL,"
205 "changetime INT NOT NULL,"
206 "authtime INT NOT NULL,"
207 "oldflags INT NOT NULL,"
208 "newflags INT NOT NULL)");
209
ee8cd7d0
CP
210 dbcreatequery("CREATE INDEX chanlevhistory_userID_index on chanserv.chanlevhistory(userID)");
211 dbcreatequery("CREATE INDEX chanlevhistory_channelID_index on chanserv.chanlevhistory(channelID)");
212 dbcreatequery("CREATE INDEX chanlevhistory_targetID_index on chanserv.chanlevhistory(targetID)");
183b8e2f 213
ee8cd7d0 214 dbcreatequery("CREATE TABLE chanserv.accounthistory ("
183b8e2f
P
215 "userID INT NOT NULL,"
216 "changetime INT NOT NULL,"
217 "authtime INT NOT NULL,"
218 "oldpassword VARCHAR(11),"
219 "newpassword VARCHAR(11),"
220 "oldemail VARCHAR(100),"
221 "newemail VARCHAR(100),"
222 "PRIMARY KEY (userID, changetime))");
223
ee8cd7d0 224 dbcreatequery("CREATE INDEX accounthistory_userID_index on chanserv.accounthistory(userID)");
97390b65 225
ee8cd7d0 226 dbcreatequery("CREATE TABLE chanserv.maillocks ("
97390b65
CP
227 "ID INT NOT NULL,"
228 "pattern VARCHAR NOT NULL,"
229 "reason VARCHAR NOT NULL,"
230 "createdby INT NOT NULL,"
231 "created INT NOT NULL,"
232 "PRIMARY KEY (ID))");
b263aa79 233}
234
235void _init() {
236 chanservext=registerchanext("chanserv");
04b12064 237 chanservaext=registerauthnameext("chanserv",1);
b263aa79 238
62f29043 239 /* Set up the hashes */
b263aa79 240 chanservhashinit();
241
242 /* And the messages */
243 initmessages();
244
ee8cd7d0 245 if (dbconnected() && (chanservext!=-1) && (chanservaext!=-1)) {
b263aa79 246 registerhook(HOOK_CORE_STATSREQUEST, csdb_handlestats);
247
248 setuptables();
249
e3805f60 250 lastuserID=lastchannelID=lastdomainID=0;
b263aa79 251
ee8cd7d0
CP
252 dbloadtable("chanserv.users",NULL,loadsomeusers,loadusersdone);
253 dbloadtable("chanserv.channels",NULL,loadsomechannels,loadchannelsdone);
254 dbloadtable("chanserv.chanusers",loadchanusersinit,loadsomechanusers,loadchanusersdone);
255 dbloadtable("chanserv.bans",NULL,loadsomechanbans,loadchanbansdone);
256 dbloadtable("chanserv.maildomain",NULL, loadsomemaildomains,loadmaildomainsdone);
257 dbloadtable("chanserv.maillocks",NULL, loadsomemaillocks,loadmaillocksdone);
e3805f60 258
b263aa79 259 loadmessages();
260 }
261}
262
263void _fini() {
6cb084fc 264 deregisterhook(HOOK_CORE_STATSREQUEST, csdb_handlestats);
265
b4d3e4be
CP
266 csdb_freestuff();
267
b263aa79 268 if (chanservext!=-1)
269 releasechanext(chanservext);
270
271 if (chanservaext!=-1)
272 releaseauthnameext(chanservaext);
273
103521a1 274 nsfreeall(POOL_CHANSERVDB);
aa944539 275 dbdetach("chanserv");
b263aa79 276}
277
278void csdb_handlestats(int hooknum, void *arg) {
279/* long level=(long)arg; */
280
281 /* Keeping options open here */
282}
283
284void chanservdbclose() {
285
286 deregisterhook(HOOK_CORE_STATSREQUEST, csdb_handlestats);
287
288}
289
b263aa79 290/*
291 * loadsomeusers():
292 * Loads some users in from the SQL DB
293 */
294
ee8cd7d0
CP
295void loadsomeusers(DBConn *dbconn, void *arg) {
296 DBResult *pgres;
b263aa79 297 reguser *rup;
e3805f60 298 char *local;
beb29b55 299 char mailbuf[1024];
b263aa79 300
ee8cd7d0 301 pgres=dbgetresult(dbconn);
b263aa79 302
ee8cd7d0 303 if (!dbquerysuccessful(pgres)) {
b263aa79 304 Error("chanserv",ERR_ERROR,"Error loading user DB");
305 return;
306 }
307
86d2bc73 308 if (dbnumfields(pgres)!=19) {
b263aa79 309 Error("chanserv",ERR_ERROR,"User DB format error");
310 return;
311 }
312
ee8cd7d0 313 while(dbfetchrow(pgres)) {
b263aa79 314 rup=getreguser();
315 rup->status=0;
ee8cd7d0
CP
316 rup->ID=strtoul(dbgetvalue(pgres,0),NULL,10);
317 strncpy(rup->username,dbgetvalue(pgres,1),NICKLEN); rup->username[NICKLEN]='\0';
318 rup->created=strtoul(dbgetvalue(pgres,2),NULL,10);
319 rup->lastauth=strtoul(dbgetvalue(pgres,3),NULL,10);
320 rup->lastemailchange=strtoul(dbgetvalue(pgres,4),NULL,10);
321 rup->flags=strtoul(dbgetvalue(pgres,5),NULL,10);
322 rup->languageid=strtoul(dbgetvalue(pgres,6),NULL,10);
323 rup->suspendby=strtoul(dbgetvalue(pgres,7),NULL,10);
324 rup->suspendexp=strtoul(dbgetvalue(pgres,8),NULL,10);
325 rup->suspendtime=strtoul(dbgetvalue(pgres,9),NULL,10);
326 rup->lockuntil=strtoul(dbgetvalue(pgres,10),NULL,10);
327 strncpy(rup->password,dbgetvalue(pgres,11),PASSLEN); rup->password[PASSLEN]='\0';
328 rup->email=getsstring(dbgetvalue(pgres,12),100);
e3805f60
P
329 if (rup->email) {
330 rup->domain=findorcreatemaildomain(rup->email->content);
331 addregusertomaildomain(rup, rup->domain);
beb29b55
CP
332
333 strlcpy(mailbuf, rup->email->content, sizeof(mailbuf));
334 if((local=strchr(mailbuf, '@'))) {
e3805f60 335 *(local++)='\0';
beb29b55 336 rup->localpart=getsstring(mailbuf,EMAILLEN);
e3805f60
P
337 } else {
338 rup->localpart=NULL;
339 }
340 } else {
341 rup->domain=NULL;
342 rup->localpart=NULL;
343 }
ee8cd7d0
CP
344 rup->lastemail=getsstring(dbgetvalue(pgres,13),100);
345 rup->lastuserhost=getsstring(dbgetvalue(pgres,14),75);
346 rup->suspendreason=getsstring(dbgetvalue(pgres,15),250);
347 rup->comment=getsstring(dbgetvalue(pgres,16),250);
348 rup->info=getsstring(dbgetvalue(pgres,17),100);
86d2bc73 349 rup->lastpasschange=strtoul(dbgetvalue(pgres,18),NULL,10);
b263aa79 350 rup->knownon=NULL;
b263aa79 351 rup->checkshd=NULL;
352 rup->stealcount=0;
353 rup->fakeuser=NULL;
354 addregusertohash(rup);
355
356 if (rup->ID > lastuserID) {
357 lastuserID=rup->ID;
358 }
359 }
360
ee8cd7d0 361 dbclear(pgres);
b263aa79 362}
363
ee8cd7d0 364void loadusersdone(DBConn *conn, void *arg) {
b263aa79 365 Error("chanserv",ERR_INFO,"Load users done (highest ID was %d)",lastuserID);
366}
367
368/*
369 * Channel loading functions
370 */
371
ee8cd7d0
CP
372void loadsomechannels(DBConn *dbconn, void *arg) {
373 DBResult *pgres;
b263aa79 374 regchan *rcp;
ee8cd7d0 375 int j;
b263aa79 376 chanindex *cip;
377 time_t now=time(NULL);
378
ee8cd7d0 379 pgres=dbgetresult(dbconn);
b263aa79 380
ee8cd7d0 381 if (!dbquerysuccessful(pgres)) {
b263aa79 382 Error("chanserv",ERR_ERROR,"Error loading channel DB");
383 return;
384 }
385
ee8cd7d0 386 if (dbnumfields(pgres)!=27) {
b263aa79 387 Error("chanserv",ERR_ERROR,"Channel DB format error");
388 return;
389 }
390
ee8cd7d0
CP
391 while(dbfetchrow(pgres)) {
392 cip=findorcreatechanindex(dbgetvalue(pgres,1));
b263aa79 393 if (cip->exts[chanservext]) {
394 Error("chanserv",ERR_WARNING,"%s in database twice - this WILL cause problems later.",cip->name->content);
395 continue;
396 }
397 rcp=getregchan();
398 cip->exts[chanservext]=rcp;
399
ee8cd7d0 400 rcp->ID=strtoul(dbgetvalue(pgres,0),NULL,10);
b263aa79 401 rcp->index=cip;
ee8cd7d0 402 rcp->flags=strtoul(dbgetvalue(pgres,2),NULL,10);
b263aa79 403 rcp->status=0; /* Non-DB field */
404 rcp->lastbancheck=0;
405 rcp->lastcountersync=now;
406 rcp->lastpart=0;
407 rcp->bans=NULL;
ee8cd7d0
CP
408 rcp->forcemodes=strtoul(dbgetvalue(pgres,3),NULL,10);
409 rcp->denymodes=strtoul(dbgetvalue(pgres,4),NULL,10);
410 rcp->limit=strtoul(dbgetvalue(pgres,5),NULL,10);
411 rcp->autolimit=strtoul(dbgetvalue(pgres,6),NULL,10);
412 rcp->banstyle=strtoul(dbgetvalue(pgres,7),NULL,10);
413 rcp->created=strtoul(dbgetvalue(pgres,8),NULL,10);
414 rcp->lastactive=strtoul(dbgetvalue(pgres,9),NULL,10);
415 rcp->statsreset=strtoul(dbgetvalue(pgres,10),NULL,10);
416 rcp->banduration=strtoul(dbgetvalue(pgres,11),NULL,10);
417 rcp->founder=strtol(dbgetvalue(pgres,12),NULL,10);
418 rcp->addedby=strtol(dbgetvalue(pgres,13),NULL,10);
419 rcp->suspendby=strtol(dbgetvalue(pgres,14),NULL,10);
420 rcp->suspendtime=strtol(dbgetvalue(pgres,15),NULL,10);
421 rcp->chantype=strtoul(dbgetvalue(pgres,16),NULL,10);
422 rcp->totaljoins=strtoul(dbgetvalue(pgres,17),NULL,10);
423 rcp->tripjoins=strtoul(dbgetvalue(pgres,18),NULL,10);
424 rcp->maxusers=strtoul(dbgetvalue(pgres,19),NULL,10);
425 rcp->tripusers=strtoul(dbgetvalue(pgres,20),NULL,10);
426 rcp->welcome=getsstring(dbgetvalue(pgres,21),500);
427 rcp->topic=getsstring(dbgetvalue(pgres,22),TOPICLEN);
428 rcp->key=getsstring(dbgetvalue(pgres,23),KEYLEN);
429 rcp->suspendreason=getsstring(dbgetvalue(pgres,24),250);
430 rcp->comment=getsstring(dbgetvalue(pgres,25),250);
b263aa79 431 rcp->checksched=NULL;
ee8cd7d0 432 rcp->ltimestamp=strtoul(dbgetvalue(pgres,26),NULL,10);
b263aa79 433 memset(rcp->regusers,0,REGCHANUSERHASHSIZE*sizeof(reguser *));
434
435 if (rcp->ID > lastchannelID)
436 lastchannelID=rcp->ID;
437
438 if (CIsAutoLimit(rcp))
439 rcp->limit=0;
1482fb78 440
441 for (j=0;j<CHANOPHISTORY;j++) {
442 rcp->chanopnicks[j][0]='\0';
443 rcp->chanopaccts[j]=0;
444 }
445 rcp->chanoppos=0;
b263aa79 446 }
447
ee8cd7d0 448 dbclear(pgres);
b263aa79 449}
450
ee8cd7d0 451void loadchannelsdone(DBConn *dbconn, void *arg) {
b263aa79 452 Error("chanserv",ERR_INFO,"Channel load done (highest ID was %d)",lastchannelID);
453}
454
ee8cd7d0 455void loadchanusersinit(DBConn *dbconn, void *arg) {
b263aa79 456 int i;
457 chanindex *cip;
458 regchan *rcp;
459
460 allchans=(regchan **)malloc((lastchannelID+1)*sizeof(regchan *));
461 memset(allchans,0,(lastchannelID+1)*sizeof(regchan *));
462 for (i=0;i<CHANNELHASHSIZE;i++) {
463 for (cip=chantable[i];cip;cip=cip->next) {
464 if (cip->exts[chanservext]) {
465 rcp=(regchan *)cip->exts[chanservext];
466 allchans[rcp->ID]=rcp;
467 }
468 }
469 }
470}
471
ee8cd7d0
CP
472void loadsomechanusers(DBConn *dbconn, void *arg) {
473 DBResult *pgres;
b263aa79 474 regchanuser *rcup;
b263aa79 475 regchan *rcp;
476 reguser *rup;
477 authname *anp;
478 int uid,cid;
479 int total=0;
480
481 /* Set up the allchans array */
ee8cd7d0 482 pgres=dbgetresult(dbconn);
b263aa79 483
ee8cd7d0 484 if (!dbquerysuccessful(pgres)) {
b263aa79 485 Error("chanserv",ERR_ERROR,"Error loading chanusers.");
486 return;
487 }
488
ee8cd7d0 489 if (dbnumfields(pgres)!=6) {
b263aa79 490 Error("chanserv",ERR_ERROR,"Chanusers format error");
491 return;
492 }
493
ee8cd7d0
CP
494 while(dbfetchrow(pgres)) {
495 uid=strtol(dbgetvalue(pgres,0),NULL,10);
496 cid=strtol(dbgetvalue(pgres,1),NULL,10);
b263aa79 497
498 if (!(anp=findauthname(uid)) || !(rup=anp->exts[chanservaext])) {
499 Error("chanserv",ERR_WARNING,"Skipping channeluser for unknown user %d",uid);
500 continue;
501 }
502
503 if (cid>lastchannelID || !(rcp=allchans[cid])) {
504 Error("chanserv",ERR_WARNING,"Skipping channeluser for unknown chan %d",cid);
505 continue;
506 }
507
508 if (rup==NULL || rcp==NULL) {
509 Error("chanserv",ERR_ERROR,"Can't add user %s on channel %s",
ee8cd7d0 510 dbgetvalue(pgres,0),dbgetvalue(pgres,1));
b263aa79 511 } else {
512 rcup=getregchanuser();
513 rcup->user=rup;
514 rcup->chan=rcp;
ee8cd7d0
CP
515 rcup->flags=strtol(dbgetvalue(pgres,2),NULL,10);
516 rcup->changetime=strtol(dbgetvalue(pgres,3),NULL,10);
517 rcup->usetime=strtol(dbgetvalue(pgres,4),NULL,10);
518 rcup->info=getsstring(dbgetvalue(pgres,5),100);
b263aa79 519 addregusertochannel(rcup);
520 total++;
521 }
522 }
523
ee8cd7d0 524 dbclear(pgres);
b263aa79 525}
526
ee8cd7d0 527void loadchanusersdone(DBConn *dbconn, void *arg) {
b263aa79 528 Error("chanserv",ERR_INFO,"Channel user load done.");
529}
530
ee8cd7d0
CP
531void loadsomechanbans(DBConn *dbconn, void *arg) {
532 DBResult *pgres;
b263aa79 533 regban *rbp;
b263aa79 534 regchan *rcp;
535 int uid,cid,bid;
ea4a0a50 536 time_t expiry;
b263aa79 537 int total=0;
538
ee8cd7d0 539 pgres=dbgetresult(dbconn);
b263aa79 540
ee8cd7d0 541 if (!dbquerysuccessful(pgres)) {
b263aa79 542 Error("chanserv",ERR_ERROR,"Error loading bans.");
543 return;
544 }
545
ee8cd7d0 546 if (dbnumfields(pgres)!=6) {
b263aa79 547 Error("chanserv",ERR_ERROR,"Ban format error");
548 return;
549 }
550
ee8cd7d0
CP
551 while(dbfetchrow(pgres)) {
552 bid=strtoul(dbgetvalue(pgres,0),NULL,10);
553 cid=strtoul(dbgetvalue(pgres,1),NULL,10);
554 uid=strtoul(dbgetvalue(pgres,2),NULL,10);
555 expiry=strtoul(dbgetvalue(pgres,4),NULL,10);
b263aa79 556
557 if (cid>lastchannelID || !(rcp=allchans[cid])) {
558 Error("chanserv",ERR_WARNING,"Skipping ban for unknown chan %d",cid);
559 continue;
560 }
561
562 rbp=getregban();
563 rbp->setby=uid;
564 rbp->ID=bid;
565 rbp->expiry=expiry;
ee8cd7d0
CP
566 rbp->reason=getsstring(dbgetvalue(pgres,5),200);
567 rbp->cbp=makeban(dbgetvalue(pgres,3));
b263aa79 568 rbp->next=rcp->bans;
569 rcp->bans=rbp;
570
571 total++;
572
573 if (bid>lastbanID)
574 lastbanID=bid;
575 }
576
ee8cd7d0 577 dbclear(pgres);
b263aa79 578}
579
ee8cd7d0 580void loadchanbansdone(DBConn *dbconn, void *arg) {
b263aa79 581 free(allchans);
582
583 Error("chanserv",ERR_INFO,"Channel ban load done, highest ID was %d",lastbanID);
b263aa79 584}
585
586void loadmessages() {
ee8cd7d0 587 dbasyncquery(loadmessages_part1, NULL, "SELECT * from chanserv.languages");
b263aa79 588}
589
ee8cd7d0 590void loadmessages_part1(DBConn *dbconn, void *arg) {
b263aa79 591 int i,j;
ee8cd7d0 592 DBResult *pgres;
b263aa79 593
594 /* Firstly, clear up any stale messages */
595 for (i=0;i<MAXLANG;i++) {
596 if (cslanguages[i]) {
597 freesstring(cslanguages[i]->name);
598 free(cslanguages[i]);
599 }
600 for (j=0;j<MAXMESSAGES;j++) {
601 if (csmessages[i][j]) {
602 freesstring(csmessages[i][j]);
603 csmessages[i][j]=NULL;
604 }
605 }
606 }
607
ee8cd7d0 608 pgres=dbgetresult(dbconn);
b263aa79 609
ee8cd7d0 610 if (!dbquerysuccessful(pgres)) {
b263aa79 611 Error("chanserv",ERR_ERROR,"Error loading language list.");
612 return;
613 }
614
ee8cd7d0 615 if (dbnumfields(pgres)!=3) {
b263aa79 616 Error("chanserv",ERR_ERROR,"Language list format error.");
617 return;
618 }
619
ee8cd7d0
CP
620 while(dbfetchrow(pgres)) {
621 j=strtol(dbgetvalue(pgres,0),NULL,10);
b263aa79 622 if (j<MAXLANG && j>=0) {
623 cslanguages[j]=(cslang *)malloc(sizeof(cslang));
624
ee8cd7d0
CP
625 strncpy(cslanguages[j]->code,dbgetvalue(pgres,1),2); cslanguages[j]->code[2]='\0';
626 cslanguages[j]->name=getsstring(dbgetvalue(pgres,2),30);
b263aa79 627 }
628 }
629
ee8cd7d0 630 dbclear(pgres);
b263aa79 631
632 if (i>MAXLANG)
633 Error("chanserv",ERR_ERROR,"Found too many languages (%d > %d)",i,MAXLANG);
634
ee8cd7d0 635 dbasyncquery(loadmessages_part2, NULL, "SELECT * from chanserv.messages");
b263aa79 636}
637
ee8cd7d0
CP
638void loadmessages_part2(DBConn *dbconn, void *arg) {
639 DBResult *pgres;
640 int j,k;
b263aa79 641
ee8cd7d0 642 pgres=dbgetresult(dbconn);
b263aa79 643
ee8cd7d0 644 if (!dbquerysuccessful(pgres)) {
b263aa79 645 Error("chanserv",ERR_ERROR,"Error loading message list.");
646 return;
647 }
648
ee8cd7d0 649 if (dbnumfields(pgres)!=3) {
b263aa79 650 Error("chanserv",ERR_ERROR,"Message list format error.");
651 return;
652 }
653
ee8cd7d0
CP
654 while(dbfetchrow(pgres)) {
655 k=strtol(dbgetvalue(pgres,0),NULL,10);
656 j=strtol(dbgetvalue(pgres,1),NULL,10);
b263aa79 657
658 if (k<0 || k >= MAXLANG) {
659 Error("chanserv",ERR_WARNING,"Language ID out of range on message: %d",k);
660 continue;
661 }
662
663 if (j<0 || j >= MAXMESSAGES) {
664 Error("chanserv",ERR_WARNING,"Message ID out of range on message: %d",j);
665 continue;
666 }
667
ee8cd7d0 668 csmessages[k][j]=getsstring(dbgetvalue(pgres,2),250);
b263aa79 669 }
670
ee8cd7d0 671 dbclear(pgres);
b263aa79 672}
673
674void loadcommandsummary(Command *cmd) {
ee8cd7d0 675 dbasyncquery(loadcommandsummary_real, (void *)cmd,
522e2b8c 676 "SELECT languageID,summary from chanserv.help where lower(command) = lower('%s')",cmd->command->content);
b263aa79 677}
678
ee8cd7d0
CP
679void loadcommandsummary_real(DBConn *dbconn, void *arg) {
680 int i,j;
681 DBResult *pgres;
b263aa79 682 cmdsummary *cs;
683 Command *cmd=arg;
684
685 /* Clear up old text first */
686 cs=cmd->ext;
687 for (i=0;i<MAXLANG;i++) {
688 if (cs->bylang[i])
689 freesstring(cs->bylang[i]);
690 }
691
ee8cd7d0 692 pgres=dbgetresult(dbconn);
b263aa79 693
ee8cd7d0 694 if (!dbquerysuccessful(pgres)) {
b263aa79 695 Error("chanserv",ERR_ERROR,"Error loading command summary.");
696 return;
697 }
698
ee8cd7d0 699 if (dbnumfields(pgres)!=2) {
b263aa79 700 Error("chanserv",ERR_ERROR,"Command summary format error.");
ee8cd7d0 701 dbclear(pgres);
b263aa79 702 return;
703 }
704
ee8cd7d0
CP
705 while(dbfetchrow(pgres)) {
706 j=strtol(dbgetvalue(pgres,0),NULL,10);
b263aa79 707 if (j<MAXLANG && j>=0) {
ee8cd7d0 708 cs->bylang[j]=getsstring(dbgetvalue(pgres,1),200);
b263aa79 709 }
710 }
711
ee8cd7d0 712 dbclear(pgres);
b263aa79 713}
714
715void csdb_freestuff() {
716 int i;
717 chanindex *cip, *ncip;
718 regchan *rcp;
719 reguser *rup;
720 regchanuser *rcup;
721 regban *rbp;
e3805f60 722 maildomain *mdp;
97390b65 723 maillock *mlp, *nmlp;
b263aa79 724
725 for (i=0;i<REGUSERHASHSIZE;i++) {
726 for (rup=regusernicktable[i];rup;rup=rup->nextbyname) {
727 freesstring(rup->email);
b4d3e4be 728 freesstring(rup->localpart);
9708f78f 729 freesstring(rup->lastemail);
b263aa79 730 freesstring(rup->lastuserhost);
731 freesstring(rup->suspendreason);
732 freesstring(rup->comment);
733 freesstring(rup->info);
734
735 for (rcup=rup->knownon;rcup;rcup=rcup->nextbyuser)
736 freesstring(rcup->info);
737 }
738 }
739
740 for (i=0;i<CHANNELHASHSIZE;i++) {
741 for (cip=chantable[i];cip;cip=ncip) {
742 ncip=cip->next;
743 if ((rcp=cip->exts[chanservext])) {
744 freesstring(rcp->welcome);
745 freesstring(rcp->topic);
746 freesstring(rcp->key);
747 freesstring(rcp->suspendreason);
748 freesstring(rcp->comment);
749 for (rbp=rcp->bans;rbp;rbp=rbp->next) {
750 freesstring(rbp->reason);
751 freechanban(rbp->cbp);
752 }
753 cip->exts[chanservext]=NULL;
754 releasechanindex(cip);
755 }
756 }
757 }
e3805f60
P
758
759 for (i=0; i<MAILDOMAINHASHSIZE; i++) {
760 for (mdp=maildomainnametable[i]; mdp; mdp=mdp->nextbyname)
761 freesstring(mdp->name);
762 }
97390b65
CP
763
764 for(mlp=maillocks;mlp;mlp=nmlp) {
765 nmlp=mlp->next;
766 freemaillock(mlp);
767 }
768 maillocks=NULL;
e3805f60
P
769}
770
ee8cd7d0
CP
771void loadsomemaildomains(DBConn *dbconn,void *arg) {
772 DBResult *pgres;
e3805f60 773 maildomain *mdp;
e3805f60 774 char *domain;
ee8cd7d0 775 pgres=dbgetresult(dbconn);
e3805f60 776
ee8cd7d0 777 if (!dbquerysuccessful(pgres)) {
e3805f60
P
778 Error("chanserv",ERR_ERROR,"Error loading maildomain DB");
779 return;
ee8cd7d0 780 }
e3805f60 781
ee8cd7d0 782 if (dbnumfields(pgres)!=5) {
e3805f60 783 Error("chanserv",ERR_ERROR,"Mail Domain DB format error");
ee8cd7d0 784 dbclear(pgres);
e3805f60
P
785 return;
786 }
e3805f60
P
787 lastdomainID=0;
788
ee8cd7d0
CP
789 while(dbfetchrow(pgres)) {
790 domain=dbgetvalue(pgres,1);
e3805f60
P
791 mdp=findorcreatemaildomain(domain); //@@@ LEN
792
ee8cd7d0
CP
793 mdp->ID=strtoul(dbgetvalue(pgres,0),NULL,10);
794 mdp->limit=strtoul(dbgetvalue(pgres,2),NULL,10);
795 mdp->actlimit=strtoul(dbgetvalue(pgres,3),NULL,10);
796 mdp->flags=strtoul(dbgetvalue(pgres,4),NULL,10);
e3805f60
P
797
798 if (mdp->ID > lastdomainID) {
799 lastdomainID=mdp->ID;
800 }
801 }
802
ee8cd7d0 803 dbclear(pgres);
e3805f60
P
804}
805
ee8cd7d0 806void loadmaildomainsdone(DBConn *dbconn, void *arg) {
e3805f60 807 Error("chanserv",ERR_INFO,"Load Mail Domains done (highest ID was %d)",lastdomainID);
b263aa79 808}
e3805f60 809
ee8cd7d0
CP
810void loadsomemaillocks(DBConn *dbconn,void *arg) {
811 DBResult *pgres;
97390b65 812 maillock *mlp;
ee8cd7d0 813 pgres=dbgetresult(dbconn);
97390b65 814
ee8cd7d0 815 if (!dbquerysuccessful(pgres)) {
97390b65
CP
816 Error("chanserv",ERR_ERROR,"Error loading maillock DB");
817 return;
ee8cd7d0 818 }
97390b65 819
ee8cd7d0 820 if (dbnumfields(pgres)!=5) {
97390b65 821 Error("chanserv",ERR_ERROR,"Maillock DB format error");
ee8cd7d0 822 dbclear(pgres);
97390b65
CP
823 return;
824 }
97390b65
CP
825 lastmaillockID=0;
826
ee8cd7d0 827 while(dbfetchrow(pgres)) {
97390b65 828 mlp=getmaillock();
ee8cd7d0
CP
829 mlp->id=strtoul(dbgetvalue(pgres,0),NULL,10);
830 mlp->pattern=getsstring(dbgetvalue(pgres,1), 300);
831 mlp->reason=getsstring(dbgetvalue(pgres,2), 300);
832 mlp->createdby=strtoul(dbgetvalue(pgres,3),NULL,10);
833 mlp->created=strtoul(dbgetvalue(pgres,4),NULL,10);
97390b65
CP
834 mlp->next=maillocks;
835 maillocks=mlp;
836
837 if (mlp->id > lastmaillockID)
838 lastmaillockID=mlp->id;
839 }
840
ee8cd7d0 841 dbclear(pgres);
97390b65
CP
842}
843
ee8cd7d0 844void loadmaillocksdone(DBConn *dbconn, void *arg) {
97390b65 845 Error("chanserv",ERR_INFO,"Load Mail Locks done (highest ID was %d)",lastmaillockID);
136d271d
P
846
847 chanservdb_ready=1;
848 triggerhook(HOOK_CHANSERV_DBLOADED, NULL);
97390b65
CP
849}
850