diff options
author | Russ Cox <rsc@swtch.com> | 2014-11-17 11:21:06 -0500 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2014-11-17 11:21:06 -0500 |
commit | c9ed52730b352448c7c644f6942d310dd3509bf6 (patch) | |
tree | d9723cd78c8b632e76e90f51ae43bd65c2139116 /src/cmd/du.c | |
parent | 08e793723cad1c7aed2e8cb16c8592aba5ad05e9 (diff) | |
download | plan9port-c9ed52730b352448c7c644f6942d310dd3509bf6.tar.gz plan9port-c9ed52730b352448c7c644f6942d310dd3509bf6.tar.bz2 plan9port-c9ed52730b352448c7c644f6942d310dd3509bf6.zip |
cmd: rename *.C to *.c
These were *.C back in 2003, before the 9 script, to avoid conflicts
with the system utilities. A later change renamed them, but that
change seems to have been lost during the hg->git conversion
because I ran the conversion on a case-insensitive file system.
Change-Id: Id32c99cb9571ef0e185c3cc9e8c8d6d5b48ca195
Diffstat (limited to 'src/cmd/du.c')
-rw-r--r-- | src/cmd/du.c | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/cmd/du.c b/src/cmd/du.c new file mode 100644 index 00000000..f62c45b7 --- /dev/null +++ b/src/cmd/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; +} |