#!/usr/bin/perl # Includes -------------------------------------------------------------------- # Common stuff: # Yell at me. use strict; use warnings; # Database use DBI; # Email use Email::MIME; use Email::Sender::Simple qw(sendmail); use POSIX qw(floor); # Not so common stuff. use IPC::System::Simple qw(capture); # We use IPC::System::Simple's capture # function instead of backticks. It # properly sanitizes arguments and does # proper error checking. # Stuff you should configure -------------------------------------------------- my $mailfrom = 'myserver@example.com'; my $mailto = 'myadmin@example.com'; my $servername = 'supercoolserver'; # Debug ----------------------------------------------------------------------- use Data::Dumper; # Enable backtraces via Carp. Comment out this section if not needed. # When enabled, the standard perl die() outputs a backtrace, which is much more # useful than the standard die-message-only behavior. use Carp 'verbose'; $SIG{ __DIE__ } = sub { Carp::confess( @_ ) }; # Globals --------------------------------------------------------------------- my $dbh; my $interactive; my $self=$0; # Subroutines ----------------------------------------------------------------- # Connects to the plesk database. sub connect_to_db() { my $db_password = capture('/bin/cat',qw(/etc/psa/.psa.shadow)); chomp($db_password); $dbh = DBI->connect( 'DBI:mysql:database=psa;host=localhost', #connection string 'admin', # username $db_password, # password {'RaiseError' => 1} # options ); } # Show usage sub show_help() { print "Usage: $self [options]\n\n"; print "-i\tInteractive - Output in shell instead of email.\n"; print "-h\tHelp - Display program help (this text).\n"; } # Entry point ----------------------------------------------------------------- # Defaults $interactive = 0; # Parse commandline args my $argc = $#ARGV; for (my $argn = 0 ; $argn <= $argc ; $argn++) { my $opt = $ARGV[$argn]; if ($opt eq '-i') { $argn++; $interactive = 1; } else { show_help(); exit 1; } } connect_to_db(); # Get results from db. my $rs = $dbh->prepare(' SELECT domains.name AS `domain`, domains.real_size AS `total`, Limits.value AS `allowed`, 0 + disk_usage.httpdocs + disk_usage.httpsdocs + disk_usage.subdomains + disk_usage.web_users + disk_usage.webapps AS `web`, 0 + disk_usage.mailboxes + disk_usage.maillists AS `mail`, 0 + disk_usage.dbases AS `databases`, 0 + disk_usage.logs AS `logs`, 0 + disk_usage.anonftp + disk_usage.domaindumps + disk_usage.configs + disk_usage.chroot AS `other` FROM disk_usage INNER JOIN domains ON domains.id=disk_usage.dom_id INNER JOIN Limits ON Limits.id=domains.limits_id WHERE domains.overuse=true AND Limits.limit_name="disk_space" ORDER BY domains.real_size DESC '); $rs->execute(); # Prepare table headers and stuff my $num_processed = 0; my $result_text = "Overuse data, all values in megabytes.\n\n"; my $colformat = "%49s | %-10s | %-11s | %-8s| %-8s | %-9s | %-8s | %-8s\n"; $result_text .= sprintf($colformat,'Domain','Total use','Allowed use','Website','Mail','Databases','Logs','Other'); $result_text .= "--------------------------------------------------+------------+-------------+---------+----------+-----------+----------+----------\n"; # Get results. my $have_results = 0; while (my $row = $rs->fetchrow_hashref()) { $have_results = 1; my $domain = $row->{'domain'}; my $total_usage = floor($row->{'total'} / (1024**2)); my $allowed_usage = floor($row->{'allowed'} / (1024**2)); my $web_usage = floor($row->{'web'} / (1024**2)); my $mail_usage = floor($row->{'mail'} / (1024**2)); my $db_usage = floor($row->{'databases'} / (1024**2)); my $log_usage = floor($row->{'logs'} / (1024**2)); my $other_usage = floor($row->{'other'} / (1024**2)); if ($allowed_usage == -1) { $allowed_usage = 'unlimited'; } $result_text .= sprintf($colformat,$domain,$total_usage,$allowed_usage,$web_usage,$mail_usage,$db_usage,$log_usage,$other_usage); } $rs->finish; $dbh->disconnect; # If no results, exit now. if ($have_results == 0) { exit 0; } # In interactive mode, show results in shell, # otherwise email results. if ($interactive == 1) { print "$result_text\n"; } else { my $message = Email::MIME->create( header_str => [ From => $mailfrom, To => $mailto, Subject => 'Overuse report ' . $servername ], attributes => { encoding => 'quoted-printable', charset => 'ISO-8859-1' }, body_str => $result_text ); sendmail($message); } exit 0;