X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/agedu/blobdiff_plain/b5af45d3e37e570183ff09f40c4e8ef09241ade2..c113ed52cc884c922f9c78ded2e66e57a8b4bfe0:/du.c?ds=sidebyside diff --git a/du.c b/du.c index 8028432..03276c4 100644 --- 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]); } @@ -245,9 +255,18 @@ void du(const char *inpath, gotdata_fn_t gotdata, err_fn_t err, size_t pathlen, pathsize; pathlen = strlen(inpath); + + /* + * Trim any trailing slashes from the input path, otherwise we'll + * store them in the index with confusing effects. + */ + while (pathlen > 1 && inpath[pathlen-1] == '/') + pathlen--; + pathsize = pathlen + 256; path = snewn(pathsize, char); - strcpy(path, inpath); + memcpy(path, inpath, pathlen); + path[pathlen] = '\0'; - du_recurse(&path, pathlen, &pathsize, gotdata, err, gotdata_ctx); + du_recurse(&path, pathlen, &pathsize, gotdata, err, gotdata_ctx, 1); }