]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservdb_updates.c
CHANSERV: batch up channel stat updates.
[irc/quakenet/newserv.git] / chanserv / chanservdb_updates.c
1 /*
2 * chanservdb_updates.c:
3 * Handle all the update requests for the database.
4 */
5
6 #include "chanserv.h"
7 #include "../dbapi/dbapi.h"
8 #include "../core/config.h"
9 #include "../lib/sstring.h"
10 #include "../parser/parser.h"
11 #include "../core/events.h"
12
13 #include <string.h>
14 #include <stdio.h>
15 #include <sys/poll.h>
16 #include <stdarg.h>
17
18 void csdb_updateauthinfo(reguser *rup) {
19 char eschost[2*HOSTLEN+1];
20
21 dbescapestring(eschost,rup->lastuserhost->content,rup->lastuserhost->length);
22 dbquery("UPDATE chanserv.users SET lastauth=%lu,lastuserhost='%s' WHERE ID=%u",
23 rup->lastauth,eschost,rup->ID);
24 }
25
26 void csdb_updatelastjoin(regchanuser *rcup) {
27 dbquery("UPDATE chanserv.chanusers SET usetime=%lu WHERE userID=%u and channelID=%u",
28 rcup->usetime, rcup->user->ID, rcup->chan->ID);
29 }
30
31 void csdb_updatetopic(regchan *rcp) {
32 char esctopic[TOPICLEN*2+5];
33
34 if (rcp->topic) {
35 dbescapestring(esctopic,rcp->topic->content,rcp->topic->length);
36 } else {
37 esctopic[0]='\0';
38 }
39 dbquery("UPDATE chanserv.channels SET topic='%s' WHERE ID=%u",esctopic,rcp->ID);
40 }
41
42 void csdb_updatechannel(regchan *rcp) {
43 char escwelcome[WELCOMELEN*2+1];
44 char esctopic[TOPICLEN*2+1];
45 char esckey[70];
46 char escreason[510];
47 char esccomment[510];
48 char escname[1000];
49
50 dbescapestring(escname, rcp->index->name->content, rcp->index->name->length);
51
52 if (rcp->welcome)
53 dbescapestring(escwelcome, rcp->welcome->content,
54 rcp->welcome->length);
55 else
56 escwelcome[0]='\0';
57
58 if (rcp->topic)
59 dbescapestring(esctopic, rcp->topic->content, rcp->topic->length);
60 else
61 esctopic[0]='\0';
62
63 if (rcp->key)
64 dbescapestring(esckey, rcp->key->content, rcp->key->length);
65 else
66 esckey[0]='\0';
67
68 if (rcp->suspendreason)
69 dbescapestring(escreason, rcp->suspendreason->content,
70 rcp->suspendreason->length);
71 else
72 escreason[0]='\0';
73
74 if (rcp->comment)
75 dbescapestring(esccomment, rcp->comment->content,
76 rcp->comment->length);
77 else
78 esccomment[0]='\0';
79
80 dbquery("UPDATE chanserv.channels SET name='%s', flags=%d, forcemodes=%d,"
81 "denymodes=%d, chanlimit=%d, autolimit=%d, banstyle=%d,"
82 "lastactive=%lu,statsreset=%lu, banduration=%lu, founder=%u,"
83 "addedby=%u, suspendby=%u, suspendtime=%lu, chantype=%d, totaljoins=%u,"
84 "tripjoins=%u, maxusers=%u, tripusers=%u,"
85 "welcome='%s', topic='%s', chankey='%s', suspendreason='%s',"
86 "comment='%s', lasttimestamp=%jd WHERE ID=%u",escname,rcp->flags,rcp->forcemodes,
87 rcp->denymodes,rcp->limit,rcp->autolimit, rcp->banstyle,
88 rcp->lastactive,rcp->statsreset,rcp->banduration,
89 rcp->founder, rcp->addedby, rcp->suspendby, rcp->suspendtime,
90 rcp->chantype,rcp->totaljoins,rcp->tripjoins,
91 rcp->maxusers,rcp->tripusers,
92 escwelcome,esctopic,esckey,escreason,esccomment,(intmax_t)rcp->ltimestamp,rcp->ID);
93 }
94
95 #define CHANNELCOUNTER_BUFSIZE 512
96 #define CHANNELCOUNTER_MAX 512
97
98 static int channelcounter_count = 0;
99 static char channelcounter_bufs[CHANNELCOUNTER_MAX][CHANNELCOUNTER_BUFSIZE];
100
101 void csdb_flushchannelcounters(void *arg) {
102 int i;
103
104 if(!channelcounter_count)
105 return;
106
107 dbquery("BEGIN TRANSACTION;");
108
109 for(i=0;i<channelcounter_count;i++)
110 dbquery("%s", channelcounter_bufs[i]);
111
112 dbquery("COMMIT;");
113
114 channelcounter_count = 0;
115 }
116
117 void csdb_updatechannelcounters(regchan *rcp) {
118 if(channelcounter_count == CHANNELCOUNTER_MAX)
119 csdb_flushchannelcounters(NULL);
120
121 snprintf(channelcounter_bufs[channelcounter_count], CHANNELCOUNTER_BUFSIZE - 1, "UPDATE chanserv.channels SET "
122 "lastactive=%lu, totaljoins=%u,"
123 "tripjoins=%u, maxusers=%u, tripusers=%u "
124 "WHERE ID=%u",
125 rcp->lastactive,
126 rcp->totaljoins,rcp->tripjoins,
127 rcp->maxusers,rcp->tripusers,
128 rcp->ID);
129
130 channelcounter_count++;
131 }
132
133 void csdb_updatechanneltimestamp(regchan *rcp) {
134 dbquery("UPDATE chanserv.channels SET "
135 "lasttimestamp=%jd WHERE ID=%u",
136 (intmax_t)rcp->ltimestamp, rcp->ID);
137 }
138
139 void csdb_createchannel(regchan *rcp) {
140 char escwelcome[WELCOMELEN*2+1];
141 char esctopic[TOPICLEN*2+1];
142 char esckey[70];
143 char escreason[510];
144 char esccomment[510];
145 char escname[510];
146
147 dbescapestring(escname, rcp->index->name->content, rcp->index->name->length);
148
149 if (rcp->welcome)
150 dbescapestring(escwelcome, rcp->welcome->content,
151 rcp->welcome->length);
152 else
153 escwelcome[0]='\0';
154
155 if (rcp->topic)
156 dbescapestring(esctopic, rcp->topic->content, rcp->topic->length);
157 else
158 esctopic[0]='\0';
159
160 if (rcp->key)
161 dbescapestring(esckey, rcp->key->content, rcp->key->length);
162 else
163 esckey[0]='\0';
164
165 if (rcp->suspendreason)
166 dbescapestring(escreason, rcp->suspendreason->content,
167 rcp->suspendreason->length);
168 else
169 escreason[0]='\0';
170
171 if (rcp->comment)
172 dbescapestring(esccomment, rcp->comment->content,
173 rcp->comment->length);
174 else
175 esccomment[0]='\0';
176
177 dbquery("INSERT INTO chanserv.channels (ID, name, flags, forcemodes, denymodes,"
178 "chanlimit, autolimit, banstyle, created, lastactive, statsreset, "
179 "banduration, founder, addedby, suspendby, suspendtime, chantype, totaljoins, tripjoins,"
180 "maxusers, tripusers, welcome, topic, chankey, suspendreason, "
181 "comment, lasttimestamp) VALUES (%u,'%s',%d,%d,%d,%d,%d,%d,%lu,%lu,%lu,%lu,%u,"
182 "%u,%u,%lu,%d,%u,%u,%u,%u,'%s','%s','%s','%s','%s',%jd)",
183 rcp->ID, escname, rcp->flags,rcp->forcemodes,
184 rcp->denymodes,rcp->limit,rcp->autolimit, rcp->banstyle, rcp->created,
185 rcp->lastactive,rcp->statsreset,rcp->banduration,
186 rcp->founder, rcp->addedby, rcp->suspendby, rcp->suspendtime,
187 rcp->chantype,rcp->totaljoins,rcp->tripjoins,
188 rcp->maxusers,rcp->tripusers,
189 escwelcome,esctopic,esckey,escreason,esccomment,(intmax_t)rcp->ltimestamp);
190 }
191
192 void csdb_deletechannel(regchan *rcp) {
193 dbquery("DELETE FROM chanserv.channels WHERE ID=%u",rcp->ID);
194 dbquery("DELETE FROM chanserv.chanusers WHERE channelID=%u",rcp->ID);
195 dbquery("DELETE FROM chanserv.bans WHERE channelID=%u",rcp->ID);
196 }
197
198 void csdb_deleteuser(reguser *rup) {
199 dbquery("DELETE FROM chanserv.users WHERE ID=%u",rup->ID);
200 dbquery("DELETE FROM chanserv.chanusers WHERE userID=%u",rup->ID);
201 }
202
203 void csdb_updateuser(reguser *rup) {
204 char escpassword[25];
205 char escemail[210];
206 char esclastuserhost[160];
207 char escreason[510];
208 char esccomment[510];
209 char escinfo[210];
210 char esclastemail[210];
211
212 dbescapestring(escpassword, rup->password, strlen(rup->password));
213
214 if (rup->email)
215 dbescapestring(escemail, rup->email->content, rup->email->length);
216 else
217 escemail[0]='\0';
218
219 if (rup->lastemail)
220 dbescapestring(esclastemail, rup->lastemail->content, rup->lastemail->length);
221 else
222 esclastemail[0]='\0';
223
224 if (rup->lastuserhost)
225 dbescapestring(esclastuserhost, rup->lastuserhost->content, rup->lastuserhost->length);
226 else
227 esclastuserhost[0]='\0';
228
229 if (rup->suspendreason)
230 dbescapestring(escreason, rup->suspendreason->content, rup->suspendreason->length);
231 else
232 escreason[0]='\0';
233
234 if (rup->comment)
235 dbescapestring(esccomment, rup->comment->content, rup->comment->length);
236 else
237 esccomment[0]='\0';
238
239 if (rup->info)
240 dbescapestring(escinfo, rup->info->content, rup->info->length);
241 else
242 escinfo[0]='\0';
243
244 dbquery("UPDATE chanserv.users SET lastauth=%lu, lastemailchng=%lu, flags=%u,"
245 "language=%u, suspendby=%u, suspendexp=%lu, suspendtime=%lu, lockuntil=%lu, password='%s', email='%s',"
246 "lastuserhost='%s', suspendreason='%s', comment='%s', info='%s', lastemail='%s', lastpasschng=%lu "
247 " WHERE ID=%u",
248 rup->lastauth, rup->lastemailchange, rup->flags, rup->languageid, rup->suspendby, rup->suspendexp,
249 rup->suspendtime, rup->lockuntil, escpassword, escemail, esclastuserhost, escreason, esccomment, escinfo, esclastemail,
250 rup->lastpasschange,
251 rup->ID);
252 }
253
254 void csdb_createuser(reguser *rup) {
255 char escpassword[25];
256 char escemail[210];
257 char esclastuserhost[160];
258 char escreason[510];
259 char esccomment[510];
260 char escusername[35];
261 char escinfo[210];
262 char esclastemail[210];
263
264 dbescapestring(escusername, rup->username, strlen(rup->username));
265 dbescapestring(escpassword, rup->password, strlen(rup->password));
266
267 if (rup->email)
268 dbescapestring(escemail, rup->email->content, rup->email->length);
269 else
270 escemail[0]='\0';
271
272 if (rup->lastemail)
273 dbescapestring(esclastemail, rup->lastemail->content, rup->lastemail->length);
274 else
275 esclastemail[0]='\0';
276
277 if (rup->lastuserhost)
278 dbescapestring(esclastuserhost, rup->lastuserhost->content, rup->lastuserhost->length);
279 else
280 esclastuserhost[0]='\0';
281
282 if (rup->suspendreason)
283 dbescapestring(escreason, rup->suspendreason->content, rup->suspendreason->length);
284 else
285 escreason[0]='\0';
286
287 if (rup->comment)
288 dbescapestring(esccomment, rup->comment->content, rup->comment->length);
289 else
290 esccomment[0]='\0';
291
292 if (rup->info)
293 dbescapestring(escinfo, rup->info->content, rup->info->length);
294 else
295 escinfo[0]='\0';
296
297 dbquery("INSERT INTO chanserv.users (ID, username, created, lastauth, lastemailchng, "
298 "flags, language, suspendby, suspendexp, suspendtime, lockuntil, password, email, lastuserhost, "
299 "suspendreason, comment, info, lastemail, lastpasschng)"
300 "VALUES (%u,'%s',%lu,%lu,%lu,%u,%u,%u,%lu,%lu,%lu,'%s','%s','%s','%s','%s','%s','%s',%lu)",
301 rup->ID, escusername, rup->created, rup->lastauth, rup->lastemailchange, rup->flags,
302 rup->languageid, rup->suspendby, rup->suspendexp, rup->suspendtime, rup->lockuntil,
303 escpassword, escemail, esclastuserhost, escreason, esccomment, escinfo, esclastemail,
304 rup->lastpasschange);
305 }
306
307
308 void csdb_updatechanuser(regchanuser *rcup) {
309 char escinfo[210];
310
311 if (rcup->info)
312 dbescapestring(escinfo, rcup->info->content, rcup->info->length);
313 else
314 escinfo[0]='\0';
315
316 dbquery("UPDATE chanserv.chanusers SET flags=%u, changetime=%lu, "
317 "usetime=%lu, info='%s' WHERE channelID=%u and userID=%u",
318 rcup->flags, rcup->changetime, rcup->usetime, escinfo, rcup->chan->ID,rcup->user->ID);
319 }
320
321 void csdb_createchanuser(regchanuser *rcup) {
322 char escinfo[210];
323
324 if (rcup->info)
325 dbescapestring(escinfo, rcup->info->content, rcup->info->length);
326 else
327 escinfo[0]='\0';
328
329 dbquery("INSERT INTO chanserv.chanusers VALUES(%u, %u, %u, %lu, %lu, '%s')",
330 rcup->user->ID, rcup->chan->ID, rcup->flags, rcup->changetime,
331 rcup->usetime, escinfo);
332 }
333
334 void csdb_deletechanuser(regchanuser *rcup) {
335 dbquery("DELETE FROM chanserv.chanusers WHERE channelid=%u AND userID=%u",
336 rcup->chan->ID, rcup->user->ID);
337 }
338
339 void csdb_createban(regchan *rcp, regban *rbp) {
340 char escreason[500];
341 char banstr[100];
342 char escban[200];
343
344 strcpy(banstr,bantostring(rbp->cbp));
345 dbescapestring(escban,banstr,strlen(banstr));
346
347 if (rbp->reason)
348 dbescapestring(escreason, rbp->reason->content, rbp->reason->length);
349 else
350 escreason[0]='\0';
351
352 dbquery("INSERT INTO chanserv.bans (banID, channelID, userID, hostmask, "
353 "expiry, reason) VALUES (%u,%u,%u,'%s',%lu,'%s')", rbp->ID, rcp->ID,
354 rbp->setby, escban, rbp->expiry, escreason);
355 }
356
357 void csdb_updateban(regchan *rcp, regban *rbp) {
358 char escreason[500];
359 char banstr[100];
360 char escban[200];
361
362 strcpy(banstr,bantostring(rbp->cbp));
363 dbescapestring(escban,banstr,strlen(banstr));
364
365 if (rbp->reason)
366 dbescapestring(escreason, rbp->reason->content, rbp->reason->length);
367 else
368 escreason[0]='\0';
369
370 dbquery("UPDATE chanserv.bans set channelID=%u, userID=%u, hostmask='%s', expiry=%lu, reason='%s' "
371 "WHERE banID=%u", rcp->ID, rbp->setby, escban, rbp->expiry, escreason, rbp->ID);
372 }
373
374 void csdb_deleteban(regban *rbp) {
375 dbquery("DELETE FROM chanserv.bans WHERE banID=%u", rbp->ID);
376 }
377
378 void csdb_createmail(reguser *rup, int type) {
379 char sqlquery[6000];
380 char escemail[210];
381
382 if (type == QMAIL_NEWEMAIL) {
383 if (rup->email) {
384 dbescapestring(escemail, rup->email->content, rup->email->length);
385 sprintf(sqlquery, "INSERT INTO chanserv.email (userID, emailType, prevEmail) "
386 "VALUES (%u,%u,'%s')", rup->ID, type, escemail);
387 }
388 } else {
389 sprintf(sqlquery, "INSERT INTO chanserv.email (userID, emailType) VALUES (%u,%u)", rup->ID, type);
390 }
391
392 dbquery("%s", sqlquery);
393 }
394
395 void csdb_deletemaildomain(maildomain *mdp) {
396 dbquery("DELETE FROM chanserv.maildomain WHERE ID=%u", mdp->ID);
397 }
398
399 void csdb_createmaildomain(maildomain *mdp) {
400 char escdomain[210];
401 dbescapestring(escdomain, mdp->name->content, mdp->name->length);
402
403 dbquery("INSERT INTO chanserv.maildomain (id, name, domainlimit, actlimit, flags) VALUES(%u, '%s', %u, %u, %u)", mdp->ID,escdomain,mdp->limit,mdp->actlimit,mdp->flags);
404 }
405
406 void csdb_updatemaildomain(maildomain *mdp) {
407 char escdomain[210];
408 dbescapestring(escdomain, mdp->name->content, mdp->name->length);
409
410 dbquery("UPDATE chanserv.maildomain SET domainlimit=%u, actlimit=%u, flags=%u, name='%s' WHERE ID=%u", mdp->limit,mdp->actlimit,mdp->flags,escdomain,mdp->ID);
411 }
412
413 void csdb_chanlevhistory_insert(regchan *rcp, nick *np, reguser *trup, flag_t oldflags, flag_t newflags) {
414 reguser *rup=getreguserfromnick(np);
415
416 dbquery("INSERT INTO chanserv.chanlevhistory (userID, channelID, targetID, changetime, authtime, "
417 "oldflags, newflags) VALUES (%u, %u, %u, %lu, %lu, %u, %u)", rup->ID, rcp->ID, trup->ID, getnettime(), np->accountts,
418 oldflags, newflags);
419 }
420
421 void csdb_accounthistory_insert(nick *np, char *oldpass, char *newpass, char *oldemail, char *newemail) {
422 reguser *rup=getreguserfromnick(np);
423 char escoldpass[PASSLEN*2+5];
424 char escnewpass[PASSLEN*2+5];
425 char escoldemail[EMAILLEN*2+5];
426 char escnewemail[EMAILLEN*2+5];
427
428 if (!rup || UHasOperPriv(rup))
429 return;
430
431 if (oldpass)
432 dbescapestring(escoldpass, oldpass, CSMIN(strlen(oldpass), PASSLEN));
433 else
434 escoldpass[0]='\0';
435
436 if (newpass)
437 dbescapestring(escnewpass, newpass, CSMIN(strlen(newpass), PASSLEN));
438 else
439 escnewpass[0]='\0';
440
441 if (oldemail)
442 dbescapestring(escoldemail, oldemail, CSMIN(strlen(oldemail), EMAILLEN));
443 else
444 escoldemail[0]='\0';
445 if (newemail)
446 dbescapestring(escnewemail, newemail, CSMIN(strlen(newemail), EMAILLEN));
447 else
448 escnewemail[0]='\0';
449
450 dbquery("INSERT INTO chanserv.accounthistory (userID, changetime, authtime, oldpassword, newpassword, oldemail, "
451 "newemail) VALUES (%u, %lu, %lu, '%s', '%s', '%s', '%s')", rup->ID, getnettime(), np->accountts, escoldpass, escnewpass,
452 escoldemail, escnewemail);
453 }
454
455 void csdb_cleanuphistories(time_t expire_time) {
456 Error("chanserv", ERR_INFO, "Cleaning histories.");
457 dbquery("DELETE FROM chanserv.authhistory WHERE disconnecttime < %lu AND disconnecttime <> 0", expire_time);
458 dbquery("DELETE FROM chanserv.chanlevhistory WHERE authtime < %lu", expire_time);
459 dbquery("DELETE FROM chanserv.accounthistory WHERE authtime < %lu", expire_time);
460 }
461
462 void csdb_deletemaillock(maillock *mlp) {
463 dbquery("DELETE FROM chanserv.maillocks WHERE ID=%u", mlp->id);
464 }
465
466 void csdb_createmaillock(maillock *mlp) {
467 char escpattern[1024], escreason[1024];
468
469 dbescapestring(escpattern, mlp->pattern->content, mlp->pattern->length);
470
471 if (mlp->reason)
472 dbescapestring(escreason, mlp->reason->content, mlp->reason->length);
473 else
474 escreason[0]='\0';
475
476 dbquery("INSERT INTO chanserv.maillocks (id, pattern, reason, createdby, created) VALUES(%u, '%s', '%s', %u, %jd)",
477 mlp->id,escpattern,escreason,mlp->createdby,(intmax_t)mlp->created);
478 }
479
480 void csdb_updatemaillock(maillock *mlp) {
481 char escpattern[1024], escreason[1024];
482
483 dbescapestring(escpattern, mlp->pattern->content, mlp->pattern->length);
484
485 if (mlp->reason)
486 dbescapestring(escreason, mlp->reason->content, mlp->reason->length);
487 else
488 escreason[0]='\0';
489
490 dbquery("UPDATE chanserv.maillocks SET pattern='%s', reason='%s', createdby=%u, created=%jd WHERE ID=%u", escpattern, escreason, mlp->createdby, (intmax_t)mlp->created, mlp->id);
491 }
492