4 #include "../lib/version.h"
5 #include "../control/control.h"
6 #include "../lib/irc_string.h"
7 #include "../lib/splitline.h"
8 #include "../lib/strlfunc.h"
9 #include "../core/nsmalloc.h"
10 #include "../irc/irc.h"
11 #include "../localuser/localuser.h"
12 #include "../localuser/localuserchannel.h"
14 #include "../trusts/trusts.h"
18 static void registercommands(int, void *);
19 static void deregistercommands(int, void *);
21 static int glines_cmdblock(void *source
, int cargc
, char **cargv
) {
22 nick
*sender
= source
;
32 target
= getnickbynick(cargv
[0]);
35 controlreply(sender
, "Sorry, couldn't find that user.");
39 duration
= durationtolong(cargv
[1]);
42 controlreply(sender
, "Invalid duration specified.");
46 if (duration
> MAXUSERGLINEDURATION
) {
47 controlreply(sender
, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION
, 0));
53 if (strlen(reason
) < MINUSERGLINEREASON
) {
54 controlreply(sender
, "Please specify a proper gline reason.");
58 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
60 glinebufinit(&gbuf
, 1);
61 glinebufaddbynick(&gbuf
, target
, 0, creator
, reason
, getnettime() + duration
, getnettime(), getnettime() + duration
);
62 glinebufcounthits(&gbuf
, &hits
, NULL
);
63 glinebufflush(&gbuf
, 1);
65 controlwall(NO_OPER
, NL_GLINES
, "%s BLOCK'ed user '%s!%s@%s' for %s with reason '%s' (%d hits)", controlid(sender
), target
->nick
, target
->ident
, target
->host
->name
->content
, longtoduration(duration
, 0), reason
, hits
);
67 controlreply(sender
, "Done.");
72 static int glines_gline_helper(void *source
, int cargc
, char **cargv
, int sanitychecks
) {
73 nick
*sender
= source
;
74 int duration
, users
, channels
;
78 #if SNIRCD_VERSION < 140
87 duration
= durationtolong(cargv
[1]);
90 controlreply(sender
, "Invalid duration specified.");
94 if (duration
> MAXUSERGLINEDURATION
) {
95 controlreply(sender
, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION
, 0));
101 if (strlen(reason
) < MINUSERGLINEREASON
) {
102 controlreply(sender
, "Please specify a proper gline reason.");
106 #if SNIRCD_VERSION < 140
107 gl
= findgline(mask
);
110 /* warn opers that they can't modify this gline */
111 if (gl
->flags
& GLINE_ACTIVE
) {
112 controlreply(sender
, "Active G-Line already exists on %s - unable to modify", cargv
[0]);
116 controlreply(sender
, "Reactivating existing gline on %s", mask
);
120 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
122 glinebufinit(&gbuf
, 1);
124 if (!glinebufadd(&gbuf
, mask
, creator
, reason
, getnettime() + duration
, getnettime(), getnettime() + duration
)) {
125 controlreply(sender
, "Invalid G-Line mask.");
129 glinebufcounthits(&gbuf
, &users
, &channels
);
131 if (channels
> MAXUSERGLINECHANNELHITS
) {
132 glinebufabandon(&gbuf
);
133 controlreply(sender
, "G-Line on '%s' would hit %d channels. Limit is %d. Not setting G-Line.", mask
, channels
, MAXUSERGLINECHANNELHITS
);
135 } else if (users
> MAXUSERGLINEUSERHITS
) {
136 glinebufabandon(&gbuf
);
137 controlreply(sender
, "G-Line on '%s' would hit %d users. Limit is %d. Not setting G-Line.", mask
, users
, MAXUSERGLINEUSERHITS
);
141 if (sanitychecks
&& glinebufsanitize(&gbuf
) > 0) {
142 glinebufabandon(&gbuf
);
143 controlreply(sender
, "G-Line failed sanity checks. Not setting G-Line.");
147 glinebufflush(&gbuf
, 1);
149 controlwall(NO_OPER
, NL_GLINES
, "%s %sGLINE'd mask '%s' for %s with reason '%s' (hits %d users/%d channels)",
151 sanitychecks
? "" : "RAW",
152 mask
, longtoduration(duration
, 0),
153 reason
, users
, channels
);
155 controlreply(sender
, "Done.");
160 static int glines_cmdrawgline(void *source
, int cargc
, char **cargv
) {
161 return glines_gline_helper(source
, cargc
, cargv
, 0);
164 static int glines_cmdgline(void *source
, int cargc
, char **cargv
) {
165 return glines_gline_helper(source
, cargc
, cargv
, 1);
168 static int glines_cmdrawglinesimulate(void *source
, int cargc
, char **cargv
) {
169 nick
*sender
= source
;
180 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
182 glinebufinit(&gbuf
, 0);
184 if (!glinebufadd(&gbuf
, mask
, creator
, "Simulate", getnettime(), getnettime(), getnettime())) {
185 glinebufabandon(&gbuf
);
186 controlreply(sender
, "Invalid G-Line mask.");
190 glinebufcounthits(&gbuf
, &users
, &channels
);
191 glinebufabandon(&gbuf
);
193 controlreply(sender
, "G-Line on '%s' would hit %d users/%d channels.", mask
, users
, channels
);
198 static int glines_cmdsmartgline(void *source
, int cargc
, char **cargv
) {
199 nick
*sender
= source
;
202 char *p
, *user
, *host
;
203 struct irc_in_addr ip
;
215 if (origmask
[0] == '#' || origmask
[0] == '&') {
216 controlreply(sender
, "Please use rawgline for badchans and regex glines.");
220 duration
= durationtolong(cargv
[1]);
223 controlreply(sender
, "Invalid duration specified.");
227 if (duration
> MAXUSERGLINEDURATION
) {
228 controlreply(sender
, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION
, 0));
234 if (strlen(reason
) < MINUSERGLINEREASON
) {
235 controlreply(sender
, "Please specify a proper gline reason.");
239 strncpy(mask
, origmask
, sizeof(mask
));
241 if (strchr(mask
, '!')) {
242 controlreply(sender
, "Use rawgline to place nick glines.");
246 p
= strchr(mask
, '@');
249 controlreply(sender
, "Mask must contain a username (e.g. user@ip).");
257 if (strchr(user
, '*') || strchr(user
, '?')) {
258 controlreply(sender
, "Usernames may not contain wildcards.");
262 if (!ipmask_parse(host
, &ip
, &bits
)) {
263 controlreply(sender
, "Invalid CIDR mask.");
267 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
269 glinebufinit(&gbuf
, 1);
270 glinebufaddbyip(&gbuf
, user
, &ip
, 128, 0, creator
, reason
, getnettime() + duration
, getnettime(), getnettime() + duration
);
271 glinebufcounthits(&gbuf
, &hits
, NULL
);
272 glinebufflush(&gbuf
, 1);
274 controlwall(NO_OPER
, NL_GLINES
, "%s GLINE'd mask '%s' for %s with reason '%s' (%d hits)",
275 controlid(sender
), cargv
[0], longtoduration(duration
, 0), reason
, hits
);
277 controlreply(sender
, "Done.");
282 static int glines_cmdungline(void *source
, int cargc
, char **cargv
) {
283 nick
*sender
= source
;
289 gl
= findgline(cargv
[0]);
292 controlreply(sender
, "No such G-Line.");
296 if (!(gl
->flags
& GLINE_ACTIVE
)) {
297 controlreply(sender
, "G-Line was already deactivated.");
301 gline_deactivate(gl
, 0, 1);
303 controlwall(NO_OPER
, NL_GLINES
, "%s UNGLINE'd mask '%s'", controlid(sender
), cargv
[0]);
305 controlreply(sender
, "G-Line deactivated.");
310 static int glines_cmdclearchan(void *source
, int cargc
, char **cargv
) {
311 nick
*sender
= source
;
314 char *reason
= "Clearing channel.";
315 int mode
, duration
, i
, slot
, hits
;
323 cp
= findchannel(cargv
[0]);
326 controlreply(sender
, "Couldn't find that channel.");
330 if (strcmp(cargv
[1], "kick") == 0)
332 else if (strcmp(cargv
[1], "kill") == 0)
334 else if (strcmp(cargv
[1], "gline") == 0)
336 else if (strcmp(cargv
[1], "glineall") == 0)
341 if (mode
== 0 || mode
== 1) {
343 rejoinline(cargv
[2], cargc
- 2);
350 duration
= durationtolong(cargv
[2]);
353 controlreply(sender
, "Invalid duration specified.");
357 if (duration
> MAXUSERGLINEDURATION
) {
358 controlreply(sender
, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION
, 0));
366 array_init(&victims
, sizeof(nick
*));
368 /* we need to make a list of the channel users here because
369 * kicking/killing them will affect their position in the channel's
371 for (i
= 0; i
< cp
->users
->hashsize
; i
++) {
372 if (cp
->users
->content
[i
] == nouser
)
375 np
= getnickbynumeric(cp
->users
->content
[i
]);
380 if (IsService(np
) || IsOper(np
) || NickOnServiceServer(np
))
383 slot
= array_getfreeslot(&victims
);
384 (((nick
**)victims
.content
)[slot
]) = np
;
387 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
389 glinebufinit(&gbuf
, 1);
391 for (i
= 0; i
< victims
.cursi
; i
++) {
392 np
= ((nick
**)victims
.content
)[i
];
396 localkickuser(NULL
, cp
, np
, reason
);
399 killuser(NULL
, np
, "%s", reason
);
406 glinebufaddbynick(&gbuf
, np
, 0, creator
, reason
, getnettime() + duration
, getnettime(), getnettime() + duration
);
413 glinebufcounthits(&gbuf
, &hits
, NULL
);
414 glinebufflush(&gbuf
, 1);
416 array_free(&victims
);
418 if (mode
== 0 || mode
== 1)
419 controlwall(NO_OPER
, NL_GLINES
, "%s CLEARCHAN'd channel '%s' with mode '%s' and reason '%s'",
420 controlid(sender
), cp
->index
->name
->content
, cargv
[1], reason
);
422 controlwall(NO_OPER
, NL_GLINES
, "%s CLEARCHAN'd channel '%s' with mode '%s', duration %s and reason '%s' (%d hits)",
423 controlid(sender
), cp
->index
->name
->content
, cargv
[1], longtoduration(duration
, 0), reason
, hits
);
425 controlreply(sender
, "Done.");
430 static int glines_cmdtrustgline(void *source
, int cargc
, char **cargv
) {
431 nick
*sender
= source
;
443 tg
= tg_strtotg(cargv
[0]);
445 if (!(tg
->flags
& TRUST_RELIABLE_USERNAME
)) {
446 controlreply(sender
, "Sorry, that trust group does not have the \"reliable username\" flag.");
450 duration
= durationtolong(cargv
[2]);
452 if (duration
<= 0 || duration
> MAXUSERGLINEDURATION
) {
453 controlreply(sender
, "Sorry, glines may not last longer than %s.", longtoduration(MAXUSERGLINEDURATION
, 0));
459 if (strlen(reason
) < MINUSERGLINEREASON
) {
460 controlreply(sender
, "Please specify a proper gline reason.");
464 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
466 glinebufinit(&gbuf
, 0);
468 for(th
= tg
->hosts
; th
; th
= th
->next
) {
469 snprintf(mask
, sizeof(mask
), "*!%s@%s", cargv
[1], trusts_cidr2str(&th
->ip
, th
->bits
));
470 glinebufadd(&gbuf
, mask
, creator
, reason
, getnettime() + duration
, getnettime(), getnettime() + duration
);
473 glinebufcounthits(&gbuf
, &hits
, NULL
);
474 glinebufflush(&gbuf
, 1);
476 controlwall(NO_OPER
, NL_GLINES
, "%s TRUSTGLINE'd user '%s' on trust group '%s' for %s with reason '%s' (%d hits)",
477 controlid(sender
), cargv
[1], tg
->name
->content
, longtoduration(duration
, 0), reason
, hits
);
479 controlreply(sender
, "Done.");
484 static int glines_cmdtrustungline(void *source
, int cargc
, char **cargv
) {
485 nick
*sender
= source
;
495 tg
= tg_strtotg(cargv
[0]);
497 if (!(tg
->flags
& TRUST_RELIABLE_USERNAME
)) {
498 controlreply(sender
, "Sorry, that trust group does not have the \"reliable username\" flag.");
504 for (th
= tg
->hosts
; th
; th
= th
->next
) {
505 snprintf(mask
, sizeof(mask
), "*!%s@%s", cargv
[1], trusts_cidr2str(&th
->ip
, th
->bits
));
507 gl
= findgline(mask
);
509 if (gl
&& (gl
->flags
& GLINE_ACTIVE
)) {
510 gline_deactivate(gl
, 0, 1);
515 controlwall(NO_OPER
, NL_GLINES
, "%s TRUSTUNGLINE'd user '%s' on trust group '%s' (%d G-Lines deactivated)",
516 controlid(sender
), cargv
[1], tg
->name
->content
, count
);
518 controlreply(sender
, "Done.");
523 static int glines_cmdglstats(void *source
, int cargc
, char **cargv
) {
524 nick
*sender
= (nick
*)source
;
526 time_t curtime
= getnettime();
527 int glinecount
= 0, hostglinecount
= 0, ipglinecount
= 0, badchancount
= 0, rnglinecount
= 0;
528 int deactivecount
= 0, activecount
= 0;
530 for (gl
= glinelist
; gl
; gl
= next
) {
533 if (gl
->lifetime
<= curtime
) {
536 } else if (gl
->expire
<= curtime
) {
537 gl
->flags
&= ~GLINE_ACTIVE
;
540 if (gl
->flags
& GLINE_ACTIVE
) {
546 if (gl
->flags
& GLINE_IPMASK
)
548 else if (gl
->flags
& GLINE_HOSTMASK
)
550 else if (gl
->flags
& GLINE_REALNAME
)
552 else if (gl
->flags
& GLINE_BADCHAN
)
557 controlreply(sender
, "Total G-Lines set: %d", glinecount
);
558 controlreply(sender
, "Hostmask G-Lines: %d", hostglinecount
);
559 controlreply(sender
, "IPMask G-Lines: %d", ipglinecount
);
560 controlreply(sender
, "Channel G-Lines: %d", badchancount
);
561 controlreply(sender
, "Realname G-Lines: %d", rnglinecount
);
563 controlreply(sender
, "Active G-Lines: %d", activecount
);
564 controlreply(sender
, "Inactive G-Lines: %d", deactivecount
);
566 /* TODO show top 10 creators here */
567 /* TODO show unique creators count */
568 /* TODO show glines per create %8.1f", ccount?((float)gcount/(float)ccount):0 */
572 static int glines_cmdglist(void *source
, int cargc
, char **cargv
) {
573 nick
*sender
= (nick
*)source
;
575 time_t curtime
= time(NULL
);
582 if (cargc
< 1 || (cargc
== 1 && cargv
[0][0] == '-')) {
583 controlreply(sender
, "Syntax: glist [-flags] <mask>");
584 controlreply(sender
, "Valid flags are:");
585 controlreply(sender
, "-c: Count G-Lines.");
586 controlreply(sender
, "-f: Find G-Lines active on <mask>.");
587 controlreply(sender
, "-x: Find G-Lines matching <mask> exactly.");
588 controlreply(sender
, "-R: Find G-lines on realnames.");
589 controlreply(sender
, "-o: Search for glines by owner.");
590 controlreply(sender
, "-r: Search for glines by reason.");
591 controlreply(sender
, "-i: Include inactive glines.");
606 flags
|= GLIST_COUNT
;
614 flags
|= GLIST_EXACT
;
618 flags
|= GLIST_REASON
;
621 flags
|= GLIST_OWNER
;
625 flags
|= GLIST_REALNAME
;
629 flags
|= GLIST_INACTIVE
;
633 controlreply(sender
, "Invalid flag '%c'.", *ch
);
642 if ((flags
& (GLIST_EXACT
|GLIST_FIND
)) == (GLIST_EXACT
|GLIST_FIND
)) {
643 controlreply(sender
, "You cannot use -x and -f flags together.");
647 if (!(flags
& GLIST_COUNT
))
648 controlreply(sender
, "%-50s %-19s %-25s %s", "Mask:", "Expires in:", "Creator:", "Reason:");
650 gline
*searchgl
= makegline(mask
);
652 for (gl
= glinelist
; gl
; gl
= next
) {
655 if (gl
->lifetime
<= curtime
) {
658 } else if (gl
->expire
<= curtime
) {
659 gl
->flags
&= ~GLINE_ACTIVE
;
662 if (!(gl
->flags
& GLINE_ACTIVE
)) {
663 if (!(flags
& GLIST_INACTIVE
)) {
668 if (flags
& GLIST_REALNAME
) {
669 if (!(gl
->flags
& GLINE_REALNAME
))
671 if (flags
& GLIST_EXACT
) {
672 if (!glineequal(searchgl
, gl
)) {
675 } else if (flags
& GLIST_FIND
) {
676 if (!gline_match_mask(searchgl
, gl
)) {
681 if (gl
->flags
& GLINE_REALNAME
)
684 if (flags
& GLIST_REASON
) {
685 if (flags
& GLIST_EXACT
) {
686 if (!gl
->reason
|| ircd_strcmp(mask
, gl
->reason
->content
) != 0)
688 } else if (flags
& GLIST_FIND
) {
689 if (!gl
->reason
|| match(gl
->reason
->content
, mask
))
691 } else if (!gl
->reason
|| match(mask
, gl
->reason
->content
))
693 } else if (flags
& GLIST_OWNER
) {
694 if (flags
& GLIST_EXACT
) {
695 if (!gl
->creator
|| ircd_strcmp(mask
, gl
->creator
->content
) != 0)
697 } else if (flags
& GLIST_FIND
) {
698 if (!gl
->creator
|| match(gl
->creator
->content
, mask
))
700 } else if (!gl
->creator
|| match(mask
, gl
->creator
->content
))
703 if (flags
& GLIST_EXACT
) {
704 if (!glineequal(searchgl
, gl
)) {
707 } else if (flags
& GLIST_FIND
) {
708 if (!gline_match_mask(searchgl
, gl
)) {
715 if (count
== limit
&& !(flags
& GLIST_COUNT
))
716 controlreply(sender
, "More than %d matches, list truncated.", limit
);
720 if (!(flags
& GLIST_COUNT
) && count
< limit
) {
721 snprintf(tmp
, 249, "%s", glinetostring(gl
));
722 controlreply(sender
, "%s%-49s %-19s %-25s %s",
723 (gl
->flags
& GLINE_ACTIVE
) ? "+" : "-",
725 (gl
->flags
& GLINE_ACTIVE
) ? (char*)longtoduration(gl
->expire
- curtime
, 0) : "<inactive>",
726 gl
->creator
? gl
->creator
->content
: "",
727 gl
->reason
? gl
->reason
->content
: "");
731 controlreply(sender
, "%s%d G-Line%s found.", (flags
& GLIST_COUNT
) ? "" : "End of list - ", count
, count
== 1 ? "" : "s");
736 static int glines_cmdcleanupglines(void *source
, int cargc
, char **cargv
) {
737 nick
*sender
= source
;
743 for (pnext
= &glinelist
; *pnext
; pnext
= &((*pnext
)->next
)) {
746 if (!(gl
->flags
& GLINE_ACTIVE
)) {
747 gline_destroy(gl
, 0, 1);
755 controlwall(NO_OPER
, NL_GLINES
, "%s CLEANUPGLINES'd %d G-Lines.",
756 controlid(sender
), count
);
758 controlreply(sender
, "Done.");
763 static int glines_cmdsyncglines(void *source
, int cargc
, char **cargv
) {
764 nick
*sender
= source
;
770 for (gl
= glinelist
; gl
; gl
= gl
->next
) {
775 controlwall(NO_OPER
, NL_GLINES
, "%s SYNCGLINE'd %d G-Lines.",
776 controlid(sender
), count
);
778 controlreply(sender
, "Done.");
783 static int glines_cmdsaveglines(void *source
, int cargc
, char **cargv
) {
784 nick
*sender
= source
;
787 count
= glstore_save();
790 controlreply(sender
, "An error occured while saving G-Lines.");
792 controlreply(sender
, "Saved %d G-Line%s.", count
, (count
== 1) ? "" : "s");
797 static int glines_cmdloadglines(void *source
, int cargc
, char **cargv
) {
798 nick
*sender
= source
;
801 count
= glstore_load();
804 controlreply(sender
, "An error occured while loading the G-Lines file.");
806 controlreply(sender
, "Loaded %d G-Line%s.", count
, (count
== 1) ? "" : "s");
811 static int commandsregistered
;
813 static void registercommands(int hooknum
, void *arg
) {
814 if (commandsregistered
)
816 commandsregistered
= 1;
818 registercontrolhelpcmd("block", NO_OPER
, 3, glines_cmdblock
, "Usage: block <nick> <duration> <reason>\nSets a gline using an appropriate mask given the user's nickname.");
819 registercontrolhelpcmd("rawgline", NO_OPER
, 3, glines_cmdrawgline
, "Usage: rawgline <mask> <duration> <reason>\nSets a gline. Does fewer sanity checks than \"gline\". Use with care.");
820 registercontrolhelpcmd("rawglinesimulate", NO_OPER
, 1, glines_cmdrawglinesimulate
, "Usage: rawglinesimulate <mask>\nSimulates what happens when a gline is set.");
821 registercontrolhelpcmd("gline", NO_OPER
, 3, glines_cmdgline
, "Usage: rawgline <mask> <duration> <reason>\nSets a gline.");
822 registercontrolhelpcmd("smartgline", NO_OPER
, 3, glines_cmdsmartgline
, "Usage: gline <user@host> <duration> <reason>\nSets a gline. Automatically adjusts the mask so as not to hit unrelated trusted users.");
823 registercontrolhelpcmd("ungline", NO_OPER
, 1, glines_cmdungline
, "Usage: ungline <mask>\nDeactivates a gline.");
824 registercontrolhelpcmd("clearchan", NO_OPER
, 4, glines_cmdclearchan
, "Usage: clearchan <#channel> <how> <duration> ?reason?\nClears a channel.\nhow can be one of:\nkick - Kicks users.\nkill - Kills users.\ngline - Glines non-authed users (using an appropriate mask).\nglineall - Glines users.\nDuration is only valid when glining users. Reason defaults to \"Clearing channel.\".");
825 registercontrolhelpcmd("trustgline", NO_OPER
, 4, glines_cmdtrustgline
, "Usage: trustgline <#id|name> <user> <duration> <reason>\nSets a gline on the specified username for each host in the specified trust group. The username may contain wildcards.");
826 registercontrolhelpcmd("trustungline", NO_OPER
, 2, glines_cmdtrustungline
, "Usage: trustungline <#id|name> <user>\nRemoves a gline that was previously set with trustgline.");
827 registercontrolhelpcmd("glstats", NO_OPER
, 0, glines_cmdglstats
, "Usage: glstat\nShows statistics about G-Lines.");
828 registercontrolhelpcmd("glist", NO_OPER
, 2, glines_cmdglist
, "Usage: glist [-flags] <mask>\nLists matching G-Lines.\nValid flags are:\n-c: Count G-Lines.\n-f: Find G-Lines active on <mask>.\n-x: Find G-Lines matching <mask> exactly.\n-R: Find G-lines on realnames.\n-o: Search for glines by owner.\n-r: Search for glines by reason.\n-i: Include inactive glines.");
829 registercontrolhelpcmd("cleanupglines", NO_OPER
, 0, glines_cmdcleanupglines
, "Usage: cleanupglines\nDestroys all deactivated G-Lines.");
830 registercontrolhelpcmd("syncglines", NO_DEVELOPER
, 0, glines_cmdsyncglines
, "Usage: syncglines\nSends all G-Lines to all other servers.");
831 registercontrolhelpcmd("loadglines", NO_DEVELOPER
, 0, glines_cmdloadglines
, "Usage: loadglines\nForce load of glines.");
832 registercontrolhelpcmd("saveglines", NO_DEVELOPER
, 0, glines_cmdsaveglines
, "Usage: saveglines\nForce save of glines.");
835 static void deregistercommands(int hooknum
, void *arg
) {
836 if (!commandsregistered
)
838 commandsregistered
= 0;
840 deregistercontrolcmd("block", glines_cmdblock
);
841 deregistercontrolcmd("rawgline", glines_cmdrawgline
);
842 deregistercontrolcmd("rawglinesimulate", glines_cmdrawglinesimulate
);
843 deregistercontrolcmd("gline", glines_cmdgline
);
844 deregistercontrolcmd("smartgline", glines_cmdsmartgline
);
845 deregistercontrolcmd("ungline", glines_cmdungline
);
846 deregistercontrolcmd("clearchan", glines_cmdclearchan
);
847 deregistercontrolcmd("trustgline", glines_cmdtrustgline
);
848 deregistercontrolcmd("trustungline", glines_cmdtrustungline
);
849 deregistercontrolcmd("glstats", glines_cmdglstats
);
850 deregistercontrolcmd("glist", glines_cmdglist
);
851 deregistercontrolcmd("cleanupglines", glines_cmdcleanupglines
);
852 deregistercontrolcmd("syncglines", glines_cmdsyncglines
);
853 deregistercontrolcmd("loadglines", glines_cmdloadglines
);
854 deregistercontrolcmd("saveglines", glines_cmdsaveglines
);
858 registerhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
859 registerhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
862 registercommands(0, NULL
);
866 deregisterhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
867 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
869 deregistercommands(0, NULL
);