Commit Diff


commit - 7ce84f65840e798d163b2760cd72d71fda4c082e
commit + c641e0473fe257a9f0836f35efc478a10af6c916
blob - 442c0c1978c37d5254288820c5cd1833b596d376
blob + cb4bacf6fae7d284f8ea0bfb11ce5c59547f0ec2
--- botnow
+++ botnow
@@ -9,7 +9,7 @@ use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 use lib "./lib";
 use IRCNOW::IO qw(readarray :DEBUG :DateTime ); # for readarray
-
+use IRCNOW::IO::IRC;
 # Path to configuration file
 my $confpath = "botnow.conf";
 my $backupspath = "/home/botnow/backups/";
@@ -101,7 +101,6 @@ my @modules;
 if (defined($conf{modules})) {
 	@modules = split(/\s+/, $conf{modules});
 }
-use lib './lib';
 foreach my $mod (@modules) {
 	eval "require BotNow::$mod";	# Eval required for magic @INC search
 	if ($@) {
@@ -439,80 +438,6 @@ while(my @ready = $sel->can_read) {
 			debug(ERRORS, "Unexpected bncnow.pl 460: $response");
 		}
 	}
-}
-
-sub putserv {
-	my( $bot, $text )=@_;
-	my $socket = $bot->{sock};
-	if ($text =~ /^([^:]+):([[:ascii:]]*)$/m) {
-		my ($cmd, $line) = ($1, $2);
-		my @lines = split /\r?\n/m, $line;
-		foreach my $l (@lines) {
-			print $socket "$cmd:$l\r\n";
-		}
-	} else {
-		print $socket "$text\r\n";
-	}
-}
-
-sub putservlocalnet {
-	my( $bot, $text )=@_;
-	my $botlocalnet;
-	foreach my $b (@bots) {
-		if($b->{name} =~ /^$localnet$/i) {
-			$botlocalnet = $b;
-			last;
-		}
-	}	
-	putserv($botlocalnet, $text);
 }
 
-sub whois {
-	my( $socket, $target )=@_;
-	print $socket "WHOIS $target $target\r\n";
-}
 
-sub ctcp {
-	my( $socket, $target )=@_;
-#	print $socket "PRIVMSG $target :".chr(01)."CLIENTINFO".chr(01)."\r\n";
-#	print $socket "PRIVMSG $target :".chr(01)."FINGER".chr(01)."\r\n";
-#	print $socket "PRIVMSG $target :".chr(01)."SOURCE".chr(01)."\r\n";
-	print $socket "PRIVMSG $target :".chr(01)."TIME".chr(01)."\r\n";
-#	print $socket "PRIVMSG $target :".chr(01)."USERINFO".chr(01)."\r\n";
-	print $socket "PRIVMSG $target :".chr(01)."VERSION".chr(01)."\r\n";
-#	print $socket "PRIVMSG $target :".chr(01)."PING".chr(01)."\r\n";
-}
-
-sub cbind {
-	my ($type, $flags, $cmd, $proc) = @_;
-	if ($type eq "pub") {
-		push(@{$call->{pub}}, {cmd => $cmd, proc => $proc});
-	} elsif ($type eq "msg") {
-		push(@{$call->{msg}}, {cmd => $cmd, proc => $proc});
-	} elsif ($type eq "notc") {
-		push(@{$call->{notc}}, {mask => $cmd, proc => $proc});
-	} elsif ($type eq "mode") {
-		push(@{$call->{mode}}, {mask => $cmd, proc => $proc});
-	} elsif ($type eq "join") {
-		push(@{$call->{join}}, {mask => $cmd, proc => $proc});
-	} elsif ($type eq "partcall") {
-		push(@{$call->{part}}, {mask => $cmd, proc => $proc});
-	} elsif ($type eq "pubm") {
-		push(@{$call->{pubm}}, {mask => $cmd, proc => $proc});
-	} elsif ($type eq "msgm") {
-		push(@{$call->{msgm}}, {mask => $cmd, proc => $proc});
-	}
-}
-
-sub isstaff {
-	my( $bot, $nick ) = @_;
-	if( !( $bot->{name} =~ /^$localnet$/i ) ) {
-		return 0;
-	}
-	foreach( @stafflist ) {
-		if( $nick eq $_ ) {
-			return 1;
-		}
-	}
-	return 0;
-}
blob - 849c46713219b11040ac3e891ee4c4ce3cbcf7ce
blob + 3c76f3f0154b2ac2cbdb9e8c07077e0816ac0631
--- lib/BotNow/BNC.pm
+++ lib/BotNow/BNC.pm
@@ -7,6 +7,7 @@ use OpenBSD::Unveil;
 use Digest::SHA qw(sha256_hex);
 use lib qw(./lib);
 use IRCNOW::IO qw(:DEBUG readarray);
+use IRCNOW::IO::IRC;
 use BotNow::SQLite;
 use BotNow::Hash;
 use BotNow::DNS;
@@ -34,13 +35,13 @@ my @networks;
 
 `doas chmod g+r /home/znc/home/znc/.znc/`;
 my @users;
