From: dms Date: Sun, 28 Jan 2001 13:00:25 +0000 (+0000) Subject: - NEW dynamic user/chan stuff. X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=623fa7b5d1e239a64f1ceee8f3117c3cd0e921af;p=infobot.git - NEW dynamic user/chan stuff. git-svn-id: https://svn.code.sf.net/p/infobot/code/trunk/blootbot@247 c11ca15a-4712-0410-83d8-924469b57eb5 --- diff --git a/src/DynaConfig.pl b/src/DynaConfig.pl new file mode 100644 index 0000000..5aa3806 --- /dev/null +++ b/src/DynaConfig.pl @@ -0,0 +1,518 @@ +# +# DynaConfig.pl: Read/Write configuration files dynamically. +# Author: dms +# Version: v0.1 (20010120) +# Created: 20010119 +# NOTE: Merged from User.pl +# + +if (&IsParam("useStrict")) { use strict; } + +##### +##### USERFILE CONFIGURATION READER/WRITER +##### + +sub readUserFile { + if (!open IN,"$bot_misc_dir/blootbot.users") { + &ERROR("cannot read userfile."); + &closeLog(); + exit 1; + } + + my $ver = ; + if ($ver !~ /^#v1/) { + &ERROR("old or invalid user file found."); + &closeLog(); + exit 1; # correct? + } + + my $nick; + while () { + chop; + + next if /^$/; + next if /^#/; + + if (/^--(\S+)[\s\t]+(.*)$/) { # user: middle entry. + my ($what,$val) = ($1,$2); + + # nice little hack. + if ($what eq "HOSTS") { + $users{$nick}{$1}{$2} = 1; + } else { + $users{$nick}{$1} = $2; + } + + } elsif (/^(\S+)$/) { # user: start entry. + $nick = $1; + + } elsif (/^::(\S+) ignore$/) { # ignore: start entry. + $chan = $1; + + } elsif (/^- (\S+):+(\d+):(\S+):(\d+):(.*)$/) { + ### ignore: middle entry. + # $mask, $count?, $whoby, $atime, $comment. + my(@array) = ($2,$3,$4,$5); + $ignore{$chan}{$1} = \@array; + + } elsif (/^::(\S+) bans$/) { # bans: start entry. + $chan = $1; + + } elsif (/^- (\S+):+(\d+):+(\d+):(\d+):(\S+):(.*)$/) { + ### bans: middle entry. + # $btime, $atime, $count, $whoby, $reason. + my(@array) = ($2,$3,$4,$5,$6); + $bans{$chan}{$1} = \@array; + + } else { # unknown. + &WARN("unknown line: $_"); + } + } + close IN; + + &status( sprintf("USERFILE: Loaded: %d users, %d bans, %d ignore", + scalar(keys %users)-1, + scalar(keys %bans), + scalar(keys %ignore), + ) + ); +} + +sub writeUserFile { + if (!open OUT,">$bot_misc_dir/blootbot.users") { + &ERROR("cannot write to userfile."); + return; + } + + my $time = scalar(localtime); + + print OUT "#v1: blootbot -- $ident -- written $time\n\n"; + + ### USER LIST. + my $cusers = 0; + foreach (sort keys %users) { + my $user = $_; + $cusers++; + my $count = scalar keys %{ $users{$user} }; + if (!$count) { + &WARN("user $user has no other attributes; skipping."); + next; + } + + print OUT "$user\n"; + + foreach (sort keys %{ $users{$user} }) { + my $what = $_; + my $val = $users{$user}{$_}; + + if (ref($val) eq "HASH") { + foreach (sort keys %{ $users{$user}{$_} }) { + print OUT "--$what\t\t$_\n"; + } + + } else { + print OUT "--$_\t\t$val\n"; + } + } + print OUT "\n"; + } + + ### BAN LIST. + my $cbans = 0; + foreach (keys %bans) { + my $chan = $_; + $cbans++; + + my $count = scalar keys %{ $bans{$chan} }; + if (!$count) { + &WARN("bans: chan $chan has no other attributes; +skipping."); + next; + } + + print OUT "::$chan bans\n"; + &DEBUG("::$chan bans"); + foreach (keys %{ $bans{$chan} }) { + printf OUT "- %s:+%d:+%d:%d:%s:%s\n", + $_, @{ $bans{$chan}{$_} }; + &DEBUG( sprintf("- %s:+%d:+%d:%d:%s:%s\n", + $_, @{ $bans{$chan}{$_} } )); + } + } + print OUT "\n" if ($cbans); + + ### IGNORE LIST. + my $cignore = 0; + foreach (keys %ignore) { + my $chan = $_; + $cignore++; + + my $count = scalar keys %{ $ignore{$chan} }; + if (!$count) { + &WARN("ignore: chan $chan has no other attributes; skipping."); + next; + } + + print OUT "::$chan ignore\n"; + &DEBUG("::$chan ignore"); + foreach (keys %{ $ignore{$chan} }) { + printf OUT "- %s:+%d:%s:%d:%s\n", + $_, @{ $bans{$chan}{$_} }; + &DEBUG( sprintf("- %s:+%d:%s:%d:%s\n", + $_, @{ $bans{$chan}{$_} } )); + } + } + + close OUT; + + $wtime_userfile = time(); + &status("--- Saved USERFILE ($cusers users; $cbans bans; $cignore ignore) at $time"); + if (defined $msgType and $msgType =~ /^chat$/) { + &performStrictReply("--- Writing user file..."); + } +} + +##### +##### CHANNEL CONFIGURATION READER/WRITER +##### + +sub readChanFile { + if (!open IN,"$bot_misc_dir/blootbot.chan") { + &ERROR("cannot erad chanfile."); + return; + } + + $_ = ; # version string. + + my $chan; + while () { + chop; + + next if /^$/; + + if (/^(\S+)\s*$/) { + $chan = $1; + next; + } + next unless (defined $chan); + + if (/^[\s\t]+\+(\S+)$/) { # bool, true. + $chanconf{$chan}{$1} = 1; + + } elsif (/^[\s\t]+\-(\S+)$/) { # bool, false. + $chanconf{$chan}{$1} = 0; + + } elsif (/^[\s\t]+(\S+)[\ss\t]+(.*)$/) {# what = val. + $chanconf{$chan}{$1} = $2; + + } else { + &WARN("unknown line: $_") unless (/^#/); + } + } + close IN; + + &status("CHANFILE: Loaded: ".(scalar(keys %chanconf)-1)." chans"); +} + +sub writeChanFile { + if (!open OUT,">$bot_misc_dir/blootbot.chan") { + &ERROR("cannot write chanfile."); + return; + } + + my $time = scalar(localtime); + print OUT "#v1: blootbot -- $ident -- written $time\n\n"; + + foreach (sort keys %chanconf) { + $chan = $_; + + print OUT "$chan\n"; + + foreach (sort keys %{ $chanconf{$chan} }) { + my $val = $chanconf{$chan}{$_}; + + if ($val =~ /^0$/) { # bool, false. + print OUT " -$_\n"; + + } elsif ($val =~ /^1$/) { # bool, true. + print OUT " +$_\n"; + + } else { # what = val. + print OUT " $_ $val\n"; + + } + + } + print OUT "\n"; + } + + close OUT; + + $wtime_chanfile = time(); + &status("--- Saved CHANFILE (".scalar(keys %chanconf). + " chans) at $time"); + + if (defined $msgType and $msgType =~ /^chat$/) { + &performStrictReply("--- Writing chan file..."); + } +} + +##### +##### USER COMMANDS. +##### + +sub IsFlag { + my $flags = shift; + my ($ret, $f, $o) = ""; + + foreach $f (split //, $users{$userHandle}{FLAGS}) { + foreach $o ( split //, $flags ) { + next unless ($f eq $o); + + $ret = $f; + last; + } + } + + $ret; +} + +sub verifyUser { + my ($nick, $lnuh) = @_; + my ($user,$m); + + $userHandle = ""; + + foreach $user (keys %users) { + next if ($user eq "_default"); + + foreach $m (keys %{$users{$user}{HOSTS}}) { + $m =~ s/\?/./g; + $m =~ s/\*/.*?/g; + $m =~ s/([\@\(\)\[\]])/\\$1/g; + + next unless ($lnuh =~ /^$m$/i); + + if ($user !~ /^\Q$nick\E$/i) { + &status("vU: host matched but diff nick ($nick != $user)."); + } + + $userHandle = $user; + last; + } + + last if ($userHandle ne ""); + + if ($user =~ /^\Q$nick\E$/i) { + &status("vU: nick matched but host is not in list ($lnuh)."); + } + } + + $userHandle ||= "_default"; + $talkWho{$talkchannel} = $who if (defined $talkchannel); + $talkWho = $who; + + return $userHandle; +} + +sub ckpasswd { + # returns true if arg1 encrypts to arg2 + my ($plain, $encrypted) = @_; + if ($encrypted eq "") { + ($plain, $encrypted) = split(/\s+/, $plain, 2); + } + return 0 unless ($plain ne "" and $encrypted ne ""); + + # MD5 // DES. Bobby Billingsley++. + my $salt = substr($encrypted, 0, 2); + if ($encrypted =~ /^\$\d\$(\w\w)\$/) { + $salt = $1; + } + + return ($encrypted eq crypt($plain, $salt)); +} + +# mainly for dcc chat... hrm. +sub hasFlag { + my ($flag) = @_; + + if (&IsFlag($flag) eq $flag) { + return 1; + } else { + &status("DCC CHAT: <$who> $message -- not enough flags."); + &performStrictReply("error: you do not have enough flags for that. ($flag required)"); + return 0; + } +} + +sub ignoreAdd { + my($mask,$chan,$expire,$comment) = @_; + + $chan ||= "*"; # global if undefined. + $comment ||= ""; # optional. + $expire ||= 0; # permament. + my $count ||= 0; + + if ($expire > 0) { + $expire = $expire*60 + time(); + } else { + $expire = 0; + } + + $ignore{$chan}{$mask} = [$expire, $count, $who, time(), $comment]; + + if (exists $ignore{$chan}{$mask}) { + return 0; + } else { + $utime_userfile = time(); + $ucount_userfile++; + + return 1; + } +} + +sub ignoreDel { + my($mask) = @_; + my @match; + + ### TODO: support wildcards. + foreach (keys %ignore) { + my $chan = $_; + + foreach (grep /^\Q$mask\E$/i, keys %{ $ignore{$chan} }) { + delete $ignore{$chan}{$mask}; + push(@match,$chan); + } + + &DEBUG("iD: scalar => ".scalar(keys %{ $ignore{$chan} }) ); + } + + if (scalar @match) { + $utime_userfile = time(); + $ucount_userfile++; + } + + return @match; +} + +sub userAdd { + my($nick,$mask) = @_; + + if (exists $users{$nick}) { + return 0; + } + + $utime_userfile = time(); + $ucount_userfile++; + + $users{$nick}{HOSTS}{$mask} = 1; + $users{$nick}{FLAGS} = $users{_default}{FLAGS}; + + return 1; +} + +sub userDel { + my($nick) = @_; + + if (!exists $users{$nick}) { + return 0; + } + + $utime_userfile = time(); + $ucount_userfile++; + + delete $users{$nick}; + + return 1; +} + +sub banAdd { + my($mask,$chan,$expire,$reason) = @_; + + $chan ||= "*"; + $expire ||= 0; + + if ($expire > 0) { + $expire = $expire*60 + time(); + } + + my $exist = 1; + $exist++ if (exists $bans{$chan}{$mask} or + exists $bans{_default}{$mask}); + $bans{$chan}{$mask} = [$expire, 0, $who, time(), $reason]; + + if ($exist == 1) { + $utime_userfile = time(); + $ucount_userfile++; + } + + return $exist; +} + +sub banDel { + my($mask) = @_; + my @match; + + foreach (keys %bans) { + my $chan = $_; + + foreach (grep /^\Q$mask\E$/i, keys %{ $bans{$chan} }) { + delete $bans{$chan}{$_}; + push(@match, $chan); + } + + &DEBUG("bans: scalar => ".scalar(keys %{ $bans{$chan} }) ); + } + + if (scalar @match) { + $utime_userfile = time(); + $ucount_userfile++; + } + + return @match; +} + +sub IsUser { + my($user) = @_; + + if ( &getUser($user) ) { + return 1; + } else { + return 0; + } +} + +sub getUser { + my($user) = @_; + + if (!defined $user) { + &WARN("getUser: user == NULL."); + return; + } + + if (my @retval = grep /^\Q$user\E$/i, keys %users) { + if ($retval[0] ne $user) { + &WARN("getUser: retval[0] ne user ($retval[0] ne $user)"); + } + my $count = scalar keys %{ $users{$retval[0]} }; + &DEBUG("count => $count."); + + return $retval[0]; + } else { + return; + } +} + +my @regFlagsChan = ( + "autojoin", + "freshmeat", + "limitcheckInterval", + "limitcheckPlus", + "allowConv", + "allowDNS", +### TODO: finish off this list. +); + +my @regFlagsUser = ("mno"); # todo... + +1;