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