From 3267984fa984637689c46e05688b81465ae3b812 Mon Sep 17 00:00:00 2001
From: Larry Hosken <tahoe at lahosken.san-francisco.ca.us>
Date: Wed, 7 Jan 2009 23:51:14 -0700
Subject: [PATCH] 'tahoe cp -r', upon encountering a dangling symlink, would
 assert out. This was somewhat sad; the assertion didn't say what path caused
 the error, what went wrong.  So... silently skip over things that are neither
 dirs nor files.

---
 src/allmydata/scripts/tahoe_cp.py |  6 ++++--
 src/allmydata/test/test_cli.py    | 15 +++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/allmydata/scripts/tahoe_cp.py b/src/allmydata/scripts/tahoe_cp.py
index 243fef80..c98e665b 100644
--- a/src/allmydata/scripts/tahoe_cp.py
+++ b/src/allmydata/scripts/tahoe_cp.py
@@ -117,9 +117,11 @@ class LocalDirectorySource:
                 self.children[n] = child
                 if recurse:
                     child.populate(True)
-            else:
-                assert os.path.isfile(pn)
+            elif os.path.isfile(pn):
                 self.children[n] = LocalFileSource(pn)
+            else:
+                # Could be dangling symlink; probably not copy-able.
+                pass
 
 class LocalDirectoryTarget:
     def __init__(self, progressfunc, pathname):
diff --git a/src/allmydata/test/test_cli.py b/src/allmydata/test/test_cli.py
index e9071d06..5fd09b55 100644
--- a/src/allmydata/test/test_cli.py
+++ b/src/allmydata/test/test_cli.py
@@ -600,3 +600,18 @@ class Cp(SystemTestMixin, CLITestMixin, unittest.TestCase):
 
         return d
     test_unicode_filename.todo = "This behavior is not yet supported, although it does happen to work (for reasons that are ill-understood) on many platforms.  See issue ticket #534."
+
+    def test_dangling_symlink_vs_recursion(self):
+        # cp -r on a directory containing a dangling symlink shouldn't assert
+        self.basedir = os.path.dirname(self.mktemp())
+        dn = os.path.join(self.basedir, "dir")
+        os.mkdir(dn)
+        fn = os.path.join(dn, "Fakebandica")
+        ln = os.path.join(dn, "link")
+        os.symlink(fn, ln)
+
+        d = self.set_up_nodes()
+        d.addCallback(lambda res: self.do_cli("create-alias", "tahoe"))
+        d.addCallback(lambda res: self.do_cli("cp", "--recursive",
+                                              dn, "tahoe:"))
+        return d
-- 
2.45.2