From 0b1acd3358466b02f32baf9423665113dc933492 Mon Sep 17 00:00:00 2001
From: James Youngman <jay@gnu.org>
Date: Mon, 2 Mar 2009 02:02:31 +0000
Subject: [PATCH 1/2] Fix Savannah bug #25359.
To: findutils-patches@gnu.org

Fix Savannah bug #25359.
* find/ftsfind.c (consider_visiting): discard mode information
from fts when the -H option is in effect and the current file is a
symbolic link.
(find): don't decode the mode information that find is trying to
pass to us in that case, since we don't want to use it.
* find.posix/sv-bug-25359.exp: new test for this bug.
* find.posix/sv-bug-25359.xo: expected output for the test.
* NEWS: Mention this bugfix.
---
 ChangeLog                                  |   12 +++++++++++
 NEWS                                       |    4 +++
 find/ftsfind.c                             |   30 ++++++++++++++++++++++++---
 find/testsuite/Makefile.am                 |    2 +
 find/testsuite/find.posix/sv-bug-25359.exp |   10 +++++++++
 find/testsuite/find.posix/sv-bug-25359.xo  |    1 +
 6 files changed, 55 insertions(+), 4 deletions(-)
 create mode 100644 find/testsuite/find.posix/sv-bug-25359.exp
 create mode 100644 find/testsuite/find.posix/sv-bug-25359.xo

diff --git a/ChangeLog b/ChangeLog
index 2fecfdd..e75fe72 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-03-02  James Youngman  <jay@gnu.org>
+
+	Fix Savannah bug #25359.
+	* find/ftsfind.c (consider_visiting): discard mode information
+	from fts when the -H option is in effect and the current file is a
+	symbolic link.
+	(find): don't decode the mode information that find is trying to
+	pass to us in that case, since we don't want to use it.
+	* find.posix/sv-bug-25359.exp: new test for this bug.
+	* find.posix/sv-bug-25359.xo: expected output for the test.
+	* NEWS: Mention this bugfix.
+	
 2009-02-21  James Youngman  <jay@gnu.org>
 
 	Updated the email address for Eric B. Decker.
diff --git a/NEWS b/NEWS
index 1f63980..82a9adc 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ minutes.
 
 ** Bug Fixes
 
+#25359: find -H wrongly behaves like -L sometimes; this bug affects
+only filesystems which populate d_type and affects -type and -printf
+%y.   This does not affect the default behaviour of find or find -P.
+
 #25144: Misleading error message when argument to find -user is an
 unknown user or is missing.
 
diff --git a/find/ftsfind.c b/find/ftsfind.c
index 5a69cc3..1c1634e 100644
--- a/find/ftsfind.c
+++ b/find/ftsfind.c
@@ -472,8 +472,22 @@ consider_visiting(FTS *p, FTSENT *ent)
       || ent->fts_info == FTS_NS /* e.g. symlink loop */)
     {
       assert (!state.have_stat);
-      assert (ent->fts_info == FTS_NSOK || state.type != 0);
-      mode = state.type;
+      if ((options.symlink_handling == SYMLINK_DEREF_ARGSONLY)
+	  && (S_ISLNK(mode)))
+	{
+	  /* Force whichever stat version we should be using; the file
+	   * type information from fts doesn't take account of -H.
+	   * This conditional fixes Savannah bug 25359, but the bug
+	   * only manifests on filesystems which populate d_type.
+	   */
+	  state.have_type = 0;
+	  state.type = mode = 0;	  
+	}
+      else
+	{
+	  assert (ent->fts_info == FTS_NSOK || state.type != 0);
+	  mode = state.type;
+	}
     }
   else
     {
@@ -615,8 +629,16 @@ find(char *arg)
       while ( (ent=fts_read(p)) != NULL )
 	{
 	  state.have_stat = false;
-	  state.have_type = !!ent->fts_statp->st_mode;
-	  state.type = state.have_type ? ent->fts_statp->st_mode : 0;
+	  if (options.symlink_handling == SYMLINK_DEREF_ARGSONLY)
+	    {
+	      state.have_type = false;
+	      state.type = 0;
+	    }
+	  else
+	    {
+	      state.have_type = !!ent->fts_statp->st_mode;
+	      state.type = state.have_type ? ent->fts_statp->st_mode : 0;
+	    }
 	  consider_visiting(p, ent);
 	}
       fts_close(p);
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
index 1b68b0d..3180e38 100644
--- a/find/testsuite/Makefile.am
+++ b/find/testsuite/Makefile.am
@@ -77,6 +77,7 @@ find.posix/grouping.xo \
 find.posix/links.xo \
 find.posix/sv-bug-11175.xo \
 find.posix/sv-bug-12181.xo \
+find.posix/sv-bug-25359.xo \
 find.posix/depth1.xo \
 find.posix/mtime0.xo \
 find.posix/sizes.xo \
@@ -195,6 +196,7 @@ find.posix/links.exp \
 find.posix/mtime0.exp \
 find.posix/sv-bug-11175.exp \
 find.posix/sv-bug-12181.exp \
+find.posix/sv-bug-25359.exp \
 find.posix/depth1.exp \
 find.posix/sizes.exp \
 find.posix/name.exp \
diff --git a/find/testsuite/find.posix/sv-bug-25359.exp b/find/testsuite/find.posix/sv-bug-25359.exp
new file mode 100644
index 0000000..1b38d3f
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-25359.exp
@@ -0,0 +1,10 @@
+# Test for Savannah bug 25359
+# (ftsfind -H thinks that non-argument symlinks are files
+# when linked with gnulib d4b129b8e5f8a8d1198020fd6fc79310d305936c
+# Affecting findutils 	
+# from acb82fe44369c108b43ec3e805aa94bf28352d0a 
+exec rm -rf  tmp
+exec mkdir tmp
+exec ln -s / tmp/symlink
+find_start p {-H tmp -type l -print}
+exec rm -rf tmp
diff --git a/find/testsuite/find.posix/sv-bug-25359.xo b/find/testsuite/find.posix/sv-bug-25359.xo
new file mode 100644
index 0000000..8ec2030
--- /dev/null
+++ b/find/testsuite/find.posix/sv-bug-25359.xo
@@ -0,0 +1 @@
+tmp/symlink
-- 
1.5.6.5

