diff options
author | Zac Medico <zmedico@gentoo.org> | 2007-09-25 05:22:18 +0000 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2007-09-25 05:22:18 +0000 |
commit | e251578f3a9020c4bd4f916f0570e6b7caa7a95c (patch) | |
tree | 22c9fd9dd6a57a5af7da6253e007efc8bad17a89 | |
parent | 8d2522f15de684808a850bb946c284c3a0bfcb2c (diff) | |
download | portage-e251578f3a9020c4bd4f916f0570e6b7caa7a95c.tar.gz portage-e251578f3a9020c4bd4f916f0570e6b7caa7a95c.tar.bz2 portage-e251578f3a9020c4bd4f916f0570e6b7caa7a95c.zip |
Bug #193695 - Add support for FreeBSD chflags during unmerge. This
code is adapted from the code that already exists in movefile()
for the merge phase.
svn path=/main/trunk/; revision=7805
-rw-r--r-- | pym/portage/dbapi/vartree.py | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 71ccdf183..ddf8c8328 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -1186,6 +1186,28 @@ class dblink(object): mydirs = [] ignored_unlink_errnos = (errno.ENOENT, errno.EISDIR) modprotect = os.path.join(self.vartree.root, "lib/modules/") + + def unlink(file_name, lstatobj): + if bsd_chflags: + if lstatobj.st_flags != 0: + bsd_chflags.lchflags(file_name, 0) + parent_name = os.path.dirname(file_name) + # Use normal stat/chflags for the parent since we want to + # follow any symlinks to the real parent directory. + pflags = os.stat(parent_name).st_flags + if pflags != 0: + bsd_chflags.chflags(parent_name, 0) + try: + if not stat.S_ISLNK(lstatobj.st_mode): + # Remove permissions to ensure that any hardlinks to + # suid/sgid files are rendered harmless. + os.chmod(file_name, 0) + os.unlink(file_name) + finally: + if bsd_chflags and pflags != 0: + # Restore the parent flags we saved before unlinking + bsd_chflags.chflags(parent_name, pflags) + def show_unmerge(zing, desc, file_type, file_name): writemsg_stdout("%s %s %s %s\n" % \ (zing, desc.ljust(8), file_type, file_name)) @@ -1235,11 +1257,7 @@ class dblink(object): not (islink and statobj and stat.S_ISDIR(statobj.st_mode)) and \ not self.isprotected(obj): try: - # Remove permissions to ensure that any hardlinks to - # suid/sgid files are rendered harmless. - if statobj and not islink: - os.chmod(obj, 0) - os.unlink(obj) + unlink(obj, lstatobj) except EnvironmentError, e: if e.errno not in ignored_unlink_errnos: raise @@ -1269,7 +1287,7 @@ class dblink(object): # contents as a directory even if it happens to correspond # to a symlink when it's merged to the live filesystem. try: - os.unlink(obj) + unlink(obj, lstatobj) show_unmerge("<<<", "", file_type, obj) except (OSError, IOError),e: if e.errno not in ignored_unlink_errnos: @@ -1294,11 +1312,7 @@ class dblink(object): show_unmerge("---", "!md5", file_type, obj) continue try: - # Remove permissions to ensure that any hardlinks to - # suid/sgid files are rendered harmless. - if not islink: - os.chmod(obj, 0) - os.unlink(obj) + unlink(obj, lstatobj) except (OSError, IOError), e: if e.errno not in ignored_unlink_errnos: raise |