]>
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"
22 typedef struct tabledesc
{
23 sstring
*tablename
; /* Name of table */
24 PQQueryHandler init
; /* Function to be called when transaction opens */
25 PQQueryHandler data
; /* Function to be called to load data */
26 PQQueryHandler fini
; /* Function to be called to clean up */
34 unsigned int lastchannelID
;
35 unsigned int lastuserID
;
36 unsigned int lastbanID
;
37 unsigned int lastdomainID
;
39 /* Local prototypes */
40 void csdb_handlestats(int hooknum
, void *arg
);
41 void loadmessages_part1(PGconn
*, void *);
42 void loadmessages_part2(PGconn
*, void *);
43 void loadcommandsummary_real(PGconn
*, void *);
45 /* Generic loading functions */
46 void loadall(char *, PQQueryHandler
, PQQueryHandler
, PQQueryHandler
);
47 void doloadall(PGconn
*, void *);
49 /* User loading functions */
50 void loadsomeusers(PGconn
*, void *);
51 void loadusersdone(PGconn
*, void *);
53 /* Channel loading functions */
54 void loadsomechannels(PGconn
*, void *);
55 void loadchannelsdone(PGconn
*, void *);
57 /* Chanuser loading functions */
58 void loadchanusersinit(PGconn
*, void *);
59 void loadsomechanusers(PGconn
*, void *);
60 void loadchanusersdone(PGconn
*, void *);
62 /* Chanban loading functions */
63 void loadsomechanbans(PGconn
*, void *);
64 void loadchanbansdone(PGconn
*, void *);
66 /* Mail Domain loading functions */
67 void loadsomemaildomains(PGconn
*, void *);
68 void loadmaildomainsdone(PGconn
*, void *);
70 /* Free sstrings in the structures */
71 void csdb_freestuff();
73 static void setuptables() {
74 /* Set up the tables */
76 pqcreatequery("CREATE TABLE users ("
78 "username VARCHAR(16) NOT NULL,"
79 "created INT NOT NULL,"
80 "lastauth INT NOT NULL,"
81 "lastemailchng INT NOT NULL,"
83 "language INT NOT NULL,"
84 "suspendby INT NOT NULL,"
85 "suspendexp INT NOT NULL,"
86 "password VARCHAR(11) NOT NULL,"
88 "lastuserhost VARCHAR(75),"
89 "suspendreason VARCHAR(250),"
90 "comment VARCHAR(250),"
94 pqcreatequery("CREATE INDEX user_username_index ON users (username)");
97 pqcreatequery("CREATE TABLE channels ("
99 "name VARCHAR(250) NOT NULL,"
100 "flags INT NOT NULL,"
101 "forcemodes INT NOT NULL,"
102 "denymodes INT NOT NULL,"
103 "chanlimit INT NOT NULL,"
104 "autolimit INT NOT NULL,"
105 "banstyle INT NOT NULL,"
106 "created INT NOT NULL,"
107 "lastactive INT NOT NULL,"
108 "statsreset INT NOT NULL,"
109 "banduration INT NOT NULL,"
110 "founder INT NOT NULL,"
111 "addedby INT NOT NULL,"
112 "suspendby 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),"
124 "PRIMARY KEY (ID))");
127 pqcreatequery("CREATE TABLE 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))");
136 pqcreatequery("CREATE INDEX chanusers_userID_index on chanusers (userID)");
137 pqcreatequery("CREATE INDEX chanusers_channelID_index on chanusers (channelID)");
139 pqcreatequery("CREATE TABLE 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))");
149 pqcreatequery("CREATE INDEX bans_channelID_index on bans (channelID)");
151 pqcreatequery("CREATE TABLE languages ("
152 "languageID INT NOT NULL,"
153 "code VARCHAR(2) NOT NULL,"
154 "name VARCHAR(30) NOT NULL)");
156 pqcreatequery("CREATE TABLE messages ("
157 "languageID INT NOT NULL,"
158 "messageID INT NOT NULL,"
159 "message VARCHAR(250) NOT NULL,"
160 "PRIMARY KEY (languageID, messageID))");
162 pqcreatequery("CREATE TABLE 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))");
170 pqcreatequery("CREATE TABLE email ("
171 "userID INT NOT NULL,"
172 "emailtype INT NOT NULL,"
173 "prevEmail VARCHAR(100),"
175 "PRIMARY KEY (mailID))");
177 pqcreatequery("CREATE TABLE maildomain ("
179 "name VARCHAR NOT NULL,"
180 "domainlimit INT NOT NULL,"
181 "actlimit INT NOT NULL,"
182 "flags INT NOT NULL,"
183 "PRIMARY KEY (ID))");
185 pqcreatequery("CREATE TABLE 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))");
196 pqcreatequery("CREATE INDEX authhistory_userID_index on authhistory(userID)");
197 pqcreatequery("CREATE TABLE 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)");
206 pqcreatequery("CREATE INDEX chanlevhistory_userID_index on chanlevhistory(userID)");
207 pqcreatequery("CREATE INDEX chanlevhistory_channelID_index on chanlevhistory(channelID)");
208 pqcreatequery("CREATE INDEX chanlevhistory_targetID_index on chanlevhistory(targetID)");
210 pqcreatequery("CREATE TABLE 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))");
220 pqcreatequery("CREATE INDEX accounthistory_userID_index on accounthistory(userID)");
224 chanservext
=registerchanext("chanserv");
225 chanservaext
=registerauthnameext("chanserv");
227 /* Set up the allocators and hashes */
231 /* And the messages */
234 if (pqconnected() && (chanservext
!=-1) && (chanservaext
!=-1)) {
235 registerhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
239 lastuserID
=lastchannelID
=lastdomainID
=0;
241 loadall("users",NULL
,loadsomeusers
,loadusersdone
);
242 loadall("channels",NULL
,loadsomechannels
,loadchannelsdone
);
243 loadall("chanusers",loadchanusersinit
,loadsomechanusers
,loadchanusersdone
);
244 loadall("bans",NULL
,loadsomechanbans
,loadchanbansdone
);
245 loadall("maildomain",NULL
, loadsomemaildomains
,loadmaildomainsdone
);
253 releasechanext(chanservext
);
255 if (chanservaext
!=-1)
256 releaseauthnameext(chanservaext
);
259 nsfreeall(POOL_CHANSERVDB
);
262 void csdb_handlestats(int hooknum
, void *arg
) {
263 /* long level=(long)arg; */
265 /* Keeping options open here */
268 void chanservdbclose() {
270 deregisterhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
276 * Generic function to handle load of an entire table..
279 void loadall(char *table
, PQQueryHandler init
, PQQueryHandler data
, PQQueryHandler fini
) {
282 thedesc
=malloc(sizeof(tabledesc
));
284 thedesc
->tablename
=getsstring(table
,100);
289 pqasyncquery(doloadall
, thedesc
, "SELECT count(*) FROM %s",thedesc
->tablename
->content
);
292 void doloadall(PGconn
*dbconn
, void *arg
) {
295 tabledesc
*thedesc
=arg
;
297 pgres
=PQgetResult(dbconn
);
299 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
300 Error("chanserv",ERR_ERROR
,"Error getting row count for %s.",thedesc
->tablename
->content
);
304 if (PQnfields(pgres
)!=1) {
305 Error("chanserv",ERR_ERROR
,"Count query format error for %s.",thedesc
->tablename
->content
);
309 count
=strtoul(PQgetvalue(pgres
,0,0),NULL
,10);
313 Error("chanserv",ERR_INFO
,"Found %d entries in table %s, scheduling load.",count
,
314 thedesc
->tablename
->content
);
316 pqasyncquery(thedesc
->init
, NULL
, "BEGIN");
317 pqquery("DECLARE mycurs CURSOR FOR SELECT * from %s",
318 thedesc
->tablename
->content
);
320 for (i
=0;(count
-i
)>1000;i
+=1000) {
321 pqasyncquery(thedesc
->data
, NULL
, "FETCH 1000 FROM mycurs");
324 pqasyncquery(thedesc
->data
, NULL
, "FETCH ALL FROM mycurs");
326 pqquery("CLOSE mycurs");
327 pqasyncquery(thedesc
->fini
, NULL
, "COMMIT");
329 /* Free structures.. */
330 freesstring(thedesc
->tablename
);
336 * Loads some users in from the SQL DB
339 void loadsomeusers(PGconn
*dbconn
, void *arg
) {
345 pgres
=PQgetResult(dbconn
);
347 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
348 Error("chanserv",ERR_ERROR
,"Error loading user DB");
352 if (PQnfields(pgres
)!=15) {
353 Error("chanserv",ERR_ERROR
,"User DB format error");
357 num
=PQntuples(pgres
);
362 rup
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
363 strncpy(rup
->username
,PQgetvalue(pgres
,i
,1),NICKLEN
); rup
->username
[NICKLEN
]='\0';
364 rup
->created
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
365 rup
->lastauth
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
366 rup
->lastemailchange
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
367 rup
->flags
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
368 rup
->languageid
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
369 rup
->suspendby
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
370 rup
->suspendexp
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
371 strncpy(rup
->password
,PQgetvalue(pgres
,i
,9),PASSLEN
); rup
->password
[PASSLEN
]='\0';
372 rup
->email
=getsstring(PQgetvalue(pgres
,i
,10),100);
374 rup
->domain
=findorcreatemaildomain(rup
->email
->content
);
375 addregusertomaildomain(rup
, rup
->domain
);
377 char *dupemail
= strdup(rup
->email
->content
);
378 if((local
=strchr(dupemail
, '@'))) {
380 rup
->localpart
=getsstring(local
,EMAILLEN
);
389 rup
->lastuserhost
=getsstring(PQgetvalue(pgres
,i
,11),75);
390 rup
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,12),250);
391 rup
->comment
=getsstring(PQgetvalue(pgres
,i
,13),250);
392 rup
->info
=getsstring(PQgetvalue(pgres
,i
,14),100);
398 addregusertohash(rup
);
400 if (rup
->ID
> lastuserID
) {
408 void loadusersdone(PGconn
*conn
, void *arg
) {
409 Error("chanserv",ERR_INFO
,"Load users done (highest ID was %d)",lastuserID
);
413 * Channel loading functions
416 void loadsomechannels(PGconn
*dbconn
, void *arg
) {
421 time_t now
=time(NULL
);
423 pgres
=PQgetResult(dbconn
);
425 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
426 Error("chanserv",ERR_ERROR
,"Error loading channel DB");
430 if (PQnfields(pgres
)!=26) {
431 Error("chanserv",ERR_ERROR
,"Channel DB format error");
435 num
=PQntuples(pgres
);
438 cip
=findorcreatechanindex(PQgetvalue(pgres
,i
,1));
439 if (cip
->exts
[chanservext
]) {
440 Error("chanserv",ERR_WARNING
,"%s in database twice - this WILL cause problems later.",cip
->name
->content
);
444 cip
->exts
[chanservext
]=rcp
;
446 rcp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
448 rcp
->flags
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
449 rcp
->status
=0; /* Non-DB field */
451 rcp
->lastcountersync
=now
;
454 rcp
->forcemodes
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
455 rcp
->denymodes
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
456 rcp
->limit
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
457 rcp
->autolimit
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
458 rcp
->banstyle
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
459 rcp
->created
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
460 rcp
->lastactive
=strtoul(PQgetvalue(pgres
,i
,9),NULL
,10);
461 rcp
->statsreset
=strtoul(PQgetvalue(pgres
,i
,10),NULL
,10);
462 rcp
->banduration
=strtoul(PQgetvalue(pgres
,i
,11),NULL
,10);
463 rcp
->founder
=strtol(PQgetvalue(pgres
,i
,12),NULL
,10);
464 rcp
->addedby
=strtol(PQgetvalue(pgres
,i
,13),NULL
,10);
465 rcp
->suspendby
=strtol(PQgetvalue(pgres
,i
,14),NULL
,10);
466 rcp
->chantype
=strtoul(PQgetvalue(pgres
,i
,15),NULL
,10);
467 rcp
->totaljoins
=strtoul(PQgetvalue(pgres
,i
,16),NULL
,10);
468 rcp
->tripjoins
=strtoul(PQgetvalue(pgres
,i
,17),NULL
,10);
469 rcp
->maxusers
=strtoul(PQgetvalue(pgres
,i
,18),NULL
,10);
470 rcp
->tripusers
=strtoul(PQgetvalue(pgres
,i
,19),NULL
,10);
471 rcp
->welcome
=getsstring(PQgetvalue(pgres
,i
,20),500);
472 rcp
->topic
=getsstring(PQgetvalue(pgres
,i
,21),TOPICLEN
);
473 rcp
->key
=getsstring(PQgetvalue(pgres
,i
,22),KEYLEN
);
474 rcp
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,23),250);
475 rcp
->comment
=getsstring(PQgetvalue(pgres
,i
,24),250);
476 rcp
->checksched
=NULL
;
477 rcp
->ltimestamp
=strtoul(PQgetvalue(pgres
,i
,25),NULL
,10);
478 memset(rcp
->regusers
,0,REGCHANUSERHASHSIZE
*sizeof(reguser
*));
480 if (rcp
->ID
> lastchannelID
)
481 lastchannelID
=rcp
->ID
;
483 if (CIsAutoLimit(rcp
))
490 void loadchannelsdone(PGconn
*dbconn
, void *arg
) {
491 Error("chanserv",ERR_INFO
,"Channel load done (highest ID was %d)",lastchannelID
);
494 void loadchanusersinit(PGconn
*dbconn
, void *arg
) {
499 allchans
=(regchan
**)malloc((lastchannelID
+1)*sizeof(regchan
*));
500 memset(allchans
,0,(lastchannelID
+1)*sizeof(regchan
*));
501 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
502 for (cip
=chantable
[i
];cip
;cip
=cip
->next
) {
503 if (cip
->exts
[chanservext
]) {
504 rcp
=(regchan
*)cip
->exts
[chanservext
];
505 allchans
[rcp
->ID
]=rcp
;
511 void loadsomechanusers(PGconn
*dbconn
, void *arg
) {
521 /* Set up the allchans array */
522 pgres
=PQgetResult(dbconn
);
524 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
525 Error("chanserv",ERR_ERROR
,"Error loading chanusers.");
529 if (PQnfields(pgres
)!=6) {
530 Error("chanserv",ERR_ERROR
,"Chanusers format error");
534 num
=PQntuples(pgres
);
537 uid
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
538 cid
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
540 if (!(anp
=findauthname(uid
)) || !(rup
=anp
->exts
[chanservaext
])) {
541 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown user %d",uid
);
545 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
546 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown chan %d",cid
);
550 if (rup
==NULL
|| rcp
==NULL
) {
551 Error("chanserv",ERR_ERROR
,"Can't add user %s on channel %s",
552 PQgetvalue(pgres
,i
,0),PQgetvalue(pgres
,i
,1));
554 rcup
=getregchanuser();
557 rcup
->flags
=strtol(PQgetvalue(pgres
,i
,2),NULL
,10);
558 rcup
->changetime
=strtol(PQgetvalue(pgres
,i
,3),NULL
,10);
559 rcup
->usetime
=strtol(PQgetvalue(pgres
,i
,4),NULL
,10);
560 rcup
->info
=getsstring(PQgetvalue(pgres
,i
,5),100);
561 addregusertochannel(rcup
);
569 void loadchanusersdone(PGconn
*dbconn
, void *arg
) {
570 Error("chanserv",ERR_INFO
,"Channel user load done.");
573 void loadsomechanbans(PGconn
*dbconn
, void *arg
) {
582 pgres
=PQgetResult(dbconn
);
584 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
585 Error("chanserv",ERR_ERROR
,"Error loading bans.");
589 if (PQnfields(pgres
)!=6) {
590 Error("chanserv",ERR_ERROR
,"Ban format error");
594 num
=PQntuples(pgres
);
599 bid
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
600 cid
=strtoul(PQgetvalue(pgres
,i
,1),NULL
,10);
601 uid
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
602 expiry
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
604 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
605 Error("chanserv",ERR_WARNING
,"Skipping ban for unknown chan %d",cid
);
613 rbp
->reason
=getsstring(PQgetvalue(pgres
,i
,5),200);
614 rbp
->cbp
=makeban(PQgetvalue(pgres
,i
,3));
627 void loadchanbansdone(PGconn
*dbconn
, void *arg
) {
630 Error("chanserv",ERR_INFO
,"Channel ban load done, highest ID was %d",lastbanID
);
633 triggerhook(HOOK_CHANSERV_DBLOADED
, NULL
);
636 void loadmessages() {
637 pqasyncquery(loadmessages_part1
, NULL
, "SELECT * from languages");
640 void loadmessages_part1(PGconn
*dbconn
, void *arg
) {
645 /* Firstly, clear up any stale messages */
646 for (i
=0;i
<MAXLANG
;i
++) {
647 if (cslanguages
[i
]) {
648 freesstring(cslanguages
[i
]->name
);
649 free(cslanguages
[i
]);
651 for (j
=0;j
<MAXMESSAGES
;j
++) {
652 if (csmessages
[i
][j
]) {
653 freesstring(csmessages
[i
][j
]);
654 csmessages
[i
][j
]=NULL
;
659 pgres
=PQgetResult(dbconn
);
661 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
662 Error("chanserv",ERR_ERROR
,"Error loading language list.");
666 if (PQnfields(pgres
)!=3) {
667 Error("chanserv",ERR_ERROR
,"Language list format error.");
671 num
=PQntuples(pgres
);
673 for (i
=0;i
<num
;i
++) {
674 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
675 if (j
<MAXLANG
&& j
>=0) {
676 cslanguages
[j
]=(cslang
*)malloc(sizeof(cslang
));
678 strncpy(cslanguages
[j
]->code
,PQgetvalue(pgres
,i
,1),2); cslanguages
[j
]->code
[2]='\0';
679 cslanguages
[j
]->name
=getsstring(PQgetvalue(pgres
,i
,2),30);
686 Error("chanserv",ERR_ERROR
,"Found too many languages (%d > %d)",i
,MAXLANG
);
688 pqasyncquery(loadmessages_part2
, NULL
, "SELECT * from messages");
691 void loadmessages_part2(PGconn
*dbconn
, void *arg
) {
695 pgres
=PQgetResult(dbconn
);
697 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
698 Error("chanserv",ERR_ERROR
,"Error loading message list.");
702 if (PQnfields(pgres
)!=3) {
703 Error("chanserv",ERR_ERROR
,"Message list format error.");
707 num
=PQntuples(pgres
);
709 for (i
=0;i
<num
;i
++) {
710 k
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
711 j
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
713 if (k
<0 || k
>= MAXLANG
) {
714 Error("chanserv",ERR_WARNING
,"Language ID out of range on message: %d",k
);
718 if (j
<0 || j
>= MAXMESSAGES
) {
719 Error("chanserv",ERR_WARNING
,"Message ID out of range on message: %d",j
);
723 csmessages
[k
][j
]=getsstring(PQgetvalue(pgres
,i
,2),250);
729 void loadcommandsummary(Command
*cmd
) {
730 pqasyncquery(loadcommandsummary_real
, (void *)cmd
,
731 "SELECT languageID,summary from help where lower(command) = lower('%s')",cmd
->command
->content
);
734 void loadcommandsummary_real(PGconn
*dbconn
, void *arg
) {
740 /* Clear up old text first */
742 for (i
=0;i
<MAXLANG
;i
++) {
744 freesstring(cs
->bylang
[i
]);
747 pgres
=PQgetResult(dbconn
);
749 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
750 Error("chanserv",ERR_ERROR
,"Error loading command summary.");
754 if (PQnfields(pgres
)!=2) {
755 Error("chanserv",ERR_ERROR
,"Command summary format error.");
759 num
=PQntuples(pgres
);
761 for (i
=0;i
<num
;i
++) {
762 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
763 if (j
<MAXLANG
&& j
>=0) {
764 cs
->bylang
[j
]=getsstring(PQgetvalue(pgres
,i
,1),200);
771 void csdb_freestuff() {
773 chanindex
*cip
, *ncip
;
780 for (i
=0;i
<REGUSERHASHSIZE
;i
++) {
781 for (rup
=regusernicktable
[i
];rup
;rup
=rup
->nextbyname
) {
782 freesstring(rup
->email
);
783 freesstring(rup
->lastuserhost
);
784 freesstring(rup
->suspendreason
);
785 freesstring(rup
->comment
);
786 freesstring(rup
->info
);
788 for (rcup
=rup
->knownon
;rcup
;rcup
=rcup
->nextbyuser
)
789 freesstring(rcup
->info
);
793 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
794 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
796 if ((rcp
=cip
->exts
[chanservext
])) {
797 freesstring(rcp
->welcome
);
798 freesstring(rcp
->topic
);
799 freesstring(rcp
->key
);
800 freesstring(rcp
->suspendreason
);
801 freesstring(rcp
->comment
);
802 for (rbp
=rcp
->bans
;rbp
;rbp
=rbp
->next
) {
803 freesstring(rbp
->reason
);
804 freechanban(rbp
->cbp
);
806 cip
->exts
[chanservext
]=NULL
;
807 releasechanindex(cip
);
812 for (i
=0; i
<MAILDOMAINHASHSIZE
; i
++) {
813 for (mdp
=maildomainnametable
[i
]; mdp
; mdp
=mdp
->nextbyname
)
814 freesstring(mdp
->name
);
818 void loadsomemaildomains(PGconn
*dbconn
,void *arg
) {
823 pgres
=PQgetResult(dbconn
);
825 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
826 Error("chanserv",ERR_ERROR
,"Error loading maildomain DB");
830 if (PQnfields(pgres
)!=4) {
831 Error("chanserv",ERR_ERROR
,"Mail Domain DB format error");
834 num
=PQntuples(pgres
);
838 domain
=strdup(PQgetvalue(pgres
,i
,1));
839 mdp
=findorcreatemaildomain(domain
); //@@@ LEN
841 mdp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
842 mdp
->limit
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
843 mdp
->actlimit
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
844 mdp
->flags
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
846 if (mdp
->ID
> lastdomainID
) {
847 lastdomainID
=mdp
->ID
;
854 void loadmaildomainsdone(PGconn
*dbconn
, void *arg
) {
855 Error("chanserv",ERR_INFO
,"Load Mail Domains done (highest ID was %d)",lastdomainID
);