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