When rolling back changed files, you can now select which ones to revert rather than always doing all of them.
---- Changes since 1.330 ----
A description of the search is now shown for searches that didn't match anything.
+---- Changes since 1.350 ----
+Rollback actions can themselves now be rolled back.
rollback_deleted=Deleted file $1.
rollback_nodeleted=Skipped non-existant file $1.
rollback_enone=No files selected
+
+log_rollback=Rolled back action $1 in module $2
--- /dev/null
+# log_parser.pl
+# Functions for parsing this module's logs
+
+do 'webminlog-lib.pl';
+
+# parse_webmin_log(user, script, action, type, object, ¶ms)
+# Converts logged information from this module into human-readable form
+sub parse_webmin_log
+{
+local ($user, $script, $action, $type, $object, $p) = @_;
+if ($action eq 'rollback') {
+ return &text('log_rollback', "<i>".$p->{'desc'}."</i>",
+ "<i>".$p->{'mdesc'}."</i>");
+ }
+return undef;
+}
+
+1;
+
!-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',
"<tt>$f->{'file'}</tt>",
"<tt>$f->{'data'}</tt>");
elsif (-e $f->{'file'} && -l $f->{'file'} &&
$f->{'type'} == 0) {
# Remove link and create file
+ &lock_file($f->{'file'});
&unlink_file($f->{'file'});
&open_tempfile(FILE, ">$f->{'file'}");
&print_tempfile(FILE, $f->{'data'});
&close_tempfile(FILE);
+ &unlock_file($f->{'file'});
print &text('rollback_madefile',
"<tt>$f->{'file'}</tt>");
}
elsif ($f->{'type'} == -1) {
if (-e $f->{'file'}) {
# Remove file
- unlink($f->{'file'});
+ &unlink_logged($f->{'file'});
print &text('rollback_deleted',
"<tt>$f->{'file'}</tt>");
}
}
else {
# Replace file with old contents
- &open_tempfile(FILE, ">$f->{'file'}");
+ &open_lock_tempfile(FILE, ">$f->{'file'}");
&print_tempfile(FILE, $f->{'data'});
&close_tempfile(FILE);
print &text('rollback_modfile',
print "<br>\n";
$done{$f->{'file'}}++;
}
+ %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
# first time seeing module ..
local %minfo = &get_module_info($m);
$minfo = $minfo_cache{$m} = \%minfo;
- if (-r "../$m/log_parser.pl") {
- &foreign_require($m, "log_parser.pl");
- $parser{$m}++;
- }
}
local @cols;
- $d = &foreign_call($m, "parse_webmin_log",
- $act->{'user'}, $act->{'script'},
- $act->{'action'}, $act->{'type'},
- $act->{'object'}, $act->{'param'})
- if ($parser{$m});
- local $desc;
- if ($d) {
- $desc = $d;
- }
- elsif ($act->{'action'} eq '_config_') {
- $desc = $text{'search_config'};
- }
- else {
- $desc = sprintf "%s %s %s\n",
- $act->{'action'},
- $act->{'type'} ? $act->{'type'} : '',
- $act->{'object'} ? $act->{'object'} : '';
- }
+ local $desc = &get_action_description($act, 0);
push(@cols, "<a href='view.cgi?id=$act->{'id'}".
"&return=".&urlize($in{'return'}).
"&returndesc=".&urlize($in{'returndesc'}).
# find the log record to view
$act = &get_action($in{'id'});
-if (-r "../$act->{'module'}/log_parser.pl") {
- &foreign_require($act->{'module'}, "log_parser.pl");
- $parser++;
- }
&can_user($act->{'user'}) || &error($text{'view_ecannot'});
&can_mod($act->{'module'}) || &error($text{'view_ecannot'});
print &ui_table_start(&text('view_header', $act->{'id'}),
"width=100%", 4);
-$d = &foreign_call($act->{'module'}, "parse_webmin_log",
- $act->{'user'}, $act->{'script'},
- $act->{'action'}, $act->{'type'},
- $act->{'object'}, $act->{'param'}, 1) if ($parser);
-print &ui_table_row($text{'view_action'},
- $d ? $d :
- $act->{'action'} eq '_config_' ? $text{'search_config'} :
- join(" ", $act->{'action'}, $act->{'type'}, $act->{'object'}),
- 3);
+# This "" is needed to make the label show properly!
+print &ui_table_row($text{'view_action'}."",
+ &get_action_description($act, 1), 3);
%minfo = &get_module_info($act->{'module'});
print &ui_table_row($text{'view_module'},
# webminlog-lib.pl
-# XXX file rollback
-# XXX should we capture all files, or just those changed?
-# XXX what about commands?
do '../web-lib.pl';
&init_config();
}
}
+# get_action_description(&action, long)
+# Returns a human-readable description of some action
+sub get_action_description
+{
+local ($act, $long) = @_;
+if (!defined($parser_cache{$act->{'module'}})) {
+ # Bring in module parser library for the first time
+ if (-r "$root_directory/$act->{'module'}/log_parser.pl") {
+ &foreign_require($act->{'module'}, "log_parser.pl");
+ $parser_cache{$act->{'module'}} = 1;
+ }
+ else {
+ $parser_cache{$act->{'module'}} = 0;
+ }
+ }
+local $d;
+if ($parser_cache{$act->{'module'}}) {
+ $d = &foreign_call($act->{'module'}, "parse_webmin_log",
+ $act->{'user'}, $act->{'script'},
+ $act->{'action'}, $act->{'type'},
+ $act->{'object'}, $act->{'param'}, $long);
+ }
+return $d ? $d :
+ $act->{'action'} eq '_config_' ? $text{'search_config'} :
+ join(" ", $act->{'action'}, $act->{'type'}, $act->{'object'});
+}
+
1;