[Rpm-metadata] [PATCH] Fix handling of symlinks pointing to a directory. BZ 969754

Zdenek Pavlas zpavlas at redhat.com
Mon Jun 3 10:53:25 UTC 2013

1) make _os_path_walk() compatible with os.path.walk()


Symbolic links to directories are not treated as subdirectories,
and that walk() therefore will not visit them. To visit linked
directories you must identify them with os.path.islink(file)
and os.path.isdir(file), and invoke walk() as necessary.

2) process each symlink only once.  This breaks directory loops.
Since we may have processed the target dir already, we process
it at most twice.
 createrepo/__init__.py | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/createrepo/__init__.py b/createrepo/__init__.py
index 1b18a9f..8be48c5 100644
--- a/createrepo/__init__.py
+++ b/createrepo/__init__.py
@@ -298,17 +298,26 @@ class MetaDataGenerator:
         for name in names:
             name = os.path.join(top, name)
             if os.path.isdir(name):
+                if os.path.islink(name):
+                    continue
                 self._os_path_walk(name, func, arg)
     def getFileList(self, directory, ext):
         """Return all files in path matching ext, store them in filelist,
         recurse dirs. Returns a list object"""
         extlen = len(ext)
+        seen = set()
         def extension_visitor(filelist, dirname, names):
             for fn in names:
                 fn = os.path.join(dirname, fn)
                 if os.path.isdir(fn):
+                    if os.path.islink(fn):
+                        st = os.stat(fn)
+                        key = st.st_dev, st.st_ino
+                        if key not in seen:
+                            seen.add(key)
+                            self._os_path_walk(fn, extension_visitor, filelist)
                 if self.conf.skip_symlinks and os.path.islink(fn):

More information about the Rpm-metadata mailing list