]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hcommands.c
Merged revisions 292-293 via svnmerge from
[irc/quakenet/newserv.git] / helpmod2 / hcommands.c
1 #include <string.h>
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <assert.h>
5 #include <sys/types.h>
6 #include <dirent.h>
7
8 #include "../nick/nick.h"
9 #include "../channel/channel.h"
10 #include "../lib/irc_string.h"
11
12 #include "hcommands.h"
13 #include "hcommand.h"
14
15 #include "helpmod.h"
16 #include "klingon.h"
17 #include "helpmod_alias.h"
18
19 #include "haccount.h"
20 #include "hqueue.h"
21 #include "hterm.h"
22
23 #include "hgen.h"
24 #include "hban.h"
25 #include "hchanban.h"
26
27 #include "hticket.h"
28 #include "hconf.h"
29
30 /* following are macros for use ONLY IN HERE
31 they may not look pretty, but work surprisingly well */
32
33 #define SKIP_WORD \
34 {\
35 if (*ostr == '"' && strchr(ostr+1, '"'))\
36 ostr = strchr(ostr+1, '"');\
37 while (!isspace(*ostr) && *ostr)\
38 ostr++;\
39 while (isspace(*ostr) && *ostr)\
40 ostr++;\
41 argc--;\
42 argv++;\
43 }
44
45 #define DEFINE_HCHANNEL \
46 {\
47 if (argc == 0)\
48 hchan = hchannel_get_by_channel(returntype);\
49 else if (*argv[0] == '#')\
50 {\
51 hchan = hchannel_get_by_name(argv[0]);\
52 SKIP_WORD;\
53 }\
54 else\
55 hchan = hchannel_get_by_channel(returntype);\
56 }
57
58 #define HCHANNEL_VERIFY_AUTHORITY(c, u)\
59 {\
60 if ((c) != NULL && !hchannel_authority((c), (u)))\
61 {\
62 helpmod_reply(u, returntype, "Sorry, channel %s is oper only", hchannel_get_name((c)));\
63 return;\
64 }\
65 }
66
67 enum
68 {
69 H_CMD_OP,
70 H_CMD_DEOP,
71 H_CMD_VOICE,
72 H_CMD_DEVOICE
73 };
74
75 enum
76 {
77 H_TERM_FIND,
78 H_TERM_MINUS,
79 H_TERM_PLUS
80 };
81
82 static void helpmod_cmd_addchan (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
83 {
84 if (argc == 0)
85 {
86 helpmod_reply(sender, returntype, "Cannot add channel: Channel not defined");
87 return;
88 }
89
90 if (*argv[0] != '#')
91 {
92 helpmod_reply(sender, returntype, "Can not add channel: Channel name must start with '#'");
93 return;
94 }
95
96 if (hchannel_get_by_name(argv[0]) != NULL)
97 {
98 helpmod_reply(sender, returntype, "Can not add channel: Channel %s already active", argv[0]);
99 return;
100 }
101
102 if (hchannel_add(argv[0]) != NULL)
103 {
104 helpmod_reply(sender, returntype, "Channel %s added succesfully", argv[0]);
105 return;
106 }
107 }
108
109 static void helpmod_cmd_delchan (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
110 {
111 hchannel *hchan;
112 char buffer[256];
113 DEFINE_HCHANNEL;
114
115 if (hchan == NULL)
116 {
117 helpmod_reply(sender, returntype, "Can not delete channel: Channel not defined or not found");
118 return;
119 }
120 strcpy(buffer, hchan->real_channel->index->name->content);
121 if (argc == 0 || strcmp(argv[0], "YesImSure"))
122 {
123 helpmod_reply(sender, returntype, "Can not delete channel: Sanity check. Please add a parameter \"YesImSure\" to confirm channel deletion");
124 return;
125 }
126 hchannel_del(hchan);
127
128 helpmod_reply(sender, returntype, "Channel %s deleted succesfully", buffer);
129 }
130
131 static void helpmod_cmd_whoami (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
132 {
133 helpmod_reply(sender, returntype, "You are %s", huser_get_nick(sender));
134 helpmod_reply(sender, returntype, "Your userlevel is %s", hlevel_name(huser_get_level(sender)));
135 if (sender->account == NULL)
136 helpmod_reply(sender, returntype, "You do not have an account with me");
137 else
138 helpmod_reply(sender, returntype, "Your accounts name is %s", sender->account->name->content);
139 if (huser_get_level(sender) < H_TRIAL)
140 {
141 if (sender->lc[0] || sender->lc[1] || sender->lc[2] || sender->lc[3] || sender->lc[4])
142 helpmod_reply(sender, returntype, "You violated the following rules: Excessive use of capital letters: %d, repeating: %d, improper use of language: %d, flooding: %d and spamming: %d", sender->lc[0], sender->lc[1], sender->lc[2], sender->lc[3], sender->lc[4]);
143 else
144 helpmod_reply(sender, returntype, "You have not violated any rules");
145 }
146
147 {
148 int pos;
149 huser_channel *huserchan = sender->hchannels;
150 for (;huserchan;huserchan = huserchan->next)
151 if ((pos = hqueue_get_position(huserchan->hchan, sender)) > -1)
152 helpmod_reply(sender, returntype, "You have queue position #%d on channel %s", pos, hchannel_get_name(huserchan->hchan));
153 }
154
155 if (IsAccount(sender->real_user))
156 {
157 hchannel *hchan;
158 hticket *htick;
159 for (hchan = hchannels;hchan;hchan = hchan->next)
160 if (hchan->flags & H_REQUIRE_TICKET)
161 {
162 htick = hticket_get(huser_get_auth(sender), hchan);
163 if (htick != NULL)
164 helpmod_reply(sender, returntype, "You have an invite ticket for channel %s that expires in %s", hchannel_get_name(hchan), helpmod_strtime(time(NULL) - htick->time_expiration));
165 }
166 }
167 }
168
169 static void helpmod_cmd_whois (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
170 {
171 huser *husr;
172 int i;
173
174 if (argc == 0)
175 {
176 helpmod_reply(sender, returntype, "Cannot get user information: User not specified");
177 return;
178 }
179 if (argc > H_CMD_MAX_ARGS)
180 argc = H_CMD_MAX_ARGS;
181
182 for (i=0;i<argc;i++)
183 {
184 husr = huser_get(getnickbynick(argv[i]));
185 if (husr == NULL)
186 {
187 if (getnickbynick(argv[i]) == NULL)
188 helpmod_reply(sender, returntype, "Cannot get user information: User %s does not exist in the network", argv[i]);
189 else
190 helpmod_reply(sender, returntype, "Cannot get user information: User %s exists but is not known to me", argv[i]);
191 continue;
192 }
193 helpmod_reply(sender, returntype, "User %s has userlevel %s", huser_get_nick(husr), hlevel_name(huser_get_level(husr)));
194 if (husr->account == NULL)
195 helpmod_reply(sender, returntype, "User %s does not have an account with me", huser_get_nick(husr));
196 else
197 helpmod_reply(sender, returntype, "User %s has account named %s", huser_get_nick(husr),husr->account->name->content);
198 if (huser_get_level(husr) < H_TRIAL)
199 {
200 if (husr->lc[0] || husr->lc[1] || husr->lc[2] || husr->lc[3] || husr->lc[4])
201 helpmod_reply(sender, returntype, "User %s has lamercontrol entries: Excessive use of capital letters: %d, repeating: %d, improper use of language: %d, flooding: %d and spamming: %d", huser_get_nick(husr), husr->lc[0], husr->lc[1], husr->lc[2], husr->lc[3], husr->lc[4]);
202 else
203 helpmod_reply(sender, returntype, "User %s has no lamercontrol entries", huser_get_nick(husr));
204 }
205 {
206 int pos;
207 huser_channel *huserchan = husr->hchannels;
208 for (;huserchan;huserchan = huserchan->next)
209 {
210 if ((pos = hqueue_get_position(huserchan->hchan, husr)) > -1)
211 helpmod_reply(sender, returntype, "User %s has queue queue position #%d on channel %s", huser_get_nick(husr), pos, hchannel_get_name(huserchan->hchan));
212 if (on_desk(husr, huserchan))
213 helpmod_reply(sender, returntype, "User %s is receiving support on channel %s", huser_get_nick(husr), hchannel_get_name(huserchan->hchan));
214 }
215 }
216 if (IsAccount(husr->real_user))
217 {
218 hchannel *hchan;
219 hticket *htick;
220 for (hchan = hchannels;hchan;hchan = hchan->next)
221 if (hchan->flags & H_REQUIRE_TICKET)
222 {
223 htick = hticket_get(huser_get_auth(husr), hchan);
224 if (htick != NULL)
225 helpmod_reply(sender, returntype, "User %s has an invite ticket for channel %s that expires in %s", huser_get_nick(husr), hchannel_get_name(hchan), helpmod_strtime(time(NULL) - htick->time_expiration));
226 }
227 }
228 }
229 }
230 /*
231 void helpmod_cmd_megod (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
232 {
233 if (sender->account == NULL)
234 sender->account = haccount_add(huser_get_nick(sender), H_ADMIN);
235
236 sender->account->level = H_ADMIN;
237 }
238 */
239
240 static void helpmod_cmd_seen (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
241 {
242 huser *target_huser;
243 haccount *target_haccount;
244 int i;
245
246 if (argc == 0)
247 {
248 helpmod_reply(sender, returntype, "No targets specified for seen");
249 return;
250 }
251 for (i=0;i < argc;i++)
252 {
253 if (*argv[i] == '#')
254 { /* account */
255 if (!ci_strcmp(argv[i] + 1, HELPMOD_AUTH))
256 { /* A nice special case */
257 helpmod_reply(sender, returntype, "I'm right here");
258 continue;
259 }
260 target_haccount = haccount_get_by_name(argv[i]);
261 if (target_haccount == NULL)
262 {
263 helpmod_reply(sender, returntype, "Account %s not found", argv[i] + 1);
264 continue;
265 }
266
267 helpmod_reply(sender, returntype, "Account %s's last recorded activity was %s ago", target_haccount->name->content, helpmod_strtime(time(NULL) - target_haccount->last_activity));
268 }
269 else
270 {
271 if (getnickbynick(argv[i]) == helpmodnick)
272 { /* A nice special case */
273 helpmod_reply(sender, returntype, "I'm right here");
274 continue;
275 }
276 target_huser = huser_get(getnickbynick(argv[i]));
277 if (target_huser == NULL)
278 {
279 helpmod_reply(sender, returntype, "User %s not found", argv[i]);
280 continue;
281 }
282 helpmod_reply(sender, returntype, "User %s's last recorded activity was %s ago", huser_get_nick(target_huser), helpmod_strtime(time(NULL) - target_huser->last_activity));
283 }
284 }
285 }
286
287 static void helpmod_cmd_change_userlevel(huser *sender, hlevel target_level, channel* returntype, char* ostr, int argc, char *argv[])
288 {
289 huser *target_huser;
290 haccount *target_haccount;
291 int i;
292
293 if (argc == 0)
294 {
295 helpmod_reply(sender, returntype, "Incorrect syntax: Nick or account required");
296 return ;
297 }
298
299 if (argc > H_CMD_MAX_ARGS)
300 argc = H_CMD_MAX_ARGS;
301
302 for (i = 0;i < argc;i++)
303 {
304 if (*argv[i] == '#') /* account */
305 {
306 target_haccount = haccount_get_by_name(argv[i]);
307 if (target_haccount == NULL)
308 {
309 helpmod_reply(sender, returntype, "Cannot change userlevel: Account '%s' not found", argv[i]);
310 continue;
311 }
312 if (target_haccount->level > huser_get_level(sender))
313 {
314 helpmod_reply(sender, returntype, "Cannot change userlevel: Account '%s' has a userlevel higher than yours", argv[i]);
315 continue;
316 }
317
318 if (target_haccount->level == target_level)
319 {
320 helpmod_reply(sender, returntype, "Cannot change userlevel: Account '%s' already has userlevel %s", argv[i], hlevel_name(target_level));
321 continue;
322 }
323
324 target_haccount->level = target_level;
325
326 helpmod_reply(sender, returntype, "Userlevel changed: Account '%s' now has userlevel %s", argv[i], hlevel_name(target_level));
327
328 }
329 else
330 {
331 target_huser = huser_get(getnickbynick(argv[i]));
332 if (target_huser == NULL)
333 {
334 helpmod_reply(sender, returntype, "Cannot change userlevel: User '%s' not found", argv[i]);
335 continue;
336 }
337 if (huser_get_level(target_huser) > huser_get_level(sender))
338 {
339 helpmod_reply(sender, returntype, "Cannot change userlevel: User '%s' has a userlevel higher than yours", argv[i]);
340 continue;
341 }
342 if (huser_get_level(target_huser) == H_STAFF && huser_get_level(sender) == H_STAFF)
343 {
344 helpmod_reply(sender, returntype, "Cannot change userlevel: User '%s' has the same userlevel as you have", argv[i]);
345 continue;
346 }
347
348 if (huser_get_level(target_huser) == target_level)
349 {
350 helpmod_reply(sender, returntype, "Cannot change userlevel: User '%s' already has userlevel %s", argv[i], hlevel_name(target_level));
351 continue;
352 }
353 if (target_huser == sender)
354 {
355 helpmod_reply(sender, returntype, "Cannot change userlevel: Sanity check, you're changing your own userlevel, use #account instead of nick if you really wish to do this");
356 continue;
357 }
358 if (!IsAccount(target_huser->real_user))
359 {
360 helpmod_reply(sender, returntype, "Cannot change userlevel: User '%s' is not authed", argv[i]);
361 continue;
362 }
363
364 if (target_huser->account == NULL)
365 {
366 if (haccount_get_by_name(huser_get_auth(target_huser)) != NULL)
367 {
368 helpmod_reply(sender, returntype, "Cannot change userlevel: Unable to create an account. Account %s already exists", huser_get_auth(target_huser));
369 continue;
370 }
371 else
372 target_huser->account = haccount_add(huser_get_auth(target_huser), target_level);
373 }
374
375 target_huser->account->level = target_level;
376
377 helpmod_reply(sender, returntype, "Userlevel changed: User '%s' now has userlevel %s", argv[i], hlevel_name(target_level));
378
379 if (huser_get_level(target_huser) == H_LAMER)
380 {
381 const char *banmask = hban_ban_string(target_huser->real_user, HBAN_HOST);
382 hban_add(banmask, "Improper user", time(NULL) + HCMD_OUT_DEFAULT, 1);
383 }
384 else
385 helpmod_reply(target_huser, NULL, "Your userlevel has been changed, your current userlevel is %s", hlevel_name(target_level));
386 }
387 }
388 }
389
390 /* pseudo commands for the above */
391 static void helpmod_cmd_improper (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_LAMER, returntype, ostr, argc, argv); }
392 static void helpmod_cmd_peon (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_PEON, returntype, ostr, argc, argv); }
393 static void helpmod_cmd_trial (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_TRIAL, returntype, ostr, argc, argv); }
394 static void helpmod_cmd_staff (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_STAFF, returntype, ostr, argc, argv); }
395 static void helpmod_cmd_oper (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_OPER, returntype, ostr, argc, argv); }
396 static void helpmod_cmd_admin (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_change_userlevel(sender, H_ADMIN, returntype, ostr, argc, argv); }
397
398 static void helpmod_cmd_deluser (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
399 {
400 int i;
401 huser *target_huser;
402 haccount *target_haccount;
403
404 if (argc == 0)
405 {
406 helpmod_reply(sender, returntype, "Usage: deluser [nick|#account]");
407 return;
408 }
409
410 if (argc > H_CMD_MAX_ARGS)
411 argc = H_CMD_MAX_ARGS;
412
413 for (i = 0;i < argc;i++)
414 {
415 if (*argv[i] != '#')
416 {
417 target_huser = huser_get(getnickbynick(argv[i]));
418 if (target_huser == NULL)
419 {
420 helpmod_reply(sender, returntype, "Cannot delete the account: User %s does not exist", argv[i]);
421 continue;
422 }
423 if (target_huser->account == NULL)
424 {
425 helpmod_reply(sender, returntype, "Cannot delete the account: User %s does not have an account", argv[i]);
426 continue;
427 }
428 target_haccount = target_huser->account;
429 }
430 else
431 target_haccount = haccount_get_by_name(argv[i]);
432
433 if (target_haccount == NULL)
434 {
435 helpmod_reply(sender, returntype, "Cannot delete the account: Account %s does not exist", argv[i]);
436 continue;
437 }
438 if (target_haccount->level > huser_get_level(sender))
439 {
440 helpmod_reply(sender, returntype, "Cannot delete the account: Account %s has higher userlevel than you", target_haccount->name->content);
441 continue;
442 }
443 helpmod_reply(sender, returntype, "Account %s deleted", target_haccount->name->content);
444 haccount_del(target_haccount);
445 }
446 }
447
448 static void helpmod_cmd_listuser (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
449 {
450 char *pattern;
451 haccount *hack = haccounts;
452 int count = 0, lvl = -1;
453 time_t timer;
454
455 if (argc > 0 && sscanf(argv[0], "%d", &lvl) && lvl >= H_LAMER && lvl <= H_ADMIN)
456 {
457 SKIP_WORD;
458 }
459 else
460 lvl = -1;
461
462 if (argc == 0)
463 pattern = "*";
464 else
465 pattern = argv[0];
466
467 if (lvl >= 0)
468 helpmod_reply(sender, returntype, "%s accounts matching pattern %s: (account name, userlevel, expires in)", hlevel_name(lvl), pattern);
469 else
470 helpmod_reply(sender, returntype, "Accounts matching pattern %s: (account name, userlevel, expires in)", pattern);
471 for (;hack;hack = hack->next)
472 {
473 if (strregexp(hack->name->content, pattern))
474 {
475 if (lvl >= 0 && hack->level != lvl)
476 continue;
477 timer = hack->last_activity + HELPMOD_ACCOUNT_EXPIRATION[hack->level];
478 helpmod_reply(sender, returntype, "%-16s %-32s %s", hack->name->content, hlevel_name(hack->level), asctime(localtime(&timer)));
479 count++;
480 }
481 }
482 if (lvl >= 0)
483 helpmod_reply(sender, returntype, "%s accounts matching pattern %d", hlevel_name(lvl), count);
484 else
485 helpmod_reply(sender, returntype, "Accounts matching pattern %d", count);
486 }
487
488 static void helpmod_cmd_censor (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
489 {
490 hchannel *hchan;
491 hcensor *hcens;
492 int i = 0;
493
494 DEFINE_HCHANNEL;
495
496 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
497
498 if (hchan == NULL)
499 {
500 helpmod_reply(sender, returntype, "Cannot handle the censor: Channel not specified or found");
501 return;
502 }
503
504 if (argc < 2 || !ci_strcmp(argv[0], "list")) /* view */
505 {
506 if (hchan->censor == NULL)
507 helpmod_reply(sender, returntype, "Nothing is censored on channel %s", hchan->real_channel->index->name->content);
508 else
509 {
510 helpmod_reply(sender, returntype, "Censored patterns for channel %s (%s):", hchan->real_channel->index->name->content, (hchan->flags & H_CENSOR)?"active":"inactive");
511 for (hcens = hchan->censor;hcens;hcens = hcens->next)
512 helpmod_reply(sender, returntype, "#%-4d %-8s %s%s%s", i++, hcensor_get_typename(hcens->type), hcens->pattern->content, hcens->reason?" :: ":"", hcens->reason?hcens->reason->content:"");
513 }
514 }
515 else
516 {
517 if (!ci_strcmp(argv[0], "add"))
518 {
519 char *pattern;
520 char *reason;
521 int type = HCENSOR_KICK;
522
523 SKIP_WORD;
524
525 /* not very elegant but will have to do */
526 if (argc > 1)
527 {
528 if (!ci_strcmp(argv[0], "warn"))
529 {
530 type = HCENSOR_WARN;
531 if (argc <= 2)
532 {
533 helpmod_reply(sender, returntype, "Cannot add censor entry: Entries of type warn require a reason");
534 return;
535 }
536 SKIP_WORD;
537 }
538 else if (!ci_strcmp(argv[0], "kick"))
539 {
540 type = HCENSOR_KICK;
541 SKIP_WORD;
542 }
543 else if (!ci_strcmp(argv[0], "chanban"))
544 {
545 type = HCENSOR_CHANBAN;
546 SKIP_WORD;
547 }
548 else if (!ci_strcmp(argv[0], "ban"))
549 {
550 type = HCENSOR_BAN;
551 SKIP_WORD;
552 }
553 }
554
555 pattern = argv[0];
556
557 if (strlen(pattern) == 0)
558 {
559 helpmod_reply(sender, returntype, "Cannot add censor entry: Pattern must be non-empty");
560 return;
561 }
562
563 SKIP_WORD;
564 if (argc && strlen(ostr) > 0)
565 reason = ostr;
566 else
567 reason = NULL;
568
569 if (hcensor_get_by_pattern(hchan->censor, pattern))
570 {
571 helpmod_reply(sender, returntype, "Cannot add censor entry: Pattern '%s' is already censored", pattern);
572 return;
573 }
574
575 if (hcensor_add(&hchan->censor, pattern, reason, type))
576 helpmod_reply(sender, returntype, "Pattern '%s' (%s) with type %s, censored succesfully", pattern, reason?reason:"no reason specified", hcensor_get_typename(type));
577 else
578 helpmod_reply(sender, returntype, "Cannot add censor entry: Pattern '%s' is already censored", pattern);
579
580 }
581 else if (!ci_strcmp(argv[0], "del"))
582 {
583 SKIP_WORD;
584 if (*argv[0] == '#')
585 {
586 int tmp;
587 if (!sscanf(argv[0], "#%d", &tmp))
588 {
589 helpmod_reply(sender, returntype, "Cannot delete censor entry: Bad index, integer expected");
590 return;
591 }
592 hcens = hcensor_get_by_index(hchan->censor, tmp);
593 }
594 else
595 hcens = hcensor_get_by_pattern(hchan->censor, argv[0]);
596
597 if (hcens == NULL)
598 helpmod_reply(sender, returntype, "Cannot delete censor entry: Entry not found");
599 else
600 {
601 hcensor_del(&hchan->censor, hcens);
602 helpmod_reply(sender, returntype, "Censor entry deleted succesfully");
603 }
604 }
605 else
606 helpmod_reply(sender, returntype, "Unknown censor command %s", argv[0]);
607 }
608 }
609
610 static void helpmod_cmd_chanconf (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
611 {
612 hchannel *hchan;
613 int old_flags=0;
614
615 DEFINE_HCHANNEL;
616
617 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
618
619 if (hchan == NULL)
620 {
621 helpmod_reply(sender, returntype, "Cannot change or view channel configuration: Channel not specified or found");
622 return;
623 }
624
625 if (argc == 0) /* view, spammy but with pretty formatting */
626 {
627 int i;
628 helpmod_reply(sender, returntype, "Channel configuration for %s:", hchan->real_channel->index->name->content);
629
630 for (i=0;i<=HCHANNEL_CONF_COUNT;i++)
631 helpmod_reply(sender, returntype, "(%02d) %-32s : %s", i, hchannel_get_sname(i), hchannel_get_state(hchan, 1 << i));
632 }
633 else /* change */
634 {
635 int i, tmp, type;
636 old_flags = hchan->flags;
637
638 if (argc > H_CMD_MAX_ARGS)
639 argc = H_CMD_MAX_ARGS;
640
641 for (i=0;i<argc;i++)
642 {
643 if (*argv[i] == '+')
644 {
645 type = 1;
646 argv[i]++;
647 }
648 else if (*argv[i] == '-')
649 {
650 type = -1;
651 argv[i]++;
652 }
653 else
654 type = 0;
655
656 if (!sscanf(argv[i], "%d", &tmp) || (tmp < 0) || (tmp > HCHANNEL_CONF_COUNT))
657 {
658 helpmod_reply(sender, returntype, "Cannot change channel configuration: Expected integer between [0, %d]", HCHANNEL_CONF_COUNT);
659 continue;
660 }
661
662 switch (type)
663 {
664 case -1: /* unset */
665 hchan->flags &= ~(1 << tmp);
666 helpmod_reply(sender, returntype, "Channel configuration for %s changed: %s set to %s",hchannel_get_name(hchan), hchannel_get_sname(tmp), hchannel_get_state(hchan, 1 << tmp));
667 break;
668 case 0: /* view */
669 helpmod_reply(sender, returntype, "(%02d) %-32s : %s", tmp, hchannel_get_sname(tmp), hchannel_get_state(hchan, 1 << tmp));
670 break;
671 case 1: /* set */
672 hchan->flags |= (1 << tmp);
673 helpmod_reply(sender, returntype, "Channel configuration for %s changed: %s set to %s", hchannel_get_name(hchan), hchannel_get_sname(tmp), hchannel_get_state(hchan, 1 << tmp));
674 break;
675 }
676 }
677 hchannel_conf_change(hchan, old_flags);
678 }
679 }
680
681 static void helpmod_cmd_acconf (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
682 {
683 haccount *hacc = sender->account;
684
685 if (hacc == NULL)
686 {
687 helpmod_reply(sender, returntype, "Account configuration impossible: You do not have an account");
688 return;
689 }
690
691 if (argc == 0) /* view, spammy but with pretty formatting */
692 {
693 int i;
694 helpmod_reply(sender, returntype, "Account configuration for %s:", hacc->name->content);
695
696 for (i=0;i<=HACCOUNT_CONF_COUNT;i++)
697 helpmod_reply(sender, returntype, "(%02d) %-35s : %s", i, haccount_get_sname(i), haccount_get_state(hacc, 1 << i));
698 }
699 else /* change */
700 {
701 int i, tmp, type;
702
703 if (argc > H_CMD_MAX_ARGS)
704 argc = H_CMD_MAX_ARGS;
705
706 for (i=0;i<argc;i++)
707 {
708 if (*argv[i] == '+')
709 {
710 type = 1;
711 argv[i]++;
712 }
713 else if (*argv[i] == '-')
714 {
715 type = -1;
716 argv[i]++;
717 }
718 else
719 type = 0;
720
721 if (!sscanf(argv[i], "%d", &tmp) || (tmp < 0) || (tmp > HACCOUNT_CONF_COUNT))
722 {
723 helpmod_reply(sender, returntype, "Cannot change account configuration: Expected integer between [0, %d]", HACCOUNT_CONF_COUNT);
724 continue;
725 }
726
727 switch (type)
728 {
729 case -1: /* unset */
730 hacc->flags &= ~(1 << tmp);
731 helpmod_reply(sender, returntype, "Account configuration for %s changed: %s set to %s",hacc->name->content, haccount_get_sname(tmp), haccount_get_state(hacc, 1 << tmp));
732 break;
733 case 0: /* view */
734 helpmod_reply(sender, returntype, "(%02d) %-35s : %s", tmp, haccount_get_sname(tmp), haccount_get_state(hacc, 1 << tmp));
735 break;
736 case 1: /* set */
737 hacc->flags |= (1 << tmp);
738 helpmod_reply(sender, returntype, "Account configuration for %s changed: %s set to %s", hacc->name->content, haccount_get_sname(tmp), haccount_get_state(hacc, 1 << tmp));
739 break;
740 }
741 }
742 }
743 }
744
745 static void helpmod_cmd_welcome (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
746 {
747 hchannel *hchan;
748
749 DEFINE_HCHANNEL;
750
751 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
752
753 if (hchan == NULL)
754 {
755 helpmod_reply(sender, returntype, "Cannot change or view the welcome message: Channel not specified or found");
756 return;
757 }
758
759 if (argc == 0) /* view */
760 {
761 helpmod_reply(sender, returntype, "Welcome message for channel %s (%s): %s", hchan->real_channel->index->name->content, hchannel_get_state(hchan, H_WELCOME), hchan->welcome);
762 }
763 else
764 {
765 strcpy(hchan->welcome, ostr);
766 helpmod_reply(sender, returntype, "Welcome message for channel %s (%s) is now: %s", hchan->real_channel->index->name->content, hchannel_get_state(hchan, H_WELCOME), hchan->welcome);
767 }
768 }
769
770 static void helpmod_cmd_aliases (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
771 {
772 char buf[512];
773 int i = 0;
774 void helpmod_list_aliases(alias_tree node)
775 {
776 if (i > 256)
777 {
778 helpmod_reply(sender, returntype, "%s", buf);
779 i = 0;
780 }
781 if (!node)
782 return;
783 sprintf(buf+i,"%.200s ",node->name->content);
784 i+=(1+strlen(node->name->content));
785 helpmod_list_aliases(node->left);
786 helpmod_list_aliases(node->right);
787 }
788 helpmod_list_aliases(aliases);
789 if (i)
790 helpmod_reply(sender, returntype, "%s", buf);
791 }
792
793 static void helpmod_cmd_showcommands (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
794 {
795 int level = H_PEON, previous_level = H_PEON;
796 hcommand *tmp;
797
798 if (!(argc && (sscanf(argv[0], "%d", &level)) && (level >= 0) && (level <= huser_get_level(sender))))
799 level = huser_get_level(sender);
800
801 helpmod_reply(sender, returntype, "HelpMod %s commands for userlevel %s:", HELPMOD_VERSION, hlevel_name(level));
802
803 hcommand_list(H_NONE);
804
805 while ((tmp = hcommand_list(level)) != NULL)
806 {
807 if (tmp->level > previous_level)
808 {
809 helpmod_reply(sender, returntype, "--- Additional commands for userlevel %s ---", hlevel_name(tmp->level));
810 previous_level = tmp->level;
811 }
812 helpmod_reply(sender, returntype, "%-16s %s", tmp->name->content, tmp->help->content);
813 }
814
815 return;
816 }
817
818 static void helpmod_cmd_lamercontrol (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
819 {
820 hchannel *hchan;
821 hlc_profile *ptr;
822
823 DEFINE_HCHANNEL;
824
825 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
826
827 if (hchan == NULL) /* list profiles */
828 {
829 helpmod_reply(sender, returntype, "Following lamercontrol profiles are available:");
830 for (ptr = hlc_profiles;ptr;ptr = ptr->next)
831 helpmod_reply(sender, returntype, "%s", ptr->name->content);
832 return;
833 }
834 if (argc == 0)
835 {
836 if (hchan->lc_profile == NULL)
837 helpmod_reply(sender, returntype, "Channel %s has no lamercontrol profile set", hchannel_get_name(hchan));
838 else
839 helpmod_reply(sender, returntype, "Channel %s is using lamercontrol profile %s (%s)", hchannel_get_name(hchan), hchan->lc_profile->name->content, hchannel_get_state(hchan, H_LAMER_CONTROL));
840 return;
841 }
842 if (!ci_strcmp(argv[0], "list"))
843 {
844 helpmod_reply(sender, returntype, "Following lamercontrol profiles are available:");
845 for (ptr = hlc_profiles;ptr;ptr = ptr->next)
846 helpmod_reply(sender, returntype, "%s", ptr->name->content);
847 return;
848 }
849 ptr = hlc_get(argv[0]);
850 if (ptr == NULL)
851 {
852 helpmod_reply(sender, returntype, "Cannot set the lamercontrol profile: Profile %s does not exist:", argv[0]);
853 return;
854 }
855 else
856 {
857 hchan->lc_profile = ptr;
858 helpmod_reply(sender, returntype, "Lamercontrol profile %s set to channel %s succesfully",ptr->name->content,hchannel_get_name(hchan));
859 }
860
861 }
862
863 static void helpmod_cmd_term_find_general (huser *sender, channel* returntype, int type, char* ostr, int argc, char *argv[])
864 {
865 hterm *htrm;
866 hterm *source;
867 hchannel *hchan;
868 huser *targets[6];
869 int i,ntargets = 0;
870
871 DEFINE_HCHANNEL;
872
873 if (hchan == NULL)
874 source = hterms;
875 else
876 source = hchan->channel_hterms;
877
878 if (argc == 0)
879 {
880 if (type == H_TERM_PLUS)
881 hqueue_advance(hchan, sender, 1);
882 else
883 helpmod_reply(sender, returntype, "Cannot find term: Term not specified");
884 return;
885 }
886 htrm = hterm_get_and_find(source, argv[0]);
887 if (htrm == NULL)
888 {
889 helpmod_reply(sender, returntype, "No term found matching '%s'", argv[0]);
890 return;
891 }
892 if (returntype != NULL && huser_get_level(sender) > H_PEON)
893 {
894 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
895
896 if (argc > 1)
897 {
898 SKIP_WORD;
899 if (argc > H_CMD_MAX_ARGS)
900 argc = H_CMD_MAX_ARGS;
901 for (i=0;i<argc;i++)
902 {
903 targets[ntargets] = huser_get(getnickbynick(argv[i]));
904 if (targets[ntargets] == NULL)
905 {
906 helpmod_reply(sender, returntype, "Error using ?: User %s not found", argv[i]);
907 continue;
908 }
909 else
910 ntargets++;
911 }
912 }
913
914 if (ntargets == 0)
915 helpmod_message_channel_long(hchannel_get_by_channel(returntype), "(%s): %s", htrm->name->content, htrm->description->content);
916 else
917 {
918 char buffer[256] = "";
919 for (i=0;i<ntargets;i++)
920 {
921 if (i != 0)
922 strcat(buffer, " ");
923 strcat(buffer, huser_get_nick(targets[i]));
924 }
925
926 helpmod_message_channel_long(hchannel_get_by_channel(returntype), "%s: (%s) %s", buffer, htrm->name->content, htrm->description->content);
927 if (type != H_TERM_FIND)
928 {
929 if (hchan->flags & H_QUEUE)
930 {
931 for (i=0;i<ntargets;i++)
932 {
933 huser_channel *huserchan = huser_on_channel(targets[i], hchan);
934 huserchan->flags |= HQUEUE_DONE;
935 if (huserchan->flags & HCUMODE_VOICE)
936 helpmod_channick_modes(targets[i], hchan, MC_DEVOICE, HLAZY);
937 }
938 if (type == H_TERM_PLUS)
939 hqueue_advance(hchan, sender, ntargets);
940 }
941 }
942 }
943 }
944 else
945 helpmod_reply(sender, returntype, "(%s): %s", htrm->name->content, htrm->description->content);
946 }
947
948 static void helpmod_cmd_term_find (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
949 {
950 helpmod_cmd_term_find_general(sender, returntype, H_TERM_FIND, ostr, argc, argv);
951 }
952
953 static void helpmod_cmd_term_find_minus (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
954 {
955 helpmod_cmd_term_find_general(sender, returntype, H_TERM_MINUS, ostr, argc, argv);
956 }
957
958 static void helpmod_cmd_term_find_plus (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
959 {
960 helpmod_cmd_term_find_general(sender, returntype, H_TERM_PLUS, ostr, argc, argv);
961 }
962
963 static void helpmod_cmd_klingon (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
964 {
965 hchannel *hchan;
966 huser *target = NULL;
967 int rand_val;
968
969 DEFINE_HCHANNEL;
970
971 if (hchan == NULL)
972 {
973 rand_val = rand() % KLINGON_NTARGETED;
974 helpmod_reply(sender, NULL, "%s: %s", huser_get_nick(sender), klingon_targeted[rand_val]);
975 return;
976 }
977
978 if (argc)
979 target = huser_get(getnickbynick(argv[0]));
980
981 if (target)
982 {
983 rand_val = rand() % KLINGON_NTARGETED;
984 helpmod_message_channel(hchan, "%s: %s", huser_get_nick(target), klingon_targeted[rand_val]);
985 }
986 else
987 {
988 rand_val = rand() % KLINGON_NGENERAL;
989 helpmod_message_channel(hchan, "%s", klingon_general[rand_val]);
990 }
991 }
992
993 void helpmod_cmd_term (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
994 {
995 hterm *htrm;
996 hterm **source;
997 hchannel *hchan;
998
999 DEFINE_HCHANNEL;
1000
1001 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1002
1003 if (hchan == NULL)
1004 source = &hterms;
1005 else
1006 source = &hchan->channel_hterms;
1007
1008 if (argc == 0)
1009 {
1010 helpmod_reply(sender, returntype, "Cannot handle terms: Operation not specified");
1011 return;
1012 }
1013 if (!ci_strcmp(argv[0], "list"))
1014 {
1015 char buffer[512];
1016 int count = 0;
1017 char *pattern = "*";
1018
1019 buffer[0] = '\0';
1020 htrm = *source;
1021
1022 if (argc >= 2)
1023 pattern = argv[1];
1024 else
1025 pattern = "*";
1026
1027 helpmod_reply(sender, returntype, "Terms matching pattern '%s'", pattern);
1028 for (;htrm;htrm = htrm->next)
1029 {
1030 if (strlen(buffer) >= 250)
1031 {
1032 helpmod_reply(sender, returntype, "%s", buffer);
1033 buffer[0] = '\0';
1034 }
1035 if (strregexp(htrm->description->content, pattern) || strregexp(htrm->name->content, pattern))
1036 {
1037 sprintf(buffer+strlen(buffer) /* :) */, "%s(%d) ", htrm->name->content, strlen(htrm->description->content));
1038 count++;
1039 }
1040 }
1041 if (buffer[0])
1042 helpmod_reply(sender, returntype, "%s", buffer);
1043 helpmod_reply(sender, returntype, "%d term%s match%s pattern '%s'", count, (count == 1)?"":"s", (count == 1)?"es":"", pattern);
1044 }
1045 else if (!ci_strcmp(argv[0], "listfull"))
1046 {
1047 htrm = *source;
1048 helpmod_reply(sender, returntype, "Following terms have been entered:");
1049 for (;htrm;htrm = htrm->next)
1050 helpmod_reply(sender, returntype, "(%s): %s", htrm->name->content, htrm->description->content);
1051 }
1052 else if (!ci_strcmp(argv[0], "get"))
1053 {
1054 if (argc < 2)
1055 {
1056 helpmod_reply(sender, returntype, "Cannot get term: Term not specified");
1057 return;
1058 }
1059 htrm = hterm_get(*source, argv[1]);
1060 if (htrm == NULL)
1061 helpmod_reply(sender, returntype, "Cannot get term: Term %s not found", argv[1]);
1062 else
1063 helpmod_reply(sender, returntype, "(%s): %s", htrm->name->content, htrm->description->content);
1064 }
1065 else if (!ci_strcmp(argv[0], "add"))
1066 {
1067 if (argc < 2)
1068 helpmod_reply(sender, returntype, "Cannot add term: Term name not specified");
1069 else if (argc < 3)
1070 helpmod_reply(sender, returntype, "Cannot add term: Term description not specified");
1071 else if ((htrm = hterm_get(*source, argv[1])) != NULL)
1072 helpmod_reply(sender, returntype, "Cannot add term: Term %s is already added", argv[1]);
1073 else
1074 {
1075 char *name = argv[1], *description;
1076 SKIP_WORD; SKIP_WORD;
1077 description = ostr;
1078 htrm = hterm_add(source, name, description);
1079 helpmod_reply(sender, returntype, "Term %s added succesfully", name);
1080 }
1081 }
1082 else if (!ci_strcmp(argv[0], "del"))
1083 {
1084 int i;
1085 if (argc < 2)
1086 {
1087 helpmod_reply(sender, returntype, "Cannot delete term: Term name not specified");
1088 return;
1089 }
1090 if (argc > H_CMD_MAX_ARGS)
1091 argc = H_CMD_MAX_ARGS;
1092 for (i=1;i<argc;i++)
1093 {
1094 htrm = hterm_get(*source, argv[i]);
1095 if (htrm == NULL)
1096 {
1097 helpmod_reply(sender, returntype, "Cannot delete term: Term %s not found", argv[i]);
1098 continue;
1099 }
1100 hterm_del(source != NULL?source:&hterms, htrm);
1101 helpmod_reply(sender, returntype, "Term %s deleted succesfully", argv[i]);
1102 }
1103 }
1104 else if (!ci_strcmp(argv[0], "find"))
1105 {
1106 if (argc < 2)
1107 {
1108 helpmod_reply(sender, returntype, "Cannot find term: Term name not specified");
1109 return;
1110 }
1111 htrm = hterm_get_and_find(*source, argv[1]);
1112
1113 if (htrm == NULL)
1114 {
1115 helpmod_reply(sender, returntype, "No term found matching '%s'", argv[1]);
1116 return;
1117 }
1118 if (returntype != NULL && huser_get_level(sender) > H_PEON)
1119 helpmod_message_channel(hchannel_get_by_channel(returntype), "(%s): %s", htrm->name->content, htrm->description->content);
1120 else
1121 helpmod_reply(sender, returntype, "(%s): %s", htrm->name->content, htrm->description->content);
1122 }
1123 else
1124 {
1125 helpmod_reply(sender, returntype, "Cannot handle terms: Operation not specified");
1126 }
1127 }
1128
1129 static void helpmod_cmd_queue (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1130 {
1131 hchannel *hchan;
1132 int operation;
1133
1134 DEFINE_HCHANNEL;
1135
1136 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1137
1138 if (argc == 0)
1139 {
1140 helpmod_reply(sender, returntype, "Cannot handle queue: Operation not specified");
1141 return;
1142 }
1143
1144 if (!ci_strcmp(argv[0], "done"))
1145 operation = HQ_DONE;
1146 else if (!ci_strcmp(argv[0], "next"))
1147 operation = HQ_NEXT;
1148 else if (!ci_strcmp(argv[0], "on"))
1149 operation = HQ_ON;
1150 else if (!ci_strcmp(argv[0], "off"))
1151 operation = HQ_OFF;
1152 else if (!ci_strcmp(argv[0], "maintain"))
1153 operation = HQ_MAINTAIN;
1154 else if (!ci_strcmp(argv[0], "list"))
1155 operation = HQ_LIST;
1156 else if (!ci_strcmp(argv[0], "summary"))
1157 operation = HQ_SUMMARY;
1158 else if (!ci_strcmp(argv[0], "reset"))
1159 operation = HQ_RESET;
1160 else
1161 operation = HQ_NONE;
1162
1163 SKIP_WORD;
1164
1165 helpmod_queue_handler(sender, returntype, hchan, operation, ostr, argc, argv);
1166 }
1167
1168 static void helpmod_cmd_done (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1169 {
1170 hchannel *hchan;
1171 DEFINE_HCHANNEL;
1172 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1173 helpmod_queue_handler(sender, returntype, hchan, HQ_DONE, ostr, argc, argv);
1174 }
1175
1176 static void helpmod_cmd_next (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1177 {
1178 hchannel *hchan;
1179 DEFINE_HCHANNEL;
1180 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1181 helpmod_queue_handler(sender, returntype, hchan, HQ_NEXT, ostr, argc, argv);
1182 }
1183
1184 static void helpmod_cmd_enqueue (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1185 {
1186 hchannel *hchan;
1187 DEFINE_HCHANNEL;
1188 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1189 helpmod_queue_handler(sender, returntype, hchan, HQ_ON, ostr, argc, argv);
1190 }
1191
1192 static void helpmod_cmd_dequeue (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1193 {
1194 hchannel *hchan;
1195 DEFINE_HCHANNEL;
1196 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1197 helpmod_queue_handler(sender, returntype, hchan, HQ_OFF, ostr, argc, argv);
1198 }
1199
1200 static void helpmod_cmd_autoqueue (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1201 {
1202 hchannel *hchan;
1203 DEFINE_HCHANNEL;
1204 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1205 helpmod_queue_handler(sender, returntype, hchan, HQ_MAINTAIN, ostr, argc, argv);
1206 }
1207
1208 static void helpmod_cmd_dnmo (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1209 {
1210 int i;
1211 if (argc == 0)
1212 {
1213 helpmod_reply(sender, returntype, "Cannot correct the luser: User not defined");
1214 return;
1215 }
1216 if (argc > H_CMD_MAX_ARGS)
1217 argc = H_CMD_MAX_ARGS;
1218 for (i=0;i<argc;i++)
1219 {
1220 huser *husr = huser_get(getnickbynick(argv[i]));
1221 if (husr == NULL)
1222 {
1223 helpmod_reply(sender, returntype, "Cannot correct the luser: User %s not found", argv[i]);
1224 continue;
1225 }
1226 if (huser_get_level(husr) > H_PEON)
1227 {
1228 helpmod_reply(sender, returntype, "Cannot correct the luser: User %s is not a peon", argv[i]);
1229 continue;
1230 }
1231 /*
1232 if (!hchannels_on_queue(husr) && !hchannels_on_desk(husr))
1233 {
1234 helpmod_reply(sender, returntype, "Cannot correct the luser: User %s is not in any queue", argv[i]);
1235 continue;
1236 }
1237 */
1238 hchannels_dnmo(husr);
1239
1240 helpmod_reply(husr, NULL, "You contacted a channel operator without permission. This is a violation of the channel rules. As a result you have been set to the last queue position");
1241 helpmod_reply(sender, returntype, "User %s has been informed of his mistake", argv[i]);
1242 }
1243 { /* fix the autoqueue for the channel(s) */
1244 hchannel *hchan;
1245 for (hchan = hchannels;hchan;hchan = hchan->next)
1246 hqueue_handle_queue(hchan, sender);
1247 }
1248 }
1249
1250 static void helpmod_cmd_ban (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1251 {
1252 if (argc == 0 || !ci_strcmp(argv[0], "list"))
1253 {
1254 hban *ptr = hbans;
1255 char *pattern;
1256 int count = 0;
1257
1258 if (argc <= 1)
1259 pattern = "*";
1260 else
1261 pattern = argv[1];
1262
1263 helpmod_reply(sender, returntype, "Global bans matching pattern %s", pattern);
1264
1265 for (;ptr;ptr = ptr->next)
1266 if (strregexp(bantostring(ptr->real_ban), pattern))
1267 {
1268 helpmod_reply(sender, returntype, "%-64s %-20s %s", bantostring(ptr->real_ban), helpmod_strtime(ptr->expiration - time(NULL)), ptr->reason?ptr->reason->content:"");
1269 count++;
1270 }
1271
1272 helpmod_reply(sender, returntype, "%d Global bans match pattern %s", count, pattern);
1273 }
1274 else if (!ci_strcmp(argv[0], "add"))
1275 {
1276 int duration = 4 * HDEF_h;
1277 char *reason = "Banned";
1278 char *target = argv[1];
1279
1280 if (argc == 1)
1281 {
1282 helpmod_reply(sender, returntype, "Cannot add global ban: Target hostmask not defined");
1283 return;
1284 }
1285 if (argc >= 3)
1286 {
1287 if ((duration = helpmod_read_strtime(argv[2])) < 0)
1288 {
1289 helpmod_reply(sender, returntype, "Cannot add global ban: Invalid time %s", argv[2]);
1290 return;
1291 }
1292 }
1293 if (argc >= 4)
1294 {
1295 SKIP_WORD;
1296 SKIP_WORD;
1297 SKIP_WORD;
1298
1299 reason = ostr;
1300 }
1301 hban_add(target, reason, time(NULL) + duration, 0);
1302 helpmod_reply(sender, returntype, "Added ban for %s (%s), expires in %s", target, reason, helpmod_strtime(duration));
1303 }
1304 else if (!ci_strcmp(argv[0], "del"))
1305 {
1306 int i;
1307 if (argc == 1)
1308 {
1309 helpmod_reply(sender, returntype, "Cannot remove global ban: Target hostmask not defined");
1310 return;
1311 }
1312 if (argc > H_CMD_MAX_ARGS)
1313 argc = H_CMD_MAX_ARGS;
1314 for (i=1;i<argc;i++)
1315 {
1316 hban *ptr = hban_get(argv[i]);
1317 if (ptr == NULL)
1318 {
1319 helpmod_reply(sender, returntype, "Cannot remove global ban: Hostmask %s is not banned", argv[i]);
1320 continue;
1321 }
1322 helpmod_reply(sender, returntype, "Global ban for hostmask %s removed", argv[i]);
1323 hban_del(ptr,0);
1324 }
1325 }
1326 else
1327 {
1328 helpmod_reply(sender, returntype, "Cannot handle global bans: Unknown operation %s", argv[0]);
1329 return;
1330 }
1331 }
1332
1333 static void helpmod_cmd_chanban (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1334 {
1335 hchannel *hchan;
1336 int i;
1337
1338 DEFINE_HCHANNEL;
1339
1340 if (hchan == NULL)
1341 {
1342 helpmod_reply(sender, returntype, "Cannot handle channel bans: Channel not defined or not found");
1343 return;
1344 }
1345
1346 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1347 /*
1348 if (argc == 0)
1349 {
1350 helpmod_reply(sender, returntype, "Cannot handle channel bans: Operation not defined");
1351 return;
1352 }
1353 */
1354 if (argc == 0 || !ci_strcmp(argv[0], "list"))
1355 {
1356 char *pattern, *cban;
1357 chanban *ptr = hchan->real_channel->bans;
1358 int count = 0;
1359
1360 if (argc <= 1)
1361 pattern = "*";
1362 else
1363 pattern = argv[1];
1364
1365 helpmod_reply(sender, returntype, "Bans matching pattern %s for channel %s", pattern, hchannel_get_name(hchan));
1366 for (;ptr;ptr = ptr->next)
1367 if (strregexp((cban = bantostring(ptr)), pattern))
1368 {
1369 count++;
1370 if (hchanban_get(hchan,cban) != NULL)
1371 helpmod_reply(sender, returntype, "%s Expires in %s", bantostring(ptr), helpmod_strtime(hchanban_get(hchan, cban)->expiration - time(NULL)));
1372 else
1373 helpmod_reply(sender, returntype, "%s", bantostring(ptr));
1374 }
1375 helpmod_reply(sender, returntype, "%d bans match pattern %s on channel %s", count, pattern, hchannel_get_name(hchan));
1376 }
1377 else if (!ci_strcmp(argv[0], "add"))
1378 {
1379 if (argc == 1)
1380 {
1381 helpmod_reply(sender, returntype, "Cannot add channel bans: Pattern not defined");
1382 return;
1383 }
1384 if (argc > H_CMD_MAX_ARGS)
1385 argc = H_CMD_MAX_ARGS;
1386 for (i=1;i<argc;i++)
1387 {
1388 /* POSSIBLE BUG ? */
1389 helpmod_setban(hchan, argv[i], H_ETERNITY, MCB_ADD, HLAZY);
1390 helpmod_reply(sender, returntype, "Added ban %s to channel %s", argv[i], hchannel_get_name(hchan));
1391 }
1392 }
1393 else if (!ci_strcmp(argv[0], "del"))
1394 {
1395 if (argc == 1)
1396 {
1397 helpmod_reply(sender, returntype, "Cannot remove channel bans: Pattern not defined");
1398 return;
1399 }
1400 if (argc > H_CMD_MAX_ARGS)
1401 argc = H_CMD_MAX_ARGS;
1402 for (i=1;i<argc;i++)
1403 {
1404 chanban *ptr = hchan->real_channel->bans;
1405 for (;ptr;ptr = ptr->next)
1406 if (strregexp(bantostring(ptr), argv[i]))
1407 {
1408 helpmod_setban(hchan, argv[i], 0, MCB_DEL, HLAZY);
1409 helpmod_reply(sender, returntype, "Channel ban %s removed from channel %s", argv[i], hchannel_get_name(hchan));
1410 break;
1411 }
1412 if (ptr == NULL)
1413 helpmod_reply(sender, returntype, "Cannot remove channel ban: Pattern %s not banned on channel %s", argv[i], hchannel_get_name(hchan));
1414 }
1415 }
1416 else
1417 {
1418 helpmod_reply(sender, returntype, "Cannot handle channel bans: Unknown operation %s", argv[0]);
1419 return;
1420 }
1421 }
1422
1423 static void helpmod_cmd_idlekick (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1424 {
1425 hchannel *hchan;
1426 int tmp;
1427
1428 DEFINE_HCHANNEL;
1429
1430 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1431
1432 if (hchan == NULL)
1433 {
1434 helpmod_reply(sender, returntype, "Cannot handle the idlekick: Channel not defined or not found");
1435 return;
1436 }
1437 if (argc == 0) /* view */
1438 {
1439 helpmod_reply(sender, returntype, "Idlekick for channel %s is set to %s", hchannel_get_name(hchan), helpmod_strtime(hchan->max_idle));
1440 return;
1441 }
1442 else if ((tmp = helpmod_read_strtime(argv[0])) < 0 || tmp < HDEF_m || tmp > HDEF_w)
1443 {
1444 helpmod_reply(sender, returntype, "Cannot set the idlekick: Invalid time given '%s'", argv[0]);
1445 return;
1446 }
1447 else /* set it ! */
1448 {
1449 hchan->max_idle = tmp;
1450 helpmod_reply(sender, returntype, "Idlekick for channel %s set to %s succesfully", hchannel_get_name(hchan), helpmod_strtime(hchan->max_idle));
1451 }
1452 }
1453
1454 static void helpmod_cmd_topic (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1455 {
1456 hchannel *hchan;
1457 DEFINE_HCHANNEL;
1458
1459 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1460
1461 if (hchan == NULL)
1462 {
1463 helpmod_reply(sender, returntype, "Cannot handle the topic: Channel not defined or not found");
1464 return;
1465 }
1466 if (!(hchan -> flags & H_HANDLE_TOPIC))
1467 helpmod_reply(sender, returntype, "Note: I'm not set to handle the topic on channel %s", hchannel_get_name(hchan));
1468
1469 if (argc == 0) /* check the topic */
1470 {
1471 helpmod_reply(sender, returntype, "Topic of channel %s is currently: %s", hchannel_get_name(hchan), htopic_construct(hchan->topic));
1472 return;
1473 }
1474 if (!ci_strcmp(argv[0], "erase"))
1475 {
1476 htopic_del_all(&hchan->topic);
1477 hchannel_set_topic(hchan);
1478 helpmod_reply(sender, returntype, "Topic of channel %s erased", hchannel_get_name(hchan));
1479 }
1480 else if (!ci_strcmp(argv[0], "refresh"))
1481 {
1482 hchannel_set_topic(hchan);
1483 helpmod_reply(sender, returntype, "Topic of channel %s refreshed", hchannel_get_name(hchan));
1484 }
1485 else if (!ci_strcmp(argv[0], "add"))
1486 {
1487 int pos;
1488 SKIP_WORD;
1489 if (argc == 0)
1490 {
1491 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1492 return;
1493 }
1494 if (sscanf(argv[0], "%d", &pos) && pos >= 0)
1495 {
1496 SKIP_WORD;
1497 }
1498 else
1499 pos = 0;
1500 if (argc == 0) /* lame repeat :( */
1501 {
1502 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1503 return;
1504 }
1505 if (htopic_len(hchan->topic) + strlen(ostr) + 3 > TOPICLEN)
1506 {
1507 helpmod_reply(sender, returntype, "Cannot add to the topic of channel %s: Maximum topic length exceeded", hchannel_get_name(hchan));
1508 return;
1509 }
1510
1511 htopic_add(&hchan->topic, ostr, pos);
1512 hchannel_set_topic(hchan);
1513 helpmod_reply(sender, returntype, "Added '%s' to the topic of channel %s", ostr, hchannel_get_name(hchan));
1514 }
1515 else if (!ci_strcmp(argv[0], "del"))
1516 {
1517 int pos;
1518 if (argc == 1)
1519 {
1520 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1521 return;
1522 }
1523 SKIP_WORD;
1524 if (!sscanf(argv[0], "%d", &pos) || pos < 0)
1525 {
1526 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Expected positive integer", hchannel_get_name(hchan));
1527 return;
1528 }
1529 if (htopic_count(hchan->topic) < pos)
1530 {
1531 helpmod_reply(sender, returntype, "Cannot delete from the topic of channel %s: No such topic element %d", hchannel_get_name(hchan), pos);
1532 return;
1533 }
1534 htopic_del(&hchan->topic, htopic_get(hchan->topic, pos));
1535 hchannel_set_topic(hchan);
1536 }
1537 else if (!ci_strcmp(argv[0], "set"))
1538 {
1539 if (argc == 1)
1540 {
1541 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1542 return;
1543 }
1544 SKIP_WORD;
1545 htopic_del_all(&hchan->topic);
1546 htopic_add(&hchan->topic, ostr, 0);
1547 hchannel_set_topic(hchan);
1548 }
1549 else
1550 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Unknown operation %s", hchannel_get_name(hchan), argv[0]);
1551 }
1552
1553 static void helpmod_cmd_out (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1554 {
1555 huser *husr;
1556 int i;
1557 char *reason = "Banned";
1558 huser *targets[H_CMD_MAX_ARGS];
1559 int ntargets = 0;
1560
1561 if (argc == 0)
1562 {
1563 helpmod_reply(sender, returntype, "Cannot get rid of the user: User not specified");
1564 return;
1565 }
1566
1567 if (argc > H_CMD_MAX_ARGS)
1568 argc = H_CMD_MAX_ARGS;
1569 for (i=0;i<argc;i++)
1570 {
1571 if (argv[i][0] == ':')
1572 {
1573 if (i == 0)
1574 {
1575 helpmod_reply(sender, returntype, "Cannot get rid of users: No users specified");
1576 return;
1577 }
1578 while (i--)
1579 {
1580 SKIP_WORD;
1581 }
1582 reason = ostr + 1;
1583
1584 if (!strncmp(reason, "?? ", 3))
1585 { /* obtain reason from hterms */
1586 hchannel *hchan = NULL;
1587 if (returntype != NULL)
1588 hchan = hchannel_get_by_channel(returntype);
1589 hterm *new_reason = hterm_get_and_find(hchan->channel_hterms, reason + 3);
1590 if (new_reason != NULL)
1591 reason = new_reason->description->content;
1592 }
1593 break;
1594 }
1595
1596 husr = huser_get(getnickbynick(argv[i]));
1597 if (husr == NULL)
1598 {
1599 helpmod_reply(sender, returntype, "Cannot get rid of the user: User %s not found", argv[i]);
1600 continue;
1601 }
1602 if (huser_get_level(husr) > H_PEON)
1603 {
1604 helpmod_reply(sender, returntype, "Cannot get rid of the user: User %s is not a peon", huser_get_nick(husr));
1605 continue;
1606 }
1607 targets[ntargets++] = husr;
1608 }
1609
1610 for (i=0;i<ntargets;i++)
1611 {
1612 const char *banmask = hban_ban_string(targets[i]->real_user, HBAN_HOST);
1613
1614 hban_add(banmask, reason, time(NULL) + HCMD_OUT_DEFAULT, HLAZY);
1615
1616 helpmod_reply(sender, returntype, "User %s is now gone", huser_get_nick(targets[i]));
1617 }
1618 hcommit_modes();
1619 }
1620
1621 static void helpmod_cmd_everyoneout (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1622 {
1623 hchannel *hchan;
1624 hchannel_user **hchanuser;
1625 char *reason = "clearing channel";
1626 int autoqueue_tmp = -1;
1627
1628 DEFINE_HCHANNEL;
1629
1630 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1631
1632 if (hchan == NULL)
1633 {
1634 helpmod_reply(sender, returntype, "Cannot clear channel: Channel not defined or not found");
1635 return;
1636 }
1637
1638 if (argc)
1639 reason = ostr;
1640
1641 hchan->flags |= H_MAINTAIN_I;
1642 hchannel_mode_check(hchan);
1643
1644 hchanuser = &hchan->channel_users;
1645
1646 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN))
1647 {
1648 autoqueue_tmp = hchan->autoqueue;
1649 hchan->autoqueue = 0;
1650 }
1651
1652 while (*hchanuser)
1653 {
1654 if (huser_get_level((*hchanuser)->husr) < H_TRIAL)
1655 helpmod_kick(hchan, (*hchanuser)->husr, reason);
1656 else
1657 hchanuser = &(*hchanuser)->next;
1658 }
1659
1660 if (autoqueue_tmp > 0)
1661 hchan->autoqueue = autoqueue_tmp;
1662
1663 helpmod_reply(sender, returntype, "Channel %s has been cleared of normal users", hchannel_get_name(hchan));
1664 }
1665
1666 static void helpmod_cmd_kick (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1667 {
1668 hchannel *hchan;
1669 int i;
1670 huser *husr, *targets[H_CMD_MAX_ARGS];
1671 int ntargets = 0;
1672 char *reason = "out";
1673 DEFINE_HCHANNEL;
1674
1675 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1676
1677 if (hchan == NULL)
1678 {
1679 helpmod_reply(sender, returntype, "Cannot kick the user: Channel not defined or not found");
1680 return;
1681 }
1682
1683 if (argc == 0)
1684 {
1685 helpmod_reply(sender, returntype, "Cannot kick users: No users specified");
1686 return;
1687 }
1688
1689 if (argc > H_CMD_MAX_ARGS)
1690 argc = H_CMD_MAX_ARGS;
1691 for (i=0;i<argc;i++)
1692 {
1693 if (*argv[i] == ':')
1694 {
1695 if (i == 0)
1696 {
1697 helpmod_reply(sender, returntype, "Cannot kick the user: No users defined");
1698 return;
1699 }
1700 while (i--)
1701 {
1702 SKIP_WORD;
1703 }
1704 reason = ostr+1;
1705 break;
1706 }
1707 husr = huser_get(getnickbynick(argv[i]));
1708 if (husr == NULL)
1709 {
1710 helpmod_reply(sender, returntype, "Cannot kick the user: User %s not found", argv[i]);
1711 continue;
1712 }
1713 if (huser_on_channel(husr, hchan) == NULL)
1714 {
1715 helpmod_reply(sender, returntype, "Cannot kick the user: User %s is not on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
1716 continue;
1717 }
1718 if (huser_get_level(husr) > H_PEON)
1719 {
1720 helpmod_reply(sender, returntype, "Cannot kick the user: User %s is not a peon", huser_get_nick(husr));
1721 continue;
1722 }
1723 targets[ntargets++] = husr;
1724 }
1725
1726 for (i=0;i<ntargets;i++)
1727 helpmod_kick(hchan, targets[i], reason);
1728 }
1729
1730 static void helpmod_cmd_stats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1731 {
1732 hchannel *hchan;
1733 haccount *target = sender->account;
1734 hstat_account *ptr;
1735 hstat_account_entry *stat_entry;
1736 int days = 1, weeks = 0;
1737 int type = HSTAT_ACCOUNT_SHORT;
1738
1739 time_t timer = time(NULL);
1740 struct tm *tstruct = localtime(&timer);
1741
1742 int i = 0;
1743
1744 DEFINE_HCHANNEL;
1745
1746 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1747
1748 if (hchan == NULL)
1749 {
1750 helpmod_reply(sender, returntype, "Cannot show user statistics: Channel not defined or not found");
1751 return;
1752 }
1753
1754 if (argc > 0 && huser_get_level(sender) == H_ADMIN)
1755 { /* not very elegant */
1756 if (argv[0][0] == '#') /* account */
1757 {
1758 target = haccount_get_by_name(argv[0]+1);
1759 if (target == NULL)
1760 {
1761 helpmod_reply(sender, returntype, "Cannot show user statistics: Account %s not found", argv[0]);
1762 return;
1763 }
1764 SKIP_WORD;
1765 }
1766 }
1767
1768 if (target == NULL)
1769 {
1770 helpmod_reply(sender, returntype, "Cannot show user statistics: You do not have an account");
1771 return;
1772 }
1773
1774 if (argc > 0)
1775 {
1776 if (!ci_strcmp(argv[0], "short") || !ci_strcmp(argv[0], "s"))
1777 {
1778 type = HSTAT_ACCOUNT_SHORT;
1779 SKIP_WORD;
1780 }
1781 else if (!ci_strcmp(argv[0], "long") || !ci_strcmp(argv[0], "l"))
1782 {
1783 type = HSTAT_ACCOUNT_LONG;
1784 SKIP_WORD;
1785 }
1786 }
1787
1788 if (argc > 0)
1789 if (sscanf(argv[0], "%d", &days))
1790 {
1791 if (days < 0 || days > 7)
1792 {
1793 helpmod_reply(sender, returntype, "Cannot show user statistics: Expected integer between [0, 7]");
1794 return;
1795 }
1796 else
1797 {
1798 SKIP_WORD;
1799 }
1800 }
1801
1802 if (argc > 0)
1803 if (sscanf(argv[0], "%d", &weeks))
1804 {
1805 if (weeks < 0 || weeks > 10)
1806 {
1807 helpmod_reply(sender, returntype, "Cannot show user statistics: Expected integer between [0, 10]");
1808 return;
1809 }
1810 else
1811 {
1812 SKIP_WORD;
1813 }
1814 }
1815
1816 for (ptr = target->stats;ptr;ptr = ptr->next)
1817 if (ptr->hchan == hchan)
1818 break;
1819
1820 if (ptr == NULL)
1821 {
1822 helpmod_reply(sender, returntype, "Cannot show user statistics: User %s has no statistics for channel %s", target->name->content, hchannel_get_name(hchan));
1823 return;
1824 }
1825
1826 if (!days && !weeks)
1827 return;
1828
1829 helpmod_reply(sender, returntype, "Statistics for user %s on channel %s", target->name->content, hchannel_get_name(hchan));
1830
1831 if (days)
1832 {
1833 helpmod_reply(sender, returntype, "Last %d day%s", days, (days==1)?"":"s");
1834 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1835 for (i=0;i<days;i++)
1836 {
1837 stat_entry = &ptr->week[(tstruct->tm_wday - i + 7) % 7];
1838 helpmod_reply(sender, returntype, "%s", hstat_account_print(stat_entry, type));
1839 }
1840 }
1841
1842 if (weeks)
1843 {
1844 helpmod_reply(sender, returntype, "Last %d week%s", weeks, (weeks==1)?"":"s");
1845 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1846 for (i=0;i<weeks;i++)
1847 {
1848 stat_entry = &ptr->longterm[(hstat_week() - i + 10) % 10];
1849 helpmod_reply(sender, returntype, "%s", hstat_account_print(stat_entry, type));
1850 }
1851 }
1852 }
1853
1854 static void helpmod_cmd_chanstats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1855 {
1856 hchannel *hchan;
1857 hstat_channel *channel_stats;
1858 hstat_channel_entry *stat_entry;
1859
1860 time_t timer = time(NULL);
1861 struct tm *tstruct = localtime(&timer);
1862
1863 int days=1;
1864 int type = HSTAT_CHANNEL_SHORT;
1865 int weeks=0;
1866
1867 int i = 7;
1868
1869 DEFINE_HCHANNEL;
1870
1871 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1872
1873 if (hchan == NULL)
1874 {
1875 helpmod_reply(sender, returntype, "Cannot show channel statistics: Channel not defined or not found");
1876 return;
1877 }
1878
1879 if (argc > 0)
1880 {
1881 if (!ci_strcmp(argv[0], "short") || !ci_strcmp(argv[0], "s"))
1882 {
1883 type = HSTAT_CHANNEL_SHORT;
1884 SKIP_WORD;
1885 }
1886 else if (!ci_strcmp(argv[0], "long") || !ci_strcmp(argv[0], "l"))
1887 {
1888 type = HSTAT_CHANNEL_LONG;
1889 SKIP_WORD;
1890 }
1891 }
1892
1893 if (argc > 0)
1894 if (sscanf(argv[0], "%d", &days))
1895 {
1896 if (days < 0 || days > 7)
1897 {
1898 helpmod_reply(sender, returntype, "Cannot show channel statistics: Expected integer between [0, 7]");
1899 return;
1900 }
1901 else
1902 {
1903 SKIP_WORD;
1904 }
1905 }
1906
1907 if (argc > 0)
1908 if (sscanf(argv[0], "%d", &weeks))
1909 {
1910 if (weeks < 0 || weeks > 10)
1911 {
1912 helpmod_reply(sender, returntype, "Cannot show channel statistics: Expected integer between [0, 10]");
1913 return;
1914 }
1915 else
1916 {
1917 SKIP_WORD;
1918 }
1919 }
1920
1921 channel_stats = hchan->stats;
1922
1923 if (!days && !weeks)
1924 return;
1925
1926 helpmod_reply(sender, returntype, "Statistics for channel %s", hchannel_get_name(hchan));
1927
1928 if (days)
1929 {
1930 helpmod_reply(sender, returntype, "Last %d day%s", days, (days==1)?"":"s");
1931 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1932 for (i=0;i<days;i++) /* latest week */
1933 {
1934 stat_entry = &hchan->stats->week[(tstruct->tm_wday - i + 7) % 7];
1935 helpmod_reply(sender, returntype, "%s", hstat_channel_print(stat_entry, type));
1936 }
1937 }
1938
1939 if (weeks)
1940 {
1941 helpmod_reply(sender, returntype, "Last %d week%s", weeks, (weeks==1)?"":"s");
1942 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1943 for (i=0;i<weeks;i++) /* latest weeks */
1944 {
1945 stat_entry = &hchan->stats->longterm[(hstat_week() - i + 10) % 10];
1946 helpmod_reply(sender, returntype, "%s", hstat_channel_print(stat_entry, type));
1947 }
1948 }
1949 }
1950
1951 static void helpmod_cmd_activestaff (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1952 {
1953 hchannel *hchan;
1954 hstat_accounts_array arr;
1955 hlevel lvl = H_OPER;
1956 int listtype = 0;
1957 int i;
1958
1959 DEFINE_HCHANNEL;
1960
1961 if (hchan == NULL)
1962 {
1963 helpmod_reply(sender, returntype, "Cannot list active staff: Channel not specified or not found");
1964 return;
1965 }
1966
1967 if (argc == 1)
1968 {
1969 if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
1970 {
1971 lvl = H_OPER;
1972 SKIP_WORD;
1973 }
1974 else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
1975 {
1976 lvl = H_STAFF;
1977 SKIP_WORD;
1978 }
1979 else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
1980 {
1981 lvl = H_ANY;
1982 SKIP_WORD;
1983 }
1984 }
1985
1986 if (argc == 1)
1987 {
1988 if (!ci_strcmp(argv[0], "active") || !ci_strcmp(argv[0], "a"))
1989 {
1990 listtype = 0;
1991 SKIP_WORD;
1992 }
1993 else if (!ci_strcmp(argv[0], "inactive") || !ci_strcmp(argv[0], "i"))
1994 {
1995 listtype = 1;
1996 SKIP_WORD;
1997 }
1998 }
1999
2000 arr = create_hstat_account_array(hchan, lvl);
2001
2002 helpmod_reply(sender, returntype, "%s %ss for channel %s", listtype?"Inactive":"Active", hlevel_name(lvl), hchannel_get_name(hchan));
2003 switch (listtype)
2004 {
2005 case 0:
2006 for (i=0;i < arr.arrlen && arr.array[i].prime_time_spent > H_ACTIVE_LIMIT;i++)
2007 helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", i+1,((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
2008 break;
2009 case 1:
2010 for (i=arr.arrlen-1;i >= 0 && arr.array[i].prime_time_spent < H_ACTIVE_LIMIT;i--)
2011 helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", (arr.arrlen - i),((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
2012 break;
2013 }
2014
2015 free(arr.array);
2016 }
2017
2018 static void helpmod_cmd_top10 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2019 {
2020 hchannel *hchan;
2021 hstat_accounts_array arr;
2022 hlevel lvl = H_OPER;
2023 int i, top_n = 10;
2024
2025 DEFINE_HCHANNEL;
2026
2027 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2028
2029 if (hchan == NULL)
2030 {
2031 helpmod_reply(sender, returntype, "Cannot list channel Top10: Channel not specified or not found");
2032 return;
2033 }
2034
2035 if (argc >= 1)
2036 {
2037 if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
2038 lvl = H_OPER;
2039 else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
2040 lvl = H_STAFF;
2041 else if (!ci_strcmp(argv[0], "all") || !ci_strcmp(argv[0], "a"))
2042 lvl = H_ANY;
2043 }
2044 if (argc == 3)
2045 {
2046 int tmp;
2047 if (sscanf(argv[1], "%d", &tmp) && (tmp >= 10) && (tmp <= 50))
2048 top_n = tmp;
2049 }
2050
2051 arr = create_hstat_account_array(hchan, lvl);
2052
2053 helpmod_reply(sender, returntype, "Top%d most active %ss of channel %s", top_n, hlevel_name(lvl), hchannel_get_name(hchan));
2054 for (i=0;i < arr.arrlen && i < top_n;i++)
2055 helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s",i+1,((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
2056
2057 free(arr.array);
2058 }
2059
2060 static void helpmod_cmd_report (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2061 {
2062 hchannel *hchan, *target;
2063 DEFINE_HCHANNEL;
2064
2065 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2066
2067 if (hchan != NULL && (argc == 2))
2068 {
2069 hchan = hchannel_get_by_name(argv[0]);
2070 SKIP_WORD;
2071 }
2072
2073 if (hchan == NULL)
2074 {
2075 helpmod_reply(sender, returntype, "Cannot view or set channel reporting: Channel not defined or not found");
2076 return;
2077 }
2078 if (argc != 1)
2079 {
2080 if (hchan->report_to == NULL || !hchannel_is_valid(hchan->report_to))
2081 helpmod_reply(sender, returntype, "Channel %s is not reported anywhere (%s)", hchannel_get_name(hchan), hchannel_get_state(hchan, H_REPORT));
2082 else
2083 helpmod_reply(sender, returntype, "Channel %s is reported to channel %s (%s)", hchannel_get_name(hchan), hchannel_get_name(hchan->report_to), hchannel_get_state(hchan, H_REPORT));
2084 return;
2085 }
2086 if ((target = hchannel_get_by_name(argv[0])) == NULL)
2087 {
2088 helpmod_reply(sender, returntype, "Cannot set channel reporting: Channel %s not found", argv[0]);
2089 return;
2090 }
2091 hchan->report_to = target;
2092 helpmod_reply(sender, returntype, "Channel %s is now reported to channel %s (%s)", hchannel_get_name(hchan), hchannel_get_name(hchan->report_to), hchannel_get_state(hchan, H_REPORT));
2093 }
2094
2095 static void helpmod_cmd_mode(huser *sender, channel* returntype, int change, char* ostr, int argc, char *argv[])
2096 {
2097 hchannel *hchan;
2098 huser_channel *huserchan;
2099 huser *husr;
2100 int i;
2101
2102 DEFINE_HCHANNEL;
2103
2104 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2105
2106 if (hchan == NULL)
2107 {
2108 helpmod_reply(sender, returntype, "Cannot change mode: Channel not specified or not found");
2109 return;
2110 }
2111
2112 if (argc==0) /* for a simple opme */
2113 {
2114 argc = 1;
2115 argv[0] = (char*)huser_get_nick(sender);
2116 }
2117
2118 if (argc > H_CMD_MAX_ARGS)
2119 argc = H_CMD_MAX_ARGS;
2120
2121 for (i=0;i<argc;i++)
2122 {
2123 husr = huser_get(getnickbynick(argv[i]));
2124 if (husr == NULL)
2125 {
2126 helpmod_reply(sender, returntype, "Cannot change mode: User %s not found", argv[i], hchannel_get_name(hchan));
2127 continue;
2128 }
2129 huserchan = huser_on_channel(husr, hchan);
2130 if (huserchan == NULL)
2131 {
2132 helpmod_reply(sender, returntype, "Cannot change mode: User %s it not on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2133 continue;
2134 }
2135
2136 switch (change)
2137 {
2138 case H_CMD_OP:
2139 {
2140 int j;
2141 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2142 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2143 break;
2144 if ((huserchan->flags & HCUMODE_OP) && !(hchan->real_channel->users->content[j] & CUMODE_OP))
2145 {
2146 huserchan->flags &= ~HCUMODE_OP;
2147 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (+o when should be -o)");
2148 }
2149 if (huserchan->flags & HCUMODE_OP)
2150 {
2151 helpmod_reply(sender, returntype, "Cannot change mode: User %s is already +o on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2152 continue;
2153 }
2154 if (huser_get_level(husr) < H_STAFF)
2155 {
2156 helpmod_reply(sender, returntype, "Cannot change mode: User %s is not allowed to have +o on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2157 continue;
2158 }
2159 helpmod_channick_modes(husr, hchan, MC_OP, HLAZY);
2160 }
2161 break;
2162 case H_CMD_DEOP:
2163 {
2164 int j;
2165 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2166 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2167 break;
2168 if (!(huserchan->flags & HCUMODE_OP) && (hchan->real_channel->users->content[j] & CUMODE_OP))
2169 {
2170 huserchan->flags |= HCUMODE_OP;
2171 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (-o when should be +o)");
2172 }
2173 if (!(huserchan->flags & HCUMODE_OP))
2174 {
2175 helpmod_reply(sender, returntype, "Cannot change mode: User %s is already -o on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2176 continue;
2177 }
2178 if (huser_get_level(husr) > huser_get_level(sender))
2179 {
2180 helpmod_reply(sender, returntype, "Cannot change mode: User %s is meant to have +o on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2181 continue;
2182 }
2183 helpmod_channick_modes(husr, hchan, MC_DEOP, HLAZY);
2184 }
2185 break;
2186 case H_CMD_VOICE:
2187 {
2188 int j;
2189 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2190 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2191 break;
2192 if ((huserchan->flags & HCUMODE_VOICE) && !(hchan->real_channel->users->content[j] & CUMODE_VOICE))
2193 {
2194 huserchan->flags &= ~HCUMODE_VOICE;
2195 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (+v when should be -v)");
2196 }
2197 if (huserchan->flags & HCUMODE_VOICE)
2198 {
2199 helpmod_reply(sender, returntype, "Cannot change mode: User %s is already +v on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2200 continue;
2201 }
2202 helpmod_channick_modes(husr, hchan, MC_VOICE, HLAZY);
2203 }
2204 break;
2205 case H_CMD_DEVOICE:
2206 {
2207 int j;
2208 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2209 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2210 break;
2211 if (!(huserchan->flags & HCUMODE_VOICE) && (hchan->real_channel->users->content[j] & CUMODE_VOICE))
2212 {
2213 huserchan->flags |= HCUMODE_VOICE;
2214 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (-v when should be +v)");
2215 }
2216 if (!(huserchan->flags & HCUMODE_VOICE))
2217 {
2218 helpmod_reply(sender, returntype, "Cannot change mode: User %s is already -v on channel %s", huser_get_nick(husr), hchannel_get_name(hchan));
2219 continue;
2220 }
2221 helpmod_channick_modes(husr, hchan, MC_DEVOICE, HLAZY);
2222 }
2223 break;
2224 }
2225 }
2226 }
2227
2228 static void helpmod_cmd_op (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_mode(sender, returntype, H_CMD_OP, ostr, argc, argv); }
2229 static void helpmod_cmd_deop (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_mode(sender, returntype, H_CMD_DEOP, ostr, argc, argv); }
2230 static void helpmod_cmd_voice (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_mode(sender, returntype, H_CMD_VOICE, ostr, argc, argv); }
2231 static void helpmod_cmd_devoice (huser *sender, channel* returntype, char* ostr, int argc, char *argv[]) { helpmod_cmd_mode(sender, returntype, H_CMD_DEVOICE, ostr, argc, argv); }
2232
2233 static void helpmod_cmd_invite (huser *sender, channel *returntype, char* arg, int argc, char *argv[])
2234 {
2235 hchannel *hchan;
2236 int i;
2237
2238 if (argc == 0)
2239 {
2240 helpmod_reply(sender, returntype, "Cannot invite: Channel not defined or not found");
2241 return;
2242 }
2243
2244 if (huser_get_level(sender) == H_PEON)
2245 {
2246 hticket *htick;
2247 hchan = hchannel_get_by_name(argv[0]);
2248 if (hchan == NULL)
2249 {
2250 helpmod_reply(sender, returntype, "Cannot invite: Unknown channel %s", argv[0]);
2251 return;
2252 }
2253 /* if tickets don't work, it's better that the user doesn't know that the channel really exists */
2254 if (!(hchan->flags & H_REQUIRE_TICKET))
2255 {
2256 helpmod_reply(sender, returntype, "Cannot invite: Unknown channel %s", argv[0]);
2257 return;
2258 }
2259 htick = hticket_get(huser_get_auth(sender), hchan);
2260
2261 if (htick == NULL)
2262 {
2263 helpmod_reply(sender, returntype, "Cannot invite: You do not have an invite ticket for channel %s", argv[0]);
2264 return;
2265 }
2266
2267 if (nickbanned(sender->real_user, hchan->real_channel))
2268 {
2269 helpmod_reply(sender, returntype, "Cannot invite: You are banned from channel %s", argv[0]);
2270 return;
2271 }
2272
2273 helpmod_invite(hchan, sender);
2274 helpmod_reply(sender, returntype, "Invited you to channel %s", hchannel_get_name(hchan));
2275 return;
2276 }
2277
2278 if (argc > H_CMD_MAX_ARGS)
2279 argc = H_CMD_MAX_ARGS;
2280
2281 for (i = 0;i < argc; i++)
2282 {
2283 hchan = hchannel_get_by_name(argv[i]);
2284 if (hchan == NULL)
2285 {
2286 helpmod_reply(sender, returntype, "Cannot invite: Unknown channel %s", argv[i]);
2287 continue;
2288 }
2289 if (!(hchannel_authority(hchan, sender) || hticket_get(huser_get_auth(sender), hchan)))
2290 {
2291 helpmod_reply(sender, returntype, "Sorry, channel %s is oper only", hchannel_get_name(hchan));
2292 continue;
2293 }
2294 if (huser_on_channel(sender, hchan) != NULL)
2295 {
2296 helpmod_reply(sender, returntype, "Cannot invite: You are already on channel %s", hchannel_get_name(hchan));
2297 continue;
2298 }
2299 helpmod_invite(hchan, sender);
2300 helpmod_reply(sender, returntype, "Invited you to channel %s", hchannel_get_name(hchan));
2301 }
2302 }
2303
2304 static void helpmod_cmd_ticket (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2305 {
2306 int expiration = HTICKET_EXPIRATION_TIME;
2307 hchannel *hchan;
2308 huser *husr;
2309 hticket *htick;
2310
2311 if (argc < 1)
2312 {
2313 helpmod_reply(sender, returntype, "Cannot issue a ticket: Channel not specified");
2314 return;
2315 }
2316
2317 hchan = hchannel_get_by_name(argv[0]);
2318 if (hchan == NULL)
2319 {
2320 helpmod_reply(sender, returntype, "Cannot issue a ticket: Unknown channel %s", argv[0]);
2321 return;
2322 }
2323 if (!(hchan->flags & H_REQUIRE_TICKET))
2324 {
2325 helpmod_reply(sender, returntype, "Cannot issue a ticket: Tickets are not enabled for channel %s", argv[0]);
2326 return;
2327 }
2328 if (argc < 2)
2329 {
2330 helpmod_reply(sender, returntype, "Cannot issue a ticket: Target user not specified");
2331 return;
2332 }
2333
2334 husr = huser_get(getnickbynick(argv[1]));
2335 if (husr == NULL)
2336 {
2337 helpmod_reply(sender, returntype, "Cannot issue a ticket: Unknown user %s", argv[1]);
2338 return;
2339 }
2340 if (!IsAccount(husr->real_user))
2341 {
2342 helpmod_reply(sender, returntype, "Cannot issue a ticket: User %s is not authed", argv[1]);
2343 return;
2344 }
2345 if (huser_get_level(husr) < H_PEON)
2346 {
2347 helpmod_reply(sender, returntype, "Cannot issue a ticket: User %s is considered improper and not worthy of a ticket", argv[1]);
2348 return;
2349 }
2350 if (huser_get_level(husr) > H_PEON)
2351 {
2352 helpmod_reply(sender, returntype, "Cannot issue a ticket: User %s does not require a ticket", argv[1]);
2353 return;
2354 }
2355 if (argc >= 3)
2356 {
2357 int tmp;
2358 tmp = helpmod_read_strtime(argv[2]);
2359 if (tmp > HDEF_m && tmp < 2 * HDEF_M)
2360 expiration = tmp;
2361 }
2362
2363 htick = hticket_get(huser_get_auth(husr), hchan);
2364
2365 if (htick != NULL)
2366 htick->time_expiration = time(NULL) + expiration;
2367 else
2368 hticket_add(huser_get_auth(husr), time(NULL) + expiration, hchan);
2369
2370 helpmod_reply(sender, returntype, "Issued an invite ticket to user %s for channel %s expiring in %s", huser_get_nick(husr), hchannel_get_name(hchan), helpmod_strtime(expiration));
2371 helpmod_reply(husr, NULL, "You have been issued an invite ticket for channel %s. This ticket is valid for a period of %s. You can use my invite command to get to the channel now. Type /msg %s invite %s",hchannel_get_name(hchan), helpmod_strtime(HTICKET_EXPIRATION_TIME), helpmodnick->nick, hchannel_get_name(hchan));
2372 if (hchan->flags & H_TICKET_MESSAGE && hchan->ticket_message != NULL)
2373 helpmod_reply(husr, NULL, "Ticket information for %s: %s", hchannel_get_name(hchan), hchan->ticket_message->content);
2374
2375 }
2376 static void helpmod_cmd_resolve (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2377 {
2378 int i;
2379 hchannel *hchan;
2380 hticket *htick;
2381 huser *husr;
2382
2383 DEFINE_HCHANNEL;
2384
2385 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2386
2387 if (argc > H_CMD_MAX_ARGS)
2388 argc = H_CMD_MAX_ARGS;
2389
2390 if (hchan == NULL)
2391 {
2392 helpmod_reply(sender, returntype, "Cannot resolve a ticket: The channel is not specified");
2393 return;
2394 }
2395
2396 for (i = 0;i< argc;i++)
2397 {
2398 if (argv[i][0] == '#')
2399 {
2400 htick = hticket_get(&argv[i][1], hchan);
2401 if (htick == NULL)
2402 {
2403 helpmod_reply(sender, returntype, "Cannot resolve a ticket: Authname %s does not have a ticket for channel %s", &argv[i][1], hchannel_get_name(hchan));
2404 continue;
2405 }
2406 hticket_del(htick, hchan);
2407 helpmod_reply(sender, returntype, "Resolved authname %s's ticket for channel %s", &argv[i][1], hchannel_get_name(hchan));
2408 }
2409 else
2410 {
2411 husr = huser_get(getnickbynick(argv[i]));
2412 if (husr == NULL)
2413 {
2414 helpmod_reply(sender, returntype, "Cannot resolve a ticket: User %s not found", argv[i]);
2415 continue;
2416 }
2417 if (!IsAccount(husr->real_user))
2418 {
2419 helpmod_reply(sender, returntype, "Cannot resolve a ticket: User %s is not authed", argv[i]);
2420 continue;
2421 }
2422 htick = hticket_get(huser_get_auth(husr),hchan);
2423 if (htick == NULL)
2424 {
2425 helpmod_reply(sender, returntype, "Cannot resolve a ticket: User %s does not have a ticket for channel %s", argv[i], hchannel_get_name(hchan));
2426 continue;
2427 }
2428 hticket_del(htick, hchan);
2429 helpmod_reply(sender, returntype, "Resolved user %s's ticket for channel %s", argv[i], hchannel_get_name(hchan));
2430 }
2431 }
2432 }
2433
2434 static void helpmod_cmd_tickets (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2435 {
2436 hchannel *hchan;
2437 hticket *htick;
2438 int i;
2439
2440 DEFINE_HCHANNEL;
2441
2442 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2443
2444 if (hchan == NULL)
2445 {
2446 helpmod_reply(sender, returntype, "Cannot list tickets: Channel not defined or not found");
2447 return;
2448 }
2449
2450 if (!(hchan->flags & H_REQUIRE_TICKET))
2451 {
2452 helpmod_reply(sender, returntype, "Cannot list tickets: Channel %s does not use the ticket system", hchannel_get_name(hchan));
2453 return;
2454 }
2455
2456 htick = hchan->htickets;
2457
2458 if (htick == NULL)
2459 {
2460 helpmod_reply(sender, returntype, "Channel %s has no valid tickets", hchannel_get_name(hchan));
2461 return;
2462 }
2463
2464 helpmod_reply(sender, returntype, "Valid tickets for channel %s", hchannel_get_name(hchan));
2465
2466 for (i = 0;htick;htick = htick->next, i++)
2467 helpmod_reply(sender, returntype, "%4d %16s %48s", i, htick->authname, helpmod_strtime(time(NULL) - htick->time_expiration));
2468
2469 helpmod_reply(sender, returntype, "Done listing tickets. Channel %s had %d valid ticket%s", hchannel_get_name(hchan), i, (i==1)?"":"s");
2470 }
2471
2472 static void helpmod_cmd_showticket (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2473 {
2474 hchannel *hchan;
2475 huser *husr;
2476 hticket *htick;
2477 int i;
2478
2479 DEFINE_HCHANNEL;
2480
2481 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2482
2483 if (argc > H_CMD_MAX_ARGS)
2484 argc = H_CMD_MAX_ARGS;
2485
2486 if (hchan == NULL)
2487 {
2488 helpmod_reply(sender, returntype, "Cannot show the ticket: Channel not defined or not found");
2489 return;
2490 }
2491 for (i = 0;i < argc;i++)
2492 {
2493 husr = huser_get(getnickbynick(argv[i]));
2494 if (husr == NULL)
2495 {
2496 helpmod_reply(sender, returntype, "Cannot show the ticket: User %s not found", argv[i]);
2497 continue;
2498 }
2499 if (!IsAccount(husr->real_user))
2500 {
2501 helpmod_reply(sender, returntype, "Cannot show the ticket: User %s is not authed", argv[i]);
2502 continue;
2503 }
2504 htick = hticket_get(huser_get_auth(husr), hchan);
2505 if (htick == NULL)
2506 {
2507 helpmod_reply(sender, returntype, "Cannot show the ticket: User %s does not have a valid ticket for channel %s", argv[i], hchannel_get_name(hchan));
2508 continue;
2509 }
2510 helpmod_reply(sender, returntype, "User %s has a ticket for channel %s expiring in %s", argv[i], hchannel_get_name(hchan), helpmod_strtime(htick->time_expiration - time(NULL)));
2511 }
2512 }
2513
2514 static int helpmod_cmd_termstats_sort(const void *left, const void *right)
2515 {
2516 return (*((hterm**)right))->usage - (*((hterm**)left))->usage;
2517 }
2518
2519 static void helpmod_cmd_termstats(huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2520 {
2521 hterm **arr, *origin;
2522 hchannel *hchan;
2523 int i, count;
2524
2525 DEFINE_HCHANNEL;
2526
2527 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2528
2529 if (hchan == NULL)
2530 origin = hterms;
2531 else
2532 origin = hchan->channel_hterms;
2533
2534 count = hterm_count(origin);
2535
2536 if (count == 0)
2537 {
2538 helpmod_reply(sender, returntype, "Cannot list term usage statistics: No terms available");
2539 return;
2540 }
2541
2542 arr = malloc(sizeof(hterm*) * count);
2543 assert(arr != NULL);
2544
2545 for (i=0;i < count;i++,origin = origin->next)
2546 arr[i] = origin;
2547
2548 qsort(arr, count, sizeof(hterm*), helpmod_cmd_termstats_sort);
2549
2550 if (hchan == NULL)
2551 helpmod_reply(sender, returntype, "10 Most used global terms");
2552 else
2553 helpmod_reply(sender, returntype, "10 Most used terms for channel %s", hchannel_get_name(hchan));
2554
2555 for (i=0;i < 10 && i < count;i++)
2556 helpmod_reply(sender, returntype, "#%02d %32s :%d",i+1, arr[i]->name->content,arr[i]->usage);
2557
2558 free(arr);
2559 }
2560
2561 static int helpmod_cmd_checkchannel_nicksort(const void *left, const void *right)
2562 {
2563 return ci_strcmp(getnickbynumeric(*((unsigned long*)left))->nick, getnickbynumeric(*((unsigned long*)right))->nick);
2564 }
2565
2566 static int helpmod_cmd_checkchannel_statussort(const void *left, const void *right)
2567 {
2568 int level1 = 0, level2 = 0;
2569
2570 if (*((unsigned long*)left) & CUMODE_VOICE)
2571 level1 = 1;
2572 if (*((unsigned long*)left) & CUMODE_OP)
2573 level1 = 2;
2574
2575 if (*((unsigned long*)right) & CUMODE_VOICE)
2576 level2 = 1;
2577 if (*((unsigned long*)right) & CUMODE_OP)
2578 level2 = 2;
2579
2580 return level2 - level1;
2581 }
2582
2583 static void helpmod_cmd_checkchannel(huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2584 {
2585 channel *chan;
2586 nick *nck;
2587 int i, j, nick_count = 0, authed_count = 0, o_limit = 0, v_limit = 0, summary_only = 0;
2588 unsigned long *numeric_array;
2589
2590 if (argc == 0)
2591 {
2592 helpmod_reply(sender, returntype, "Cannot check channel: Channel not defined");
2593 return;
2594 }
2595
2596 chan = findchannel(argv[0]);
2597 if (chan == NULL)
2598 {
2599 helpmod_reply(sender, returntype, "Cannot check channel: Channel %s not found", argv[0]);
2600 return;
2601 }
2602 if (argc > 1 && !ci_strcmp(argv[1], "summary"))
2603 summary_only = 1;
2604
2605 /* first pass - verify validity and count nicks */
2606 for (i=0;i < chan->users->hashsize;i++)
2607 {
2608 nck = getnickbynumeric(chan->users->content[i]);
2609 if (!nck) /* it's a hash, not an array */
2610 continue;
2611
2612 nick_count++;
2613
2614 if (IsAccount(nck))
2615 authed_count++;
2616
2617 if (IsOper(nck) && strlen(nck->nick) > 1)
2618 {
2619 helpmod_reply(sender, returntype, "Cannot check channel: Permission denied. Channel %s has an oper on it", argv[0]);
2620 return;
2621 }
2622 }
2623
2624 numeric_array = (unsigned long*)malloc(nick_count * sizeof(unsigned long));
2625
2626 /* second pass - construct array */
2627 for (i=0,j=0;i < chan->users->hashsize;i++)
2628 {
2629 if (getnickbynumeric(chan->users->content[i]) == NULL) /* it's a hash, not an array */
2630 continue;
2631
2632 numeric_array[j++] = chan->users->content[i];
2633 }
2634
2635 qsort(numeric_array, nick_count, sizeof(unsigned long), helpmod_cmd_checkchannel_statussort);
2636
2637 /* third pass - find status boundaries */
2638 {
2639 for (;o_limit < nick_count && numeric_array[o_limit] & CUMODE_OP; o_limit++);
2640 v_limit = o_limit;
2641 for(v_limit = o_limit; (v_limit < nick_count) && numeric_array[v_limit] & CUMODE_VOICE; v_limit++);
2642 }
2643
2644 helpmod_reply(sender, returntype, "Information on channel %s", argv[0]);
2645 helpmod_reply(sender, returntype, "Channel created %s ago", helpmod_strtime(time(NULL) - chan->timestamp));
2646 if (!IsKey(chan) && !IsInviteOnly(chan))
2647 helpmod_reply(sender, returntype, "Channel topic: %s", chan->topic?chan->topic->content:"Not set");
2648 helpmod_reply(sender, returntype, "Channel modes: %s", printflags(chan->flags, cmodeflags));
2649
2650
2651 /* sort the sub arrays */
2652
2653 if (o_limit > 0)
2654 qsort(numeric_array, o_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2655 if (v_limit - o_limit > 0)
2656 qsort(numeric_array + o_limit, v_limit - o_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2657 if (nick_count - v_limit > 0)
2658 qsort(numeric_array + v_limit, nick_count - v_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2659
2660 /* fourth pass - print results */
2661 if (!summary_only)
2662 for (i=0;i < nick_count;i++)
2663 {
2664 char buf[256], status;
2665
2666 if (numeric_array[i] & CUMODE_OP)
2667 status = '@';
2668 else if (numeric_array[i] & CUMODE_VOICE)
2669 status = '+';
2670 else
2671 status = ' ';
2672
2673 visiblehostmask(getnickbynumeric(numeric_array[i]), buf);
2674 if (IsAccount(getnickbynumeric(numeric_array[i])))
2675 helpmod_reply(sender, returntype, "%c%s (%s)", status, buf, getnickbynumeric(numeric_array[i])->authname);
2676 else
2677 helpmod_reply(sender, returntype, "%c%s", status, buf);
2678 }
2679
2680 helpmod_reply(sender, returntype, "Users: %d Clones: %d Opped: %d Voiced: %d Authed: %3.0f%%", nick_count, nick_count - countuniquehosts(chan), o_limit, v_limit - o_limit, ((float)authed_count / (float)nick_count) * 100.0);
2681
2682 free(numeric_array);
2683 }
2684
2685 static void helpmod_cmd_statsdump (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2686 {
2687 haccount *hacc = haccounts;
2688 hstat_account *ptr;
2689 int i;
2690
2691 helpmod_reply(sender, returntype, "Account statistics");
2692 for (;hacc;hacc = hacc->next)
2693 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2694 {
2695 helpmod_reply(sender, returntype, "Account %s channel %s short-term", hacc->name->content, hchannel_get_name(ptr->hchan));
2696 for (i = 0;i < 7;i++)
2697 helpmod_reply(sender, returntype, "%d %d %d %d", ptr->week[i].time_spent, ptr->week[i].prime_time_spent, ptr->week[i].lines, ptr->week[i].words);
2698 helpmod_reply(sender, returntype, "Account %s channel %s long-term", hacc->name->content, hchannel_get_name(ptr->hchan));
2699 for (i = 0;i < 10;i++)
2700 helpmod_reply(sender, returntype, "%d %d %d %d", ptr->longterm[i].time_spent, ptr->longterm[i].prime_time_spent, ptr->longterm[i].lines, ptr->longterm[i].words);
2701 }
2702 }
2703
2704 static void helpmod_cmd_statsrepair (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2705 {
2706 haccount *hacc = haccounts;
2707 hstat_account *ptr;
2708 int i;
2709
2710 helpmod_reply(sender, returntype, "Repairing account statistics");
2711 for (;hacc;hacc = hacc->next)
2712 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2713 {
2714 for (i = 0;i < 7;i++)
2715 {
2716 if (ptr->week[i].time_spent > HDEF_d)
2717 {
2718 ptr->week[i].time_spent = 0;
2719 helpmod_reply(sender, returntype, "repaired short term TimeSpent %s @ %s : Greater than one day",hacc->name->content, hchannel_get_name(ptr->hchan));
2720 }
2721 if (ptr->week[i].time_spent < 0)
2722 {
2723 ptr->week[i].time_spent = 0;
2724 helpmod_reply(sender, returntype, "repaired short term TimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2725 }
2726
2727 if (ptr->week[i].prime_time_spent > HDEF_d)
2728 {
2729 ptr->week[i].prime_time_spent = 0;
2730 helpmod_reply(sender, returntype, "repaired short term PrimeTimeSpent %s @ %s : Greater than one day",hacc->name->content, hchannel_get_name(ptr->hchan));
2731 }
2732 if (ptr->week[i].prime_time_spent < 0)
2733 {
2734 ptr->week[i].prime_time_spent = 0;
2735 helpmod_reply(sender, returntype, "repaired short term PrimeTimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2736 }
2737
2738 if (ptr->week[i].lines > 10000)
2739 {
2740 ptr->week[i].lines = 0;
2741 helpmod_reply(sender, returntype, "repaired short term Lines %s @ %s : Greater than 10000",hacc->name->content, hchannel_get_name(ptr->hchan));
2742 }
2743 if (ptr->week[i].lines < 0)
2744 {
2745 ptr->week[i].lines = 0;
2746 helpmod_reply(sender, returntype, "repaired short term Lines %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2747 }
2748
2749 if (ptr->week[i].words > 50000)
2750 {
2751 ptr->week[i].words = 0;
2752 helpmod_reply(sender, returntype, "repaired short term Words %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2753 }
2754 if (ptr->week[i].words < 0)
2755 {
2756 ptr->week[i].words = 0;
2757 helpmod_reply(sender, returntype, "repaired short term Words %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2758 }
2759 }
2760 for (i = 0;i < 10;i++)
2761 {
2762 if (ptr->longterm[i].time_spent > HDEF_w)
2763 {
2764 ptr->longterm[i].time_spent = 0;
2765 helpmod_reply(sender, returntype, "repaired long term TimeSpent %s @ %s : Greater than one week",hacc->name->content, hchannel_get_name(ptr->hchan));
2766 }
2767 if (ptr->longterm[i].time_spent < 0)
2768 {
2769 ptr->longterm[i].time_spent = 0;
2770 helpmod_reply(sender, returntype, "repaired long term TimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2771 }
2772
2773 if (ptr->longterm[i].prime_time_spent > HDEF_w)
2774 {
2775 ptr->longterm[i].prime_time_spent = 0;
2776 helpmod_reply(sender, returntype, "repaired long term PrimeTimeSpent %s @ %s : Greater than one week",hacc->name->content, hchannel_get_name(ptr->hchan));
2777 }
2778 if (ptr->longterm[i].prime_time_spent < 0)
2779 {
2780 ptr->longterm[i].prime_time_spent = 0;
2781 helpmod_reply(sender, returntype, "repaired long term PrimeTimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2782 }
2783
2784 if (ptr->longterm[i].lines > 50000)
2785 {
2786 ptr->longterm[i].lines = 0;
2787 helpmod_reply(sender, returntype, "repaired long term Lines %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2788 }
2789 if (ptr->longterm[i].lines < 0)
2790 {
2791 ptr->longterm[i].lines = 0;
2792 helpmod_reply(sender, returntype, "repaired long term Lines %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2793 }
2794
2795 if (ptr->longterm[i].words > 50000)
2796 {
2797 ptr->longterm[i].words = 0;
2798 helpmod_reply(sender, returntype, "repaired long term Words %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2799 }
2800 if (ptr->longterm[i].words < 0)
2801 {
2802 ptr->longterm[i].words = 0;
2803 helpmod_reply(sender, returntype, "repaired long term Words %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2804 }
2805 }
2806 }
2807 helpmod_reply(sender, returntype, "Account statistics repaired");
2808
2809 }
2810
2811 static void helpmod_cmd_statsreset (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2812 {
2813 haccount *hacc = haccounts;
2814 hstat_account *ptr;
2815 hchannel *hchan;
2816 int i, short_del, long_del;
2817
2818 if (argc < 2)
2819 {
2820 helpmod_reply(sender, returntype, "Insufficient parameters");
2821 return;
2822 }
2823
2824 if (sscanf(argv[0], "%d", &short_del) == 0)
2825 {
2826 helpmod_reply(sender, returntype, "Invalid parameter");
2827 return;
2828 }
2829 if (sscanf(argv[1], "%d", &long_del) == 0)
2830 {
2831 helpmod_reply(sender, returntype, "Invalid parameter");
2832 return;
2833 }
2834
2835 for (;hacc;hacc = hacc->next)
2836 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2837 {
2838 for (i = 1;i < short_del + 1;i++)
2839 HSTAT_ACCOUNT_ZERO(ptr->week[(hstat_day() + i) % 7]);
2840 for (i = 1;i < long_del + 1;i++)
2841 HSTAT_ACCOUNT_ZERO(ptr->longterm[(hstat_week() + i) % 10]);
2842 }
2843
2844 for (hchan = hchannels;hchan;hchan = hchan->next)
2845 {
2846 for (i = 1;i < short_del + 1;i++)
2847 HSTAT_CHANNEL_ZERO(hchan->stats->week[(hstat_day() + i) % 7]);
2848 for (i = 1;i < long_del + 1;i++)
2849 HSTAT_CHANNEL_ZERO(hchan->stats->longterm[(hstat_week() + i) % 10]);
2850
2851 }
2852
2853 helpmod_reply(sender, returntype, "Statistics reset complete");
2854 }
2855
2856 static void helpmod_cmd_message (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2857 {
2858 hchannel *hchan;
2859
2860 if (argc < 2)
2861 {
2862 helpmod_reply(sender, returntype, "Cannot send a message: Insufficient arguments");
2863 return;
2864 }
2865 hchan = hchannel_get_by_name(argv[0]);
2866 if (hchan == NULL)
2867 {
2868 helpmod_reply(sender, returntype, "Cannot send a message: Invalid channel %s", argv[0]);
2869 return;
2870 }
2871 SKIP_WORD;
2872 helpmod_message_channel(hchan, "(%s) %s", huser_get_nick(sender), ostr);
2873 helpmod_reply(sender, returntype, "Message sent to %s", hchannel_get_name(hchan));
2874 }
2875
2876 static void helpmod_cmd_version (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2877 {
2878 helpmod_reply(sender, returntype, "HelpMod version " HELPMOD_VERSION " by strutsi (strutsi@quakenet.org)");
2879 }
2880
2881 static void helpmod_cmd_ticketmsg (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2882 {
2883 hchannel *hchan;
2884
2885 DEFINE_HCHANNEL;
2886
2887 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2888
2889 if (hchan == NULL)
2890 {
2891 helpmod_reply(sender, returntype, "Can not view or set ticket message: No channel is specified.");
2892 return;
2893 }
2894
2895 if (argc == 0)
2896 { /* view */
2897 if (hchan->ticket_message == NULL)
2898 helpmod_reply(sender, returntype, "No ticket message is set for channel %s", hchannel_get_name(hchan));
2899 else
2900 helpmod_reply(sender, returntype, "Ticket message for channel %s is: %s", hchannel_get_name(hchan), hchan->ticket_message->content);
2901 return;
2902 }
2903
2904 /* set */
2905 if (hchan->ticket_message != NULL)
2906 freesstring(hchan->ticket_message);
2907
2908 hchan->ticket_message = getsstring(ostr, strlen(ostr));
2909 helpmod_reply(sender, returntype, "Ticket message for channel %s set to: %s", hchannel_get_name(hchan), hchan->ticket_message->content);
2910 }
2911
2912 static void helpmod_cmd_lcedit (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2913 {
2914 hlc_profile *profile;
2915
2916 if (argc == 0)
2917 {
2918 helpmod_reply(sender, returntype, "Can not handle lamer control profiles: Operation not defined");
2919 return;
2920 }
2921
2922 if (!ci_strcmp(argv[0], "list"))
2923 {
2924 if (hlc_profiles == NULL)
2925 {
2926 helpmod_reply(sender, returntype, "Can not list lamer control profiles: No profiles");
2927 return;
2928 }
2929 helpmod_reply(sender, returntype, "Following lamer control profiles are currently available:");
2930 for (profile = hlc_profiles;profile != NULL;profile = profile->next)
2931 helpmod_reply(sender, returntype, "%s", profile->name->content);
2932 }
2933 else if (!ci_strcmp(argv[0], "add"))
2934 {
2935 if (argc < 2)
2936 {
2937 helpmod_reply(sender, returntype, "Can not add a lamer control profile: Profile name not defined");
2938 return;
2939 }
2940
2941 profile = hlc_get(argv[1]);
2942
2943 if (profile != NULL)
2944 {
2945 helpmod_reply(sender, returntype, "Can not add a lamer control profile: Profile named %s already exists", argv[1]);
2946 return;
2947 }
2948 profile = hlc_add(argv[1]);
2949
2950 { /* set the default values */
2951 profile->caps_max_percentage = 40;
2952 profile->caps_min_count = 20;
2953
2954 profile->repeats_max_count = 3;
2955 profile->repeats_min_length = 7;
2956
2957 profile->symbol_repeat_max_count = 6;
2958 profile->character_repeat_max_count = 7;
2959 profile->symbol_max_count = 9;
2960
2961 profile->tolerance_flood = 5;
2962
2963 profile->tolerance_spam = 0.008;
2964 profile->constant_spam = 10;
2965
2966 profile->tolerance_warn = 1;
2967 profile->tolerance_kick = 3;
2968 profile->tolerance_remove = 5;
2969 }
2970
2971 helpmod_reply(sender, returntype, "Lamer control profile %s added", argv[1]);
2972 }
2973 else if (!ci_strcmp(argv[0], "del"))
2974 {
2975 hchannel *hchan;
2976 if (argc < 2)
2977 {
2978 helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile name not defined");
2979 return;
2980 }
2981
2982 profile = hlc_get(argv[1]);
2983
2984 if (profile == NULL)
2985 {
2986 helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile named %s does not exist", argv[1]);
2987 return;
2988 }
2989 for (hchan = hchannels;hchan != NULL;hchan = hchan->next)
2990 if (hchan->lc_profile == profile)
2991 {
2992 helpmod_reply(sender, returntype, "Can not delete a lamer control profile: Profile %s is in use", argv[1]);
2993 return;
2994 }
2995 hlc_del(profile);
2996 helpmod_reply(sender, returntype, "Lamer control profile %s deleted", argv[1]);
2997 }
2998 else if (!ci_strcmp(argv[0], "view"))
2999 {
3000 if (argc < 2)
3001 {
3002 helpmod_reply(sender, returntype, "Can not view a lamer control profile: Profile name not defined");
3003 return;
3004 }
3005
3006 profile = hlc_get(argv[1]);
3007
3008 if (profile == NULL)
3009 {
3010 helpmod_reply(sender, returntype, "Can not view a lamer control profile: Profile named %s not found", argv[1]);
3011 return;
3012 }
3013
3014 helpmod_reply(sender, returntype, "Lamer control profile %s:", profile->name->content);
3015 helpmod_reply(sender, returntype, "Maximum caps percentage: %d", profile->caps_max_percentage);
3016 helpmod_reply(sender, returntype, "Caps minimum count: %d", profile->caps_min_count);
3017 helpmod_reply(sender, returntype, "Repeat tolerance: %d", profile->repeats_max_count);
3018 helpmod_reply(sender, returntype, "Repeat minimum length: %d", profile->repeats_min_length);
3019 helpmod_reply(sender, returntype, "Symbol repeat tolerance: %d", profile->symbol_repeat_max_count);
3020 helpmod_reply(sender, returntype, "Character repeat tolerance: %d", profile->character_repeat_max_count);
3021 helpmod_reply(sender, returntype, "Continous symbol tolerance: %d", profile->symbol_max_count);
3022 helpmod_reply(sender, returntype, "Flood tolerance: %d", profile->tolerance_flood);
3023 helpmod_reply(sender, returntype, "Spam tolerance: %d", profile->tolerance_spam);
3024 helpmod_reply(sender, returntype, "Spam multiplier: %f", profile->constant_spam);
3025 helpmod_reply(sender, returntype, "Warning limit: %d", profile->tolerance_warn);
3026 helpmod_reply(sender, returntype, "Kick limit: %d", profile->tolerance_kick);
3027 helpmod_reply(sender, returntype, "Ban limit: %d", profile->tolerance_remove);
3028 }
3029 else if (!ci_strcmp(argv[0], "edit"))
3030 {
3031 int int_val = -1;
3032 double dbl_val = -1;
3033
3034 if (argc != 4)
3035 {
3036 helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Syntax error");
3037 return;
3038 }
3039
3040 profile = hlc_get(argv[1]);
3041
3042 if (profile == NULL)
3043 {
3044 helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Profile %s not found", argv[1]);
3045 return;
3046 }
3047
3048 sscanf(argv[3], "%d", &int_val);
3049 sscanf(argv[3], "%lf", &dbl_val);
3050
3051 if (dbl_val < 0)
3052 { /* All int values are also valid double values */
3053 helpmod_reply(sender, returntype, "Can not edit a lamer control profile: Invalid argument");
3054 return;
3055 }
3056
3057 if (!ci_strcmp(argv[2], "caps_percentage"))
3058 profile->caps_max_percentage = int_val;
3059 else if (!ci_strcmp(argv[2], "caps_count"))
3060 profile->caps_min_count = int_val;
3061 else if (!ci_strcmp(argv[2], "repeat_tolerance"))
3062 profile->repeats_max_count = int_val;
3063 else if (!ci_strcmp(argv[2], "repeat_length"))
3064 profile->repeats_min_length = int_val;
3065 else if (!ci_strcmp(argv[2], "symbol_repeat"))
3066 profile->symbol_repeat_max_count = int_val;
3067 else if (!ci_strcmp(argv[2], "character_repeat"))
3068 profile->character_repeat_max_count = int_val;
3069 else if (!ci_strcmp(argv[2], "continuous_symbol"))
3070 profile->symbol_max_count = int_val;
3071 else if (!ci_strcmp(argv[2], "flood_tolerance"))
3072 profile->tolerance_flood = int_val;
3073 else if (!ci_strcmp(argv[2], "spam_tolerance"))
3074 profile->tolerance_spam = int_val;
3075 else if (!ci_strcmp(argv[2], "spam_multiplier"))
3076 profile->constant_spam = dbl_val;
3077 else if (!ci_strcmp(argv[2], "warn_limit"))
3078 profile->tolerance_warn = int_val;
3079 else if (!ci_strcmp(argv[2], "kick_limit"))
3080 profile->tolerance_kick = int_val;
3081 else if (!ci_strcmp(argv[2], "ban_limit"))
3082 profile->tolerance_remove = int_val;
3083 else
3084 {
3085 helpmod_reply(sender, returntype, "Can not edit a lamer control profile: No component named %s", argv[2]);
3086 return;
3087 }
3088 helpmod_reply(sender, returntype, "Lamer control profile component value changed succesfully.");
3089 }
3090 }
3091
3092 static void helpmod_cmd_ged (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3093 {
3094 helpmod_editor *editor;
3095
3096 if (sender->editor == NULL)
3097 { /* Start a new editor */
3098 if (argc == 0)
3099 {
3100 helpmod_reply(sender, returntype, "Can not use ged: Filename not specified");
3101 return;
3102 }
3103 editor = hed_open(sender, argv[0]);
3104 if (editor == NULL)
3105 {
3106 helpmod_reply(sender, returntype, "Can not use ged: Invalid filename %s", argv[0]);
3107 return;
3108 }
3109 if (editor->user != sender)
3110 {
3111 helpmod_reply(sender, returntype, "Can not use ged: File %s is currently being edited by %s", editor->filename, huser_get_nick(editor->user));
3112 return;
3113 }
3114 editor->user = sender;
3115 sender->editor = editor;
3116
3117 helpmod_reply(sender, returntype, "Ged: %d", hed_byte_count(editor));
3118 }
3119 else
3120 {
3121 hed_command(sender, returntype, ostr, argc, argv);
3122 }
3123 }
3124
3125 static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3126 {
3127 hchannel *hchan;
3128 DEFINE_HCHANNEL;
3129 FILE *in;
3130
3131 if (argc == 0 || !ci_strcmp(argv[0], "list"))
3132 {
3133 DIR *dir;
3134 struct dirent *dent;
3135 char buffer[384], **lines, *start;
3136 int nwritten, bufpos = 0, nlines = 0,i;
3137
3138 dir = opendir(HELPMOD_TEXT_DIR);
3139 assert(dir != NULL);
3140
3141 /* First pass, count */
3142 for (dent = readdir(dir);dent != NULL;dent = readdir(dir))
3143 {
3144 /* Skip stuff like . and .. */
3145 if (!strncmp(dent->d_name, ".", 1))
3146 continue;
3147 nlines++;
3148 }
3149
3150 if (nlines == 0)
3151 {
3152 helpmod_reply(sender, returntype, "No texts are available.");
3153 return;
3154 }
3155
3156 helpmod_reply(sender, returntype, "Following texts are available:");
3157
3158 {
3159 lines = (char **)malloc(sizeof(char*) * nlines);
3160 *lines = (char *)malloc(sizeof(char) * (HED_FILENAME_LENGTH+1) * nlines);
3161 /* We need the start to free this array */
3162 start = *lines;
3163 for(i=0;i < nlines;i++)
3164 lines[i] = &lines[0][(HED_FILENAME_LENGTH+1) * i];
3165 }
3166
3167 /* Second pass, create array */
3168 rewinddir(dir);
3169 for (dent = readdir(dir), i = 0;dent != NULL && i < nlines;dent = readdir(dir))
3170 {
3171 /* Skip stuff like . and .. */
3172 if (!strncmp(dent->d_name, ".", 1))
3173 continue;
3174 strncpy(lines[i], dent->d_name, 64);
3175 i++;
3176 }
3177 /* Sort */
3178 qsort(*lines, nlines, sizeof(char)*(HED_FILENAME_LENGTH+1), (int (*)(const void*, const void*))&strcmp);
3179
3180 for (i = 0;i < nlines;i++)
3181 {
3182 if (bufpos)
3183 {
3184 buffer[bufpos] = ' ';
3185 bufpos++;
3186 }
3187 sprintf(buffer + bufpos, "%s%n", lines[i], &nwritten);
3188 bufpos+=nwritten;
3189
3190 if (bufpos > (384 - (HED_FILENAME_LENGTH+1)))
3191 {
3192 helpmod_reply(sender, returntype, buffer);
3193 bufpos = 0;
3194 }
3195 }
3196
3197 if (bufpos)
3198 helpmod_reply(sender, returntype, buffer);
3199
3200 free(start);
3201 free(lines);
3202
3203 return;
3204 }
3205 else if (!ci_strcmp(argv[0], "show"))
3206 {
3207 char fname_buffer[128], buffer[512];
3208 if (argc < 2)
3209 {
3210 helpmod_reply(sender, returntype, "Can not show text: Text not specified");
3211 return;
3212 }
3213 if (!hed_is_valid_filename(argv[1]))
3214 {
3215 helpmod_reply(sender, returntype, "Can not show text: Invalid filename");
3216 return;
3217 }
3218 sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
3219 in = fopen(fname_buffer, "rwt");
3220 if (in == NULL)
3221 {
3222 helpmod_reply(sender, returntype, "Can not show text: Text %s not found", argv[1]);
3223 return;
3224 }
3225 while (!feof(in))
3226 {
3227 if (!fgets(buffer, 512, in))
3228 break;
3229 if (returntype != NULL && huser_get_level(sender) > H_PEON)
3230 helpmod_message_channel(hchannel_get_by_channel(returntype), "%s: %s", argv[1], buffer);
3231 else
3232 helpmod_reply(sender, returntype, "%s: %s", argv[1], buffer);
3233 }
3234 fclose (in);
3235 return;
3236 }
3237
3238 if (huser_get_level(sender) < H_STAFF)
3239 {
3240 helpmod_reply(sender, returntype, "Can not handle text: Insufficient user level");
3241 return;
3242 }
3243
3244 if (!ci_strcmp(argv[0], "add"))
3245 {
3246 char fname_buffer[128];
3247 if (argc < 2)
3248 {
3249 helpmod_reply(sender, returntype, "Can not add text: Text not specified");
3250 return;
3251 }
3252 if (!hed_is_valid_filename(argv[1]))
3253 {
3254 helpmod_reply(sender, returntype, "Can not add text: Invalid filename");
3255 return;
3256 }
3257 sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
3258 if ((in = fopen(fname_buffer, "rt")) != NULL)
3259 {
3260 helpmod_reply(sender, returntype, "Can not add text: Text %s already exists", argv[1]);
3261 return;
3262 }
3263 else
3264 {
3265 if ((in = fopen(fname_buffer, "wt")) == NULL)
3266 {
3267 helpmod_reply(sender, returntype, "Can not add text: Unexpected error, please contact strutsi");
3268 return;
3269 }
3270 fclose(in);
3271 }
3272 helpmod_reply(sender, returntype, "Text %s added succesfully", argv[1]);
3273 }
3274 else if (!ci_strcmp(argv[0], "del"))
3275 {
3276 char fname_buffer[128];
3277 if (argc < 2)
3278 {
3279 helpmod_reply(sender, returntype, "Can not delete text: Text not specified");
3280 return;
3281 }
3282 if (!hed_is_valid_filename(argv[1]))
3283 {
3284 helpmod_reply(sender, returntype, "Can not delete text: Invalid filename");
3285 return;
3286 }
3287 sprintf(fname_buffer, HELPMOD_TEXT_DIR"/%s" ,argv[1]);
3288
3289 if (!remove(fname_buffer))
3290 helpmod_reply(sender, returntype, "Text %s removed", argv[1]);
3291 else
3292 helpmod_reply(sender, returntype, "Can not delete text: Text %s does not exist or can not be deleted", argv[1]);
3293 }
3294 else
3295 {
3296 helpmod_reply(sender, returntype, "Can not handle text: Unknown operation %s", argv[0]);
3297 return;
3298 }
3299 }
3300
3301 static void helpmod_cmd_rating (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3302 {
3303 hchannel *hchan;
3304 hstat_account_entry sum = {0,0,0,0};
3305 hstat_account *ptr;
3306 int i;
3307
3308 DEFINE_HCHANNEL;
3309
3310 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
3311
3312 if (hchan == NULL)
3313 {
3314 helpmod_reply(sender, returntype, "Can not show rating: Unknown channel");
3315 return;
3316 }
3317 if (sender->account == NULL)
3318 {
3319 helpmod_reply(sender, returntype, "Can not show rating: You do not have an account");
3320 return;
3321 }
3322 for (ptr = sender->account->stats;ptr != NULL;ptr = ptr->next)
3323 if (ptr->hchan == hchan)
3324 {
3325 if (hstat_day() == 0)
3326 { /* Sunday screws the indexing */
3327 for (i = 0;i < 7;i++)
3328 HSTAT_ACCOUNT_SUM(sum, sum, ptr->week[i]);
3329 }
3330 else
3331 { /* Normal case */
3332 for (i = 1;i <= hstat_day();i++)
3333 HSTAT_ACCOUNT_SUM(sum, sum, ptr->week[i]);
3334 }
3335
3336 helpmod_reply(sender, returntype, "Your rating for channel %s for this week is: %s", hchannel_get_name(hchan), helpmod_strtime(sum.time_spent));
3337 return;
3338 }
3339 helpmod_reply(sender, returntype, "Can not show rating: You do not have any statistics for channel %s", hchannel_get_name(hchan));
3340 }
3341
3342 static void helpmod_cmd_writedb (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3343 {
3344 rename(HELPMOD_DEFAULT_DB, HELPMOD_DEFAULT_DB".old");
3345 helpmod_config_write(HELPMOD_DEFAULT_DB);
3346
3347 helpmod_reply(sender, returntype, "Database written");
3348 }
3349
3350 static void helpmod_cmd_evilhack1 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3351 {
3352 int tmp;
3353
3354 if (argc == 0)
3355 helpmod_reply(sender, returntype, "hstat_cycle: %d", hstat_cycle);
3356 else
3357 {
3358 if (!sscanf(argv[0], "%d", &tmp) || tmp < 0)
3359 {
3360 helpmod_reply(sender, returntype, "Invalid argument");
3361 return;
3362 }
3363 hstat_cycle = tmp;
3364 helpmod_reply(sender, returntype, "hstat_cycle is now: %d", hstat_cycle);
3365 }
3366 }
3367
3368 static void helpmod_cmd_evilhack2 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3369 {
3370 haccount *hacc = haccounts;
3371 hchannel *hchan;
3372 hstat_account *ptr;
3373 hstat_account_entry tmp_account;
3374 hstat_channel_entry tmp_channel;
3375 int first, second;
3376
3377 if (argc != 2)
3378 {
3379 helpmod_reply(sender, returntype, "Syntax error: evilhack2 <first> <second>");
3380 return;
3381 }
3382
3383 if (!sscanf(argv[0],"%d", &first) || first < 0 || first > 9)
3384 {
3385 helpmod_reply(sender, returntype, "Syntax error: Invalid first");
3386 return;
3387 }
3388
3389 if (!sscanf(argv[1],"%d", &second) || second < 0 || second > 9)
3390 {
3391 helpmod_reply(sender, returntype, "Syntax error: Invalid second");
3392 return;
3393 }
3394
3395 for (;hacc;hacc = hacc->next)
3396 for (ptr = hacc->stats;ptr;ptr = ptr->next)
3397 {
3398 tmp_account = ptr->longterm[first];
3399 ptr->longterm[first] = ptr->longterm[second];
3400 ptr->longterm[second] = tmp_account;
3401 }
3402
3403 for (hchan = hchannels;hchan;hchan = hchan->next)
3404 {
3405 tmp_channel = hchan->stats->longterm[first];
3406 hchan->stats->longterm[first] = hchan->stats->longterm[second];
3407 hchan->stats->longterm[second] = tmp_channel;
3408 }
3409
3410 helpmod_reply(sender, returntype, "Evilhack2 done: Swapped %d and %d", first, second);
3411 }
3412
3413 /* old H stuff */
3414 void helpmod_cmd_load (huser *sender, channel *returntype, char* arg, int argc, char *argv[])
3415 {
3416 FILE *tmp_file;
3417 char buf[128] = "helpmod/default";
3418
3419 if (!arg)
3420 helpmod_reply(sender, returntype, "Warning: No config specified, using default");
3421 else
3422 {
3423 if (strlen(arg) >= 100)
3424 return;
3425 else
3426 sprintf(buf, "helpmod/%s", arg);
3427 }
3428
3429 if (!(tmp_file = fopen(buf, "rt")))
3430 {
3431 helpmod_reply(sender, returntype, "File %s not found", buf);
3432 return;
3433 }
3434 else
3435 fclose(tmp_file);
3436
3437 helpmod_clear_aliases(&aliases);
3438 helpmod_clear_all_entries();
3439 helpmod_init_entry(&helpmod_base);
3440 huser_reset_states();
3441 helpmod_load_entries(buf);
3442 strcpy(helpmod_db, buf);
3443 helpmod_reply(sender, returntype, "New config loaded and system reset");
3444 }
3445
3446 void helpmod_cmd_status (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
3447 {
3448 helpmod_reply(sender, returntype, "HelpMod version %s (built %s, up %s)", HELPMOD_VERSION, __DATE__, helpmod_strtime(time(NULL) - helpmod_startup_time));
3449 helpmod_reply(sender, returntype, "Channels %d", hchannel_count());
3450 helpmod_reply(sender, returntype, "Accounts %d", haccount_count(H_ANY));
3451 helpmod_reply(sender, returntype, "Users %d", huser_count());
3452 helpmod_reply(sender, returntype, "Help entries %d", helpmod_entry_count(helpmod_base));
3453 helpmod_reply(sender, returntype, "Bans %d", hban_count());
3454 helpmod_reply(sender, returntype, "Help provided %d", helpmod_usage);
3455 helpmod_reply(sender, returntype, "Tickets %d", hticket_count());
3456 }
3457
3458 /* not really a command, but help wants this one */
3459 void helpmod_send_help(huser* target)
3460 {
3461 int i;
3462 helpmod_usage++;
3463 for (i=0;i<target->state->text_lines;i++)
3464 helpmod_reply(target, NULL, "%s", target->state->text[i]->content);
3465 for (i=0;i<target->state->option_count;i++)
3466 helpmod_reply(target, NULL, "%d) %s", i+1, target->state->options[i]->description->content);
3467 if (!target->state->option_count)
3468 {
3469 helpmod_reply(target, NULL, "This concludes the help for this topic, if you want to, you can restart the service with the 'help' command, or return to the previous entry by selecting 0");
3470 }
3471 }
3472
3473 void helpmod_cmd_command(huser* sender, channel* returntype, char* arg, int argc, char *argv[])
3474 {
3475 hcommand *hcom;
3476 char buffer[512], *ptr = argv[0];
3477 FILE *in;
3478
3479 if (argc == 0)
3480 {
3481 helpmod_reply(sender, returntype, "Usage: command [name of the command] for a list see 'showcommands'");
3482 return;
3483 }
3484
3485 hcom = hcommand_get(argv[0], huser_get_level(sender));
3486
3487 if (hcom == NULL)
3488 {
3489 helpmod_reply(sender, returntype, "Unknown command '%s'", argv[0]);
3490 return;
3491 }
3492
3493 /* tolower */
3494 while (*(ptr++))
3495 *ptr = tolower(*ptr);
3496
3497 /* ?,?+.?- is handled like this because windows is shit */
3498 if (!ci_strcmp(argv[0], "?"))
3499 sprintf(buffer, "./helpmod2/commands/questionmark");
3500 else if (!ci_strcmp(argv[0], "?+"))
3501 sprintf(buffer, "./helpmod2/commands/questionmarkplus");
3502 else if (!ci_strcmp(argv[0], "?-"))
3503 sprintf(buffer, "./helpmod2/commands/questionmarkminus");
3504 else
3505 sprintf(buffer, "./helpmod2/commands/%s", argv[0]);
3506
3507 if ((in = fopen(buffer, "rt")) == NULL)
3508 {
3509 helpmod_reply(sender, returntype, "No help available for command '%s' (Ask strutsi to write it)", argv[0]);
3510 return;
3511 }
3512
3513 while (!feof(in))
3514 {
3515 fgets(buffer, 512, in);
3516 if (feof(in))
3517 break;
3518 helpmod_reply(sender, returntype, "%s", buffer);
3519 }
3520
3521 fclose(in);
3522 }
3523
3524 void helpmod_cmd_help (huser* sender, channel* returntype, char* arg, int argc, char *argv[])
3525 {
3526 int hlp_target;
3527
3528 if (helpmod_base == NULL || !helpmod_base->option_count)
3529 {
3530 helpmod_reply(sender, returntype, "The help service is not available at this time, please try again later");
3531 return;
3532 }
3533
3534 if (!argc)
3535 {
3536 sender->state = helpmod_base;
3537 helpmod_send_help(sender);
3538 return;
3539 }
3540 else
3541 if (!sscanf(arg, "%d", &hlp_target))
3542 {
3543 helpmod_entry tmp;
3544
3545 tmp = helpmod_get_alias(arg);
3546 if (!tmp)
3547 helpmod_reply(sender, returntype, "Invalid value. Either use 'help' to restart or give an integer as a valid selection");
3548 else
3549 {
3550 sender->state = tmp;
3551 helpmod_send_help(sender);
3552 }
3553 return;
3554 }
3555
3556 hlp_target--;
3557 if (!helpmod_valid_selection(sender->state, hlp_target))
3558 {
3559 if (!sender->state->option_count)
3560 helpmod_reply(sender, returntype, "There are no more options to choose from, you can restart the service by giving the 'help' command or select 0 to return to the previous entry");
3561 else if (!sender->state->parent)
3562 helpmod_reply(sender, returntype, "Bad selection, please enter your selection as an integer from %d to %d", 1, sender->state->option_count);
3563 else
3564 helpmod_reply(sender, returntype, "Bad selection, please enter your selection as an integer from %d to %d, selecting 0 will take you to the previous entry", 1, sender->state->option_count);
3565 return;
3566 }
3567
3568 sender->state = helpmod_make_selection(sender->state, hlp_target);
3569 helpmod_send_help(sender);
3570
3571 return;
3572 }
3573 /* adds all of the abowe to the system */
3574 void hcommands_add(void)
3575 {
3576 hcommand_add("help", H_PEON, helpmod_cmd_help,"Offers the H1 type help");
3577 hcommand_add("status",H_OPER, helpmod_cmd_status,"Gives service status");
3578 hcommand_add("load", H_OPER, helpmod_cmd_load,"Loads a new help database");
3579 hcommand_add("aliases",H_STAFF, helpmod_cmd_aliases,"Lists all aliases currently in use");
3580 hcommand_add("showcommands", H_LAMER, helpmod_cmd_showcommands,"Lists all commands available to you");
3581
3582 hcommand_add("improper", H_STAFF, helpmod_cmd_improper, "Sets the userlevel of the target to banned (lvl 0). Long term ban.");
3583 hcommand_add("peon", H_STAFF, helpmod_cmd_peon, "Sets the userlevel of the target to peon (lvl 1)");
3584 hcommand_add("trial", H_OPER, helpmod_cmd_trial, "Sets the userlevel of the target to trial staff (lvl 2)");
3585 hcommand_add("staff", H_OPER, helpmod_cmd_staff, "Sets the userlevel of the target to staff (lvl 3)");
3586 hcommand_add("oper", H_OPER, helpmod_cmd_oper, "Sets the userlevel of the target to oper (lvl 4)");
3587 hcommand_add("admin", H_ADMIN, helpmod_cmd_admin, "Sets the userlevel of the target to admin (lvl 5)");
3588 hcommand_add("deluser", H_OPER, helpmod_cmd_deluser, "Removes an account from " HELPMOD_NICK);
3589 hcommand_add("listuser", H_STAFF, helpmod_cmd_listuser, "Lists user accounts of " HELPMOD_NICK);
3590
3591 hcommand_add("chanconf", H_STAFF, helpmod_cmd_chanconf, "Channel configuration");
3592 hcommand_add("acconf", H_TRIAL, helpmod_cmd_acconf, "Personalise " HELPMOD_NICK " behaviour");
3593 hcommand_add("welcome", H_STAFF, helpmod_cmd_welcome, "Views or changes the channel welcome message");
3594 hcommand_add("censor", H_STAFF, helpmod_cmd_censor, "Handles the censored patterns for a channel");
3595
3596 hcommand_add("queue", H_TRIAL, helpmod_cmd_queue, "Handles the channel queue");
3597 hcommand_add("next", H_TRIAL, helpmod_cmd_next, "Same as queue next");
3598 hcommand_add("done", H_TRIAL, helpmod_cmd_done, "Same as queue done");
3599 hcommand_add("enqueue", H_TRIAL, helpmod_cmd_enqueue, "Same as queue on or chanconf +3");
3600 hcommand_add("dequeue", H_TRIAL, helpmod_cmd_dequeue, "Same as queue off or chanconf -3");
3601 hcommand_add("autoqueue", H_TRIAL, helpmod_cmd_autoqueue, "Same as queue maintain");
3602
3603 hcommand_add("?", H_PEON, helpmod_cmd_term_find, "Same as term find with multiple targets");
3604 hcommand_add("?+", H_TRIAL, helpmod_cmd_term_find_plus, "Multitarget term find which advances the queue");
3605 hcommand_add("?-", H_TRIAL, helpmod_cmd_term_find_minus, "Multitarget term find which removes users from queue");
3606 hcommand_add("term", H_STAFF, helpmod_cmd_term, "Term handling");
3607
3608 hcommand_add("klingon", H_OPER, helpmod_cmd_klingon, "Phrases in klingon, both targeted and general");
3609 hcommand_add("out", H_STAFF, helpmod_cmd_out, "Sets the userlevel of the target to banned (lvl 0) for a short while");
3610 hcommand_add("kick", H_TRIAL, helpmod_cmd_kick, "Kicks user(s) from a channel");
3611 hcommand_add("ban", H_STAFF, helpmod_cmd_ban, "Handles global bans");
3612 hcommand_add("chanban", H_TRIAL, helpmod_cmd_chanban, "Handles channel bans");
3613 hcommand_add("dnmo", H_STAFF, helpmod_cmd_dnmo, "DoNotMessageOpers informs the luser of his mistake and sets him to the bottom of the queue");
3614 hcommand_add("lamercontrol", H_OPER, helpmod_cmd_lamercontrol, "Views or changes the channel lamercontrol profile");
3615 hcommand_add("topic", H_STAFF, helpmod_cmd_topic, "Handles the topic of a channel");
3616 hcommand_add("idlekick", H_OPER, helpmod_cmd_idlekick, "Views or sets the idle kick time");
3617 hcommand_add("everyoneout", H_STAFF, helpmod_cmd_everyoneout, "Removes all normal users from a channel and enforces +i");
3618
3619 hcommand_add("stats", H_STAFF, helpmod_cmd_stats, "Shows staff activity statistics");
3620 hcommand_add("chanstats", H_STAFF, helpmod_cmd_chanstats, "Shows channel activity statistics");
3621 hcommand_add("activestaff", H_ADMIN, helpmod_cmd_activestaff, "Shows active staff members for a channel");
3622 hcommand_add("top10", H_STAFF, helpmod_cmd_top10, "Shows the top 10 most active staff");
3623 hcommand_add("report", H_OPER, helpmod_cmd_report, "Sets the channel where to report this channels statistics every 5 minutes");
3624
3625 hcommand_add("whoami", H_LAMER, helpmod_cmd_whoami, "Tells who you are to " HELPMOD_NICK);
3626 hcommand_add("whois", H_STAFF, helpmod_cmd_whois, "Tells you who someone is");
3627 hcommand_add("command", H_LAMER, helpmod_cmd_command, "Gives detailed information on a command");
3628 hcommand_add("addchan", H_ADMIN, helpmod_cmd_addchan, "Joins " HELPMOD_NICK " to a new channel");
3629 hcommand_add("delchan", H_ADMIN, helpmod_cmd_delchan, "Removes " HELPMOD_NICK " permanently from a channel");
3630
3631 hcommand_add("seen", H_STAFF, helpmod_cmd_seen, "Tells when a specific user/account has had activity");
3632 hcommand_add("op", H_STAFF, helpmod_cmd_op, "Sets mode +o on channels");
3633 hcommand_add("deop", H_STAFF, helpmod_cmd_deop, "Sets mode -o on channels");
3634 hcommand_add("voice", H_TRIAL, helpmod_cmd_voice, "Sets mode +v on channels");
3635 hcommand_add("devoice", H_TRIAL, helpmod_cmd_devoice, "Sets mode -v on channels");
3636
3637 hcommand_add("invite", H_PEON, helpmod_cmd_invite, "Invites you to a channel");
3638 hcommand_add("ticket", H_TRIAL, helpmod_cmd_ticket, "Gives a ticket to be used with invite");
3639 hcommand_add("resolve", H_STAFF, helpmod_cmd_resolve, "Resolves (deletes) a ticket");
3640 hcommand_add("tickets", H_STAFF, helpmod_cmd_tickets, "Lists all valid tickets for a channel");
3641 hcommand_add("showticket", H_STAFF, helpmod_cmd_showticket, "Shows the ticket for the user");
3642
3643 hcommand_add("termstats", H_OPER, helpmod_cmd_termstats, "Lists usage statistics for terms");
3644 hcommand_add("checkchannel", H_STAFF, helpmod_cmd_checkchannel, "Shows channel information for any channel");
3645 hcommand_add("message", H_TRIAL, helpmod_cmd_message, "Sends a message to a channel");
3646 hcommand_add("version", H_PEON, helpmod_cmd_version, "G version information");
3647 hcommand_add("ticketmsg", H_STAFF, helpmod_cmd_ticketmsg, "Handle the ticket message for a channel");
3648
3649 hcommand_add("lcedit", H_ADMIN, helpmod_cmd_lcedit, "Lamer control profile manager");
3650 hcommand_add("ged", H_STAFF, helpmod_cmd_ged, "Ged IRC text editor");
3651 hcommand_add("text", H_PEON, helpmod_cmd_text, "Lists or shows text files");
3652 hcommand_add("evilhack1", H_ADMIN, helpmod_cmd_evilhack1, "An evil hack, don't use");
3653 hcommand_add("evilhack2", H_ADMIN, helpmod_cmd_evilhack2, "Another evil hack, don't use");
3654
3655 hcommand_add("statsdump", H_ADMIN, helpmod_cmd_statsdump, "Statistics dump command");
3656 hcommand_add("statsrepair", H_ADMIN, helpmod_cmd_statsrepair, "Statistics repair command");
3657 hcommand_add("statsreset", H_ADMIN, helpmod_cmd_statsreset, "Statistics reset command");
3658 hcommand_add("rating", H_TRIAL, helpmod_cmd_rating, "Simple rating for the current week");
3659 hcommand_add("writedb", H_OPER, helpmod_cmd_writedb, "Writes the " HELPMOD_NICK " database to disk");
3660
3661 /*hcommand_add("megod", H_PEON, helpmod_cmd_megod, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
3662 /*hcommand_add("test", H_PEON, helpmod_cmd_test, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
3663 }
3664
3665 void helpmod_command(huser *sender, channel* returntype, char *args)
3666 {
3667 int argc = 0, useless_var;
3668 char args_copy[512];
3669 char *parsed_args[H_CMD_MAX_ARGS + 3], *ptr = args_copy;
3670
3671 /* only accept commands from valid sources */
3672 if (huser_get_level(sender) > H_ADMIN)
3673 return;
3674
3675 if (returntype && !strncmp(args, helpmodnick->nick, strlen(helpmodnick->nick)))
3676 {
3677 if (!args[1])
3678 return;
3679 else
3680 args+=strlen(helpmodnick->nick)+1;
3681 }
3682
3683 if (*args == '-' || *args == '?')
3684 args++;
3685
3686 strcpy(args_copy, args);
3687 /* FIX stringituki */
3688 while (argc < 10)
3689 {
3690 while (isspace(*ptr) && *ptr)
3691 ptr++;
3692
3693 if (*ptr == '\0')
3694 break;
3695
3696 if (*ptr == '"' && strchr(ptr+1, '"'))
3697 { /* string support */
3698 parsed_args[argc++] = ptr+1;
3699 ptr = strchr(ptr+1, '"');
3700
3701 *(ptr++) = '\0';
3702
3703 while (!isspace(*ptr) && *ptr)
3704 ptr++;
3705
3706 if (*ptr == '\0')
3707 break;
3708 }
3709 else
3710 {
3711 parsed_args[argc++] = ptr;
3712
3713 while (!isspace(*ptr) && *ptr)
3714 ptr++;
3715
3716 if (*ptr == '\0')
3717 break;
3718
3719 *(ptr++) = '\0';
3720 }
3721 }
3722
3723 if (!argc)
3724 return;
3725
3726 /* old H compatibility */
3727 if (sscanf(parsed_args[0], "%d", &useless_var) && returntype == NULL)
3728 {
3729 helpmod_cmd_help(sender, NULL, parsed_args[0], 1, NULL);
3730 return;
3731 }
3732
3733 {
3734 char *ostr = args, **argv = (char**)&parsed_args;
3735 hcommand *hcom = hcommand_get(parsed_args[0], huser_get_level(sender));
3736
3737 if (hcom == NULL)
3738 {
3739 if ((returntype == NULL) ||
3740 (sender->account != NULL && !(sender->account->flags & H_NO_CMD_ERROR)))
3741 helpmod_reply(sender, returntype, "Unknown command '%s', please see showcommands for a list of all commands available to you", parsed_args[0]);
3742 }
3743 else
3744 {
3745 SKIP_WORD;
3746 hcom->function(sender, returntype, ostr, argc, argv);
3747 }
3748 }
3749 }
3750
3751 #undef SKIP_WORD
3752 #undef DEFINE_HCHANNEL
3753 #undef HCHANNEL_VERIFY_AUTHORITY