From 9801e16c4b79fe4cafc40a573bac139767333942 Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Mon, 9 Feb 2015 22:18:49 +0000 Subject: [PATCH 7/8] du.c: add symlink dereferencing flags -H and -L --- du.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/du.c b/du.c index 6d96190..e18bae0 100644 --- 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)); } -- 2.3.0