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