#!/perl/bin
#
############################################################
#                       DIRSIZE.PL
#
# This script was written and produced by Michael Stenzler
# Date Created: 12-20-97
#
#   You may copy this under the terms of the GNU General Public
#   License or the Artistic License which is distributed with
#   copies of Perl v5.x for UNIX
#    
#   By using this code you agree to indemnify Michael K. Stenzler from 
#   any liability that might arise from it's use.
#
# FUNCTION: Lists the number of bytes in the directory specified or the
#           current directory if none is specified.
#
############################################################

#usage is:
#         dirsize.pl [-hvr] [directory]
#
# options:
#         h print usage info
#         v Verbose - prints the size of each file
#         r recurse through all sub-directories and return the total size

require "getopts.pl" || die "require opts failed\n";

#undef $/;

&Getopts('hvr') || die "get opts failed\n";

if (defined($opt_v)) {
	print "verbose set ...\n";
    $verbose = 'TRUE';
}
else {
    $verbose = '';
}

if (defined($opt_r)) {
	print "recurse set ...\n";
    $recurse = 'TRUE';
}
else {
    $recurse = '';
}

$Total_bytes=0;

#show user how to run the program if h switch is used
if (defined($opt_h)) {
    print "usage is: dirsize.pl [-hvr] [directory]
 options:
         h print this message
         v Verbose - prints the size of each file
         r recurse through all sub-directories and return the total size

";
    exit(0);
}

#get directory
$curr_dir = shift(@ARGV);

if ($curr_dir) {
	if ($verbose) {
		print "current direcory is: $curr_dir\n";
	}
    chdir($curr_dir);
}

#start the recursion
&do_recursive;

print "Total number of bytes: $Total_bytes";
print " or " . get_nn($Total_bytes) . " or " . b2ks1($Total_bytes);
print "\n";

sub do_recursive {
    local $curr_size;

    opendir(THISDIR, ".");
    local ($directory);
    local(@dirs) = grep(!-l, grep(!/^\.\.?$/, grep(-d, readdir(THISDIR))));
    rewinddir(THISDIR);
    local(@dirfiles) = grep(-f, readdir(THISDIR));
    closedir(THISDIR);

    foreach $file (@dirfiles) {
		stat $file;
		$curr_size = -s _;
		$Total_bytes += $curr_size;
		if ($verbose) {
			print "$file: $curr_size\n";
		}
    }

    if ((scalar(@dirs) > 0) && $recurse) { 
		foreach $directory (@dirs) {
			if ($verbose) {
				print "current direcory is: $directory\n";
			}
			chdir $directory || die "can't cd to $directory: $!\n";
			&do_recursive;	
			chdir ".." || die "can't cd up one $!\n";   
		}
    }

}


sub get_nn {
	local ($n) = @_;
	if (length($n) > 3) {
		local $mod = length($n) % 3;
		local $ret = (($mod > 0) ? substr( $n, 0, $mod ) : '');
		local $mx = int( length($n) / 3 );
		for (local $i = 0; $i < $mx; $i++ ) {
			if ($mod || $i) {
				$ret .= ','; # add comma
			}
			$ret .= substr( $n, ($mod+(3*$i)), 3 );
		}
		return $ret;
	}
	return $n;
}

#string dirghtml::b2ks1(double d) // b2ks1(double d)
sub b2ks1 {
	local ($d) = @_;
	local $oss;
	local $kss;
	local $lg = 0;
	local $ks = ($d / 1024); #// get Ks
	local $div = 1;
   if( $ks < 1000 ) {
      $div = 1;
      $oss = "KB";
   } elsif ( $ks < 1000000 ) {
	  $div = 1000;
      $oss = "MB";
   } elsif ( $ks < 1000000000 ) {
      $div = 1000000;
      $oss = "GB";
   } else {
      $div = 1000000000;
      $oss = "TB";
   }
   $kss = $ks / $div;
   $kss += 0.05;
   $kss *= 10;
   $lg = int($kss);
   return( ($lg / 10) . $oss );
}
