#! /usr/bin/perl -w
# $Header: /global/src/usr.bin/src/RCS/rquota.pl,v 1.15 2016/01/29 12:04:07 pb22 Exp $

# Use "pod2text" for info

=head1 NAME

cl-rquota - display user quota info from latest snapshot

=head1 SYNOPSIS

B<cl-rquota>

=head1 OPTIONS

=over 4

=item B<--verbose>

show what it's doing

=item B<--help>

generate help info.

=item B<--raw>

Display raw figures (KB and inodes)

=item B<--gbyte>

Display filespace as GB and files as inodes

=item B<--user> I<user>

Show info for user I<user>

=item B<--qtree> I<qtree>

Only show entries whose qtree matches I<qtree>

=item B<--filesystem> I<filesystem>

Only show entries whose filesystem matches I<filesystem>

=back

=head1 DESCRIPTION

Display the user's quotas

=cut

use Getopt::Long;
use Getopt::Long qw(:config require_order);
use Pod::Usage;
use Text::ParseWords;

%opts = (
	"verbose|v"	=> \$verbose,
	"help|h"	=> \$help,
	"filesystem|f:s"=> \$filesystem,
	"user|u:s"	=> \$user,
	"qtree:s"	=> \$qtree,
	"raw|r"		=> \$raw,
	"gbyte|g"	=> \$gbyte,
);

GetOptions (%opts) || pod2usage();
pod2usage(-verbose => 2) if $help;
$user = $ENV{'USER'} unless defined $user;

$k = 1024;

# used by &size below
%size = (
	$k*$k*$k	=> "G",
	$k*$k		=> "M",
	$k		=> "K",
	1		=> ""
);

# The format to use for the output lines
$format="%-15s %-10s %8s %8s %4s %8s %8s %4s\n";

($cmd = $0) =~ s=^/usr/bin/==;

$fields = 5;	# chomp through 5 fields at a time for "u1"
chomp($quotainfo = `/usr/groups/admin/netapp/run/get_quotas u1 $user`);
die("$cmd: get_quotas failed: $!\n") if $?;

@quotainfo = quotewords(' ', 0, $quotainfo);

$expected_max_age = (5 * 60) +10;	# two servers poll every 10 mins

$age = shift @quotainfo;
$age /= 60;

if ($age < 1) {
	$when = 'less than a minute ago';
} else {
	$age = int ($age+0.5);
        $when = sprintf '%d minute%s ago', $age, $age==1 ? '' : 's';
}

print "'$quotainfo' for '$user' gives '@quotainfo'\n" if $verbose;

die("$0: no quota found for '$user'\n") if $#quotainfo < 0;

print STDERR "$0: warning: quota data was generated $when\n\n" if $age > $expected_max_age;

# HACK the colum headers
printf $format, "File system", "qtree", ($raw) ? "space KB" : "space", "quota", "%age", "files" , "quota", "%age";

# Print the main data
while ($#quotainfo > ($fields-1)) {
	($a, $b, $c, $d, $e, $f) = (shift @quotainfo, shift @quotainfo, shift @quotainfo,shift @quotainfo,shift @quotainfo,shift @quotainfo);
	next if $qtree && $b !~ /$qtree/o;
	next if $filesystem && $a !~ /$filesystem/o;
	($pc, $pd, $pe, $pf) = ($raw) ? ($c, $d, $e, $f) :
		($gbyte) ? (&gbyte($c), &gbyte($d), $e, $f) :
		(&size($c*$k), &size($d*$k), &size($e), &size($f));
	printf $format, $a, $b, $pc, $pd, &percent($c/$d), $pe, $pf, &percent($e/$f);
}

# Check that there are no unused values.
printf STDERR "$cmd: warning: unused: @quotainfo\n" if $#quotainfo >= 0;

# =============================================================================

# return a 4 character %age
sub percent {
	return sprintf "%3d%%", int (($_[0] * 100) + 0.5);
}

# -----------------------------------------------------------------------------

# return a number as GB
sub gbyte {
	return sprintf "%.2fG", $_[0] / ($k*$k);
}

# -----------------------------------------------------------------------------

# return a number using a suitable unit
sub size {
	my($arg) = @_;
	# return "small" numbers ASIS
	return $arg if $arg < 1000000;

	# Find the most appropriate size letter and use it.
	for $key (sort {$b <=> $a} (keys %size)) {
		my $val = $arg / $key;
		return sprintf   "%d%s", $val, $size{$key} if $val > 99.99;
		return sprintf "%.1f%s", $val, $size{$key} if $val > 9.999;
		return sprintf "%.2f%s", $val, $size{$key} if $val > 0.999;
		return sprintf "%.3f%s", $val, $size{$key} if $val > 0.099;
	}
	# "should not happen" ...
	return $arg;
}
