#!/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 "; } 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; }