403Webshell
Server IP : 216.92.14.13  /  Your IP : 216.73.216.171
Web Server : Apache
System : Linux vps4089.pairvps.com 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64
User : rmlac2fmr ( 1040637)
PHP Version : 8.2.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/local/bin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/local/bin/disk_usage.pl
#!/usr/local/bin/perl

use strict;

=head1 NAME
    
disk_usage.pl

=head1 DESCRIPTION

This script reports the disk usage on an account.  This script takes in
account Dovecot index files that does not go against a user's disk usage.

disk_usage.pl is used by dbc.pl only for legacy hosting accounts. It
should produce accurate results on legacy accounts and vps's, though
vps's don't count disk space for billing purposes. 

=cut

use Getopt::Long;
use Data::Dumper;

my $GNUDU;
if ($^O eq 'linux') {
    $GNUDU = '/usr/bin/du';
} elsif ($^O eq 'freebsd') {
    $GNUDU = '/usr/local/bin/gdu';
} else {
    die "unsupported os: $^O";
}

my $TOTALS = {};

# Run CLI portion if we're not calling it from somewhere.
run() unless caller();

=head2 run

This is the portion that is run if this file is call as a script.  This will
use the funtions below to print out diskusage in a user friendly way.

=cut

sub run {

    # We get a few different keys back from the get_counts_for_user, we want
    # to only report on some of them.
    my $report_on_keys = { 
        mail => 1, 
        home => 1, 
        www  => 1, 
        misc => 1, 
        ftp  => 1, 
    };

    # Options defaults.
    my %opt = (
        u  => undef,
        h  => 1,
    );

    GetOptions (
        \%opt,
        'u=s',
        'h!',
    );

    # if we are running as a user who is not root, default it to the current
    # running user.  Ignoring anything that might of been passed into -u.
    my $uid  = $>;
    my $user = getpwuid($uid);

    $opt{u} = $user if $uid != 0;

    if (!$opt{u}) {
        print "ERROR: Please specifiy a user with the -u switch.\n";
        exit;
    }

    print "Gathering stats for $opt{u} ...\n";

    my $data = get_counts_for_user($opt{u}, 0);

    for my $key (keys %$report_on_keys ) {

        if ($opt{h}) {
            printf "%5s: %-15s\n", $key, _human_readable($data->{$key});
        } else { 
            printf "%5s: %-15s\n", $key, "$data->{$key} KB";
        }
    } 

        
    if ($opt{h}) {
        my $size = _human_readable($TOTALS->{total});
        printf "%5s: %-15s\n", "total", $size;
    } else { 
        printf "%5s: %-15s\n", "total", "$TOTALS->{total} KB";
    }


}

=head2 get_counts_for_user

Takes the username and returns a hash of disk counts for mail, web, and ftp.

=cut

sub get_counts_for_user {
    my ($uname) = @_;

    my %counts;

    # home
    $counts{home} = _getdu(path => "/usr/home/$uname");

    # www paths should only be counted if they aren't symlinks.
    my @www_paths;

    if (-e "/usr/www/users/$uname" && !-l "/usr/www/users/$uname") {
        push @www_paths, "/usr/www/users/$uname";
    }
    if (-e '/usr/wwws' && !-l '/usr/wwws' &&
        -e "/usr/wwws/users/$uname" && !-l "/usr/wwws/users/$uname") {
        push @www_paths, "/usr/wwws/users/$uname";
    } 
    $counts{www} = _getdu(path => \@www_paths);

    $TOTALS->{total} += $counts{www};

    # ftp
    $counts{ftp}      = _getdu(path => ["/usr/ftp/pub/$uname", "/usr/public_ftp/$uname"]);
    $TOTALS->{total} += $counts{ftp};
    
    # misc
    $counts{misc}     = _getdu(path => ["/var/cron/tabs/$uname", "/var/at/jobs/$uname"]);
    $TOTALS->{total} += $counts{misc};

    # mail
    $counts{mail}     = _getdu(path => ["/usr/boxes/$uname"], ignore => '*.index*');
    # We explicitly do not count /var/mail/$uname here, on legacy accounts.
    # The reason for this is: an early version of disk_usage.pl
    # accidentally failed to count /var/mail. Fixing that bug would
    # cause a lot of unexpected disk overusage charges. It was decided
    # to continue to not count this usage. The change only affects
    # legacy customers.

    # - _getdu the .imap directory, skipping .index files; add this to mail
    #   usage.
    $counts{'mail.imap.skip'} = _getdu(path => "/usr/home/$uname/.imap", ignore => '*.index*');
    $counts{mail}            += $counts{'mail.imap.skip'};
    $TOTALS->{total}         += $counts{mail};

    # - _getdu the .imap directory, not skipping .index files; subtract
    #   this from the home usage.
    $counts{'mail.imap'} = _getdu(path => "/usr/home/$uname/.imap");
    $counts{home}       -= $counts{'mail.imap'};

    $TOTALS->{total}    += $counts{home};

    return \%counts;

}

=head2 _getdu 

_getdu takes a directory or directories and returns the total disk space
used. It takes the following named parameters:

=over

=item path

Either a single path, or an arrayref of paths, to calculate usage for.

=item ignore

Either a single glob, or an arrayref of globs, to pass to (g)du's
--exclude.

=back

When successful, returns a number representing the disk space used, in
kilobytes. On error, warns and returns 0.

=cut 

sub _getdu {
    my %args = @_;

    my @ignore;
    if ($args{ignore}) {
        my $i = ref $args{ignore} ? $args{ignore} : [$args{ignore}];
        @ignore = map {"--exclude=$_"} @$i;
    }
    $args{path}
        or die "You have to provide a path";
    my $p = ref $args{path} ? $args{path} : [$args{path}];
    # do this so that we can trust the return value of du more;
    # otherwise, if some extra path, like /usr/wwws/users/$user, doesn't
    # exist, we'd fail
    my @paths = grep {-e $_} @$p;
    @paths
        or return 0;

    my $tot = 0;

    my @du_cmd = ($GNUDU, '-Dksc', @ignore, @paths);
    my $du_cmd = join(' ', @du_cmd, '2>/dev/null');
    my $du;
    unless (open $du, '-|', $du_cmd) {
        warn "Failed to run @du_cmd: $!";
        return 0;
    }
    while (defined (my $line = <$du>)) {
        if ($line =~ /^(\d+)\ttotal$/) {
            $tot = $1;
            last;
        }
    }

    return $tot;
}

=head2 _human_readable

A helper function that prints out the disk usage in a human friendly 
format.

=cut

sub _human_readable {
    my $data = shift;

    # we already have results in K
    my $M = 1024;
    my $G = $M * 1024;

    return "0 KB" unless $data;

    # Hack.  We only show Megabytes for disk usage
    if ((my $g = $data/$G) >= 1) {
       return sprintf "%0.2f GB", $g;
    } elsif ((my $m = $data/$M) >= 1) {
       return sprintf "%0.2f MB", $m;
    } else {
        return sprintf "%0.2f KB", $data;
    }

}

1;

Youez - 2016 - github.com/yon3zu
LinuXploit