#!/usr/local/bin/perl
# upgrade.cgi
# Upgrade usermin if possible

require './usermin-lib.pl';
$access{'upgrade'} || &error($text{'acl_ecannot'});
&foreign_require("proc", "proc-lib.pl");
&ReadParseMime();
&get_usermin_miniserv_config(\%miniserv);

$| = 1;
$theme_no_table = 1;
&header($text{'upgrade_title'}, "");
print "<hr>\n";

if ($in{'source'} == 0) {
	# from local file
	&error_setup(&text('upgrade_err1', $in{'file'}));
	$file = $in{'file'};
	if (!(-r $file)) { &inst_error($text{'upgrade_efile'}); }
	}
elsif ($in{'source'} == 1) {
	# from uploaded file
	&error_setup($text{'upgrade_err2'});
	$file = &tempname();
	$need_unlink = 1;
	if ($no_upload) {
                &inst_error($text{'upgrade_ebrowser'});
                }
	open(MOD, "> $file");
	print MOD $in{'upload'};
	close(MOD);
	}
elsif ($in{'source'} == 2) {
	# find latest version at www.webmin.com by looking at index page
	&error_setup($text{'upgrade_err3'});
	$file = &tempname();
	&http_download('www.webmin.com', 80, '/index6.html', $file, \$error);
	$error && &inst_error($error);
	open(FILE, $file);
	while(<FILE>) {
		if (/usermin-([0-9\.]+)\.tar\.gz/) {
			$version = $1;
			last;
			}
		}
	close(FILE);
	unlink($file);
	if ($version == &get_usermin_version()) {
		&inst_error(&text('upgrade_elatest', $version));
		}
	elsif ($version <= &get_usermin_version()) {
		&inst_error(&text('upgrade_eversion', $version));
		}
	if ($in{'mode'} eq 'rpm') {
		$progress_callback_url = "http://www.webmin.com/download/rpm/usermin-$version-1.noarch.rpm";
		&http_download('www.webmin.com', 80,
		  "/download/rpm/usermin-$version-1.noarch.rpm", $file,
		  \$error, \&progress_callback);
		}
	else {
		$progress_callback_url = "http://www.webmin.com/download/usermin-$version.tar.gz";
		&http_download('www.webmin.com', 80,
		  "/download/usermin-$version.tar.gz", $file,
		  \$error, \&progress_callback);
		}
	$error && &inst_error($error);
	$need_unlink = 1;
	}
elsif ($in{'source'} == 5) {
	# Download from some URL
	&error_setup(&text('upgrade_err5', $in{'url'}));
	$file = &tempname();
	$progress_callback_url = $in{'url'};
	if ($in{'url'} =~ /^http:\/\/([^\/]+)(\/.*)$/) {
		$host = $1; $page = $2; $port = 80;
		if ($host =~ /^(.*):(\d+)$/) { $host = $1; $port = $2; }
		&http_download($host, $port, $page, $file, \$error,
			       \&progress_callback);
		}
	elsif ($in{'url'} =~ /^ftp:\/\/([^\/]+)(:21)?\/(.*)$/) {
		$host = $1; $ffile = $3;
		&ftp_download($host, $ffile, $file,
			      \$error, \&progress_callback);
		}
	else { &inst_error($text{'upgrade_eurl'}); }
	$need_unlink = 1;
	$error && &inst_error($error);
	}

# gunzip the file if needed
open(FILE, $file);
read(FILE, $two, 2);
close(FILE);
if ($two eq "\037\213") {
	if (!&has_command("gunzip")) {
		&inst_error($text{'upgrade_egunzip'});
		}
	$newfile = &tempname();
	$out = `gunzip -c $file 2>&1 >$newfile`;
	if ($?) {
		unlink($newfile);
		&inst_error(&text('upgrade_egzip', "<tt>$out</tt>"));
		}
	unlink($file) if ($need_unlink);
	$need_unlink = 1;
	$file = $newfile;
	}

if ($in{'mode'} eq 'rpm') {
	# Check if it is an RPM package
	$out = `rpm -qp $file`;
	$out =~ /^usermin-(\d+\.\d+)/ ||
		&inst_error($text{'upgrade_erpm'});
	if ($1 <= &get_usermin_version()) {
		&inst_error(&text('upgrade_eversion', "$1"));
		}

	# Install the RPM
	$cmd = "rpm -U --ignoreos --ignorearch --nodeps $file";
	print "<p>",&text('upgrade_setup', "<tt>$cmd</tt>"),"<br>\n";
	print "<pre>";
	&proc::safe_process_exec($cmd, 0, 0, STDOUT, undef, 1);
	print "</pre>";
	unlink($file) if ($need_unlink);
	}
else {
	# Check if it is a usermin tarfile
	open(TAR, "tar tf $file 2>&1 |");
	while(<TAR>) {
		if (/^usermin-([0-9\.]+)\//) {
			$version = $1;
			}
		if (/^webmin-([0-9\.]+)\//) {
			$webmin_version = $1;
			}
		if (/^[^\/]+\/(\S+)$/) {
			$hasfile{$1}++;
			}
		}
	close(TAR);
	if ($webmin_version) {
		&inst_error(&text('upgrade_ewebmin', $webmin_version));
		}
	if (!$version) {
		if ($hasfile{'module.info'}) {
			&inst_error(&text('upgrade_emod', 'edit_mods.cgi'));
			}
		else {
			&inst_error($text{'upgrade_etar'});
			}
		}
	if ($version <= &get_usermin_version()) {
		&inst_error(&text('upgrade_eversion', $version));
		}

	# Extract it next to the current directory and run setup.sh
	$| = 1;
	$out = `cd $miniserv{'root'}/.. ; tar xf $file 2>&1 >/dev/null`;
	if ($?) {
		&inst_error(&text('upgrade_euntar', "<tt>$out</tt>"));
		}
	unlink($file) if ($need_unlink);
	$ENV{'config_dir'} = $config{'usermin_dir'};
	$ENV{'webmin_upgrade'} = 1;
	$ENV{'autothird'} = 1;
	local $cmd;
	if ($in{'delete'}) {
		$cmd = "(cd $miniserv{'root'}/../usermin-$version ; ./setup.sh && rm -rf \"$miniserv{'root'}\")";
		}
	else {
		$cmd = "(cd $miniserv{'root'}/../usermin-$version ; ./setup.sh)";
		}
	print "<p>",&text('upgrade_setup', "<tt>setup.sh</tt>"),"<br>\n";
	print "<pre>";
	&proc::safe_process_exec($cmd, 0, 0, STDOUT, undef, 1);
	print "</pre>";
	}
&webmin_log("upgrade", undef, undef, { 'version' => $version,
				       'mode' => $in{'mode'} });

print "<hr>\n";
&footer("", $text{'index_return'});

sub inst_error
{
unlink($file) if ($need_unlink);
print "<br><b>$whatfailed : $_[0]</b> <p>\n";
print "<hr>\n";
&footer("", $text{'index_return'});
exit;
}

