php IHDR w Q )Ba pHYs sRGB gAMA a IDATxMk\U s&uo,mD )Xw+e?tw.oWp;QHZnw`gaiJ9̟灙a=nl[ ʨ G;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ w@H;@ q$ y H@E7j 1j+OFRg}ܫ;@Ea~ j`u'o> j- $_q?qS XzG'ay
files >> /usr/libexec/webmin/authentic-theme/ |
files >> //usr/libexec/webmin/authentic-theme/stats.cgi |
#!/usr/bin/perl # # Authentic Theme (https://github.com/authentic-theme/authentic-theme) # Copyright Ilia Rostovtsev <ilia@virtualmin.com> # Licensed under MIT (https://github.com/authentic-theme/authentic-theme/blob/master/LICENSE) # use strict; no warnings 'uninitialized'; use lib ("$ENV{'THEME_ROOT'}/lib"); use Async; BEGIN {push(@INC, "..");} use WebminCore; our (%in, $config_directory, $var_directory, $current_theme, $remote_user); do("$ENV{'THEME_ROOT'}/authentic-funcs.pl"); init_config(); ReadParse(); print_json({}), exit if (!webmin_user_is_admin()); # Load theme language and settings our %text = load_language($current_theme); my %settings = settings("$config_directory/$current_theme/settings.js", 'settings_'); my $option = sub { if ($_[1]) { return $settings{"settings_sysinfo_real_time_$_[0]"}; } if (!scalar %settings) { return 1; } return ($settings{"settings_sysinfo_real_time_$_[0]"} eq 'false') ? 0 : 1; }; my %data; my $tdata = {}; my $sdata = $in{'sdata'} ? 1 : 0; my $fdatad = "$var_directory/modules/$current_theme"; my $fdata = "$fdatad/stats-$remote_user.json"; my $cdata = read_file_contents($fdata); my $time = time(); my $ddata = sub { my ($k, $d) = @_; # Save and return data if (!$k) { if (&$option('stored')) { # Clear existing cache if available features was disabled my %map = (cpu => ['cpu', 'disk'], mem => ['mem', 'virt'], load => ['proc', 'net']); foreach my $key (keys %map) { my $feature = acl_system_status($key); if (ref($map{$key}) eq 'ARRAY') { foreach my $skey (@{ $map{$key} }) { if (!$feature) { delete $cdata->{$skey}; } } } else { if (!$feature) { delete $cdata->{ $map{$key} }; } } } # Cache complete dataset mkdir($fdatad, 0700) if (!-d $fdatad); write_file_contents($fdata, convert_to_json($cdata)); # Return requested data if ($sdata) { $data{'fcached'} = $cdata; } else { $data{'scached'} = $tdata; } } return; } # Store complete dataset if (ref($cdata->{$k}) ne 'ARRAY') { $cdata->{$k} = []; } push(@{ $cdata->{$k} }, { x => $time, y => $d }); my $n = &$option('stored_length', 1) || 600; # User option sanity check if ($n < 600 || $n > 86400) { $n = 600; } # Trim dataset for my $i (0 .. @{ $cdata->{$k} }) { if (defined(@{ $cdata->{$k} }[$i])) { if (($time - @{ $cdata->{$k} }[$i]->{'x'}) > $n) { delete @{ $cdata->{$k} }[$i]; } } } @{ $cdata->{$k} } = grep {$_ ne undef} @{ $cdata->{$k} }; # Store single dataset if (ref($tdata->{$k}) ne 'ARRAY') { $tdata->{$k} = []; } push(@{ $tdata->{$k} }, { x => time(), y => $d }); }; eval {$cdata = convert_from_json($cdata) if ($cdata);}; unlink($fdata), $cdata = {} if ($@); $cdata ||= {}; if ($in{'xhr-stats'} =~ /[[:alpha:]]/) { my $target = $in{'xhr-stats'}; if ($target eq 'general') { # Run in async to reduce script execution time my $network; if (acl_system_status('load')) { $network = Async->new(sub {network_stats('io')}); } if (foreign_check("proc")) { foreign_require("proc"); # CPU stats if (acl_system_status('cpu')) { my @cpuinfo = defined(&proc::get_cpu_info) ? proc::get_cpu_info() : (); my @cpuusage = defined(&proc::get_cpu_io_usage) ? proc::get_cpu_io_usage() : (); if (@cpuinfo && @cpuusage) { # CPU load my $cpu = int($cpuusage[0] + $cpuusage[1] + $cpuusage[3]); $data{'cpu'} = [$cpu, text('body_load', ($cpuinfo[0], $cpuinfo[1], $cpuinfo[2]))]; &$ddata('cpu', $cpu); # Disk I/O my $in = $cpuusage[5]; my $out = $cpuusage[6]; if ($in && $out || $in eq '0' || $out eq '0') { $data{'io'} = [$in, $out]; &$ddata('disk', [$in, $out]); } } } # Memory stats if (acl_system_status('mem')) { my @memory = defined(&proc::get_memory_info) ? proc::get_memory_info() : (); if (@memory) { $data{'mem'} = []; $data{'virt'} = []; if (@memory && $memory[0] && $memory[0] > 0) { my $mem = (100 - int(($memory[1] / $memory[0]) * 100)); $data{'mem'} = [$mem, text(($memory[4] ? 'body_used_cached_total' : 'body_used'), nice_size($memory[0] * 1024), nice_size(($memory[0] - $memory[1]) * 1024), ($memory[4] ? nice_size($memory[4] * 1024) : undef) )]; &$ddata('mem', $mem); } if (@memory && $memory[2] && $memory[2] > 0) { my $virt = (100 - int(($memory[3] / $memory[2]) * 100)); $data{'virt'} = [$virt, text('body_used', nice_size(($memory[2]) * 1024), nice_size(($memory[2] - $memory[3]) * 1024) )]; &$ddata('virt', $virt); } } } # Number of running processes if (acl_system_status('load')) { my @processes = proc::list_processes(); my $proc = scalar(@processes); $data{'proc'} = $proc; &$ddata('proc', $proc); } } # Disk space if (acl_system_status('disk')) { if (foreign_check("mount") && &$option('status_disk')) { foreign_require("mount"); my @disk_space = defined(&mount::local_disk_space) ? mount::local_disk_space() : (); if (@disk_space) { $data{'disk'} = []; if (@disk_space && $disk_space[0] && $disk_space[0] > 0) { my $disk = int(($disk_space[0] - $disk_space[1]) / $disk_space[0] * 100); $data{'disk'} = [$disk, text('body_used_and_free', nice_size($disk_space[0]), nice_size($disk_space[1]), nice_size($disk_space[0] - $disk_space[1]) )]; } } } } # Network I/O if ($network) { for (;;) { if ($network->ready) { if (!$network->error) { my $nrs = unserialise_variable($network->result); my $in = @{$nrs}[0]; my $out = @{$nrs}[1]; if ($in && $out || $in eq '0' || $out eq '0') { $data{'net'} = [$in, $out]; &$ddata('net', [$in, $out]); } } last; } select(undef, undef, undef, 0.1); } } # Reverse output for LTR users if (get_text_ltr()) { my @watched = ('mem', 'virt', 'disk'); foreach my $key (@watched) { if ($data{$key} && $data{$key}[1]) { $data{$key}[1] = reverse_string($data{$key}[1], "/"); } } } } &$ddata(); } print_json(\%data);y~or5J={Eeu磝Qk ᯘG{?+]ן?wM3X^歌>{7پK>on\jy Rg/=fOroNVv~Y+ NGuÝHWyw[eQʨSb> >}Gmx[o[<{Ϯ_qFvM IENDB`