]>
jfr.im git - irc/quakenet/newserv.git/blob - chanserv/database/chanservdb.c
3 * Handles the SQL stuff for the channel service.
6 #include "../chanserv.h"
7 #include "../../pqsql/pqsql.h"
8 #include "../../core/config.h"
9 #include "../../lib/sstring.h"
10 #include "../../parser/parser.h"
11 #include "../../core/events.h"
12 #include "../../core/nsmalloc.h"
13 #include "../../lib/strlfunc.h"
23 typedef struct tabledesc
{
24 sstring
*tablename
; /* Name of table */
25 PQQueryHandler init
; /* Function to be called when transaction opens */
26 PQQueryHandler data
; /* Function to be called to load data */
27 PQQueryHandler fini
; /* Function to be called to clean up */
36 unsigned int lastchannelID
;
37 unsigned int lastuserID
;
38 unsigned int lastbanID
;
39 unsigned int lastdomainID
;
40 unsigned int lastmaillockID
;
42 /* Local prototypes */
43 void csdb_handlestats(int hooknum
, void *arg
);
44 void loadmessages_part1(PGconn
*, void *);
45 void loadmessages_part2(PGconn
*, void *);
46 void loadcommandsummary_real(PGconn
*, void *);
48 /* Generic loading functions */
49 void loadall(char *, PQQueryHandler
, PQQueryHandler
, PQQueryHandler
);
50 void doloadall(PGconn
*, void *);
52 /* User loading functions */
53 void loadsomeusers(PGconn
*, void *);
54 void loadusersdone(PGconn
*, void *);
56 /* Channel loading functions */
57 void loadsomechannels(PGconn
*, void *);
58 void loadchannelsdone(PGconn
*, void *);
60 /* Chanuser loading functions */
61 void loadchanusersinit(PGconn
*, void *);
62 void loadsomechanusers(PGconn
*, void *);
63 void loadchanusersdone(PGconn
*, void *);
65 /* Chanban loading functions */
66 void loadsomechanbans(PGconn
*, void *);
67 void loadchanbansdone(PGconn
*, void *);
69 /* Mail Domain loading functions */
70 void loadsomemaildomains(PGconn
*, void *);
71 void loadmaildomainsdone(PGconn
*, void *);
73 /* Mail lock loading functions */
74 void loadsomemaillocks(PGconn
*, void *);
75 void loadmaillocksdone(PGconn
*, void *);
77 /* Free sstrings in the structures */
78 void csdb_freestuff();
80 static void setuptables() {
81 /* Set up the tables */
83 pqcreatequery("CREATE TABLE users ("
85 "username VARCHAR(16) NOT NULL,"
86 "created INT NOT NULL,"
87 "lastauth INT NOT NULL,"
88 "lastemailchng INT NOT NULL,"
90 "language INT NOT NULL,"
91 "suspendby INT NOT NULL,"
92 "suspendexp INT NOT NULL,"
93 "suspendtime INT NOT NULL,"
94 "lockuntil INT NOT NULL,"
95 "password VARCHAR(11) NOT NULL,"
97 "lastemail VARCHAR(100),"
98 "lastuserhost VARCHAR(75),"
99 "suspendreason VARCHAR(250),"
100 "comment VARCHAR(250),"
102 "PRIMARY KEY (ID))");
104 pqcreatequery("CREATE INDEX user_username_index ON users (username)");
107 pqcreatequery("CREATE TABLE channels ("
109 "name VARCHAR(250) NOT NULL,"
110 "flags INT NOT NULL,"
111 "forcemodes INT NOT NULL,"
112 "denymodes INT NOT NULL,"
113 "chanlimit INT NOT NULL,"
114 "autolimit INT NOT NULL,"
115 "banstyle INT NOT NULL,"
116 "created INT NOT NULL,"
117 "lastactive INT NOT NULL,"
118 "statsreset INT NOT NULL,"
119 "banduration INT NOT NULL,"
120 "founder INT NOT NULL,"
121 "addedby INT NOT NULL,"
122 "suspendby INT NOT NULL,"
123 "suspendtime INT NOT NULL,"
124 "chantype SMALLINT NOT NULL,"
125 "totaljoins INT NOT NULL,"
126 "tripjoins INT NOT NULL,"
127 "maxusers INT NOT NULL,"
128 "tripusers INT NOT NULL,"
129 "welcome VARCHAR(500),"
130 "topic VARCHAR(250),"
131 "chankey VARCHAR(23),"
132 "suspendreason VARCHAR(250),"
133 "comment VARCHAR(250),"
135 "PRIMARY KEY (ID))");
138 pqcreatequery("CREATE TABLE chanusers ("
139 "userID INT NOT NULL,"
140 "channelID INT NOT NULL,"
141 "flags INT NOT NULL,"
142 "changetime INT NOT NULL,"
143 "usetime INT NOT NULL,"
144 "info VARCHAR(100) NOT NULL,"
145 "PRIMARY KEY (userID, channelID))");
147 pqcreatequery("CREATE INDEX chanusers_userID_index on chanusers (userID)");
148 pqcreatequery("CREATE INDEX chanusers_channelID_index on chanusers (channelID)");
150 pqcreatequery("CREATE TABLE bans ("
151 "banID INT NOT NULL," /* Unique number for the ban to make
152 DELETEs process in finite time.. */
153 "channelID INT NOT NULL,"
154 "userID INT NOT NULL," /* Who set the ban.. */
155 "hostmask VARCHAR(100) NOT NULL," /* needs to be at least USERLEN+NICKLEN+HOSTLEN+2 */
156 "expiry INT NOT NULL,"
157 "reason VARCHAR(200),"
158 "PRIMARY KEY(banID))");
160 pqcreatequery("CREATE INDEX bans_channelID_index on bans (channelID)");
162 pqcreatequery("CREATE TABLE languages ("
163 "languageID INT NOT NULL,"
164 "code VARCHAR(2) NOT NULL,"
165 "name VARCHAR(30) NOT NULL)");
167 pqcreatequery("CREATE TABLE messages ("
168 "languageID INT NOT NULL,"
169 "messageID INT NOT NULL,"
170 "message VARCHAR(250) NOT NULL,"
171 "PRIMARY KEY (languageID, messageID))");
173 pqcreatequery("CREATE TABLE help ("
174 "commandID INT NOT NULL,"
175 "command VARCHAR(30) NOT NULL,"
176 "languageID INT NOT NULL,"
177 "summary VARCHAR(200) NOT NULL,"
178 "fullinfo TEXT NOT NULL,"
179 "PRIMARY KEY (commandID, languageID))");
181 pqcreatequery("CREATE TABLE email ("
182 "userID INT NOT NULL,"
183 "emailtype INT NOT NULL,"
184 "prevEmail VARCHAR(100),"
186 "PRIMARY KEY (mailID))");
188 pqcreatequery("CREATE TABLE maildomain ("
190 "name VARCHAR NOT NULL,"
191 "domainlimit INT NOT NULL,"
192 "actlimit INT NOT NULL,"
193 "flags INT NOT NULL,"
194 "PRIMARY KEY (ID))");
196 pqcreatequery("CREATE TABLE authhistory ("
197 "userID INT NOT NULL,"
198 "nick VARCHAR(15) NOT NULL,"
199 "username VARCHAR(10) NOT NULL,"
200 "host VARCHAR(63) NOT NULL,"
201 "authtime INT NOT NULL,"
202 "disconnecttime INT NOT NULL,"
203 "numeric INT NOT NULL,"
204 "quitreason VARCHAR(100) ,"
205 "PRIMARY KEY (userID, authtime))");
207 pqcreatequery("CREATE INDEX authhistory_userID_index on authhistory(userID)");
208 pqcreatequery("CREATE TABLE chanlevhistory ("
209 "userID INT NOT NULL,"
210 "channelID INT NOT NULL,"
211 "targetID INT NOT NULL,"
212 "changetime INT NOT NULL,"
213 "authtime INT NOT NULL,"
214 "oldflags INT NOT NULL,"
215 "newflags INT NOT NULL)");
217 pqcreatequery("CREATE INDEX chanlevhistory_userID_index on chanlevhistory(userID)");
218 pqcreatequery("CREATE INDEX chanlevhistory_channelID_index on chanlevhistory(channelID)");
219 pqcreatequery("CREATE INDEX chanlevhistory_targetID_index on chanlevhistory(targetID)");
221 pqcreatequery("CREATE TABLE accounthistory ("
222 "userID INT NOT NULL,"
223 "changetime INT NOT NULL,"
224 "authtime INT NOT NULL,"
225 "oldpassword VARCHAR(11),"
226 "newpassword VARCHAR(11),"
227 "oldemail VARCHAR(100),"
228 "newemail VARCHAR(100),"
229 "PRIMARY KEY (userID, changetime))");
231 pqcreatequery("CREATE INDEX accounthistory_userID_index on accounthistory(userID)");
233 pqcreatequery("CREATE TABLE maillocks ("
235 "pattern VARCHAR NOT NULL,"
236 "reason VARCHAR NOT NULL,"
237 "createdby INT NOT NULL,"
238 "created INT NOT NULL,"
239 "PRIMARY KEY (ID))");
243 chanservext
=registerchanext("chanserv");
244 chanservaext
=registerauthnameext("chanserv");
246 /* Set up the allocators and hashes */
250 /* And the messages */
253 if (pqconnected() && (chanservext
!=-1) && (chanservaext
!=-1)) {
254 registerhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
258 lastuserID
=lastchannelID
=lastdomainID
=0;
260 loadall("users",NULL
,loadsomeusers
,loadusersdone
);
261 loadall("channels",NULL
,loadsomechannels
,loadchannelsdone
);
262 loadall("chanusers",loadchanusersinit
,loadsomechanusers
,loadchanusersdone
);
263 loadall("bans",NULL
,loadsomechanbans
,loadchanbansdone
);
264 loadall("maildomain",NULL
, loadsomemaildomains
,loadmaildomainsdone
);
265 loadall("maillocks",NULL
, loadsomemaillocks
,loadmaillocksdone
);
272 deregisterhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
277 releasechanext(chanservext
);
279 if (chanservaext
!=-1)
280 releaseauthnameext(chanservaext
);
282 nsfreeall(POOL_CHANSERVDB
);
285 void csdb_handlestats(int hooknum
, void *arg
) {
286 /* long level=(long)arg; */
288 /* Keeping options open here */
291 void chanservdbclose() {
293 deregisterhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
299 * Generic function to handle load of an entire table..
302 void loadall(char *table
, PQQueryHandler init
, PQQueryHandler data
, PQQueryHandler fini
) {
305 thedesc
=malloc(sizeof(tabledesc
));
307 thedesc
->tablename
=getsstring(table
,100);
312 pqasyncquery(doloadall
, thedesc
, "SELECT count(*) FROM %s",thedesc
->tablename
->content
);
315 void doloadall(PGconn
*dbconn
, void *arg
) {
318 tabledesc
*thedesc
=arg
;
320 pgres
=PQgetResult(dbconn
);
322 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
323 Error("chanserv",ERR_ERROR
,"Error getting row count for %s.",thedesc
->tablename
->content
);
327 if (PQnfields(pgres
)!=1) {
328 Error("chanserv",ERR_ERROR
,"Count query format error for %s.",thedesc
->tablename
->content
);
332 count
=strtoul(PQgetvalue(pgres
,0,0),NULL
,10);
336 Error("chanserv",ERR_INFO
,"Found %d entries in table %s, scheduling load.",count
,
337 thedesc
->tablename
->content
);
339 pqasyncquery(thedesc
->init
, NULL
, "BEGIN");
340 pqquery("DECLARE mycurs CURSOR FOR SELECT * from %s",
341 thedesc
->tablename
->content
);
343 for (i
=0;(count
-i
)>1000;i
+=1000) {
344 pqasyncquery(thedesc
->data
, NULL
, "FETCH 1000 FROM mycurs");
347 pqasyncquery(thedesc
->data
, NULL
, "FETCH ALL FROM mycurs");
349 pqquery("CLOSE mycurs");
350 pqasyncquery(thedesc
->fini
, NULL
, "COMMIT");
352 /* Free structures.. */
353 freesstring(thedesc
->tablename
);
359 * Loads some users in from the SQL DB
362 void loadsomeusers(PGconn
*dbconn
, void *arg
) {
369 pgres
=PQgetResult(dbconn
);
371 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
372 Error("chanserv",ERR_ERROR
,"Error loading user DB");
376 if (PQnfields(pgres
)!=18) {
377 Error("chanserv",ERR_ERROR
,"User DB format error");
381 num
=PQntuples(pgres
);
386 rup
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
387 strncpy(rup
->username
,PQgetvalue(pgres
,i
,1),NICKLEN
); rup
->username
[NICKLEN
]='\0';
388 rup
->created
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
389 rup
->lastauth
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
390 rup
->lastemailchange
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
391 rup
->flags
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
392 rup
->languageid
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
393 rup
->suspendby
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
394 rup
->suspendexp
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
395 rup
->suspendtime
=strtoul(PQgetvalue(pgres
,i
,9),NULL
,10);
396 rup
->lockuntil
=strtoul(PQgetvalue(pgres
,i
,10),NULL
,10);
397 strncpy(rup
->password
,PQgetvalue(pgres
,i
,11),PASSLEN
); rup
->password
[PASSLEN
]='\0';
398 rup
->email
=getsstring(PQgetvalue(pgres
,i
,12),100);
400 rup
->domain
=findorcreatemaildomain(rup
->email
->content
);
401 addregusertomaildomain(rup
, rup
->domain
);
403 strlcpy(mailbuf
, rup
->email
->content
, sizeof(mailbuf
));
404 if((local
=strchr(mailbuf
, '@'))) {
406 rup
->localpart
=getsstring(mailbuf
,EMAILLEN
);
414 rup
->lastemail
=getsstring(PQgetvalue(pgres
,i
,13),100);
415 rup
->lastuserhost
=getsstring(PQgetvalue(pgres
,i
,14),75);
416 rup
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,15),250);
417 rup
->comment
=getsstring(PQgetvalue(pgres
,i
,16),250);
418 rup
->info
=getsstring(PQgetvalue(pgres
,i
,17),100);
423 addregusertohash(rup
);
425 if (rup
->ID
> lastuserID
) {
433 void loadusersdone(PGconn
*conn
, void *arg
) {
434 Error("chanserv",ERR_INFO
,"Load users done (highest ID was %d)",lastuserID
);
438 * Channel loading functions
441 void loadsomechannels(PGconn
*dbconn
, void *arg
) {
446 time_t now
=time(NULL
);
448 pgres
=PQgetResult(dbconn
);
450 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
451 Error("chanserv",ERR_ERROR
,"Error loading channel DB");
455 if (PQnfields(pgres
)!=27) {
456 Error("chanserv",ERR_ERROR
,"Channel DB format error");
460 num
=PQntuples(pgres
);
463 cip
=findorcreatechanindex(PQgetvalue(pgres
,i
,1));
464 if (cip
->exts
[chanservext
]) {
465 Error("chanserv",ERR_WARNING
,"%s in database twice - this WILL cause problems later.",cip
->name
->content
);
469 cip
->exts
[chanservext
]=rcp
;
471 rcp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
473 rcp
->flags
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
474 rcp
->status
=0; /* Non-DB field */
476 rcp
->lastcountersync
=now
;
479 rcp
->forcemodes
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
480 rcp
->denymodes
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
481 rcp
->limit
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
482 rcp
->autolimit
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
483 rcp
->banstyle
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
484 rcp
->created
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
485 rcp
->lastactive
=strtoul(PQgetvalue(pgres
,i
,9),NULL
,10);
486 rcp
->statsreset
=strtoul(PQgetvalue(pgres
,i
,10),NULL
,10);
487 rcp
->banduration
=strtoul(PQgetvalue(pgres
,i
,11),NULL
,10);
488 rcp
->founder
=strtol(PQgetvalue(pgres
,i
,12),NULL
,10);
489 rcp
->addedby
=strtol(PQgetvalue(pgres
,i
,13),NULL
,10);
490 rcp
->suspendby
=strtol(PQgetvalue(pgres
,i
,14),NULL
,10);
491 rcp
->suspendtime
=strtol(PQgetvalue(pgres
,i
,15),NULL
,10);
492 rcp
->chantype
=strtoul(PQgetvalue(pgres
,i
,16),NULL
,10);
493 rcp
->totaljoins
=strtoul(PQgetvalue(pgres
,i
,17),NULL
,10);
494 rcp
->tripjoins
=strtoul(PQgetvalue(pgres
,i
,18),NULL
,10);
495 rcp
->maxusers
=strtoul(PQgetvalue(pgres
,i
,19),NULL
,10);
496 rcp
->tripusers
=strtoul(PQgetvalue(pgres
,i
,20),NULL
,10);
497 rcp
->welcome
=getsstring(PQgetvalue(pgres
,i
,21),500);
498 rcp
->topic
=getsstring(PQgetvalue(pgres
,i
,22),TOPICLEN
);
499 rcp
->key
=getsstring(PQgetvalue(pgres
,i
,23),KEYLEN
);
500 rcp
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,24),250);
501 rcp
->comment
=getsstring(PQgetvalue(pgres
,i
,25),250);
502 rcp
->checksched
=NULL
;
503 rcp
->ltimestamp
=strtoul(PQgetvalue(pgres
,i
,26),NULL
,10);
504 memset(rcp
->regusers
,0,REGCHANUSERHASHSIZE
*sizeof(reguser
*));
506 if (rcp
->ID
> lastchannelID
)
507 lastchannelID
=rcp
->ID
;
509 if (CIsAutoLimit(rcp
))
512 for (j
=0;j
<CHANOPHISTORY
;j
++) {
513 rcp
->chanopnicks
[j
][0]='\0';
514 rcp
->chanopaccts
[j
]=0;
522 void loadchannelsdone(PGconn
*dbconn
, void *arg
) {
523 Error("chanserv",ERR_INFO
,"Channel load done (highest ID was %d)",lastchannelID
);
526 void loadchanusersinit(PGconn
*dbconn
, void *arg
) {
531 allchans
=(regchan
**)malloc((lastchannelID
+1)*sizeof(regchan
*));
532 memset(allchans
,0,(lastchannelID
+1)*sizeof(regchan
*));
533 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
534 for (cip
=chantable
[i
];cip
;cip
=cip
->next
) {
535 if (cip
->exts
[chanservext
]) {
536 rcp
=(regchan
*)cip
->exts
[chanservext
];
537 allchans
[rcp
->ID
]=rcp
;
543 void loadsomechanusers(PGconn
*dbconn
, void *arg
) {
553 /* Set up the allchans array */
554 pgres
=PQgetResult(dbconn
);
556 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
557 Error("chanserv",ERR_ERROR
,"Error loading chanusers.");
561 if (PQnfields(pgres
)!=6) {
562 Error("chanserv",ERR_ERROR
,"Chanusers format error");
566 num
=PQntuples(pgres
);
569 uid
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
570 cid
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
572 if (!(anp
=findauthname(uid
)) || !(rup
=anp
->exts
[chanservaext
])) {
573 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown user %d",uid
);
577 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
578 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown chan %d",cid
);
582 if (rup
==NULL
|| rcp
==NULL
) {
583 Error("chanserv",ERR_ERROR
,"Can't add user %s on channel %s",
584 PQgetvalue(pgres
,i
,0),PQgetvalue(pgres
,i
,1));
586 rcup
=getregchanuser();
589 rcup
->flags
=strtol(PQgetvalue(pgres
,i
,2),NULL
,10);
590 rcup
->changetime
=strtol(PQgetvalue(pgres
,i
,3),NULL
,10);
591 rcup
->usetime
=strtol(PQgetvalue(pgres
,i
,4),NULL
,10);
592 rcup
->info
=getsstring(PQgetvalue(pgres
,i
,5),100);
593 addregusertochannel(rcup
);
601 void loadchanusersdone(PGconn
*dbconn
, void *arg
) {
602 Error("chanserv",ERR_INFO
,"Channel user load done.");
605 void loadsomechanbans(PGconn
*dbconn
, void *arg
) {
614 pgres
=PQgetResult(dbconn
);
616 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
617 Error("chanserv",ERR_ERROR
,"Error loading bans.");
621 if (PQnfields(pgres
)!=6) {
622 Error("chanserv",ERR_ERROR
,"Ban format error");
626 num
=PQntuples(pgres
);
631 bid
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
632 cid
=strtoul(PQgetvalue(pgres
,i
,1),NULL
,10);
633 uid
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
634 expiry
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
636 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
637 Error("chanserv",ERR_WARNING
,"Skipping ban for unknown chan %d",cid
);
645 rbp
->reason
=getsstring(PQgetvalue(pgres
,i
,5),200);
646 rbp
->cbp
=makeban(PQgetvalue(pgres
,i
,3));
659 void loadchanbansdone(PGconn
*dbconn
, void *arg
) {
662 Error("chanserv",ERR_INFO
,"Channel ban load done, highest ID was %d",lastbanID
);
665 triggerhook(HOOK_CHANSERV_DBLOADED
, NULL
);
668 void loadmessages() {
669 pqasyncquery(loadmessages_part1
, NULL
, "SELECT * from languages");
672 void loadmessages_part1(PGconn
*dbconn
, void *arg
) {
677 /* Firstly, clear up any stale messages */
678 for (i
=0;i
<MAXLANG
;i
++) {
679 if (cslanguages
[i
]) {
680 freesstring(cslanguages
[i
]->name
);
681 free(cslanguages
[i
]);
683 for (j
=0;j
<MAXMESSAGES
;j
++) {
684 if (csmessages
[i
][j
]) {
685 freesstring(csmessages
[i
][j
]);
686 csmessages
[i
][j
]=NULL
;
691 pgres
=PQgetResult(dbconn
);
693 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
694 Error("chanserv",ERR_ERROR
,"Error loading language list.");
698 if (PQnfields(pgres
)!=3) {
699 Error("chanserv",ERR_ERROR
,"Language list format error.");
703 num
=PQntuples(pgres
);
705 for (i
=0;i
<num
;i
++) {
706 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
707 if (j
<MAXLANG
&& j
>=0) {
708 cslanguages
[j
]=(cslang
*)malloc(sizeof(cslang
));
710 strncpy(cslanguages
[j
]->code
,PQgetvalue(pgres
,i
,1),2); cslanguages
[j
]->code
[2]='\0';
711 cslanguages
[j
]->name
=getsstring(PQgetvalue(pgres
,i
,2),30);
718 Error("chanserv",ERR_ERROR
,"Found too many languages (%d > %d)",i
,MAXLANG
);
720 pqasyncquery(loadmessages_part2
, NULL
, "SELECT * from messages");
723 void loadmessages_part2(PGconn
*dbconn
, void *arg
) {
727 pgres
=PQgetResult(dbconn
);
729 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
730 Error("chanserv",ERR_ERROR
,"Error loading message list.");
734 if (PQnfields(pgres
)!=3) {
735 Error("chanserv",ERR_ERROR
,"Message list format error.");
739 num
=PQntuples(pgres
);
741 for (i
=0;i
<num
;i
++) {
742 k
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
743 j
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
745 if (k
<0 || k
>= MAXLANG
) {
746 Error("chanserv",ERR_WARNING
,"Language ID out of range on message: %d",k
);
750 if (j
<0 || j
>= MAXMESSAGES
) {
751 Error("chanserv",ERR_WARNING
,"Message ID out of range on message: %d",j
);
755 csmessages
[k
][j
]=getsstring(PQgetvalue(pgres
,i
,2),250);
761 void loadcommandsummary(Command
*cmd
) {
762 pqasyncquery(loadcommandsummary_real
, (void *)cmd
,
763 "SELECT languageID,summary from help where lower(command) = lower('%s')",cmd
->command
->content
);
766 void loadcommandsummary_real(PGconn
*dbconn
, void *arg
) {
772 /* Clear up old text first */
774 for (i
=0;i
<MAXLANG
;i
++) {
776 freesstring(cs
->bylang
[i
]);
779 pgres
=PQgetResult(dbconn
);
781 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
782 Error("chanserv",ERR_ERROR
,"Error loading command summary.");
786 if (PQnfields(pgres
)!=2) {
787 Error("chanserv",ERR_ERROR
,"Command summary format error.");
792 num
=PQntuples(pgres
);
794 for (i
=0;i
<num
;i
++) {
795 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
796 if (j
<MAXLANG
&& j
>=0) {
797 cs
->bylang
[j
]=getsstring(PQgetvalue(pgres
,i
,1),200);
804 void csdb_freestuff() {
806 chanindex
*cip
, *ncip
;
812 maillock
*mlp
, *nmlp
;
814 for (i
=0;i
<REGUSERHASHSIZE
;i
++) {
815 for (rup
=regusernicktable
[i
];rup
;rup
=rup
->nextbyname
) {
816 freesstring(rup
->email
);
817 freesstring(rup
->localpart
);
818 freesstring(rup
->lastemail
);
819 freesstring(rup
->lastuserhost
);
820 freesstring(rup
->suspendreason
);
821 freesstring(rup
->comment
);
822 freesstring(rup
->info
);
824 for (rcup
=rup
->knownon
;rcup
;rcup
=rcup
->nextbyuser
)
825 freesstring(rcup
->info
);
829 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
830 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
832 if ((rcp
=cip
->exts
[chanservext
])) {
833 freesstring(rcp
->welcome
);
834 freesstring(rcp
->topic
);
835 freesstring(rcp
->key
);
836 freesstring(rcp
->suspendreason
);
837 freesstring(rcp
->comment
);
838 for (rbp
=rcp
->bans
;rbp
;rbp
=rbp
->next
) {
839 freesstring(rbp
->reason
);
840 freechanban(rbp
->cbp
);
842 cip
->exts
[chanservext
]=NULL
;
843 releasechanindex(cip
);
848 for (i
=0; i
<MAILDOMAINHASHSIZE
; i
++) {
849 for (mdp
=maildomainnametable
[i
]; mdp
; mdp
=mdp
->nextbyname
)
850 freesstring(mdp
->name
);
853 for(mlp
=maillocks
;mlp
;mlp
=nmlp
) {
860 void loadsomemaildomains(PGconn
*dbconn
,void *arg
) {
865 pgres
=PQgetResult(dbconn
);
867 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
868 Error("chanserv",ERR_ERROR
,"Error loading maildomain DB");
872 if (PQnfields(pgres
)!=5) {
873 Error("chanserv",ERR_ERROR
,"Mail Domain DB format error");
876 num
=PQntuples(pgres
);
880 domain
=PQgetvalue(pgres
,i
,1);
881 mdp
=findorcreatemaildomain(domain
); //@@@ LEN
883 mdp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
884 mdp
->limit
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
885 mdp
->actlimit
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
886 mdp
->flags
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
888 if (mdp
->ID
> lastdomainID
) {
889 lastdomainID
=mdp
->ID
;
896 void loadmaildomainsdone(PGconn
*dbconn
, void *arg
) {
897 Error("chanserv",ERR_INFO
,"Load Mail Domains done (highest ID was %d)",lastdomainID
);
900 void loadsomemaillocks(PGconn
*dbconn
,void *arg
) {
904 pgres
=PQgetResult(dbconn
);
906 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
907 Error("chanserv",ERR_ERROR
,"Error loading maillock DB");
911 if (PQnfields(pgres
)!=5) {
912 Error("chanserv",ERR_ERROR
,"Maillock DB format error");
915 num
=PQntuples(pgres
);
920 mlp
->id
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
921 mlp
->pattern
=getsstring(PQgetvalue(pgres
,i
,1), 300);
922 mlp
->reason
=getsstring(PQgetvalue(pgres
,i
,2), 300);
923 mlp
->createdby
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
924 mlp
->created
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
928 if (mlp
->id
> lastmaillockID
)
929 lastmaillockID
=mlp
->id
;
935 void loadmaillocksdone(PGconn
*dbconn
, void *arg
) {
936 Error("chanserv",ERR_INFO
,"Load Mail Locks done (highest ID was %d)",lastmaillockID
);