From 74efdfaf97ff538bd5bc18d15bc1854e15a7ad05 Mon Sep 17 00:00:00 2001 From: Simon Doppler <dopsi@dopsi.ch> Date: Wed, 23 Jan 2019 08:55:38 +0100 Subject: [PATCH] Add a '--follow-symlinks' option Symlink loops are handled by the stat(2) syscall. Symlinks pointing to a directory are ignored (to avoid loops in the recursive scan). --- doc/ncdu.pod | 5 +++++ src/dir_scan.c | 6 ++++++ src/global.h | 2 ++ src/main.c | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/doc/ncdu.pod b/doc/ncdu.pod index c499a40..eaa0ddc 100644 --- a/doc/ncdu.pod +++ b/doc/ncdu.pod @@ -172,6 +172,11 @@ displayed, but not their content, and they are not counted towards the disk usage statistics. See http://www.brynosaurus.com/cachedir/ +=item -L,--follow-symlinks + +Follow symlinks (except to directories) 00and count the size of the file +they point to. Symlink loops and directories will be ignored. + =back diff --git a/src/dir_scan.c b/src/dir_scan.c index f226114..3ec508c 100644 --- a/src/dir_scan.c +++ b/src/dir_scan.c @@ -207,6 +207,12 @@ static int dir_scan_item(const char *name) { if(!(buf_dir->flags & (FF_ERR|FF_EXL))) stat_to_dir(&st); + if (!(buf_dir->flags & (FF_ERR|FF_EXL)) && follow_symlinks && S_ISLNK(st.st_mode)) + if (!stat(name, &st)) { + if (!S_ISDIR(st.st_mode)) + stat_to_dir(&st); + } + if(cachedir_tags && (buf_dir->flags & FF_DIR) && !(buf_dir->flags & (FF_ERR|FF_EXL|FF_OTHFS))) if(has_cachedir_tag(buf_dir->name)) { buf_dir->flags |= FF_EXL; diff --git a/src/global.h b/src/global.h index effd86f..4404bf4 100644 --- a/src/global.h +++ b/src/global.h @@ -103,6 +103,8 @@ extern int cachedir_tags; extern int confirm_quit; /* flag whether we want to enable use of struct dir_ext */ extern int extended_info; +/* flag whether we want to follow symlinks */ +extern int follow_symlinks; /* handle input from keyboard and update display */ int input_handle(int); diff --git a/src/main.c b/src/main.c index c71afc2..6d8967b 100644 --- a/src/main.c +++ b/src/main.c @@ -41,6 +41,7 @@ int read_only = 0; long update_delay = 100; int cachedir_tags = 0; int extended_info = 0; +int follow_symlinks = 0; static int min_rows = 17, min_cols = 60; static int ncurses_init = 0; @@ -132,6 +133,7 @@ static void argv_parse(int argc, char **argv) { { '2', 0, "-2" }, { 1, 1, "--exclude" }, { 'X', 1, "-X,--exclude-from" }, + { 'L', 0, "-L,--follow-symlinks" }, { 'C', 0, "--exclude-caches" }, { 's', 0, "--si" }, { 'Q', 0, "--confirm-quit" }, @@ -160,6 +162,7 @@ static void argv_parse(int argc, char **argv) { printf(" --si Use base 10 (SI) prefixes instead of base 2\n"); printf(" --exclude PATTERN Exclude files that match PATTERN\n"); printf(" -X, --exclude-from FILE Exclude files that match any pattern in FILE\n"); + printf(" -L, --follow-symlinks Follow symbolic links (excluding directories)\n"); printf(" --exclude-caches Exclude directories containing CACHEDIR.TAG\n"); printf(" --confirm-quit Confirm quitting ncdu\n"); printf(" --color SCHEME Set color scheme\n"); @@ -185,6 +188,7 @@ static void argv_parse(int argc, char **argv) { exit(1); } break; + case 'L': follow_symlinks = 1; break; case 'C': cachedir_tags = 1; break; -- GitLab