# Copyright 1998-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import unicode_literals

__all__ = [
	"vardbapi", "vartree", "dblink"] + \
	["write_contents", "tar_contents"]

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.checksum:_perform_md5_merge@perform_md5',
	'portage.data:portage_gid,portage_uid,secpass',
	'portage.dbapi.dep_expand:dep_expand',
	'portage.dbapi._MergeProcess:MergeProcess',
	'portage.dbapi._SyncfsProcess:SyncfsProcess',
	'portage.dep:dep_getkey,isjustname,isvalidatom,match_from_list,' + \
	 	'use_reduce,_slot_separator,_repo_separator',
	'portage.eapi:_get_eapi_attrs',
	'portage.elog:collect_ebuild_messages,collect_messages,' + \
		'elog_process,_merge_logentries',
	'portage.locks:lockdir,unlockdir,lockfile,unlockfile',
	'portage.output:bold,colorize',
	'portage.package.ebuild.doebuild:doebuild_environment,' + \
		'_merge_unicode_error', '_spawn_phase',
	'portage.package.ebuild.prepare_build_dirs:prepare_build_dirs',
	'portage.package.ebuild._ipc.QueryCommand:QueryCommand',
	'portage.util:apply_secpass_permissions,ConfigProtect,ensure_dirs,' + \
		'writemsg,writemsg_level,write_atomic,atomic_ofstream,writedict,' + \
		'grabdict,normalize_path,new_protect_filename',
	'portage.util.digraph:digraph',
	'portage.util.env_update:env_update',
	'portage.util.listdir:dircache,listdir',
	'portage.util.movefile:movefile',
	'portage.util.writeable_check:get_ro_checker',
	'portage.util._dyn_libs.PreservedLibsRegistry:PreservedLibsRegistry',
	'portage.util._dyn_libs.LinkageMapELF:LinkageMapELF@LinkageMap',
	'portage.util._async.SchedulerInterface:SchedulerInterface',
	'portage.util._eventloop.EventLoop:EventLoop',
	'portage.util._eventloop.global_event_loop:global_event_loop',
	'portage.versions:best,catpkgsplit,catsplit,cpv_getkey,vercmp,' + \
		'_get_slot_re,_pkgsplit@pkgsplit,_pkg_str,_unknown_repo',
	'subprocess',
	'tarfile',
)

from portage.const import CACHE_PATH, CONFIG_MEMORY_FILE, \
	MERGING_IDENTIFIER, PORTAGE_PACKAGE_ATOM, PRIVATE_PATH, VDB_PATH
from portage.dbapi import dbapi
from portage.exception import CommandNotFound, \
	InvalidData, InvalidLocation, InvalidPackageName, \
	FileNotFound, PermissionDenied, UnsupportedAPIException
from portage.localization import _

from portage import abssymlink, _movefile, bsd_chflags

# This is a special version of the os module, wrapped for unicode support.
from portage import os
from portage import shutil
from portage import _encodings
from portage import _os_merge
from portage import _selinux_merge
from portage import _unicode_decode
from portage import _unicode_encode

from _emerge.EbuildBuildDir import EbuildBuildDir
from _emerge.EbuildPhase import EbuildPhase
from _emerge.emergelog import emergelog
from _emerge.MiscFunctionsProcess import MiscFunctionsProcess
from _emerge.SpawnProcess import SpawnProcess

import errno
import fnmatch
import gc
import grp
import io
from itertools import chain
import logging
import os as _os
import platform
import pwd
import re
import stat
import sys
import tempfile
import textwrap
import time
import warnings

try:
	import cPickle as pickle
except ImportError:
	import pickle

if sys.hexversion >= 0x3000000:
	# pylint: disable=W0622
	basestring = str
	long = int
	_unicode = str
else:
	_unicode = unicode

