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

from __future__ import unicode_literals

__all__ = ["bindbapi", "binarytree"]

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.checksum:get_valid_checksum_keys,perform_multiple_checksums,' + \
		'verify_all,_apply_hash_filter,_hash_filter',
	'portage.dbapi.dep_expand:dep_expand',
	'portage.dep:dep_getkey,isjustname,isvalidatom,match_from_list',
	'portage.output:EOutput,colorize',
	'portage.locks:lockfile,unlockfile',
	'portage.package.ebuild.fetch:_check_distfile,_hide_url_passwd',
	'portage.update:update_dbentries',
	'portage.util:atomic_ofstream,ensure_dirs,normalize_path,' + \
		'writemsg,writemsg_stdout',
	'portage.util.path:first_existing',
	'portage.util._urlopen:urlopen@_urlopen,have_pep_476@_have_pep_476',
	'portage.versions:best,catpkgsplit,catsplit,_pkg_str',
)

from portage.cache.mappings import slot_dict_class
from portage.const import CACHE_PATH, SUPPORTED_XPAK_EXTENSIONS
from portage.dbapi.virtual import fakedbapi
from portage.dep import Atom, use_reduce, paren_enclose
from portage.exception import AlarmSignal, InvalidData, InvalidPackageName, \
	ParseError, PermissionDenied, PortageException
from portage.localization import _
from portage.package.ebuild.profile_iuse import iter_iuse_vars
from portage import _movefile
from portage import os
from portage import _encodings
from portage import _unicode_decode
from portage import _unicode_encode

import codecs
import errno
import io
import stat
import subprocess
import sys
import tempfile
import textwrap
import time
import traceback
import warnings
from gzip import GzipFile
from itertools import chain
try:
	from urllib.parse import urlparse
except ImportError:
	from urlparse import urlparse

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

class UseCachedCopyOfRemoteIndex(Exception):
	# If the local copy is recent enough
	# then fetching the remote index can be skipped.
	pass

class bindbapi(fakedbapi):
	_known_keys = frozenset(list(fakedbapi._known_keys) + \
		["CHOST", "repository", "USE"])
	def __init__(self, mybintree=None, **kwargs):
		# Always enable multi_instance mode for bindbapi indexing. This
		# does not affect the local PKGDIR file layout, since that is
		# controlled independently by FEATURES=binpkg-multi-instance.
		# The multi_instance mode is useful for the following reasons:
		# * binary packages with the same cpv from multiple binhosts
		#   can be considered simultaneously
		# * if binpkg-multi-instance is disabled, it's still possible
		#   to properly access a PKGDIR which has binpkg-multi-instance
		#   layout (or mixed layout)
		fakedbapi.__init__(self, exclusive_slots=False,
			multi_instance=True, **kwargs)
		self.bintree = mybintree
		self.move_ent = mybintree.move_ent
		# Selectively cache metadata in order to optimize dep matching.
		self._aux_cache_keys = set(
			["BDEPEND", "BUILD_ID", "BUILD_TIME", "CHOST", "DEFINED_PHASES",
			"DEPEND", "EAPI", "HDEPEND", "IUSE", "KEYWORDS",
			"LICENSE", "MD5", "PDEPEND", "PROPERTIES",
			"PROVIDES", "RDEPEND", "repository", "REQUIRES", "RESTRICT",
			"SIZE", "SLOT", "USE", "_mtime_"
			])
		self._aux_cache_slot_dict = slot_dict_class(self._aux_cache_keys)
		self._aux_cache = {}

	@property
	def writable(self):
		"""
		Check if PKGDIR is writable, or permissions are sufficient
		to create it if it does not exist yet.
		@rtype: bool
		@return: True if PKGDIR is writable or can be created,
			False otherwise
		"""
		return os.access(first_existing(self.bintree.pkgdir), os.W_OK)

	def match(self, *pargs, **kwargs):
		if self.bintree and not self.bintree.populated:
			self.bintree.populate()
		return fakedbapi.match(self, *pargs, **kwargs)

	def cpv_exists(self, cpv, myrepo=None):
		if self.bintree and not self.bintree.populated:
			self.bintree.populate()
		return fakedbapi.cpv_exists(self, cpv)

	def cpv_inject(self, cpv, **kwargs):
		if not self.bintree.populated:
			self.bintree.populate()
		fakedbapi.cpv_inject(self, cpv,
			metadata=cpv._metadata, **kwargs)

	def cpv_remove(self, cpv):
		if not self.bintree.populated:
			self.bintree.populate()
		fakedbapi.cpv_remove(self, cpv)

	def aux_get(self, mycpv, wants, myrepo=None):
		if self.bintree and not self.bintree.populated:
			self.bintree.populate()
		# Support plain string for backward compatibility with API
		# consumers (including portageq, which passes in a cpv from
		# a command-line argument).
		instance_key = self._instance_key(mycpv,
			support_string=True)
		if not self._known_keys.intersection(
			wants).difference(self._aux_cache_keys):
			aux_cache = self.cpvdict[instance_key]
			if aux_cache is not None:
				return [aux_cache.get(x, "") for x in wants]
		mysplit = mycpv.split("/")
		mylist = []
		if not self.bintree._remotepkgs or \
			not self.bintree.isremote(mycpv):
			try:
				tbz2_path = self.bintree._pkg_paths[instance_key]
			except KeyError:
				raise KeyError(mycpv)
			tbz2_path = os.path.join(self.bintree.pkgdir, tbz2_path)
			try:
				st = os.lstat(tbz2_path)
			except OSError:
				raise KeyError(mycpv)
			metadata_bytes = portage.xpak.tbz2(tbz2_path).get_data()
			def getitem(k):
				if k == "_mtime_":
					return _unicode(st[stat.ST_MTIME])
				elif k == "SIZE":
					return _unicode(st.st_size)
				v = metadata_bytes.get(_unicode_encode(k,
					encoding=_encodings['repo.content'],
					errors='backslashreplace'))
				if v is not None:
					v = _unicode_decode(v,
						encoding=_encodings['repo.content'], errors='replace')
				return v
		else:
			getitem = self.cpvdict[instance_key].get
		mydata = {}
		mykeys = wants
		for x in mykeys:
			myval = getitem(x)
			# myval is None if the key doesn't exist
			# or the tbz2 is corrupt.
			if myval:
				mydata[x] = " ".join(myval.split())

		if not mydata.setdefault('EAPI', '0'):
			mydata['EAPI'] = '0'

		return [mydata.get(x, '') for x in wants]

	def aux_update(self, cpv, values):
		if not self.bintree.populated:
			self.bintree.populate()
		build_id = None
		try:
			build_id = cpv.build_id
		except AttributeError:
			if self.bintree._multi_instance:
				# The cpv.build_id attribute is required if we are in
				# multi-instance mode, since otherwise we won't know
				# which instance to update.
				raise
			else:
				cpv = self._instance_key(cpv, support_string=True)[0]
				build_id = cpv.build_id

		tbz2path = self.bintree.getname(cpv)
		if not os.path.exists(tbz2path):
			raise KeyError(cpv)
		mytbz2 = portage.xpak.tbz2(tbz2path)
		mydata = mytbz2.get_data()

		for k, v in values.items():
			k = _unicode_encode(k,
				encoding=_encodings['repo.content'], errors='backslashreplace')
			v = _unicode_encode(v,
				encoding=_encodings['repo.content'], errors='backslashreplace')
			mydata[k] = v

		for k, v in list(mydata.items()):
			if not v:
				del mydata[k]
		mytbz2.recompose_mem(portage.xpak.xpak_mem(mydata))
		# inject will clear stale caches via cpv_inject.
		self.bintree.inject(cpv, filename=tbz2path)

	def cp_list(self, *pargs, **kwargs):
		if not self.bintree.populated:
			self.bintree.populate()
		return fakedbapi.cp_list(self, *pargs, **kwargs)

	def cp_all(self, sort=False):
		if not self.bintree.populated:
			self.bintree.populate()
		return fakedbapi.cp_all(self, sort=sort)

	def cpv_all(self):
		if not self.bintree.populated:
			self.bintree.populate()
		return fakedbapi.cpv_all(self)

	def getfetchsizes(self, pkg):
		"""
		This will raise MissingSignature if SIZE signature is not available,
		or InvalidSignature if SIZE signature is invalid.
		"""

		if not self.bintree.populated:
			self.bintree.populate()

		pkg = getattr(pkg, 'cpv', pkg)

		filesdict = {}
		if not self.bintree.isremote(pkg):
			pass
		else:
			metadata = self.bintree._remotepkgs[self._instance_key(pkg)]
			try:
				size = int(metadata["SIZE"])
			except KeyError:
				raise portage.exception.MissingSignature("SIZE")
			except ValueError:
				raise portage.exception.InvalidSignature(
					"SIZE: %s" % metadata["SIZE"])
			else:
				filesdict[os.path.basename(self.bintree.getname(pkg))] = size

		return filesdict

