summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cnf/make.globals2
-rw-r--r--man/make.conf.55
-rw-r--r--pym/portage/dbapi/vartree.py22
3 files changed, 26 insertions, 3 deletions
diff --git a/cnf/make.globals b/cnf/make.globals
index 61e426642..d180c5389 100644
--- a/cnf/make.globals
+++ b/cnf/make.globals
@@ -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"
diff --git a/man/make.conf.5 b/man/make.conf.5
index 8fd59d363..35e4447ef 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -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.
diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
index 5e91adebc..e234f00f1 100644
--- a/pym/portage/dbapi/vartree.py
+++ b/pym/portage/dbapi/vartree.py
@@ -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))