Blame


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