-main::cbind("pub", "-", "bnc", \&mbnc);
-main::cbind("msg", "-", "bnc", \&mbnc);
-main::cbind("msg", "-", "regex", \&mregex);
-main::cbind("msg", "-", "foreach", \&mforeach);
-main::cbind("msgm", "-", "*", \&mcontrolpanel);
-main::cbind("msg", "-", "taillog", \&mtaillog);
-main::cbind("msg", "-", "lastseen", \&mlastseen);
+IRCNOW::IO::IRC::cbind("pub", "-", "bnc", \&mbnc);
+IRCNOW::IO::IRC::cbind("msg", "-", "bnc", \&mbnc);
+IRCNOW::IO::IRC::cbind("msg", "-", "regex", \&mregex);
+IRCNOW::IO::IRC::cbind("msg", "-", "foreach", \&mforeach);
+IRCNOW::IO::IRC::cbind("msgm", "-", "*", \&mcontrolpanel);
+IRCNOW::IO::IRC::cbind("msg", "-", "taillog", \&mtaillog);
+IRCNOW::IO::IRC::cbind("msg", "-", "lastseen", \&mlastseen);
 
 sub init {
 	# File containing IRC networks
@@ -50,6 +51,7 @@ sub init {
 	unveil("/usr/lib/libc.so.95.1", "r") or die "Unable to unveil $!";
 	unveil("/usr/libexec/ld.so", "r") or die "Unable to unveil $!";
 	unveil("/usr/bin/tail", "rx") or die "Unable to unveil $!";
+	unveil("/usr/bin/encrypt", "rx") or die "Unable to unveil $!";
 	unveil("$netpath", "r") or die "Unable to unveil $!";
 	
 	@networks = readnetworks($netpath);
@@ -99,49 +101,49 @@ sub mbnc {
 	debug(ALL, "mbnc: !BNC Command: $text");
 	my $hostmask = "$nick!$host";
 	if (defined($chan) && $chans =~ /$chan/) {
-		main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
 	}
 	if ($text =~ /^$/) {
-		main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		if (BotNow::SQLite::deleterows("bnc", "username", $username)) {
-			main::putserv($bot, "PRIVMSG *controlpanel :deluser $username");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :deluser $username");
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :$username deleted");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username deleted");
 			}
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		if (BotNow::SQLite::selectrows("bnc", "username", $username)) {
 			my $email = BotNow::SQLite::get("bnc", "username", $username, "email");
 			my $password = BotNow::Hash::newpass();
-			main::putserv($bot,"privmsg *controlpanel :set Password $username $password");
- 			main::putserv($bot, "PRIVMSG *blockuser :unblock $username");
+			IRCNOW::IO::IRC::putserv($bot,"privmsg *controlpanel :set Password $username $password");
+ 			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *blockuser :unblock $username");
 			mailbncApproved($username,$email,$password);
 			foreach my $chan (@teamchans) {
-			main::putserv($bot, "PRIVMSG $chan :$username bnc approved");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username bnc approved");
 			}
 		} else {
-			main::putserv($bot, "PRIVMSG $chan :$username hasn't requested a bnc account");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username hasn't requested a bnc account");
 		}
 		return;
 	} elsif ($staff =~ /$nick/ && $text =~ /^cloneuser$/i) {
-		main::putserv($bot, "PRIVMSG *controlpanel :deluser cloneuser");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :deluser cloneuser");
 		sleep 3;
-		main::putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser");
 	}
 	### Check duplicate hostmasks ###
 	my @rows = BotNow::SQLite::selectrows("irc", "hostmask", $hostmask);
 	foreach my $row (@rows) {
 		my $password = BotNow::SQLite::get("bnc", "ircid", $row->{id}, "password");
 		if (defined($password)) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 			return;
 		}
 	}
@@ -152,11 +154,11 @@ sub mbnc {
 		my $ircid = BotNow::SQLite::id("irc", "nick", $nick, $expires);
 		my $captcha = BotNow::SQLite::get("bnc", "ircid", $ircid, "captcha");
 		if ($text ne $captcha) {
-			main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !bnc <username> <email>");
 			return;
 		}
 		my $pass = BotNow::Hash::newpass();
-		chomp(my $encrypted = `encrypt $pass`);
+		chomp(my $encrypted = `/usr/bin/encrypt $pass`);
 		my $username = BotNow::SQLite::get("bnc", "ircid", $ircid, "username");
 		my $email = BotNow::SQLite::get("bnc", "ircid", $ircid, "email");
 		my $hashirc = BotNow::SQLite::get("irc", "id", $ircid, "hashid");
@@ -166,23 +168,23 @@ sub mbnc {
 			sleep(2);
 			createbnc($bot, $username, $pass, $bindhost);
 			if ($approval eq "true") {
-				main::putserv($bot, "PRIVMSG *blockuser :block $username");
-				main::putserv($bot, "PRIVMSG $nick :Your account has been created but must be approved by your admins ($staff) before it can be used. Please reply to the email and contact staff over IRC.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *blockuser :block $username");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Your account has been created but must be approved by your admins ($staff) before it can be used. Please reply to the email and contact staff over IRC.");
 				mailbncPending($username, $email);
 				foreach my $chan (@teamchans) {
-					main::putservlocalnet($bot, "PRIVMSG $chan :$staff: To approve $nick, you must type !bnc approve $username");
+					IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: To approve $nick, you must type !bnc approve $username");
 				}
 			} else {
-				main::putserv($bot, "PRIVMSG $nick :Check your email! Please reply to the email and contact staff over IRC.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Check your email! Please reply to the email and contact staff over IRC.");
 				mailbncApproved($username,$email,$pass);
 			}
 			foreach my $chan (@teamchans) {
-				main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s bnc registration of $username on $bot->{name} was successful, *but* you *must* help him connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Bouncer.Bouncer and give him connection instructions");
+				IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s bnc registration of $username on $bot->{name} was successful, *but* you *must* help him connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Bouncer.Bouncer and give him connection instructions");
 			}
 			#www($newnick, $reply, $password, "bouncer");
 		} else {
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
 			}
 		}
 		return;
@@ -192,7 +194,7 @@ sub mbnc {
 		foreach my $row (@userrows) {
 			my $password = BotNow::SQLite::get("bnc", "ircid", $row->{id}, "password");
 			if (defined($password)) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -200,7 +202,7 @@ sub mbnc {
 		foreach my $row (@userrows) {
 			my $password = BotNow::SQLite::get("bnc", "ircid", $row->{id}, "password");
 			if (defined($password)) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -208,7 +210,7 @@ sub mbnc {
 #		my @users = treeget($znctree, "User", "Node");
 		foreach my $user (@users) {
 			if ($user eq $username) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -219,39 +221,39 @@ sub mbnc {
 		my $hashid = sha256_hex("$ircid");
 		BotNow::SQLite::set("irc", "id", $ircid, "localtime", time());
 		BotNow::SQLite::set("irc", "id", $ircid, "hashid", sha256_hex($ircid));
-		BotNow::SQLite::set("irc", "id", $ircid, "date", main::date());
+		BotNow::SQLite::set("irc", "id", $ircid, "date", IRCNOW::IO::date());
 		BotNow::SQLite::set("irc", "id", $ircid, "hostmask", $hostmask);
 		BotNow::SQLite::set("irc", "id", $ircid, "nick", $nick);
 		BotNow::SQLite::set("bnc", "ircid", $ircid, "username", $username);
 		BotNow::SQLite::set("bnc", "ircid", $ircid, "email", $email);
 		BotNow::SQLite::set("bnc", "ircid", $ircid, "captcha", $captcha);
 		BotNow::SQLite::set("bnc", "ircid", $ircid, "hashid", $hashid);
-		main::whois($bot->{sock}, $nick);
-		main::ctcp($bot->{sock}, $nick);
-		main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
-#main::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
-#main::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
-		main::putserv($bot, "PRIVMSG $nick :Type !bnc captcha <text>");
+		IRCNOW::IO::IRC::whois($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::ctcp($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
+#IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
+#IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !bnc captcha <text>");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} bnc captcha is $captcha");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} bnc captcha is $captcha");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !bnc <username> <email> to try again.");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !bnc <username> <email> to try again.");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name});
 		}
 	}
 }
 
 sub mregex {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (!main::isstaff($bot, $nick)) { return; }
+	if (!IRCNOW::IO::IRC::isstaff($bot, $nick)) { return; }
 	if ($text =~ /^ips?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
 		my $ips = $1; # space-separated list of IPs
-		main::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
 	} elsif ($text =~ /^users?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
 		my $users = $1; # space-separated list of usernames
-		main::putserv($bot, "PRIVMSG $nick :".regexlist($users));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".regexlist($users));
 	} elsif ($text =~ /^[-_()|0-9A-Za-z:,\.?*\s]{3,}$/) {
 		my @lines = regex($text);
 		foreach my $l (@lines) { print "$l\n"; }
@@ -263,7 +265,7 @@ sub mforeach {
 	if ($text =~ /^network\s+del\s+([[:graph:]]+)\s+(#[[:graph:]]+)$/) {
 		my ($user, $chan) = ($1, $2);
 		foreach my $n (@networks) {
-			main::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
 		}
 	}
 }
@@ -278,9 +280,9 @@ sub mcontrolpanel {
 	if($hostmask eq '*controlpanel!znc@znc.in') {
 		if ($text =~ /^Error: User \[cloneuser\] does not exist/) {
 			createclone($bot);
-			main::putserv($bot, "PRIVMSG *status :loadmod blockuser");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *status :loadmod blockuser");
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :Cloneuser created");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :Cloneuser created");
 			}
 		} elsif ($text =~ /^User (.*) added!$/) {
 			debug(ALL, "User $1 created");
@@ -290,7 +292,7 @@ sub mcontrolpanel {
 			debug(ALL, "$2 now connecting to $1...");
 		} elsif ($text =~ /^Admin = false/) {
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :ERROR: $nick is not admin");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :ERROR: $nick is not admin");
 			}
 			die "ERROR: $nick is not admin";
 		} elsif ($text =~ /^Admin = true/) {
@@ -362,7 +364,7 @@ set Timezone cloneuser US/Pacific
 LoadModule cloneuser controlpanel
 LoadModule cloneuser chansaver
 EOF
-	main::putserv($bot, "PRIVMSG *controlpanel :$msg");
+	IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :$msg");
 	foreach my $n (@networks) {
 		my $net = $n->{name};
 		my $server = $n->{server};
@@ -380,7 +382,7 @@ EOF
 		foreach my $chan (@chans) {
 			$msg .= "addchan cloneuser $net $chan\r\n";
 		}
-		main::putserv($bot, "PRIVMSG *controlpanel :$msg");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :$msg");
 	}
 }
 
@@ -406,7 +408,7 @@ set DenySetBindHost $username true
 reconnect $username $netname
 EOF
 #set Language $username en-US
-	main::putserv($bot, "PRIVMSG *controlpanel :$msg");
+	IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :$msg");
 	return 1;
 }
 sub mailbncApproved {
@@ -460,7 +462,7 @@ sub mtaillog {
 	open(my $fh, "-|", "/usr/bin/tail", "-f", $znclog) or die "could not start tail: $!";
 	while (my $line = <$fh>) {
 		foreach my $chan (@teamchans) {
-			main::putserv($bot, "PRIVMSG $chan :$line");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$line");
 		}
 	}
 }
@@ -478,7 +480,7 @@ sub mlastseen {
 		my @lines = grep(/^\[\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\] \[$user\] connected to ZNC from [.0-9a-fA-F:]+/, @logs);
 		if (scalar(@lines) == 0) {
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :$user never logged in");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$user never logged in");
 			}
 			next;
 		}
@@ -486,7 +488,7 @@ sub mlastseen {
 		if ($recent =~ /^\[(\d{4}-\d\d-\d\d) \d\d:\d\d:\d\d\] \[$user\] connected to ZNC from [.0-9a-fA-F:]+/) {
 			my $date = $1;
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :$user $date");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$user $date");
 			}
 		}
 	}
blob - 3d12bc62f3204cd3ebdc1628e046e137226e8966
blob + d7a45c1ec048a41f46881a14e853247f9b6f81c0
--- lib/BotNow/DNS.pm
+++ lib/BotNow/DNS.pm
@@ -6,7 +6,7 @@ use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 use lib qw(./lib);
 use IRCNOW::IO qw(readarray writefile appendfile);
-
+use IRCNOW::IO::IRC;
 use File::Copy qw(copy);
 
 my %conf = %main::conf;
@@ -24,13 +24,13 @@ my $hostnameif = $conf{hostnameif};
 if (host($hostname) =~ /(\d+\.){3,}\d+/) {
 	$ip4 = $&;
 }
-main::cbind("msg", "-", "setrdns", \&msetrdns);
-main::cbind("msg", "-", "delrdns", \&mdelrdns);
-main::cbind("msg", "-", "setdns", \&msetdns);
-main::cbind("msg", "-", "deldns", \&mdeldns);
-main::cbind("msg", "-", "host", \&mhost);
-main::cbind("msg", "-", "nextdns", \&mnextdns);
-main::cbind("msg", "-", "readip6s", \&mreadip6s);
+IRCNOW::IO::IRC::cbind("msg", "-", "setrdns", \&msetrdns);
+IRCNOW::IO::IRC::cbind("msg", "-", "delrdns", \&mdelrdns);
+IRCNOW::IO::IRC::cbind("msg", "-", "setdns", \&msetdns);
+IRCNOW::IO::IRC::cbind("msg", "-", "deldns", \&mdeldns);
+IRCNOW::IO::IRC::cbind("msg", "-", "host", \&mhost);
+IRCNOW::IO::IRC::cbind("msg", "-", "nextdns", \&mnextdns);
+IRCNOW::IO::IRC::cbind("msg", "-", "readip6s", \&mreadip6s);
 
 sub init {
 	unveil("$zonedir", "rwc") or die "Unable to unveil $!";
@@ -42,13 +42,13 @@ sub init {
 # !setrdns 2001:bd8:: username.example.com
 sub msetrdns {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([0-9A-Fa-f:\.]{3,})\s+([-0-9A-Za-z\.]+)$/) {
 		my ($ip, $hostname) = ($1, $2);
 		if (setrdns($ip, $ip6subnet, $hostname)) {
-			main::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$hostname set to $ip");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
 		}
 	}
 }
@@ -56,28 +56,28 @@ sub msetrdns {
 # !delrdns 2001:bd8::
 sub mdelrdns {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([0-9A-Fa-f:\.]{3,})$/) {
 		my ($ip) = ($1);
 		if (delrdns($ip, $ip6subnet)) {
-			main::putserv($bot, "PRIVMSG $nick :$ip rDNS deleted");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$ip rDNS deleted");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :ERROR: failed to set rDNS");
 		}
 	}
 }
 # !setdns username 1.2.3.4
 sub msetdns {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-0-9A-Za-z\.]+)\s+([0-9A-Fa-f:\.]+)/) {
 		my ($name, $value) = ($1, $2);
 		if ($value =~ /:/ and setdns($name, $hostname, "AAAA", $value)) {
-			main::putserv($bot, "PRIVMSG $nick :$name.$hostname AAAA set to $value");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$name.$hostname AAAA set to $value");
 		} elsif (setdns($name, $hostname, "A", $value)) {
-			main::putserv($bot, "PRIVMSG $nick :$name.$hostname A set to $value");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$name.$hostname A set to $value");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :ERROR: failed to set DNS");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :ERROR: failed to set DNS");
 		}
 	}
 }
@@ -85,13 +85,13 @@ sub msetdns {
 # !deldns username
 sub mdeldns {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-0-9A-Za-z\.]+)$/) {
 		my ($name) = ($1);
 		if (setdns($name, $hostname)) {
-			main::putserv($bot, "PRIVMSG $nick :$text deleted");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$text deleted");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :ERROR: failed to delete DNS records");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :ERROR: failed to delete DNS records");
 		}
 	}
 }
