Support ACCEPT_RESTRICT for bug #467622.
diff --git a/cnf/make.globals b/cnf/make.globals
index f0597c1..6dd3509 100644
--- a/cnf/make.globals
+++ b/cnf/make.globals
@@ -28,6 +28,7 @@
 
 ACCEPT_LICENSE="* -@EULA"
 ACCEPT_PROPERTIES="*"
+ACCEPT_RESTRICT="*"
 
 # Repository Paths
 PORTDIR=/usr/portage
diff --git a/man/emerge.1 b/man/emerge.1
index 15e8185..23b023c 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -277,6 +277,21 @@
 configuration, this would result in an effective
 \fBACCEPT_PROPERTIES\fR value of "* -interactive".
 .TP
+.BR \-\-accept\-restrict=ACCEPT_RESTRICT
+This option temporarily overrides the \fBACCEPT_RESTRICT\fR
+variable. The \fBACCEPT_RESTRICT\fR variable is incremental,
+which means that the specified setting is appended to the
+existing value from your configuration. The special \fB-*\fR
+token can be used to discard the existing configuration
+value and start fresh. See the \fBMASKED PACKAGES\fR section
+and \fBmake.conf\fR(5) for more information about
+ACCEPT_RESTRICT. A typical usage example for this option
+would be to use \fI\-\-accept\-restrict=\-bindist\fR to
+temporarily mask packages that are not binary
+re\-distributable. With default
+configuration, this would result in an effective
+\fBACCEPT_RESTRICT\fR value of "* -bindist".
+.TP
 .BR "\-\-alphabetical "
 When displaying USE and other flag output, combines the enabled and
 disabled lists into one list and sorts the whole list alphabetically.
@@ -1041,6 +1056,15 @@
 about \fBACCEPT_PROPERTIES\fR, and see \fBportage\fR(5) for information about
 \fI/etc/portage/package.properties\fR. Use the \fB\-\-accept\-properties\fR
 option to temporarily override \fBACCEPT_PROPERTIES\fR.
+.TP
+.BR RESTRICT
+The \fBRESTRICT\fR variable in an \fBebuild\fR file can be used to mask
+packages based on RESTRICT tokens. \fBemerge\fR examines the
+\fBACCEPT_RESTRICT\fR environment variable to allow or disallow the emerging
+of a package masked by \fBRESTRICT\fR. See \fBmake.conf\fR(5) for information
+about \fBACCEPT_RESTRICT\fR, and see \fBportage\fR(5) for information about
+\fI/etc/portage/package.accept_restrict\fR. Use the \fB\-\-accept\-restrict\fR
+option to temporarily override \fBACCEPT_RESTRICT\fR.
 .SH "CONFIGURATION FILES"
 Portage has a special feature called "config file protection". The purpose of
 this feature is to prevent new package installs from clobbering existing
diff --git a/man/make.conf.5 b/man/make.conf.5
index 8c6d477..19118ff 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -80,6 +80,23 @@
 ACCEPT_PROPERTIES="* -interactive"
 .fi
 .TP
+\fBACCEPT_RESTRICT\fR = \fI[space delimited list of RESTRICT tokens]\fR
+This variable is used to mask packages based on RESTRICT tokens.
+In addition to RESTRICT tokens, the \fI*\fR and \fI-*\fR wildcard tokens are
+also supported. This variable can be temporarily overridden using the
+\fB\-\-accept\-restrict\fR option of \fBemerge\fR(1).
+See \fBebuild\fR(5) for more information about RESTRICT.
+.br
+Defaults to the value of *.
+.br
+.I Examples:
+.nf
+# Accept any restrict tokens
+ACCEPT_RESTRICT="*"
+# Accept any tokens except "bindist"
+ACCEPT_RESTRICT="* -bindist"
+.fi
+.TP
 .B CBUILD
 This variable is passed by the \fIebuild scripts\fR to the \fIconfigure\fR
 as \fI\-\-build=${CBUILD}\fR only if it is defined.  Do not set this yourself
