From 882a32613d5addd01c669bb36b1cdab93317a1b8 Mon Sep 17 00:00:00 2001
From: Yorhel <git@yorhel.nl>
Date: Thu, 24 Jan 2019 08:56:19 +0100
Subject: [PATCH] symlinks: Only call stat_to_dir() once, impove manual

stat_to_dir() assumes that buf_dir is clean; calling it twice breaks
that asumption.
---
 doc/ncdu.pod   |  8 +++++---
 src/dir_scan.c | 16 +++++++---------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/doc/ncdu.pod b/doc/ncdu.pod
index eaa0ddc..784500f 100644
--- a/doc/ncdu.pod
+++ b/doc/ncdu.pod
@@ -172,10 +172,12 @@ 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
+=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.
+Follow symlinks and count the size of the file they point to. As of ncdu 1.14,
+this option will not follow symlinks to directories and will count each
+symlinked file as a unique file (i.e. unlike how hard links are handled). This
+is subject to change in later versions.
 
 =back
 
diff --git a/src/dir_scan.c b/src/dir_scan.c
index 3ec508c..38068f1 100644
--- a/src/dir_scan.c
+++ b/src/dir_scan.c
@@ -185,7 +185,7 @@ static int dir_scan_recurse(const char *name) {
  * directory. Assumes we're chdir'ed in the directory in which this item
  * resides. */
 static int dir_scan_item(const char *name) {
-  struct stat st;
+  static struct stat st, stl;
   int fail = 0;
 
 #ifdef __CYGWIN__
@@ -204,14 +204,12 @@ static int dir_scan_item(const char *name) {
     dir_setlasterr(dir_curpath);
   }
 
-  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(!(buf_dir->flags & (FF_ERR|FF_EXL))) {
+    if(follow_symlinks && S_ISLNK(st.st_mode) && !stat(name, &stl) && !S_ISDIR(stl.st_mode))
+      stat_to_dir(&stl);
+    else
+      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)) {
-- 
GitLab