@@ -99,26 +99,26 @@ sub mdeldns {
 # !host username
 sub mhost {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-0-9A-Za-z:\.]{3,})/) {
 		my ($hostname) = ($1);
-		main::putserv($bot, "PRIVMSG $nick :".host($hostname));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".host($hostname));
 	}
 }
 
 # !nextdns username
 sub mnextdns {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-0-9a-zA-Z]+)/) {
-		main::putserv($bot, "PRIVMSG $nick :$text set to ".nextdns($text));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$text set to ".nextdns($text));
 	}
 }
 
 # !readip6s
 sub mreadip6s {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	foreach my $line (readip6s($hostnameif)) {
 		print "$line\n"
 	}
@@ -170,7 +170,7 @@ sub setdns {
 	foreach my $line (@lines) {
 		# increment the zone's serial number
 		if ($line =~ /(\d{8})(\d{2})((\s+\d+){4}\s*\))/) {
-			my $date = main::date();
+			my $date = IRCNOW::IO::date();
 			my $serial = 0;
 			if ($date <= $1) { $serial = $2+1; }
 			$line = $`.$date.sprintf("%02d",$serial).$3.$';
blob - ab06993cb605c3f017486e41fe35a5b2f9ae7639
blob + 113220a433c9bc7f92201a1a1036fc7db5633940
--- lib/BotNow/Help.pm
+++ lib/BotNow/Help.pm
@@ -5,6 +5,10 @@ use warnings;
 use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 
+
+use lib qw(./lib);
+use IRCNOW::IO::IRC;
+
 my %conf = %main::conf;
 my $chans = $conf{chans};
 my $teamchans = $conf{teamchans};
@@ -12,9 +16,9 @@ my @teamchans = split /[,\s]+/m, $teamchans;
 my $staff = $conf{staff};
 my $terms = $conf{terms};
 my $time = "600";
-main::cbind("pub", "-", "help", \&help);
-main::cbind("msg", "-", "help", \&help);
-main::cbind("pub", "-", "request", \&help);
+IRCNOW::IO::IRC::cbind("pub", "-", "help", \&help);
+IRCNOW::IO::IRC::cbind("msg", "-", "help", \&help);
+IRCNOW::IO::IRC::cbind("pub", "-", "request", \&help);
 
 sub init {
 }
@@ -47,7 +51,7 @@ To delete a shell account, type !shell delete <usernam
 To verify a captcha, type !shell captcha <username>
 EOF
 	};
-	if (main::isstaff($bot, $nick)) {
+	if (IRCNOW::IO::IRC::isstaff($bot, $nick)) {
 		for my $mod (split ' ',$conf{modules}) {
 			if (exists $mod_admin_msgs->{$mod}) {
 				$msg.=$mod_admin_msgs->{$mod};
@@ -65,14 +69,14 @@ EOF
 	if (@args == 2) {
 		($chan, $text) = ($args[0], $args[1]);
 		if ($chans =~ $chan) {
-			main::putserv($bot, "PRIVMSG $chan :$nick: Please see private message.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$nick: Please see private message.");
 		}
 	} else {
 		$text = $args[0];
 	}
-	main::putserv($bot, "PRIVMSG $nick :$msg");
+	IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$msg");
 	foreach my $chan (@teamchans) {
-		main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}.". If you don't help the user, he will probably leave");
+		IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}.". If you don't help the user, he will probably leave");
 	}
 }
 
blob - 2cee5193d1821c0d1d63f8ca6a14f35c5766baea
blob + cf0e088ca4e13e263abd86615d38a43500cfc497
--- lib/BotNow/Mail.pm
+++ lib/BotNow/Mail.pm
@@ -6,6 +6,7 @@ use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 use lib qw(./lib);
 use IRCNOW::IO qw(readarray writefile);
+use IRCNOW::IO::IRC;
 use BotNow::Hash;
 use File::Copy qw(copy);
 use MIME::Base64;
@@ -29,7 +30,7 @@ my $virtualspath = "/etc/mail/virtuals";
 my $senderspath = "/etc/mail/users";
 my @users;
 
-main::cbind("msg", "-", "mail", \&mmail);
+IRCNOW::IO::IRC::cbind("msg", "-", "mail", \&mmail);
 
 sub init {
 	#dependencies for encrypt
@@ -54,24 +55,24 @@ sub mmail {
 	} else { $text = $args[0]; }
 	my $hostmask = "$nick!$host";
 	if (defined($chan) && $chans =~ /$chan/) {
-		main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
 	}
 	if ($text =~ /^$/) {
-		main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with mail");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with mail");
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		if (BotNow::SQLite::deleterows("mail", "username", $username)) {
 			deletemail($username);
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :$username email deleted");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username email deleted");
 			}
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		my @passwd = readarray($passwdpath);
 		foreach my $line (@passwd) {
@@ -84,7 +85,7 @@ sub mmail {
 		copy "${passwdpath}.bak", $passwdpath;
 
 		foreach my $chan (@teamchans) {
-			main::putserv($bot, "PRIVMSG $chan :$username mail approved");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username mail approved");
 		}
 		return;
 	}
@@ -93,7 +94,7 @@ sub mmail {
 	foreach my $row (@rows) {
 		my $password = BotNow::SQLite::get("mail", "ircid", $row->{id}, "password");
 		if (defined($password)) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 			return;
 		}
 	}
@@ -104,7 +105,7 @@ sub mmail {
 		my $ircid = BotNow::SQLite::id("irc", "nick", $nick, $expires);
 		my $captcha = BotNow::SQLite::get("mail", "ircid", $ircid, "captcha");
 		if ($text ne $captcha) {
-			main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !mail <username> <email>");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !mail <username> <email>");
 			return;
 		}
 		my $pass = BotNot::Hash::newpass();
@@ -115,7 +116,7 @@ sub mmail {
 		BotNow::SQLite::set("mail", "ircid", $ircid, "password", $encrypted);
 		sleep(2);
 		createmail($pass, $username);
-		main::putserv($bot, "PRIVMSG $nick :Check your email!");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Check your email!");
 		sleep(5);
 		mailmail($username, $pass, $email);
 		if ($approval) {
@@ -129,13 +130,13 @@ sub mmail {
 			writefile("$passwdpath.bak", join("\n", @passwd)."\n");
 			copy "${passwdpath}.bak", $passwdpath;
 
-			main::putserv($bot, "PRIVMSG $nick :Your account has been created but must be manually approved by your admins ($staff) before it can be used.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Your account has been created but must be manually approved by your admins ($staff) before it can be used.");
 			foreach my $chan (@teamchans) {
-				main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s account $username must be manually unblocked before it can be used.");
+				IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s account $username must be manually unblocked before it can be used.");
 			}
 		}
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s mail registration of $username\@$mailhostname on $bot->{name} was successful, but you *must* help him to connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Email.Email");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s mail registration of $username\@$mailhostname on $bot->{name} was successful, but you *must* help him to connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Email.Email");
 		}
 		#www($newnick, $reply, $password, "bouncer");
 		return;
@@ -145,7 +146,7 @@ sub mmail {
 		foreach my $row (@userrows) {
 			my $password = BotNow::SQLite::get("mail", "ircid", $row->{id}, "password");
 			if (defined($password)) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -153,7 +154,7 @@ sub mmail {
 		foreach my $row (@userrows) {
 			my $password = BotNow::SQLite::get("mail", "ircid", $row->{id}, "password");
 			if (defined($password)) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -161,7 +162,7 @@ sub mmail {
 #		my @users = treeget($znctree, "User", "Node");
 		foreach my $user (@users) {
 			if ($user eq $username) {
-				main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please contact staff if you need help.");
 				return;
 			}
 		}
@@ -179,19 +180,19 @@ sub mmail {
 		BotNow::SQLite::set("mail", "ircid", $ircid, "email", $email);
 		BotNow::SQLite::set("mail", "ircid", $ircid, "captcha", $captcha);
 		BotNow::SQLite::set("mail", "ircid", $ircid, "hashid", $hashid);
-		main::whois($bot->{sock}, $nick);
-		main::ctcp($bot->{sock}, $nick);
-		main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
-#main::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
-#main::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
-		main::putserv($bot, "PRIVMSG $nick :Type !mail captcha <text>");
+		IRCNOW::IO::IRC::whois($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::ctcp($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
+#IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :https://$hostname/$hashid/captcha.png");
+#IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :https://$hostname/register.php?hashirc=$hashid");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !mail captcha <text>");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} mail captcha is $captcha");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s on $bot->{name} mail captcha is $captcha");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !mail <username> <email> to try again.");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !mail <username> <email> to try again.");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with mail");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with mail");
 		}
 	}
 }
blob - d0635f8de487aacb83c0d4a8d28ca9b93691aadf
blob + a8c6a9676056119f2a4041799c5acf11bcde2196
--- lib/BotNow/SQLite.pm
+++ lib/BotNow/SQLite.pm
@@ -6,30 +6,25 @@ use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 use lib qw(./lib);
 use IRCNOW::IO qw(readstr :DEBUG);
+use IRCNOW::IO::IRC;
 
 use Data::Dumper;
 use DBI;
 use DBD::SQLite;
 
-use constant {
-	NONE => 0,
-	ERRORS => 1,
-	WARNINGS => 2,
-	ALL => 3,
-};
 my %conf = %main::conf;
 my $staff = $conf{staff};
 my $dbh;
 my $verbose = $conf{verbose};
 my $dbpath = "/var/www/botnow/botnow.db";
 my $database = "/var/www/botnow/"; # database path
-main::cbind("msg", "-", "get", \&mget);
-main::cbind("msg", "-", "set", \&mset);
-main::cbind("msg", "-", "connectdb", \&mconnectdb);
-main::cbind("msg", "-", "insert", \&minsert);
-main::cbind("msg", "-", "update", \&mupdate);
-main::cbind("msg", "-", "delete", \&mdelete);
-main::cbind("msg", "-", "select", \&mselect);
+IRCNOW::IO::IRC::cbind("msg", "-", "get", \&mget);
+IRCNOW::IO::IRC::cbind("msg", "-", "set", \&mset);
+IRCNOW::IO::IRC::cbind("msg", "-", "connectdb", \&mconnectdb);
+IRCNOW::IO::IRC::cbind("msg", "-", "insert", \&minsert);
+IRCNOW::IO::IRC::cbind("msg", "-", "update", \&mupdate);
+IRCNOW::IO::IRC::cbind("msg", "-", "delete", \&mdelete);
+IRCNOW::IO::IRC::cbind("msg", "-", "select", \&mselect);
 
 sub init {
 	unveil("$dbpath", "rwc") or die "Unable to unveil $!";
@@ -40,11 +35,11 @@ sub init {
 # !connectdb
 sub mconnectdb {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if (connectdb()) {
-		main::putserv($bot, "PRIVMSG $nick :connectdb succeeded");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :connectdb succeeded");
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :ERROR: connectdb failed");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :ERROR: connectdb failed");
 	}
 }
 
@@ -52,18 +47,18 @@ sub mconnectdb {
 # Insert comma-separated keys and vals into table
 sub minsert {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+([[:ascii:]]+)/) {
 		my ($table, $keys, $vals) = ($1, $2, $3);
 		# strings in the values must be quoted
 		if ($vals =~ s{,}{","}g) { $vals = '"'.$vals.'"'; }
 		if (insertrow($table, $keys, $vals)) {
-			main::putserv($bot, "PRIVMSG $nick :$table ($keys) => ($vals)");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table ($keys) => ($vals)");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :$table insert failed");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table insert failed");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :invalid insert");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :invalid insert");
 	}
 }
 
@@ -71,16 +66,16 @@ sub minsert {
 # !update <table> <idkey> <idval> <key> <val>
 sub mupdate {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+(\S+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
 		my ($table, $idkey, $idval, $key, $val) = ($1, $2, $3, $4, $5);
 		if (updaterow($table, $idkey, $idval, $key, $val)) {
-			main::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :update failed");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :update failed");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :invalid update");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :invalid update");
 	}
 }
 
@@ -88,16 +83,16 @@ sub mupdate {
 # !delete <table> <key> <val>
 sub mdelete {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
 		my ($table, $key, $val) = ($1, $2, $3);
 		if (deleterows($table, $key, $val)) {
-			main::putserv($bot, "PRIVMSG $nick :$table $key = $val deleted");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table $key = $val deleted");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :delete failed");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :delete failed");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :invalid delete");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :invalid delete");
 	}
 }
 
@@ -105,7 +100,7 @@ sub mdelete {
 # !select <table> <key> <val>
 sub mselect {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
 		my ($table, $key, $val) = ($1, $2, $3);
 		my @rows = selectrows($table, $key, $val);
@@ -116,13 +111,13 @@ sub mselect {
 					my $val = $row->{$key} || "";
 					push(@pairs, "$key => $val");
 				}
-				main::putserv($bot, "PRIVMSG $nick :$table ".join(',', @pairs));
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table ".join(',', @pairs));
 			}
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :no results");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :no results");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :select invalid");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :select invalid");
 	}
 }
 
@@ -130,32 +125,32 @@ sub mselect {
 # !get <table> <idkey> <idval> <key>
 sub mget {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+(\S+)\s+([-_[:alnum:]]+)/) {
 		my ($table, $idkey, $idval, $key) = ($1, $2, $3, $4);
 		my $val = get($table, $idkey, $idval, $key);
 		if (defined($val)) {
-			main::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :undefined");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :undefined");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :invalid get");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :invalid get");
 	}
 }
 # !set <table> <idkey> <idval> <key> <val>
 sub mset {
 	my ($bot, $nick, $host, $hand, $text) = @_;
-	if (! (main::isstaff($bot, $nick))) { return; }
+	if (! (IRCNOW::IO::IRC::isstaff($bot, $nick))) { return; }
 	if ($text =~ /^([-_~@!,\.[:alnum:]]+)\s+([-_~@!,\.[:alnum:]]+)\s+(\S+)\s+([-_[:alnum:]]+)\s+(\S+)/) {
 		my ($table, $idkey, $idval, $key, $val) = ($1, $2, $3, $4, $5);
 		if (set($table, $idkey, $idval, $key, $val)) {
-			main::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$table $key => $val where $idkey = $idval");
 		} else {
-			main::putserv($bot, "PRIVMSG $nick :failed set");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :failed set");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :invalid set");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :invalid set");
 	}
 }
 
blob - fc9c7f68334fbf37df0bdade7e009c8cb8be410a
blob + b29fc08961862de6e3c59c2afb6ba166869f76ea
--- lib/BotNow/Shell.pm
+++ lib/BotNow/Shell.pm
@@ -10,6 +10,7 @@ use Digest::SHA qw(sha256_hex);
 
 use lib './lib';
 use IRCNOW::IO qw(:FILEIO :DEBUG);
+use IRCNOW::IO::IRC;
 use BotNow::SQLite;
 use BotNow::Hash;
 
@@ -43,8 +44,8 @@ use constant {
 	ALL => 3,
 };
 
-main::cbind("pub", "-", "shell", \&mshell);
-main::cbind("msg", "-", "shell", \&mshell);
+IRCNOW::IO::IRC::cbind("pub", "-", "shell", \&mshell);
+IRCNOW::IO::IRC::cbind("msg", "-", "shell", \&mshell);
 
 sub init {
 	#dependencies for figlet
@@ -82,29 +83,29 @@ sub mshell {
 	} else { $text = $args[0]; }
 	my $hostmask = "$nick!$host";
 	if (defined($chan) && $chans =~ /$chan/) {
-		main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
 	}
 	if ($text =~ /^$/) {
-		main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with shell registration");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with shell registration");
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^delete\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		if (BotNow::SQLite::deleterows("shell", "username", $username)) {
 			# TODO delete shell
 			deleteshell($username);
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :$username deleted");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username deleted");
 			}
 		}
 		return;
-	} elsif (main::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
+	} elsif (IRCNOW::IO::IRC::isstaff($bot, $nick) && $text =~ /^approve\s+([[:ascii:]]+)/) {
 		my $username = $1;
 		system "doas usermod -U $username";
 		foreach my $chan (@teamchans) {
-			main::putserv($bot, "PRIVMSG $chan :$username approved");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$username approved");
 		}
 		return;
 	}
@@ -113,7 +114,7 @@ sub mshell {
 	foreach my $row (@rows) {
 		my $password = BotNow::SQLite::get("shell", "ircid", $row->{id}, "password");
 		if (defined($password)) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 			return;
 		}
 	}
@@ -125,7 +126,7 @@ sub mshell {
 		if (!defined($ircid)) { die "undefined ircid"; }
 		my $captcha = BotNow::SQLite::get("shell", "ircid", $ircid, "captcha");
 		if ($text ne $captcha) {
-			main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !shell <username> <email>");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !shell <username> <email>");
 			return;
 		}
 		my $pass = BotNow::Hash::newpass();
@@ -139,23 +140,23 @@ sub mshell {
 			sleep(2);
 			createshell($username, $pass, $bindhost);
 			mailshell($username, $email, $pass, "shell", $version);
-			main::putserv($bot, "PRIVMSG $nick :Check your email!");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Check your email!");
 			if ($approval eq "true") {
 				system "doas usermod -Z $username";
-				main::putserv($bot, "PRIVMSG $nick :Your account has been created but must be manually approved by your admins ($staff) before it can be used.");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Your account has been created but must be manually approved by your admins ($staff) before it can be used.");
 				foreach my $chan (@teamchans) {
-					main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s account $username must be manually unblocked before it can be used.");
+					IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s account $username must be manually unblocked before it can be used.");
 				}
 			}
 			foreach my $chan (@teamchans) {
-				main::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s shell registration of $username on $bot->{name} was successful, *but* you *must* help him connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Shell.Shell");
+				IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: $nick\'s shell registration of $username on $bot->{name} was successful, *but* you *must* help him connect. Most users are unable to connect. Show him https://wiki.ircnow.org/?n=Shell.Shell");
 			}
 
 
 			#www($newnick, $reply, $password, "bouncer");
 		} else {
 			foreach my $chan (@teamchans) {
-				main::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
+				IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :Assigning bindhost $bindhost failed");
 			}
 		}
 		return;
@@ -164,7 +165,7 @@ sub mshell {
 		my @users = col($passpath, 1, ":");
 		my @matches = grep(/^$username$/i, @users);
 		if (scalar(@matches) > 0) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help.");
 			return;
 		}
 		#		my $captcha = join'', map +(0..9,'a'..'z','A'..'Z')[rand(10+26*2)], 1..4;
@@ -177,18 +178,18 @@ sub mshell {
 		BotNow::SQLite::set("shell", "ircid", $ircid, "username", $username);
 		BotNow::SQLite::set("shell", "ircid", $ircid, "email", $email);
 		BotNow::SQLite::set("shell", "ircid", $ircid, "captcha", $captcha);
-		main::whois($bot->{sock}, $nick);
-		main::ctcp($bot->{sock}, $nick);
-		main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
-		#		main::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
-		main::putserv($bot, "PRIVMSG $nick :Type !shell captcha <text>");
+		IRCNOW::IO::IRC::whois($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::ctcp($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
+		#		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !shell captcha <text>");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha");
 		}
 	} else {
-		main::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !shell <username> <email> to try again.");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Invalid username or email. Type !shell <username> <email> to try again.");
 		foreach my $chan (@teamchans) {
-			main::putserv($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with shell registration");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$staff: Help *$nick* on network ".$bot->{name}." with shell registration");
 		}
 	}
 }
@@ -234,10 +235,10 @@ EOF
 #	if ($staff !~ /$nick/) { return; }
 #	if ($text =~ /^ips?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
 #		my $ips = $1; # space-separated list of IPs
-#		main::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
+#		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".regexlist($ips));
 #	} elsif ($text =~ /^users?\s+([-_()|0-9A-Za-z:\.?*\s]{3,})$/) {
 #		my $users = $1; # space-separated list of usernames
-#		main::putserv($bot, "PRIVMSG $nick :".regexlist($users));
+#		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".regexlist($users));
 #	} elsif ($text =~ /^[-_()|0-9A-Za-z:,\.?*\s]{3,}$/) {
 #		my @lines = regex($text);
 #		foreach my $l (@lines) { print "$l\n"; }
@@ -249,7 +250,7 @@ EOF
 #	if ($text =~ /^network\s+del\s+([[:graph:]]+)\s+(#[[:graph:]]+)$/) {
 #		my ($user, $chan) = ($1, $2);
 #		foreach my $n (@main::networks) {
-#			main::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
+#			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG *controlpanel :delchan $user $n->{name} $chan");
 #		}
 #	}
 #}
blob - a4458d218b90f0eb6900a88a8106198c9b7cc12e
blob + 74f111b30cdf483d670c95dd133b06cb00ccc4c1
--- lib/BotNow/VPN.pm
+++ lib/BotNow/VPN.pm
@@ -6,6 +6,7 @@ use OpenBSD::Pledge;
 use OpenBSD::Unveil;
 use lib qw(./lib);
 use IRCNOW::IO qw(:DEBUG readarray);
+use IRCNOW::IO::IRC;
 use BotNow::DNS;
 use BotNow::SQLite;
 
@@ -20,8 +21,8 @@ my $ikedconf = $conf{ikedconf} || "/etc/iked.conf";
 my $netpath = "networks";
 my @networks;
 
-main::cbind("pub", "-", "vpn", \&vpn);
-main::cbind("msg", "-", "vpn", \&vpn);
+IRCNOW::IO::IRC::cbind("pub", "-", "vpn", \&vpn);
+IRCNOW::IO::IRC::cbind("msg", "-", "vpn", \&vpn);
 
 sub init {
 #        unveil("/usr/bin/rcctl", "rx") or die "Unable to unveil $!";
@@ -36,12 +37,12 @@ sub vpn {
 	} else { $text = $args[0]; }
 	my $hostmask = "$nick!$host";
 	if (defined($chan) && $chans =~ /$chan/) {
-		main::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $chan :$nick: Please check private message");
 	}
 	if ($text =~ /^$/) {
-		main::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !help for new instructions");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network".$bot->{name});
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: Help *$nick* on network".$bot->{name});
 		}
 		return;
 	}
@@ -49,7 +50,7 @@ sub vpn {
 	foreach my $row (@rows) {
 		my $password = BotNow::SQLite::get("vpn", "ircid", $row->{id}, "password");
 		if (defined($password)) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, only one account per person. Please contact staff if you need help.");
 			return;
 		}
 	}
@@ -59,7 +60,7 @@ sub vpn {
 		if (!defined($ircid)) { die "undefined ircid"; }
 		my $captcha = BotNow::SQLite::get("vpn", "ircid", $ircid, "captcha");
 		if ($text ne $captcha) {
-			main::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !vpn <username> <email>");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Wrong captcha. To get a new captcha, type !vpn <username> <email>");
 			return;
 		}
 		my $pass = Hash::newpass();
@@ -71,14 +72,14 @@ sub vpn {
 
 		createvpn($username, $pass);
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$staff: vpn created for $username");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$staff: vpn created for $username");
 		}
 		my $msg = <<"EOF";
 Your vpn account has been created! Username: $username with password: $pass
 Our official support channel is #vpn. To connect, please follow these instructions:
 https://wiki.ircnow.org/Vpn/Vpn
 EOF
-		main::putserv($bot, "PRIVMSG $nick :$msg");
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$msg");
 	} elsif ($text =~ /^([[:alnum:]]+)\s+([[:ascii:]]+)/) {
 		my ($username, $email) = ($1, $2);
 		if ($staff !~ /$nick/) {
@@ -87,7 +88,7 @@ EOF
 		my @users = col($ikedconf);
 		my @matches = grep(/^$username$/i, @users);
 		if (scalar(@matches) > 0) {
-			main::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help.");
+			IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Sorry, username taken. Please choose another username, or contact staff for help.");
 			return;
 		}
 
@@ -100,13 +101,13 @@ EOF
 		BotNow::SQLite::set("vpn", "ircid", $ircid, "username", $username);
 		BotNow::SQLite::set("vpn", "ircid", $ircid, "email", $email);
 		BotNow::SQLite::set("vpn", "ircid", $ircid, "captcha", $captcha);
-		main::whois($bot->{sock}, $nick);
-		main::ctcp($bot->{sock}, $nick);
-		main::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
-                # main::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
-		main::putserv($bot, "PRIVMSG $nick :Type !vpn captcha <text>");
+		IRCNOW::IO::IRC::whois($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::ctcp($bot->{sock}, $nick);
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :".`figlet $captcha`);
+                # IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :$captchaURL".encode_base64($captcha));
+		IRCNOW::IO::IRC::putserv($bot, "PRIVMSG $nick :Type !vpn captcha <text>");
 		foreach my $chan (@teamchans) {
-			main::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha");
+			IRCNOW::IO::IRC::putservlocalnet($bot, "PRIVMSG $chan :$nick\'s captcha on $bot->{name} is $captcha");
 		}
 	}
 }
blob - 1b9d3c102d84fe256286ae734552cf81aa9d564c
blob + 2d3ea918fdac8984935809211926f9da6fd78479
--- report
+++ report
@@ -91,10 +91,10 @@ sub connectdb {
 		FetchHashKeyName => 'NAME_lc',
 	}) or die "Couldn't connect to database: " . $DBI::errstr;
 	if (!(-s "$dbpath")) {
-		main::debug(ALL, "Cant locate $dbpath");
+		debug(ALL, "Cant locate $dbpath");
 		exit 1;
 	}
-	main::debug(ALL, "connected to $dbpath");
+	debug(ALL, "connected to $dbpath");
 	return $dbh;
 }
 # Read and index the znc log file.