URI: 
       update - 9base - revived minimalist port of Plan 9 userland to Unix
  HTML git clone git://git.suckless.org/9base
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 56196e76fd80ff6fdd6365d8fa028d8b4675ff4b
   DIR parent f61f650899ccc18561eb21fce96e4770508adb71
  HTML Author: Anselm R Garbe <garbeam@gmail.com>
       Date:   Mon, 10 Aug 2009 15:05:01 +0100
       
       update
       Diffstat:
         A du/Makefile                         |       6 ++++++
         A du/du.1                             |       9 +++++++++
         A du/du.c                             |     194 ++++++++++++++++++++++++++++++
       
       3 files changed, 209 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/du/Makefile b/du/Makefile
       @@ -0,0 +1,6 @@
       +# du - du unix port from plan9
       +# Depends on ../lib9
       +
       +TARG      = du
       +
       +include ../std.mk
   DIR diff --git a/du/du.1 b/du/du.1
       @@ -0,0 +1,9 @@
       +.TH DU 1 
       +.SH NAME
       +du
       +.SH SYNOPSIS
       +.B du
       +.SH DESCRIPTION
       +.I du
       +.SH SOURCE
       +.B \*9/src/cmd/du.c
   DIR diff --git a/du/du.c b/du/du.c
       @@ -0,0 +1,194 @@
       +#include <u.h>
       +#include <libc.h>
       +
       +extern        vlong        du(char*, Dir*);
       +extern        vlong        k(vlong);
       +extern        void        err(char*);
       +extern        int        warn(char*);
       +extern        int        seen(Dir*);
       +
       +int        aflag;
       +int        fflag;
       +int        nflag;
       +int        sflag;
       +int        tflag;
       +int        uflag;
       +int        qflag;
       +char        *fmt = "%llud\t%s\n";
       +vlong        blocksize = 1024LL;
       +
       +void
       +main(int argc, char *argv[])
       +{
       +        int i;
       +        char *s, *ss;
       +
       +        ARGBEGIN {
       +        case 'a':        /* all files */
       +                aflag = 1;
       +                break;
       +        case 's':        /* only top level */
       +                sflag = 1;
       +                break;
       +        case 'f':        /* ignore errors */
       +                fflag = 1;
       +                break;
       +        case 'n':        /* all files, number of bytes */
       +                aflag = 1;
       +                nflag = 1;
       +                break;
       +        case 't':        /* return modified/accessed time */
       +                tflag = 1;
       +                break;
       +        case 'u':        /* accessed time */
       +                uflag = 1;
       +                break;
       +        case 'q':        /* qid */
       +                fmt = "%.16llux\t%s\n";
       +                qflag = 1;
       +                break;
       +        case 'b':        /* block size */
       +                s = ARGF();
       +                if(s) {
       +                        blocksize = strtoul(s, &ss, 0);
       +                        if(s == ss)
       +                                blocksize = 1;
       +                        if(*ss == 'k')
       +                                blocksize *= 1024;
       +                }
       +                break;
       +        } ARGEND
       +        if(argc==0)
       +                print(fmt, du(".", dirstat(".")), ".");
       +        else
       +                for(i=0; i<argc; i++)
       +                        print(fmt, du(argv[i], dirstat(argv[i])), argv[i]);
       +        exits(0);
       +}
       +
       +vlong
       +du(char *name, Dir *dir)
       +{
       +        int fd, i, n;
       +        Dir *buf, *d;
       +        char file[256];
       +        vlong nk, t;
       +
       +        if(dir == nil)
       +                return warn(name);
       +
       +        fd = open(name, OREAD);
       +        if(fd < 0)
       +                return warn(name);
       +
       +        if((dir->qid.type&QTDIR) == 0)
       +                nk = k(dir->length);
       +        else{
       +                nk = 0;
       +                while((n=dirread(fd, &buf)) > 0) {
       +                        d = buf;
       +                        for(i=0; i<n; i++, d++) {
       +                                if((d->qid.type&QTDIR) == 0) {
       +                                        t = k(d->length);
       +                                        nk += t;
       +                                        if(aflag) {
       +                                                sprint(file, "%s/%s", name, d->name);
       +                                                if(tflag) {
       +                                                        t = d->mtime;
       +                                                        if(uflag)
       +                                                                t = d->atime;
       +                                                }
       +                                                if(qflag)
       +                                                        t = d->qid.path;
       +                                                print(fmt, t, file);
       +                                        }
       +                                        continue;
       +                                }
       +                                if(strcmp(d->name, ".") == 0 ||
       +                                   strcmp(d->name, "..") == 0 ||
       +                                   seen(d))
       +                                        continue;
       +                                sprint(file, "%s/%s", name, d->name);
       +                                t = du(file, d);
       +                                nk += t;
       +                                if(tflag) {
       +                                        t = d->mtime;
       +                                        if(uflag)
       +                                                t = d->atime;
       +                                }
       +                                if(qflag)
       +                                        t = d->qid.path;
       +                                if(!sflag)
       +                                        print(fmt, t, file);
       +                        }
       +                        free(buf);
       +                }
       +                if(n < 0)
       +                        warn(name);
       +        }
       +        close(fd);
       +        if(tflag) {
       +                if(uflag)
       +                        return dir->atime;
       +                return dir->mtime;
       +        }
       +        if(qflag)
       +                return dir->qid.path;
       +        return nk;
       +}
       +
       +#define        NCACHE        128        /* must be power of two */
       +typedef        struct        Cache        Cache;
       +struct        Cache
       +{
       +        Dir*        cache;
       +        int        n;
       +        int        max;
       +} cache[NCACHE];
       +
       +int
       +seen(Dir *dir)
       +{
       +        Dir *dp;
       +        int i;
       +        Cache *c;
       +
       +        c = &cache[dir->qid.path&(NCACHE-1)];
       +        dp = c->cache;
       +        for(i=0; i<c->n; i++, dp++)
       +                if(dir->qid.path == dp->qid.path &&
       +                   dir->type == dp->type &&
       +                   dir->dev == dp->dev)
       +                        return 1;
       +        if(c->n == c->max){
       +                c->cache = realloc(c->cache, (c->max+=20)*sizeof(Dir));
       +                if(c->cache == 0)
       +                        err("malloc failure");
       +        }
       +        c->cache[c->n++] = *dir;
       +        return 0;
       +}
       +
       +void
       +err(char *s)
       +{
       +        fprint(2, "du: %s: %r\n", s);
       +        exits(s);
       +}
       +
       +int
       +warn(char *s)
       +{
       +        if(fflag == 0)
       +                fprint(2, "du: %s: %r\n", s);
       +        return 0;
       +}
       +
       +vlong
       +k(vlong n)
       +{
       +        if(nflag)
       +                return n;
       +        n = (n+blocksize-1)/blocksize;
       +        return n*blocksize/1024LL;
       +}