summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Doppler <dopsi@dopsi.ch>2019-01-23 08:55:38 +0100
committerYorhel <git@yorhel.nl>2019-01-24 08:24:09 +0100
commit74efdfaf97ff538bd5bc18d15bc1854e15a7ad05 (patch)
tree0dea4af2bc75dace972fa737e7d039bd02da7fac
parent2409cc7a327f29e3f630efc0c4fc35797324b0b8 (diff)
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).
-rw-r--r--doc/ncdu.pod5
-rw-r--r--src/dir_scan.c6
-rw-r--r--src/global.h2
-rw-r--r--src/main.c4
4 files changed, 17 insertions, 0 deletions
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;