Blame


1 e11136a3 2023-02-10 jrmu #!/usr/bin/perl
2 e11136a3 2023-02-10 jrmu
3 e11136a3 2023-02-10 jrmu use strict;
4 e11136a3 2023-02-10 jrmu use warnings;
5 e11136a3 2023-02-10 jrmu no strict 'refs';
6 e11136a3 2023-02-10 jrmu use IO::Socket;
7 e11136a3 2023-02-10 jrmu use IO::Select;
8 e11136a3 2023-02-10 jrmu use OpenBSD::Pledge;
9 e11136a3 2023-02-10 jrmu use OpenBSD::Unveil;
10 357efc9b 2023-03-07 jrmu use File::Copy qw(copy);
11 0c4b2fea 2023-03-07 jrmu use File::Basename;
12 a87dee89 2023-03-07 jrmu
13 a87dee89 2023-03-07 jrmu # Path to configuration file
14 a87dee89 2023-03-07 jrmu my $confpath = "botnow.conf";
15 a87dee89 2023-03-07 jrmu my $backupspath = "/home/botnow/backups/";
16 e11136a3 2023-02-10 jrmu
17 357efc9b 2023-03-07 jrmu # Returns date in YYYYMMDD format
18 357efc9b 2023-03-07 jrmu sub date {
19 357efc9b 2023-03-07 jrmu my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
20 357efc9b 2023-03-07 jrmu my $localtime = sprintf("%04d%02d%02d", $year+1900, $mon+1, $mday);
21 357efc9b 2023-03-07 jrmu return $localtime;
22 357efc9b 2023-03-07 jrmu }
23 357efc9b 2023-03-07 jrmu
24 e11136a3 2023-02-10 jrmu # Read from filename and return array of lines without trailing newlines
25 e11136a3 2023-02-10 jrmu sub readarray {
26 e11136a3 2023-02-10 jrmu my ($filename) = @_;
27 e11136a3 2023-02-10 jrmu open(my $fh, '<', $filename) or die "Could not read file '$filename' $!";
28 e11136a3 2023-02-10 jrmu chomp(my @lines = <$fh>);
29 e11136a3 2023-02-10 jrmu close $fh;
30 e11136a3 2023-02-10 jrmu return @lines;
31 e11136a3 2023-02-10 jrmu }
32 e11136a3 2023-02-10 jrmu
33 e11136a3 2023-02-10 jrmu # Read from filename and return as string
34 e11136a3 2023-02-10 jrmu sub readstr {
35 e11136a3 2023-02-10 jrmu my ($filename) = @_;
36 e11136a3 2023-02-10 jrmu open(my $fh, '<', $filename) or die "Could not read file '$filename' $!";
37 e11136a3 2023-02-10 jrmu my $str = do { local $/; <$fh> };
38 e11136a3 2023-02-10 jrmu close $fh;
39 e11136a3 2023-02-10 jrmu return $str;
40 e11136a3 2023-02-10 jrmu }
41 e11136a3 2023-02-10 jrmu
42 e11136a3 2023-02-10 jrmu # Write str to filename
43 e11136a3 2023-02-10 jrmu sub writefile {
44 e11136a3 2023-02-10 jrmu my ($filename, $str) = @_;
45 357efc9b 2023-03-07 jrmu my $date = date();
46 0dc24f13 2023-03-07 jrmu copy($filename, $backupspath.basename($filename).".".date()) or die "Could not make backup of $filename";
47 e11136a3 2023-02-10 jrmu open(my $fh, '>', "$filename") or die "Could not write to $filename";
48 e11136a3 2023-02-10 jrmu print $fh $str;
49 e11136a3 2023-02-10 jrmu close $fh;
50 e11136a3 2023-02-10 jrmu }
51 e11136a3 2023-02-10 jrmu
52 e11136a3 2023-02-10 jrmu # Append str to filename
53 e11136a3 2023-02-10 jrmu sub appendfile {
54 e11136a3 2023-02-10 jrmu my ($filename, $str) = @_;
55 e11136a3 2023-02-10 jrmu open(my $fh, '>>', "$filename") or die "Could not append to $filename";
56 e11136a3 2023-02-10 jrmu print $fh $str;
57 e11136a3 2023-02-10 jrmu close $fh;
58 e11136a3 2023-02-10 jrmu }
59 e11136a3 2023-02-10 jrmu
60 102b2e6e 2023-02-19 jrmu # Returns timestamp in "Day MM DD HH:MM:SS" format
61 102b2e6e 2023-02-19 jrmu sub gettime {
62 102b2e6e 2023-02-19 jrmu my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
63 102b2e6e 2023-02-19 jrmu my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);
64 102b2e6e 2023-02-19 jrmu my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
65 102b2e6e 2023-02-19 jrmu my $localtime = sprintf("%s %s %d %02d:%02d:%02d", $days[$wday], $months[$mon], $mday, $hour, $min, $sec);
66 eea90820 2023-02-26 jrmu return $localtime;
67 4a735b99 2023-03-07 jrmu }
68 4a735b99 2023-03-07 jrmu
69 bcee9bd5 2023-08-01 jrmu # Send email using sendmail
70 4a735b99 2023-03-07 jrmu sub mail {
71 4a735b99 2023-03-07 jrmu my( $from, $to, $fromname, $subject, $body )=@_;
72 4a735b99 2023-03-07 jrmu my $msg = <<"EOF";
73 4a735b99 2023-03-07 jrmu From: $from
74 4a735b99 2023-03-07 jrmu To: $to
75 4a735b99 2023-03-07 jrmu Subject: $subject
76 4a735b99 2023-03-07 jrmu MIME-Version: 1.0
77 4a735b99 2023-03-07 jrmu Content-Type: text/plain; charset=us-ascii
78 4a735b99 2023-03-07 jrmu Content-Disposition: inline
79 4a735b99 2023-03-07 jrmu
80 4a735b99 2023-03-07 jrmu $body
81 4a735b99 2023-03-07 jrmu EOF
82 4a735b99 2023-03-07 jrmu open(my $fh, "| /usr/sbin/sendmail -tv -F '$fromname' -f $from") or die "Could not send mail $!";
83 4a735b99 2023-03-07 jrmu print $fh $msg;
84 4a735b99 2023-03-07 jrmu close $fh;
85 4a735b99 2023-03-07 jrmu return "true";
86 eea90820 2023-02-26 jrmu }
87 e11136a3 2023-02-10 jrmu
88 e11136a3 2023-02-10 jrmu # Configuration variables will be stored in key => value pairs
89 e11136a3 2023-02-10 jrmu our %conf;
90 e11136a3 2023-02-10 jrmu
91 e11136a3 2023-02-10 jrmu foreach my $line (readarray($confpath)) {
92 e11136a3 2023-02-10 jrmu if ($line =~ /^#/ or $line =~ /^\s*$/) { # skip comments and whitespace
93 e11136a3 2023-02-10 jrmu next;
94 e11136a3 2023-02-10 jrmu } elsif ($line =~ /^([-_a-zA-Z0-9]+)\s*=\s*([[:print:]]+)$/) {
95 e11136a3 2023-02-10 jrmu $conf{$1} = $2;
96 e11136a3 2023-02-10 jrmu } else {
97 e11136a3 2023-02-10 jrmu die "ERROR: botnow.conf format invalid: $line";
98 e11136a3 2023-02-10 jrmu }
99 e11136a3 2023-02-10 jrmu }
100 e11136a3 2023-02-10 jrmu
101 e11136a3 2023-02-10 jrmu # Name of local network
102 e11136a3 2023-02-10 jrmu $conf{localnet} = $conf{localnet} or die "ERROR: botnow.conf: localnet";
103 e11136a3 2023-02-10 jrmu
104 e11136a3 2023-02-10 jrmu # Internal IPv4 address and plaintext port
105 e11136a3 2023-02-10 jrmu $conf{host} = $conf{host} || "127.0.0.1";
106 e11136a3 2023-02-10 jrmu $conf{port} = $conf{port} || 1337;
107 e11136a3 2023-02-10 jrmu
108 e11136a3 2023-02-10 jrmu # Bouncer hostname
109 e11136a3 2023-02-10 jrmu chomp($conf{hostname} = $conf{hostname} || `hostname`);
110 cae514a3 2023-03-07 jrmu
111 cae514a3 2023-03-07 jrmu # Mail hostname
112 cae514a3 2023-03-07 jrmu chomp($conf{mailhostname} = $conf{mailhostname} || `hostname`);
113 e11136a3 2023-02-10 jrmu
114 c54830ad 2023-03-05 jrmu # Webpanel URL
115 c54830ad 2023-03-05 jrmu chomp($conf{webpanel} = $conf{webpanel} || "https://bnc.$conf{hostname}");
116 c54830ad 2023-03-05 jrmu
117 cae514a3 2023-03-07 jrmu # Webmail URL
118 cae514a3 2023-03-07 jrmu chomp($conf{webmail} = $conf{webmail} || "https://mail.$conf{hostname}");
119 cae514a3 2023-03-07 jrmu
120 e11136a3 2023-02-10 jrmu # External IPv4 address, plaintext and ssl port
121 e11136a3 2023-02-10 jrmu $conf{ip4} = $conf{ip4} or die "ERROR: botnow.conf: ip4";
122 e11136a3 2023-02-10 jrmu $conf{ip6} = $conf{ip6} or die "ERROR: botnow.conf: ip6";
123 e11136a3 2023-02-10 jrmu $conf{ip6subnet} = $conf{ip6subnet} or die "ERROR: botnow.conf: ip6subnet";
124 e11136a3 2023-02-10 jrmu $conf{ip6prefix} = $conf{ip6prefix} or die "ERROR: botnow.conf: ip6prefix";
125 e11136a3 2023-02-10 jrmu $conf{plainport} = $conf{plainport} || 1337;
126 e11136a3 2023-02-10 jrmu $conf{sslport} = $conf{sslport} || 31337;
127 3a155d60 2023-03-05 jrmu $conf{imapport} = $conf{imapport} || 143;
128 3a155d60 2023-03-05 jrmu $conf{smtpport} = $conf{smtpport} || 587;
129 e11136a3 2023-02-10 jrmu
130 e11136a3 2023-02-10 jrmu # Nick and password of bot -- Make sure to add to oper block
131 e11136a3 2023-02-10 jrmu $conf{nick} = $conf{nick} or die "ERROR: botnow.conf: nick";
132 e11136a3 2023-02-10 jrmu $conf{pass} = $conf{pass} or die "ERROR: botnow.conf: pass";
133 e11136a3 2023-02-10 jrmu
134 e11136a3 2023-02-10 jrmu # Comma-separated list of channels for requesting bouncers
135 e11136a3 2023-02-10 jrmu $conf{chans} = $conf{chans} or die "ERROR: botnow.conf: chans";
136 e11136a3 2023-02-10 jrmu
137 166ac4ea 2023-02-17 jrmu my @networks;
138 166ac4ea 2023-02-17 jrmu if (defined($conf{networks})) {
139 166ac4ea 2023-02-17 jrmu @networks = split(/\s+/, $conf{networks});
140 36684717 2023-02-17 jrmu }
141 e11136a3 2023-02-10 jrmu
142 e11136a3 2023-02-10 jrmu # Mail from address
143 e11136a3 2023-02-10 jrmu if (!defined($conf{mailname})) {
144 e11136a3 2023-02-10 jrmu if ($conf{mailfrom} =~ /^([^@]+)@/) {
145 e11136a3 2023-02-10 jrmu $conf{mailname} = $1 or die "ERROR: botnow.conf mailname";
146 e11136a3 2023-02-10 jrmu }
147 e11136a3 2023-02-10 jrmu }
148 e11136a3 2023-02-10 jrmu
149 bcee9bd5 2023-08-01 jrmu # Terms of Service
150 36684717 2023-02-17 jrmu $conf{terms} = $conf{terms} or die "ERROR: botnow.conf terms";
151 36684717 2023-02-17 jrmu
152 36684717 2023-02-17 jrmu # Number of words in password
153 36684717 2023-02-17 jrmu $conf{passlength} = $conf{passlength} || 3;
154 36684717 2023-02-17 jrmu
155 36684717 2023-02-17 jrmu # Time before captcha expires
156 36684717 2023-02-17 jrmu $conf{expires} = $conf{expires} || 1800;
157 36684717 2023-02-17 jrmu
158 e11136a3 2023-02-10 jrmu # NSD zone dir
159 e11136a3 2023-02-10 jrmu $conf{zonedir} = $conf{zonedir} || "/var/nsd/zones/master/";
160 36684717 2023-02-17 jrmu
161 36684717 2023-02-17 jrmu # ZNC install directory
162 36684717 2023-02-17 jrmu $conf{zncdir} = $conf{zncdir} || "/home/znc/home/znc";
163 e11136a3 2023-02-10 jrmu
164 e11136a3 2023-02-10 jrmu # Network Interface Config File
165 e11136a3 2023-02-10 jrmu $conf{hostnameif} = $conf{hostnameif} || "/etc/hostname.vio0";
166 e11136a3 2023-02-10 jrmu
167 e11136a3 2023-02-10 jrmu # Verbosity: 0 (no errors), 1 (errors), 2 (warnings), 3 (diagnostic)
168 e11136a3 2023-02-10 jrmu use constant {
169 e11136a3 2023-02-10 jrmu NONE => 0,
170 e11136a3 2023-02-10 jrmu ERRORS => 1,
171 e11136a3 2023-02-10 jrmu WARNINGS => 2,
172 e11136a3 2023-02-10 jrmu ALL => 3,
173 e11136a3 2023-02-10 jrmu };
174 bcee9bd5 2023-08-01 jrmu
175 e11136a3 2023-02-10 jrmu $conf{verbose} = $conf{verbose} || ERRORS;
176 e11136a3 2023-02-10 jrmu
177 e11136a3 2023-02-10 jrmu if(defined($conf{die})) { die $conf{die}; }
178 e11136a3 2023-02-10 jrmu
179 b2b6fd90 2023-02-17 jrmu my @modules;
180 b2b6fd90 2023-02-17 jrmu if (defined($conf{modules})) {
181 b2b6fd90 2023-02-17 jrmu @modules = split(/\s+/, $conf{modules});
182 b2b6fd90 2023-02-17 jrmu }
183 b2b6fd90 2023-02-17 jrmu use lib './';
184 b2b6fd90 2023-02-17 jrmu foreach my $mod (@modules) {
185 b2b6fd90 2023-02-17 jrmu require "$mod.pm";
186 b2b6fd90 2023-02-17 jrmu }
187 b2b6fd90 2023-02-17 jrmu foreach my $mod (@modules) {
188 b2b6fd90 2023-02-17 jrmu my $init = "${mod}::init";
189 b2b6fd90 2023-02-17 jrmu $init->();
190 b2b6fd90 2023-02-17 jrmu }
191 b2b6fd90 2023-02-17 jrmu
192 e11136a3 2023-02-10 jrmu my @bots;
193 e11136a3 2023-02-10 jrmu my @chans = split /[,\s]+/m, $conf{chans};
194 e11136a3 2023-02-10 jrmu my @teamchans;
195 e11136a3 2023-02-10 jrmu if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; }
196 e11136a3 2023-02-10 jrmu my $call;
197 166ac4ea 2023-02-17 jrmu my $nick = $conf{nick};
198 e11136a3 2023-02-10 jrmu my $host = $conf{host};
199 e11136a3 2023-02-10 jrmu my $port = $conf{port};
200 e11136a3 2023-02-10 jrmu my $pass = $conf{pass};
201 e11136a3 2023-02-10 jrmu my $localnet = $conf{localnet};
202 e11136a3 2023-02-10 jrmu my $staff = $conf{staff};
203 e11136a3 2023-02-10 jrmu my @stafflist = split(/ /,$staff);
204 e11136a3 2023-02-10 jrmu my $verbose = $conf{verbose};
205 e11136a3 2023-02-10 jrmu my $expires = $conf{expires};
206 e11136a3 2023-02-10 jrmu
207 bcee9bd5 2023-08-01 jrmu # Unveil limits files and directories that botnow can access
208 e11136a3 2023-02-10 jrmu unveil("./", "r") or die "Unable to unveil $!";
209 e11136a3 2023-02-10 jrmu unveil("$confpath", "r") or die "Unable to unveil $!";
210 0dc24f13 2023-03-07 jrmu unveil("$backupspath", "rwc") or die "Unable to unveil $!";
211 8e4fb2f7 2023-06-03 jrmu unveil("/usr/sbin/sendmail", "rx") or die "Unable to unveil $!";
212 8e4fb2f7 2023-06-03 jrmu unveil("/bin/sh", "rx") or die "Unable to unveil $!";
213 e11136a3 2023-02-10 jrmu unveil() or die "Unable to lock unveil $!";
214 e11136a3 2023-02-10 jrmu
215 bcee9bd5 2023-08-01 jrmu # Pledge limits botnow's syscalls
216 bcee9bd5 2023-08-01 jrmu # dns and inet for sockets, proc and exec for figlet
217 bcee9bd5 2023-08-01 jrmu # rpath for reading file, wpath for writing file, cpath for creating path
218 bcee9bd5 2023-08-01 jrmu # flock, fattr for sqlite
219 e11136a3 2023-02-10 jrmu pledge( qw(stdio rpath wpath cpath inet dns proc exec flock fattr) ) or die "Unable to pledge: $!";
220 166ac4ea 2023-02-17 jrmu
221 bcee9bd5 2023-08-01 jrmu # Writes text to the network socket
222 bcee9bd5 2023-08-01 jrmu sub putserv {
223 bcee9bd5 2023-08-01 jrmu my( $bot, $text )=@_;
224 bcee9bd5 2023-08-01 jrmu my $socket = $bot->{sock};
225 bcee9bd5 2023-08-01 jrmu # If a multiline command, write multiple times; else write once
226 bcee9bd5 2023-08-01 jrmu if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) {
227 bcee9bd5 2023-08-01 jrmu my ($cmd, $line) = ($1, $2);
228 bcee9bd5 2023-08-01 jrmu my @lines = split /\r?\n/m, $line;
229 bcee9bd5 2023-08-01 jrmu foreach my $l (@lines) {
230 bcee9bd5 2023-08-01 jrmu print $socket "$cmd:$l\r\n";
231 bcee9bd5 2023-08-01 jrmu }
232 bcee9bd5 2023-08-01 jrmu } else {
233 bcee9bd5 2023-08-01 jrmu print $socket "$text\r\n";
234 bcee9bd5 2023-08-01 jrmu }
235 bcee9bd5 2023-08-01 jrmu }
236 bcee9bd5 2023-08-01 jrmu
237 bcee9bd5 2023-08-01 jrmu # Writes text to the local network socket
238 bcee9bd5 2023-08-01 jrmu sub putservlocalnet {
239 bcee9bd5 2023-08-01 jrmu my( $bot, $text )=@_;
240 bcee9bd5 2023-08-01 jrmu foreach my $b (@bots) {
241 bcee9bd5 2023-08-01 jrmu if($b->{name} =~ /^$localnet$/i) {
242 bcee9bd5 2023-08-01 jrmu putserv($b, $text);
243 bcee9bd5 2023-08-01 jrmu return;
244 bcee9bd5 2023-08-01 jrmu }
245 bcee9bd5 2023-08-01 jrmu }
246 bcee9bd5 2023-08-01 jrmu }
247 bcee9bd5 2023-08-01 jrmu
248 bcee9bd5 2023-08-01 jrmu sub whois {
249 bcee9bd5 2023-08-01 jrmu my( $bot, $target )=@_;
250 9340b0c7 2023-08-01 jrmu putserv($bot, "WHOIS $target $target\r\n");
251 bcee9bd5 2023-08-01 jrmu }
252 bcee9bd5 2023-08-01 jrmu
253 bcee9bd5 2023-08-01 jrmu sub ctcp {
254 bcee9bd5 2023-08-01 jrmu my( $bot, $target )=@_;
255 9340b0c7 2023-08-01 jrmu #putserv($bot, "PRIVMSG $target :".chr(01)."CLIENTINFO".chr(01)."\r\n");
256 9340b0c7 2023-08-01 jrmu #putserv($bot, "PRIVMSG $target :".chr(01)."FINGER".chr(01)."\r\n");
257 9340b0c7 2023-08-01 jrmu #putserv($bot, "PRIVMSG $target :".chr(01)."SOURCE".chr(01)."\r\n");
258 9340b0c7 2023-08-01 jrmu putserv($bot, "PRIVMSG $target :".chr(01)."TIME".chr(01)."\r\n");
259 9340b0c7 2023-08-01 jrmu #putserv($bot, "PRIVMSG $target :".chr(01)."USERINFO".chr(01)."\r\n");
260 9340b0c7 2023-08-01 jrmu putserv($bot, "PRIVMSG $target :".chr(01)."VERSION".chr(01)."\r\n");
261 9340b0c7 2023-08-01 jrmu #putserv($bot, "PRIVMSG $target :".chr(01)."PING".chr(01)."\r\n");
262 bcee9bd5 2023-08-01 jrmu }
263 bcee9bd5 2023-08-01 jrmu
264 bcee9bd5 2023-08-01 jrmu sub debug {
265 bcee9bd5 2023-08-01 jrmu my ($level, $msg) = @_;
266 bcee9bd5 2023-08-01 jrmu if ($verbose >= $level) { print "$msg\n"; }
267 bcee9bd5 2023-08-01 jrmu }
268 bcee9bd5 2023-08-01 jrmu
269 bcee9bd5 2023-08-01 jrmu sub isstaff {
270 bcee9bd5 2023-08-01 jrmu my( $bot, $nick ) = @_;
271 bcee9bd5 2023-08-01 jrmu if( !( $bot->{name} =~ /^$localnet$/i ) ) {
272 bcee9bd5 2023-08-01 jrmu return 0;
273 bcee9bd5 2023-08-01 jrmu }
274 bcee9bd5 2023-08-01 jrmu foreach( @stafflist ) {
275 bcee9bd5 2023-08-01 jrmu if( $nick eq $_ ) {
276 bcee9bd5 2023-08-01 jrmu return 1;
277 bcee9bd5 2023-08-01 jrmu }
278 bcee9bd5 2023-08-01 jrmu }
279 bcee9bd5 2023-08-01 jrmu return 0;
280 bcee9bd5 2023-08-01 jrmu }
281 bcee9bd5 2023-08-01 jrmu
282 bcee9bd5 2023-08-01 jrmu
283 bcee9bd5 2023-08-01 jrmu # Create sockets
284 e11136a3 2023-02-10 jrmu my $sel = IO::Select->new( );
285 166ac4ea 2023-02-17 jrmu foreach my $network (@networks) {
286 e11136a3 2023-02-10 jrmu my $socket = IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port, Proto=>'tcp', Timeout=>'300') || print "Failed to establish connection\n";
287 e11136a3 2023-02-10 jrmu $sel->add($socket);
288 e11136a3 2023-02-10 jrmu my $bot = {("sock" => $socket), ("name" => $network)};
289 e11136a3 2023-02-10 jrmu push(@bots, $bot);
290 166ac4ea 2023-02-17 jrmu putserv($bot, "NICK $nick");
291 166ac4ea 2023-02-17 jrmu putserv($bot, "USER $nick * * :$nick");
292 e11136a3 2023-02-10 jrmu }
293 e11136a3 2023-02-10 jrmu
294 e11136a3 2023-02-10 jrmu while(my @ready = $sel->can_read) {
295 bcee9bd5 2023-08-01 jrmu my ($bot, $response, $sender, $val);
296 e11136a3 2023-02-10 jrmu foreach my $socket (@ready) {
297 e11136a3 2023-02-10 jrmu foreach my $b (@bots) {
298 e11136a3 2023-02-10 jrmu if($socket == $b->{sock}) {
299 e11136a3 2023-02-10 jrmu $bot = $b;
300 e11136a3 2023-02-10 jrmu last;
301 e11136a3 2023-02-10 jrmu }
302 e11136a3 2023-02-10 jrmu }
303 bcee9bd5 2023-08-01 jrmu ### TODO: Reconnect if znc crashes
304 e11136a3 2023-02-10 jrmu if (!defined($response = <$socket>)) {
305 e11136a3 2023-02-10 jrmu debug(ERRORS, "ERROR ".$bot->{name}." has no response:");
306 e11136a3 2023-02-10 jrmu next;
307 e11136a3 2023-02-10 jrmu }
308 e11136a3 2023-02-10 jrmu if ($response =~ /^PING :(.*)\r\n$/i) {
309 e11136a3 2023-02-10 jrmu putserv($bot, "PONG :$1");
310 e11136a3 2023-02-10 jrmu } elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) {
311 e11136a3 2023-02-10 jrmu my ($type, $target, $text) = ($1, $2, $3);
312 102b2e6e 2023-02-19 jrmu if ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Password required") {
313 166ac4ea 2023-02-17 jrmu putserv($bot, "PASS $nick/$bot->{name}:$pass");
314 e11136a3 2023-02-10 jrmu if ($bot->{name} =~ /^$localnet$/i) {
315 166ac4ea 2023-02-17 jrmu putserv($bot, "OPER $nick $pass");
316 e11136a3 2023-02-10 jrmu putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel");
317 166ac4ea 2023-02-17 jrmu putserv($bot, "PRIVMSG *controlpanel :get Admin $nick");
318 e11136a3 2023-02-10 jrmu putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
319 e11136a3 2023-02-10 jrmu foreach my $chan (@teamchans) {
320 e11136a3 2023-02-10 jrmu putserv($bot, "JOIN $chan");
321 e11136a3 2023-02-10 jrmu }
322 e11136a3 2023-02-10 jrmu }
323 e11136a3 2023-02-10 jrmu if ($bot->{name} !~ /^$localnet$/i) {
324 e11136a3 2023-02-10 jrmu foreach my $chan (@chans) {
325 e11136a3 2023-02-10 jrmu putserv($bot, "JOIN $chan");
326 e11136a3 2023-02-10 jrmu }
327 e11136a3 2023-02-10 jrmu }
328 166ac4ea 2023-02-17 jrmu } elsif ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Invalid Password") {
329 e11136a3 2023-02-10 jrmu die "ERROR: Wrong Username/Password: $bot->{name}";
330 e11136a3 2023-02-10 jrmu } else {
331 102b2e6e 2023-02-19 jrmu debug(ALL, "Debug type: $type, target: $target, text: $text");
332 e11136a3 2023-02-10 jrmu }
333 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) {
334 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $target, $text) = ($1, $2, $3, $4, $5);
335 166ac4ea 2023-02-17 jrmu if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$nick.?$/) {
336 e11136a3 2023-02-10 jrmu if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) {
337 166ac4ea 2023-02-17 jrmu debug(ERRORS, "ERROR: nonexistent: $1");
338 e11136a3 2023-02-10 jrmu } elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") {
339 166ac4ea 2023-02-17 jrmu debug(ERRORS, "ERROR: disconnected: $bot->{name}");
340 e11136a3 2023-02-10 jrmu } elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) {
341 e11136a3 2023-02-10 jrmu debug(ALL, "Module $1 already loaded\n");
342 e11136a3 2023-02-10 jrmu } elsif ($text =~ /^Disconnected from IRC.*$/) {
343 166ac4ea 2023-02-17 jrmu debug(ERRORS, "ERROR: $bot->{name}: $text");
344 e11136a3 2023-02-10 jrmu } elsif ($text =~ /^|/) {
345 166ac4ea 2023-02-17 jrmu debug(ERRORS, "ERROR: $bot->{name}: $text");
346 e11136a3 2023-02-10 jrmu } else {
347 166ac4ea 2023-02-17 jrmu debug(ERRORS, "ERROR: Unexpected: $response");
348 e11136a3 2023-02-10 jrmu }
349 e11136a3 2023-02-10 jrmu } elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) {
350 e11136a3 2023-02-10 jrmu my ($cmd, $text) = ($1, $2);
351 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
352 e11136a3 2023-02-10 jrmu if ($target =~ /^#/) {
353 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{pub}}) {
354 e11136a3 2023-02-10 jrmu if ($cmd eq $c->{cmd}) {
355 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
356 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $target, $text);
357 e11136a3 2023-02-10 jrmu }
358 e11136a3 2023-02-10 jrmu }
359 e11136a3 2023-02-10 jrmu } else {
360 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{msg}}) {
361 e11136a3 2023-02-10 jrmu if ($cmd eq $c->{cmd}) {
362 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
363 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $text);
364 e11136a3 2023-02-10 jrmu }
365 e11136a3 2023-02-10 jrmu }
366 e11136a3 2023-02-10 jrmu }
367 e11136a3 2023-02-10 jrmu } else {
368 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
369 e11136a3 2023-02-10 jrmu if ($target =~ /^#/) {
370 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{pubm}}) {
371 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
372 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $target, $text);
373 e11136a3 2023-02-10 jrmu }
374 e11136a3 2023-02-10 jrmu } else {
375 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{msgm}}) {
376 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
377 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $text);
378 e11136a3 2023-02-10 jrmu }
379 e11136a3 2023-02-10 jrmu }
380 e11136a3 2023-02-10 jrmu }
381 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask $target $text");
382 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) {
383 e11136a3 2023-02-10 jrmu my ($hostmask, $target, $text) = ($1, $2, $3);
384 e11136a3 2023-02-10 jrmu if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
385 166ac4ea 2023-02-17 jrmu my ($sendnick, $host) = ($1, $2);
386 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
387 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{notc}}) {
388 e11136a3 2023-02-10 jrmu # if ($text eq $c->{mask}) { # TODO fix later
389 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
390 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $text, $target);
391 e11136a3 2023-02-10 jrmu # }
392 e11136a3 2023-02-10 jrmu }
393 166ac4ea 2023-02-17 jrmu
394 e11136a3 2023-02-10 jrmu # CTCP replies
395 e11136a3 2023-02-10 jrmu if ($hostmask ne '*status!znc@znc.in') {
396 e11136a3 2023-02-10 jrmu if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) {
397 e11136a3 2023-02-10 jrmu my ($key, $val) = ($1, $2);
398 166ac4ea 2023-02-17 jrmu my $id = SQLite::id("irc", "nick", $sendnick, $expires);
399 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, "ctcp".lc($key), $val);
400 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, "localtime", time());
401 e11136a3 2023-02-10 jrmu }
402 e11136a3 2023-02-10 jrmu }
403 e11136a3 2023-02-10 jrmu }
404 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask NOTICE $target $text");
405 e11136a3 2023-02-10 jrmu #:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients)
406 e11136a3 2023-02-10 jrmu #:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr
407 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) {
408 e11136a3 2023-02-10 jrmu my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4);
409 e11136a3 2023-02-10 jrmu if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) {
410 166ac4ea 2023-02-17 jrmu my ($sendnick, $host) = ($1, $2);
411 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
412 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{mode}}) {
413 e11136a3 2023-02-10 jrmu # TODO filter by mask
414 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
415 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $chan, $change, $targets);
416 e11136a3 2023-02-10 jrmu }
417 e11136a3 2023-02-10 jrmu }
418 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask MODE $chan $change $targets");
419 e11136a3 2023-02-10 jrmu #:guava!guava@guava.guava.ircnow.org MODE guava :+Ci
420 e11136a3 2023-02-10 jrmu #:ChanServ!services@services.irc.ircnow.org MODE #testing +q jrmu
421 e11136a3 2023-02-10 jrmu #:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu
422 e11136a3 2023-02-10 jrmu #Unexpected bncnow.pl 460: :irc.guava.ircnow.org MODE guava :+o
423 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) {
424 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $chan) = ($1, $2, $3, $4);
425 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
426 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{join}}) {
427 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
428 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $chan);
429 e11136a3 2023-02-10 jrmu }
430 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask JOIN $chan");
431 e11136a3 2023-02-10 jrmu #:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing
432 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) {
433 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $chan, $text) = ($1, $2, $3, $4, $5);
434 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
435 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{part}}) {
436 e11136a3 2023-02-10 jrmu # if ($text eq $c->{mask}) { # TODO fix later
437 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
438 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $chan, $text);
439 e11136a3 2023-02-10 jrmu # }
440 e11136a3 2023-02-10 jrmu }
441 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask PART $chan :$text");
442 e11136a3 2023-02-10 jrmu #:jrmu!jrmu@jrmu.staff.ircnow.org PART #testing :
443 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) KICK (#[^ ]+) ([^ ]+) :(.*)\r\n$/i) {
444 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $chan, $kicked, $text) = ($1, $2, $3, $4, $5, $6);
445 e11136a3 2023-02-10 jrmu my $hand = $staff; # TODO fix later
446 e11136a3 2023-02-10 jrmu foreach my $c (@{$call->{kick}}) {
447 e11136a3 2023-02-10 jrmu # if ($text eq $c->{mask}) { # TODO fix later
448 e11136a3 2023-02-10 jrmu my $proc = $c->{proc};
449 166ac4ea 2023-02-17 jrmu $proc->($bot, $sendnick, $host, $hand, $chan, $text);
450 e11136a3 2023-02-10 jrmu # }
451 e11136a3 2023-02-10 jrmu }
452 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask KICK $chan $kicked :$text");
453 e11136a3 2023-02-10 jrmu #jrmu!jrmu@jrmu.users.undernet.org KICK #ircnow guava :this is a test
454 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NICK :?(.*)\r\n$/i) {
455 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4);
456 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask NICK $text");
457 e11136a3 2023-02-10 jrmu #:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal
458 e11136a3 2023-02-10 jrmu } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) QUIT :(.*)\r\n$/i) {
459 166ac4ea 2023-02-17 jrmu my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4);
460 e11136a3 2023-02-10 jrmu debug(ALL, "$hostmask QUIT :$text");
461 e11136a3 2023-02-10 jrmu #:Testah!~sid268081@aa38a510 QUIT :Client closed connection
462 e11136a3 2023-02-10 jrmu } elsif($response =~ /^NOTICE AUTH :(.*)\r\n$/i) {
463 e11136a3 2023-02-10 jrmu my ($text) = ($1);
464 e11136a3 2023-02-10 jrmu debug(ALL, "NOTICE AUTH: $text");
465 e11136a3 2023-02-10 jrmu #NOTICE AUTH :*** Looking up your hostname
466 e11136a3 2023-02-10 jrmu #NOTICE AUTH: *** Looking up your hostname
467 e11136a3 2023-02-10 jrmu #NOTICE AUTH: *** Checking Ident
468 e11136a3 2023-02-10 jrmu #NOTICE AUTH: *** Got ident response
469 e11136a3 2023-02-10 jrmu #NOTICE AUTH: *** Found your hostname
470 166ac4ea 2023-02-17 jrmu } elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $nick.? :?(.*)\r?\n?\r$/i) {
471 e11136a3 2023-02-10 jrmu my ($server, $code, $text) = ($1, $2, $3);
472 e11136a3 2023-02-10 jrmu if ($code =~ /^001$/) { # Server Info
473 e11136a3 2023-02-10 jrmu debug(ERRORS, "connected: $bot->{name}");
474 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^0\d\d$/) { # Server Info
475 e11136a3 2023-02-10 jrmu debug(ALL, "$server $code $text");
476 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^2\d\d$/) { # Server Stats
477 e11136a3 2023-02-10 jrmu debug(ALL, "$server $code $text");
478 e11136a3 2023-02-10 jrmu } elsif ($code == 301 && $text =~ /^([-_\|`a-zA-Z0-9]+) :([[:graph:]]+)/) {
479 e11136a3 2023-02-10 jrmu debug(ALL, "$text");
480 e11136a3 2023-02-10 jrmu } elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) {
481 e11136a3 2023-02-10 jrmu my ($sender, $key) = ($1, "registered");
482 e11136a3 2023-02-10 jrmu $val = $2 eq ":is a registered nick" ? "True" : "$2";
483 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
484 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, "identified", $val);
485 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
486 e11136a3 2023-02-10 jrmu } elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) {
487 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "hostmask", "$1\!$2\@$3");
488 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
489 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
490 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
491 e11136a3 2023-02-10 jrmu } elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) {
492 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "server", $2);
493 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
494 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
495 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
496 e11136a3 2023-02-10 jrmu } elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) {
497 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2"));
498 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
499 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
500 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
501 e11136a3 2023-02-10 jrmu } elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHO(IS)? list/) {
502 e11136a3 2023-02-10 jrmu debug(ALL, "End of WHOIS");
503 e11136a3 2023-02-10 jrmu } elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) {
504 e11136a3 2023-02-10 jrmu ($sender, my $idle, my $epochtime) = ($1, $2, $3);
505 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
506 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, "idle", $idle);
507 e11136a3 2023-02-10 jrmu # SQLite::set("irc", "id", $id, "epochtime", time());
508 e11136a3 2023-02-10 jrmu debug(ALL, "idle: $idle, epochtime: $epochtime");
509 e11136a3 2023-02-10 jrmu } elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) {
510 e11136a3 2023-02-10 jrmu debug(ALL, "End of WHOIS");
511 e11136a3 2023-02-10 jrmu } elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) {
512 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "chans", $2);
513 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
514 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
515 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
516 e11136a3 2023-02-10 jrmu } elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) {
517 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2));
518 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
519 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
520 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
521 e11136a3 2023-02-10 jrmu } elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) {
522 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "ip", $2);
523 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
524 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
525 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
526 e11136a3 2023-02-10 jrmu #Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host
527 e11136a3 2023-02-10 jrmu } elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) {
528 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "ip", $3);
529 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
530 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
531 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
532 e11136a3 2023-02-10 jrmu } elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) {
533 e11136a3 2023-02-10 jrmu my ($sender, $key, $val) = ($1, "ssl", "True");
534 e11136a3 2023-02-10 jrmu my $id = SQLite::id("irc", "nick", $sender, $expires);
535 e11136a3 2023-02-10 jrmu SQLite::set("irc", "id", $id, $key, $val);
536 e11136a3 2023-02-10 jrmu debug(ALL, "$key: $val");
537 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^332$/) { # Topic
538 e11136a3 2023-02-10 jrmu # print "$text\r\n";
539 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^333$/) { #
540 e11136a3 2023-02-10 jrmu # print "$server $text\r\n";
541 e11136a3 2023-02-10 jrmu #karatkievich.freenode.net 333 #ircnow jrmu!znc@206.253.167.44 1579277253
542 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^352$/) { # Hostmask
543 e11136a3 2023-02-10 jrmu #:datapacket.hk.quakenet.org 352 * znc guava.guava.ircnow.org *.quakenet.org guava H :0 guava
544 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
545 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^353$/) { # Names
546 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
547 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^366$/) { # End of names
548 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
549 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^37\d$/) { # MOTD
550 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
551 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^381$/) { # IRC Operator Verified
552 e11136a3 2023-02-10 jrmu # print "IRC Oper Verified\r\n";
553 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^401$/) { # IRC Operator Verified
554 e11136a3 2023-02-10 jrmu # print "IRC Oper Verified\r\n";
555 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^403$/) { # No such channel
556 e11136a3 2023-02-10 jrmu # debug(ERRORS, "$text");
557 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^422$/) { # MOTD missing
558 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
559 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^396$/) { # Display hostname
560 e11136a3 2023-02-10 jrmu # print "$server $code $text\r\n";
561 e11136a3 2023-02-10 jrmu #Unexpected bncnow.pl 454: irc.guava.ircnow.org 396 guava.guava.ircnow.org :is your displayed hostname now
562 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^464$/) { # Invalid password for oper
563 e11136a3 2023-02-10 jrmu foreach my $chan (@teamchans) {
564 166ac4ea 2023-02-17 jrmu putserv($bot, "PRIVMSG $chan :$nick oper password failed; the bot will be unable to view uncloaked IP addresses");
565 e11136a3 2023-02-10 jrmu }
566 e11136a3 2023-02-10 jrmu } elsif ($code =~ /^477$/) { # Can't join channel
567 e11136a3 2023-02-10 jrmu foreach my $chan (@teamchans) {
568 166ac4ea 2023-02-17 jrmu putserv($bot, "PRIVMSG $chan :ERROR: $nick on $server: $text");
569 e11136a3 2023-02-10 jrmu }
570 e11136a3 2023-02-10 jrmu } elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) {
571 e11136a3 2023-02-10 jrmu debug(ALL, "$text");
572 e11136a3 2023-02-10 jrmu } else {
573 e11136a3 2023-02-10 jrmu debug(ERRORS, "Unexpected bncnow.pl 454: $server $code $text");
574 e11136a3 2023-02-10 jrmu }
575 e11136a3 2023-02-10 jrmu } else {
576 e11136a3 2023-02-10 jrmu debug(ERRORS, "Unexpected bncnow.pl 460: $response");
577 e11136a3 2023-02-10 jrmu }
578 e11136a3 2023-02-10 jrmu }
579 e11136a3 2023-02-10 jrmu }
580 e11136a3 2023-02-10 jrmu
581 e11136a3 2023-02-10 jrmu sub cbind {
582 e11136a3 2023-02-10 jrmu my ($type, $flags, $cmd, $proc) = @_;
583 e11136a3 2023-02-10 jrmu if ($type eq "pub") {
584 e11136a3 2023-02-10 jrmu push(@{$call->{pub}}, {cmd => $cmd, proc => $proc});
585 e11136a3 2023-02-10 jrmu } elsif ($type eq "msg") {
586 e11136a3 2023-02-10 jrmu push(@{$call->{msg}}, {cmd => $cmd, proc => $proc});
587 e11136a3 2023-02-10 jrmu } elsif ($type eq "notc") {
588 e11136a3 2023-02-10 jrmu push(@{$call->{notc}}, {mask => $cmd, proc => $proc});
589 e11136a3 2023-02-10 jrmu } elsif ($type eq "mode") {
590 e11136a3 2023-02-10 jrmu push(@{$call->{mode}}, {mask => $cmd, proc => $proc});
591 e11136a3 2023-02-10 jrmu } elsif ($type eq "join") {
592 e11136a3 2023-02-10 jrmu push(@{$call->{join}}, {mask => $cmd, proc => $proc});
593 e11136a3 2023-02-10 jrmu } elsif ($type eq "partcall") {
594 e11136a3 2023-02-10 jrmu push(@{$call->{part}}, {mask => $cmd, proc => $proc});
595 e11136a3 2023-02-10 jrmu } elsif ($type eq "pubm") {
596 e11136a3 2023-02-10 jrmu push(@{$call->{pubm}}, {mask => $cmd, proc => $proc});
597 e11136a3 2023-02-10 jrmu } elsif ($type eq "msgm") {
598 e11136a3 2023-02-10 jrmu push(@{$call->{msgm}}, {mask => $cmd, proc => $proc});
599 e11136a3 2023-02-10 jrmu }
600 e11136a3 2023-02-10 jrmu }