2 # UserDCC.pl: User Commands, DCC CHAT.
4 # Version: v0.2 (20010119)
5 # Created: 20000707 (from UserExtra.pl)
10 use vars qw(%users %ignore %sched %bans %mask %cache %channels %param
12 use vars qw($who $chan $message $msgType $user $chnick $conn $ident
13 $verifyUser $ucount_userfile $utime_userfile $lobotomized
14 $utime_chanfile $ucount_chanfile);
15 use vars qw(@backlog);
24 if ( $message =~ /^(exit|quit)$/i ) {
26 # do ircII clients support remote close? if so, cool!
27 &FIXME("userDCC: quit called.");
29 &status("userDCC: after dcc_close!");
35 if ( $message =~ /^who$/ ) {
36 my $count = scalar( keys %{ $dcc{'CHAT'} } );
37 my $dccCHAT = $message;
39 &performStrictReply("Start of who ($count users).");
40 foreach ( keys %{ $dcc{'CHAT'} } ) {
41 &performStrictReply("=> $_");
43 &performStrictReply("End of who.");
48 ### for those users with enough flags.
50 if ( $message =~ /^tellme(\s+(.*))?$/i ) {
52 if ( $args =~ /^\s*$/ ) {
57 my $result = &doQuestion($args);
58 &performStrictReply($result);
64 if ( $message =~ /^4op(\s+($mask{chan}))?$/i ) {
65 return unless ( &hasFlag('o') );
74 if ( !$channels{$chan}{'o'}{$ident} ) {
75 &msg( $who, "i don't have ops on $chan to do that." );
79 # on non-4mode(<4) servers, this may be exploited.
80 if ( $channels{$chan}{'o'}{$who} ) {
81 rawout( "MODE $chan -o+o-o+o" . ( " $who" x 4 ) );
84 rawout( "MODE $chan +o-o+o-o" . ( " $who" x 4 ) );
91 if ( $message =~ /^opme(\s+($mask{chan}))?$/i ) {
92 return unless ( &hasFlag('o') );
93 return unless ( &hasFlag('A') );
102 # can this be exploited?
103 rawout("MODE $chan +o $who");
109 if ( $message =~ /^backlog(\s+(.*))?$/i ) {
110 return unless ( &hasFlag('o') );
111 return unless ( &IsParam('backlog') );
113 my $max = $param{'backlog'};
115 if ( !defined $num ) {
119 elsif ( $num !~ /^\d+/ ) {
120 &msg( $who, "error: argument is not positive integer." );
123 elsif ( $num > $max or $num < 0 ) {
124 &msg( $who, "error: argument is out of range (max $max)." );
128 &msg( $who, "Start of backlog..." );
129 for ( 0 .. $num - 1 ) {
130 sleep 1 if ( $_ % 4 == 0 and $_ != 0 );
131 $conn->privmsg( $who,
132 "[" . ( $_ + 1 ) . "]: $backlog[$max-$num+$_]" );
134 &msg( $who, "End of backlog." );
140 if ( $message =~ /^dumpvars$/i ) {
141 return unless ( &hasFlag('o') );
142 return unless ( &IsParam('DumpVars') );
144 &status("Dumping all variables...");
151 if ( $message =~ /^symdump$/i ) {
152 return unless ( &hasFlag('o') );
153 return unless ( &IsParam('DumpVars2') );
155 &status("Dumping all variables...");
162 if ( $message =~ /^kick(\s+(.*?))$/ ) {
163 return unless ( &hasFlag('o') );
171 my @args = split( /\s+/, $arg );
172 my ( $nick, $chan, $reason ) = @args;
174 if ( &validChan($chan) == 0 ) {
175 &msg( $who, "error: invalid channel \002$chan\002" );
179 if ( &IsNickInChan( $nick, $chan ) == 0 ) {
180 &msg( $who, "$nick is not in $chan." );
184 &kick( $nick, $chan, $reason );
190 if ( $message =~ /^mode(\s+(.*))?$/ ) {
191 return unless ( &hasFlag('n') );
192 my ( $chan, $mode ) = split /\s+/, $2, 2;
199 if ( &validChan($chan) == 0 ) {
200 &msg( $who, "error: invalid channel \002$chan\002" );
204 if ( !$channels{$chan}{o}{$ident} ) {
205 &msg( $who, "error: don't have ops on \002$chan\002" );
209 &mode( $chan, $mode );
215 if ( $message =~ /^part(\s+(\S+))?$/i ) {
216 return unless ( &hasFlag('o') );
219 if ( $jchan !~ /^$mask{chan}$/ ) {
220 &msg( $who, "error, invalid chan." );
225 if ( !&validChan($jchan) ) {
226 &msg( $who, "error, I'm not on that chan." );
230 &msg( $jchan, "Leaving. (courtesy of $who)." );
235 # lobotomy. sometimes we want the bot to be _QUIET_.
236 if ( $message =~ /^(lobotomy|bequiet)$/i ) {
237 return unless ( &hasFlag('o') );
240 &performReply("i'm already lobotomized");
243 &performReply('i have been lobotomized');
251 if ( $message =~ /^(unlobotomy|benoisy)$/i ) {
252 return unless ( &hasFlag('o') );
255 &performReply('i have been unlobotomized, woohoo');
257 delete $cache{lobotomy};
259 # undef $cache{lobotomy}; # ??
262 &performReply("i'm not lobotomized");
269 if ( $message =~ /^op(\s+(.*))?$/i ) {
270 return unless ( &hasFlag('o') );
274 if ( $opee =~ / / ) {
275 if ( $opee =~ /^(\S+)\s+(\S+)$/ ) {
278 if ( !&validChan($2) ) {
279 &msg( $who, "error: invalid chan ($2)." );
284 &msg( $who, "error: invalid params." );
289 @chans = keys %channels;
295 next unless ( &IsNickInChan( $opee, $_ ) );
297 if ( $channels{$_}{'o'}{$opee} ) {
298 &performStrictReply("op: $opee already has ops on $_");
303 &performStrictReply("opping $opee on $_");
307 if ( $found != $op ) {
308 &performStrictReply("op: opped on all possible channels.");
311 &DEBUG("op: found => '$found'.");
312 &DEBUG("op: op => '$op'.");
319 if ( $message =~ /^deop(\s+(.*))?$/i ) {
320 return unless ( &hasFlag('o') );
324 if ( $opee =~ / / ) {
325 if ( $opee =~ /^(\S+)\s+(\S+)$/ ) {
328 if ( !&validChan($2) ) {
329 &msg( $who, "error: invalid chan ($2)." );
334 &msg( $who, "error: invalid params." );
339 @chans = keys %channels;
345 next unless ( &IsNickInChan( $opee, $_ ) );
347 if ( !exists $channels{$_}{'o'}{$opee} ) {
348 &status("deop: $opee already has no ops on $_");
353 &status("deopping $opee on $_ at ${who}'s request");
357 if ( $found != $op ) {
358 &status("deop: deopped on all possible channels.");
361 &DEBUG("deop: found => '$found'.");
362 &DEBUG("deop: op => '$op'.");
369 if ( $message =~ s/^say\s+(\S+)\s+(.*)// ) {
370 return unless ( &hasFlag('o') );
371 my ( $chan, $msg ) = ( lc $1, $2 );
373 &DEBUG("chan => '$1', msg => '$msg'.");
381 if ( $message =~ s/^do\s+(\S+)\s+(.*)// ) {
382 return unless ( &hasFlag('o') );
383 my ( $chan, $msg ) = ( lc $1, $2 );
385 &DEBUG("chan => '$1', msg => '$msg'.");
387 &action( $chan, $msg );
393 if ( $message =~ /^die$/ ) {
394 return unless ( &hasFlag('n') );
398 &status("Dying by $who\'s request");
402 # global factoid substitution.
403 if ( $message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$| ) {
404 my ( $delim, $op, $np ) = ( $1, $2, $3 );
405 return unless ( &hasFlag('n') );
406 ### TODO: support flags to do full-on global.
409 if ( $np =~ /$delim/ ) {
411 "looks like you used the delimiter too many times. You may want to use a different delimiter, like ':' or '#'."
416 ### TODO: fix up $op to support mysql/sqlite/pgsql
417 ### TODO: => add db/sql specific function to fix this.
419 &searchTable( 'factoids', 'factoid_key', 'factoid_value', $op );
421 if ( !scalar @list ) {
422 &performReply("Expression didn't match anything.");
426 if ( scalar @list > 100 ) {
427 &performReply("regex found more than 100 matches... not doing.");
431 &status( "gsubst: going to alter " . scalar(@list) . " factoids." );
432 &performReply( 'going to alter ' . scalar(@list) . " factoids." );
438 next if ( &IsLocked($faqtoid) == 1 );
439 my $result = &getFactoid($faqtoid);
441 &DEBUG("was($faqtoid) => '$was'.");
444 # we could support global local (once off).
445 if ( $result =~ s/\Q$op/$np/gi ) {
446 if ( length $result > $param{'maxDataSize'} ) {
447 &performReply("that's too long (or was long)");
450 &setFactInfo( $faqtoid, 'factoid_value', $result );
451 &status("update: '$faqtoid' =is=> '$result'; was '$was'");
455 "subst: that's weird... thought we found the string ($op) in '$faqtoid'."
462 &ERROR("Some warnings/errors?");
465 &performReply( "Ok... did s/$op/$np/ for "
466 . ( scalar(@list) - $error )
473 if ( $message =~ /^jump(\s+(\S+))?$/i ) {
474 return unless ( &hasFlag('n') );
481 my ( $server, $port );
482 if ( $2 =~ /^(\S+)(:(\d+))?$/ ) {
487 &msg( $who, "invalid format." );
491 &status("jumping servers... $server...");
492 $conn->quit("jumping to $server");
494 if ( &irc( $server, $port ) == 0 ) {
500 if ( $message =~ /^reload$/i ) {
501 return unless ( &hasFlag('n') );
503 &status("USER reload $who");
504 &performStrictReply("reloading...");
506 &performStrictReply("reloaded.");
512 if ( $message =~ /^reset$/i ) {
513 return unless ( &hasFlag('n') );
515 &msg( $who, "resetting..." );
517 foreach ( keys %channels, keys %chanconf ) {
519 next if ( grep /^\Q$c\E$/i, @done );
526 &DEBUG('before clearircvars');
528 &DEBUG('before joinnextchan');
530 &DEBUG('after joinnextchan');
532 &status("USER reset $who");
533 &msg( $who, 'reset complete' );
539 if ( $message =~ /^rehash$/ ) {
540 return unless ( &hasFlag('n') );
542 &msg( $who, "rehashing..." );
544 &status("USER rehash $who");
545 &msg( $who, 'rehashed' );
551 ##### USER//CHAN SPECIFIC CONFIGURATION COMMANDS
554 if ( $message =~ /^chaninfo(\s+(.*))?$/ ) {
555 my @args = split /[\s\t]+/, $2; # hrm.
557 if ( scalar @args != 1 ) {
562 if ( !exists $chanconf{ $args[0] } ) {
563 &performStrictReply("no such channel $args[0]");
567 &performStrictReply("showing channel conf.");
568 foreach ( sort keys %{ $chanconf{ $args[0] } } ) {
569 &performStrictReply("$chan: $_ => $chanconf{$args[0]}{$_}");
571 &performStrictReply("End of chaninfo.");
577 if ( $message =~ /^(chanset|\+chan)(\s+(.*?))?$/ ) {
582 if ( !defined $args ) {
588 while ( $args =~ s/^($mask{chan})\s*// ) {
589 push( @chans, lc($1) );
592 if ( !scalar @chans ) {
593 push( @chans, '_default' );
597 my ( $what, $val ) = split /[\s\t]+/, $args, 2;
599 ### TODO: "cannot set values without +m".
600 return unless ( &hasFlag('n') );
603 if ( defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan )
605 &performStrictReply("Showing $what values on all channels...");
608 foreach ( keys %chanconf ) {
610 if ( defined $chanconf{$_}{$what} ) {
611 $val = $chanconf{$_}{$what};
619 foreach ( keys %vals ) {
620 &performStrictReply( " $what = $_("
621 . scalar( keys %{ $vals{$_} } ) . "): "
622 . join( ' ', sort keys %{ $vals{$_} } ) );
625 &performStrictReply("End of list.");
630 ### TODO: move to UserDCC again.
631 if ( $cmd eq 'chanset' and !defined $what ) {
632 &DEBUG("showing channel conf.");
634 foreach $chan (@chans) {
635 if ( $chan eq '_default' ) {
636 &performStrictReply('Default channel settings');
639 &performStrictReply("chan: $chan (see _default also)");
643 foreach ( sort keys %{ $chanconf{$chan} } ) {
644 my $newstr = join( ', ', @items );
645 ### TODO: make length use channel line limit?
646 if ( length $newstr > 370 ) {
647 &performStrictReply(" $str");
651 push( @items, "$_ => $chanconf{$chan}{$_}" );
654 my $str = join( ', ', @items );
655 &performStrictReply(" $str");
661 $cache{confvars}{$what} = $val;
665 &chanSet( $cmd, $_, $what, $val );
671 if ( $message =~ /^(chanunset|\-chan)(\s+(.*))?$/ ) {
672 return unless ( &hasFlag('n') );
676 if ( !defined $args ) {
683 if ( $args =~ s/^(\-)?($mask{chan})\s*// ) {
685 $delete = ($1) ? 1 : 0;
688 &VERB( "no chan arg; setting to default.", 2 );
693 if ( !exists $chanconf{$chan} ) {
694 &performStrictReply("no such channel $chan");
700 if ( !&getChanConf( $args, $chan ) ) {
701 &performStrictReply("$args does not exist for $chan");
705 my @chans = &ChanConfList($args);
706 &DEBUG( "scalar chans => " . scalar(@chans) );
707 if ( scalar @chans == 1 and $chans[0] eq '_default' and !$no_chan )
710 "ok, $args was set only for _default; unsetting for _defaul but setting for other chans."
713 my $val = $chanconf{$_}{_default};
714 foreach ( keys %chanconf ) {
715 $chanconf{$_}{$args} = $val;
717 delete $chanconf{_default}{$args};
718 $cache{confvars}{$args} = 0;
724 if ( $no_chan and !exists( $chanconf{_default}{$args} ) ) {
726 "ok, $args for _default does not exist, removing from all chans."
729 foreach ( keys %chanconf ) {
730 next unless ( exists $chanconf{$_}{$args} );
731 &DEBUG("delete chanconf{$_}{$args};");
732 delete $chanconf{$_}{$args};
734 $cache{confvars}{$args} = 0;
741 "Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})"
743 delete $chanconf{$chan}{$args};
749 &performStrictReply("Deleting channel $chan for sure!");
750 $utime_chanfile = time();
754 &performStrictReply("Leaving $chan...");
756 delete $chanconf{$chan};
759 &performStrictReply("Prefix channel with '-' to delete for sure.");
765 if ( $message =~ /^newpass(\s+(.*))?$/ ) {
766 my (@args) = split /[\s\t]+/, $2 || '';
768 if ( scalar @args != 1 ) {
773 my $u = &getUser($who);
774 my $crypt = &mkcrypt( $args[0] );
776 &performStrictReply("Set your passwd to '$crypt'");
777 $users{$u}{PASS} = $crypt;
779 $utime_userfile = time();
785 if ( $message =~ /^chpass(\s+(.*))?$/ ) {
786 my (@args) = split /[\s\t]+/, $2 || '';
788 if ( !scalar @args ) {
793 if ( !&IsUser( $args[0] ) ) {
794 &performStrictReply("user $args[0] is not valid.");
798 my $u = &getUser( $args[0] );
800 &performStrictReply("Internal error, u = NULL.");
804 if ( scalar @args == 1 ) {
807 if ( !&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i ) {
808 &performStrictReply("cannot remove passwd of others.");
812 if ( !exists $users{$u}{PASS} ) {
813 &performStrictReply("$u does not have pass set anyway.");
817 &performStrictReply("Deleted pass from $u.");
819 $utime_userfile = time();
822 delete $users{$u}{PASS};
827 my $crypt = &mkcrypt( $args[1] );
828 &performStrictReply("Set $u's passwd to '$crypt'");
829 $users{$u}{PASS} = $crypt;
831 $utime_userfile = time();
837 if ( $message =~ /^chattr(\s+(.*))?$/ ) {
838 my (@args) = split /[\s\t]+/, $2 || '';
840 if ( !scalar @args ) {
847 if ( $args[0] =~ /^$mask{nick}$/i ) {
850 $user = &getUser( $args[0] );
856 $user = &getUser($who);
857 &DEBUG("user $who... nope.") unless ( defined $user );
858 $user = &getUser($verifyUser);
862 if ( !defined $user ) {
863 &performStrictReply("user does not exist.");
867 my $flags = $users{$user}{FLAGS};
868 if ( !defined $chflag ) {
869 &performStrictReply("Flags for $user: $flags");
873 &DEBUG("who => $who");
874 &DEBUG("verifyUser => $verifyUser");
875 if ( !&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i ) {
876 &performStrictReply("cannto change attributes of others.");
882 foreach ( split //, $chflag ) {
883 if ( $_ eq "+" ) { $state = 1; next; }
884 if ( $_ eq "-" ) { $state = 0; next; }
886 if ( !defined $state ) {
887 &performStrictReply("no initial + or - was found in attr.");
892 next if ( $flags =~ /\Q$_\E/ );
896 if ( &IsParam('owner')
897 and $param{owner} =~ /^\Q$user\E$/i
898 and $flags =~ /[nmo]/ )
900 &performStrictReply("not removing flag $_ for $user.");
903 next unless ( $flags =~ s/\Q$_\E// );
910 $utime_userfile = time();
914 $flags = join( '', sort split( '', $flags ) );
915 &performStrictReply("Current flags: $flags");
916 $users{$user}{FLAGS} = $flags;
919 &performStrictReply("No flags changed: $flags");
925 if ( $message =~ /^chnick(\s+(.*))?$/ ) {
926 my (@args) = split /[\s\t]+/, $2 || '';
928 if ( $who eq '_default' ) {
929 &WARN("$who or verifyuser tried to run chnick.");
933 if ( !scalar @args or scalar @args > 2 ) {
938 if ( scalar @args == 1 ) { # 1
939 $user = &getUser($who);
940 &DEBUG("nope, not $who.") unless ( defined $user );
941 $user ||= &getUser($verifyUser);
945 $user = &getUser( $args[0] );
949 if ( !defined $user ) {
950 &performStrictReply("user $who or $args[0] does not exist.");
954 if ( $user =~ /^\Q$chnick\E$/i ) {
955 &performStrictReply("user == chnick. why should I do that?");
959 if ( &getUser($chnick) ) {
960 &performStrictReply("user $chnick is already used!");
964 if ( !&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i ) {
965 &performStrictReply("cannto change nick of others.");
966 return 'REPLY' if ( $who eq '_default' );
970 foreach ( keys %{ $users{$user} } ) {
971 $users{$chnick}{$_} = $users{$user}{$_};
972 delete $users{$user}{$_};
974 undef $users{$user}; # ???
976 $utime_userfile = time();
979 &performStrictReply("Changed '$user' to '$chnick' successfully.");
984 if ( $message =~ /^([-+])host(\s+(.*))?$/ ) {
985 my $cmd = $1 . 'host';
986 my (@args) = split /[\s\t]+/, $3 || '';
987 my $state = ( $1 eq "+" ) ? 1 : 0;
989 if ( !scalar @args ) {
994 if ( $who eq '_default' ) {
995 &WARN("$who or verifyuser tried to run $cmd.");
1000 if ( $args[0] =~ /^$mask{nick}$/i ) { # <nick>
1001 return unless ( &hasFlag('n') );
1002 $user = &getUser( $args[0] );
1006 # FIXME: who or verifyUser. (don't remember why)
1007 $user = &getUser($who);
1011 if ( !defined $user ) {
1012 &performStrictReply("user $user does not exist.");
1016 if ( !defined $mask ) {
1017 &performStrictReply( "Hostmasks for $user: "
1018 . join( ' ', keys %{ $users{$user}{HOSTS} } ) );
1022 if ( !&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i ) {
1023 &performStrictReply("cannto change masks of others.");
1027 my $count = scalar keys %{ $users{$user}{HOSTS} };
1029 if ($state) { # add.
1030 if ( $mask !~ /^$mask{nuh}$/ ) {
1031 &performStrictReply(
1032 "error: mask ($mask) is not a real hostmask.");
1036 if ( exists $users{$user}{HOSTS}{$mask} ) {
1037 &performStrictReply("mask $mask already exists.");
1041 ### TODO: override support.
1042 $users{$user}{HOSTS}{$mask} = 1;
1044 &performStrictReply("Added $mask to list of masks.");
1049 if ( !exists $users{$user}{HOSTS}{$mask} ) {
1050 &performStrictReply("mask $mask does not exist.");
1054 ### TODO: wildcard support. ?
1055 delete $users{$user}{HOSTS}{$mask};
1057 if ( scalar keys %{ $users{$user}{HOSTS} } != $count ) {
1058 &performStrictReply("Removed $mask from list of masks.");
1061 &performStrictReply(
1062 "error: could not find $mask in list of masks.");
1067 $utime_userfile = time();
1073 if ( $message =~ /^([-+])ban(\s+(.*))?$/ ) {
1074 my $cmd = $1 . 'ban';
1076 my (@args) = split /[\s\t]+/, $3 || '';
1077 my $state = ( $1 eq "+" ) ? 1 : 0;
1079 if ( !scalar @args ) {
1084 my ( $mask, $chan, $time, $reason );
1086 if ( $flatarg =~ s/^($mask{nuh})\s*// ) {
1090 &DEBUG("arg does not contain nuh mask?");
1093 if ( $flatarg =~ s/^($mask{chan})\s*// ) {
1097 $chan = '*'; # _default instead?
1100 if ( $state == 0 ) { # delete.
1101 my @c = &banDel($mask);
1104 &unban( $mask, $_ );
1108 &performStrictReply("Removed $mask from chans: @c");
1111 &performStrictReply("$mask was not found in ban list.");
1122 if ( $flatarg =~ s/^(\d+)\s*// ) {
1124 &DEBUG("time = $time.");
1126 &performStrictReply("error: time cannot be negatime?");
1134 if ( $flatarg =~ s/^(.*)$// ) { # need length?
1138 if ( !&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i ) {
1139 &performStrictReply("cannto change masks of others.");
1143 if ( $mask !~ /^$mask{nuh}$/ ) {
1144 &performStrictReply("error: mask ($mask) is not a real hostmask.");
1148 if ( &banAdd( $mask, $chan, $time, $reason ) == 2 ) {
1149 &performStrictReply("ban already exists; overwriting.");
1151 &performStrictReply(
1152 "Added $mask for $chan (time => $time, reason => $reason)");
1157 if ( $message =~ /^whois(\s+(.*))?$/ ) {
1160 if ( !defined $arg ) {
1165 my $user = &getUser($arg);
1166 if ( !defined $user ) {
1167 &performStrictReply("whois: user $user does not exist.");
1171 ### TODO: better (eggdrop-like) output.
1172 &performStrictReply("user: $user");
1173 foreach ( keys %{ $users{$user} } ) {
1174 my $ref = ref $users{$user}{$_};
1176 if ( $ref eq 'HASH' ) {
1178 ### DOES NOT WORK???
1179 foreach ( keys %{ $users{$user}{$type} } ) {
1180 &performStrictReply(" $type => $_");
1185 &performStrictReply(" $_ => $users{$user}{$_}");
1187 &performStrictReply("End of USER whois.");
1192 if ( $message =~ /^bans(\s+(.*))?$/ ) {
1195 if ( defined $arg ) {
1196 if ( $arg ne '_default' and !&validChan($arg) ) {
1197 &performStrictReply("error: chan $chan is invalid.");
1202 if ( !scalar keys %bans ) {
1203 &performStrictReply("Ban list is empty.");
1208 &performStrictReply(
1209 " mask: expire, time-added, count, who-by, reason");
1210 foreach $c ( keys %bans ) {
1211 next unless ( !defined $arg or $arg =~ /^\Q$c\E$/i );
1212 &performStrictReply(" $c:");
1214 foreach ( keys %{ $bans{$c} } ) {
1215 my $val = $bans{$c}{$_};
1217 if ( ref $val eq 'ARRAY' ) {
1218 my @array = @{$val};
1219 &performStrictReply(" $_: @array");
1222 &DEBUG("unknown ban: $val");
1226 &performStrictReply("END of bans.");
1231 if ( $message =~ /^banlist(\s+(.*))?$/ ) {
1234 if ( defined $arg and $arg !~ /^$mask{chan}$/ ) {
1235 &performStrictReply("error: chan $chan is invalid.");
1239 &DEBUG("bans for global or arg => $arg.");
1240 foreach ( keys %bans ) { #CHANGE!!!
1241 &DEBUG(" $_ => $bans{$_}.");
1244 &DEBUG("End of bans.");
1245 &performStrictReply("END of bans.");
1250 if ( $message =~ /^save$/ ) {
1251 return unless ( &hasFlag('o') );
1255 &performStrictReply('saved user and chan files');
1261 $message =~ s/^addignore/+ignore/;
1262 $message =~ s/^(del|un)ignore/-ignore/;
1265 if ( $message =~ /^(\+|\-)ignore(\s+(.*))?$/i ) {
1266 return unless ( &hasFlag('o') );
1267 my $state = ( $1 eq "+" ) ? 1 : 0;
1268 my $str = $1 . 'ignore';
1276 my ( $mask, $chan, $time, $comment );
1279 if ( $args =~ s/^($mask{nuh})\s*// ) {
1283 &ERROR("no NUH mask?");
1287 if ( !$state ) { # delignore.
1288 if ( &ignoreDel($mask) ) {
1289 &performStrictReply("ok, deleted ignores for $mask.");
1292 &performStrictReply("could not find $mask in ignore list.");
1302 if ( $args =~ s/^($mask{chan}|\*)\s*// ) {
1310 if ( $args =~ s/^(\d+)\s*// ) {
1311 $time = $1; # time is in minutes
1322 $comment = "added by $who";
1325 if ( &ignoreAdd( $mask, $chan, $time, $comment ) > 1 ) {
1326 &performStrictReply(
1327 "FIXME: $mask already in ignore list; written over anyway.");
1330 &performStrictReply("added $mask to ignore list.");
1336 if ( $message =~ /^ignore(\s+(.*))?$/ ) {
1339 if ( defined $arg ) {
1340 if ( $arg !~ /^$mask{chan}$/ ) {
1341 &performStrictReply("error: chan $chan is invalid.");
1345 if ( !&validChan($arg) ) {
1346 &performStrictReply("error: chan $arg is invalid.");
1350 &performStrictReply("Showing bans for $arg only.");
1353 if ( !scalar keys %ignore ) {
1354 &performStrictReply("Ignore list is empty.");
1358 ### TODO: proper (eggdrop-like) formatting.
1360 &performStrictReply(" mask: expire, time-added, who, comment");
1361 foreach $c ( keys %ignore ) {
1362 next unless ( !defined $arg or $arg =~ /^\Q$c\E$/i );
1363 &performStrictReply(" $c:");
1365 foreach ( keys %{ $ignore{$c} } ) {
1366 my $ref = ref $ignore{$c}{$_};
1367 if ( $ref eq 'ARRAY' ) {
1368 my @array = @{ $ignore{$c}{$_} };
1369 &performStrictReply(" $_: @array");
1372 &DEBUG("unknown ignore line?");
1376 &performStrictReply("END of ignore.");
1382 if ( $message =~ /^(add|del)user(\s+(.*))?$/i ) {
1384 my $strstr = $1 . 'user';
1385 my @args = split /\s+/, $3 || '';
1387 my $state = ( $str =~ /^(add)$/ ) ? 1 : 0;
1389 if ( !scalar @args ) {
1394 if ( $str eq 'add' ) {
1395 if ( scalar @args != 2 ) {
1396 &performStrictReply('adduser requires hostmask argument.');
1400 elsif ( scalar @args != 1 ) {
1401 &performStrictReply('too many arguments.');
1408 if ( scalar @args == 1 ) {
1409 $args[1] = &getHostMask( $args[0] );
1410 &performStrictReply(
1411 "Attemping to guess $args[0]'s hostmask...");
1413 # crude hack... crappy Net::IRC
1418 # hopefully this is right.
1419 my $nick = ( keys %{ $cache{nuhInfo} } )[0];
1420 if ( !defined $nick ) {
1421 &performStrictReply(
1422 "couldn't get nuhinfo... adding user without a hostmask."
1427 my $mask = &makeHostMask( $cache{nuhInfo}{$nick}{NUH} );
1429 if ( &userAdd( $nick, $mask ) ) {
1432 &performStrictReply(
1433 "Added $nick with flags $users{$nick}{FLAGS}");
1434 my @hosts = keys %{ $users{$nick}{HOSTS} };
1435 &performStrictReply("hosts: @hosts");
1442 &DEBUG("args => @args");
1443 if ( &userAdd(@args) ) { # success.
1444 &performStrictReply(
1445 "Added $args[0] with flags $users{$args[0]}{FLAGS}");
1446 my @hosts = keys %{ $users{ $args[0] }{HOSTS} };
1447 &performStrictReply("hosts: @hosts");
1451 &performStrictReply("User $args[0] already exists");
1457 if ( &userDel( $args[0] ) ) { # success.
1458 &performStrictReply("Deleted $args[0] successfully.");
1462 &performStrictReply("User $args[0] does not exist.");
1469 if ( $message =~ /^sched$/ ) {
1474 foreach ( keys %sched ) {
1475 next unless ( exists $sched{$_}{TIME} );
1476 $time{ $sched{$_}{TIME} - time() }{$_} = 1;
1479 next unless ( exists $sched{$_}{RUNNING} );
1484 foreach ( sort { $a <=> $b } keys %time ) {
1485 my $str = join( ', ', sort keys %{ $time{$_} } );
1486 &DEBUG("time => $_, str => $str");
1487 push( @time, "$str (" . &Time2String($_) . ")" );
1490 &performStrictReply( &formListReply( 0, "Schedulers: ", @time ) );
1491 &performStrictReply(
1492 &formListReply( 0, "Scheds to run: ", sort @list ) );
1493 &performStrictReply(
1495 0, "Scheds running(should not happen?) ",
1503 # quite a cool hack: reply in DCC CHAT.
1504 $msgType = 'chat' if ( exists $dcc{'CHAT'}{$who} );
1507 $done++ if &parseCmdHook($message);
1508 $done++ unless ( &Modules() );
1511 &DEBUG("running non DCC CHAT command inside DCC CHAT!");
1520 # vim:ts=4:sw=4:expandtab:tw=80