diff --git a/man/portage.5 b/man/portage.5
index 686e318..46a64f1 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -57,6 +57,7 @@
 mirrors
 modules
 package.accept_keywords
+package.accept_restrict
 package.env
 package.keywords
 package.license
@@ -673,6 +674,16 @@
 games-fps/quake3-demo x86
 
 .TP
+.BR package.accept_restrict
+This will allow ACCEPT_RESTRICT (see \fBmake.conf\fR(5)) to be augmented for a
+single package.
+
+.I Format:
+.nf
+\- comment lines begin with # (no inline comments)
+\- one DEPEND atom per line followed by additional RESTRICT tokens
+.fi
+.TP
 .BR package.env
 Per\-package environment variable settings. Entries refer to
 environment files that are placed in the \fB/etc/portage/env/\fR
diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py
index ae03576..c795568 100644
--- a/pym/_emerge/Package.py
+++ b/pym/_emerge/Package.py
@@ -332,6 +332,15 @@
 			# already recorded as 'invalid'
 			pass
 
+		try:
+			missing_restricts = settings._getMissingRestrict(
+				self.cpv, self._metadata)
+			if missing_restricts:
+				masks['RESTRICT'] = missing_restricts
+		except InvalidDependString:
+			# already recorded as 'invalid'
+			pass
+
 		mask_atom = settings._getMaskAtom(self.cpv, self._metadata)
 		if mask_atom is not None:
 			masks['package.mask'] = mask_atom
@@ -364,7 +373,8 @@
 				'CHOST' in masks or \
 				'EAPI.deprecated' in masks or \
 				'KEYWORDS' in masks or \
-				'PROPERTIES' in masks):
+				'PROPERTIES' in masks or \
+				'RESTRICT' in masks):
 				return False
 
 			if 'package.mask' in masks or \
diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py
index c0e2d96..8afb56d 100644
--- a/pym/_emerge/main.py
+++ b/pym/_emerge/main.py
@@ -326,6 +326,11 @@
 			"action":"store"
 		},
 
+		"--accept-restrict": {
+			"help":"temporarily override ACCEPT_RESTRICT",
+			"action":"store"
+		},
+
 		"--backtrack": {
 
 			"help"   : "Specifies how many times to backtrack if dependency " + \
@@ -1016,6 +1021,8 @@
 		os.environ["ROOT"] = myopts["--root"]
 	if "--accept-properties" in myopts:
 		os.environ["ACCEPT_PROPERTIES"] = myopts["--accept-properties"]
+	if "--accept-restrict" in myopts:
+		os.environ["ACCEPT_RESTRICT"] = myopts["--accept-restrict"]
 
 	# optimize --help (no need to load config / EMERGE_DEFAULT_OPTS)
 	if myaction == "help":
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index 01dbad1..cdd10b3 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -314,7 +314,7 @@
 				"PDEPEND", "PROPERTIES", "PROVIDE")
 			self._pkgindex_header_keys = set([
 				"ACCEPT_KEYWORDS", "ACCEPT_LICENSE",
-				"ACCEPT_PROPERTIES", "CBUILD",
+				"ACCEPT_PROPERTIES", "ACCEPT_RESTRICT", "CBUILD",
 				"CONFIG_PROTECT", "CONFIG_PROTECT_MASK", "FEATURES",
 				"GENTOO_MIRRORS", "INSTALL_MASK", "SYNC", "USE"])
 			self._pkgindex_default_pkg_data = {
diff --git a/pym/portage/dbapi/porttree.py b/pym/portage/dbapi/porttree.py
index e21e53c..77f633f 100644
--- a/pym/portage/dbapi/porttree.py
+++ b/pym/portage/dbapi/porttree.py
@@ -988,6 +988,8 @@
 					return False
 				if settings._getMissingProperties(cpv, metadata):
 					return False
+				if settings._getMissingRestrict(cpv, metadata):
+					return False
 			except InvalidDependString:
 				return False
 
diff --git a/pym/portage/package/ebuild/_config/special_env_vars.py b/pym/portage/package/ebuild/_config/special_env_vars.py
index 481ce69..9662571 100644
--- a/pym/portage/package/ebuild/_config/special_env_vars.py
+++ b/pym/portage/package/ebuild/_config/special_env_vars.py
@@ -144,7 +144,8 @@
 
 # portage config variables and variables set directly by portage
 environ_filter += [
-	"ACCEPT_CHOSTS", "ACCEPT_KEYWORDS", "ACCEPT_PROPERTIES", "AUTOCLEAN",
+	"ACCEPT_CHOSTS", "ACCEPT_KEYWORDS", "ACCEPT_PROPERTIES",
+	"ACCEPT_RESTRICT", "AUTOCLEAN",
 	"CLEAN_DELAY", "COLLISION_IGNORE",
 	"CONFIG_PROTECT", "CONFIG_PROTECT_MASK",
 	"DCO_SIGNED_OFF_BY",
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index 96c1734..1c29af9 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -219,6 +219,7 @@
 		self.uvlist = []
 		self._accept_chost_re = None
 		self._accept_properties = None
+		self._accept_restrict = None
 		self._features_overrides = []
 		self._make_defaults = None
 		self._parent_stable = None
@@ -307,6 +308,8 @@
 
 			self._accept_properties = copy.deepcopy(clone._accept_properties)
 			self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict)
+			self._accept_restrict = copy.deepcopy(clone._accept_restrict)
+			self._paccept_restrict = copy.deepcopy(clone._paccept_restrict)
 			self._penvdict = copy.deepcopy(clone._penvdict)
 			self._expand_map = copy.deepcopy(clone._expand_map)
 
@@ -603,6 +606,7 @@
 			self.backup_changes("EROOT")
 
 			self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict)
