X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FModules%2FUserDCC.pl;h=49a91723dfd1c4f3d067396a3314cb1e621fa11f;hb=73555fc86ddc2021610ab944855b11d1c19816e6;hp=5085751469422c0bb487097f2838aa53ce888316;hpb=310818956c54751bc88e31f324a2aeb5fe0e3da4;p=infobot.git diff --git a/src/Modules/UserDCC.pl b/src/Modules/UserDCC.pl index 5085751..49a9172 100644 --- a/src/Modules/UserDCC.pl +++ b/src/Modules/UserDCC.pl @@ -5,7 +5,14 @@ # Created: 20000707 (from UserExtra.pl) # -if (&IsParam("useStrict")) { use strict; } +use strict; + +use vars qw(%users %ignore %sched %bans %mask %cache %channels %param + %chanconf %dcc); +use vars qw($who $chan $message $msgType $user $chnick $conn $ident + $verifyUser $ucount_userfile $utime_userfile $lobotomized + $utime_chanfile $ucount_chanfile); +use vars qw(@backlog); sub userDCC { # hrm... @@ -15,20 +22,20 @@ 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("hrmm...."); + &status("userDCC: after dcc_close!"); return; } # who. if ($message =~ /^who$/) { - my $count = scalar(keys %{$dcc{'CHAT'}}); + my $count = scalar(keys %{ $dcc{'CHAT'} }); my $dccCHAT = $message; &pSReply("Start of who ($count users)."); - foreach (keys %{$dcc{'CHAT'}}) { + foreach (keys %{ $dcc{'CHAT'} }) { &pSReply("=> $_"); } &pSReply("End of who."); @@ -38,6 +45,19 @@ sub userDCC { ### for those users with enough flags. + if ($message =~ /^tellme(\s+(.*))?$/i) { + my $args = $2; + if ($args =~ /^\s*$/) { + &help("tellme"); + return; + } + + my $result = &doQuestion($args); + &pSReply($result); + + return; + } + # 4op. if ($message =~ /^4op(\s+($mask{chan}))?$/i) { return unless (&hasFlag("o")); @@ -95,7 +115,7 @@ sub userDCC { # dump variables. if ($message =~ /^dumpvars$/i) { return unless (&hasFlag("o")); - return '' unless (&IsParam("dumpvars")); + return unless (&IsParam("dumpvars")); &status("Dumping all variables..."); &dumpallvars(); @@ -103,15 +123,29 @@ sub userDCC { return; } + # dump variables ][. + if ($message =~ /^symdump$/i) { + return unless (&hasFlag("o")); + return unless (&IsParam("symdump")); + + &status("Dumping all variables..."); + &symdumpAllFile(); + + return; + } + # kick. - if ($message =~ /^kick(\s+(\S+)(\s+(\S+))?)?/) { + if ($message =~ /^kick(\s+(.*?))$/) { return unless (&hasFlag("o")); - my ($nick,$chan) = (lc $2,lc $4); - if ($nick eq "") { + my $arg = $2; + + 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"); @@ -123,14 +157,14 @@ sub userDCC { return; } - &kick($nick,$chan); + &kick($nick,$chan,$reason); return; } - # kick. + # mode. if ($message =~ /^mode(\s+(.*))?$/) { - return unless (&hasFlag("m")); + return unless (&hasFlag("n")); my ($chan,$mode) = split /\s+/,$2,2; if ($chan eq "") { @@ -191,12 +225,16 @@ sub userDCC { # unlobotomy. if ($message =~ /^(unlobotomy|benoisy)$/i) { return unless (&hasFlag("o")); + if ($lobotomized) { &performReply("i have been unlobotomized, woohoo"); $lobotomized = 0; + delete $cache{lobotomy}; +# undef $cache{lobotomy}; # ?? } else { &performReply("i'm not lobotomized"); } + return; } @@ -228,21 +266,20 @@ sub userDCC { next unless (&IsNickInChan($opee,$_)); $found++; if ($channels{$_}{'o'}{$opee}) { - &status("op: $opee already has ops on $_"); + &pSReply("op: $opee already has ops on $_"); next; } $op++; - &status("opping $opee on $_ at ${who}'s request"); &pSReply("opping $opee on $_"); &op($_, $opee); } if ($found != $op) { - &status("op: opped on all possible channels."); + &pSReply("op: opped on all possible channels."); } else { - &DEBUG("found => '$found'."); - &DEBUG("op => '$op'."); + &DEBUG("op: found => '$found'."); + &DEBUG("op: op => '$op'."); } return; @@ -299,13 +336,16 @@ sub userDCC { if ($message =~ s/^say\s+(\S+)\s+(.*)//) { return unless (&hasFlag("o")); my ($chan,$msg) = (lc $1, $2); + &DEBUG("chan => '$1', msg => '$msg'."); + # TODO: add nick destination. if (&validChan($chan)) { - &msg($chan, $2); + &msg($chan, $msg); } else { - &msg($who,"i'm not on \002$1\002, sorry."); + &msg($who,"i'm not on \002$chan\002, sorry."); } + return; } @@ -331,7 +371,7 @@ sub userDCC { return; } - ### TODO: fix up $op to support mysql/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); @@ -402,7 +442,7 @@ sub userDCC { } &status("jumping servers... $server..."); - &rawout("QUIT :jumping to $server"); + $conn->quit("jumping to $server"); if (&irc($server,$port) == 0) { &ircloop(); @@ -421,6 +461,33 @@ sub userDCC { return; } + # reset. + if ($message =~ /^reset$/i) { + return unless (&hasFlag("n")); + + &msg($who,"resetting..."); + my @done; + foreach ( keys %channels, keys %chanconf ) { + my $c = $_; + next if (grep /^\Q$c\E$/i, @done); + + &part($_); + + push(@done, $_); + sleep 1; + } + &DEBUG("before clearircvars"); + &clearIRCVars(); + &DEBUG("before joinnextchan"); + &joinNextChan(); + &DEBUG("after joinnextchan"); + + &status("USER reset $who"); + &msg($who,"reset complete"); + + return; + } + # rehash. if ($message =~ /^rehash$/) { return unless (&hasFlag("n")); @@ -470,122 +537,82 @@ sub userDCC { return; } - my $chan; - if ($args =~ s/^($mask{chan})\s*//) { - $chan = $1; - } else { - $chan = "_default"; + my @chans; + while ($args =~ s/^($mask{chan})\s*//) { + push(@chans, lc($1)); + } + + if (!scalar @chans) { + push(@chans, "_default"); $no_chan = 1; } my($what,$val) = split /[\s\t]+/, $args, 2; ### TODO: "cannot set values without +m". - return unless (&hasFlag("m")); - - if ($cmd eq "+chan") { - &DEBUG("setting _time_added..."); - $chanconf{$chan}{_time_added} = time(); - - &pSReply("Joining $chan..."); - &joinchan($chan); - - return; - } - - if (!exists $chanconf{$chan}) { - &pSReply("no such channel $chan"); - return; - } - - my $update = 0; - ### TODO: $what can be undefined. fix it! - if ($what =~ s/^\+(\S+)/$1/) { - my $was = $chanconf{$chan}{$1}; - if ($was eq "1") { - &pSReply("setting $what for $chan already 1."); - return; - } - - $was = ($was) ? "; was '$was'" : ""; - &pSReply("Setting $what for $chan to '1'$was."); - - $chanconf{$chan}{$what} = 1; + return unless (&hasFlag("n")); - $update++; - } elsif ($what =~ s/^\-(\S+)/$1/) { - my $was = $chanconf{$chan}{$1}; - # hrm... - if (!defined $was) { - &pSReply("setting $1 for $chan is not set."); - return; - } + # READ ONLY. + if (defined $what and $what !~ /^[-+]/ and !defined $val and $no_chan) { + &pSReply("Showing $what values on all channels..."); - if ($was eq "0") { - &pSReply("setting $1 for $chan already 0."); - return; + my %vals; + foreach (keys %chanconf) { + my $val; + if (defined $chanconf{$_}{$what}) { + $val = $chanconf{$_}{$what}; + } else { + $val = "NOT-SET"; + } + $vals{$val}{$_} = 1; } - $was = ($was) ? "; was '$was'" : ""; - &pSReply("Setting $what for $chan to '0'$was."); - - $chanconf{$chan}{$what} = 0; - - $update++; - } elsif (defined $val) { - my $was = $chanconf{$chan}{$what}; - if ($was eq $val) { - &pSReply("setting $1 for $chan already '$val'."); - return; + foreach (keys %vals) { + &pSReply(" $what = $_: ".join(' ', keys %{ $vals{$_} } ) ); } - $was = ($was) ? "; was '$was'" : ""; - &pSReply("Setting $what for $chan to '$val'$was."); - - $chanconf{$chan}{$what} = $val; - $update++; - } elsif (defined $what) { - if (exists $chanconf{$chan}{$what}) { - &pSReply("$what for $chan is '$chanconf{$chan}{$what}'"); - } else { - &pSReply("$what for $chan is not set.'"); - } - } + &pSReply("End of list."); - if ($update) { - $utime_chanfile = time(); - $ucount_chanfile++; return; } + ### TODO: move to UserDCC again. 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) { + &pSReply("chan: $chan (will also use _default)"); my @items; 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 > 400) { + &pSReply(" $str"); @items = (); } $str = $newstr; push(@items, "$_ => $chanconf{$chan}{$_}"); } + &pSReply(" $str") if (@items); } - return; } + $cache{confvars}{$what} = $val; + &rehashConfVars(); + + foreach (@chans) { + &chanSet($cmd, $_, $what, $val); + } + return; } if ($message =~ /^(chanunset|\-chan)(\s+(.*))?$/) { - return unless (&hasFlag("m")); + return unless (&hasFlag("n")); my $args = $3; + my $no_chan = 0; if (!defined $args) { &help("chanunset"); @@ -597,10 +624,10 @@ sub userDCC { if ($args =~ s/^(\-)?($mask{chan})\s*//) { $chan = $2; $delete = ($1) ? 1 : 0; - &DEBUG("chan => $chan."); } else { - &DEBUG("no chan arg; setting to default."); + &VERB("no chan arg; setting to default.",2); $chan = "_default"; + $no_chan = 1; } if (!exists $chanconf{$chan}) { @@ -609,14 +636,45 @@ sub userDCC { } if ($args ne "") { - if (&getChanConf($args,$chan)) { - &pSReply("Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})"); - delete $chanconf{$chan}{$args}; - } else { + if (!&getChanConf($args,$chan)) { &pSReply("$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."); + + my $val = $chanconf{$_}{_default}; + foreach (keys %chanconf) { + $chanconf{$_}{$args} = $val; + } + delete $chanconf{_default}{$args}; + $cache{confvars}{$args} = 0; + &rehashConfVars(); + + return; + } + + if ($no_chan and !exists($chanconf{_default}{$args})) { + &pSReply("ok, $args for _default does not exist, removing from all chans."); + + foreach (keys %chanconf) { + next unless (exists $chanconf{$_}{$args}); + &DEBUG("delete chanconf{$_}{$args};"); + delete $chanconf{$_}{$args}; + } + $cache{confvars}{$args} = 0; + &rehashConfVars(); + + return; } + &pSReply("Unsetting channel ($chan) option $args. (was $chanconf{$chan}{$args})"); + delete $chanconf{$chan}{$args}; + return; } @@ -636,6 +694,25 @@ sub userDCC { return; } + if ($message =~ /^newpass(\s+(.*))?$/) { + my(@args) = split /[\s\t]+/, $2 || ''; + + if (scalar @args != 1) { + &help("newpass"); + return; + } + + my $u = &getUser($who); + my $crypt = &mkcrypt($args[0]); + + &pSReply("Set your passwd to '$crypt'"); + $users{$u}{PASS} = $crypt; + + $utime_userfile = time(); + $ucount_userfile++; + + return; + } if ($message =~ /^chpass(\s+(.*))?$/) { my(@args) = split /[\s\t]+/, $2 || ''; @@ -650,11 +727,15 @@ sub userDCC { return; } - my $u = &getUser($who); + my $u = &getUser($args[0]); + if (!defined $u) { + &pSReply("Internal error, u = NULL."); + return; + } if (scalar @args == 1) { # del pass. - if (!&IsFlag("m") and $who !~ /^\Q$verifyUser\E$/i) { - &pSReply("cannto remove passwd of others."); + if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { + &pSReply("cannot remove passwd of others."); return; } @@ -673,8 +754,7 @@ sub userDCC { return; } - my $salt = join '',('.','/',0..9,'A'..'Z','a'..'z')[rand 64, rand 64]; - my $crypt = crypt($args[1], $salt); + my $crypt = &mkcrypt($args[1]); &pSReply("Set $u's passwd to '$crypt'"); $users{$u}{PASS} = $crypt; @@ -692,6 +772,7 @@ sub userDCC { return; } + my $chflag; my $user; if ($args[0] =~ /^$mask{nick}$/i) { # $user = &getUser($args[0]); @@ -704,7 +785,7 @@ sub userDCC { } if (!defined $user) { - &pSReply("user $user does not exist."); + &pSReply("user does not exist."); return; } @@ -716,7 +797,7 @@ sub userDCC { &DEBUG("who => $who"); &DEBUG("verifyUser => $verifyUser"); - if (!&IsFlag("m") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { &pSReply("cannto change attributes of others."); return "REPLY"; } @@ -799,7 +880,7 @@ sub userDCC { return; } - if (!&IsFlag("m") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { &pSReply("cannto change nick of others."); return "REPLY" if ($who eq "_default"); return; @@ -836,11 +917,11 @@ sub userDCC { my ($user,$mask); if ($args[0] =~ /^$mask{nick}$/i) { # - return unless (&hasFlag("m")); + return unless (&hasFlag("n")); $user = &getUser($args[0]); $mask = $args[1]; } else { # - # who or verifyUser. FIXME!!! + # FIXME: who or verifyUser. (don't remember why) $user = &getUser($who); $mask = $args[0]; } @@ -851,13 +932,13 @@ sub userDCC { } if (!defined $mask) { - ### FIXME. + ### FIXME: &pSReply("Hostmasks for $user: $users{$user}{HOSTS}"); return; } - if (!&IsFlag("m") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { &pSReply("cannto change masks of others."); return; } @@ -930,10 +1011,14 @@ sub userDCC { } if ($state == 0) { # delete. - my $c = join(' ', &banDel($mask) ); + my @c = &banDel($mask); + + foreach (@c) { + &unban($mask, $_); + } - if ($c) { - &pSReply("Removed $mask from chans: $c"); + if (@c) { + &pSReply("Removed $mask from chans: @c"); } else { &pSReply("$mask was not found in ban list."); } @@ -961,7 +1046,7 @@ sub userDCC { $reason = $1; } - if (!&IsFlag("m") and $who !~ /^\Q$verifyUser\E$/i) { + if (!&IsFlag("n") and $who !~ /^\Q$verifyUser\E$/i) { &pSReply("cannto change masks of others."); return; } @@ -1054,7 +1139,7 @@ sub userDCC { if ($message =~ /^banlist(\s+(.*))?$/) { my $arg = $2; - if (defined $arg and $arg !~ /^$mask_chan$/) { + if (defined $arg and $arg !~ /^$mask{chan}$/) { &pSReply("error: chan $chan is invalid."); return; } @@ -1107,7 +1192,7 @@ sub userDCC { if (!$state) { # delignore. if ( &ignoreDel($mask) ) { - &pSReply("ok, deleted X ignores."); + &pSReply("ok, deleted ignores for $mask."); } else { &pSReply("could not find $mask in ignore list."); } @@ -1127,7 +1212,7 @@ sub userDCC { # time. if ($args =~ s/^(\d+)\s*//) { - $time = $1*60; # ?? + $time = $1; # time is in minutes } else { $time = 0; } @@ -1140,7 +1225,7 @@ sub userDCC { } if ( &ignoreAdd($mask, $chan, $time, $comment) > 1) { - &pSReply("warn: $mask already in ignore list; written over anyway. FIXME"); + &pSReply("FIXME: $mask already in ignore list; written over anyway."); } else { &pSReply("added $mask to ignore list."); } @@ -1218,14 +1303,34 @@ sub userDCC { if ($state) { # adduser. if (scalar @args == 1) { $args[1] = &getHostMask($args[0]); - if (!defined $args[1]) { - &ERROR("could not get hostmask?"); - return; - } + &pSReply("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} ); + + if ( &userAdd($nick, $mask) ) { # success. + &pSReply("Added $nick with flags $users{$nick}{FLAGS}"); + my @hosts = keys %{ $users{$nick}{HOSTS} }; + &pSReply("hosts: @hosts"); + } +}); + return; } + &DEBUG("args => @args"); if ( &userAdd(@args) ) { # success. - &pSReply("Added $args[0]..."); + &pSReply("Added $args[0] with flags $users{$args[0]}{FLAGS}"); + my @hosts = keys %{ $users{$args[0]}{HOSTS} }; + &pSReply("hosts: @hosts"); } else { # failure. &pSReply("User $args[0] already exists"); @@ -1247,20 +1352,44 @@ sub userDCC { if ($message =~ /^sched$/) { my @list; my @run; + + my %time; foreach (keys %sched) { next unless (exists $sched{$_}{TIME}); + $time{ $sched{$_}{TIME}-time() }{$_} = 1; push(@list,$_); next unless (exists $sched{$_}{RUNNING}); push(@run,$_); } - &pSReply( &formListReply(0,"Scheds to run: ", sort @list ) ); + my @time; + foreach (sort { $a <=> $b } 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 ) ); return; } + # quite a cool hack: reply in DCC CHAT. + $msgType = "chat" if (exists $dcc{'CHAT'}{$who}); + + my $done = 0; + $done++ if &parseCmdHook("main", $message); + $done++ if &parseCmdHook("extra", $message); + $done++ unless (&Modules()); + + if ($done) { + &DEBUG("running non DCC CHAT command inside DCC CHAT!"); + return; + } + return "REPLY"; }