]>
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,"
87 "masterpass VARCHAR(11),"
89 "lastuserhost VARCHAR(75),"
90 "suspendreason VARCHAR(250),"
91 "comment VARCHAR(250),"
95 pqcreatequery("CREATE INDEX user_username_index ON users (username)");
98 pqcreatequery("CREATE TABLE channels ("
100 "name VARCHAR(250) NOT NULL,"
101 "flags INT NOT NULL,"
102 "forcemodes INT NOT NULL,"
103 "denymodes INT NOT NULL,"
104 "chanlimit INT NOT NULL,"
105 "autolimit INT NOT NULL,"
106 "banstyle INT NOT NULL,"
107 "created INT NOT NULL,"
108 "lastactive INT NOT NULL,"
109 "statsreset INT NOT NULL,"
110 "banduration INT NOT NULL,"
111 "founder INT NOT NULL,"
112 "addedby INT NOT NULL,"
113 "suspendby INT NOT NULL,"
114 "chantype SMALLINT NOT NULL,"
115 "totaljoins INT NOT NULL,"
116 "tripjoins INT NOT NULL,"
117 "maxusers INT NOT NULL,"
118 "tripusers INT NOT NULL,"
119 "welcome VARCHAR(500),"
120 "topic VARCHAR(250),"
121 "chankey VARCHAR(23),"
122 "suspendreason VARCHAR(250),"
123 "comment VARCHAR(250),"
125 "PRIMARY KEY (ID))");
128 pqcreatequery("CREATE TABLE chanusers ("
129 "userID INT NOT NULL,"
130 "channelID INT NOT NULL,"
131 "flags INT NOT NULL,"
132 "changetime INT NOT NULL,"
133 "usetime INT NOT NULL,"
134 "info VARCHAR(100) NOT NULL,"
135 "PRIMARY KEY (userID, channelID))");
137 pqcreatequery("CREATE INDEX chanusers_userID_index on chanusers (userID)");
138 pqcreatequery("CREATE INDEX chanusers_channelID_index on chanusers (channelID)");
140 pqcreatequery("CREATE TABLE bans ("
141 "banID INT NOT NULL," /* Unique number for the ban to make
142 DELETEs process in finite time.. */
143 "channelID INT NOT NULL,"
144 "userID INT NOT NULL," /* Who set the ban.. */
145 "hostmask VARCHAR(100) NOT NULL," /* needs to be at least USERLEN+NICKLEN+HOSTLEN+2 */
146 "expiry INT NOT NULL,"
147 "reason VARCHAR(200),"
148 "PRIMARY KEY(banID))");
150 pqcreatequery("CREATE INDEX bans_channelID_index on bans (channelID)");
152 pqcreatequery("CREATE TABLE languages ("
153 "languageID INT NOT NULL,"
154 "code VARCHAR(2) NOT NULL,"
155 "name VARCHAR(30) NOT NULL)");
157 pqcreatequery("CREATE TABLE messages ("
158 "languageID INT NOT NULL,"
159 "messageID INT NOT NULL,"
160 "message VARCHAR(250) NOT NULL,"
161 "PRIMARY KEY (languageID, messageID))");
163 pqcreatequery("CREATE TABLE help ("
164 "commandID INT NOT NULL,"
165 "command VARCHAR(30) NOT NULL,"
166 "languageID INT NOT NULL,"
167 "summary VARCHAR(200) NOT NULL,"
168 "fullinfo TEXT NOT NULL,"
169 "PRIMARY KEY (commandID, languageID))");
171 pqcreatequery("CREATE TABLE email ("
172 "userID INT NOT NULL,"
173 "emailtype INT NOT NULL,"
174 "prevEmail VARCHAR(100),"
175 "mailID VARCHAR(128))");
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 "PRIMARY KEY (userID, authtime))");
194 pqcreatequery("CREATE INDEX authhistory_userID_index on authhistory(userID)");
195 pqcreatequery("CREATE TABLE chanlevhistory ("
196 "userID INT NOT NULL,"
197 "channelID INT NOT NULL,"
198 "targetID INT NOT NULL,"
199 "changetime INT NOT NULL,"
200 "authtime INT NOT NULL,"
201 "oldflags INT NOT NULL,"
202 "newflags INT NOT NULL)");
204 pqcreatequery("CREATE INDEX chanlevhistory_userID_index on chanlevhistory(userID)");
205 pqcreatequery("CREATE INDEX chanlevhistory_channelID_index on chanlevhistory(channelID)");
206 pqcreatequery("CREATE INDEX chanlevhistory_targetID_index on chanlevhistory(targetID)");
208 pqcreatequery("CREATE TABLE accounthistory ("
209 "userID INT NOT NULL,"
210 "changetime INT NOT NULL,"
211 "authtime INT NOT NULL,"
212 "oldpassword VARCHAR(11),"
213 "newpassword VARCHAR(11),"
214 "oldemail VARCHAR(100),"
215 "newemail VARCHAR(100),"
216 "PRIMARY KEY (userID, changetime))");
218 pqcreatequery("CREATE INDEX accounthistory_userID_index on accounthistory(userID)");
222 chanservext
=registerchanext("chanserv");
223 chanservaext
=registerauthnameext("chanserv");
225 /* Set up the allocators and hashes */
229 /* And the messages */
232 if (pqconnected() && (chanservext
!=-1) && (chanservaext
!=-1)) {
233 registerhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
237 lastuserID
=lastchannelID
=lastdomainID
=0;
239 loadall("users",NULL
,loadsomeusers
,loadusersdone
);
240 loadall("channels",NULL
,loadsomechannels
,loadchannelsdone
);
241 loadall("chanusers",loadchanusersinit
,loadsomechanusers
,loadchanusersdone
);
242 loadall("bans",NULL
,loadsomechanbans
,loadchanbansdone
);
243 loadall("maildomain",NULL
, loadsomemaildomains
,loadmaildomainsdone
);
251 releasechanext(chanservext
);
253 if (chanservaext
!=-1)
254 releaseauthnameext(chanservaext
);
257 nsfreeall(POOL_CHANSERVDB
);
260 void csdb_handlestats(int hooknum
, void *arg
) {
261 /* long level=(long)arg; */
263 /* Keeping options open here */
266 void chanservdbclose() {
268 deregisterhook(HOOK_CORE_STATSREQUEST
, csdb_handlestats
);
274 * Generic function to handle load of an entire table..
277 void loadall(char *table
, PQQueryHandler init
, PQQueryHandler data
, PQQueryHandler fini
) {
280 thedesc
=malloc(sizeof(tabledesc
));
282 thedesc
->tablename
=getsstring(table
,100);
287 pqasyncquery(doloadall
, thedesc
, "SELECT count(*) FROM %s",thedesc
->tablename
->content
);
290 void doloadall(PGconn
*dbconn
, void *arg
) {
293 tabledesc
*thedesc
=arg
;
295 pgres
=PQgetResult(dbconn
);
297 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
298 Error("chanserv",ERR_ERROR
,"Error getting row count for %s.",thedesc
->tablename
->content
);
302 if (PQnfields(pgres
)!=1) {
303 Error("chanserv",ERR_ERROR
,"Count query format error for %s.",thedesc
->tablename
->content
);
307 count
=strtoul(PQgetvalue(pgres
,0,0),NULL
,10);
311 Error("chanserv",ERR_INFO
,"Found %d entries in table %s, scheduling load.",count
,
312 thedesc
->tablename
->content
);
314 pqasyncquery(thedesc
->init
, NULL
, "BEGIN");
315 pqquery("DECLARE mycurs CURSOR FOR SELECT * from %s",
316 thedesc
->tablename
->content
);
318 for (i
=0;(count
-i
)>1000;i
+=1000) {
319 pqasyncquery(thedesc
->data
, NULL
, "FETCH 1000 FROM mycurs");
322 pqasyncquery(thedesc
->data
, NULL
, "FETCH ALL FROM mycurs");
324 pqquery("CLOSE mycurs");
325 pqasyncquery(thedesc
->fini
, NULL
, "COMMIT");
327 /* Free structures.. */
328 freesstring(thedesc
->tablename
);
334 * Loads some users in from the SQL DB
337 void loadsomeusers(PGconn
*dbconn
, void *arg
) {
343 pgres
=PQgetResult(dbconn
);
345 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
346 Error("chanserv",ERR_ERROR
,"Error loading user DB");
350 if (PQnfields(pgres
)!=16) {
351 Error("chanserv",ERR_ERROR
,"User DB format error");
355 num
=PQntuples(pgres
);
360 rup
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
361 strncpy(rup
->username
,PQgetvalue(pgres
,i
,1),NICKLEN
); rup
->username
[NICKLEN
]='\0';
362 rup
->created
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
363 rup
->lastauth
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
364 rup
->lastemailchange
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
365 rup
->flags
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
366 rup
->languageid
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
367 rup
->suspendby
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
368 rup
->suspendexp
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
369 strncpy(rup
->password
,PQgetvalue(pgres
,i
,9),PASSLEN
); rup
->password
[PASSLEN
]='\0';
370 strncpy(rup
->masterpass
,PQgetvalue(pgres
,i
,10),PASSLEN
); rup
->masterpass
[PASSLEN
]='\0';
371 rup
->email
=getsstring(PQgetvalue(pgres
,i
,11),100);
373 rup
->domain
=findorcreatemaildomain(rup
->email
->content
);
374 addregusertomaildomain(rup
, rup
->domain
);
376 char *dupemail
= strdup(rup
->email
->content
);
377 if(local
=strchr(dupemail
, '@')) {
379 rup
->localpart
=getsstring(local
,EMAILLEN
);
388 rup
->lastuserhost
=getsstring(PQgetvalue(pgres
,i
,12),75);
389 rup
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,13),250);
390 rup
->comment
=getsstring(PQgetvalue(pgres
,i
,14),250);
391 rup
->info
=getsstring(PQgetvalue(pgres
,i
,15),100);
397 addregusertohash(rup
);
399 if (rup
->ID
> lastuserID
) {
407 void loadusersdone(PGconn
*conn
, void *arg
) {
408 Error("chanserv",ERR_INFO
,"Load users done (highest ID was %d)",lastuserID
);
412 * Channel loading functions
415 void loadsomechannels(PGconn
*dbconn
, void *arg
) {
420 time_t now
=time(NULL
);
422 pgres
=PQgetResult(dbconn
);
424 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
425 Error("chanserv",ERR_ERROR
,"Error loading channel DB");
429 if (PQnfields(pgres
)!=26) {
430 Error("chanserv",ERR_ERROR
,"Channel DB format error");
434 num
=PQntuples(pgres
);
437 cip
=findorcreatechanindex(PQgetvalue(pgres
,i
,1));
438 if (cip
->exts
[chanservext
]) {
439 Error("chanserv",ERR_WARNING
,"%s in database twice - this WILL cause problems later.",cip
->name
->content
);
443 cip
->exts
[chanservext
]=rcp
;
445 rcp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
447 rcp
->flags
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
448 rcp
->status
=0; /* Non-DB field */
450 rcp
->lastcountersync
=now
;
453 rcp
->forcemodes
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
454 rcp
->denymodes
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
455 rcp
->limit
=strtoul(PQgetvalue(pgres
,i
,5),NULL
,10);
456 rcp
->autolimit
=strtoul(PQgetvalue(pgres
,i
,6),NULL
,10);
457 rcp
->banstyle
=strtoul(PQgetvalue(pgres
,i
,7),NULL
,10);
458 rcp
->created
=strtoul(PQgetvalue(pgres
,i
,8),NULL
,10);
459 rcp
->lastactive
=strtoul(PQgetvalue(pgres
,i
,9),NULL
,10);
460 rcp
->statsreset
=strtoul(PQgetvalue(pgres
,i
,10),NULL
,10);
461 rcp
->banduration
=strtoul(PQgetvalue(pgres
,i
,11),NULL
,10);
462 rcp
->founder
=strtol(PQgetvalue(pgres
,i
,12),NULL
,10);
463 rcp
->addedby
=strtol(PQgetvalue(pgres
,i
,13),NULL
,10);
464 rcp
->suspendby
=strtol(PQgetvalue(pgres
,i
,14),NULL
,10);
465 rcp
->chantype
=strtoul(PQgetvalue(pgres
,i
,15),NULL
,10);
466 rcp
->totaljoins
=strtoul(PQgetvalue(pgres
,i
,16),NULL
,10);
467 rcp
->tripjoins
=strtoul(PQgetvalue(pgres
,i
,17),NULL
,10);
468 rcp
->maxusers
=strtoul(PQgetvalue(pgres
,i
,18),NULL
,10);
469 rcp
->tripusers
=strtoul(PQgetvalue(pgres
,i
,19),NULL
,10);
470 rcp
->welcome
=getsstring(PQgetvalue(pgres
,i
,20),500);
471 rcp
->topic
=getsstring(PQgetvalue(pgres
,i
,21),TOPICLEN
);
472 rcp
->key
=getsstring(PQgetvalue(pgres
,i
,22),KEYLEN
);
473 rcp
->suspendreason
=getsstring(PQgetvalue(pgres
,i
,23),250);
474 rcp
->comment
=getsstring(PQgetvalue(pgres
,i
,24),250);
475 rcp
->checksched
=NULL
;
476 rcp
->ltimestamp
=strtoul(PQgetvalue(pgres
,i
,25),NULL
,10);
477 memset(rcp
->regusers
,0,REGCHANUSERHASHSIZE
*sizeof(reguser
*));
479 if (rcp
->ID
> lastchannelID
)
480 lastchannelID
=rcp
->ID
;
482 if (CIsAutoLimit(rcp
))
489 void loadchannelsdone(PGconn
*dbconn
, void *arg
) {
490 Error("chanserv",ERR_INFO
,"Channel load done (highest ID was %d)",lastchannelID
);
493 void loadchanusersinit(PGconn
*dbconn
, void *arg
) {
498 allchans
=(regchan
**)malloc((lastchannelID
+1)*sizeof(regchan
*));
499 memset(allchans
,0,(lastchannelID
+1)*sizeof(regchan
*));
500 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
501 for (cip
=chantable
[i
];cip
;cip
=cip
->next
) {
502 if (cip
->exts
[chanservext
]) {
503 rcp
=(regchan
*)cip
->exts
[chanservext
];
504 allchans
[rcp
->ID
]=rcp
;
510 void loadsomechanusers(PGconn
*dbconn
, void *arg
) {
520 /* Set up the allchans array */
521 pgres
=PQgetResult(dbconn
);
523 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
524 Error("chanserv",ERR_ERROR
,"Error loading chanusers.");
528 if (PQnfields(pgres
)!=6) {
529 Error("chanserv",ERR_ERROR
,"Chanusers format error");
533 num
=PQntuples(pgres
);
536 uid
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
537 cid
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
539 if (!(anp
=findauthname(uid
)) || !(rup
=anp
->exts
[chanservaext
])) {
540 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown user %d",uid
);
544 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
545 Error("chanserv",ERR_WARNING
,"Skipping channeluser for unknown chan %d",cid
);
549 if (rup
==NULL
|| rcp
==NULL
) {
550 Error("chanserv",ERR_ERROR
,"Can't add user %s on channel %s",
551 PQgetvalue(pgres
,i
,0),PQgetvalue(pgres
,i
,1));
553 rcup
=getregchanuser();
556 rcup
->flags
=strtol(PQgetvalue(pgres
,i
,2),NULL
,10);
557 rcup
->changetime
=strtol(PQgetvalue(pgres
,i
,3),NULL
,10);
558 rcup
->usetime
=strtol(PQgetvalue(pgres
,i
,4),NULL
,10);
559 rcup
->info
=getsstring(PQgetvalue(pgres
,i
,5),100);
560 addregusertochannel(rcup
);
568 void loadchanusersdone(PGconn
*dbconn
, void *arg
) {
569 Error("chanserv",ERR_INFO
,"Channel user load done.");
572 void loadsomechanbans(PGconn
*dbconn
, void *arg
) {
581 pgres
=PQgetResult(dbconn
);
583 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
584 Error("chanserv",ERR_ERROR
,"Error loading bans.");
588 if (PQnfields(pgres
)!=6) {
589 Error("chanserv",ERR_ERROR
,"Ban format error");
593 num
=PQntuples(pgres
);
598 bid
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
599 cid
=strtoul(PQgetvalue(pgres
,i
,1),NULL
,10);
600 uid
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
601 expiry
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
603 if (cid
>lastchannelID
|| !(rcp
=allchans
[cid
])) {
604 Error("chanserv",ERR_WARNING
,"Skipping ban for unknown chan %d",cid
);
612 rbp
->reason
=getsstring(PQgetvalue(pgres
,i
,5),200);
613 rbp
->cbp
=makeban(PQgetvalue(pgres
,i
,3));
626 void loadchanbansdone(PGconn
*dbconn
, void *arg
) {
629 Error("chanserv",ERR_INFO
,"Channel ban load done, highest ID was %d",lastbanID
);
632 triggerhook(HOOK_CHANSERV_DBLOADED
, NULL
);
635 void loadmessages() {
636 pqasyncquery(loadmessages_part1
, NULL
, "SELECT * from languages");
639 void loadmessages_part1(PGconn
*dbconn
, void *arg
) {
644 /* Firstly, clear up any stale messages */
645 for (i
=0;i
<MAXLANG
;i
++) {
646 if (cslanguages
[i
]) {
647 freesstring(cslanguages
[i
]->name
);
648 free(cslanguages
[i
]);
650 for (j
=0;j
<MAXMESSAGES
;j
++) {
651 if (csmessages
[i
][j
]) {
652 freesstring(csmessages
[i
][j
]);
653 csmessages
[i
][j
]=NULL
;
658 pgres
=PQgetResult(dbconn
);
660 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
661 Error("chanserv",ERR_ERROR
,"Error loading language list.");
665 if (PQnfields(pgres
)!=3) {
666 Error("chanserv",ERR_ERROR
,"Language list format error.");
670 num
=PQntuples(pgres
);
672 for (i
=0;i
<num
;i
++) {
673 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
674 if (j
<MAXLANG
&& j
>=0) {
675 cslanguages
[j
]=(cslang
*)malloc(sizeof(cslang
));
677 strncpy(cslanguages
[j
]->code
,PQgetvalue(pgres
,i
,1),2); cslanguages
[j
]->code
[2]='\0';
678 cslanguages
[j
]->name
=getsstring(PQgetvalue(pgres
,i
,2),30);
685 Error("chanserv",ERR_ERROR
,"Found too many languages (%d > %d)",i
,MAXLANG
);
687 pqasyncquery(loadmessages_part2
, NULL
, "SELECT * from messages");
690 void loadmessages_part2(PGconn
*dbconn
, void *arg
) {
694 pgres
=PQgetResult(dbconn
);
696 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
697 Error("chanserv",ERR_ERROR
,"Error loading message list.");
701 if (PQnfields(pgres
)!=3) {
702 Error("chanserv",ERR_ERROR
,"Message list format error.");
706 num
=PQntuples(pgres
);
708 for (i
=0;i
<num
;i
++) {
709 k
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
710 j
=strtol(PQgetvalue(pgres
,i
,1),NULL
,10);
712 if (k
<0 || k
>= MAXLANG
) {
713 Error("chanserv",ERR_WARNING
,"Language ID out of range on message: %d",k
);
717 if (j
<0 || j
>= MAXMESSAGES
) {
718 Error("chanserv",ERR_WARNING
,"Message ID out of range on message: %d",j
);
722 csmessages
[k
][j
]=getsstring(PQgetvalue(pgres
,i
,2),250);
728 void loadcommandsummary(Command
*cmd
) {
729 pqasyncquery(loadcommandsummary_real
, (void *)cmd
,
730 "SELECT languageID,summary from help where lower(command) = lower('%s')",cmd
->command
->content
);
733 void loadcommandsummary_real(PGconn
*dbconn
, void *arg
) {
739 /* Clear up old text first */
741 for (i
=0;i
<MAXLANG
;i
++) {
743 freesstring(cs
->bylang
[i
]);
746 pgres
=PQgetResult(dbconn
);
748 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
749 Error("chanserv",ERR_ERROR
,"Error loading command summary.");
753 if (PQnfields(pgres
)!=2) {
754 Error("chanserv",ERR_ERROR
,"Command summary format error.");
758 num
=PQntuples(pgres
);
760 for (i
=0;i
<num
;i
++) {
761 j
=strtol(PQgetvalue(pgres
,i
,0),NULL
,10);
762 if (j
<MAXLANG
&& j
>=0) {
763 cs
->bylang
[j
]=getsstring(PQgetvalue(pgres
,i
,1),200);
770 void csdb_freestuff() {
772 chanindex
*cip
, *ncip
;
779 for (i
=0;i
<REGUSERHASHSIZE
;i
++) {
780 for (rup
=regusernicktable
[i
];rup
;rup
=rup
->nextbyname
) {
781 freesstring(rup
->email
);
782 freesstring(rup
->lastuserhost
);
783 freesstring(rup
->suspendreason
);
784 freesstring(rup
->comment
);
785 freesstring(rup
->info
);
787 for (rcup
=rup
->knownon
;rcup
;rcup
=rcup
->nextbyuser
)
788 freesstring(rcup
->info
);
792 for (i
=0;i
<CHANNELHASHSIZE
;i
++) {
793 for (cip
=chantable
[i
];cip
;cip
=ncip
) {
795 if ((rcp
=cip
->exts
[chanservext
])) {
796 freesstring(rcp
->welcome
);
797 freesstring(rcp
->topic
);
798 freesstring(rcp
->key
);
799 freesstring(rcp
->suspendreason
);
800 freesstring(rcp
->comment
);
801 for (rbp
=rcp
->bans
;rbp
;rbp
=rbp
->next
) {
802 freesstring(rbp
->reason
);
803 freechanban(rbp
->cbp
);
805 cip
->exts
[chanservext
]=NULL
;
806 releasechanindex(cip
);
811 for (i
=0; i
<MAILDOMAINHASHSIZE
; i
++) {
812 for (mdp
=maildomainnametable
[i
]; mdp
; mdp
=mdp
->nextbyname
)
813 freesstring(mdp
->name
);
817 void loadsomemaildomains(PGconn
*dbconn
,void *arg
) {
822 pgres
=PQgetResult(dbconn
);
824 if (PQresultStatus(pgres
) != PGRES_TUPLES_OK
) {
825 Error("chanserv",ERR_ERROR
,"Error loading maildomain DB");
829 if (PQnfields(pgres
)!=4) {
830 Error("chanserv",ERR_ERROR
,"Mail Domain DB format error");
833 num
=PQntuples(pgres
);
837 domain
=strdup(PQgetvalue(pgres
,i
,1));
838 mdp
=findorcreatemaildomain(domain
); //@@@ LEN
840 mdp
->ID
=strtoul(PQgetvalue(pgres
,i
,0),NULL
,10);
841 mdp
->limit
=strtoul(PQgetvalue(pgres
,i
,2),NULL
,10);
842 mdp
->actlimit
=strtoul(PQgetvalue(pgres
,i
,3),NULL
,10);
843 mdp
->flags
=strtoul(PQgetvalue(pgres
,i
,4),NULL
,10);
845 if (mdp
->ID
> lastdomainID
) {
846 lastdomainID
=mdp
->ID
;
853 void loadmaildomainsdone(PGconn
*dbconn
, void *arg
) {
854 Error("chanserv",ERR_INFO
,"Load Mail Domains done (highest ID was %d)",lastdomainID
);