]> git.donarmstrong.com Git - infobot.git/blobdiff - src/Modules/UserDCC.pl
* Add vim formatting comments ( # vim:ts=4:sw=4:expandtab:tw=80 )
[infobot.git] / src / Modules / UserDCC.pl
index 49c10f0fa2073ab5ab490a6ad6aa51f26dd74b34..d6c306bdd93f633369744239303de4e2d927ca8f 100644 (file)
@@ -22,7 +22,7 @@ sub userDCC {
     # quit.
     if ($message =~ /^(exit|quit)$/i) {
        # do ircII clients support remote close? if so, cool!
-       &status("userDCC: quit called. FIXME");
+       &FIXME("userDCC: quit called.");
        &dcc_close($who);
        &status("userDCC: after dcc_close!");
 
@@ -34,11 +34,11 @@ sub userDCC {
        my $count = scalar(keys %{ $dcc{'CHAT'} });
        my $dccCHAT = $message;
 
-       &pSReply("Start of who ($count users).");
+       &performStrictReply("Start of who ($count users).");
        foreach (keys %{ $dcc{'CHAT'} }) {
-           &pSReply("=> $_");
+           &performStrictReply("=> $_");
        }
-       &pSReply("End of who.");
+       &performStrictReply("End of who.");
 
        return;
     }
@@ -48,24 +48,24 @@ sub userDCC {
     if ($message =~ /^tellme(\s+(.*))?$/i) {
        my $args = $2;
        if ($args =~ /^\s*$/) {
-           &help("tellme");
+           &help('tellme');
            return;
        }
 
        my $result = &doQuestion($args);
-       &pSReply($result);
+       &performStrictReply($result);
 
        return;
     }
 
     # 4op.
     if ($message =~ /^4op(\s+($mask{chan}))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        my $chan = $2;
 
-       if ($chan eq "") {
-           &help("4op");
+       if ($chan eq '') {
+           &help('4op');
            return;
        }
 
@@ -84,15 +84,33 @@ sub userDCC {
        return;
     }
 
+    # opme.
+    if ($message =~ /^opme(\s+($mask{chan}))?$/i) {
+       return unless (&hasFlag('o'));
+       return unless (&hasFlag('A'));
+
+       my $chan = $2;
+
+       if ($chan eq '') {
+           &help('4op');
+           return;
+       }
+
+       # can this be exploited?
+       rawout("MODE $chan +o $who");
+
+       return;
+    }
+
     # backlog.
     if ($message =~ /^backlog(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&hasParam("backlog"));
+       return unless (&hasFlag('o'));
+       return unless (&IsParam('backlog'));
        my $num = $2;
        my $max = $param{'backlog'};
 
        if (!defined $num) {
-           &help("backlog");
+           &help('backlog');
            return;
        } elsif ($num !~ /^\d+/) {
            &msg($who, "error: argument is not positive integer.");
@@ -114,8 +132,8 @@ sub userDCC {
 
     # dump variables.
     if ($message =~ /^dumpvars$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&IsParam("dumpvars"));
+       return unless (&hasFlag('o'));
+       return unless (&IsParam('DumpVars'));
 
        &status("Dumping all variables...");
        &dumpallvars();
@@ -125,8 +143,8 @@ sub userDCC {
 
     # dump variables ][.
     if ($message =~ /^symdump$/i) {
-       return unless (&hasFlag("o"));
-       return unless (&IsParam("symdump"));
+       return unless (&hasFlag('o'));
+       return unless (&IsParam('DumpVars2'));
 
        &status("Dumping all variables...");
        &symdumpAllFile();
@@ -135,14 +153,17 @@ sub userDCC {
     }
 
     # kick.
-    if ($message =~ /^kick(\s+(\S+)(\s+(\S+))?)?/) {
-       return unless (&hasFlag("o"));
-       my ($nick,$chan) = (lc $2,lc $4);
+    if ($message =~ /^kick(\s+(.*?))$/) {
+       return unless (&hasFlag('o'));
+
+       my $arg = $2;
 
-       if ($nick eq "") {
-           &help("kick");
+       if ($arg eq '') {
+           &help('kick');
            return;
        }
+       my @args = split(/\s+/, $arg);
+       my ($nick,$chan,$reason) = @args;
 
        if (&validChan($chan) == 0) {
            &msg($who,"error: invalid channel \002$chan\002");
@@ -154,18 +175,18 @@ sub userDCC {
            return;
        }
 
-       &kick($nick,$chan);
+       &kick($nick,$chan,$reason);
 
        return;
     }
 
-    # kick.
+    # mode.
     if ($message =~ /^mode(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my ($chan,$mode) = split /\s+/,$2,2;
 
-       if ($chan eq "") {
-           &help("mode");
+       if ($chan eq '') {
+           &help('mode');
            return;
        }
 
@@ -186,12 +207,12 @@ sub userDCC {
 
     # part.
     if ($message =~ /^part(\s+(\S+))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $jchan = $2;
 
        if ($jchan !~ /^$mask{chan}$/) {
            &msg($who, "error, invalid chan.");
-           &help("part");
+           &help('part');
            return;
        }
 
@@ -207,12 +228,12 @@ sub userDCC {
 
     # lobotomy. sometimes we want the bot to be _QUIET_.
     if ($message =~ /^(lobotomy|bequiet)$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        if ($lobotomized) {
            &performReply("i'm already lobotomized");
        } else {
-           &performReply("i have been lobotomized");
+           &performReply('i have been lobotomized');
            $lobotomized = 1;
        }
 
@@ -221,10 +242,10 @@ sub userDCC {
 
     # unlobotomy.
     if ($message =~ /^(unlobotomy|benoisy)$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        if ($lobotomized) {
-           &performReply("i have been unlobotomized, woohoo");
+           &performReply('i have been unlobotomized, woohoo');
            $lobotomized = 0;
            delete $cache{lobotomy};
 #          undef $cache{lobotomy};     # ??
@@ -237,7 +258,7 @@ sub userDCC {
 
     # op.
     if ($message =~ /^op(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
@@ -263,17 +284,17 @@ sub userDCC {
            next unless (&IsNickInChan($opee,$_));
            $found++;
            if ($channels{$_}{'o'}{$opee}) {
-               &pSReply("op: $opee already has ops on $_");
+               &performStrictReply("op: $opee already has ops on $_");
                next;
            }
            $op++;
 
-           &pSReply("opping $opee on $_");
+           &performStrictReply("opping $opee on $_");
            &op($_, $opee);
        }
 
        if ($found != $op) {
-           &pSReply("op: opped on all possible channels.");
+           &performStrictReply("op: opped on all possible channels.");
        } else {
            &DEBUG("op: found => '$found'.");
            &DEBUG("op:    op => '$op'.");
@@ -284,7 +305,7 @@ sub userDCC {
 
     # deop.
     if ($message =~ /^deop(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($opee) = lc $2;
        my @chans;
 
@@ -331,21 +352,31 @@ sub userDCC {
 
     # say.
     if ($message =~ s/^say\s+(\S+)\s+(.*)//) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my ($chan,$msg) = (lc $1, $2);
+
        &DEBUG("chan => '$1', msg => '$msg'.");
 
-       if (&validChan($chan)) {
-           &msg($chan, $2);
-       } else {
-           &msg($who,"i'm not on \002$1\002, sorry.");
-       }
+       &msg($chan, $msg);
+
+       return;
+    }
+
+    # do.
+    if ($message =~ s/^do\s+(\S+)\s+(.*)//) {
+       return unless (&hasFlag('o'));
+       my ($chan,$msg) = (lc $1, $2);
+
+       &DEBUG("chan => '$1', msg => '$msg'.");
+
+       &action($chan, $msg);
+
        return;
     }
 
     # die.
     if ($message =~ /^die$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &doExit();
 
@@ -354,9 +385,9 @@ sub userDCC {
     }
 
     # global factoid substitution.
-    if ($message =~ m|^s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
+    if ($message =~ m|^\* =~ s([/,#])(.+?)\1(.*?)\1;?\s*$|) {
        my ($delim,$op,$np) = ($1, $2, $3);
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        ### TODO: support flags to do full-on global.
 
        # incorrect format.
@@ -365,10 +396,10 @@ sub userDCC {
            return;
        }
 
-       ### TODO: fix up $op to support mysql/sqlite/pgsql/dbm(perl)
+       ### TODO: fix up $op to support mysql/sqlite/pgsql
        ### TODO: => add db/sql specific function to fix this.
-       my @list = &searchTable("factoids", "factoid_key",
-                       "factoid_value", $op);
+       my @list = &searchTable('factoids', 'factoid_key',
+                       'factoid_value', $op);
 
        if (!scalar @list) {
            &performReply("Expression didn't match anything.");
@@ -381,7 +412,7 @@ sub userDCC {
        }
 
        &status("gsubst: going to alter ".scalar(@list)." factoids.");
-       &performReply("going to alter ".scalar(@list)." factoids.");
+       &performReply('going to alter '.scalar(@list)." factoids.");
 
        my $error = 0;
        foreach (@list) {
@@ -399,7 +430,7 @@ sub userDCC {
                    &performReply("that's too long (or was long)");
                    return;
                }
-               &setFactInfo($faqtoid, "factoid_value", $result);
+               &setFactInfo($faqtoid, 'factoid_value', $result);
                &status("update: '$faqtoid' =is=> '$result'; was '$was'");
            } else {
                &WARN("subst: that's weird... thought we found the string ($op) in '$faqtoid'.");
@@ -412,17 +443,17 @@ sub userDCC {
        }
 
        &performReply("Ok... did s/$op/$np/ for ".
-                               (scalar(@list) - $error)." factoids");
+                               (scalar(@list) - $error).' factoids');
 
        return;
     }
 
     # jump.
     if ($message =~ /^jump(\s+(\S+))?$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
-       if ($2 eq "") {
-           &help("jump");
+       if ($2 eq '') {
+           &help('jump');
            return;
        }
 
@@ -445,19 +476,19 @@ sub userDCC {
 
     # reload.
     if ($message =~ /^reload$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &status("USER reload $who");
-       &pSReply("reloading...");
+       &performStrictReply("reloading...");
        &reloadAllModules();
-       &pSReply("reloaded.");
+       &performStrictReply("reloaded.");
 
        return;
     }
 
     # reset.
     if ($message =~ /^reset$/i) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"resetting...");
        my @done;
@@ -470,26 +501,26 @@ sub userDCC {
            push(@done, $_);
            sleep 1;
        }
-       &DEBUG("before clearircvars");
+       &DEBUG('before clearircvars');
        &clearIRCVars();
-       &DEBUG("before joinnextchan");
+       &DEBUG('before joinnextchan');
        &joinNextChan();
-       &DEBUG("after joinnextchan");
+       &DEBUG('after joinnextchan');
 
        &status("USER reset $who");
-       &msg($who,"resetted");
+       &msg($who,'reset complete');
 
        return;
     }
 
     # rehash.
     if ($message =~ /^rehash$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        &msg($who,"rehashing...");
-       &restart("REHASH");
+       &restart('REHASH');
        &status("USER rehash $who");
-       &msg($who,"rehashed");
+       &msg($who,'rehashed');
 
        return;
     }
@@ -502,20 +533,20 @@ sub userDCC {
        my @args = split /[\s\t]+/, $2; # hrm.
 
        if (scalar @args != 1) {
-           &help("chaninfo");
+           &help('chaninfo');
            return;
        }
 
        if (!exists $chanconf{$args[0]}) {
-           &pSReply("no such channel $args[0]");
+           &performStrictReply("no such channel $args[0]");
            return;
        }
 
-       &pSReply("showing channel conf.");
+       &performStrictReply("showing channel conf.");
        foreach (sort keys %{ $chanconf{$args[0]} }) {
-           &pSReply("$chan: $_ => $chanconf{$args[0]}{$_}");
+           &performStrictReply("$chan: $_ => $chanconf{$args[0]}{$_}");
        }
-       &pSReply("End of chaninfo.");
+       &performStrictReply("End of chaninfo.");
 
        return;
     }
@@ -533,57 +564,69 @@ sub userDCC {
 
        my @chans;
        while ($args =~ s/^($mask{chan})\s*//) {
-           push(@chans, $1);
+           push(@chans, lc($1));
        }
 
        if (!scalar @chans) {
-           push(@chans, "_default");
+           push(@chans, '_default');
            $no_chan    = 1;
        }
 
        my($what,$val) = split /[\s\t]+/, $args, 2;
 
        ### TODO: "cannot set values without +m".
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
 
        # READ ONLY.
        if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) {
-           &pSReply("Showing $what values on all channels...");
+           &performStrictReply("Showing $what values on all channels...");
 
            my %vals;
            foreach (keys %chanconf) {
-               my $val = $chanconf{$_}{$what} || "NOT-SET";
+               my $val;
+               if (defined $chanconf{$_}{$what}) {
+                   $val = $chanconf{$_}{$what};
+               } else {
+                   $val = "NOT-SET";
+               }
                $vals{$val}{$_} = 1;
            }
 
            foreach (keys %vals) {
-               &pSReply("  $what = $_: ".join(' ', keys %{ $vals{$_} } ) );
+               &performStrictReply("  $what = $_(" . scalar(keys %{$vals{$_}}) . "): ".join(' ', sort keys %{ $vals{$_} } ) );
            }
 
-           &pSReply("End of list.");
+           &performStrictReply("End of list.");
 
            return;
        }
 
        ### TODO: move to UserDCC again.
-       if ($cmd eq "chanset" and !defined $what) {
+       if ($cmd eq 'chanset' and !defined $what) {
            &DEBUG("showing channel conf.");
 
-           foreach $chan ($chan, "_default") {
-               &pSReply("chan: $chan");
-               ### TODO: merge 2 or 3 per line.
+           foreach $chan (@chans) {
+               if ($chan eq '_default') {
+                   &performStrictReply('Default channel settings');
+               } else {
+                   &performStrictReply("chan: $chan (see _default also)");
+               }
                my @items;
-               my $str = "";
+               my $str = '';
                foreach (sort keys %{ $chanconf{$chan} }) {
                    my $newstr = join(', ', @items);
-                   if (length $newstr > 60) {
-                       &pSReply("    $str");
+                   ### TODO: make length use channel line limit?
+                   if (length $newstr > 370) {
+                       &performStrictReply(" $str");
                        @items = ();
                    }
                    $str = $newstr;
                    push(@items, "$_ => $chanconf{$chan}{$_}");
                }
-               &pSReply("    $str") if (@items);
+               if (@items) {
+                   my $str = join(', ', @items);
+                   &performStrictReply(" $str");
+               }
            }
            return;
        }
@@ -599,12 +642,12 @@ sub userDCC {
     }
 
     if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) {
-       return unless (&hasFlag("n"));
+       return unless (&hasFlag('n'));
        my $args        = $3;
        my $no_chan     = 0;
 
        if (!defined $args) {
-           &help("chanunset");
+           &help('chanunset');
            return;
        }
 
@@ -613,29 +656,28 @@ sub userDCC {
        if ($args =~ s/^(\-)?($mask{chan})\s*//) {
            $chan       = $2;
            $delete     = ($1) ? 1 : 0;
-           &DEBUG("chan => $chan.");
        } else {
            &VERB("no chan arg; setting to default.",2);
-           $chan       = "_default";
+           $chan       = '_default';
            $no_chan    = 1;
        }
 
        if (!exists $chanconf{$chan}) {
-           &pSReply("no such channel $chan");
+           &performStrictReply("no such channel $chan");
            return;
        }
 
-       if ($args ne "") {
+       if ($args ne '') {
 
            if (!&getChanConf($args,$chan)) {
-               &pSReply("$args does not exist for $chan");
+               &performStrictReply("$args does not exist for $chan");
                return;
            }
 
            my @chans = &ChanConfList($args);
            &DEBUG("scalar chans => ".scalar(@chans) );
-           if (scalar @chans == 1 and $chans[0] eq "_default" and !$no_chan) {
-               &psReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans.");
+           if (scalar @chans == 1 and $chans[0] eq '_default' and !$no_chan) {
+               &performStrictReply("ok, $args was set only for _default; unsetting for _defaul but setting for other chans.");
 
                my $val = $chanconf{$_}{_default};
                foreach (keys %chanconf) {
@@ -649,7 +691,7 @@ sub userDCC {
            }
 
            if ($no_chan and !exists($chanconf{_default}{$args})) {
-               &pSReply("ok, $args for _default does not exist, removing from all chans.");
+               &performStrictReply("ok, $args for _default does not exist, removing from all chans.");
 
                foreach (keys %chanconf) {
                    next unless (exists $chanconf{$_}{$args});
@@ -662,23 +704,23 @@ sub userDCC {
                return;
            }
 
-           &pSReply("Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})");
+           &performStrictReply("Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})");
            delete $chanconf{$chan}{$args};
 
            return;
        }
 
        if ($delete) {
-           &pSReply("Deleting channel $chan for sure!");
+           &performStrictReply("Deleting channel $chan for sure!");
            $utime_chanfile = time();
            $ucount_chanfile++;
 
            &part($chan);
-           &pSReply("Leaving $chan...");
+           &performStrictReply("Leaving $chan...");
 
            delete $chanconf{$chan};
        } else {
-           &pSReply("Prefix channel with '-' to delete for sure.");
+           &performStrictReply("Prefix channel with '-' to delete for sure.");
        }
 
        return;
@@ -688,14 +730,14 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (scalar @args != 1) {
-           &help("newpass");
+           &help('newpass');
            return;
        }
 
-       my $u           = &getUser($who);
-       my $crypt       = &mkcrypt($args[0]);
+       my $u = &getUser($who);
+       my $crypt = &mkcrypt($args[0]);
 
-       &pSReply("Set your passwd to '$crypt'");
+       &performStrictReply("Set your passwd to '$crypt'");
        $users{$u}{PASS} = $crypt;
 
        $utime_userfile = time();
@@ -708,33 +750,34 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chpass");
+           &help('chpass');
            return;
        }
 
        if (!&IsUser($args[0])) {
-           &pSReply("user $args[0] is not valid.");
+           &performStrictReply("user $args[0] is not valid.");
            return;
        }
 
        my $u = &getUser($args[0]);
        if (!defined $u) {
-           &pSReply("Internal error, u = NULL.");
+           &performStrictReply("Internal error, u = NULL.");
            return;
        }
 
-       if (scalar @args == 1) {        # del pass.
-           if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
-               &pSReply("cannot remove passwd of others.");
+       if (scalar @args == 1) {
+           # del pass.
+           if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
+               &performStrictReply("cannot remove passwd of others.");
                return;
            }
 
            if (!exists $users{$u}{PASS}) {
-               &pSReply("$u does not have pass set anyway.");
+               &performStrictReply("$u does not have pass set anyway.");
                return;
            }
 
-           &pSReply("Deleted pass from $u.");
+           &performStrictReply("Deleted pass from $u.");
 
            $utime_userfile = time();
            $ucount_userfile++;
@@ -745,7 +788,7 @@ sub userDCC {
        }
 
        my $crypt       = &mkcrypt($args[1]);
-       &pSReply("Set $u's passwd to '$crypt'");
+       &performStrictReply("Set $u's passwd to '$crypt'");
        $users{$u}{PASS} = $crypt;
 
        $utime_userfile = time();
@@ -758,16 +801,18 @@ sub userDCC {
        my(@args) = split /[\s\t]+/, $2 || '';
 
        if (!scalar @args) {
-           &help("chattr");
+           &help('chattr');
            return;
        }
 
        my $chflag;
        my $user;
-       if ($args[0] =~ /^$mask{nick}$/i) {     # <nick>
+       if ($args[0] =~ /^$mask{nick}$/i) {
+           # <nick>
            $user       = &getUser($args[0]);
            $chflag     = $args[1];
-       } else {                                # <flags>
+       } else {
+           # <flags>
            $user       = &getUser($who);
            &DEBUG("user $who... nope.") unless (defined $user);
            $user       = &getUser($verifyUser);
@@ -775,21 +820,21 @@ sub userDCC {
        }
 
        if (!defined $user) {
-           &pSReply("user does not exist.");
+           &performStrictReply("user does not exist.");
            return;
        }
 
        my $flags = $users{$user}{FLAGS};
        if (!defined $chflag) {
-           &pSReply("Flags for $user: $flags");
+           &performStrictReply("Flags for $user: $flags");
            return;
        }
 
        &DEBUG("who => $who");
        &DEBUG("verifyUser => $verifyUser");
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
-           &pSReply("cannto change attributes of others.");
-           return "REPLY";
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
+           &performStrictReply("cannto change attributes of others.");
+           return 'REPLY';
        }
 
        my $state;
@@ -799,7 +844,7 @@ sub userDCC {
            if ($_ eq "-") { $state = 0; next; }
 
            if (!defined $state) {
-               &pSReply("no initial + or - was found in attr.");
+               &performStrictReply("no initial + or - was found in attr.");
                return;
            }
 
@@ -807,11 +852,11 @@ sub userDCC {
                next if ($flags =~ /\Q$_\E/);
                $flags .= $_;
            } else {
-               if (&IsParam("owner")
+               if (&IsParam('owner')
                        and $param{owner} =~ /^\Q$user\E$/i
                        and $flags =~ /[nmo]/
                ) {
-                   &pSReply("not removing flag $_ for $user.");
+                   &performStrictReply("not removing flag $_ for $user.");
                    next;
                }
                next unless ($flags =~ s/\Q$_\E//);
@@ -823,10 +868,12 @@ sub userDCC {
        if ($change) {
            $utime_userfile = time();
            $ucount_userfile++;
-           &pSReply("Current flags: $flags");
+           #$flags.*FLAGS sort
+           $flags = join('', sort split('', $flags));
+           &performStrictReply("Current flags: $flags");
            $users{$user}{FLAGS} = $flags;
        } else {
-           &pSReply("No flags changed: $flags");
+           &performStrictReply("No flags changed: $flags");
        }
 
        return;
@@ -835,13 +882,13 @@ sub userDCC {
     if ($message =~ /^chnick(\s+(.*))?$/) {
        my(@args) = split /[\s\t]+/, $2 || '';
 
-       if ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run chnick.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        if (!scalar @args or scalar @args > 2) {
-           &help("chnick");
+           &help('chnick');
            return;
        }
 
@@ -856,23 +903,23 @@ sub userDCC {
        }
 
        if (!defined $user) {
-           &pSReply("user $who or $args[0] does not exist.");
+           &performStrictReply("user $who or $args[0] does not exist.");
            return;
        }
 
        if ($user =~ /^\Q$chnick\E$/i) {
-           &pSReply("user == chnick. why should I do that?");
+           &performStrictReply("user == chnick. why should I do that?");
            return;
        }
 
        if (&getUser($chnick)) {
-           &pSReply("user $chnick is already used!");
+           &performStrictReply("user $chnick is already used!");
            return;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
-           &pSReply("cannto change nick of others.");
-           return "REPLY" if ($who eq "_default");
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
+           &performStrictReply("cannto change nick of others.");
+           return 'REPLY' if ($who eq '_default');
            return;
        }
 
@@ -885,13 +932,13 @@ sub userDCC {
        $utime_userfile = time();
        $ucount_userfile++;
 
-       &pSReply("Changed '$user' to '$chnick' successfully.");
+       &performStrictReply("Changed '$user' to '$chnick' successfully.");
 
        return;
     }
 
     if ($message =~ /^([-+])host(\s+(.*))?$/) {
-       my $cmd         = $1."host";
+       my $cmd         = $1.'host';
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
 
@@ -900,61 +947,59 @@ sub userDCC {
            return;
        }
 
-       if ($who eq "_default") {
+       if ($who eq '_default') {
            &WARN("$who or verifyuser tried to run $cmd.");
-           return "REPLY";
+           return 'REPLY';
        }
 
        my ($user,$mask);
        if ($args[0] =~ /^$mask{nick}$/i) {     # <nick>
-           return unless (&hasFlag("n"));
+           return unless (&hasFlag('n'));
            $user       = &getUser($args[0]);
            $mask       = $args[1];
        } else {                                # <mask>
-           # who or verifyUser. FIXME (don't remember why)
+           # FIXME: who or verifyUser. (don't remember why)
            $user       = &getUser($who);
            $mask       = $args[0];
        }
 
        if (!defined $user) {
-           &pSReply("user $user does not exist.");
+           &performStrictReply("user $user does not exist.");
            return;
        }
 
        if (!defined $mask) {
-           ### FIXME.
-           &pSReply("Hostmasks for $user: $users{$user}{HOSTS}");
-
+           &performStrictReply("Hostmasks for $user: " . join(' ', keys %{$users{$user}{HOSTS}}));
            return;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
-           &pSReply("cannto change masks of others.");
-           return;
-       }
-
-       if ($mask !~ /^$mask{nuh}$/) {
-           &pSReply("error: mask ($mask) is not a real hostmask.");
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
+           &performStrictReply("cannto change masks of others.");
            return;
        }
 
        my $count = scalar keys %{ $users{$user}{HOSTS} };
 
        if ($state) {                           # add.
+           if ($mask !~ /^$mask{nuh}$/) {
+               &performStrictReply("error: mask ($mask) is not a real hostmask.");
+               return;
+           }
+
            if (exists $users{$user}{HOSTS}{$mask}) {
-               &pSReply("mask $mask already exists.");
+               &performStrictReply("mask $mask already exists.");
                return;
            }
 
            ### TODO: override support.
            $users{$user}{HOSTS}{$mask} = 1;
 
-           &pSReply("Added $mask to list of masks.");
+           &performStrictReply("Added $mask to list of masks.");
 
        } else {                                # delete.
 
            if (!exists $users{$user}{HOSTS}{$mask}) {
-               &pSReply("mask $mask does not exist.");
+               &performStrictReply("mask $mask does not exist.");
                return;
            }
 
@@ -962,9 +1007,9 @@ sub userDCC {
            delete $users{$user}{HOSTS}{$mask};
 
            if (scalar keys %{ $users{$user}{HOSTS} } != $count) {
-               &pSReply("Removed $mask from list of masks.");
+               &performStrictReply("Removed $mask from list of masks.");
            } else {
-               &pSReply("error: could not find $mask in list of masks.");
+               &performStrictReply("error: could not find $mask in list of masks.");
                return;
            }
        }
@@ -976,7 +1021,7 @@ sub userDCC {
     }
 
     if ($message =~ /^([-+])ban(\s+(.*))?$/) {
-       my $cmd         = $1."ban";
+       my $cmd         = $1.'ban';
        my $flatarg     = $3;
        my(@args)       = split /[\s\t]+/, $3 || '';
        my $state       = ($1 eq "+") ? 1 : 0;
@@ -997,7 +1042,7 @@ sub userDCC {
        if ($flatarg =~ s/^($mask{chan})\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";        # _default instead?
+           $chan = '*';        # _default instead?
        }
 
        if ($state == 0) {              # delete.
@@ -1008,9 +1053,9 @@ sub userDCC {
            }
 
            if (@c) {
-               &pSReply("Removed $mask from chans: @c");
+               &performStrictReply("Removed $mask from chans: @c");
            } else {
-               &pSReply("$mask was not found in ban list.");
+               &performStrictReply("$mask was not found in ban list.");
            }
 
            return;
@@ -1025,7 +1070,7 @@ sub userDCC {
            $time = $1;
            &DEBUG("time = $time.");
            if ($time < 0) {
-               &pSReply("error: time cannot be negatime?");
+               &performStrictReply("error: time cannot be negatime?");
                return;
            }
        } else {
@@ -1036,20 +1081,20 @@ sub userDCC {
            $reason     = $1;
        }
 
-       if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) {
-           &pSReply("cannto change masks of others.");
+       if (!&IsFlag('n') and $who !~ /^\Q$verifyUser\E$/i) {
+           &performStrictReply("cannto change masks of others.");
            return;
        }
 
        if ($mask !~ /^$mask{nuh}$/) {
-           &pSReply("error: mask ($mask) is not a real hostmask.");
+           &performStrictReply("error: mask ($mask) is not a real hostmask.");
            return;
        }
 
        if ( &banAdd($mask,$chan,$time,$reason) == 2) {
-           &pSReply("ban already exists; overwriting.");
+           &performStrictReply("ban already exists; overwriting.");
        }
-       &pSReply("Added $mask for $chan (time => $time, reason => $reason)");
+       &performStrictReply("Added $mask for $chan (time => $time, reason => $reason)");
 
        return;
     }
@@ -1058,33 +1103,33 @@ sub userDCC {
        my $arg = $2;
 
        if (!defined $arg) {
-           &help("whois");
+           &help('whois');
            return;
        }
 
        my $user = &getUser($arg);
        if (!defined $user) {
-           &pSReply("whois: user $user does not exist.");
+           &performStrictReply("whois: user $user does not exist.");
            return;
        }
 
        ### TODO: better (eggdrop-like) output.
-       &pSReply("user: $user");
+       &performStrictReply("user: $user");
        foreach (keys %{ $users{$user} }) {
            my $ref = ref $users{$user}{$_};
 
-           if ($ref eq "HASH") {
+           if ($ref eq 'HASH') {
                my $type = $_;
                ### DOES NOT WORK???
                foreach (keys %{ $users{$user}{$type} }) {
-                   &pSReply("    $type => $_");
+                   &performStrictReply("    $type => $_");
                }
                next;
            }
 
-           &pSReply("    $_ => $users{$user}{$_}");
+           &performStrictReply("    $_ => $users{$user}{$_}");
        }
-       &pSReply("End of USER whois.");
+       &performStrictReply("End of USER whois.");
 
        return;
     }
@@ -1093,35 +1138,35 @@ sub userDCC {
        my $arg = $2;
 
        if (defined $arg) {
-           if ($arg ne "_default" and !&validChan($arg) ) {
-               &pSReply("error: chan $chan is invalid.");
+           if ($arg ne '_default' and !&validChan($arg) ) {
+               &performStrictReply("error: chan $chan is invalid.");
                return;
            }
        }
 
        if (!scalar keys %bans) {
-           &pSReply("Ban list is empty.");
+           &performStrictReply("Ban list is empty.");
            return;
        }
 
        my $c;
-       &pSReply("     mask: expire, time-added, count, who-by, reason");
+       &performStrictReply("     mask: expire, time-added, count, who-by, reason");
        foreach $c (keys %bans) {
            next unless (!defined $arg or $arg =~ /^\Q$c\E$/i);
-           &pSReply("  $c:");
+           &performStrictReply("  $c:");
 
            foreach (keys %{ $bans{$c} }) {
                my $val = $bans{$c}{$_};
 
-               if (ref $val eq "ARRAY") {
+               if (ref $val eq 'ARRAY') {
                    my @array = @{ $val };
-                   &pSReply("    $_: @array");
+                   &performStrictReply("    $_: @array");
                } else {
                    &DEBUG("unknown ban: $val");
                }
            }
        }
-       &pSReply("END of bans.");
+       &performStrictReply("END of bans.");
 
        return;
     }
@@ -1130,7 +1175,7 @@ sub userDCC {
        my $arg = $2;
 
        if (defined $arg and $arg !~ /^$mask{chan}$/) {
-           &pSReply("error: chan $chan is invalid.");
+           &performStrictReply("error: chan $chan is invalid.");
            return;
        }
 
@@ -1140,17 +1185,17 @@ sub userDCC {
        }
 
        &DEBUG("End of bans.");
-       &pSReply("END of bans.");
+       &performStrictReply("END of bans.");
 
        return;
     }
 
     if ($message =~ /^save$/) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
 
        &writeUserFile();
        &writeChanFile();
-       &News::writeNews() if (&ChanConfList("news"));
+       &performStrictReply('saved user and chan files');
 
        return;
     }
@@ -1161,9 +1206,9 @@ sub userDCC {
 
     # ignore.
     if ($message =~ /^(\+|\-)ignore(\s+(.*))?$/i) {
-       return unless (&hasFlag("o"));
+       return unless (&hasFlag('o'));
        my $state       = ($1 eq "+") ? 1 : 0;
-       my $str         = $1."ignore";
+       my $str         = $1.'ignore';
        my $args        = $3;
 
        if (!$args) {
@@ -1183,9 +1228,9 @@ sub userDCC {
 
        if (!$state) {                  # delignore.
            if ( &ignoreDel($mask) ) {
-               &pSReply("ok, deleted X ignores.");
+               &performStrictReply("ok, deleted ignores for $mask.");
            } else {
-               &pSReply("could not find $mask in ignore list.");
+               &performStrictReply("could not find $mask in ignore list.");
            }
            return;
        }
@@ -1198,12 +1243,12 @@ sub userDCC {
        if ($args =~ s/^($mask{chan}|\*)\s*//) {
            $chan = $1;
        } else {
-           $chan = "*";
+           $chan = '*';
        }
 
        # time.
        if ($args =~ s/^(\d+)\s*//) {
-           $time = $1*60;      # ??
+           $time = $1; # time is in minutes
        } else {
            $time = 0;
        }
@@ -1216,9 +1261,9 @@ sub userDCC {
        }
 
        if ( &ignoreAdd($mask, $chan, $time, $comment) > 1) {
-           &pSReply("warn: $mask already in ignore list; written over anyway. FIXME");
+           &performStrictReply("FIXME: $mask already in ignore list; written over anyway.");
        } else {
-           &pSReply("added $mask to ignore list.");
+           &performStrictReply("added $mask to ignore list.");
        }
 
        return;
@@ -1229,111 +1274,112 @@ sub userDCC {
 
        if (defined $arg) {
            if ($arg !~ /^$mask{chan}$/) {
-               &pSReply("error: chan $chan is invalid.");
+               &performStrictReply("error: chan $chan is invalid.");
                return;
            }
 
            if (!&validChan($arg)) {
-               &pSReply("error: chan $arg is invalid.");
+               &performStrictReply("error: chan $arg is invalid.");
                return;
            }
 
-           &pSReply("Showing bans for $arg only.");
+           &performStrictReply("Showing bans for $arg only.");
        }
 
        if (!scalar keys %ignore) {
-           &pSReply("Ignore list is empty.");
+           &performStrictReply("Ignore list is empty.");
            return;
        }
 
        ### TODO: proper (eggdrop-like) formatting.
        my $c;
-       &pSReply("    mask: expire, time-added, who, comment");
+       &performStrictReply("    mask: expire, time-added, who, comment");
        foreach $c (keys %ignore) {
            next unless (!defined $arg or $arg =~ /^\Q$c\E$/i);
-           &pSReply("  $c:");
+           &performStrictReply("  $c:");
 
            foreach (keys %{ $ignore{$c} }) {
                my $ref = ref $ignore{$c}{$_};
-               if ($ref eq "ARRAY") {
+               if ($ref eq 'ARRAY') {
                    my @array = @{ $ignore{$c}{$_} };
-                   &pSReply("      $_: @array");
+                   &performStrictReply("      $_: @array");
                } else {
                    &DEBUG("unknown ignore line?");
                }
            }
        }
-       &pSReply("END of ignore.");
+       &performStrictReply("END of ignore.");
 
        return;
     }
 
     # adduser/deluser.
-    if ($message =~ /^(\+|\-|add|del)user(\s+(.*))?$/i) {
+    if ($message =~ /^(add|del)user(\s+(.*))?$/i) {
        my $str         = $1;
-       my $strstr      = $1."user";
+       my $strstr      = $1.'user';
        my @args        = split /\s+/, $3 || '';
        my $args        = $3;
-       my $state       = ($str =~ /^(\+|add)$/) ? 1 : 0;
+       my $state       = ($str =~ /^(add)$/) ? 1 : 0;
 
        if (!scalar @args) {
            &help($strstr);
            return;
        }
 
-       if ($str eq "+") {
+       if ($str eq 'add') {
            if (scalar @args != 2) {
-               &pSReply(".+host requires hostmask argument.");
+               &performStrictReply('adduser requires hostmask argument.');
                return;
            }
        } elsif (scalar @args != 1) {
-           &pSReply("too many arguments.");
+           &performStrictReply('too many arguments.');
            return;
        }
 
-       if ($state) {                   # adduser.
+       if ($state) {
+           # adduser.
            if (scalar @args == 1) {
                $args[1]        = &getHostMask($args[0]);
-               &pSReply("Attemping to guess $args[0]'s hostmask...");
+               &performStrictReply("Attemping to guess $args[0]'s hostmask...");
 
                # crude hack... crappy Net::IRC
                $conn->schedule(5, sub {
-       # hopefully this is right.
-       my $nick = (keys %{ $cache{nuhInfo} })[0];
-       if (!defined $nick) {
-           &pSReply("couldn't get nuhinfo... adding user without a hostmask.");
-           &userAdd($nick);
-           return;
-       }
-
-       my $mask = &makeHostMask( $cache{nuhInfo}{$nick}{NUH} );
+                   # hopefully this is right.
+                   my $nick = (keys %{ $cache{nuhInfo} })[0];
+                   if (!defined $nick) {
+                       &performStrictReply("couldn't get nuhinfo... adding user without a hostmask.");
+                       &userAdd($nick);
+                       return;
+                   }
+                   my $mask = &makeHostMask( $cache{nuhInfo}{$nick}{NUH} );
 
-       if ( &userAdd($nick, $mask) ) { # success.
-               &pSReply("Added $nick with flags $users{$nick}{FLAGS}");
-               my @hosts = keys %{ $users{$nick}{HOSTS} };
-               &pSReply("hosts: @hosts");
-       }
-});
+                   if ( &userAdd($nick, $mask) ) {
+                       # success.
+                       &performStrictReply("Added $nick with flags $users{$nick}{FLAGS}");
+                       my @hosts = keys %{ $users{$nick}{HOSTS} };
+                       &performStrictReply("hosts: @hosts");
+                   }
+               });
                return;
            }
 
            &DEBUG("args => @args");
            if ( &userAdd(@args) ) {    # success.
-               &pSReply("Added $args[0] with flags $users{$args[0]}{FLAGS}");
+               &performStrictReply("Added $args[0] with flags $users{$args[0]}{FLAGS}");
                my @hosts = keys %{ $users{$args[0]}{HOSTS} };
-               &pSReply("hosts: @hosts");
+               &performStrictReply("hosts: @hosts");
 
            } else {                    # failure.
-               &pSReply("User $args[0] already exists");
+               &performStrictReply("User $args[0] already exists");
            }
 
        } else {                        # deluser.
 
            if ( &userDel($args[0]) ) { # success.
-               &pSReply("Deleted $args[0] successfully.");
+               &performStrictReply("Deleted $args[0] successfully.");
 
            } else {                    # failure.
-               &pSReply("User $args[0] does not exist.");
+               &performStrictReply("User $args[0] does not exist.");
            }
 
        }
@@ -1356,24 +1402,23 @@ sub userDCC {
 
        my @time;
        foreach (sort { $a <=> $b } keys %time) {
-           my $str = join(", ", sort keys %{ $time{$_} });
+           my $str = join(', ', sort keys %{ $time{$_} });
            &DEBUG("time => $_, str => $str");
            push(@time, "$str (".&Time2String($_).")");
        }
 
-       &pSReply( &formListReply(0, "Schedulers: ", @time ) );
-       &pSReply( &formListReply(0, "Scheds to run: ", sort @list ) );
-       &pSReply( &formListReply(0, "Scheds running(should not happen?) ", sort @run ) );
+       &performStrictReply( &formListReply(0, "Schedulers: ", @time ) );
+       &performStrictReply( &formListReply(0, "Scheds to run: ", sort @list ) );
+       &performStrictReply( &formListReply(0, "Scheds running(should not happen?) ", sort @run ) );
 
        return;
     }
 
     # quite a cool hack: reply in DCC CHAT.
-    $msgType = "chat";
+    $msgType = 'chat' if (exists $dcc{'CHAT'}{$who});
 
     my $done = 0;
-    $done++ if &parseCmdHook("main", $message);
-    $done++ if &parseCmdHook("extra", $message);
+    $done++ if &parseCmdHook($message);
     $done++ unless (&Modules());
 
     if ($done) {
@@ -1381,7 +1426,9 @@ sub userDCC {
        return;
     }
 
-    return "REPLY";
+    return 'REPLY';
 }
 
 1;
+
+# vim:ts=4:sw=4:expandtab:tw=80