]> jfr.im git - irc/quakenet/newserv.git/blame - request/request.c
r592@blue (orig r482): cruicky | 2006-05-04 15:00:58 +0100
[irc/quakenet/newserv.git] / request / request.c
CommitLineData
25b7d0fa
P
1 /* shroud's service request */
2
bdd430cb 3#include <stdio.h>
25b7d0fa
P
4#include "../localuser/localuser.h"
5#include "../localuser/localuserchannel.h"
6#include "../core/schedule.h"
7#include "../lib/irc_string.h"
8#include "../lib/splitline.h"
9#include "../control/control.h"
10#include "request.h"
11#include "request_block.h"
12#include "lrequest.h"
13#include "sqrequest.h"
f3c45977 14#include "user.h"
25b7d0fa
P
15
16nick *rqnick;
17CommandTree *rqcommands;
18
19void rq_registeruser(void);
20void rq_handler(nick *target, int type, void **args);
21
22int rqcmd_showcommands(void *user, int cargc, char **cargv);
23int rqcmd_request(void *user, int cargc, char **cargv);
24int rqcmd_requestspamscan(void *user, int cargc, char **cargv);
25int rqcmd_addblock(void *user, int cargc, char **cargv);
26int rqcmd_delblock(void *user, int cargc, char **cargv);
27int rqcmd_listblocks(void *user, int cargc, char **cargv);
28int rqcmd_stats(void *user, int cargc, char **cargv);
aee804f9 29int rqcmd_requestop(void *user, int cargc, char **cargv);
25b7d0fa 30
f3c45977
P
31int rqcmd_adduser(void *user, int cargc, char **cargv);
32int rqcmd_deluser(void *user, int cargc, char **cargv);
33int rqcmd_changelev(void *user, int cargc, char **cargv);
34int rqcmd_userlist(void *user, int cargc, char **cargv);
35
25b7d0fa
P
36#define min(a,b) ((a > b) ? b : a)
37
38/* stats counters */
39int rq_count = 0;
40int rq_failed = 0;
41int rq_success = 0;
42int rq_blocked = 0;
43
bdd430cb
CP
44/* log fd */
45FILE *rq_logfd;
46
25b7d0fa
P
47void _init(void) {
48 rqcommands = newcommandtree();
49
50 addcommandtotree(rqcommands, "showcommands", RQU_ANY, 1, &rqcmd_showcommands);
51 addcommandtotree(rqcommands, "requestbot", RQU_ANY, 1, &rqcmd_request);
52 addcommandtotree(rqcommands, "requestspamscan", RQU_ANY, 1, &rqcmd_requestspamscan);
aee804f9
CP
53 addcommandtotree(rqcommands, "requestop", RQU_ANY, 2, &rqcmd_requestop);
54
f3c45977
P
55 addcommandtotree(rqcommands, "addblock", RQU_ACCOUNT, 3, &rqcmd_addblock);
56 addcommandtotree(rqcommands, "delblock", RQU_ACCOUNT, 1, &rqcmd_delblock);
57 addcommandtotree(rqcommands, "listblocks", RQU_ACCOUNT, 1, &rqcmd_listblocks);
58 addcommandtotree(rqcommands, "stats", RQU_ACCOUNT, 1, &rqcmd_stats);
59
60 addcommandtotree(rqcommands, "adduser", RQU_OPER, 2, &rqcmd_adduser);
61 addcommandtotree(rqcommands, "deluser", RQU_OPER, 1, &rqcmd_deluser);
62 addcommandtotree(rqcommands, "changelev", RQU_OPER, 2, &rqcmd_changelev);
63 addcommandtotree(rqcommands, "userlist", RQU_OPER, 1, &rqcmd_userlist);
64
25b7d0fa
P
65 rq_initblocks();
66 qr_initrequest();
f3c45977 67 ru_load();
25b7d0fa 68
bdd430cb
CP
69 rq_logfd = fopen(RQ_LOGFILE, "a");
70
25b7d0fa
P
71 scheduleoneshot(time(NULL) + 1, (ScheduleCallback)&rq_registeruser, NULL);
72}
73
74void _fini(void) {
75 deregisterlocaluser(rqnick, NULL);
76
77 deletecommandfromtree(rqcommands, "showcommands", &rqcmd_showcommands);
78 deletecommandfromtree(rqcommands, "requestbot", &rqcmd_request);
79 deletecommandfromtree(rqcommands, "requestspamscan", &rqcmd_requestspamscan);
aee804f9
CP
80 deletecommandfromtree(rqcommands, "requestop", &rqcmd_requestop);
81
25b7d0fa
P
82 deletecommandfromtree(rqcommands, "addblock", &rqcmd_addblock);
83 deletecommandfromtree(rqcommands, "delblock", &rqcmd_delblock);
84 deletecommandfromtree(rqcommands, "listblocks", &rqcmd_listblocks);
85 deletecommandfromtree(rqcommands, "stats", &rqcmd_stats);
86
f3c45977
P
87 deletecommandfromtree(rqcommands, "adduser", &rqcmd_adduser);
88 deletecommandfromtree(rqcommands, "deluser", &rqcmd_deluser);
89 deletecommandfromtree(rqcommands, "changelev", &rqcmd_changelev);
90 deletecommandfromtree(rqcommands, "userlist", &rqcmd_userlist);
91
25b7d0fa
P
92 destroycommandtree(rqcommands);
93
94 rq_finiblocks();
95 qr_finirequest();
f3c45977 96 ru_persist();
25b7d0fa 97
bdd430cb
CP
98 if (rq_logfd != NULL)
99 fclose(rq_logfd);
100
25b7d0fa
P
101 deleteallschedules((ScheduleCallback)&rq_registeruser);
102}
103
104void rq_registeruser(void) {
105 channel *cp;
106
107 rqnick = registerlocaluser(RQ_REQUEST_NICK, RQ_REQUEST_USER, RQ_REQUEST_HOST,
108 RQ_REQUEST_REAL, RQ_REQUEST_AUTH,
109 UMODE_ACCOUNT | UMODE_SERVICE | UMODE_OPER,
110 rq_handler);
111
112 cp = findchannel(RQ_TLZ);
113
114 if (cp == NULL)
115 localcreatechannel(rqnick, RQ_TLZ);
116 else
117 localjoinchannel(rqnick, cp);
118}
119
120char *rq_longtoduration(unsigned long interval) {
121 static char buf[100];
122
123 strncpy(buf, longtoduration(interval, 0), sizeof(buf));
124
125 /* chop off last character if it's a space */
126 if (buf[strlen(buf)] == ' ')
127 buf[strlen(buf)] = '\0';
128
129 return buf;
130}
131
132void rq_handler(nick *target, int type, void **params) {
133 Command* cmd;
134 nick* user;
135 char* line;
136 int cargc;
137 char* cargv[30];
138
139 switch (type) {
140 case LU_PRIVMSG:
141 case LU_SECUREMSG:
142 user = params[0];
143 line = params[1];
144 cargc = splitline(line, cargv, 30, 0);
145
146 if (cargc == 0)
147 return;
148
149 cmd = findcommandintree(rqcommands, cargv[0], 1);
150
151 if (cmd == NULL) {
152 sendnoticetouser(rqnick, user, "Unknown command.");
153
154 return;
155 }
156
f3c45977 157 if ((cmd->level & RQU_OPER) && !IsOper(user)) {
25b7d0fa
P
158 sendnoticetouser(rqnick, user, "Sorry, this command is not "
159 "available to you.");
160
161 return;
162 }
163
f3c45977
P
164 if ((cmd->level & RQU_ACCOUNT) && (!IsAccount(user) || ru_getlevel(user) == 0) && !IsOper(user)) {
165 sendnoticetouser(rqnick, user, "Sorry, this command is not "
166 "available to you.");
167
168 return;
169 }
170
25b7d0fa
P
171 if (cargc - 1 > cmd->maxparams)
172 rejoinline(cargv[cmd->maxparams], cargc - cmd->maxparams);
173
174 /* handle the command */
175 cmd->handler((void*)user, min(cargc - 1, cmd->maxparams), &(cargv[1]));
176
177 break;
178 case LU_KILLED:
179 scheduleoneshot(time(NULL) + 5, (ScheduleCallback)&rq_registeruser, NULL);
180
181 break;
182 case LU_PRIVNOTICE:
183 qr_handlenotice(params[0], params[1]);
184
185 break;
186 }
187}
188
189int rqcmd_showcommands(void *user, int cargc, char **cargv) {
190 int n, i;
191 Command* cmdlist[50];
192
193 n = getcommandlist(rqcommands, cmdlist, 50);
194
195 sendnoticetouser(rqnick, (nick*)user, "Available commands:");
196 sendnoticetouser(rqnick, (nick*)user, "-------------------");
197
198 for (i = 0; i < n; i++) {
f3c45977
P
199 if (((cmdlist[i]->level & RQU_OPER) == 0 || IsOper((nick*)user)) &&
200 (((cmdlist[i]->level & RQU_ACCOUNT) == 0 || (IsOper((nick*)user) || (IsAccount((nick*)user)) && ru_getlevel((nick*)user) > 0))))
25b7d0fa
P
201 sendnoticetouser(rqnick, (nick*)user, "%s", cmdlist[i]->command->content);
202 }
203
204 sendnoticetouser(rqnick, (nick*)user, "End of SHOWCOMMANDS");
205
206 return 0;
207}
208
209int rq_genericrequestcheck(nick *np, char *channelname, channel **cp, nick **lnick, nick **qnick) {
210 unsigned long *userhand;
211 rq_block *block;
212
213 if (!IsAccount(np)) {
214 sendnoticetouser(rqnick, np, "Error: You must be authed.");
215
216 return RQ_ERROR;
217 }
218
219 *cp = findchannel(channelname);
220
221 if (*cp == NULL) {
222 sendnoticetouser(rqnick, np, "Error: Channel %s does not exist.",
223 channelname);
224
225 return RQ_ERROR;
226 }
227
228 *lnick = getnickbynick(RQ_LNICK);
229
230 if (*lnick == NULL || findserver(RQ_LSERVER) < 0) {
231 sendnoticetouser(rqnick, np, "Error: %s does not seem to be online. "
232 "Try again later.", RQ_LNICK);
233
234 return RQ_ERROR;
235 }
236
237 *qnick = getnickbynick(RQ_QNICK);
238
239 if (*qnick == NULL || findserver(RQ_QSERVER) < 0) {
240 sendnoticetouser(rqnick, np, "Error: %s does not seem to be online. "
241 "Try again later.", RQ_QNICK);
242
243 return RQ_ERROR;
244 }
245
246 userhand = getnumerichandlefromchanhash((*cp)->users, np->numeric);
247
248 if (userhand == NULL) {
249 sendnoticetouser(rqnick, np, "Error: You're not on that channel.");
250
251 return RQ_ERROR;
252 }
253
254 if ((*userhand & CUMODE_OP) == 0) {
255 sendnoticetouser(rqnick, np, "Error: You must be op'd on the channel to "
256 "request a service.");
257
258 return RQ_ERROR;
259 }
260
261 block = rq_findblock(channelname);
262
263 if (block != NULL) {
264 sendnoticetouser(rqnick, np, "Error: You are not allowed to request a "
265 "service to this channel.");
266 sendnoticetouser(rqnick, np, "Reason: %s", block->reason->content);
267
268 rq_blocked++;
269
270 return RQ_ERROR;
271 }
272
273 block = rq_findblock(np->authname);
274
275 /* only tell the user if the block is going to expire in the next 48 hours
276 so we can have our fun with longterm blocks.
277 the request subsystems should deal with longterm blocks on their own */
278 if (block != NULL && block->expires < getnettime() + 3600 * 24 * 2) {
279 sendnoticetouser(rqnick, np, "Error: You are not allowed to request a "
280 "service. Keep waiting for at least %s before you try again.",
281 rq_longtoduration(block->expires - getnettime()));
282
283 sendnoticetouser(rqnick, np, "Reason: %s", block->reason->content);
284
285 /* give them another 5 minutes to think about it */
286 block->expires += 300;
287 rq_saveblocks();
288
289 rq_blocked++;
290
291 return RQ_ERROR;
292 }
293
294 return RQ_OK;
295}
296
297int rqcmd_request(void *user, int cargc, char **cargv) {
298 nick *np = (nick*)user;
299 nick *lnick, *qnick;
300 unsigned long *lhand, *qhand;
cbdd5aab 301 channel *cp, *logcp;
25b7d0fa 302 int retval;
bdd430cb
CP
303 time_t now_ts;
304 char now[50];
25b7d0fa
P
305
306 if (cargc < 1) {
307 sendnoticetouser(rqnick, np, "Syntax: requestbot <#channel>");
308
309 return RQ_ERROR;
310 }
311
312 rq_count++;
313
314 if (rq_genericrequestcheck(np, cargv[0], &cp, &lnick, &qnick) == RQ_ERROR) {
315 rq_failed++;
316
317 return RQ_ERROR;
318 }
319
320 lhand = getnumerichandlefromchanhash(cp->users, lnick->numeric);
321
322 qhand = getnumerichandlefromchanhash(cp->users, qnick->numeric);
323
324 if (qhand != NULL) {
325 sendnoticetouser(rqnick, np, "Error: %s is already on that channel.", RQ_QNICK);
326
327 rq_failed++;
328
329 return RQ_ERROR;
330 }
331
332 retval = RQ_ERROR;
333
334 if (lhand == NULL && qhand == NULL) {
335 /* try 'instant' Q request */
336 retval = qr_instantrequestq(np, cp);
337 }
338
339 if (retval == RQ_ERROR) {
340 if (lhand == NULL) {
341 /* user 'wants' L */
342
343 retval = lr_requestl(rqnick, np, cp, lnick);
cbdd5aab 344
bdd430cb
CP
345 if (rq_logfd != NULL) {
346 now[0] = '\0';
347 now_ts = time(NULL);
348 strftime(now, sizeof(now), "%c", localtime(&now_ts));
cbdd5aab 349
bdd430cb
CP
350 fprintf(rq_logfd, "%s: request (%s) for %s from %s: Request was %s.\n", now, RQ_LNICK, cp->index->name->content, np->nick, (retval == RQ_OK) ? "accepted" : "denied");
351 fflush(rq_logfd);
cbdd5aab 352 }
25b7d0fa
P
353 } else {
354 /* user 'wants' Q */
355
356 retval = qr_requestq(rqnick, np, cp, lnick, qnick);
357 }
358 }
359
360 if (retval == RQ_ERROR)
361 rq_failed++;
362 else if (retval == RQ_OK)
363 rq_success++;
364
365 return retval;
366}
367
368int rqcmd_requestspamscan(void *user, int cargc, char **cargv) {
369 nick *np = (nick*)user;
370 channel *cp;
371 nick *lnick, *qnick, *snick;
372 unsigned long *lhand, *qhand, *shand;
373 int retval;
374
375 if (cargc < 1) {
376 sendnoticetouser(rqnick, np, "Syntax: requestspamscan <#channel>");
377
378 return RQ_ERROR;
379 }
380
381 rq_count++;
382
383 if (rq_genericrequestcheck(np, cargv[0], &cp, &lnick, &qnick) == RQ_ERROR) {
384 rq_failed++;
385
386 return RQ_ERROR;
387 }
388
389 snick = getnickbynick(RQ_SNICK);
390
391 if (snick == NULL || findserver(RQ_SSERVER) < 0) {
392 sendnoticetouser(rqnick, np, "Error: %s does not seem to be online. "
393 "Try again later.", RQ_SNICK);
394
395 rq_failed++;
396
397 return RQ_ERROR;
398 }
399
400 /* does the user already have S on that channel? */
401 shand = getnumerichandlefromchanhash(cp->users, snick->numeric);
402
403 if (shand != NULL) {
404 sendnoticetouser(rqnick, np, "Error: %s is already on that channel.", RQ_SNICK);
405
406 rq_failed++;
407
408 return RQ_ERROR;
409 }
410
411 /* we need either L or Q */
412 lhand = getnumerichandlefromchanhash(cp->users, lnick->numeric);
413 qhand = getnumerichandlefromchanhash(cp->users, qnick->numeric);
414
415 if (lhand || qhand) {
416 /* great, now try to request */
417 retval = qr_requests(rqnick, np, cp, lnick, qnick);
418
419 if (retval == RQ_OK)
420 rq_success++;
421 else if (retval == RQ_ERROR)
422 rq_failed++;
423
424 return retval;
425 } else {
426 /* channel apparently doesn't have L or Q */
427
428 sendnoticetouser(rqnick, np, "Error: You need %s or %s in order to be "
429 "able to request %s.", RQ_LNICK, RQ_QNICK, RQ_SNICK);
430
431 rq_failed++;
432
433 return RQ_ERROR;
434 }
435}
436
aee804f9
CP
437int rqcmd_requestop(void *source, int cargc, char **cargv) {
438 nick *np2, *np = (nick *)source;
439 nick *user = np;
440 channel *cp;
441 int ret, a, count;
442 unsigned long *hand;
443 modechanges changes;
444
445 if (cargc < 1) {
446 sendnoticetouser(rqnick, np, "Syntax: requestop <#channel> [nick]");
447
448 return CMD_ERROR;
449 }
450
451 cp = findchannel(cargv[0]);
452
453 if (cp == NULL) {
454 sendnoticetouser(rqnick, np, "Error: No such channel.");
455
456 return CMD_ERROR;
457 }
458
459 if (cargc > 1) {
460 user = getnickbynick(cargv[1]);
461
462 if (!user) {
463 sendnoticetouser(rqnick, np, "Error: No such user.");
464
465 return CMD_ERROR;
466 }
467 }
468
469 if (getnettime() - np->timestamp < 300) {
470 sendnoticetouser(rqnick, np, "Error: You connected %s ago. To"
471 " request ops you must have been on the network for"
472 " at least 5 minutes.",
473 rq_longtoduration(getnettime() - np->timestamp));
474
475 return CMD_ERROR;
476 }
477
478 if (getnettime() - user->timestamp < 300) {
479 sendnoticetouser(rqnick, np, "Error: The nick you requested op for"
480 " connected %s ago. To request op, it must have"
481 "been on the network for at least 5 minutes.",
482 rq_longtoduration(getnettime() - user->timestamp));
483
484 return CMD_ERROR;
485 }
486
487 hand = getnumerichandlefromchanhash(cp->users, user->numeric);
488
489 if (!hand) {
490 sendnoticetouser(rqnick, np, "Error: User %s is not on channel %s.", user->nick, cargv[0]);
491
492 return CMD_ERROR;
493 }
494
495
496 count = 0;
497
498 localsetmodeinit(&changes, cp, rqnick);
499
500 /* reop any services first */
501 for(a=0;a<cp->users->hashsize;a++) {
502 if(cp->users->content[a] != nouser) {
503 np2 = getnickbynumeric(cp->users->content[a]);
504
505 if (IsService(np2) && !(cp->users->content[a] & CUMODE_OP)) {
506 localdosetmode_nick(&changes, np2, MC_OP);
507 count++;
508 }
509 }
510 }
511
512 localsetmodeflush(&changes, 1);
513
514 if (count > 0) {
515 if (count == 1)
516 sendnoticetouser(rqnick, np, "1 service was reopped.");
517 else
518 sendnoticetouser(rqnick, np, "%d services were reopped.", count);
519
520 return CMD_ERROR;
521 }
522
523 for (a=0;a<cp->users->hashsize;a++) {
524 if ((cp->users->content[a] != nouser) && (cp->users->content[a] & CUMODE_OP)) {
525 sendnoticetouser(rqnick, np, "There are ops on channel %s. This command can only be"
526 " used if there are no ops.", cargv[0]);
527
528 return CMD_ERROR;
529 }
530 }
531
532 if (sp_countsplitservers() > 0) {
533 sendnoticetouser(rqnick, np, "One or more servers are currently split. Wait until the"
534 " netsplit is over and try again.");
535
536 return CMD_ERROR;
537 }
538
539 if (cf_wouldreop(user, cp)) {
540 localsetmodeinit(&changes, cp, rqnick);
541 localdosetmode_nick(&changes, user, MC_OP);
542 localsetmodeflush(&changes, 1);
543
544 sendnoticetouser(rqnick, np, "Chanfix opped you on the specified channel.");
545 } else {
546 ret = cf_fixchannel(cp);
547
548 if (ret == CFX_NOUSERSAVAILABLE)
549 sendnoticetouser(rqnick, np, "Chanfix knows regular ops for that channel. They will"
550 " be opped when they return.");
551 else
552 sendnoticetouser(rqnick, np, "Chanfix has opped known ops for that channel.");
553 }
554
555 return CMD_OK;
556
557}
558
25b7d0fa
P
559int rqcmd_addblock(void *user, int cargc, char **cargv) {
560 nick *np = (nick*)user;
561 rq_block *block;
562 time_t expires;
563 char *account;
f3c45977
P
564 int level = ru_getlevel(np);
565
566 if (level < 20) {
567 sendnoticetouser(rqnick, np, "You do not have access to this command.");
25b7d0fa 568
f3c45977
P
569 return RQ_ERROR;
570 }
571
25b7d0fa
P
572 if (cargc < 3) {
573 sendnoticetouser(rqnick, np, "Syntax: addblock <mask> <duration> <reason>");
574
575 return RQ_ERROR;
576 }
577
578 block = rq_findblock(cargv[0]);
579
580 if (block != NULL) {
581 sendnoticetouser(rqnick, np, "That mask is already blocked by %s "
582 "(reason: %s).", block->creator->content, block->reason->content);
583
584 return RQ_ERROR;
585 }
586
587 if (IsAccount(np))
588 account = np->authname;
589 else
590 account = "unknown";
591
592 expires = getnettime() + durationtolong(cargv[1]);
593
f3c45977
P
594 if (expires > getnettime() + RQU_HELPER_MAXEXPIRE && level < 30) {
595 sendnoticetouser(rqnick, np, "Maximum expiry time is %s.", rq_longtoduration(RQU_HELPER_MAXEXPIRE));
596
597 return RQ_ERROR;
598 }
599
25b7d0fa
P
600 rq_addblock(cargv[0], cargv[2], account, 0, expires);
601
602 sendnoticetouser(rqnick, np, "Blocked channels/accounts matching '%s' from "
603 "requesting a service.", cargv[0]);
604
605 return RQ_OK;
606}
607
608int rqcmd_delblock(void *user, int cargc, char **cargv) {
609 nick *np = (nick*)user;
f3c45977
P
610 int result, level;
611 rq_block *block;
612
613 level = ru_getlevel(np);
614
615 if (level < 20) {
616 sendnoticetouser(rqnick, np, "You do not have access to this command.");
25b7d0fa 617
f3c45977
P
618 return RQ_ERROR;
619 }
620
25b7d0fa 621 if (cargc < 1) {
f3c45977 622 sendnoticetouser(rqnick, np, "Syntax: delblock <mask>");
25b7d0fa
P
623
624 return RQ_ERROR;
625 }
626
f3c45977
P
627 block = rq_findblock(cargv[0]);
628
629 if (block != NULL && level < 50) {
630 if (ircd_strcmp(block->creator->content, np->authname) != 0) {
631 sendnoticetouser(rqnick, np, "This block was created by someone else. You cannot remove it.");
632
633 return RQ_ERROR;
634 }
635 }
636
25b7d0fa
P
637 result = rq_removeblock(cargv[0]);
638
639 if (result > 0) {
640 sendnoticetouser(rqnick, np, "Block for '%s' was removed.", cargv[0]);
641
642 return RQ_OK;
643 } else {
644 sendnoticetouser(rqnick, np, "There is no such block.");
645
646 return RQ_OK;
647 }
648}
649
650int rqcmd_listblocks(void *user, int cargc, char **cargv) {
651 nick *np = (nick*)user;
652 rq_block block;
f3c45977
P
653 int i, level;
654
655 level = ru_getlevel(np);
656
657 if (level < 10) {
658 sendnoticetouser(rqnick, np, "You do not have access to this command.");
25b7d0fa 659
f3c45977
P
660 return RQ_ERROR;
661 }
662
25b7d0fa
P
663 sendnoticetouser(rqnick, np, "Mask By Expires"
664 " Reason");
665
666 for (i = 0; i < rqblocks.cursi; i++) {
667 block = ((rq_block*)rqblocks.content)[i];
668
669 if (block.expires != 0 && block.expires < getnettime())
670 continue; /* ignore blocks which have already expired,
671 rq_findblock will deal with them later on */
672
673 if (cargc < 1 || match2strings(block.pattern->content, cargv[0]))
674 sendnoticetouser(rqnick, np, "%-11s %-9s %-25s %s",
675 block.pattern->content, block.creator->content,
676 rq_longtoduration(block.expires - getnettime()),
677 block.reason->content);
678 }
679
680 sendnoticetouser(rqnick, np, "--- End of blocklist");
681
682 return RQ_OK;
683}
684
685int rqcmd_stats(void *user, int cargc, char **cargv) {
686 nick *np = (nick*)user;
f3c45977
P
687 int level = ru_getlevel(np);
688
689 if (level < 10) {
690 sendnoticetouser(rqnick, np, "You do not have access to this command.");
25b7d0fa 691
f3c45977
P
692 return RQ_ERROR;
693 }
694
25b7d0fa
P
695 sendnoticetouser(rqnick, np, "Total requests: %d", rq_count);
696 sendnoticetouser(rqnick, np, "Successful requests: %d", rq_success);
697 sendnoticetouser(rqnick, np, "Failed requests: %d", rq_failed);
698 sendnoticetouser(rqnick, np, "- Blocked: %d", rq_blocked);
699
700 lr_requeststats(rqnick, np);
701 qr_requeststats(rqnick, np);
702
703 return RQ_OK;
704}
705
f3c45977
P
706int rqcmd_adduser(void *user, int cargc, char **cargv) {
707 nick *np = (nick*)user;
708 int result, level;
709
710 if (cargc < 2) {
711 sendnoticetouser(rqnick, np, "Syntax: adduser <account> <level>");
712
713 return RQ_ERROR;
714 }
715
716 level = atoi(cargv[1]);
717
718 if (level <= 0) {
719 sendnoticetouser(rqnick, np, "Level must be a positive integer.");
720
721 return RQ_ERROR;
722 }
723
724 result = ru_create(cargv[0], level);
725
726 if (result) {
727 sendnoticetouser(rqnick, np, "User '%s' was added with level '%d'.", cargv[0], level);
728
729 return RQ_OK;
730 } else {
731 sendnoticetouser(rqnick, np, "Something strange happened. Contact shroud.");
732
733 return RQ_ERROR;
734 }
735}
736
737int rqcmd_deluser(void *user, int cargc, char **cargv) {
738 nick *np = (nick*)user;
739 int level;
740
741 if (cargc < 1) {
742 sendnoticetouser(rqnick, np, "Syntax: deluser <account>");
743
744 return RQ_ERROR;
745 }
746
747 level = ru_getlevel_str(cargv[0]);
748
749 if (level <= 0) {
750 sendnoticetouser(rqnick, np, "There is no such user.");
751
752 return RQ_ERROR;
753 }
754
755 ru_destroy(cargv[0]);
756
757 sendnoticetouser(rqnick, np, "Done.");
758
759 return RQ_OK;
760}
761
762int rqcmd_changelev(void *user, int cargc, char **cargv) {
763 nick *np = (nick*)user;
764 int result, level;
765
766 if (cargc < 2) {
767 sendnoticetouser(rqnick, np, "Syntax: changelev <account> <level>");
768
769 return RQ_ERROR;
770 }
771
772 level = atoi(cargv[1]);
773
774 if (level <= 0) {
775 sendnoticetouser(rqnick, np, "Level must be a positive integer.");
776
777 return RQ_ERROR;
778 }
779
780 if (ru_getlevel_str(cargv[0]) <= 0) {
781 sendnoticetouser(rqnick, np, "Unknown user.");
782
783 return RQ_ERROR;
784 }
785
786 result = ru_setlevel(cargv[0], level);
787
788 if (result != 0) {
789 sendnoticetouser(rqnick, np, "Done.");
790
791 return RQ_OK;
792 } else {
793 sendnoticetouser(rqnick, np, "Something strange happened. Contact shroud.");
794
795 return RQ_ERROR;
796 }
797}
798
799int rqcmd_userlist(void *user, int cargc, char **cargv) {
800 nick *np = (nick*)user;
801 r_user_t *userp = r_userlist;
802
803 sendnoticetouser(rqnick, np, "User Level");
804
805 while (userp) {
806 sendnoticetouser(rqnick, np, "%s %d", userp->name, userp->level);
807 userp = userp->next;
808 }
809
810 sendnoticetouser(rqnick, np, "--- End of USERS.");
811
812 return RQ_OK;
813}
814