For bug #134620, add a FEATURES=unmerge-orphans option that causes unmerge to remove...
authorZac Medico <zmedico@gentoo.org>
Wed, 13 Jun 2007 07:21:59 +0000 (07:21 -0000)
committerZac Medico <zmedico@gentoo.org>
Wed, 13 Jun 2007 07:21:59 +0000 (07:21 -0000)
svn path=/main/trunk/; revision=6829

cnf/make.globals
man/make.conf.5
pym/portage/dbapi/vartree.py

index 61e4266420902b25e875d1cf6d970a467b2a5ab4..d180c5389515bfccffb7cb6d8b3d3309b048ff8b 100644 (file)
@@ -33,7 +33,7 @@ FETCHCOMMAND="/usr/bin/wget -t 5 -T 60 --passive-ftp -O \${DISTDIR}/\${FILE} \${
 RESUMECOMMAND="/usr/bin/wget -c -t 5 -T 60 --passive-ftp -O \${DISTDIR}/\${FILE} \${URI}"
 
 # Default user options
-FEATURES="sandbox distlocks metadata-transfer"
+FEATURES="sandbox distlocks metadata-transfer unmerge-orphans"
 
 # Default chunksize for binhost comms
 PORTAGE_BINHOST_CHUNKSIZE="3000"
index 8fd59d363674162ac59e75baa6662dfec211f82d..35e4447efc2da2dd4b4116790cb0eabed13be015 100644 (file)
@@ -270,6 +270,11 @@ the package compiled properly.  See \fItest\fR in \fBebuild\fR(1)
 and \fIsrc_test()\fR in \fBebuild\fR(5). This feature implies the "test"
 \fBUSE\fR flag.
 .TP
+.B unmerge-orphans
+If a file is not claimed by another package in the same slot and it is not
+protected by \fICONFIG_PROTECT\fR, unmerge it even if the modification time or
+checksum differs from the file that was originally installed.
+.TP
 .B userfetch
 When portage is run as root, drop privileges to portage:portage during the
 fetching of package sources.
index 5e91adebcbeb43d6daaaedb1f7f48fc7091e14ee..e234f00f1266807213ff8795e1be41056aeda000 100644 (file)
@@ -1150,6 +1150,8 @@ class dblink(object):
                for dblnk in others_in_slot:
                        claimed_paths.update(dblnk.getcontents())
 
+               unmerge_orphans = "unmerge-orphans" in self.settings.features
+
                if pkgfiles:
                        mykeys = pkgfiles.keys()
                        mykeys.sort()
@@ -1157,9 +1159,11 @@ class dblink(object):
 
                        #process symlinks second-to-last, directories last.
                        mydirs = []
-                       modprotect = "/lib/modules/"
+                       modprotect = os.path.join(self.vartree.root, "lib/modules/")
                        for objkey in mykeys:
                                obj = normalize_path(objkey)
+                               file_data = pkgfiles[objkey]
+                               file_type = file_data[0]
                                if obj in claimed_paths:
                                        # A new instance of this package claims the file, so don't
                                        # unmerge it.
@@ -1177,7 +1181,7 @@ class dblink(object):
                                except (OSError, AttributeError):
                                        pass
                                islink = lstatobj is not None and stat.S_ISLNK(lstatobj.st_mode)
-                               if statobj is None:
+                               if not unmerge_orphans and statobj is None:
                                        if not islink:
                                                #we skip this if we're dealing with a symlink
                                                #because os.stat() will operate on the
@@ -1193,6 +1197,20 @@ class dblink(object):
                                        writemsg_stdout("--- cfgpro %s %s\n" % (pkgfiles[objkey][0], obj))
                                        continue
 
+                               if unmerge_orphans and \
+                                       lstatobj and not stat.S_ISDIR(lstatobj.st_mode) and \
+                                       not self.isprotected(obj):
+                                       try:
+                                               # Remove permissions to ensure that any hardlinks to
+                                               # suid/sgid files are rendered harmless.
+                                               if statobj:
+                                                       os.chmod(obj, 0)
+                                               os.unlink(obj)
+                                       except EnvironmentError, e:
+                                               pass
+                                       writemsg_stdout("<<<        %s %s\n" % (file_type, obj))
+                                       continue
+
                                lmtime = str(lstatobj[stat.ST_MTIME])
                                if (pkgfiles[objkey][0] not in ("dir", "fif", "dev")) and (lmtime != pkgfiles[objkey][1]):
                                        writemsg_stdout("--- !mtime %s %s\n" % (pkgfiles[objkey][0], obj))