class vardbapi(dbapi):

	_excluded_dirs = ["CVS", "lost+found"]
	_excluded_dirs = [re.escape(x) for x in _excluded_dirs]
	_excluded_dirs = re.compile(r'^(\..*|' + MERGING_IDENTIFIER + '.*|' + \
		"|".join(_excluded_dirs) + r')$')

	_aux_cache_version        = "1"
	_owners_cache_version     = "1"

	# Number of uncached packages to trigger cache update, since
	# it's wasteful to update it for every vdb change.
	_aux_cache_threshold = 5

	_aux_cache_keys_re = re.compile(r'^NEEDED\..*$')
	_aux_multi_line_re = re.compile(r'^(CONTENTS|NEEDED\..*)$')

	def __init__(self, _unused_param=DeprecationWarning,
		categories=None, settings=None, vartree=None):
		"""
		The categories parameter is unused since the dbapi class
		now has a categories property that is generated from the
		available packages.
		"""

		# Used by emerge to check whether any packages
		# have been added or removed.
		self._pkgs_changed = False

		# The _aux_cache_threshold doesn't work as designed
		# if the cache is flushed from a subprocess, so we
		# use this to avoid waste vdb cache updates.
		self._flush_cache_enabled = True

		#cache for category directory mtimes
		self.mtdircache = {}

		#cache for dependency checks
		self.matchcache = {}

		#cache for cp_list results
		self.cpcache = {}

		self.blockers = None
		if settings is None:
			settings = portage.settings
		self.settings = settings

		if _unused_param is not DeprecationWarning:
			warnings.warn("The first parameter of the "
				"portage.dbapi.vartree.vardbapi"
				" constructor is now unused. Instead "
				"settings['ROOT'] is used.",
				DeprecationWarning, stacklevel=2)

		self._eroot = settings['EROOT']
		self._dbroot = self._eroot + VDB_PATH
		self._lock = None
		self._lock_count = 0

		self._conf_mem_file = self._eroot + CONFIG_MEMORY_FILE
		self._fs_lock_obj = None
		self._fs_lock_count = 0

		if vartree is None:
			vartree = portage.db[settings['EROOT']]['vartree']
		self.vartree = vartree
		self._aux_cache_keys = set(
			["BUILD_TIME", "CHOST", "COUNTER", "DEPEND", "DESCRIPTION",
			"EAPI", "HDEPEND", "HOMEPAGE", "IUSE", "KEYWORDS",
			"LICENSE", "PDEPEND", "PROPERTIES", "PROVIDE", "RDEPEND",
			"repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASES",
			])
		self._aux_cache_obj = None
		self._aux_cache_filename = os.path.join(self._eroot,
			CACHE_PATH, "vdb_metadata.pickle")
		self._counter_path = os.path.join(self._eroot,
			CACHE_PATH, "counter")

		self._plib_registry = PreservedLibsRegistry(settings["ROOT"],
			os.path.join(self._eroot, PRIVATE_PATH, "preserved_libs_registry"))
		self._linkmap = LinkageMap(self)
		self._owners = self._owners_db(self)

		self._cached_counter = None

	@property
	def root(self):
		warnings.warn("The root attribute of "
			"portage.dbapi.vartree.vardbapi"
			" is deprecated. Use "
			"settings['ROOT'] instead.",
			DeprecationWarning, stacklevel=3)
		return self.settings['ROOT']

	def getpath(self, mykey, filename=None):
		# This is an optimized hotspot, so don't use unicode-wrapped
		# os module and don't use os.path.join().
		rValue = self._eroot + VDB_PATH + _os.sep + mykey
		if filename is not None:
			# If filename is always relative, we can do just
			# rValue += _os.sep + filename
			rValue = _os.path.join(rValue, filename)
		return rValue

	def lock(self):
		"""
		Acquire a reentrant lock, blocking, for cooperation with concurrent
		processes. State is inherited by subprocesses, allowing subprocesses
		to reenter a lock that was acquired by a parent process. However,
		a lock can be released only by the same process that acquired it.
		"""
		if self._lock_count:
			self._lock_count += 1
		else:
			if self._lock is not None:
				raise AssertionError("already locked")
			# At least the parent needs to exist for the lock file.
			ensure_dirs(self._dbroot)
			self._lock = lockdir(self._dbroot)
			self._lock_count += 1

	def unlock(self):
		"""
		Release a lock, decrementing the recursion level. Each unlock() call
		must be matched with a prior lock() call, or else an AssertionError
		will be raised if unlock() is called while not locked.
		"""
		if self._lock_count > 1:
			self._lock_count -= 1
		else:
			if self._lock is None:
				raise AssertionError("not locked")
			self._lock_count = 0
			unlockdir(self._lock)
			self._lock = None

	def _fs_lock(self):
		"""
		Acquire a reentrant lock, blocking, for cooperation with concurrent
		processes.
		"""
		if self._fs_lock_count < 1:
			if self._fs_lock_obj is not None:
				raise AssertionError("already locked")
			try:
				self._fs_lock_obj = lockfile(self._conf_mem_file)
			except InvalidLocation:
				self.settings._init_dirs()
				self._fs_lock_obj = lockfile(self._conf_mem_file)
		self._fs_lock_count += 1

	def _fs_unlock(self):
		"""
		Release a lock, decrementing the recursion level.
		"""
		if self._fs_lock_count <= 1:
			if self._fs_lock_obj is None:
				raise AssertionError("not locked")
			unlockfile(self._fs_lock_obj)
			self._fs_lock_obj = None
		self._fs_lock_count -= 1

	def _bump_mtime(self, cpv):
		"""
		This is called before an after any modifications, so that consumers
		can use directory mtimes to validate caches. See bug #290428.
		"""
		base = self._eroot + VDB_PATH
		cat = catsplit(cpv)[0]
		catdir = base + _os.sep + cat
		t = time.time()
		t = (t, t)
		try:
			for x in (catdir, base):
				os.utime(x, t)
		except OSError:
			ensure_dirs(catdir)

	def cpv_exists(self, mykey, myrepo=None):
		"Tells us whether an actual ebuild exists on disk (no masking)"
		return os.path.exists(self.getpath(mykey))

	def cpv_counter(self, mycpv):
		"This method will grab the COUNTER. Returns a counter value."
		try:
			return long(self.aux_get(mycpv, ["COUNTER"])[0])
		except (KeyError, ValueError):
			pass
		writemsg_level(_("portage: COUNTER for %s was corrupted; " \
			"resetting to value of 0\n") % (mycpv,),
			level=logging.ERROR, noiselevel=-1)
		return 0

	def cpv_inject(self, mycpv):
		"injects a real package into our on-disk database; assumes mycpv is valid and doesn't already exist"
		ensure_dirs(self.getpath(mycpv))
		counter = self.counter_tick(mycpv=mycpv)
		# write local package counter so that emerge clean does the right thing
		write_atomic(self.getpath(mycpv, filename="COUNTER"), str(counter))

	def isInjected(self, mycpv):
		if self.cpv_exists(mycpv):
			if os.path.exists(self.getpath(mycpv, filename="INJECTED")):
				return True
			if not os.path.exists(self.getpath(mycpv, filename="CONTENTS")):
				return True
		return False

	def move_ent(self, mylist, repo_match=None):
		origcp = mylist[1]
		newcp = mylist[2]

		# sanity check
		for atom in (origcp, newcp):
			if not isjustname(atom):
				raise InvalidPackageName(str(atom))
		origmatches = self.match(origcp, use_cache=0)
		moves = 0
		if not origmatches:
			return moves
		for mycpv in origmatches:
			try:
				mycpv = self._pkg_str(mycpv, None)
			except (KeyError, InvalidData):
				continue
			mycpv_cp = cpv_getkey(mycpv)
			if mycpv_cp != origcp:
				# Ignore PROVIDE virtual match.
				continue
			if repo_match is not None \
				and not repo_match(mycpv.repo):
				continue

			# Use isvalidatom() to check if this move is valid for the
			# EAPI (characters allowed in package names may vary).
			if not isvalidatom(newcp, eapi=mycpv.eapi):
				continue

			mynewcpv = mycpv.replace(mycpv_cp, _unicode(newcp), 1)
			mynewcat = catsplit(newcp)[0]
			origpath = self.getpath(mycpv)
			if not os.path.exists(origpath):
				continue
			moves += 1
			if not os.path.exists(self.getpath(mynewcat)):
				#create the directory
				ensure_dirs(self.getpath(mynewcat))
			newpath = self.getpath(mynewcpv)
			if os.path.exists(newpath):
				#dest already exists; keep this puppy where it is.
				continue
			_movefile(origpath, newpath, mysettings=self.settings)
			self._clear_pkg_cache(self._dblink(mycpv))
			self._clear_pkg_cache(self._dblink(mynewcpv))

			# We need to rename the ebuild now.
			old_pf = catsplit(mycpv)[1]
			new_pf = catsplit(mynewcpv)[1]
			if new_pf != old_pf:
				try:
					os.rename(os.path.join(newpath, old_pf + ".ebuild"),
						os.path.join(newpath, new_pf + ".ebuild"))
				except EnvironmentError as e:
					if e.errno != errno.ENOENT:
						raise
					del e
			write_atomic(os.path.join(newpath, "PF"), new_pf+"\n")
			write_atomic(os.path.join(newpath, "CATEGORY"), mynewcat+"\n")

		return moves

	def cp_list(self, mycp, use_cache=1):
		mysplit=catsplit(mycp)
		if mysplit[0] == '*':
			mysplit[0] = mysplit[0][1:]
		try:
			if sys.hexversion >= 0x3030000:
				mystat = os.stat(self.getpath(mysplit[0])).st_mtime_ns
			else:
				mystat = os.stat(self.getpath(mysplit[0])).st_mtime
		except OSError:
			mystat = 0
		if use_cache and mycp in self.cpcache:
			cpc = self.cpcache[mycp]
			if cpc[0] == mystat:
				return cpc[1][:]
		cat_dir = self.getpath(mysplit[0])
		try:
			dir_list = os.listdir(cat_dir)
		except EnvironmentError as e:
			if e.errno == PermissionDenied.errno:
				raise PermissionDenied(cat_dir)
			del e
			dir_list = []

		returnme = []
		for x in dir_list:
			if self._excluded_dirs.match(x) is not None:
				continue
			ps = pkgsplit(x)
			if not ps:
				self.invalidentry(os.path.join(self.getpath(mysplit[0]), x))
				continue
			if len(mysplit) > 1:
				if ps[0] == mysplit[1]:
					returnme.append(_pkg_str(mysplit[0]+"/"+x))
		self._cpv_sort_ascending(returnme)
		if use_cache:
			self.cpcache[mycp] = [mystat, returnme[:]]
		elif mycp in self.cpcache:
			del self.cpcache[mycp]
		return returnme

	def cpv_all(self, use_cache=1):
		"""
		Set use_cache=0 to bypass the portage.cachedir() cache in cases
		when the accuracy of mtime staleness checks should not be trusted
		(generally this is only necessary in critical sections that
		involve merge or unmerge of packages).
		"""
		returnme = []
		basepath = os.path.join(self._eroot, VDB_PATH) + os.path.sep

		if use_cache:
			from portage import listdir
		else:
			def listdir(p, **kwargs):
				try:
					return [x for x in os.listdir(p) \
						if os.path.isdir(os.path.join(p, x))]
				except EnvironmentError as e:
					if e.errno == PermissionDenied.errno:
						raise PermissionDenied(p)
					del e
					return []

		for x in listdir(basepath, EmptyOnError=1, ignorecvs=1, dirsonly=1):
			if self._excluded_dirs.match(x) is not None:
				continue
			if not self._category_re.match(x):
				continue
			for y in listdir(basepath + x, EmptyOnError=1, dirsonly=1):
				if self._excluded_dirs.match(y) is not None:
					continue
				subpath = x + "/" + y
				# -MERGING- should never be a cpv, nor should files.
				try:
					if catpkgsplit(subpath) is None:
						self.invalidentry(self.getpath(subpath))
						continue
				except InvalidData:
					self.invalidentry(self.getpath(subpath))
					continue
				returnme.append(subpath)

		return returnme

	def cp_all(self, use_cache=1):
		mylist = self.cpv_all(use_cache=use_cache)
		d={}
		for y in mylist:
			if y[0] == '*':
				y = y[1:]
			try:
				mysplit = catpkgsplit(y)
			except InvalidData:
				self.invalidentry(self.getpath(y))
				continue
			if not mysplit:
				self.invalidentry(self.getpath(y))
				continue
			d[mysplit[0]+"/"+mysplit[1]] = None
		return list(d)

	def checkblockers(self, origdep):
		pass

	def _clear_cache(self):
		self.mtdircache.clear()
		self.matchcache.clear()
		self.cpcache.clear()
		self._aux_cache_obj = None

	def _add(self, pkg_dblink):
		self._pkgs_changed = True
		self._clear_pkg_cache(pkg_dblink)

	def _remove(self, pkg_dblink):
		self._pkgs_changed = True
		self._clear_pkg_cache(pkg_dblink)

	def _clear_pkg_cache(self, pkg_dblink):
		# Due to 1 second mtime granularity in <python-2.5, mtime checks
		# are not always sufficient to invalidate vardbapi caches. Therefore,
		# the caches need to be actively invalidated here.
		self.mtdircache.pop(pkg_dblink.cat, None)
		self.matchcache.pop(pkg_dblink.cat, None)
		self.cpcache.pop(pkg_dblink.mysplit[0], None)
		dircache.pop(pkg_dblink.dbcatdir, None)

	def match(self, origdep, use_cache=1):
		"caching match function"
		mydep = dep_expand(
			origdep, mydb=self, use_cache=use_cache, settings=self.settings)
		cache_key = (mydep, mydep.unevaluated_atom)
		mykey = dep_getkey(mydep)
		mycat = catsplit(mykey)[0]
		if not use_cache:
			if mycat in self.matchcache:
				del self.mtdircache[mycat]
				del self.matchcache[mycat]
			return list(self._iter_match(mydep,
				self.cp_list(mydep.cp, use_cache=use_cache)))
		try:
			if sys.hexversion >= 0x3030000:
				curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime_ns
			else:
				curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime
		except (IOError, OSError):
			curmtime=0

		if mycat not in self.matchcache or \
			self.mtdircache[mycat] != curmtime:
			# clear cache entry
			self.mtdircache[mycat] = curmtime
			self.matchcache[mycat] = {}
		if mydep not in self.matchcache[mycat]:
			mymatch = list(self._iter_match(mydep,
				self.cp_list(mydep.cp, use_cache=use_cache)))
			self.matchcache[mycat][cache_key] = mymatch
		return self.matchcache[mycat][cache_key][:]

	def findname(self, mycpv, myrepo=None):
		return self.getpath(str(mycpv), filename=catsplit(mycpv)[1]+".ebuild")

	def flush_cache(self):
		"""If the current user has permission and the internal aux_get cache has
		been updated, save it to disk and mark it unmodified.  This is called
		by emerge after it has loaded the full vdb for use in dependency
		calculations.  Currently, the cache is only written if the user has
		superuser privileges (since that's required to obtain a lock), but all
		users have read access and benefit from faster metadata lookups (as
		long as at least part of the cache is still valid)."""
		if self._flush_cache_enabled and \
			self._aux_cache is not None and \
			len(self._aux_cache["modified"]) >= self._aux_cache_threshold and \
			secpass >= 2:
			self._owners.populate() # index any unindexed contents
			valid_nodes = set(self.cpv_all())
			for cpv in list(self._aux_cache["packages"]):
				if cpv not in valid_nodes:
					del self._aux_cache["packages"][cpv]
			del self._aux_cache["modified"]
			try:
				f = atomic_ofstream(self._aux_cache_filename, 'wb')
				pickle.dump(self._aux_cache, f, protocol=2)
				f.close()
				apply_secpass_permissions(
					self._aux_cache_filename, gid=portage_gid, mode=0o644)
			except (IOError, OSError) as e:
				pass
			self._aux_cache["modified"] = set()

	@property
	def _aux_cache(self):
		if self._aux_cache_obj is None:
			self._aux_cache_init()
		return self._aux_cache_obj

	def _aux_cache_init(self):
		aux_cache = None
		open_kwargs = {}
		if sys.hexversion >= 0x3000000 and sys.hexversion < 0x3020000:
			# Buffered io triggers extreme performance issues in
			# Unpickler.load() (problem observed with python-3.0.1).
			# Unfortunately, performance is still poor relative to
			# python-2.x, but buffering makes it much worse (problem
			# appears to be solved in Python >=3.2 at least).
			open_kwargs["buffering"] = 0
		try:
			with open(_unicode_encode(self._aux_cache_filename,
				encoding=_encodings['fs'], errors='strict'),
				mode='rb', **open_kwargs) as f:
				mypickle = pickle.Unpickler(f)
				try:
					mypickle.find_global = None
				except AttributeError:
					# TODO: If py3k, override Unpickler.find_class().
					pass
				aux_cache = mypickle.load()
		except (SystemExit, KeyboardInterrupt):
			raise
		except Exception as e:
			if isinstance(e, EnvironmentError) and \
				getattr(e, 'errno', None) in (errno.ENOENT, errno.EACCES):
				pass
			else:
				writemsg(_("!!! Error loading '%s': %s\n") % \
					(self._aux_cache_filename, e), noiselevel=-1)
			del e

		if not aux_cache or \
			not isinstance(aux_cache, dict) or \
			aux_cache.get("version") != self._aux_cache_version or \
			not aux_cache.get("packages"):
			aux_cache = {"version": self._aux_cache_version}
			aux_cache["packages"] = {}

		owners = aux_cache.get("owners")
		if owners is not None:
			if not isinstance(owners, dict):
				owners = None
			elif "version" not in owners:
				owners = None
			elif owners["version"] != self._owners_cache_version:
				owners = None
			elif "base_names" not in owners:
				owners = None
			elif not isinstance(owners["base_names"], dict):
				owners = None

		if owners is None:
			owners = {
				"base_names" : {},
				"version"    : self._owners_cache_version
			}
			aux_cache["owners"] = owners

		aux_cache["modified"] = set()
		self._aux_cache_obj = aux_cache

	def aux_get(self, mycpv, wants, myrepo = None):
		"""This automatically caches selected keys that are frequently needed
		by emerge for dependency calculations.  The cached metadata is
		considered valid if the mtime of the package directory has not changed
		since the data was cached.  The cache is stored in a pickled dict
		object with the following format:

		{version:"1", "packages":{cpv1:(mtime,{k1,v1, k2,v2, ...}), cpv2...}}

		If an error occurs while loading the cache pickle or the version is
		unrecognized, the cache will simple be recreated from scratch (it is
		completely disposable).
		"""
		cache_these_wants = self._aux_cache_keys.intersection(wants)
		for x in wants:
			if self._aux_cache_keys_re.match(x) is not None:
				cache_these_wants.add(x)

		if not cache_these_wants:
			mydata = self._aux_get(mycpv, wants)
			return [mydata[x] for x in wants]

		cache_these = set(self._aux_cache_keys)
		cache_these.update(cache_these_wants)

		mydir = self.getpath(mycpv)
		mydir_stat = None
		try:
			mydir_stat = os.stat(mydir)
		except OSError as e:
			if e.errno != errno.ENOENT:
				raise
			raise KeyError(mycpv)
		# Use float mtime when available.
		mydir_mtime = mydir_stat.st_mtime
		pkg_data = self._aux_cache["packages"].get(mycpv)
		pull_me = cache_these.union(wants)
		mydata = {"_mtime_" : mydir_mtime}
		cache_valid = False
		cache_incomplete = False
		cache_mtime = None
		metadata = None
		if pkg_data is not None:
			if not isinstance(pkg_data, tuple) or len(pkg_data) != 2:
				pkg_data = None
			else:
				cache_mtime, metadata = pkg_data
				if not isinstance(cache_mtime, (float, long, int)) or \
					not isinstance(metadata, dict):
					pkg_data = None

		if pkg_data:
			cache_mtime, metadata = pkg_data
			if isinstance(cache_mtime, float):
				cache_valid = cache_mtime == mydir_stat.st_mtime
			else:
				# Cache may contain integer mtime.
				cache_valid = cache_mtime == mydir_stat[stat.ST_MTIME]

		if cache_valid:
			# Migrate old metadata to unicode.
			for k, v in metadata.items():
				metadata[k] = _unicode_decode(v,
					encoding=_encodings['repo.content'], errors='replace')

			mydata.update(metadata)
			pull_me.difference_update(mydata)

		if pull_me:
			# pull any needed data and cache it
			aux_keys = list(pull_me)
			mydata.update(self._aux_get(mycpv, aux_keys, st=mydir_stat))
			if not cache_valid or cache_these.difference(metadata):
				cache_data = {}
				if cache_valid and metadata:
					cache_data.update(metadata)
				for aux_key in cache_these:
					cache_data[aux_key] = mydata[aux_key]
				self._aux_cache["packages"][_unicode(mycpv)] = \
					(mydir_mtime, cache_data)
				self._aux_cache["modified"].add(mycpv)

		eapi_attrs = _get_eapi_attrs(mydata['EAPI'])
		if _get_slot_re(eapi_attrs).match(mydata['SLOT']) is None:
			# Empty or invalid slot triggers InvalidAtom exceptions when
			# generating slot atoms for packages, so translate it to '0' here.
			mydata['SLOT'] = '0'

		return [mydata[x] for x in wants]

	def _aux_get(self, mycpv, wants, st=None):
		mydir = self.getpath(mycpv)
		if st is None:
			try:
				st = os.stat(mydir)
			except OSError as e:
				if e.errno == errno.ENOENT:
					raise KeyError(mycpv)
				elif e.errno == PermissionDenied.errno:
					raise PermissionDenied(mydir)
				else:
					raise
		if not stat.S_ISDIR(st.st_mode):
			raise KeyError(mycpv)
		results = {}
		env_keys = []
		for x in wants:
			if x == "_mtime_":
				results[x] = st[stat.ST_MTIME]
				continue
			try:
				with io.open(
					_unicode_encode(os.path.join(mydir, x),
					encoding=_encodings['fs'], errors='strict'),
					mode='r', encoding=_encodings['repo.content'],
					errors='replace') as f:
					myd = f.read()
			except IOError:
				if x not in self._aux_cache_keys and \
					self._aux_cache_keys_re.match(x) is None:
					env_keys.append(x)
					continue
				myd = ''

			# Preserve \n for metadata that is known to
			# contain multiple lines.
			if self._aux_multi_line_re.match(x) is None:
				myd = " ".join(myd.split())

			results[x] = myd

		if env_keys:
			env_results = self._aux_env_search(mycpv, env_keys)
			for k in env_keys:
				v = env_results.get(k)
				if v is None:
					v = ''
				if self._aux_multi_line_re.match(k) is None:
					v = " ".join(v.split())
				results[k] = v

		if results.get("EAPI") == "":
			results["EAPI"] = '0'

		return results

	def _aux_env_search(self, cpv, variables):
		"""
		Search environment.bz2 for the specified variables. Returns
		a dict mapping variables to values, and any variables not
		found in the environment will not be included in the dict.
		This is useful for querying variables like ${SRC_URI} and
		${A}, which are not saved in separate files but are available
		in environment.bz2 (see bug #395463).
		"""
		env_file = self.getpath(cpv, filename="environment.bz2")
		if not os.path.isfile(env_file):
			return {}
		bunzip2_cmd = portage.util.shlex_split(
			self.settings.get("PORTAGE_BUNZIP2_COMMAND", ""))
		if not bunzip2_cmd:
			bunzip2_cmd = portage.util.shlex_split(
				self.settings["PORTAGE_BZIP2_COMMAND"])
			bunzip2_cmd.append("-d")
		args = bunzip2_cmd + ["-c", env_file]
		try:
			proc = subprocess.Popen(args, stdout=subprocess.PIPE)
		except EnvironmentError as e:
			if e.errno != errno.ENOENT:
				raise
			raise portage.exception.CommandNotFound(args[0])

		# Parts of the following code are borrowed from
		# filter-bash-environment.py (keep them in sync).
		var_assign_re = re.compile(r'(^|^declare\s+-\S+\s+|^declare\s+|^export\s+)([^=\s]+)=("|\')?(.*)$')
		close_quote_re = re.compile(r'(\\"|"|\')\s*$')
		def have_end_quote(quote, line):
			close_quote_match = close_quote_re.search(line)
			return close_quote_match is not None and \
				close_quote_match.group(1) == quote

		variables = frozenset(variables)
		results = {}
		for line in proc.stdout:
			line = _unicode_decode(line,
				encoding=_encodings['content'], errors='replace')
			var_assign_match = var_assign_re.match(line)
			if var_assign_match is not None:
				key = var_assign_match.group(2)
				quote = var_assign_match.group(3)
				if quote is not None:
					if have_end_quote(quote,
						line[var_assign_match.end(2)+2:]):
						value = var_assign_match.group(4)
					else:
						value = [var_assign_match.group(4)]
						for line in proc.stdout:
							line = _unicode_decode(line,
								encoding=_encodings['content'],
								errors='replace')
							value.append(line)
							if have_end_quote(quote, line):
								break
						value = ''.join(value)
					# remove trailing quote and whitespace
					value = value.rstrip()[:-1]
				else:
					value = var_assign_match.group(4).rstrip()

				if key in variables:
					results[key] = value

		proc.wait()
		proc.stdout.close()
		return results

	def aux_update(self, cpv, values):
		mylink = self._dblink(cpv)
		if not mylink.exists():
			raise KeyError(cpv)
		self._bump_mtime(cpv)
		self._clear_pkg_cache(mylink)
		for k, v in values.items():
			if v:
				mylink.setfile(k, v)
			else:
				try:
					os.unlink(os.path.join(self.getpath(cpv), k))
				except EnvironmentError:
					pass
		self._bump_mtime(cpv)

	def counter_tick(self, myroot=None, mycpv=None):
		"""
		@param myroot: ignored, self._eroot is used instead
		"""
		return self.counter_tick_core(incrementing=1, mycpv=mycpv)

	def get_counter_tick_core(self, myroot=None, mycpv=None):
		"""
		Use this method to retrieve the counter instead
		of having to trust the value of a global counter
		file that can lead to invalid COUNTER
		generation. When cache is valid, the package COUNTER
		files are not read and we rely on the timestamp of
		the package directory to validate cache. The stat
		calls should only take a short time, so performance
		is sufficient without having to rely on a potentially
		corrupt global counter file.

		The global counter file located at
		$CACHE_PATH/counter serves to record the
		counter of the last installed package and
		it also corresponds to the total number of
		installation actions that have occurred in
		the history of this package database.

		@param myroot: ignored, self._eroot is used instead
		"""
		del myroot
		counter = -1
		try:
			with io.open(
				_unicode_encode(self._counter_path,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace') as f:
				try:
					counter = long(f.readline().strip())
				except (OverflowError, ValueError) as e:
					writemsg(_("!!! COUNTER file is corrupt: '%s'\n") %
						self._counter_path, noiselevel=-1)
					writemsg("!!! %s\n" % (e,), noiselevel=-1)
		except EnvironmentError as e:
			# Silently allow ENOENT since files under
			# /var/cache/ are allowed to disappear.
			if e.errno != errno.ENOENT:
				writemsg(_("!!! Unable to read COUNTER file: '%s'\n") % \
					self._counter_path, noiselevel=-1)
				writemsg("!!! %s\n" % str(e), noiselevel=-1)
			del e

		if self._cached_counter == counter:
			max_counter = counter
		else:
			# We must ensure that we return a counter
			# value that is at least as large as the
			# highest one from the installed packages,
			# since having a corrupt value that is too low
			# can trigger incorrect AUTOCLEAN behavior due
			# to newly installed packages having lower
			# COUNTERs than the previous version in the
			# same slot.
			max_counter = counter
			for cpv in self.cpv_all():
				try:
					pkg_counter = int(self.aux_get(cpv, ["COUNTER"])[0])
				except (KeyError, OverflowError, ValueError):
					continue
				if pkg_counter > max_counter:
					max_counter = pkg_counter

		return max_counter + 1

	def counter_tick_core(self, myroot=None, incrementing=1, mycpv=None):
		"""
		This method will grab the next COUNTER value and record it back
		to the global file. Note that every package install must have
		a unique counter, since a slotmove update can move two packages
		into the same SLOT and in that case it's important that both
		packages have different COUNTER metadata.

		@param myroot: ignored, self._eroot is used instead
		@param mycpv: ignored
		@rtype: int
		@return: new counter value
		"""
		myroot = None
		mycpv = None
		self.lock()
		try:
			counter = self.get_counter_tick_core() - 1
			if incrementing:
				#increment counter
				counter += 1
				# update new global counter file
				try:
					write_atomic(self._counter_path, str(counter))
				except InvalidLocation:
					self.settings._init_dirs()
					write_atomic(self._counter_path, str(counter))
			self._cached_counter = counter

			# Since we hold a lock, this is a good opportunity
			# to flush the cache. Note that this will only
			# flush the cache periodically in the main process
			# when _aux_cache_threshold is exceeded.
			self.flush_cache()
		finally:
			self.unlock()

		return counter

	def _dblink(self, cpv):
		category, pf = catsplit(cpv)
		return dblink(category, pf, settings=self.settings,
			vartree=self.vartree, treetype="vartree")

	def removeFromContents(self, pkg, paths, relative_paths=True):
		"""
		@param pkg: cpv for an installed package
		@type pkg: string
		@param paths: paths of files to remove from contents
		@type paths: iterable
		"""
		if not hasattr(pkg, "getcontents"):
			pkg = self._dblink(pkg)
		root = self.settings['ROOT']
		root_len = len(root) - 1
		new_contents = pkg.getcontents().copy()
		removed = 0

		for filename in paths:
			filename = _unicode_decode(filename,
				encoding=_encodings['content'], errors='strict')
			filename = normalize_path(filename)
			if relative_paths:
				relative_filename = filename
			else:
				relative_filename = filename[root_len:]
			contents_key = pkg._match_contents(relative_filename)
			if contents_key:
				# It's possible for two different paths to refer to the same
				# contents_key, due to directory symlinks. Therefore, pass a
				# default value to pop, in order to avoid a KeyError which
				# could otherwise be triggered (see bug #454400).
				new_contents.pop(contents_key, None)
				removed += 1

		if removed:
			self.writeContentsToContentsFile(pkg, new_contents)

	def writeContentsToContentsFile(self, pkg, new_contents):
		"""
		@param pkg: package to write contents file for
		@type pkg: dblink
		@param new_contents: contents to write to CONTENTS file
		@type new_contents: contents dictionary of the form
					{u'/path/to/file' : (contents_attribute 1, ...), ...}
		"""
		root = self.settings['ROOT']
		self._bump_mtime(pkg.mycpv)
		f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS"))
		write_contents(new_contents, root, f)
		f.close()
		self._bump_mtime(pkg.mycpv)
		pkg._clear_contents_cache()

	class _owners_cache(object):
		"""
		This class maintains an hash table that serves to index package
		contents by mapping the basename of file to a list of possible
		packages that own it. This is used to optimize owner lookups
		by narrowing the search down to a smaller number of packages.
		"""
		try:
			from hashlib import md5 as _new_hash
		except ImportError:
			from md5 import new as _new_hash

		_hash_bits = 16
		_hex_chars = int(_hash_bits / 4)

		def __init__(self, vardb):
			self._vardb = vardb

		def add(self, cpv):
			eroot_len = len(self._vardb._eroot)
			contents = self._vardb._dblink(cpv).getcontents()
			pkg_hash = self._hash_pkg(cpv)
			if not contents:
				# Empty path is a code used to represent empty contents.
				self._add_path("", pkg_hash)

			for x in contents:
				self._add_path(x[eroot_len:], pkg_hash)

			self._vardb._aux_cache["modified"].add(cpv)

		def _add_path(self, path, pkg_hash):
			"""
			Empty path is a code that represents empty contents.
			"""
			if path:
				name = os.path.basename(path.rstrip(os.path.sep))
				if not name:
					return
			else:
				name = path
			name_hash = self._hash_str(name)
			base_names = self._vardb._aux_cache["owners"]["base_names"]
			pkgs = base_names.get(name_hash)
			if pkgs is None:
				pkgs = {}
				base_names[name_hash] = pkgs
			pkgs[pkg_hash] = None

		def _hash_str(self, s):
			h = self._new_hash()
			# Always use a constant utf_8 encoding here, since
			# the "default" encoding can change.
			h.update(_unicode_encode(s,
				encoding=_encodings['repo.content'],
				errors='backslashreplace'))
			h = h.hexdigest()
			h = h[-self._hex_chars:]
			h = int(h, 16)
			return h

		def _hash_pkg(self, cpv):
			counter, mtime = self._vardb.aux_get(
				cpv, ["COUNTER", "_mtime_"])
			try:
				counter = int(counter)
			except ValueError:
				counter = 0
			return (_unicode(cpv), counter, mtime)

	class _owners_db(object):

		def __init__(self, vardb):
			self._vardb = vardb

		def populate(self):
			self._populate()

		def _populate(self):
			owners_cache = vardbapi._owners_cache(self._vardb)
			cached_hashes = set()
			base_names = self._vardb._aux_cache["owners"]["base_names"]

			# Take inventory of all cached package hashes.
			for name, hash_values in list(base_names.items()):
				if not isinstance(hash_values, dict):
					del base_names[name]
					continue
				cached_hashes.update(hash_values)

			# Create sets of valid package hashes and uncached packages.
			uncached_pkgs = set()
			hash_pkg = owners_cache._hash_pkg
			valid_pkg_hashes = set()
			for cpv in self._vardb.cpv_all():
				hash_value = hash_pkg(cpv)
				valid_pkg_hashes.add(hash_value)
				if hash_value not in cached_hashes:
					uncached_pkgs.add(cpv)

			# Cache any missing packages.
			for cpv in uncached_pkgs:
				owners_cache.add(cpv)

			# Delete any stale cache.
			stale_hashes = cached_hashes.difference(valid_pkg_hashes)
			if stale_hashes:
				for base_name_hash, bucket in list(base_names.items()):
					for hash_value in stale_hashes.intersection(bucket):
						del bucket[hash_value]
					if not bucket:
						del base_names[base_name_hash]

			return owners_cache

		def get_owners(self, path_iter):
			"""
			@return the owners as a dblink -> set(files) mapping.
			"""
			owners = {}
			for owner, f in self.iter_owners(path_iter):
				owned_files = owners.get(owner)
				if owned_files is None:
					owned_files = set()
					owners[owner] = owned_files
				owned_files.add(f)
			return owners

		def getFileOwnerMap(self, path_iter):
			owners = self.get_owners(path_iter)
			file_owners = {}
			for pkg_dblink, files in owners.items():
				for f in files:
					owner_set = file_owners.get(f)
					if owner_set is None:
						owner_set = set()
						file_owners[f] = owner_set
					owner_set.add(pkg_dblink)
			return file_owners

		def iter_owners(self, path_iter):
			"""
			Iterate over tuples of (dblink, path). In order to avoid
			consuming too many resources for too much time, resources
			are only allocated for the duration of a given iter_owners()
			call. Therefore, to maximize reuse of resources when searching
			for multiple files, it's best to search for them all in a single
			call.
			"""

			if not isinstance(path_iter, list):
				path_iter = list(path_iter)
			owners_cache = self._populate()
			vardb = self._vardb
			root = vardb._eroot
			hash_pkg = owners_cache._hash_pkg
			hash_str = owners_cache._hash_str
			base_names = self._vardb._aux_cache["owners"]["base_names"]

			dblink_cache = {}

			def dblink(cpv):
				x = dblink_cache.get(cpv)
				if x is None:
					if len(dblink_cache) > 20:
						# Ensure that we don't run out of memory.
						raise StopIteration()
					x = self._vardb._dblink(cpv)
					dblink_cache[cpv] = x
				return x

			while path_iter:

				path = path_iter.pop()
				is_basename = os.sep != path[:1]
				if is_basename:
					name = path
				else:
					name = os.path.basename(path.rstrip(os.path.sep))

				if not name:
					continue

				name_hash = hash_str(name)
				pkgs = base_names.get(name_hash)
				owners = []
				if pkgs is not None:
					try:
						for hash_value in pkgs:
							if not isinstance(hash_value, tuple) or \
								len(hash_value) != 3:
								continue
							cpv, counter, mtime = hash_value
							if not isinstance(cpv, basestring):
								continue
							try:
								current_hash = hash_pkg(cpv)
							except KeyError:
								continue

							if current_hash != hash_value:
								continue

							if is_basename:
								for p in dblink(cpv).getcontents():
									if os.path.basename(p) == name:
										owners.append((cpv, p[len(root):]))
							else:
								if dblink(cpv).isowner(path):
									owners.append((cpv, path))

					except StopIteration:
						path_iter.append(path)
						del owners[:]
						dblink_cache.clear()
						gc.collect()
						for x in self._iter_owners_low_mem(path_iter):
							yield x
						return
					else:
						for cpv, p in owners:
							yield (dblink(cpv), p)

		def _iter_owners_low_mem(self, path_list):
			"""
			This implemention will make a short-lived dblink instance (and
			parse CONTENTS) for every single installed package. This is
			slower and but uses less memory than the method which uses the
			basename cache.
			"""

			if not path_list:
				return

			path_info_list = []
			for path in path_list:
				is_basename = os.sep != path[:1]
				if is_basename:
					name = path
				else:
					name = os.path.basename(path.rstrip(os.path.sep))
				path_info_list.append((path, name, is_basename))

			# Do work via the global event loop, so that it can be used
			# for indication of progress during the search (bug #461412).
			event_loop = (portage._internal_caller and
				global_event_loop() or EventLoop(main=False))
			root = self._vardb._eroot

			def search_pkg(cpv):
				dblnk = self._vardb._dblink(cpv)
				for path, name, is_basename in path_info_list:
					if is_basename:
						for p in dblnk.getcontents():
							if os.path.basename(p) == name:
								search_pkg.results.append((dblnk, p[len(root):]))
					else:
						if dblnk.isowner(path):
							search_pkg.results.append((dblnk, path))
				search_pkg.complete = True
				return False

			search_pkg.results = []

			for cpv in self._vardb.cpv_all():
				del search_pkg.results[:]
				search_pkg.complete = False
				event_loop.idle_add(search_pkg, cpv)
				while not search_pkg.complete:
					event_loop.iteration()
				for result in search_pkg.results:
					yield result

class vartree(object):
	"this tree will scan a var/db/pkg database located at root (passed to init)"
	def __init__(self, root=None, virtual=DeprecationWarning, categories=None,
		settings=None):

		if settings is None:
			settings = portage.settings

		if root is not None and root != settings['ROOT']:
			warnings.warn("The 'root' parameter of the "
				"portage.dbapi.vartree.vartree"
				" constructor is now unused. Use "
				"settings['ROOT'] instead.",
				DeprecationWarning, stacklevel=2)

		if virtual is not DeprecationWarning:
			warnings.warn("The 'virtual' parameter of the "
				"portage.dbapi.vartree.vartree"
				" constructor is unused",
				DeprecationWarning, stacklevel=2)

		self.settings = settings
		self.dbapi = vardbapi(settings=settings, vartree=self)
		self.populated = 1

	@property
	def root(self):
		warnings.warn("The root attribute of "
			"portage.dbapi.vartree.vartree"
			" is deprecated. Use "
			"settings['ROOT'] instead.",
			DeprecationWarning, stacklevel=3)
		return self.settings['ROOT']

	def getpath(self, mykey, filename=None):
		return self.dbapi.getpath(mykey, filename=filename)

	def zap(self, mycpv):
		return

	def inject(self, mycpv):
		return

	def get_provide(self, mycpv):
		myprovides = []
		mylines = None
		try:
			mylines, myuse = self.dbapi.aux_get(mycpv, ["PROVIDE", "USE"])
			if mylines:
				myuse = myuse.split()
				mylines = use_reduce(mylines, uselist=myuse, flat=True)
				for myprovide in mylines:
					mys = catpkgsplit(myprovide)
					if not mys:
						mys = myprovide.split("/")
					myprovides += [mys[0] + "/" + mys[1]]
			return myprovides
		except SystemExit as e:
			raise
		except Exception as e:
			mydir = self.dbapi.getpath(mycpv)
			writemsg(_("\nParse Error reading PROVIDE and USE in '%s'\n") % mydir,
				noiselevel=-1)
			if mylines:
				writemsg(_("Possibly Invalid: '%s'\n") % str(mylines),
					noiselevel=-1)
			writemsg(_("Exception: %s\n\n") % str(e), noiselevel=-1)
			return []

	def get_all_provides(self):
		myprovides = {}
		for node in self.getallcpv():
			for mykey in self.get_provide(node):
				if mykey in myprovides:
					myprovides[mykey] += [node]
				else:
					myprovides[mykey] = [node]
		return myprovides

	def dep_bestmatch(self, mydep, use_cache=1):
		"compatibility method -- all matches, not just visible ones"
		#mymatch=best(match(dep_expand(mydep,self.dbapi),self.dbapi))
		mymatch = best(self.dbapi.match(
			dep_expand(mydep, mydb=self.dbapi, settings=self.settings),
			use_cache=use_cache))
		if mymatch is None:
			return ""
		else:
			return mymatch

	def dep_match(self, mydep, use_cache=1):
		"compatibility method -- we want to see all matches, not just visible ones"
		#mymatch = match(mydep,self.dbapi)
		mymatch = self.dbapi.match(mydep, use_cache=use_cache)
		if mymatch is None:
			return []
		else:
			return mymatch

	def exists_specific(self, cpv):
		return self.dbapi.cpv_exists(cpv)

	def getallcpv(self):
		"""temporary function, probably to be renamed --- Gets a list of all
		category/package-versions installed on the system."""
		return self.dbapi.cpv_all()

	def getallnodes(self):
		"""new behavior: these are all *unmasked* nodes.  There may or may not be available
		masked package for nodes in this nodes list."""
		return self.dbapi.cp_all()

	def getebuildpath(self, fullpackage):
		cat, package = catsplit(fullpackage)
		return self.getpath(fullpackage, filename=package+".ebuild")

	def getslot(self, mycatpkg):
		"Get a slot for a catpkg; assume it exists."
		try:
			return self.dbapi._pkg_str(mycatpkg, None).slot
		except KeyError:
			return ""

	def populate(self):
		self.populated=1

class dblink(object):
	"""
	This class provides an interface to the installed package database
	At present this is implemented as a text backend in /var/db/pkg.
	"""

	import re
	_normalize_needed = re.compile(r'//|^[^/]|./$|(^|/)\.\.?(/|$)')

	_contents_re = re.compile(r'^(' + \
		r'(?P<dir>(dev|dir|fif) (.+))|' + \
		r'(?P<obj>(obj) (.+) (\S+) (\d+))|' + \
		r'(?P<sym>(sym) (.+) -> (.+) ((\d+)|(?P<oldsym>(' + \
		r'\(\d+, \d+L, \d+L, \d+, \d+, \d+, \d+L, \d+, (\d+), \d+\)))))' + \
		r')$'
	)

	# These files are generated by emerge, so we need to remove
	# them when they are the only thing left in a directory.
	_infodir_cleanup = frozenset(["dir", "dir.old"])

	_ignored_unlink_errnos = (
		errno.EBUSY, errno.ENOENT,
		errno.ENOTDIR, errno.EISDIR)

	_ignored_rmdir_errnos = (
		errno.EEXIST, errno.ENOTEMPTY,
		errno.EBUSY, errno.ENOENT,
		errno.ENOTDIR, errno.EISDIR,
		errno.EPERM)

	def __init__(self, cat, pkg, myroot=None, settings=None, treetype=None,
		vartree=None, blockers=None, scheduler=None, pipe=None):
		"""
		Creates a DBlink object for a given CPV.
		The given CPV may not be present in the database already.

		@param cat: Category
		@type cat: String
		@param pkg: Package (PV)
		@type pkg: String
		@param myroot: ignored, settings['ROOT'] is used instead
		@type myroot: String (Path)
		@param settings: Typically portage.settings
		@type settings: portage.config
		@param treetype: one of ['porttree','bintree','vartree']
		@type treetype: String
		@param vartree: an instance of vartree corresponding to myroot.
		@type vartree: vartree
		"""

		if settings is None:
			raise TypeError("settings argument is required")

		mysettings = settings
		self._eroot = mysettings['EROOT']
		self.cat = cat
		self.pkg = pkg
		self.mycpv = self.cat + "/" + self.pkg
		if self.mycpv == settings.mycpv and \
			isinstance(settings.mycpv, _pkg_str):
			self.mycpv = settings.mycpv
		else:
			self.mycpv = _pkg_str(self.mycpv)
		self.mysplit = list(self.mycpv.cpv_split[1:])
		self.mysplit[0] = self.mycpv.cp
		self.treetype = treetype
		if vartree is None:
			vartree = portage.db[self._eroot]["vartree"]
		self.vartree = vartree
		self._blockers = blockers
		self._scheduler = scheduler
		self.dbroot = normalize_path(os.path.join(self._eroot, VDB_PATH))
		self.dbcatdir = self.dbroot+"/"+cat
		self.dbpkgdir = self.dbcatdir+"/"+pkg
		self.dbtmpdir = self.dbcatdir+"/"+MERGING_IDENTIFIER+pkg
		self.dbdir = self.dbpkgdir
		self.settings = mysettings
		self._verbose = self.settings.get("PORTAGE_VERBOSE") == "1"

		self.myroot = self.settings['ROOT']
		self._installed_instance = None
		self.contentscache = None
		self._contents_inodes = None
		self._contents_basenames = None
		self._linkmap_broken = False
		self._device_path_map = {}
		self._hardlink_merge_map = {}
		self._hash_key = (self._eroot, self.mycpv)
		self._protect_obj = None
		self._pipe = pipe

		# When necessary, this attribute is modified for
		# compliance with RESTRICT=preserve-libs.
		self._preserve_libs = "preserve-libs" in mysettings.features

	def __hash__(self):
		return hash(self._hash_key)

	def __eq__(self, other):
		return isinstance(other, dblink) and \
			self._hash_key == other._hash_key

	def _get_protect_obj(self):

		if self._protect_obj is None:
			self._protect_obj = ConfigProtect(self._eroot,
			portage.util.shlex_split(
				self.settings.get("CONFIG_PROTECT", "")),
			portage.util.shlex_split(
				self.settings.get("CONFIG_PROTECT_MASK", "")))

		return self._protect_obj

	def isprotected(self, obj):
		return self._get_protect_obj().isprotected(obj)

	def updateprotect(self):
		self._get_protect_obj().updateprotect()

	def lockdb(self):
		self.vartree.dbapi.lock()

	def unlockdb(self):
		self.vartree.dbapi.unlock()

	def getpath(self):
		"return path to location of db information (for >>> informational display)"
		return self.dbdir

	def exists(self):
		"does the db entry exist?  boolean."
		return os.path.exists(self.dbdir)

	def delete(self):
		"""
		Remove this entry from the database
		"""
		try:
			os.lstat(self.dbdir)
		except OSError as e:
			if e.errno not in (errno.ENOENT, errno.ENOTDIR, errno.ESTALE):
				raise
			return

		# Check validity of self.dbdir before attempting to remove it.
		if not self.dbdir.startswith(self.dbroot):
			writemsg(_("portage.dblink.delete(): invalid dbdir: %s\n") % \
				self.dbdir, noiselevel=-1)
			return

		shutil.rmtree(self.dbdir)
		# If empty, remove parent category directory.
		try:
			os.rmdir(os.path.dirname(self.dbdir))
		except OSError:
			pass
		self.vartree.dbapi._remove(self)

		# Use self.dbroot since we need an existing path for syncfs.
		try:
			self._merged_path(self.dbroot, os.lstat(self.dbroot))
		except OSError:
			pass

		self._post_merge_sync()

	def clearcontents(self):
		"""
		For a given db entry (self), erase the CONTENTS values.
		"""
		self.lockdb()
		try:
			if os.path.exists(self.dbdir+"/CONTENTS"):
				os.unlink(self.dbdir+"/CONTENTS")
		finally:
			self.unlockdb()

	def _clear_contents_cache(self):
		self.contentscache = None
		self._contents_inodes = None
		self._contents_basenames = None

	def getcontents(self):
		"""
		Get the installed files of a given package (aka what that package installed)
		"""
		contents_file = os.path.join(self.dbdir, "CONTENTS")
		if self.contentscache is not None:
			return self.contentscache
		pkgfiles = {}
		try:
			with io.open(_unicode_encode(contents_file,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace') as f:
				mylines = f.readlines()
		except EnvironmentError as e:
			if e.errno != errno.ENOENT:
				raise
			del e
			self.contentscache = pkgfiles
			return pkgfiles

		null_byte = "\0"
		normalize_needed = self._normalize_needed
		contents_re = self._contents_re
		obj_index = contents_re.groupindex['obj']
		dir_index = contents_re.groupindex['dir']
		sym_index = contents_re.groupindex['sym']
		# The old symlink format may exist on systems that have packages
		# which were installed many years ago (see bug #351814).
		oldsym_index = contents_re.groupindex['oldsym']
		# CONTENTS files already contain EPREFIX
		myroot = self.settings['ROOT']
		if myroot == os.path.sep:
			myroot = None
		# used to generate parent dir entries
		dir_entry = ("dir",)
		eroot_split_len = len(self.settings["EROOT"].split(os.sep)) - 1
		pos = 0
		errors = []
		for pos, line in enumerate(mylines):
			if null_byte in line:
				# Null bytes are a common indication of corruption.
				errors.append((pos + 1, _("Null byte found in CONTENTS entry")))
				continue
			line = line.rstrip("\n")
			m = contents_re.match(line)
			if m is None:
				errors.append((pos + 1, _("Unrecognized CONTENTS entry")))
				continue

			if m.group(obj_index) is not None:
				base = obj_index
				#format: type, mtime, md5sum
				data = (m.group(base+1), m.group(base+4), m.group(base+3))
			elif m.group(dir_index) is not None:
				base = dir_index
				#format: type
				data = (m.group(base+1),)
			elif m.group(sym_index) is not None:
				base = sym_index
				if m.group(oldsym_index) is None:
					mtime = m.group(base+5)
				else:
					mtime = m.group(base+8)
				#format: type, mtime, dest
				data = (m.group(base+1), mtime, m.group(base+3))
			else:
				# This won't happen as long the regular expression
				# is written to only match valid entries.
				raise AssertionError(_("required group not found " + \
					"in CONTENTS entry: '%s'") % line)

			path = m.group(base+2)
			if normalize_needed.search(path) is not None:
				path = normalize_path(path)
				if not path.startswith(os.path.sep):
					path = os.path.sep + path

			if myroot is not None:
				path = os.path.join(myroot, path.lstrip(os.path.sep))

			# Implicitly add parent directories, since we can't necessarily
			# assume that they are explicitly listed in CONTENTS, and it's
			# useful for callers if they can rely on parent directory entries
			# being generated here (crucial for things like dblink.isowner()).
			path_split = path.split(os.sep)
			path_split.pop()
			while len(path_split) > eroot_split_len:
				parent = os.sep.join(path_split)
				if parent in pkgfiles:
					break
				pkgfiles[parent] = dir_entry
				path_split.pop()

			pkgfiles[path] = data

		if errors:
			writemsg(_("!!! Parse error in '%s'\n") % contents_file, noiselevel=-1)
			for pos, e in errors:
				writemsg(_("!!!   line %d: %s\n") % (pos, e), noiselevel=-1)
		self.contentscache = pkgfiles
		return pkgfiles

	def _prune_plib_registry(self, unmerge=False,
		needed=None, preserve_paths=None):
		# remove preserved libraries that don't have any consumers left
		if not (self._linkmap_broken or
			self.vartree.dbapi._linkmap is None or
			self.vartree.dbapi._plib_registry is None):
			self.vartree.dbapi._fs_lock()
			plib_registry = self.vartree.dbapi._plib_registry
			plib_registry.lock()
			try:
				plib_registry.load()

				unmerge_with_replacement = \
					unmerge and preserve_paths is not None
				if unmerge_with_replacement:
					# If self.mycpv is about to be unmerged and we
					# have a replacement package, we want to exclude
					# the irrelevant NEEDED data that belongs to
					# files which are being unmerged now.
					exclude_pkgs = (self.mycpv,)
				else:
					exclude_pkgs = None

				self._linkmap_rebuild(exclude_pkgs=exclude_pkgs,
					include_file=needed, preserve_paths=preserve_paths)

				if unmerge:
					unmerge_preserve = None
					if not unmerge_with_replacement:
						unmerge_preserve = \
							self._find_libs_to_preserve(unmerge=True)
					counter = self.vartree.dbapi.cpv_counter(self.mycpv)
					try:
						slot = self.mycpv.slot
					except AttributeError:
						slot = _pkg_str(self.mycpv, slot=self.settings["SLOT"]).slot
					plib_registry.unregister(self.mycpv, slot, counter)
					if unmerge_preserve:
						for path in sorted(unmerge_preserve):
							contents_key = self._match_contents(path)
							if not contents_key:
								continue
							obj_type = self.getcontents()[contents_key][0]
							self._display_merge(_(">>> needed   %s %s\n") % \
								(obj_type, contents_key), noiselevel=-1)
						plib_registry.register(self.mycpv,
							slot, counter, unmerge_preserve)
						# Remove the preserved files from our contents
						# so that they won't be unmerged.
						self.vartree.dbapi.removeFromContents(self,
							unmerge_preserve)

				unmerge_no_replacement = \
					unmerge and not unmerge_with_replacement
				cpv_lib_map = self._find_unused_preserved_libs(
					unmerge_no_replacement)
				if cpv_lib_map:
					self._remove_preserved_libs(cpv_lib_map)
					self.vartree.dbapi.lock()
					try:
						for cpv, removed in cpv_lib_map.items():
							if not self.vartree.dbapi.cpv_exists(cpv):
								continue
							self.vartree.dbapi.removeFromContents(cpv, removed)
					finally:
						self.vartree.dbapi.unlock()

				plib_registry.store()
			finally:
				plib_registry.unlock()
				self.vartree.dbapi._fs_unlock()

	def unmerge(self, pkgfiles=None, trimworld=None, cleanup=True,
		ldpath_mtimes=None, others_in_slot=None, needed=None,
		preserve_paths=None):
		"""
		Calls prerm
		Unmerges a given package (CPV)
		calls postrm
		calls cleanrm
		calls env_update

		@param pkgfiles: files to unmerge (generally self.getcontents() )
		@type pkgfiles: Dictionary
		@param trimworld: Unused
		@type trimworld: Boolean
		@param cleanup: cleanup to pass to doebuild (see doebuild)
		@type cleanup: Boolean
		@param ldpath_mtimes: mtimes to pass to env_update (see env_update)
		@type ldpath_mtimes: Dictionary
		@param others_in_slot: all dblink instances in this slot, excluding self
		@type others_in_slot: list
		@param needed: Filename containing libraries needed after unmerge.
		@type needed: String
		@param preserve_paths: Libraries preserved by a package instance that
			is currently being merged. They need to be explicitly passed to the
			LinkageMap, since they are not registered in the
			PreservedLibsRegistry yet.
		@type preserve_paths: set
		@rtype: Integer
		@return:
		1. os.EX_OK if everything went well.
		2. return code of the failed phase (for prerm, postrm, cleanrm)
		"""

		if trimworld is not None:
			warnings.warn("The trimworld parameter of the " + \
				"portage.dbapi.vartree.dblink.unmerge()" + \
				" method is now unused.",
				DeprecationWarning, stacklevel=2)

		background = False
		log_path = self.settings.get("PORTAGE_LOG_FILE")
		if self._scheduler is None:
			# We create a scheduler instance and use it to
			# log unmerge output separately from merge output.
			self._scheduler = SchedulerInterface(portage._internal_caller and
				global_event_loop() or EventLoop(main=False))
		if self.settings.get("PORTAGE_BACKGROUND") == "subprocess":
			if self.settings.get("PORTAGE_BACKGROUND_UNMERGE") == "1":
				self.settings["PORTAGE_BACKGROUND"] = "1"
				self.settings.backup_changes("PORTAGE_BACKGROUND")
				background = True
			elif self.settings.get("PORTAGE_BACKGROUND_UNMERGE") == "0":
				self.settings["PORTAGE_BACKGROUND"] = "0"
				self.settings.backup_changes("PORTAGE_BACKGROUND")
		elif self.settings.get("PORTAGE_BACKGROUND") == "1":
			background = True

		self.vartree.dbapi._bump_mtime(self.mycpv)
		showMessage = self._display_merge
		if self.vartree.dbapi._categories is not None:
			self.vartree.dbapi._categories = None

		# When others_in_slot is not None, the backup has already been
		# handled by the caller.
		caller_handles_backup = others_in_slot is not None

		# When others_in_slot is supplied, the security check has already been
		# done for this slot, so it shouldn't be repeated until the next
		# replacement or unmerge operation.
		if others_in_slot is None:
			slot = self.vartree.dbapi._pkg_str(self.mycpv, None).slot
			slot_matches = self.vartree.dbapi.match(
				"%s:%s" % (portage.cpv_getkey(self.mycpv), slot))
			others_in_slot = []
			for cur_cpv in slot_matches:
				if cur_cpv == self.mycpv:
					continue
				others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1],
					settings=self.settings, vartree=self.vartree,
					treetype="vartree", pipe=self._pipe))

			retval = self._security_check([self] + others_in_slot)
			if retval:
				return retval

		contents = self.getcontents()
		# Now, don't assume that the name of the ebuild is the same as the
		# name of the dir; the package may have been moved.
		myebuildpath = os.path.join(self.dbdir, self.pkg + ".ebuild")
		failures = 0
		ebuild_phase = "prerm"
		mystuff = os.listdir(self.dbdir)
		for x in mystuff:
			if x.endswith(".ebuild"):
				if x[:-7] != self.pkg:
					# Clean up after vardbapi.move_ent() breakage in
					# portage versions before 2.1.2
					os.rename(os.path.join(self.dbdir, x), myebuildpath)
					write_atomic(os.path.join(self.dbdir, "PF"), self.pkg+"\n")
				break

		if self.mycpv != self.settings.mycpv or \
			"EAPI" not in self.settings.configdict["pkg"]:
			# We avoid a redundant setcpv call here when
			# the caller has already taken care of it.
			self.settings.setcpv(self.mycpv, mydb=self.vartree.dbapi)

		eapi_unsupported = False
		try:
			doebuild_environment(myebuildpath, "prerm",
				settings=self.settings, db=self.vartree.dbapi)
		except UnsupportedAPIException as e:
			eapi_unsupported = e

		if self._preserve_libs and "preserve-libs" in \
			self.settings["PORTAGE_RESTRICT"].split():
			self._preserve_libs = False

		builddir_lock = None
		scheduler = self._scheduler
		retval = os.EX_OK
		try:
			# Only create builddir_lock if the caller
			# has not already acquired the lock.
			if "PORTAGE_BUILDDIR_LOCKED" not in self.settings:
				builddir_lock = EbuildBuildDir(
					scheduler=scheduler,
					settings=self.settings)
				builddir_lock.lock()
				prepare_build_dirs(settings=self.settings, cleanup=True)
				log_path = self.settings.get("PORTAGE_LOG_FILE")

			# Do this before the following _prune_plib_registry call, since
			# that removes preserved libraries from our CONTENTS, and we
			# may want to backup those libraries first.
			if not caller_handles_backup:
				retval = self._pre_unmerge_backup(background)
				if retval != os.EX_OK:
					showMessage(_("!!! FAILED prerm: quickpkg: %s\n") % retval,
						level=logging.ERROR, noiselevel=-1)
					return retval

			self._prune_plib_registry(unmerge=True, needed=needed,
				preserve_paths=preserve_paths)

			# Log the error after PORTAGE_LOG_FILE is initialized
			# by prepare_build_dirs above.
			if eapi_unsupported:
				# Sometimes this happens due to corruption of the EAPI file.
				failures += 1
				showMessage(_("!!! FAILED prerm: %s\n") % \
					os.path.join(self.dbdir, "EAPI"),
					level=logging.ERROR, noiselevel=-1)
				showMessage("%s\n" % (eapi_unsupported,),
					level=logging.ERROR, noiselevel=-1)
			elif os.path.isfile(myebuildpath):
				phase = EbuildPhase(background=background,
					phase=ebuild_phase, scheduler=scheduler,
					settings=self.settings)
				phase.start()
				retval = phase.wait()

				# XXX: Decide how to handle failures here.
				if retval != os.EX_OK:
					failures += 1
					showMessage(_("!!! FAILED prerm: %s\n") % retval,
						level=logging.ERROR, noiselevel=-1)

			self.vartree.dbapi._fs_lock()
			try:
				self._unmerge_pkgfiles(pkgfiles, others_in_slot)
			finally:
				self.vartree.dbapi._fs_unlock()
			self._clear_contents_cache()

			if not eapi_unsupported and os.path.isfile(myebuildpath):
				ebuild_phase = "postrm"
				phase = EbuildPhase(background=background,
					phase=ebuild_phase, scheduler=scheduler,
					settings=self.settings)
				phase.start()
				retval = phase.wait()

				# XXX: Decide how to handle failures here.
				if retval != os.EX_OK:
					failures += 1
					showMessage(_("!!! FAILED postrm: %s\n") % retval,
						level=logging.ERROR, noiselevel=-1)

		finally:
			self.vartree.dbapi._bump_mtime(self.mycpv)
			try:
					if not eapi_unsupported and os.path.isfile(myebuildpath):
						if retval != os.EX_OK:
							msg_lines = []
							msg = _("The '%(ebuild_phase)s' "
							"phase of the '%(cpv)s' package "
							"has failed with exit value %(retval)s.") % \
							{"ebuild_phase":ebuild_phase, "cpv":self.mycpv,
							"retval":retval}
							from textwrap import wrap
							msg_lines.extend(wrap(msg, 72))
							msg_lines.append("")

							ebuild_name = os.path.basename(myebuildpath)
							ebuild_dir = os.path.dirname(myebuildpath)
							msg = _("The problem occurred while executing "
							"the ebuild file named '%(ebuild_name)s' "
							"located in the '%(ebuild_dir)s' directory. "
							"If necessary, manually remove "
							"the environment.bz2 file and/or the "
							"ebuild file located in that directory.") % \
							{"ebuild_name":ebuild_name, "ebuild_dir":ebuild_dir}
							msg_lines.extend(wrap(msg, 72))
							msg_lines.append("")

							msg = _("Removal "
							"of the environment.bz2 file is "
							"preferred since it may allow the "
							"removal phases to execute successfully. "
							"The ebuild will be "
							"sourced and the eclasses "
							"from the current portage tree will be used "
							"when necessary. Removal of "
							"the ebuild file will cause the "
							"pkg_prerm() and pkg_postrm() removal "
							"phases to be skipped entirely.")
							msg_lines.extend(wrap(msg, 72))

							self._eerror(ebuild_phase, msg_lines)

					self._elog_process(phasefilter=("prerm", "postrm"))

					if retval == os.EX_OK:
						try:
							doebuild_environment(myebuildpath, "cleanrm",
								settings=self.settings, db=self.vartree.dbapi)
						except UnsupportedAPIException:
							pass
						phase = EbuildPhase(background=background,
							phase="cleanrm", scheduler=scheduler,
							settings=self.settings)
						phase.start()
						retval = phase.wait()
			finally:
					if builddir_lock is not None:
						builddir_lock.unlock()

		if log_path is not None:

			if not failures and 'unmerge-logs' not in self.settings.features:
				try:
					os.unlink(log_path)
				except OSError:
					pass

			try:
				st = os.stat(log_path)
			except OSError:
				pass
			else:
				if st.st_size == 0:
					try:
						os.unlink(log_path)
					except OSError:
						pass

		if log_path is not None and os.path.exists(log_path):
			# Restore this since it gets lost somewhere above and it
			# needs to be set for _display_merge() to be able to log.
			# Note that the log isn't necessarily supposed to exist
			# since if PORT_LOGDIR is unset then it's a temp file
			# so it gets cleaned above.
			self.settings["PORTAGE_LOG_FILE"] = log_path
		else:
			self.settings.pop("PORTAGE_LOG_FILE", None)

		env_update(target_root=self.settings['ROOT'],
			prev_mtimes=ldpath_mtimes,
			contents=contents, env=self.settings,
			writemsg_level=self._display_merge, vardbapi=self.vartree.dbapi)

		unmerge_with_replacement = preserve_paths is not None
		if not unmerge_with_replacement:
			# When there's a replacement package which calls us via treewalk,
			# treewalk will automatically call _prune_plib_registry for us.
			# Otherwise, we need to call _prune_plib_registry ourselves.
			# Don't pass in the "unmerge=True" flag here, since that flag
			# is intended to be used _prior_ to unmerge, not after.
			self._prune_plib_registry()

		return os.EX_OK

	def _display_merge(self, msg, level=0, noiselevel=0):
		if not self._verbose and noiselevel >= 0 and level < logging.WARN:
			return
		if self._scheduler is None:
			writemsg_level(msg, level=level, noiselevel=noiselevel)
		else:
			log_path = None
			if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
				log_path = self.settings.get("PORTAGE_LOG_FILE")
			background = self.settings.get("PORTAGE_BACKGROUND") == "1"

			if background and log_path is None:
				if level >= logging.WARN:
					writemsg_level(msg, level=level, noiselevel=noiselevel)
			else:
				self._scheduler.output(msg,
					log_path=log_path, background=background,
					level=level, noiselevel=noiselevel)

	def _show_unmerge(self, zing, desc, file_type, file_name):
		self._display_merge("%s %s %s %s\n" % \
			(zing, desc.ljust(8), file_type, file_name))

	def _unmerge_pkgfiles(self, pkgfiles, others_in_slot):
		"""

		Unmerges the contents of a package from the liveFS
		Removes the VDB entry for self

		@param pkgfiles: typically self.getcontents()
		@type pkgfiles: Dictionary { filename: [ 'type', '?', 'md5sum' ] }
		@param others_in_slot: all dblink instances in this slot, excluding self
		@type others_in_slot: list
		@rtype: None
		"""

		os = _os_merge
		perf_md5 = perform_md5
		showMessage = self._display_merge
		show_unmerge = self._show_unmerge
		ignored_unlink_errnos = self._ignored_unlink_errnos
		ignored_rmdir_errnos = self._ignored_rmdir_errnos

		if not pkgfiles:
			showMessage(_("No package files given... Grabbing a set.\n"))
			pkgfiles = self.getcontents()

		if others_in_slot is None:
			others_in_slot = []
			slot = self.vartree.dbapi._pkg_str(self.mycpv, None).slot
			slot_matches = self.vartree.dbapi.match(
				"%s:%s" % (portage.cpv_getkey(self.mycpv), slot))
			for cur_cpv in slot_matches:
				if cur_cpv == self.mycpv:
					continue
				others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1],
					settings=self.settings,
					vartree=self.vartree, treetype="vartree", pipe=self._pipe))

		cfgfiledict = grabdict(self.vartree.dbapi._conf_mem_file)
		stale_confmem = []
		protected_symlinks = {}

		unmerge_orphans = "unmerge-orphans" in self.settings.features
		calc_prelink = "prelink-checksums" in self.settings.features

		if pkgfiles:
			self.updateprotect()
			mykeys = list(pkgfiles)
			mykeys.sort()
			mykeys.reverse()

			#process symlinks second-to-last, directories last.
			mydirs = set()

			uninstall_ignore = portage.util.shlex_split(
				self.settings.get("UNINSTALL_IGNORE", ""))

			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)
				except OSError as ose:
					# If the chmod or unlink fails, you are in trouble.
					# With Prefix this can be because the file is owned
					# by someone else (a screwup by root?), on a normal
					# system maybe filesystem corruption.  In any case,
					# if we backtrace and die here, we leave the system
					# in a totally undefined state, hence we just bleed
					# like hell and continue to hopefully finish all our
					# administrative and pkg_postinst stuff.
					self._eerror("postrm",
						["Could not chmod or unlink '%s': %s" % \
						(file_name, ose)])
				else:

					# Even though the file no longer exists, we log it
					# here so that _unmerge_dirs can see that we've
					# removed a file from this device, and will record
					# the parent directory for a syncfs call.
					self._merged_path(file_name, lstatobj, exists=False)

				finally:
					if bsd_chflags and pflags != 0:
						# Restore the parent flags we saved before unlinking
						bsd_chflags.chflags(parent_name, pflags)

			unmerge_desc = {}
			unmerge_desc["cfgpro"] = _("cfgpro")
			unmerge_desc["replaced"] = _("replaced")
			unmerge_desc["!dir"] = _("!dir")
			unmerge_desc["!empty"] = _("!empty")
			unmerge_desc["!fif"] = _("!fif")
			unmerge_desc["!found"] = _("!found")
			unmerge_desc["!md5"] = _("!md5")
			unmerge_desc["!mtime"] = _("!mtime")
			unmerge_desc["!obj"] = _("!obj")
			unmerge_desc["!sym"] = _("!sym")
			unmerge_desc["!prefix"] = _("!prefix")

			real_root = self.settings['ROOT']
			real_root_len = len(real_root) - 1
			eroot = self.settings["EROOT"]

			infodirs = frozenset(infodir for infodir in chain(
				self.settings.get("INFOPATH", "").split(":"),
				self.settings.get("INFODIR", "").split(":")) if infodir)
			infodirs_inodes = set()
			for infodir in infodirs:
				infodir = os.path.join(real_root, infodir.lstrip(os.sep))
				try:
					statobj = os.stat(infodir)
				except OSError:
					pass
				else:
					infodirs_inodes.add((statobj.st_dev, statobj.st_ino))

			for i, objkey in enumerate(mykeys):

				obj = normalize_path(objkey)
				if os is _os_merge:
					try:
						_unicode_encode(obj,
							encoding=_encodings['merge'], errors='strict')
					except UnicodeEncodeError:
						# The package appears to have been merged with a
						# different value of sys.getfilesystemencoding(),
						# so fall back to utf_8 if appropriate.
						try:
							_unicode_encode(obj,
								encoding=_encodings['fs'], errors='strict')
						except UnicodeEncodeError:
							pass
						else:
							os = portage.os
							perf_md5 = portage.checksum.perform_md5

				file_data = pkgfiles[objkey]
				file_type = file_data[0]

				# don't try to unmerge the prefix offset itself
				if len(obj) <= len(eroot) or not obj.startswith(eroot):
					show_unmerge("---", unmerge_desc["!prefix"], file_type, obj)
					continue

				statobj = None
				try:
					statobj = os.stat(obj)
				except OSError:
					pass
				lstatobj = None
				try:
					lstatobj = os.lstat(obj)
				except (OSError, AttributeError):
					pass
				islink = lstatobj is not None and stat.S_ISLNK(lstatobj.st_mode)
				if lstatobj is None:
						show_unmerge("---", unmerge_desc["!found"], file_type, obj)
						continue

				f_match = obj[len(eroot)-1:]
				ignore = False
				for pattern in uninstall_ignore:
					if fnmatch.fnmatch(f_match, pattern):
						ignore = True
						break

				if not ignore:
					if islink and f_match in \
						("/lib", "/usr/lib", "/usr/local/lib"):
						# Ignore libdir symlinks for bug #423127.
						ignore = True

				if ignore:
					show_unmerge("---", unmerge_desc["cfgpro"], file_type, obj)
					continue

				# don't use EROOT, CONTENTS entries already contain EPREFIX
				if obj.startswith(real_root):
					relative_path = obj[real_root_len:]
					is_owned = False
					for dblnk in others_in_slot:
						if dblnk.isowner(relative_path):
							is_owned = True
							break

					if is_owned and islink and \
						file_type in ("sym", "dir") and \
						statobj and stat.S_ISDIR(statobj.st_mode):
						# A new instance of this package claims the file, so
						# don't unmerge it. If the file is symlink to a
						# directory and the unmerging package installed it as
						# a symlink, but the new owner has it listed as a
						# directory, then we'll produce a warning since the
						# symlink is a sort of orphan in this case (see
						# bug #326685).
						symlink_orphan = False
						for dblnk in others_in_slot:
							parent_contents_key = \
								dblnk._match_contents(relative_path)
							if not parent_contents_key:
								continue
							if not parent_contents_key.startswith(
								real_root):
								continue
							if dblnk.getcontents()[
								parent_contents_key][0] == "dir":
								symlink_orphan = True
								break

						if symlink_orphan:
							protected_symlinks.setdefault(
								(statobj.st_dev, statobj.st_ino),
								[]).append(relative_path)

					if is_owned:
						show_unmerge("---", unmerge_desc["replaced"], file_type, obj)
						continue
					elif relative_path in cfgfiledict:
						stale_confmem.append(relative_path)

				# Don't unlink symlinks to directories here since that can
				# remove /lib and /usr/lib symlinks.
				if unmerge_orphans and \
					lstatobj and not stat.S_ISDIR(lstatobj.st_mode) and \
					not (islink and statobj and stat.S_ISDIR(statobj.st_mode)) and \
					not self.isprotected(obj):
					try:
						unlink(obj, lstatobj)
					except EnvironmentError as e:
						if e.errno not in ignored_unlink_errnos:
							raise
						del e
					show_unmerge("<<<", "", file_type, obj)
					continue

				lmtime = str(lstatobj[stat.ST_MTIME])
				if (pkgfiles[objkey][0] not in ("dir", "fif", "dev")) and (lmtime != pkgfiles[objkey][1]):
					show_unmerge("---", unmerge_desc["!mtime"], file_type, obj)
					continue

				if file_type == "dir" and not islink:
					if lstatobj is None or not stat.S_ISDIR(lstatobj.st_mode):
						show_unmerge("---", unmerge_desc["!dir"], file_type, obj)
						continue
					mydirs.add((obj, (lstatobj.st_dev, lstatobj.st_ino)))
				elif file_type == "sym" or (file_type == "dir" and islink):
					if not islink:
						show_unmerge("---", unmerge_desc["!sym"], file_type, obj)
						continue

					# If this symlink points to a directory then we don't want
					# to unmerge it if there are any other packages that
					# installed files into the directory via this symlink
					# (see bug #326685).
					# TODO: Resolving a symlink to a directory will require
					# simulation if $ROOT != / and the link is not relative.
					if islink and statobj and stat.S_ISDIR(statobj.st_mode) \
						and obj.startswith(real_root):

						relative_path = obj[real_root_len:]
						try:
							target_dir_contents = os.listdir(obj)
						except OSError:
							pass
						else:
							if target_dir_contents:
								# If all the children are regular files owned
								# by this package, then the symlink should be
								# safe to unmerge.
								all_owned = True
								for child in target_dir_contents:
									child = os.path.join(relative_path, child)
									if not self.isowner(child):
										all_owned = False
										break
									try:
										child_lstat = os.lstat(os.path.join(
											real_root, child.lstrip(os.sep)))
									except OSError:
										continue

									if not stat.S_ISREG(child_lstat.st_mode):
										# Nested symlinks or directories make
										# the issue very complex, so just
										# preserve the symlink in order to be
										# on the safe side.
										all_owned = False
										break

								if not all_owned:
									protected_symlinks.setdefault(
										(statobj.st_dev, statobj.st_ino),
										[]).append(relative_path)
									show_unmerge("---", unmerge_desc["!empty"],
										file_type, obj)
									continue

					# Go ahead and unlink symlinks to directories here when
					# they're actually recorded as symlinks in the contents.
					# Normally, symlinks such as /lib -> lib64 are not recorded
					# as symlinks in the contents of a package.  If a package
					# installs something into ${D}/lib/, it is recorded in the
					# contents as a directory even if it happens to correspond
					# to a symlink when it's merged to the live filesystem.
					try:
						unlink(obj, lstatobj)
						show_unmerge("<<<", "", file_type, obj)
					except (OSError, IOError) as e:
						if e.errno not in ignored_unlink_errnos:
							raise
						del e
						show_unmerge("!!!", "", file_type, obj)
				elif pkgfiles[objkey][0] == "obj":
					if statobj is None or not stat.S_ISREG(statobj.st_mode):
						show_unmerge("---", unmerge_desc["!obj"], file_type, obj)
						continue
					mymd5 = None
					try:
						mymd5 = perf_md5(obj, calc_prelink=calc_prelink)
					except FileNotFound as e:
						# the file has disappeared between now and our stat call
						show_unmerge("---", unmerge_desc["!obj"], file_type, obj)
						continue

					# string.lower is needed because db entries used to be in upper-case.  The
					# string.lower allows for backwards compatibility.
					if mymd5 != pkgfiles[objkey][2].lower():
						show_unmerge("---", unmerge_desc["!md5"], file_type, obj)
						continue
					try:
						unlink(obj, lstatobj)
					except (OSError, IOError) as e:
						if e.errno not in ignored_unlink_errnos:
							raise
						del e
					show_unmerge("<<<", "", file_type, obj)
				elif pkgfiles[objkey][0] == "fif":
					if not stat.S_ISFIFO(lstatobj[stat.ST_MODE]):
						show_unmerge("---", unmerge_desc["!fif"], file_type, obj)
						continue
					show_unmerge("---", "", file_type, obj)
				elif pkgfiles[objkey][0] == "dev":
					show_unmerge("---", "", file_type, obj)

			self._unmerge_dirs(mydirs, infodirs_inodes,
				protected_symlinks, unmerge_desc, unlink, os)
			mydirs.clear()

		if protected_symlinks:
			self._unmerge_protected_symlinks(others_in_slot, infodirs_inodes,
				protected_symlinks, unmerge_desc, unlink, os)

		if protected_symlinks:
			msg = "One or more symlinks to directories have been " + \
				"preserved in order to ensure that files installed " + \
				"via these symlinks remain accessible. " + \
				"This indicates that the mentioned symlink(s) may " + \
				"be obsolete remnants of an old install, and it " + \
				"may be appropriate to replace a given symlink " + \
				"with the directory that it points to."
			lines = textwrap.wrap(msg, 72)
			lines.append("")
			flat_list = set()
			flat_list.update(*protected_symlinks.values())
			flat_list = sorted(flat_list)
			for f in flat_list:
				lines.append("\t%s" % (os.path.join(real_root,
					f.lstrip(os.sep))))
			lines.append("")
			self._elog("elog", "postrm", lines)

		# Remove stale entries from config memory.
		if stale_confmem:
			for filename in stale_confmem:
				del cfgfiledict[filename]
			writedict(cfgfiledict, self.vartree.dbapi._conf_mem_file)

		#remove self from vartree database so that our own virtual gets zapped if we're the last node
		self.vartree.zap(self.mycpv)

	def _unmerge_protected_symlinks(self, others_in_slot, infodirs_inodes,
		protected_symlinks, unmerge_desc, unlink, os):

		real_root = self.settings['ROOT']
		show_unmerge = self._show_unmerge
		ignored_unlink_errnos = self._ignored_unlink_errnos

		flat_list = set()
		flat_list.update(*protected_symlinks.values())
		flat_list = sorted(flat_list)

		for f in flat_list:
			for dblnk in others_in_slot:
				if dblnk.isowner(f):
					# If another package in the same slot installed
					# a file via a protected symlink, return early
					# and don't bother searching for any other owners.
					return

		msg = []
		msg.append("")
		msg.append(_("Directory symlink(s) may need protection:"))
		msg.append("")

		for f in flat_list:
			msg.append("\t%s" % \
				os.path.join(real_root, f.lstrip(os.path.sep)))

		msg.append("")
		msg.append(_("Searching all installed"
			" packages for files installed via above symlink(s)..."))
		msg.append("")
		self._elog("elog", "postrm", msg)

		self.lockdb()
		try:
			owners = self.vartree.dbapi._owners.get_owners(flat_list)
			self.vartree.dbapi.flush_cache()
		finally:
			self.unlockdb()

		for owner in list(owners):
			if owner.mycpv == self.mycpv:
				owners.pop(owner, None)

		if not owners:
			msg = []
			msg.append(_("The above directory symlink(s) are all "
				"safe to remove. Removing them now..."))
			msg.append("")
			self._elog("elog", "postrm", msg)
			dirs = set()
			for unmerge_syms in protected_symlinks.values():
				for relative_path in unmerge_syms:
					obj = os.path.join(real_root,
						relative_path.lstrip(os.sep))
					parent = os.path.dirname(obj)
					while len(parent) > len(self._eroot):
						try:
							lstatobj = os.lstat(parent)
						except OSError:
							break
						else:
							dirs.add((parent,
								(lstatobj.st_dev, lstatobj.st_ino)))
							parent = os.path.dirname(parent)
					try:
						unlink(obj, os.lstat(obj))
						show_unmerge("<<<", "", "sym", obj)
					except (OSError, IOError) as e:
						if e.errno not in ignored_unlink_errnos:
							raise
						del e
						show_unmerge("!!!", "", "sym", obj)

			protected_symlinks.clear()
			self._unmerge_dirs(dirs, infodirs_inodes,
				protected_symlinks, unmerge_desc, unlink, os)
			dirs.clear()

	def _unmerge_dirs(self, dirs, infodirs_inodes,
		protected_symlinks, unmerge_desc, unlink, os):

		show_unmerge = self._show_unmerge
		infodir_cleanup = self._infodir_cleanup
		ignored_unlink_errnos = self._ignored_unlink_errnos
		ignored_rmdir_errnos = self._ignored_rmdir_errnos
		real_root = self.settings['ROOT']

		dirs = sorted(dirs)
		dirs.reverse()

		for obj, inode_key in dirs:
			# Treat any directory named "info" as a candidate here,
			# since it might have been in INFOPATH previously even
			# though it may not be there now.
			if inode_key in infodirs_inodes or \
				os.path.basename(obj) == "info":
				try:
					remaining = os.listdir(obj)
				except OSError:
					pass
				else:
					cleanup_info_dir = ()
					if remaining and \
						len(remaining) <= len(infodir_cleanup):
						if not set(remaining).difference(infodir_cleanup):
							cleanup_info_dir = remaining

					for child in cleanup_info_dir:
						child = os.path.join(obj, child)
						try:
							lstatobj = os.lstat(child)
							if stat.S_ISREG(lstatobj.st_mode):
								unlink(child, lstatobj)
								show_unmerge("<<<", "", "obj", child)
						except EnvironmentError as e:
							if e.errno not in ignored_unlink_errnos:
								raise
							del e
							show_unmerge("!!!", "", "obj", child)

			try:
				parent_name = os.path.dirname(obj)
				parent_stat = os.stat(parent_name)

				if bsd_chflags:
					lstatobj = os.lstat(obj)
					if lstatobj.st_flags != 0:
						bsd_chflags.lchflags(obj, 0)

					# Use normal stat/chflags for the parent since we want to
					# follow any symlinks to the real parent directory.
					pflags = parent_stat.st_flags
					if pflags != 0:
						bsd_chflags.chflags(parent_name, 0)
				try:
					os.rmdir(obj)
				finally:
					if bsd_chflags and pflags != 0:
						# Restore the parent flags we saved before unlinking
						bsd_chflags.chflags(parent_name, pflags)

				# Record the parent directory for use in syncfs calls.
				# Note that we use a realpath and a regular stat here, since
				# we want to follow any symlinks back to the real device where
				# the real parent directory resides.
				self._merged_path(os.path.realpath(parent_name), parent_stat)

				show_unmerge("<<<", "", "dir", obj)
			except EnvironmentError as e:
				if e.errno not in ignored_rmdir_errnos:
					raise
				if e.errno != errno.ENOENT:
					show_unmerge("---", unmerge_desc["!empty"], "dir", obj)

				# Since we didn't remove this directory, record the directory
				# itself for use in syncfs calls, if we have removed another
				# file from the same device.
				# Note that we use a realpath and a regular stat here, since
				# we want to follow any symlinks back to the real device where
				# the real directory resides.
				try:
					dir_stat = os.stat(obj)
				except OSError:
					pass
				else:
					if dir_stat.st_dev in self._device_path_map:
						self._merged_path(os.path.realpath(obj), dir_stat)

			else:
				# When a directory is successfully removed, there's
				# no need to protect symlinks that point to it.
				unmerge_syms = protected_symlinks.pop(inode_key, None)
				if unmerge_syms is not None:
					for relative_path in unmerge_syms:
						obj = os.path.join(real_root,
							relative_path.lstrip(os.sep))
						try:
							unlink(obj, os.lstat(obj))
							show_unmerge("<<<", "", "sym", obj)
						except (OSError, IOError) as e:
							if e.errno not in ignored_unlink_errnos:
								raise
							del e
							show_unmerge("!!!", "", "sym", obj)

	def isowner(self, filename, destroot=None):
		"""
		Check if a file belongs to this package. This may
		result in a stat call for the parent directory of
		every installed file, since the inode numbers are
		used to work around the problem of ambiguous paths
		caused by symlinked directories. The results of
		stat calls are cached to optimize multiple calls
		to this method.

		@param filename:
		@type filename:
		@param destroot:
		@type destroot:
		@rtype: Boolean
		@return:
		1. True if this package owns the file.
		2. False if this package does not own the file.
		"""

		if destroot is not None and destroot != self._eroot:
			warnings.warn("The second parameter of the " + \
				"portage.dbapi.vartree.dblink.isowner()" + \
				" is now unused. Instead " + \
				"self.settings['EROOT'] will be used.",
				DeprecationWarning, stacklevel=2)

		return bool(self._match_contents(filename))

	def _match_contents(self, filename, destroot=None):
		"""
		The matching contents entry is returned, which is useful
		since the path may differ from the one given by the caller,
		due to symlinks.

		@rtype: String
		@return: the contents entry corresponding to the given path, or False
			if the file is not owned by this package.
		"""

		filename = _unicode_decode(filename,
			encoding=_encodings['content'], errors='strict')

		if destroot is not None and destroot != self._eroot:
			warnings.warn("The second parameter of the " + \
				"portage.dbapi.vartree.dblink._match_contents()" + \
				" is now unused. Instead " + \
				"self.settings['ROOT'] will be used.",
				DeprecationWarning, stacklevel=2)

		# don't use EROOT here, image already contains EPREFIX
		destroot = self.settings['ROOT']

		# The given filename argument might have a different encoding than the
		# the filenames contained in the contents, so use separate wrapped os
		# modules for each. The basename is more likely to contain non-ascii
		# characters than the directory path, so use os_filename_arg for all
		# operations involving the basename of the filename arg.
		os_filename_arg = _os_merge
		os = _os_merge

		try:
			_unicode_encode(filename,
				encoding=_encodings['merge'], errors='strict')
		except UnicodeEncodeError:
			# The package appears to have been merged with a
			# different value of sys.getfilesystemencoding(),
			# so fall back to utf_8 if appropriate.
			try:
				_unicode_encode(filename,
					encoding=_encodings['fs'], errors='strict')
			except UnicodeEncodeError:
				pass
			else:
				os_filename_arg = portage.os

		destfile = normalize_path(
			os_filename_arg.path.join(destroot,
			filename.lstrip(os_filename_arg.path.sep)))

		pkgfiles = self.getcontents()
		if pkgfiles and destfile in pkgfiles:
			return destfile
		if pkgfiles:
			basename = os_filename_arg.path.basename(destfile)
			if self._contents_basenames is None:

				try:
					for x in pkgfiles:
						_unicode_encode(x,
							encoding=_encodings['merge'],
							errors='strict')
				except UnicodeEncodeError:
					# The package appears to have been merged with a
					# different value of sys.getfilesystemencoding(),
					# so fall back to utf_8 if appropriate.
					try:
						for x in pkgfiles:
							_unicode_encode(x,
								encoding=_encodings['fs'],
								errors='strict')
					except UnicodeEncodeError:
						pass
					else:
						os = portage.os

				self._contents_basenames = set(
					os.path.basename(x) for x in pkgfiles)
			if basename not in self._contents_basenames:
				# This is a shortcut that, in most cases, allows us to
				# eliminate this package as an owner without the need
				# to examine inode numbers of parent directories.
				return False

			# Use stat rather than lstat since we want to follow
			# any symlinks to the real parent directory.
			parent_path = os_filename_arg.path.dirname(destfile)
			try:
				parent_stat = os_filename_arg.stat(parent_path)
			except EnvironmentError as e:
				if e.errno != errno.ENOENT:
					raise
				del e
				return False
			if self._contents_inodes is None:

				if os is _os_merge:
					try:
						for x in pkgfiles:
							_unicode_encode(x,
								encoding=_encodings['merge'],
								errors='strict')
					except UnicodeEncodeError:
						# The package appears to have been merged with a
						# different value of sys.getfilesystemencoding(),
						# so fall back to utf_8 if appropriate.
						try:
							for x in pkgfiles:
								_unicode_encode(x,
									encoding=_encodings['fs'],
									errors='strict')
						except UnicodeEncodeError:
							pass
						else:
							os = portage.os

				self._contents_inodes = {}
				parent_paths = set()
				for x in pkgfiles:
					p_path = os.path.dirname(x)
					if p_path in parent_paths:
						continue
					parent_paths.add(p_path)
					try:
						s = os.stat(p_path)
					except OSError:
						pass
					else:
						inode_key = (s.st_dev, s.st_ino)
						# Use lists of paths in case multiple
						# paths reference the same inode.
						p_path_list = self._contents_inodes.get(inode_key)
						if p_path_list is None:
							p_path_list = []
							self._contents_inodes[inode_key] = p_path_list
						if p_path not in p_path_list:
							p_path_list.append(p_path)

			p_path_list = self._contents_inodes.get(
				(parent_stat.st_dev, parent_stat.st_ino))
			if p_path_list:
				for p_path in p_path_list:
					x = os_filename_arg.path.join(p_path, basename)
					if x in pkgfiles:
						return x

		return False

	def _linkmap_rebuild(self, **kwargs):
		"""
		Rebuild the self._linkmap if it's not broken due to missing
		scanelf binary. Also, return early if preserve-libs is disabled
		and the preserve-libs registry is empty.
		"""
		if self._linkmap_broken or \
			self.vartree.dbapi._linkmap is None or \
			self.vartree.dbapi._plib_registry is None or \
			("preserve-libs" not in self.settings.features and \
			not self.vartree.dbapi._plib_registry.hasEntries()):
			return
		try:
			self.vartree.dbapi._linkmap.rebuild(**kwargs)
		except CommandNotFound as e:
			self._linkmap_broken = True
			self._display_merge(_("!!! Disabling preserve-libs " \
				"due to error: Command Not Found: %s\n") % (e,),
				level=logging.ERROR, noiselevel=-1)

	def _find_libs_to_preserve(self, unmerge=False):
		"""
		Get set of relative paths for libraries to be preserved. When
		unmerge is False, file paths to preserve are selected from
		self._installed_instance. Otherwise, paths are selected from
		self.
		"""
		if self._linkmap_broken or \
			self.vartree.dbapi._linkmap is None or \
			self.vartree.dbapi._plib_registry is None or \
			(not unmerge and self._installed_instance is None) or \
			not self._preserve_libs:
			return set()

		os = _os_merge
		linkmap = self.vartree.dbapi._linkmap
		if unmerge:
			installed_instance = self
		else:
			installed_instance = self._installed_instance
		old_contents = installed_instance.getcontents()
		root = self.settings['ROOT']
		root_len = len(root) - 1
		lib_graph = digraph()
		path_node_map = {}

		def path_to_node(path):
			node = path_node_map.get(path)
			if node is None:
				node = LinkageMap._LibGraphNode(linkmap._obj_key(path))
				alt_path_node = lib_graph.get(node)
				if alt_path_node is not None:
					node = alt_path_node
				node.alt_paths.add(path)
				path_node_map[path] = node
			return node

		consumer_map = {}
		provider_nodes = set()
		# Create provider nodes and add them to the graph.
		for f_abs in old_contents:

			if os is _os_merge:
				try:
					_unicode_encode(f_abs,
						encoding=_encodings['merge'], errors='strict')
				except UnicodeEncodeError:
					# The package appears to have been merged with a
					# different value of sys.getfilesystemencoding(),
					# so fall back to utf_8 if appropriate.
					try:
						_unicode_encode(f_abs,
							encoding=_encodings['fs'], errors='strict')
					except UnicodeEncodeError:
						pass
					else:
						os = portage.os

			f = f_abs[root_len:]
			if not unmerge and self.isowner(f):
				# We have an indentically named replacement file,
				# so we don't try to preserve the old copy.
				continue
			try:
				consumers = linkmap.findConsumers(f,
					exclude_providers=(installed_instance.isowner,))
			except KeyError:
				continue
			if not consumers:
				continue
			provider_node = path_to_node(f)
			lib_graph.add(provider_node, None)
			provider_nodes.add(provider_node)
			consumer_map[provider_node] = consumers

		# Create consumer nodes and add them to the graph.
		# Note that consumers can also be providers.
		for provider_node, consumers in consumer_map.items():
			for c in consumers:
				consumer_node = path_to_node(c)
				if installed_instance.isowner(c) and \
					consumer_node not in provider_nodes:
					# This is not a provider, so it will be uninstalled.
					continue
				lib_graph.add(provider_node, consumer_node)

		# Locate nodes which should be preserved. They consist of all
		# providers that are reachable from consumers that are not
		# providers themselves.
		preserve_nodes = set()
		for consumer_node in lib_graph.root_nodes():
			if consumer_node in provider_nodes:
				continue
			# Preserve all providers that are reachable from this consumer.
			node_stack = lib_graph.child_nodes(consumer_node)
			while node_stack:
				provider_node = node_stack.pop()
				if provider_node in preserve_nodes:
					continue
				preserve_nodes.add(provider_node)
				node_stack.extend(lib_graph.child_nodes(provider_node))

		preserve_paths = set()
		for preserve_node in preserve_nodes:
			# Preserve the library itself, and also preserve the
			# soname symlink which is the only symlink that is
			# strictly required.
			hardlinks = set()
			soname_symlinks = set()
			soname = linkmap.getSoname(next(iter(preserve_node.alt_paths)))
			for f in preserve_node.alt_paths:
				f_abs = os.path.join(root, f.lstrip(os.sep))
				try:
					if stat.S_ISREG(os.lstat(f_abs).st_mode):
						hardlinks.add(f)
					elif os.path.basename(f) == soname:
						soname_symlinks.add(f)
				except OSError:
					pass

			if hardlinks:
				preserve_paths.update(hardlinks)
				preserve_paths.update(soname_symlinks)

		return preserve_paths

	def _add_preserve_libs_to_contents(self, preserve_paths):
		"""
		Preserve libs returned from _find_libs_to_preserve().
		"""

		if not preserve_paths:
			return

		os = _os_merge
		showMessage = self._display_merge
		root = self.settings['ROOT']

		# Copy contents entries from the old package to the new one.
		new_contents = self.getcontents().copy()
		old_contents = self._installed_instance.getcontents()
		for f in sorted(preserve_paths):
			f = _unicode_decode(f,
				encoding=_encodings['content'], errors='strict')
			f_abs = os.path.join(root, f.lstrip(os.sep))
			contents_entry = old_contents.get(f_abs)
			if contents_entry is None:
				# This will probably never happen, but it might if one of the
				# paths returned from findConsumers() refers to one of the libs
				# that should be preserved yet the path is not listed in the
				# contents. Such a path might belong to some other package, so
				# it shouldn't be preserved here.
				showMessage(_("!!! File '%s' will not be preserved "
					"due to missing contents entry\n") % (f_abs,),
					level=logging.ERROR, noiselevel=-1)
				preserve_paths.remove(f)
				continue
			new_contents[f_abs] = contents_entry
			obj_type = contents_entry[0]
			showMessage(_(">>> needed    %s %s\n") % (obj_type, f_abs),
				noiselevel=-1)
			# Add parent directories to contents if necessary.
			parent_dir = os.path.dirname(f_abs)
			while len(parent_dir) > len(root):
				new_contents[parent_dir] = ["dir"]
				prev = parent_dir
				parent_dir = os.path.dirname(parent_dir)
				if prev == parent_dir:
					break
		outfile = atomic_ofstream(os.path.join(self.dbtmpdir, "CONTENTS"))
		write_contents(new_contents, root, outfile)
		outfile.close()
		self._clear_contents_cache()

	def _find_unused_preserved_libs(self, unmerge_no_replacement):
		"""
		Find preserved libraries that don't have any consumers left.
		"""

		if self._linkmap_broken or \
			self.vartree.dbapi._linkmap is None or \
			self.vartree.dbapi._plib_registry is None or \
			not self.vartree.dbapi._plib_registry.hasEntries():
			return {}

		# Since preserved libraries can be consumers of other preserved
		# libraries, use a graph to track consumer relationships.
		plib_dict = self.vartree.dbapi._plib_registry.getPreservedLibs()
		linkmap = self.vartree.dbapi._linkmap
		lib_graph = digraph()
		preserved_nodes = set()
		preserved_paths = set()
		path_cpv_map = {}
		path_node_map = {}
		root = self.settings['ROOT']

		def path_to_node(path):
			node = path_node_map.get(path)
			if node is None:
				node = LinkageMap._LibGraphNode(linkmap._obj_key(path))
				alt_path_node = lib_graph.get(node)
				if alt_path_node is not None:
					node = alt_path_node
				node.alt_paths.add(path)
				path_node_map[path] = node
			return node

		for cpv, plibs in plib_dict.items():
			for f in plibs:
				path_cpv_map[f] = cpv
				preserved_node = path_to_node(f)
				if not preserved_node.file_exists():
					continue
				lib_graph.add(preserved_node, None)
				preserved_paths.add(f)
				preserved_nodes.add(preserved_node)
				for c in self.vartree.dbapi._linkmap.findConsumers(f):
					consumer_node = path_to_node(c)
					if not consumer_node.file_exists():
						continue
					# Note that consumers may also be providers.
					lib_graph.add(preserved_node, consumer_node)

		# Eliminate consumers having providers with the same soname as an
		# installed library that is not preserved. This eliminates
		# libraries that are erroneously preserved due to a move from one
		# directory to another.
		# Also eliminate consumers that are going to be unmerged if
		# unmerge_no_replacement is True.
		provider_cache = {}
		for preserved_node in preserved_nodes:
			soname = linkmap.getSoname(preserved_node)
			for consumer_node in lib_graph.parent_nodes(preserved_node):
				if consumer_node in preserved_nodes:
					continue
				if unmerge_no_replacement:
					will_be_unmerged = True
					for path in consumer_node.alt_paths:
						if not self.isowner(path):
							will_be_unmerged = False
							break
					if will_be_unmerged:
						# This consumer is not preserved and it is
						# being unmerged, so drop this edge.
						lib_graph.remove_edge(preserved_node, consumer_node)
						continue

				providers = provider_cache.get(consumer_node)
				if providers is None:
					providers = linkmap.findProviders(consumer_node)
					provider_cache[consumer_node] = providers
				providers = providers.get(soname)
				if providers is None:
					continue
				for provider in providers:
					if provider in preserved_paths:
						continue
					provider_node = path_to_node(provider)
					if not provider_node.file_exists():
						continue
					if provider_node in preserved_nodes:
						continue
					# An alternative provider seems to be
					# installed, so drop this edge.
					lib_graph.remove_edge(preserved_node, consumer_node)
					break

		cpv_lib_map = {}
		while lib_graph:
			root_nodes = preserved_nodes.intersection(lib_graph.root_nodes())
			if not root_nodes:
				break
			lib_graph.difference_update(root_nodes)
			unlink_list = set()
			for node in root_nodes:
				unlink_list.update(node.alt_paths)
			unlink_list = sorted(unlink_list)
			for obj in unlink_list:
				cpv = path_cpv_map.get(obj)
				if cpv is None:
					# This means that a symlink is in the preserved libs
					# registry, but the actual lib it points to is not.
					self._display_merge(_("!!! symlink to lib is preserved, "
						"but not the lib itself:\n!!! '%s'\n") % (obj,),
						level=logging.ERROR, noiselevel=-1)
					continue
				removed = cpv_lib_map.get(cpv)
				if removed is None:
					removed = set()
					cpv_lib_map[cpv] = removed
				removed.add(obj)

		return cpv_lib_map

	def _remove_preserved_libs(self, cpv_lib_map):
		"""
		Remove files returned from _find_unused_preserved_libs().
		"""

		os = _os_merge

		files_to_remove = set()
		for files in cpv_lib_map.values():
			files_to_remove.update(files)
		files_to_remove = sorted(files_to_remove)
		showMessage = self._display_merge
		root = self.settings['ROOT']

		parent_dirs = set()
		for obj in files_to_remove:
			obj = os.path.join(root, obj.lstrip(os.sep))
			parent_dirs.add(os.path.dirname(obj))
			if os.path.islink(obj):
				obj_type = _("sym")
			else:
				obj_type = _("obj")
			try:
				os.unlink(obj)
			except OSError as e:
				if e.errno != errno.ENOENT:
					raise
				del e
			else:
				showMessage(_("<<< !needed  %s %s\n") % (obj_type, obj),
					noiselevel=-1)

		# Remove empty parent directories if possible.
		while parent_dirs:
			x = parent_dirs.pop()
			while True:
				try:
					os.rmdir(x)
				except OSError:
					break
				prev = x
				x = os.path.dirname(x)
				if x == prev:
					break

		self.vartree.dbapi._plib_registry.pruneNonExisting()

	def _collision_protect(self, srcroot, destroot, mypkglist,
		file_list, symlink_list):

			os = _os_merge

			collision_ignore = []
			for x in portage.util.shlex_split(
				self.settings.get("COLLISION_IGNORE", "")):
				if os.path.isdir(os.path.join(self._eroot, x.lstrip(os.sep))):
					x = normalize_path(x)
					x += "/*"
				collision_ignore.append(x)

			# For collisions with preserved libraries, the current package
			# will assume ownership and the libraries will be unregistered.
			if self.vartree.dbapi._plib_registry is None:
				# preserve-libs is entirely disabled
				plib_cpv_map = None
				plib_paths = None
				plib_inodes = {}
			else:
				plib_dict = self.vartree.dbapi._plib_registry.getPreservedLibs()
				plib_cpv_map = {}
				plib_paths = set()
				for cpv, paths in plib_dict.items():
					plib_paths.update(paths)
					for f in paths:
						plib_cpv_map[f] = cpv
				plib_inodes = self._lstat_inode_map(plib_paths)

			plib_collisions = {}

			showMessage = self._display_merge
			stopmerge = False
			collisions = []
			symlink_collisions = []
			destroot = self.settings['ROOT']
			showMessage(_(" %s checking %d files for package collisions\n") % \
				(colorize("GOOD", "*"), len(file_list) + len(symlink_list)))
			for i, (f, f_type) in enumerate(chain(
				((f, "reg") for f in file_list),
				((f, "sym") for f in symlink_list))):
				if i % 1000 == 0 and i != 0:
					showMessage(_("%d files checked ...\n") % i)

				dest_path = normalize_path(
					os.path.join(destroot, f.lstrip(os.path.sep)))
				try:
					dest_lstat = os.lstat(dest_path)
				except EnvironmentError as e:
					if e.errno == errno.ENOENT:
						del e
						continue
					elif e.errno == errno.ENOTDIR:
						del e
						# A non-directory is in a location where this package
						# expects to have a directory.
						dest_lstat = None
						parent_path = dest_path
						while len(parent_path) > len(destroot):
							parent_path = os.path.dirname(parent_path)
							try:
								dest_lstat = os.lstat(parent_path)
								break
							except EnvironmentError as e:
								if e.errno != errno.ENOTDIR:
									raise
								del e
						if not dest_lstat:
							raise AssertionError(
								"unable to find non-directory " + \
								"parent for '%s'" % dest_path)
						dest_path = parent_path
						f = os.path.sep + dest_path[len(destroot):]
						if f in collisions:
							continue
					else:
						raise
				if f[0] != "/":
					f="/"+f

				if stat.S_ISDIR(dest_lstat.st_mode):
					if f_type == "sym":
						# This case is explicitly banned
						# by PMS (see bug #326685).
						symlink_collisions.append(f)
						collisions.append(f)
						continue

				plibs = plib_inodes.get((dest_lstat.st_dev, dest_lstat.st_ino))
				if plibs:
					for path in plibs:
						cpv = plib_cpv_map[path]
						paths = plib_collisions.get(cpv)
						if paths is None:
							paths = set()
							plib_collisions[cpv] = paths
						paths.add(path)
					# The current package will assume ownership and the
					# libraries will be unregistered, so exclude this
					# path from the normal collisions.
					continue

				isowned = False
				full_path = os.path.join(destroot, f.lstrip(os.path.sep))
				for ver in mypkglist:
					if ver.isowner(f):
						isowned = True
						break
				if not isowned and self.isprotected(full_path):
					isowned = True
				if not isowned:
					f_match = full_path[len(self._eroot)-1:]
					stopmerge = True
					for pattern in collision_ignore:
						if fnmatch.fnmatch(f_match, pattern):
							stopmerge = False
							break
					if stopmerge:
						collisions.append(f)
			return collisions, symlink_collisions, plib_collisions

	def _lstat_inode_map(self, path_iter):
		"""
		Use lstat to create a map of the form:
		  {(st_dev, st_ino) : set([path1, path2, ...])}
		Multiple paths may reference the same inode due to hardlinks.
		All lstat() calls are relative to self.myroot.
		"""

		os = _os_merge

		root = self.settings['ROOT']
		inode_map = {}
		for f in path_iter:
			path = os.path.join(root, f.lstrip(os.sep))
			try:
				st = os.lstat(path)
			except OSError as e:
				if e.errno not in (errno.ENOENT, errno.ENOTDIR):
					raise
				del e
				continue
			key = (st.st_dev, st.st_ino)
			paths = inode_map.get(key)
			if paths is None:
				paths = set()
				inode_map[key] = paths
			paths.add(f)
		return inode_map

	def _security_check(self, installed_instances):
		if not installed_instances:
			return 0

		os = _os_merge

		showMessage = self._display_merge

		file_paths = set()
		for dblnk in installed_instances:
			file_paths.update(dblnk.getcontents())
		inode_map = {}
		real_paths = set()
		for i, path in enumerate(file_paths):

			if os is _os_merge:
				try:
					_unicode_encode(path,
						encoding=_encodings['merge'], errors='strict')
				except UnicodeEncodeError:
					# The package appears to have been merged with a
					# different value of sys.getfilesystemencoding(),
					# so fall back to utf_8 if appropriate.
					try:
						_unicode_encode(path,
							encoding=_encodings['fs'], errors='strict')
					except UnicodeEncodeError:
						pass
					else:
						os = portage.os

			try:
				s = os.lstat(path)
			except OSError as e:
				if e.errno not in (errno.ENOENT, errno.ENOTDIR):
					raise
				del e
				continue
			if not stat.S_ISREG(s.st_mode):
				continue
			path = os.path.realpath(path)
			if path in real_paths:
				continue
			real_paths.add(path)
			if s.st_nlink > 1 and \
				s.st_mode & (stat.S_ISUID | stat.S_ISGID):
				k = (s.st_dev, s.st_ino)
				inode_map.setdefault(k, []).append((path, s))
		suspicious_hardlinks = []
		for path_list in inode_map.values():
			path, s = path_list[0]
			if len(path_list) == s.st_nlink:
				# All hardlinks seem to be owned by this package.
				continue
			suspicious_hardlinks.append(path_list)
		if not suspicious_hardlinks:
			return 0

		msg = []
		msg.append(_("suid/sgid file(s) "
			"with suspicious hardlink(s):"))
		msg.append("")
		for path_list in suspicious_hardlinks:
			for path, s in path_list:
				msg.append("\t%s" % path)
		msg.append("")
		msg.append(_("See the Gentoo Security Handbook "
			"guide for advice on how to proceed."))

		self._eerror("preinst", msg)

		return 1

	def _eqawarn(self, phase, lines):
		self._elog("eqawarn", phase, lines)

	def _eerror(self, phase, lines):
		self._elog("eerror", phase, lines)

	def _elog(self, funcname, phase, lines):
		func = getattr(portage.elog.messages, funcname)
		if self._scheduler is None:
			for l in lines:
				func(l, phase=phase, key=self.mycpv)
		else:
			background = self.settings.get("PORTAGE_BACKGROUND") == "1"
			log_path = None
			if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
				log_path = self.settings.get("PORTAGE_LOG_FILE")
			out = io.StringIO()
			for line in lines:
				func(line, phase=phase, key=self.mycpv, out=out)
			msg = out.getvalue()
			self._scheduler.output(msg,
				background=background, log_path=log_path)

	def _elog_process(self, phasefilter=None):
		cpv = self.mycpv
		if self._pipe is None:
			elog_process(cpv, self.settings, phasefilter=phasefilter)
		else:
			logdir = os.path.join(self.settings["T"], "logging")
			ebuild_logentries = collect_ebuild_messages(logdir)
			# phasefilter is irrelevant for the above collect_ebuild_messages
			# call, since this package instance has a private logdir. However,
			# it may be relevant for the following collect_messages call.
			py_logentries = collect_messages(key=cpv, phasefilter=phasefilter).get(cpv, {})
			logentries = _merge_logentries(py_logentries, ebuild_logentries)
			funcnames = {
				"INFO": "einfo",
				"LOG": "elog",
				"WARN": "ewarn",
				"QA": "eqawarn",
				"ERROR": "eerror"
			}
			str_buffer = []
			for phase, messages in logentries.items():
				for key, lines in messages:
					funcname = funcnames[key]
					if isinstance(lines, basestring):
						lines = [lines]
					for line in lines:
						for line in line.split('\n'):
							fields = (funcname, phase, cpv, line)
							str_buffer.append(' '.join(fields))
							str_buffer.append('\n')
			if str_buffer:
				str_buffer = _unicode_encode(''.join(str_buffer))
				while str_buffer:
					str_buffer = str_buffer[os.write(self._pipe, str_buffer):]

	def _emerge_log(self, msg):
		emergelog(False, msg)

	def treewalk(self, srcroot, destroot, inforoot, myebuild, cleanup=0,
		mydbapi=None, prev_mtimes=None, counter=None):
		"""

		This function does the following:

		calls get_ro_checker to retrieve a function for checking whether Portage
		will write to a read-only filesystem, then runs it against the directory list
		calls self._preserve_libs if FEATURES=preserve-libs
		calls self._collision_protect if FEATURES=collision-protect
		calls doebuild(mydo=pkg_preinst)
		Merges the package to the livefs
		unmerges old version (if required)
		calls doebuild(mydo=pkg_postinst)
		calls env_update

		@param srcroot: Typically this is ${D}
		@type srcroot: String (Path)
		@param destroot: ignored, self.settings['ROOT'] is used instead
		@type destroot: String (Path)
		@param inforoot: root of the vardb entry ?
		@type inforoot: String (Path)
		@param myebuild: path to the ebuild that we are processing
		@type myebuild: String (Path)
		@param mydbapi: dbapi which is handed to doebuild.
		@type mydbapi: portdbapi instance
		@param prev_mtimes: { Filename:mtime } mapping for env_update
		@type prev_mtimes: Dictionary
		@rtype: Boolean
		@return:
		1. 0 on success
		2. 1 on failure

		secondhand is a list of symlinks that have been skipped due to their target
		not existing; we will merge these symlinks at a later time.
		"""

		os = _os_merge

		srcroot = _unicode_decode(srcroot,
			encoding=_encodings['content'], errors='strict')
		destroot = self.settings['ROOT']
		inforoot = _unicode_decode(inforoot,
			encoding=_encodings['content'], errors='strict')
		myebuild = _unicode_decode(myebuild,
			encoding=_encodings['content'], errors='strict')

		showMessage = self._display_merge
		srcroot = normalize_path(srcroot).rstrip(os.path.sep) + os.path.sep

		if not os.path.isdir(srcroot):
			showMessage(_("!!! Directory Not Found: D='%s'\n") % srcroot,
				level=logging.ERROR, noiselevel=-1)
			return 1

		is_binpkg = self.settings.get("EMERGE_FROM") == "binary"
		slot = ''
		for var_name in ('CHOST', 'SLOT'):
			if var_name == 'CHOST' and self.cat == 'virtual':
				try:
					os.unlink(os.path.join(inforoot, var_name))
				except OSError:
					pass
				continue

			try:
				with io.open(_unicode_encode(
					os.path.join(inforoot, var_name),
					encoding=_encodings['fs'], errors='strict'),
					mode='r', encoding=_encodings['repo.content'],
					errors='replace') as f:
					val = f.readline().strip()
			except EnvironmentError as e:
				if e.errno != errno.ENOENT:
					raise
				del e
				val = ''

			if var_name == 'SLOT':
				slot = val

				if not slot.strip():
					slot = self.settings.get(var_name, '')
					if not slot.strip():
						showMessage(_("!!! SLOT is undefined\n"),
							level=logging.ERROR, noiselevel=-1)
						return 1
					write_atomic(os.path.join(inforoot, var_name), slot + '\n')

			# This check only applies when built from source, since
			# inforoot values are written just after src_install.
			if not is_binpkg and val != self.settings.get(var_name, ''):
				self._eqawarn('preinst',
					[_("QA Notice: Expected %(var_name)s='%(expected_value)s', got '%(actual_value)s'\n") % \
					{"var_name":var_name, "expected_value":self.settings.get(var_name, ''), "actual_value":val}])

		def eerror(lines):
			self._eerror("preinst", lines)

		if not os.path.exists(self.dbcatdir):
			ensure_dirs(self.dbcatdir)

		# NOTE: We use SLOT obtained from the inforoot
		#	directory, in order to support USE=multislot.
		# Use _pkg_str discard the sub-slot part if necessary.
		slot = _pkg_str(self.mycpv, slot=slot).slot
		cp = self.mysplit[0]
		slot_atom = "%s:%s" % (cp, slot)

		self.lockdb()
		try:
			# filter any old-style virtual matches
			slot_matches = [cpv for cpv in self.vartree.dbapi.match(slot_atom)
				if cpv_getkey(cpv) == cp]

			if self.mycpv not in slot_matches and \
				self.vartree.dbapi.cpv_exists(self.mycpv):
				# handle multislot or unapplied slotmove
				slot_matches.append(self.mycpv)

			others_in_slot = []
			for cur_cpv in slot_matches:
				# Clone the config in case one of these has to be unmerged,
				# since we need it to have private ${T} etc... for things
				# like elog.
				settings_clone = portage.config(clone=self.settings)
				settings_clone.pop("PORTAGE_BUILDDIR_LOCKED", None)
				settings_clone.setcpv(cur_cpv, mydb=self.vartree.dbapi)
				if self._preserve_libs and "preserve-libs" in \
					settings_clone["PORTAGE_RESTRICT"].split():
					self._preserve_libs = False
				others_in_slot.append(dblink(self.cat, catsplit(cur_cpv)[1],
					settings=settings_clone,
					vartree=self.vartree, treetype="vartree",
					scheduler=self._scheduler, pipe=self._pipe))
		finally:
			self.unlockdb()

		# If any instance has RESTRICT=preserve-libs, then
		# restrict it for all instances.
		if not self._preserve_libs:
			for dblnk in others_in_slot:
				dblnk._preserve_libs = False

		retval = self._security_check(others_in_slot)
		if retval:
			return retval

		if slot_matches:
			# Used by self.isprotected().
			max_dblnk = None
			max_counter = -1
			for dblnk in others_in_slot:
				cur_counter = self.vartree.dbapi.cpv_counter(dblnk.mycpv)
				if cur_counter > max_counter:
					max_counter = cur_counter
					max_dblnk = dblnk
			self._installed_instance = max_dblnk

		if self.settings.get("INSTALL_MASK") or \
			"nodoc" in self.settings.features or \
			"noinfo" in self.settings.features or \
			"noman" in self.settings.features:
			# Apply INSTALL_MASK before collision-protect, since it may
			# be useful to avoid collisions in some scenarios.
			phase = MiscFunctionsProcess(background=False,
				commands=["preinst_mask"], phase="preinst",
				scheduler=self._scheduler, settings=self.settings)
			phase.start()
			phase.wait()

		# We check for unicode encoding issues after src_install. However,
		# the check must be repeated here for binary packages (it's
		# inexpensive since we call os.walk() here anyway).
		unicode_errors = []
		line_ending_re = re.compile('[\n\r]')
		srcroot_len = len(srcroot)
		ed_len = len(self.settings["ED"])

		while True:

			unicode_error = False
			eagain_error = False

			filelist = []
			dirlist = []
			linklist = []
			paths_with_newlines = []
			def onerror(e):
				raise
			walk_iter = os.walk(srcroot, onerror=onerror)
			while True:
				try:
					parent, dirs, files = next(walk_iter)
				except StopIteration:
					break
				except OSError as e:
					if e.errno != errno.EAGAIN:
						raise
					# Observed with PyPy 1.8.
					eagain_error = True
					break

				try:
					parent = _unicode_decode(parent,
						encoding=_encodings['merge'], errors='strict')
				except UnicodeDecodeError:
					new_parent = _unicode_decode(parent,
						encoding=_encodings['merge'], errors='replace')
					new_parent = _unicode_encode(new_parent,
						encoding='ascii', errors='backslashreplace')
					new_parent = _unicode_decode(new_parent,
						encoding=_encodings['merge'], errors='replace')
					os.rename(parent, new_parent)
					unicode_error = True
					unicode_errors.append(new_parent[ed_len:])
					break

				relative_path = parent[srcroot_len:]
				dirlist.append(os.path.join("/", relative_path))

				for fname in files:
					try:
						fname = _unicode_decode(fname,
							encoding=_encodings['merge'], errors='strict')
					except UnicodeDecodeError:
						fpath = portage._os.path.join(
							parent.encode(_encodings['merge']), fname)
						new_fname = _unicode_decode(fname,
							encoding=_encodings['merge'], errors='replace')
						new_fname = _unicode_encode(new_fname,
							encoding='ascii', errors='backslashreplace')
						new_fname = _unicode_decode(new_fname,
							encoding=_encodings['merge'], errors='replace')
						new_fpath = os.path.join(parent, new_fname)
						os.rename(fpath, new_fpath)
						unicode_error = True
						unicode_errors.append(new_fpath[ed_len:])
						fname = new_fname
						fpath = new_fpath
					else:
						fpath = os.path.join(parent, fname)

					relative_path = fpath[srcroot_len:]

					if line_ending_re.search(relative_path) is not None:
						paths_with_newlines.append(relative_path)

					file_mode = os.lstat(fpath).st_mode
					if stat.S_ISREG(file_mode):
						filelist.append(relative_path)
					elif stat.S_ISLNK(file_mode):
						# Note: os.walk puts symlinks to directories in the "dirs"
						# list and it does not traverse them since that could lead
						# to an infinite recursion loop.
						linklist.append(relative_path)

						myto = _unicode_decode(
							_os.readlink(_unicode_encode(fpath,
							encoding=_encodings['merge'], errors='strict')),
							encoding=_encodings['merge'], errors='replace')
						if line_ending_re.search(myto) is not None:
							paths_with_newlines.append(relative_path)

				if unicode_error:
					break

			if not (unicode_error or eagain_error):
				break

		if unicode_errors:
			self._elog("eqawarn", "preinst",
				_merge_unicode_error(unicode_errors))

		if paths_with_newlines:
			msg = []
			msg.append(_("This package installs one or more files containing line ending characters:"))
			msg.append("")
			paths_with_newlines.sort()
			for f in paths_with_newlines:
				msg.append("\t/%s" % (f.replace("\n", "\\n").replace("\r", "\\r")))
			msg.append("")
			msg.append(_("package %s NOT merged") % self.mycpv)
			msg.append("")
			eerror(msg)
			return 1

		# If there are no files to merge, and an installed package in the same
		# slot has files, it probably means that something went wrong.
		if self.settings.get("PORTAGE_PACKAGE_EMPTY_ABORT") == "1" and \
			not filelist and not linklist and others_in_slot:
			installed_files = None
			for other_dblink in others_in_slot:
				installed_files = other_dblink.getcontents()
				if not installed_files:
					continue
				from textwrap import wrap
				wrap_width = 72
				msg = []
				d = {
					"new_cpv":self.mycpv,
					"old_cpv":other_dblink.mycpv
				}
				msg.extend(wrap(_("The '%(new_cpv)s' package will not install "
					"any files, but the currently installed '%(old_cpv)s'"
					" package has the following files: ") % d, wrap_width))
				msg.append("")
				msg.extend(sorted(installed_files))
				msg.append("")
				msg.append(_("package %s NOT merged") % self.mycpv)
				msg.append("")
				msg.extend(wrap(
					_("Manually run `emerge --unmerge =%s` if you "
					"really want to remove the above files. Set "
					"PORTAGE_PACKAGE_EMPTY_ABORT=\"0\" in "
					"/etc/portage/make.conf if you do not want to "
					"abort in cases like this.") % other_dblink.mycpv,
					wrap_width))
				eerror(msg)
			if installed_files:
				return 1

		# Make sure the ebuild environment is initialized and that ${T}/elog
		# exists for logging of collision-protect eerror messages.
		if myebuild is None:
			myebuild = os.path.join(inforoot, self.pkg + ".ebuild")
		doebuild_environment(myebuild, "preinst",
			settings=self.settings, db=mydbapi)
		self.settings["REPLACING_VERSIONS"] = " ".join(
			[portage.versions.cpv_getversion(other.mycpv)
			for other in others_in_slot])
		prepare_build_dirs(settings=self.settings, cleanup=cleanup)

		# Check for read-only filesystems.
		ro_checker = get_ro_checker()
		rofilesystems = ro_checker(dirlist)

		if rofilesystems:
			msg = _("One or more files installed to this package are "
				"set to be installed to read-only filesystems. "
				"Please mount the following filesystems as read-write "
				"and retry.")
			msg = textwrap.wrap(msg, 70)
			msg.append("")
			for f in rofilesystems:
				msg.append("\t%s" % os.path.join(destroot,
					f.lstrip(os.path.sep)))
			msg.append("")
			self._elog("eerror", "preinst", msg)

			msg = _("Package '%s' NOT merged due to read-only file systems.") % \
				self.settings.mycpv
			msg += _(" If necessary, refer to your elog "
				"messages for the whole content of the above message.")
			msg = textwrap.wrap(msg, 70)
			eerror(msg)
			return 1

		# check for package collisions
		blockers = self._blockers
		if blockers is None:
			blockers = []
		collisions, symlink_collisions, plib_collisions = \
			self._collision_protect(srcroot, destroot,
			others_in_slot + blockers, filelist, linklist)

		if symlink_collisions:
			# Symlink collisions need to be distinguished from other types
			# of collisions, in order to avoid confusion (see bug #409359).
			msg = _("Package '%s' has one or more collisions "
				"between symlinks and directories, which is explicitly "
				"forbidden by PMS section 13.4 (see bug #326685):") % \
				(self.settings.mycpv,)
			msg = textwrap.wrap(msg, 70)
			msg.append("")
			for f in symlink_collisions:
				msg.append("\t%s" % os.path.join(destroot,
					f.lstrip(os.path.sep)))
			msg.append("")
			self._elog("eerror", "preinst", msg)

		if collisions:
			collision_protect = "collision-protect" in self.settings.features
			protect_owned = "protect-owned" in self.settings.features
			msg = _("This package will overwrite one or more files that"
			" may belong to other packages (see list below).")
			if not (collision_protect or protect_owned):
				msg += _(" Add either \"collision-protect\" or"
				" \"protect-owned\" to FEATURES in"
				" make.conf if you would like the merge to abort"
				" in cases like this. See the make.conf man page for"
				" more information about these features.")
			if self.settings.get("PORTAGE_QUIET") != "1":
				msg += _(" You can use a command such as"
				" `portageq owners / <filename>` to identify the"
				" installed package that owns a file. If portageq"
				" reports that only one package owns a file then do NOT"
				" file a bug report. A bug report is only useful if it"
				" identifies at least two or more packages that are known"
				" to install the same file(s)."
				" If a collision occurs and you"
				" can not explain where the file came from then you"
				" should simply ignore the collision since there is not"
				" enough information to determine if a real problem"
				" exists. Please do NOT file a bug report at"
				" http://bugs.gentoo.org unless you report exactly which"
				" two packages install the same file(s). See"
				" http://wiki.gentoo.org/wiki/Knowledge_Base:Blockers"
				" for tips on how to solve the problem. And once again,"
				" please do NOT file a bug report unless you have"
				" completely understood the above message.")

			self.settings["EBUILD_PHASE"] = "preinst"
			from textwrap import wrap
			msg = wrap(msg, 70)
			if collision_protect:
				msg.append("")
				msg.append(_("package %s NOT merged") % self.settings.mycpv)
			msg.append("")
			msg.append(_("Detected file collision(s):"))
			msg.append("")

			for f in collisions:
				msg.append("\t%s" % \
					os.path.join(destroot, f.lstrip(os.path.sep)))

			eerror(msg)

			owners = None
			if collision_protect or protect_owned or symlink_collisions:
				msg = []
				msg.append("")
				msg.append(_("Searching all installed"
					" packages for file collisions..."))
				msg.append("")
				msg.append(_("Press Ctrl-C to Stop"))
				msg.append("")
				eerror(msg)

				if len(collisions) > 20:
					# get_owners is slow for large numbers of files, so
					# don't look them all up.
					collisions = collisions[:20]

				pkg_info_strs = {}
				self.lockdb()
				try:
					owners = self.vartree.dbapi._owners.get_owners(collisions)
					self.vartree.dbapi.flush_cache()

					for pkg in owners:
						pkg = self.vartree.dbapi._pkg_str(pkg.mycpv, None)
						pkg_info_str = "%s%s%s" % (pkg,
							_slot_separator, pkg.slot)
						if pkg.repo != _unknown_repo:
							pkg_info_str += "%s%s" % (_repo_separator,
								pkg.repo)
						pkg_info_strs[pkg] = pkg_info_str

				finally:
					self.unlockdb()

				for pkg, owned_files in owners.items():
					msg = []
					msg.append(pkg_info_strs[pkg.mycpv])
					for f in sorted(owned_files):
						msg.append("\t%s" % os.path.join(destroot,
							f.lstrip(os.path.sep)))
					msg.append("")
					eerror(msg)

				if not owners:
					eerror([_("None of the installed"
						" packages claim the file(s)."), ""])

			symlink_abort_msg =_("Package '%s' NOT merged since it has "
				"one or more collisions between symlinks and directories, "
				"which is explicitly forbidden by PMS section 13.4 "
				"(see bug #326685).")

			# The explanation about the collision and how to solve
			# it may not be visible via a scrollback buffer, especially
			# if the number of file collisions is large. Therefore,
			# show a summary at the end.
			abort = False
			if symlink_collisions:
				abort = True
				msg = symlink_abort_msg % (self.settings.mycpv,)
			elif collision_protect:
				abort = True
				msg = _("Package '%s' NOT merged due to file collisions.") % \
					self.settings.mycpv
			elif protect_owned and owners:
				abort = True
				msg = _("Package '%s' NOT merged due to file collisions.") % \
					self.settings.mycpv
			else:
				msg = _("Package '%s' merged despite file collisions.") % \
					self.settings.mycpv
			msg += _(" If necessary, refer to your elog "
				"messages for the whole content of the above message.")
			eerror(wrap(msg, 70))

			if abort:
				return 1

		# The merge process may move files out of the image directory,
		# which causes invalidation of the .installed flag.
		try:
			os.unlink(os.path.join(
				os.path.dirname(normalize_path(srcroot)), ".installed"))
		except OSError as e:
			if e.errno != errno.ENOENT:
				raise
			del e

		self.dbdir = self.dbtmpdir
		self.delete()
		ensure_dirs(self.dbtmpdir)

		downgrade = False
		if self._installed_instance is not None and \
			vercmp(self.mycpv.version,
			self._installed_instance.mycpv.version) < 0:
			downgrade = True

		if self._installed_instance is not None:
			rval = self._pre_merge_backup(self._installed_instance, downgrade)
			if rval != os.EX_OK:
				showMessage(_("!!! FAILED preinst: ") +
					"quickpkg: %s\n" % rval,
					level=logging.ERROR, noiselevel=-1)
				return rval

		# run preinst script
		showMessage(_(">>> Merging %(cpv)s to %(destroot)s\n") % \
			{"cpv":self.mycpv, "destroot":destroot})
		phase = EbuildPhase(background=False, phase="preinst",
			scheduler=self._scheduler, settings=self.settings)
		phase.start()
		a = phase.wait()

		# XXX: Decide how to handle failures here.
		if a != os.EX_OK:
			showMessage(_("!!! FAILED preinst: ")+str(a)+"\n",
				level=logging.ERROR, noiselevel=-1)
			return a

		# copy "info" files (like SLOT, CFLAGS, etc.) into the database
		for x in os.listdir(inforoot):
			self.copyfile(inforoot+"/"+x)

		# write local package counter for recording
		if counter is None:
			counter = self.vartree.dbapi.counter_tick(mycpv=self.mycpv)
		with io.open(_unicode_encode(os.path.join(self.dbtmpdir, 'COUNTER'),
			encoding=_encodings['fs'], errors='strict'),
			mode='w', encoding=_encodings['repo.content'],
			errors='backslashreplace') as f:
			f.write("%s" % counter)

		self.updateprotect()

		#if we have a file containing previously-merged config file md5sums, grab it.
		self.vartree.dbapi._fs_lock()
		try:
			# Always behave like --noconfmem is enabled for downgrades
			# so that people who don't know about this option are less
			# likely to get confused when doing upgrade/downgrade cycles.
			cfgfiledict = grabdict(self.vartree.dbapi._conf_mem_file)
			if "NOCONFMEM" in self.settings or downgrade:
				cfgfiledict["IGNORE"]=1
			else:
				cfgfiledict["IGNORE"]=0

			rval = self._merge_contents(srcroot, destroot, cfgfiledict)
			if rval != os.EX_OK:
				return rval
		finally:
			self.vartree.dbapi._fs_unlock()

		# These caches are populated during collision-protect and the data
		# they contain is now invalid. It's very important to invalidate
		# the contents_inodes cache so that FEATURES=unmerge-orphans
		# doesn't unmerge anything that belongs to this package that has
		# just been merged.
		for dblnk in others_in_slot:
			dblnk._clear_contents_cache()
		self._clear_contents_cache()

		linkmap = self.vartree.dbapi._linkmap
		plib_registry = self.vartree.dbapi._plib_registry
		# We initialize preserve_paths to an empty set rather
		# than None here because it plays an important role
		# in prune_plib_registry logic by serving to indicate
		# that we have a replacement for a package that's
		# being unmerged.

		preserve_paths = set()
		needed = None
		if not (self._linkmap_broken or linkmap is None or
			plib_registry is None):
			self.vartree.dbapi._fs_lock()
			plib_registry.lock()
			try:
				plib_registry.load()
				needed = os.path.join(inforoot, linkmap._needed_aux_key)
				self._linkmap_rebuild(include_file=needed)

				# Preserve old libs if they are still in use
				# TODO: Handle cases where the previous instance
				# has already been uninstalled but it still has some
				# preserved libraries in the registry that we may
				# want to preserve here.
				preserve_paths = self._find_libs_to_preserve()
			finally:
				plib_registry.unlock()
				self.vartree.dbapi._fs_unlock()

			if preserve_paths:
				self._add_preserve_libs_to_contents(preserve_paths)

		# If portage is reinstalling itself, remove the old
		# version now since we want to use the temporary
		# PORTAGE_BIN_PATH that will be removed when we return.
		reinstall_self = False
		if self.myroot == "/" and \
			match_from_list(PORTAGE_PACKAGE_ATOM, [self.mycpv]):
			reinstall_self = True

		emerge_log = self._emerge_log

		# If we have any preserved libraries then autoclean
		# is forced so that preserve-libs logic doesn't have
		# to account for the additional complexity of the
		# AUTOCLEAN=no mode.
		autoclean = self.settings.get("AUTOCLEAN", "yes") == "yes" \
			or preserve_paths

		if autoclean:
			emerge_log(_(" >>> AUTOCLEAN: %s") % (slot_atom,))

		others_in_slot.append(self)  # self has just been merged
		for dblnk in list(others_in_slot):
			if dblnk is self:
				continue
			if not (autoclean or dblnk.mycpv == self.mycpv or reinstall_self):
				continue
			showMessage(_(">>> Safely unmerging already-installed instance...\n"))
			emerge_log(_(" === Unmerging... (%s)") % (dblnk.mycpv,))
			others_in_slot.remove(dblnk) # dblnk will unmerge itself now
			dblnk._linkmap_broken = self._linkmap_broken
			dblnk.settings["REPLACED_BY_VERSION"] = portage.versions.cpv_getversion(self.mycpv)
			dblnk.settings.backup_changes("REPLACED_BY_VERSION")
			unmerge_rval = dblnk.unmerge(ldpath_mtimes=prev_mtimes,
				others_in_slot=others_in_slot, needed=needed,
				preserve_paths=preserve_paths)
			dblnk.settings.pop("REPLACED_BY_VERSION", None)

			if unmerge_rval == os.EX_OK:
				emerge_log(_(" >>> unmerge success: %s") % (dblnk.mycpv,))
			else:
				emerge_log(_(" !!! unmerge FAILURE: %s") % (dblnk.mycpv,))

			self.lockdb()
			try:
				# TODO: Check status and abort if necessary.
				dblnk.delete()
			finally:
				self.unlockdb()
			showMessage(_(">>> Original instance of package unmerged safely.\n"))

		if len(others_in_slot) > 1:
			showMessage(colorize("WARN", _("WARNING:"))
				+ _(" AUTOCLEAN is disabled.  This can cause serious"
				" problems due to overlapping packages.\n"),
				level=logging.WARN, noiselevel=-1)

		# We hold both directory locks.
		self.dbdir = self.dbpkgdir
		self.lockdb()
		try:
			self.delete()
			_movefile(self.dbtmpdir, self.dbpkgdir, mysettings=self.settings)
			self._merged_path(self.dbpkgdir, os.lstat(self.dbpkgdir))
		finally:
			self.unlockdb()

		# Check for file collisions with blocking packages
		# and remove any colliding files from their CONTENTS
		# since they now belong to this package.
		self._clear_contents_cache()
		contents = self.getcontents()
		destroot_len = len(destroot) - 1
		self.lockdb()
		try:
			for blocker in blockers:
				self.vartree.dbapi.removeFromContents(blocker, iter(contents),
					relative_paths=False)
		finally:
			self.unlockdb()

		plib_registry = self.vartree.dbapi._plib_registry
		if plib_registry:
			self.vartree.dbapi._fs_lock()
			plib_registry.lock()
			try:
				plib_registry.load()

				if preserve_paths:
					# keep track of the libs we preserved
					plib_registry.register(self.mycpv, slot, counter,
						sorted(preserve_paths))

				# Unregister any preserved libs that this package has overwritten
				# and update the contents of the packages that owned them.
				plib_dict = plib_registry.getPreservedLibs()
				for cpv, paths in plib_collisions.items():
					if cpv not in plib_dict:
						continue
					has_vdb_entry = False
					if cpv != self.mycpv:
						# If we've replaced another instance with the
						# same cpv then the vdb entry no longer belongs
						# to it, so we'll have to get the slot and counter
						# from plib_registry._data instead.
						self.vartree.dbapi.lock()
						try:
							try:
								slot = self.vartree.dbapi._pkg_str(cpv, None).slot
								counter = self.vartree.dbapi.cpv_counter(cpv)
							except (KeyError, InvalidData):
								pass
							else:
								has_vdb_entry = True
								self.vartree.dbapi.removeFromContents(
									cpv, paths)
						finally:
							self.vartree.dbapi.unlock()

					if not has_vdb_entry:
						# It's possible for previously unmerged packages
						# to have preserved libs in the registry, so try
						# to retrieve the slot and counter from there.
						has_registry_entry = False
						for plib_cps, (plib_cpv, plib_counter, plib_paths) in \
							plib_registry._data.items():
							if plib_cpv != cpv:
								continue
							try:
								cp, slot = plib_cps.split(":", 1)
							except ValueError:
								continue
							counter = plib_counter
							has_registry_entry = True
							break

						if not has_registry_entry:
							continue

					remaining = [f for f in plib_dict[cpv] if f not in paths]
					plib_registry.register(cpv, slot, counter, remaining)

				plib_registry.store()
			finally:
				plib_registry.unlock()
				self.vartree.dbapi._fs_unlock()

		self.vartree.dbapi._add(self)
		contents = self.getcontents()

		#do postinst script
		self.settings["PORTAGE_UPDATE_ENV"] = \
			os.path.join(self.dbpkgdir, "environment.bz2")
		self.settings.backup_changes("PORTAGE_UPDATE_ENV")
		try:
			phase = EbuildPhase(background=False, phase="postinst",
				scheduler=self._scheduler, settings=self.settings)
			phase.start()
			a = phase.wait()
			if a == os.EX_OK:
				showMessage(_(">>> %s merged.\n") % self.mycpv)
		finally:
			self.settings.pop("PORTAGE_UPDATE_ENV", None)

		if a != os.EX_OK:
			# It's stupid to bail out here, so keep going regardless of
			# phase return code.
			showMessage(_("!!! FAILED postinst: ")+str(a)+"\n",
				level=logging.ERROR, noiselevel=-1)

		#update environment settings, library paths. DO NOT change symlinks.
		env_update(
			target_root=self.settings['ROOT'], prev_mtimes=prev_mtimes,
			contents=contents, env=self.settings,
			writemsg_level=self._display_merge, vardbapi=self.vartree.dbapi)

		# For gcc upgrades, preserved libs have to be removed after the
		# the library path has been updated.
		self._prune_plib_registry()
		self._post_merge_sync()

		return os.EX_OK

	def _new_backup_path(self, p):
		"""
		The works for any type path, such as a regular file, symlink,
		or directory. The parent directory is assumed to exist.
		The returned filename is of the form p + '.backup.' + x, where
		x guarantees that the returned path does not exist yet.
		"""
		os = _os_merge

		x = -1
		while True:
			x += 1
			backup_p = '%s.backup.%04d' % (p, x)
			try:
				os.lstat(backup_p)
			except OSError:
				break

		return backup_p

	def _merge_contents(self, srcroot, destroot, cfgfiledict):

		cfgfiledict_orig = cfgfiledict.copy()

		# open CONTENTS file (possibly overwriting old one) for recording
		# Use atomic_ofstream for automatic coercion of raw bytes to
		# unicode, in order to prevent TypeError when writing raw bytes
		# to TextIOWrapper with python2.
		outfile = atomic_ofstream(_unicode_encode(
			os.path.join(self.dbtmpdir, 'CONTENTS'),
			encoding=_encodings['fs'], errors='strict'),
			mode='w', encoding=_encodings['repo.content'],
			errors='backslashreplace')

		# Don't bump mtimes on merge since some application require
		# preservation of timestamps.  This means that the unmerge phase must
		# check to see if file belongs to an installed instance in the same
		# slot.
		mymtime = None

		# set umask to 0 for merging; back up umask, save old one in prevmask (since this is a global change)
		prevmask = os.umask(0)
		secondhand = []

		# we do a first merge; this will recurse through all files in our srcroot but also build up a
		# "second hand" of symlinks to merge later
		if self.mergeme(srcroot, destroot, outfile, secondhand,
			self.settings["EPREFIX"].lstrip(os.sep), cfgfiledict, mymtime):
			return 1

		# now, it's time for dealing our second hand; we'll loop until we can't merge anymore.	The rest are
		# broken symlinks.  We'll merge them too.
		lastlen = 0
		while len(secondhand) and len(secondhand)!=lastlen:
			# clear the thirdhand.	Anything from our second hand that
			# couldn't get merged will be added to thirdhand.

			thirdhand = []
			if self.mergeme(srcroot, destroot, outfile, thirdhand,
				secondhand, cfgfiledict, mymtime):
				return 1

			#swap hands
			lastlen = len(secondhand)

			# our thirdhand now becomes our secondhand.  It's ok to throw
			# away secondhand since thirdhand contains all the stuff that
			# couldn't be merged.
			secondhand = thirdhand

		if len(secondhand):
			# force merge of remaining symlinks (broken or circular; oh well)
			if self.mergeme(srcroot, destroot, outfile, None,
				secondhand, cfgfiledict, mymtime):
				return 1

		#restore umask
		os.umask(prevmask)

		#if we opened it, close it
		outfile.flush()
		outfile.close()

		# write out our collection of md5sums
		if cfgfiledict != cfgfiledict_orig:
			cfgfiledict.pop("IGNORE", None)
			try:
				writedict(cfgfiledict, self.vartree.dbapi._conf_mem_file)
			except InvalidLocation:
				self.settings._init_dirs()
				writedict(cfgfiledict, self.vartree.dbapi._conf_mem_file)

		return os.EX_OK

	def mergeme(self, srcroot, destroot, outfile, secondhand, stufftomerge, cfgfiledict, thismtime):
		"""

		This function handles actual merging of the package contents to the livefs.
		It also handles config protection.

		@param srcroot: Where are we copying files from (usually ${D})
		@type srcroot: String (Path)
		@param destroot: Typically ${ROOT}
		@type destroot: String (Path)
		@param outfile: File to log operations to
		@type outfile: File Object
		@param secondhand: A set of items to merge in pass two (usually
		or symlinks that point to non-existing files that may get merged later)
		@type secondhand: List
		@param stufftomerge: Either a diretory to merge, or a list of items.
		@type stufftomerge: String or List
		@param cfgfiledict: { File:mtime } mapping for config_protected files
		@type cfgfiledict: Dictionary
		@param thismtime: None or new mtime for merged files (expressed in seconds
		in Python <3.3 and nanoseconds in Python >=3.3)
		@type thismtime: None or Int
		@rtype: None or Boolean
		@return:
		1. True on failure
		2. None otherwise

		"""

		showMessage = self._display_merge
		writemsg = self._display_merge

		os = _os_merge
		sep = os.sep
		join = os.path.join
		srcroot = normalize_path(srcroot).rstrip(sep) + sep
		destroot = normalize_path(destroot).rstrip(sep) + sep
		calc_prelink = "prelink-checksums" in self.settings.features

		protect_if_modified = \
			"config-protect-if-modified" in self.settings.features and \
			self._installed_instance is not None

		# this is supposed to merge a list of files.  There will be 2 forms of argument passing.
		if isinstance(stufftomerge, basestring):
			#A directory is specified.  Figure out protection paths, listdir() it and process it.
			mergelist = [join(stufftomerge, child) for child in \
				os.listdir(join(srcroot, stufftomerge))]
		else:
			mergelist = stufftomerge[:]

		while mergelist:

			relative_path = mergelist.pop()
			mysrc = join(srcroot, relative_path)
			mydest = join(destroot, relative_path)
			# myrealdest is mydest without the $ROOT prefix (makes a difference if ROOT!="/")
			myrealdest = join(sep, relative_path)
			# stat file once, test using S_* macros many times (faster that way)
			mystat = os.lstat(mysrc)
			mymode = mystat[stat.ST_MODE]
			# handy variables; mydest is the target object on the live filesystems;
			# mysrc is the source object in the temporary install dir
			try:
				mydstat = os.lstat(mydest)
				mydmode = mydstat.st_mode
			except OSError as e:
				if e.errno != errno.ENOENT:
					raise
				del e
				#dest file doesn't exist
				mydstat = None
				mydmode = None

			if stat.S_ISLNK(mymode):
				# we are merging a symbolic link
				# The file name of mysrc and the actual file that it points to
				# will have earlier been forcefully converted to the 'merge'
				# encoding if necessary, but the content of the symbolic link
				# may need to be forcefully converted here.
				myto = _os.readlink(_unicode_encode(mysrc,
					encoding=_encodings['merge'], errors='strict'))
				try:
					myto = _unicode_decode(myto,
						encoding=_encodings['merge'], errors='strict')
				except UnicodeDecodeError:
					myto = _unicode_decode(myto, encoding=_encodings['merge'],
						errors='replace')
					myto = _unicode_encode(myto, encoding='ascii',
						errors='backslashreplace')
					myto = _unicode_decode(myto, encoding=_encodings['merge'],
						errors='replace')
					os.unlink(mysrc)
					os.symlink(myto, mysrc)

				# Pass in the symlink target in order to bypass the
				# os.readlink() call inside abssymlink(), since that
				# call is unsafe if the merge encoding is not ascii
				# or utf_8 (see bug #382021).
				myabsto = abssymlink(mysrc, target=myto)

				if myabsto.startswith(srcroot):
					myabsto = myabsto[len(srcroot):]
				myabsto = myabsto.lstrip(sep)
				if self.settings and self.settings["D"]:
					if myto.startswith(self.settings["D"]):
						myto = myto[len(self.settings["D"])-1:]
				# myrealto contains the path of the real file to which this symlink points.
				# we can simply test for existence of this file to see if the target has been merged yet
				myrealto = normalize_path(os.path.join(destroot, myabsto))
				if mydmode!=None:
					#destination exists
					if stat.S_ISDIR(mydmode):
						# we can't merge a symlink over a directory
						newdest = self._new_backup_path(mydest)
						msg = []
						msg.append("")
						msg.append(_("Installation of a symlink is blocked by a directory:"))
						msg.append("  '%s'" % mydest)
						msg.append(_("This symlink will be merged with a different name:"))
						msg.append("  '%s'" % newdest)
						msg.append("")
						self._eerror("preinst", msg)
						mydest = newdest

					elif not stat.S_ISLNK(mydmode):
						if os.path.exists(mysrc) and stat.S_ISDIR(os.stat(mysrc)[stat.ST_MODE]):
							# Kill file blocking installation of symlink to dir #71787
							pass
						elif self.isprotected(mydest):
							# Use md5 of the target in ${D} if it exists...
							try:
								newmd5 = perform_md5(join(srcroot, myabsto))
							except FileNotFound:
								# Maybe the target is merged already.
								try:
									newmd5 = perform_md5(myrealto)
								except FileNotFound:
									newmd5 = None
							mydest = new_protect_filename(mydest, newmd5=newmd5)

				# if secondhand is None it means we're operating in "force" mode and should not create a second hand.
				if (secondhand != None) and (not os.path.exists(myrealto)):
					# either the target directory doesn't exist yet or the target file doesn't exist -- or
					# the target is a broken symlink.  We will add this file to our "second hand" and merge
					# it later.
					secondhand.append(mysrc[len(srcroot):])
					continue
				# unlinking no longer necessary; "movefile" will overwrite symlinks atomically and correctly
				mymtime = movefile(mysrc, mydest, newmtime=thismtime,
					sstat=mystat, mysettings=self.settings,
					encoding=_encodings['merge'])

				try:
					self._merged_path(mydest, os.lstat(mydest))
				except OSError:
					pass

				if mymtime != None:
					# Use lexists, since if the target happens to be a broken
					# symlink then that should trigger an independent warning.
					if not (os.path.lexists(myrealto) or
						os.path.lexists(join(srcroot, myabsto))):
						self._eqawarn('preinst',
							[_("QA Notice: Symbolic link /%s points to /%s which does not exist.")
							% (relative_path, myabsto)])

					showMessage(">>> %s -> %s\n" % (mydest, myto))
					if sys.hexversion >= 0x3030000:
						outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime // 1000000000)+"\n")
					else:
						outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime)+"\n")
				else:
					showMessage(_("!!! Failed to move file.\n"),
						level=logging.ERROR, noiselevel=-1)
					showMessage("!!! %s -> %s\n" % (mydest, myto),
						level=logging.ERROR, noiselevel=-1)
					return 1
			elif stat.S_ISDIR(mymode):
				# we are merging a directory
				if mydmode != None:
					# destination exists

					if bsd_chflags:
						# Save then clear flags on dest.
						dflags = mydstat.st_flags
						if dflags != 0:
							bsd_chflags.lchflags(mydest, 0)

					if not os.access(mydest, os.W_OK):
						pkgstuff = pkgsplit(self.pkg)
						writemsg(_("\n!!! Cannot write to '%s'.\n") % mydest, noiselevel=-1)
						writemsg(_("!!! Please check permissions and directories for broken symlinks.\n"))
						writemsg(_("!!! You may start the merge process again by using ebuild:\n"))
						writemsg("!!! ebuild "+self.settings["PORTDIR"]+"/"+self.cat+"/"+pkgstuff[0]+"/"+self.pkg+".ebuild merge\n")
						writemsg(_("!!! And finish by running this: env-update\n\n"))
						return 1

					if stat.S_ISDIR(mydmode) or \
						(stat.S_ISLNK(mydmode) and os.path.isdir(mydest)):
						# a symlink to an existing directory will work for us; keep it:
						showMessage("--- %s/\n" % mydest)
						if bsd_chflags:
							bsd_chflags.lchflags(mydest, dflags)
					else:
						# a non-directory and non-symlink-to-directory.  Won't work for us.  Move out of the way.
						backup_dest = self._new_backup_path(mydest)
						msg = []
						msg.append("")
						msg.append(_("Installation of a directory is blocked by a file:"))
						msg.append("  '%s'" % mydest)
						msg.append(_("This file will be renamed to a different name:"))
						msg.append("  '%s'" % backup_dest)
						msg.append("")
						self._eerror("preinst", msg)
						if movefile(mydest, backup_dest,
							mysettings=self.settings,
							encoding=_encodings['merge']) is None:
							return 1
						showMessage(_("bak %s %s.backup\n") % (mydest, mydest),
							level=logging.ERROR, noiselevel=-1)
						#now create our directory
						try:
							if self.settings.selinux_enabled():
								_selinux_merge.mkdir(mydest, mysrc)
							else:
								os.mkdir(mydest)
						except OSError as e:
							# Error handling should be equivalent to
							# portage.util.ensure_dirs() for cases
							# like bug #187518.
							if e.errno in (errno.EEXIST,):
								pass
							elif os.path.isdir(mydest):
								pass
							else:
								raise
							del e

						if bsd_chflags:
							bsd_chflags.lchflags(mydest, dflags)
						os.chmod(mydest, mystat[0])
						os.chown(mydest, mystat[4], mystat[5])
						showMessage(">>> %s/\n" % mydest)
				else:
					try:
						#destination doesn't exist
						if self.settings.selinux_enabled():
							_selinux_merge.mkdir(mydest, mysrc)
						else:
							os.mkdir(mydest)
					except OSError as e:
						# Error handling should be equivalent to
						# portage.util.ensure_dirs() for cases
						# like bug #187518.
						if e.errno in (errno.EEXIST,):
							pass
						elif os.path.isdir(mydest):
							pass
						else:
							raise
						del e
					os.chmod(mydest, mystat[0])
					os.chown(mydest, mystat[4], mystat[5])
					showMessage(">>> %s/\n" % mydest)

				try:
					self._merged_path(mydest, os.lstat(mydest))
				except OSError:
					pass

				outfile.write("dir "+myrealdest+"\n")
				# recurse and merge this directory
				mergelist.extend(join(relative_path, child) for child in
					os.listdir(join(srcroot, relative_path)))

			elif stat.S_ISREG(mymode):
				# we are merging a regular file
				mymd5 = perform_md5(mysrc, calc_prelink=calc_prelink)
				# calculate config file protection stuff
				mydestdir = os.path.dirname(mydest)
				moveme = 1
				zing = "!!!"
				mymtime = None
				protected = self.isprotected(mydest)
				if mydmode != None:
					# destination file exists

					if stat.S_ISDIR(mydmode):
						# install of destination is blocked by an existing directory with the same name
						newdest = self._new_backup_path(mydest)
						msg = []
						msg.append("")
						msg.append(_("Installation of a regular file is blocked by a directory:"))
						msg.append("  '%s'" % mydest)
						msg.append(_("This file will be merged with a different name:"))
						msg.append("  '%s'" % newdest)
						msg.append("")
						self._eerror("preinst", msg)
						mydest = newdest

					elif stat.S_ISREG(mydmode) or (stat.S_ISLNK(mydmode) and os.path.exists(mydest) and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])):
						# install of destination is blocked by an existing regular file,
						# or by a symlink to an existing regular file;
						# now, config file management may come into play.
						# we only need to tweak mydest if cfg file management is in play.
						if protected:
							destmd5 = perform_md5(mydest, calc_prelink=calc_prelink)
							if protect_if_modified:
								contents_key = \
									self._installed_instance._match_contents(myrealdest)
								if contents_key:
									inst_info = self._installed_instance.getcontents()[contents_key]
									if inst_info[0] == "obj" and inst_info[2] == destmd5:
										protected = False

						if protected:
							# we have a protection path; enable config file management.
							cfgprot = 0
							if mymd5 == destmd5:
								#file already in place; simply update mtimes of destination
								moveme = 1
							else:
								if mymd5 == cfgfiledict.get(myrealdest, [None])[0]:
									""" An identical update has previously been
									merged.  Skip it unless the user has chosen
									--noconfmem."""
									moveme = cfgfiledict["IGNORE"]
									cfgprot = cfgfiledict["IGNORE"]
									if not moveme:
										zing = "---"
										if sys.hexversion >= 0x3030000:
											mymtime = mystat.st_mtime_ns
										else:
											mymtime = mystat[stat.ST_MTIME]
								else:
									moveme = 1
									cfgprot = 1
							if moveme:
								# Merging a new file, so update confmem.
								cfgfiledict[myrealdest] = [mymd5]
							elif destmd5 == cfgfiledict.get(myrealdest, [None])[0]:
								"""A previously remembered update has been
								accepted, so it is removed from confmem."""
								del cfgfiledict[myrealdest]

							if cfgprot:
								mydest = new_protect_filename(mydest, newmd5=mymd5)

				# whether config protection or not, we merge the new file the
				# same way.  Unless moveme=0 (blocking directory)
				if moveme:
					# Create hardlinks only for source files that already exist
					# as hardlinks (having identical st_dev and st_ino).
					hardlink_key = (mystat.st_dev, mystat.st_ino)

					hardlink_candidates = self._hardlink_merge_map.get(hardlink_key)
					if hardlink_candidates is None:
						hardlink_candidates = []
						self._hardlink_merge_map[hardlink_key] = hardlink_candidates

					mymtime = movefile(mysrc, mydest, newmtime=thismtime,
						sstat=mystat, mysettings=self.settings,
						hardlink_candidates=hardlink_candidates,
						encoding=_encodings['merge'])
					if mymtime is None:
						return 1
					hardlink_candidates.append(mydest)
					zing = ">>>"

					try:
						self._merged_path(mydest, os.lstat(mydest))
					except OSError:
						pass

				if mymtime != None:
					if sys.hexversion >= 0x3030000:
						outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime // 1000000000)+"\n")
					else:
						outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime)+"\n")
				showMessage("%s %s\n" % (zing,mydest))
			else:
				# we are merging a fifo or device node
				zing = "!!!"
				if mydmode is None:
					# destination doesn't exist
					if movefile(mysrc, mydest, newmtime=thismtime,
						sstat=mystat, mysettings=self.settings,
						encoding=_encodings['merge']) is not None:
						zing = ">>>"

						try:
							self._merged_path(mydest, os.lstat(mydest))
						except OSError:
							pass

					else:
						return 1
				if stat.S_ISFIFO(mymode):
					outfile.write("fif %s\n" % myrealdest)
				else:
					outfile.write("dev %s\n" % myrealdest)
				showMessage(zing + " " + mydest + "\n")

	def _merged_path(self, path, lstatobj, exists=True):
		previous_path = self._device_path_map.get(lstatobj.st_dev)
		if previous_path is None or previous_path is False or \
			(exists and len(path) < len(previous_path)):
			if exists:
				self._device_path_map[lstatobj.st_dev] = path
			else:
				# This entry is used to indicate that we've unmerged
				# a file from this device, and later, this entry is
				# replaced by a parent directory.
				self._device_path_map[lstatobj.st_dev] = False

	def _post_merge_sync(self):
		"""
		Call this after merge or unmerge, in order to sync relevant files to
		disk and avoid data-loss in the event of a power failure. This method
		does nothing if FEATURES=merge-sync is disabled.
		"""
		if not self._device_path_map or \
			"merge-sync" not in self.settings.features:
			return

		returncode = None
		if platform.system() == "Linux":

			paths = []
			for path in self._device_path_map.values():
				if path is not False:
					paths.append(path)
			paths = tuple(paths)

			proc = SyncfsProcess(paths=paths,
				scheduler=(self._scheduler or
					portage._internal_caller and global_event_loop() or
					EventLoop(main=False)))
			proc.start()
			returncode = proc.wait()

		if returncode is None or returncode != os.EX_OK:
			try:
				proc = subprocess.Popen(["sync"])
			except EnvironmentError:
				pass
			else:
				proc.wait()

	def merge(self, mergeroot, inforoot, myroot=None, myebuild=None, cleanup=0,
		mydbapi=None, prev_mtimes=None, counter=None):
		"""
		@param myroot: ignored, self._eroot is used instead
		"""
		myroot = None
		retval = -1
		parallel_install = "parallel-install" in self.settings.features
		if not parallel_install:
			self.lockdb()
		self.vartree.dbapi._bump_mtime(self.mycpv)
		if self._scheduler is None:
			self._scheduler = SchedulerInterface(portage._internal_caller and
				global_event_loop() or EventLoop(main=False))
		try:
			retval = self.treewalk(mergeroot, myroot, inforoot, myebuild,
				cleanup=cleanup, mydbapi=mydbapi, prev_mtimes=prev_mtimes,
				counter=counter)

			# If PORTAGE_BUILDDIR doesn't exist, then it probably means
			# fail-clean is enabled, and the success/die hooks have
			# already been called by EbuildPhase.
			if os.path.isdir(self.settings['PORTAGE_BUILDDIR']):

				if retval == os.EX_OK:
					phase = 'success_hooks'
				else:
					phase = 'die_hooks'

				ebuild_phase = MiscFunctionsProcess(
					background=False, commands=[phase],
					scheduler=self._scheduler, settings=self.settings)
				ebuild_phase.start()
				ebuild_phase.wait()
				self._elog_process()

				if 'noclean' not in self.settings.features and \
					(retval == os.EX_OK or \
					'fail-clean' in self.settings.features):
					if myebuild is None:
						myebuild = os.path.join(inforoot, self.pkg + ".ebuild")

					doebuild_environment(myebuild, "clean",
						settings=self.settings, db=mydbapi)
					phase = EbuildPhase(background=False, phase="clean",
						scheduler=self._scheduler, settings=self.settings)
					phase.start()
					phase.wait()
		finally:
			self.settings.pop('REPLACING_VERSIONS', None)
			if self.vartree.dbapi._linkmap is None:
				# preserve-libs is entirely disabled
				pass
			else:
				self.vartree.dbapi._linkmap._clear_cache()
			self.vartree.dbapi._bump_mtime(self.mycpv)
			if not parallel_install:
				self.unlockdb()
		return retval

	def getstring(self,name):
		"returns contents of a file with whitespace converted to spaces"
		if not os.path.exists(self.dbdir+"/"+name):
			return ""
		with io.open(
			_unicode_encode(os.path.join(self.dbdir, name),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace'
			) as f:
			mydata = f.read().split()
		return " ".join(mydata)

	def copyfile(self,fname):
		shutil.copyfile(fname,self.dbdir+"/"+os.path.basename(fname))

	def getfile(self,fname):
		if not os.path.exists(self.dbdir+"/"+fname):
			return ""
		with io.open(_unicode_encode(os.path.join(self.dbdir, fname),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace'
			) as f:
			return f.read()

	def setfile(self,fname,data):
		kwargs = {}
		if fname == 'environment.bz2' or not isinstance(data, basestring):
			kwargs['mode'] = 'wb'
		else:
			kwargs['mode'] = 'w'
			kwargs['encoding'] = _encodings['repo.content']
		write_atomic(os.path.join(self.dbdir, fname), data,
			**portage._native_kwargs(kwargs))

	def getelements(self,ename):
		if not os.path.exists(self.dbdir+"/"+ename):
			return []
		with io.open(_unicode_encode(
			os.path.join(self.dbdir, ename),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'], errors='replace'
			) as f:
			mylines = f.readlines()
		myreturn = []
		for x in mylines:
			for y in x[:-1].split():
				myreturn.append(y)
		return myreturn

	def setelements(self,mylist,ename):
		with io.open(_unicode_encode(
			os.path.join(self.dbdir, ename),
			encoding=_encodings['fs'], errors='strict'),
			mode='w', encoding=_encodings['repo.content'],
			errors='backslashreplace') as f:
			for x in mylist:
				f.write("%s\n" % x)

	def isregular(self):
		"Is this a regular package (does it have a CATEGORY file?  A dblink can be virtual *and* regular)"
		return os.path.exists(os.path.join(self.dbdir, "CATEGORY"))

	def _pre_merge_backup(self, backup_dblink, downgrade):

		if ("unmerge-backup" in self.settings.features or
			(downgrade and "downgrade-backup" in self.settings.features)):
			return self._quickpkg_dblink(backup_dblink, False, None)

		return os.EX_OK

	def _pre_unmerge_backup(self, background):

		if "unmerge-backup" in self.settings.features :
			logfile = None
			if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
				logfile = self.settings.get("PORTAGE_LOG_FILE")
			return self._quickpkg_dblink(self, background, logfile)

		return os.EX_OK

	def _quickpkg_dblink(self, backup_dblink, background, logfile):

		trees = QueryCommand.get_db()[self.settings["EROOT"]]
		bintree = trees["bintree"]
		binpkg_path = bintree.getname(backup_dblink.mycpv)
		if os.path.exists(binpkg_path) and \
			catsplit(backup_dblink.mycpv)[1] not in bintree.invalids:
			return os.EX_OK

		self.lockdb()
		try:

			if not backup_dblink.exists():
				# It got unmerged by a concurrent process.
				return os.EX_OK

			# Call quickpkg for support of QUICKPKG_DEFAULT_OPTS and stuff.
			quickpkg_binary = os.path.join(self.settings["PORTAGE_BIN_PATH"],
				"quickpkg")

			# Let quickpkg inherit the global vartree config's env.
			env = dict(self.vartree.settings.items())
			env["__PORTAGE_INHERIT_VARDB_LOCK"] = "1"

			pythonpath = [x for x in env.get('PYTHONPATH', '').split(":") if x]
			if not pythonpath or \
				not os.path.samefile(pythonpath[0], portage._pym_path):
				pythonpath.insert(0, portage._pym_path)
			env['PYTHONPATH'] = ":".join(pythonpath)

			quickpkg_proc = SpawnProcess(
				args=[portage._python_interpreter, quickpkg_binary,
					"=%s" % (backup_dblink.mycpv,)],
				background=background, env=env,
				scheduler=self._scheduler, logfile=logfile)
			quickpkg_proc.start()

			return quickpkg_proc.wait()

		finally:
			self.unlockdb()

def merge(mycat, mypkg, pkgloc, infloc,
	myroot=None, settings=None, myebuild=None,
	mytree=None, mydbapi=None, vartree=None, prev_mtimes=None, blockers=None,
	scheduler=None, fd_pipes=None):
	"""
	@param myroot: ignored, settings['EROOT'] is used instead
	"""
	myroot = None
	if settings is None:
		raise TypeError("settings argument is required")
	if not os.access(settings['EROOT'], os.W_OK):
		writemsg(_("Permission denied: access('%s', W_OK)\n") % settings['EROOT'],
			noiselevel=-1)
		return errno.EACCES
	background = (settings.get('PORTAGE_BACKGROUND') == '1')
	merge_task = MergeProcess(
		mycat=mycat, mypkg=mypkg, settings=settings,
		treetype=mytree, vartree=vartree,
		scheduler=(scheduler or portage._internal_caller and
			global_event_loop() or EventLoop(main=False)),
		background=background, blockers=blockers, pkgloc=pkgloc,
		infloc=infloc, myebuild=myebuild, mydbapi=mydbapi,
		prev_mtimes=prev_mtimes, logfile=settings.get('PORTAGE_LOG_FILE'),
		fd_pipes=fd_pipes)
	merge_task.start()
	retcode = merge_task.wait()
	return retcode

def unmerge(cat, pkg, myroot=None, settings=None,
	mytrimworld=None, vartree=None,
	ldpath_mtimes=None, scheduler=None):
	"""
	@param myroot: ignored, settings['EROOT'] is used instead
	@param mytrimworld: ignored
	"""
	myroot = None
	if settings is None:
		raise TypeError("settings argument is required")
	mylink = dblink(cat, pkg, settings=settings, treetype="vartree",
		vartree=vartree, scheduler=scheduler)
	vartree = mylink.vartree
	parallel_install = "parallel-install" in settings.features
	if not parallel_install:
		mylink.lockdb()
	try:
		if mylink.exists():
			retval = mylink.unmerge(ldpath_mtimes=ldpath_mtimes)
			if retval == os.EX_OK:
				mylink.lockdb()
				try:
					mylink.delete()
				finally:
					mylink.unlockdb()
			return retval
		return os.EX_OK
	finally:
		if vartree.dbapi._linkmap is None:
			# preserve-libs is entirely disabled
			pass
		else:
			vartree.dbapi._linkmap._clear_cache()
		if not parallel_install:
			mylink.unlockdb()

def write_contents(contents, root, f):
	"""
	Write contents to any file like object. The file will be left open.
	"""
	root_len = len(root) - 1
	for filename in sorted(contents):
		entry_data = contents[filename]
		entry_type = entry_data[0]
		relative_filename = filename[root_len:]
		if entry_type == "obj":
			entry_type, mtime, md5sum = entry_data
			line = "%s %s %s %s\n" % \
				(entry_type, relative_filename, md5sum, mtime)
		elif entry_type == "sym":
			entry_type, mtime, link = entry_data
			line = "%s %s -> %s %s\n" % \
				(entry_type, relative_filename, link, mtime)
		else: # dir, dev, fif
			line = "%s %s\n" % (entry_type, relative_filename)
		f.write(line)

def tar_contents(contents, root, tar, protect=None, onProgress=None):
	os = _os_merge
	encoding = _encodings['merge']

	try:
		for x in contents:
			_unicode_encode(x,
				encoding=_encodings['merge'],
				errors='strict')
	except UnicodeEncodeError:
		# The package appears to have been merged with a
		# different value of sys.getfilesystemencoding(),
		# so fall back to utf_8 if appropriate.
		try:
			for x in contents:
				_unicode_encode(x,
					encoding=_encodings['fs'],
					errors='strict')
		except UnicodeEncodeError:
			pass
		else:
			os = portage.os
			encoding = _encodings['fs']

	tar.encoding = encoding
	root = normalize_path(root).rstrip(os.path.sep) + os.path.sep
	id_strings = {}
	maxval = len(contents)
	curval = 0
	if onProgress:
		onProgress(maxval, 0)
	paths = list(contents)
	paths.sort()
	for path in paths:
		curval += 1
		try:
			lst = os.lstat(path)
		except OSError as e:
			if e.errno != errno.ENOENT:
				raise
			del e
			if onProgress:
				onProgress(maxval, curval)
			continue
		contents_type = contents[path][0]
		if path.startswith(root):
			arcname = "./" + path[len(root):]
		else:
			raise ValueError("invalid root argument: '%s'" % root)
		live_path = path
		if 'dir' == contents_type and \
			not stat.S_ISDIR(lst.st_mode) and \
			os.path.isdir(live_path):
			# Even though this was a directory in the original ${D}, it exists
			# as a symlink to a directory in the live filesystem.  It must be
			# recorded as a real directory in the tar file to ensure that tar
			# can properly extract it's children.
			live_path = os.path.realpath(live_path)
			lst = os.lstat(live_path)

		# Since os.lstat() inside TarFile.gettarinfo() can trigger a
		# UnicodeEncodeError when python has something other than utf_8
		# return from sys.getfilesystemencoding() (as in bug #388773),
		# we implement the needed functionality here, using the result
		# of our successful lstat call. An alternative to this would be
		# to pass in the fileobj argument to TarFile.gettarinfo(), so
		# that it could use fstat instead of lstat. However, that would
		# have the unwanted effect of dereferencing symlinks.

		tarinfo = tar.tarinfo()
		tarinfo.name = arcname
		tarinfo.mode = lst.st_mode
		tarinfo.uid = lst.st_uid
		tarinfo.gid = lst.st_gid
		tarinfo.size = 0
		tarinfo.mtime = lst.st_mtime
		tarinfo.linkname = ""
		if stat.S_ISREG(lst.st_mode):
			inode = (lst.st_ino, lst.st_dev)
			if (lst.st_nlink > 1 and
				inode in tar.inodes and
				arcname != tar.inodes[inode]):
				tarinfo.type = tarfile.LNKTYPE
				tarinfo.linkname = tar.inodes[inode]
			else:
				tar.inodes[inode] = arcname
				tarinfo.type = tarfile.REGTYPE
				tarinfo.size = lst.st_size
		elif stat.S_ISDIR(lst.st_mode):
			tarinfo.type = tarfile.DIRTYPE
		elif stat.S_ISLNK(lst.st_mode):
			tarinfo.type = tarfile.SYMTYPE
			tarinfo.linkname = os.readlink(live_path)
		else:
			continue
		try:
			tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0]
		except KeyError:
			pass
		try:
			tarinfo.gname = grp.getgrgid(tarinfo.gid)[0]
		except KeyError:
			pass

		if stat.S_ISREG(lst.st_mode):
			if protect and protect(path):
				# Create an empty file as a place holder in order to avoid
				# potential collision-protect issues.
				f = tempfile.TemporaryFile()
				f.write(_unicode_encode(
					"# empty file because --include-config=n " + \
					"when `quickpkg` was used\n"))
				f.flush()
				f.seek(0)
				tarinfo.size = os.fstat(f.fileno()).st_size
				tar.addfile(tarinfo, f)
				f.close()
			else:
				with open(_unicode_encode(path,
					encoding=encoding,
					errors='strict'), 'rb') as f:
					tar.addfile(tarinfo, f)

		else:
			tar.addfile(tarinfo)
		if onProgress:
			onProgress(maxval, curval)
