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