Server IP : 195.201.23.43 / Your IP : 3.12.107.192 Web Server : Apache System : Linux webserver2.vercom.be 5.4.0-192-generic #212-Ubuntu SMP Fri Jul 5 09:47:39 UTC 2024 x86_64 User : kdecoratie ( 1041) PHP Version : 7.1.33-63+ubuntu20.04.1+deb.sury.org+1 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/share/webmin/virtual-server/ |
Upload File : |
# Provide more system info blocks specific to Virtualmin do 'virtual-server-lib.pl'; use Time::Local; sub list_system_info { my ($data, $in) = @_; # If user doesn't have access to Virtualmin, none of this makes sense if (!&foreign_available($module_name)) { return ( ); } my @rv; my $info = &get_collected_info(); my @vposs = $info ? @{$info->{'vposs'}} : ( ); my @doms = &list_visible_domains(); # Check for wizard redirect my $redir = &wizard_redirect(); if ($redir) { push(@rv, { 'type' => 'redirect', 'url' => $redir }); } # Custom URL redirect if ($data->{'alt'} && !$in{'noalt'}) { push(@rv, { 'type' => 'redirect', 'url' => $data->{'alt'} }); } # Refresh button that does Virtualmin too, and replaces the one # from the system-status module push(@rv, { 'type' => 'link', 'id' => 'vrecollect', 'priority' => 100, 'desc' => $text{'right_recollect'}, 'link' => '/'.$module_name.'/recollect.cgi' }); push(@rv, { 'type' => 'veto', 'veto' => 'recollect' }); # Warning messages foreach my $warn (&list_warning_messages()) { push(@rv, { 'type' => 'warning', 'level' => 'warn', 'warning' => $warn }); } # Need to check module config? if (&need_config_check() && &can_check_config()) { push(@rv, { 'type' => 'warning', 'level' => 'info', 'warning' => &ui_form_start('/'.$module_name.'/check.cgi'). "$text{'index_needcheck'}<p>\n". &ui_submit($text{'index_srefresh'}). &ui_form_end(), }); } # Suggest to GPL user to get Virtualmin Pro if (!$virtualmin_pro && &should_show_pro_tip('dashboard', 'force')) { # Do not show dashboard alert within first three days, until things settle down &foreign_require("webmin"); my $uptime = &webmin::get_system_uptime(); $uptime = (!$uptime || $uptime > 60*60*24 * 4); # Show alert in another five days if reminder been set my ($remind) = &should_show_pro_tip('dashboard_reminder', 'force'); my $futureremind = (int($remind) + (60*60*24 * 5)); my $doremind = ($remind && $futureremind < time()); if (($uptime && !$remind) || ($uptime && $doremind)) { push(@rv, { 'type' => 'warning', 'level' => 'info', 'warning' => { 'alert' => &alert_pro_tip('dashboard', { 'alert_title' => $text{'scripts_gpl_pro_tip_title_dashboard'}, 'alert_body1' => $text{'scripts_gpl_pro_tip_dashboard'} . " ", 'alert_body2' => &text('scripts_gpl_pro_tip_enroll_dashboard', 'https://www.virtualmin.com/product-category/virtualmin/'), 'button_text' => $text{'scripts_gpl_pro_tip_hide2'}, 'button_icon' => 'fa fa-fw fa-heartbeat', 'button_text2' => $text{'scripts_gpl_pro_tip_open'}, 'button_icon2' => 'fa fa-fw fa-unlock', 'button_text3' => $text{'scripts_gpl_pro_tip_remind'}, 'button_icon3' => 'fa fa-fw fa-clock', }) }, }); } } # Show a domain owner info about his domain, but NOT info about the system if (!&master_admin() && !&reseller_admin()) { my @table; # General info about the domain my $ex = &extra_admin(); my $d = $ex ? &get_domain($ex) : &get_domain_by("user", $remote_user, "parent", ""); push(@table, { 'desc' => $text{'right_login'}, 'value' => $remote_user }); push(@table, { 'desc' => $text{'right_from'}, 'value' => $ENV{'REMOTE_HOST'} }); push(@table, { 'desc' => $text{'right_virtualmin'}, 'value' => $module_info{'version'} }); push(@table, { 'desc' => $text{'right_dom'}, 'value' => &show_domain_name($d) }); # Number of sub-servers my @subs = ( $d, virtual_server::get_domain_by("parent", $d->{'id'}) ); my @reals = grep { !$_->{'alias'} } @subs; my @mails = grep { $_->{'mail'} } @subs; my ($sleft, $sreason, $stotal, $shide) = &count_domains("realdoms"); if ($sleft < 0 || $shide) { push(@table, { 'desc' => $text{'right_subs'}, 'value' => scalar(@reals) }); } else { push(@table, { 'desc' => $text{'right_subs'}, 'value' => &text('right_of', scalar(@reals), $stotal) }); } # Number of alias domains my @aliases = grep { $_->{'alias'} } @subs; if (@aliases) { my ($aleft, $areason, $atotal, $ahide) = &count_domains("aliasdoms"); if ($aleft < 0 || $ahide) { push(@table, { 'desc' => $text{'right_aliases'}, 'value' => scalar(@aliases) }); } else { push(@table, { 'desc' => $text{'right_aliases'}, 'value' => &text('right_of', scalar(@aliases), $atotal) }); } } # Users and aliases my $users = &count_domain_feature("mailboxes", @subs); my ($uleft, $ureason, $utotal, $uhide) = &count_feature("mailboxes"); my $msg = @mails ? $text{'right_fusers'} : $text{'right_fusers2'}; if ($uleft < 0 || $uhide) { push(@table, { 'desc' => $msg, 'value' => $users }); } else { push(@table, { 'desc' => $msg, 'value' => &text('right_of', $users, $utotal) }); } # Mail aliases if (@mails) { my $aliases = &count_domain_feature("aliases", @subs); my ($aleft, $areason, $atotal, $ahide) = virtual_server::count_feature("aliases"); if ($aleft < 0 || $ahide) { push(@table, { 'desc' => $text{'right_faliases'}, 'value' => $aliases }); } else { push(@table, { 'desc' => $text{'right_faliases'}, 'value' => &text('right_of', $aliases, $atotal) }); } } # Database count my $dbs = &count_domain_feature("dbs", @subs); my ($dleft, $dreason, $dtotal, $dhide) = virtual_server::count_feature("dbs"); if ($dleft < 0 || $dhide) { push(@table, { 'desc' => $text{'right_fdbs'}, 'value' => $dbs }); } else { push(@table, { 'desc' => $text{'right_fdbs'}, 'value' => &text('right_of', $dbs, $dtotal) }); } # Quota summary for top-level domain if (!$data->{'noquotas'} && virtual_server::has_home_quotas()) { my $homesize = virtual_server::quota_bsize("home"); my $mailsize = virtual_server::quota_bsize("mail"); my ($home, $mail, $db) = &get_domain_quota($d, 1); my $usage = $home*$homesize + $mail*$mailsize + $db; my $limit = $d->{'quota'}*$homesize; if ($limit) { if ($usage > $limit) { $limit = $usage; } push(@table, { 'desc' => $text{'right_quota'}, 'value' => &text('right_out', &nice_size($usage), &nice_size($limit)), 'chart' => [ $limit, $usage-$db, $db ]}); } else { push(@table, { 'desc' => $text{'right_quota'}, 'value' => &nice_size($usage), 'wide' => 1 }); } } push(@rv, { 'type' => 'table', 'id' => 'domain', 'desc' => $text{'right_header3'}, 'table' => \@table }); if ($data->{'nosysinfo'}) { push(@rv, { 'type' => 'veto', 'veto' => 'sysinfo' }); } } # If this user can't see system info, block it if (!&can_view_sysinfo()) { push(@rv, { 'type' => 'veto', 'veto' => 'sysinfo' }); } # Virtualmin package updates, filtered from the possible updates list my $hasvposs = foreign_check("package-updates"); my $canvposs = foreign_available("package-updates"); if (!$data->{'noupdates'} && $hasvposs && $canvposs && @vposs) { my $html = &ui_form_start("@{[&get_webprefix_safe()]}/package-updates/update.cgi"); $html .= &ui_hidden("redirdesc", $text{'right_sysinfo'}); $html .= &ui_hidden("confirm", 1); $html .= &text(@vposs > 1 ? 'right_upcount' : 'right_upcount1', scalar(@vposs), &get_webprefix_safe() . '/package-updates/index.cgi?mode=updates')."<p>\n"; $html .= &ui_columns_start([ $text{'right_upname'}, $text{'right_updesc'}, $text{'right_upver'} ], "80%"); foreach my $p (@vposs) { $html .= &ui_columns_row([ ($p->{'name'} . &ui_hidden("u", $p->{'update'}."/".$p->{'system'})), $p->{'desc'}, $p->{'version'} ] ); } $html .= &ui_columns_end(); $html .= &ui_form_end([ [ undef, $text{'right_upok'} ] ]); push(@rv, { 'type' => 'html', 'id' => 'updates', 'open' => 1, 'desc' => $text{'right_updatesheader'}, 'html' => $html }); # Block same section from being shown by Cloudmin push(@rv, { 'type' => 'veto', 'veto' => 'updates', 'veto_module' => 'server-manager' }); } # Status of various servers if (!$data->{'nostatus'} && $info->{'startstop'} && &can_stop_servers()) { my @ss = @{$info->{'startstop'}}; my @down = grep { !$_->{'status'} } @ss; my @table; my $idir = &get_webprefix_safe() . '/'.$module_name.'/images'; foreach my $status (@ss) { # Work out label, possibly with link my $label; foreach my $l (@{$status->{'links'}}) { if ($l->{'manage'}) { $label = &ui_link(&get_webprefix_safe() . $l->{'link'}, $status->{'name'}); } } $label ||= $status->{'name'}; # Stop / start icon my $action = ($status->{'status'} ? "stop_feature.cgi" : "start_feature.cgi"); my $action_icon = ($status->{'status'} ? "<img src='$idir/stop.png' alt='$status->{'desc'}' />" : "<img src='$idir/start.png' alt='$status->{'desc'}' />"); my $action_link = "<a href='@{[&get_webprefix_safe()]}/$module_name/$action?". "feature=$status->{'feature'}&id=$status->{'id'}'". " title='$status->{'desc'}'>". "$action_icon</a>"; # Restart link my $restart_link_style = $status->{'status'} ? "" : "style='visibility: hidden; pointer-events: none;' "; my $restart_link = "<a ${restart_link_style}href='@{[&get_webprefix_safe()]}/$module_name/restart_feature.cgi?". "feature=$status->{'feature'}&id=$status->{'id'}'". " title='$status->{'restartdesc'}'>". "<img src='$idir/reload.png'". "alt='$status->{'restartdesc'}'></a>\n"; push(@table, { 'desc' => $label, 'value' => (!$status->{'status'} ? "<img src='$idir/down.gif' alt='Stopped'>" : "<img src='$idir/up.gif' alt='Running'>"). (" " x 10). $action_link. " ".$restart_link }); } push(@rv, { 'type' => 'table', 'id' => 'status', 'desc' => $text{'right_statusheader'}, 'open' => @down ? 1 : 0, 'table' => \@table }); } # New features if ($data->{'dom'}) { $defdom = &get_domain($data->{'dom'}); if ($defdom && !&can_edit_domain($defdom)) { $defdom = undef; } } if (!$defdom && @doms) { $defdom = $doms[0]; } my $newhtml = &get_new_features_html($defdom); if ($newhtml) { push(@rv, { 'type' => 'html', 'id' => 'newfeatures', 'open' => 1, 'desc' => $text{'right_newfeaturesheader'}, 'html' => $newhtml }); } # Show usage count by type if (&master_admin() && !$data->{'novirtualmin'} && $info->{'fcount'}) { my @table; foreach my $f (@{$info->{'ftypes'}}) { my $cur = int($info->{'fcount'}->{$f}); my $extra = $info->{'fextra'}->{$f}; my $max = $info->{'fmax'}->{$f}; my $hide = $info->{'fhide'}->{$f}; if ($extra < 0 || $hide) { push(@table, { 'desc' => $text{'right_f'.$f}, 'value' => $cur }); } else { push(@table, { 'desc' => $text{'right_f'.$f}, 'value' => &text('right_out', $cur, $max) }); } } push(@rv, { 'type' => 'table', 'id' => 'ftypes', 'desc' => $text{'right_virtheader'}, 'open' => 0, 'table' => \@table }); } # Top quota users my @quota = $info->{'quota'} ? grep { &can_edit_domain($_->[0]) } @{$info->{'quota'}} : ( ); if (!$data->{'noquotas'} && @quota && (&master_admin() || &reseller_admin())) { my @usage; my $max = $data->{'max'} || 10; my $maxquota = $info->{'maxquota'}; # Work out if showing by percent makes sense my $qshow = $data->{'qshow'}; if ($qshow) { my @quotawithlimit = grep { $_->[2] } @quota; $qshow = 0 if (!@quotawithlimit); } # Limit to those with a quota limit, if showing a percent if ($qshow) { @quota = grep { $_->[2] } @quota; } if ($qshow) { # Sort by percent used @quota = grep { $_->[2] } @quota; @quota = sort { ($b->[1]+$b->[3])/$b->[2] <=> ($a->[1]+$a->[3])/$a->[2] } @quota; } else { # Sort by usage @quota = sort { $b->[1]+$b->[3] <=> $a->[1]+$a->[3] } @quota; } # Message above list my $qmsg; if (@quota > $max) { @quota = @quota[0..($max-1)]; $qmsg = &text('right_quotamax', $max); } elsif (&master_admin()) { $qmsg = $text{'right_quotaall'}; } else { $qmsg = $text{'right_quotayours'}; } my $open = 0; foreach my $q (@quota) { my $cmd = &can_edit_domain($q->[0]) ? "edit_domain.cgi" : "view_domain.cgi"; my $chart = { 'desc' => &ui_link( &get_webprefix_safe() . '/'.$module_name.'/'.$cmd.'?dom='.$q->[0]->{'id'}, &show_domain_name($q->[0])) }; if ($qshow) { # By percent used my $qpc = int($q->[1]*100 / $q->[2]); my $dpc = int($q->[3]*100 / $q->[2]); $chart->{'chart'} = [ 100, $qpc, $dpc ]; } else { # By actual usage $chart->{'chart'} = [ $maxquota, $q->[1], $q->[3] ]; } if ($q->[2]) { # Show used and limit my $pc = int(($q->[1]+$q->[3])*100 / $q->[2]); $pc = " $pc" if ($pc < 10); $chart->{'value'} = &text('right_out', &nice_size($q->[1]+$q->[3]), &nice_size($q->[2])); } else { # Just show used $chart->{'value'} = &nice_size($q->[1]+$q->[3]); } if ($q->[2] && $q->[1]+$q->[3] >= $q->[2]) { # Domain is over quota $open = 1; } push(@usage, $chart); } push(@rv, { 'type' => 'chart', 'id' => 'quota', 'desc' => $text{'right_quotasheader'}, 'open' => $open, 'header' => $qmsg, 'chart' => \@usage }); } # Top BW users my @bwdoms = grep { !$_->{'parent'} && defined($_->{'bw_usage'}) } @doms; my $maxbw = 0; foreach my $d (@doms) { $maxbw = $d->{'bw_limit'} if ($d->{'bw_limit'} > $maxbw); $maxbw = $d->{'bw_usage'} if ($d->{'bw_usage'} > $maxbw); } if (!$data->{'nobw'} && $config{'bw_active'} && @bwdoms && $maxbw) { my $qshow = $data->{'qshow'}; # Work out if showing by percent makes sense my $qshow = $data->{'qshow'}; if ($qshow) { my @domswithlimit = grep { $_->{'bw_limit'} } @doms; $qshow = 0 if (!@domswithlimit); } if ($qshow) { # Sort by percent used @doms = grep { $_->{'bw_limit'} } @doms; @doms = sort { $b->{'bw_usage'}/$b->{'bw_limit'} <=> $a->{'bw_usage'}/$a->{'bw_limit'} } @doms; } else { # Sort by usage @doms = sort { $b->{'bw_usage'} <=> $a->{'bw_usage'} } @doms; } # Show message about number of domains being displayed my $max = $data->{'max'} || 10; my $qmsg; if (@doms > $max) { @doms = @doms[0..($max-1)]; $qmsg = &text('right_quotamax', $max); } else { $qmsg = $text{'right_quotaall'}; } # Add the table of domains my $open = 0; foreach my $d (@doms) { my $cmd = &can_edit_domain($d) ? "edit_domain.cgi" : "view_domain.cgi"; my $chart = { 'desc' => &ui_link( &get_webprefix_safe() . '/'.$module_name.'/'.$cmd.'?dom='.$d->{'id'}, &show_domain_name($d)) }; my $pc = $d->{'bw_limit'} ? int($d->{'bw_usage'}*100 / $d->{'bw_limit'}) : undef; if ($qshow) { # By percent used $chart->{'chart'} = [ 100, $pc ]; } else { # By actual usage $chart->{'chart'} = [ $maxbw, $d->{'bw_usage'} ]; } # Percent used, if available if ($d->{'bw_limit'}) { $pc = " $pc" if ($pc < 10); $chart->{'value'} = &text('right_out', &nice_size($d->{'bw_usage'}), &nice_size($d->{'bw_limit'})); } else { $chart->{'value'} = &nice_size($d->{'bw_usage'}); } push(@usage, $chart); if ($d->{'bw_limit'} && $d->{'bw_usage'} >= $d->{'bw_limit'}) { $open = 1; } } push(@rv, { 'type' => 'chart', 'id' => 'bw', 'desc' => $text{'right_bwheader'}, 'open' => $open, 'header' => $qmsg, 'chart' => \@usage }); } # IP addresses used if (&master_admin() && !$data->{'noips'} && $info->{'ips'}) { my @table; my @allips = @{$info->{'ips'}}; push(@allips, @{$info->{'ips6'}}) if ($info->{'ips6'}); foreach my $ipi (@allips) { my $umsg; if ($ipi->[3] == 1) { $umsg = "<tt>$ipi->[4]</tt>"; } else { my $slink = &get_webprefix_safe() . '/'.$module_name. '/search.cgi?field=ip&what='.$ipi->[0]; $umsg = &ui_link($slink, &text('right_ips', $ipi->[3])); } push(@table, { 'desc' => $ipi->[0], 'value' => ($ipi->[1] eq 'def' ? $text{'right_defip'} : $ipi->[1] eq 'reseller' ? text('right_reselip', $ipi->[2]) : $ipi->[1] eq 'shared' ? $text{'right_sharedip'} : $text{'right_ip'})." ".$umsg }); } if ($info->{'ipranges'}) { foreach my $r (@{$info->{'ipranges'}}) { push(@table, { 'desc' => $r->[0], 'value' => &text('right_iprange', $r->[1], $r->[2]), 'wide' => 1 }); } } push(@rv, { 'type' => 'table', 'id' => 'ips', 'desc' => $text{'right_ipsheader'}, 'open' => 0, 'table' => \@table }); } # Programs and versions if (!$data->{'nosysinfo'} && $info->{'progs'} && &can_view_sysinfo()) { my @table; foreach my $info (@{$info->{'progs'}}) { push(@table, { 'desc' => $info->[0], 'value' => $info->[1] }); } push(@rv, { 'type' => 'table', 'id' => 'sysinfo', 'desc' => $text{'right_sysinfoheader'}, 'open' => 0, 'table' => \@table }); } # Virtualmin licence my %vserial; if (&read_env_file($virtualmin_license_file, \%vserial) && $vserial{'SerialNumber'} ne 'GPL' && &master_admin()) { my @table; my $open = 0; # Serial and key push(@table, { 'desc' => $text{'right_vserial'}, 'value' => $vserial{'SerialNumber'} }); # Allowed domain counts my ($dleft, $dreason, $dmax, $dhide) = &count_domains("realdoms"); push(@table, { 'desc' => $text{'right_vmax'}, 'value' => $dmax <= 0 ? $text{'right_vunlimited'} : $dmax }); push(@table, { 'desc' => $text{'right_vleft'}, 'value' => $dleft < 0 ? $text{'right_vunlimited'} : $dleft }); # Add allowed domain counts my %lstatus; &read_file($licence_status, \%lstatus); if ($lstatus{'used_servers'}) { push(@table, { 'desc' => $text{'right_smax'}, 'value' => $lstatus{'servers'} || $text{'right_vunlimited'} }); push(@table, { 'desc' => $text{'right_sused'}, 'value' => $lstatus{'used_servers'} }); } # Show license expiry date if ($lstatus{'expiry'} =~ /^203[2-8]-/) { push(@table, { 'desc' => $text{'right_expiry'}, 'value' => $text{'right_expirynever'} }); } elsif ($lstatus{'expiry'}) { push(@table, { 'desc' => $text{'right_expiry'}, 'value' => $lstatus{'expiry'} }); my $ltm = &parse_license_date($lstatus{'expiry'}); if ($ltm) { my $days = int(($ltm - time()) / (24*60*60)); push(@table, { 'desc' => $text{'right_expirydays'}, 'value' => $days < 0 ? &text('right_expiryago', -$days) : $days }); $open = 1 if ($days < 7); } } push(@rv, { 'type' => 'table', 'id' => 'serial', 'desc' => $text{'right_licenceheader'}, 'open' => $open, 'table' => \@table }); # Re-check licence link push(@rv, { 'type' => 'link', 'priority' => 20, 'desc' => $text{'right_vlcheck'}, 'link' => '/'.$module_name.'/licence.cgi' }); } # Documentation links my $doclink = &get_virtualmin_docs(); push(@rv, { 'type' => 'link', 'priority' => 50, 'desc' => $text{'right_virtdocs'}, 'target' => 'new', 'link' => $doclink }); if ($config{'docs_link'}) { push(@rv, { 'type' => 'link', 'priority' => 49, 'desc' => $text{'right_virtdocs2'}, 'target' => 'new', 'link' => $config{'docs_link'} }); } # Sections defined by plugins my $level = &master_admin() ? 0 : &reseller_admin() ? 2 : 1; foreach my $p (&list_plugin_sections($level)) { push(@rv, { 'type' => 'html', 'id' => 'plugin_'.$p->{'name'}, 'desc' => $p->{'title'}, 'html' => $p->{'html'}, 'open' => $p->{'status'} }); } return @rv; } sub get_virtualmin_docs { return &master_admin() ? "https://www.virtualmin.com/documentation" : &reseller_admin() ? "https://www.virtualmin.com/documentation/users/reseller" : "https://www.virtualmin.com/documentation/users/server-owner"; } sub parse_license_date { my ($str) = @_; if ($str =~ /^(\d{4})-(\d+)-(\d+)$/) { return eval { timelocal(0, 0, 0, $3, $2-1, $1) }; } return undef; } 1;Private