Blame
Date:
Sun Dec 27 01:56:09 2020 UTC
Message:
Updated p5-Class-DBI-SQLite-0.11p2
001
2020-09-08
jrmu
#!/usr/bin/perl
002
2020-09-08
jrmu
003
2020-09-22
jrmu
use strict;
004
2020-11-15
jrmu
no strict 'refs';
005
2020-09-22
jrmu
use warnings;
006
2020-09-22
jrmu
use IO::Socket;
007
2020-09-22
jrmu
use IO::Select;
008
2020-09-22
jrmu
use OpenBSD::Pledge;
009
2020-09-22
jrmu
use OpenBSD::Unveil;
010
2020-09-22
jrmu
011
2020-09-22
jrmu
my $confpath = "botnow.conf";
012
2020-10-11
jrmu
our %conf;
013
2020-10-11
jrmu
foreach my $line (readarray($confpath)) {
014
2020-09-22
jrmu
if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace
015
2020-09-22
jrmu
next;
016
2020-09-22
jrmu
} elsif ($line =~ /^([-_a-zA-Z0-9]+)\s*=\s*([[:print:]]+)$/) {
017
2020-09-22
jrmu
$conf{$1} = $2;
018
2020-09-22
jrmu
} else {
019
2020-09-24
jrmu
die "ERROR: botnow.conf format invalid: $line";
020
2020-09-22
jrmu
}
021
2020-09-22
jrmu
}
022
2020-09-22
jrmu
023
2020-09-13
jrmu
# Name of local network
024
2020-10-11
jrmu
$conf{localnet} = $conf{localnet} || "ircnow";
025
2020-09-08
jrmu
026
2020-09-13
jrmu
# Internal IPv4 address and plaintext port
027
2020-10-11
jrmu
$conf{host} = $conf{host} || "127.0.0.1";
028
2020-10-11
jrmu
$conf{port} = $conf{port} || 1337;
029
2020-09-13
jrmu
030
2020-09-08
jrmu
# Bouncer hostname
031
2020-10-11
jrmu
chomp($conf{hostname} = $conf{hostname} || `hostname`);
032
2020-09-08
jrmu
033
2020-09-10
jrmu
# External IPv4 address, plaintext and ssl port
034
2020-11-15
jrmu
$conf{ip4} = $conf{ip4} or die "ERROR: botnow.conf: ip4";
035
2020-10-11
jrmu
$conf{plainport} = $conf{plainport} || 1337;
036
2020-10-11
jrmu
$conf{sslport} = $conf{sslport} || 31337;
037
2020-09-08
jrmu
038
2020-09-10
jrmu
# Nick and password of bot -- Make sure to add to oper block
039
2020-10-11
jrmu
$conf{nick} = $conf{nick} || "botnow";
040
2020-10-11
jrmu
$conf{pass} = $conf{pass} or die "ERROR: botnow.conf: pass";
041
2020-09-08
jrmu
042
2020-09-08
jrmu
# Comma-separated list of channels for requesting bouncers
043
2020-10-11
jrmu
$conf{chans} = $conf{chans} || "#ircnow";
044
2020-09-08
jrmu
045
2020-11-17
jrmu
#Join chans on localnet?
046
2020-11-17
jrmu
$conf{localchans} = defined($conf{localchans}) && ($conf{localchans} =~ /^true/i);
047
2020-11-17
jrmu
048
2020-09-08
jrmu
# Number of words in password
049
2020-10-11
jrmu
$conf{passlength} = $conf{passlength} || 3;
050
2020-09-08
jrmu
051
2020-09-08
jrmu
# Mail from address
052
2020-10-11
jrmu
if (!defined($conf{mailname})) {
053
2020-10-11
jrmu
if ($conf{mailfrom} =~ /^([^@]+)@/) {
054
2020-11-15
jrmu
$conf{mailname} = $1 or die "ERROR: botnow.conf mailname";
055
2020-09-22
jrmu
}
056
2020-09-22
jrmu
}
057
2020-09-08
jrmu
058
2020-09-08
jrmu
# rDNS keys from Stallion in BuyVM
059
2020-10-11
jrmu
$conf{key} = $conf{key} or die "ERROR: botnow.conf: key";
060
2020-10-11
jrmu
$conf{hash} = $conf{hash} or die "ERROR: botnow.conf: hash";
061
2020-09-08
jrmu
062
2020-09-16
jrmu
# ZNC install directory
063
2020-10-11
jrmu
$conf{zncdir} = $conf{zncdir} || "/home/znc/home/znc";
064
2020-09-16
jrmu
065
2020-10-23
jrmu
# NSD zone dir
066
2020-10-23
jrmu
$conf{zonedir} = $conf{zonedir} || "/var/nsd/zones/master/";
067
2020-10-23
jrmu
068
2020-09-10
jrmu
# Network Interface Config File
069
2020-10-11
jrmu
$conf{hostnameif} = $conf{hostnameif} || "/etc/hostname.vio0";
070
2020-09-08
jrmu
071
2020-09-10
jrmu
# Verbosity: 0 (no errors), 1 (errors), 2 (warnings), 3 (diagnostic)
072
2020-10-11
jrmu
use constant {
073
2020-10-11
jrmu
NONE => 0,
074
2020-10-11
jrmu
ERRORS => 1,
075
2020-10-11
jrmu
WARNINGS => 2,
076
2020-10-11
jrmu
ALL => 3,
077
2020-10-11
jrmu
};
078
2020-10-11
jrmu
$conf{verbose} = $conf{verbose} || ERRORS;
079
2020-09-08
jrmu
080
2020-09-10
jrmu
# Terms of Service; don't edit lines with the word EOF
081
2020-10-23
jrmu
$conf{terms} = $conf{terms} || "IRCNow: Of the User, By the User, For the User. Rules: no profanity, 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";
082
2020-09-08
jrmu
083
2020-10-20
jrmu
$conf{ipv6path} = "ipv6s"; # ipv6 file path
084
2020-10-20
jrmu
$conf{netpath} = "networks"; # networks file path
085
2020-11-05
jrmu
$conf{expires} = $conf{expires} || 1800; # time before captcha expires
086
2020-10-20
jrmu
087
2020-09-22
jrmu
if(defined($conf{die})) { die $conf{die}; }
088
2020-09-08
jrmu
089
2020-11-15
jrmu
my @modules;
090
2020-11-15
jrmu
if (defined($conf{modules})) {
091
2020-11-15
jrmu
@modules = split(/\s+/, $conf{modules});
092
2020-11-15
jrmu
}
093
2020-11-15
jrmu
use lib './';
094
2020-11-15
jrmu
foreach my $mod (@modules) {
095
2020-11-15
jrmu
require "$mod.pm";
096
2020-11-15
jrmu
}
097
2020-11-15
jrmu
foreach my $mod (@modules) {
098
2020-11-15
jrmu
my $init = "${mod}::init";
099
2020-11-15
jrmu
$init->();
100
2020-11-15
jrmu
}
101
2020-09-08
jrmu
102
2020-10-15
jrmu
our @networks;
103
2020-10-15
jrmu
my @bots;
104
2020-10-15
jrmu
my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
105
2020-10-15
jrmu
my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
106
2020-10-15
jrmu
my @chans = split /[,\s]+/m, $conf{chans};
107
2020-10-15
jrmu
my @teamchans;
108
2020-10-15
jrmu
if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; }
109
2020-11-15
jrmu
my $call;
110
2020-10-15
jrmu
my $botnick = $conf{nick};
111
2020-10-15
jrmu
my $host = $conf{host};
112
2020-10-15
jrmu
my $port = $conf{port};
113
2020-10-15
jrmu
my $pass = $conf{pass};
114
2020-10-15
jrmu
my $localnet = $conf{localnet};
115
2020-10-15
jrmu
my $staff = $conf{staff};
116
2020-10-15
jrmu
my $verbose = $conf{verbose};
117
2020-10-20
jrmu
my $ipv6path = $conf{ipv6path};
118
2020-10-20
jrmu
my $netpath = $conf{netpath};
119
2020-11-05
jrmu
my $expires = $conf{expires};
120
2020-11-17
jrmu
my $localchans = $conf{localchans};
121
2020-10-11
jrmu
122
2020-10-20
jrmu
unveil("./", "r") or die "Unable to unveil $!";
123
2020-10-20
jrmu
unveil("$confpath", "r") or die "Unable to unveil $!";
124
2020-10-20
jrmu
unveil("$netpath", "r") or die "Unable to unveil $!";
125
2020-10-20
jrmu
unveil("$ipv6path", "rwc") or die "Unable to unveil $!";
126
2020-10-20
jrmu
unveil() or die "Unable to lock unveil $!";
127
2020-10-20
jrmu
128
2020-10-20
jrmu
#dns and inet for sockets, proc and exec for figlet
129
2020-10-20
jrmu
#rpath for reading file, wpath for writing file, cpath for creating path
130
2020-10-20
jrmu
#flock, fattr for sqlite
131
2020-10-20
jrmu
pledge( qw(stdio rpath wpath cpath inet dns proc exec flock fattr) ) or die "Unable to pledge: $!";
132
2020-10-20
jrmu
133
2020-10-11
jrmu
# Read from filename and return array of lines without trailing newlines
134
2020-10-11
jrmu
sub readarray {
135
2020-09-21
jrmu
my ($filename) = @_;
136
2020-10-20
jrmu
open(my $fh, '<', $filename) or die "Could not read file '$filename' $!";
137
2020-10-15
jrmu
chomp(my @lines = <$fh>);
138
2020-09-21
jrmu
close $fh;
139
2020-09-21
jrmu
return @lines;
140
2020-09-21
jrmu
}
141
2020-10-11
jrmu
142
2020-10-11
jrmu
# Read from filename and return as string
143
2020-10-11
jrmu
sub readstr {
144
2020-10-11
jrmu
my ($filename) = @_;
145
2020-10-11
jrmu
open my $fh, '<', $filename or die "Could not read file '$filename' $!";
146
2020-10-11
jrmu
my $str = do { local $/; <$fh> };
147
2020-10-15
jrmu
close $fh;
148
2020-10-11
jrmu
return $str;
149
2020-10-11
jrmu
}
150
2020-10-11
jrmu
151
2020-09-24
jrmu
# Write str to filename
152
2020-09-21
jrmu
sub writefile {
153
2020-09-21
jrmu
my ($filename, $str) = @_;
154
2020-10-15
jrmu
open(my $fh, '>', "$filename") or die "Could not write to $filename";
155
2020-09-21
jrmu
print $fh $str;
156
2020-09-21
jrmu
close $fh;
157
2020-09-21
jrmu
}
158
2020-09-08
jrmu
159
2020-10-27
jrmu
# Append str to filename
160
2020-10-27
jrmu
sub appendfile {
161
2020-10-27
jrmu
my ($filename, $str) = @_;
162
2020-10-27
jrmu
open(my $fh, '>>', "$filename") or die "Could not append to $filename";
163
2020-10-27
jrmu
print $fh $str;
164
2020-10-27
jrmu
close $fh;
165
2020-10-27
jrmu
}
166
2020-10-27
jrmu
167
2020-09-24
jrmu
# Return list of networks from filename
168
2020-09-24
jrmu
# To add multiple servers for a single network, simply create a new entry with
169
2020-09-24
jrmu
# the same net name; znc ignores addnetwork commands when a network already exists
170
2020-09-24
jrmu
sub readnetworks {
171
2020-09-24
jrmu
my ($filename) = @_;
172
2020-10-11
jrmu
my @lines = readarray($filename);
173
2020-09-24
jrmu
my @networks;
174
2020-09-21
jrmu
foreach my $line (@lines) {
175
2020-09-24
jrmu
if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace
176
2020-09-24
jrmu
next;
177
2020-09-24
jrmu
} elsif ($line =~ /^\s*([-a-zA-Z0-9]+)\s*([-_.:a-zA-Z0-9]+)\s*(~|\+)?([0-9]+)\s*$/) {
178
2020-09-24
jrmu
my ($name, $server, $port) = ($1, $2, $4);
179
2020-09-24
jrmu
my $trustcerts;
180
2020-09-24
jrmu
if (!defined($3)) {
181
2020-09-24
jrmu
$trustcerts = 0;
182
2020-09-24
jrmu
} elsif ($3 eq "~") { # Use SSL but trust all certs
183
2020-09-24
jrmu
$port = "+".$port;
184
2020-09-24
jrmu
$trustcerts = 1;
185
2020-09-24
jrmu
} else { # Use SSL and verify certs
186
2020-09-24
jrmu
$port = "+".$port;
187
2020-09-24
jrmu
$trustcerts = 0;
188
2020-09-24
jrmu
}
189
2020-09-24
jrmu
push(@networks, {"name" => $name, "server" => $server, "port" => $port, "trustcerts" => $trustcerts });
190
2020-09-24
jrmu
} else {
191
2020-09-24
jrmu
die "network format invalid: $line\n";
192
2020-09-08
jrmu
}
193
2020-09-08
jrmu
}
194
2020-09-24
jrmu
return @networks;
195
2020-09-08
jrmu
}
196
2020-09-08
jrmu
197
2020-09-24
jrmu
@networks = readnetworks($netpath);
198
2020-09-08
jrmu
199
2020-09-24
jrmu
# networks must be sorted to avoid multiple connections
200
2020-09-24
jrmu
@networks = sort @networks;
201
2020-09-24
jrmu
202
2020-09-08
jrmu
# create sockets
203
2020-09-08
jrmu
my $sel = IO::Select->new( );
204
2020-09-24
jrmu
my $lastnet = "";
205
2020-09-08
jrmu
foreach my $network (@networks) {
206
2020-09-21
jrmu
# avoid duplicate connections
207
2020-09-24
jrmu
if ($lastnet eq $network->{name}) { next; }
208
2020-09-24
jrmu
$lastnet = $network->{name};
209
2020-10-15
jrmu
my $socket = IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n";
210
2020-09-08
jrmu
$sel->add($socket);
211
2020-10-11
jrmu
my $bot = {("sock" => $socket), %$network};
212
2020-10-11
jrmu
push(@bots, $bot);
213
2020-10-15
jrmu
putserv($bot, "NICK $botnick");
214
2020-10-15
jrmu
putserv($bot, "USER $botnick * * :$botnick");
215
2020-09-08
jrmu
}
216
2020-09-08
jrmu
217
2020-09-08
jrmu
while(my @ready = $sel->can_read) {
218
2020-09-10
jrmu
my ($bot, $response);
219
2020-10-11
jrmu
my ($sender, $val);
220
2020-09-08
jrmu
foreach my $socket (@ready) {
221
2020-09-08
jrmu
foreach my $b (@bots) {
222
2020-09-08
jrmu
if($socket == $b->{sock}) {
223
2020-09-08
jrmu
$bot = $b;
224
2020-09-08
jrmu
last;
225
2020-09-08
jrmu
}
226
2020-09-08
jrmu
}
227
2020-09-08
jrmu
if (!defined($response = <$socket>)) {
228
2020-10-11
jrmu
debug(ERRORS, "ERROR ".$bot->{name}." has no response:");
229
2020-09-08
jrmu
next;
230
2020-09-08
jrmu
}
231
2020-10-11
jrmu
if ($response =~ /^PING :(.*)\r\n$/i) {
232
2020-10-11
jrmu
putserv($bot, "PONG :$1");
233
2020-09-10
jrmu
} elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) {
234
2020-10-11
jrmu
my ($type, $target, $text) = ($1, $2, $3);
235
2020-10-15
jrmu
if ($type eq "001" && $target =~ /^$botnick.?$/ && $text eq "Welcome to ZNC") {
236
2020-10-15
jrmu
} elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** To connect now, you can use /quote PASS <username>:<password>, or /quote PASS <username>/<network>:<password> to connect to a specific network.") {
237
2020-10-15
jrmu
} elsif ($type eq "NOTICE" && $target =~ /^$botnick.?$/ && $text eq "*** You need to send your password. Configure your client to send a server password.") {
238
2020-10-15
jrmu
} elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Password required") {
239
2020-10-15
jrmu
putserv($bot, "PASS $botnick/$bot->{name}:$pass");
240
2020-10-15
jrmu
if ($bot->{name} =~ /^$localnet$/i) {
241
2020-10-15
jrmu
putserv($bot, "OPER $botnick $pass");
242
2020-10-11
jrmu
putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel");
243
2020-10-15
jrmu
putserv($bot, "PRIVMSG *controlpanel :get Admin $botnick");
244
2020-10-11
jrmu
putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
245
2020-10-11
jrmu
foreach my $chan (@teamchans) {
246
2020-10-11
jrmu
putserv($bot, "JOIN $chan");
247
2020-10-11
jrmu
}
248
2020-10-11
jrmu
}
249
2020-11-17
jrmu
if ($bot->{name} !~ /^$localnet$/i or $localchans) {
250
2020-11-17
jrmu
foreach my $chan (@chans) {
251
2020-11-17
jrmu
putserv($bot, "JOIN $chan");
252
2020-11-17
jrmu
}
253
2020-11-17
jrmu
}
254
2020-10-15
jrmu
} elsif ($type eq "464" && $target =~ /^$botnick.?$/ && $text eq "Invalid Password") {
255
2020-10-11
jrmu
die "ERROR: Wrong Username/Password: $bot->{name}";
256
2020-10-11
jrmu
} else {
257
2020-11-17
jrmu
debug(ERRORS, "Unexpected bncnow.pl 257: type: $type, target: $target, text: $text");
258
2020-09-08
jrmu
}
259
2020-10-11
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) {
260
2020-10-11
jrmu
my ($hostmask, $nick, $host, $target, $text) = ($1, $2, $3, $4, $5);
261
2020-10-23
jrmu
if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$botnick.?$/) {
262
2020-10-23
jrmu
if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) {
263
2020-11-17
jrmu
debug(ERRORS, "nonexistent: $1");
264
2020-10-23
jrmu
} elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") {
265
2020-11-17
jrmu
debug(ERRORS, "disconnected: $bot->{name}");
266
2020-10-23
jrmu
} elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) {
267
2020-10-23
jrmu
debug(ALL, "Module $1 already loaded\n");
268
2020-11-17
jrmu
} elsif ($text =~ /^Disconnected from IRC.*$/) {
269
2020-11-17
jrmu
debug(ERRORS, "$bot->{name}: $text");
270
2020-11-17
jrmu
} elsif ($text =~ /^|/) {
271
2020-11-17
jrmu
debug(ERRORS, "$bot->{name}: $text");
272
2020-10-23
jrmu
} else {
273
2020-11-17
jrmu
debug(ERRORS, "Unexpected bncnow.pl 273: $response");
274
2020-10-23
jrmu
}
275
2020-11-23
jrmu
} elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) {
276
2020-10-11
jrmu
my ($cmd, $text) = ($1, $2);
277
2020-10-15
jrmu
my $hand = $staff; # TODO fix later
278
2020-10-11
jrmu
if ($target =~ /^#/) {
279
2020-10-11
jrmu
foreach my $c (@{$call->{pub}}) {
280
2020-10-11
jrmu
if ($cmd eq $c->{cmd}) {
281
2020-10-11
jrmu
my $proc = $c->{proc};
282
2020-10-11
jrmu
$proc->($bot, $nick, $host, $hand, $target, $text);
283
2020-10-11
jrmu
}
284
2020-10-11
jrmu
}
285
2020-10-11
jrmu
} else {
286
2020-10-11
jrmu
foreach my $c (@{$call->{msg}}) {
287
2020-10-11
jrmu
if ($cmd eq $c->{cmd}) {
288
2020-10-11
jrmu
my $proc = $c->{proc};
289
2020-10-11
jrmu
$proc->($bot, $nick, $host, $hand, $text);
290
2020-10-11
jrmu
}
291
2020-10-11
jrmu
}
292
2020-10-11
jrmu
}
293
2020-10-23
jrmu
} else {
294
2020-10-23
jrmu
my $hand = $staff; # TODO fix later
295
2020-10-23
jrmu
if ($target =~ /^#/) {
296
2020-10-23
jrmu
foreach my $c (@{$call->{pubm}}) {
297
2020-10-23
jrmu
my $proc = $c->{proc};
298
2020-10-23
jrmu
$proc->($bot, $nick, $host, $hand, $target, $text);
299
2020-10-23
jrmu
}
300
2020-10-23
jrmu
} else {
301
2020-10-23
jrmu
foreach my $c (@{$call->{msgm}}) {
302
2020-10-23
jrmu
my $proc = $c->{proc};
303
2020-10-23
jrmu
$proc->($bot, $nick, $host, $hand, $text);
304
2020-10-23
jrmu
}
305
2020-10-23
jrmu
}
306
2020-10-11
jrmu
}
307
2020-10-11
jrmu
debug(ALL, "$hostmask $target $text");
308
2020-11-17
jrmu
} elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) {
309
2020-11-17
jrmu
my ($hostmask, $target, $text) = ($1, $2, $3);
310
2020-11-17
jrmu
if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
311
2020-11-17
jrmu
my ($nick, $host) = ($1, $2);
312
2020-11-17
jrmu
my $hand = $staff; # TODO fix later
313
2020-11-17
jrmu
foreach my $c (@{$call->{notc}}) {
314
2020-11-17
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
315
2020-11-17
jrmu
my $proc = $c->{proc};
316
2020-11-17
jrmu
$proc->($bot, $nick, $host, $hand, $text, $target);
317
2020-11-17
jrmu
# }
318
2020-11-17
jrmu
}
319
2020-11-17
jrmu
# TODO use CTCR
320
2020-11-17
jrmu
# CTCP replies
321
2020-11-17
jrmu
if ($hostmask ne '*status!znc@znc.in') {
322
2020-11-17
jrmu
if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) {
323
2020-11-17
jrmu
my ($key, $val) = ($1, $2);
324
2020-11-17
jrmu
my $id = SQLite::id("irc", "nick", $nick, $expires);
325
2020-11-17
jrmu
SQLite::set("irc", "id", $id, "ctcp".lc($key), $val);
326
2020-11-17
jrmu
SQLite::set("irc", "id", $id, "localtime", time());
327
2020-11-17
jrmu
}
328
2020-11-17
jrmu
}
329
2020-10-11
jrmu
}
330
2020-11-17
jrmu
debug(ALL, "$hostmask NOTICE $target $text");
331
2020-11-17
jrmu
#:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients)
332
2020-11-17
jrmu
#:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr
333
2020-11-17
jrmu
} elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) {
334
2020-11-17
jrmu
my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4);
335
2020-11-17
jrmu
if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
336
2020-11-17
jrmu
my ($nick, $host) = ($1, $2);
337
2020-11-17
jrmu
my $hand = $staff; # TODO fix later
338
2020-11-17
jrmu
foreach my $c (@{$call->{mode}}) {
339
2020-11-17
jrmu
# TODO filter by mask
340
2020-11-17
jrmu
my $proc = $c->{proc};
341
2020-11-17
jrmu
$proc->($bot, $nick, $host, $hand, $chan, $change, $targets);
342
2020-10-11
jrmu
}
343
2020-10-11
jrmu
}
344
2020-11-17
jrmu
debug(ALL, "$hostmask MODE $chan $change $targets");
345
2020-09-10
jrmu
#:guava!guava@guava.guava.ircnow.org MODE guava :+Ci
346
2020-09-10
jrmu
#:ChanServ!services@services.irc.ircnow.org MODE #testing +q jrmu
347
2020-09-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu
348
2020-11-17
jrmu
#Unexpected bncnow.pl 460: :irc.guava.ircnow.org MODE guava :+o
349
2020-10-11
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) {
350
2020-10-11
jrmu
my ($hostmask, $nick, $host, $chan) = ($1, $2, $3, $4);
351
2020-10-15
jrmu
my $hand = $staff; # TODO fix later
352
2020-10-11
jrmu
foreach my $c (@{$call->{join}}) {
353
2020-10-11
jrmu
my $proc = $c->{proc};
354
2020-10-11
jrmu
$proc->($bot, $nick, $host, $hand, $chan);
355
2020-10-11
jrmu
}
356
2020-10-11
jrmu
debug(ALL, "$hostmask JOIN $chan");
357
2020-09-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing
358
2020-10-11
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) {
359
2020-10-11
jrmu
my ($hostmask, $nick, $host, $chan, $text) = ($1, $2, $3, $4, $5);
360
2020-10-15
jrmu
my $hand = $staff; # TODO fix later
361
2020-10-11
jrmu
foreach my $c (@{$call->{part}}) {
362
2020-10-11
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
363
2020-10-11
jrmu
my $proc = $c->{proc};
364
2020-10-11
jrmu
$proc->($bot, $nick, $host, $hand, $chan, $text);
365
2020-10-11
jrmu
# }
366
2020-10-11
jrmu
}
367
2020-10-11
jrmu
debug(ALL, "$hostmask PART $chan :$text");
368
2020-09-10
jrmu
#:jrmu!jrmu@jrmu.staff.ircnow.org PART #testing :
369
2020-11-17
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) KICK (#[^ ]+) ([^ ]+) :(.*)\r\n$/i) {
370
2020-11-17
jrmu
my ($hostmask, $nick, $host, $chan, $kicked, $text) = ($1, $2, $3, $4, $5, $6);
371
2020-11-17
jrmu
my $hand = $staff; # TODO fix later
372
2020-11-17
jrmu
foreach my $c (@{$call->{kick}}) {
373
2020-11-17
jrmu
# if ($text eq $c->{mask}) { # TODO fix later
374
2020-11-17
jrmu
my $proc = $c->{proc};
375
2020-11-17
jrmu
$proc->($bot, $nick, $host, $hand, $chan, $text);
376
2020-11-17
jrmu
# }
377
2020-11-17
jrmu
}
378
2020-11-17
jrmu
debug(ALL, "$hostmask KICK $chan $kicked :$text");
379
2020-11-17
jrmu
#jrmu!jrmu@jrmu.users.undernet.org KICK #ircnow guava :this is a test
380
2020-10-11
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NICK :?(.*)\r\n$/i) {
381
2020-10-11
jrmu
my ($hostmask, $nick, $host, $text) = ($1, $2, $3, $4);
382
2020-10-11
jrmu
debug(ALL, "$hostmask NICK $text");
383
2020-09-10
jrmu
#:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal
384
2020-11-17
jrmu
} elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) QUIT :(.*)\r\n$/i) {
385
2020-11-17
jrmu
my ($hostmask, $nick, $host, $text) = ($1, $2, $3, $4);
386
2020-11-17
jrmu
debug(ALL, "$hostmask QUIT :$text");
387
2020-11-17
jrmu
#:Testah!~sid268081@aa38a510 QUIT :Client closed connection
388
2020-11-17
jrmu
} elsif($response =~ /^NOTICE AUTH :(.*)\r\n$/i) {
389
2020-11-17
jrmu
my ($text) = ($1);
390
2020-11-17
jrmu
debug(ALL, "NOTICE AUTH: $text");
391
2020-11-17
jrmu
#NOTICE AUTH :*** Looking up your hostname
392
2020-11-17
jrmu
#NOTICE AUTH: *** Looking up your hostname
393
2020-11-17
jrmu
#NOTICE AUTH: *** Checking Ident
394
2020-11-17
jrmu
#NOTICE AUTH: *** Got ident response
395
2020-11-17
jrmu
#NOTICE AUTH: *** Found your hostname
396
2020-10-15
jrmu
} elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $botnick.? :?(.*)\r?\n?\r$/i) {
397
2020-10-11
jrmu
my ($server, $code, $text) = ($1, $2, $3);
398
2020-10-11
jrmu
if ($code =~ /^001$/) { # Server Info
399
2020-11-17
jrmu
debug(ERRORS, "connected: $bot->{name}");
400
2020-10-11
jrmu
} elsif ($code =~ /^0\d\d$/) { # Server Info
401
2020-10-11
jrmu
debug(ALL, "$server $code $text");
402
2020-10-11
jrmu
} elsif ($code =~ /^2\d\d$/) { # Server Stats
403
2020-10-11
jrmu
debug(ALL, "$server $code $text");
404
2020-10-11
jrmu
} elsif ($code == 301 && $text =~ /^([-_\|`a-zA-Z0-9]+) :([[:graph:]]+)/) {
405
2020-10-11
jrmu
debug(ALL, "$text");
406
2020-10-11
jrmu
} elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) {
407
2020-10-11
jrmu
my ($sender, $key) = ($1, "registered");
408
2020-10-11
jrmu
$val = $2 eq ":is a registered nick" ? "True" : "$2";
409
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
410
2020-10-20
jrmu
SQLite::set("irc", "id", $id, "identified", $val);
411
2020-10-11
jrmu
debug(ALL, "$key: $val");
412
2020-10-11
jrmu
} elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) {
413
2020-10-20
jrmu
my ($sender, $key, $val) = ($1, "hostmask", "$1\!$2\@$3");
414
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
415
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
416
2020-10-11
jrmu
debug(ALL, "$key: $val");
417
2020-10-11
jrmu
} elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) {
418
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "server", $2);
419
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
420
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
421
2020-10-11
jrmu
debug(ALL, "$key: $val");
422
2020-10-11
jrmu
} elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) {
423
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2"));
424
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
425
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
426
2020-10-11
jrmu
debug(ALL, "$key: $val");
427
2020-11-17
jrmu
} elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHO(IS)? list/) {
428
2020-10-11
jrmu
debug(ALL, "End of WHOIS");
429
2020-10-11
jrmu
} elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) {
430
2020-10-11
jrmu
($sender, my $idle, my $epochtime) = ($1, $2, $3);
431
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
432
2020-10-20
jrmu
SQLite::set("irc", "id", $id, "idle", $idle);
433
2020-10-20
jrmu
# SQLite::set("irc", "id", $id, "epochtime", time());
434
2020-10-11
jrmu
debug(ALL, "idle: $idle, epochtime: $epochtime");
435
2020-10-11
jrmu
} elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) {
436
2020-10-11
jrmu
debug(ALL, "End of WHOIS");
437
2020-10-11
jrmu
} elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) {
438
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "chans", $2);
439
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
440
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
441
2020-10-11
jrmu
debug(ALL, "$key: $val");
442
2020-10-11
jrmu
} elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) {
443
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2));
444
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
445
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
446
2020-10-11
jrmu
debug(ALL, "$key: $val");
447
2020-10-11
jrmu
} elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) {
448
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "ip", $2);
449
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
450
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
451
2020-10-11
jrmu
debug(ALL, "$key: $val");
452
2020-10-11
jrmu
#Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host
453
2020-10-11
jrmu
} elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) {
454
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "ip", $3);
455
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
456
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
457
2020-10-11
jrmu
debug(ALL, "$key: $val");
458
2020-10-11
jrmu
} elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) {
459
2020-10-11
jrmu
my ($sender, $key, $val) = ($1, "ssl", "True");
460
2020-11-05
jrmu
my $id = SQLite::id("irc", "nick", $sender, $expires);
461
2020-10-20
jrmu
SQLite::set("irc", "id", $id, $key, $val);
462
2020-10-11
jrmu
debug(ALL, "$key: $val");
463
2020-10-11
jrmu
} elsif ($code =~ /^332$/) { # Topic
464
2020-10-11
jrmu
# print "$text\r\n";
465
2020-11-17
jrmu
} elsif ($code =~ /^333$/) { #
466
2020-10-11
jrmu
# print "$server $text\r\n";
467
2020-10-11
jrmu
#karatkievich.freenode.net 333 #ircnow jrmu!znc@206.253.167.44 1579277253
468
2020-11-17
jrmu
} elsif ($code =~ /^352$/) { # Hostmask
469
2020-11-17
jrmu
#:datapacket.hk.quakenet.org 352 * znc guava.guava.ircnow.org *.quakenet.org guava H :0 guava
470
2020-11-17
jrmu
# print "$server $code $text\r\n";
471
2020-10-11
jrmu
} elsif ($code =~ /^353$/) { # Names
472
2020-10-11
jrmu
# print "$server $code $text\r\n";
473
2020-10-11
jrmu
} elsif ($code =~ /^366$/) { # End of names
474
2020-10-11
jrmu
# print "$server $code $text\r\n";
475
2020-10-11
jrmu
} elsif ($code =~ /^37\d$/) { # MOTD
476
2020-10-11
jrmu
# print "$server $code $text\r\n";
477
2020-10-11
jrmu
} elsif ($code =~ /^381$/) { # IRC Operator Verified
478
2020-10-11
jrmu
# print "IRC Oper Verified\r\n";
479
2020-10-11
jrmu
} elsif ($code =~ /^401$/) { # IRC Operator Verified
480
2020-10-11
jrmu
# print "IRC Oper Verified\r\n";
481
2020-11-17
jrmu
} elsif ($code =~ /^403$/) { # No such channel
482
2020-11-17
jrmu
# debug(ERRORS, "$text");
483
2020-10-11
jrmu
} elsif ($code =~ /^422$/) { # MOTD missing
484
2020-10-11
jrmu
# print "$server $code $text\r\n";
485
2020-11-17
jrmu
} elsif ($code =~ /^396$/) { # Display hostname
486
2020-11-17
jrmu
# print "$server $code $text\r\n";
487
2020-11-17
jrmu
#Unexpected bncnow.pl 454: irc.guava.ircnow.org 396 guava.guava.ircnow.org :is your displayed hostname now
488
2020-10-11
jrmu
} elsif ($code =~ /^464$/) { # Invalid password for oper
489
2020-10-11
jrmu
foreach my $chan (@teamchans) {
490
2020-10-15
jrmu
putserv($bot, "PRIVMSG $chan :$botnick oper password failed; the bot will be unable to view uncloaked IP addresses");
491
2020-09-21
jrmu
}
492
2020-10-11
jrmu
} elsif ($code =~ /^477$/) { # Can't join channel
493
2020-10-11
jrmu
foreach my $chan (@teamchans) {
494
2020-10-15
jrmu
putserv($bot, "PRIVMSG $chan :ERROR: $botnick on $server: $text");
495
2020-10-11
jrmu
}
496
2020-10-11
jrmu
} elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) {
497
2020-10-11
jrmu
debug(ALL, "$text");
498
2020-10-11
jrmu
} else {
499
2020-11-17
jrmu
debug(ERRORS, "Unexpected bncnow.pl 454: $server $code $text");
500
2020-09-21
jrmu
}
501
2020-09-21
jrmu
} else {
502
2020-11-17
jrmu
debug(ERRORS, "Unexpected bncnow.pl 460: $response");
503
2020-09-08
jrmu
}
504
2020-09-08
jrmu
}
505
2020-09-08
jrmu
}
506
2020-10-11
jrmu
507
2020-10-11
jrmu
sub putserv {
508
2020-10-11
jrmu
my( $bot, $text )=@_;
509
2020-10-11
jrmu
my $socket = $bot->{sock};
510
2020-10-11
jrmu
if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) {
511
2020-10-11
jrmu
my ($cmd, $line) = ($1, $2);
512
2020-10-11
jrmu
my @lines = split /\r?\n/m, $line;
513
2020-10-11
jrmu
foreach my $l (@lines) {
514
2020-10-11
jrmu
print $socket "$cmd:$l\r\n";
515
2020-09-08
jrmu
}
516
2020-10-11
jrmu
} else {
517
2020-10-11
jrmu
print $socket "$text\r\n";
518
2020-09-08
jrmu
}
519
2020-09-08
jrmu
}
520
2020-10-11
jrmu
521
2020-09-10
jrmu
sub date {
522
2020-09-10
jrmu
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
523
2020-09-10
jrmu
my $localtime = sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday);
524
2020-09-10
jrmu
return $localtime;
525
2020-09-08
jrmu
}
526
2020-10-11
jrmu
sub gettime {
527
2020-09-10
jrmu
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
528
2020-09-10
jrmu
my $localtime = sprintf("%s %s %d %02d:%02d:%02d", $days[$wday], $months[$mon], $mday, $hour, $min, $sec);
529
2020-09-10
jrmu
return $localtime;
530
2020-09-08
jrmu
}
531
2020-09-08
jrmu
532
2020-09-08
jrmu
sub whois {
533
2020-09-08
jrmu
my( $socket, $target )=@_;
534
2020-09-08
jrmu
print $socket "WHOIS $target $target\r\n";
535
2020-09-08
jrmu
}
536
2020-09-08
jrmu
537
2020-09-08
jrmu
sub ctcp {
538
2020-09-08
jrmu
my( $socket, $target )=@_;
539
2020-09-08
jrmu
# print $socket "PRIVMSG $target :".chr(01)."CLIENTINFO".chr(01)."\r\n";
540
2020-09-08
jrmu
# print $socket "PRIVMSG $target :".chr(01)."FINGER".chr(01)."\r\n";
541
2020-09-08
jrmu
# print $socket "PRIVMSG $target :".chr(01)."SOURCE".chr(01)."\r\n";
542
2020-09-08
jrmu
print $socket "PRIVMSG $target :".chr(01)."TIME".chr(01)."\r\n";
543
2020-09-08
jrmu
# print $socket "PRIVMSG $target :".chr(01)."USERINFO".chr(01)."\r\n";
544
2020-09-08
jrmu
print $socket "PRIVMSG $target :".chr(01)."VERSION".chr(01)."\r\n";
545
2020-09-08
jrmu
# print $socket "PRIVMSG $target :".chr(01)."PING".chr(01)."\r\n";
546
2020-09-08
jrmu
}
547
2020-09-08
jrmu
548
2020-10-11
jrmu
sub cbind {
549
2020-10-11
jrmu
my ($type, $flags, $cmd, $proc) = @_;
550
2020-10-11
jrmu
if ($type eq "pub") {
551
2020-10-11
jrmu
push(@{$call->{pub}}, {cmd => $cmd, proc => $proc});
552
2020-10-11
jrmu
} elsif ($type eq "msg") {
553
2020-10-11
jrmu
push(@{$call->{msg}}, {cmd => $cmd, proc => $proc});
554
2020-10-11
jrmu
} elsif ($type eq "notc") {
555
2020-10-11
jrmu
push(@{$call->{notc}}, {mask => $cmd, proc => $proc});
556
2020-10-11
jrmu
} elsif ($type eq "mode") {
557
2020-10-11
jrmu
push(@{$call->{mode}}, {mask => $cmd, proc => $proc});
558
2020-10-11
jrmu
} elsif ($type eq "join") {
559
2020-10-11
jrmu
push(@{$call->{join}}, {mask => $cmd, proc => $proc});
560
2020-10-11
jrmu
} elsif ($type eq "partcall") {
561
2020-10-11
jrmu
push(@{$call->{part}}, {mask => $cmd, proc => $proc});
562
2020-10-23
jrmu
} elsif ($type eq "pubm") {
563
2020-10-23
jrmu
push(@{$call->{pubm}}, {mask => $cmd, proc => $proc});
564
2020-10-23
jrmu
} elsif ($type eq "msgm") {
565
2020-10-23
jrmu
push(@{$call->{msgm}}, {mask => $cmd, proc => $proc});
566
2020-09-08
jrmu
}
567
2020-09-08
jrmu
}
568
2020-09-08
jrmu
569
2020-10-11
jrmu
sub debug {
570
2020-10-11
jrmu
my ($level, $msg) = @_;
571
2020-10-15
jrmu
if ($verbose >= $level) { print "$msg\n"; }
572
2020-09-08
jrmu
}