commit db0dd6f2c7250ca257652efdfa203134e5f7094e from: jrmu date: Fri Feb 10 04:42:37 2023 UTC Rename botnow.pl to botnow commit - e11136a333c70cd414281eecca353983c8443183 commit + db0dd6f2c7250ca257652efdfa203134e5f7094e blob - cdbebe8d78a43a813448a2f619801a58732d8dbe (mode 644) blob + /dev/null --- botnow.pl +++ /dev/null @@ -1,613 +0,0 @@ -#!/usr/bin/perl - -use strict; -no strict 'refs'; -use warnings; -use IO::Socket; -use IO::Select; -use OpenBSD::Pledge; -use OpenBSD::Unveil; - -my $confpath = "botnow.conf"; -our %conf; -foreach my $line (readarray($confpath)) { - if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace - next; - } elsif ($line =~ /^([-_a-zA-Z0-9]+)\s*=\s*([[:print:]]+)$/) { - $conf{$1} = $2; - } else { - die "ERROR: botnow.conf format invalid: $line"; - } -} - -# Name of local network -$conf{localnet} = $conf{localnet} || "ircnow"; - -# Internal IPv4 address and plaintext port -$conf{host} = $conf{host} || "127.0.0.1"; -$conf{port} = $conf{port} || 1337; - -# Bouncer hostname -chomp($conf{hostname} = $conf{hostname} || `hostname`); - -# External IPv4 address, plaintext and ssl port -$conf{ip4} = $conf{ip4} or die "ERROR: botnow.conf: ip4"; -$conf{ip6} = $conf{ip6} or die "ERROR: botnow.conf: ip6"; -$conf{ip6subnet} = $conf{ip6subnet} or die "ERROR: botnow.conf: ip6subnet"; -$conf{plainport} = $conf{plainport} || 1337; -$conf{sslport} = $conf{sslport} || 31337; - -# Nick and password of bot -- Make sure to add to oper block -$conf{nick} = $conf{nick} || "botnow"; -$conf{pass} = $conf{pass} or die "ERROR: botnow.conf: pass"; - -# Comma-separated list of channels for requesting bouncers -$conf{chans} = $conf{chans} || "#ircnow"; - -#Join chans on localnet? -$conf{localchans} = defined($conf{localchans}) && ($conf{localchans} =~ /^true/i); - -# Number of words in password -$conf{passlength} = $conf{passlength} || 3; - -# Mail from address -if (!defined($conf{mailname})) { - if ($conf{mailfrom} =~ /^([^@]+)@/) { - $conf{mailname} = $1 or die "ERROR: botnow.conf mailname"; - } -} - -# ZNC install directory -$conf{zncdir} = $conf{zncdir} || "/home/znc/home/znc"; - -# NSD zone dir -$conf{zonedir} = $conf{zonedir} || "/var/nsd/zones/master/"; - -# Network Interface Config File -$conf{hostnameif} = $conf{hostnameif} || "/etc/hostname.vio0"; - -# Verbosity: 0 (no errors), 1 (errors), 2 (warnings), 3 (diagnostic) -use constant { - NONE => 0, - ERRORS => 1, - WARNINGS => 2, - ALL => 3, -}; -$conf{verbose} = $conf{verbose} || ERRORS; - -# Terms of Service; don't edit lines with the word EOF -$conf{terms} = $conf{terms} || "IRCNow: Of the User, By the User, For the User. Rules: no porn, no illegal drugs, no gambling, no slander, no warez, no promoting violence, no spam, illegal cracking, or DDoS. Only one account per person. Don't share passwords. Full terms: https://ircnow.org/terms.php"; - -$conf{ipv6path} = "ipv6s"; # ipv6 file path -$conf{netpath} = "networks"; # networks file path -$conf{expires} = $conf{expires} || 1800; # time before captcha expires - -if(defined($conf{die})) { die $conf{die}; } - -my @modules; -if (defined($conf{modules})) { - @modules = split(/\s+/, $conf{modules}); -} -use lib './'; -foreach my $mod (@modules) { - require "$mod.pm"; -} -foreach my $mod (@modules) { - my $init = "${mod}::init"; - $init->(); -} - -our @networks; -my @bots; -my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); -my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun); -my @chans = split /[,\s]+/m, $conf{chans}; -my @teamchans; -if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; } -my $call; -my $botnick = $conf{nick}; -my $host = $conf{host}; -my $port = $conf{port}; -my $pass = $conf{pass}; -my $localnet = $conf{localnet}; -my $staff = $conf{staff}; -my @stafflist = split(/ /,$staff); -my $verbose = $conf{verbose}; -my $ipv6path = $conf{ipv6path}; -my $netpath = $conf{netpath}; -my $expires = $conf{expires}; -my $localchans = $conf{localchans}; - -unveil("./", "r") or die "Unable to unveil $!"; -unveil("$confpath", "r") or die "Unable to unveil $!"; -unveil("$netpath", "r") or die "Unable to unveil $!"; -unveil("$ipv6path", "rwc") or die "Unable to unveil $!"; -unveil() or die "Unable to lock unveil $!"; - -#dns and inet for sockets, proc and exec for figlet -#rpath for reading file, wpath for writing file, cpath for creating path -#flock, fattr for sqlite -pledge( qw(stdio rpath wpath cpath inet dns proc exec flock fattr) ) or die "Unable to pledge: $!"; - -# Read from filename and return array of lines without trailing newlines -sub readarray { - my ($filename) = @_; - open(my $fh, '<', $filename) or die "Could not read file '$filename' $!"; - chomp(my @lines = <$fh>); - close $fh; - return @lines; -} - -# Read from filename and return as string -sub readstr { - my ($filename) = @_; - open my $fh, '<', $filename or die "Could not read file '$filename' $!"; - my $str = do { local $/; <$fh> }; - close $fh; - return $str; -} - -# Write str to filename -sub writefile { - my ($filename, $str) = @_; - open(my $fh, '>', "$filename") or die "Could not write to $filename"; - print $fh $str; - close $fh; -} - -# Append str to filename -sub appendfile { - my ($filename, $str) = @_; - open(my $fh, '>>', "$filename") or die "Could not append to $filename"; - print $fh $str; - close $fh; -} - -# Return list of networks from filename -# To add multiple servers for a single network, simply create a new entry with -# the same net name; znc ignores addnetwork commands when a network already exists -sub readnetworks { - my ($filename) = @_; - my @lines = readarray($filename); - my @networks; - foreach my $line (@lines) { - if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace - next; - } elsif ($line =~ /^\s*([-a-zA-Z0-9]+)\s*([-_.:a-zA-Z0-9]+)\s*(~|\+)?([0-9]+)\s*$/) { - my ($name, $server, $port) = ($1, $2, $4); - my $trustcerts; - if (!defined($3)) { - $trustcerts = 0; - } elsif ($3 eq "~") { # Use SSL but trust all certs - $port = "+".$port; - $trustcerts = 1; - } else { # Use SSL and verify certs - $port = "+".$port; - $trustcerts = 0; - } - push(@networks, {"name" => $name, "server" => $server, "port" => $port, "trustcerts" => $trustcerts }); - } else { - die "network format invalid: $line\n"; - } - } - return @networks; -} - -@networks = readnetworks($netpath); - -# networks must be sorted to avoid multiple connections -@networks = sort @networks; - -# create sockets -my $sel = IO::Select->new( ); -my $lastnet = ""; -foreach my $network (@networks) { - # avoid duplicate connections - if ($lastnet eq $network->{name}) { next; } - $lastnet = $network->{name}; - my $socket = IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n"; - $sel->add($socket); - my $bot = {("sock" => $socket), %$network}; - push(@bots, $bot); - putserv($bot, "NICK $botnick"); - putserv($bot, "USER $botnick * * :$botnick"); -} - -while(my @ready = $sel->can_read) { - my ($bot, $response); - my ($sender, $val); - foreach my $socket (@ready) { - foreach my $b (@bots) { - if($socket == $b->{sock}) { - $bot = $b; - last; - } - } - if (!defined($response = <$socket>)) { - debug(ERRORS, "ERROR ".$bot->{name}." has no response:"); - next; - } - if ($response =~ /^PING :(.*)\r\n$/i) { - putserv($bot, "PONG :$1"); - } elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) { - my ($type, $target, $text) = ($1, $2, $3); - if ($type eq "001" && $target =~ /^$botnick.?$/ && $text eq "Welcome to ZNC") { - } elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** To connect now, you can use /quote PASS :, or /quote PASS /: to connect to a specific network.") { - } elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** You need to send your password. Configure your client to send a server password.") { - } elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Password required") { - putserv($bot, "PASS $botnick/$bot->{name}:$pass"); - if ($bot->{name} =~ /^$localnet$/i) { - putserv($bot, "OPER $botnick $pass"); - putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel"); - putserv($bot, "PRIVMSG *controlpanel :get Admin $botnick"); - putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser"); - foreach my $chan (@teamchans) { - putserv($bot, "JOIN $chan"); - } - } - if ($bot->{name} !~ /^$localnet$/i or $localchans) { - foreach my $chan (@chans) { - putserv($bot, "JOIN $chan"); - } - } - } elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Invalid Password") { - die "ERROR: Wrong Username/Password: $bot->{name}"; - } else { - debug(ERRORS, "Unexpected bncnow.pl 257: type: $type, target: $target, text: $text"); - } - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $target, $text) = ($1, $2, $3, $4, $5); - if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$botnick.?$/) { - if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) { - debug(ERRORS, "nonexistent: $1"); - } elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") { - debug(ERRORS, "disconnected: $bot->{name}"); - } elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) { - debug(ALL, "Module $1 already loaded\n"); - } elsif ($text =~ /^Disconnected from IRC.*$/) { - debug(ERRORS, "$bot->{name}: $text"); - } elsif ($text =~ /^|/) { - debug(ERRORS, "$bot->{name}: $text"); - } else { - debug(ERRORS, "Unexpected bncnow.pl 273: $response"); - } - } elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) { - my ($cmd, $text) = ($1, $2); - my $hand = $staff; # TODO fix later - if ($target =~ /^#/) { - foreach my $c (@{$call->{pub}}) { - if ($cmd eq $c->{cmd}) { - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $target, $text); - } - } - } else { - foreach my $c (@{$call->{msg}}) { - if ($cmd eq $c->{cmd}) { - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $text); - } - } - } - } else { - my $hand = $staff; # TODO fix later - if ($target =~ /^#/) { - foreach my $c (@{$call->{pubm}}) { - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $target, $text); - } - } else { - foreach my $c (@{$call->{msgm}}) { - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $text); - } - } - } - debug(ALL, "$hostmask $target $text"); - } elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $target, $text) = ($1, $2, $3); - if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) { - my ($nick, $host) = ($1, $2); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{notc}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $text, $target); - # } - } - # TODO use CTCR - # CTCP replies - if ($hostmask ne '*status!znc@znc.in') { - if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) { - my ($key, $val) = ($1, $2); - my $id = SQLite::id("irc", "nick", $nick, $expires); - SQLite::set("irc", "id", $id, "ctcp".lc($key), $val); - SQLite::set("irc", "id", $id, "localtime", time()); - } - } - } - debug(ALL, "$hostmask NOTICE $target $text"); -#:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients) -#:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr - } elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) { - my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4); - if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) { - my ($nick, $host) = ($1, $2); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{mode}}) { - # TODO filter by mask - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $chan, $change, $targets); - } - } - debug(ALL, "$hostmask MODE $chan $change $targets"); -#:guava!guava@guava.guava.ircnow.org MODE guava :+Ci -#:ChanServ!services@services.irc.ircnow.org MODE #testing +q jrmu -#:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu -#Unexpected bncnow.pl 460: :irc.guava.ircnow.org MODE guava :+o - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $chan) = ($1, $2, $3, $4); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{join}}) { - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $chan); - } - debug(ALL, "$hostmask JOIN $chan"); -#:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $chan, $text) = ($1, $2, $3, $4, $5); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{part}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $chan, $text); - # } - } - debug(ALL, "$hostmask PART $chan :$text"); -#:jrmu!jrmu@jrmu.staff.ircnow.org PART #testing : - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) KICK (#[^ ]+) ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $chan, $kicked, $text) = ($1, $2, $3, $4, $5, $6); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{kick}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $nick, $host, $hand, $chan, $text); - # } - } - debug(ALL, "$hostmask KICK $chan $kicked :$text"); -#jrmu!jrmu@jrmu.users.undernet.org KICK #ircnow guava :this is a test - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NICK :?(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $text) = ($1, $2, $3, $4); - debug(ALL, "$hostmask NICK $text"); -#:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) QUIT :(.*)\r\n$/i) { - my ($hostmask, $nick, $host, $text) = ($1, $2, $3, $4); - debug(ALL, "$hostmask QUIT :$text"); -#:Testah!~sid268081@aa38a510 QUIT :Client closed connection - } elsif($response =~ /^NOTICE AUTH :(.*)\r\n$/i) { - my ($text) = ($1); - debug(ALL, "NOTICE AUTH: $text"); -#NOTICE AUTH :*** Looking up your hostname -#NOTICE AUTH: *** Looking up your hostname -#NOTICE AUTH: *** Checking Ident -#NOTICE AUTH: *** Got ident response -#NOTICE AUTH: *** Found your hostname - } elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $botnick.? :?(.*)\r?\n?\r$/i) { - my ($server, $code, $text) = ($1, $2, $3); - if ($code =~ /^001$/) { # Server Info - debug(ERRORS, "connected: $bot->{name}"); - } elsif ($code =~ /^0\d\d$/) { # Server Info - debug(ALL, "$server $code $text"); - } elsif ($code =~ /^2\d\d$/) { # Server Stats - debug(ALL, "$server $code $text"); - } elsif ($code == 301 && $text =~ /^([-_\|`a-zA-Z0-9]+) :([[:graph:]]+)/) { - debug(ALL, "$text"); - } elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) { - my ($sender, $key) = ($1, "registered"); - $val = $2 eq ":is a registered nick" ? "True" : "$2"; - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, "identified", $val); - debug(ALL, "$key: $val"); - } elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) { - my ($sender, $key, $val) = ($1, "hostmask", "$1\!$2\@$3"); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) { - my ($sender, $key, $val) = ($1, "server", $2); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) { - my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2")); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHO(IS)? list/) { - debug(ALL, "End of WHOIS"); - } elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) { - ($sender, my $idle, my $epochtime) = ($1, $2, $3); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, "idle", $idle); -# SQLite::set("irc", "id", $id, "epochtime", time()); - debug(ALL, "idle: $idle, epochtime: $epochtime"); - } elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) { - debug(ALL, "End of WHOIS"); - } elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) { - my ($sender, $key, $val) = ($1, "chans", $2); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) { - my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2)); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) { - my ($sender, $key, $val) = ($1, "ip", $2); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - #Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host - } elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) { - my ($sender, $key, $val) = ($1, "ip", $3); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) { - my ($sender, $key, $val) = ($1, "ssl", "True"); - my $id = SQLite::id("irc", "nick", $sender, $expires); - SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code =~ /^332$/) { # Topic - # print "$text\r\n"; - } elsif ($code =~ /^333$/) { # - # print "$server $text\r\n"; - #karatkievich.freenode.net 333 #ircnow jrmu!znc@206.253.167.44 1579277253 - } elsif ($code =~ /^352$/) { # Hostmask -#:datapacket.hk.quakenet.org 352 * znc guava.guava.ircnow.org *.quakenet.org guava H :0 guava - # print "$server $code $text\r\n"; - } elsif ($code =~ /^353$/) { # Names - # print "$server $code $text\r\n"; - } elsif ($code =~ /^366$/) { # End of names - # print "$server $code $text\r\n"; - } elsif ($code =~ /^37\d$/) { # MOTD - # print "$server $code $text\r\n"; - } elsif ($code =~ /^381$/) { # IRC Operator Verified - # print "IRC Oper Verified\r\n"; - } elsif ($code =~ /^401$/) { # IRC Operator Verified - # print "IRC Oper Verified\r\n"; - } elsif ($code =~ /^403$/) { # No such channel - # debug(ERRORS, "$text"); - } elsif ($code =~ /^422$/) { # MOTD missing - # print "$server $code $text\r\n"; - } elsif ($code =~ /^396$/) { # Display hostname - # print "$server $code $text\r\n"; -#Unexpected bncnow.pl 454: irc.guava.ircnow.org 396 guava.guava.ircnow.org :is your displayed hostname now - } elsif ($code =~ /^464$/) { # Invalid password for oper - foreach my $chan (@teamchans) { - putserv($bot, "PRIVMSG $chan :$botnick oper password failed; the bot will be unable to view uncloaked IP addresses"); - } - } elsif ($code =~ /^477$/) { # Can't join channel - foreach my $chan (@teamchans) { - putserv($bot, "PRIVMSG $chan :ERROR: $botnick on $server: $text"); - } - } elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) { - debug(ALL, "$text"); - } else { - debug(ERRORS, "Unexpected bncnow.pl 454: $server $code $text"); - } - } else { - debug(ERRORS, "Unexpected bncnow.pl 460: $response"); - } - } -} - -sub putserv { - my( $bot, $text )=@_; - my $socket = $bot->{sock}; - if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) { - my ($cmd, $line) = ($1, $2); - my @lines = split /\r?\n/m, $line; - foreach my $l (@lines) { - print $socket "$cmd:$l\r\n"; - } - } else { - print $socket "$text\r\n"; - } -} - -sub putserv { - my( $bot, $text )=@_; - my $socket = $bot->{sock}; - if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) { - my ($cmd, $line) = ($1, $2); - my @lines = split /\r?\n/m, $line; - foreach my $l (@lines) { - print $socket "$cmd:$l\r\n"; - } - } else { - print $socket "$text\r\n"; - } -} - -sub putservlocalnet { - my( $bot, $text )=@_; - my $botlocalnet; - foreach my $b (@bots) { - if($b->{name} =~ /^$localnet$/i) { - $botlocalnet = $b; - last; - } - } - putserv($botlocalnet, $text); -} - - -sub date { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); - my $localtime = sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday); - return $localtime; -} -sub gettime { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(); - my $localtime = sprintf("%s %s %d %02d:%02d:%02d", $days[$wday], $months[$mon], $mday, $hour, $min, $sec); - return $localtime; -} - -sub whois { - my( $socket, $target )=@_; - print $socket "WHOIS $target $target\r\n"; -} - -sub ctcp { - my( $socket, $target )=@_; -# print $socket "PRIVMSG $target :".chr(01)."CLIENTINFO".chr(01)."\r\n"; -# print $socket "PRIVMSG $target :".chr(01)."FINGER".chr(01)."\r\n"; -# print $socket "PRIVMSG $target :".chr(01)."SOURCE".chr(01)."\r\n"; - print $socket "PRIVMSG $target :".chr(01)."TIME".chr(01)."\r\n"; -# print $socket "PRIVMSG $target :".chr(01)."USERINFO".chr(01)."\r\n"; - print $socket "PRIVMSG $target :".chr(01)."VERSION".chr(01)."\r\n"; -# print $socket "PRIVMSG $target :".chr(01)."PING".chr(01)."\r\n"; -} - -sub cbind { - my ($type, $flags, $cmd, $proc) = @_; - if ($type eq "pub") { - push(@{$call->{pub}}, {cmd => $cmd, proc => $proc}); - } elsif ($type eq "msg") { - push(@{$call->{msg}}, {cmd => $cmd, proc => $proc}); - } elsif ($type eq "notc") { - push(@{$call->{notc}}, {mask => $cmd, proc => $proc}); - } elsif ($type eq "mode") { - push(@{$call->{mode}}, {mask => $cmd, proc => $proc}); - } elsif ($type eq "join") { - push(@{$call->{join}}, {mask => $cmd, proc => $proc}); - } elsif ($type eq "partcall") { - push(@{$call->{part}}, {mask => $cmd, proc => $proc}); - } elsif ($type eq "pubm") { - push(@{$call->{pubm}}, {mask => $cmd, proc => $proc}); - } elsif ($type eq "msgm") { - push(@{$call->{msgm}}, {mask => $cmd, proc => $proc}); - } -} - -sub debug { - my ($level, $msg) = @_; - if ($verbose >= $level) { print "$msg\n"; } -} - -sub isstaff { - my( $bot, $nick ) = @_; - if( !( $bot->{name} =~ /^$localnet$/i ) ) - { - return 0; - } - my $lnick = lc $nick; - foreach( @stafflist ) { - if( $lnick eq $_ ) { - return 1; - } - } - return 0; -}