Be willing to follow a symlink if the user specifies one as the root
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 25 Nov 2008 18:09:14 +0000 (18:09 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 25 Nov 2008 18:09:14 +0000 (18:09 +0000)
of the recursive scan, on the grounds that they're more likely to
have wanted a scan of the link target than of the link itself. We
still don't follow symlinks once we've started recursing, of course.

git-svn-id: svn://svn.tartarus.org/sgt/agedu@8329 cda61777-01e9-0310-a592-d414129be87e

agedu.h
du.c

diff --git a/agedu.h b/agedu.h
index fecce2e..2e6cc51 100644 (file)
--- a/agedu.h
+++ b/agedu.h
 
 extern char pathsep;
 
-#ifdef HAVE_LSTAT64
+#if defined HAVE_LSTAT64 && HAVE_STAT64
 #define STRUCT_STAT struct stat64
 #define LSTAT lstat64
+#define STAT stat64
 #else
 #define STRUCT_STAT struct stat
 #define LSTAT lstat
+#define STAT stat
 #endif
diff --git a/du.c b/du.c
index 8028432..6d26c34 100644 (file)
--- a/du.c
+++ b/du.c
@@ -170,15 +170,25 @@ static int str_cmp(const void *av, const void *bv)
 }
 
 static void du_recurse(char **path, size_t pathlen, size_t *pathsize,
-                      gotdata_fn_t gotdata, err_fn_t err, void *gotdata_ctx)
+                      gotdata_fn_t gotdata, err_fn_t err, void *gotdata_ctx,
+                      int toplevel)
 {
     const char *name;
     dirhandle d;
     STRUCT_STAT st;
     char **names;
     size_t i, nnames, namesize;
+    int statret;
 
-    if (LSTAT(*path, &st) < 0) {
+    /*
+     * Special case: at the very top of the scan, we follow a
+     * symlink.
+     */
+    if (toplevel)
+       statret = STAT(*path, &st);
+    else
+       statret = LSTAT(*path, &st);
+    if (statret < 0) {
        err(gotdata_ctx, "%s: lstat: %s\n", *path, strerror(errno));
        return;
     }
@@ -231,7 +241,7 @@ static void du_recurse(char **path, size_t pathlen, size_t *pathsize,
            sprintf(*path + pathlen, "/%s", names[i]);
        }
 
-       du_recurse(path, newpathlen, pathsize, gotdata, err, gotdata_ctx);
+       du_recurse(path, newpathlen, pathsize, gotdata, err, gotdata_ctx, 0);
 
        sfree(names[i]);
     }
@@ -249,5 +259,5 @@ void du(const char *inpath, gotdata_fn_t gotdata, err_fn_t err,
     path = snewn(pathsize, char);
     strcpy(path, inpath);
 
-    du_recurse(&path, pathlen, &pathsize, gotdata, err, gotdata_ctx);
+    du_recurse(&path, pathlen, &pathsize, gotdata, err, gotdata_ctx, 1);
 }