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