+			self._paccept_restrict = portage.dep.ExtendedAtomDict(dict)
 			self._penvdict = portage.dep.ExtendedAtomDict(dict)
 
 			#filling PORTDIR and PORTDIR_OVERLAY variable for compatibility
@@ -677,6 +681,20 @@
 				for k, v in propdict.items():
 					self._ppropertiesdict.setdefault(k.cp, {})[k] = v
 
+				# package.accept_restrict
+				d = grabdict_package(os.path.join(
+					abs_user_config, "package.accept_restrict"),
+					recursive=True, allow_wildcard=True,
+					allow_repo=True, verify_eapi=False)
+				v = d.pop("*/*", None)
+				if v is not None:
+					if "ACCEPT_RESTRICT" in self.configdict["conf"]:
+						self.configdict["conf"]["ACCEPT_RESTRICT"] += " " + " ".join(v)
+					else:
+						self.configdict["conf"]["ACCEPT_RESTRICT"] = " ".join(v)
+				for k, v in d.items():
+					self._paccept_restrict.setdefault(k.cp, {})[k] = v
+
 				#package.env
 				penvdict = grabdict_package(os.path.join(
 					abs_user_config, "package.env"), recursive=1, allow_wildcard=True, \
@@ -1970,6 +1988,56 @@
 		return [x for x in use_reduce(properties_str, uselist=use, flat=True)
 			if x not in acceptable_properties]
 
+	def _getMissingRestrict(self, cpv, metadata):
+		"""
+		Take a RESTRICT string and return a list of any tokens the user
+		may need to accept for the given package.  The returned list will not
+		contain any tokens that have already been accepted.  This method
+		can throw an InvalidDependString exception.
+
+		@param cpv: The package name (for package.accept_restrict support)
+		@type cpv: String
+		@param metadata: A dictionary of raw package metadata
+		@type metadata: dict
+		@rtype: List
+		@return: A list of tokens that have not been accepted.
+		"""
+		accept_restrict = self._accept_restrict
+		try:
+			cpv.slot
+		except AttributeError:
+			cpv = _pkg_str(cpv, metadata=metadata, settings=self)
+		cp = cpv_getkey(cpv)
+		cpdict = self._paccept_restrict.get(cp)
+		if cpdict:
+			paccept_restrict_list = ordered_by_atom_specificity(cpdict, cpv)
+			if paccept_restrict_list:
+				accept_restrict = list(self._accept_restrict)
+				for x in paccept_restrict_list:
+					accept_restrict.extend(x)
+
+		restrict_str = metadata.get("RESTRICT", "")
+		all_restricts = set(use_reduce(restrict_str, matchall=1, flat=True))
+
+		acceptable_restricts = set()
+		for x in accept_restrict:
+			if x == '*':
+				acceptable_restricts.update(all_restricts)
+			elif x == '-*':
+				acceptable_restricts.clear()
+			elif x[:1] == '-':
+				acceptable_restricts.discard(x[1:])
+			else:
+				acceptable_restricts.add(x)
+
+		if "?" in restrict_str:
+			use = metadata["USE"].split()
+		else:
+			use = []
+
+		return [x for x in use_reduce(restrict_str, uselist=use, flat=True)
+			if x not in acceptable_restricts]
+
 	def _accept_chost(self, cpv, metadata):
 		"""
 		@return True if pkg CHOST is accepted, False otherwise.
@@ -2107,6 +2175,18 @@
 			# repoman will accept any property
 			self._accept_properties = ('*',)
 
+		if self.local_config:
+			mysplit = []
+			for curdb in mydbs:
+				mysplit.extend(curdb.get('ACCEPT_RESTRICT', '').split())
+			mysplit = prune_incremental(mysplit)
+			self.configlist[-1]['ACCEPT_RESTRICT'] = ' '.join(mysplit)
+			if tuple(mysplit) != self._accept_restrict:
+				self._accept_restrict = tuple(mysplit)
+		else:
+			# repoman will accept any property
+			self._accept_restrict = ('*',)
+
 		increment_lists = {}
 		for k in myincrementals:
 			incremental_list = []
diff --git a/pym/portage/package/ebuild/getmaskingstatus.py b/pym/portage/package/ebuild/getmaskingstatus.py
index 5c14b36..c8954aa 100644
--- a/pym/portage/package/ebuild/getmaskingstatus.py
+++ b/pym/portage/package/ebuild/getmaskingstatus.py
@@ -1,12 +1,15 @@
-# Copyright 2010-2012 Gentoo Foundation
+# Copyright 2010-2013 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
 
+from __future__ import unicode_literals
+
 __all__ = ['getmaskingstatus']
 
 import sys
 
 import portage
 from portage import eapi_is_supported, _eapi_is_deprecated
+from portage.exception import InvalidDependString
 from portage.localization import _
 from portage.package.ebuild.config import config
 from portage.versions import catpkgsplit, _pkg_str
@@ -84,6 +87,7 @@
 	mygroups = settings._getKeywords(mycpv, metadata)
 	licenses = metadata["LICENSE"]
 	properties = metadata["PROPERTIES"]
+	restrict = metadata["RESTRICT"]
 	if not eapi_is_supported(eapi):
 		return [_MaskReason("EAPI", "EAPI %s" % eapi)]
 	elif _eapi_is_deprecated(eapi) and not installed:
@@ -169,6 +173,15 @@
 	except portage.exception.InvalidDependString as e:
 		rValue.append(_MaskReason("invalid", "PROPERTIES: "+str(e)))
 
+	try:
+		missing_restricts = settings._getMissingRestrict(mycpv, metadata)
+		if missing_restricts:
+			msg = list(missing_restricts)
+			msg.append("in RESTRICT")
+			rValue.append(_MaskReason("RESTRICT", " ".join(msg)))
+	except InvalidDependString as e:
+		rValue.append(_MaskReason("invalid", "RESTRICT: %s" % (e,)))
+
 	# Only show KEYWORDS masks for installed packages
 	# if they're not masked for any other reason.
 	if kmask and (not installed or not rValue):