--- Makefile | 1 + du.1 | 18 ++++++++++ du.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 du.1 create mode 100644 du.c diff --git a/Makefile b/Makefile index 1cd6fbb..326cae8 100644 --- a/Makefile +++ b/Makefile _AT_@ -39,6 +39,7 @@ SRC = \ cut.c \ date.c \ dirname.c \ + du.c \ echo.c \ env.c \ expand.c \ diff --git a/du.1 b/du.1 new file mode 100644 index 0000000..a5046e1 --- /dev/null +++ b/du.1 _AT_@ -0,0 +1,18 @@ +.TH DU 1 sbase\-VERSION +.SH NAME +du \- display disk usage statistics +.SH SYNOPSIS +.B du +.RB [ \-a ] +.RI [ file ...] +.SH DESCRIPTION +.B du +displays the file system block usage for each +.I file +argument and for each directory in the file hierarchy rooted in directory argument. +If no file is specified, the block usage of the hierarchy rooted in the current +directory is displayed. +.SH OPTIONS +.TP +.BI \-a +Display an entry for each file in the file hierarchy. diff --git a/du.c b/du.c new file mode 100644 index 0000000..5e33dec --- /dev/null +++ b/du.c _AT_@ -0,0 +1,123 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <limits.h> +#include "util.h" + +static long blksize = 512; + +static bool aflag = false; + +static long du(const char *); +static void usage(void); + +int +main(int argc, char *argv[]) +{ + char *bsize; + + ARGBEGIN { + case 'a': + aflag = true; + break; + default: + usage(); + } ARGEND; + + bsize = getenv("BLOCKSIZE"); + if (bsize) + blksize = estrtol(bsize, 0); + + if (argc < 1) { + du("."); + } else { + for (; argc > 0; argc--, argv++) + du(argv[0]); + } + return EXIT_SUCCESS; +} + +static char * +push(const char *path) +{ + char *cwd; + + cwd = agetcwd(); + if (chdir(path) < 0) + eprintf("chdir %s:", path); + return cwd; +} + +static void +pop(char *path) +{ + if (chdir(path) < 0) + eprintf("chdir %s:", path); + free(path); +} + +static void +print(long n, char *path) +{ + printf("%lu\t%s\n", n, path); + free(path); +} + +static long +du(const char *path) +{ + DIR *dirp; + char *cwd; + struct dirent *dent; + struct stat st; + long n = 0, m; + + if (lstat(path, &st) < 0) + eprintf("stat: %s:", path); + n = 512 * st.st_blocks / blksize; + + switch (st.st_mode & S_IFMT) { + case S_IFDIR: + dirp = opendir(path); + if (!dirp) { + fprintf(stderr, "opendir: %s: %s\n", path, + strerror(errno)); + break; + } + cwd = push(path); + while ((dent = readdir(dirp))) { + if (strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) + continue; + if (lstat(dent->d_name, &st) < 0) + eprintf("stat: %s:", dent->d_name); + if (S_ISDIR(st.st_mode)) { + n += du(dent->d_name); + } else { + m = 512 * st.st_blocks / blksize; + n += m; + if (aflag) + print(m, realpath(dent->d_name, NULL)); + } + } + pop(cwd); + closedir(dirp); + break; + } + + print(n, realpath(path, NULL)); + return n; +} + +void +usage(void) +{ + eprintf("usage: %s [-a] [file...]\n", argv0); +} -- 1.8.3.4 --VS++wcV0S1rZb1Fb--Received on Mon Sep 17 2001 - 00:00:00 CEST
This archive was generated by hypermail 2.3.0 : Wed Oct 16 2013 - 18:36:03 CEST