Listing 1 program output
=1= #!/usr/bin/perl
=2= use strict;
=3= use warnings;
=4=
=5= use constant ONEOVERLOG2 => 1/log(2);
=6=
=7= use File::Find;
=8= use Template;
=9=
=10= my %sums;
=11= ## $sums{$uid}[$log_2_blocks]{blocks} += $blocks;
=12= ## $sums{$uid}[$log_2_blocks]{count} ++;
=13=
=14= @ARGV = qw(.) unless @ARGV;
=15=
=16= my %seen;
=17=
=18= find sub {
=19= return if -l;
=20= return unless -f _ or -d _;
=21= my @stat = stat(_) or return;
=22= my ($dev, $ino, $uid, $blocks) = @stat[0, 1, 4, 12];
=23= return if $seen{"$dev $ino"}++;
=24=
=25= my $slot = $blocks ? log($blocks) * ONEOVERLOG2 : 0;
=26= $sums{$uid}[$slot]{blocks} += $blocks;
=27= $sums{$uid}[$slot]{count}++;
=28= }, @ARGV;
=29=
=30= my %usernames = map { $_ => scalar getpwuid $_ } keys %sums;
=31= my @labels;
=32= for (values %sums) {
=33= while (@labels < @$_) {
=34= push @labels, 2**@labels;
=35= }
=36= }
=37=
=38= my %VARS =
=39= (sums => \%sums,
=40= usernames => \%usernames,
=41= labels => \@labels);
=42=
=43= Template->new({ POST_CHOMP => 1 })
=44= ->process(\<<'END_OF_TEMPLATE', \%VARS) or die Template->error;
=45= [% BLOCKSIZE = 1024 %]
=46= <style type="text/css">
=47= th, td {
=48= margin: 0; border: 1px dotted black; padding: 0.2em; text-align: center;
=49= }
=50= </style>
=51= [% MACRO nice(n) BLOCK;
=52= IF n >= 1073741824 * 9.995;
=53= n / 1073741824 | format('%dG');
=54= ELSIF n >= 1073741824;
=55= n / 1073741824 | format('%.2gG');
=56= ELSIF n >= 1048576 * 9.995;
=57= n / 1048576 | format('%dM');
=58= ELSIF n >= 1048576;
=59= n / 1048576 | format('%.2gM');
=60= ELSIF n >= 1024 * 9.995;
=61= n / 1024 | format('%dK');
=62= ELSIF n >= 1024;
=63= n / 1024 | format('%.2gK');
=64= ELSE;
=65= n;
=66= END;
=67= END %]
=68= [% MACRO bc(b,c) BLOCK %]
=69= <td>[% bytes = b * BLOCKSIZE; nice(bytes) %]<br/>[% nice(c) %]</td>
=70= [% END %]
=71= [% FOR uid = sums.keys.nsort %]
=72= [% IF loop.first %]
=73= <table>
=74= [% FOR label = labels %]
=75= [% IF loop.first %]
=76= <tr><th>User</th>
=77= [% END %]
=78= <th>[% label_bytes = label * BLOCKSIZE; nice(label_bytes) %]</th>
=79= [% IF loop.last %]
=80= <th>Total</th>
=81= </tr>
=82= [% END %]
=83= [% END %]
=84= [% END %]
=85= [% labels_max = labels.max %]
=86= [% FOR column = [0..labels_max] %]
=87= [% cell = sums.$uid.$column %]
=88= [% IF loop.first %]
=89= [% total_blocks = 0; total_count = 0 %]
=90= <tr><th>[% usernames.$uid || "?"; " ("; uid; ")" %]</th>
=91= [% END %]
=92= [% IF cell %]
=93= [% total_blocks = total_blocks + cell.blocks %]
=94= [% total_count = total_count + cell.count %]
=95= [% bc(cell.blocks, cell.count) %]
=96= [% ELSE %]
=97= <td> </td>
=98= [% END %]
=99= [% IF loop.last %]
=100= [% bc(total_blocks, total_count) %]
=101= </tr>
=102= [% END %]
=103= [% END %]
=104= [% IF loop.last %]
=105= </table>
=106= [% END %]
=107= [% END %]
=108= END_OF_TEMPLATE
|