# index.cgi
# Display logging search form
+use strict;
+use warnings;
require './webminlog-lib.pl';
+our (%text, %gconfig, %access_users, %in, %config);
&foreign_require("acl", "acl-lib.pl");
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
print &ui_form_start("search.cgi");
print &ui_table_start($text{'index_header'}, undef, 2);
-@ulist = sort { $a->{'name'} cmp $b->{'name'} } &acl::list_users();
-@canulist = grep { &can_user($_->{'name'}) } @ulist;
+my @ulist = sort { $a->{'name'} cmp $b->{'name'} } &acl::list_users();
+my @canulist = grep { &can_user($_->{'name'}) } @ulist;
if (@canulist == 1) {
# Can only show one user, so skip this field
print &ui_hidden("uall", 1),"\n";
}
else {
# Show user selectors
- @unames = grep { &can_user($_) } map { $_->{'name'} } @ulist;
- @opts = ( [ 1, $text{'index_uall'}."<br>" ],
- [ 0, $text{'index_user'}." ".
+ my @unames = grep { &can_user($_) } map { $_->{'name'} } @ulist;
+ my @opts = ( [ 1, $text{'index_uall'}."<br>" ],
+ [ 0, $text{'index_user'}." ".
&ui_select("user", undef, \@unames)."<br>" ] );
if ($access_users{'*'}) {
push(@opts, [ 2, $text{'index_nuser'}." ".
}
# Modules to search
+my @mods;
if (&can_mod("global")) {
push(@mods, [ "global", $text{'index_global'} ]);
}
-foreach $m (sort { $a->{'desc'} cmp $b->{'desc'} } &get_all_module_infos()) {
+foreach my $m (sort { $a->{'desc'} cmp $b->{'desc'} } &get_all_module_infos()) {
next if (!&can_mod($m->{'dir'}));
- $mdir = &module_root_directory($m->{'dir'});
+ my $mdir = &module_root_directory($m->{'dir'});
if (-r "$mdir/log_parser.pl" && &check_os_support($m)) {
push(@mods, [ $m->{'dir'}, $m->{'desc'} ]);
}
}
-@opts = ( [ 1, $text{'index_mall'}."<br>" ],
- [ 0, $text{'index_module'}." ".
+my @opts = ( [ 1, $text{'index_mall'}."<br>" ],
+ [ 0, $text{'index_module'}." ".
&ui_select("module", $in{'module'}, \@mods) ] );
print &ui_table_row($text{'index_smods'},
&ui_radio("mall", 1, \@opts));
sub time_input
{
-local $rv = "<input name=$_[0]_d size=2>/";
-$rv .= "<select name=$_[0]_m>";
-for($i=0; $i<12; $i++) {
- $rv .= "<option value=$i>".$text{"smonth_".($i+1)}."\n";
- }
-$rv .= "</select>/<input name=$_[0]_y size=4>";
-$rv .= " ".&date_chooser_button("$_[0]_d", "$_[0]_m", "$_[0]_y");
-return $rv;
+my ($name) = @_;
+return &ui_date_input(undef, undef, undef,
+ $name."_d", $name."_m", $name."_y").
+ &date_chooser_button($name."_d", $name."_m", $name."_y");
}
# rollback.cgi
# Revert all changed config files, after asking for confirmation
+use strict;
+use warnings;
require './webminlog-lib.pl';
+our (%text, %in, %access);
&ReadParse();
-$act = &get_action($in{'id'});
+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'});
-%r = map { $_, 1 } split(/\0/, $in{'r'});
+my %r = map { $_, 1 } split(/\0/, $in{'r'});
%r || &error($text{'rollback_enone'});
-@files = grep { $r{$_->{'file'}} } &list_files($act);
+my @files = grep { $r{$_->{'file'}} } &list_files($act);
&ui_print_header(undef, $text{'rollback_title'}, "");
if ($in{'confirm'}) {
# Do it!
- foreach $f (@files) {
+ my %done;
+ foreach my $f (@files) {
next if ($done{$f->{'file'}});
if (-d $f->{'file'} || $f->{'type'} == 1) {
# Skip directory
# 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);
+ my $fh;
+ &open_tempfile($fh, ">$f->{'file'}");
+ &print_tempfile($fh, $f->{'data'});
+ &close_tempfile($fh);
&unlock_file($f->{'file'});
print &text('rollback_madefile',
"<tt>$f->{'file'}</tt>");
}
else {
# Replace file with old contents
- &open_lock_tempfile(FILE, ">$f->{'file'}");
- &print_tempfile(FILE, $f->{'data'});
- &close_tempfile(FILE);
+ my $fh;
+ &open_lock_tempfile($fh, ">$f->{'file'}");
+ &print_tempfile($fh, $f->{'data'});
+ &close_tempfile($fh);
print &text('rollback_modfile',
"<tt>$f->{'file'}</tt>");
}
print "<br>\n";
$done{$f->{'file'}}++;
}
- %minfo = &get_module_info($act->{'module'});
+ my %minfo = &get_module_info($act->{'module'});
&webmin_log("rollback", undef, $in{'id'},
{ 'desc' => &get_action_description($act),
'mdesc' => $minfo{'desc'} });
print &ui_form_start("rollback.cgi");
print &ui_hidden("id", $in{'id'});
print &ui_hidden("search", $in{'search'});
- foreach $r (keys %r) {
+ foreach my $r (keys %r) {
print &ui_hidden("r", $r);
}
print $text{'rollback_rusure'},"<p>\n";
- foreach $f (@files) {
+ my %done;
+ my $count = 0;
+ foreach my $f (@files) {
next if ($done{$f->{'file'}});
print &ui_table_start("<tt>$f->{'file'}</tt>", "width=100%", 2);
print "<tr> <td colspan=2>";
# search.cgi
# Find webmin actions
+use strict;
+use warnings;
+use Time::Local;
require './webminlog-lib.pl';
-require 'timelocal.pl';
+our (%text, %config, %gconfig, $webmin_logfile, %in, $in);
&foreign_require("acl", "acl-lib.pl");
&ReadParse();
&error_setup($text{'search_err'});
$in{'wall'} = 1 if (!defined($in{'wall'}));
# Parse entered time ranges
+my ($from, $to);
if ($in{'tall'} == 2) {
# Today
- @now = localtime(time());
+ my @now = localtime(time());
$from = timelocal(0, 0, 0, $now[3], $now[4], $now[5]);
$to = timelocal(59, 59, 23, $now[3], $now[4], $now[5]);
$in{'tall'} = 0;
}
elsif ($in{'tall'} == 3) {
# Yesterday
- @now = localtime(time()-24*60*60);
+ my @now = localtime(time()-24*60*60);
$from = timelocal(0, 0, 0, $now[3], $now[4], $now[5]);
$to = timelocal(59, 59, 23, $now[3], $now[4], $now[5]);
$in{'tall'} = 0;
}
elsif ($in{'tall'} == 4) {
# Over the last week
- @week = localtime(time()-7*24*60*60);
+ my @week = localtime(time()-7*24*60*60);
$from = timelocal(0, 0, 0, $week[3], $week[4], $week[5]);
$to = time();
$in{'tall'} = 0;
}
# Perform initial search in index
+my @match;
+my %index;
&build_log_index(\%index);
open(LOG, $webmin_logfile);
-while(($id, $idx) = each %index) {
+while(my ($id, $idx) = each %index) {
my ($pos, $time, $user, $module, $sid) = split(/\s+/, $idx);
if (($in{'uall'} == 1 ||
$in{'uall'} == 0 && $in{'user'} eq $user ||
($in{'tall'} || $from < $time && $to > $time)) {
# Passed index check .. now look at actual log entry
seek(LOG, $pos, 0);
- $line = <LOG>;
- $act = &parse_logline($line);
+ my $line = <LOG>;
+ my $act = &parse_logline($line);
# Check Webmin server
next if (!$in{'wall'} && $in{'webmin'} ne $act->{'webmin'});
if ($gconfig{'logfiles'} && (!$in{'fall'} || !$in{'dall'})) {
# Make sure the specified file was modified
my $found = 0;
- foreach $d (&list_diffs($act)) {
+ foreach my $d (&list_diffs($act)) {
my $filematch = $in{'fall'} ||
$d->{'object'} &&
$d->{'object'} eq $in{'file'};
close(LOG);
# Build search description
-@from = localtime($from);
-@to = localtime($to);
-$fromstr = sprintf "%2.2d/%s/%4.4d",
- $from[3], $text{"smonth_".($from[4]+1)}, $from[5]+1900;
-$tostr = sprintf "%2.2d/%s/%4.4d",
- $to[3], $text{"smonth_".($to[4]+1)}, $to[5]+1900;
+my $fromstr = &make_date($from, 1);
+my $tostr = &make_date($to, 1);
+my %minfo;
if (!$in{'mall'}) {
%minfo = &get_module_info($in{'module'});
}
-$searchmsg = join(" ",
+my $searchmsg = join(" ",
$in{'uall'} == 0 ? &text('search_critu',
"<tt>".&html_escape($in{'user'})."</tt>") :
$in{'uall'} == 3 ? &text('search_critu',
$fromstr eq $tostr ? &text('search_critt2', $tostr) :
&text('search_critt', $fromstr, $tostr));
+my %minfo_cache;
if ($in{'csv'}) {
# Show search results as CSV
- foreach $act (sort { $b->{'time'} <=> $a->{'time'} } @match) {
- $minfo = $m eq "global" ?
+ my @cols;
+ foreach my $act (sort { $b->{'time'} <=> $a->{'time'} } @match) {
+ my $m = $act->{'module'};
+ my $minfo = $m eq "global" ?
{ 'desc' => $text{'search_global'} } :
$minfo_cache{$m};
if (!$minfo) {
print "<b>$text{'search_critall'} ..</b><p>\n";
}
else {
- @from = localtime($from); @to = localtime($to);
- $fromstr = sprintf "%2.2d/%s/%4.4d",
- $from[3], $text{"smonth_".($from[4]+1)}, $from[5]+1900;
- $tostr = sprintf "%2.2d/%s/%4.4d",
- $to[3], $text{"smonth_".($to[4]+1)}, $to[5]+1900;
- %minfo = &get_module_info($in{'module'}) if (!$in{'mall'});
+ my %minfo = &get_module_info($in{'module'}) if (!$in{'mall'});
print "<b>$text{'search_crit'} $searchmsg ...</b><p>\n";
}
print &ui_columns_start(
$config{'host_search'} ? ( $text{'search_webmin'} ) : ( ),
$text{'search_date'},
$text{'search_time'} ], "100");
- foreach $act (sort { $b->{'time'} <=> $a->{'time'} } @match) {
+ foreach my $act (sort { $b->{'time'} <=> $a->{'time'} } @match) {
my @tm = localtime($act->{'time'});
my $m = $act->{'module'};
my $d;
- $minfo = $m eq "global" ?
+ my $minfo = $m eq "global" ?
{ 'desc' => $text{'search_global'} } :
$minfo_cache{$m};
if (!$minfo) {
sub parse_time
{
-local $d = $in{"$_[0]_d"};
-local $m = $in{"$_[0]_m"};
-local $y = $in{"$_[0]_y"};
+my $d = $in{"$_[0]_d"};
+my $m = $in{"$_[0]_m"};
+my $y = $in{"$_[0]_y"};
return 0 if (!$d && !$y);
my $rv;
eval { $rv = timelocal(0, 0, 0, $d, $m, $y-1900) };
# view.cgi
# Show details of the action, including changed files
+use strict;
+use warnings;
require './webminlog-lib.pl';
+our (%text, %in);
&ReadParse();
# find the log record to view
-$act = &get_action($in{'id'});
+my $act = &get_action($in{'id'});
&can_user($act->{'user'}) || &error($text{'view_ecannot'});
&can_mod($act->{'module'}) || &error($text{'view_ecannot'});
# display info about the action
&ui_print_header(undef, $text{'view_title'}, "");
-@files = &list_files($act);
+my @files = &list_files($act);
print &ui_form_start("rollback.cgi");
print &ui_hidden("id", $in{'id'});
print &ui_hidden("search", $in{'search'});
print &ui_table_row($text{'view_action'}."",
&get_action_description($act, 1), 3);
-%minfo = $act->{'module'} eq 'global' ?
+my %minfo = $act->{'module'} eq 'global' ?
( 'desc' => $text{'search_global'} ) :
&get_module_info($act->{'module'});
print &ui_table_row($text{'view_module'},
"<a href='search.cgi?sid=$act->{'sid'}&uall=1&mall=1&tall=1&fall=1&return=".&urlize($in{'return'})."&returndesc=".&urlize($in{'returndesc'})."'>$act->{'sid'}</a>");
}
-@tm = localtime($act->{'time'});
-print &ui_table_row($text{'view_time'},
- sprintf("%2.2d/%s/%4.4d %2.2d:%2.2d:%2.2d",
- $tm[3], $text{"smonth_".($tm[4]+1)}, $tm[5]+1900,
- $tm[2], $tm[1], $tm[0]));
+print &ui_table_row($text{'view_time'}, &make_date($act->{'time'}));
if ($act->{'webmin'}) {
print &ui_table_row($text{'view_host'},
print &ui_hidden_table_end("main");
# Annotations for this log entry
-$text = &get_annotation($act);
+my $text = &get_annotation($act);
print &ui_hidden_table_start($text{'view_anno'}, "width=100%", 1, "anno",
$text ? 1 : 0);
print &ui_table_row(undef,
print &ui_hidden_table_end("anno");
# Page output, if any
-$output = &get_action_output($act);
+my $output = &get_action_output($act);
if ($output && &foreign_check("mailboxes")) {
&foreign_require("mailboxes");
$output = &mailboxes::filter_javascript($output);
# Raw log data, hidden by default
print &ui_hidden_table_start($text{'view_raw'}, "width=100%", 1, "raw", 0);
-@tds = ( "width=20% ");
-$rtable = &ui_columns_start([ $text{'view_rawname'}, $text{'view_rawvalue'} ],
- 100, 0, \@tds);
-foreach $k (keys %$act) {
+my @tds = ( "width=20% ");
+my $rtable = &ui_columns_start(
+ [ $text{'view_rawname'}, $text{'view_rawvalue'} ], 100, 0, \@tds);
+foreach my $k (keys %$act) {
next if ($k eq 'param');
$rtable .= &ui_columns_row([
"<b>".&html_escape($k)."</b>",
&html_escape($act->{$k}) ], \@tds);
}
-foreach $k (keys %{$act->{'param'}}) {
+foreach my $k (keys %{$act->{'param'}}) {
$rtable .= &ui_columns_row([
&html_escape($k),
&html_escape(join("\n", split(/\0/, $act->{'param'}->{$k}))) ],
print &ui_hidden_table_end("raw");
# display modified and commands run files
-$rbcount = 0;
-$i = 0;
-$fhtml = "";
-foreach $d (&list_diffs($act)) {
+my $rbcount = 0;
+my $i = 0;
+my $fhtml = "";
+my $anydiffs = 0;
+foreach my $d (&list_diffs($act)) {
my $t = $text{"view_type_".$d->{'type'}};
my $rb;
if ($d->{'type'} eq 'create' || $d->{'type'} eq 'modify' ||
=cut
BEGIN { push(@INC, ".."); };
+use strict;
+use warnings;
use WebminCore;
&init_config();
-%access = &get_module_acl();
-%access_mods = map { $_, 1 } split(/\s+/, $access{'mods'});
-%access_users = map { $_, 1 } split(/\s+/, $access{'users'});
+our %access = &get_module_acl();
+our %access_mods = map { $_, 1 } split(/\s+/, $access{'mods'});
+our %access_users = map { $_, 1 } split(/\s+/, $access{'users'});
+our %parser_cache;
+our (%text, $module_config_directory, $root_directory);
=head2 list_webmin_log([only-user], [only-module], [start-time, end-time])
}
$p = $3;
}
- foreach $k (keys %param) {
+ foreach my $k (keys %param) {
$param{$k} =~ s/%(..)/pack("c",hex($1))/ge;
}
$rv->{'param'} = \%param;
=cut
sub list_diffs
{
+my ($act) = @_;
my $i = 0;
my @rv;
my $idprefix = substr($act->{'id'}, 0, 5);
=cut
sub list_files
{
+my ($act) = @_;
my $i = 0;
my @rv;
my $idprefix = substr($act->{'id'}, 0, 5);
}
else {
&make_dir($dir, 0700) if (!-d $dir);
- &open_tempfile(ANNO, ">$file");
- &print_tempfile(ANNO, $text);
- &close_tempfile(ANNO);
+ my $fh;
+ &open_tempfile($fh, ">$file");
+ &print_tempfile($fh, $text);
+ &close_tempfile($fh);
}
}
}
else {
# Files are those that start with id
- $i = 0;
+ my $i = 0;
while(-r "$base.$i") {
push(@files, "$base.$i");
$i++;
my %index;
&build_log_index(\%index);
open(LOG, $webmin_logfile);
-local @idx = split(/\s+/, $index{$_[0]});
+my @idx = split(/\s+/, $index{$_[0]});
seek(LOG, $idx[0], 0);
my $line = <LOG>;
my $act = &parse_logline($line);
%$index = ( 'lastpos' => 0 );
}
while(<LOG>) {
+ my $act;
if ($act = &parse_logline($_)) {
$index->{$act->{'id'}} = $index->{'lastpos'}." ".
$act->{'time'}." ".