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