All pastes #950338 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-03-20 14:36 UTC
rendered paste body
#!/usr/bin/perl -w

use strict;
use File::Find;
use File::stat;
use Getopt::Std;
use Sys::Hostname;
use Mail::Sendmail;

my %opts;
getopts('hd:p:s:t:rm',\%opts);

usage() if ( $opts{h} || ( !$opts{d} ) );
my ($directory) = ("")x1;

if ($opts{d}) { $directory = $opts{'d'}; }
if ($opts{r}) { report(); }
if ($opts{m}) { mail(); }

my @dirList = "";
my @users = "";
my $summary = "";
my $host = hostname;

sub usage
{
  print "Usage:\n\n";
  print "\t dirmonitor -d <dir>";
}


sub report
{

  my ($owner,@fileList,%HoA_Sizes,%HoA_Dirs,@tokens,$user,$file,$dir,$size,$cat,$sum);
  print "Inspecting directory: $directory ...\n\n";

  # ignore any duplicate files and directories but to proceed normally otherwise
  find( {wanted => \&wanted, follow_skip => 2 }, $directory);

  # Create a hash of arrays with our newly found directories, each array in the
  # hash contains directories that the user owns.  Each array is keyed by the
  # owners user name.
  foreach (@dirList) {
    $dir = $_;
    $user = getpwuid(stat($dir)->uid);
    $size = -s $dir;
    # test if we have an undefined user or not
    if (defined $user) {
      push @{$HoA_Sizes{$user}}, $size;
      push @{$HoA_Dirs{$user}}, $dir;
    }
  }

  # grab list of users
  @users = keys %HoA_Sizes;

  # sum up the sizes of directories that the user owns
  foreach $owner ( @users ) {
    my %dirHash;

    # dereference the array reference and grab the list of values
    my @ownersDirSizes = @{ $HoA_Sizes{$owner} };
    my @ownersDirs = @{ $HoA_Dirs{$owner} };
    @dirHash{ @ownersDirs } = @ownersDirSizes;

    foreach my $toke ( keys %dirHash ) {
      $sum += $dirHash{$toke};
    }

    push @{$HoA_Sizes{$owner}}, $sum;

    $sum = 0;
    @ownersDirSizes = "";
    @ownersDirs = "";
  }

  # sort the hash of arrays by comparing the first value of a users
  # array(sum of all users dirs)
  foreach $owner ( sort { $HoA_Sizes{$b}->[-1] <=> $HoA_Sizes{$a}->[-1] } keys %HoA_Sizes ) {
    $summary .= sprintf "%-12s %2.2f GB\n", $owner, @{[$HoA_Sizes{$owner}->[-1]/1000000000]};
  }

  print "$summary\n";
  #mail();

}

sub wanted {
  # if file exists
  if (-e $_) {
    if ($_ ne ".") {
      push(@dirList,$File::Find::name);
    }
  }

sub mail {

  foreach my $user (@users) {

    print "recipient is: $user\n";

    my %message = ( To  => $user,
          From          => 'root@localhost',
          Subject       => 'Disk usage summary',
          Message       => $summary
          );

    sendmail(%message) or die $Mail::Sendmail::error;
  }

  print "Log says: \n", $Mail::Sendmail::log;

}