diff --git a/CHANGELOG b/CHANGELOG index 0e238772e..e2ad5d562 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -95,3 +95,4 @@ MD5 encryption for Webmin and Unix passwords can be used on systems that have ei ---- Changes since 1.410 ---- Many Korean updates, thanks to JoungKyun Kim. More Dutch updates, thanks to Gandyman. +Added a debugging log file, which records all files read and written, commands run and more. This can be enabled in the Webmin Configuration module. diff --git a/web-lib-funcs.pl b/web-lib-funcs.pl index 999141447..0a3ae10fd 100755 --- a/web-lib-funcs.pl +++ b/web-lib-funcs.pl @@ -906,7 +906,7 @@ local(@pids); @pids = &find_byname($_[0]); return scalar(@pids) if (&is_readonly_mode()); &webmin_debug_log('KILL', "signal=$_[1] name=$_[0]") - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_procs'}); if (@pids) { kill($_[1], @pids); return scalar(@pids); } else { return 0; } } @@ -2609,19 +2609,35 @@ else { &error("Script was not run with full path (failed to find $0 under $root_directory)") if (!$rok); } +# Work out of this is a web, command line or cron job +if (!$main::webmin_script_type) { + if ($ENV{'SCRIPT_NAME'}) { + # Run via a CGI + $main::webmin_script_type = 'web'; + } + else { + # Cron jobs have no TTY + if ($gconfig{'os_type'} eq 'windows' || + open(DEVTTY, ">/dev/tty")) { + $main::webmin_script_type = 'cmd'; + close(DEVTTY); + } + else { + $main::webmin_script_type = 'cron'; + } + } + } + # Set the umask based on config if ($gconfig{'umask'} && !$main::umask_already++) { umask(oct($gconfig{'umask'})); } # If this is a cron job or other background task, set the nice level -if (!$main::nice_already && !$ENV{'SCRIPT_NAME'} && $gconfig{'nice'} && - $gconfig{'os_type'} ne 'windows') { +if (!$main::nice_already && $gconfig{'nice'} && + $main::webmin_script_type eq 'cron') { # Cron jobs have no tty - if (!open(TTY, ">/dev/tty")) { - eval 'use POSIX; POSIX::nice($gconfig{\'nice\'});'; - } - close(TTY); + eval 'use POSIX; POSIX::nice($gconfig{\'nice\'});'; } $main::nice_already++; @@ -2678,8 +2694,8 @@ if ($gconfig{'debug_enabled'} && !$main::opened_debug_log++) { if ($gconfig{'debug_what_start'}) { local $script_name = $0 =~ /([^\/]+)$/ ? $1 : '-'; $main::debug_log_start_time = time(); - &webmin_debug_log("START", - "module=$module_name script=$script_name"); + &webmin_debug_log("START", "script=$script_name"); + $main::debug_log_start_module = $module_name; } } @@ -3598,6 +3614,7 @@ sub webmin_debug_log { local ($type, $msg) = @_; return 0 if (!$main::opened_debug_log); +return 0 if ($gconfig{'debug_no'.$main::webmin_script_type}); local $now = time(); local @tm = localtime($now); local $line = sprintf @@ -3714,7 +3731,7 @@ sub kill_logged { return scalar(@_)-1 if (&is_readonly_mode()); &webmin_debug_log('KILL', "signal=$_[0] pids=".join(" ", @_[1..@_-1])) - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_procs'}); &additional_log('kill', $_[0], join(" ", @_[1..@_-1])) if (@_ > 1); if ($gconfig{'os_type'} eq 'windows') { # Emulate some kills with process.exe @@ -3759,7 +3776,7 @@ if (&is_readonly_mode()) { local $src = &translate_filename($_[0]); local $dst = &translate_filename($_[1]); &webmin_debug_log('RENAME', "src=$src dst=$dst") - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_ops'}); local $ok = rename($src, $dst); if (!$ok && $! !~ /permission/i) { # Try the mv command, in case this is a cross-filesystem rename @@ -3800,7 +3817,7 @@ if (&is_readonly_mode()) { local $src = &translate_filename($_[0]); local $dst = &translate_filename($_[1]); &webmin_debug_log('SYMLINK', "src=$src dst=$dst") - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_ops'}); return symlink($src, $dst); } @@ -3816,7 +3833,7 @@ if (&is_readonly_mode()) { local $src = &translate_filename($_[0]); local $dst = &translate_filename($_[1]); &webmin_debug_log('LINK', "src=$src dst=$dst") - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_ops'}); unlink($dst); # make sure link works return link($src, $dst); } @@ -3832,7 +3849,7 @@ if (&is_readonly_mode()) { } $dir = &translate_filename($dir); return 1 if (-d $dir && $recur); # already exists -&webmin_debug_log('MKDIR', $dir) if ($gconfig{'debug_what_write'}); +&webmin_debug_log('MKDIR', $dir) if ($gconfig{'debug_what_ops'}); local $rv = mkdir($dir, $perms); if (!$rv && $recur) { # Failed .. try mkdir -p @@ -3856,7 +3873,7 @@ if (&is_readonly_mode()) { return 1; } @files = map { &translate_filename($_) } @files; -if ($gconfig{'debug_what_write'}) { +if ($gconfig{'debug_what_ops'}) { foreach my $f (@files) { &webmin_debug_log('PERMS', "file=$f user=$user group=$group perms=$perms"); @@ -3909,7 +3926,7 @@ my $rv = 1; my $err; foreach my $f (@_) { my $realf = &translate_filename($f); - &webmin_debug_log('UNLINK', $realf) if ($gconfig{'debug_what_write'}); + &webmin_debug_log('UNLINK', $realf) if ($gconfig{'debug_what_ops'}); if (-d $realf) { if (!rmdir($realf)) { if ($gconfig{'os_type'} eq 'windows') { @@ -3952,7 +3969,7 @@ local ($src, $dst) = @_; local $ok = 1; local ($err, $out); &webmin_debug_log('COPY', "src=$src dst=$dst") - if ($gconfig{'debug_what_write'}); + if ($gconfig{'debug_what_ops'}); if ($gconfig{'os_type'} eq 'windows') { # No tar or cp on windows, so need to use copy command $src =~ s/\//\\/g; @@ -5807,7 +5824,8 @@ sub END { if ($$ == $main::initial_process_id) { &cleanup_tempnames(); - if ($gconfig{'debug_what_start'} && $main::debug_log_start_time) { + if ($gconfig{'debug_what_start'} && $main::debug_log_start_time && + $main::debug_log_start_module eq $module_name) { local $len = time() - $main::debug_log_start_time; &webmin_debug_log("STOP", "runtime=$len"); $main::debug_log_start_time = 0; diff --git a/webmin/change_debug.cgi b/webmin/change_debug.cgi index 2f0f6324d..12c3378a6 100644 --- a/webmin/change_debug.cgi +++ b/webmin/change_debug.cgi @@ -37,6 +37,11 @@ else { $gconfig{'debug_size'} = $in{'debug_size'}*$in{'debug_size_units'}; } +# What to debug +$gconfig{'debug_noweb'} = !$in{'debug_web'}; +$gconfig{'debug_nocmd'} = !$in{'debug_cmd'}; +$gconfig{'debug_nocron'} = !$in{'debug_cron'}; + # Write out &write_file("$config_directory/config", \%gconfig); &unlock_file("$config_directory/config"); diff --git a/webmin/edit_debug.cgi b/webmin/edit_debug.cgi index 429ad68ac..94ac52c25 100644 --- a/webmin/edit_debug.cgi +++ b/webmin/edit_debug.cgi @@ -32,6 +32,15 @@ print &ui_table_row($text{'debug_size'}, [ 0, &ui_bytesbox("debug_size", $gconfig{'debug_size'}) ] ] )); +# Debug background processes? +print &ui_table_row($text{'debug_procs'}, + &ui_checkbox("debug_web", 1, $text{'debug_web'}, + !$gconfig{'debug_noweb'})."\n". + &ui_checkbox("debug_cmd", 1, $text{'debug_cmd'}, + !$gconfig{'debug_nocmd'})."\n". + &ui_checkbox("debug_cron", 1, $text{'debug_cron'}, + !$gconfig{'debug_nocron'})); + print &ui_table_end(); print &ui_form_end([ [ "save", $text{'save'} ] ]); diff --git a/webmin/lang/en b/webmin/lang/en index 6cdb46ee2..2a89ffb09 100644 --- a/webmin/lang/en +++ b/webmin/lang/en @@ -813,6 +813,8 @@ debug_what=Events to log debug_what_start=Scripts starting and stopping debug_what_write=Files opened for writing debug_what_read=Files opened for reading +debug_what_ops=Other file operations +debug_what_procs=Operations on processes debug_what_diff=Configuration file diffs debug_what_cmd=Commands executed debug_what_net=Network connections made @@ -824,3 +826,7 @@ debug_ewhat=No events to log selected debug_efile=Debug log file must be an absolute path debug_edir=Directory '$1' for debug log file does not exist debug_esize=Maximum size must be a number +debug_procs=Script types to debug +debug_web=Web interface CGIs +debug_cmd=Command line +debug_cron=Background jobs diff --git a/webmin/webmin-lib.pl b/webmin/webmin-lib.pl index ad89b05bf..0ff750aeb 100644 --- a/webmin/webmin-lib.pl +++ b/webmin/webmin-lib.pl @@ -41,7 +41,7 @@ $detect_operating_system_cache = "$module_config_directory/oscache"; @webmin_date_formats = ( "dd/mon/yyyy", "dd/mm/yyyy", "mm/dd/yyyy", "yyyy/mm/dd" ); -@debug_what_events = ( 'start', 'read', 'write', 'diff', 'cmd', 'net', 'sql' ); +@debug_what_events = ( 'start', 'read', 'write', 'ops', 'procs', 'diff', 'cmd', 'net', 'sql' ); sub setup_ca {