File: //proc/self/root/proc/self/root/scripts.20110531.215904.25158/quotacheck
#!/usr/bin/perl
# cpanel - quotacheck Copyright(c) 2010 cPanel, Inc.
# All rights Reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cpanel license. Unauthorized copying is prohibited
BEGIN { unshift @INC, '/usr/local/cpanel'; }
use strict;
use Cpanel::DataStore ();
use Cpanel::Encoder::URI ();
use Cpanel::Email::DiskUsage ();
use Cpanel::SysQuota ();
use Cpanel::SysBackup ();
use Cpanel::Template ();
use Cpanel::ContactInfo ();
use Cpanel::Config::LoadCpConf ();
use Cpanel::Config::LoadConfig ();
use Cpanel::Config::FlushConfig ();
use Cpanel::Config::LoadUserDomains ();
use Cpanel::Config::LoadCpUserFile ();
use Cpanel::Hostname ();
use Cpanel::PwCache ();
use Cpanel::Logger ();
my $logger = Cpanel::Logger->new();
my %CPCONF = Cpanel::Config::LoadCpConf::loadcpconf();
if ( exists $CPCONF{'skipdiskcheck'} && $CPCONF{'skipdiskcheck'} eq '1' && exists $CPCONF{'skipboxcheck'} && $CPCONF{'skipboxcheck'} eq '1' ) {
$logger->info('Quota checks and notifications disabled for mail accounts and disk usage per Tweak Settings');
exit;
}
Cpanel::PwCache::no_uid_cache(); #uid cache only needed if we are going to make lots of getpwuid calls
Cpanel::PwCache::init_passwdless_pwcache();
my $debug = @ARGV && grep( /debug/, @ARGV ) ? 1 : 0;
my $hasyaml = 0;
eval '
use YAML::Syck;
$hasyaml=1;
';
if ( !$hasyaml ) { print "Skipping quotacheck: YAML::Syck install still pending\n"; }
my $quotawarnedfile = '/var/cpanel/quotawarned';
my $hostname = Cpanel::Hostname::gethostname();
my %notify_defaults = (
'emailusers_diskusage_full_percent' => 98,
'emailusers_diskusage_critical_percent' => 90,
'emailusers_diskusage_warn_percent' => 80,
'emailusers_mailbox_full_percent' => 98,
'emailusers_mailbox_critical_percent' => 90,
'emailusers_mailbox_warn_percent' => 80,
'emailusers_diskusage_full_contact_admin' => 1,
'emailusers_diskusage_critical_contact_admin' => 1,
'emailusers_diskusage_warn_contact_admin' => 0,
);
foreach my $key ( keys %notify_defaults ) {
if ( !exists $CPCONF{$key} || $CPCONF{$key} eq '' || ( $key =~ m/_percent$/ && $CPCONF{$key} !~ m/^\d+$/ ) ) {
$CPCONF{$key} = $notify_defaults{$key};
}
}
my %WARNED;
Cpanel::Config::LoadConfig::loadConfig( $quotawarnedfile, \%WARNED, ':', '^$' );
my $backupdir = Cpanel::SysBackup::fetchbackupdir();
my $repquota = Cpanel::SysQuota::fetchrepquota();
my ( $rUSED, $rLIMIT ) = Cpanel::SysQuota::analyzerepquotadata( $repquota, $backupdir );
my %UD;
Cpanel::Config::LoadUserDomains::loadtrueuserdomains( \%UD, 1 );
$UD{'root'} = '(system)';
my $pwcache_ref = Cpanel::PwCache::fetch_pwcache();
my %HOMES;
my %CPD;
foreach my $pw (@$pwcache_ref) {
next if ( !exists $UD{ $pw->[0] } );
my $cpuser_ref = Cpanel::Config::LoadCpUserFile::loadcpuserfile( $pw->[0] );
if ( !scalar keys %{$cpuser_ref} ) {
delete $UD{ $pw->[0] };
next;
}
$HOMES{ $pw->[0] } = $pw->[7];
$CPD{ $pw->[0] } = $cpuser_ref;
}
my $rCONTACT_INFO = Cpanel::ContactInfo::fetch_contactinfo( \%UD, \%CPD, 1 );
foreach my $user ( keys %UD ) {
my $domain = $UD{$user};
my $homedir = $HOMES{$user};
$Cpanel::homedir = $homedir; #for email disk usage
print "Checking user $user\n" if $debug;
my $cpuser = $CPD{$user};
my $owner = $cpuser->{'OWNER'};
my @warned_email_users;
# Tweak Setting skipboxcheck disables all mail box quota warnings. The cPanel user setting 'notify_email_quota_limit' is set on a per user basis and on unless
# specifically disabled
if ( $CPCONF{'skipboxcheck'} ne '1' && ( !exists $rCONTACT_INFO->{$user}{'notify_email_quota_limit'} || $rCONTACT_INFO->{$user}{'notify_email_quota_limit'} ne '0' ) ) {
my @DOMAINLIST = ( $cpuser->{'DOMAIN'} );
if ( ref $cpuser->{'DOMAINS'} eq 'ARRAY' ) {
push @DOMAINLIST, @{ $cpuser->{'DOMAINS'} };
}
foreach my $domain (@DOMAINLIST) {
print "\tDomain: $domain\n" if $debug;
next if ( !$homedir || !$domain || !-e "$homedir/etc/$domain/quota" || -z _ );
if ( -B "$homedir/etc/$domain/quota" ) { # binary file check
$logger->warn("WARNING $homedir/etc/$domain/quota is a binary file. Expected standard mail quota format.");
next;
}
my %domain_quota;
if ( open my $quota_fh, '<', "$homedir/etc/$domain/quota" ) {
while (<$quota_fh>) {
chomp;
s/\0//g;
next if m/^[\r\n\s]*$/;
my ( $euser, $quota ) = split( /:/, $_, 2 );
next
if ( !defined $euser
|| $euser eq ''
|| !defined $quota
|| $quota eq ''
|| lc $quota eq 'unlimited' );
$domain_quota{$euser} = $quota;
}
close $quota_fh;
}
else {
$logger->warn("Unable to open $homedir/etc/$domain/quota: $!");
next;
}
foreach my $euser ( keys %domain_quota ) {
my $quota = $domain_quota{$euser};
# Determine mail box size
next if ( !-e "$homedir/mail/$domain/$euser" );
my $size = Cpanel::Email::DiskUsage::get_disk_used( $euser, $domain, $homedir )
|| 0;
my $percent = ( $quota == 0 ) ? 0 : sprintf( "%.2f", ( ( $size / $quota ) * 100 ) );
print "\t\tMail User: $euser QUOTA: $quota SIZE: $size $percent%\n" if $debug;
if ( defined $CPCONF{'emailusers_mailbox_full_percent'}
&& $CPCONF{'emailusers_mailbox_full_percent'} != 0
&& $percent >= $CPCONF{'emailusers_mailbox_full_percent'}
) {
if ( !exists $WARNED{ $euser . '@' . $domain }
|| $WARNED{ $euser . '@' . $domain } ne 'full' ) {
push @warned_email_users, $euser . '@' . $domain;
dispatchbox_mainacct( $euser . '@' . $domain, $rCONTACT_INFO->{$user}->{'emails'}, 'full', $quota, $size, $percent, $cpuser->{'RS'}, $domain );
}
$WARNED{ $euser . '@' . $domain } = 'full';
}
elsif ( defined $CPCONF{'emailusers_mailbox_critical_percent'}
&& $CPCONF{'emailusers_mailbox_critical_percent'} != 0
&& $percent >= $CPCONF{'emailusers_mailbox_critical_percent'}
) {
if ( !exists $WARNED{ $euser . '@' . $domain }
|| $WARNED{ $euser . '@' . $domain } ne 'critical' ) {
push @warned_email_users, $euser . '@' . $domain;
dispatchbox( $euser . '@' . $domain, [ $euser . '@' . $domain ], 'critical', $quota, $size, $percent );
}
$WARNED{ $euser . '@' . $domain } = 'critical';
}
elsif ( defined $CPCONF{'emailusers_mailbox_warn_percent'}
&& $CPCONF{'emailusers_mailbox_warn_percent'} != 0
&& $percent >= $CPCONF{'emailusers_mailbox_warn_percent'}
) {
if ( !exists $WARNED{ $euser . '@' . $domain }
|| $WARNED{ $euser . '@' . $domain } ne 'warn' ) {
push @warned_email_users, $euser . '@' . $domain;
dispatchbox( $euser . '@' . $domain, [ $euser . '@' . $domain ], 'warn', $quota, $size, $percent );
}
$WARNED{ $euser . '@' . $domain } = 'warn';
}
else {
$WARNED{ $euser . '@' . $domain } = 0;
}
}
if (@warned_email_users) {
my $user_list;
foreach my $mail_user ( sort @warned_email_users ) {
$user_list .= "$mail_user: $WARNED{$mail_user}\n";
}
dispatchmessagetomainacct( $rCONTACT_INFO->{$user}->{'emails'}, $user_list );
}
}
}
if ( !exists $CPCONF{'skipdiskcheck'} || $CPCONF{'skipdiskcheck'} ne '1' ) {
my $used = exists $rUSED->{$user} && $rUSED->{$user} ? int $rUSED->{$user} : 0;
my $limit = exists $rLIMIT->{$user} && $rLIMIT->{$user} ? int $rLIMIT->{$user} : 0;
print "Disk Info for $user: USED: $used LIMIT: $limit " if $debug;
my $mpercent = $limit ? sprintf( "%.2f", ( ( $used / $limit ) * 100 ) ) : 0;
print "$mpercent%\n\n" if $debug;
if ( defined $CPCONF{'emailusers_diskusage_full_percent'}
&& $CPCONF{'emailusers_diskusage_full_percent'} != 0
&& $mpercent >= $CPCONF{'emailusers_diskusage_full_percent'}
) {
if ( !exists $WARNED{$user} || $WARNED{$user} ne 'full' ) {
if ( $CPCONF{'emailusers_diskusage_full_contact_admin'} ) {
if ( $owner ne $user ) {
if ( $rCONTACT_INFO->{$owner}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{$owner}->{'emails'}, 'full', $limit, $used, $mpercent, $user, $domain );
}
}
else {
if ( $rCONTACT_INFO->{'root'}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{'root'}->{'emails'}, 'full', $limit, $used, $mpercent, $user, $domain );
}
}
}
if ( $rCONTACT_INFO->{$user}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk_user( $rCONTACT_INFO->{$user}->{'emails'}, 'full', $limit, $used, $mpercent, $user, $domain );
}
}
$WARNED{$user} = 'full';
}
elsif ( defined $CPCONF{'emailusers_diskusage_critical_percent'}
&& $CPCONF{'emailusers_diskusage_critical_percent'} != 0
&& $mpercent >= $CPCONF{'emailusers_diskusage_critical_percent'}
) {
if ( !exists $WARNED{$user} || $WARNED{$user} ne 'critical' ) {
if ( $CPCONF{'emailusers_diskusage_critical_contact_admin'} ) {
if ( $owner ne $user ) {
if ( $rCONTACT_INFO->{$owner}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{$owner}->{'emails'}, 'critical', $limit, $used, $mpercent, $user, $domain );
}
}
else {
if ( $rCONTACT_INFO->{'root'}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{'root'}->{'emails'}, 'critical', $limit, $used, $mpercent, $user, $domain );
}
}
}
if ( $rCONTACT_INFO->{$user}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk_user( $rCONTACT_INFO->{$user}->{'emails'}, 'critical', $limit, $used, $mpercent, $user, $domain );
}
}
$WARNED{$user} = 'critical';
}
elsif ( defined $CPCONF{'emailusers_diskusage_warn_percent'}
&& $CPCONF{'emailusers_diskusage_warn_percent'} != 0
&& $mpercent >= $CPCONF{'emailusers_diskusage_warn_percent'}
) {
if ( !exists $WARNED{$user} || $WARNED{$user} ne 'warn' ) {
if ( $CPCONF{'emailusers_diskusage_warn_contact_admin'} ) {
if ( $owner ne $user ) {
if ( $rCONTACT_INFO->{$owner}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{$owner}->{'emails'}, 'warn', $limit, $used, $mpercent, $user, $domain );
}
}
else {
if ( $rCONTACT_INFO->{'root'}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk( $rCONTACT_INFO->{'root'}->{'emails'}, 'warn', $limit, $used, $mpercent, $user, $domain );
}
}
}
if ( $rCONTACT_INFO->{$user}->{'notify_disk_limit'} ne '0' ) {
dispatchdisk_user( $rCONTACT_INFO->{$user}->{'emails'}, 'warn', $limit, $used, $mpercent, $user, $domain );
}
}
$WARNED{$user} = 'warn';
}
else {
$WARNED{$user} = 0;
}
}
}
# Delete 0 from %WARNED
Cpanel::Config::FlushConfig::flushConfig( '/var/cpanel/quotawarned', \%WARNED, ':' );
sub dispatchbox_mainacct {
return if $debug;
my ( $box, $sendmail, $status, $limit, $used, $percentused, $theme, $domain ) = @_;
$box =~ s/\n//g;
$sendmail =~ s/\n//g;
my $euser = ( split( /\@/, $box ) )[0];
my $notifyopts = {
'tos' => $sendmail,
'from' => ${$sendmail}[0],
'hasgoodcontact' => 0,
'box' => $box,
'diskused' => sprintf( "%.2f", ( ( $used / 1024 ) / 1024 ) ),
'disklimit' => sprintf( "%.2f", ( ( $limit / 1024 ) / 1024 ) ),
'status' => $status,
'warn' => ( $status eq 'warn' ? 1 : 0 ),
'adjusturl' => 'https://mail.' . $domain . ':2083/frontend/' . $theme . '/mail/editquota.html?email=' . Cpanel::Encoder::URI::uri_encode_str($euser) . '&domain=' . Cpanel::Encoder::URI::uri_encode_str($domain) . '&redirectdomain=' . Cpanel::Encoder::URI::uri_encode_str($domain),
'percentused' => $percentused
};
sendmsg( 'mainacct_mailbox_size_warning', $notifyopts, ${$sendmail}[0] );
print "MailBox ($box) [$status]\n";
}
sub dispatchbox {
return if $debug;
my ( $box, $sendmail, $status, $limit, $used, $percentused ) = @_;
$box =~ s/\n//g;
return if ( ref $sendmail ne 'ARRAY' ); #no contact emails
my $notifyopts = {
'tos' => $sendmail,
'from' => ${$sendmail}[0],
'hasgoodcontact' => 0,
'box' => $box,
'diskused' => sprintf( "%.2f", ( ( $used / 1024 ) / 1024 ) ),
'disklimit' => sprintf( "%.2f", ( ( $limit / 1024 ) / 1024 ) ),
'status' => $status,
'warn' => ( $status eq 'warn' ? 1 : 0 ),
'percentused' => $percentused
};
sendmsg( 'mailbox_size_warning', $notifyopts, ${$sendmail}[0] );
print "MailBox ($box) [$status]\n";
}
sub dispatchmessagetomainacct {
return if $debug;
my ( $sendmail, $user_list ) = @_;
return if ( ref $sendmail ne 'ARRAY' ); #no contact emails
my $notifyopts = {
'tos' => $sendmail,
'from' => ${$sendmail}[0],
'hasgoodcontact' => 0,
'user_list' => $user_list
};
sendmsg( 'mainacct_emailquota_notifylist', $notifyopts, ${$sendmail}[0] );
}
sub dispatchdisk_user {
return if $debug;
my ( $sendmail, $status, $limit, $used, $percentused, $user, $domain ) = @_;
return if ( ref $sendmail ne 'ARRAY' ); #no contact emails
my $notifyopts = {
'tos' => $sendmail,
'from' => ${$sendmail}[0],
'hasgoodcontact' => 0,
'domain' => $domain,
'user' => $user,
'status' => $status,
'warn' => ( $status eq 'warn' ? 1 : 0 ),
'diskused' => sprintf( "%.2f", $used / 1024 ),
'disklimit' => sprintf( "%.2f", $limit / 1024 ),
'percentused' => $percentused
};
sendmsg( 'mainacct_disk_warning', $notifyopts, ${$sendmail}[0] );
}
sub dispatchdisk {
return if $debug;
my ( $sendmail, $status, $limit, $used, $percentused, $user, $domain ) = @_;
return if ( ref $sendmail ne 'ARRAY' ); #no contact emails
my $notifyopts = {
'tos' => $sendmail,
'from' => ${$sendmail}[0],
'hasgoodcontact' => 0,
'domain' => $domain,
'user' => $user,
'status' => $status,
'warn' => ( $status eq 'warn' ? 1 : 0 ),
'diskused' => sprintf( "%.2f", $used / 1024 ),
'disklimit' => sprintf( "%.2f", $limit / 1024 ),
'percentused' => $percentused
};
sendmsg( 'admin_disk_warning', $notifyopts, ${$sendmail}[0] );
}
sub sendmsg {
my $template = shift;
my $notifyopts = shift;
my $sendmail = shift;
my ( $tstatus, $output_ref ) = Cpanel::Template::process_template( $template, $notifyopts );
open( SENDMAIL, "|/usr/sbin/sendmail -t" );
if ($tstatus) {
print SENDMAIL $$output_ref;
}
else {
print STDERR "quotacheck: Error while trying to use $template template: [$output_ref]\n";
print SENDMAIL qq{To: $sendmail\nTo: $sendmail\nSubject: Error while trying to use $template template\n\n$output_ref};
}
close(SENDMAIL);
print "Sent $template\n";
}