class binarytree(object):
	"this tree scans for a list of all packages available in PKGDIR"
	def __init__(self, _unused=DeprecationWarning, pkgdir=None,
		virtual=DeprecationWarning, settings=None):

		if pkgdir is None:
			raise TypeError("pkgdir parameter is required")

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

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

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

		if True:
			self.pkgdir = normalize_path(pkgdir)
			# NOTE: Event if binpkg-multi-instance is disabled, it's
			# still possible to access a PKGDIR which uses the
			# binpkg-multi-instance layout (or mixed layout).
			self._multi_instance = ("binpkg-multi-instance" in
				settings.features)
			if self._multi_instance:
				self._allocate_filename = self._allocate_filename_multi
			self.dbapi = bindbapi(self, settings=settings)
			self.update_ents = self.dbapi.update_ents
			self.move_slot_ent = self.dbapi.move_slot_ent
			self.populated = 0
			self.tree = {}
			self._remote_has_index = False
			self._remotepkgs = None # remote metadata indexed by cpv
			self.invalids = []
			self.settings = settings
			self._pkg_paths = {}
			self._populating = False
			self._all_directory = os.path.isdir(
				os.path.join(self.pkgdir, "All"))
			self._pkgindex_version = 0
			self._pkgindex_hashes = ["MD5","SHA1"]
			self._pkgindex_file = os.path.join(self.pkgdir, "Packages")
			self._pkgindex_keys = self.dbapi._aux_cache_keys.copy()
			self._pkgindex_keys.update(["CPV", "SIZE"])
			self._pkgindex_aux_keys = \
				["BASE_URI", "BDEPEND", "BUILD_ID", "BUILD_TIME", "CHOST",
				"DEFINED_PHASES", "DEPEND", "DESCRIPTION", "EAPI",
				"HDEPEND", "IUSE", "KEYWORDS", "LICENSE", "PDEPEND",
				"PKGINDEX_URI", "PROPERTIES", "PROVIDES",
				"RDEPEND", "repository", "REQUIRES", "RESTRICT",
				"SIZE", "SLOT", "USE"]
			self._pkgindex_aux_keys = list(self._pkgindex_aux_keys)
			self._pkgindex_use_evaluated_keys = \
				("BDEPEND", "DEPEND", "HDEPEND", "LICENSE", "RDEPEND",
				"PDEPEND", "PROPERTIES", "RESTRICT")
			self._pkgindex_header = None
			self._pkgindex_header_keys = set([
				"ACCEPT_KEYWORDS", "ACCEPT_LICENSE",
				"ACCEPT_PROPERTIES", "ACCEPT_RESTRICT", "CBUILD",
				"CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "FEATURES",
				"GENTOO_MIRRORS", "INSTALL_MASK", "IUSE_IMPLICIT", "USE",
				"USE_EXPAND", "USE_EXPAND_HIDDEN", "USE_EXPAND_IMPLICIT",
				"USE_EXPAND_UNPREFIXED"])
			self._pkgindex_default_pkg_data = {
				"BDEPEND" : "",
				"BUILD_ID"           : "",
				"BUILD_TIME"         : "",
				"DEFINED_PHASES"     : "",
				"DEPEND"  : "",
				"EAPI"    : "0",
				"HDEPEND" : "",
				"IUSE"    : "",
				"KEYWORDS": "",
				"LICENSE" : "",
				"PATH"    : "",
				"PDEPEND" : "",
				"PROPERTIES" : "",
				"PROVIDES": "",
				"RDEPEND" : "",
				"REQUIRES": "",
				"RESTRICT": "",
				"SLOT"    : "0",
				"USE"     : "",
			}
			self._pkgindex_inherited_keys = ["CHOST", "repository"]

			# Populate the header with appropriate defaults.
			self._pkgindex_default_header_data = {
				"CHOST"        : self.settings.get("CHOST", ""),
				"repository"   : "",
			}

			self._pkgindex_translated_keys = (
				("DESCRIPTION"   ,   "DESC"),
				("_mtime_"       ,   "MTIME"),
				("repository"    ,   "REPO"),
			)

			self._pkgindex_allowed_pkg_keys = set(chain(
				self._pkgindex_keys,
				self._pkgindex_aux_keys,
				self._pkgindex_hashes,
				self._pkgindex_default_pkg_data,
				self._pkgindex_inherited_keys,
				chain(*self._pkgindex_translated_keys)
			))

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

	def move_ent(self, mylist, repo_match=None):
		if not self.populated:
			self.populate()
		origcp = mylist[1]
		newcp = mylist[2]
		# sanity check
		for atom in (origcp, newcp):
			if not isjustname(atom):
				raise InvalidPackageName(_unicode(atom))
		mynewcat = catsplit(newcp)[0]
		origmatches=self.dbapi.cp_list(origcp)
		moves = 0
		if not origmatches:
			return moves
		for mycpv in origmatches:
			try:
				mycpv = self.dbapi._pkg_str(mycpv, None)
			except (KeyError, InvalidData):
				continue
			mycpv_cp = portage.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)
			myoldpkg = catsplit(mycpv)[1]
			mynewpkg = catsplit(mynewcpv)[1]

			if (mynewpkg != myoldpkg) and os.path.exists(self.getname(mynewcpv)):
				writemsg(_("!!! Cannot update binary: Destination exists.\n"),
					noiselevel=-1)
				writemsg("!!! "+mycpv+" -> "+mynewcpv+"\n", noiselevel=-1)
				continue

			tbz2path = self.getname(mycpv)
			if os.path.exists(tbz2path) and not os.access(tbz2path,os.W_OK):
				writemsg(_("!!! Cannot update readonly binary: %s\n") % mycpv,
					noiselevel=-1)
				continue

			moves += 1
			mytbz2 = portage.xpak.tbz2(tbz2path)
			mydata = mytbz2.get_data()
			updated_items = update_dbentries([mylist], mydata, parent=mycpv)
			mydata.update(updated_items)
			mydata[b'PF'] = \
				_unicode_encode(mynewpkg + "\n",
				encoding=_encodings['repo.content'])
			mydata[b'CATEGORY'] = \
				_unicode_encode(mynewcat + "\n",
				encoding=_encodings['repo.content'])
			if mynewpkg != myoldpkg:
				ebuild_data = mydata.pop(_unicode_encode(myoldpkg + '.ebuild',
					encoding=_encodings['repo.content']), None)
				if ebuild_data is not None:
					mydata[_unicode_encode(mynewpkg + '.ebuild',
						encoding=_encodings['repo.content'])] = ebuild_data

			mytbz2.recompose_mem(portage.xpak.xpak_mem(mydata))

			self.dbapi.cpv_remove(mycpv)
			del self._pkg_paths[self.dbapi._instance_key(mycpv)]
			metadata = self.dbapi._aux_cache_slot_dict()
			for k in self.dbapi._aux_cache_keys:
				v = mydata.get(_unicode_encode(k))
				if v is not None:
					v = _unicode_decode(v)
					metadata[k] = " ".join(v.split())
			mynewcpv = _pkg_str(mynewcpv, metadata=metadata, db=self.dbapi)
			new_path = self.getname(mynewcpv)
			self._pkg_paths[
				self.dbapi._instance_key(mynewcpv)] = new_path[len(self.pkgdir)+1:]
			if new_path != mytbz2:
				self._ensure_dir(os.path.dirname(new_path))
				_movefile(tbz2path, new_path, mysettings=self.settings)
			self.inject(mynewcpv)

		return moves

	def prevent_collision(self, cpv):
		warnings.warn("The "
			"portage.dbapi.bintree.binarytree.prevent_collision "
			"method is deprecated.",
			DeprecationWarning, stacklevel=2)

	def _ensure_dir(self, path):
		"""
		Create the specified directory. Also, copy gid and group mode
		bits from self.pkgdir if possible.
		@param cat_dir: Absolute path of the directory to be created.
		@type cat_dir: String
		"""
		try:
			pkgdir_st = os.stat(self.pkgdir)
		except OSError:
			ensure_dirs(path)
			return
		pkgdir_gid = pkgdir_st.st_gid
		pkgdir_grp_mode = 0o2070 & pkgdir_st.st_mode
		try:
			ensure_dirs(path, gid=pkgdir_gid, mode=pkgdir_grp_mode, mask=0)
		except PortageException:
			if not os.path.isdir(path):
				raise

	def _file_permissions(self, path):
		try:
			pkgdir_st = os.stat(self.pkgdir)
		except OSError:
			pass
		else:
			pkgdir_gid = pkgdir_st.st_gid
			pkgdir_grp_mode = 0o0060 & pkgdir_st.st_mode
			try:
				portage.util.apply_permissions(path, gid=pkgdir_gid,
					mode=pkgdir_grp_mode, mask=0)
			except PortageException:
				pass

	def populate(self, getbinpkgs=False, getbinpkg_refresh=True):
		"""
		Populates the binarytree with package metadata.

		@param getbinpkgs: include remote packages
		@type getbinpkgs: bool
		@param getbinpkg_refresh: attempt to refresh the cache
			of remote package metadata if getbinpkgs is also True
		@type getbinpkg_refresh: bool
		"""

		if self._populating:
			return

		if not os.path.isdir(self.pkgdir) and not getbinpkgs:
			self.populated = True
			return

		# Clear all caches in case populate is called multiple times
		# as may be the case when _global_updates calls populate()
		# prior to performing package moves since it only wants to
		# operate on local packages (getbinpkgs=0).
		self._remotepkgs = None

		self._populating = True
		try:
			update_pkgindex = self._populate_local(
				reindex='pkgdir-index-trusted' not in self.settings.features)

			if update_pkgindex and self.dbapi.writable:
				# If the Packages file needs to be updated, then _populate_local
				# needs to be called once again while the file is locked, so
				# that changes made by a concurrent process cannot be lost. This
				# case is avoided when possible, in order to minimize lock
				# contention.
				pkgindex_lock = None
				try:
					pkgindex_lock = lockfile(self._pkgindex_file,
						wantnewlockfile=True)
					update_pkgindex = self._populate_local()
					if update_pkgindex:
						self._pkgindex_write(update_pkgindex)
				finally:
					if pkgindex_lock:
						unlockfile(pkgindex_lock)

			if getbinpkgs:
				if not self.settings.get("PORTAGE_BINHOST"):
					writemsg(_("!!! PORTAGE_BINHOST unset, but use is requested.\n"),
						noiselevel=-1)
				else:
					self._populate_remote(getbinpkg_refresh=getbinpkg_refresh)

		finally:
			self._populating = False

		self.populated = True

	def _populate_local(self, reindex=True):
		"""
		Populates the binarytree with local package metadata.

		@param reindex: detect added / modified / removed packages and
			regenerate the index file if necessary
		@type reindex: bool
		"""
		self.dbapi.clear()
		_instance_key = self.dbapi._instance_key
		# In order to minimize disk I/O, we never compute digests here.
		# Therefore we exclude hashes from the minimum_keys, so that
		# the Packages file will not be needlessly re-written due to
		# missing digests.
		minimum_keys = self._pkgindex_keys.difference(self._pkgindex_hashes)
		if True:
			pkg_paths = {}
			self._pkg_paths = pkg_paths
			dir_files = {}
			if reindex:
				for parent, dir_names, file_names in os.walk(self.pkgdir):
					relative_parent = parent[len(self.pkgdir)+1:]
					dir_files[relative_parent] = file_names

			pkgindex = self._load_pkgindex()
			if not self._pkgindex_version_supported(pkgindex):
				pkgindex = self._new_pkgindex()
			metadata = {}
			basename_index = {}
			for d in pkgindex.packages:
				cpv = _pkg_str(d["CPV"], metadata=d,
					settings=self.settings, db=self.dbapi)
				d["CPV"] = cpv
				metadata[_instance_key(cpv)] = d
				path = d.get("PATH")
				if not path:
					path = cpv + ".tbz2"

				if reindex:
					basename = os.path.basename(path)
					basename_index.setdefault(basename, []).append(d)
				else:
					instance_key = _instance_key(cpv)
					pkg_paths[instance_key] = path
					self.dbapi.cpv_inject(cpv)

			update_pkgindex = False
			for mydir, file_names in dir_files.items():
				try:
					mydir = _unicode_decode(mydir,
						encoding=_encodings["fs"], errors="strict")
				except UnicodeDecodeError:
					continue
				for myfile in file_names:
					try:
						myfile = _unicode_decode(myfile,
							encoding=_encodings["fs"], errors="strict")
					except UnicodeDecodeError:
						continue
					if not myfile.endswith(SUPPORTED_XPAK_EXTENSIONS):
						continue
					# Filter out FEATURES=separatedebug archives.
					if myfile.endswith('.debug.tbz2'):
						continue
					mypath = os.path.join(mydir, myfile)
					full_path = os.path.join(self.pkgdir, mypath)
					s = os.lstat(full_path)

					if not stat.S_ISREG(s.st_mode):
						continue

					# Validate data from the package index and try to avoid
					# reading the xpak if possible.
					possibilities = basename_index.get(myfile)
					if possibilities:
						match = None
						for d in possibilities:
							try:
								if long(d["_mtime_"]) != s[stat.ST_MTIME]:
									continue
							except (KeyError, ValueError):
								continue
							try:
								if long(d["SIZE"]) != long(s.st_size):
									continue
							except (KeyError, ValueError):
								continue
							if not minimum_keys.difference(d):
								match = d
								break
						if match:
							mycpv = match["CPV"]
							instance_key = _instance_key(mycpv)
							pkg_paths[instance_key] = mypath
							# update the path if the package has been moved
							oldpath = d.get("PATH")
							if oldpath and oldpath != mypath:
								update_pkgindex = True
							# Omit PATH if it is the default path for
							# the current Packages format version.
							if mypath != mycpv + ".tbz2":
								d["PATH"] = mypath
								if not oldpath:
									update_pkgindex = True
							else:
								d.pop("PATH", None)
								if oldpath:
									update_pkgindex = True
							self.dbapi.cpv_inject(mycpv)
							continue
					if not os.access(full_path, os.R_OK):
						writemsg(_("!!! Permission denied to read " \
							"binary package: '%s'\n") % full_path,
							noiselevel=-1)
						self.invalids.append(myfile[:-5])
						continue
					pkg_metadata = self._read_metadata(full_path, s,
						keys=chain(self.dbapi._aux_cache_keys,
						("PF", "CATEGORY")))
					mycat = pkg_metadata.get("CATEGORY", "")
					mypf = pkg_metadata.get("PF", "")
					slot = pkg_metadata.get("SLOT", "")
					mypkg = myfile[:-5]
					if not mycat or not mypf or not slot:
						#old-style or corrupt package
						writemsg(_("\n!!! Invalid binary package: '%s'\n") % full_path,
							noiselevel=-1)
						missing_keys = []
						if not mycat:
							missing_keys.append("CATEGORY")
						if not mypf:
							missing_keys.append("PF")
						if not slot:
							missing_keys.append("SLOT")
						msg = []
						if missing_keys:
							missing_keys.sort()
							msg.append(_("Missing metadata key(s): %s.") % \
								", ".join(missing_keys))
						msg.append(_(" This binary package is not " \
							"recoverable and should be deleted."))
						for line in textwrap.wrap("".join(msg), 72):
							writemsg("!!! %s\n" % line, noiselevel=-1)
						self.invalids.append(mypkg)
						continue

					multi_instance = False
					invalid_name = False
					build_id = None
					if myfile.endswith(".xpak"):
						multi_instance = True
						build_id = self._parse_build_id(myfile)
						if build_id < 1:
							invalid_name = True
						elif myfile != "%s-%s.xpak" % (
							mypf, build_id):
							invalid_name = True
						else:
							mypkg = mypkg[:-len(str(build_id))-1]
					elif myfile.endswith('.debug.tbz2'):
						# Files generated by FEATURES=separatedebug.
						continue
					elif myfile != mypf + ".tbz2":
						invalid_name = True

					if invalid_name:
						writemsg(_("\n!!! Binary package name is "
							"invalid: '%s'\n") % full_path,
							noiselevel=-1)
						continue

					if pkg_metadata.get("BUILD_ID"):
						try:
							build_id = long(pkg_metadata["BUILD_ID"])
						except ValueError:
							writemsg(_("!!! Binary package has "
								"invalid BUILD_ID: '%s'\n") %
								full_path, noiselevel=-1)
							continue
					else:
						build_id = None

					if multi_instance:
						name_split = catpkgsplit("%s/%s" %
							(mycat, mypf))
						if (name_split is None or
							tuple(catsplit(mydir)) != name_split[:2]):
							continue
					elif mycat != mydir and mydir != "All":
						continue
					if mypkg != mypf.strip():
						continue
					mycpv = mycat + "/" + mypkg
					if not self.dbapi._category_re.match(mycat):
						writemsg(_("!!! Binary package has an " \
							"unrecognized category: '%s'\n") % full_path,
							noiselevel=-1)
						writemsg(_("!!! '%s' has a category that is not" \
							" listed in %setc/portage/categories\n") % \
							(mycpv, self.settings["PORTAGE_CONFIGROOT"]),
							noiselevel=-1)
						continue
					if build_id is not None:
						pkg_metadata["BUILD_ID"] = _unicode(build_id)
					pkg_metadata["SIZE"] = _unicode(s.st_size)
					# Discard items used only for validation above.
					pkg_metadata.pop("CATEGORY")
					pkg_metadata.pop("PF")
					mycpv = _pkg_str(mycpv,
						metadata=self.dbapi._aux_cache_slot_dict(pkg_metadata),
						db=self.dbapi)
					pkg_paths[_instance_key(mycpv)] = mypath
					self.dbapi.cpv_inject(mycpv)
					update_pkgindex = True
					d = metadata.get(_instance_key(mycpv),
						pkgindex._pkg_slot_dict())
					if d:
						try:
							if long(d["_mtime_"]) != s[stat.ST_MTIME]:
								d.clear()
						except (KeyError, ValueError):
							d.clear()
					if d:
						try:
							if long(d["SIZE"]) != long(s.st_size):
								d.clear()
						except (KeyError, ValueError):
							d.clear()

					for k in self._pkgindex_allowed_pkg_keys:
						v = pkg_metadata.get(k)
						if v:
							d[k] = v
					d["CPV"] = mycpv

					try:
						self._eval_use_flags(mycpv, d)
					except portage.exception.InvalidDependString:
						writemsg(_("!!! Invalid binary package: '%s'\n") % \
							self.getname(mycpv), noiselevel=-1)
						self.dbapi.cpv_remove(mycpv)
						del pkg_paths[_instance_key(mycpv)]

					# record location if it's non-default
					if mypath != mycpv + ".tbz2":
						d["PATH"] = mypath
					else:
						d.pop("PATH", None)
					metadata[_instance_key(mycpv)] = d

			if reindex:
				for instance_key in list(metadata):
					if instance_key not in pkg_paths:
						del metadata[instance_key]

			if update_pkgindex:
				del pkgindex.packages[:]
				pkgindex.packages.extend(iter(metadata.values()))
				self._update_pkgindex_header(pkgindex.header)

			self._pkgindex_header = {}
			self._merge_pkgindex_header(pkgindex.header,
				self._pkgindex_header)

		return pkgindex if update_pkgindex else None

	def _populate_remote(self, getbinpkg_refresh=True):

		self._remote_has_index = False
		self._remotepkgs = {}
		for base_url in self.settings["PORTAGE_BINHOST"].split():
			parsed_url = urlparse(base_url)
			host = parsed_url.netloc
			port = parsed_url.port
			user = None
			passwd = None
			user_passwd = ""
			if "@" in host:
				user, host = host.split("@", 1)
				user_passwd = user + "@"
				if ":" in user:
					user, passwd = user.split(":", 1)

			if port is not None:
				port_str = ":%s" % (port,)
				if host.endswith(port_str):
					host = host[:-len(port_str)]
			pkgindex_file = os.path.join(self.settings["EROOT"], CACHE_PATH, "binhost",
				host, parsed_url.path.lstrip("/"), "Packages")
			pkgindex = self._new_pkgindex()
			try:
				f = io.open(_unicode_encode(pkgindex_file,
					encoding=_encodings['fs'], errors='strict'),
					mode='r', encoding=_encodings['repo.content'],
					errors='replace')
				try:
					pkgindex.read(f)
				finally:
					f.close()
			except EnvironmentError as e:
				if e.errno != errno.ENOENT:
					raise
			local_timestamp = pkgindex.header.get("TIMESTAMP", None)
			try:
				download_timestamp = \
					float(pkgindex.header.get("DOWNLOAD_TIMESTAMP", 0))
			except ValueError:
				download_timestamp = 0
			remote_timestamp = None
			rmt_idx = self._new_pkgindex()
			proc = None
			tmp_filename = None
			try:
				# urlparse.urljoin() only works correctly with recognized
				# protocols and requires the base url to have a trailing
				# slash, so join manually...
				url = base_url.rstrip("/") + "/Packages"
				f = None

				if not getbinpkg_refresh and local_timestamp:
					raise UseCachedCopyOfRemoteIndex()

				try:
					ttl = float(pkgindex.header.get("TTL", 0))
				except ValueError:
					pass
				else:
					if download_timestamp and ttl and \
						download_timestamp + ttl > time.time():
						raise UseCachedCopyOfRemoteIndex()

				# Don't use urlopen for https, unless
				# PEP 476 is supported (bug #469888).
				if parsed_url.scheme not in ('https',) or _have_pep_476():
					try:
						f = _urlopen(url, if_modified_since=local_timestamp)
						if hasattr(f, 'headers') and f.headers.get('timestamp', ''):
							remote_timestamp = f.headers.get('timestamp')
					except IOError as err:
						if hasattr(err, 'code') and err.code == 304: # not modified (since local_timestamp)
							raise UseCachedCopyOfRemoteIndex()

						if parsed_url.scheme in ('ftp', 'http', 'https'):
							# This protocol is supposedly supported by urlopen,
							# so apparently there's a problem with the url
							# or a bug in urlopen.
							if self.settings.get("PORTAGE_DEBUG", "0") != "0":
								traceback.print_exc()

							raise
					except ValueError:
						raise ParseError("Invalid Portage BINHOST value '%s'"
										 % url.lstrip())

				if f is None:

					path = parsed_url.path.rstrip("/") + "/Packages"

					if parsed_url.scheme == 'ssh':
						# Use a pipe so that we can terminate the download
						# early if we detect that the TIMESTAMP header
						# matches that of the cached Packages file.
						ssh_args = ['ssh']
						if port is not None:
							ssh_args.append("-p%s" % (port,))
						# NOTE: shlex evaluates embedded quotes
						ssh_args.extend(portage.util.shlex_split(
							self.settings.get("PORTAGE_SSH_OPTS", "")))
						ssh_args.append(user_passwd + host)
						ssh_args.append('--')
						ssh_args.append('cat')
						ssh_args.append(path)

						proc = subprocess.Popen(ssh_args,
							stdout=subprocess.PIPE)
						f = proc.stdout
					else:
						setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper()
						fcmd = self.settings.get(setting)
						if not fcmd:
							fcmd = self.settings.get('FETCHCOMMAND')
							if not fcmd:
								raise EnvironmentError("FETCHCOMMAND is unset")

						fd, tmp_filename = tempfile.mkstemp()
						tmp_dirname, tmp_basename = os.path.split(tmp_filename)
						os.close(fd)

						fcmd_vars = {
							"DISTDIR": tmp_dirname,
							"FILE": tmp_basename,
							"URI": url
						}

						for k in ("PORTAGE_SSH_OPTS",):
							v = self.settings.get(k)
							if v is not None:
								fcmd_vars[k] = v

						success = portage.getbinpkg.file_get(
							fcmd=fcmd, fcmd_vars=fcmd_vars)
						if not success:
							raise EnvironmentError("%s failed" % (setting,))
						f = open(tmp_filename, 'rb')

				f_dec = codecs.iterdecode(f,
					_encodings['repo.content'], errors='replace')
				try:
					rmt_idx.readHeader(f_dec)
					if not remote_timestamp: # in case it had not been read from HTTP header
						remote_timestamp = rmt_idx.header.get("TIMESTAMP", None)
					if not remote_timestamp:
						# no timestamp in the header, something's wrong
						pkgindex = None
						writemsg(_("\n\n!!! Binhost package index " \
						" has no TIMESTAMP field.\n"), noiselevel=-1)
					else:
						if not self._pkgindex_version_supported(rmt_idx):
							writemsg(_("\n\n!!! Binhost package index version" \
							" is not supported: '%s'\n") % \
							rmt_idx.header.get("VERSION"), noiselevel=-1)
							pkgindex = None
						elif local_timestamp != remote_timestamp:
							rmt_idx.readBody(f_dec)
							pkgindex = rmt_idx
				finally:
					# Timeout after 5 seconds, in case close() blocks
					# indefinitely (see bug #350139).
					try:
						try:
							AlarmSignal.register(5)
							f.close()
						finally:
							AlarmSignal.unregister()
					except AlarmSignal:
						writemsg("\n\n!!! %s\n" % \
							_("Timed out while closing connection to binhost"),
							noiselevel=-1)
			except UseCachedCopyOfRemoteIndex:
				rmt_idx = pkgindex
			except EnvironmentError as e:
				# This includes URLError which is raised for SSL
				# certificate errors when PEP 476 is supported.
				writemsg(_("\n\n!!! Error fetching binhost package" \
					" info from '%s'\n") % _hide_url_passwd(base_url))
				# With Python 2, the EnvironmentError message may
				# contain bytes or unicode, so use _unicode to ensure
				# safety with all locales (bug #532784).
				try:
					error_msg = _unicode(e)
				except UnicodeDecodeError as uerror:
					error_msg = _unicode(uerror.object,
						encoding='utf_8', errors='replace')
				writemsg("!!! %s\n\n" % error_msg)
				del e
				pkgindex = None
			if proc is not None:
				if proc.poll() is None:
					proc.kill()
					proc.wait()
				proc = None
			if tmp_filename is not None:
				try:
					os.unlink(tmp_filename)
				except OSError:
					pass
			if pkgindex is rmt_idx:
				pkgindex.modified = False # don't update the header
				pkgindex.header["DOWNLOAD_TIMESTAMP"] = "%d" % time.time()
				try:
					ensure_dirs(os.path.dirname(pkgindex_file))
					f = atomic_ofstream(pkgindex_file)
					pkgindex.write(f)
					f.close()
				except (IOError, PortageException):
					if os.access(os.path.dirname(pkgindex_file), os.W_OK):
						raise
					# The current user doesn't have permission to cache the
					# file, but that's alright.
			if pkgindex:
				remote_base_uri = pkgindex.header.get("URI", base_url)
				for d in pkgindex.packages:
					cpv = _pkg_str(d["CPV"], metadata=d,
						settings=self.settings, db=self.dbapi)
					# Local package instances override remote instances
					# with the same instance_key.
					if self.dbapi.cpv_exists(cpv):
						continue

					# Clear the build time before inserting the binpkg details.
					# In CrOS, we want the order of the PORTAGE_BINHOST setting
					# to dictate preference rather than the build time.
					# https://crbug.com/809312
					d = dict(d)
					d['BUILD_TIME'] = 0
					cpv = _pkg_str(d['CPV'], metadata=d, settings=self.settings,
								   db=self.dbapi)

					d["CPV"] = cpv
					d["BASE_URI"] = remote_base_uri
					d["PKGINDEX_URI"] = url
					self._remotepkgs[self.dbapi._instance_key(cpv)] = d
					self.dbapi.cpv_inject(cpv)

				self._remote_has_index = True
				self._merge_pkgindex_header(pkgindex.header,
					self._pkgindex_header)

	def inject(self, cpv, filename=None):
		"""Add a freshly built package to the database.  This updates
		$PKGDIR/Packages with the new package metadata (including MD5).
		@param cpv: The cpv of the new package to inject
		@type cpv: string
		@param filename: File path of the package to inject, or None if it's
			already in the location returned by getname()
		@type filename: string
		@rtype: _pkg_str or None
		@return: A _pkg_str instance on success, or None on failure.
		"""
		mycat, mypkg = catsplit(cpv)
		if not self.populated:
			self.populate()
		if filename is None:
			full_path = self.getname(cpv)
		else:
			full_path = filename
		try:
			s = os.stat(full_path)
		except OSError as e:
			if e.errno != errno.ENOENT:
				raise
			del e
			writemsg(_("!!! Binary package does not exist: '%s'\n") % full_path,
				noiselevel=-1)
			return
		metadata = self._read_metadata(full_path, s)
		invalid_depend = False
		try:
			self._eval_use_flags(cpv, metadata)
		except portage.exception.InvalidDependString:
			invalid_depend = True
		if invalid_depend or not metadata.get("SLOT"):
			writemsg(_("!!! Invalid binary package: '%s'\n") % full_path,
				noiselevel=-1)
			return

		fetched = False
		try:
			build_id = cpv.build_id
		except AttributeError:
			build_id = None
		else:
			instance_key = self.dbapi._instance_key(cpv)
			if instance_key in self.dbapi.cpvdict:
				# This means we've been called by aux_update (or
				# similar). The instance key typically changes (due to
				# file modification), so we need to discard existing
				# instance key references.
				self.dbapi.cpv_remove(cpv)
				self._pkg_paths.pop(instance_key, None)
				if self._remotepkgs is not None:
					fetched = self._remotepkgs.pop(instance_key, None)

		cpv = _pkg_str(cpv, metadata=metadata, settings=self.settings,
			db=self.dbapi)

		# Reread the Packages index (in case it's been changed by another
		# process) and then updated it, all while holding a lock.
		pkgindex_lock = None
		try:
			pkgindex_lock = lockfile(self._pkgindex_file,
				wantnewlockfile=1)
			if filename is not None:
				new_filename = self.getname(cpv, allocate_new=True)
				try:
					samefile = os.path.samefile(filename, new_filename)
				except OSError:
					samefile = False
				if not samefile:
					self._ensure_dir(os.path.dirname(new_filename))
					_movefile(filename, new_filename, mysettings=self.settings)
				full_path = new_filename

			basename = os.path.basename(full_path)
			pf = catsplit(cpv)[1]
			if (build_id is None and not fetched and
				basename.endswith(".xpak")):
				# Apply the newly assigned BUILD_ID. This is intended
				# to occur only for locally built packages. If the
				# package was fetched, we want to preserve its
				# attributes, so that we can later distinguish that it
				# is identical to its remote counterpart.
				build_id = self._parse_build_id(basename)
				metadata["BUILD_ID"] = _unicode(build_id)
				cpv = _pkg_str(cpv, metadata=metadata,
					settings=self.settings, db=self.dbapi)
				binpkg = portage.xpak.tbz2(full_path)
				binary_data = binpkg.get_data()
				binary_data[b"BUILD_ID"] = _unicode_encode(
					metadata["BUILD_ID"])
				binpkg.recompose_mem(portage.xpak.xpak_mem(binary_data))

			self._file_permissions(full_path)
			pkgindex = self._load_pkgindex()
			if not self._pkgindex_version_supported(pkgindex):
				pkgindex = self._new_pkgindex()

			d = self._inject_file(pkgindex, cpv, full_path)
			self._update_pkgindex_header(pkgindex.header)
			self._pkgindex_write(pkgindex)

		finally:
			if pkgindex_lock:
				unlockfile(pkgindex_lock)

		# This is used to record BINPKGMD5 in the installed package
		# database, for a package that has just been built.
		cpv._metadata["MD5"] = d["MD5"]

		return cpv

	def _read_metadata(self, filename, st, keys=None):
		"""
		Read metadata from a binary package. The returned metadata
		dictionary will contain empty strings for any values that
		are undefined (this is important because the _pkg_str class
		distinguishes between missing and undefined values).

		@param filename: File path of the binary package
		@type filename: string
		@param st: stat result for the binary package
		@type st: os.stat_result
		@param keys: optional list of specific metadata keys to retrieve
		@type keys: iterable
		@rtype: dict
		@return: package metadata
		"""
		if keys is None:
			keys = self.dbapi._aux_cache_keys
			metadata = self.dbapi._aux_cache_slot_dict()
		else:
			metadata = {}
		binary_metadata = portage.xpak.tbz2(filename).get_data()
		for k in keys:
			if k == "_mtime_":
				metadata[k] = _unicode(st[stat.ST_MTIME])
			elif k == "SIZE":
				metadata[k] = _unicode(st.st_size)
			else:
				v = binary_metadata.get(_unicode_encode(k))
				if v is None:
					if k == "EAPI":
						metadata[k] = "0"
					else:
						metadata[k] = ""
				else:
					v = _unicode_decode(v)
					metadata[k] = " ".join(v.split())
		return metadata

	def _inject_file(self, pkgindex, cpv, filename):
		"""
		Add a package to internal data structures, and add an
		entry to the given pkgindex.
		@param pkgindex: The PackageIndex instance to which an entry
			will be added.
		@type pkgindex: PackageIndex
		@param cpv: A _pkg_str instance corresponding to the package
			being injected.
		@type cpv: _pkg_str
		@param filename: Absolute file path of the package to inject.
		@type filename: string
		@rtype: dict
		@return: A dict corresponding to the new entry which has been
			added to pkgindex. This may be used to access the checksums
			which have just been generated.
		"""
		# Update state for future isremote calls.
		instance_key = self.dbapi._instance_key(cpv)
		if self._remotepkgs is not None:
			self._remotepkgs.pop(instance_key, None)

		self.dbapi.cpv_inject(cpv)
		self._pkg_paths[instance_key] = filename[len(self.pkgdir)+1:]
		d = self._pkgindex_entry(cpv)

		# If found, remove package(s) with duplicate path.
		path = d.get("PATH", "")
		for i in range(len(pkgindex.packages) - 1, -1, -1):
			d2 = pkgindex.packages[i]
			if path and path == d2.get("PATH"):
				# Handle path collisions in $PKGDIR/All
				# when CPV is not identical.
				del pkgindex.packages[i]
			elif cpv == d2.get("CPV"):
				if path == d2.get("PATH", ""):
					del pkgindex.packages[i]

		pkgindex.packages.append(d)
		return d

	def _pkgindex_write(self, pkgindex):
		contents = codecs.getwriter(_encodings['repo.content'])(io.BytesIO())
		pkgindex.write(contents)
		contents = contents.getvalue()
		atime = mtime = long(pkgindex.header["TIMESTAMP"])
		output_files = [(atomic_ofstream(self._pkgindex_file, mode="wb"),
			self._pkgindex_file, None)]

		if "compress-index" in self.settings.features:
			gz_fname = self._pkgindex_file + ".gz"
			fileobj = atomic_ofstream(gz_fname, mode="wb")
			output_files.append((GzipFile(filename='', mode="wb",
				fileobj=fileobj, mtime=mtime), gz_fname, fileobj))

		for f, fname, f_close in output_files:
			f.write(contents)
			f.close()
			if f_close is not None:
				f_close.close()
			self._file_permissions(fname)
			# some seconds might have elapsed since TIMESTAMP
			os.utime(fname, (atime, mtime))

	def _pkgindex_entry(self, cpv):
		"""
		Performs checksums, and gets size and mtime via lstat.
		Raises InvalidDependString if necessary.
		@rtype: dict
		@return: a dict containing entry for the give cpv.
		"""

		pkg_path = self.getname(cpv)

		d = dict(cpv._metadata.items())
		d.update(perform_multiple_checksums(
			pkg_path, hashes=self._pkgindex_hashes))

		d["CPV"] = cpv
		st = os.lstat(pkg_path)
		d["_mtime_"] = _unicode(st[stat.ST_MTIME])
		d["SIZE"] = _unicode(st.st_size)

		rel_path = pkg_path[len(self.pkgdir)+1:]
		# record location if it's non-default
		if rel_path != cpv + ".tbz2":
			d["PATH"] = rel_path

		return d

	def _new_pkgindex(self):
		return portage.getbinpkg.PackageIndex(
			allowed_pkg_keys=self._pkgindex_allowed_pkg_keys,
			default_header_data=self._pkgindex_default_header_data,
			default_pkg_data=self._pkgindex_default_pkg_data,
			inherited_keys=self._pkgindex_inherited_keys,
			translated_keys=self._pkgindex_translated_keys)

	@staticmethod
	def _merge_pkgindex_header(src, dest):
		"""
		Merge Packages header settings from src to dest, in order to
		propagate implicit IUSE and USE_EXPAND settings for use with
		binary and installed packages. Values are appended, so the
		result is a union of elements from src and dest.

		Pull in ARCH if it's not defined, since it's used for validation
		by emerge's profile_check function, and also for KEYWORDS logic
		in the _getmaskingstatus function.

		@param src: source mapping (read only)
		@type src: Mapping
		@param dest: destination mapping
		@type dest: MutableMapping
		"""
		for k, v in iter_iuse_vars(src):
			v_before = dest.get(k)
			if v_before is not None:
				merged_values = set(v_before.split())
				merged_values.update(v.split())
				v = ' '.join(sorted(merged_values))
			dest[k] = v

		if 'ARCH' not in dest and 'ARCH' in src:
			dest['ARCH'] = src['ARCH']

	def _propagate_config(self, config):
		"""
		Propagate implicit IUSE and USE_EXPAND settings from the binary
		package database to a config instance. If settings are not
		available to propagate, then this will do nothing and return
		False.

		@param config: config instance
		@type config: portage.config
		@rtype: bool
		@return: True if settings successfully propagated, False if settings
			were not available to propagate.
		"""
		if self._pkgindex_header is None:
			return False

		self._merge_pkgindex_header(self._pkgindex_header,
			config.configdict['defaults'])
		config.regenerate()
		config._init_iuse()
		return True

	def _update_pkgindex_header(self, header):
		"""
		Add useful settings to the Packages file header, for use by
		binhost clients.

		This will return silently if the current profile is invalid or
		does not have an IUSE_IMPLICIT variable, since it's useful to
		maintain a cache of implicit IUSE settings for use with binary
		packages.
		"""
		if not (self.settings.profile_path and
			"IUSE_IMPLICIT" in self.settings):
			header.setdefault("VERSION", _unicode(self._pkgindex_version))
			return

		portdir = normalize_path(os.path.realpath(self.settings["PORTDIR"]))
		profiles_base = os.path.join(portdir, "profiles") + os.path.sep
		if self.settings.profile_path:
			profile_path = normalize_path(
				os.path.realpath(self.settings.profile_path))
			if profile_path.startswith(profiles_base):
				profile_path = profile_path[len(profiles_base):]
			header["PROFILE"] = profile_path
		header["VERSION"] = _unicode(self._pkgindex_version)
		base_uri = self.settings.get("PORTAGE_BINHOST_HEADER_URI")
		if base_uri:
			header["URI"] = base_uri
		else:
			header.pop("URI", None)
		for k in list(self._pkgindex_header_keys) + \
			self.settings.get("USE_EXPAND_IMPLICIT", "").split() + \
			self.settings.get("USE_EXPAND_UNPREFIXED", "").split():
			v = self.settings.get(k, None)
			if v:
				header[k] = v
			else:
				header.pop(k, None)

		# These values may be useful for using a binhost without
		# having a local copy of the profile (bug #470006).
		for k in self.settings.get("USE_EXPAND_IMPLICIT", "").split():
			k = "USE_EXPAND_VALUES_" + k
			v = self.settings.get(k)
			if v:
				header[k] = v
			else:
				header.pop(k, None)

	def _pkgindex_version_supported(self, pkgindex):
		version = pkgindex.header.get("VERSION")
		if version:
			try:
				if int(version) <= self._pkgindex_version:
					return True
			except ValueError:
				pass
		return False

	def _eval_use_flags(self, cpv, metadata):
		use = frozenset(metadata.get("USE", "").split())
		for k in self._pkgindex_use_evaluated_keys:
			if k.endswith('DEPEND'):
				token_class = Atom
			else:
				token_class = None

			deps = metadata.get(k)
			if deps is None:
				continue
			try:
				deps = use_reduce(deps, uselist=use, token_class=token_class)
				deps = paren_enclose(deps)
			except portage.exception.InvalidDependString as e:
				writemsg("%s: %s\n" % (k, e), noiselevel=-1)
				raise
			metadata[k] = deps

	def exists_specific(self, cpv):
		if not self.populated:
			self.populate()
		return self.dbapi.match(
			dep_expand("="+cpv, mydb=self.dbapi, settings=self.settings))

	def dep_bestmatch(self, mydep):
		"compatibility method -- all matches, not just visible ones"
		if not self.populated:
			self.populate()
		writemsg("\n\n", 1)
		writemsg("mydep: %s\n" % mydep, 1)
		mydep = dep_expand(mydep, mydb=self.dbapi, settings=self.settings)
		writemsg("mydep: %s\n" % mydep, 1)
		mykey = dep_getkey(mydep)
		writemsg("mykey: %s\n" % mykey, 1)
		mymatch = best(match_from_list(mydep,self.dbapi.cp_list(mykey)))
		writemsg("mymatch: %s\n" % mymatch, 1)
		if mymatch is None:
			return ""
		return mymatch

	def getname(self, cpv, allocate_new=None):
		"""Returns a file location for this package.
		If cpv has both build_time and build_id attributes, then the
		path to the specific corresponding instance is returned.
		Otherwise, allocate a new path and return that. When allocating
		a new path, behavior depends on the binpkg-multi-instance
		FEATURES setting.
		"""
		if not self.populated:
			self.populate()

		try:
			cpv.cp
		except AttributeError:
			cpv = _pkg_str(cpv)

		filename = None
		if allocate_new:
			filename = self._allocate_filename(cpv)
		elif self._is_specific_instance(cpv):
			instance_key = self.dbapi._instance_key(cpv)
			path = self._pkg_paths.get(instance_key)
			if path is not None:
				filename = os.path.join(self.pkgdir, path)

		if filename is None and not allocate_new:
			try:
				instance_key = self.dbapi._instance_key(cpv,
					support_string=True)
			except KeyError:
				pass
			else:
				filename = self._pkg_paths.get(instance_key)
				if filename is not None:
					filename = os.path.join(self.pkgdir, filename)

		if filename is None:
			if self._multi_instance:
				pf = catsplit(cpv)[1]
				filename = "%s-%s.xpak" % (
					os.path.join(self.pkgdir, cpv.cp, pf), "1")
			else:
				filename = os.path.join(self.pkgdir, cpv + ".tbz2")

		return filename

	def _is_specific_instance(self, cpv):
		specific = True
		try:
			build_time = cpv.build_time
			build_id = cpv.build_id
		except AttributeError:
			specific = False
		else:
			if build_time is None or build_id is None:
				specific = False
		return specific

	def _max_build_id(self, cpv):
		max_build_id = 0
		for x in self.dbapi.cp_list(cpv.cp):
			if (x == cpv and x.build_id is not None and
				x.build_id > max_build_id):
				max_build_id = x.build_id
		return max_build_id

	def _allocate_filename(self, cpv):
		return os.path.join(self.pkgdir, cpv + ".tbz2")

	def _allocate_filename_multi(self, cpv):

		# First, get the max build_id found when _populate was
		# called.
		max_build_id = self._max_build_id(cpv)

		# A new package may have been added concurrently since the
		# last _populate call, so use increment build_id until
		# we locate an unused id.
		pf = catsplit(cpv)[1]
		build_id = max_build_id + 1

		while True:
			filename = "%s-%s.xpak" % (
				os.path.join(self.pkgdir, cpv.cp, pf), build_id)
			if os.path.exists(filename):
				build_id += 1
			else:
				return filename

	@staticmethod
	def _parse_build_id(filename):
		build_id = -1
		suffixlen = len(".xpak")
		hyphen = filename.rfind("-", 0, -(suffixlen + 1))
		if hyphen != -1:
			build_id = filename[hyphen+1:-suffixlen]
		try:
			build_id = long(build_id)
		except ValueError:
			pass
		return build_id

	def isremote(self, pkgname):
		"""Returns true if the package is kept remotely and it has not been
		downloaded (or it is only partially downloaded)."""
		if (self._remotepkgs is None or
		self.dbapi._instance_key(pkgname) not in self._remotepkgs):
			return False
		# Presence in self._remotepkgs implies that it's remote. When a
		# package is downloaded, state is updated by self.inject().
		return True

	def get_pkgindex_uri(self, cpv):
		"""Returns the URI to the Packages file for a given package."""
		uri = None
		if self._remotepkgs is not None:
			metadata = self._remotepkgs.get(self.dbapi._instance_key(cpv))
			if metadata is not None:
				uri = metadata["PKGINDEX_URI"]
		return uri

	def gettbz2(self, pkgname):
		"""Fetches the package from a remote site, if necessary.  Attempts to
		resume if the file appears to be partially downloaded."""
		instance_key = self.dbapi._instance_key(pkgname)
		tbz2_path = self.getname(pkgname)
		tbz2name = os.path.basename(tbz2_path)
		resume = False
		if os.path.exists(tbz2_path):
			if tbz2name[:-5] not in self.invalids:
				return
			else:
				resume = True
				writemsg(_("Resuming download of this tbz2, but it is possible that it is corrupt.\n"),
					noiselevel=-1)
		
		mydest = os.path.dirname(self.getname(pkgname))
		self._ensure_dir(mydest)
		# urljoin doesn't work correctly with unrecognized protocols like sftp
		if self._remote_has_index:
			rel_url = self._remotepkgs[instance_key].get("PATH")
			if not rel_url:
				rel_url = pkgname + ".tbz2"
			remote_base_uri = self._remotepkgs[instance_key]["BASE_URI"]
			url = remote_base_uri.rstrip("/") + "/" + rel_url.lstrip("/")
		else:
			url = self.settings["PORTAGE_BINHOST"].rstrip("/") + "/" + tbz2name
		protocol = urlparse(url)[0]
		fcmd_prefix = "FETCHCOMMAND"
		if resume:
			fcmd_prefix = "RESUMECOMMAND"
		fcmd = self.settings.get(fcmd_prefix + "_" + protocol.upper())
		if not fcmd:
			fcmd = self.settings.get(fcmd_prefix)
		success = portage.getbinpkg.file_get(url, mydest, fcmd=fcmd)
		if not success:
			try:
				os.unlink(self.getname(pkgname))
			except OSError:
				pass
			raise portage.exception.FileNotFound(mydest)
		self.inject(pkgname)

	def _load_pkgindex(self):
		pkgindex = self._new_pkgindex()
		try:
			f = io.open(_unicode_encode(self._pkgindex_file,
				encoding=_encodings['fs'], errors='strict'),
				mode='r', encoding=_encodings['repo.content'],
				errors='replace')
		except EnvironmentError:
			pass
		else:
			try:
				pkgindex.read(f)
			finally:
				f.close()
		return pkgindex

	def _get_digests(self, pkg):

		try:
			cpv = pkg.cpv
		except AttributeError:
			cpv = pkg

		_instance_key = self.dbapi._instance_key
		instance_key = _instance_key(cpv)
		digests = {}
		metadata = (None if self._remotepkgs is None else
			self._remotepkgs.get(instance_key))
		if metadata is None:
			for d in self._load_pkgindex().packages:
				if (d["CPV"] == cpv and
					instance_key == _instance_key(_pkg_str(d["CPV"],
					metadata=d, settings=self.settings))):
					metadata = d
					break

		if metadata is None:
			return digests

		for k in get_valid_checksum_keys():
			v = metadata.get(k)
			if not v:
				continue
			digests[k] = v

		if "SIZE" in metadata:
			try:
				digests["size"] = int(metadata["SIZE"])
			except ValueError:
				writemsg(_("!!! Malformed SIZE attribute in remote " \
				"metadata for '%s'\n") % cpv)

		return digests

	def digestCheck(self, pkg):
		"""
		Verify digests for the given package and raise DigestException
		if verification fails.
		@rtype: bool
		@return: True if digests could be located, False otherwise.
		"""

		digests = self._get_digests(pkg)

		if not digests:
			return False

		try:
			cpv = pkg.cpv
		except AttributeError:
			cpv = pkg

		pkg_path = self.getname(cpv)
		hash_filter = _hash_filter(
			self.settings.get("PORTAGE_CHECKSUM_FILTER", ""))
		if not hash_filter.transparent:
			digests = _apply_hash_filter(digests, hash_filter)
		eout = EOutput()
		eout.quiet = self.settings.get("PORTAGE_QUIET") == "1"
		ok, st = _check_distfile(pkg_path, digests, eout, show_errors=0)
		if not ok:
			ok, reason = verify_all(pkg_path, digests)
			if not ok:
				raise portage.exception.DigestException(
					(pkg_path,) + tuple(reason))

		return True

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