]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanservstdcmds.c
renamed failedinit -> cffailedinit
[irc/quakenet/newserv.git] / chanserv / chanservstdcmds.c
1 /*
2 * This contains Q9's "built in" commands and CTCP handlers
3 */
4
5 #include "chanserv.h"
6 #include "../core/schedule.h"
7 #include "../lib/irc_string.h"
8 #include "../pqsql/pqsql.h"
9
10 #include <string.h>
11
12 int cs_dorehash(void *source, int cargc, char **cargv) {
13 nick *sender=source;
14 Command *cmdlist[200];
15 int i,n;
16
17 /* Reload the response text first */
18 loadmessages();
19
20 /* Now the commands */
21 n=getcommandlist(cscommands, cmdlist, 200);
22
23 for(i=0;i<n;i++)
24 loadcommandsummary(cmdlist[i]);
25
26 chanservstdmessage(sender, QM_DONE);
27
28 return CMD_OK;
29 }
30
31 int cs_doquit(void *source, int cargc, char **cargv) {
32 char *reason="Leaving";
33 nick *sender=(nick *)source;
34
35 if (cargc>0) {
36 reason=cargv[0];
37 }
38
39 chanservstdmessage(sender, QM_DONE);
40
41 deregisterlocaluser(chanservnick, reason);
42 scheduleoneshot(time(NULL)+1,&chanservreguser,NULL);
43
44 return CMD_OK;
45 }
46
47 int cs_dorename(void *source, int cargc, char **cargv) {
48 char newnick[NICKLEN+1];
49 nick *sender=source;
50
51 if (cargc<1) {
52 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "rename");
53 return CMD_ERROR;
54 }
55
56 strncpy(newnick,cargv[0],NICKLEN);
57 newnick[NICKLEN]='\0';
58
59 renamelocaluser(chanservnick, newnick);
60 chanservstdmessage(sender, QM_DONE);
61
62 return CMD_OK;
63 }
64
65 int cs_doshowcommands(void *source, int cargc, char **cargv) {
66 nick *sender=source;
67 reguser *rup;
68 Command *cmdlist[200];
69 int i,n;
70 int lang;
71 char *message;
72 cmdsummary *summary;
73
74 n=getcommandlist(cscommands, cmdlist, 200);
75 rup=getreguserfromnick(sender);
76
77 if (!rup)
78 lang=0;
79 else
80 lang=rup->languageid;
81
82 chanservstdmessage(sender, QM_COMMANDLIST);
83
84 for (i=0;i<n;i++) {
85 if (cargc>0 && !match2strings(cargv[0],cmdlist[i]->command->content))
86 continue;
87
88 /* Don't list aliases */
89 if (cmdlist[i]->level & QCMD_ALIAS)
90 continue;
91
92 /* Check that this user can use this command.. */
93 if ((cmdlist[i]->level & QCMD_AUTHED) && !rup)
94 continue;
95
96 if ((cmdlist[i]->level & QCMD_NOTAUTHED) && rup)
97 continue;
98
99 if ((cmdlist[i]->level & QCMD_HELPER) &&
100 (!rup || !UHasHelperPriv(rup)))
101 continue;
102
103 if ((cmdlist[i]->level & QCMD_OPER) &&
104 (!rup || !UHasOperPriv(rup) || !IsOper(sender)))
105 continue;
106
107 if ((cmdlist[i]->level & QCMD_ADMIN) &&
108 (!rup || !UHasAdminPriv(rup) || !IsOper(sender)))
109 continue;
110
111 if ((cmdlist[i]->level & QCMD_DEV) &&
112 (!rup || !UIsDev(rup) || !IsOper(sender)))
113 continue;
114
115 summary=(cmdsummary *)cmdlist[i]->ext;
116
117 if (summary->bylang[lang]) {
118 message=summary->bylang[lang]->content;
119 } else if (summary->bylang[0]) {
120 message=summary->bylang[0]->content;
121 } else {
122 message=summary->def->content;
123 }
124
125 chanservsendmessage(sender, "%-20s %s",cmdlist[i]->command->content, message);
126 }
127
128 chanservstdmessage(sender, QM_ENDOFLIST);
129
130 return CMD_OK;
131 }
132
133 int cs_dohelp(void *source, int cargc, char **cargv) {
134 nick *sender=source;
135 Command *cmd;
136
137 if (cargc==0)
138 return cs_doshowcommands(source,cargc,cargv);
139
140 if (!(cmd=findcommandintree(cscommands, cargv[0], 1))) {
141 chanservstdmessage(sender, QM_UNKNOWNCMD, cargv[0]);
142 return CMD_ERROR;
143 }
144
145 csdb_dohelp(sender, cmd);
146
147 return CMD_OK;
148 }
149
150
151 int cs_doctcpping(void *source, int cargc, char **cargv) {
152 char *nullbuf="\001";
153
154 sendnoticetouser(chanservnick, source, "%cPING %s",
155 1, cargc?cargv[0]:nullbuf);
156
157 return CMD_OK;
158 }
159
160 int cs_doctcpversion(void *source, int cargc, char **cargv) {
161 sendnoticetouser(chanservnick, source, "\01VERSION Q9 version %s (Compiled on " __DATE__ ") (C) 2002-3 David Mansell (splidge)\01", QVERSION);
162 sendnoticetouser(chanservnick, source, "\01VERSION Built on newserv version 1.00. (C) 2002-3 David Mansell (splidge)\01");
163
164 return CMD_OK;
165 }
166
167 int cs_doversion(void *source, int cargc, char **cargv) {
168 chanservsendmessage((nick *)source, "Q9 version %s (Compiled on " __DATE__ ") (C) 2002-3 David Mansell (splidge)", QVERSION);
169 chanservsendmessage((nick *)source, "Built on newserv version 1.00. (C) 2002-3 David Mansell (splidge)");
170 return CMD_OK;
171 }
172
173 int cs_doctcpgender(void *source, int cargc, char **cargv) {
174 sendnoticetouser(chanservnick, source, "\1GENDER Anyone who has a bitch mode has to be female ;)\1");
175
176 return CMD_OK;
177 }
178
179 void csdb_dohelp_real(PGconn *, void *);
180
181 struct helpinfo {
182 unsigned int numeric;
183 sstring *commandname;
184 };
185
186 /* Help stuff */
187 void csdb_dohelp(nick *np, Command *cmd) {
188 struct helpinfo *hip;
189
190 hip=(struct helpinfo *)malloc(sizeof(struct helpinfo));
191
192 hip->numeric=np->numeric;
193 hip->commandname=getsstring(cmd->command->content, cmd->command->length);
194
195 pqasyncquery(csdb_dohelp_real, (void *)hip,
196 "SELECT languageID, fullinfo from help where lower(command)=lower('%s')",cmd->command->content);
197 }
198
199 void csdb_dohelp_real(PGconn *dbconn, void *arg) {
200 struct helpinfo *hip=arg;
201 nick *np=getnickbynumeric(hip->numeric);
202 reguser *rup;
203 char *result;
204 PGresult *pgres;
205 int i,j,num,lang=0;
206
207 pgres=PQgetResult(dbconn);
208
209 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
210 Error("chanserv",ERR_ERROR,"Error loading help text.");
211 return;
212 }
213
214 if (PQnfields(pgres)!=2) {
215 Error("chanserv",ERR_ERROR,"Help text format error.");
216 return;
217 }
218
219 num=PQntuples(pgres);
220
221 if (!np) {
222 PQclear(pgres);
223 freesstring(hip->commandname);
224 free(hip);
225 return;
226 }
227
228 if ((rup=getreguserfromnick(np)))
229 lang=rup->languageid;
230
231 result=NULL;
232
233 for (i=0;i<num;i++) {
234 j=strtoul(PQgetvalue(pgres,i,0),NULL,10);
235 if ((j==0 && result==NULL) || (j==lang)) {
236 result=PQgetvalue(pgres,i,1);
237 if(strlen(result)==0)
238 result=NULL;
239 }
240 }
241
242 if (!result)
243 chanservstdmessage(np, QM_NOHELP, hip->commandname->content);
244 else
245 chanservsendmessage(np, result);
246
247 freesstring(hip->commandname);
248 free(hip);
249 }
250
251 void csdb_doauthhistory_real(PGconn *dbconn,void *arg);
252 void csdb_dochanlevhistory_real(PGconn *dbconn,void *arg);
253 void csdb_doaccounthistory_real(PGconn *dbconn,void *arg);
254 void csc_dorollbackchan_real(PGconn *dbconn,void *arg);
255 void csdb_dorollbackaccount_real(PGconn *dbconn,void *arg);
256
257 struct authhistoryinfo {
258 unsigned int numeric;
259 unsigned int userID;
260 };
261
262 void csdb_retreiveauthhistory(nick *np, reguser *rup, int limit) {
263 struct authhistoryinfo *ahi;
264
265 ahi=(struct authhistoryinfo *)malloc(sizeof(struct authhistoryinfo));
266 ahi->numeric=np->numeric;
267 ahi->userID=rup->ID;
268 pqasyncquery(csdb_doauthhistory_real, (void *)ahi,
269 "SELECT userID, nick, username, host, authtime, disconnecttime from authhistory where "
270 "userID=%u order by authtime desc limit %d", rup->ID, limit);
271 }
272
273 void csdb_doauthhistory_real(PGconn *dbconn, void *arg) {
274 struct authhistoryinfo *ahi=(struct authhistoryinfo*)arg;
275 nick *np=getnickbynumeric(ahi->numeric);
276 reguser *rup;
277 char *ahnick, *ahuser, *ahhost;
278 time_t ahauthtime, ahdisconnecttime;
279 PGresult *pgres;
280 int i, num, count=0;
281 struct tm *tmp;
282 char tbuf1[15], tbuf2[15];
283
284 pgres=PQgetResult(dbconn);
285
286 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
287 Error("chanserv", ERR_ERROR, "Error loading auth history data.");
288 return;
289 }
290
291 if (PQnfields(pgres) != 6) {
292 Error("chanserv", ERR_ERROR, "Auth history data format error.");
293 return;
294 }
295
296 num=PQntuples(pgres);
297
298 if (!np) {
299 PQclear(pgres);
300 free(ahi);
301 return;
302 }
303
304 if (!(rup=getreguserfromnick(np))) {
305 PQclear(pgres);
306 free(ahi);
307 return;
308 }
309 chanservstdmessage(np, QM_AUTHHISTORYHEADER);
310 for (i=0; i<num; i++) {
311 if (!UHasHelperPriv(rup) && (strtoul(PQgetvalue(pgres, i, 0), NULL, 10) != rup->ID)) {
312 PQclear(pgres);
313 free(ahi);
314 return;
315 }
316 ahnick=PQgetvalue(pgres, i, 1);
317 ahuser=PQgetvalue(pgres, i, 2);
318 ahhost=PQgetvalue(pgres, i, 3);
319 ahauthtime=strtoul(PQgetvalue(pgres, i, 4), NULL, 10);
320 ahdisconnecttime=strtoul(PQgetvalue(pgres, i, 5), NULL, 10);
321 tmp=localtime(&ahauthtime);
322 strftime(tbuf1, 15, "%d/%m/%y %H:%M", tmp);
323 if (ahdisconnecttime) {
324 tmp=localtime(&ahdisconnecttime);
325 strftime(tbuf2, 15, "%d/%m/%y %H:%M", tmp);
326 }
327 chanservsendmessage(np, "#%-6d %-15s %-15s %-15s %s@%s", ++count, tbuf1, ahdisconnecttime?tbuf2:"never", ahnick, ahuser, ahhost);
328 }
329 chanservstdmessage(np, QM_ENDOFLIST);
330
331 PQclear(pgres);
332 free(ahi);
333 }
334
335 void csdb_retreivechanlevhistory(nick *np, regchan *rcp, time_t starttime) {
336 pqasyncquery(csdb_dochanlevhistory_real, (void *)np->numeric,
337 "SELECT userID, channelID, targetID, changetime, authtime, oldflags, newflags from chanlevhistory where "
338 "channelID=%u and changetime>%lu order by changetime desc limit 1000", rcp->ID, starttime);
339 }
340 void csdb_dochanlevhistory_real(PGconn *dbconn, void *arg) {
341 nick *np=getnickbynumeric((unsigned int)arg);
342 reguser *rup, *crup1, *crup2;
343 unsigned int userID, channelID, targetID;
344 time_t changetime, authtime;
345 flag_t oldflags, newflags;
346 PGresult *pgres;
347 int i, num, count=0;
348 struct tm *tmp;
349 char tbuf[15], fbuf[18];
350
351 pgres=PQgetResult(dbconn);
352
353 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
354 Error("chanserv", ERR_ERROR, "Error loading chanlev history data.");
355 return;
356 }
357
358 if (PQnfields(pgres) != 7) {
359 Error("chanserv", ERR_ERROR, "Chanlev history data format error.");
360 return;
361 }
362 num=PQntuples(pgres);
363
364 if (!np) {
365 PQclear(pgres);
366 return;
367 }
368
369 if (!(rup=getreguserfromnick(np)) || !UHasHelperPriv(rup)) {
370 PQclear(pgres);
371 return;
372 }
373
374 chanservsendmessage(np, "Number: Time: Changing user: Changed user: Old flags: New flags:");
375 for (i=0; i<num; i++) {
376 userID=strtoul(PQgetvalue(pgres, i, 0), NULL, 10);
377 channelID=strtoul(PQgetvalue(pgres, i, 1), NULL, 10);
378 targetID=strtoul(PQgetvalue(pgres, i, 2), NULL, 10);
379 changetime=strtoul(PQgetvalue(pgres, i, 3), NULL, 10);
380 authtime=strtoul(PQgetvalue(pgres, i, 4), NULL, 10);
381 oldflags=strtoul(PQgetvalue(pgres, i, 5), NULL, 10);
382 newflags=strtoul(PQgetvalue(pgres, i, 6), NULL, 10);
383 tmp=localtime(&changetime);
384 strftime(tbuf, 15, "%d/%m/%y %H:%M", tmp);
385 strncpy(fbuf, printflags(oldflags, rcuflags), 17);
386 fbuf[17]='\0';
387 chanservsendmessage(np, "#%-6d %-15s %-15s %-15s %-15s %s", ++count, tbuf,
388 (crup1=findreguserbyID(userID))?crup1->username:"Unknown", (crup2=findreguserbyID(targetID))?crup2->username:"Unknown",
389 fbuf, printflags(newflags, rcuflags));
390 }
391 chanservstdmessage(np, QM_ENDOFLIST);
392
393 PQclear(pgres);
394 }
395
396 void csdb_rollbackchanlevhistory(nick *np, regchan *rcp, reguser* rup, time_t starttime) {
397 if (rup)
398 pqasyncquery(csc_dorollbackchan_real, (void *)np->numeric,
399 "SELECT userID, channelID, targetID, changetime, authtime, oldflags, newflags from chanlevhistory where "
400 "userID=%u and channelID=%u and changetime>%lu order by changetime desc limit 1000", rup->ID, rcp->ID, starttime);
401 else
402 pqasyncquery(csc_dorollbackchan_real, (void *)np->numeric,
403 "SELECT userID, channelID, targetID, changetime, authtime, oldflags, newflags from chanlevhistory where "
404 "channelID=%u and changetime>%lu order by changetime desc limit 1000", rcp->ID, starttime);
405 }
406
407 void csc_dorollbackchan_real(PGconn *dbconn, void *arg) {
408 nick *np=getnickbynumeric((unsigned int)arg);
409 reguser *rup, *crup1, *crup2;
410 chanindex *cip;
411 regchan *rcp=NULL;
412 regchanuser *rcup;
413 unsigned int userID, channelID, targetID;
414 time_t changetime, authtime;
415 flag_t oldflags, newflags;
416 PGresult *pgres;
417 int i, j, num, count=0, newuser;
418 struct tm *tmp;
419 char tbuf[15], fbuf[18];
420
421 pgres=PQgetResult(dbconn);
422
423 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
424 Error("chanserv", ERR_ERROR, "Error loading chanlev history data.");
425 return;
426 }
427
428 if (PQnfields(pgres) != 7) {
429 Error("chanserv", ERR_ERROR, "Chanlev history data format error.");
430 return;
431 }
432
433 num=PQntuples(pgres);
434
435 if (!np) {
436 Error("chanserv", ERR_ERROR, "No nick pointer in rollback.");
437 PQclear(pgres);
438 return;
439 }
440 if (!(rup=getreguserfromnick(np)) || !UHasOperPriv(rup)) {
441 Error("chanserv", ERR_ERROR, "No reguser pointer or oper privs in rollback.");
442 PQclear(pgres);
443 return;
444 }
445
446 for (i=0; i<num; i++) {
447 userID=strtoul(PQgetvalue(pgres, i, 0), NULL, 10);
448 channelID=strtoul(PQgetvalue(pgres, i, 1), NULL, 10);
449
450 if (!rcp) {
451 for (j=0; j<CHANNELHASHSIZE && !rcp; j++) {
452 for (cip=chantable[j]; cip && !rcp; cip=cip->next) {
453 if (!cip->exts[chanservext])
454 continue;
455
456 if (((regchan*)cip->exts[chanservext])->ID == channelID)
457 rcp=(regchan*)cip->exts[chanservext];
458 }
459 }
460
461 if (!rcp) {
462 Error("chanserv", ERR_ERROR, "No regchan pointer or oper privs in rollback.");
463 PQclear(pgres);
464 return;
465 }
466
467 cip=rcp->index;
468
469 chanservsendmessage(np, "Attempting to roll back %s:", cip->name->content);
470 }
471 targetID=strtoul(PQgetvalue(pgres, i, 2), NULL, 10);
472 changetime=strtoul(PQgetvalue(pgres, i, 3), NULL, 10);
473 authtime=strtoul(PQgetvalue(pgres, i, 4), NULL, 10);
474 oldflags=strtoul(PQgetvalue(pgres, i, 5), NULL, 10);
475 newflags=strtoul(PQgetvalue(pgres, i, 6), NULL, 10);
476 strncpy(fbuf, printflags(newflags, rcuflags), 17);
477 fbuf[17]='\0';
478 crup1=findreguserbyID(userID);
479 crup2=findreguserbyID(targetID);
480
481 if (!crup2) {
482 chanservsendmessage(np, "Affected user (ID: %d) is no longer in database, continuing...", targetID);
483 continue;
484 }
485
486 if (!(rcup=findreguseronchannel(rcp, crup2))) {
487 rcup=getregchanuser();
488 rcup->user=crup2;
489 rcup->chan=rcp;
490 rcup->flags=0;
491 rcup->changetime=time(NULL);
492 rcup->usetime=0;
493 rcup->info=NULL;
494 newuser=1;
495 }
496 else
497 newuser=0;
498 csdb_chanlevhistory_insert(rcp, np, rcup->user, rcup->flags, oldflags);
499 rcup->flags=oldflags;
500 chanservsendmessage(np, "%s user flags for %s (%s -> %s)", newflags?oldflags?"Restoring":"Deleting":"Readding",
501 crup2->username, fbuf, printflags(oldflags, rcuflags));
502
503 if (rcup->flags) {
504 if (newuser) {
505 addregusertochannel(rcup);
506 csdb_createchanuser(rcup);
507 }
508 else
509 csdb_updatechanuser(rcup);
510 }
511 else {
512 if (!newuser) {
513 csdb_deletechanuser(rcup);
514 delreguserfromchannel(rcp, crup2);
515 }
516
517 freesstring(rcup->info);
518 freeregchanuser(rcup);
519 rcup=NULL;
520
521 for (j=0; j<REGCHANUSERHASHSIZE; j++)
522 if (rcp->regusers[j])
523 break;
524
525 if (i==REGCHANUSERHASHSIZE) {
526 cs_log(np, "DELCHAN %s (Cleared chanlev from rollback)", cip->name->content);
527 chanservsendmessage(np, "Rollback cleared chanlev list, channel deleted.");
528 rcp=NULL;
529 }
530 }
531 }
532 chanservstdmessage(np, QM_DONE);
533
534 PQclear(pgres);
535 }
536
537 void csdb_retreiveaccounthistory(nick *np, reguser *rup, int limit) {
538 pqasyncquery(csdb_doaccounthistory_real, (void *)np->numeric,
539 "SELECT userID, changetime, authtime, oldpassword, newpassword, oldemail, newemail from accounthistory where "
540 "userID=%u order by changetime desc limit %d", rup->ID, limit);
541 }
542
543 void csdb_doaccounthistory_real(PGconn *dbconn, void *arg) {
544 nick *np=getnickbynumeric((unsigned int)arg);
545 reguser *rup;
546 unsigned int userID;
547 char *oldpass, *newpass, *oldemail, *newemail;
548 time_t changetime, authtime;
549 PGresult *pgres;
550 int i, num, count=0;
551 struct tm *tmp;
552 char tbuf[15];
553
554 pgres=PQgetResult(dbconn);
555
556 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
557 Error("chanserv", ERR_ERROR, "Error loading account history data.");
558 return;
559 }
560
561 if (PQnfields(pgres) != 7) {
562 Error("chanserv", ERR_ERROR, "Account history data format error.");
563 return;
564 }
565
566 num=PQntuples(pgres);
567
568 if (!np) {
569 PQclear(pgres);
570 return;
571 }
572
573 if (!(rup=getreguserfromnick(np)) || !UHasOperPriv(rup)) {
574 Error("chanserv", ERR_ERROR, "No reguser pointer or oper privs in account history.");
575 PQclear(pgres);
576 return;
577 }
578
579 chanservsendmessage(np, "Number: Time: Old password: New password: Old email: New email:");
580 for (i=0; i<num; i++) {
581 userID=strtoul(PQgetvalue(pgres, i, 0), NULL, 10);
582 changetime=strtoul(PQgetvalue(pgres, i, 1), NULL, 10);
583 authtime=strtoul(PQgetvalue(pgres, i, 2), NULL, 10);
584 oldpass=PQgetvalue(pgres, i, 3);
585 newpass=PQgetvalue(pgres, i, 4);
586 oldemail=PQgetvalue(pgres, i, 5);
587 newemail=PQgetvalue(pgres, i, 6);
588 tmp=localtime(&changetime);
589 strftime(tbuf, 15, "%d/%m/%y %H:%M", tmp);
590 chanservsendmessage(np, "#%-6d %-15s %-14s %-14s %-30s %s", ++count, tbuf, oldpass, newpass, oldemail, newemail);
591 }
592 chanservstdmessage(np, QM_ENDOFLIST);
593
594 PQclear(pgres);
595 }
596
597 void csdb_rollbackaccounthistory(nick *np, reguser* rup, time_t starttime) {
598 pqasyncquery(csdb_dorollbackaccount_real, (void *)np->numeric,
599 "SELECT userID, changetime, authtime, oldpassword, newpassword, oldemail, newemail from accounthistory where "
600 "userID=%u and changetime>%lu order by changetime desc limit 10", rup->ID, starttime);
601 }
602
603 void csdb_dorollbackaccount_real(PGconn *dbconn, void *arg) {
604 nick *np=getnickbynumeric((unsigned int)arg);
605 reguser *rup;
606 unsigned int userID;
607 char *oldpass, *newpass, *oldemail, *newemail;
608 time_t changetime, authtime;
609 PGresult *pgres;
610 int i, num, count=0;
611 struct tm *tmp;
612 char tbuf[15];
613
614 pgres=PQgetResult(dbconn);
615
616 if (PQresultStatus(pgres) != PGRES_TUPLES_OK) {
617 Error("chanserv", ERR_ERROR, "Error loading account rollback data.");
618 return;
619 }
620
621 if (PQnfields(pgres) != 7) {
622 Error("chanserv", ERR_ERROR, "Account rollback data format error.");
623 return;
624 }
625
626 num=PQntuples(pgres);
627
628 if (!np) {
629 PQclear(pgres);
630 return;
631 }
632
633 if (!(rup=getreguserfromnick(np)) || !UHasOperPriv(rup)) {
634 Error("chanserv", ERR_ERROR, "No reguser pointer or oper privs in rollback account.");
635 PQclear(pgres);
636 return;
637 }
638
639 chanservsendmessage(np, "Attempting to rollback account %s:", rup->username);
640 for (i=0; i<num; i++) {
641 userID=strtoul(PQgetvalue(pgres, i, 0), NULL, 10);
642 changetime=strtoul(PQgetvalue(pgres, i, 1), NULL, 10);
643 authtime=strtoul(PQgetvalue(pgres, i, 2), NULL, 10);
644 oldpass=PQgetvalue(pgres, i, 3);
645 newpass=PQgetvalue(pgres, i, 4);
646 oldemail=PQgetvalue(pgres, i, 5);
647 newemail=PQgetvalue(pgres, i, 6);
648 if (strlen(newpass) > 0) {
649 setpassword(rup, oldpass);
650 chanservsendmessage(np, "Restoring old password (%s -> %s)", newpass, oldpass);
651 }
652 else if (strlen(newemail) > 0) {
653 freesstring(rup->email);
654 rup->email=getsstring(oldemail, EMAILLEN);
655 rup->lastemailchange=changetime;
656 chanservsendmessage(np, "Restoring old email (%s -> %s)", newemail, oldemail);
657 }
658 }
659 csdb_updateuser(rup);
660 chanservstdmessage(np, QM_DONE);
661
662 PQclear(pgres);
663 }
664