#!/usr/bin/perl -w
use strict;

# $Id: dunk,v 1.10 2002-05-06 10:43:59-04 roderick Exp $
#
# Roderick Schertler <roderick@argon.org>
#
# dunk == du no kids
#
# This is like du but sizes exclude subdirectories and the numbers are
# output in fixed-width format.  It relies on depth first output from
# du.  Nowadays you can GNU du's --separate-dirs switch for the same
# effect (except you'd have to postprocess it for the formatting).

# Copyright (C) 2001 Roderick Schertler
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# For a copy of the GNU General Public License write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

use Proc::WaitStat	qw(close_die waitstat_reuse);
use RS::Handy		qw(xdie);

my $du = $ENV{DUNK_DU} || 'du';
my $cmd = "$du " . join ' ', map { quotemeta } @ARGV;
open DU, "$cmd |" or xdie "can't fork:";

my (%size, $this_size, $dir, $s);
while (<DU>) {
    chomp;
    ($this_size, $dir) = split ' ', $_, 2;

    # Remove the size of me and all my kids from my dad's (making him
    # more negative).
    $size{substr $dir, 0, rindex($dir, '/')} -= $this_size;

    # Add the size of me and all my kids to me, leaving my size without
    # my kids.
    $s = $size{$dir} += $this_size;

    printf "%8d %s\n", $s, $dir unless $s < 0;
}

close_die *DU, $du;
exit waitstat_reuse $?;
