sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 1d2d28a8e4ef182f9f8b4dc7c66eef0e6b8c684f
parent bd89474b8a068fbd03b665370a8988bd7dae0f8b
Author: Tai Chi Minh Ralph Eastwood <tcmreastwood@gmail.com>
Date:   Mon,  9 Feb 2015 22:18:49 +0000

du.c: add symlink dereferencing flags -H and -L

Diffstat:
Mdu.c | 23+++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/du.c b/du.c @@ -21,6 +21,7 @@ static int dflag = 0; static int sflag = 0; static int kflag = 0; static int hflag = 0; +static char HLflag = 'P'; static char * xrealpath(const char *pathname, char *resolved) @@ -68,7 +69,7 @@ nblks(struct stat *st) } static size_t -du(const char *path) +du(const char *path, char follow) { struct dirent *dent; struct stat st; @@ -81,9 +82,13 @@ du(const char *path) eprintf("stat: %s:", path); n = nblks(&st); - if (!S_ISDIR(st.st_mode)) + if (!(S_ISDIR(st.st_mode) || + (follow != 'P' && S_ISLNK(st.st_mode) && + stat(path, &st) == 0 && S_ISDIR(st.st_mode)))) goto done; + follow = follow == 'H' ? 'P' : follow; + dp = opendir(path); if (!dp) { weprintf("opendir %s:", path); @@ -97,10 +102,12 @@ du(const char *path) continue; if (lstat(dent->d_name, &st) < 0) eprintf("stat: %s:", dent->d_name); - if (S_ISDIR(st.st_mode)) { + if (S_ISDIR(st.st_mode) || + (follow != 'P' && S_ISLNK(st.st_mode) && + stat(dent->d_name, &st) == 0 && S_ISDIR(st.st_mode))) { t = curdepth; curdepth++; - n += du(dent->d_name); + n += du(dent->d_name, follow); curdepth = t; continue; } @@ -157,6 +164,10 @@ main(int argc, char *argv[]) case 'h': hflag = 1; break; + case 'H': + case 'L': + HLflag = ARGC(); + break; default: usage(); } ARGEND; @@ -172,13 +183,13 @@ main(int argc, char *argv[]) blksize = 1024; if (argc < 1) { - n = du("."); + n = du(".", HLflag); if (sflag) print(n, xrealpath(".", file)); } else { for (; argc > 0; argc--, argv++) { curdepth = 0; - n = du(argv[0]); + n = du(argv[0], HLflag); if (sflag) print(n, xrealpath(argv[0], file)); }