#!/usr/local/bin/perl
# change_bind.cgi
# Update the binding IP address and port for miniserv

require './webmin-lib.pl';
use Socket;
&ReadParse();
&get_miniserv_config(\%miniserv);
&error_setup($text{'bind_err'});

# check inputs
if ($in{'port'} !~ /^\d+$/ || $in{'port'} > 65535) {
	&error("'$in{'port'}' is not a valid port number");
	}
$baddr = $in{'bind_def'} ? INADDR_ANY : inet_aton($in{'bind'});
if (!$baddr) { &error(&text('bind_eip', $in{'bind'})); }
if ($baddr ne INADDR_ANY) {
	# check if address can be used
	local ($i, $ok);
	for($i=0; $i<10; $i++) {
		local $p = int(rand() * 1024)+1;
		socket(TEST, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
		setsockopt(TEST, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
		if (bind(TEST, sockaddr_in($p, $baddr))) {
			$ok++;
			}
		close(TEST);
		}
	$ok || &error(&text('bind_eassign', $in{'bind'}));
	}
if ($in{'port'} != $miniserv{'port'}) {
	# port has changed.. check if it is in use
	socket(TEST, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
	setsockopt(TEST, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
	bind(TEST, sockaddr_in($in{'port'}, $baddr)) ||
		&error(&text('bind_eport', $in{'port'}));
	close(TEST);
	}

&lock_file($ENV{'MINISERV_CONFIG'});
$miniserv{'port'} = $in{'port'};
if ($in{'bind_def'}) { delete($miniserv{'bind'}); }
else { $miniserv{'bind'} = $in{'bind'}; }
&put_miniserv_config(\%miniserv);
&unlock_file($ENV{'MINISERV_CONFIG'});
&restart_miniserv();
&webmin_log("bind", undef, undef, \%in);

if ($miniserv{'bind'}) { $url = $miniserv{'bind'}; }
else { $url = $ENV{'SERVER_NAME'}; }
$url .= ":$miniserv{'port'}/webmin/";
if ($ENV{'HTTPS'} eq "ON") { &redirect("https://$url"); }
else { &redirect("http://$url"); }

