]> jfr.im git - irc/quakenet/newserv.git/blob - helpmod2/hcommands.c
2.09
[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 /*
1181 if (!hchannels_on_queue(husr) && !hchannels_on_desk(husr))
1182 {
1183 helpmod_reply(sender, returntype, "Can not correct the luser: User %s is not in any queue", argv[i]);
1184 continue;
1185 }
1186 */
1187 hchannels_dnmo(husr);
1188
1189 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");
1190 helpmod_reply(sender, returntype, "User %s has been informed of his mistake", argv[i]);
1191 }
1192 { /* fix the autoqueue for the channel(s) */
1193 hchannel *hchan;
1194 for (hchan = hchannels;hchan;hchan = hchan->next)
1195 hqueue_handle_queue(hchan, sender);
1196 }
1197 }
1198
1199 static void helpmod_cmd_ban (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1200 {
1201 if (argc == 0)
1202 {
1203 helpmod_reply(sender, returntype, "Can not global handle bans: Operation not defined");
1204 return;
1205 }
1206
1207 else if (!ci_strcmp(argv[0], "list"))
1208 {
1209 hban *ptr = hbans;
1210 char *pattern;
1211 int count = 0;
1212
1213 if (argc == 1)
1214 pattern = "*";
1215 else
1216 pattern = argv[1];
1217
1218 helpmod_reply(sender, returntype, "Global bans matching pattern %s", pattern);
1219
1220 for (;ptr;ptr = ptr->next)
1221 if (strregexp(bantostring(ptr->real_ban), pattern))
1222 {
1223 helpmod_reply(sender, returntype, "%-64s %-15s %s", bantostring(ptr->real_ban), helpmod_strtime(ptr->expiration - time(NULL)), ptr->reason?ptr->reason->content:"");
1224 count++;
1225 }
1226
1227 helpmod_reply(sender, returntype, "%d Global bans match pattern %s", count, pattern);
1228 }
1229
1230 else if (!ci_strcmp(argv[0], "add"))
1231 {
1232 int duration = 4 * HDEF_h;
1233 char *reason = "Banned";
1234 char *target = argv[1];
1235
1236 if (argc == 1)
1237 {
1238 helpmod_reply(sender, returntype, "Can not add global ban: Target hostmask not defined");
1239 return;
1240 }
1241 if (argc >= 3)
1242 {
1243 if ((duration = helpmod_read_strtime(argv[2])) < 0)
1244 {
1245 helpmod_reply(sender, returntype, "Can not add global ban: Invalid time %s", argv[2]);
1246 return;
1247 }
1248 }
1249 if (argc >= 4)
1250 {
1251 SKIP_WORD;
1252 SKIP_WORD;
1253 SKIP_WORD;
1254
1255 reason = ostr;
1256 }
1257 hban_add(target, reason, time(NULL) + duration, 0);
1258 helpmod_reply(sender, returntype, "Added ban for %s (%s), expires in %s", target, reason, helpmod_strtime(duration));
1259 }
1260 else if (!ci_strcmp(argv[0], "del"))
1261 {
1262 int i;
1263 if (argc == 1)
1264 {
1265 helpmod_reply(sender, returntype, "Can not remove global ban: Target hostmask not defined");
1266 return;
1267 }
1268 if (argc > H_CMD_MAX_ARGS)
1269 argc = H_CMD_MAX_ARGS;
1270 for (i=1;i<argc;i++)
1271 {
1272 hban *ptr = hban_get(argv[i]);
1273 if (ptr == NULL)
1274 {
1275 helpmod_reply(sender, returntype, "Can not remove global ban: Hostmask %s is not banned", argv[i]);
1276 continue;
1277 }
1278 helpmod_reply(sender, returntype, "Global ban for hostmask %s removed", argv[i]);
1279 hban_del(ptr,0);
1280 }
1281 }
1282 else
1283 {
1284 helpmod_reply(sender, returntype, "Can not handle global bans: Unknown operation %s", argv[0]);
1285 return;
1286 }
1287 }
1288
1289 static void helpmod_cmd_chanban (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1290 {
1291 hchannel *hchan;
1292 int i;
1293
1294 DEFINE_HCHANNEL;
1295
1296 if (hchan == NULL)
1297 {
1298 helpmod_reply(sender, returntype, "Can not handle channel bans: Channel not defined or not found");
1299 return;
1300 }
1301
1302 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1303
1304 if (argc == 0)
1305 {
1306 helpmod_reply(sender, returntype, "Can not handle channel bans: Operation not defined");
1307 return;
1308 }
1309
1310 if (!ci_strcmp(argv[0], "list"))
1311 {
1312 char *pattern, *cban;
1313 chanban *ptr = hchan->real_channel->bans;
1314 int count = 0;
1315
1316 if (argc == 1)
1317 pattern = "*";
1318 else
1319 pattern = argv[1];
1320
1321 helpmod_reply(sender, returntype, "Bans matching pattern %s for channel %s", pattern, hchannel_get_name(hchan));
1322 for (;ptr;ptr = ptr->next)
1323 if (strregexp((cban = bantostring(ptr)), pattern))
1324 {
1325 count++;
1326 if (hchanban_get(hchan,cban))
1327 helpmod_reply(sender, returntype, "%s Expires in %s", bantostring(ptr), helpmod_strtime(hchanban_get(hchan, cban)->expiration - time(NULL)));
1328 else
1329 helpmod_reply(sender, returntype, "%s", bantostring(ptr));
1330 }
1331 helpmod_reply(sender, returntype, "%d bans match pattern %s on channel %s", count, pattern, hchannel_get_name(hchan));
1332 }
1333 else if (!ci_strcmp(argv[0], "add"))
1334 {
1335 if (argc == 1)
1336 {
1337 helpmod_reply(sender, returntype, "Can not add channel bans: Pattern not defined");
1338 return;
1339 }
1340 if (argc > H_CMD_MAX_ARGS)
1341 argc = H_CMD_MAX_ARGS;
1342 for (i=1;i<argc;i++)
1343 {
1344 /* POSSIBLE BUG ? */
1345 helpmod_setban(hchan, argv[i], H_ETERNITY, MCB_ADD, HLAZY);
1346 helpmod_reply(sender, returntype, "Added ban %s to channel %s", argv[i], hchannel_get_name(hchan));
1347 }
1348 }
1349 else if (!ci_strcmp(argv[0], "del"))
1350 {
1351 if (argc == 1)
1352 {
1353 helpmod_reply(sender, returntype, "Can not remove channel bans: Pattern not defined");
1354 return;
1355 }
1356 if (argc > H_CMD_MAX_ARGS)
1357 argc = H_CMD_MAX_ARGS;
1358 for (i=1;i<argc;i++)
1359 {
1360 chanban *ptr = hchan->real_channel->bans;
1361 for (;ptr;ptr = ptr->next)
1362 if (strregexp(bantostring(ptr), argv[i]))
1363 {
1364 helpmod_setban(hchan, argv[i], 0, MCB_DEL, HLAZY);
1365 helpmod_reply(sender, returntype, "Channel ban %s removed from channel %s", argv[i], hchannel_get_name(hchan));
1366 break;
1367 }
1368 if (ptr == NULL)
1369 helpmod_reply(sender, returntype, "Can not remove channel ban: Pattern %s not banned on channel %s", argv[i], hchannel_get_name(hchan));
1370 }
1371 }
1372 else
1373 {
1374 helpmod_reply(sender, returntype, "Can not handle channel bans: Unknown operation %s", argv[0]);
1375 return;
1376 }
1377 }
1378
1379 static void helpmod_cmd_idlekick (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1380 {
1381 hchannel *hchan;
1382 int tmp;
1383
1384 DEFINE_HCHANNEL;
1385
1386 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1387
1388 if (hchan == NULL)
1389 {
1390 helpmod_reply(sender, returntype, "Can not handle the idlekick: Channel not defined or not found");
1391 return;
1392 }
1393 if (argc == 0) /* view */
1394 {
1395 helpmod_reply(sender, returntype, "Idlekick for channel %s is set to %s", hchannel_get_name(hchan), helpmod_strtime(hchan->max_idle));
1396 return;
1397 }
1398 else if ((tmp = helpmod_read_strtime(argv[0])) < 0 || tmp < HDEF_m || tmp > HDEF_w)
1399 {
1400 helpmod_reply(sender, returntype, "Can not set the idlekick: Invalid time given '%s'", argv[0]);
1401 return;
1402 }
1403 else /* set it ! */
1404 {
1405 hchan->max_idle = tmp;
1406 helpmod_reply(sender, returntype, "Idlekick for channel %s set to %s succesfully", hchannel_get_name(hchan), helpmod_strtime(hchan->max_idle));
1407 }
1408 }
1409
1410 static void helpmod_cmd_topic (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1411 {
1412 hchannel *hchan;
1413 DEFINE_HCHANNEL;
1414
1415 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1416
1417 if (hchan == NULL)
1418 {
1419 helpmod_reply(sender, returntype, "Can not handle the topic: Channel not defined or not found");
1420 return;
1421 }
1422 if (!(hchan -> flags & H_HANDLE_TOPIC))
1423 helpmod_reply(sender, returntype, "Note: I'm not set to handle the topic on channel %s", hchannel_get_name(hchan));
1424
1425 if (argc == 0) /* check the topic */
1426 {
1427 helpmod_reply(sender, returntype, "Topic of channel %s is currently: %s", hchannel_get_name(hchan), htopic_construct(hchan->topic));
1428 return;
1429 }
1430 if (!ci_strcmp(argv[0], "erase"))
1431 {
1432 htopic_del_all(&hchan->topic);
1433 hchannel_set_topic(hchan);
1434 helpmod_reply(sender, returntype, "Topic of channel %s erased", hchannel_get_name(hchan));
1435 }
1436 else if (!ci_strcmp(argv[0], "refresh"))
1437 {
1438 hchannel_set_topic(hchan);
1439 helpmod_reply(sender, returntype, "Topic of channel %s refreshed", hchannel_get_name(hchan));
1440 }
1441 else if (!ci_strcmp(argv[0], "add"))
1442 {
1443 int pos;
1444 SKIP_WORD;
1445 if (argc == 0)
1446 {
1447 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1448 return;
1449 }
1450 if (sscanf(argv[0], "%d", &pos) && pos >= 0)
1451 {
1452 SKIP_WORD;
1453 }
1454 else
1455 pos = 0;
1456 if (argc == 0) /* lame repeat :( */
1457 {
1458 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1459 return;
1460 }
1461 if (htopic_len(hchan->topic) + strlen(ostr) + 3 > TOPICLEN)
1462 {
1463 helpmod_reply(sender, returntype, "Cannot add to the topic of channel %s: Maximum topic length exceeded", hchannel_get_name(hchan));
1464 return;
1465 }
1466
1467 htopic_add(&hchan->topic, ostr, pos);
1468 hchannel_set_topic(hchan);
1469 helpmod_reply(sender, returntype, "Added '%s' to the topic of channel %s", ostr, hchannel_get_name(hchan));
1470 }
1471 else if (!ci_strcmp(argv[0], "del"))
1472 {
1473 int pos;
1474 if (argc == 1)
1475 {
1476 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1477 return;
1478 }
1479 SKIP_WORD;
1480 if (!sscanf(argv[0], "%d", &pos) || pos < 0)
1481 {
1482 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Expected positive integer", hchannel_get_name(hchan));
1483 return;
1484 }
1485 if (htopic_count(hchan->topic) < pos)
1486 {
1487 helpmod_reply(sender, returntype, "Cannot delete from the topic of channel %s: No such topic element %d", hchannel_get_name(hchan), pos);
1488 return;
1489 }
1490 htopic_del(&hchan->topic, htopic_get(hchan->topic, pos));
1491 hchannel_set_topic(hchan);
1492 }
1493 else if (!ci_strcmp(argv[0], "set"))
1494 {
1495 if (argc == 1)
1496 {
1497 helpmod_reply(sender, returntype, "Cannot handle the topic of channel %s: Additional arguments required", hchannel_get_name(hchan));
1498 return;
1499 }
1500 SKIP_WORD;
1501 htopic_del_all(&hchan->topic);
1502 htopic_add(&hchan->topic, ostr, 0);
1503 hchannel_set_topic(hchan);
1504 }
1505 else
1506 helpmod_reply(sender, returntype, "Can not handle the topic of channel %s: Unknown operation %s", hchannel_get_name(hchan), argv[0]);
1507 }
1508
1509 static void helpmod_cmd_out (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1510 {
1511 huser *husr;
1512 int i;
1513 char *reason = "Banned";
1514 huser *targets[H_CMD_MAX_ARGS];
1515 int ntargets = 0;
1516
1517 if (argc == 0)
1518 {
1519 helpmod_reply(sender, returntype, "Can not get rid of the user: User not specified");
1520 return;
1521 }
1522
1523 if (argc > H_CMD_MAX_ARGS)
1524 argc = H_CMD_MAX_ARGS;
1525 for (i=0;i<argc;i++)
1526 {
1527 if (argv[i][0] == ':')
1528 {
1529 if (i == 0)
1530 {
1531 helpmod_reply(sender, returntype, "Can not get rid of users: No users specified");
1532 return;
1533 }
1534 while (i--)
1535 {
1536 SKIP_WORD;
1537 }
1538 reason = ostr + 1;
1539 break;
1540 }
1541
1542 husr = huser_get(getnickbynick(argv[i]));
1543 if (husr == NULL)
1544 {
1545 helpmod_reply(sender, returntype, "Can not get rid of the user: User %s not found", argv[i]);
1546 continue;
1547 }
1548 if (huser_get_level(husr) > H_PEON)
1549 {
1550 helpmod_reply(sender, returntype, "Can not get rid of the user: User %s is not a peon", husr->real_user->nick);
1551 continue;
1552 }
1553 targets[ntargets++] = husr;
1554 }
1555
1556 for (i=0;i<ntargets;i++)
1557 {
1558 const char *banmask = hban_ban_string(targets[i]->real_user, HBAN_HOST);
1559
1560 hban_add(banmask, reason, time(NULL) + HCMD_OUT_DEFAULT, 0);
1561
1562 helpmod_reply(sender, returntype, "User %s is now gone", targets[i]->real_user->nick);
1563 }
1564 }
1565
1566 static void helpmod_cmd_everyoneout (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1567 {
1568 hchannel *hchan;
1569 hchannel_user **hchanuser;
1570 char *reason = "clearing channel";
1571 int autoqueue_tmp = -1;
1572
1573 DEFINE_HCHANNEL;
1574
1575 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1576
1577 if (hchan == NULL)
1578 {
1579 helpmod_reply(sender, returntype, "Can not clear channel: Channel not defined or not found");
1580 return;
1581 }
1582
1583 if (argc)
1584 reason = ostr;
1585
1586 hchan->flags |= H_MAINTAIN_I;
1587 hchannel_mode_check(hchan);
1588
1589 hchanuser = &hchan->channel_users;
1590
1591 if ((hchan->flags & H_QUEUE) && (hchan->flags & H_QUEUE_MAINTAIN))
1592 {
1593 autoqueue_tmp = hchan->autoqueue;
1594 hchan->autoqueue = 0;
1595 }
1596
1597 while (*hchanuser)
1598 {
1599 if (huser_get_level((*hchanuser)->husr) < H_TRIAL)
1600 helpmod_kick(hchan, (*hchanuser)->husr, reason);
1601 else
1602 hchanuser = &(*hchanuser)->next;
1603 }
1604
1605 if (autoqueue_tmp > 0)
1606 hchan->autoqueue = autoqueue_tmp;
1607
1608 helpmod_reply(sender, returntype, "Channel %s has been cleared of normal users", hchannel_get_name(hchan));
1609 }
1610
1611 static void helpmod_cmd_kick (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1612 {
1613 hchannel *hchan;
1614 int i;
1615 huser *husr, *targets[H_CMD_MAX_ARGS];
1616 int ntargets = 0;
1617 char *reason = "out";
1618 DEFINE_HCHANNEL;
1619
1620 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1621
1622 if (hchan == NULL)
1623 {
1624 helpmod_reply(sender, returntype, "Can not kick the user: Channel not defined or not found");
1625 return;
1626 }
1627
1628 if (argc == 0)
1629 {
1630 helpmod_reply(sender, returntype, "Can not kick users: No users specified");
1631 return;
1632 }
1633
1634 if (argc > H_CMD_MAX_ARGS)
1635 argc = H_CMD_MAX_ARGS;
1636 for (i=0;i<argc;i++)
1637 {
1638 if (*argv[i] == ':')
1639 {
1640 if (i == 0)
1641 {
1642 helpmod_reply(sender, returntype, "Can not kick the user: No users defined");
1643 return;
1644 }
1645 while (i--)
1646 {
1647 SKIP_WORD;
1648 }
1649 reason = ostr+1;
1650 break;
1651 }
1652 husr = huser_get(getnickbynick(argv[i]));
1653 if (husr == NULL)
1654 {
1655 helpmod_reply(sender, returntype, "Can not kick the user: User %s not found", argv[i]);
1656 continue;
1657 }
1658 if (huser_on_channel(husr, hchan) == NULL)
1659 {
1660 helpmod_reply(sender, returntype, "Can not kick the user: User %s is not on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
1661 continue;
1662 }
1663 if (huser_get_level(husr) > H_PEON)
1664 {
1665 helpmod_reply(sender, returntype, "Can not kick the user: User %s is not a peon", husr->real_user->nick);
1666 continue;
1667 }
1668 targets[ntargets++] = husr;
1669 }
1670
1671 for (i=0;i<ntargets;i++)
1672 helpmod_kick(hchan, targets[i], reason);
1673 }
1674
1675 static void helpmod_cmd_stats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1676 {
1677 hchannel *hchan;
1678 haccount *target = sender->account;
1679 hstat_account *ptr;
1680 hstat_account_entry *stat_entry;
1681 int days = 1, weeks = 0;
1682 int type = HSTAT_ACCOUNT_SHORT;
1683
1684 time_t timer = time(NULL);
1685 struct tm *tstruct = localtime(&timer);
1686
1687 int i = 0;
1688
1689 DEFINE_HCHANNEL;
1690
1691 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1692
1693 if (hchan == NULL)
1694 {
1695 helpmod_reply(sender, returntype, "Can not show user statistics: Channel not defined or not found");
1696 return;
1697 }
1698
1699 if (argc > 0 && huser_get_level(sender) == H_ADMIN)
1700 { /* not very elegant */
1701 if (argv[0][0] == '#') /* account */
1702 {
1703 target = haccount_get_by_name(argv[0]+1);
1704 if (target == NULL)
1705 {
1706 helpmod_reply(sender, returntype, "Can not show user statistics: Account %s not found", argv[0]);
1707 return;
1708 }
1709 SKIP_WORD;
1710 }
1711 }
1712
1713 if (target == NULL)
1714 {
1715 helpmod_reply(sender, returntype, "Can not show user statistics: You do not have an account");
1716 return;
1717 }
1718
1719 if (argc > 0)
1720 {
1721 if (!ci_strcmp(argv[0], "short") || !ci_strcmp(argv[0], "s"))
1722 {
1723 type = HSTAT_ACCOUNT_SHORT;
1724 SKIP_WORD;
1725 }
1726 else if (!ci_strcmp(argv[0], "long") || !ci_strcmp(argv[0], "l"))
1727 {
1728 type = HSTAT_ACCOUNT_LONG;
1729 SKIP_WORD;
1730 }
1731 }
1732
1733 if (argc > 0)
1734 if (sscanf(argv[0], "%d", &days))
1735 {
1736 if (days < 0 || days > 7)
1737 {
1738 helpmod_reply(sender, returntype, "Can not show user statistics: Expected integer between [0, 7]");
1739 return;
1740 }
1741 else
1742 {
1743 SKIP_WORD;
1744 }
1745 }
1746
1747 if (argc > 0)
1748 if (sscanf(argv[0], "%d", &weeks))
1749 {
1750 if (weeks < 0 || weeks > 10)
1751 {
1752 helpmod_reply(sender, returntype, "Can not show user statistics: Expected integer between [0, 10]");
1753 return;
1754 }
1755 else
1756 {
1757 SKIP_WORD;
1758 }
1759 }
1760
1761 for (ptr = target->stats;ptr;ptr = ptr->next)
1762 if (ptr->hchan == hchan)
1763 break;
1764
1765 if (ptr == NULL)
1766 {
1767 helpmod_reply(sender, returntype, "Can not show user statistics: User %s has no statistics for channel %s", target->name->content, hchannel_get_name(hchan));
1768 return;
1769 }
1770
1771 if (!days && !weeks)
1772 return;
1773
1774 helpmod_reply(sender, returntype, "Statistics for user %s on channel %s", target->name->content, hchannel_get_name(hchan));
1775
1776 if (days)
1777 {
1778 helpmod_reply(sender, returntype, "Last %d day%s", days, (days==1)?"":"s");
1779 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1780 for (i=0;i<days;i++)
1781 {
1782 stat_entry = &ptr->week[(tstruct->tm_wday - i + 7) % 7];
1783 helpmod_reply(sender, returntype, "%s", hstat_account_print(stat_entry, type));
1784 }
1785 }
1786
1787 if (weeks)
1788 {
1789 helpmod_reply(sender, returntype, "Last %d week%s", weeks, (weeks==1)?"":"s");
1790 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1791 for (i=0;i<weeks;i++)
1792 {
1793 stat_entry = &ptr->longterm[(hstat_week() - i + 10) % 10];
1794 helpmod_reply(sender, returntype, "%s", hstat_account_print(stat_entry, type));
1795 }
1796 }
1797 }
1798
1799 static void helpmod_cmd_chanstats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1800 {
1801 hchannel *hchan;
1802 hstat_channel *channel_stats;
1803 hstat_channel_entry *stat_entry;
1804
1805 time_t timer = time(NULL);
1806 struct tm *tstruct = localtime(&timer);
1807
1808 int days=1;
1809 int type = HSTAT_CHANNEL_SHORT;
1810 int weeks=0;
1811
1812 int i = 7;
1813
1814 DEFINE_HCHANNEL;
1815
1816 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1817
1818 if (hchan == NULL)
1819 {
1820 helpmod_reply(sender, returntype, "Can not show channel statistics: Channel not defined or not found");
1821 return;
1822 }
1823
1824 if (argc > 0)
1825 {
1826 if (!ci_strcmp(argv[0], "short") || !ci_strcmp(argv[0], "s"))
1827 {
1828 type = HSTAT_CHANNEL_SHORT;
1829 SKIP_WORD;
1830 }
1831 else if (!ci_strcmp(argv[0], "long") || !ci_strcmp(argv[0], "l"))
1832 {
1833 type = HSTAT_CHANNEL_LONG;
1834 SKIP_WORD;
1835 }
1836 }
1837
1838 if (argc > 0)
1839 if (sscanf(argv[0], "%d", &days))
1840 {
1841 if (days < 0 || days > 7)
1842 {
1843 helpmod_reply(sender, returntype, "Can not show channel statistics: Expected integer between [0, 7]");
1844 return;
1845 }
1846 else
1847 {
1848 SKIP_WORD;
1849 }
1850 }
1851
1852 if (argc > 0)
1853 if (sscanf(argv[0], "%d", &weeks))
1854 {
1855 if (weeks < 0 || weeks > 10)
1856 {
1857 helpmod_reply(sender, returntype, "Can not show channel statistics: Expected integer between [0, 10]");
1858 return;
1859 }
1860 else
1861 {
1862 SKIP_WORD;
1863 }
1864 }
1865
1866
1867 channel_stats = hchan->stats;
1868
1869 if (!days && !weeks)
1870 return;
1871
1872 helpmod_reply(sender, returntype, "Statistics for channel %s", hchannel_get_name(hchan));
1873
1874 if (days)
1875 {
1876 helpmod_reply(sender, returntype, "Last %d day%s", days, (days==1)?"":"s");
1877 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1878 for (i=0;i<days;i++) /* latest week */
1879 {
1880 stat_entry = &hchan->stats->week[(tstruct->tm_wday - i + 7) % 7];
1881 helpmod_reply(sender, returntype, "%s", hstat_channel_print(stat_entry, type));
1882 }
1883 }
1884
1885 if (weeks)
1886 {
1887 helpmod_reply(sender, returntype, "Last %d week%s", weeks, (weeks==1)?"":"s");
1888 helpmod_reply(sender, returntype, "%s", hstat_header(type));
1889 for (i=0;i<weeks;i++) /* latest weeks */
1890 {
1891 stat_entry = &hchan->stats->longterm[(hstat_week() - i + 10) % 10];
1892 helpmod_reply(sender, returntype, "%s", hstat_channel_print(stat_entry, type));
1893 }
1894 }
1895 }
1896
1897 static void helpmod_cmd_activestaff (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1898 {
1899 hchannel *hchan;
1900 hstat_accounts_array arr;
1901 hlevel lvl = H_OPER;
1902 int listtype = 0;
1903 int i;
1904
1905 DEFINE_HCHANNEL;
1906
1907 if (hchan == NULL)
1908 {
1909 helpmod_reply(sender, returntype, "Can not list active staff: Channel not specified or not found");
1910 return;
1911 }
1912
1913 if (argc == 1)
1914 {
1915 if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
1916 {
1917 lvl = H_OPER;
1918 SKIP_WORD;
1919 }
1920 else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
1921 {
1922 lvl = H_STAFF;
1923 SKIP_WORD;
1924 }
1925 }
1926
1927 if (argc == 1)
1928 {
1929 if (!ci_strcmp(argv[0], "active") || !ci_strcmp(argv[0], "a"))
1930 {
1931 listtype = 0;
1932 SKIP_WORD;
1933 }
1934 else if (!ci_strcmp(argv[0], "inactive") || !ci_strcmp(argv[0], "i"))
1935 {
1936 listtype = 1;
1937 SKIP_WORD;
1938 }
1939 }
1940
1941 arr = create_hstat_account_array(hchan, lvl);
1942
1943 helpmod_reply(sender, returntype, "%s %ss for channel %s", listtype?"Inactive":"Active", hlevel_name(lvl), hchannel_get_name(hchan));
1944 switch (listtype)
1945 {
1946 case 0:
1947 for (i=0;i < arr.arrlen && arr.array[i].prime_time_spent > H_ACTIVE_LIMIT;i++)
1948 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));
1949 break;
1950 case 1:
1951 for (i=arr.arrlen-1;i >= 0 && arr.array[i].prime_time_spent < H_ACTIVE_LIMIT;i--)
1952 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));
1953 break;
1954 }
1955
1956 free(arr.array);
1957 }
1958
1959 static void helpmod_cmd_top10 (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
1960 {
1961 hchannel *hchan;
1962 hstat_accounts_array arr;
1963 hlevel lvl = H_OPER;
1964 int i, top_n = 10;
1965
1966 DEFINE_HCHANNEL;
1967
1968 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
1969
1970 if (hchan == NULL)
1971 {
1972 helpmod_reply(sender, returntype, "Can not list channel Top10: Channel not specified or not found");
1973 return;
1974 }
1975
1976 if (argc >= 1)
1977 {
1978 if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
1979 lvl = H_OPER;
1980 else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
1981 lvl = H_STAFF;
1982 }
1983 if (argc == 3)
1984 {
1985 int tmp;
1986 if (sscanf(argv[1], "%d", &tmp) && (tmp >= 10) && (tmp <= 50))
1987 top_n = tmp;
1988 }
1989
1990 arr = create_hstat_account_array(hchan, lvl);
1991
1992 helpmod_reply(sender, returntype, "Top%d most active %ss of channel %s", top_n, hlevel_name(lvl), hchannel_get_name(hchan));
1993 for (i=0;i < arr.arrlen && i < top_n;i++)
1994 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));
1995
1996 free(arr.array);
1997 }
1998
1999 static void helpmod_cmd_report (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2000 {
2001 hchannel *hchan, *target;
2002 DEFINE_HCHANNEL;
2003
2004 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2005
2006 if (hchan != NULL && (argc == 2))
2007 {
2008 hchan = hchannel_get_by_name(argv[0]);
2009 SKIP_WORD;
2010 }
2011
2012 if (hchan == NULL)
2013 {
2014 helpmod_reply(sender, returntype, "Can not view or set channel reporting: Channel not defined or not found");
2015 return;
2016 }
2017 if (argc != 1)
2018 {
2019 if (hchan->report_to == NULL || !hchannel_is_valid(hchan->report_to))
2020 helpmod_reply(sender, returntype, "Channel %s is not reported anywhere (%s)", hchannel_get_name(hchan), hchannel_get_state(hchan, H_REPORT));
2021 else
2022 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));
2023 return;
2024 }
2025 if ((target = hchannel_get_by_name(argv[0])) == NULL)
2026 {
2027 helpmod_reply(sender, returntype, "Can not set channel reporting: Channel %s not found", argv[0]);
2028 return;
2029 }
2030 hchan->report_to = target;
2031 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));
2032 }
2033
2034 static void helpmod_cmd_mode(huser *sender, channel* returntype, int change, char* ostr, int argc, char *argv[])
2035 {
2036 hchannel *hchan;
2037 huser_channel *huserchan;
2038 huser *husr;
2039 int i;
2040
2041 DEFINE_HCHANNEL;
2042
2043 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2044
2045 if (hchan == NULL)
2046 {
2047 helpmod_reply(sender, returntype, "Can not change mode: Channel not specified or not found");
2048 return;
2049 }
2050
2051 if (argc==0) /* for a simple opme */
2052 {
2053 argc = 1;
2054 argv[0] = sender->real_user->nick;
2055 }
2056
2057 if (argc > H_CMD_MAX_ARGS)
2058 argc = H_CMD_MAX_ARGS;
2059
2060 for (i=0;i<argc;i++)
2061 {
2062 husr = huser_get(getnickbynick(argv[i]));
2063 if (husr == NULL)
2064 {
2065 helpmod_reply(sender, returntype, "Can not change mode: User %s not found", argv[i], hchannel_get_name(hchan));
2066 continue;
2067 }
2068 huserchan = huser_on_channel(husr, hchan);
2069 if (huserchan == NULL)
2070 {
2071 helpmod_reply(sender, returntype, "Can not change mode: User %s it not on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
2072 continue;
2073 }
2074
2075 switch (change)
2076 {
2077 case H_CMD_OP:
2078 {
2079 int j;
2080 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2081 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2082 break;
2083 if ((huserchan->flags & HCUMODE_OP) && !(hchan->real_channel->users->content[j] & CUMODE_OP))
2084 {
2085 huserchan->flags &= ~HCUMODE_OP;
2086 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (+o when should be -o)");
2087 }
2088 if (huserchan->flags & HCUMODE_OP)
2089 {
2090 helpmod_reply(sender, returntype, "Can not change mode: User %s is already +o on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
2091 continue;
2092 }
2093 if (huser_get_level(husr) < H_STAFF)
2094 {
2095 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));
2096 continue;
2097 }
2098 helpmod_channick_modes(husr, hchan, MC_OP, HLAZY);
2099 }
2100 break;
2101 case H_CMD_DEOP:
2102 {
2103 int j;
2104 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2105 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2106 break;
2107 if (!(huserchan->flags & HCUMODE_OP) && (hchan->real_channel->users->content[j] & CUMODE_OP))
2108 {
2109 huserchan->flags |= HCUMODE_OP;
2110 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (-o when should be +o)");
2111 }
2112 if (!(huserchan->flags & HCUMODE_OP))
2113 {
2114 helpmod_reply(sender, returntype, "Can not change mode: User %s is already -o on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
2115 continue;
2116 }
2117 if (huser_get_level(husr) > huser_get_level(sender))
2118 {
2119 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));
2120 continue;
2121 }
2122 helpmod_channick_modes(husr, hchan, MC_DEOP, HLAZY);
2123 }
2124 break;
2125 case H_CMD_VOICE:
2126 {
2127 int j;
2128 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2129 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2130 break;
2131 if ((huserchan->flags & HCUMODE_VOICE) && !(hchan->real_channel->users->content[j] & CUMODE_VOICE))
2132 {
2133 huserchan->flags &= ~HCUMODE_VOICE;
2134 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (+v when should be -v)");
2135 }
2136 if (huserchan->flags & HCUMODE_VOICE)
2137 {
2138 helpmod_reply(sender, returntype, "Can not change mode: User %s is already -v on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
2139 continue;
2140 }
2141 helpmod_channick_modes(husr, hchan, MC_VOICE, HLAZY);
2142 }
2143 break;
2144 case H_CMD_DEVOICE:
2145 {
2146 int j;
2147 for (j=0;j < hchan->real_channel->users->hashsize;j++)
2148 if (getnickbynumeric(hchan->real_channel->users->content[j]) == husr->real_user)
2149 break;
2150 if (!(huserchan->flags & HCUMODE_VOICE) && (hchan->real_channel->users->content[j] & CUMODE_VOICE))
2151 {
2152 huserchan->flags |= HCUMODE_VOICE;
2153 Error("helpmod", ERR_ERROR, "userchannelmode inconsistency (-v when should be +v)");
2154 }
2155 if (!(huserchan->flags & HCUMODE_VOICE))
2156 {
2157 helpmod_reply(sender, returntype, "Can not change mode: User %s is already -v on channel %s", husr->real_user->nick, hchannel_get_name(hchan));
2158 continue;
2159 }
2160 helpmod_channick_modes(husr, hchan, MC_DEVOICE, HLAZY);
2161 }
2162 break;
2163 }
2164 }
2165 }
2166
2167 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); }
2168 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); }
2169 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); }
2170 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); }
2171
2172 static void helpmod_cmd_invite (huser *sender, channel *returntype, char* arg, int argc, char *argv[])
2173 {
2174 hchannel *hchan;
2175 int i;
2176
2177 if (argc == 0)
2178 {
2179 helpmod_reply(sender, returntype, "Can not invite: Channel not defined or not found");
2180 return;
2181 }
2182
2183 if (huser_get_level(sender) == H_PEON)
2184 {
2185 hticket *htick;
2186 hchan = hchannel_get_by_name(argv[0]);
2187 if (hchan == NULL)
2188 {
2189 helpmod_reply(sender, returntype, "Can not invite: Unknown channel %s", argv[0]);
2190 return;
2191 }
2192 /* if tickets don't work, it's better that the user doesn't know that the channel really exists */
2193 if (!(hchan->flags & H_REQUIRE_TICKET))
2194 {
2195 helpmod_reply(sender, returntype, "Can not invite: Unknown channel %s", argv[0]);
2196 return;
2197 }
2198 htick = hticket_get(sender->real_user->authname, hchan);
2199
2200 if (htick == NULL)
2201 {
2202 helpmod_reply(sender, returntype, "Can not invite: You do not have an invite ticket for channel %s", argv[0]);
2203 return;
2204 }
2205
2206 if (nickbanned(sender->real_user, hchan->real_channel))
2207 {
2208 helpmod_reply(sender, returntype, "Can not invite: You are banned from channel %s", argv[0]);
2209 return;
2210 }
2211
2212 helpmod_invite(hchan, sender);
2213 helpmod_reply(sender, returntype, "Invited you to channel %s", hchannel_get_name(hchan));
2214 return;
2215 }
2216
2217 if (argc > H_CMD_MAX_ARGS)
2218 argc = H_CMD_MAX_ARGS;
2219
2220 for (i = 0;i < argc; i++)
2221 {
2222 hchan = hchannel_get_by_name(argv[0]);
2223 if (hchan == NULL)
2224 {
2225 helpmod_reply(sender, returntype, "Can not invite: Unknown channel %s", argv[i]);
2226 continue;
2227 }
2228 if (!(hchannel_authority(hchan, sender) || hticket_get(sender->real_user->authname, hchan)))
2229 {
2230 helpmod_reply(sender, returntype, "Sorry, channel %s is oper only", hchannel_get_name(hchan));
2231 continue;
2232 }
2233 if (huser_on_channel(sender, hchan) != NULL)
2234 {
2235 helpmod_reply(sender, returntype, "Can not invite: You are already on channel %s", hchannel_get_name(hchan));
2236 continue;
2237 }
2238 helpmod_invite(hchan, sender);
2239 helpmod_reply(sender, returntype, "Invited you to channel %s", hchannel_get_name(hchan));
2240 }
2241 }
2242
2243 static void helpmod_cmd_ticket (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2244 {
2245 int expiration = HTICKET_EXPIRATION_TIME;
2246 hchannel *hchan;
2247 huser *husr;
2248 hticket *htick;
2249
2250 if (argc < 1)
2251 {
2252 helpmod_reply(sender, returntype, "Can not issue a ticket: Channel not specified");
2253 return;
2254 }
2255
2256 hchan = hchannel_get_by_name(argv[0]);
2257 if (hchan == NULL)
2258 {
2259 helpmod_reply(sender, returntype, "Can not issue a ticket: Unknown channel %s", argv[0]);
2260 return;
2261 }
2262 if (!(hchan->flags & H_REQUIRE_TICKET))
2263 {
2264 helpmod_reply(sender, returntype, "Can not issue a ticket: Tickets are not enabled for channel %s", argv[0]);
2265 return;
2266 }
2267 if (argc < 2)
2268 {
2269 helpmod_reply(sender, returntype, "Can not issue a ticket: Target user not specified");
2270 return;
2271 }
2272
2273 husr = huser_get(getnickbynick(argv[1]));
2274 if (husr == NULL)
2275 {
2276 helpmod_reply(sender, returntype, "Can not issue a ticket: Unknown user %s", argv[1]);
2277 return;
2278 }
2279 if (!IsAccount(husr->real_user))
2280 {
2281 helpmod_reply(sender, returntype, "Can not issue a ticket: User %s is not authed", argv[1]);
2282 return;
2283 }
2284 if (huser_get_level(husr) < H_PEON)
2285 {
2286 helpmod_reply(sender, returntype, "Can not issue a ticket: User %s is considered improper and not worthy of a ticket", argv[1]);
2287 return;
2288 }
2289 if (argc >= 3)
2290 {
2291 int tmp;
2292 tmp = helpmod_read_strtime(argv[2]);
2293 if (tmp > HDEF_m && tmp < 2 * HDEF_M)
2294 expiration = tmp;
2295 }
2296
2297 htick = hticket_get(husr->real_user->authname, hchan);
2298
2299 if (htick != NULL)
2300 htick->time_expiration = time(NULL) + expiration;
2301 else
2302 hticket_add(husr->real_user->authname, time(NULL) + expiration, hchan);
2303
2304 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));
2305 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));
2306 }
2307
2308 static void helpmod_cmd_resolve (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2309 {
2310 int i;
2311 hchannel *hchan;
2312 hticket *htick;
2313 huser *husr;
2314
2315 DEFINE_HCHANNEL;
2316
2317 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2318
2319 if (argc > H_CMD_MAX_ARGS)
2320 argc = H_CMD_MAX_ARGS;
2321
2322 if (hchan == NULL)
2323 {
2324 helpmod_reply(sender, returntype, "Can not resolve a ticket: The channel is not specified");
2325 return;
2326 }
2327
2328 for (i = 0;i< argc;i++)
2329 {
2330 if (argv[i][0] == '#')
2331 {
2332 htick = hticket_get(&argv[i][1], hchan);
2333 if (htick == NULL)
2334 {
2335 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));
2336 continue;
2337 }
2338 hticket_del(htick, hchan);
2339 helpmod_reply(sender, returntype, "Resolved authname %s's ticket for channel %s", &argv[i][1], hchannel_get_name(hchan));
2340 }
2341 else
2342 {
2343 husr = huser_get(getnickbynick(argv[i]));
2344 if (husr == NULL)
2345 {
2346 helpmod_reply(sender, returntype, "Can not resolve a ticket: User %s not found", argv[i]);
2347 continue;
2348 }
2349 if (!IsAccount(husr->real_user))
2350 {
2351 helpmod_reply(sender, returntype, "Can not resolve a ticket: User %s is not authed", argv[i]);
2352 continue;
2353 }
2354 htick = hticket_get(husr->real_user->authname,hchan);
2355 if (htick == NULL)
2356 {
2357 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));
2358 continue;
2359 }
2360 hticket_del(htick, hchan);
2361 helpmod_reply(sender, returntype, "Resolved user %s's ticket for channel %s", argv[i], hchannel_get_name(hchan));
2362 }
2363 }
2364 }
2365
2366 static void helpmod_cmd_tickets (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2367 {
2368 hchannel *hchan;
2369 hticket *htick;
2370 int i;
2371
2372 DEFINE_HCHANNEL;
2373
2374 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2375
2376 if (hchan == NULL)
2377 {
2378 helpmod_reply(sender, returntype, "Can not list tickets: Channel not defined or not found");
2379 return;
2380 }
2381
2382 if (!(hchan->flags & H_REQUIRE_TICKET))
2383 {
2384 helpmod_reply(sender, returntype, "Can not list tickets: Channel %s does not use the ticket system", hchannel_get_name(hchan));
2385 return;
2386 }
2387
2388 htick = hchan->htickets;
2389
2390 if (htick == NULL)
2391 {
2392 helpmod_reply(sender, returntype, "Channel %s has no valid tickets", hchannel_get_name(hchan));
2393 return;
2394 }
2395
2396 helpmod_reply(sender, returntype, "Valid tickets for channel %s", hchannel_get_name(hchan));
2397
2398 for (i = 0;htick;htick = htick->next, i++)
2399 helpmod_reply(sender, returntype, "%4d %16s %48s", i, htick->authname, helpmod_strtime(time(NULL) - htick->time_expiration));
2400
2401 helpmod_reply(sender, returntype, "Done listing tickets. Channel %s had %d valid ticket%s", hchannel_get_name(hchan), i, (i==1)?"":"s");
2402 }
2403
2404 static void helpmod_cmd_showticket (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2405 {
2406 hchannel *hchan;
2407 huser *husr;
2408 hticket *htick;
2409 int i;
2410
2411 DEFINE_HCHANNEL;
2412
2413 HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
2414
2415 if (argc > H_CMD_MAX_ARGS)
2416 argc = H_CMD_MAX_ARGS;
2417
2418 if (hchan == NULL)
2419 {
2420 helpmod_reply(sender, returntype, "Can not show the ticket: Channel not defined or not found");
2421 return;
2422 }
2423 for (i = 0;i < argc;i++)
2424 {
2425 husr = huser_get(getnickbynick(argv[i]));
2426 if (husr == NULL)
2427 {
2428 helpmod_reply(sender, returntype, "Can not show the ticket: User %s not found", argv[i]);
2429 continue;
2430 }
2431 if (!IsAccount(husr->real_user))
2432 {
2433 helpmod_reply(sender, returntype, "Can not show the ticket: User %s is not authed", argv[i]);
2434 continue;
2435 }
2436 htick = hticket_get(husr->real_user->authname, hchan);
2437 if (htick == NULL)
2438 {
2439 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));
2440 continue;
2441 }
2442 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)));
2443 }
2444 }
2445
2446 static int helpmod_cmd_termstats_sort(const void *left, const void *right)
2447 {
2448 return (*((hterm**)right))->usage - (*((hterm**)left))->usage;
2449 }
2450
2451 static void helpmod_cmd_termstats(huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2452 {
2453 hterm **arr, *origin;
2454 hchannel *hchan;
2455 int i, count;
2456
2457 DEFINE_HCHANNEL;
2458
2459 if (hchan == NULL)
2460 origin = hterms;
2461 else
2462 origin = hchan->channel_hterms;
2463
2464 count = hterm_count(origin);
2465
2466 if (count == 0)
2467 {
2468 helpmod_reply(sender, returntype, "Can not list term usage statistics: No terms available");
2469 return;
2470 }
2471
2472 arr = malloc(sizeof(hterm*) * count);
2473 assert(arr != NULL);
2474
2475 for (i=0;i < count;i++,origin = origin->next)
2476 arr[i] = origin;
2477
2478 qsort(arr, count, sizeof(hterm*), helpmod_cmd_termstats_sort);
2479
2480 if (hchan == NULL)
2481 helpmod_reply(sender, returntype, "10 Most used global terms");
2482 else
2483 helpmod_reply(sender, returntype, "10 Most used terms for channel %s", hchannel_get_name(hchan));
2484
2485 for (i=0;i < 10 && i < count;i++)
2486 helpmod_reply(sender, returntype, "#%02d %32s :%d",i+1, arr[i]->name->content,arr[i]->usage);
2487
2488 free(arr);
2489 }
2490
2491 static int helpmod_cmd_checkchannel_nicksort(const void *left, const void *right)
2492 {
2493 return ci_strcmp(getnickbynumeric(*((unsigned long*)left))->nick, getnickbynumeric(*((unsigned long*)right))->nick);
2494 }
2495
2496 static int helpmod_cmd_checkchannel_statussort(const void *left, const void *right)
2497 {
2498 int level1 = 0, level2 = 0;
2499
2500 if (*((unsigned long*)left) & CUMODE_VOICE)
2501 level1 = 1;
2502 if (*((unsigned long*)left) & CUMODE_OP)
2503 level1 = 2;
2504
2505 if (*((unsigned long*)right) & CUMODE_VOICE)
2506 level2 = 1;
2507 if (*((unsigned long*)right) & CUMODE_OP)
2508 level2 = 2;
2509
2510 return level2 - level1;
2511 }
2512
2513 static void helpmod_cmd_checkchannel(huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2514 {
2515 channel *chan;
2516 nick *nck;
2517 int i, j, nick_count = 0, authed_count = 0, o_limit = 0, v_limit = 0, summary_only = 0;
2518 unsigned long *numeric_array;
2519
2520 if (argc == 0)
2521 {
2522 helpmod_reply(sender, returntype, "Can not check channel: Channel not defined");
2523 return;
2524 }
2525
2526 chan = findchannel(argv[0]);
2527 if (chan == NULL)
2528 {
2529 helpmod_reply(sender, returntype, "Can not check channel: Channel %s not found", argv[0]);
2530 return;
2531 }
2532 if (argc > 1 && !ci_strcmp(argv[1], "summary"))
2533 summary_only = 1;
2534
2535 /* first pass - verify validity and count nicks */
2536 for (i=0;i < chan->users->hashsize;i++)
2537 {
2538 nck = getnickbynumeric(chan->users->content[i]);
2539 if (!nck) /* it's a hash, not an array */
2540 continue;
2541
2542 nick_count++;
2543
2544 if (IsAccount(nck))
2545 authed_count++;
2546
2547 if (IsOper(nck) && strlen(nck->nick) > 1)
2548 {
2549 helpmod_reply(sender, returntype, "Can not check channel: Permission denied. Channel %s has an oper on it", argv[0]);
2550 return;
2551 }
2552 }
2553
2554 numeric_array = (unsigned long*)malloc(nick_count * sizeof(unsigned long));
2555
2556 /* second pass - construct array */
2557 for (i=0,j=0;i < chan->users->hashsize;i++)
2558 {
2559 if (getnickbynumeric(chan->users->content[i]) == NULL) /* it's a hash, not an array */
2560 continue;
2561
2562 numeric_array[j++] = chan->users->content[i];
2563 }
2564
2565 qsort(numeric_array, nick_count, sizeof(unsigned long), helpmod_cmd_checkchannel_statussort);
2566
2567 /* third pass - find status boundaries */
2568 {
2569 for (;o_limit < nick_count && numeric_array[o_limit] & CUMODE_OP; o_limit++);
2570 v_limit = o_limit;
2571 for(v_limit = o_limit; (v_limit < nick_count) && numeric_array[v_limit] & CUMODE_VOICE; v_limit++);
2572 }
2573
2574 helpmod_reply(sender, returntype, "Information on channel %s", argv[0]);
2575 helpmod_reply(sender, returntype, "Channel created %s ago", helpmod_strtime(time(NULL) - chan->timestamp));
2576 if (!IsKey(chan) && !IsInviteOnly(chan))
2577 helpmod_reply(sender, returntype, "Channel topic: %s", chan->topic?chan->topic->content:"Not set");
2578 helpmod_reply(sender, returntype, "Channel modes: %s", printflags(chan->flags, cmodeflags));
2579
2580
2581 /* sort the sub arrays */
2582
2583 if (o_limit > 0)
2584 qsort(numeric_array, o_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2585 if (v_limit - o_limit > 0)
2586 qsort(numeric_array + o_limit, v_limit - o_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2587 if (nick_count - v_limit > 0)
2588 qsort(numeric_array + v_limit, nick_count - v_limit, sizeof(unsigned long), helpmod_cmd_checkchannel_nicksort);
2589
2590 /* fourth pass - print results */
2591 if (!summary_only)
2592 for (i=0;i < nick_count;i++)
2593 {
2594 char buf[256], status;
2595
2596 if (numeric_array[i] & CUMODE_OP)
2597 status = '@';
2598 else if (numeric_array[i] & CUMODE_VOICE)
2599 status = '+';
2600 else
2601 status = ' ';
2602
2603 visiblehostmask(getnickbynumeric(numeric_array[i]), buf);
2604 if (IsAccount(getnickbynumeric(numeric_array[i])))
2605 helpmod_reply(sender, returntype, "%c%s (%s)", status, buf, getnickbynumeric(numeric_array[i])->authname);//nick_array[i]->authname);
2606 else
2607 helpmod_reply(sender, returntype, "%c%s", status, buf);
2608 }
2609
2610 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);
2611
2612 free(numeric_array);
2613 }
2614
2615 static void helpmod_cmd_statsdump (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2616 {
2617 haccount *hacc = haccounts;
2618 hstat_account *ptr;
2619 int i;
2620
2621 helpmod_reply(sender, returntype, "Account statistics");
2622 for (;hacc;hacc = hacc->next)
2623 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2624 {
2625 helpmod_reply(sender, returntype, "Account %s channel %s short-term", hacc->name->content, hchannel_get_name(ptr->hchan));
2626 for (i = 0;i < 7;i++)
2627 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);
2628 helpmod_reply(sender, returntype, "Account %s channel %s long-term", hacc->name->content, hchannel_get_name(ptr->hchan));
2629 for (i = 0;i < 10;i++)
2630 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);
2631 }
2632 }
2633
2634 static void helpmod_cmd_statsrepair (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2635 {
2636 haccount *hacc = haccounts;
2637 hstat_account *ptr;
2638 int i;
2639
2640 helpmod_reply(sender, returntype, "Repairing account statistics");
2641 for (;hacc;hacc = hacc->next)
2642 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2643 {
2644 for (i = 0;i < 7;i++)
2645 {
2646 if (ptr->week[i].time_spent > HDEF_d)
2647 {
2648 ptr->week[i].time_spent = 0;
2649 helpmod_reply(sender, returntype, "repaired short term TimeSpent %s @ %s : Greater than one day",hacc->name->content, hchannel_get_name(ptr->hchan));
2650 }
2651 if (ptr->week[i].time_spent < 0)
2652 {
2653 ptr->week[i].time_spent = 0;
2654 helpmod_reply(sender, returntype, "repaired short term TimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2655 }
2656
2657 if (ptr->week[i].prime_time_spent > HDEF_d)
2658 {
2659 ptr->week[i].prime_time_spent = 0;
2660 helpmod_reply(sender, returntype, "repaired short term PrimeTimeSpent %s @ %s : Greater than one day",hacc->name->content, hchannel_get_name(ptr->hchan));
2661 }
2662 if (ptr->week[i].prime_time_spent < 0)
2663 {
2664 ptr->week[i].prime_time_spent = 0;
2665 helpmod_reply(sender, returntype, "repaired short term PrimeTimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2666 }
2667
2668 if (ptr->week[i].lines > 10000)
2669 {
2670 ptr->week[i].lines = 0;
2671 helpmod_reply(sender, returntype, "repaired short term Lines %s @ %s : Greater than 10000",hacc->name->content, hchannel_get_name(ptr->hchan));
2672 }
2673 if (ptr->week[i].lines < 0)
2674 {
2675 ptr->week[i].lines = 0;
2676 helpmod_reply(sender, returntype, "repaired short term Lines %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2677 }
2678
2679 if (ptr->week[i].words > 50000)
2680 {
2681 ptr->week[i].words = 0;
2682 helpmod_reply(sender, returntype, "repaired short term Words %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2683 }
2684 if (ptr->week[i].words < 0)
2685 {
2686 ptr->week[i].words = 0;
2687 helpmod_reply(sender, returntype, "repaired short term Words %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2688 }
2689 }
2690 for (i = 0;i < 10;i++)
2691 {
2692 if (ptr->longterm[i].time_spent > HDEF_w)
2693 {
2694 ptr->longterm[i].time_spent = 0;
2695 helpmod_reply(sender, returntype, "repaired long term TimeSpent %s @ %s : Greater than one week",hacc->name->content, hchannel_get_name(ptr->hchan));
2696 }
2697 if (ptr->longterm[i].time_spent < 0)
2698 {
2699 ptr->longterm[i].time_spent = 0;
2700 helpmod_reply(sender, returntype, "repaired long term TimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2701 }
2702
2703 if (ptr->longterm[i].prime_time_spent > HDEF_w)
2704 {
2705 ptr->longterm[i].prime_time_spent = 0;
2706 helpmod_reply(sender, returntype, "repaired long term PrimeTimeSpent %s @ %s : Greater than one week",hacc->name->content, hchannel_get_name(ptr->hchan));
2707 }
2708 if (ptr->longterm[i].prime_time_spent < 0)
2709 {
2710 ptr->longterm[i].prime_time_spent = 0;
2711 helpmod_reply(sender, returntype, "repaired long term PrimeTimeSpent %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2712 }
2713
2714 if (ptr->longterm[i].lines > 50000)
2715 {
2716 ptr->longterm[i].lines = 0;
2717 helpmod_reply(sender, returntype, "repaired long term Lines %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2718 }
2719 if (ptr->longterm[i].lines < 0)
2720 {
2721 ptr->longterm[i].lines = 0;
2722 helpmod_reply(sender, returntype, "repaired long term Lines %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2723 }
2724
2725 if (ptr->longterm[i].words > 50000)
2726 {
2727 ptr->longterm[i].words = 0;
2728 helpmod_reply(sender, returntype, "repaired long term Words %s @ %s : Greater than 50000",hacc->name->content, hchannel_get_name(ptr->hchan));
2729 }
2730 if (ptr->longterm[i].words < 0)
2731 {
2732 ptr->longterm[i].words = 0;
2733 helpmod_reply(sender, returntype, "repaired long term Words %s @ %s : Less than zero",hacc->name->content, hchannel_get_name(ptr->hchan));
2734 }
2735 }
2736 }
2737 helpmod_reply(sender, returntype, "Account statistics repaired");
2738
2739 }
2740
2741 static void helpmod_cmd_statsreset (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2742 {
2743 haccount *hacc = haccounts;
2744 hstat_account *ptr;
2745 hchannel *hchan;
2746 int i, short_del, long_del;
2747
2748 if (argc < 2)
2749 {
2750 helpmod_reply(sender, returntype, "Insufficient parameters");
2751 return;
2752 }
2753
2754 if (sscanf(argv[0], "%d", &short_del) == 0)
2755 {
2756 helpmod_reply(sender, returntype, "Invalid parameter");
2757 return;
2758 }
2759 if (sscanf(argv[1], "%d", &long_del) == 0)
2760 {
2761 helpmod_reply(sender, returntype, "Invalid parameter");
2762 return;
2763 }
2764
2765 for (;hacc;hacc = hacc->next)
2766 for (ptr = hacc->stats;ptr;ptr = ptr->next)
2767 {
2768 for (i = 1;i < short_del + 1;i++)
2769 HSTAT_ACCOUNT_ZERO(ptr->week[(hstat_day() + i) % 7]);
2770 for (i = 1;i < long_del + 1;i++)
2771 HSTAT_ACCOUNT_ZERO(ptr->longterm[(hstat_week() + i) % 10]);
2772 }
2773
2774 for (hchan = hchannels;hchan;hchan = hchan->next)
2775 {
2776 for (i = 1;i < short_del + 1;i++)
2777 HSTAT_CHANNEL_ZERO(hchan->stats->week[(hstat_day() + i) % 7]);
2778 for (i = 1;i < long_del + 1;i++)
2779 HSTAT_CHANNEL_ZERO(hchan->stats->longterm[(hstat_week() + i) % 10]);
2780
2781 }
2782
2783 helpmod_reply(sender, returntype, "Statistics reset complete");
2784 }
2785
2786 static void helpmod_cmd_message (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2787 {
2788 hchannel *hchan;
2789
2790 if (argc < 2)
2791 {
2792 helpmod_reply(sender, returntype, "Can not send a message: Insufficient arguments");
2793 return;
2794 }
2795 hchan = hchannel_get_by_name(argv[0]);
2796 if (hchan == NULL)
2797 {
2798 helpmod_reply(sender, returntype, "Can not send a message: Invalid channel %s", argv[0]);
2799 return;
2800 }
2801 SKIP_WORD;
2802 helpmod_message_channel(hchan, "(%s) %s", sender->real_user->nick, ostr);
2803 helpmod_reply(sender, returntype, "Message sent to %s", hchannel_get_name(hchan));
2804 }
2805
2806 /* old H stuff */
2807 void helpmod_cmd_load (huser *sender, channel *returntype, char* arg, int argc, char *argv[])
2808 {
2809 FILE *tmp_file;
2810 char buf[128] = "helpmod/default";
2811
2812 if (!arg)
2813 helpmod_reply(sender, returntype, "Warning: No config specified, using default");
2814 else
2815 {
2816 if (strlen(arg) >= 100)
2817 return;
2818 else
2819 sprintf(buf, "helpmod/%s", arg);
2820 }
2821
2822 if (!(tmp_file = fopen(buf, "rt")))
2823 {
2824 helpmod_reply(sender, returntype, "File %s not found", buf);
2825 return;
2826 }
2827 else
2828 fclose(tmp_file);
2829
2830 helpmod_clear_aliases(&aliases);
2831 helpmod_clear_all_entries();
2832 helpmod_init_entry(&helpmod_base);
2833 huser_reset_states();
2834 helpmod_load_entries(buf);
2835 strcpy(helpmod_db, buf);
2836 helpmod_reply(sender, returntype, "New config loaded and system reset");
2837 }
2838
2839 void helpmod_cmd_status (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
2840 {
2841 helpmod_reply(sender, returntype, "HelpMod version %s (built %s, up %s)", HELPMOD_VERSION, __DATE__, helpmod_strtime(time(NULL) - helpmod_startup_time));
2842 helpmod_reply(sender, returntype, "Channels %d", hchannel_count());
2843 helpmod_reply(sender, returntype, "Accounts %d", haccount_count(H_ANY));
2844 helpmod_reply(sender, returntype, "Users %d", huser_count());
2845 helpmod_reply(sender, returntype, "Help entries %d", helpmod_entry_count(helpmod_base));
2846 helpmod_reply(sender, returntype, "Bans %d", hban_count());
2847 helpmod_reply(sender, returntype, "Help provided %d", helpmod_usage);
2848 helpmod_reply(sender, returntype, "Tickets %d", hticket_count());
2849 }
2850
2851 /* not really a command, but help wants this one */
2852 void helpmod_send_help(huser* target)
2853 {
2854 int i;
2855 helpmod_usage++;
2856 for (i=0;i<target->state->text_lines;i++)
2857 helpmod_reply(target, NULL, "%s", target->state->text[i]->content);
2858 for (i=0;i<target->state->option_count;i++)
2859 helpmod_reply(target, NULL, "%d) %s", i+1, target->state->options[i]->description->content);
2860 if (!target->state->option_count)
2861 {
2862 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");
2863 }
2864 }
2865
2866 void helpmod_cmd_command(huser* sender, channel* returntype, char* arg, int argc, char *argv[])
2867 {
2868 hcommand *hcom;
2869 char buffer[512], *ptr = argv[0];
2870 FILE *in;
2871
2872 if (argc == 0)
2873 {
2874 helpmod_reply(sender, returntype, "Usage: command [name of the command] for a list see 'showcommands'");
2875 return;
2876 }
2877
2878 hcom = hcommand_get(argv[0], huser_get_level(sender));
2879
2880 if (hcom == NULL)
2881 {
2882 helpmod_reply(sender, returntype, "Unknown command '%s'", argv[0]);
2883 return;
2884 }
2885
2886 /* tolower */
2887 while (*(ptr++))
2888 *ptr = tolower(*ptr);
2889
2890 /* ? is handled like this because windows is shit */
2891 if (!ci_strcmp(argv[0], "?"))
2892 sprintf(buffer, "./helpmod2/commands/questionmark");
2893 else
2894 sprintf(buffer, "./helpmod2/commands/%s", argv[0]);
2895
2896 if ((in = fopen(buffer, "rt")) == NULL)
2897 {
2898 helpmod_reply(sender, returntype, "No help available for command '%s' (Ask strutsi to write it)", argv[0]);
2899 return;
2900 }
2901
2902 while (!feof(in))
2903 {
2904 fgets(buffer, 512, in);
2905 if (feof(in))
2906 break;
2907 helpmod_reply(sender, returntype, "%s", buffer);
2908 }
2909
2910 fclose(in);
2911 }
2912
2913 void helpmod_cmd_help (huser* sender, channel* returntype, char* arg, int argc, char *argv[])
2914 {
2915 int hlp_target;
2916
2917 if (helpmod_base == NULL || !helpmod_base->option_count)
2918 {
2919 helpmod_reply(sender, returntype, "The help service is not available at this time, please try again later");
2920 return;
2921 }
2922
2923 if (!argc)
2924 {
2925 sender->state = helpmod_base;
2926 helpmod_send_help(sender);
2927 return;
2928 }
2929 else
2930 if (!sscanf(arg, "%d", &hlp_target))
2931 {
2932 helpmod_entry tmp;
2933
2934 tmp = helpmod_get_alias(arg);
2935 if (!tmp)
2936 helpmod_reply(sender, returntype, "Invalid value. Either use 'help' to restart or give an integer as a valid selection");
2937 else
2938 {
2939 sender->state = tmp;
2940 helpmod_send_help(sender);
2941 }
2942 return;
2943 }
2944
2945 hlp_target--;
2946 if (!helpmod_valid_selection(sender->state, hlp_target))
2947 {
2948 if (!sender->state->option_count)
2949 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");
2950 else if (!sender->state->parent)
2951 helpmod_reply(sender, returntype, "Bad selection, please enter your selection as an integer from %d to %d", 1, sender->state->option_count);
2952 else
2953 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);
2954 return;
2955 }
2956
2957 sender->state = helpmod_make_selection(sender->state, hlp_target);
2958 helpmod_send_help(sender);
2959
2960 return;
2961 }
2962 /* adds all of the abowe to the system */
2963 void hcommands_add(void)
2964 {
2965 hcommand_add("help", H_PEON, helpmod_cmd_help,"Offers the H1 type help");
2966 hcommand_add("status",H_OPER, helpmod_cmd_status,"Gives service status");
2967 hcommand_add("load", H_OPER, helpmod_cmd_load,"Loads a new help database");
2968 hcommand_add("aliases",H_STAFF, helpmod_cmd_aliases,"Lists all aliases currently in use");
2969 hcommand_add("showcommands", H_LAMER, helpmod_cmd_showcommands,"Lists all commands available to you");
2970
2971 hcommand_add("improper", H_STAFF, helpmod_cmd_improper, "Sets the userlevel of the target to banned (lvl 0). Long term ban.");
2972 hcommand_add("peon", H_STAFF, helpmod_cmd_peon, "Sets the userlevel of the target to peon (lvl 1)");
2973 hcommand_add("trial", H_OPER, helpmod_cmd_trial, "Sets the userlevel of the target to trial staff (lvl 2)");
2974 hcommand_add("staff", H_OPER, helpmod_cmd_staff, "Sets the userlevel of the target to staff (lvl 3)");
2975 hcommand_add("oper", H_OPER, helpmod_cmd_oper, "Sets the userlevel of the target to oper (lvl 4)");
2976 hcommand_add("admin", H_ADMIN, helpmod_cmd_admin, "Sets the userlevel of the target to admin (lvl 5)");
2977 hcommand_add("deluser", H_OPER, helpmod_cmd_deluser, "Removes an account from " HELPMOD_NICK);
2978 hcommand_add("listuser", H_STAFF, helpmod_cmd_listuser, "Lists user accounts of " HELPMOD_NICK);
2979
2980 hcommand_add("chanconf", H_STAFF, helpmod_cmd_chanconf, "Channel configuration");
2981 hcommand_add("acconf", H_TRIAL, helpmod_cmd_acconf, "Personalise " HELPMOD_NICK " behaviour");
2982 hcommand_add("welcome", H_STAFF, helpmod_cmd_welcome, "Views or changes the channel welcome message");
2983 hcommand_add("censor", H_STAFF, helpmod_cmd_censor, "Handles the censored patterns for a channel");
2984
2985 hcommand_add("queue", H_TRIAL, helpmod_cmd_queue, "Handles the channel queue");
2986 hcommand_add("next", H_TRIAL, helpmod_cmd_next, "Same as queue next");
2987 hcommand_add("done", H_TRIAL, helpmod_cmd_done, "Same as queue done");
2988 hcommand_add("enqueue", H_TRIAL, helpmod_cmd_enqueue, "Same as queue on or chanconf +3");
2989 hcommand_add("dequeue", H_TRIAL, helpmod_cmd_dequeue, "Same as queue off or chanconf -3");
2990 hcommand_add("autoqueue", H_TRIAL, helpmod_cmd_autoqueue, "Same as queue maintain");
2991
2992 hcommand_add("?", H_PEON, helpmod_cmd_term_find, "Same as term find with multiple targets");
2993 hcommand_add("?+", H_TRIAL, helpmod_cmd_term_find_plus, "Multitarget term find which advances the queue");
2994 hcommand_add("?-", H_TRIAL, helpmod_cmd_term_find_minus, "Multitarget term find which removes users from queue");
2995 hcommand_add("term", H_STAFF, helpmod_cmd_term, "Term handling");
2996
2997 hcommand_add("klingon", H_OPER, helpmod_cmd_klingon, "Phrases in klingon, both targeted and general");
2998 hcommand_add("out", H_STAFF, helpmod_cmd_out, "Sets the userlevel of the target to banned (lvl 0) for a short while");
2999 hcommand_add("kick", H_TRIAL, helpmod_cmd_kick, "Kicks user(s) from a channel");
3000 hcommand_add("ban", H_STAFF, helpmod_cmd_ban, "Handles global bans");
3001 hcommand_add("chanban", H_TRIAL, helpmod_cmd_chanban, "Handles channel bans");
3002 hcommand_add("dnmo", H_STAFF, helpmod_cmd_dnmo, "DoNotMessageOpers informs the luser of his mistake and sets him to the bottom of the queue");
3003 hcommand_add("lamercontrol", H_OPER, helpmod_cmd_lamercontrol, "Views or changes the channel lamercontrol profile");
3004 hcommand_add("topic", H_STAFF, helpmod_cmd_topic, "Handles the topic of a channel");
3005 hcommand_add("idlekick", H_OPER, helpmod_cmd_idlekick, "Views or sets the idle kick time");
3006 hcommand_add("everyoneout", H_STAFF, helpmod_cmd_everyoneout, "Removes all normal users from a channel and enforces +i");
3007
3008 hcommand_add("stats", H_STAFF, helpmod_cmd_stats, "Shows staff activity statistics");
3009 hcommand_add("chanstats", H_STAFF, helpmod_cmd_chanstats, "Shows channel activity statistics");
3010 hcommand_add("activestaff", H_ADMIN, helpmod_cmd_activestaff, "Shows active staff members for a channel");
3011 hcommand_add("top10", H_STAFF, helpmod_cmd_top10, "Shows the top 10 most active staff");
3012 hcommand_add("report", H_OPER, helpmod_cmd_report, "Sets the channel where to report this channels statistics every 5 minutes");
3013
3014 hcommand_add("whoami", H_LAMER, helpmod_cmd_whoami, "Tells who you are to " HELPMOD_NICK);
3015 hcommand_add("whois", H_STAFF, helpmod_cmd_whois, "Tells you who someone is");
3016 hcommand_add("command", H_LAMER, helpmod_cmd_command, "Gives detailed information on a command");
3017 hcommand_add("addchan", H_ADMIN, helpmod_cmd_addchan, "Joins " HELPMOD_NICK " to a new channel");
3018 hcommand_add("delchan", H_ADMIN, helpmod_cmd_delchan, "Removes " HELPMOD_NICK " permanently from a channel");
3019 hcommand_add("seen", H_STAFF, helpmod_cmd_seen, "Tells when a specific user/account has had activity");
3020
3021 hcommand_add("op", H_STAFF, helpmod_cmd_op, "Sets mode +o on channels");
3022 hcommand_add("deop", H_STAFF, helpmod_cmd_deop, "Sets mode -o on channels");
3023 hcommand_add("voice", H_STAFF, helpmod_cmd_voice, "Sets mode +v on channels");
3024 hcommand_add("devoice", H_STAFF, helpmod_cmd_devoice, "Sets mode -v on channels");
3025
3026 hcommand_add("invite", H_PEON, helpmod_cmd_invite, "Invites you to a channel");
3027 hcommand_add("ticket", H_TRIAL, helpmod_cmd_ticket, "Gives a ticket to be used with invite");
3028 hcommand_add("resolve", H_STAFF, helpmod_cmd_resolve, "Resolves (deletes) a ticket");
3029 hcommand_add("tickets", H_STAFF, helpmod_cmd_tickets, "Lists all valid tickets for a channel");
3030 hcommand_add("showticket", H_STAFF, helpmod_cmd_showticket, "Shows the ticket for the user");
3031
3032 hcommand_add("termstats", H_OPER, helpmod_cmd_termstats, "Lists usage statistics for terms");
3033 hcommand_add("checkchannel", H_STAFF, helpmod_cmd_checkchannel, "Shows channel information for any channel");
3034 hcommand_add("statsdump", H_ADMIN, helpmod_cmd_statsdump, "Statistics dump command");
3035 hcommand_add("statsrepair", H_ADMIN, helpmod_cmd_statsrepair, "Statistics repair command");
3036 hcommand_add("statsreset", H_ADMIN, helpmod_cmd_statsreset, "Statistics reset command");
3037
3038 hcommand_add("message", H_TRIAL, helpmod_cmd_message, "Sends a message to a channel");
3039 /*hcommand_add("megod", H_PEON, helpmod_cmd_megod, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
3040 /*hcommand_add("test", H_PEON, helpmod_cmd_test, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
3041 }
3042
3043 void helpmod_command(huser *sender, channel* returntype, char *args)
3044 {
3045 int argc = 0, useless_var;
3046 char args_copy[512];
3047 char *parsed_args[H_CMD_MAX_ARGS + 3], *ptr = args_copy;
3048
3049 /* only accept commands from valid sources */
3050 if (huser_get_level(sender) < H_PEON || huser_get_level(sender) > H_ADMIN)
3051 return;
3052
3053 if (returntype && !strncmp(args, helpmodnick->nick, strlen(helpmodnick->nick)))
3054 {
3055 if (!args[1])
3056 return;
3057 else
3058 args+=strlen(helpmodnick->nick)+1;
3059 }
3060
3061 if (*args == '-' || *args == '?')
3062 args++;
3063
3064 strcpy(args_copy, args);
3065 /* FIX stringituki */
3066 while (argc < 10)
3067 {
3068 while (isspace(*ptr) && *ptr)
3069 ptr++;
3070
3071 if (*ptr == '\0')
3072 break;
3073
3074 if (*ptr == '"' && strchr(ptr+1, '"'))
3075 { /* string support */
3076 parsed_args[argc++] = ptr+1;
3077 ptr = strchr(ptr+1, '"');
3078
3079 *(ptr++) = '\0';
3080
3081 while (!isspace(*ptr) && *ptr)
3082 ptr++;
3083
3084 if (*ptr == '\0')
3085 break;
3086 }
3087 else
3088 {
3089 parsed_args[argc++] = ptr;
3090
3091 while (!isspace(*ptr) && *ptr)
3092 ptr++;
3093
3094 if (*ptr == '\0')
3095 break;
3096
3097 *(ptr++) = '\0';
3098 }
3099 }
3100
3101 if (!argc)
3102 return;
3103
3104 /* old H compatibility */
3105 if (sscanf(parsed_args[0], "%d", &useless_var) && returntype == NULL)
3106 {
3107 helpmod_cmd_help(sender, NULL, parsed_args[0], 1, NULL);
3108 return;
3109 }
3110
3111 {
3112 char *ostr = args, **argv = (char**)&parsed_args; // for SKIP_WORD
3113 hcommand *hcom = hcommand_get(parsed_args[0], huser_get_level(sender));
3114
3115 if (hcom == NULL)
3116 {
3117 if ((sender->account == NULL && returntype == NULL) || (sender->account != NULL && !(sender->account->flags & H_NO_CMD_ERROR)))
3118 helpmod_reply(sender, returntype, "Unknown command '%s', please see showcommands for a list of all commands available to you", parsed_args[0]);
3119 }
3120 else
3121 {
3122 SKIP_WORD;
3123 hcom->function(sender, returntype, ostr, argc, argv);
3124 }
3125 }
3126 }
3127
3128 #undef SKIP_WORD
3129 #undef DEFINE_HCHANNEL
3130 #undef HCHANNEL_VERIFY_AUTHORITY