#!/usr/local/bin/perl
# rollback.cgi
# Revert all changed config files, after asking for confirmation
use strict;
use warnings;
require './webminlog-lib.pl';
our (%text, %in, %access);
&ReadParse();
my $act = &get_action($in{'id'});
if ($in{'annosave'}) {
# Just saving an annotation
$in{'anno'} =~ s/\r//g;
&save_annotation($act, $in{'anno'});
&redirect("view.cgi?id=$in{'id'}&search=".&urlize($in{'search'}));
exit;
}
$access{'rollback'} || &error($text{'rollback_ecannot'});
&can_user($act->{'user'}) || &error($text{'view_ecannot'});
&can_mod($act->{'module'}) || &error($text{'view_ecannot'});
my %r = map { $_, 1 } split(/\0/, $in{'r'});
%r || &error($text{'rollback_enone'});
my @files = grep { $r{$_->{'file'}} } &list_files($act);
&ui_print_header(undef, $text{'rollback_title'}, "");
if ($in{'confirm'}) {
# Do it!
my %done;
foreach my $f (@files) {
next if ($done{$f->{'file'}});
if (-d $f->{'file'} || $f->{'type'} == 1) {
# Skip directory
print &text('rollback_skipdir',"$f->{'file'}");
}
elsif (-l $f->{'file'} && $f->{'type'} == 2 ||
!-e $f->{'file'} && $f->{'type'} == 2 ||
!-l $f->{'file'} && $f->{'type'} == 2) {
# Modify or create link
&lock_file($f->{'file'});
&unlink_file($f->{'file'});
&symlink_file($f->{'data'}, $f->{'file'});
&unlock_file($f->{'file'});
print &text('rollback_madelink',
"$f->{'file'}",
"$f->{'data'}");
}
elsif (-e $f->{'file'} && -l $f->{'file'} &&
$f->{'type'} == 0) {
# Remove link and create file
&lock_file($f->{'file'});
&unlink_file($f->{'file'});
my $fh;
&open_tempfile($fh, ">$f->{'file'}");
&print_tempfile($fh, $f->{'data'});
&close_tempfile($fh);
&unlock_file($f->{'file'});
print &text('rollback_madefile',
"$f->{'file'}");
}
elsif ($f->{'type'} == -1) {
if (-e $f->{'file'}) {
# Remove file
&unlink_logged($f->{'file'});
print &text('rollback_deleted',
"$f->{'file'}");
}
else {
print &text('rollback_nodeleted',
"$f->{'file'}");
}
}
else {
# Replace file with old contents
my $fh;
&open_lock_tempfile($fh, ">$f->{'file'}");
&print_tempfile($fh, $f->{'data'});
&close_tempfile($fh);
print &text('rollback_modfile',
"$f->{'file'}");
}
print "
\n";
$done{$f->{'file'}}++;
}
my %minfo = &get_module_info($act->{'module'});
&webmin_log("rollback", undef, $in{'id'},
{ 'desc' => &get_action_description($act),
'mdesc' => $minfo{'desc'} });
}
else {
# Show the user what will be done
print &ui_form_start("rollback.cgi");
print &ui_hidden("id", $in{'id'});
print &ui_hidden("search", $in{'search'});
foreach my $r (keys %r) {
print &ui_hidden("r", $r);
}
print $text{'rollback_rusure'},"
\n"; my %done; my $count = 0; foreach my $f (@files) { next if ($done{$f->{'file'}}); print &ui_table_start("$f->{'file'}", "width=100%", 2); print "
$f->{'data'}"; $count++; } elsif (!-l $f->{'file'} && $f->{'type'} == 2) { # Was a link, but is now a file print &text('rollback_makelink', "$f->{'data'}"); $count++; } elsif ($f->{'type'} == -1) { # Was created if (-e $f->{'file'}) { print &text('rollback_delete', "$f->{'file'}"); $count++; } else { print &text('rollback_nodelete', "$f->{'file'}"); } } elsif (!-e $f->{'file'}) { # No longer exists print $text{'rollback_fillfile'}; print "
$f->{'data'}"; $count++; } else { # Was a file, and is one now my $qnew = quotemeta($f->{'file'}); my $temp = &transname(); open(TEMP, ">$temp"); print TEMP $f->{'data'}; close(TEMP); my $out = &backquote_command("diff $qnew $temp"); if ($out) { print $text{'rollback_changes'}; print "
$out"; $count++; } else { print $text{'rollback_nochanges'}; } } $done{$f->{'file'}}++; print "