aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bersenev <bay@hackerdom.ru>2011-08-21 17:35:50 +0000
committerAlexander Bersenev <bay@hackerdom.ru>2011-08-21 17:35:50 +0000
commit91ffc6c50001d41fe1d16981baa32fb557463375 (patch)
tree393551fe844a9c7ee030ad71efe03a92b76ac569 /portage_with_autodep/bin
parentportage integration patch is added (diff)
downloadautodep-91ffc6c50001d41fe1d16981baa32fb557463375.tar.gz
autodep-91ffc6c50001d41fe1d16981baa32fb557463375.tar.bz2
autodep-91ffc6c50001d41fe1d16981baa32fb557463375.zip
add a patched version of portage
Diffstat (limited to 'portage_with_autodep/bin')
-rwxr-xr-xportage_with_autodep/bin/archive-conf111
-rwxr-xr-xportage_with_autodep/bin/banned-helper6
-rwxr-xr-xportage_with_autodep/bin/binhost-snapshot142
-rwxr-xr-xportage_with_autodep/bin/check-implicit-pointer-usage.py84
-rwxr-xr-xportage_with_autodep/bin/clean_locks47
-rwxr-xr-xportage_with_autodep/bin/dispatch-conf434
-rwxr-xr-xportage_with_autodep/bin/dohtml.py191
-rwxr-xr-xportage_with_autodep/bin/ebuild346
l---------portage_with_autodep/bin/ebuild-helpers/4/dodoc1
l---------portage_with_autodep/bin/ebuild-helpers/4/dohard1
l---------portage_with_autodep/bin/ebuild-helpers/4/dosed1
l---------portage_with_autodep/bin/ebuild-helpers/4/prepalldocs1
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/die7
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dobin29
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doconfd14
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dodir10
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dodoc31
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doenvd14
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doexe43
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dohard13
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dohtml14
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doinfo24
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doinitd14
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doins155
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dolib43
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dolib.a6
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dolib.so6
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/doman64
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/domo34
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dosbin29
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dosed35
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/dosym18
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/ecompress161
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/ecompressdir143
l---------portage_with_autodep/bin/ebuild-helpers/eerror1
l---------portage_with_autodep/bin/ebuild-helpers/einfo1
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/elog7
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/emake28
l---------portage_with_autodep/bin/ebuild-helpers/eqawarn1
l---------portage_with_autodep/bin/ebuild-helpers/ewarn1
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/fowners13
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/fperms13
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newbin19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newconfd19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newdoc19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newenvd19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newexe19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newinitd19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newins35
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newlib.a19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newlib.so19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newman19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/newsbin19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/portageq8
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepall23
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepalldocs15
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepallinfo9
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepallman19
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepallstrip5
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepinfo34
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/preplib28
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepman32
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/prepstrip193
-rwxr-xr-xportage_with_autodep/bin/ebuild-helpers/sed27
-rwxr-xr-xportage_with_autodep/bin/ebuild-ipc8
-rwxr-xr-xportage_with_autodep/bin/ebuild-ipc.py276
-rwxr-xr-xportage_with_autodep/bin/ebuild.sh2424
-rwxr-xr-xportage_with_autodep/bin/egencache851
-rwxr-xr-xportage_with_autodep/bin/emaint654
-rwxr-xr-xportage_with_autodep/bin/emerge66
-rwxr-xr-xportage_with_autodep/bin/emerge-webrsync457
-rwxr-xr-xportage_with_autodep/bin/env-update41
-rwxr-xr-xportage_with_autodep/bin/etc-update616
-rwxr-xr-xportage_with_autodep/bin/filter-bash-environment.py150
-rwxr-xr-xportage_with_autodep/bin/fixpackages45
-rwxr-xr-xportage_with_autodep/bin/glsa-check316
-rw-r--r--portage_with_autodep/bin/isolated-functions.sh630
-rwxr-xr-xportage_with_autodep/bin/lock-helper.py28
-rwxr-xr-xportage_with_autodep/bin/misc-functions.sh1002
-rwxr-xr-xportage_with_autodep/bin/portageq822
-rwxr-xr-xportage_with_autodep/bin/quickpkg291
-rwxr-xr-xportage_with_autodep/bin/regenworld144
-rwxr-xr-xportage_with_autodep/bin/repoman2672
-rwxr-xr-xportage_with_autodep/bin/xpak-helper.py68
84 files changed, 14516 insertions, 0 deletions
diff --git a/portage_with_autodep/bin/archive-conf b/portage_with_autodep/bin/archive-conf
new file mode 100755
index 0000000..5a03b85
--- /dev/null
+++ b/portage_with_autodep/bin/archive-conf
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+#
+# archive-conf -- save off a config file in the dispatch-conf archive dir
+#
+# Written by Wayne Davison <gentoo@blorf.net> with code snagged from
+# Jeremy Wohl's dispatch-conf script and the portage chkcontents script.
+#
+
+from __future__ import print_function
+
+import sys
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+import dispatch_conf
+
+FIND_EXTANT_CONTENTS = "find %s -name CONTENTS"
+
+MANDATORY_OPTS = [ 'archive-dir' ]
+
+try:
+ import fchksum
+ def perform_checksum(filename): return fchksum.fmd5t(filename)
+except ImportError:
+ import md5
+ def md5_to_hex(md5sum):
+ hexform = ""
+ for ix in range(len(md5sum)):
+ hexform = hexform + "%02x" % ord(md5sum[ix])
+ return hexform.lower()
+
+ def perform_checksum(filename):
+ f = open(filename, 'rb')
+ blocksize=32768
+ data = f.read(blocksize)
+ size = 0
+ sum = md5.new()
+ while data:
+ sum.update(data)
+ size = size + len(data)
+ data = f.read(blocksize)
+ return (md5_to_hex(sum.digest()),size)
+
+def archive_conf():
+ args = []
+ content_files = []
+ md5_match_hash = {}
+
+ options = portage.dispatch_conf.read_config(MANDATORY_OPTS)
+
+ for conf in sys.argv[1:]:
+ if not os.path.isabs(conf):
+ conf = os.path.abspath(conf)
+ args += [ conf ]
+ md5_match_hash[conf] = ''
+
+ # Find all the CONTENT files in VDB_PATH.
+ content_files += os.popen(FIND_EXTANT_CONTENTS %
+ (os.path.join(portage.settings['EROOT'], portage.VDB_PATH))).readlines()
+
+ # Search for the saved md5 checksum of all the specified config files
+ # and see if the current file is unmodified or not.
+ try:
+ todo_cnt = len(args)
+ for file in content_files:
+ file = file.rstrip()
+ try:
+ contents = open(file, "r")
+ except IOError as e:
+ print('archive-conf: Unable to open %s: %s' % (file, e), file=sys.stderr)
+ sys.exit(1)
+ lines = contents.readlines()
+ for line in lines:
+ items = line.split()
+ if items[0] == 'obj':
+ for conf in args:
+ if items[1] == conf:
+ stored = items[2].lower()
+ real = perform_checksum(conf)[0].lower()
+ if stored == real:
+ md5_match_hash[conf] = conf
+ todo_cnt -= 1
+ if todo_cnt == 0:
+ raise StopIteration()
+ except StopIteration:
+ pass
+
+ for conf in args:
+ archive = os.path.join(options['archive-dir'], conf.lstrip('/'))
+ if options['use-rcs'] == 'yes':
+ portage.dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '')
+ if md5_match_hash[conf]:
+ portage.dispatch_conf.rcs_archive_post_process(archive)
+ else:
+ portage.dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '')
+ if md5_match_hash[conf]:
+ portage.dispatch_conf.file_archive_post_process(archive)
+
+# run
+if len(sys.argv) > 1:
+ archive_conf()
+else:
+ print('Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]', file=sys.stderr)
diff --git a/portage_with_autodep/bin/banned-helper b/portage_with_autodep/bin/banned-helper
new file mode 100755
index 0000000..17ea991
--- /dev/null
+++ b/portage_with_autodep/bin/banned-helper
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Copyright 2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+die "'${0##*/}' has been banned for EAPI '$EAPI'"
+exit 1
diff --git a/portage_with_autodep/bin/binhost-snapshot b/portage_with_autodep/bin/binhost-snapshot
new file mode 100755
index 0000000..9d2697d
--- /dev/null
+++ b/portage_with_autodep/bin/binhost-snapshot
@@ -0,0 +1,142 @@
+#!/usr/bin/python
+# Copyright 2010-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import io
+import optparse
+import os
+import sys
+import textwrap
+
+try:
+ from urllib.parse import urlparse
+except ImportError:
+ from urlparse import urlparse
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(
+ osp.realpath(__file__))), "pym"))
+ import portage
+
+def parse_args(argv):
+ prog_name = os.path.basename(argv[0])
+ usage = prog_name + ' [options] ' + \
+ '<src_pkg_dir> <snapshot_dir> <snapshot_uri> <binhost_dir>'
+
+ prog_desc = "This program will copy src_pkg_dir to snapshot_dir " + \
+ "and inside binhost_dir it will create a Packages index file " + \
+ "which refers to snapshot_uri. This is intended to solve race " + \
+ "conditions on binhosts as described at http://crosbug.com/3225."
+
+ usage += "\n\n"
+ for line in textwrap.wrap(prog_desc, 70):
+ usage += line + "\n"
+
+ usage += "\n"
+ usage += "Required Arguments:\n\n"
+ usage += " src_pkg_dir - the source $PKGDIR\n"
+ usage += " snapshot_dir - destination snapshot " + \
+ "directory (must not exist)\n"
+ usage += " snapshot_uri - URI which refers to " + \
+ "snapshot_dir from the\n" + \
+ " client side\n"
+ usage += " binhost_dir - directory in which to " + \
+ "write Packages index with\n" + \
+ " snapshot_uri"
+
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option('--hardlinks', help='create hardlinks (y or n, default is y)',
+ choices=('y', 'n'))
+ parser.set_defaults(hardlinks='y')
+ options, args = parser.parse_args(argv[1:])
+
+ if len(args) != 4:
+ parser.error("Required 4 arguments, got %d" % (len(args),))
+
+ return parser, options, args
+
+def main(argv):
+ parser, options, args = parse_args(argv)
+
+ src_pkg_dir, snapshot_dir, snapshot_uri, binhost_dir = args
+ src_pkgs_index = os.path.join(src_pkg_dir, 'Packages')
+
+ if not os.path.isdir(src_pkg_dir):
+ parser.error("src_pkg_dir is not a directory: '%s'" % (src_pkg_dir,))
+
+ if not os.path.isfile(src_pkgs_index):
+ parser.error("src_pkg_dir does not contain a " + \
+ "'Packages' index: '%s'" % (src_pkg_dir,))
+
+ parse_result = urlparse(snapshot_uri)
+ if not (parse_result.scheme and parse_result.netloc and parse_result.path):
+ parser.error("snapshot_uri is not a valid URI: '%s'" % (snapshot_uri,))
+
+ if os.path.isdir(snapshot_dir):
+ parser.error("snapshot_dir already exists: '%s'" % snapshot_dir)
+
+ try:
+ os.makedirs(os.path.dirname(snapshot_dir))
+ except OSError:
+ pass
+ if not os.path.isdir(os.path.dirname(snapshot_dir)):
+ parser.error("snapshot_dir parent could not be created: '%s'" % \
+ os.path.dirname(snapshot_dir))
+
+ try:
+ os.makedirs(binhost_dir)
+ except OSError:
+ pass
+ if not os.path.isdir(binhost_dir):
+ parser.error("binhost_dir could not be created: '%s'" % binhost_dir)
+
+ cp_opts = 'RP'
+ if options.hardlinks == 'n':
+ cp_opts += 'p'
+ else:
+ cp_opts += 'l'
+
+ cp_cmd = 'cp -%s %s %s' % (
+ cp_opts,
+ portage._shell_quote(src_pkg_dir),
+ portage._shell_quote(snapshot_dir)
+ )
+
+ ret = os.system(cp_cmd)
+ if not (os.WIFEXITED(ret) and os.WEXITSTATUS(ret) == os.EX_OK):
+ return 1
+
+ infile = io.open(portage._unicode_encode(src_pkgs_index,
+ encoding=portage._encodings['fs'], errors='strict'),
+ mode='r', encoding=portage._encodings['repo.content'],
+ errors='strict')
+
+ outfile = portage.util.atomic_ofstream(
+ os.path.join(binhost_dir, "Packages"),
+ encoding=portage._encodings['repo.content'],
+ errors='strict')
+
+ for line in infile:
+ if line[:4] == 'URI:':
+ # skip existing URI line
+ pass
+ else:
+ if not line.strip():
+ # end of header
+ outfile.write("URI: %s\n\n" % snapshot_uri)
+ break
+ outfile.write(line)
+
+ for line in infile:
+ outfile.write(line)
+
+ infile.close()
+ outfile.close()
+
+ return os.EX_OK
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
diff --git a/portage_with_autodep/bin/check-implicit-pointer-usage.py b/portage_with_autodep/bin/check-implicit-pointer-usage.py
new file mode 100755
index 0000000..8822c45
--- /dev/null
+++ b/portage_with_autodep/bin/check-implicit-pointer-usage.py
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+
+# Ripped from HP and updated from Debian
+# Update by Gentoo to support unicode output
+
+#
+# Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
+# David Mosberger <davidm@hpl.hp.com>
+#
+# Scan standard input for GCC warning messages that are likely to
+# source of real 64-bit problems. In particular, see whether there
+# are any implicitly declared functions whose return values are later
+# interpreted as pointers. Those are almost guaranteed to cause
+# crashes.
+#
+
+from __future__ import print_function
+
+import re
+import sys
+
+implicit_pattern = re.compile("([^:]*):(\d+): warning: implicit declaration "
+ + "of function [`']([^']*)'")
+pointer_pattern = (
+ "([^:]*):(\d+): warning: "
+ + "("
+ + "(assignment"
+ + "|initialization"
+ + "|return"
+ + "|passing arg \d+ of `[^']*'"
+ + "|passing arg \d+ of pointer to function"
+ + ") makes pointer from integer without a cast"
+ + "|"
+ + "cast to pointer from integer of different size)")
+
+if sys.hexversion < 0x3000000:
+ # Use encoded byte strings in python-2.x, since the python ebuilds are
+ # known to remove the encodings module when USE=build is enabled (thus
+ # disabling unicode decoding/encoding). The portage module has a
+ # workaround for this, but currently we don't import that here since we
+ # don't want to trigger potential sandbox violations due to stale pyc
+ # files for the portage module.
+ unicode_quote_open = '\xE2\x80\x98'
+ unicode_quote_close = '\xE2\x80\x99'
+ def write(msg):
+ sys.stdout.write(msg)
+else:
+ unicode_quote_open = '\u2018'
+ unicode_quote_close = '\u2019'
+ def write(msg):
+ sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
+
+pointer_pattern = re.compile(pointer_pattern)
+
+last_implicit_filename = ""
+last_implicit_linenum = -1
+last_implicit_func = ""
+
+while True:
+ if sys.hexversion >= 0x3000000:
+ line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
+ else:
+ line = sys.stdin.readline()
+ if not line:
+ break
+ # translate unicode open/close quotes to ascii ones
+ line = line.replace(unicode_quote_open, "`")
+ line = line.replace(unicode_quote_close, "'")
+ m = implicit_pattern.match(line)
+ if m:
+ last_implicit_filename = m.group(1)
+ last_implicit_linenum = int(m.group(2))
+ last_implicit_func = m.group(3)
+ else:
+ m = pointer_pattern.match(line)
+ if m:
+ pointer_filename = m.group(1)
+ pointer_linenum = int(m.group(2))
+ if (last_implicit_filename == pointer_filename
+ and last_implicit_linenum == pointer_linenum):
+ write("Function `%s' implicitly converted to pointer at " \
+ "%s:%d\n" % (last_implicit_func,
+ last_implicit_filename,
+ last_implicit_linenum))
diff --git a/portage_with_autodep/bin/clean_locks b/portage_with_autodep/bin/clean_locks
new file mode 100755
index 0000000..8c4299c
--- /dev/null
+++ b/portage_with_autodep/bin/clean_locks
@@ -0,0 +1,47 @@
+#!/usr/bin/python -O
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import sys, errno
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+
+if not sys.argv[1:] or "--help" in sys.argv or "-h" in sys.argv:
+ import portage
+ print()
+ print("You must specify directories with hardlink-locks to clean.")
+ print("You may optionally specify --force, which will remove all")
+ print("of the locks, even if we can't establish if they are in use.")
+ print("Please attempt cleaning without force first.")
+ print()
+ print("%s %s/.locks" % (sys.argv[0], portage.settings["DISTDIR"]))
+ print("%s --force %s/.locks" % (sys.argv[0], portage.settings["DISTDIR"]))
+ print()
+ sys.exit(1)
+
+force = False
+if "--force" in sys.argv[1:]:
+ force=True
+
+for x in sys.argv[1:]:
+ if x == "--force":
+ continue
+ try:
+ for y in portage.locks.hardlock_cleanup(x, remove_all_locks=force):
+ print(y)
+ print()
+
+ except OSError as e:
+ if e.errno in (errno.ENOENT, errno.ENOTDIR):
+ print("!!! %s is not a directory or does not exist" % x)
+ else:
+ raise
+ sys.exit(e.errno)
diff --git a/portage_with_autodep/bin/dispatch-conf b/portage_with_autodep/bin/dispatch-conf
new file mode 100755
index 0000000..1e21a52
--- /dev/null
+++ b/portage_with_autodep/bin/dispatch-conf
@@ -0,0 +1,434 @@
+#!/usr/bin/python -O
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+#
+# dispatch-conf -- Integrate modified configs, post-emerge
+#
+# Jeremy Wohl (http://igmus.org)
+#
+# TODO
+# dialog menus
+#
+
+from __future__ import print_function
+
+from stat import ST_GID, ST_MODE, ST_UID
+from random import random
+import atexit, re, shutil, stat, sys
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage import dispatch_conf
+from portage import _unicode_decode
+from portage.dispatch_conf import diffstatusoutput_len
+from portage.process import find_binary
+
+FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print"
+DIFF_CONTENTS = "diff -Nu '%s' '%s'"
+DIFF_CVS_INTERP = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '# .Header:.*'"
+DIFF_WSCOMMENTS = "diff -Nu '%s' '%s' | grep '^[+-][^+-]' | grep -v '^[-+]#' | grep -v '^[-+][:space:]*$'"
+
+# We need a secure scratch dir and python does silly verbose errors on the use of tempnam
+oldmask = os.umask(0o077)
+SCRATCH_DIR = None
+while SCRATCH_DIR is None:
+ try:
+ mydir = "/tmp/dispatch-conf."
+ for x in range(0,8):
+ if int(random() * 3) == 0:
+ mydir += chr(int(65+random()*26.0))
+ elif int(random() * 2) == 0:
+ mydir += chr(int(97+random()*26.0))
+ else:
+ mydir += chr(int(48+random()*10.0))
+ if os.path.exists(mydir):
+ continue
+ os.mkdir(mydir)
+ SCRATCH_DIR = mydir
+ except OSError as e:
+ if e.errno != 17:
+ raise
+os.umask(oldmask)
+
+# Ensure the scratch dir is deleted
+def cleanup(mydir=SCRATCH_DIR):
+ shutil.rmtree(mydir)
+atexit.register(cleanup)
+
+MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ]
+
+class dispatch:
+ options = {}
+
+ def grind (self, config_paths):
+ confs = []
+ count = 0
+
+ config_root = '/'
+ self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS)
+
+ if "log-file" in self.options:
+ if os.path.isfile(self.options["log-file"]):
+ shutil.copy(self.options["log-file"], self.options["log-file"] + '.old')
+ if os.path.isfile(self.options["log-file"]) \
+ or not os.path.exists(self.options["log-file"]):
+ open(self.options["log-file"], 'w').close() # Truncate it
+ os.chmod(self.options["log-file"], 0o600)
+ else:
+ self.options["log-file"] = "/dev/null"
+
+ #
+ # Build list of extant configs
+ #
+
+ for path in config_paths:
+ path = portage.normalize_path(path)
+ try:
+ mymode = os.stat(path).st_mode
+ except OSError:
+ continue
+ basename = "*"
+ find_opts = "-name '.*' -type d -prune -o"
+ if not stat.S_ISDIR(mymode):
+ path, basename = os.path.split(path)
+ find_opts = "-maxdepth 1"
+
+ confs += self.massage(os.popen(FIND_EXTANT_CONFIGS % (path, find_opts, basename)).readlines())
+
+ if self.options['use-rcs'] == 'yes':
+ for rcs_util in ("rcs", "ci", "co", "rcsmerge"):
+ if not find_binary(rcs_util):
+ print('dispatch-conf: Error finding all RCS utils and " + \
+ "use-rcs=yes in config; fatal', file=sys.stderr)
+ return False
+
+
+ # config file freezing support
+ frozen_files = set(self.options.get("frozen-files", "").split())
+ auto_zapped = []
+ protect_obj = portage.util.ConfigProtect(
+ config_root, config_paths,
+ portage.util.shlex_split(
+ portage.settings.get('CONFIG_PROTECT_MASK', '')))
+
+ #
+ # Remove new configs identical to current
+ # and
+ # Auto-replace configs a) whose differences are simply CVS interpolations,
+ # or b) whose differences are simply ws or comments,
+ # or c) in paths now unprotected by CONFIG_PROTECT_MASK,
+ #
+
+ def f (conf):
+ mrgconf = re.sub(r'\._cfg', '._mrg', conf['new'])
+ archive = os.path.join(self.options['archive-dir'], conf['current'].lstrip('/'))
+ if self.options['use-rcs'] == 'yes':
+ mrgfail = portage.dispatch_conf.rcs_archive(archive, conf['current'], conf['new'], mrgconf)
+ else:
+ mrgfail = portage.dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf)
+ if os.path.exists(archive + '.dist'):
+ unmodified = diffstatusoutput_len(DIFF_CONTENTS % (conf['current'], archive + '.dist'))[1] == 0
+ else:
+ unmodified = 0
+ if os.path.exists(mrgconf):
+ if mrgfail or diffstatusoutput_len(DIFF_CONTENTS % (conf['new'], mrgconf))[1] == 0:
+ os.unlink(mrgconf)
+ newconf = conf['new']
+ else:
+ newconf = mrgconf
+ else:
+ newconf = conf['new']
+
+ if newconf == mrgconf and \
+ self.options.get('ignore-previously-merged') != 'yes' and \
+ os.path.exists(archive+'.dist') and \
+ diffstatusoutput_len(DIFF_CONTENTS % (archive+'.dist', conf['new']))[1] == 0:
+ # The current update is identical to the archived .dist
+ # version that has previously been merged.
+ os.unlink(mrgconf)
+ newconf = conf['new']
+
+ mystatus, myoutput_len = diffstatusoutput_len(
+ DIFF_CONTENTS % (conf ['current'], newconf))
+ same_file = 0 == myoutput_len
+ if mystatus >> 8 == 2:
+ # Binary files differ
+ same_cvs = False
+ same_wsc = False
+ else:
+ same_cvs = 0 == diffstatusoutput_len(
+ DIFF_CVS_INTERP % (conf ['current'], newconf))[1]
+ same_wsc = 0 == diffstatusoutput_len(
+ DIFF_WSCOMMENTS % (conf ['current'], newconf))[1]
+
+ # Do options permit?
+ same_cvs = same_cvs and self.options['replace-cvs'] == 'yes'
+ same_wsc = same_wsc and self.options['replace-wscomments'] == 'yes'
+ unmodified = unmodified and self.options['replace-unmodified'] == 'yes'
+
+ if same_file:
+ os.unlink (conf ['new'])
+ self.post_process(conf['current'])
+ if os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ return False
+ elif conf['current'] in frozen_files:
+ """Frozen files are automatically zapped. The new config has
+ already been archived with a .new suffix. When zapped, it is
+ left with the .new suffix (post_process is skipped), since it
+ hasn't been merged into the current config."""
+ auto_zapped.append(conf['current'])
+ os.unlink(conf['new'])
+ try:
+ os.unlink(mrgconf)
+ except OSError:
+ pass
+ return False
+ elif unmodified or same_cvs or same_wsc or \
+ not protect_obj.isprotected(conf['current']):
+ self.replace(newconf, conf['current'])
+ self.post_process(conf['current'])
+ if newconf == mrgconf:
+ os.unlink(conf['new'])
+ elif os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ return False
+ else:
+ return True
+
+ confs = [x for x in confs if f(x)]
+
+ #
+ # Interactively process remaining
+ #
+
+ valid_input = "qhtnmlezu"
+
+ for conf in confs:
+ count = count + 1
+
+ newconf = conf['new']
+ mrgconf = re.sub(r'\._cfg', '._mrg', newconf)
+ if os.path.exists(mrgconf):
+ newconf = mrgconf
+ show_new_diff = 0
+
+ while 1:
+ clear_screen()
+ if show_new_diff:
+ cmd = self.options['diff'] % (conf['new'], mrgconf)
+ spawn_shell(cmd)
+ show_new_diff = 0
+ else:
+ cmd = self.options['diff'] % (conf['current'], newconf)
+ spawn_shell(cmd)
+
+ print()
+ print('>> (%i of %i) -- %s' % (count, len(confs), conf ['current']))
+ print('>> q quit, h help, n next, e edit-new, z zap-new, u use-new\n m merge, t toggle-merge, l look-merge: ', end=' ')
+
+ # In some cases getch() will return some spurious characters
+ # that do not represent valid input. If we don't validate the
+ # input then the spurious characters can cause us to jump
+ # back into the above "diff" command immediatly after the user
+ # has exited it (which can be quite confusing and gives an
+ # "out of control" feeling).
+ while True:
+ c = getch()
+ if c in valid_input:
+ sys.stdout.write('\n')
+ sys.stdout.flush()
+ break
+
+ if c == 'q':
+ sys.exit (0)
+ if c == 'h':
+ self.do_help ()
+ continue
+ elif c == 't':
+ if newconf == mrgconf:
+ newconf = conf['new']
+ elif os.path.exists(mrgconf):
+ newconf = mrgconf
+ continue
+ elif c == 'n':
+ break
+ elif c == 'm':
+ merged = SCRATCH_DIR+"/"+os.path.basename(conf['current'])
+ print()
+ ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf))
+ ret = os.WEXITSTATUS(ret)
+ if ret < 2:
+ ret = 0
+ if ret:
+ print("Failure running 'merge' command")
+ continue
+ shutil.copyfile(merged, mrgconf)
+ os.remove(merged)
+ mystat = os.lstat(conf['new'])
+ os.chmod(mrgconf, mystat[ST_MODE])
+ os.chown(mrgconf, mystat[ST_UID], mystat[ST_GID])
+ newconf = mrgconf
+ continue
+ elif c == 'l':
+ show_new_diff = 1
+ continue
+ elif c == 'e':
+ if 'EDITOR' not in os.environ:
+ os.environ['EDITOR']='nano'
+ os.system(os.environ['EDITOR'] + ' ' + newconf)
+ continue
+ elif c == 'z':
+ os.unlink(conf['new'])
+ if os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ break
+ elif c == 'u':
+ self.replace(newconf, conf ['current'])
+ self.post_process(conf['current'])
+ if newconf == mrgconf:
+ os.unlink(conf['new'])
+ elif os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ break
+ else:
+ raise AssertionError("Invalid Input: %s" % c)
+
+ if auto_zapped:
+ print()
+ print(" One or more updates are frozen and have been automatically zapped:")
+ print()
+ for frozen in auto_zapped:
+ print(" * '%s'" % frozen)
+ print()
+
+ def replace (self, newconf, curconf):
+ """Replace current config with the new/merged version. Also logs
+ the diff of what changed into the configured log file."""
+ os.system((DIFF_CONTENTS % (curconf, newconf)) + '>>' + self.options["log-file"])
+ try:
+ os.rename(newconf, curconf)
+ except (IOError, os.error) as why:
+ print('dispatch-conf: Error renaming %s to %s: %s; fatal' % \
+ (newconf, curconf, str(why)), file=sys.stderr)
+
+
+ def post_process(self, curconf):
+ archive = os.path.join(self.options['archive-dir'], curconf.lstrip('/'))
+ if self.options['use-rcs'] == 'yes':
+ portage.dispatch_conf.rcs_archive_post_process(archive)
+ else:
+ portage.dispatch_conf.file_archive_post_process(archive)
+
+
+ def massage (self, newconfigs):
+ """Sort, rstrip, remove old versions, break into triad hash.
+
+ Triad is dictionary of current (/etc/make.conf), new (/etc/._cfg0003_make.conf)
+ and dir (/etc).
+
+ We keep ._cfg0002_conf over ._cfg0001_conf and ._cfg0000_conf.
+ """
+ h = {}
+ configs = []
+ newconfigs.sort ()
+
+ for nconf in newconfigs:
+ nconf = nconf.rstrip ()
+ conf = re.sub (r'\._cfg\d+_', '', nconf)
+ dirname = os.path.dirname(nconf)
+ conf_map = {
+ 'current' : conf,
+ 'dir' : dirname,
+ 'new' : nconf,
+ }
+
+ if conf in h:
+ mrgconf = re.sub(r'\._cfg', '._mrg', h[conf]['new'])
+ if os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ os.unlink(h[conf]['new'])
+ h[conf].update(conf_map)
+ else:
+ h[conf] = conf_map
+ configs.append(conf_map)
+
+ return configs
+
+
+ def do_help (self):
+ print(); print
+
+ print(' u -- update current config with new config and continue')
+ print(' z -- zap (delete) new config and continue')
+ print(' n -- skip to next config, leave all intact')
+ print(' e -- edit new config')
+ print(' m -- interactively merge current and new configs')
+ print(' l -- look at diff between pre-merged and merged configs')
+ print(' t -- toggle new config between merged and pre-merged state')
+ print(' h -- this screen')
+ print(' q -- quit')
+
+ print(); print('press any key to return to diff...', end=' ')
+
+ getch ()
+
+
+def getch ():
+ # from ASPN - Danny Yoo
+ #
+ import sys, tty, termios
+
+ fd = sys.stdin.fileno()
+ old_settings = termios.tcgetattr(fd)
+ try:
+ tty.setraw(sys.stdin.fileno())
+ ch = sys.stdin.read(1)
+ finally:
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
+ return ch
+
+def clear_screen():
+ try:
+ import curses
+ try:
+ curses.setupterm()
+ sys.stdout.write(_unicode_decode(curses.tigetstr("clear")))
+ sys.stdout.flush()
+ return
+ except curses.error:
+ pass
+ except ImportError:
+ pass
+ os.system("clear 2>/dev/null")
+
+from portage.process import find_binary, spawn
+shell = os.environ.get("SHELL")
+if not shell or not os.access(shell, os.EX_OK):
+ shell = find_binary("sh")
+
+def spawn_shell(cmd):
+ if shell:
+ spawn([shell, "-c", cmd], env=os.environ,
+ fd_pipes = { 0 : sys.stdin.fileno(),
+ 1 : sys.stdout.fileno(),
+ 2 : sys.stderr.fileno()})
+ else:
+ os.system(cmd)
+
+# run
+d = dispatch ()
+
+if len(sys.argv) > 1:
+ # for testing
+ d.grind(sys.argv[1:])
+else:
+ d.grind(portage.util.shlex_split(
+ portage.settings.get('CONFIG_PROTECT', '')))
diff --git a/portage_with_autodep/bin/dohtml.py b/portage_with_autodep/bin/dohtml.py
new file mode 100755
index 0000000..00258ec
--- /dev/null
+++ b/portage_with_autodep/bin/dohtml.py
@@ -0,0 +1,191 @@
+#!/usr/bin/python
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+#
+# Typical usage:
+# dohtml -r docs/*
+# - put all files and directories in docs into /usr/share/doc/${PF}/html
+# dohtml foo.html
+# - put foo.html into /usr/share/doc/${PF}/html
+#
+#
+# Detailed usage:
+# dohtml <list-of-files>
+# - will install the files in the list of files (space-separated list) into
+# /usr/share/doc/${PF}/html, provided the file ends in .htm, .html, .css,
+# .js, ,gif, .jpeg, .jpg, or .png.
+# dohtml -r <list-of-files-and-directories>
+# - will do as 'dohtml', but recurse into all directories, as long as the
+# directory name is not CVS
+# dohtml -A jpe,java [-r] <list-of-files[-and-directories]>
+# - will do as 'dohtml' but add .jpe,.java (default filter list is
+# added to your list)
+# dohtml -a png,gif,html,htm [-r] <list-of-files[-and-directories]>
+# - will do as 'dohtml' but filter on .png,.gif,.html,.htm (default filter
+# list is ignored)
+# dohtml -x CVS,SCCS,RCS -r <list-of-files-and-directories>
+# - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS
+#
+
+from __future__ import print_function
+
+import os
+import sys
+
+def dodir(path):
+ os.spawnlp(os.P_WAIT, "install", "install", "-d", path)
+
+def dofile(src,dst):
+ os.spawnlp(os.P_WAIT, "install", "install", "-m0644", src, dst)
+
+def eqawarn(lines):
+ cmd = "source '%s/isolated-functions.sh' ; " % \
+ os.environ["PORTAGE_BIN_PATH"]
+ for line in lines:
+ cmd += "eqawarn \"%s\" ; " % line
+ os.spawnlp(os.P_WAIT, "bash", "bash", "-c", cmd)
+
+skipped_directories = []
+
+def install(basename, dirname, options, prefix=""):
+ fullpath = basename
+ if prefix:
+ fullpath = prefix + "/" + fullpath
+ if dirname:
+ fullpath = dirname + "/" + fullpath
+
+ if options.DOCDESTTREE:
+ destdir = options.D + "usr/share/doc/" + options.PF + "/" + options.DOCDESTTREE + "/" + options.doc_prefix + "/" + prefix
+ else:
+ destdir = options.D + "usr/share/doc/" + options.PF + "/html/" + options.doc_prefix + "/" + prefix
+
+ if not os.path.exists(fullpath):
+ sys.stderr.write("!!! dohtml: %s does not exist\n" % fullpath)
+ return False
+ elif os.path.isfile(fullpath):
+ ext = os.path.splitext(basename)[1]
+ if (len(ext) and ext[1:] in options.allowed_exts) or basename in options.allowed_files:
+ dodir(destdir)
+ dofile(fullpath, destdir + "/" + basename)
+ elif options.recurse and os.path.isdir(fullpath) and \
+ basename not in options.disallowed_dirs:
+ for i in os.listdir(fullpath):
+ pfx = basename
+ if prefix: pfx = prefix + "/" + pfx
+ install(i, dirname, options, pfx)
+ elif not options.recurse and os.path.isdir(fullpath):
+ global skipped_directories
+ skipped_directories.append(fullpath)
+ return False
+ else:
+ return False
+ return True
+
+
+class OptionsClass:
+ def __init__(self):
+ self.PF = ""
+ self.D = ""
+ self.DOCDESTTREE = ""
+
+ if "PF" in os.environ:
+ self.PF = os.environ["PF"]
+ if "D" in os.environ:
+ self.D = os.environ["D"]
+ if "_E_DOCDESTTREE_" in os.environ:
+ self.DOCDESTTREE = os.environ["_E_DOCDESTTREE_"]
+
+ self.allowed_exts = [ 'htm', 'html', 'css', 'js',
+ 'gif', 'jpeg', 'jpg', 'png' ]
+ self.allowed_files = []
+ self.disallowed_dirs = [ 'CVS' ]
+ self.recurse = False
+ self.verbose = False
+ self.doc_prefix = ""
+
+def print_help():
+ opts = OptionsClass()
+
+ print("dohtml [-a .foo,.bar] [-A .foo,.bar] [-f foo,bar] [-x foo,bar]")
+ print(" [-r] [-V] <file> [file ...]")
+ print()
+ print(" -a Set the list of allowed to those that are specified.")
+ print(" Default:", ",".join(opts.allowed_exts))
+ print(" -A Extend the list of allowed file types.")
+ print(" -f Set list of allowed extensionless file names.")
+ print(" -x Set directories to be excluded from recursion.")
+ print(" Default:", ",".join(opts.disallowed_dirs))
+ print(" -p Set a document prefix for installed files (empty by default).")
+ print(" -r Install files and directories recursively.")
+ print(" -V Be verbose.")
+ print()
+
+def parse_args():
+ options = OptionsClass()
+ args = []
+
+ x = 1
+ while x < len(sys.argv):
+ arg = sys.argv[x]
+ if arg in ["-h","-r","-V"]:
+ if arg == "-h":
+ print_help()
+ sys.exit(0)
+ elif arg == "-r":
+ options.recurse = True
+ elif arg == "-V":
+ options.verbose = True
+ elif sys.argv[x] in ["-A","-a","-f","-x","-p"]:
+ x += 1
+ if x == len(sys.argv):
+ print_help()
+ sys.exit(0)
+ elif arg == "-p":
+ options.doc_prefix = sys.argv[x]
+ else:
+ values = sys.argv[x].split(",")
+ if arg == "-A":
+ options.allowed_exts.extend(values)
+ elif arg == "-a":
+ options.allowed_exts = values
+ elif arg == "-f":
+ options.allowed_files = values
+ elif arg == "-x":
+ options.disallowed_dirs = values
+ else:
+ args.append(sys.argv[x])
+ x += 1
+
+ return (options, args)
+
+def main():
+
+ (options, args) = parse_args()
+
+ if options.verbose:
+ print("Allowed extensions:", options.allowed_exts)
+ print("Document prefix : '" + options.doc_prefix + "'")
+ print("Allowed files :", options.allowed_files)
+
+ success = False
+
+ for x in args:
+ basename = os.path.basename(x)
+ dirname = os.path.dirname(x)
+ success |= install(basename, dirname, options)
+
+ global skipped_directories
+ for x in skipped_directories:
+ eqawarn(["QA Notice: dohtml on directory " + \
+ "'%s' without recursion option" % x])
+
+ if success:
+ retcode = 0
+ else:
+ retcode = 1
+
+ sys.exit(retcode)
+
+if __name__ == "__main__":
+ main()
diff --git a/portage_with_autodep/bin/ebuild b/portage_with_autodep/bin/ebuild
new file mode 100755
index 0000000..f8b6d79
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild
@@ -0,0 +1,346 @@
+#!/usr/bin/python -O
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import signal
+import sys
+# This block ensures that ^C interrupts are handled quietly.
+try:
+
+ def exithandler(signum,frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ sys.exit(128 + signum)
+
+ signal.signal(signal.SIGINT, exithandler)
+ signal.signal(signal.SIGTERM, exithandler)
+ # Prevent "[Errno 32] Broken pipe" exceptions when
+ # writing to a pipe.
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+except KeyboardInterrupt:
+ sys.exit(128 + signal.SIGINT)
+
+def debug_signal(signum, frame):
+ import pdb
+ pdb.set_trace()
+signal.signal(signal.SIGUSR1, debug_signal)
+
+import imp
+import optparse
+import os
+
+description = "See the ebuild(1) man page for more info"
+usage = "Usage: ebuild <ebuild file> <command> [command] ..."
+parser = optparse.OptionParser(description=description, usage=usage)
+
+force_help = "When used together with the digest or manifest " + \
+ "command, this option forces regeneration of digests for all " + \
+ "distfiles associated with the current ebuild. Any distfiles " + \
+ "that do not already exist in ${DISTDIR} will be automatically fetched."
+
+parser.add_option("--force", help=force_help, action="store_true", dest="force")
+parser.add_option("--color", help="enable or disable color output",
+ type="choice", choices=("y", "n"))
+parser.add_option("--debug", help="show debug output",
+ action="store_true", dest="debug")
+parser.add_option("--ignore-default-opts",
+ action="store_true",
+ help="do not use the EBUILD_DEFAULT_OPTS environment variable")
+parser.add_option("--skip-manifest", help="skip all manifest checks",
+ action="store_true", dest="skip_manifest")
+
+opts, pargs = parser.parse_args(args=sys.argv[1:])
+
+if len(pargs) < 2:
+ parser.error("missing required args")
+
+if "merge" in pargs:
+ print("Disabling noauto in features... merge disables it. (qmerge doesn't)")
+ os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
+
+os.environ["PORTAGE_CALLER"]="ebuild"
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+portage.dep._internal_warnings = True
+from portage import os
+from portage import _encodings
+from portage import _shell_quote
+from portage import _unicode_decode
+from portage import _unicode_encode
+from portage.const import VDB_PATH
+from _emerge.Package import Package
+from _emerge.RootConfig import RootConfig
+
+if not opts.ignore_default_opts:
+ default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
+ opts, pargs = parser.parse_args(default_opts + sys.argv[1:])
+
+debug = opts.debug
+force = opts.force
+
+import portage.util, portage.const
+
+# do this _after_ 'import portage' to prevent unnecessary tracing
+if debug and "python-trace" in portage.features:
+ import portage.debug
+ portage.debug.set_trace(True)
+
+if not opts.color == 'y' and \
+ (opts.color == 'n' or \
+ portage.settings.get('NOCOLOR') in ('yes', 'true') or \
+ portage.settings.get('TERM') == 'dumb' or \
+ not sys.stdout.isatty()):
+ portage.output.nocolor()
+ portage.settings.unlock()
+ portage.settings['NOCOLOR'] = 'true'
+ portage.settings.lock()
+
+ebuild = pargs.pop(0)
+
+pf = None
+if ebuild.endswith(".ebuild"):
+ pf = os.path.basename(ebuild)[:-7]
+
+if pf is None:
+ portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
+ (ebuild,), noiselevel=-1)
+ sys.exit(1)
+
+if not os.path.isabs(ebuild):
+ mycwd = os.getcwd()
+ # Try to get the non-canonical path from the PWD evironment variable, since
+ # the canonical path returned from os.getcwd() may may be unusable in
+ # cases where the directory stucture is built from symlinks.
+ pwd = os.environ.get('PWD', '')
+ if sys.hexversion < 0x3000000:
+ pwd = _unicode_decode(pwd, encoding=_encodings['content'],
+ errors='strict')
+ if pwd and pwd != mycwd and \
+ os.path.realpath(pwd) == mycwd:
+ mycwd = portage.normalize_path(pwd)
+ ebuild = os.path.join(mycwd, ebuild)
+ebuild = portage.normalize_path(ebuild)
+# portdbapi uses the canonical path for the base of the portage tree, but
+# subdirectories of the base can be built from symlinks (like crossdev does).
+ebuild_portdir = os.path.realpath(
+ os.path.dirname(os.path.dirname(os.path.dirname(ebuild))))
+ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:])
+vdb_path = os.path.realpath(os.path.join(portage.settings['EROOT'], VDB_PATH))
+
+# Make sure that portdb.findname() returns the correct ebuild.
+if ebuild_portdir != vdb_path and \
+ ebuild_portdir not in portage.portdb.porttrees:
+ if sys.hexversion >= 0x3000000:
+ os.environ["PORTDIR_OVERLAY"] = \
+ os.environ.get("PORTDIR_OVERLAY","") + \
+ " " + _shell_quote(ebuild_portdir)
+ else:
+ os.environ["PORTDIR_OVERLAY"] = \
+ os.environ.get("PORTDIR_OVERLAY","") + \
+ " " + _unicode_encode(_shell_quote(ebuild_portdir),
+ encoding=_encodings['content'], errors='strict')
+
+ print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
+ imp.reload(portage)
+
+# Constrain eclass resolution to the master(s)
+# that are specified in layout.conf (using an
+# approach similar to repoman's).
+myrepo = None
+if ebuild_portdir != vdb_path:
+ myrepo = portage.portdb.getRepositoryName(ebuild_portdir)
+ repo_info = portage.portdb._repo_info[ebuild_portdir]
+ portage.portdb.porttrees = list(repo_info.eclass_db.porttrees)
+
+if not os.path.exists(ebuild):
+ print("'%s' does not exist." % ebuild)
+ sys.exit(1)
+
+ebuild_split = ebuild.split("/")
+cpv = "%s/%s" % (ebuild_split[-3], pf)
+
+if not portage.catpkgsplit(cpv):
+ print("!!! %s does not follow correct package syntax." % (cpv))
+ sys.exit(1)
+
+if ebuild.startswith(vdb_path):
+ mytree = "vartree"
+ pkg_type = "installed"
+
+ portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv, myrepo=myrepo)
+
+ if os.path.realpath(portage_ebuild) != ebuild:
+ print("!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild))
+ sys.exit(1)
+
+else:
+ mytree = "porttree"
+ pkg_type = "ebuild"
+
+ portage_ebuild = portage.portdb.findname(cpv, myrepo=myrepo)
+
+ if not portage_ebuild or portage_ebuild != ebuild:
+ print("!!! %s does not seem to have a valid PORTDIR structure." % ebuild)
+ sys.exit(1)
+
+if len(pargs) > 1 and "config" in pargs:
+ print("config must be called on it's own, not combined with any other phase")
+ sys.exit(1)
+
+def discard_digests(myebuild, mysettings, mydbapi):
+ """Discard all distfiles digests for the given ebuild. This is useful when
+ upstream has changed the identity of the distfiles and the user would
+ otherwise have to manually remove the Manifest and files/digest-* files in
+ order to ensure correct results."""
+ try:
+ portage._doebuild_manifest_exempt_depend += 1
+ pkgdir = os.path.dirname(myebuild)
+ fetchlist_dict = portage.FetchlistDict(pkgdir, mysettings, mydbapi)
+ from portage.manifest import Manifest
+ mf = Manifest(pkgdir, mysettings["DISTDIR"],
+ fetchlist_dict=fetchlist_dict, manifest1_compat=False)
+ mf.create(requiredDistfiles=None,
+ assumeDistHashesSometimes=True, assumeDistHashesAlways=True)
+ distfiles = fetchlist_dict[cpv]
+ for myfile in distfiles:
+ try:
+ del mf.fhashdict["DIST"][myfile]
+ except KeyError:
+ pass
+ mf.write()
+ finally:
+ portage._doebuild_manifest_exempt_depend -= 1
+
+portage.settings.validate() # generate warning messages if necessary
+
+build_dir_phases = set(["setup", "unpack", "prepare", "configure", "compile",
+ "test", "install", "package", "rpm", "merge", "qmerge"])
+
+# If the current metadata is invalid then force the ebuild to be
+# sourced again even if $T/environment already exists.
+ebuild_changed = False
+if mytree == "porttree" and build_dir_phases.intersection(pargs):
+ metadata, st, emtime = \
+ portage.portdb._pull_valid_cache(cpv, ebuild, ebuild_portdir)
+ if metadata is None:
+ ebuild_changed = True
+
+tmpsettings = portage.config(clone=portage.settings)
+tmpsettings["PORTAGE_VERBOSE"] = "1"
+tmpsettings.backup_changes("PORTAGE_VERBOSE")
+
+if opts.skip_manifest:
+ tmpsettings["EBUILD_SKIP_MANIFEST"] = "1"
+ tmpsettings.backup_changes("EBUILD_SKIP_MANIFEST")
+
+if opts.skip_manifest or \
+ "digest" in tmpsettings.features or \
+ "digest" in pargs or \
+ "manifest" in pargs:
+ portage._doebuild_manifest_exempt_depend += 1
+
+if "test" in pargs:
+ # This variable is a signal to config.regenerate() to
+ # indicate that the test phase should be enabled regardless
+ # of problems such as masked "test" USE flag.
+ tmpsettings["EBUILD_FORCE_TEST"] = "1"
+ tmpsettings.backup_changes("EBUILD_FORCE_TEST")
+ tmpsettings.features.add("test")
+
+tmpsettings.features.discard("fail-clean")
+
+try:
+ metadata = dict(zip(Package.metadata_keys,
+ portage.db[portage.settings["ROOT"]][mytree].dbapi.aux_get(
+ cpv, Package.metadata_keys, myrepo=myrepo)))
+except KeyError:
+ # aux_get failure, message should have been shown on stderr.
+ sys.exit(1)
+
+root_config = RootConfig(portage.settings,
+ portage.db[portage.settings["ROOT"]], None)
+
+pkg = Package(built=(pkg_type != "ebuild"), cpv=cpv,
+ installed=(pkg_type=="installed"),
+ metadata=metadata, root_config=root_config,
+ type_name=pkg_type)
+
+# Apply package.env and repo-level settings. This allows per-package
+# FEATURES and other variables (possibly PORTAGE_TMPDIR) to be
+# available as soon as possible.
+tmpsettings.setcpv(pkg)
+
+def stale_env_warning():
+ if "clean" not in pargs and \
+ "noauto" not in tmpsettings.features and \
+ build_dir_phases.intersection(pargs):
+ portage.doebuild_environment(ebuild, "setup", portage.root,
+ tmpsettings, debug, 1, portage.portdb)
+ env_filename = os.path.join(tmpsettings["T"], "environment")
+ if os.path.exists(env_filename):
+ msg = ("Existing ${T}/environment for '%s' will be sourced. " + \
+ "Run 'clean' to start with a fresh environment.") % \
+ (tmpsettings["PF"], )
+ from textwrap import wrap
+ msg = wrap(msg, 70)
+ for x in msg:
+ portage.writemsg(">>> %s\n" % x)
+
+ if ebuild_changed:
+ open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
+ '.ebuild_changed'), 'w')
+
+from portage.exception import PermissionDenied, \
+ PortagePackageException, UnsupportedAPIException
+
+if 'digest' in tmpsettings.features and \
+ not set(["digest", "manifest"]).intersection(pargs):
+ pargs = ['digest'] + pargs
+
+checked_for_stale_env = False
+
+for arg in pargs:
+ try:
+ if not checked_for_stale_env and arg not in ("digest","manifest"):
+ # This has to go after manifest generation since otherwise
+ # aux_get() might fail due to invalid ebuild digests.
+ stale_env_warning()
+ checked_for_stale_env = True
+
+ if arg in ("digest", "manifest") and force:
+ discard_digests(ebuild, tmpsettings, portage.portdb)
+ a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
+ debug=debug, tree=mytree,
+ vartree=portage.db[portage.root]['vartree'])
+ except KeyboardInterrupt:
+ print("Interrupted.")
+ a = 1
+ except KeyError:
+ # aux_get error
+ a = 1
+ except UnsupportedAPIException as e:
+ from textwrap import wrap
+ msg = wrap(str(e), 70)
+ del e
+ for x in msg:
+ portage.writemsg("!!! %s\n" % x, noiselevel=-1)
+ a = 1
+ except PortagePackageException as e:
+ portage.writemsg("!!! %s\n" % (e,), noiselevel=-1)
+ a = 1
+ except PermissionDenied as e:
+ portage.writemsg("!!! Permission Denied: %s\n" % (e,), noiselevel=-1)
+ a = 1
+ if a == None:
+ print("Could not run the required binary?")
+ a = 127
+ if a:
+ sys.exit(a)
diff --git a/portage_with_autodep/bin/ebuild-helpers/4/dodoc b/portage_with_autodep/bin/ebuild-helpers/4/dodoc
new file mode 120000
index 0000000..35080ad
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/4/dodoc
@@ -0,0 +1 @@
+../doins \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/4/dohard b/portage_with_autodep/bin/ebuild-helpers/4/dohard
new file mode 120000
index 0000000..1a6b57a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/4/dohard
@@ -0,0 +1 @@
+../../banned-helper \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/4/dosed b/portage_with_autodep/bin/ebuild-helpers/4/dosed
new file mode 120000
index 0000000..1a6b57a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/4/dosed
@@ -0,0 +1 @@
+../../banned-helper \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/4/prepalldocs b/portage_with_autodep/bin/ebuild-helpers/4/prepalldocs
new file mode 120000
index 0000000..1a6b57a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/4/prepalldocs
@@ -0,0 +1 @@
+../../banned-helper \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/die b/portage_with_autodep/bin/ebuild-helpers/die
new file mode 100755
index 0000000..9869141
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/die
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+die "$@"
+exit 1
diff --git a/portage_with_autodep/bin/ebuild-helpers/dobin b/portage_with_autodep/bin/ebuild-helpers/dobin
new file mode 100755
index 0000000..e385455
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dobin
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $# -lt 1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d ${D}${DESTTREE}/bin ]] ; then
+ install -d "${D}${DESTTREE}/bin" || { helpers_die "${0##*/}: failed to install ${D}${DESTTREE}/bin"; exit 2; }
+fi
+
+ret=0
+
+for x in "$@" ; do
+ if [[ -e ${x} ]] ; then
+ install -m0755 -o ${PORTAGE_INST_UID:-0} -g ${PORTAGE_INST_GID:-0} "${x}" "${D}${DESTTREE}/bin"
+ else
+ echo "!!! ${0##*/}: $x does not exist" 1>&2
+ false
+ fi
+ ((ret|=$?))
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/doconfd b/portage_with_autodep/bin/ebuild-helpers/doconfd
new file mode 100755
index 0000000..e146000
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doconfd
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+if [[ $# -lt 1 ]] ; then
+ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+exec \
+env \
+INSDESTTREE="/etc/conf.d/" \
+doins "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/dodir b/portage_with_autodep/bin/ebuild-helpers/dodir
new file mode 100755
index 0000000..f40bee7
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dodir
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+install -d ${DIROPTIONS} "${@/#/${D}/}"
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/dodoc b/portage_with_autodep/bin/ebuild-helpers/dodoc
new file mode 100755
index 0000000..65713db
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dodoc
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [ $# -lt 1 ] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+dir="${D}usr/share/doc/${PF}/${_E_DOCDESTTREE_}"
+if [ ! -d "${dir}" ] ; then
+ install -d "${dir}"
+fi
+
+ret=0
+for x in "$@" ; do
+ if [ -d "${x}" ] ; then
+ eqawarn "QA Notice: dodoc argument '${x}' is a directory"
+ elif [ -s "${x}" ] ; then
+ install -m0644 "${x}" "${dir}" || { ((ret|=1)); continue; }
+ ecompress --queue "${dir}/${x##*/}"
+ elif [ ! -e "${x}" ] ; then
+ echo "!!! ${0##*/}: $x does not exist" 1>&2
+ ((ret|=1))
+ fi
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/doenvd b/portage_with_autodep/bin/ebuild-helpers/doenvd
new file mode 100755
index 0000000..28ab5d2
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doenvd
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+if [[ $# -lt 1 ]] ; then
+ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+exec \
+env \
+INSDESTTREE="/etc/env.d/" \
+doins "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/doexe b/portage_with_autodep/bin/ebuild-helpers/doexe
new file mode 100755
index 0000000..360800e
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doexe
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $# -lt 1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d ${D}${_E_EXEDESTTREE_} ]] ; then
+ install -d "${D}${_E_EXEDESTTREE_}"
+fi
+
+TMP=$T/.doexe_tmp
+mkdir "$TMP"
+
+ret=0
+
+for x in "$@" ; do
+ if [ -L "${x}" ] ; then
+ cp "$x" "$TMP"
+ mysrc=$TMP/${x##*/}
+ elif [ -d "${x}" ] ; then
+ vecho "doexe: warning, skipping directory ${x}"
+ continue
+ else
+ mysrc="${x}"
+ fi
+ if [ -e "$mysrc" ] ; then
+ install $EXEOPTIONS "$mysrc" "$D$_E_EXEDESTTREE_"
+ else
+ echo "!!! ${0##*/}: $mysrc does not exist" 1>&2
+ false
+ fi
+ ((ret|=$?))
+done
+
+rm -rf "$TMP"
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/dohard b/portage_with_autodep/bin/ebuild-helpers/dohard
new file mode 100755
index 0000000..2270487
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dohard
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+if [[ $# -ne 2 ]] ; then
+ echo "$0: two arguments needed" 1>&2
+ exit 1
+fi
+
+destdir=${2%/*}
+[[ ! -d ${D}${destdir} ]] && dodir "${destdir}"
+
+exec ln -f "${D}$1" "${D}$2"
diff --git a/portage_with_autodep/bin/ebuild-helpers/dohtml b/portage_with_autodep/bin/ebuild-helpers/dohtml
new file mode 100755
index 0000000..630629a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dohtml
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Copyright 2009-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/dohtml.py" "$@"
+
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/doinfo b/portage_with_autodep/bin/ebuild-helpers/doinfo
new file mode 100755
index 0000000..54fb8da
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doinfo
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z $1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d ${D}usr/share/info ]] ; then
+ install -d "${D}usr/share/info" || { helpers_die "${0##*/}: failed to install ${D}usr/share/info"; exit 1; }
+fi
+
+install -m0644 "$@" "${D}usr/share/info"
+rval=$?
+if [ $rval -ne 0 ] ; then
+ for x in "$@" ; do
+ [ -e "$x" ] || echo "!!! ${0##*/}: $x does not exist" 1>&2
+ done
+ helpers_die "${0##*/} failed"
+fi
+exit $rval
diff --git a/portage_with_autodep/bin/ebuild-helpers/doinitd b/portage_with_autodep/bin/ebuild-helpers/doinitd
new file mode 100755
index 0000000..b711e19
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doinitd
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+if [[ $# -lt 1 ]] ; then
+ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+exec \
+env \
+_E_EXEDESTTREE_="/etc/init.d/" \
+doexe "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/doins b/portage_with_autodep/bin/ebuild-helpers/doins
new file mode 100755
index 0000000..7dec146
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doins
@@ -0,0 +1,155 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ ${0##*/} == dodoc ]] ; then
+ if [ $# -eq 0 ] ; then
+ # default_src_install may call dodoc with no arguments
+ # when DOC is defined but empty, so simply return
+ # sucessfully in this case.
+ exit 0
+ fi
+ export INSOPTIONS=-m0644
+ export INSDESTTREE=usr/share/doc/${PF}/${_E_DOCDESTTREE_}
+fi
+
+if [ $# -lt 1 ] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+if [[ "$1" == "-r" ]] ; then
+ DOINSRECUR=y
+ shift
+else
+ DOINSRECUR=n
+fi
+
+if [[ ${INSDESTTREE#${D}} != "${INSDESTTREE}" ]]; then
+ vecho "-------------------------------------------------------" 1>&2
+ vecho "You should not use \${D} with helpers." 1>&2
+ vecho " --> ${INSDESTTREE}" 1>&2
+ vecho "-------------------------------------------------------" 1>&2
+ helpers_die "${0##*/} used with \${D}"
+ exit 1
+fi
+
+case "$EAPI" in
+ 0|1|2|3|3_pre2)
+ PRESERVE_SYMLINKS=n
+ ;;
+ *)
+ PRESERVE_SYMLINKS=y
+ ;;
+esac
+
+export TMP=$T/.doins_tmp
+# Use separate directories to avoid potential name collisions.
+mkdir -p "$TMP"/{1,2}
+
+[[ ! -d ${D}${INSDESTTREE} ]] && dodir "${INSDESTTREE}"
+
+_doins() {
+ local mysrc="$1" mydir="$2" cleanup="" rval
+
+ if [ -L "$mysrc" ] ; then
+ # Our fake $DISTDIR contains symlinks that should
+ # not be reproduced inside $D. In order to ensure
+ # that things like dodoc "$DISTDIR"/foo.pdf work
+ # as expected, we dereference symlinked files that
+ # refer to absolute paths inside
+ # $PORTAGE_ACTUAL_DISTDIR/.
+ if [ $PRESERVE_SYMLINKS = y ] && \
+ ! [[ $(readlink "$mysrc") == "$PORTAGE_ACTUAL_DISTDIR"/* ]] ; then
+ rm -rf "$D$INSDESTTREE/$mydir/${mysrc##*/}" || return $?
+ cp -P "$mysrc" "$D$INSDESTTREE/$mydir/${mysrc##*/}"
+ return $?
+ else
+ cp "$mysrc" "$TMP/2/${mysrc##*/}" || return $?
+ mysrc="$TMP/2/${mysrc##*/}"
+ cleanup=$mysrc
+ fi
+ fi
+
+ install ${INSOPTIONS} "${mysrc}" "${D}${INSDESTTREE}/${mydir}"
+ rval=$?
+ [[ -n ${cleanup} ]] && rm -f "${cleanup}"
+ [ $rval -ne 0 ] && echo "!!! ${0##*/}: $mysrc does not exist" 1>&2
+ return $rval
+}
+
+_xdoins() {
+ local -i failed=0
+ while read -r -d $'\0' x ; do
+ _doins "$x" "${x%/*}"
+ ((failed|=$?))
+ done
+ return $failed
+}
+
+success=0
+failed=0
+
+for x in "$@" ; do
+ if [[ $PRESERVE_SYMLINKS = n && -d $x ]] || \
+ [[ $PRESERVE_SYMLINKS = y && -d $x && ! -L $x ]] ; then
+ if [ "${DOINSRECUR}" == "n" ] ; then
+ if [[ ${0##*/} == dodoc ]] ; then
+ echo "!!! ${0##*/}: $x is a directory" 1>&2
+ ((failed|=1))
+ fi
+ continue
+ fi
+
+ while [ "$x" != "${x%/}" ] ; do
+ x=${x%/}
+ done
+ if [ "$x" = "${x%/*}" ] ; then
+ pushd "$PWD" >/dev/null
+ else
+ pushd "${x%/*}" >/dev/null
+ fi
+ x=${x##*/}
+ x_orig=$x
+ # Follow any symlinks recursively until we've got
+ # a normal directory for 'find' to traverse. The
+ # name of the symlink will be used for the name
+ # of the installed directory, as discussed in
+ # bug #239529.
+ while [ -L "$x" ] ; do
+ pushd "$(readlink "$x")" >/dev/null
+ x=${PWD##*/}
+ pushd "${PWD%/*}" >/dev/null
+ done
+ if [[ $x != $x_orig ]] ; then
+ mv "$x" "$TMP/1/$x_orig"
+ pushd "$TMP/1" >/dev/null
+ fi
+ find "$x_orig" -type d -exec dodir "${INSDESTTREE}/{}" \;
+ find "$x_orig" \( -type f -or -type l \) -print0 | _xdoins
+ if [[ ${PIPESTATUS[1]} -eq 0 ]] ; then
+ # NOTE: Even if only an empty directory is installed here, it
+ # still counts as success, since an empty directory given as
+ # an argument to doins -r should not trigger failure.
+ ((success|=1))
+ else
+ ((failed|=1))
+ fi
+ if [[ $x != $x_orig ]] ; then
+ popd >/dev/null
+ mv "$TMP/1/$x_orig" "$x"
+ fi
+ while popd >/dev/null 2>&1 ; do true ; done
+ else
+ _doins "${x}"
+ if [[ $? -eq 0 ]] ; then
+ ((success|=1))
+ else
+ ((failed|=1))
+ fi
+ fi
+done
+rm -rf "$TMP"
+[[ $failed -ne 0 || $success -eq 0 ]] && { helpers_die "${0##*/} failed"; exit 1; } || exit 0
diff --git a/portage_with_autodep/bin/ebuild-helpers/dolib b/portage_with_autodep/bin/ebuild-helpers/dolib
new file mode 100755
index 0000000..87ade42
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dolib
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+# Setup ABI cruft
+LIBDIR_VAR="LIBDIR_${ABI}"
+if [[ -n ${ABI} && -n ${!LIBDIR_VAR} ]] ; then
+ CONF_LIBDIR=${!LIBDIR_VAR}
+fi
+unset LIBDIR_VAR
+# we need this to default to lib so that things dont break
+CONF_LIBDIR=${CONF_LIBDIR:-lib}
+libdir="${D}${DESTTREE}/${CONF_LIBDIR}"
+
+
+if [[ $# -lt 1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+if [[ ! -d ${libdir} ]] ; then
+ install -d "${libdir}" || { helpers_die "${0##*/}: failed to install ${libdir}"; exit 1; }
+fi
+
+ret=0
+
+for x in "$@" ; do
+ if [[ -e ${x} ]] ; then
+ if [[ ! -L ${x} ]] ; then
+ install ${LIBOPTIONS} "${x}" "${libdir}"
+ else
+ ln -s "$(readlink "${x}")" "${libdir}/${x##*/}"
+ fi
+ else
+ echo "!!! ${0##*/}: ${x} does not exist" 1>&2
+ false
+ fi
+ ((ret|=$?))
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/dolib.a b/portage_with_autodep/bin/ebuild-helpers/dolib.a
new file mode 100755
index 0000000..d2279dc
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dolib.a
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+exec env LIBOPTIONS="-m0644" \
+ dolib "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/dolib.so b/portage_with_autodep/bin/ebuild-helpers/dolib.so
new file mode 100755
index 0000000..4bdbfab
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dolib.so
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+exec env LIBOPTIONS="-m0755" \
+ dolib "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/doman b/portage_with_autodep/bin/ebuild-helpers/doman
new file mode 100755
index 0000000..4561bef
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/doman
@@ -0,0 +1,64 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $# -lt 1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+i18n=""
+
+ret=0
+
+for x in "$@" ; do
+ if [[ ${x:0:6} == "-i18n=" ]] ; then
+ i18n=${x:6}/
+ continue
+ fi
+ if [[ ${x:0:6} == ".keep_" ]] ; then
+ continue
+ fi
+
+ suffix=${x##*.}
+
+ # These will be automatically decompressed by ecompressdir.
+ if has ${suffix} Z gz bz2 ; then
+ realname=${x%.*}
+ suffix=${realname##*.}
+ fi
+
+ if has "${EAPI:-0}" 2 3 || [[ -z ${i18n} ]] \
+ && ! has "${EAPI:-0}" 0 1 \
+ && [[ $x =~ (.*)\.([a-z][a-z](_[A-Z][A-Z])?)\.(.*) ]]
+ then
+ name=${BASH_REMATCH[1]##*/}.${BASH_REMATCH[4]}
+ mandir=${BASH_REMATCH[2]}/man${suffix:0:1}
+ else
+ name=${x##*/}
+ mandir=${i18n#/}man${suffix:0:1}
+ fi
+
+
+ if [[ ${mandir} == *man[0-9n] ]] ; then
+ if [[ -s ${x} ]] ; then
+ if [[ ! -d ${D}/usr/share/man/${mandir} ]] ; then
+ install -d "${D}/usr/share/man/${mandir}"
+ fi
+
+ install -m0644 "${x}" "${D}/usr/share/man/${mandir}/${name}"
+ ((ret|=$?))
+ elif [[ ! -e ${x} ]] ; then
+ echo "!!! ${0##*/}: $x does not exist" 1>&2
+ ((ret|=1))
+ fi
+ else
+ vecho "doman: '${x}' is probably not a man page; skipping" 1>&2
+ ((ret|=1))
+ fi
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/domo b/portage_with_autodep/bin/ebuild-helpers/domo
new file mode 100755
index 0000000..4737f44
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/domo
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+mynum=${#}
+if [ ${mynum} -lt 1 ] ; then
+ helpers_die "${0}: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${D}${DESTTREE}/share/locale" ] ; then
+ install -d "${D}${DESTTREE}/share/locale/"
+fi
+
+ret=0
+
+for x in "$@" ; do
+ if [ -e "${x}" ] ; then
+ mytiny="${x##*/}"
+ mydir="${D}${DESTTREE}/share/locale/${mytiny%.*}/LC_MESSAGES"
+ if [ ! -d "${mydir}" ] ; then
+ install -d "${mydir}"
+ fi
+ install -m0644 "${x}" "${mydir}/${MOPREFIX}.mo"
+ else
+ echo "!!! ${0##*/}: $x does not exist" 1>&2
+ false
+ fi
+ ((ret|=$?))
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/dosbin b/portage_with_autodep/bin/ebuild-helpers/dosbin
new file mode 100755
index 0000000..87a3091
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dosbin
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $# -lt 1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+if [[ ! -d ${D}${DESTTREE}/sbin ]] ; then
+ install -d "${D}${DESTTREE}/sbin" || { helpers_die "${0##*/}: failed to install ${D}${DESTTREE}/sbin"; exit 2; }
+fi
+
+ret=0
+
+for x in "$@" ; do
+ if [[ -e ${x} ]] ; then
+ install -m0755 -o ${PORTAGE_INST_UID:-0} -g ${PORTAGE_INST_GID:-0} "${x}" "${D}${DESTTREE}/sbin"
+ else
+ echo "!!! ${0##*/}: ${x} does not exist" 1>&2
+ false
+ fi
+ ((ret|=$?))
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/dosed b/portage_with_autodep/bin/ebuild-helpers/dosed
new file mode 100755
index 0000000..afc949b
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dosed
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+if [[ $# -lt 1 ]] ; then
+ echo "!!! ${0##*/}: at least one argument needed" >&2
+ exit 1
+fi
+
+ret=0
+file_found=0
+mysed="s:${D}::g"
+
+for x in "$@" ; do
+ y=$D${x#/}
+ if [ -e "${y}" ] ; then
+ if [ -f "${y}" ] ; then
+ file_found=1
+ sed -i -e "${mysed}" "${y}"
+ else
+ echo "${y} is not a regular file!" >&2
+ false
+ fi
+ ((ret|=$?))
+ else
+ mysed="${x}"
+ fi
+done
+
+if [ $file_found = 0 ] ; then
+ echo "!!! ${0##*/}: $y does not exist" 1>&2
+ ((ret|=1))
+fi
+
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/dosym b/portage_with_autodep/bin/ebuild-helpers/dosym
new file mode 100755
index 0000000..500dad0
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/dosym
@@ -0,0 +1,18 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $# -ne 2 ]] ; then
+ helpers_die "${0##*/}: two arguments needed"
+ exit 1
+fi
+
+destdir=${2%/*}
+[[ ! -d ${D}${destdir} ]] && dodir "${destdir}"
+
+ln -snf "$1" "${D}$2"
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/ecompress b/portage_with_autodep/bin/ebuild-helpers/ecompress
new file mode 100755
index 0000000..b61421b
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/ecompress
@@ -0,0 +1,161 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z $1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+# setup compression stuff
+PORTAGE_COMPRESS=${PORTAGE_COMPRESS-bzip2}
+[[ -z ${PORTAGE_COMPRESS} ]] && exit 0
+
+if [[ ${PORTAGE_COMPRESS_FLAGS+set} != "set" ]] ; then
+ case ${PORTAGE_COMPRESS} in
+ bzip2|gzip) PORTAGE_COMPRESS_FLAGS="-9";;
+ esac
+fi
+
+# decompress_args(suffix, binary)
+# - suffix: the compression suffix to work with
+# - binary: the program to execute that'll compress/decompress
+# new_args: global array used to return revised arguments
+decompress_args() {
+ local suffix=$1 binary=$2
+ shift 2
+
+ # Initialize the global new_args array.
+ new_args=()
+ declare -a decompress_args=()
+ local x i=0 decompress_count=0
+ for x in "$@" ; do
+ if [[ ${x%$suffix} = $x ]] ; then
+ new_args[$i]=$x
+ else
+ new_args[$i]=${x%$suffix}
+ decompress_args[$decompress_count]=$x
+ ((decompress_count++))
+ fi
+ ((i++))
+ done
+
+ if [ $decompress_count -gt 0 ] ; then
+ ${binary} "${decompress_args[@]}"
+ if [ $? -ne 0 ] ; then
+ # Apparently decompression failed for one or more files, so
+ # drop those since we don't want to compress them twice.
+ new_args=()
+ local x i=0
+ for x in "$@" ; do
+ if [[ ${x%$suffix} = $x ]] ; then
+ new_args[$i]=$x
+ ((i++))
+ elif [[ -f ${x%$suffix} ]] ; then
+ new_args[$i]=${x%$suffix}
+ ((i++))
+ else
+ # Apparently decompression failed for this one, so drop
+ # it since we don't want to compress it twice.
+ true
+ fi
+ done
+ fi
+ fi
+}
+
+case $1 in
+ --suffix)
+ [[ -n $2 ]] && vecho "${0##*/}: --suffix takes no additional arguments" 1>&2
+
+ if [[ ! -e ${T}/.ecompress.suffix ]] ; then
+ set -e
+ tmpdir="${T}"/.ecompress$$.${RANDOM}
+ mkdir "${tmpdir}"
+ cd "${tmpdir}"
+ # we have to fill the file enough so that there is something
+ # to compress as some programs will refuse to do compression
+ # if it cannot actually compress the file
+ echo {0..1000} > compressme
+ ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS} compressme > /dev/null
+ # If PORTAGE_COMPRESS_FLAGS contains -k then we need to avoid
+ # having our glob match the uncompressed file here.
+ suffix=$(echo compressme.*)
+ [[ -z $suffix || "$suffix" == "compressme.*" ]] && \
+ suffix=$(echo compressme*)
+ suffix=${suffix#compressme}
+ cd /
+ rm -rf "${tmpdir}"
+ echo "${suffix}" > "${T}/.ecompress.suffix"
+ fi
+ cat "${T}/.ecompress.suffix"
+ ;;
+ --bin)
+ [[ -n $2 ]] && vecho "${0##*/}: --bin takes no additional arguments" 1>&2
+
+ echo "${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
+ ;;
+ --queue)
+ shift
+ ret=0
+ for x in "${@/%/.ecompress.file}" ; do
+ >> "$x"
+ ((ret|=$?))
+ done
+ [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ exit $ret
+ ;;
+ --dequeue)
+ [[ -n $2 ]] && vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
+ find "${D}" -name '*.ecompress.file' -print0 \
+ | sed -e 's:\.ecompress\.file::g' \
+ | ${XARGS} -0 ecompress
+ find "${D}" -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
+ ;;
+ --*)
+ helpers_die "${0##*/}: unknown arguments '$*'"
+ exit 1
+ ;;
+ *)
+ # Since dodoc calls ecompress on files that are already compressed,
+ # perform decompression here (similar to ecompressdir behavior).
+ decompress_args ".Z" "gunzip -f" "$@"
+ set -- "${new_args[@]}"
+ decompress_args ".gz" "gunzip -f" "$@"
+ set -- "${new_args[@]}"
+ decompress_args ".bz2" "bunzip2 -f" "$@"
+ set -- "${new_args[@]}"
+
+ mask_ext_re=""
+ set -f
+ for x in $PORTAGE_COMPRESS_EXCLUDE_SUFFIXES ; do
+ mask_ext_re+="|$x"
+ done
+ set +f
+ mask_ext_re="^(${mask_ext_re:1})\$"
+ declare -a filtered_args=()
+ i=0
+ for x in "$@" ; do
+ [[ ${x##*.} =~ $mask_ext_re ]] && continue
+ [[ -s ${x} ]] || continue
+ filtered_args[$i]=$x
+ ((i++))
+ done
+ [ $i -eq 0 ] && exit 0
+ set -- "${filtered_args[@]}"
+
+ # If a compressed version of the file already exists, simply
+ # delete it so that the compressor doesn't whine (bzip2 will
+ # complain and skip, gzip will prompt for input)
+ suffix=$(ecompress --suffix)
+ [[ -n ${suffix} ]] && echo -n "${@/%/${suffix}$'\001'}" | \
+ tr '\001' '\000' | ${XARGS} -0 rm -f
+ # Finally, let's actually do some real work
+ "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
+ ret=$?
+ [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ exit $ret
+ ;;
+esac
diff --git a/portage_with_autodep/bin/ebuild-helpers/ecompressdir b/portage_with_autodep/bin/ebuild-helpers/ecompressdir
new file mode 100755
index 0000000..7a95120
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/ecompressdir
@@ -0,0 +1,143 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z $1 ]] ; then
+ helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+case $1 in
+ --ignore)
+ shift
+ for skip in "$@" ; do
+ [[ -d ${D}${skip} || -f ${D}${skip} ]] \
+ && >> "${D}${skip}.ecompress.skip"
+ done
+ exit 0
+ ;;
+ --queue)
+ shift
+ set -- "${@/%/.ecompress.dir}"
+ set -- "${@/#/${D}}"
+ ret=0
+ for x in "$@" ; do
+ >> "$x"
+ ((ret|=$?))
+ done
+ [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ exit $ret
+ ;;
+ --dequeue)
+ [[ -n $2 ]] && vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
+ find "${D}" -name '*.ecompress.dir' -print0 \
+ | sed -e 's:\.ecompress\.dir::g' -e "s:${D}:/:g" \
+ | ${XARGS} -0 ecompressdir
+ find "${D}" -name '*.ecompress.skip' -print0 | ${XARGS} -0 rm -f
+ exit 0
+ ;;
+ --*)
+ helpers_die "${0##*/}: unknown arguments '$*'"
+ exit 1
+ ;;
+esac
+
+# figure out the new suffix
+suffix=$(ecompress --suffix)
+
+# funk_up_dir(action, suffix, binary)
+# - action: compress or decompress
+# - suffix: the compression suffix to work with
+# - binary: the program to execute that'll compress/decompress
+# The directory we act on is implied in the ${dir} variable
+funk_up_dir() {
+ local act=$1 suffix=$2 binary=$3
+
+ local negate=""
+ [[ ${act} == "compress" ]] && negate="!"
+
+ # first we act on all the files
+ find "${dir}" -type f ${negate} -iname '*'${suffix} -print0 | ${XARGS} -0 ${binary}
+ ((ret|=$?))
+
+ find "${dir}" -type l -print0 | \
+ while read -r -d $'\0' brokenlink ; do
+ [[ -e ${brokenlink} ]] && continue
+ olddest=$(readlink "${brokenlink}")
+ [[ ${act} == "compress" ]] \
+ && newdest="${olddest}${suffix}" \
+ || newdest="${olddest%${suffix}}"
+ rm -f "${brokenlink}"
+ [[ ${act} == "compress" ]] \
+ && ln -snf "${newdest}" "${brokenlink}${suffix}" \
+ || ln -snf "${newdest}" "${brokenlink%${suffix}}"
+ ((ret|=$?))
+ done
+}
+
+# _relocate_skip_dirs(srctree, dsttree)
+# Move all files and directories we want to skip running compression
+# on from srctree to dsttree.
+_relocate_skip_dirs() {
+ local srctree="$1" dsttree="$2"
+
+ [[ -d ${srctree} ]] || return 0
+
+ find "${srctree}" -name '*.ecompress.skip' -print0 | \
+ while read -r -d $'\0' src ; do
+ src=${src%.ecompress.skip}
+ dst="${dsttree}${src#${srctree}}"
+ parent=${dst%/*}
+ mkdir -p "${parent}"
+ mv "${src}" "${dst}"
+ mv "${src}.ecompress.skip" "${dst}.ecompress.skip"
+ done
+}
+hide_skip_dirs() { _relocate_skip_dirs "${D}" "${T}"/ecompress-skip/ ; }
+restore_skip_dirs() { _relocate_skip_dirs "${T}"/ecompress-skip/ "${D}" ; }
+
+ret=0
+
+rm -rf "${T}"/ecompress-skip
+
+for dir in "$@" ; do
+ dir=${dir#/}
+ dir="${D}${dir}"
+ if [[ ! -d ${dir} ]] ; then
+ vecho "${0##*/}: /${dir#${D}} does not exist!"
+ continue
+ fi
+ cd "${dir}"
+ actual_dir=${dir}
+ dir=. # use relative path to avoid 'Argument list too long' errors
+
+ # hide all the stuff we want to skip
+ hide_skip_dirs "${dir}"
+
+ # since we've been requested to compress the whole dir,
+ # delete any individual queued requests
+ rm -f "${actual_dir}.ecompress.dir"
+ find "${dir}" -type f -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
+
+ # not uncommon for packages to compress doc files themselves
+ funk_up_dir "decompress" ".Z" "gunzip -f"
+ funk_up_dir "decompress" ".gz" "gunzip -f"
+ funk_up_dir "decompress" ".bz2" "bunzip2 -f"
+
+ # forcibly break all hard links as some compressors whine about it
+ find "${dir}" -type f -links +1 -exec env file="{}" sh -c \
+ 'cp -p "${file}" "${file}.ecompress.break" ; mv -f "${file}.ecompress.break" "${file}"' \;
+
+ # now lets do our work
+ [[ -z ${suffix} ]] && continue
+ vecho "${0##*/}: $(ecompress --bin) /${actual_dir#${D}}"
+ funk_up_dir "compress" "${suffix}" "ecompress"
+
+ # finally, restore the skipped stuff
+ restore_skip_dirs
+done
+
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/eerror b/portage_with_autodep/bin/ebuild-helpers/eerror
new file mode 120000
index 0000000..a403c75
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/eerror
@@ -0,0 +1 @@
+elog \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/einfo b/portage_with_autodep/bin/ebuild-helpers/einfo
new file mode 120000
index 0000000..a403c75
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/einfo
@@ -0,0 +1 @@
+elog \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/elog b/portage_with_autodep/bin/ebuild-helpers/elog
new file mode 100755
index 0000000..a2303af
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/elog
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+${0##*/} "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/emake b/portage_with_autodep/bin/ebuild-helpers/emake
new file mode 100755
index 0000000..d842781
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/emake
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+#
+# emake: Supplies some default parameters to GNU make. At the moment the
+# only parameter supplied is -jN, where N is a number of
+# parallel processes that should be ideal for the running host
+# (e.g. on a single-CPU machine, N=2). The MAKEOPTS variable
+# is set in make.globals. We don't source make.globals
+# here because emake is only called from an ebuild.
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ $PORTAGE_QUIET != 1 ]] ; then
+ (
+ for arg in ${MAKE:-make} $MAKEOPTS $EXTRA_EMAKE "$@" ; do
+ [[ ${arg} == *" "* ]] \
+ && printf "'%s' " "${arg}" \
+ || printf "%s " "${arg}"
+ done
+ printf "\n"
+ ) >&2
+fi
+
+${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/eqawarn b/portage_with_autodep/bin/ebuild-helpers/eqawarn
new file mode 120000
index 0000000..a403c75
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/eqawarn
@@ -0,0 +1 @@
+elog \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/ewarn b/portage_with_autodep/bin/ebuild-helpers/ewarn
new file mode 120000
index 0000000..a403c75
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/ewarn
@@ -0,0 +1 @@
+elog \ No newline at end of file
diff --git a/portage_with_autodep/bin/ebuild-helpers/fowners b/portage_with_autodep/bin/ebuild-helpers/fowners
new file mode 100755
index 0000000..4cc6bfa
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/fowners
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+# we can't prefix all arguments because
+# chown takes random options
+slash="/"
+chown "${@/#${slash}/${D}${slash}}"
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/fperms b/portage_with_autodep/bin/ebuild-helpers/fperms
new file mode 100755
index 0000000..0260bdc
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/fperms
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+# we can't prefix all arguments because
+# chmod takes random options
+slash="/"
+chmod "${@/#${slash}/${D}${slash}}"
+ret=$?
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/newbin b/portage_with_autodep/bin/ebuild-helpers/newbin
new file mode 100755
index 0000000..30f19b0
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newbin
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec dobin "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newconfd b/portage_with_autodep/bin/ebuild-helpers/newconfd
new file mode 100755
index 0000000..5752cfa
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newconfd
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec doconfd "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newdoc b/portage_with_autodep/bin/ebuild-helpers/newdoc
new file mode 100755
index 0000000..f97ce0d
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newdoc
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec dodoc "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newenvd b/portage_with_autodep/bin/ebuild-helpers/newenvd
new file mode 100755
index 0000000..83c556e
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newenvd
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec doenvd "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newexe b/portage_with_autodep/bin/ebuild-helpers/newexe
new file mode 100755
index 0000000..92dbe9f
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newexe
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec doexe "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newinitd b/portage_with_autodep/bin/ebuild-helpers/newinitd
new file mode 100755
index 0000000..fc6003a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newinitd
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec doinitd "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newins b/portage_with_autodep/bin/ebuild-helpers/newins
new file mode 100755
index 0000000..065477f
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newins
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" || exit $?
+case "$EAPI" in
+ 0|1|2|3|3_pre2)
+ cp "$1" "$T/$2" || exit $?
+ ;;
+ *)
+ cp -P "$1" "$T/$2"
+ ret=$?
+ if [[ $ret -ne 0 ]] ; then
+ helpers_die "${0##*/} failed"
+ exit $ret
+ fi
+ ;;
+esac
+doins "${T}/${2}"
+ret=$?
+rm -rf "${T}/${2}"
+[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+exit $ret
diff --git a/portage_with_autodep/bin/ebuild-helpers/newlib.a b/portage_with_autodep/bin/ebuild-helpers/newlib.a
new file mode 100755
index 0000000..eef4104
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newlib.a
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec dolib.a "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newlib.so b/portage_with_autodep/bin/ebuild-helpers/newlib.so
new file mode 100755
index 0000000..c8696f3
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newlib.so
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec dolib.so "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newman b/portage_with_autodep/bin/ebuild-helpers/newman
new file mode 100755
index 0000000..ffb8a2d
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newman
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec doman "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/newsbin b/portage_with_autodep/bin/ebuild-helpers/newsbin
new file mode 100755
index 0000000..82242aa
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/newsbin
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
+ helpers_die "${0##*/}: Need two arguments, old file and new file"
+ exit 1
+fi
+
+if [ ! -e "$1" ] ; then
+ helpers_die "!!! ${0##*/}: $1 does not exist"
+ exit 1
+fi
+
+rm -rf "${T}/${2}" && \
+cp -f "${1}" "${T}/${2}" && \
+exec dosbin "${T}/${2}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/portageq b/portage_with_autodep/bin/ebuild-helpers/portageq
new file mode 100755
index 0000000..ec30b66
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/portageq
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 2009-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+ exec "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/portageq" "$@"
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepall b/portage_with_autodep/bin/ebuild-helpers/prepall
new file mode 100755
index 0000000..701ecba
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepall
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if has chflags $FEATURES ; then
+ # Save all the file flags for restoration at the end of prepall.
+ mtree -c -p "${D}" -k flags > "${T}/bsdflags.mtree"
+ # Remove all the file flags so that prepall can do anything necessary.
+ chflags -R noschg,nouchg,nosappnd,nouappnd "${D}"
+ chflags -R nosunlnk,nouunlnk "${D}" 2>/dev/null
+fi
+
+prepallman
+prepallinfo
+
+prepallstrip
+
+if has chflags $FEATURES ; then
+ # Restore all the file flags that were saved at the beginning of prepall.
+ mtree -U -e -p "${D}" -k flags < "${T}/bsdflags.mtree" &> /dev/null
+fi
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepalldocs b/portage_with_autodep/bin/ebuild-helpers/prepalldocs
new file mode 100755
index 0000000..fdc735d
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepalldocs
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -n $1 ]] ; then
+ vecho "${0##*/}: invalid usage; takes no arguments" 1>&2
+fi
+
+cd "${D}"
+[[ -d usr/share/doc ]] || exit 0
+
+ecompressdir --ignore /usr/share/doc/${PF}/html
+ecompressdir --queue /usr/share/doc
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepallinfo b/portage_with_autodep/bin/ebuild-helpers/prepallinfo
new file mode 100755
index 0000000..0d97803
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepallinfo
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+[[ ! -d ${D}usr/share/info ]] && exit 0
+
+exec prepinfo
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepallman b/portage_with_autodep/bin/ebuild-helpers/prepallman
new file mode 100755
index 0000000..e50de6d
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepallman
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+# replaced by controllable compression in EAPI 4
+has "${EAPI}" 0 1 2 3 || exit 0
+
+ret=0
+
+find "${D}" -type d -name man > "${T}"/prepallman.filelist
+while read -r mandir ; do
+ mandir=${mandir#${D}}
+ prepman "${mandir%/man}"
+ ((ret|=$?))
+done < "${T}"/prepallman.filelist
+
+exit ${ret}
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepallstrip b/portage_with_autodep/bin/ebuild-helpers/prepallstrip
new file mode 100755
index 0000000..ec12ce6
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepallstrip
@@ -0,0 +1,5 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+exec prepstrip "${D}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepinfo b/portage_with_autodep/bin/ebuild-helpers/prepinfo
new file mode 100755
index 0000000..691fd13
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepinfo
@@ -0,0 +1,34 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z $1 ]] ; then
+ infodir="/usr/share/info"
+else
+ if [[ -d ${D}$1/share/info ]] ; then
+ infodir="$1/share/info"
+ else
+ infodir="$1/info"
+ fi
+fi
+
+if [[ ! -d ${D}${infodir} ]] ; then
+ if [[ -n $1 ]] ; then
+ vecho "${0##*/}: '${infodir}' does not exist!"
+ exit 1
+ else
+ exit 0
+ fi
+fi
+
+find "${D}${infodir}" -type d -print0 | while read -r -d $'\0' x ; do
+ for f in "${x}"/.keepinfodir*; do
+ [[ -e ${f} ]] && continue 2
+ done
+ rm -f "${x}"/dir{,.info}{,.gz,.bz2}
+done
+
+has "${EAPI}" 0 1 2 3 || exit 0
+exec ecompressdir --queue "${infodir}"
diff --git a/portage_with_autodep/bin/ebuild-helpers/preplib b/portage_with_autodep/bin/ebuild-helpers/preplib
new file mode 100755
index 0000000..76aabe6
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/preplib
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+eqawarn "QA Notice: Deprecated call to 'preplib'"
+
+LIBDIR_VAR="LIBDIR_${ABI}"
+if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
+ CONF_LIBDIR="${!LIBDIR_VAR}"
+fi
+unset LIBDIR_VAR
+
+if [ -z "${CONF_LIBDIR}" ]; then
+ # we need this to default to lib so that things dont break
+ CONF_LIBDIR="lib"
+fi
+
+if [ -z "$1" ] ; then
+ z="${D}usr/${CONF_LIBDIR}"
+else
+ z="${D}$1/${CONF_LIBDIR}"
+fi
+
+if [ -d "${z}" ] ; then
+ ldconfig -n -N "${z}"
+fi
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepman b/portage_with_autodep/bin/ebuild-helpers/prepman
new file mode 100755
index 0000000..c9add8a
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepman
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if [[ -z $1 ]] ; then
+ mandir="${D}usr/share/man"
+else
+ mandir="${D}$1/man"
+fi
+
+if [[ ! -d ${mandir} ]] ; then
+ eqawarn "QA Notice: prepman called with non-existent dir '${mandir#${D}}'"
+ exit 0
+fi
+
+# replaced by controllable compression in EAPI 4
+has "${EAPI}" 0 1 2 3 || exit 0
+
+shopt -s nullglob
+
+really_is_mandir=0
+
+# use some heuristics to test if this is a real mandir
+for subdir in "${mandir}"/man* "${mandir}"/*/man* ; do
+ [[ -d ${subdir} ]] && really_is_mandir=1 && break
+done
+
+[[ ${really_is_mandir} == 1 ]] && exec ecompressdir --queue "${mandir#${D}}"
+
+exit 0
diff --git a/portage_with_autodep/bin/ebuild-helpers/prepstrip b/portage_with_autodep/bin/ebuild-helpers/prepstrip
new file mode 100755
index 0000000..d25259d
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/prepstrip
@@ -0,0 +1,193 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+banner=false
+SKIP_STRIP=false
+if has nostrip ${FEATURES} || \
+ has strip ${RESTRICT}
+then
+ SKIP_STRIP=true
+ banner=true
+ has installsources ${FEATURES} || exit 0
+fi
+
+STRIP=${STRIP:-${CHOST}-strip}
+type -P -- ${STRIP} > /dev/null || STRIP=strip
+OBJCOPY=${OBJCOPY:-${CHOST}-objcopy}
+type -P -- ${OBJCOPY} > /dev/null || OBJCOPY=objcopy
+
+# We'll leave out -R .note for now until we can check out the relevance
+# of the section when it has the ALLOC flag set on it ...
+export SAFE_STRIP_FLAGS="--strip-unneeded"
+export PORTAGE_STRIP_FLAGS=${PORTAGE_STRIP_FLAGS-${SAFE_STRIP_FLAGS} -R .comment}
+prepstrip_sources_dir=/usr/src/debug/${CATEGORY}/${PF}
+
+if has installsources ${FEATURES} && ! type -P debugedit >/dev/null ; then
+ ewarn "FEATURES=installsources is enabled but the debugedit binary could not"
+ ewarn "be found. This feature will not work unless debugedit is installed!"
+fi
+
+unset ${!INODE_*}
+
+inode_var_name() {
+ if [[ $USERLAND = BSD ]] ; then
+ stat -f 'INODE_%d_%i' "$1"
+ else
+ stat -c 'INODE_%d_%i' "$1"
+ fi
+}
+
+save_elf_sources() {
+ has installsources ${FEATURES} || return 0
+ has installsources ${RESTRICT} && return 0
+ type -P debugedit >/dev/null || return 0
+
+ local x=$1
+ local inode=$(inode_var_name "$x")
+ [[ -n ${!inode} ]] && return 0
+ debugedit -b "${WORKDIR}" -d "${prepstrip_sources_dir}" \
+ -l "${T}"/debug.sources "${x}"
+}
+
+save_elf_debug() {
+ has splitdebug ${FEATURES} || return 0
+
+ local x=$1
+ local y="${D}usr/lib/debug/${x:${#D}}.debug"
+
+ # dont save debug info twice
+ [[ ${x} == *".debug" ]] && return 0
+
+ # this will recompute the build-id, but for now that's ok
+ local buildid="$( type -P debugedit >/dev/null && debugedit -i "${x}" )"
+
+ mkdir -p $(dirname "${y}")
+
+ local inode=$(inode_var_name "$x")
+ if [[ -n ${!inode} ]] ; then
+ ln "${D}usr/lib/debug/${!inode:${#D}}.debug" "$y"
+ else
+ eval $inode=\$x
+ ${OBJCOPY} --only-keep-debug "${x}" "${y}"
+ ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}"
+ [[ -g ${x} ]] && chmod go-r "${y}"
+ [[ -u ${x} ]] && chmod go-r "${y}"
+ chmod a-x,o-w "${y}"
+ fi
+
+ if [[ -n ${buildid} ]] ; then
+ local buildid_dir="${D}usr/lib/debug/.build-id/${buildid:0:2}"
+ local buildid_file="${buildid_dir}/${buildid:2}"
+ mkdir -p "${buildid_dir}"
+ ln -s "../../${x:${#D}}.debug" "${buildid_file}.debug"
+ ln -s "/${x:${#D}}" "${buildid_file}"
+ fi
+}
+
+# The existance of the section .symtab tells us that a binary is stripped.
+# We want to log already stripped binaries, as this may be a QA violation.
+# They prevent us from getting the splitdebug data.
+if ! has binchecks ${RESTRICT} && \
+ ! has strip ${RESTRICT} ; then
+ log=$T/scanelf-already-stripped.log
+ qa_var="QA_PRESTRIPPED_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_PRESTRIPPED="${!qa_var}"
+ scanelf -yqRBF '#k%F' -k '!.symtab' "$@" | sed -e "s#^$D##" > "$log"
+ if [[ -n $QA_PRESTRIPPED && -s $log && \
+ ${QA_STRICT_PRESTRIPPED-unset} = unset ]] ; then
+ shopts=$-
+ set -o noglob
+ for x in $QA_PRESTRIPPED ; do
+ sed -e "s#^${x#/}\$##" -i "$log"
+ done
+ set +o noglob
+ set -$shopts
+ fi
+ sed -e "/^\$/d" -e "s#^#/#" -i "$log"
+ if [[ -s $log ]] ; then
+ vecho -e "\n"
+ eqawarn "QA Notice: Pre-stripped files found:"
+ eqawarn "$(<"$log")"
+ else
+ rm -f "$log"
+ fi
+fi
+
+# Now we look for unstripped binaries.
+for x in \
+ $(scanelf -yqRBF '#k%F' -k '.symtab' "$@") \
+ $(find "$@" -type f -name '*.a')
+do
+ if ! ${banner} ; then
+ vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
+ banner=true
+ fi
+
+ f=$(file "${x}") || continue
+ [[ -z ${f} ]] && continue
+
+ if ! ${SKIP_STRIP} ; then
+ # The noglob funk is to support STRIP_MASK="/*/booga" and to keep
+ # the for loop from expanding the globs.
+ # The eval echo is to support STRIP_MASK="/*/{booga,bar}" sex.
+ set -o noglob
+ strip_this=true
+ for m in $(eval echo ${STRIP_MASK}) ; do
+ [[ /${x#${D}} == ${m} ]] && strip_this=false && break
+ done
+ set +o noglob
+ else
+ strip_this=false
+ fi
+
+ # only split debug info for final linked objects
+ # or kernel modules as debuginfo for intermediatary
+ # files (think crt*.o from gcc/glibc) is useless and
+ # actually causes problems. install sources for all
+ # elf types though cause that stuff is good.
+
+ if [[ ${f} == *"current ar archive"* ]] ; then
+ vecho " ${x:${#D}}"
+ if ${strip_this} ; then
+ # hmm, can we split debug/sources for .a ?
+ ${STRIP} -g "${x}"
+ fi
+ elif [[ ${f} == *"SB executable"* || ${f} == *"SB shared object"* ]] ; then
+ vecho " ${x:${#D}}"
+ save_elf_sources "${x}"
+ if ${strip_this} ; then
+ save_elf_debug "${x}"
+ ${STRIP} ${PORTAGE_STRIP_FLAGS} "${x}"
+ fi
+ elif [[ ${f} == *"SB relocatable"* ]] ; then
+ vecho " ${x:${#D}}"
+ save_elf_sources "${x}"
+ if ${strip_this} ; then
+ [[ ${x} == *.ko ]] && save_elf_debug "${x}"
+ ${STRIP} ${SAFE_STRIP_FLAGS} "${x}"
+ fi
+ fi
+done
+
+if [[ -s ${T}/debug.sources ]] && \
+ has installsources ${FEATURES} && \
+ ! has installsources ${RESTRICT} && \
+ type -P debugedit >/dev/null
+then
+ vecho "installsources: rsyncing source files"
+ [[ -d ${D}${prepstrip_sources_dir} ]] || mkdir -p "${D}${prepstrip_sources_dir}"
+ grep -zv '/<[^/>]*>$' "${T}"/debug.sources | \
+ (cd "${WORKDIR}"; LANG=C sort -z -u | \
+ rsync -tL0 --files-from=- "${WORKDIR}/" "${D}${prepstrip_sources_dir}/" )
+
+ # Preserve directory structure.
+ # Needed after running save_elf_sources.
+ # https://bugzilla.redhat.com/show_bug.cgi?id=444310
+ while read -r -d $'\0' emptydir
+ do
+ >> "$emptydir"/.keepdir
+ done < <(find "${D}${prepstrip_sources_dir}/" -type d -empty -print0)
+fi
diff --git a/portage_with_autodep/bin/ebuild-helpers/sed b/portage_with_autodep/bin/ebuild-helpers/sed
new file mode 100755
index 0000000..b21e856
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-helpers/sed
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright 2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+scriptpath=${BASH_SOURCE[0]}
+scriptname=${scriptpath##*/}
+
+if [[ sed == ${scriptname} ]] && [[ -n ${ESED} ]]; then
+ exec ${ESED} "$@"
+elif type -P g${scriptname} > /dev/null ; then
+ exec g${scriptname} "$@"
+else
+ old_IFS="${IFS}"
+ IFS=":"
+
+ for path in $PATH; do
+ [[ ${path}/${scriptname} == ${scriptpath} ]] && continue
+ if [[ -x ${path}/${scriptname} ]]; then
+ exec ${path}/${scriptname} "$@"
+ exit 0
+ fi
+ done
+
+ IFS="${old_IFS}"
+fi
+
+exit 1
diff --git a/portage_with_autodep/bin/ebuild-ipc b/portage_with_autodep/bin/ebuild-ipc
new file mode 100755
index 0000000..43e4a02
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-ipc
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+ exec "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/ebuild-ipc.py" "$@"
diff --git a/portage_with_autodep/bin/ebuild-ipc.py b/portage_with_autodep/bin/ebuild-ipc.py
new file mode 100755
index 0000000..68ad985
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild-ipc.py
@@ -0,0 +1,276 @@
+#!/usr/bin/python
+# Copyright 2010-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+#
+# This is a helper which ebuild processes can use
+# to communicate with portage's main python process.
+
+import errno
+import logging
+import os
+import pickle
+import select
+import signal
+import sys
+import time
+
+def debug_signal(signum, frame):
+ import pdb
+ pdb.set_trace()
+signal.signal(signal.SIGUSR1, debug_signal)
+
+# Avoid sandbox violations after python upgrade.
+pym_path = os.path.join(os.path.dirname(
+ os.path.dirname(os.path.realpath(__file__))), "pym")
+if os.environ.get("SANDBOX_ON") == "1":
+ sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
+ if pym_path not in sandbox_write:
+ sandbox_write.append(pym_path)
+ os.environ["SANDBOX_WRITE"] = \
+ ":".join(filter(None, sandbox_write))
+
+import portage
+portage._disable_legacy_globals()
+
+class EbuildIpc(object):
+
+ # Timeout for each individual communication attempt (we retry
+ # as long as the daemon process appears to be alive).
+ _COMMUNICATE_RETRY_TIMEOUT_SECONDS = 15
+ _BUFSIZE = 4096
+
+ def __init__(self):
+ self.fifo_dir = os.environ['PORTAGE_BUILDDIR']
+ self.ipc_in_fifo = os.path.join(self.fifo_dir, '.ipc_in')
+ self.ipc_out_fifo = os.path.join(self.fifo_dir, '.ipc_out')
+ self.ipc_lock_file = os.path.join(self.fifo_dir, '.ipc_lock')
+
+ def _daemon_is_alive(self):
+ try:
+ builddir_lock = portage.locks.lockfile(self.fifo_dir,
+ wantnewlockfile=True, flags=os.O_NONBLOCK)
+ except portage.exception.TryAgain:
+ return True
+ else:
+ portage.locks.unlockfile(builddir_lock)
+ return False
+
+ def communicate(self, args):
+
+ # Make locks quiet since unintended locking messages displayed on
+ # stdout could corrupt the intended output of this program.
+ portage.locks._quiet = True
+ lock_obj = portage.locks.lockfile(self.ipc_lock_file, unlinkfile=True)
+
+ try:
+ return self._communicate(args)
+ finally:
+ portage.locks.unlockfile(lock_obj)
+
+ def _timeout_retry_msg(self, start_time, when):
+ time_elapsed = time.time() - start_time
+ portage.util.writemsg_level(
+ portage.localization._(
+ 'ebuild-ipc timed out %s after %d seconds,' + \
+ ' retrying...\n') % (when, time_elapsed),
+ level=logging.ERROR, noiselevel=-1)
+
+ def _no_daemon_msg(self):
+ portage.util.writemsg_level(
+ portage.localization._(
+ 'ebuild-ipc: daemon process not detected\n'),
+ level=logging.ERROR, noiselevel=-1)
+
+ def _wait(self, pid, pr, msg):
+ """
+ Wait on pid and return an appropriate exit code. This
+ may return unsuccessfully due to timeout if the daemon
+ process does not appear to be alive.
+ """
+
+ start_time = time.time()
+
+ while True:
+ try:
+ events = select.select([pr], [], [],
+ self._COMMUNICATE_RETRY_TIMEOUT_SECONDS)
+ except select.error as e:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % \
+ (portage.localization._('during select'), e),
+ level=logging.ERROR, noiselevel=-1)
+ continue
+
+ if events[0]:
+ break
+
+ if self._daemon_is_alive():
+ self._timeout_retry_msg(start_time, msg)
+ else:
+ self._no_daemon_msg()
+ try:
+ os.kill(pid, signal.SIGKILL)
+ os.waitpid(pid, 0)
+ except OSError as e:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s\n" % (e,),
+ level=logging.ERROR, noiselevel=-1)
+ return 2
+
+ try:
+ wait_retval = os.waitpid(pid, 0)
+ except OSError as e:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % (msg, e),
+ level=logging.ERROR, noiselevel=-1)
+ return 2
+
+ if not os.WIFEXITED(wait_retval[1]):
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % (msg,
+ portage.localization._('subprocess failure: %s') % \
+ wait_retval[1]),
+ level=logging.ERROR, noiselevel=-1)
+ return 2
+
+ return os.WEXITSTATUS(wait_retval[1])
+
+ def _receive_reply(self, input_fd):
+
+ # Timeouts are handled by the parent process, so just
+ # block until input is available. For maximum portability,
+ # use a single atomic read.
+ buf = None
+ while True:
+ try:
+ events = select.select([input_fd], [], [])
+ except select.error as e:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % \
+ (portage.localization._('during select for read'), e),
+ level=logging.ERROR, noiselevel=-1)
+ continue
+
+ if events[0]:
+ # For maximum portability, use os.read() here since
+ # array.fromfile() and file.read() are both known to
+ # erroneously return an empty string from this
+ # non-blocking fifo stream on FreeBSD (bug #337465).
+ try:
+ buf = os.read(input_fd, self._BUFSIZE)
+ except OSError as e:
+ if e.errno != errno.EAGAIN:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % \
+ (portage.localization._('read error'), e),
+ level=logging.ERROR, noiselevel=-1)
+ break
+ # Assume that another event will be generated
+ # if there's any relevant data.
+ continue
+
+ # Only one (atomic) read should be necessary.
+ if buf:
+ break
+
+ retval = 2
+
+ if not buf:
+
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s\n" % \
+ (portage.localization._('read failed'),),
+ level=logging.ERROR, noiselevel=-1)
+
+ else:
+
+ try:
+ reply = pickle.loads(buf)
+ except SystemExit:
+ raise
+ except Exception as e:
+ # The pickle module can raise practically
+ # any exception when given corrupt data.
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s\n" % (e,),
+ level=logging.ERROR, noiselevel=-1)
+
+ else:
+
+ (out, err, retval) = reply
+
+ if out:
+ portage.util.writemsg_stdout(out, noiselevel=-1)
+
+ if err:
+ portage.util.writemsg(err, noiselevel=-1)
+
+ return retval
+
+ def _communicate(self, args):
+
+ if not self._daemon_is_alive():
+ self._no_daemon_msg()
+ return 2
+
+ # Open the input fifo before the output fifo, in order to make it
+ # possible for the daemon to send a reply without blocking. This
+ # improves performance, and also makes it possible for the daemon
+ # to do a non-blocking write without a race condition.
+ input_fd = os.open(self.ipc_out_fifo,
+ os.O_RDONLY|os.O_NONBLOCK)
+
+ # Use forks so that the child process can handle blocking IO
+ # un-interrupted, while the parent handles all timeout
+ # considerations. This helps to avoid possible race conditions
+ # from interference between timeouts and blocking IO operations.
+ pr, pw = os.pipe()
+ pid = os.fork()
+
+ if pid == 0:
+ os.close(pr)
+
+ # File streams are in unbuffered mode since we do atomic
+ # read and write of whole pickles.
+ output_file = open(self.ipc_in_fifo, 'wb', 0)
+ output_file.write(pickle.dumps(args))
+ output_file.close()
+ os._exit(os.EX_OK)
+
+ os.close(pw)
+
+ msg = portage.localization._('during write')
+ retval = self._wait(pid, pr, msg)
+ os.close(pr)
+
+ if retval != os.EX_OK:
+ portage.util.writemsg_level(
+ "ebuild-ipc: %s: %s\n" % (msg,
+ portage.localization._('subprocess failure: %s') % \
+ retval), level=logging.ERROR, noiselevel=-1)
+ return retval
+
+ if not self._daemon_is_alive():
+ self._no_daemon_msg()
+ return 2
+
+ pr, pw = os.pipe()
+ pid = os.fork()
+
+ if pid == 0:
+ os.close(pr)
+ retval = self._receive_reply(input_fd)
+ os._exit(retval)
+
+ os.close(pw)
+ retval = self._wait(pid, pr, portage.localization._('during read'))
+ os.close(pr)
+ os.close(input_fd)
+ return retval
+
+def ebuild_ipc_main(args):
+ ebuild_ipc = EbuildIpc()
+ return ebuild_ipc.communicate(args)
+
+if __name__ == '__main__':
+ sys.exit(ebuild_ipc_main(sys.argv[1:]))
diff --git a/portage_with_autodep/bin/ebuild.sh b/portage_with_autodep/bin/ebuild.sh
new file mode 100755
index 0000000..d68e54b
--- /dev/null
+++ b/portage_with_autodep/bin/ebuild.sh
@@ -0,0 +1,2424 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+PORTAGE_BIN_PATH="${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"
+PORTAGE_PYM_PATH="${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}"
+
+if [[ $PORTAGE_SANDBOX_COMPAT_LEVEL -lt 22 ]] ; then
+ # Ensure that /dev/std* streams have appropriate sandbox permission for
+ # bug #288863. This can be removed after sandbox is fixed and portage
+ # depends on the fixed version (sandbox-2.2 has the fix but it is
+ # currently unstable).
+ export SANDBOX_WRITE="${SANDBOX_WRITE:+${SANDBOX_WRITE}:}/dev/stdout:/dev/stderr"
+ export SANDBOX_READ="${SANDBOX_READ:+${SANDBOX_READ}:}/dev/stdin"
+fi
+
+# Don't use sandbox's BASH_ENV for new shells because it does
+# 'source /etc/profile' which can interfere with the build
+# environment by modifying our PATH.
+unset BASH_ENV
+
+ROOTPATH=${ROOTPATH##:}
+ROOTPATH=${ROOTPATH%%:}
+PREROOTPATH=${PREROOTPATH##:}
+PREROOTPATH=${PREROOTPATH%%:}
+PATH=$PORTAGE_BIN_PATH/ebuild-helpers:$PREROOTPATH${PREROOTPATH:+:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin${ROOTPATH:+:}$ROOTPATH
+export PATH
+
+# This is just a temporary workaround for portage-9999 users since
+# earlier portage versions do not detect a version change in this case
+# (9999 to 9999) and therefore they try execute an incompatible version of
+# ebuild.sh during the upgrade.
+export PORTAGE_BZIP2_COMMAND=${PORTAGE_BZIP2_COMMAND:-bzip2}
+
+# These two functions wrap sourcing and calling respectively. At present they
+# perform a qa check to make sure eclasses and ebuilds and profiles don't mess
+# with shell opts (shopts). Ebuilds/eclasses changing shopts should reset them
+# when they are done.
+
+qa_source() {
+ local shopts=$(shopt) OLDIFS="$IFS"
+ local retval
+ source "$@"
+ retval=$?
+ set +e
+ [[ $shopts != $(shopt) ]] &&
+ eqawarn "QA Notice: Global shell options changed and were not restored while sourcing '$*'"
+ [[ "$IFS" != "$OLDIFS" ]] &&
+ eqawarn "QA Notice: Global IFS changed and was not restored while sourcing '$*'"
+ return $retval
+}
+
+qa_call() {
+ local shopts=$(shopt) OLDIFS="$IFS"
+ local retval
+ "$@"
+ retval=$?
+ set +e
+ [[ $shopts != $(shopt) ]] &&
+ eqawarn "QA Notice: Global shell options changed and were not restored while calling '$*'"
+ [[ "$IFS" != "$OLDIFS" ]] &&
+ eqawarn "QA Notice: Global IFS changed and was not restored while calling '$*'"
+ return $retval
+}
+
+EBUILD_SH_ARGS="$*"
+
+shift $#
+
+# Prevent aliases from causing portage to act inappropriately.
+# Make sure it's before everything so we don't mess aliases that follow.
+unalias -a
+
+# Unset some variables that break things.
+unset GZIP BZIP BZIP2 CDPATH GREP_OPTIONS GREP_COLOR GLOBIGNORE
+
+source "${PORTAGE_BIN_PATH}/isolated-functions.sh" &>/dev/null
+
+[[ $PORTAGE_QUIET != "" ]] && export PORTAGE_QUIET
+
+# sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex)
+_sb_append_var() {
+ local _v=$1 ; shift
+ local var="SANDBOX_${_v}"
+ [[ -z $1 || -n $2 ]] && die "Usage: add$(echo ${_v} | \
+ LC_ALL=C tr [:upper:] [:lower:]) <colon-delimited list of paths>"
+ export ${var}="${!var:+${!var}:}$1"
+}
+# bash-4 version:
+# local var="SANDBOX_${1^^}"
+# addread() { _sb_append_var ${0#add} "$@" ; }
+addread() { _sb_append_var READ "$@" ; }
+addwrite() { _sb_append_var WRITE "$@" ; }
+adddeny() { _sb_append_var DENY "$@" ; }
+addpredict() { _sb_append_var PREDICT "$@" ; }
+
+addwrite "${PORTAGE_TMPDIR}"
+addread "/:${PORTAGE_TMPDIR}"
+[[ -n ${PORTAGE_GPG_DIR} ]] && addpredict "${PORTAGE_GPG_DIR}"
+
+# Avoid sandbox violations in temporary directories.
+if [[ -w $T ]] ; then
+ export TEMP=$T
+ export TMP=$T
+ export TMPDIR=$T
+elif [[ $SANDBOX_ON = 1 ]] ; then
+ for x in TEMP TMP TMPDIR ; do
+ [[ -n ${!x} ]] && addwrite "${!x}"
+ done
+ unset x
+fi
+
+# the sandbox is disabled by default except when overridden in the relevant stages
+export SANDBOX_ON=0
+
+lchown() {
+ chown -h "$@"
+}
+
+lchgrp() {
+ chgrp -h "$@"
+}
+
+esyslog() {
+ # Custom version of esyslog() to take care of the "Red Star" bug.
+ # MUST follow functions.sh to override the "" parameter problem.
+ return 0
+}
+
+useq() {
+ has $EBUILD_PHASE prerm postrm || eqawarn \
+ "QA Notice: The 'useq' function is deprecated (replaced by 'use')"
+ use ${1}
+}
+
+usev() {
+ if use ${1}; then
+ echo "${1#!}"
+ return 0
+ fi
+ return 1
+}
+
+use() {
+ local u=$1
+ local found=0
+
+ # if we got something like '!flag', then invert the return value
+ if [[ ${u:0:1} == "!" ]] ; then
+ u=${u:1}
+ found=1
+ fi
+
+ if [[ $EBUILD_PHASE = depend ]] ; then
+ # TODO: Add a registration interface for eclasses to register
+ # any number of phase hooks, so that global scope eclass
+ # initialization can by migrated to phase hooks in new EAPIs.
+ # Example: add_phase_hook before pkg_setup $ECLASS_pre_pkg_setup
+ #if [[ -n $EAPI ]] && ! has "$EAPI" 0 1 2 3 ; then
+ # die "use() called during invalid phase: $EBUILD_PHASE"
+ #fi
+ true
+
+ # Make sure we have this USE flag in IUSE
+ elif [[ -n $PORTAGE_IUSE && -n $EBUILD_PHASE ]] ; then
+ [[ $u =~ $PORTAGE_IUSE ]] || \
+ eqawarn "QA Notice: USE Flag '${u}' not" \
+ "in IUSE for ${CATEGORY}/${PF}"
+ fi
+
+ if has ${u} ${USE} ; then
+ return ${found}
+ else
+ return $((!found))
+ fi
+}
+
+# Return true if given package is installed. Otherwise return false.
+# Takes single depend-type atoms.
+has_version() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ die "portageq calls (has_version calls portageq) are not allowed in the global scope"
+ fi
+
+ if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+ "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "$ROOT" "$1"
+ else
+ PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" has_version "${ROOT}" "$1"
+ fi
+ local retval=$?
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ *)
+ die "unexpected portageq exit code: ${retval}"
+ ;;
+ esac
+}
+
+portageq() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ die "portageq calls are not allowed in the global scope"
+ fi
+
+ PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" "$@"
+}
+
+
+# ----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
+
+
+# Returns the best/most-current match.
+# Takes single depend-type atoms.
+best_version() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ die "portageq calls (best_version calls portageq) are not allowed in the global scope"
+ fi
+
+ if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+ "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "$ROOT" "$1"
+ else
+ PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" 'best_version' "${ROOT}" "$1"
+ fi
+ local retval=$?
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ *)
+ die "unexpected portageq exit code: ${retval}"
+ ;;
+ esac
+}
+
+use_with() {
+ if [ -z "$1" ]; then
+ echo "!!! use_with() called without a parameter." >&2
+ echo "!!! use_with <USEFLAG> [<flagname> [value]]" >&2
+ return 1
+ fi
+
+ if ! has "${EAPI:-0}" 0 1 2 3 ; then
+ local UW_SUFFIX=${3+=$3}
+ else
+ local UW_SUFFIX=${3:+=$3}
+ fi
+ local UWORD=${2:-$1}
+
+ if use $1; then
+ echo "--with-${UWORD}${UW_SUFFIX}"
+ else
+ echo "--without-${UWORD}"
+ fi
+ return 0
+}
+
+use_enable() {
+ if [ -z "$1" ]; then
+ echo "!!! use_enable() called without a parameter." >&2
+ echo "!!! use_enable <USEFLAG> [<flagname> [value]]" >&2
+ return 1
+ fi
+
+ if ! has "${EAPI:-0}" 0 1 2 3 ; then
+ local UE_SUFFIX=${3+=$3}
+ else
+ local UE_SUFFIX=${3:+=$3}
+ fi
+ local UWORD=${2:-$1}
+
+ if use $1; then
+ echo "--enable-${UWORD}${UE_SUFFIX}"
+ else
+ echo "--disable-${UWORD}"
+ fi
+ return 0
+}
+
+register_die_hook() {
+ local x
+ for x in $* ; do
+ has $x $EBUILD_DEATH_HOOKS || \
+ export EBUILD_DEATH_HOOKS="$EBUILD_DEATH_HOOKS $x"
+ done
+}
+
+register_success_hook() {
+ local x
+ for x in $* ; do
+ has $x $EBUILD_SUCCESS_HOOKS || \
+ export EBUILD_SUCCESS_HOOKS="$EBUILD_SUCCESS_HOOKS $x"
+ done
+}
+
+# Ensure that $PWD is sane whenever possible, to protect against
+# exploitation of insecure search path for python -c in ebuilds.
+# See bug #239560.
+if ! has "$EBUILD_PHASE" clean cleanrm depend help ; then
+ cd "$PORTAGE_BUILDDIR" || \
+ die "PORTAGE_BUILDDIR does not exist: '$PORTAGE_BUILDDIR'"
+fi
+
+#if no perms are specified, dirs/files will have decent defaults
+#(not secretive, but not stupid)
+umask 022
+export DESTTREE=/usr
+export INSDESTTREE=""
+export _E_EXEDESTTREE_=""
+export _E_DOCDESTTREE_=""
+export INSOPTIONS="-m0644"
+export EXEOPTIONS="-m0755"
+export LIBOPTIONS="-m0644"
+export DIROPTIONS="-m0755"
+export MOPREFIX=${PN}
+declare -a PORTAGE_DOCOMPRESS=( /usr/share/{doc,info,man} )
+declare -a PORTAGE_DOCOMPRESS_SKIP=( /usr/share/doc/${PF}/html )
+
+# adds ".keep" files so that dirs aren't auto-cleaned
+keepdir() {
+ dodir "$@"
+ local x
+ if [ "$1" == "-R" ] || [ "$1" == "-r" ]; then
+ shift
+ find "$@" -type d -printf "${D}%p/.keep_${CATEGORY}_${PN}-${SLOT}\n" \
+ | tr "\n" "\0" | \
+ while read -r -d $'\0' ; do
+ >> "$REPLY" || \
+ die "Failed to recursively create .keep files"
+ done
+ else
+ for x in "$@"; do
+ >> "${D}${x}/.keep_${CATEGORY}_${PN}-${SLOT}" || \
+ die "Failed to create .keep in ${D}${x}"
+ done
+ fi
+}
+
+unpack() {
+ local srcdir
+ local x
+ local y
+ local myfail
+ local eapi=${EAPI:-0}
+ [ -z "$*" ] && die "Nothing passed to the 'unpack' command"
+
+ for x in "$@"; do
+ vecho ">>> Unpacking ${x} to ${PWD}"
+ y=${x%.*}
+ y=${y##*.}
+
+ if [[ ${x} == "./"* ]] ; then
+ srcdir=""
+ elif [[ ${x} == ${DISTDIR%/}/* ]] ; then
+ die "Arguments to unpack() cannot begin with \${DISTDIR}."
+ elif [[ ${x} == "/"* ]] ; then
+ die "Arguments to unpack() cannot be absolute"
+ else
+ srcdir="${DISTDIR}/"
+ fi
+ [[ ! -s ${srcdir}${x} ]] && die "${x} does not exist"
+
+ _unpack_tar() {
+ if [ "${y}" == "tar" ]; then
+ $1 -c -- "$srcdir$x" | tar xof -
+ assert_sigpipe_ok "$myfail"
+ else
+ local cwd_dest=${x##*/}
+ cwd_dest=${cwd_dest%.*}
+ $1 -c -- "${srcdir}${x}" > "${cwd_dest}" || die "$myfail"
+ fi
+ }
+
+ myfail="failure unpacking ${x}"
+ case "${x##*.}" in
+ tar)
+ tar xof "$srcdir$x" || die "$myfail"
+ ;;
+ tgz)
+ tar xozf "$srcdir$x" || die "$myfail"
+ ;;
+ tbz|tbz2)
+ ${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d} -c -- "$srcdir$x" | tar xof -
+ assert_sigpipe_ok "$myfail"
+ ;;
+ ZIP|zip|jar)
+ # unzip will interactively prompt under some error conditions,
+ # as reported in bug #336285
+ ( while true ; do echo n || break ; done ) | \
+ unzip -qo "${srcdir}${x}" || die "$myfail"
+ ;;
+ gz|Z|z)
+ _unpack_tar "gzip -d"
+ ;;
+ bz2|bz)
+ _unpack_tar "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}"
+ ;;
+ 7Z|7z)
+ local my_output
+ my_output="$(7z x -y "${srcdir}${x}")"
+ if [ $? -ne 0 ]; then
+ echo "${my_output}" >&2
+ die "$myfail"
+ fi
+ ;;
+ RAR|rar)
+ unrar x -idq -o+ "${srcdir}${x}" || die "$myfail"
+ ;;
+ LHa|LHA|lha|lzh)
+ lha xfq "${srcdir}${x}" || die "$myfail"
+ ;;
+ a)
+ ar x "${srcdir}${x}" || die "$myfail"
+ ;;
+ deb)
+ # Unpacking .deb archives can not always be done with
+ # `ar`. For instance on AIX this doesn't work out. If
+ # we have `deb2targz` installed, prefer it over `ar` for
+ # that reason. We just make sure on AIX `deb2targz` is
+ # installed.
+ if type -P deb2targz > /dev/null; then
+ y=${x##*/}
+ local created_symlink=0
+ if [ ! "$srcdir$x" -ef "$y" ] ; then
+ # deb2targz always extracts into the same directory as
+ # the source file, so create a symlink in the current
+ # working directory if necessary.
+ ln -sf "$srcdir$x" "$y" || die "$myfail"
+ created_symlink=1
+ fi
+ deb2targz "$y" || die "$myfail"
+ if [ $created_symlink = 1 ] ; then
+ # Clean up the symlink so the ebuild
+ # doesn't inadvertently install it.
+ rm -f "$y"
+ fi
+ mv -f "${y%.deb}".tar.gz data.tar.gz || die "$myfail"
+ else
+ ar x "$srcdir$x" || die "$myfail"
+ fi
+ ;;
+ lzma)
+ _unpack_tar "lzma -d"
+ ;;
+ xz)
+ if has $eapi 0 1 2 ; then
+ vecho "unpack ${x}: file format not recognized. Ignoring."
+ else
+ _unpack_tar "xz -d"
+ fi
+ ;;
+ *)
+ vecho "unpack ${x}: file format not recognized. Ignoring."
+ ;;
+ esac
+ done
+ # Do not chmod '.' since it's probably ${WORKDIR} and PORTAGE_WORKDIR_MODE
+ # should be preserved.
+ find . -mindepth 1 -maxdepth 1 ! -type l -print0 | \
+ ${XARGS} -0 chmod -fR a+rX,u+w,g-w,o-w
+}
+
+strip_duplicate_slashes() {
+ if [[ -n $1 ]] ; then
+ local removed=$1
+ while [[ ${removed} == *//* ]] ; do
+ removed=${removed//\/\///}
+ done
+ echo ${removed}
+ fi
+}
+
+hasg() {
+ local x s=$1
+ shift
+ for x ; do [[ ${x} == ${s} ]] && echo "${x}" && return 0 ; done
+ return 1
+}
+hasgq() { hasg "$@" >/dev/null ; }
+econf() {
+ local x
+
+ local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE")
+ if [[ -n $phase_func ]] ; then
+ if has "$EAPI" 0 1 ; then
+ [[ $phase_func != src_compile ]] && \
+ eqawarn "QA Notice: econf called in" \
+ "$phase_func instead of src_compile"
+ else
+ [[ $phase_func != src_configure ]] && \
+ eqawarn "QA Notice: econf called in" \
+ "$phase_func instead of src_configure"
+ fi
+ fi
+
+ : ${ECONF_SOURCE:=.}
+ if [ -x "${ECONF_SOURCE}/configure" ]; then
+ if [[ -n $CONFIG_SHELL && \
+ "$(head -n1 "$ECONF_SOURCE/configure")" =~ ^'#!'[[:space:]]*/bin/sh([[:space:]]|$) ]] ; then
+ sed -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" -i "$ECONF_SOURCE/configure" || \
+ die "Substition of shebang in '$ECONF_SOURCE/configure' failed"
+ fi
+ if [ -e /usr/share/gnuconfig/ ]; then
+ find "${WORKDIR}" -type f '(' \
+ -name config.guess -o -name config.sub ')' -print0 | \
+ while read -r -d $'\0' x ; do
+ vecho " * econf: updating ${x/${WORKDIR}\/} with /usr/share/gnuconfig/${x##*/}"
+ cp -f /usr/share/gnuconfig/"${x##*/}" "${x}"
+ done
+ fi
+
+ # EAPI=4 adds --disable-dependency-tracking to econf
+ if ! has "$EAPI" 0 1 2 3 3_pre2 && \
+ "${ECONF_SOURCE}/configure" --help 2>/dev/null | \
+ grep -q disable-dependency-tracking ; then
+ set -- --disable-dependency-tracking "$@"
+ fi
+
+ # if the profile defines a location to install libs to aside from default, pass it on.
+ # if the ebuild passes in --libdir, they're responsible for the conf_libdir fun.
+ local CONF_LIBDIR LIBDIR_VAR="LIBDIR_${ABI}"
+ if [[ -n ${ABI} && -n ${!LIBDIR_VAR} ]] ; then
+ CONF_LIBDIR=${!LIBDIR_VAR}
+ fi
+ if [[ -n ${CONF_LIBDIR} ]] && ! hasgq --libdir=\* "$@" ; then
+ export CONF_PREFIX=$(hasg --exec-prefix=\* "$@")
+ [[ -z ${CONF_PREFIX} ]] && CONF_PREFIX=$(hasg --prefix=\* "$@")
+ : ${CONF_PREFIX:=/usr}
+ CONF_PREFIX=${CONF_PREFIX#*=}
+ [[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX="/${CONF_PREFIX}"
+ [[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR="/${CONF_LIBDIR}"
+ set -- --libdir="$(strip_duplicate_slashes ${CONF_PREFIX}${CONF_LIBDIR})" "$@"
+ fi
+
+ set -- \
+ --prefix=/usr \
+ ${CBUILD:+--build=${CBUILD}} \
+ --host=${CHOST} \
+ ${CTARGET:+--target=${CTARGET}} \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --datadir=/usr/share \
+ --sysconfdir=/etc \
+ --localstatedir=/var/lib \
+ "$@" \
+ ${EXTRA_ECONF}
+ vecho "${ECONF_SOURCE}/configure" "$@"
+
+ if ! "${ECONF_SOURCE}/configure" "$@" ; then
+
+ if [ -s config.log ]; then
+ echo
+ echo "!!! Please attach the following file when seeking support:"
+ echo "!!! ${PWD}/config.log"
+ fi
+ die "econf failed"
+ fi
+ elif [ -f "${ECONF_SOURCE}/configure" ]; then
+ die "configure is not executable"
+ else
+ die "no configure script found"
+ fi
+}
+
+einstall() {
+ # CONF_PREFIX is only set if they didn't pass in libdir above.
+ local LOCAL_EXTRA_EINSTALL="${EXTRA_EINSTALL}"
+ LIBDIR_VAR="LIBDIR_${ABI}"
+ if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
+ CONF_LIBDIR="${!LIBDIR_VAR}"
+ fi
+ unset LIBDIR_VAR
+ if [ -n "${CONF_LIBDIR}" ] && [ "${CONF_PREFIX:+set}" = set ]; then
+ EI_DESTLIBDIR="${D}/${CONF_PREFIX}/${CONF_LIBDIR}"
+ EI_DESTLIBDIR="$(strip_duplicate_slashes ${EI_DESTLIBDIR})"
+ LOCAL_EXTRA_EINSTALL="libdir=${EI_DESTLIBDIR} ${LOCAL_EXTRA_EINSTALL}"
+ unset EI_DESTLIBDIR
+ fi
+
+ if [ -f ./[mM]akefile -o -f ./GNUmakefile ] ; then
+ if [ "${PORTAGE_DEBUG}" == "1" ]; then
+ ${MAKE:-make} -n prefix="${D}usr" \
+ datadir="${D}usr/share" \
+ infodir="${D}usr/share/info" \
+ localstatedir="${D}var/lib" \
+ mandir="${D}usr/share/man" \
+ sysconfdir="${D}etc" \
+ ${LOCAL_EXTRA_EINSTALL} \
+ ${MAKEOPTS} ${EXTRA_EMAKE} -j1 \
+ "$@" install
+ fi
+ ${MAKE:-make} prefix="${D}usr" \
+ datadir="${D}usr/share" \
+ infodir="${D}usr/share/info" \
+ localstatedir="${D}var/lib" \
+ mandir="${D}usr/share/man" \
+ sysconfdir="${D}etc" \
+ ${LOCAL_EXTRA_EINSTALL} \
+ ${MAKEOPTS} ${EXTRA_EMAKE} -j1 \
+ "$@" install || die "einstall failed"
+ else
+ die "no Makefile found"
+ fi
+}
+
+_eapi0_pkg_nofetch() {
+ [ -z "${SRC_URI}" ] && return
+
+ elog "The following are listed in SRC_URI for ${PN}:"
+ local x
+ for x in $(echo ${SRC_URI}); do
+ elog " ${x}"
+ done
+}
+
+_eapi0_src_unpack() {
+ [[ -n ${A} ]] && unpack ${A}
+}
+
+_eapi0_src_compile() {
+ if [ -x ./configure ] ; then
+ econf
+ fi
+ _eapi2_src_compile
+}
+
+_eapi0_src_test() {
+ # Since we don't want emake's automatic die
+ # support (EAPI 4 and later), and we also don't
+ # want the warning messages that it produces if
+ # we call it in 'nonfatal' mode, we use emake_cmd
+ # to emulate the desired parts of emake behavior.
+ local emake_cmd="${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE}"
+ if $emake_cmd -j1 check -n &> /dev/null; then
+ vecho ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ if ! $emake_cmd -j1 check; then
+ has test $FEATURES && die "Make check failed. See above for details."
+ has test $FEATURES || eerror "Make check failed. See above for details."
+ fi
+ elif $emake_cmd -j1 test -n &> /dev/null; then
+ vecho ">>> Test phase [test]: ${CATEGORY}/${PF}"
+ if ! $emake_cmd -j1 test; then
+ has test $FEATURES && die "Make test failed. See above for details."
+ has test $FEATURES || eerror "Make test failed. See above for details."
+ fi
+ else
+ vecho ">>> Test phase [none]: ${CATEGORY}/${PF}"
+ fi
+}
+
+_eapi1_src_compile() {
+ _eapi2_src_configure
+ _eapi2_src_compile
+}
+
+_eapi2_src_configure() {
+ if [[ -x ${ECONF_SOURCE:-.}/configure ]] ; then
+ econf
+ fi
+}
+
+_eapi2_src_compile() {
+ if [ -f Makefile ] || [ -f GNUmakefile ] || [ -f makefile ]; then
+ emake || die "emake failed"
+ fi
+}
+
+_eapi4_src_install() {
+ if [[ -f Makefile || -f GNUmakefile || -f makefile ]] ; then
+ emake DESTDIR="${D}" install
+ fi
+
+ if ! declare -p DOCS &>/dev/null ; then
+ local d
+ for d in README* ChangeLog AUTHORS NEWS TODO CHANGES \
+ THANKS BUGS FAQ CREDITS CHANGELOG ; do
+ [[ -s "${d}" ]] && dodoc "${d}"
+ done
+ elif [[ $(declare -p DOCS) == "declare -a "* ]] ; then
+ dodoc "${DOCS[@]}"
+ else
+ dodoc ${DOCS}
+ fi
+}
+
+ebuild_phase() {
+ declare -F "$1" >/dev/null && qa_call $1
+}
+
+ebuild_phase_with_hooks() {
+ local x phase_name=${1}
+ for x in {pre_,,post_}${phase_name} ; do
+ ebuild_phase ${x}
+ done
+}
+
+dyn_pretend() {
+ if [[ -e $PORTAGE_BUILDDIR/.pretended ]] ; then
+ vecho ">>> It appears that '$PF' is already pretended; skipping."
+ vecho ">>> Remove '$PORTAGE_BUILDDIR/.pretended' to force pretend."
+ return 0
+ fi
+ ebuild_phase pre_pkg_pretend
+ ebuild_phase pkg_pretend
+ >> "$PORTAGE_BUILDDIR/.pretended" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.pretended"
+ ebuild_phase post_pkg_pretend
+}
+
+dyn_setup() {
+ if [[ -e $PORTAGE_BUILDDIR/.setuped ]] ; then
+ vecho ">>> It appears that '$PF' is already setup; skipping."
+ vecho ">>> Remove '$PORTAGE_BUILDDIR/.setuped' to force setup."
+ return 0
+ fi
+ ebuild_phase pre_pkg_setup
+ ebuild_phase pkg_setup
+ >> "$PORTAGE_BUILDDIR/.setuped" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.setuped"
+ ebuild_phase post_pkg_setup
+}
+
+dyn_unpack() {
+ local newstuff="no"
+ if [ -e "${WORKDIR}" ]; then
+ local x
+ local checkme
+ for x in $A ; do
+ vecho ">>> Checking ${x}'s mtime..."
+ if [ "${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}/${x}" -nt "${WORKDIR}" ]; then
+ vecho ">>> ${x} has been updated; recreating WORKDIR..."
+ newstuff="yes"
+ break
+ fi
+ done
+ if [ ! -f "${PORTAGE_BUILDDIR}/.unpacked" ] ; then
+ vecho ">>> Not marked as unpacked; recreating WORKDIR..."
+ newstuff="yes"
+ fi
+ fi
+ if [ "${newstuff}" == "yes" ]; then
+ # We don't necessarily have privileges to do a full dyn_clean here.
+ rm -rf "${PORTAGE_BUILDDIR}"/{.setuped,.unpacked,.prepared,.configured,.compiled,.tested,.installed,.packaged,build-info}
+ if ! has keepwork $FEATURES ; then
+ rm -rf "${WORKDIR}"
+ fi
+ if [ -d "${T}" ] && \
+ ! has keeptemp $FEATURES ; then
+ rm -rf "${T}" && mkdir "${T}"
+ fi
+ fi
+ if [ -e "${WORKDIR}" ]; then
+ if [ "$newstuff" == "no" ]; then
+ vecho ">>> WORKDIR is up-to-date, keeping..."
+ return 0
+ fi
+ fi
+
+ if [ ! -d "${WORKDIR}" ]; then
+ install -m${PORTAGE_WORKDIR_MODE:-0700} -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'"
+ fi
+ cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`"
+ ebuild_phase pre_src_unpack
+ vecho ">>> Unpacking source..."
+ ebuild_phase src_unpack
+ >> "$PORTAGE_BUILDDIR/.unpacked" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.unpacked"
+ vecho ">>> Source unpacked in ${WORKDIR}"
+ ebuild_phase post_src_unpack
+}
+
+dyn_clean() {
+ if [ -z "${PORTAGE_BUILDDIR}" ]; then
+ echo "Aborting clean phase because PORTAGE_BUILDDIR is unset!"
+ return 1
+ elif [ ! -d "${PORTAGE_BUILDDIR}" ] ; then
+ return 0
+ fi
+ if has chflags $FEATURES ; then
+ chflags -R noschg,nouchg,nosappnd,nouappnd "${PORTAGE_BUILDDIR}"
+ chflags -R nosunlnk,nouunlnk "${PORTAGE_BUILDDIR}" 2>/dev/null
+ fi
+
+ rm -rf "${PORTAGE_BUILDDIR}/image" "${PORTAGE_BUILDDIR}/homedir"
+ rm -f "${PORTAGE_BUILDDIR}/.installed"
+
+ if [[ $EMERGE_FROM = binary ]] || \
+ ! has keeptemp $FEATURES && ! has keepwork $FEATURES ; then
+ rm -rf "${T}"
+ fi
+
+ if [[ $EMERGE_FROM = binary ]] || ! has keepwork $FEATURES; then
+ rm -f "$PORTAGE_BUILDDIR"/.{ebuild_changed,logid,pretended,setuped,unpacked,prepared} \
+ "$PORTAGE_BUILDDIR"/.{configured,compiled,tested,packaged} \
+ "$PORTAGE_BUILDDIR"/.die_hooks \
+ "$PORTAGE_BUILDDIR"/.ipc_{in,out,lock} \
+ "$PORTAGE_BUILDDIR"/.exit_status
+
+ rm -rf "${PORTAGE_BUILDDIR}/build-info"
+ rm -rf "${WORKDIR}"
+ fi
+
+ if [ -f "${PORTAGE_BUILDDIR}/.unpacked" ]; then
+ find "${PORTAGE_BUILDDIR}" -type d ! -regex "^${WORKDIR}" | sort -r | tr "\n" "\0" | $XARGS -0 rmdir &>/dev/null
+ fi
+
+ # do not bind this to doebuild defined DISTDIR; don't trust doebuild, and if mistakes are made it'll
+ # result in it wiping the users distfiles directory (bad).
+ rm -rf "${PORTAGE_BUILDDIR}/distdir"
+
+ # Some kernels, such as Solaris, return EINVAL when an attempt
+ # is made to remove the current working directory.
+ cd "$PORTAGE_BUILDDIR"/../..
+ rmdir "$PORTAGE_BUILDDIR" 2>/dev/null
+
+ true
+}
+
+into() {
+ if [ "$1" == "/" ]; then
+ export DESTTREE=""
+ else
+ export DESTTREE=$1
+ if [ ! -d "${D}${DESTTREE}" ]; then
+ install -d "${D}${DESTTREE}"
+ local ret=$?
+ if [[ $ret -ne 0 ]] ; then
+ helpers_die "${FUNCNAME[0]} failed"
+ return $ret
+ fi
+ fi
+ fi
+}
+
+insinto() {
+ if [ "$1" == "/" ]; then
+ export INSDESTTREE=""
+ else
+ export INSDESTTREE=$1
+ if [ ! -d "${D}${INSDESTTREE}" ]; then
+ install -d "${D}${INSDESTTREE}"
+ local ret=$?
+ if [[ $ret -ne 0 ]] ; then
+ helpers_die "${FUNCNAME[0]} failed"
+ return $ret
+ fi
+ fi
+ fi
+}
+
+exeinto() {
+ if [ "$1" == "/" ]; then
+ export _E_EXEDESTTREE_=""
+ else
+ export _E_EXEDESTTREE_="$1"
+ if [ ! -d "${D}${_E_EXEDESTTREE_}" ]; then
+ install -d "${D}${_E_EXEDESTTREE_}"
+ local ret=$?
+ if [[ $ret -ne 0 ]] ; then
+ helpers_die "${FUNCNAME[0]} failed"
+ return $ret
+ fi
+ fi
+ fi
+}
+
+docinto() {
+ if [ "$1" == "/" ]; then
+ export _E_DOCDESTTREE_=""
+ else
+ export _E_DOCDESTTREE_="$1"
+ if [ ! -d "${D}usr/share/doc/${PF}/${_E_DOCDESTTREE_}" ]; then
+ install -d "${D}usr/share/doc/${PF}/${_E_DOCDESTTREE_}"
+ local ret=$?
+ if [[ $ret -ne 0 ]] ; then
+ helpers_die "${FUNCNAME[0]} failed"
+ return $ret
+ fi
+ fi
+ fi
+}
+
+insopts() {
+ export INSOPTIONS="$@"
+
+ # `install` should never be called with '-s' ...
+ has -s ${INSOPTIONS} && die "Never call insopts() with -s"
+}
+
+diropts() {
+ export DIROPTIONS="$@"
+}
+
+exeopts() {
+ export EXEOPTIONS="$@"
+
+ # `install` should never be called with '-s' ...
+ has -s ${EXEOPTIONS} && die "Never call exeopts() with -s"
+}
+
+libopts() {
+ export LIBOPTIONS="$@"
+
+ # `install` should never be called with '-s' ...
+ has -s ${LIBOPTIONS} && die "Never call libopts() with -s"
+}
+
+docompress() {
+ has "${EAPI}" 0 1 2 3 && die "'docompress' not supported in this EAPI"
+
+ local f g
+ if [[ $1 = "-x" ]]; then
+ shift
+ for f; do
+ f=$(strip_duplicate_slashes "${f}"); f=${f%/}
+ [[ ${f:0:1} = / ]] || f="/${f}"
+ for g in "${PORTAGE_DOCOMPRESS_SKIP[@]}"; do
+ [[ ${f} = "${g}" ]] && continue 2
+ done
+ PORTAGE_DOCOMPRESS_SKIP[${#PORTAGE_DOCOMPRESS_SKIP[@]}]=${f}
+ done
+ else
+ for f; do
+ f=$(strip_duplicate_slashes "${f}"); f=${f%/}
+ [[ ${f:0:1} = / ]] || f="/${f}"
+ for g in "${PORTAGE_DOCOMPRESS[@]}"; do
+ [[ ${f} = "${g}" ]] && continue 2
+ done
+ PORTAGE_DOCOMPRESS[${#PORTAGE_DOCOMPRESS[@]}]=${f}
+ done
+ fi
+}
+
+abort_handler() {
+ local msg
+ if [ "$2" != "fail" ]; then
+ msg="${EBUILD}: ${1} aborted; exiting."
+ else
+ msg="${EBUILD}: ${1} failed; exiting."
+ fi
+ echo
+ echo "$msg"
+ echo
+ eval ${3}
+ #unset signal handler
+ trap - SIGINT SIGQUIT
+}
+
+abort_prepare() {
+ abort_handler src_prepare $1
+ rm -f "$PORTAGE_BUILDDIR/.prepared"
+ exit 1
+}
+
+abort_configure() {
+ abort_handler src_configure $1
+ rm -f "$PORTAGE_BUILDDIR/.configured"
+ exit 1
+}
+
+abort_compile() {
+ abort_handler "src_compile" $1
+ rm -f "${PORTAGE_BUILDDIR}/.compiled"
+ exit 1
+}
+
+abort_test() {
+ abort_handler "dyn_test" $1
+ rm -f "${PORTAGE_BUILDDIR}/.tested"
+ exit 1
+}
+
+abort_install() {
+ abort_handler "src_install" $1
+ rm -rf "${PORTAGE_BUILDDIR}/image"
+ exit 1
+}
+
+has_phase_defined_up_to() {
+ local phase
+ for phase in unpack prepare configure compile install; do
+ has ${phase} ${DEFINED_PHASES} && return 0
+ [[ ${phase} == $1 ]] && return 1
+ done
+ # We shouldn't actually get here
+ return 1
+}
+
+dyn_prepare() {
+
+ if [[ -e $PORTAGE_BUILDDIR/.prepared ]] ; then
+ vecho ">>> It appears that '$PF' is already prepared; skipping."
+ vecho ">>> Remove '$PORTAGE_BUILDDIR/.prepared' to force prepare."
+ return 0
+ fi
+
+ if [[ -d $S ]] ; then
+ cd "${S}"
+ elif has $EAPI 0 1 2 3 3_pre2 ; then
+ cd "${WORKDIR}"
+ elif [[ -z ${A} ]] && ! has_phase_defined_up_to prepare; then
+ cd "${WORKDIR}"
+ else
+ die "The source directory '${S}' doesn't exist"
+ fi
+
+ trap abort_prepare SIGINT SIGQUIT
+
+ ebuild_phase pre_src_prepare
+ vecho ">>> Preparing source in $PWD ..."
+ ebuild_phase src_prepare
+ >> "$PORTAGE_BUILDDIR/.prepared" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.prepared"
+ vecho ">>> Source prepared."
+ ebuild_phase post_src_prepare
+
+ trap - SIGINT SIGQUIT
+}
+
+dyn_configure() {
+
+ if [[ -e $PORTAGE_BUILDDIR/.configured ]] ; then
+ vecho ">>> It appears that '$PF' is already configured; skipping."
+ vecho ">>> Remove '$PORTAGE_BUILDDIR/.configured' to force configuration."
+ return 0
+ fi
+
+ if [[ -d $S ]] ; then
+ cd "${S}"
+ elif has $EAPI 0 1 2 3 3_pre2 ; then
+ cd "${WORKDIR}"
+ elif [[ -z ${A} ]] && ! has_phase_defined_up_to configure; then
+ cd "${WORKDIR}"
+ else
+ die "The source directory '${S}' doesn't exist"
+ fi
+
+ trap abort_configure SIGINT SIGQUIT
+
+ ebuild_phase pre_src_configure
+
+ vecho ">>> Configuring source in $PWD ..."
+ ebuild_phase src_configure
+ >> "$PORTAGE_BUILDDIR/.configured" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.configured"
+ vecho ">>> Source configured."
+
+ ebuild_phase post_src_configure
+
+ trap - SIGINT SIGQUIT
+}
+
+dyn_compile() {
+
+ if [[ -e $PORTAGE_BUILDDIR/.compiled ]] ; then
+ vecho ">>> It appears that '${PF}' is already compiled; skipping."
+ vecho ">>> Remove '$PORTAGE_BUILDDIR/.compiled' to force compilation."
+ return 0
+ fi
+
+ if [[ -d $S ]] ; then
+ cd "${S}"
+ elif has $EAPI 0 1 2 3 3_pre2 ; then
+ cd "${WORKDIR}"
+ elif [[ -z ${A} ]] && ! has_phase_defined_up_to compile; then
+ cd "${WORKDIR}"
+ else
+ die "The source directory '${S}' doesn't exist"
+ fi
+
+ trap abort_compile SIGINT SIGQUIT
+
+ if has distcc $FEATURES && has distcc-pump $FEATURES ; then
+ if [[ -z $INCLUDE_SERVER_PORT ]] || [[ ! -w $INCLUDE_SERVER_PORT ]] ; then
+ eval $(pump --startup)
+ trap "pump --shutdown" EXIT
+ fi
+ fi
+
+ ebuild_phase pre_src_compile
+
+ vecho ">>> Compiling source in $PWD ..."
+ ebuild_phase src_compile
+ >> "$PORTAGE_BUILDDIR/.compiled" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.compiled"
+ vecho ">>> Source compiled."
+
+ ebuild_phase post_src_compile
+
+ trap - SIGINT SIGQUIT
+}
+
+dyn_test() {
+
+ if [[ -e $PORTAGE_BUILDDIR/.tested ]] ; then
+ vecho ">>> It appears that ${PN} has already been tested; skipping."
+ vecho ">>> Remove '${PORTAGE_BUILDDIR}/.tested' to force test."
+ return
+ fi
+
+ if [ "${EBUILD_FORCE_TEST}" == "1" ] ; then
+ # If USE came from ${T}/environment then it might not have USE=test
+ # like it's supposed to here.
+ ! has test ${USE} && export USE="${USE} test"
+ fi
+
+ trap "abort_test" SIGINT SIGQUIT
+ if [ -d "${S}" ]; then
+ cd "${S}"
+ else
+ cd "${WORKDIR}"
+ fi
+
+ if ! has test $FEATURES && [ "${EBUILD_FORCE_TEST}" != "1" ]; then
+ vecho ">>> Test phase [not enabled]: ${CATEGORY}/${PF}"
+ elif has test $RESTRICT; then
+ einfo "Skipping make test/check due to ebuild restriction."
+ vecho ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}"
+ else
+ local save_sp=${SANDBOX_PREDICT}
+ addpredict /
+ ebuild_phase pre_src_test
+ ebuild_phase src_test
+ >> "$PORTAGE_BUILDDIR/.tested" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.tested"
+ ebuild_phase post_src_test
+ SANDBOX_PREDICT=${save_sp}
+ fi
+
+ trap - SIGINT SIGQUIT
+}
+
+dyn_install() {
+ [ -z "$PORTAGE_BUILDDIR" ] && die "${FUNCNAME}: PORTAGE_BUILDDIR is unset"
+ if has noauto $FEATURES ; then
+ rm -f "${PORTAGE_BUILDDIR}/.installed"
+ elif [[ -e $PORTAGE_BUILDDIR/.installed ]] ; then
+ vecho ">>> It appears that '${PF}' is already installed; skipping."
+ vecho ">>> Remove '${PORTAGE_BUILDDIR}/.installed' to force install."
+ return 0
+ fi
+ trap "abort_install" SIGINT SIGQUIT
+ ebuild_phase pre_src_install
+ rm -rf "${PORTAGE_BUILDDIR}/image"
+ mkdir "${PORTAGE_BUILDDIR}/image"
+ if [[ -d $S ]] ; then
+ cd "${S}"
+ elif has $EAPI 0 1 2 3 3_pre2 ; then
+ cd "${WORKDIR}"
+ elif [[ -z ${A} ]] && ! has_phase_defined_up_to install; then
+ cd "${WORKDIR}"
+ else
+ die "The source directory '${S}' doesn't exist"
+ fi
+
+ vecho
+ vecho ">>> Install ${PF} into ${D} category ${CATEGORY}"
+ #our custom version of libtool uses $S and $D to fix
+ #invalid paths in .la files
+ export S D
+
+ # Reset exeinto(), docinto(), insinto(), and into() state variables
+ # in case the user is running the install phase multiple times
+ # consecutively via the ebuild command.
+ export DESTTREE=/usr
+ export INSDESTTREE=""
+ export _E_EXEDESTTREE_=""
+ export _E_DOCDESTTREE_=""
+
+ ebuild_phase src_install
+ >> "$PORTAGE_BUILDDIR/.installed" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.installed"
+ vecho ">>> Completed installing ${PF} into ${D}"
+ vecho
+ ebuild_phase post_src_install
+
+ cd "${PORTAGE_BUILDDIR}"/build-info
+ set -f
+ local f x
+ IFS=$' \t\n\r'
+ for f in CATEGORY DEFINED_PHASES FEATURES INHERITED IUSE REQUIRED_USE \
+ PF PKGUSE SLOT KEYWORDS HOMEPAGE DESCRIPTION ; do
+ x=$(echo -n ${!f})
+ [[ -n $x ]] && echo "$x" > $f
+ done
+ if [[ $CATEGORY != virtual ]] ; then
+ for f in ASFLAGS CBUILD CC CFLAGS CHOST CTARGET CXX \
+ CXXFLAGS EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \
+ LDFLAGS LIBCFLAGS LIBCXXFLAGS ; do
+ x=$(echo -n ${!f})
+ [[ -n $x ]] && echo "$x" > $f
+ done
+ fi
+ echo "${USE}" > USE
+ echo "${EAPI:-0}" > EAPI
+ set +f
+
+ # local variables can leak into the saved environment.
+ unset f
+
+ save_ebuild_env --exclude-init-phases | filter_readonly_variables \
+ --filter-path --filter-sandbox --allow-extra-vars > environment
+ assert "save_ebuild_env failed"
+
+ ${PORTAGE_BZIP2_COMMAND} -f9 environment
+
+ cp "${EBUILD}" "${PF}.ebuild"
+ [ -n "${PORTAGE_REPO_NAME}" ] && echo "${PORTAGE_REPO_NAME}" > repository
+ if has nostrip ${FEATURES} ${RESTRICT} || has strip ${RESTRICT}
+ then
+ >> DEBUGBUILD
+ fi
+ trap - SIGINT SIGQUIT
+}
+
+dyn_preinst() {
+ if [ -z "${D}" ]; then
+ eerror "${FUNCNAME}: D is unset"
+ return 1
+ fi
+ ebuild_phase_with_hooks pkg_preinst
+}
+
+dyn_help() {
+ echo
+ echo "Portage"
+ echo "Copyright 1999-2010 Gentoo Foundation"
+ echo
+ echo "How to use the ebuild command:"
+ echo
+ echo "The first argument to ebuild should be an existing .ebuild file."
+ echo
+ echo "One or more of the following options can then be specified. If more"
+ echo "than one option is specified, each will be executed in order."
+ echo
+ echo " help : show this help screen"
+ echo " pretend : execute package specific pretend actions"
+ echo " setup : execute package specific setup actions"
+ echo " fetch : download source archive(s) and patches"
+ echo " digest : create a manifest file for the package"
+ echo " manifest : create a manifest file for the package"
+ echo " unpack : unpack sources (auto-dependencies if needed)"
+ echo " prepare : prepare sources (auto-dependencies if needed)"
+ echo " configure : configure sources (auto-fetch/unpack if needed)"
+ echo " compile : compile sources (auto-fetch/unpack/configure if needed)"
+ echo " test : test package (auto-fetch/unpack/configure/compile if needed)"
+ echo " preinst : execute pre-install instructions"
+ echo " postinst : execute post-install instructions"
+ echo " install : install the package to the temporary install directory"
+ echo " qmerge : merge image into live filesystem, recording files in db"
+ echo " merge : do fetch, unpack, compile, install and qmerge"
+ echo " prerm : execute pre-removal instructions"
+ echo " postrm : execute post-removal instructions"
+ echo " unmerge : remove package from live filesystem"
+ echo " config : execute package specific configuration actions"
+ echo " package : create a tarball package in ${PKGDIR}/All"
+ echo " rpm : build a RedHat RPM package"
+ echo " clean : clean up all source and temporary files"
+ echo
+ echo "The following settings will be used for the ebuild process:"
+ echo
+ echo " package : ${PF}"
+ echo " slot : ${SLOT}"
+ echo " category : ${CATEGORY}"
+ echo " description : ${DESCRIPTION}"
+ echo " system : ${CHOST}"
+ echo " c flags : ${CFLAGS}"
+ echo " c++ flags : ${CXXFLAGS}"
+ echo " make flags : ${MAKEOPTS}"
+ echo -n " build mode : "
+ if has nostrip ${FEATURES} ${RESTRICT} || has strip ${RESTRICT} ;
+ then
+ echo "debug (large)"
+ else
+ echo "production (stripped)"
+ fi
+ echo " merge to : ${ROOT}"
+ echo
+ if [ -n "$USE" ]; then
+ echo "Additionally, support for the following optional features will be enabled:"
+ echo
+ echo " ${USE}"
+ fi
+ echo
+}
+
+# debug-print() gets called from many places with verbose status information useful
+# for tracking down problems. The output is in $T/eclass-debug.log.
+# You can set ECLASS_DEBUG_OUTPUT to redirect the output somewhere else as well.
+# The special "on" setting echoes the information, mixing it with the rest of the
+# emerge output.
+# You can override the setting by exporting a new one from the console, or you can
+# set a new default in make.*. Here the default is "" or unset.
+
+# in the future might use e* from /etc/init.d/functions.sh if i feel like it
+debug-print() {
+ # if $T isn't defined, we're in dep calculation mode and
+ # shouldn't do anything
+ [[ $EBUILD_PHASE = depend || ! -d ${T} || ${#} -eq 0 ]] && return 0
+
+ if [[ ${ECLASS_DEBUG_OUTPUT} == on ]]; then
+ printf 'debug: %s\n' "${@}" >&2
+ elif [[ -n ${ECLASS_DEBUG_OUTPUT} ]]; then
+ printf 'debug: %s\n' "${@}" >> "${ECLASS_DEBUG_OUTPUT}"
+ fi
+
+ if [[ -w $T ]] ; then
+ # default target
+ printf '%s\n' "${@}" >> "${T}/eclass-debug.log"
+ # let the portage user own/write to this file
+ chgrp portage "${T}/eclass-debug.log" &>/dev/null
+ chmod g+w "${T}/eclass-debug.log" &>/dev/null
+ fi
+}
+
+# The following 2 functions are debug-print() wrappers
+
+debug-print-function() {
+ debug-print "${1}: entering function, parameters: ${*:2}"
+}
+
+debug-print-section() {
+ debug-print "now in section ${*}"
+}
+
+# Sources all eclasses in parameters
+declare -ix ECLASS_DEPTH=0
+inherit() {
+ ECLASS_DEPTH=$(($ECLASS_DEPTH + 1))
+ if [[ ${ECLASS_DEPTH} > 1 ]]; then
+ debug-print "*** Multiple Inheritence (Level: ${ECLASS_DEPTH})"
+ fi
+
+ if [[ -n $ECLASS && -n ${!__export_funcs_var} ]] ; then
+ echo "QA Notice: EXPORT_FUNCTIONS is called before inherit in" \
+ "$ECLASS.eclass. For compatibility with <=portage-2.1.6.7," \
+ "only call EXPORT_FUNCTIONS after inherit(s)." \
+ | fmt -w 75 | while read -r ; do eqawarn "$REPLY" ; done
+ fi
+
+ local location
+ local olocation
+ local x
+
+ # These variables must be restored before returning.
+ local PECLASS=$ECLASS
+ local prev_export_funcs_var=$__export_funcs_var
+
+ local B_IUSE
+ local B_REQUIRED_USE
+ local B_DEPEND
+ local B_RDEPEND
+ local B_PDEPEND
+ while [ "$1" ]; do
+ location="${ECLASSDIR}/${1}.eclass"
+ olocation=""
+
+ export ECLASS="$1"
+ __export_funcs_var=__export_functions_$ECLASS_DEPTH
+ unset $__export_funcs_var
+
+ if [ "${EBUILD_PHASE}" != "depend" ] && \
+ [[ ${EBUILD_PHASE} != *rm ]] && \
+ [[ ${EMERGE_FROM} != "binary" ]] ; then
+ # This is disabled in the *rm phases because they frequently give
+ # false alarms due to INHERITED in /var/db/pkg being outdated
+ # in comparison the the eclasses from the portage tree.
+ if ! has $ECLASS $INHERITED $__INHERITED_QA_CACHE ; then
+ eqawarn "QA Notice: ECLASS '$ECLASS' inherited illegally in $CATEGORY/$PF $EBUILD_PHASE"
+ fi
+ fi
+
+ # any future resolution code goes here
+ if [ -n "$PORTDIR_OVERLAY" ]; then
+ local overlay
+ for overlay in ${PORTDIR_OVERLAY}; do
+ olocation="${overlay}/eclass/${1}.eclass"
+ if [ -e "$olocation" ]; then
+ location="${olocation}"
+ debug-print " eclass exists: ${location}"
+ fi
+ done
+ fi
+ debug-print "inherit: $1 -> $location"
+ [ ! -e "$location" ] && die "${1}.eclass could not be found by inherit()"
+
+ if [ "${location}" == "${olocation}" ] && \
+ ! has "${location}" ${EBUILD_OVERLAY_ECLASSES} ; then
+ EBUILD_OVERLAY_ECLASSES="${EBUILD_OVERLAY_ECLASSES} ${location}"
+ fi
+
+ #We need to back up the value of DEPEND and RDEPEND to B_DEPEND and B_RDEPEND
+ #(if set).. and then restore them after the inherit call.
+
+ #turn off glob expansion
+ set -f
+
+ # Retain the old data and restore it later.
+ unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND
+ [ "${IUSE+set}" = set ] && B_IUSE="${IUSE}"
+ [ "${REQUIRED_USE+set}" = set ] && B_REQUIRED_USE="${REQUIRED_USE}"
+ [ "${DEPEND+set}" = set ] && B_DEPEND="${DEPEND}"
+ [ "${RDEPEND+set}" = set ] && B_RDEPEND="${RDEPEND}"
+ [ "${PDEPEND+set}" = set ] && B_PDEPEND="${PDEPEND}"
+ unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND
+ #turn on glob expansion
+ set +f
+
+ qa_source "$location" || die "died sourcing $location in inherit()"
+
+ #turn off glob expansion
+ set -f
+
+ # If each var has a value, append it to the global variable E_* to
+ # be applied after everything is finished. New incremental behavior.
+ [ "${IUSE+set}" = set ] && export E_IUSE="${E_IUSE} ${IUSE}"
+ [ "${REQUIRED_USE+set}" = set ] && export E_REQUIRED_USE="${E_REQUIRED_USE} ${REQUIRED_USE}"
+ [ "${DEPEND+set}" = set ] && export E_DEPEND="${E_DEPEND} ${DEPEND}"
+ [ "${RDEPEND+set}" = set ] && export E_RDEPEND="${E_RDEPEND} ${RDEPEND}"
+ [ "${PDEPEND+set}" = set ] && export E_PDEPEND="${E_PDEPEND} ${PDEPEND}"
+
+ [ "${B_IUSE+set}" = set ] && IUSE="${B_IUSE}"
+ [ "${B_IUSE+set}" = set ] || unset IUSE
+
+ [ "${B_REQUIRED_USE+set}" = set ] && REQUIRED_USE="${B_REQUIRED_USE}"
+ [ "${B_REQUIRED_USE+set}" = set ] || unset REQUIRED_USE
+
+ [ "${B_DEPEND+set}" = set ] && DEPEND="${B_DEPEND}"
+ [ "${B_DEPEND+set}" = set ] || unset DEPEND
+
+ [ "${B_RDEPEND+set}" = set ] && RDEPEND="${B_RDEPEND}"
+ [ "${B_RDEPEND+set}" = set ] || unset RDEPEND
+
+ [ "${B_PDEPEND+set}" = set ] && PDEPEND="${B_PDEPEND}"
+ [ "${B_PDEPEND+set}" = set ] || unset PDEPEND
+
+ #turn on glob expansion
+ set +f
+
+ if [[ -n ${!__export_funcs_var} ]] ; then
+ for x in ${!__export_funcs_var} ; do
+ debug-print "EXPORT_FUNCTIONS: $x -> ${ECLASS}_$x"
+ declare -F "${ECLASS}_$x" >/dev/null || \
+ die "EXPORT_FUNCTIONS: ${ECLASS}_$x is not defined"
+ eval "$x() { ${ECLASS}_$x \"\$@\" ; }" > /dev/null
+ done
+ fi
+ unset $__export_funcs_var
+
+ has $1 $INHERITED || export INHERITED="$INHERITED $1"
+
+ shift
+ done
+ ((--ECLASS_DEPTH)) # Returns 1 when ECLASS_DEPTH reaches 0.
+ if (( ECLASS_DEPTH > 0 )) ; then
+ export ECLASS=$PECLASS
+ __export_funcs_var=$prev_export_funcs_var
+ else
+ unset ECLASS __export_funcs_var
+ fi
+ return 0
+}
+
+# Exports stub functions that call the eclass's functions, thereby making them default.
+# For example, if ECLASS="base" and you call "EXPORT_FUNCTIONS src_unpack", the following
+# code will be eval'd:
+# src_unpack() { base_src_unpack; }
+EXPORT_FUNCTIONS() {
+ if [ -z "$ECLASS" ]; then
+ die "EXPORT_FUNCTIONS without a defined ECLASS"
+ fi
+ eval $__export_funcs_var+=\" $*\"
+}
+
+# this is a function for removing any directory matching a passed in pattern from
+# PATH
+remove_path_entry() {
+ save_IFS
+ IFS=":"
+ stripped_path="${PATH}"
+ while [ -n "$1" ]; do
+ cur_path=""
+ for p in ${stripped_path}; do
+ if [ "${p/${1}}" == "${p}" ]; then
+ cur_path="${cur_path}:${p}"
+ fi
+ done
+ stripped_path="${cur_path#:*}"
+ shift
+ done
+ restore_IFS
+ PATH="${stripped_path}"
+}
+
+# @FUNCTION: _ebuild_arg_to_phase
+# @DESCRIPTION:
+# Translate a known ebuild(1) argument into the precise
+# name of it's corresponding ebuild phase.
+_ebuild_arg_to_phase() {
+ [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
+ local eapi=$1
+ local arg=$2
+ local phase_func=""
+
+ case "$arg" in
+ pretend)
+ ! has $eapi 0 1 2 3 3_pre2 && \
+ phase_func=pkg_pretend
+ ;;
+ setup)
+ phase_func=pkg_setup
+ ;;
+ nofetch)
+ phase_func=pkg_nofetch
+ ;;
+ unpack)
+ phase_func=src_unpack
+ ;;
+ prepare)
+ ! has $eapi 0 1 && \
+ phase_func=src_prepare
+ ;;
+ configure)
+ ! has $eapi 0 1 && \
+ phase_func=src_configure
+ ;;
+ compile)
+ phase_func=src_compile
+ ;;
+ test)
+ phase_func=src_test
+ ;;
+ install)
+ phase_func=src_install
+ ;;
+ preinst)
+ phase_func=pkg_preinst
+ ;;
+ postinst)
+ phase_func=pkg_postinst
+ ;;
+ prerm)
+ phase_func=pkg_prerm
+ ;;
+ postrm)
+ phase_func=pkg_postrm
+ ;;
+ esac
+
+ [[ -z $phase_func ]] && return 1
+ echo "$phase_func"
+ return 0
+}
+
+_ebuild_phase_funcs() {
+ [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
+ local eapi=$1
+ local phase_func=$2
+ local default_phases="pkg_nofetch src_unpack src_prepare src_configure
+ src_compile src_install src_test"
+ local x y default_func=""
+
+ for x in pkg_nofetch src_unpack src_test ; do
+ declare -F $x >/dev/null || \
+ eval "$x() { _eapi0_$x \"\$@\" ; }"
+ done
+
+ case $eapi in
+
+ 0|1)
+
+ if ! declare -F src_compile >/dev/null ; then
+ case $eapi in
+ 0)
+ src_compile() { _eapi0_src_compile "$@" ; }
+ ;;
+ *)
+ src_compile() { _eapi1_src_compile "$@" ; }
+ ;;
+ esac
+ fi
+
+ for x in $default_phases ; do
+ eval "default_$x() {
+ die \"default_$x() is not supported with EAPI='$eapi' during phase $phase_func\"
+ }"
+ done
+
+ eval "default() {
+ die \"default() is not supported with EAPI='$eapi' during phase $phase_func\"
+ }"
+
+ ;;
+
+ *)
+
+ declare -F src_configure >/dev/null || \
+ src_configure() { _eapi2_src_configure "$@" ; }
+
+ declare -F src_compile >/dev/null || \
+ src_compile() { _eapi2_src_compile "$@" ; }
+
+ has $eapi 2 3 3_pre2 || declare -F src_install >/dev/null || \
+ src_install() { _eapi4_src_install "$@" ; }
+
+ if has $phase_func $default_phases ; then
+
+ _eapi2_pkg_nofetch () { _eapi0_pkg_nofetch "$@" ; }
+ _eapi2_src_unpack () { _eapi0_src_unpack "$@" ; }
+ _eapi2_src_prepare () { true ; }
+ _eapi2_src_test () { _eapi0_src_test "$@" ; }
+ _eapi2_src_install () { die "$FUNCNAME is not supported" ; }
+
+ for x in $default_phases ; do
+ eval "default_$x() { _eapi2_$x \"\$@\" ; }"
+ done
+
+ eval "default() { _eapi2_$phase_func \"\$@\" ; }"
+
+ case $eapi in
+ 2|3)
+ ;;
+ *)
+ eval "default_src_install() { _eapi4_src_install \"\$@\" ; }"
+ [[ $phase_func = src_install ]] && \
+ eval "default() { _eapi4_$phase_func \"\$@\" ; }"
+ ;;
+ esac
+
+ else
+
+ for x in $default_phases ; do
+ eval "default_$x() {
+ die \"default_$x() is not supported in phase $default_func\"
+ }"
+ done
+
+ eval "default() {
+ die \"default() is not supported with EAPI='$eapi' during phase $phase_func\"
+ }"
+
+ fi
+
+ ;;
+ esac
+}
+
+# Set given variables unless these variable have been already set (e.g. during emerge
+# invocation) to values different than values set in make.conf.
+set_unless_changed() {
+ if [[ $# -lt 1 ]]; then
+ die "${FUNCNAME}() requires at least 1 argument: VARIABLE=VALUE"
+ fi
+
+ local argument value variable
+ for argument in "$@"; do
+ if [[ ${argument} != *=* ]]; then
+ die "${FUNCNAME}(): Argument '${argument}' has incorrect syntax"
+ fi
+ variable="${argument%%=*}"
+ value="${argument#*=}"
+ if eval "[[ \${${variable}} == \$(env -u ${variable} portageq envvar ${variable}) ]]"; then
+ eval "${variable}=\"\${value}\""
+ fi
+ done
+}
+
+# Unset given variables unless these variable have been set (e.g. during emerge
+# invocation) to values different than values set in make.conf.
+unset_unless_changed() {
+ if [[ $# -lt 1 ]]; then
+ die "${FUNCNAME}() requires at least 1 argument: VARIABLE"
+ fi
+
+ local variable
+ for variable in "$@"; do
+ if eval "[[ \${${variable}} == \$(env -u ${variable} portageq envvar ${variable}) ]]"; then
+ unset ${variable}
+ fi
+ done
+}
+
+PORTAGE_BASHRCS_SOURCED=0
+
+# @FUNCTION: source_all_bashrcs
+# @DESCRIPTION:
+# Source a relevant bashrc files and perform other miscellaneous
+# environment initialization when appropriate.
+#
+# If EAPI is set then define functions provided by the current EAPI:
+#
+# * default_* aliases for the current EAPI phase functions
+# * A "default" function which is an alias for the default phase
+# function for the current phase.
+#
+source_all_bashrcs() {
+ [[ $PORTAGE_BASHRCS_SOURCED = 1 ]] && return 0
+ PORTAGE_BASHRCS_SOURCED=1
+ local x
+
+ local OCC="${CC}" OCXX="${CXX}"
+
+ if [[ $EBUILD_PHASE != depend ]] ; then
+ # source the existing profile.bashrcs.
+ save_IFS
+ IFS=$'\n'
+ local path_array=($PROFILE_PATHS)
+ restore_IFS
+ for x in "${path_array[@]}" ; do
+ [ -f "$x/profile.bashrc" ] && qa_source "$x/profile.bashrc"
+ done
+ fi
+
+ # We assume if people are changing shopts in their bashrc they do so at their
+ # own peril. This is the ONLY non-portage bit of code that can change shopts
+ # without a QA violation.
+ for x in "${PORTAGE_BASHRC}" "${PM_EBUILD_HOOK_DIR}"/${CATEGORY}/{${PN},${PN}:${SLOT},${P},${PF}}; do
+ if [ -r "${x}" ]; then
+ # If $- contains x, then tracing has already enabled elsewhere for some
+ # reason. We preserve it's state so as not to interfere.
+ if [ "$PORTAGE_DEBUG" != "1" ] || [ "${-/x/}" != "$-" ]; then
+ source "${x}"
+ else
+ set -x
+ source "${x}"
+ set +x
+ fi
+ fi
+ done
+
+ [ ! -z "${OCC}" ] && export CC="${OCC}"
+ [ ! -z "${OCXX}" ] && export CXX="${OCXX}"
+}
+
+# Hardcoded bash lists are needed for backward compatibility with
+# <portage-2.1.4 since they assume that a newly installed version
+# of ebuild.sh will work for pkg_postinst, pkg_prerm, and pkg_postrm
+# when portage is upgrading itself.
+
+PORTAGE_READONLY_METADATA="DEFINED_PHASES DEPEND DESCRIPTION
+ EAPI HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
+ PDEPEND PROVIDE RDEPEND RESTRICT SLOT SRC_URI"
+
+PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE \
+ EBUILD_SH_ARGS ECLASSDIR EMERGE_FROM FILESDIR MERGE_TYPE \
+ PM_EBUILD_HOOK_DIR \
+ PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST PORTAGE_BASHRC \
+ PORTAGE_BINPKG_FILE PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE \
+ PORTAGE_BIN_PATH PORTAGE_BUILDDIR PORTAGE_BUNZIP2_COMMAND \
+ PORTAGE_BZIP2_COMMAND PORTAGE_COLORMAP PORTAGE_CONFIGROOT \
+ PORTAGE_DEBUG PORTAGE_DEPCACHEDIR PORTAGE_EBUILD_EXIT_FILE \
+ PORTAGE_GID PORTAGE_GRPNAME PORTAGE_INST_GID PORTAGE_INST_UID \
+ PORTAGE_IPC_DAEMON PORTAGE_IUSE PORTAGE_LOG_FILE \
+ PORTAGE_MUTABLE_FILTERED_VARS PORTAGE_PYM_PATH PORTAGE_PYTHON \
+ PORTAGE_READONLY_METADATA PORTAGE_READONLY_VARS \
+ PORTAGE_REPO_NAME PORTAGE_RESTRICT PORTAGE_SANDBOX_COMPAT_LEVEL \
+ PORTAGE_SAVED_READONLY_VARS PORTAGE_SIGPIPE_STATUS \
+ PORTAGE_TMPDIR PORTAGE_UPDATE_ENV PORTAGE_USERNAME \
+ PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTDIR PORTDIR_OVERLAY \
+ PROFILE_PATHS REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR"
+
+PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR"
+
+# Variables that portage sets but doesn't mark readonly.
+# In order to prevent changed values from causing unexpected
+# interference, they are filtered out of the environment when
+# it is saved or loaded (any mutations do not persist).
+PORTAGE_MUTABLE_FILTERED_VARS="AA HOSTNAME"
+
+# @FUNCTION: filter_readonly_variables
+# @DESCRIPTION: [--filter-sandbox] [--allow-extra-vars]
+# Read an environment from stdin and echo to stdout while filtering variables
+# with names that are known to cause interference:
+#
+# * some specific variables for which bash does not allow assignment
+# * some specific variables that affect portage or sandbox behavior
+# * variable names that begin with a digit or that contain any
+# non-alphanumeric characters that are not be supported by bash
+#
+# --filter-sandbox causes all SANDBOX_* variables to be filtered, which
+# is only desired in certain cases, such as during preprocessing or when
+# saving environment.bz2 for a binary or installed package.
+#
+# --filter-features causes the special FEATURES variable to be filtered.
+# Generally, we want it to persist between phases since the user might
+# want to modify it via bashrc to enable things like splitdebug and
+# installsources for specific packages. They should be able to modify it
+# in pre_pkg_setup() and have it persist all the way through the install
+# phase. However, if FEATURES exist inside environment.bz2 then they
+# should be overridden by current settings.
+#
+# --filter-locale causes locale related variables such as LANG and LC_*
+# variables to be filtered. These variables should persist between phases,
+# in case they are modified by the ebuild. However, the current user
+# settings should be used when loading the environment from a binary or
+# installed package.
+#
+# --filter-path causes the PATH variable to be filtered. This variable
+# should persist between phases, in case it is modified by the ebuild.
+# However, old settings should be overridden when loading the
+# environment from a binary or installed package.
+#
+# ---allow-extra-vars causes some extra vars to be allowd through, such
+# as ${PORTAGE_SAVED_READONLY_VARS} and ${PORTAGE_MUTABLE_FILTERED_VARS}.
+#
+# In bash-3.2_p20+ an attempt to assign BASH_*, FUNCNAME, GROUPS or any
+# readonly variable cause the shell to exit while executing the "source"
+# builtin command. To avoid this problem, this function filters those
+# variables out and discards them. See bug #190128.
+filter_readonly_variables() {
+ local x filtered_vars
+ local readonly_bash_vars="BASHOPTS BASHPID DIRSTACK EUID
+ FUNCNAME GROUPS PIPESTATUS PPID SHELLOPTS UID"
+ local bash_misc_vars="BASH BASH_.* COMP_WORDBREAKS HISTCMD
+ HISTFILE HOSTNAME HOSTTYPE IFS LINENO MACHTYPE OLDPWD
+ OPTERR OPTIND OSTYPE POSIXLY_CORRECT PS4 PWD RANDOM
+ SECONDS SHELL SHLVL"
+ local filtered_sandbox_vars="SANDBOX_ACTIVE SANDBOX_BASHRC
+ SANDBOX_DEBUG_LOG SANDBOX_DISABLED SANDBOX_LIB
+ SANDBOX_LOG SANDBOX_ON"
+ local misc_garbage_vars="_portage_filter_opts"
+ filtered_vars="$readonly_bash_vars $bash_misc_vars
+ $PORTAGE_READONLY_VARS $misc_garbage_vars"
+
+ # Don't filter/interfere with prefix variables unless they are
+ # supported by the current EAPI.
+ case "${EAPI:-0}" in
+ 0|1|2)
+ ;;
+ *)
+ filtered_vars+=" ED EPREFIX EROOT"
+ ;;
+ esac
+
+ if has --filter-sandbox $* ; then
+ filtered_vars="${filtered_vars} SANDBOX_.*"
+ else
+ filtered_vars="${filtered_vars} ${filtered_sandbox_vars}"
+ fi
+ if has --filter-features $* ; then
+ filtered_vars="${filtered_vars} FEATURES PORTAGE_FEATURES"
+ fi
+ if has --filter-path $* ; then
+ filtered_vars+=" PATH"
+ fi
+ if has --filter-locale $* ; then
+ filtered_vars+=" LANG LC_ALL LC_COLLATE
+ LC_CTYPE LC_MESSAGES LC_MONETARY
+ LC_NUMERIC LC_PAPER LC_TIME"
+ fi
+ if ! has --allow-extra-vars $* ; then
+ filtered_vars="
+ ${filtered_vars}
+ ${PORTAGE_SAVED_READONLY_VARS}
+ ${PORTAGE_MUTABLE_FILTERED_VARS}
+ "
+ fi
+
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}"/filter-bash-environment.py "${filtered_vars}" || die "filter-bash-environment.py failed"
+}
+
+# @FUNCTION: preprocess_ebuild_env
+# @DESCRIPTION:
+# Filter any readonly variables from ${T}/environment, source it, and then
+# save it via save_ebuild_env(). This process should be sufficient to prevent
+# any stale variables or functions from an arbitrary environment from
+# interfering with the current environment. This is useful when an existing
+# environment needs to be loaded from a binary or installed package.
+preprocess_ebuild_env() {
+ local _portage_filter_opts="--filter-features --filter-locale --filter-path --filter-sandbox"
+
+ # If environment.raw is present, this is a signal from the python side,
+ # indicating that the environment may contain stale FEATURES and
+ # SANDBOX_{DENY,PREDICT,READ,WRITE} variables that should be filtered out.
+ # Otherwise, we don't need to filter the environment.
+ [ -f "${T}/environment.raw" ] || return 0
+
+ filter_readonly_variables $_portage_filter_opts < "${T}"/environment \
+ >> "$T/environment.filtered" || return $?
+ unset _portage_filter_opts
+ mv "${T}"/environment.filtered "${T}"/environment || return $?
+ rm -f "${T}/environment.success" || return $?
+ # WARNING: Code inside this subshell should avoid making assumptions
+ # about variables or functions after source "${T}"/environment has been
+ # called. Any variables that need to be relied upon should already be
+ # filtered out above.
+ (
+ export SANDBOX_ON=1
+ source "${T}/environment" || exit $?
+ # We have to temporarily disable sandbox since the
+ # SANDBOX_{DENY,READ,PREDICT,WRITE} values we've just loaded
+ # may be unusable (triggering in spurious sandbox violations)
+ # until we've merged them with our current values.
+ export SANDBOX_ON=0
+
+ # It's remotely possible that save_ebuild_env() has been overridden
+ # by the above source command. To protect ourselves, we override it
+ # here with our own version. ${PORTAGE_BIN_PATH} is safe to use here
+ # because it's already filtered above.
+ source "${PORTAGE_BIN_PATH}/isolated-functions.sh" || exit $?
+
+ # Rely on save_ebuild_env() to filter out any remaining variables
+ # and functions that could interfere with the current environment.
+ save_ebuild_env || exit $?
+ >> "$T/environment.success" || exit $?
+ ) > "${T}/environment.filtered"
+ local retval
+ if [ -e "${T}/environment.success" ] ; then
+ filter_readonly_variables --filter-features < \
+ "${T}/environment.filtered" > "${T}/environment"
+ retval=$?
+ else
+ retval=1
+ fi
+ rm -f "${T}"/environment.{filtered,raw,success}
+ return ${retval}
+}
+
+# === === === === === === === === === === === === === === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === === === === === === === === === === === === === ===
+
+export SANDBOX_ON="1"
+export S=${WORKDIR}/${P}
+
+unset E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND
+
+# Turn of extended glob matching so that g++ doesn't get incorrectly matched.
+shopt -u extglob
+
+if [[ ${EBUILD_PHASE} == depend ]] ; then
+ QA_INTERCEPTORS="awk bash cc egrep equery fgrep g++
+ gawk gcc grep javac java-config nawk perl
+ pkg-config python python-config sed"
+elif [[ ${EBUILD_PHASE} == clean* ]] ; then
+ unset QA_INTERCEPTORS
+else
+ QA_INTERCEPTORS="autoconf automake aclocal libtoolize"
+fi
+# level the QA interceptors if we're in depend
+if [[ -n ${QA_INTERCEPTORS} ]] ; then
+ for BIN in ${QA_INTERCEPTORS}; do
+ BIN_PATH=$(type -Pf ${BIN})
+ if [ "$?" != "0" ]; then
+ BODY="echo \"*** missing command: ${BIN}\" >&2; return 127"
+ else
+ BODY="${BIN_PATH} \"\$@\"; return \$?"
+ fi
+ if [[ ${EBUILD_PHASE} == depend ]] ; then
+ FUNC_SRC="${BIN}() {
+ if [ \$ECLASS_DEPTH -gt 0 ]; then
+ eqawarn \"QA Notice: '${BIN}' called in global scope: eclass \${ECLASS}\"
+ else
+ eqawarn \"QA Notice: '${BIN}' called in global scope: \${CATEGORY}/\${PF}\"
+ fi
+ ${BODY}
+ }"
+ elif has ${BIN} autoconf automake aclocal libtoolize ; then
+ FUNC_SRC="${BIN}() {
+ if ! has \${FUNCNAME[1]} eautoreconf eaclocal _elibtoolize \\
+ eautoheader eautoconf eautomake autotools_run_tool \\
+ autotools_check_macro autotools_get_subdirs \\
+ autotools_get_auxdir ; then
+ eqawarn \"QA Notice: '${BIN}' called by \${FUNCNAME[1]}: \${CATEGORY}/\${PF}\"
+ eqawarn \"Use autotools.eclass instead of calling '${BIN}' directly.\"
+ fi
+ ${BODY}
+ }"
+ else
+ FUNC_SRC="${BIN}() {
+ eqawarn \"QA Notice: '${BIN}' called by \${FUNCNAME[1]}: \${CATEGORY}/\${PF}\"
+ ${BODY}
+ }"
+ fi
+ eval "$FUNC_SRC" || echo "error creating QA interceptor ${BIN}" >&2
+ done
+ unset BIN_PATH BIN BODY FUNC_SRC
+fi
+
+# Subshell/helper die support (must export for the die helper).
+export EBUILD_MASTER_PID=$BASHPID
+trap 'exit 1' SIGTERM
+
+if ! has "$EBUILD_PHASE" clean cleanrm depend && \
+ [ -f "${T}"/environment ] ; then
+ # The environment may have been extracted from environment.bz2 or
+ # may have come from another version of ebuild.sh or something.
+ # In any case, preprocess it to prevent any potential interference.
+ preprocess_ebuild_env || \
+ die "error processing environment"
+ # Colon separated SANDBOX_* variables need to be cumulative.
+ for x in SANDBOX_DENY SANDBOX_READ SANDBOX_PREDICT SANDBOX_WRITE ; do
+ export PORTAGE_${x}=${!x}
+ done
+ PORTAGE_SANDBOX_ON=${SANDBOX_ON}
+ export SANDBOX_ON=1
+ source "${T}"/environment || \
+ die "error sourcing environment"
+ # We have to temporarily disable sandbox since the
+ # SANDBOX_{DENY,READ,PREDICT,WRITE} values we've just loaded
+ # may be unusable (triggering in spurious sandbox violations)
+ # until we've merged them with our current values.
+ export SANDBOX_ON=0
+ for x in SANDBOX_DENY SANDBOX_PREDICT SANDBOX_READ SANDBOX_WRITE ; do
+ y="PORTAGE_${x}"
+ if [ -z "${!x}" ] ; then
+ export ${x}=${!y}
+ elif [ -n "${!y}" ] && [ "${!y}" != "${!x}" ] ; then
+ # filter out dupes
+ export ${x}=$(printf "${!y}:${!x}" | tr ":" "\0" | \
+ sort -z -u | tr "\0" ":")
+ fi
+ export ${x}=${!x%:}
+ unset PORTAGE_${x}
+ done
+ unset x y
+ export SANDBOX_ON=${PORTAGE_SANDBOX_ON}
+ unset PORTAGE_SANDBOX_ON
+ [[ -n $EAPI ]] || EAPI=0
+fi
+
+if ! has "$EBUILD_PHASE" clean cleanrm ; then
+ if [[ $EBUILD_PHASE = depend || ! -f $T/environment || \
+ -f $PORTAGE_BUILDDIR/.ebuild_changed ]] || \
+ has noauto $FEATURES ; then
+ # The bashrcs get an opportunity here to set aliases that will be expanded
+ # during sourcing of ebuilds and eclasses.
+ source_all_bashrcs
+
+ # When EBUILD_PHASE != depend, INHERITED comes pre-initialized
+ # from cache. In order to make INHERITED content independent of
+ # EBUILD_PHASE during inherit() calls, we unset INHERITED after
+ # we make a backup copy for QA checks.
+ __INHERITED_QA_CACHE=$INHERITED
+
+ # *DEPEND and IUSE will be set during the sourcing of the ebuild.
+ # In order to ensure correct interaction between ebuilds and
+ # eclasses, they need to be unset before this process of
+ # interaction begins.
+ unset DEPEND RDEPEND PDEPEND INHERITED IUSE REQUIRED_USE \
+ ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND
+
+ if [[ $PORTAGE_DEBUG != 1 || ${-/x/} != $- ]] ; then
+ source "$EBUILD" || die "error sourcing ebuild"
+ else
+ set -x
+ source "$EBUILD" || die "error sourcing ebuild"
+ set +x
+ fi
+
+ if [[ "${EBUILD_PHASE}" != "depend" ]] ; then
+ RESTRICT=${PORTAGE_RESTRICT}
+ [[ -e $PORTAGE_BUILDDIR/.ebuild_changed ]] && \
+ rm "$PORTAGE_BUILDDIR/.ebuild_changed"
+ fi
+
+ [[ -n $EAPI ]] || EAPI=0
+
+ if has "$EAPI" 0 1 2 3 3_pre2 ; then
+ export RDEPEND=${RDEPEND-${DEPEND}}
+ debug-print "RDEPEND: not set... Setting to: ${DEPEND}"
+ fi
+
+ # add in dependency info from eclasses
+ IUSE="${IUSE} ${E_IUSE}"
+ DEPEND="${DEPEND} ${E_DEPEND}"
+ RDEPEND="${RDEPEND} ${E_RDEPEND}"
+ PDEPEND="${PDEPEND} ${E_PDEPEND}"
+ REQUIRED_USE="${REQUIRED_USE} ${E_REQUIRED_USE}"
+
+ unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND \
+ __INHERITED_QA_CACHE
+
+ # alphabetically ordered by $EBUILD_PHASE value
+ case "$EAPI" in
+ 0|1)
+ _valid_phases="src_compile pkg_config pkg_info src_install
+ pkg_nofetch pkg_postinst pkg_postrm pkg_preinst pkg_prerm
+ pkg_setup src_test src_unpack"
+ ;;
+ 2|3|3_pre2)
+ _valid_phases="src_compile pkg_config src_configure pkg_info
+ src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst
+ src_prepare pkg_prerm pkg_setup src_test src_unpack"
+ ;;
+ *)
+ _valid_phases="src_compile pkg_config src_configure pkg_info
+ src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst
+ src_prepare pkg_prerm pkg_pretend pkg_setup src_test src_unpack"
+ ;;
+ esac
+
+ DEFINED_PHASES=
+ for _f in $_valid_phases ; do
+ if declare -F $_f >/dev/null ; then
+ _f=${_f#pkg_}
+ DEFINED_PHASES+=" ${_f#src_}"
+ fi
+ done
+ [[ -n $DEFINED_PHASES ]] || DEFINED_PHASES=-
+
+ unset _f _valid_phases
+
+ if [[ $EBUILD_PHASE != depend ]] ; then
+
+ case "$EAPI" in
+ 0|1|2|3)
+ _ebuild_helpers_path="$PORTAGE_BIN_PATH/ebuild-helpers"
+ ;;
+ *)
+ _ebuild_helpers_path="$PORTAGE_BIN_PATH/ebuild-helpers/4:$PORTAGE_BIN_PATH/ebuild-helpers"
+ ;;
+ esac
+
+ PATH=$_ebuild_helpers_path:$PREROOTPATH${PREROOTPATH:+:}/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin${ROOTPATH:+:}$ROOTPATH
+ unset _ebuild_helpers_path
+
+ # Use default ABI libdir in accordance with bug #355283.
+ x=LIBDIR_${DEFAULT_ABI}
+ [[ -n $DEFAULT_ABI && -n ${!x} ]] && x=${!x} || x=lib
+
+ if has distcc $FEATURES ; then
+ PATH="/usr/$x/distcc/bin:$PATH"
+ [[ -n $DISTCC_LOG ]] && addwrite "${DISTCC_LOG%/*}"
+ fi
+
+ if has ccache $FEATURES ; then
+ PATH="/usr/$x/ccache/bin:$PATH"
+
+ if [[ -n $CCACHE_DIR ]] ; then
+ addread "$CCACHE_DIR"
+ addwrite "$CCACHE_DIR"
+ fi
+
+ [[ -n $CCACHE_SIZE ]] && ccache -M $CCACHE_SIZE &> /dev/null
+ fi
+
+ unset x
+
+ if [[ -n $QA_PREBUILT ]] ; then
+
+ # these ones support fnmatch patterns
+ QA_EXECSTACK+=" $QA_PREBUILT"
+ QA_TEXTRELS+=" $QA_PREBUILT"
+ QA_WX_LOAD+=" $QA_PREBUILT"
+
+ # these ones support regular expressions, so translate
+ # fnmatch patterns to regular expressions
+ for x in QA_DT_HASH QA_DT_NEEDED QA_PRESTRIPPED QA_SONAME ; do
+ if [[ $(declare -p $x 2>/dev/null) = declare\ -a* ]] ; then
+ eval "$x=(\"\${$x[@]}\" ${QA_PREBUILT//\*/.*})"
+ else
+ eval "$x+=\" ${QA_PREBUILT//\*/.*}\""
+ fi
+ done
+
+ unset x
+ fi
+
+ # This needs to be exported since prepstrip is a separate shell script.
+ [[ -n $QA_PRESTRIPPED ]] && export QA_PRESTRIPPED
+ eval "[[ -n \$QA_PRESTRIPPED_${ARCH/-/_} ]] && \
+ export QA_PRESTRIPPED_${ARCH/-/_}"
+ fi
+ fi
+fi
+
+# unset USE_EXPAND variables that contain only the special "*" token
+for x in ${USE_EXPAND} ; do
+ [ "${!x}" == "*" ] && unset ${x}
+done
+unset x
+
+if has nostrip ${FEATURES} ${RESTRICT} || has strip ${RESTRICT}
+then
+ export DEBUGBUILD=1
+fi
+
+#a reasonable default for $S
+[[ -z ${S} ]] && export S=${WORKDIR}/${P}
+
+# Note: readonly variables interfere with preprocess_ebuild_env(), so
+# declare them only after it has already run.
+if [ "${EBUILD_PHASE}" != "depend" ] ; then
+ declare -r $PORTAGE_READONLY_METADATA $PORTAGE_READONLY_VARS
+ case "$EAPI" in
+ 0|1|2)
+ ;;
+ *)
+ declare -r ED EPREFIX EROOT
+ ;;
+ esac
+fi
+
+ebuild_main() {
+
+ # Subshell/helper die support (must export for the die helper).
+ # Since this function is typically executed in a subshell,
+ # setup EBUILD_MASTER_PID to refer to the current $BASHPID,
+ # which seems to give the best results when further
+ # nested subshells call die.
+ export EBUILD_MASTER_PID=$BASHPID
+ trap 'exit 1' SIGTERM
+
+ if [[ $EBUILD_PHASE != depend ]] ; then
+ # Force configure scripts that automatically detect ccache to
+ # respect FEATURES="-ccache".
+ has ccache $FEATURES || export CCACHE_DISABLE=1
+
+ local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE")
+ [[ -n $phase_func ]] && _ebuild_phase_funcs "$EAPI" "$phase_func"
+ unset phase_func
+ fi
+
+ source_all_bashrcs
+
+ case ${EBUILD_SH_ARGS} in
+ nofetch)
+ ebuild_phase_with_hooks pkg_nofetch
+ ;;
+ prerm|postrm|postinst|config|info)
+ if has "$EBUILD_SH_ARGS" config info && \
+ ! declare -F "pkg_$EBUILD_SH_ARGS" >/dev/null ; then
+ ewarn "pkg_${EBUILD_SH_ARGS}() is not defined: '${EBUILD##*/}'"
+ fi
+ export SANDBOX_ON="0"
+ if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
+ ebuild_phase_with_hooks pkg_${EBUILD_SH_ARGS}
+ else
+ set -x
+ ebuild_phase_with_hooks pkg_${EBUILD_SH_ARGS}
+ set +x
+ fi
+ if [[ $EBUILD_PHASE == postinst ]] && [[ -n $PORTAGE_UPDATE_ENV ]]; then
+ # Update environment.bz2 in case installation phases
+ # need to pass some variables to uninstallation phases.
+ save_ebuild_env --exclude-init-phases | \
+ filter_readonly_variables --filter-path \
+ --filter-sandbox --allow-extra-vars \
+ | ${PORTAGE_BZIP2_COMMAND} -c -f9 > "$PORTAGE_UPDATE_ENV"
+ assert "save_ebuild_env failed"
+ fi
+ ;;
+ unpack|prepare|configure|compile|test|clean|install)
+ if [[ ${SANDBOX_DISABLED:-0} = 0 ]] ; then
+ export SANDBOX_ON="1"
+ else
+ export SANDBOX_ON="0"
+ fi
+
+ case "$EBUILD_SH_ARGS" in
+ configure|compile)
+
+ local x
+ for x in ASFLAGS CCACHE_DIR CCACHE_SIZE \
+ CFLAGS CXXFLAGS LDFLAGS LIBCFLAGS LIBCXXFLAGS ; do
+ [[ ${!x+set} = set ]] && export $x
+ done
+ unset x
+
+ has distcc $FEATURES && [[ -n $DISTCC_DIR ]] && \
+ [[ ${SANDBOX_WRITE/$DISTCC_DIR} = $SANDBOX_WRITE ]] && \
+ addwrite "$DISTCC_DIR"
+
+ x=LIBDIR_$ABI
+ [ -z "$PKG_CONFIG_PATH" -a -n "$ABI" -a -n "${!x}" ] && \
+ export PKG_CONFIG_PATH=/usr/${!x}/pkgconfig
+
+ if has noauto $FEATURES && \
+ [[ ! -f $PORTAGE_BUILDDIR/.unpacked ]] ; then
+ echo
+ echo "!!! We apparently haven't unpacked..." \
+ "This is probably not what you"
+ echo "!!! want to be doing... You are using" \
+ "FEATURES=noauto so I'll assume"
+ echo "!!! that you know what you are doing..." \
+ "You have 5 seconds to abort..."
+ echo
+
+ local x
+ for x in 1 2 3 4 5 6 7 8; do
+ LC_ALL=C sleep 0.25
+ done
+
+ sleep 3
+ fi
+
+ cd "$PORTAGE_BUILDDIR"
+ if [ ! -d build-info ] ; then
+ mkdir build-info
+ cp "$EBUILD" "build-info/$PF.ebuild"
+ fi
+
+ #our custom version of libtool uses $S and $D to fix
+ #invalid paths in .la files
+ export S D
+
+ ;;
+ esac
+
+ if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
+ dyn_${EBUILD_SH_ARGS}
+ else
+ set -x
+ dyn_${EBUILD_SH_ARGS}
+ set +x
+ fi
+ export SANDBOX_ON="0"
+ ;;
+ help|pretend|setup|preinst)
+ #pkg_setup needs to be out of the sandbox for tmp file creation;
+ #for example, awking and piping a file in /tmp requires a temp file to be created
+ #in /etc. If pkg_setup is in the sandbox, both our lilo and apache ebuilds break.
+ export SANDBOX_ON="0"
+ if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
+ dyn_${EBUILD_SH_ARGS}
+ else
+ set -x
+ dyn_${EBUILD_SH_ARGS}
+ set +x
+ fi
+ ;;
+ depend)
+ export SANDBOX_ON="0"
+ set -f
+
+ if [ -n "${dbkey}" ] ; then
+ if [ ! -d "${dbkey%/*}" ]; then
+ install -d -g ${PORTAGE_GID} -m2775 "${dbkey%/*}"
+ fi
+ # Make it group writable. 666&~002==664
+ umask 002
+ fi
+
+ auxdbkeys="DEPEND RDEPEND SLOT SRC_URI RESTRICT HOMEPAGE LICENSE
+ DESCRIPTION KEYWORDS INHERITED IUSE REQUIRED_USE PDEPEND PROVIDE EAPI
+ PROPERTIES DEFINED_PHASES UNUSED_05 UNUSED_04
+ UNUSED_03 UNUSED_02 UNUSED_01"
+
+ #the extra $(echo) commands remove newlines
+ [ -n "${EAPI}" ] || EAPI=0
+
+ if [ -n "${dbkey}" ] ; then
+ > "${dbkey}"
+ for f in ${auxdbkeys} ; do
+ echo $(echo ${!f}) >> "${dbkey}" || exit $?
+ done
+ else
+ for f in ${auxdbkeys} ; do
+ echo $(echo ${!f}) 1>&9 || exit $?
+ done
+ exec 9>&-
+ fi
+ set +f
+ ;;
+ _internal_test)
+ ;;
+ *)
+ export SANDBOX_ON="1"
+ echo "Unrecognized EBUILD_SH_ARGS: '${EBUILD_SH_ARGS}'"
+ echo
+ dyn_help
+ exit 1
+ ;;
+ esac
+}
+
+if [[ -s $SANDBOX_LOG ]] ; then
+ # We use SANDBOX_LOG to check for sandbox violations,
+ # so we ensure that there can't be a stale log to
+ # interfere with our logic.
+ x=
+ if [[ -n SANDBOX_ON ]] ; then
+ x=$SANDBOX_ON
+ export SANDBOX_ON=0
+ fi
+
+ rm -f "$SANDBOX_LOG" || \
+ die "failed to remove stale sandbox log: '$SANDBOX_LOG'"
+
+ if [[ -n $x ]] ; then
+ export SANDBOX_ON=$x
+ fi
+ unset x
+fi
+
+if [[ $EBUILD_PHASE = depend ]] ; then
+ ebuild_main
+elif [[ -n $EBUILD_SH_ARGS ]] ; then
+ (
+ # Don't allow subprocesses to inherit the pipe which
+ # emerge uses to monitor ebuild.sh.
+ exec 9>&-
+
+ ebuild_main
+
+ # Save the env only for relevant phases.
+ if ! has "$EBUILD_SH_ARGS" clean help info nofetch ; then
+ umask 002
+ save_ebuild_env | filter_readonly_variables \
+ --filter-features > "$T/environment"
+ assert "save_ebuild_env failed"
+ chown portage:portage "$T/environment" &>/dev/null
+ chmod g+w "$T/environment" &>/dev/null
+ fi
+ [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
+ if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+ [[ ! -s $SANDBOX_LOG ]]
+ "$PORTAGE_BIN_PATH"/ebuild-ipc exit $?
+ fi
+ exit 0
+ )
+ exit $?
+fi
+
+# Do not exit when ebuild.sh is sourced by other scripts.
+true
diff --git a/portage_with_autodep/bin/egencache b/portage_with_autodep/bin/egencache
new file mode 100755
index 0000000..1b4265d
--- /dev/null
+++ b/portage_with_autodep/bin/egencache
@@ -0,0 +1,851 @@
+#!/usr/bin/python
+# Copyright 2009-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import signal
+import sys
+# This block ensures that ^C interrupts are handled quietly.
+try:
+
+ def exithandler(signum,frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ sys.exit(128 + signum)
+
+ signal.signal(signal.SIGINT, exithandler)
+ signal.signal(signal.SIGTERM, exithandler)
+
+except KeyboardInterrupt:
+ sys.exit(128 + signal.SIGINT)
+
+import io
+import logging
+import optparse
+import subprocess
+import time
+import textwrap
+import re
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os, _encodings, _unicode_encode, _unicode_decode
+from _emerge.MetadataRegen import MetadataRegen
+from portage.cache.cache_errors import CacheError, StatCollision
+from portage.manifest import guessManifestFileType
+from portage.util import cmp_sort_key, writemsg_level
+from portage import cpv_getkey
+from portage.dep import Atom, isjustname
+from portage.versions import pkgcmp, pkgsplit, vercmp
+
+try:
+ from xml.etree import ElementTree
+except ImportError:
+ pass
+else:
+ try:
+ from xml.parsers.expat import ExpatError
+ except ImportError:
+ pass
+ else:
+ from repoman.utilities import parse_metadata_use
+
+from repoman.utilities import FindVCS
+
+if sys.hexversion >= 0x3000000:
+ long = int
+
+def parse_args(args):
+ usage = "egencache [options] <action> ... [atom] ..."
+ parser = optparse.OptionParser(usage=usage)
+
+ actions = optparse.OptionGroup(parser, 'Actions')
+ actions.add_option("--update",
+ action="store_true",
+ help="update metadata/cache/ (generate as necessary)")
+ actions.add_option("--update-use-local-desc",
+ action="store_true",
+ help="update the use.local.desc file from metadata.xml")
+ actions.add_option("--update-changelogs",
+ action="store_true",
+ help="update the ChangeLog files from SCM logs")
+ parser.add_option_group(actions)
+
+ common = optparse.OptionGroup(parser, 'Common options')
+ common.add_option("--repo",
+ action="store",
+ help="name of repo to operate on (default repo is located at $PORTDIR)")
+ common.add_option("--config-root",
+ help="location of portage config files",
+ dest="portage_configroot")
+ common.add_option("--portdir",
+ help="override the portage tree location",
+ dest="portdir")
+ common.add_option("--tolerant",
+ action="store_true",
+ help="exit successfully if only minor errors occurred")
+ common.add_option("--ignore-default-opts",
+ action="store_true",
+ help="do not use the EGENCACHE_DEFAULT_OPTS environment variable")
+ parser.add_option_group(common)
+
+ update = optparse.OptionGroup(parser, '--update options')
+ update.add_option("--cache-dir",
+ help="location of the metadata cache",
+ dest="cache_dir")
+ update.add_option("--jobs",
+ action="store",
+ help="max ebuild processes to spawn")
+ update.add_option("--load-average",
+ action="store",
+ help="max load allowed when spawning multiple jobs",
+ dest="load_average")
+ update.add_option("--rsync",
+ action="store_true",
+ help="enable rsync stat collision workaround " + \
+ "for bug 139134 (use with --update)")
+ parser.add_option_group(update)
+
+ uld = optparse.OptionGroup(parser, '--update-use-local-desc options')
+ uld.add_option("--preserve-comments",
+ action="store_true",
+ help="preserve the comments from the existing use.local.desc file")
+ uld.add_option("--use-local-desc-output",
+ help="output file for use.local.desc data (or '-' for stdout)",
+ dest="uld_output")
+ parser.add_option_group(uld)
+
+ options, args = parser.parse_args(args)
+
+ if options.jobs:
+ jobs = None
+ try:
+ jobs = int(options.jobs)
+ except ValueError:
+ jobs = -1
+
+ if jobs < 1:
+ parser.error("Invalid: --jobs='%s'" % \
+ (options.jobs,))
+
+ options.jobs = jobs
+
+ else:
+ options.jobs = None
+
+ if options.load_average:
+ try:
+ load_average = float(options.load_average)
+ except ValueError:
+ load_average = 0.0
+
+ if load_average <= 0.0:
+ parser.error("Invalid: --load-average='%s'" % \
+ (options.load_average,))
+
+ options.load_average = load_average
+
+ else:
+ options.load_average = None
+
+ options.config_root = options.portage_configroot
+ if options.config_root is not None and \
+ not os.path.isdir(options.config_root):
+ parser.error("Not a directory: --config-root='%s'" % \
+ (options.config_root,))
+
+ if options.cache_dir is not None and not os.path.isdir(options.cache_dir):
+ parser.error("Not a directory: --cache-dir='%s'" % \
+ (options.cache_dir,))
+
+ for atom in args:
+ try:
+ atom = portage.dep.Atom(atom)
+ except portage.exception.InvalidAtom:
+ parser.error('Invalid atom: %s' % (atom,))
+
+ if not isjustname(atom):
+ parser.error('Atom is too specific: %s' % (atom,))
+
+ if options.update_use_local_desc:
+ try:
+ ElementTree
+ ExpatError
+ except NameError:
+ parser.error('--update-use-local-desc requires python with USE=xml!')
+
+ if options.uld_output == '-' and options.preserve_comments:
+ parser.error('--preserve-comments can not be used when outputting to stdout')
+
+ return parser, options, args
+
+class GenCache(object):
+ def __init__(self, portdb, cp_iter=None, max_jobs=None, max_load=None,
+ rsync=False):
+ self._portdb = portdb
+ # We can globally cleanse stale cache only if we
+ # iterate over every single cp.
+ self._global_cleanse = cp_iter is None
+ if cp_iter is not None:
+ self._cp_set = set(cp_iter)
+ cp_iter = iter(self._cp_set)
+ self._cp_missing = self._cp_set.copy()
+ else:
+ self._cp_set = None
+ self._cp_missing = set()
+ self._regen = MetadataRegen(portdb, cp_iter=cp_iter,
+ consumer=self._metadata_callback,
+ max_jobs=max_jobs, max_load=max_load)
+ self.returncode = os.EX_OK
+ metadbmodule = portdb.settings.load_best_module("portdbapi.metadbmodule")
+ self._trg_cache = metadbmodule(portdb.porttrees[0],
+ "metadata/cache", portage.auxdbkeys[:])
+ if rsync:
+ self._trg_cache.raise_stat_collision = True
+ try:
+ self._trg_cache.ec = \
+ portdb._repo_info[portdb.porttrees[0]].eclass_db
+ except AttributeError:
+ pass
+ self._existing_nodes = set()
+
+ def _metadata_callback(self, cpv, ebuild_path, repo_path, metadata):
+ self._existing_nodes.add(cpv)
+ self._cp_missing.discard(cpv_getkey(cpv))
+ if metadata is not None:
+ if metadata.get('EAPI') == '0':
+ del metadata['EAPI']
+ try:
+ try:
+ self._trg_cache[cpv] = metadata
+ except StatCollision as sc:
+ # If the content of a cache entry changes and neither the
+ # file mtime nor size changes, it will prevent rsync from
+ # detecting changes. Cache backends may raise this
+ # exception from _setitem() if they detect this type of stat
+ # collision. These exceptions are handled by bumping the
+ # mtime on the ebuild (and the corresponding cache entry).
+ # See bug #139134.
+ max_mtime = sc.mtime
+ for ec, (loc, ec_mtime) in metadata['_eclasses_'].items():
+ if max_mtime < ec_mtime:
+ max_mtime = ec_mtime
+ if max_mtime == sc.mtime:
+ max_mtime += 1
+ max_mtime = long(max_mtime)
+ try:
+ os.utime(ebuild_path, (max_mtime, max_mtime))
+ except OSError as e:
+ self.returncode |= 1
+ writemsg_level(
+ "%s writing target: %s\n" % (cpv, e),
+ level=logging.ERROR, noiselevel=-1)
+ else:
+ metadata['_mtime_'] = max_mtime
+ self._trg_cache[cpv] = metadata
+ self._portdb.auxdb[repo_path][cpv] = metadata
+
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "%s writing target: %s\n" % (cpv, ce),
+ level=logging.ERROR, noiselevel=-1)
+
+ def run(self):
+
+ received_signal = []
+
+ def sighandler(signum, frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ self._regen.terminate()
+ received_signal.append(128 + signum)
+
+ earlier_sigint_handler = signal.signal(signal.SIGINT, sighandler)
+ earlier_sigterm_handler = signal.signal(signal.SIGTERM, sighandler)
+
+ try:
+ self._regen.run()
+ finally:
+ # Restore previous handlers
+ if earlier_sigint_handler is not None:
+ signal.signal(signal.SIGINT, earlier_sigint_handler)
+ else:
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+ if earlier_sigterm_handler is not None:
+ signal.signal(signal.SIGTERM, earlier_sigterm_handler)
+ else:
+ signal.signal(signal.SIGTERM, signal.SIG_DFL)
+
+ if received_signal:
+ sys.exit(received_signal[0])
+
+ self.returncode |= self._regen.returncode
+ cp_missing = self._cp_missing
+
+ trg_cache = self._trg_cache
+ dead_nodes = set()
+ if self._global_cleanse:
+ try:
+ for cpv in trg_cache:
+ cp = cpv_getkey(cpv)
+ if cp is None:
+ self.returncode |= 1
+ writemsg_level(
+ "Unable to parse cp for '%s'\n" % (cpv,),
+ level=logging.ERROR, noiselevel=-1)
+ else:
+ dead_nodes.add(cpv)
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "Error listing cache entries for " + \
+ "'%s/metadata/cache': %s, continuing...\n" % \
+ (self._portdb.porttree_root, ce),
+ level=logging.ERROR, noiselevel=-1)
+
+ else:
+ cp_set = self._cp_set
+ try:
+ for cpv in trg_cache:
+ cp = cpv_getkey(cpv)
+ if cp is None:
+ self.returncode |= 1
+ writemsg_level(
+ "Unable to parse cp for '%s'\n" % (cpv,),
+ level=logging.ERROR, noiselevel=-1)
+ else:
+ cp_missing.discard(cp)
+ if cp in cp_set:
+ dead_nodes.add(cpv)
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "Error listing cache entries for " + \
+ "'%s/metadata/cache': %s, continuing...\n" % \
+ (self._portdb.porttree_root, ce),
+ level=logging.ERROR, noiselevel=-1)
+
+ if cp_missing:
+ self.returncode |= 1
+ for cp in sorted(cp_missing):
+ writemsg_level(
+ "No ebuilds or cache entries found for '%s'\n" % (cp,),
+ level=logging.ERROR, noiselevel=-1)
+
+ if dead_nodes:
+ dead_nodes.difference_update(self._existing_nodes)
+ for k in dead_nodes:
+ try:
+ del trg_cache[k]
+ except KeyError:
+ pass
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "%s deleting stale cache: %s\n" % (k, ce),
+ level=logging.ERROR, noiselevel=-1)
+
+ if not trg_cache.autocommits:
+ try:
+ trg_cache.commit()
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "committing target: %s\n" % (ce,),
+ level=logging.ERROR, noiselevel=-1)
+
+class GenUseLocalDesc(object):
+ def __init__(self, portdb, output=None,
+ preserve_comments=False):
+ self.returncode = os.EX_OK
+ self._portdb = portdb
+ self._output = output
+ self._preserve_comments = preserve_comments
+
+ def run(self):
+ repo_path = self._portdb.porttrees[0]
+ ops = {'<':0, '<=':1, '=':2, '>=':3, '>':4}
+
+ if self._output is None or self._output != '-':
+ if self._output is None:
+ prof_path = os.path.join(repo_path, 'profiles')
+ desc_path = os.path.join(prof_path, 'use.local.desc')
+ try:
+ os.mkdir(prof_path)
+ except OSError:
+ pass
+ else:
+ desc_path = self._output
+
+ try:
+ if self._preserve_comments:
+ # Probe in binary mode, in order to avoid
+ # potential character encoding issues.
+ output = open(_unicode_encode(desc_path,
+ encoding=_encodings['fs'], errors='strict'), 'r+b')
+ else:
+ output = io.open(_unicode_encode(desc_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='w', encoding=_encodings['repo.content'],
+ errors='backslashreplace')
+ except IOError as e:
+ if not self._preserve_comments or \
+ os.path.isfile(desc_path):
+ writemsg_level(
+ "ERROR: failed to open output file %s: %s\n" \
+ % (desc_path, e), level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 2
+ return
+
+ # Open in r+b mode failed because the file doesn't
+ # exist yet. We can probably recover if we disable
+ # preserve_comments mode now.
+ writemsg_level(
+ "WARNING: --preserve-comments enabled, but " + \
+ "output file not found: %s\n" % (desc_path,),
+ level=logging.WARNING, noiselevel=-1)
+ self._preserve_comments = False
+ try:
+ output = io.open(_unicode_encode(desc_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='w', encoding=_encodings['repo.content'],
+ errors='backslashreplace')
+ except IOError as e:
+ writemsg_level(
+ "ERROR: failed to open output file %s: %s\n" \
+ % (desc_path, e), level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 2
+ return
+ else:
+ output = sys.stdout
+
+ if self._preserve_comments:
+ while True:
+ pos = output.tell()
+ if not output.readline().startswith(b'#'):
+ break
+ output.seek(pos)
+ output.truncate()
+ output.close()
+
+ # Finished probing comments in binary mode, now append
+ # in text mode.
+ output = io.open(_unicode_encode(desc_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='a', encoding=_encodings['repo.content'],
+ errors='backslashreplace')
+ output.write(_unicode_decode('\n'))
+ else:
+ output.write(_unicode_decode('''
+# This file is deprecated as per GLEP 56 in favor of metadata.xml. Please add
+# your descriptions to your package's metadata.xml ONLY.
+# * generated automatically using egencache *
+
+'''.lstrip()))
+
+ # The cmp function no longer exists in python3, so we'll
+ # implement our own here under a slightly different name
+ # since we don't want any confusion given that we never
+ # want to rely on the builtin cmp function.
+ def cmp_func(a, b):
+ if a is None or b is None:
+ # None can't be compared with other types in python3.
+ if a is None and b is None:
+ return 0
+ elif a is None:
+ return -1
+ else:
+ return 1
+ return (a > b) - (a < b)
+
+ for cp in self._portdb.cp_all():
+ metadata_path = os.path.join(repo_path, cp, 'metadata.xml')
+ try:
+ metadata = ElementTree.parse(metadata_path)
+ except IOError:
+ pass
+ except (ExpatError, EnvironmentError) as e:
+ writemsg_level(
+ "ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 1
+ else:
+ try:
+ usedict = parse_metadata_use(metadata)
+ except portage.exception.ParseError as e:
+ writemsg_level(
+ "ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 1
+ else:
+ for flag in sorted(usedict):
+ def atomcmp(atoma, atomb):
+ # None is better than an atom, that's why we reverse the args
+ if atoma is None or atomb is None:
+ return cmp_func(atomb, atoma)
+ # Same for plain PNs (.operator is None then)
+ elif atoma.operator is None or atomb.operator is None:
+ return cmp_func(atomb.operator, atoma.operator)
+ # Version matching
+ elif atoma.cpv != atomb.cpv:
+ return pkgcmp(pkgsplit(atoma.cpv), pkgsplit(atomb.cpv))
+ # Versions match, let's fallback to operator matching
+ else:
+ return cmp_func(ops.get(atoma.operator, -1),
+ ops.get(atomb.operator, -1))
+
+ def _Atom(key):
+ if key is not None:
+ return Atom(key)
+ return None
+
+ resdict = usedict[flag]
+ if len(resdict) == 1:
+ resdesc = next(iter(resdict.items()))[1]
+ else:
+ try:
+ reskeys = dict((_Atom(k), k) for k in resdict)
+ except portage.exception.InvalidAtom as e:
+ writemsg_level(
+ "ERROR: failed parsing %s/metadata.xml: %s\n" % (cp, e),
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 1
+ resdesc = next(iter(resdict.items()))[1]
+ else:
+ resatoms = sorted(reskeys, key=cmp_sort_key(atomcmp))
+ resdesc = resdict[reskeys[resatoms[-1]]]
+
+ output.write(_unicode_decode(
+ '%s:%s - %s\n' % (cp, flag, resdesc)))
+
+ output.close()
+
+if sys.hexversion < 0x3000000:
+ _filename_base = unicode
+else:
+ _filename_base = str
+
+class _special_filename(_filename_base):
+ """
+ Helps to sort file names by file type and other criteria.
+ """
+ def __new__(cls, status_change, file_name):
+ return _filename_base.__new__(cls, status_change + file_name)
+
+ def __init__(self, status_change, file_name):
+ _filename_base.__init__(status_change + file_name)
+ self.status_change = status_change
+ self.file_name = file_name
+ self.file_type = guessManifestFileType(file_name)
+
+ def file_type_lt(self, a, b):
+ """
+ Defines an ordering between file types.
+ """
+ first = a.file_type
+ second = b.file_type
+ if first == second:
+ return False
+
+ if first == "EBUILD":
+ return True
+ elif first == "MISC":
+ return second in ("EBUILD",)
+ elif first == "AUX":
+ return second in ("EBUILD", "MISC")
+ elif first == "DIST":
+ return second in ("EBUILD", "MISC", "AUX")
+ elif first is None:
+ return False
+ else:
+ raise ValueError("Unknown file type '%s'" % first)
+
+ def __lt__(self, other):
+ """
+ Compare different file names, first by file type and then
+ for ebuilds by version and lexicographically for others.
+ EBUILD < MISC < AUX < DIST < None
+ """
+ if self.__class__ != other.__class__:
+ raise NotImplementedError
+
+ # Sort by file type as defined by file_type_lt().
+ if self.file_type_lt(self, other):
+ return True
+ elif self.file_type_lt(other, self):
+ return False
+
+ # Files have the same type.
+ if self.file_type == "EBUILD":
+ # Sort by version. Lowest first.
+ ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
+ other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
+ return vercmp(ver, other_ver) < 0
+ else:
+ # Sort lexicographically.
+ return self.file_name < other.file_name
+
+class GenChangeLogs(object):
+ def __init__(self, portdb):
+ self.returncode = os.EX_OK
+ self._portdb = portdb
+ self._wrapper = textwrap.TextWrapper(
+ width = 78,
+ initial_indent = ' ',
+ subsequent_indent = ' '
+ )
+
+ @staticmethod
+ def grab(cmd):
+ p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ return _unicode_decode(p.communicate()[0],
+ encoding=_encodings['stdio'], errors='strict')
+
+ def generate_changelog(self, cp):
+ try:
+ output = io.open('ChangeLog',
+ mode='w', encoding=_encodings['repo.content'],
+ errors='backslashreplace')
+ except IOError as e:
+ writemsg_level(
+ "ERROR: failed to open ChangeLog for %s: %s\n" % (cp,e,),
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 2
+ return
+
+ output.write(_unicode_decode('''
+# ChangeLog for %s
+# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2
+# $Header: $
+
+''' % (cp, time.strftime('%Y'))).lstrip())
+
+ # now grab all the commits
+ commits = self.grab(['git', 'rev-list', 'HEAD', '--', '.']).split()
+
+ for c in commits:
+ # Explaining the arguments:
+ # --name-status to get a list of added/removed files
+ # --no-renames to avoid getting more complex records on the list
+ # --format to get the timestamp, author and commit description
+ # --root to make it work fine even with the initial commit
+ # --relative to get paths relative to ebuilddir
+ # -r (recursive) to get per-file changes
+ # then the commit-id and path.
+
+ cinfo = self.grab(['git', 'diff-tree', '--name-status', '--no-renames',
+ '--format=%ct %cN <%cE>%n%B', '--root', '--relative', '-r',
+ c, '--', '.']).rstrip('\n').split('\n')
+
+ # Expected output:
+ # timestamp Author Name <author@email>
+ # commit message l1
+ # ...
+ # commit message ln
+ #
+ # status1 filename1
+ # ...
+ # statusn filenamen
+
+ changed = []
+ for n, l in enumerate(reversed(cinfo)):
+ if not l:
+ body = cinfo[1:-n-1]
+ break
+ else:
+ f = l.split()
+ if f[1] == 'Manifest':
+ pass # XXX: remanifest commits?
+ elif f[1] == 'ChangeLog':
+ pass
+ elif f[0].startswith('A'):
+ changed.append(_special_filename("+", f[1]))
+ elif f[0].startswith('D'):
+ changed.append(_special_filename("-", f[1]))
+ elif f[0].startswith('M'):
+ changed.append(_special_filename("", f[1]))
+ else:
+ writemsg_level(
+ "ERROR: unexpected git file status for %s: %s\n" % (cp,f,),
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode |= 1
+
+ if not changed:
+ continue
+
+ (ts, author) = cinfo[0].split(' ', 1)
+ date = time.strftime('%d %b %Y', time.gmtime(float(ts)))
+
+ changed = [str(x) for x in sorted(changed)]
+
+ wroteheader = False
+ # Reverse the sort order for headers.
+ for c in reversed(changed):
+ if c.startswith('+') and c.endswith('.ebuild'):
+ output.write(_unicode_decode(
+ '*%s (%s)\n' % (c[1:-7], date)))
+ wroteheader = True
+ if wroteheader:
+ output.write(_unicode_decode('\n'))
+
+ # strip '<cp>: ', '[<cp>] ', and similar
+ body[0] = re.sub(r'^\W*' + re.escape(cp) + r'\W+', '', body[0])
+ # strip trailing newline
+ if not body[-1]:
+ body = body[:-1]
+ # strip git-svn id
+ if body[-1].startswith('git-svn-id:') and not body[-2]:
+ body = body[:-2]
+ # strip the repoman version/manifest note
+ if body[-1] == ' (Signed Manifest commit)' or body[-1] == ' (Unsigned Manifest commit)':
+ body = body[:-1]
+ if body[-1].startswith('(Portage version:') and body[-1].endswith(')'):
+ body = body[:-1]
+ if not body[-1]:
+ body = body[:-1]
+
+ # don't break filenames on hyphens
+ self._wrapper.break_on_hyphens = False
+ output.write(_unicode_decode(
+ self._wrapper.fill(
+ '%s; %s %s:' % (date, author, ', '.join(changed)))))
+ # but feel free to break commit messages there
+ self._wrapper.break_on_hyphens = True
+ output.write(_unicode_decode(
+ '\n%s\n\n' % '\n'.join(self._wrapper.fill(x) for x in body)))
+
+ output.close()
+
+ def run(self):
+ repo_path = self._portdb.porttrees[0]
+ os.chdir(repo_path)
+
+ if 'git' not in FindVCS():
+ writemsg_level(
+ "ERROR: --update-changelogs supported only in git repos\n",
+ level=logging.ERROR, noiselevel=-1)
+ self.returncode = 127
+ return
+
+ for cp in self._portdb.cp_all():
+ os.chdir(os.path.join(repo_path, cp))
+ # Determine whether ChangeLog is up-to-date by comparing
+ # the newest commit timestamp with the ChangeLog timestamp.
+ lmod = self.grab(['git', 'log', '--format=%ct', '-1', '.'])
+ if not lmod:
+ # This cp has not been added to the repo.
+ continue
+
+ try:
+ cmod = os.stat('ChangeLog').st_mtime
+ except OSError:
+ cmod = 0
+
+ if float(cmod) < float(lmod):
+ self.generate_changelog(cp)
+
+def egencache_main(args):
+ parser, options, atoms = parse_args(args)
+
+ config_root = options.config_root
+ if config_root is None:
+ config_root = '/'
+
+ # The calling environment is ignored, so the program is
+ # completely controlled by commandline arguments.
+ env = {}
+
+ if options.repo is None:
+ env['PORTDIR_OVERLAY'] = ''
+
+ if options.cache_dir is not None:
+ env['PORTAGE_DEPCACHEDIR'] = options.cache_dir
+
+ if options.portdir is not None:
+ env['PORTDIR'] = options.portdir
+
+ settings = portage.config(config_root=config_root,
+ target_root='/', local_config=False, env=env)
+
+ default_opts = None
+ if not options.ignore_default_opts:
+ default_opts = settings.get('EGENCACHE_DEFAULT_OPTS', '').split()
+
+ if default_opts:
+ parser, options, args = parse_args(default_opts + args)
+
+ if options.config_root is not None:
+ config_root = options.config_root
+
+ if options.cache_dir is not None:
+ env['PORTAGE_DEPCACHEDIR'] = options.cache_dir
+
+ settings = portage.config(config_root=config_root,
+ target_root='/', local_config=False, env=env)
+
+ if not options.update and not options.update_use_local_desc \
+ and not options.update_changelogs:
+ parser.error('No action specified')
+ return 1
+
+ if options.update and 'metadata-transfer' not in settings.features:
+ writemsg_level("ecachegen: warning: " + \
+ "automatically enabling FEATURES=metadata-transfer\n",
+ level=logging.WARNING, noiselevel=-1)
+ settings.features.add('metadata-transfer')
+
+ settings.lock()
+
+ portdb = portage.portdbapi(mysettings=settings)
+ if options.repo is not None:
+ repo_path = portdb.getRepositoryPath(options.repo)
+ if repo_path is None:
+ parser.error("Unable to locate repository named '%s'" % \
+ (options.repo,))
+ return 1
+
+ # Limit ebuilds to the specified repo.
+ portdb.porttrees = [repo_path]
+
+ ret = [os.EX_OK]
+
+ if options.update:
+ cp_iter = None
+ if atoms:
+ cp_iter = iter(atoms)
+
+ gen_cache = GenCache(portdb, cp_iter=cp_iter,
+ max_jobs=options.jobs,
+ max_load=options.load_average,
+ rsync=options.rsync)
+ gen_cache.run()
+ if options.tolerant:
+ ret.append(os.EX_OK)
+ else:
+ ret.append(gen_cache.returncode)
+
+ if options.update_use_local_desc:
+ gen_desc = GenUseLocalDesc(portdb,
+ output=options.uld_output,
+ preserve_comments=options.preserve_comments)
+ gen_desc.run()
+ ret.append(gen_desc.returncode)
+
+ if options.update_changelogs:
+ gen_clogs = GenChangeLogs(portdb)
+ gen_clogs.run()
+ ret.append(gen_clogs.returncode)
+
+ return max(ret)
+
+if __name__ == "__main__":
+ portage._disable_legacy_globals()
+ portage.util.noiselimit = -1
+ sys.exit(egencache_main(sys.argv[1:]))
diff --git a/portage_with_autodep/bin/emaint b/portage_with_autodep/bin/emaint
new file mode 100755
index 0000000..fdd01ed
--- /dev/null
+++ b/portage_with_autodep/bin/emaint
@@ -0,0 +1,654 @@
+#!/usr/bin/python -O
+# vim: noet :
+
+from __future__ import print_function
+
+import errno
+import re
+import signal
+import stat
+import sys
+import textwrap
+import time
+from optparse import OptionParser, OptionValueError
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage.util import writemsg
+
+if sys.hexversion >= 0x3000000:
+ long = int
+
+class WorldHandler(object):
+
+ short_desc = "Fix problems in the world file"
+
+ def name():
+ return "world"
+ name = staticmethod(name)
+
+ def __init__(self):
+ self.invalid = []
+ self.not_installed = []
+ self.invalid_category = []
+ self.okay = []
+ from portage._sets import load_default_config
+ setconfig = load_default_config(portage.settings,
+ portage.db[portage.settings["ROOT"]])
+ self._sets = setconfig.getSets()
+
+ def _check_world(self, onProgress):
+ categories = set(portage.settings.categories)
+ myroot = portage.settings["ROOT"]
+ self.world_file = os.path.join(portage.settings["EROOT"], portage.const.WORLD_FILE)
+ self.found = os.access(self.world_file, os.R_OK)
+ vardb = portage.db[myroot]["vartree"].dbapi
+
+ from portage._sets import SETPREFIX
+ sets = self._sets
+ world_atoms = list(sets["selected"])
+ maxval = len(world_atoms)
+ if onProgress:
+ onProgress(maxval, 0)
+ for i, atom in enumerate(world_atoms):
+ if not isinstance(atom, portage.dep.Atom):
+ if atom.startswith(SETPREFIX):
+ s = atom[len(SETPREFIX):]
+ if s in sets:
+ self.okay.append(atom)
+ else:
+ self.not_installed.append(atom)
+ else:
+ self.invalid.append(atom)
+ if onProgress:
+ onProgress(maxval, i+1)
+ continue
+ okay = True
+ if not vardb.match(atom):
+ self.not_installed.append(atom)
+ okay = False
+ if portage.catsplit(atom.cp)[0] not in categories:
+ self.invalid_category.append(atom)
+ okay = False
+ if okay:
+ self.okay.append(atom)
+ if onProgress:
+ onProgress(maxval, i+1)
+
+ def check(self, onProgress=None):
+ self._check_world(onProgress)
+ errors = []
+ if self.found:
+ errors += ["'%s' is not a valid atom" % x for x in self.invalid]
+ errors += ["'%s' is not installed" % x for x in self.not_installed]
+ errors += ["'%s' has a category that is not listed in /etc/portage/categories" % x for x in self.invalid_category]
+ else:
+ errors.append(self.world_file + " could not be opened for reading")
+ return errors
+
+ def fix(self, onProgress=None):
+ world_set = self._sets["selected"]
+ world_set.lock()
+ try:
+ world_set.load() # maybe it's changed on disk
+ before = set(world_set)
+ self._check_world(onProgress)
+ after = set(self.okay)
+ errors = []
+ if before != after:
+ try:
+ world_set.replace(self.okay)
+ except portage.exception.PortageException:
+ errors.append("%s could not be opened for writing" % \
+ self.world_file)
+ return errors
+ finally:
+ world_set.unlock()
+
+class BinhostHandler(object):
+
+ short_desc = "Generate a metadata index for binary packages"
+
+ def name():
+ return "binhost"
+ name = staticmethod(name)
+
+ def __init__(self):
+ myroot = portage.settings["ROOT"]
+ self._bintree = portage.db[myroot]["bintree"]
+ self._bintree.populate()
+ self._pkgindex_file = self._bintree._pkgindex_file
+ self._pkgindex = self._bintree._load_pkgindex()
+
+ def _need_update(self, cpv, data):
+
+ if "MD5" not in data:
+ return True
+
+ size = data.get("SIZE")
+ if size is None:
+ return True
+
+ mtime = data.get("MTIME")
+ if mtime is None:
+ return True
+
+ pkg_path = self._bintree.getname(cpv)
+ try:
+ s = os.lstat(pkg_path)
+ except OSError as e:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
+ raise
+ # We can't update the index for this one because
+ # it disappeared.
+ return False
+
+ try:
+ if long(mtime) != s[stat.ST_MTIME]:
+ return True
+ if long(size) != long(s.st_size):
+ return True
+ except ValueError:
+ return True
+
+ return False
+
+ def check(self, onProgress=None):
+ missing = []
+ cpv_all = self._bintree.dbapi.cpv_all()
+ cpv_all.sort()
+ maxval = len(cpv_all)
+ if onProgress:
+ onProgress(maxval, 0)
+ pkgindex = self._pkgindex
+ missing = []
+ metadata = {}
+ for d in pkgindex.packages:
+ metadata[d["CPV"]] = d
+ for i, cpv in enumerate(cpv_all):
+ d = metadata.get(cpv)
+ if not d or self._need_update(cpv, d):
+ missing.append(cpv)
+ if onProgress:
+ onProgress(maxval, i+1)
+ errors = ["'%s' is not in Packages" % cpv for cpv in missing]
+ stale = set(metadata).difference(cpv_all)
+ for cpv in stale:
+ errors.append("'%s' is not in the repository" % cpv)
+ return errors
+
+ def fix(self, onProgress=None):
+ bintree = self._bintree
+ cpv_all = self._bintree.dbapi.cpv_all()
+ cpv_all.sort()
+ missing = []
+ maxval = 0
+ if onProgress:
+ onProgress(maxval, 0)
+ pkgindex = self._pkgindex
+ missing = []
+ metadata = {}
+ for d in pkgindex.packages:
+ metadata[d["CPV"]] = d
+
+ for i, cpv in enumerate(cpv_all):
+ d = metadata.get(cpv)
+ if not d or self._need_update(cpv, d):
+ missing.append(cpv)
+
+ stale = set(metadata).difference(cpv_all)
+ if missing or stale:
+ from portage import locks
+ pkgindex_lock = locks.lockfile(
+ self._pkgindex_file, wantnewlockfile=1)
+ try:
+ # Repopulate with lock held.
+ bintree._populate()
+ cpv_all = self._bintree.dbapi.cpv_all()
+ cpv_all.sort()
+
+ pkgindex = bintree._load_pkgindex()
+ self._pkgindex = pkgindex
+
+ metadata = {}
+ for d in pkgindex.packages:
+ metadata[d["CPV"]] = d
+
+ # Recount missing packages, with lock held.
+ del missing[:]
+ for i, cpv in enumerate(cpv_all):
+ d = metadata.get(cpv)
+ if not d or self._need_update(cpv, d):
+ missing.append(cpv)
+
+ maxval = len(missing)
+ for i, cpv in enumerate(missing):
+ try:
+ metadata[cpv] = bintree._pkgindex_entry(cpv)
+ except portage.exception.InvalidDependString:
+ writemsg("!!! Invalid binary package: '%s'\n" % \
+ bintree.getname(cpv), noiselevel=-1)
+
+ if onProgress:
+ onProgress(maxval, i+1)
+
+ for cpv in set(metadata).difference(
+ self._bintree.dbapi.cpv_all()):
+ del metadata[cpv]
+
+ # We've updated the pkgindex, so set it to
+ # repopulate when necessary.
+ bintree.populated = False
+
+ del pkgindex.packages[:]
+ pkgindex.packages.extend(metadata.values())
+ from portage.util import atomic_ofstream
+ f = atomic_ofstream(self._pkgindex_file)
+ try:
+ self._pkgindex.write(f)
+ finally:
+ f.close()
+ finally:
+ locks.unlockfile(pkgindex_lock)
+
+ if onProgress:
+ if maxval == 0:
+ maxval = 1
+ onProgress(maxval, maxval)
+ return None
+
+class MoveHandler(object):
+
+ def __init__(self, tree, porttree):
+ self._tree = tree
+ self._portdb = porttree.dbapi
+ self._update_keys = ["DEPEND", "RDEPEND", "PDEPEND", "PROVIDE"]
+ self._master_repo = \
+ self._portdb.getRepositoryName(self._portdb.porttree_root)
+
+ def _grab_global_updates(self):
+ from portage.update import grab_updates, parse_updates
+ retupdates = {}
+ errors = []
+
+ for repo_name in self._portdb.getRepositories():
+ repo = self._portdb.getRepositoryPath(repo_name)
+ updpath = os.path.join(repo, "profiles", "updates")
+ if not os.path.isdir(updpath):
+ continue
+
+ try:
+ rawupdates = grab_updates(updpath)
+ except portage.exception.DirectoryNotFound:
+ rawupdates = []
+ upd_commands = []
+ for mykey, mystat, mycontent in rawupdates:
+ commands, errors = parse_updates(mycontent)
+ upd_commands.extend(commands)
+ errors.extend(errors)
+ retupdates[repo_name] = upd_commands
+
+ if self._master_repo in retupdates:
+ retupdates['DEFAULT'] = retupdates[self._master_repo]
+
+ return retupdates, errors
+
+ def check(self, onProgress=None):
+ allupdates, errors = self._grab_global_updates()
+ # Matching packages and moving them is relatively fast, so the
+ # progress bar is updated in indeterminate mode.
+ match = self._tree.dbapi.match
+ aux_get = self._tree.dbapi.aux_get
+ if onProgress:
+ onProgress(0, 0)
+ for repo, updates in allupdates.items():
+ if repo == 'DEFAULT':
+ continue
+ if not updates:
+ continue
+
+ def repo_match(repository):
+ return repository == repo or \
+ (repo == self._master_repo and \
+ repository not in allupdates)
+
+ for i, update_cmd in enumerate(updates):
+ if update_cmd[0] == "move":
+ origcp, newcp = update_cmd[1:]
+ for cpv in match(origcp):
+ if repo_match(aux_get(cpv, ["repository"])[0]):
+ errors.append("'%s' moved to '%s'" % (cpv, newcp))
+ elif update_cmd[0] == "slotmove":
+ pkg, origslot, newslot = update_cmd[1:]
+ for cpv in match(pkg):
+ slot, prepo = aux_get(cpv, ["SLOT", "repository"])
+ if slot == origslot and repo_match(prepo):
+ errors.append("'%s' slot moved from '%s' to '%s'" % \
+ (cpv, origslot, newslot))
+ if onProgress:
+ onProgress(0, 0)
+
+ # Searching for updates in all the metadata is relatively slow, so this
+ # is where the progress bar comes out of indeterminate mode.
+ cpv_all = self._tree.dbapi.cpv_all()
+ cpv_all.sort()
+ maxval = len(cpv_all)
+ aux_update = self._tree.dbapi.aux_update
+ meta_keys = self._update_keys + ['repository']
+ from portage.update import update_dbentries
+ if onProgress:
+ onProgress(maxval, 0)
+ for i, cpv in enumerate(cpv_all):
+ metadata = dict(zip(meta_keys, aux_get(cpv, meta_keys)))
+ repository = metadata.pop('repository')
+ try:
+ updates = allupdates[repository]
+ except KeyError:
+ try:
+ updates = allupdates['DEFAULT']
+ except KeyError:
+ continue
+ if not updates:
+ continue
+ metadata_updates = update_dbentries(updates, metadata)
+ if metadata_updates:
+ errors.append("'%s' has outdated metadata" % cpv)
+ if onProgress:
+ onProgress(maxval, i+1)
+ return errors
+
+ def fix(self, onProgress=None):
+ allupdates, errors = self._grab_global_updates()
+ # Matching packages and moving them is relatively fast, so the
+ # progress bar is updated in indeterminate mode.
+ move = self._tree.dbapi.move_ent
+ slotmove = self._tree.dbapi.move_slot_ent
+ if onProgress:
+ onProgress(0, 0)
+ for repo, updates in allupdates.items():
+ if repo == 'DEFAULT':
+ continue
+ if not updates:
+ continue
+
+ def repo_match(repository):
+ return repository == repo or \
+ (repo == self._master_repo and \
+ repository not in allupdates)
+
+ for i, update_cmd in enumerate(updates):
+ if update_cmd[0] == "move":
+ move(update_cmd, repo_match=repo_match)
+ elif update_cmd[0] == "slotmove":
+ slotmove(update_cmd, repo_match=repo_match)
+ if onProgress:
+ onProgress(0, 0)
+
+ # Searching for updates in all the metadata is relatively slow, so this
+ # is where the progress bar comes out of indeterminate mode.
+ self._tree.dbapi.update_ents(allupdates, onProgress=onProgress)
+ return errors
+
+class MoveInstalled(MoveHandler):
+
+ short_desc = "Perform package move updates for installed packages"
+
+ def name():
+ return "moveinst"
+ name = staticmethod(name)
+ def __init__(self):
+ myroot = portage.settings["ROOT"]
+ MoveHandler.__init__(self, portage.db[myroot]["vartree"], portage.db[myroot]["porttree"])
+
+class MoveBinary(MoveHandler):
+
+ short_desc = "Perform package move updates for binary packages"
+
+ def name():
+ return "movebin"
+ name = staticmethod(name)
+ def __init__(self):
+ myroot = portage.settings["ROOT"]
+ MoveHandler.__init__(self, portage.db[myroot]["bintree"], portage.db[myroot]["porttree"])
+
+class VdbKeyHandler(object):
+ def name():
+ return "vdbkeys"
+ name = staticmethod(name)
+
+ def __init__(self):
+ self.list = portage.db["/"]["vartree"].dbapi.cpv_all()
+ self.missing = []
+ self.keys = ["HOMEPAGE", "SRC_URI", "KEYWORDS", "DESCRIPTION"]
+
+ for p in self.list:
+ mydir = os.path.join(portage.settings["EROOT"], portage.const.VDB_PATH, p)+os.sep
+ ismissing = True
+ for k in self.keys:
+ if os.path.exists(mydir+k):
+ ismissing = False
+ break
+ if ismissing:
+ self.missing.append(p)
+
+ def check(self):
+ return ["%s has missing keys" % x for x in self.missing]
+
+ def fix(self):
+
+ errors = []
+
+ for p in self.missing:
+ mydir = os.path.join(portage.settings["EROOT"], portage.const.VDB_PATH, p)+os.sep
+ if not os.access(mydir+"environment.bz2", os.R_OK):
+ errors.append("Can't access %s" % (mydir+"environment.bz2"))
+ elif not os.access(mydir, os.W_OK):
+ errors.append("Can't create files in %s" % mydir)
+ else:
+ env = os.popen("bzip2 -dcq "+mydir+"environment.bz2", "r")
+ envlines = env.read().split("\n")
+ env.close()
+ for k in self.keys:
+ s = [l for l in envlines if l.startswith(k+"=")]
+ if len(s) > 1:
+ errors.append("multiple matches for %s found in %senvironment.bz2" % (k, mydir))
+ elif len(s) == 0:
+ s = ""
+ else:
+ s = s[0].split("=",1)[1]
+ s = s.lstrip("$").strip("\'\"")
+ s = re.sub("(\\\\[nrt])+", " ", s)
+ s = " ".join(s.split()).strip()
+ if s != "":
+ try:
+ keyfile = open(mydir+os.sep+k, "w")
+ keyfile.write(s+"\n")
+ keyfile.close()
+ except (IOError, OSError) as e:
+ errors.append("Could not write %s, reason was: %s" % (mydir+k, e))
+
+ return errors
+
+class ProgressHandler(object):
+ def __init__(self):
+ self.curval = 0
+ self.maxval = 0
+ self.last_update = 0
+ self.min_display_latency = 0.2
+
+ def onProgress(self, maxval, curval):
+ self.maxval = maxval
+ self.curval = curval
+ cur_time = time.time()
+ if cur_time - self.last_update >= self.min_display_latency:
+ self.last_update = cur_time
+ self.display()
+
+ def display(self):
+ raise NotImplementedError(self)
+
+class CleanResume(object):
+
+ short_desc = "Discard emerge --resume merge lists"
+
+ def name():
+ return "cleanresume"
+ name = staticmethod(name)
+
+ def check(self, onProgress=None):
+ messages = []
+ mtimedb = portage.mtimedb
+ resume_keys = ("resume", "resume_backup")
+ maxval = len(resume_keys)
+ if onProgress:
+ onProgress(maxval, 0)
+ for i, k in enumerate(resume_keys):
+ try:
+ d = mtimedb.get(k)
+ if d is None:
+ continue
+ if not isinstance(d, dict):
+ messages.append("unrecognized resume list: '%s'" % k)
+ continue
+ mergelist = d.get("mergelist")
+ if mergelist is None or not hasattr(mergelist, "__len__"):
+ messages.append("unrecognized resume list: '%s'" % k)
+ continue
+ messages.append("resume list '%s' contains %d packages" % \
+ (k, len(mergelist)))
+ finally:
+ if onProgress:
+ onProgress(maxval, i+1)
+ return messages
+
+ def fix(self, onProgress=None):
+ delete_count = 0
+ mtimedb = portage.mtimedb
+ resume_keys = ("resume", "resume_backup")
+ maxval = len(resume_keys)
+ if onProgress:
+ onProgress(maxval, 0)
+ for i, k in enumerate(resume_keys):
+ try:
+ if mtimedb.pop(k, None) is not None:
+ delete_count += 1
+ finally:
+ if onProgress:
+ onProgress(maxval, i+1)
+ if delete_count:
+ mtimedb.commit()
+
+def emaint_main(myargv):
+
+ # Similar to emerge, emaint needs a default umask so that created
+ # files (such as the world file) have sane permissions.
+ os.umask(0o22)
+
+ # TODO: Create a system that allows external modules to be added without
+ # the need for hard coding.
+ modules = {
+ "world" : WorldHandler,
+ "binhost":BinhostHandler,
+ "moveinst":MoveInstalled,
+ "movebin":MoveBinary,
+ "cleanresume":CleanResume
+ }
+
+ module_names = list(modules)
+ module_names.sort()
+ module_names.insert(0, "all")
+
+ def exclusive(option, *args, **kw):
+ var = kw.get("var", None)
+ if var is None:
+ raise ValueError("var not specified to exclusive()")
+ if getattr(parser, var, ""):
+ raise OptionValueError("%s and %s are exclusive options" % (getattr(parser, var), option))
+ setattr(parser, var, str(option))
+
+
+ usage = "usage: emaint [options] COMMAND"
+
+ desc = "The emaint program provides an interface to system health " + \
+ "checks and maintenance. See the emaint(1) man page " + \
+ "for additional information about the following commands:"
+
+ usage += "\n\n"
+ for line in textwrap.wrap(desc, 65):
+ usage += "%s\n" % line
+ usage += "\n"
+ usage += " %s" % "all".ljust(15) + \
+ "Perform all supported commands\n"
+ for m in module_names[1:]:
+ usage += " %s%s\n" % (m.ljust(15), modules[m].short_desc)
+
+ parser = OptionParser(usage=usage, version=portage.VERSION)
+ parser.add_option("-c", "--check", help="check for problems",
+ action="callback", callback=exclusive, callback_kwargs={"var":"action"})
+ parser.add_option("-f", "--fix", help="attempt to fix problems",
+ action="callback", callback=exclusive, callback_kwargs={"var":"action"})
+ parser.action = None
+
+
+ (options, args) = parser.parse_args(args=myargv)
+ if len(args) != 1:
+ parser.error("Incorrect number of arguments")
+ if args[0] not in module_names:
+ parser.error("%s target is not a known target" % args[0])
+
+ if parser.action:
+ action = parser.action
+ else:
+ print("Defaulting to --check")
+ action = "-c/--check"
+
+ if args[0] == "all":
+ tasks = modules.values()
+ else:
+ tasks = [modules[args[0]]]
+
+
+ if action == "-c/--check":
+ status = "Checking %s for problems"
+ func = "check"
+ else:
+ status = "Attempting to fix %s"
+ func = "fix"
+
+ isatty = os.environ.get('TERM') != 'dumb' and sys.stdout.isatty()
+ for task in tasks:
+ print(status % task.name())
+ inst = task()
+ onProgress = None
+ if isatty:
+ progressBar = portage.output.TermProgressBar()
+ progressHandler = ProgressHandler()
+ onProgress = progressHandler.onProgress
+ def display():
+ progressBar.set(progressHandler.curval, progressHandler.maxval)
+ progressHandler.display = display
+ def sigwinch_handler(signum, frame):
+ lines, progressBar.term_columns = \
+ portage.output.get_term_size()
+ signal.signal(signal.SIGWINCH, sigwinch_handler)
+ result = getattr(inst, func)(onProgress=onProgress)
+ if isatty:
+ # make sure the final progress is displayed
+ progressHandler.display()
+ print()
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
+ if result:
+ print()
+ print("\n".join(result))
+ print("\n")
+
+ print("Finished")
+
+if __name__ == "__main__":
+ emaint_main(sys.argv[1:])
diff --git a/portage_with_autodep/bin/emerge b/portage_with_autodep/bin/emerge
new file mode 100755
index 0000000..6f69244
--- /dev/null
+++ b/portage_with_autodep/bin/emerge
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+# Copyright 2006-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import signal
+import sys
+# This block ensures that ^C interrupts are handled quietly.
+try:
+
+ def exithandler(signum,frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ sys.exit(128 + signum)
+
+ signal.signal(signal.SIGINT, exithandler)
+ signal.signal(signal.SIGTERM, exithandler)
+ # Prevent "[Errno 32] Broken pipe" exceptions when
+ # writing to a pipe.
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+except KeyboardInterrupt:
+ sys.exit(128 + signal.SIGINT)
+
+def debug_signal(signum, frame):
+ import pdb
+ pdb.set_trace()
+signal.signal(signal.SIGUSR1, debug_signal)
+
+try:
+ from _emerge.main import emerge_main
+except ImportError:
+ from os import path as osp
+ import sys
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ from _emerge.main import emerge_main
+
+if __name__ == "__main__":
+ import sys
+ from portage.exception import ParseError, PermissionDenied
+ try:
+ retval = emerge_main()
+ except PermissionDenied as e:
+ sys.stderr.write("Permission denied: '%s'\n" % str(e))
+ sys.exit(e.errno)
+ except ParseError as e:
+ sys.stderr.write("%s\n" % str(e))
+ sys.exit(1)
+ except SystemExit:
+ raise
+ except Exception:
+ # If an unexpected exception occurs then we don't want the mod_echo
+ # output to obscure the traceback, so dump the mod_echo output before
+ # showing the traceback.
+ import traceback
+ tb_str = traceback.format_exc()
+ try:
+ from portage.elog import mod_echo
+ except ImportError:
+ pass
+ else:
+ mod_echo.finalize()
+ sys.stderr.write(tb_str)
+ sys.exit(1)
+ sys.exit(retval)
diff --git a/portage_with_autodep/bin/emerge-webrsync b/portage_with_autodep/bin/emerge-webrsync
new file mode 100755
index 0000000..d933871
--- /dev/null
+++ b/portage_with_autodep/bin/emerge-webrsync
@@ -0,0 +1,457 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
+# Rewritten from the old, Perl-based emerge-webrsync script
+# Author: Alon Bar-Lev <alon.barlev@gmail.com>
+# Major rewrite from Karl's scripts.
+
+# TODO:
+# - all output should prob be converted to e* funcs
+# - add support for ROOT
+
+#
+# gpg key import
+# KEY_ID=0x239C75C4
+# gpg --homedir /etc/portage/gnupg --keyserver subkeys.pgp.net --recv-keys $KEY_ID
+# gpg --homedir /etc/portage/gnupg --edit-key $KEY_ID trust
+#
+
+# Only echo if in verbose mode
+vvecho() { [[ ${do_verbose} -eq 1 ]] && echo "$@" ; }
+# Only echo if not in verbose mode
+nvecho() { [[ ${do_verbose} -eq 0 ]] && echo "$@" ; }
+# warning echos
+wecho() { echo "${argv0}: warning: $*" 1>&2 ; }
+# error echos
+eecho() { echo "${argv0}: error: $*" 1>&2 ; }
+
+argv0=$0
+if ! type -P portageq > /dev/null ; then
+ eecho "could not find 'portageq'; aborting"
+ exit 1
+fi
+eval $(portageq envvar -v FEATURES FETCHCOMMAND GENTOO_MIRRORS \
+ PORTAGE_BIN_PATH PORTAGE_GPG_DIR \
+ PORTAGE_NICENESS PORTAGE_RSYNC_EXTRA_OPTS PORTAGE_TMPDIR PORTDIR \
+ SYNC http_proxy ftp_proxy)
+DISTDIR="${PORTAGE_TMPDIR}/emerge-webrsync"
+export http_proxy ftp_proxy
+
+# If PORTAGE_NICENESS is overriden via the env then it will
+# still pass through the portageq call and override properly.
+if [ -n "${PORTAGE_NICENESS}" ]; then
+ renice $PORTAGE_NICENESS $$ > /dev/null
+fi
+
+source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
+
+do_verbose=0
+do_debug=0
+
+if has webrsync-gpg ${FEATURES} ; then
+ WEBSYNC_VERIFY_SIGNATURE=1
+else
+ WEBSYNC_VERIFY_SIGNATURE=0
+fi
+if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 -a -z "${PORTAGE_GPG_DIR}" ]; then
+ eecho "please set PORTAGE_GPG_DIR in make.conf"
+ exit 1
+fi
+
+do_tar() {
+ local file=$1; shift
+ local decompressor
+ case ${file} in
+ *.xz) decompressor="xzcat" ;;
+ *.bz2) decompressor="bzcat" ;;
+ *.gz) decompressor="zcat" ;;
+ *) decompressor="cat" ;;
+ esac
+ ${decompressor} "${file}" | tar "$@"
+ _pipestatus=${PIPESTATUS[*]}
+ [[ ${_pipestatus// /} -eq 0 ]]
+}
+
+get_utc_date_in_seconds() {
+ date -u +"%s"
+}
+
+get_date_part() {
+ local utc_time_in_secs="$1"
+ local part="$2"
+
+ if [[ ${USERLAND} == BSD ]] ; then
+ date -r ${utc_time_in_secs} -u +"${part}"
+ else
+ date -d @${utc_time_in_secs} -u +"${part}"
+ fi
+}
+
+get_utc_second_from_string() {
+ local s="$1"
+ if [[ ${USERLAND} == BSD ]] ; then
+ date -juf "%Y%m%d" "$s" +"%s"
+ else
+ date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s"
+ fi
+}
+
+get_portage_timestamp() {
+ local portage_current_timestamp=0
+
+ if [ -f "${PORTDIR}/metadata/timestamp.x" ]; then
+ portage_current_timestamp=$(cut -f 1 -d " " "${PORTDIR}/metadata/timestamp.x" )
+ fi
+
+ echo "${portage_current_timestamp}"
+}
+
+fetch_file() {
+ local URI="$1"
+ local FILE="$2"
+ local opts
+
+ if [ "${FETCHCOMMAND/wget/}" != "${FETCHCOMMAND}" ]; then
+ opts="--continue $(nvecho -q)"
+ elif [ "${FETCHCOMMAND/curl/}" != "${FETCHCOMMAND}" ]; then
+ opts="--continue-at - $(nvecho -s -f)"
+ else
+ rm -f "${FILE}"
+ fi
+
+ vecho "Fetching file ${FILE} ..."
+ # already set DISTDIR=
+ eval "${FETCHCOMMAND}" ${opts}
+ [ -s "${FILE}" ]
+}
+
+check_file_digest() {
+ local digest="$1"
+ local file="$2"
+ local r=1
+
+ vecho "Checking digest ..."
+
+ if type -P md5sum > /dev/null; then
+ md5sum -c $digest && r=0
+ elif type -P md5 > /dev/null; then
+ [ "$(md5 -q "${file}")" == "$(cut -d ' ' -f 1 "${digest}")" ] && r=0
+ else
+ eecho "cannot check digest: no suitable md5/md5sum binaries found"
+ fi
+
+ return "${r}"
+}
+
+check_file_signature() {
+ local signature="$1"
+ local file="$2"
+ local r=1
+
+ if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 ]; then
+
+ vecho "Checking signature ..."
+
+ if type -P gpg > /dev/null; then
+ gpg --homedir "${PORTAGE_GPG_DIR}" --verify "$signature" "$file" && r=0
+ else
+ eecho "cannot check signature: gpg binary not found"
+ fi
+ else
+ r=0
+ fi
+
+ return "${r}"
+}
+
+get_snapshot_timestamp() {
+ local file="$1"
+
+ do_tar "${file}" --to-stdout -xf - portage/metadata/timestamp.x | cut -f 1 -d " "
+}
+
+sync_local() {
+ local file="$1"
+
+ vecho "Syncing local tree ..."
+
+ if type -P tarsync > /dev/null ; then
+ local chown_opts="-o portage -g portage"
+ chown portage:portage portage > /dev/null 2>&1 || chown_opts=""
+ if ! tarsync $(vvecho -v) -s 1 ${chown_opts} \
+ -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then
+ eecho "tarsync failed; tarball is corrupt? (${file})"
+ return 1
+ fi
+ else
+ if ! do_tar "${file}" xf -; then
+ eecho "tar failed to extract the image. tarball is corrupt? (${file})"
+ rm -fr portage
+ return 1
+ fi
+
+ # Free disk space
+ rm -f "${file}"
+
+ chown portage:portage portage > /dev/null 2>&1 && \
+ chown -R portage:portage portage
+ cd portage
+ rsync -av --progress --stats --delete --delete-after \
+ --exclude='/distfiles' --exclude='/packages' \
+ --exclude='/local' ${PORTAGE_RSYNC_EXTRA_OPTS} . "${PORTDIR%%/}"
+ cd ..
+
+ vecho "Cleaning up ..."
+ rm -fr portage
+ fi
+
+ if has metadata-transfer ${FEATURES} ; then
+ vecho "Updating cache ..."
+ emerge --metadata
+ fi
+ [ -x /etc/portage/bin/post_sync ] && /etc/portage/bin/post_sync
+ return 0
+}
+
+do_snapshot() {
+ local ignore_timestamp="$1"
+ local date="$2"
+
+ local r=1
+
+ local base_file="portage-${date}.tar"
+
+ local have_files=0
+ local mirror
+
+ local compressions=""
+ # xz is not supported in app-arch/tarsync, so use
+ # bz2 format if we have tarsync.
+ if ! type -P tarsync > /dev/null ; then
+ type -P xzcat > /dev/null && compressions="${compressions} xz"
+ fi
+ type -P bzcat > /dev/null && compressions="${compressions} bz2"
+ type -P zcat > /dev/null && compressions="${compressions} gz"
+ if [[ -z ${compressions} ]] ; then
+ eecho "unable to locate any decompressors (xzcat or bzcat or zcat)"
+ exit 1
+ fi
+
+ for mirror in ${GENTOO_MIRRORS} ; do
+
+ vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
+
+ for compression in ${compressions} ; do
+ local file="portage-${date}.tar.${compression}"
+ local digest="${file}.md5sum"
+ local signature="${file}.gpgsig"
+
+ if [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] ; then
+ check_file_digest "${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \
+ check_file_signature "${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \
+ have_files=1
+ fi
+
+ if [ ${have_files} -eq 0 ] ; then
+ fetch_file "${mirror}/snapshots/${digest}" "${digest}" && \
+ fetch_file "${mirror}/snapshots/${signature}" "${signature}" && \
+ fetch_file "${mirror}/snapshots/${file}" "${file}" && \
+ check_file_digest "${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \
+ check_file_signature "${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \
+ have_files=1
+ fi
+
+ #
+ # If timestamp is invalid
+ # we want to try and retrieve
+ # from a different mirror
+ #
+ if [ ${have_files} -eq 1 ]; then
+
+ vecho "Getting snapshot timestamp ..."
+ local snapshot_timestamp=$(get_snapshot_timestamp "${file}")
+
+ if [ ${ignore_timestamp} == 0 ]; then
+ if [ ${snapshot_timestamp} -lt $(get_portage_timestamp) ]; then
+ wecho "portage is newer than snapshot"
+ have_files=0
+ fi
+ else
+ local utc_seconds=$(get_utc_second_from_string "${date}")
+
+ #
+ # Check that this snapshot
+ # is what it claims to be ...
+ #
+ if [ ${snapshot_timestamp} -lt ${utc_seconds} ] || \
+ [ ${snapshot_timestamp} -gt $((${utc_seconds}+ 2*86400)) ]; then
+
+ wecho "snapshot timestamp is not in acceptable period"
+ have_files=0
+ fi
+ fi
+ fi
+
+ if [ ${have_files} -eq 1 ]; then
+ break
+ else
+ #
+ # Remove files and use a different mirror
+ #
+ rm -f "${file}" "${digest}" "${signature}"
+ fi
+ done
+
+ [ ${have_files} -eq 1 ] && break
+ done
+
+ if [ ${have_files} -eq 1 ]; then
+ sync_local "${file}" && r=0
+ else
+ vecho "${date} snapshot was not found"
+ fi
+
+ rm -f "${file}" "${digest}" "${signature}"
+ return "${r}"
+}
+
+do_latest_snapshot() {
+ local attempts=0
+ local r=1
+
+ vecho "Fetching most recent snapshot ..."
+
+ # The snapshot for a given day is generated at 01:45 UTC on the following
+ # day, so the current day's snapshot (going by UTC time) hasn't been
+ # generated yet. Therefore, always start by looking for the previous day's
+ # snapshot (for attempts=1, subtract 1 day from the current UTC time).
+
+ # Timestamps that differ by less than 2 hours
+ # are considered to be approximately equal.
+ local min_time_diff=$(( 2 * 60 * 60 ))
+
+ local existing_timestamp=$(get_portage_timestamp)
+ local timestamp_difference
+ local timestamp_problem
+ local approx_snapshot_time
+ local start_time=$(get_utc_date_in_seconds)
+ local start_hour=$(get_date_part ${start_time} "%H")
+
+ # Daily snapshots are created at 1:45 AM and are not
+ # available until after 2 AM. Don't waste time trying
+ # to fetch a snapshot before it's been created.
+ if [ ${start_hour} -lt 2 ] ; then
+ (( start_time -= 86400 ))
+ fi
+ local snapshot_date=$(get_date_part ${start_time} "%Y%m%d")
+ local snapshot_date_seconds=$(get_utc_second_from_string ${snapshot_date})
+
+ while (( ${attempts} < 40 )) ; do
+ (( attempts++ ))
+ (( snapshot_date_seconds -= 86400 ))
+ # snapshots are created at 1:45 AM
+ (( approx_snapshot_time = snapshot_date_seconds + 86400 + 6300 ))
+ (( timestamp_difference = existing_timestamp - approx_snapshot_time ))
+ [ ${timestamp_difference} -lt 0 ] && (( timestamp_difference = -1 * timestamp_difference ))
+ snapshot_date=$(get_date_part ${snapshot_date_seconds} "%Y%m%d")
+
+ timestamp_problem=""
+ if [ ${timestamp_difference} -eq 0 ]; then
+ timestamp_problem="is identical to"
+ elif [ ${timestamp_difference} -lt ${min_time_diff} ]; then
+ timestamp_problem="is possibly identical to"
+ elif [ ${approx_snapshot_time} -lt ${existing_timestamp} ] ; then
+ timestamp_problem="is newer than"
+ fi
+
+ if [ -n "${timestamp_problem}" ]; then
+ ewarn "Latest snapshot date: ${snapshot_date}"
+ ewarn
+ ewarn "Approximate snapshot timestamp: ${approx_snapshot_time}"
+ ewarn " Current local timestamp: ${existing_timestamp}"
+ ewarn
+ echo -e "The current local timestamp" \
+ "${timestamp_problem} the" \
+ "timestamp of the latest" \
+ "snapshot. In order to force sync," \
+ "use the --revert option or remove" \
+ "the timestamp file located at" \
+ "'${PORTDIR}/metadata/timestamp.x'." | fmt -w 70 | \
+ while read -r line ; do
+ ewarn "${line}"
+ done
+ r=0
+ break
+ fi
+
+ if do_snapshot 0 "${snapshot_date}"; then
+ r=0
+ break;
+ fi
+ done
+
+ return "${r}"
+}
+
+usage() {
+ cat <<-EOF
+ Usage: $0 [options]
+
+ Options:
+ --revert=yyyymmdd Revert to snapshot
+ -q, --quiet Only output errors
+ -v, --verbose Enable verbose output
+ -x, --debug Enable debug output
+ -h, --help This help screen (duh!)
+ EOF
+ if [[ -n $* ]] ; then
+ printf "\nError: %s\n" "$*" 1>&2
+ exit 1
+ else
+ exit 0
+ fi
+}
+
+main() {
+ local arg
+ local revert_date
+
+ [ ! -d "${DISTDIR}" ] && mkdir -p "${DISTDIR}"
+ cd "${DISTDIR}"
+
+ for arg in "$@" ; do
+ local v=${arg#*=}
+ case ${arg} in
+ -h|--help) usage ;;
+ -q|--quiet) PORTAGE_QUIET=1 ;;
+ -v|--verbose) do_verbose=1 ;;
+ -x|--debug) do_debug=1 ;;
+ --revert=*) revert_date=${v} ;;
+ *) usage "Invalid option '${arg}'" ;;
+ esac
+ done
+
+ # This is a sanity check to help prevent people like funtoo users
+ # from accidentally wiping out their git tree.
+ if [[ -n $SYNC && ${SYNC#rsync:} = $SYNC ]] ; then
+ echo "The current SYNC variable setting does not refer to an rsync URI:" >&2
+ echo >&2
+ echo " SYNC=$SYNC" >&2
+ echo >&2
+ echo "If you intend to use emerge-webrsync then please" >&2
+ echo "adjust SYNC to refer to an rsync URI." >&2
+ echo "emerge-webrsync exiting due to abnormal SYNC setting." >&2
+ exit 1
+ fi
+
+ [[ ${do_debug} -eq 1 ]] && set -x
+
+ if [[ -n ${revert_date} ]] ; then
+ do_snapshot 1 "${revert_date}"
+ else
+ do_latest_snapshot
+ fi
+}
+
+main "$@"
diff --git a/portage_with_autodep/bin/env-update b/portage_with_autodep/bin/env-update
new file mode 100755
index 0000000..8a69f2b
--- /dev/null
+++ b/portage_with_autodep/bin/env-update
@@ -0,0 +1,41 @@
+#!/usr/bin/python -O
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import errno
+import sys
+
+def usage(status):
+ print("Usage: env-update [--no-ldconfig]")
+ print("")
+ print("See the env-update(1) man page for more info")
+ sys.exit(status)
+
+if "-h" in sys.argv or "--help" in sys.argv:
+ usage(0)
+
+makelinks=1
+if "--no-ldconfig" in sys.argv:
+ makelinks=0
+ sys.argv.pop(sys.argv.index("--no-ldconfig"))
+
+if len(sys.argv) > 1:
+ print("!!! Invalid command line options!\n")
+ usage(1)
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+try:
+ portage.env_update(makelinks)
+except IOError as e:
+ if e.errno == errno.EACCES:
+ print("env-update: Need superuser access")
+ sys.exit(1)
+ else:
+ raise
diff --git a/portage_with_autodep/bin/etc-update b/portage_with_autodep/bin/etc-update
new file mode 100755
index 0000000..42518ad
--- /dev/null
+++ b/portage_with_autodep/bin/etc-update
@@ -0,0 +1,616 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# Author Brandon Low <lostlogic@gentoo.org>
+#
+# Previous version (from which I've borrowed a few bits) by:
+# Jochem Kossen <j.kossen@home.nl>
+# Leo Lipelis <aeoo@gentoo.org>
+# Karl Trygve Kalleberg <karltk@gentoo.org>
+
+cd /
+
+if type -P gsed >/dev/null ; then
+ sed() { gsed "$@"; }
+fi
+
+get_config() {
+ # the sed here does:
+ # - strip off comments
+ # - match lines that set item in question
+ # - delete the "item =" part
+ # - store the actual value into the hold space
+ # - on the last line, restore the hold space and print it
+ # If there's more than one of the same configuration item, then
+ # the store to the hold space clobbers previous value so the last
+ # setting takes precedence.
+ local item=$1
+ eval echo $(sed -n \
+ -e 's:[[:space:]]*#.*$::' \
+ -e "/^[[:space:]]*$item[[:space:]]*=/{s:[^=]*=[[:space:]]*\([\"']\{0,1\}\)\(.*\)\1:\2:;h}" \
+ -e '${g;p}' \
+ "${PORTAGE_CONFIGROOT}"etc/etc-update.conf)
+}
+
+diff_command() {
+ local cmd=${diff_command//%file1/$1}
+ ${cmd//%file2/$2}
+}
+
+scan() {
+ echo "Scanning Configuration files..."
+ rm -rf ${TMP}/files > /dev/null 2>&1
+ mkdir ${TMP}/files || die "Failed mkdir command!" 1
+ count=0
+ input=0
+ local find_opts
+ local my_basename
+
+ for path in ${CONFIG_PROTECT} ; do
+ path="${ROOT}${path}"
+ # Do not traverse hidden directories such as .svn or .git.
+ find_opts="-name .* -type d -prune -o -name ._cfg????_*"
+ if [ ! -d "${path}" ]; then
+ [ ! -f "${path}" ] && continue
+ my_basename="${path##*/}"
+ path="${path%/*}"
+ find_opts="-maxdepth 1 -name ._cfg????_${my_basename}"
+ fi
+
+ ofile=""
+ # The below set -f turns off file name globbing in the ${find_opts} expansion.
+ for file in $(set -f ; find ${path}/ ${find_opts} \
+ ! -name '.*~' ! -iname '.*.bak' -print |
+ sed -e "s:\(^.*/\)\(\._cfg[0-9]*_\)\(.*$\):\1\2\3\%\1%\2\%\3:" |
+ sort -t'%' -k2,2 -k4,4 -k3,3 | LANG=POSIX LC_ALL=POSIX cut -f1 -d'%'); do
+
+ rpath=$(echo "${file/\/\///}" | sed -e "s:/[^/]*$::")
+ rfile=$(echo "${file/\/\///}" | sed -e "s:^.*/::")
+ for mpath in ${CONFIG_PROTECT_MASK}; do
+ mpath="${ROOT}${mpath}"
+ mpath=$(echo "${mpath/\/\///}")
+ if [[ "${rpath}" == "${mpath}"* ]]; then
+ mv ${rpath}/${rfile} ${rpath}/${rfile:10}
+ break
+ fi
+ done
+ if [[ ! -f ${file} ]] ; then
+ echo "Skipping non-file ${file} ..."
+ continue
+ fi
+
+ if [[ "${ofile:10}" != "${rfile:10}" ]] ||
+ [[ ${opath} != ${rpath} ]]; then
+ MATCHES=0
+ if [[ "${EU_AUTOMERGE}" == "yes" ]]; then
+ if [ ! -e "${rpath}/${rfile}" ] || [ ! -e "${rpath}/${rfile:10}" ]; then
+ MATCHES=0
+ else
+ diff -Bbua ${rpath}/${rfile} ${rpath}/${rfile:10} | egrep '^[+-]' | egrep -v '^[+-][\t ]*#|^--- |^\+\+\+ ' | egrep -qv '^[-+][\t ]*$'
+ MATCHES=$?
+ fi
+ elif [[ -z $(diff -Nua ${rpath}/${rfile} ${rpath}/${rfile:10}|
+ grep "^[+-][^+-]"|grep -v '# .Header:.*') ]]; then
+ MATCHES=1
+ fi
+ if [[ "${MATCHES}" == "1" ]]; then
+ echo "Automerging trivial changes in: ${rpath}/${rfile:10}"
+ mv ${rpath}/${rfile} ${rpath}/${rfile:10}
+ continue
+ else
+ count=${count}+1
+ echo "${rpath}/${rfile:10}" > ${TMP}/files/${count}
+ echo "${rpath}/${rfile}" >> ${TMP}/files/${count}
+ ofile="${rfile}"
+ opath="${rpath}"
+ continue
+ fi
+ fi
+
+ if [[ -z $(diff -Nua ${rpath}/${rfile} ${rpath}/${ofile}|
+ grep "^[+-][^+-]"|grep -v '# .Header:.*') ]]; then
+ mv ${rpath}/${rfile} ${rpath}/${ofile}
+ continue
+ else
+ echo "${rpath}/${rfile}" >> ${TMP}/files/${count}
+ ofile="${rfile}"
+ opath="${rpath}"
+ fi
+ done
+ done
+
+}
+
+sel_file() {
+ local -i isfirst=0
+ until [[ -f ${TMP}/files/${input} ]] || \
+ [[ ${input} == -1 ]] || \
+ [[ ${input} == -3 ]]
+ do
+ local numfiles=$(ls ${TMP}/files|wc -l)
+ local numwidth=${#numfiles}
+ for file in $(ls ${TMP}/files|sort -n); do
+ if [[ ${isfirst} == 0 ]] ; then
+ isfirst=${file}
+ fi
+ numshow=$(printf "%${numwidth}i${PAR} " ${file})
+ numupdates=$(( $(wc -l <${TMP}/files/${file}) - 1 ))
+ echo -n "${numshow}"
+ if [[ ${mode} == 0 ]] ; then
+ echo "$(head -n1 ${TMP}/files/${file}) (${numupdates})"
+ else
+ head -n1 ${TMP}/files/${file}
+ fi
+ done > ${TMP}/menuitems
+
+ if [ "${OVERWRITE_ALL}" == "yes" ]; then
+ input=0
+ elif [ "${DELETE_ALL}" == "yes" ]; then
+ input=0
+ else
+ [[ $CLEAR_TERM == yes ]] && clear
+ if [[ ${mode} == 0 ]] ; then
+ echo "The following is the list of files which need updating, each
+configuration file is followed by a list of possible replacement files."
+ else
+ local my_title="Please select a file to update"
+ fi
+
+ if [[ ${mode} == 0 ]] ; then
+ cat ${TMP}/menuitems
+ echo "Please select a file to edit by entering the corresponding number."
+ echo " (don't use -3, -5, -7 or -9 if you're unsure what to do)"
+ echo " (-1 to exit) (-3 to auto merge all remaining files)"
+ echo " (-5 to auto-merge AND not use 'mv -i')"
+ echo " (-7 to discard all updates)"
+ echo -n " (-9 to discard all updates AND not use 'rm -i'): "
+ input=$(read_int)
+ else
+ dialog --title "${title}" --menu "${my_title}" \
+ 0 0 0 $(echo -e "-1 Exit\n$(<${TMP}/menuitems)") \
+ 2> ${TMP}/input || die "User termination!" 0
+ input=$(<${TMP}/input)
+ fi
+ if [[ ${input} == -9 ]]; then
+ read -p "Are you sure that you want to delete all updates (type YES):" reply
+ if [[ ${reply} != "YES" ]]; then
+ continue
+ else
+ input=-7
+ export rm_opts=""
+ fi
+ fi
+ if [[ ${input} == -7 ]]; then
+ input=0
+ export DELETE_ALL="yes"
+ fi
+ if [[ ${input} == -5 ]] ; then
+ input=-3
+ export mv_opts=" ${mv_opts} "
+ mv_opts="${mv_opts// -i / }"
+ fi
+ if [[ ${input} == -3 ]] ; then
+ input=0
+ export OVERWRITE_ALL="yes"
+ fi
+ fi # -3 automerge
+ if [[ -z ${input} ]] || [[ ${input} == 0 ]] ; then
+ input=${isfirst}
+ fi
+ done
+}
+
+user_special() {
+ if [ -r ${PORTAGE_CONFIGROOT}etc/etc-update.special ]; then
+ if [ -z "$1" ]; then
+ echo "ERROR: user_special() called without arguments"
+ return 1
+ fi
+ while read -r pat; do
+ echo ${1} | grep "${pat}" > /dev/null && return 0
+ done < ${PORTAGE_CONFIGROOT}etc/etc-update.special
+ fi
+ return 1
+}
+
+read_int() {
+ # Read an integer from stdin. Continously loops until a valid integer is
+ # read. This is a workaround for odd behavior of bash when an attempt is
+ # made to store a value such as "1y" into an integer-only variable.
+ local my_input
+ while true; do
+ read my_input
+ # failed integer conversions will break a loop unless they're enclosed
+ # in a subshell.
+ echo "${my_input}" | ( declare -i x; read x) 2>/dev/null && break
+ echo -n "Value '$my_input' is not valid. Please enter an integer value:" >&2
+ done
+ echo ${my_input}
+}
+
+do_file() {
+ interactive_echo() { [ "${OVERWRITE_ALL}" != "yes" ] && [ "${DELETE_ALL}" != "yes" ] && echo; }
+ interactive_echo
+ local -i my_input
+ local -i fcount=0
+ until (( $(wc -l < ${TMP}/files/${input}) < 2 )); do
+ my_input=0
+ if (( $(wc -l < ${TMP}/files/${input}) == 2 )); then
+ my_input=1
+ fi
+ until (( ${my_input} > 0 )) && (( ${my_input} < $(wc -l < ${TMP}/files/${input}) )); do
+ fcount=0
+
+ if [ "${OVERWRITE_ALL}" == "yes" ]; then
+ my_input=0
+ elif [ "${DELETE_ALL}" == "yes" ]; then
+ my_input=0
+ else
+ for line in $(<${TMP}/files/${input}); do
+ if (( ${fcount} > 0 )); then
+ echo -n "${fcount}${PAR} "
+ echo "${line}"
+ else
+ if [[ ${mode} == 0 ]] ; then
+ echo "Below are the new config files for ${line}:"
+ else
+ local my_title="Please select a file to process for ${line}"
+ fi
+ fi
+ fcount=${fcount}+1
+ done > ${TMP}/menuitems
+
+ if [[ ${mode} == 0 ]] ; then
+ cat ${TMP}/menuitems
+ echo -n "Please select a file to process (-1 to exit this file): "
+ my_input=$(read_int)
+ else
+ dialog --title "${title}" --menu "${my_title}" \
+ 0 0 0 $(echo -e "$(<${TMP}/menuitems)\n${fcount} Exit") \
+ 2> ${TMP}/input || die "User termination!" 0
+ my_input=$(<${TMP}/input)
+ fi
+ fi # OVERWRITE_ALL
+
+ if [[ ${my_input} == 0 ]] ; then
+ my_input=1
+ elif [[ ${my_input} == -1 ]] ; then
+ input=0
+ return
+ elif [[ ${my_input} == ${fcount} ]] ; then
+ break
+ fi
+ done
+ if [[ ${my_input} == ${fcount} ]] ; then
+ break
+ fi
+
+ fcount=${my_input}+1
+
+ file=$(sed -e "${fcount}p;d" ${TMP}/files/${input})
+ ofile=$(head -n1 ${TMP}/files/${input})
+
+ do_cfg "${file}" "${ofile}"
+
+ sed -e "${fcount}!p;d" ${TMP}/files/${input} > ${TMP}/files/sed
+ mv ${TMP}/files/sed ${TMP}/files/${input}
+
+ if [[ ${my_input} == -1 ]] ; then
+ break
+ fi
+ done
+ interactive_echo
+ rm ${TMP}/files/${input}
+ count=${count}-1
+}
+
+do_cfg() {
+
+ local file="${1}"
+ local ofile="${2}"
+ local -i my_input=0
+
+ until (( ${my_input} == -1 )) || [ ! -f ${file} ]; do
+ if [[ "${OVERWRITE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then
+ my_input=1
+ elif [[ "${DELETE_ALL}" == "yes" ]] && ! user_special "${ofile}"; then
+ my_input=2
+ else
+ [[ $CLEAR_TERM == yes ]] && clear
+ if [ "${using_editor}" == 0 ]; then
+ (
+ echo "Showing differences between ${ofile} and ${file}"
+ diff_command "${ofile}" "${file}"
+ ) | ${pager}
+ else
+ echo "Beginning of differences between ${ofile} and ${file}"
+ diff_command "${ofile}" "${file}"
+ echo "End of differences between ${ofile} and ${file}"
+ fi
+ if [ -L "${file}" ]; then
+ echo
+ echo "-------------------------------------------------------------"
+ echo "NOTE: File is a symlink to another file. REPLACE recommended."
+ echo " The original file may simply have moved. Please review."
+ echo "-------------------------------------------------------------"
+ echo
+ fi
+ echo -n "File: ${file}
+1) Replace original with update
+2) Delete update, keeping original as is
+3) Interactively merge original with update
+4) Show differences again
+5) Save update as example config
+Please select from the menu above (-1 to ignore this update): "
+ my_input=$(read_int)
+ fi
+
+ case ${my_input} in
+ 1) echo "Replacing ${ofile} with ${file}"
+ mv ${mv_opts} ${file} ${ofile}
+ [ -n "${OVERWRITE_ALL}" ] && my_input=-1
+ continue
+ ;;
+ 2) echo "Deleting ${file}"
+ rm ${rm_opts} ${file}
+ [ -n "${DELETE_ALL}" ] && my_input=-1
+ continue
+ ;;
+ 3) do_merge "${file}" "${ofile}"
+ my_input=${?}
+# [ ${my_input} == 255 ] && my_input=-1
+ continue
+ ;;
+ 4) continue
+ ;;
+ 5) do_distconf "${file}" "${ofile}"
+ ;;
+ *) continue
+ ;;
+ esac
+ done
+}
+
+do_merge() {
+ # make sure we keep the merged file in the secure tempdir
+ # so we dont leak any information contained in said file
+ # (think of case where the file has 0600 perms; during the
+ # merging process, the temp file gets umask perms!)
+
+ local file="${1}"
+ local ofile="${2}"
+ local mfile="${TMP}/${2}.merged"
+ local -i my_input=0
+ echo "${file} ${ofile} ${mfile}"
+
+ if [[ -e ${mfile} ]] ; then
+ echo "A previous version of the merged file exists, cleaning..."
+ rm ${rm_opts} "${mfile}"
+ fi
+
+ # since mfile will be like $TMP/path/to/original-file.merged, we
+ # need to make sure the full /path/to/ exists ahead of time
+ mkdir -p "${mfile%/*}"
+
+ until (( ${my_input} == -1 )); do
+ echo "Merging ${file} and ${ofile}"
+ $(echo "${merge_command}" |
+ sed -e "s:%merged:${mfile}:g" \
+ -e "s:%orig:${ofile}:g" \
+ -e "s:%new:${file}:g")
+ until (( ${my_input} == -1 )); do
+ echo -n "1) Replace ${ofile} with merged file
+2) Show differences between merged file and original
+3) Remerge original with update
+4) Edit merged file
+5) Return to the previous menu
+Please select from the menu above (-1 to exit, losing this merge): "
+ my_input=$(read_int)
+ case ${my_input} in
+ 1) echo "Replacing ${ofile} with ${mfile}"
+ if [[ ${USERLAND} == BSD ]] ; then
+ chown "$(stat -f %Su:%Sg "${ofile}")" "${mfile}"
+ chmod $(stat -f %Mp%Lp "${ofile}") "${mfile}"
+ else
+ chown --reference="${ofile}" "${mfile}"
+ chmod --reference="${ofile}" "${mfile}"
+ fi
+ mv ${mv_opts} "${mfile}" "${ofile}"
+ rm ${rm_opts} "${file}"
+ return 255
+ ;;
+ 2)
+ [[ $CLEAR_TERM == yes ]] && clear
+ if [ "${using_editor}" == 0 ]; then
+ (
+ echo "Showing differences between ${ofile} and ${mfile}"
+ diff_command "${ofile}" "${mfile}"
+ ) | ${pager}
+ else
+ echo "Beginning of differences between ${ofile} and ${mfile}"
+ diff_command "${ofile}" "${mfile}"
+ echo "End of differences between ${ofile} and ${mfile}"
+ fi
+ continue
+ ;;
+ 3) break
+ ;;
+ 4) ${EDITOR:-nano -w} "${mfile}"
+ continue
+ ;;
+ 5) rm ${rm_opts} "${mfile}"
+ return 0
+ ;;
+ *) continue
+ ;;
+ esac
+ done
+ done
+ rm ${rm_opts} "${mfile}"
+ return 255
+}
+
+do_distconf() {
+ # search for any previously saved distribution config
+ # files and number the current one accordingly
+
+ local file="${1}"
+ local ofile="${2}"
+ local -i count
+ local -i fill
+ local suffix
+ local efile
+
+ for ((count = 0; count <= 9999; count++)); do
+ suffix=".dist_"
+ for ((fill = 4 - ${#count}; fill > 0; fill--)); do
+ suffix+="0"
+ done
+ suffix+="${count}"
+ efile="${ofile}${suffix}"
+ if [[ ! -f ${efile} ]]; then
+ mv ${mv_opts} "${file}" "${efile}"
+ break
+ elif diff_command "${file}" "${efile}" &> /dev/null; then
+ # replace identical copy
+ mv "${file}" "${efile}"
+ break
+ fi
+ done
+}
+
+die() {
+ trap SIGTERM
+ trap SIGINT
+
+ if [ "$2" -eq 0 ]; then
+ echo "Exiting: ${1}"
+ scan > /dev/null
+ [ ${count} -gt 0 ] && echo "NOTE: ${count} updates remaining"
+ else
+ echo "ERROR: ${1}"
+ fi
+
+ rm -rf "${TMP}"
+ exit ${2}
+}
+
+usage() {
+ cat <<-EOF
+ etc-update: Handle configuration file updates
+
+ Usage: etc-update [options]
+
+ Options:
+ -d, --debug Enable shell debugging
+ -h, --help Show help and run away
+ -V, --version Show version and trundle away
+ EOF
+
+ [[ -n ${*:2} ]] && printf "\nError: %s\n" "${*:2}" 1>&2
+
+ exit ${1:-0}
+}
+
+#
+# Run the script
+#
+
+SET_X=false
+while [[ -n $1 ]] ; do
+ case $1 in
+ -d|--debug) SET_X=true;;
+ -h|--help) usage;;
+ -V|--version) emerge --version ; exit 0;;
+ *) usage 1 "Invalid option '$1'";;
+ esac
+ shift
+done
+${SET_X} && set -x
+
+type portageq > /dev/null || exit $?
+eval $(portageq envvar -v CONFIG_PROTECT \
+ CONFIG_PROTECT_MASK PORTAGE_CONFIGROOT PORTAGE_TMPDIR ROOT USERLAND)
+export PORTAGE_TMPDIR
+
+TMP="${PORTAGE_TMPDIR}/etc-update-$$"
+trap "die terminated 1" SIGTERM
+trap "die interrupted 1" SIGINT
+
+[ -w ${PORTAGE_CONFIGROOT}etc ] || die "Need write access to ${PORTAGE_CONFIGROOT}etc" 1
+#echo $PORTAGE_TMPDIR
+#echo $CONFIG_PROTECT
+#echo $CONFIG_PROTECT_MASK
+#export PORTAGE_TMPDIR=$(/usr/lib/portage/bin/portageq envvar PORTAGE_TMPDIR)
+
+rm -rf "${TMP}" 2> /dev/null
+mkdir "${TMP}" || die "failed to create temp dir" 1
+# make sure we have a secure directory to work in
+chmod 0700 "${TMP}" || die "failed to set perms on temp dir" 1
+chown ${UID:-0}:${GID:-0} "${TMP}" || die "failed to set ownership on temp dir" 1
+
+# I need the CONFIG_PROTECT value
+#CONFIG_PROTECT=$(/usr/lib/portage/bin/portageq envvar CONFIG_PROTECT)
+#CONFIG_PROTECT_MASK=$(/usr/lib/portage/bin/portageq envvar CONFIG_PROTECT_MASK)
+
+# load etc-config's configuration
+CLEAR_TERM=$(get_config clear_term)
+EU_AUTOMERGE=$(get_config eu_automerge)
+rm_opts=$(get_config rm_opts)
+mv_opts=$(get_config mv_opts)
+cp_opts=$(get_config cp_opts)
+pager=$(get_config pager)
+diff_command=$(get_config diff_command)
+using_editor=$(get_config using_editor)
+merge_command=$(get_config merge_command)
+declare -i mode=$(get_config mode)
+[[ -z ${mode} ]] && mode=0
+[[ -z ${pager} ]] && pager="cat"
+
+if [ "${using_editor}" == 0 ]; then
+ # Sanity check to make sure diff exists and works
+ echo > "${TMP}"/.diff-test-1
+ echo > "${TMP}"/.diff-test-2
+
+ if ! diff_command "${TMP}"/.diff-test-1 "${TMP}"/.diff-test-2 ; then
+ die "'${diff_command}' does not seem to work, aborting" 1
+ fi
+else
+ if ! type ${diff_command%% *} >/dev/null; then
+ die "'${diff_command}' does not seem to work, aborting" 1
+ fi
+fi
+
+if [[ ${mode} == "1" ]] ; then
+ if ! type dialog >/dev/null || ! dialog --help >/dev/null ; then
+ die "mode=1 and 'dialog' not found or not executable, aborting" 1
+ fi
+fi
+
+#echo "rm_opts: $rm_opts, mv_opts: $mv_opts, cp_opts: $cp_opts"
+#echo "pager: $pager, diff_command: $diff_command, merge_command: $merge_command"
+
+if (( ${mode} == 0 )); then
+ PAR=")"
+else
+ PAR=""
+fi
+
+declare -i count=0
+declare input=0
+declare title="Gentoo's etc-update tool!"
+
+scan
+
+until (( ${input} == -1 )); do
+ if (( ${count} == 0 )); then
+ die "Nothing left to do; exiting. :)" 0
+ fi
+ sel_file
+ if (( ${input} != -1 )); then
+ do_file
+ fi
+done
+
+die "User termination!" 0
diff --git a/portage_with_autodep/bin/filter-bash-environment.py b/portage_with_autodep/bin/filter-bash-environment.py
new file mode 100755
index 0000000..b9aec96
--- /dev/null
+++ b/portage_with_autodep/bin/filter-bash-environment.py
@@ -0,0 +1,150 @@
+#!/usr/bin/python
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import codecs
+import io
+import optparse
+import os
+import re
+import sys
+
+here_doc_re = re.compile(r'.*\s<<[-]?(\w+)$')
+func_start_re = re.compile(r'^[-\w]+\s*\(\)\s*$')
+func_end_re = re.compile(r'^\}$')
+
+var_assign_re = re.compile(r'(^|^declare\s+-\S+\s+|^declare\s+|^export\s+)([^=\s]+)=("|\')?.*$')
+close_quote_re = re.compile(r'(\\"|"|\')\s*$')
+readonly_re = re.compile(r'^declare\s+-(\S*)r(\S*)\s+')
+# declare without assignment
+var_declare_re = re.compile(r'^declare(\s+-\S+)?\s+([^=\s]+)\s*$')
+
+def have_end_quote(quote, line):
+ """
+ Check if the line has an end quote (useful for handling multi-line
+ quotes). This handles escaped double quotes that may occur at the
+ end of a line. The posix spec does not allow escaping of single
+ quotes inside of single quotes, so that case is not handled.
+ """
+ close_quote_match = close_quote_re.search(line)
+ return close_quote_match is not None and \
+ close_quote_match.group(1) == quote
+
+def filter_declare_readonly_opt(line):
+ readonly_match = readonly_re.match(line)
+ if readonly_match is not None:
+ declare_opts = ''
+ for i in (1, 2):
+ group = readonly_match.group(i)
+ if group is not None:
+ declare_opts += group
+ if declare_opts:
+ line = 'declare -%s %s' % \
+ (declare_opts, line[readonly_match.end():])
+ else:
+ line = 'declare ' + line[readonly_match.end():]
+ return line
+
+def filter_bash_environment(pattern, file_in, file_out):
+ # Filter out any instances of the \1 character from variable values
+ # since this character multiplies each time that the environment
+ # is saved (strange bash behavior). This can eventually result in
+ # mysterious 'Argument list too long' errors from programs that have
+ # huge strings of \1 characters in their environment. See bug #222091.
+ here_doc_delim = None
+ in_func = None
+ multi_line_quote = None
+ multi_line_quote_filter = None
+ for line in file_in:
+ if multi_line_quote is not None:
+ if not multi_line_quote_filter:
+ file_out.write(line.replace("\1", ""))
+ if have_end_quote(multi_line_quote, line):
+ multi_line_quote = None
+ multi_line_quote_filter = None
+ continue
+ if here_doc_delim is None and in_func is None:
+ var_assign_match = var_assign_re.match(line)
+ if var_assign_match is not None:
+ quote = var_assign_match.group(3)
+ filter_this = pattern.match(var_assign_match.group(2)) \
+ is not None
+ # Exclude the start quote when searching for the end quote,
+ # to ensure that the start quote is not misidentified as the
+ # end quote (happens if there is a newline immediately after
+ # the start quote).
+ if quote is not None and not \
+ have_end_quote(quote, line[var_assign_match.end(2)+2:]):
+ multi_line_quote = quote
+ multi_line_quote_filter = filter_this
+ if not filter_this:
+ line = filter_declare_readonly_opt(line)
+ file_out.write(line.replace("\1", ""))
+ continue
+ else:
+ declare_match = var_declare_re.match(line)
+ if declare_match is not None:
+ # declare without assignment
+ filter_this = pattern.match(declare_match.group(2)) \
+ is not None
+ if not filter_this:
+ line = filter_declare_readonly_opt(line)
+ file_out.write(line)
+ continue
+
+ if here_doc_delim is not None:
+ if here_doc_delim.match(line):
+ here_doc_delim = None
+ file_out.write(line)
+ continue
+ here_doc = here_doc_re.match(line)
+ if here_doc is not None:
+ here_doc_delim = re.compile("^%s$" % here_doc.group(1))
+ file_out.write(line)
+ continue
+ # Note: here-documents are handled before functions since otherwise
+ # it would be possible for the content of a here-document to be
+ # mistaken as the end of a function.
+ if in_func:
+ if func_end_re.match(line) is not None:
+ in_func = None
+ file_out.write(line)
+ continue
+ in_func = func_start_re.match(line)
+ if in_func is not None:
+ file_out.write(line)
+ continue
+ # This line is not recognized as part of a variable assignment,
+ # function definition, or here document, so just allow it to
+ # pass through.
+ file_out.write(line)
+
+if __name__ == "__main__":
+ description = "Filter out variable assignments for variable " + \
+ "names matching a given PATTERN " + \
+ "while leaving bash function definitions and here-documents " + \
+ "intact. The PATTERN is a space separated list of variable names" + \
+ " and it supports python regular expression syntax."
+ usage = "usage: %s PATTERN" % os.path.basename(sys.argv[0])
+ parser = optparse.OptionParser(description=description, usage=usage)
+ options, args = parser.parse_args(sys.argv[1:])
+ if len(args) != 1:
+ parser.error("Missing required PATTERN argument.")
+ file_in = sys.stdin
+ file_out = sys.stdout
+ if sys.hexversion >= 0x3000000:
+ file_in = codecs.iterdecode(sys.stdin.buffer.raw,
+ 'utf_8', errors='replace')
+ file_out = io.TextIOWrapper(sys.stdout.buffer,
+ 'utf_8', errors='backslashreplace')
+
+ var_pattern = args[0].split()
+
+ # Filter invalid variable names that are not supported by bash.
+ var_pattern.append(r'\d.*')
+ var_pattern.append(r'.*\W.*')
+
+ var_pattern = "^(%s)$" % "|".join(var_pattern)
+ filter_bash_environment(
+ re.compile(var_pattern), file_in, file_out)
+ file_out.flush()
diff --git a/portage_with_autodep/bin/fixpackages b/portage_with_autodep/bin/fixpackages
new file mode 100755
index 0000000..5e1df70
--- /dev/null
+++ b/portage_with_autodep/bin/fixpackages
@@ -0,0 +1,45 @@
+#!/usr/bin/python
+# Copyright 1999-2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import os,sys
+os.environ["PORTAGE_CALLER"]="fixpackages"
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage.output import EOutput
+from textwrap import wrap
+from portage._global_updates import _global_updates
+mysettings = portage.settings
+mytrees = portage.db
+mtimedb = portage.mtimedb
+
+if mysettings['ROOT'] != "/":
+ out = EOutput()
+ msg = "The fixpackages program is not intended for use with " + \
+ "ROOT != \"/\". Instead use `emaint --fix movebin` and/or " + \
+ "`emaint --fix moveinst."
+ for line in wrap(msg, 72):
+ out.eerror(line)
+ sys.exit(1)
+
+try:
+ os.nice(int(mysettings.get("PORTAGE_NICENESS", "0")))
+except (OSError, ValueError) as e:
+ portage.writemsg("!!! Failed to change nice value to '%s'\n" % \
+ mysettings["PORTAGE_NICENESS"])
+ portage.writemsg("!!! %s\n" % str(e))
+ del e
+
+_global_updates(mytrees, mtimedb["updates"])
+
+print()
+print("Done.")
+print()
diff --git a/portage_with_autodep/bin/glsa-check b/portage_with_autodep/bin/glsa-check
new file mode 100755
index 0000000..2f2d555
--- /dev/null
+++ b/portage_with_autodep/bin/glsa-check
@@ -0,0 +1,316 @@
+#!/usr/bin/python
+# Copyright 2008-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import sys
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage.output import *
+
+from optparse import OptionGroup, OptionParser
+
+__program__ = "glsa-check"
+__author__ = "Marius Mauch <genone@gentoo.org>"
+__version__ = "1.0"
+
+def cb_version(*args, **kwargs):
+ """Callback for --version"""
+ sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
+ sys.stderr.write("Author: " + __author__ + "\n")
+ sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
+ sys.exit(0)
+
+# option parsing
+parser = OptionParser(usage="%prog <option> [glsa-list]",
+ version="%prog "+ __version__)
+parser.epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
+ " filenames containing GLSAs or the special identifiers" \
+ " 'all', 'new' and 'affected'"
+
+modes = OptionGroup(parser, "Modes")
+modes.add_option("-l", "--list", action="store_const",
+ const="list", dest="mode",
+ help="List all unapplied GLSA")
+modes.add_option("-d", "--dump", action="store_const",
+ const="dump", dest="mode",
+ help="Show all information about the given GLSA")
+modes.add_option("", "--print", action="store_const",
+ const="dump", dest="mode",
+ help="Alias for --dump")
+modes.add_option("-t", "--test", action="store_const",
+ const="test", dest="mode",
+ help="Test if this system is affected by the given GLSA")
+modes.add_option("-p", "--pretend", action="store_const",
+ const="pretend", dest="mode",
+ help="Show the necessary commands to apply this GLSA")
+modes.add_option("-f", "--fix", action="store_const",
+ const="fix", dest="mode",
+ help="Try to auto-apply this GLSA (experimental)")
+modes.add_option("-i", "--inject", action="store_const", dest="mode",
+ help="Inject the given GLSA into the checkfile")
+modes.add_option("-m", "--mail", action="store_const",
+ const="mail", dest="mode",
+ help="Send a mail with the given GLSAs to the administrator")
+parser.add_option_group(modes)
+
+parser.remove_option("--version")
+parser.add_option("-V", "--version", action="callback",
+ callback=cb_version, help="Some information about this tool")
+parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+ help="Print more information")
+parser.add_option("-n", "--nocolor", action="callback",
+ callback=lambda *args, **kwargs: nocolor(),
+ help="Disable colors")
+parser.add_option("-e", "--emergelike", action="store_false", dest="least_change",
+ help="Do not use a least-change algorithm")
+parser.add_option("-c", "--cve", action="store_true", dest="list_cve",
+ help="Show CAN ids in listing mode")
+
+options, params = parser.parse_args()
+
+mode = options.mode
+least_change = options.least_change
+list_cve = options.list_cve
+verbose = options.verbose
+
+# Sanity checking
+if mode is None:
+ sys.stderr.write("No mode given: what should I do?\n")
+ parser.print_help()
+ sys.exit(1)
+elif mode != "list" and not params:
+ sys.stderr.write("\nno GLSA given, so we'll do nothing for now. \n")
+ sys.stderr.write("If you want to run on all GLSA please tell me so \n")
+ sys.stderr.write("(specify \"all\" as parameter)\n\n")
+ parser.print_help()
+ sys.exit(1)
+elif mode in ["fix", "inject"] and os.geteuid() != 0:
+ # we need root privileges for write access
+ sys.stderr.write("\nThis tool needs root access to "+options.mode+" this GLSA\n\n")
+ sys.exit(2)
+elif mode == "list" and not params:
+ params.append("new")
+
+# delay this for speed increase
+from portage.glsa import *
+
+vardb = portage.db[portage.settings["ROOT"]]["vartree"].dbapi
+portdb = portage.db["/"]["porttree"].dbapi
+
+# build glsa lists
+completelist = get_glsa_list(portage.settings)
+
+checklist = get_applied_glsas(portage.settings)
+todolist = [e for e in completelist if e not in checklist]
+
+glsalist = []
+if "new" in params:
+ glsalist = todolist
+ params.remove("new")
+
+if "all" in params:
+ glsalist = completelist
+ params.remove("all")
+if "affected" in params:
+ # replaced completelist with todolist on request of wschlich
+ for x in todolist:
+ try:
+ myglsa = Glsa(x, portage.settings, vardb, portdb)
+ except (GlsaTypeException, GlsaFormatException) as e:
+ if verbose:
+ sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (x, e)))
+ continue
+ if myglsa.isVulnerable():
+ glsalist.append(x)
+ params.remove("affected")
+
+# remove invalid parameters
+for p in params[:]:
+ if not (p in completelist or os.path.exists(p)):
+ sys.stderr.write(("(removing %s from parameter list as it isn't a valid GLSA specification)\n" % p))
+ params.remove(p)
+
+glsalist.extend([g for g in params if g not in glsalist])
+
+def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
+ fd2.write(white("[A]")+" means this GLSA was already applied,\n")
+ fd2.write(green("[U]")+" means the system is not affected and\n")
+ fd2.write(red("[N]")+" indicates that the system might be affected.\n\n")
+
+ myglsalist.sort()
+ for myid in myglsalist:
+ try:
+ myglsa = Glsa(myid, portage.settings, vardb, portdb)
+ except (GlsaTypeException, GlsaFormatException) as e:
+ if verbose:
+ fd2.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
+ continue
+ if myglsa.isApplied():
+ status = "[A]"
+ color = white
+ elif myglsa.isVulnerable():
+ status = "[N]"
+ color = red
+ else:
+ status = "[U]"
+ color = green
+
+ if verbose:
+ access = ("[%-8s] " % myglsa.access)
+ else:
+ access=""
+
+ fd1.write(color(myglsa.nr) + " " + color(status) + " " + color(access) + myglsa.title + " (")
+ if not verbose:
+ for pkg in list(myglsa.packages)[:3]:
+ fd1.write(" " + pkg + " ")
+ if len(myglsa.packages) > 3:
+ fd1.write("... ")
+ else:
+ for pkg in myglsa.packages:
+ mylist = vardb.match(pkg)
+ if len(mylist) > 0:
+ pkg = color(" ".join(mylist))
+ fd1.write(" " + pkg + " ")
+
+ fd1.write(")")
+ if list_cve:
+ fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]])))
+ fd1.write("\n")
+ return 0
+
+if mode == "list":
+ sys.exit(summarylist(glsalist))
+
+# dump, fix, inject and fix are nearly the same code, only the glsa method call differs
+if mode in ["dump", "fix", "inject", "pretend"]:
+ for myid in glsalist:
+ try:
+ myglsa = Glsa(myid, portage.settings, vardb, portdb)
+ except (GlsaTypeException, GlsaFormatException) as e:
+ if verbose:
+ sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
+ continue
+ if mode == "dump":
+ myglsa.dump()
+ elif mode == "fix":
+ sys.stdout.write("fixing "+myid+"\n")
+ mergelist = myglsa.getMergeList(least_change=least_change)
+ for pkg in mergelist:
+ sys.stdout.write(">>> merging "+pkg+"\n")
+ # using emerge for the actual merging as it contains the dependency
+ # code and we want to be consistent in behaviour. Also this functionality
+ # will be integrated in emerge later, so it shouldn't hurt much.
+ emergecmd = "emerge --oneshot " + portage.settings["EMERGE_OPTS"] + " =" + pkg
+ if verbose:
+ sys.stderr.write(emergecmd+"\n")
+ exitcode = os.system(emergecmd)
+ # system() returns the exitcode in the high byte of a 16bit integer
+ if exitcode >= 1<<8:
+ exitcode >>= 8
+ if exitcode:
+ sys.exit(exitcode)
+ myglsa.inject()
+ elif mode == "pretend":
+ sys.stdout.write("Checking GLSA "+myid+"\n")
+ mergelist = myglsa.getMergeList(least_change=least_change)
+ if mergelist:
+ sys.stdout.write("The following updates will be performed for this GLSA:\n")
+ for pkg in mergelist:
+ oldver = None
+ for x in vardb.match(portage.cpv_getkey(pkg)):
+ if vardb.aux_get(x, ["SLOT"]) == portdb.aux_get(pkg, ["SLOT"]):
+ oldver = x
+ if oldver == None:
+ raise ValueError("could not find old version for package %s" % pkg)
+ oldver = oldver[len(portage.cpv_getkey(oldver))+1:]
+ sys.stdout.write(" " + pkg + " (" + oldver + ")\n")
+ else:
+ sys.stdout.write("Nothing to do for this GLSA\n")
+ elif mode == "inject":
+ sys.stdout.write("injecting " + myid + "\n")
+ myglsa.inject()
+ sys.stdout.write("\n")
+ sys.exit(0)
+
+# test is a bit different as Glsa.test() produces no output
+if mode == "test":
+ outputlist = []
+ for myid in glsalist:
+ try:
+ myglsa = Glsa(myid, portage.settings, vardb, portdb)
+ except (GlsaTypeException, GlsaFormatException) as e:
+ if verbose:
+ sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
+ continue
+ if myglsa.isVulnerable():
+ outputlist.append(str(myglsa.nr))
+ if len(outputlist) > 0:
+ sys.stderr.write("This system is affected by the following GLSAs:\n")
+ if verbose:
+ summarylist(outputlist)
+ else:
+ sys.stdout.write("\n".join(outputlist)+"\n")
+ else:
+ sys.stderr.write("This system is not affected by any of the listed GLSAs\n")
+ sys.exit(0)
+
+# mail mode as requested by solar
+if mode == "mail":
+ import portage.mail, socket
+ from io import StringIO
+ from email.mime.text import MIMEText
+
+ # color doesn't make any sense for mail
+ nocolor()
+
+ if "PORTAGE_ELOG_MAILURI" in portage.settings:
+ myrecipient = portage.settings["PORTAGE_ELOG_MAILURI"].split()[0]
+ else:
+ myrecipient = "root@localhost"
+
+ if "PORTAGE_ELOG_MAILFROM" in portage.settings:
+ myfrom = portage.settings["PORTAGE_ELOG_MAILFROM"]
+ else:
+ myfrom = "glsa-check"
+
+ mysubject = "[glsa-check] Summary for %s" % socket.getfqdn()
+
+ # need a file object for summarylist()
+ myfd = StringIO()
+ myfd.write("GLSA Summary report for host %s\n" % socket.getfqdn())
+ myfd.write("(Command was: %s)\n\n" % " ".join(sys.argv))
+ summarylist(glsalist, fd1=myfd, fd2=myfd)
+ summary = str(myfd.getvalue())
+ myfd.close()
+
+ myattachments = []
+ for myid in glsalist:
+ try:
+ myglsa = Glsa(myid, portage.settings, vardb, portdb)
+ except (GlsaTypeException, GlsaFormatException) as e:
+ if verbose:
+ sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
+ continue
+ myfd = StringIO()
+ myglsa.dump(outstream=myfd)
+ myattachments.append(MIMEText(str(myfd.getvalue()), _charset="utf8"))
+ myfd.close()
+
+ mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, summary, myattachments)
+ portage.mail.send_mail(portage.settings, mymessage)
+
+ sys.exit(0)
+
+# something wrong here, all valid paths are covered with sys.exit()
+sys.stderr.write("nothing more to do\n")
+sys.exit(2)
diff --git a/portage_with_autodep/bin/isolated-functions.sh b/portage_with_autodep/bin/isolated-functions.sh
new file mode 100644
index 0000000..65bb1d5
--- /dev/null
+++ b/portage_with_autodep/bin/isolated-functions.sh
@@ -0,0 +1,630 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# We need this next line for "die" and "assert". It expands
+# It _must_ preceed all the calls to die and assert.
+shopt -s expand_aliases
+alias save_IFS='[ "${IFS:-unset}" != "unset" ] && old_IFS="${IFS}"'
+alias restore_IFS='if [ "${old_IFS:-unset}" != "unset" ]; then IFS="${old_IFS}"; unset old_IFS; else unset IFS; fi'
+
+assert() {
+ local x pipestatus=${PIPESTATUS[*]}
+ for x in $pipestatus ; do
+ [[ $x -eq 0 ]] || die "$@"
+ done
+}
+
+assert_sigpipe_ok() {
+ # When extracting a tar file like this:
+ #
+ # bzip2 -dc foo.tar.bz2 | tar xof -
+ #
+ # For some tar files (see bug #309001), tar will
+ # close its stdin pipe when the decompressor still has
+ # remaining data to be written to its stdout pipe. This
+ # causes the decompressor to be killed by SIGPIPE. In
+ # this case, we want to ignore pipe writers killed by
+ # SIGPIPE, and trust the exit status of tar. We refer
+ # to the bash manual section "3.7.5 Exit Status"
+ # which says, "When a command terminates on a fatal
+ # signal whose number is N, Bash uses the value 128+N
+ # as the exit status."
+
+ local x pipestatus=${PIPESTATUS[*]}
+ for x in $pipestatus ; do
+ # Allow SIGPIPE through (128 + 13)
+ [[ $x -ne 0 && $x -ne ${PORTAGE_SIGPIPE_STATUS:-141} ]] && die "$@"
+ done
+
+ # Require normal success for the last process (tar).
+ [[ $x -eq 0 ]] || die "$@"
+}
+
+shopt -s extdebug
+
+# dump_trace([number of funcs on stack to skip],
+# [whitespacing for filenames],
+# [whitespacing for line numbers])
+dump_trace() {
+ local funcname="" sourcefile="" lineno="" s="yes" n p
+ declare -i strip=${1:-1}
+ local filespacing=$2 linespacing=$3
+
+ # The qa_call() function and anything before it are portage internals
+ # that the user will not be interested in. Therefore, the stack trace
+ # should only show calls that come after qa_call().
+ (( n = ${#FUNCNAME[@]} - 1 ))
+ (( p = ${#BASH_ARGV[@]} ))
+ while (( n > 0 )) ; do
+ [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
+ (( p -= ${BASH_ARGC[${n}]} ))
+ (( n-- ))
+ done
+ if (( n == 0 )) ; then
+ (( n = ${#FUNCNAME[@]} - 1 ))
+ (( p = ${#BASH_ARGV[@]} ))
+ fi
+
+ eerror "Call stack:"
+ while (( n > ${strip} )) ; do
+ funcname=${FUNCNAME[${n} - 1]}
+ sourcefile=$(basename "${BASH_SOURCE[${n}]}")
+ lineno=${BASH_LINENO[${n} - 1]}
+ # Display function arguments
+ args=
+ if [[ -n "${BASH_ARGV[@]}" ]]; then
+ for (( j = 1 ; j <= ${BASH_ARGC[${n} - 1]} ; ++j )); do
+ newarg=${BASH_ARGV[$(( p - j - 1 ))]}
+ args="${args:+${args} }'${newarg}'"
+ done
+ (( p -= ${BASH_ARGC[${n} - 1]} ))
+ fi
+ eerror " $(printf "%${filespacing}s" "${sourcefile}"), line $(printf "%${linespacing}s" "${lineno}"): Called ${funcname}${args:+ ${args}}"
+ (( n-- ))
+ done
+}
+
+nonfatal() {
+ if has "${EAPI:-0}" 0 1 2 3 3_pre2 ; then
+ die "$FUNCNAME() not supported in this EAPI"
+ fi
+ if [[ $# -lt 1 ]]; then
+ die "$FUNCNAME(): Missing argument"
+ fi
+
+ PORTAGE_NONFATAL=1 "$@"
+}
+
+helpers_die() {
+ case "${EAPI:-0}" in
+ 0|1|2|3)
+ echo -e "$@" >&2
+ ;;
+ *)
+ die "$@"
+ ;;
+ esac
+}
+
+die() {
+ if [[ $PORTAGE_NONFATAL -eq 1 ]]; then
+ echo -e " $WARN*$NORMAL ${FUNCNAME[1]}: WARNING: $@" >&2
+ return 1
+ fi
+
+ set +e
+ if [ -n "${QA_INTERCEPTORS}" ] ; then
+ # die was called from inside inherit. We need to clean up
+ # QA_INTERCEPTORS since sed is called below.
+ unset -f ${QA_INTERCEPTORS}
+ unset QA_INTERCEPTORS
+ fi
+ local n filespacing=0 linespacing=0
+ # setup spacing to make output easier to read
+ (( n = ${#FUNCNAME[@]} - 1 ))
+ while (( n > 0 )) ; do
+ [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
+ (( n-- ))
+ done
+ (( n == 0 )) && (( n = ${#FUNCNAME[@]} - 1 ))
+ while (( n > 0 )); do
+ sourcefile=${BASH_SOURCE[${n}]} sourcefile=${sourcefile##*/}
+ lineno=${BASH_LINENO[${n}]}
+ ((filespacing < ${#sourcefile})) && filespacing=${#sourcefile}
+ ((linespacing < ${#lineno})) && linespacing=${#lineno}
+ (( n-- ))
+ done
+
+ # When a helper binary dies automatically in EAPI 4 and later, we don't
+ # get a stack trace, so at least report the phase that failed.
+ local phase_str=
+ [[ -n $EBUILD_PHASE ]] && phase_str=" ($EBUILD_PHASE phase)"
+ eerror "ERROR: $CATEGORY/$PF failed${phase_str}:"
+ eerror " ${*:-(no error message)}"
+ eerror
+ # dump_trace is useless when the main script is a helper binary
+ local main_index
+ (( main_index = ${#BASH_SOURCE[@]} - 1 ))
+ if has ${BASH_SOURCE[$main_index]##*/} ebuild.sh misc-functions.sh ; then
+ dump_trace 2 ${filespacing} ${linespacing}
+ eerror " $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"): Called die"
+ eerror "The specific snippet of code:"
+ # This scans the file that called die and prints out the logic that
+ # ended in the call to die. This really only handles lines that end
+ # with '|| die' and any preceding lines with line continuations (\).
+ # This tends to be the most common usage though, so let's do it.
+ # Due to the usage of appending to the hold space (even when empty),
+ # we always end up with the first line being a blank (thus the 2nd sed).
+ sed -n \
+ -e "# When we get to the line that failed, append it to the
+ # hold space, move the hold space to the pattern space,
+ # then print out the pattern space and quit immediately
+ ${BASH_LINENO[0]}{H;g;p;q}" \
+ -e '# If this line ends with a line continuation, append it
+ # to the hold space
+ /\\$/H' \
+ -e '# If this line does not end with a line continuation,
+ # erase the line and set the hold buffer to it (thus
+ # erasing the hold buffer in the process)
+ /[^\]$/{s:^.*$::;h}' \
+ "${BASH_SOURCE[1]}" \
+ | sed -e '1d' -e 's:^:RETAIN-LEADING-SPACE:' \
+ | while read -r n ; do eerror " ${n#RETAIN-LEADING-SPACE}" ; done
+ eerror
+ fi
+ eerror "If you need support, post the output of 'emerge --info =$CATEGORY/$PF',"
+ eerror "the complete build log and the output of 'emerge -pqv =$CATEGORY/$PF'."
+ if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
+ eerror "This ebuild used the following eclasses from overlays:"
+ local x
+ for x in ${EBUILD_OVERLAY_ECLASSES} ; do
+ eerror " ${x}"
+ done
+ fi
+ if [ "${EMERGE_FROM}" != "binary" ] && \
+ ! has ${EBUILD_PHASE} prerm postrm && \
+ [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
+ local overlay=${EBUILD%/*}
+ overlay=${overlay%/*}
+ overlay=${overlay%/*}
+ if [[ -n $PORTAGE_REPO_NAME ]] ; then
+ eerror "This ebuild is from an overlay named" \
+ "'$PORTAGE_REPO_NAME': '${overlay}/'"
+ else
+ eerror "This ebuild is from an overlay: '${overlay}/'"
+ fi
+ elif [[ -n $PORTAGE_REPO_NAME && -f "$PORTDIR"/profiles/repo_name ]] ; then
+ local portdir_repo_name=$(<"$PORTDIR"/profiles/repo_name)
+ if [[ -n $portdir_repo_name && \
+ $portdir_repo_name != $PORTAGE_REPO_NAME ]] ; then
+ eerror "This ebuild is from a repository" \
+ "named '$PORTAGE_REPO_NAME'"
+ fi
+ fi
+
+ if [[ "${EBUILD_PHASE/depend}" == "${EBUILD_PHASE}" ]] ; then
+ local x
+ for x in $EBUILD_DEATH_HOOKS; do
+ ${x} "$@" >&2 1>&2
+ done
+ > "$PORTAGE_BUILDDIR/.die_hooks"
+ fi
+
+ [[ -n ${PORTAGE_LOG_FILE} ]] \
+ && eerror "The complete build log is located at '${PORTAGE_LOG_FILE}'."
+ if [ -f "${T}/environment" ] ; then
+ eerror "The ebuild environment file is located at '${T}/environment'."
+ elif [ -d "${T}" ] ; then
+ {
+ set
+ export
+ } > "${T}/die.env"
+ eerror "The ebuild environment file is located at '${T}/die.env'."
+ fi
+ eerror "S: '${S}'"
+
+ [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
+ [[ -n $PORTAGE_IPC_DAEMON ]] && "$PORTAGE_BIN_PATH"/ebuild-ipc exit 1
+
+ # subshell die support
+ [[ $BASHPID = $EBUILD_MASTER_PID ]] || kill -s SIGTERM $EBUILD_MASTER_PID
+ exit 1
+}
+
+# We need to implement diefunc() since environment.bz2 files contain
+# calls to it (due to alias expansion).
+diefunc() {
+ die "${@}"
+}
+
+quiet_mode() {
+ [[ ${PORTAGE_QUIET} -eq 1 ]]
+}
+
+vecho() {
+ quiet_mode || echo "$@"
+}
+
+# Internal logging function, don't use this in ebuilds
+elog_base() {
+ local messagetype
+ [ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
+ case "${1}" in
+ INFO|WARN|ERROR|LOG|QA)
+ messagetype="${1}"
+ shift
+ ;;
+ *)
+ vecho -e " ${BAD}*${NORMAL} Invalid use of internal function elog_base(), next message will not be logged"
+ return 1
+ ;;
+ esac
+ echo -e "$@" | while read -r ; do
+ echo "$messagetype $REPLY" >> \
+ "${T}/logging/${EBUILD_PHASE:-other}"
+ done
+ return 0
+}
+
+eqawarn() {
+ elog_base QA "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e "$@" | while read -r ; do
+ vecho " $WARN*$NORMAL $REPLY" >&2
+ done
+ LAST_E_CMD="eqawarn"
+ return 0
+}
+
+elog() {
+ elog_base LOG "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e "$@" | while read -r ; do
+ echo " $GOOD*$NORMAL $REPLY"
+ done
+ LAST_E_CMD="elog"
+ return 0
+}
+
+esyslog() {
+ local pri=
+ local tag=
+
+ if [ -x /usr/bin/logger ]
+ then
+ pri="$1"
+ tag="$2"
+
+ shift 2
+ [ -z "$*" ] && return 0
+
+ /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
+ fi
+
+ return 0
+}
+
+einfo() {
+ elog_base INFO "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e "$@" | while read -r ; do
+ echo " $GOOD*$NORMAL $REPLY"
+ done
+ LAST_E_CMD="einfo"
+ return 0
+}
+
+einfon() {
+ elog_base INFO "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -ne " ${GOOD}*${NORMAL} $*"
+ LAST_E_CMD="einfon"
+ return 0
+}
+
+ewarn() {
+ elog_base WARN "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e "$@" | while read -r ; do
+ echo " $WARN*$NORMAL $RC_INDENTATION$REPLY" >&2
+ done
+ LAST_E_CMD="ewarn"
+ return 0
+}
+
+eerror() {
+ elog_base ERROR "$*"
+ [[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
+ echo -e "$@" | while read -r ; do
+ echo " $BAD*$NORMAL $RC_INDENTATION$REPLY" >&2
+ done
+ LAST_E_CMD="eerror"
+ return 0
+}
+
+ebegin() {
+ local msg="$*" dots spaces=${RC_DOT_PATTERN//?/ }
+ if [[ -n ${RC_DOT_PATTERN} ]] ; then
+ dots=$(printf "%$(( COLS - 3 - ${#RC_INDENTATION} - ${#msg} - 7 ))s" '')
+ dots=${dots//${spaces}/${RC_DOT_PATTERN}}
+ msg="${msg}${dots}"
+ else
+ msg="${msg} ..."
+ fi
+ einfon "${msg}"
+ [[ ${RC_ENDCOL} == "yes" ]] && echo
+ LAST_E_LEN=$(( 3 + ${#RC_INDENTATION} + ${#msg} ))
+ LAST_E_CMD="ebegin"
+ return 0
+}
+
+_eend() {
+ local retval=${1:-0} efunc=${2:-eerror} msg
+ shift 2
+
+ if [[ ${retval} == "0" ]] ; then
+ msg="${BRACKET}[ ${GOOD}ok${BRACKET} ]${NORMAL}"
+ else
+ if [[ -n $* ]] ; then
+ ${efunc} "$*"
+ fi
+ msg="${BRACKET}[ ${BAD}!!${BRACKET} ]${NORMAL}"
+ fi
+
+ if [[ ${RC_ENDCOL} == "yes" ]] ; then
+ echo -e "${ENDCOL} ${msg}"
+ else
+ [[ ${LAST_E_CMD} == ebegin ]] || LAST_E_LEN=0
+ printf "%$(( COLS - LAST_E_LEN - 7 ))s%b\n" '' "${msg}"
+ fi
+
+ return ${retval}
+}
+
+eend() {
+ local retval=${1:-0}
+ shift
+
+ _eend ${retval} eerror "$*"
+
+ LAST_E_CMD="eend"
+ return ${retval}
+}
+
+KV_major() {
+ [[ -z $1 ]] && return 1
+
+ local KV=$@
+ echo "${KV%%.*}"
+}
+
+KV_minor() {
+ [[ -z $1 ]] && return 1
+
+ local KV=$@
+ KV=${KV#*.}
+ echo "${KV%%.*}"
+}
+
+KV_micro() {
+ [[ -z $1 ]] && return 1
+
+ local KV=$@
+ KV=${KV#*.*.}
+ echo "${KV%%[^[:digit:]]*}"
+}
+
+KV_to_int() {
+ [[ -z $1 ]] && return 1
+
+ local KV_MAJOR=$(KV_major "$1")
+ local KV_MINOR=$(KV_minor "$1")
+ local KV_MICRO=$(KV_micro "$1")
+ local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))
+
+ # We make version 2.2.0 the minimum version we will handle as
+ # a sanity check ... if its less, we fail ...
+ if [[ ${KV_int} -ge 131584 ]] ; then
+ echo "${KV_int}"
+ return 0
+ fi
+
+ return 1
+}
+
+_RC_GET_KV_CACHE=""
+get_KV() {
+ [[ -z ${_RC_GET_KV_CACHE} ]] \
+ && _RC_GET_KV_CACHE=$(uname -r)
+
+ echo $(KV_to_int "${_RC_GET_KV_CACHE}")
+
+ return $?
+}
+
+unset_colors() {
+ COLS=80
+ ENDCOL=
+
+ GOOD=
+ WARN=
+ BAD=
+ NORMAL=
+ HILITE=
+ BRACKET=
+}
+
+set_colors() {
+ COLS=${COLUMNS:-0} # bash's internal COLUMNS variable
+ (( COLS == 0 )) && COLS=$(set -- $(stty size 2>/dev/null) ; echo $2)
+ (( COLS > 0 )) || (( COLS = 80 ))
+
+ # Now, ${ENDCOL} will move us to the end of the
+ # column; irregardless of character width
+ ENDCOL=$'\e[A\e['$(( COLS - 8 ))'C'
+ if [ -n "${PORTAGE_COLORMAP}" ] ; then
+ eval ${PORTAGE_COLORMAP}
+ else
+ GOOD=$'\e[32;01m'
+ WARN=$'\e[33;01m'
+ BAD=$'\e[31;01m'
+ HILITE=$'\e[36;01m'
+ BRACKET=$'\e[34;01m'
+ fi
+ NORMAL=$'\e[0m'
+}
+
+RC_ENDCOL="yes"
+RC_INDENTATION=''
+RC_DEFAULT_INDENT=2
+RC_DOT_PATTERN=''
+
+case "${NOCOLOR:-false}" in
+ yes|true)
+ unset_colors
+ ;;
+ no|false)
+ set_colors
+ ;;
+esac
+
+if [[ -z ${USERLAND} ]] ; then
+ case $(uname -s) in
+ *BSD|DragonFly)
+ export USERLAND="BSD"
+ ;;
+ *)
+ export USERLAND="GNU"
+ ;;
+ esac
+fi
+
+if [[ -z ${XARGS} ]] ; then
+ case ${USERLAND} in
+ BSD)
+ export XARGS="xargs"
+ ;;
+ *)
+ export XARGS="xargs -r"
+ ;;
+ esac
+fi
+
+hasq() {
+ has $EBUILD_PHASE prerm postrm || eqawarn \
+ "QA Notice: The 'hasq' function is deprecated (replaced by 'has')"
+ has "$@"
+}
+
+hasv() {
+ if has "$@" ; then
+ echo "$1"
+ return 0
+ fi
+ return 1
+}
+
+has() {
+ local needle=$1
+ shift
+
+ local x
+ for x in "$@"; do
+ [ "${x}" = "${needle}" ] && return 0
+ done
+ return 1
+}
+
+# @FUNCTION: save_ebuild_env
+# @DESCRIPTION:
+# echo the current environment to stdout, filtering out redundant info.
+#
+# --exclude-init-phases causes pkg_nofetch and src_* phase functions to
+# be excluded from the output. These function are not needed for installation
+# or removal of the packages, and can therefore be safely excluded.
+#
+save_ebuild_env() {
+ (
+
+ if has --exclude-init-phases $* ; then
+ unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_
+ if [[ -n $PYTHONPATH ]] ; then
+ export PYTHONPATH=${PYTHONPATH/${PORTAGE_PYM_PATH}:}
+ [[ -z $PYTHONPATH ]] && unset PYTHONPATH
+ fi
+ fi
+
+ # misc variables inherited from the calling environment
+ unset COLORTERM DISPLAY EDITOR LESS LESSOPEN LOGNAME LS_COLORS PAGER \
+ TERM TERMCAP USER ftp_proxy http_proxy no_proxy
+
+ # other variables inherited from the calling environment
+ unset CVS_RSH ECHANGELOG_USER GPG_AGENT_INFO \
+ SSH_AGENT_PID SSH_AUTH_SOCK STY WINDOW XAUTHORITY
+
+ # CCACHE and DISTCC config
+ unset ${!CCACHE_*} ${!DISTCC_*}
+
+ # There's no need to bloat environment.bz2 with internally defined
+ # functions and variables, so filter them out if possible.
+
+ for x in pkg_setup pkg_nofetch src_unpack src_prepare src_configure \
+ src_compile src_test src_install pkg_preinst pkg_postinst \
+ pkg_prerm pkg_postrm ; do
+ unset -f default_$x _eapi{0,1,2,3,4}_$x
+ done
+ unset x
+
+ unset -f assert assert_sigpipe_ok dump_trace die diefunc \
+ quiet_mode vecho elog_base eqawarn elog \
+ esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
+ KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
+ has_phase_defined_up_to \
+ hasg hasgq hasv hasq qa_source qa_call \
+ addread addwrite adddeny addpredict _sb_append_var \
+ lchown lchgrp esyslog use usev useq has_version portageq \
+ best_version use_with use_enable register_die_hook \
+ keepdir unpack strip_duplicate_slashes econf einstall \
+ dyn_setup dyn_unpack dyn_clean into insinto exeinto docinto \
+ insopts diropts exeopts libopts docompress \
+ abort_handler abort_prepare abort_configure abort_compile \
+ abort_test abort_install dyn_prepare dyn_configure \
+ dyn_compile dyn_test dyn_install \
+ dyn_preinst dyn_help debug-print debug-print-function \
+ debug-print-section inherit EXPORT_FUNCTIONS remove_path_entry \
+ save_ebuild_env filter_readonly_variables preprocess_ebuild_env \
+ set_unless_changed unset_unless_changed source_all_bashrcs \
+ ebuild_main ebuild_phase ebuild_phase_with_hooks \
+ _ebuild_arg_to_phase _ebuild_phase_funcs default \
+ _pipestatus \
+ ${QA_INTERCEPTORS}
+
+ # portage config variables and variables set directly by portage
+ unset ACCEPT_LICENSE BAD BRACKET BUILD_PREFIX COLS \
+ DISTCC_DIR DISTDIR DOC_SYMLINKS_DIR \
+ EBUILD_FORCE_TEST EBUILD_MASTER_PID \
+ ECLASS_DEPTH ENDCOL FAKEROOTKEY \
+ GOOD HILITE HOME \
+ LAST_E_CMD LAST_E_LEN LD_PRELOAD MISC_FUNCTIONS_ARGS MOPREFIX \
+ NOCOLOR NORMAL PKGDIR PKGUSE PKG_LOGDIR PKG_TMPDIR \
+ PORTAGE_BASHRCS_SOURCED PORTAGE_NONFATAL PORTAGE_QUIET \
+ PORTAGE_SANDBOX_DENY PORTAGE_SANDBOX_PREDICT \
+ PORTAGE_SANDBOX_READ PORTAGE_SANDBOX_WRITE PREROOTPATH \
+ QA_INTERCEPTORS \
+ RC_DEFAULT_INDENT RC_DOT_PATTERN RC_ENDCOL RC_INDENTATION \
+ ROOT ROOTPATH RPMDIR TEMP TMP TMPDIR USE_EXPAND \
+ WARN XARGS _RC_GET_KV_CACHE
+
+ # user config variables
+ unset DOC_SYMLINKS_DIR INSTALL_MASK PKG_INSTALL_MASK
+
+ declare -p
+ declare -fp
+ if [[ ${BASH_VERSINFO[0]} == 3 ]]; then
+ export
+ fi
+ )
+}
+
+true
diff --git a/portage_with_autodep/bin/lock-helper.py b/portage_with_autodep/bin/lock-helper.py
new file mode 100755
index 0000000..5f3ea9f
--- /dev/null
+++ b/portage_with_autodep/bin/lock-helper.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import os
+import sys
+sys.path.insert(0, os.environ['PORTAGE_PYM_PATH'])
+import portage
+
+def main(args):
+
+ if args and sys.hexversion < 0x3000000 and not isinstance(args[0], unicode):
+ for i, x in enumerate(args):
+ args[i] = portage._unicode_decode(x, errors='strict')
+
+ # Make locks quiet since unintended locking messages displayed on
+ # stdout would corrupt the intended output of this program.
+ portage.locks._quiet = True
+ lock_obj = portage.locks.lockfile(args[0], wantnewlockfile=True)
+ sys.stdout.write('\0')
+ sys.stdout.flush()
+ sys.stdin.read(1)
+ portage.locks.unlockfile(lock_obj)
+ return portage.os.EX_OK
+
+if __name__ == "__main__":
+ rval = main(sys.argv[1:])
+ sys.exit(rval)
diff --git a/portage_with_autodep/bin/misc-functions.sh b/portage_with_autodep/bin/misc-functions.sh
new file mode 100755
index 0000000..8c191ff
--- /dev/null
+++ b/portage_with_autodep/bin/misc-functions.sh
@@ -0,0 +1,1002 @@
+#!/bin/bash
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+#
+# Miscellaneous shell functions that make use of the ebuild env but don't need
+# to be included directly in ebuild.sh.
+#
+# We're sourcing ebuild.sh here so that we inherit all of it's goodness,
+# including bashrc trickery. This approach allows us to do our miscellaneous
+# shell work withing the same env that ebuild.sh has, but without polluting
+# ebuild.sh itself with unneeded logic and shell code.
+#
+# XXX hack: clear the args so ebuild.sh doesn't see them
+MISC_FUNCTIONS_ARGS="$@"
+shift $#
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}/ebuild.sh"
+
+install_symlink_html_docs() {
+ cd "${D}" || die "cd failed"
+ #symlink the html documentation (if DOC_SYMLINKS_DIR is set in make.conf)
+ if [ -n "${DOC_SYMLINKS_DIR}" ] ; then
+ local mydocdir docdir
+ for docdir in "${HTMLDOC_DIR:-does/not/exist}" "${PF}/html" "${PF}/HTML" "${P}/html" "${P}/HTML" ; do
+ if [ -d "usr/share/doc/${docdir}" ] ; then
+ mydocdir="/usr/share/doc/${docdir}"
+ fi
+ done
+ if [ -n "${mydocdir}" ] ; then
+ local mysympath
+ if [ -z "${SLOT}" -o "${SLOT}" = "0" ] ; then
+ mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}"
+ else
+ mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}-${SLOT}"
+ fi
+ einfo "Symlinking ${mysympath} to the HTML documentation"
+ dodir "${DOC_SYMLINKS_DIR}/${CATEGORY}"
+ dosym "${mydocdir}" "${mysympath}"
+ fi
+ fi
+}
+
+# replacement for "readlink -f" or "realpath"
+canonicalize() {
+ local f=$1 b n=10 wd=$(pwd)
+ while (( n-- > 0 )); do
+ while [[ ${f: -1} = / && ${#f} -gt 1 ]]; do
+ f=${f%/}
+ done
+ b=${f##*/}
+ cd "${f%"${b}"}" 2>/dev/null || break
+ if [[ ! -L ${b} ]]; then
+ f=$(pwd -P)
+ echo "${f%/}/${b}"
+ cd "${wd}"
+ return 0
+ fi
+ f=$(readlink "${b}")
+ done
+ cd "${wd}"
+ return 1
+}
+
+prepcompress() {
+ local -a include exclude incl_d incl_f
+ local f g i real_f real_d
+
+ # Canonicalize path names and check for their existence.
+ real_d=$(canonicalize "${D}")
+ for (( i = 0; i < ${#PORTAGE_DOCOMPRESS[@]}; i++ )); do
+ real_f=$(canonicalize "${D}${PORTAGE_DOCOMPRESS[i]}")
+ f=${real_f#"${real_d}"}
+ if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
+ then
+ include[${#include[@]}]=${f:-/}
+ elif [[ ${i} -ge 3 ]]; then
+ ewarn "prepcompress:" \
+ "ignoring nonexistent path '${PORTAGE_DOCOMPRESS[i]}'"
+ fi
+ done
+ for (( i = 0; i < ${#PORTAGE_DOCOMPRESS_SKIP[@]}; i++ )); do
+ real_f=$(canonicalize "${D}${PORTAGE_DOCOMPRESS_SKIP[i]}")
+ f=${real_f#"${real_d}"}
+ if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
+ then
+ exclude[${#exclude[@]}]=${f:-/}
+ elif [[ ${i} -ge 1 ]]; then
+ ewarn "prepcompress:" \
+ "ignoring nonexistent path '${PORTAGE_DOCOMPRESS_SKIP[i]}'"
+ fi
+ done
+
+ # Remove redundant entries from lists.
+ # For the include list, remove any entries that are:
+ # a) contained in a directory in the include or exclude lists, or
+ # b) identical with an entry in the exclude list.
+ for (( i = ${#include[@]} - 1; i >= 0; i-- )); do
+ f=${include[i]}
+ for g in "${include[@]}"; do
+ if [[ ${f} == "${g%/}"/* ]]; then
+ unset include[i]
+ continue 2
+ fi
+ done
+ for g in "${exclude[@]}"; do
+ if [[ ${f} = "${g}" || ${f} == "${g%/}"/* ]]; then
+ unset include[i]
+ continue 2
+ fi
+ done
+ done
+ # For the exclude list, remove any entries that are:
+ # a) contained in a directory in the exclude list, or
+ # b) _not_ contained in a directory in the include list.
+ for (( i = ${#exclude[@]} - 1; i >= 0; i-- )); do
+ f=${exclude[i]}
+ for g in "${exclude[@]}"; do
+ if [[ ${f} == "${g%/}"/* ]]; then
+ unset exclude[i]
+ continue 2
+ fi
+ done
+ for g in "${include[@]}"; do
+ [[ ${f} == "${g%/}"/* ]] && continue 2
+ done
+ unset exclude[i]
+ done
+
+ # Split the include list into directories and files
+ for f in "${include[@]}"; do
+ if [[ -d ${D}${f} ]]; then
+ incl_d[${#incl_d[@]}]=${f}
+ else
+ incl_f[${#incl_f[@]}]=${f}
+ fi
+ done
+
+ # Queue up for compression.
+ # ecompress{,dir} doesn't like to be called with empty argument lists.
+ [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --queue "${incl_d[@]}"
+ [[ ${#incl_f[@]} -gt 0 ]] && ecompress --queue "${incl_f[@]/#/${D}}"
+ [[ ${#exclude[@]} -gt 0 ]] && ecompressdir --ignore "${exclude[@]}"
+ return 0
+}
+
+install_qa_check() {
+ local f x
+
+ cd "${D}" || die "cd failed"
+
+ export STRIP_MASK
+ prepall
+ has "${EAPI}" 0 1 2 3 || prepcompress
+ ecompressdir --dequeue
+ ecompress --dequeue
+
+ f=
+ for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
+ [[ -d $D/$x ]] && f+=" $x\n"
+ done
+
+ if [[ -n $f ]] ; then
+ eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
+ eqawarn
+ eqawarn "$f"
+ fi
+
+ # Now we look for all world writable files.
+ local i
+ for i in $(find "${D}/" -type f -perm -2); do
+ vecho "QA Security Notice:"
+ vecho "- ${i:${#D}:${#i}} will be a world writable file."
+ vecho "- This may or may not be a security problem, most of the time it is one."
+ vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
+ sleep 1
+ done
+
+ if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then
+ local qa_var insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET}
+ local x
+
+ # display warnings when using stricter because we die afterwards
+ if has stricter ${FEATURES} ; then
+ unset PORTAGE_QUIET
+ fi
+
+ # Make sure we disallow insecure RUNPATH/RPATHs.
+ # 1) References to PORTAGE_BUILDDIR are banned because it's a
+ # security risk. We don't want to load files from a
+ # temporary directory.
+ # 2) If ROOT != "/", references to ROOT are banned because
+ # that directory won't exist on the target system.
+ # 3) Null paths are banned because the loader will search $PWD when
+ # it finds null paths.
+ local forbidden_dirs="${PORTAGE_BUILDDIR}"
+ if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then
+ forbidden_dirs+=" ${ROOT}"
+ fi
+ local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${D}")
+ f=""
+ for dir in ${forbidden_dirs}; do
+ for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
+ f+=" ${l%%:*}\n"
+ if ! has stricter ${FEATURES}; then
+ vecho "Auto fixing rpaths for ${l%%:*}"
+ TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
+ fi
+ done
+ done
+
+ # Reject set*id binaries with $ORIGIN in RPATH #260331
+ x=$(
+ find "${D}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \
+ xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN'
+ )
+
+ # Print QA notice.
+ if [[ -n ${f}${x} ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain insecure RUNPATHs"
+ eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
+ eqawarn " with the maintaining herd of the package."
+ eqawarn "${f}${f:+${x:+\n}}${x}"
+ vecho -ne '\n'
+ if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
+ insecure_rpath=1
+ fi
+ fi
+
+ # TEXTRELs are baaaaaaaad
+ # Allow devs to mark things as ignorable ... e.g. things that are
+ # binary-only and upstream isn't cooperating (nvidia-glx) ... we
+ # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ...
+ # the former overrides the latter ... regexes allowed ! :)
+ qa_var="QA_TEXTRELS_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var}
+ [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS=""
+ export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko"
+ f=$(scanelf -qyRF '%t %p' "${D}" | grep -v 'usr/lib/debug/')
+ if [[ -n ${f} ]] ; then
+ scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
+ vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain runtime text relocations"
+ eqawarn " Text relocations force the dynamic linker to perform extra"
+ eqawarn " work at startup, waste system resources, and may pose a security"
+ eqawarn " risk. On some architectures, the code may not even function"
+ eqawarn " properly, if at all."
+ eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn "${f}"
+ vecho -ne '\n'
+ die_msg="${die_msg} textrels,"
+ sleep 1
+ fi
+
+ # Also, executable stacks only matter on linux (and just glibc atm ...)
+ f=""
+ case ${CTARGET:-${CHOST}} in
+ *-linux-gnu*)
+ # Check for files with executable stacks, but only on arches which
+ # are supported at the moment. Keep this list in sync with
+ # http://hardened.gentoo.org/gnu-stack.xml (Arch Status)
+ case ${CTARGET:-${CHOST}} in
+ arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
+ # Allow devs to mark things as ignorable ... e.g. things
+ # that are binary-only and upstream isn't cooperating ...
+ # we allow ebuild authors to set QA_EXECSTACK_arch and
+ # QA_EXECSTACK ... the former overrides the latter ...
+ # regexes allowed ! :)
+
+ qa_var="QA_EXECSTACK_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var}
+ [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK=""
+ qa_var="QA_WX_LOAD_${ARCH/-/_}"
+ [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var}
+ [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD=""
+ export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko"
+ export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko"
+ f=$(scanelf -qyRAF '%e %p' "${D}" | grep -v 'usr/lib/debug/')
+ ;;
+ esac
+ ;;
+ esac
+ if [[ -n ${f} ]] ; then
+ # One more pass to help devs track down the source
+ scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
+ vecho -ne '\n'
+ eqawarn "QA Notice: The following files contain writable and executable sections"
+ eqawarn " Files with such sections will not work properly (or at all!) on some"
+ eqawarn " architectures/operating systems. A bug should be filed at"
+ eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed."
+ eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn " Note: Bugs should be filed for the respective maintainers"
+ eqawarn " of the package in question and not hardened@g.o."
+ eqawarn "${f}"
+ vecho -ne '\n'
+ die_msg="${die_msg} execstacks"
+ sleep 1
+ fi
+
+ # Check for files built without respecting LDFLAGS
+ if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && [[ "${PN}" != *-bin ]] ; then
+ qa_var="QA_DT_HASH_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_DT_HASH=(\"\${${qa_var}[@]}\")"
+ f=$(scanelf -qyRF '%k %p' -k .hash "${D}" | sed -e "s:\.hash ::")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
+ if [ "${QA_STRICT_DT_HASH-unset}" == unset ] ; then
+ if [[ ${#QA_DT_HASH[@]} -gt 1 ]] ; then
+ for x in "${QA_DT_HASH[@]}" ; do
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
+ done
+ else
+ local shopts=$-
+ set -o noglob
+ for x in ${QA_DT_HASH} ; do
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log
+ done
+ set +o noglob
+ set -${shopts}
+ fi
+ fi
+ # Filter anything under /usr/lib/debug/ in order to avoid
+ # duplicate warnings for splitdebug files.
+ sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \
+ -i "${T}"/scanelf-ignored-LDFLAGS.log
+ f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
+ if [[ -n ${f} ]] ; then
+ vecho -ne '\n'
+ eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
+ eqawarn " Please include the following list of files in your report:"
+ eqawarn "${f}"
+ vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-ignored-LDFLAGS.log
+ fi
+ fi
+ fi
+
+ # Save NEEDED information after removing self-contained providers
+ rm -f "$PORTAGE_BUILDDIR"/build-info/NEEDED{,.ELF.2}
+ scanelf -qyRF '%a;%p;%S;%r;%n' "${D}" | { while IFS= read -r l; do
+ arch=${l%%;*}; l=${l#*;}
+ obj="/${l%%;*}"; l=${l#*;}
+ soname=${l%%;*}; l=${l#*;}
+ rpath=${l%%;*}; l=${l#*;}; [ "${rpath}" = " - " ] && rpath=""
+ needed=${l%%;*}; l=${l#*;}
+ if [ -z "${rpath}" -o -n "${rpath//*ORIGIN*}" ]; then
+ # object doesn't contain $ORIGIN in its runpath attribute
+ echo "${obj} ${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
+ echo "${arch:3};${obj};${soname};${rpath};${needed}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
+ else
+ dir=${obj%/*}
+ # replace $ORIGIN with the dirname of the current object for the lookup
+ opath=$(echo :${rpath}: | sed -e "s#.*:\(.*\)\$ORIGIN\(.*\):.*#\1${dir}\2#")
+ sneeded=$(echo ${needed} | tr , ' ')
+ rneeded=""
+ for lib in ${sneeded}; do
+ found=0
+ for path in ${opath//:/ }; do
+ [ -e "${D}/${path}/${lib}" ] && found=1 && break
+ done
+ [ "${found}" -eq 0 ] && rneeded="${rneeded},${lib}"
+ done
+ rneeded=${rneeded:1}
+ if [ -n "${rneeded}" ]; then
+ echo "${obj} ${rneeded}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED
+ echo "${arch:3};${obj};${soname};${rpath};${rneeded}" >> "${PORTAGE_BUILDDIR}"/build-info/NEEDED.ELF.2
+ fi
+ fi
+ done }
+
+ if [[ ${insecure_rpath} -eq 1 ]] ; then
+ die "Aborting due to serious QA concerns with RUNPATH/RPATH"
+ elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then
+ die "Aborting due to QA concerns: ${die_msg}"
+ fi
+
+ # Check for shared libraries lacking SONAMEs
+ qa_var="QA_SONAME_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
+ f=$(scanelf -ByF '%S %p' "${D}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${D}:/:")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-missing-SONAME.log
+ if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
+ if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then
+ for x in "${QA_SONAME[@]}" ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
+ done
+ else
+ local shopts=$-
+ set -o noglob
+ for x in ${QA_SONAME} ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log
+ done
+ set +o noglob
+ set -${shopts}
+ fi
+ fi
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
+ f=$(<"${T}"/scanelf-missing-SONAME.log)
+ if [[ -n ${f} ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: The following shared libraries lack a SONAME"
+ eqawarn "${f}"
+ vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-missing-SONAME.log
+ fi
+ fi
+
+ # Check for shared libraries lacking NEEDED entries
+ qa_var="QA_DT_NEEDED_${ARCH/-/_}"
+ eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
+ f=$(scanelf -ByF '%n %p' "${D}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${D}:/:")
+ if [[ -n ${f} ]] ; then
+ echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
+ if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
+ if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then
+ for x in "${QA_DT_NEEDED[@]}" ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
+ done
+ else
+ local shopts=$-
+ set -o noglob
+ for x in ${QA_DT_NEEDED} ; do
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log
+ done
+ set +o noglob
+ set -${shopts}
+ fi
+ fi
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
+ f=$(<"${T}"/scanelf-missing-NEEDED.log)
+ if [[ -n ${f} ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
+ eqawarn "${f}"
+ vecho -ne '\n'
+ sleep 1
+ else
+ rm -f "${T}"/scanelf-missing-NEEDED.log
+ fi
+ fi
+
+ PORTAGE_QUIET=${tmp_quiet}
+ fi
+
+ local unsafe_files=$(find "${D}" -type f '(' -perm -2002 -o -perm -4002 ')')
+ if [[ -n ${unsafe_files} ]] ; then
+ eqawarn "QA Notice: Unsafe files detected (set*id and world writable)"
+ eqawarn "${unsafe_files}"
+ die "Unsafe files found in \${D}. Portage will not install them."
+ fi
+
+ if [[ -d ${D}/${D} ]] ; then
+ declare -i INSTALLTOD=0
+ for i in $(find "${D}/${D}/"); do
+ eqawarn "QA Notice: /${i##${D}/${D}} installed in \${D}/\${D}"
+ ((INSTALLTOD++))
+ done
+ die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D}/${D}"
+ unset INSTALLTOD
+ fi
+
+ # Sanity check syntax errors in init.d scripts
+ local d
+ for d in /etc/conf.d /etc/init.d ; do
+ [[ -d ${D}/${d} ]] || continue
+ for i in "${D}"/${d}/* ; do
+ [[ -L ${i} ]] && continue
+ # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
+ [[ ! -e ${i} ]] && continue
+ bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
+ done
+ done
+
+ # this should help to ensure that all (most?) shared libraries are executable
+ # and that all libtool scripts / static libraries are not executable
+ local j
+ for i in "${D}"opt/*/lib{,32,64} \
+ "${D}"lib{,32,64} \
+ "${D}"usr/lib{,32,64} \
+ "${D}"usr/X11R6/lib{,32,64} ; do
+ [[ ! -d ${i} ]] && continue
+
+ for j in "${i}"/*.so.* "${i}"/*.so ; do
+ [[ ! -e ${j} ]] && continue
+ [[ -L ${j} ]] && continue
+ [[ -x ${j} ]] && continue
+ vecho "making executable: ${j#${D}}"
+ chmod +x "${j}"
+ done
+
+ for j in "${i}"/*.a "${i}"/*.la ; do
+ [[ ! -e ${j} ]] && continue
+ [[ -L ${j} ]] && continue
+ [[ ! -x ${j} ]] && continue
+ vecho "removing executable bit: ${j#${D}}"
+ chmod -x "${j}"
+ done
+
+ for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do
+ [[ ! -e ${j} ]] && continue
+ [[ ! -L ${j} ]] && continue
+ linkdest=$(readlink "${j}")
+ if [[ ${linkdest} == /* ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: Found an absolute symlink in a library directory:"
+ eqawarn " ${j#${D}} -> ${linkdest}"
+ eqawarn " It should be a relative symlink if in the same directory"
+ eqawarn " or a linker script if it crosses the /usr boundary."
+ fi
+ done
+ done
+
+ # When installing static libraries into /usr/lib and shared libraries into
+ # /lib, we have to make sure we have a linker script in /usr/lib along side
+ # the static library, or gcc will utilize the static lib when linking :(.
+ # http://bugs.gentoo.org/4411
+ abort="no"
+ local a s
+ for a in "${D}"usr/lib*/*.a ; do
+ s=${a%.a}.so
+ if [[ ! -e ${s} ]] ; then
+ s=${s%usr/*}${s##*/usr/}
+ if [[ -e ${s} ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
+ abort="yes"
+ fi
+ fi
+ done
+ [[ ${abort} == "yes" ]] && die "add those ldscripts"
+
+ # Make sure people don't store libtool files or static libs in /lib
+ f=$(ls "${D}"lib*/*.{a,la} 2>/dev/null)
+ if [[ -n ${f} ]] ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: Excessive files found in the / partition"
+ eqawarn "${f}"
+ vecho -ne '\n'
+ die "static archives (*.a) and libtool library files (*.la) do not belong in /"
+ fi
+
+ # Verify that the libtool files don't contain bogus $D entries.
+ local abort=no gentoo_bug=no always_overflow=no
+ for a in "${D}"usr/lib*/*.la ; do
+ s=${a##*/}
+ if grep -qs "${D}" "${a}" ; then
+ vecho -ne '\n'
+ eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
+ abort="yes"
+ fi
+ done
+ [[ ${abort} == "yes" ]] && die "soiled libtool library files found"
+
+ # Evaluate misc gcc warnings
+ if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
+ # In debug mode, this variable definition and corresponding grep calls
+ # will produce false positives if they're shown in the trace.
+ local reset_debug=0
+ if [[ ${-/x/} != $- ]] ; then
+ set +x
+ reset_debug=1
+ fi
+ local m msgs=(
+ ": warning: dereferencing type-punned pointer will break strict-aliasing rules"
+ ": warning: dereferencing pointer .* does break strict-aliasing rules"
+ ": warning: implicit declaration of function"
+ ": warning: incompatible implicit declaration of built-in function"
+ ": warning: is used uninitialized in this function" # we'll ignore "may" and "might"
+ ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning"
+ ": warning: null argument where non-null required"
+ ": warning: array subscript is below array bounds"
+ ": warning: array subscript is above array bounds"
+ ": warning: attempt to free a non-heap object"
+ ": warning: .* called with .*bigger.* than .* destination buffer"
+ ": warning: call to .* will always overflow destination buffer"
+ ": warning: assuming pointer wraparound does not occur when comparing"
+ ": warning: hex escape sequence out of range"
+ ": warning: [^ ]*-hand operand of comma .*has no effect"
+ ": warning: converting to non-pointer type .* from NULL"
+ ": warning: NULL used in arithmetic"
+ ": warning: passing NULL to non-pointer argument"
+ ": warning: the address of [^ ]* will always evaluate as"
+ ": warning: the address of [^ ]* will never be NULL"
+ ": warning: too few arguments for format"
+ ": warning: reference to local variable .* returned"
+ ": warning: returning reference to temporary"
+ ": warning: function returns address of local variable"
+ # this may be valid code :/
+ #": warning: multi-character character constant"
+ # need to check these two ...
+ #": warning: assuming signed overflow does not occur when"
+ #": warning: comparison with string literal results in unspecified behav"
+ # yacc/lex likes to trigger this one
+ #": warning: extra tokens at end of .* directive"
+ # only gcc itself triggers this ?
+ #": warning: .*noreturn.* function does return"
+ # these throw false positives when 0 is used instead of NULL
+ #": warning: missing sentinel in function call"
+ #": warning: not enough variable arguments to fit a sentinel"
+ )
+ abort="no"
+ i=0
+ local grep_cmd=grep
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep
+ while [[ -n ${msgs[${i}]} ]] ; do
+ m=${msgs[$((i++))]}
+ # force C locale to work around slow unicode locales #160234
+ f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}")
+ if [[ -n ${f} ]] ; then
+ abort="yes"
+ # for now, don't make this fatal (see bug #337031)
+ #case "$m" in
+ # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;;
+ #esac
+ if [[ $always_overflow = yes ]] ; then
+ eerror
+ eerror "QA Notice: Package has poor programming practices which may compile"
+ eerror " fine but exhibit random runtime failures."
+ eerror
+ eerror "${f}"
+ eerror
+ eerror " Please file a bug about this at http://bugs.gentoo.org/"
+ eerror " with the maintaining herd of the package."
+ eerror
+ else
+ vecho -ne '\n'
+ eqawarn "QA Notice: Package has poor programming practices which may compile"
+ eqawarn " fine but exhibit random runtime failures."
+ eqawarn "${f}"
+ vecho -ne '\n'
+ fi
+ fi
+ done
+ local cat_cmd=cat
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
+ [[ $reset_debug = 1 ]] && set -x
+ f=$($cat_cmd "${PORTAGE_LOG_FILE}" | \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
+ if [[ -n ${f} ]] ; then
+
+ # In the future this will be a forced "die". In preparation,
+ # increase the log level from "qa" to "eerror" so that people
+ # are aware this is a problem that must be fixed asap.
+
+ # just warn on 32bit hosts but bail on 64bit hosts
+ case ${CHOST} in
+ alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;;
+ esac
+
+ abort=yes
+
+ if [[ $gentoo_bug = yes ]] ; then
+ eerror
+ eerror "QA Notice: Package has poor programming practices which may compile"
+ eerror " but will almost certainly crash on 64bit architectures."
+ eerror
+ eerror "${f}"
+ eerror
+ eerror " Please file a bug about this at http://bugs.gentoo.org/"
+ eerror " with the maintaining herd of the package."
+ eerror
+ else
+ vecho -ne '\n'
+ eqawarn "QA Notice: Package has poor programming practices which may compile"
+ eqawarn " but will almost certainly crash on 64bit architectures."
+ eqawarn "${f}"
+ vecho -ne '\n'
+ fi
+
+ fi
+ if [[ ${abort} == "yes" ]] ; then
+ if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then
+ die "install aborted due to" \
+ "poor programming practices shown above"
+ else
+ echo "Please do not file a Gentoo bug and instead" \
+ "report the above QA issues directly to the upstream" \
+ "developers of this software." | fmt -w 70 | \
+ while read -r line ; do eqawarn "${line}" ; done
+ eqawarn "Homepage: ${HOMEPAGE}"
+ has stricter ${FEATURES} && die "install aborted due to" \
+ "poor programming practices shown above"
+ fi
+ fi
+ fi
+
+ # Portage regenerates this on the installed system.
+ rm -f "${D}"/usr/share/info/dir{,.gz,.bz2}
+
+ if has multilib-strict ${FEATURES} && \
+ [[ -x /usr/bin/file && -x /usr/bin/find ]] && \
+ [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
+ then
+ local abort=no dir file firstrun=yes
+ MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
+ for dir in ${MULTILIB_STRICT_DIRS} ; do
+ [[ -d ${D}/${dir} ]] || continue
+ for file in $(find ${D}/${dir} -type f | grep -v "^${D}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
+ if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
+ if [[ ${firstrun} == yes ]] ; then
+ echo "Files matching a file type that is not allowed:"
+ firstrun=no
+ fi
+ abort=yes
+ echo " ${file#${D}//}"
+ fi
+ done
+ done
+ [[ ${abort} == yes ]] && die "multilib-strict check failed!"
+ fi
+
+ # ensure packages don't install systemd units automagically
+ if ! has systemd ${INHERITED} && \
+ [[ -d "${D}"/lib/systemd/system ]]
+ then
+ eqawarn "QA Notice: package installs systemd unit files (/lib/systemd/system)"
+ eqawarn " but does not inherit systemd.eclass."
+ has stricter ${FEATURES} \
+ && die "install aborted due to missing inherit of systemd.eclass"
+ fi
+}
+
+
+install_mask() {
+ local root="$1"
+ shift
+ local install_mask="$*"
+
+ # we don't want globbing for initial expansion, but afterwards, we do
+ local shopts=$-
+ set -o noglob
+ local no_inst
+ for no_inst in ${install_mask}; do
+ set +o noglob
+ quiet_mode || einfo "Removing ${no_inst}"
+ # normal stuff
+ rm -Rf "${root}"/${no_inst} >&/dev/null
+
+ # we also need to handle globs (*.a, *.h, etc)
+ find "${root}" \( -path "${no_inst}" -or -name "${no_inst}" \) \
+ -exec rm -fR {} \; >/dev/null 2>&1
+ done
+ # set everything back the way we found it
+ set +o noglob
+ set -${shopts}
+}
+
+preinst_mask() {
+ if [ -z "${D}" ]; then
+ eerror "${FUNCNAME}: D is unset"
+ return 1
+ fi
+
+ # Make sure $PWD is not ${D} so that we don't leave gmon.out files
+ # in there in case any tools were built with -pg in CFLAGS.
+ cd "${T}"
+
+ # remove man pages, info pages, docs if requested
+ local f
+ for f in man info doc; do
+ if has no${f} $FEATURES; then
+ INSTALL_MASK="${INSTALL_MASK} /usr/share/${f}"
+ fi
+ done
+
+ install_mask "${D}" "${INSTALL_MASK}"
+
+ # remove share dir if unnessesary
+ if has nodoc $FEATURES || has noman $FEATURES || has noinfo $FEATURES; then
+ rmdir "${D}usr/share" &> /dev/null
+ fi
+}
+
+preinst_sfperms() {
+ if [ -z "${D}" ]; then
+ eerror "${FUNCNAME}: D is unset"
+ return 1
+ fi
+ # Smart FileSystem Permissions
+ if has sfperms $FEATURES; then
+ local i
+ find "${D}" -type f -perm -4000 -print0 | \
+ while read -r -d $'\0' i ; do
+ if [ -n "$(find "$i" -perm -2000)" ] ; then
+ ebegin ">>> SetUID and SetGID: [chmod o-r] /${i#${D}}"
+ chmod o-r "$i"
+ eend $?
+ else
+ ebegin ">>> SetUID: [chmod go-r] /${i#${D}}"
+ chmod go-r "$i"
+ eend $?
+ fi
+ done
+ find "${D}" -type f -perm -2000 -print0 | \
+ while read -r -d $'\0' i ; do
+ if [ -n "$(find "$i" -perm -4000)" ] ; then
+ # This case is already handled
+ # by the SetUID check above.
+ true
+ else
+ ebegin ">>> SetGID: [chmod o-r] /${i#${D}}"
+ chmod o-r "$i"
+ eend $?
+ fi
+ done
+ fi
+}
+
+preinst_suid_scan() {
+ if [ -z "${D}" ]; then
+ eerror "${FUNCNAME}: D is unset"
+ return 1
+ fi
+ # total suid control.
+ if has suidctl $FEATURES; then
+ local i sfconf x
+ sfconf=${PORTAGE_CONFIGROOT}etc/portage/suidctl.conf
+ # sandbox prevents us from writing directly
+ # to files outside of the sandbox, but this
+ # can easly be bypassed using the addwrite() function
+ addwrite "${sfconf}"
+ vecho ">>> Performing suid scan in ${D}"
+ for i in $(find "${D}" -type f \( -perm -4000 -o -perm -2000 \) ); do
+ if [ -s "${sfconf}" ]; then
+ install_path=/${i#${D}}
+ if grep -q "^${install_path}\$" "${sfconf}" ; then
+ vecho "- ${install_path} is an approved suid file"
+ else
+ vecho ">>> Removing sbit on non registered ${install_path}"
+ for x in 5 4 3 2 1 0; do sleep 0.25 ; done
+ ls_ret=$(ls -ldh "${i}")
+ chmod ugo-s "${i}"
+ grep "^#${install_path}$" "${sfconf}" > /dev/null || {
+ vecho ">>> Appending commented out entry to ${sfconf} for ${PF}"
+ echo "## ${ls_ret%${D}*}${install_path}" >> "${sfconf}"
+ echo "#${install_path}" >> "${sfconf}"
+ # no delwrite() eh?
+ # delwrite ${sconf}
+ }
+ fi
+ else
+ vecho "suidctl feature set but you are lacking a ${sfconf}"
+ fi
+ done
+ fi
+}
+
+preinst_selinux_labels() {
+ if [ -z "${D}" ]; then
+ eerror "${FUNCNAME}: D is unset"
+ return 1
+ fi
+ if has selinux ${FEATURES}; then
+ # SELinux file labeling (needs to always be last in dyn_preinst)
+ # only attempt to label if setfiles is executable
+ # and 'context' is available on selinuxfs.
+ if [ -f /selinux/context -a -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then
+ vecho ">>> Setting SELinux security labels"
+ (
+ eval "$(/usr/sbin/selinuxconfig)" || \
+ die "Failed to determine SELinux policy paths.";
+
+ addwrite /selinux/context;
+
+ /usr/sbin/setfiles "${file_contexts_path}" -r "${D}" "${D}"
+ ) || die "Failed to set SELinux security labels."
+ else
+ # nonfatal, since merging can happen outside a SE kernel
+ # like during a recovery situation
+ vecho "!!! Unable to set SELinux security labels"
+ fi
+ fi
+}
+
+dyn_package() {
+ # Make sure $PWD is not ${D} so that we don't leave gmon.out files
+ # in there in case any tools were built with -pg in CFLAGS.
+ cd "${T}"
+ install_mask "${PORTAGE_BUILDDIR}/image" "${PKG_INSTALL_MASK}"
+ local tar_options=""
+ [[ $PORTAGE_VERBOSE = 1 ]] && tar_options+=" -v"
+ # Sandbox is disabled in case the user wants to use a symlink
+ # for $PKGDIR and/or $PKGDIR/All.
+ export SANDBOX_ON="0"
+ [ -z "${PORTAGE_BINPKG_TMPFILE}" ] && \
+ die "PORTAGE_BINPKG_TMPFILE is unset"
+ mkdir -p "${PORTAGE_BINPKG_TMPFILE%/*}" || die "mkdir failed"
+ tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS -C "${D}" . | \
+ $PORTAGE_BZIP2_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE"
+ assert "failed to pack binary package: '$PORTAGE_BINPKG_TMPFILE'"
+ PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/xpak-helper.py recompose \
+ "$PORTAGE_BINPKG_TMPFILE" "$PORTAGE_BUILDDIR/build-info"
+ if [ $? -ne 0 ]; then
+ rm -f "${PORTAGE_BINPKG_TMPFILE}"
+ die "Failed to append metadata to the tbz2 file"
+ fi
+ local md5_hash=""
+ if type md5sum &>/dev/null ; then
+ md5_hash=$(md5sum "${PORTAGE_BINPKG_TMPFILE}")
+ md5_hash=${md5_hash%% *}
+ elif type md5 &>/dev/null ; then
+ md5_hash=$(md5 "${PORTAGE_BINPKG_TMPFILE}")
+ md5_hash=${md5_hash##* }
+ fi
+ [ -n "${md5_hash}" ] && \
+ echo ${md5_hash} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5
+ vecho ">>> Done."
+ cd "${PORTAGE_BUILDDIR}"
+ >> "$PORTAGE_BUILDDIR/.packaged" || \
+ die "Failed to create $PORTAGE_BUILDDIR/.packaged"
+}
+
+dyn_spec() {
+ local sources_dir=/usr/src/rpm/SOURCES
+ mkdir -p "${sources_dir}"
+ declare -a tar_args=("${EBUILD}")
+ [[ -d ${FILESDIR} ]] && tar_args=("${EBUILD}" "${FILESDIR}")
+ tar czf "${sources_dir}/${PF}.tar.gz" \
+ "${tar_args[@]}" || \
+ die "Failed to create base rpm tarball."
+
+ cat <<__END1__ > ${PF}.spec
+Summary: ${DESCRIPTION}
+Name: ${PN}
+Version: ${PV}
+Release: ${PR}
+Copyright: GPL
+Group: portage/${CATEGORY}
+Source: ${PF}.tar.gz
+Buildroot: ${D}
+%description
+${DESCRIPTION}
+
+${HOMEPAGE}
+
+%prep
+%setup -c
+
+%build
+
+%install
+
+%clean
+
+%files
+/
+__END1__
+
+}
+
+dyn_rpm() {
+ cd "${T}" || die "cd failed"
+ local machine_name=$(uname -m)
+ local dest_dir=/usr/src/rpm/RPMS/${machine_name}
+ addwrite /usr/src/rpm
+ addwrite "${RPMDIR}"
+ dyn_spec
+ rpmbuild -bb --clean --rmsource "${PF}.spec" || die "Failed to integrate rpm spec file"
+ install -D "${dest_dir}/${PN}-${PV}-${PR}.${machine_name}.rpm" \
+ "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || \
+ die "Failed to move rpm"
+}
+
+die_hooks() {
+ [[ -f $PORTAGE_BUILDDIR/.die_hooks ]] && return
+ local x
+ for x in $EBUILD_DEATH_HOOKS ; do
+ $x >&2
+ done
+ > "$PORTAGE_BUILDDIR/.die_hooks"
+}
+
+success_hooks() {
+ local x
+ for x in $EBUILD_SUCCESS_HOOKS ; do
+ $x
+ done
+}
+
+if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then
+ source_all_bashrcs
+ [ "$PORTAGE_DEBUG" == "1" ] && set -x
+ for x in ${MISC_FUNCTIONS_ARGS}; do
+ ${x}
+ done
+ unset x
+ [[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
+ if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
+ [[ ! -s $SANDBOX_LOG ]]
+ "$PORTAGE_BIN_PATH"/ebuild-ipc exit $?
+ fi
+fi
+
+:
diff --git a/portage_with_autodep/bin/portageq b/portage_with_autodep/bin/portageq
new file mode 100755
index 0000000..57a7c39
--- /dev/null
+++ b/portage_with_autodep/bin/portageq
@@ -0,0 +1,822 @@
+#!/usr/bin/python -O
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import signal
+import sys
+# This block ensures that ^C interrupts are handled quietly.
+try:
+
+ def exithandler(signum, frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ signal.signal(signal.SIGTERM, signal.SIG_IGN)
+ sys.exit(128 + signum)
+
+ signal.signal(signal.SIGINT, exithandler)
+ signal.signal(signal.SIGTERM, exithandler)
+
+except KeyboardInterrupt:
+ sys.exit(128 + signal.SIGINT)
+
+import os
+import types
+
+# Avoid sandbox violations after python upgrade.
+pym_path = os.path.join(os.path.dirname(
+ os.path.dirname(os.path.realpath(__file__))), "pym")
+if os.environ.get("SANDBOX_ON") == "1":
+ sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":")
+ if pym_path not in sandbox_write:
+ sandbox_write.append(pym_path)
+ os.environ["SANDBOX_WRITE"] = \
+ ":".join(filter(None, sandbox_write))
+ del sandbox_write
+
+try:
+ import portage
+except ImportError:
+ sys.path.insert(0, pym_path)
+ import portage
+del pym_path
+
+from portage import os
+from portage.util import writemsg, writemsg_stdout
+portage.proxy.lazyimport.lazyimport(globals(),
+ 'subprocess',
+ '_emerge.Package:Package',
+ '_emerge.RootConfig:RootConfig',
+ 'portage.dbapi._expand_new_virt:expand_new_virt',
+)
+
+def eval_atom_use(atom):
+ if 'USE' in os.environ:
+ use = frozenset(os.environ['USE'].split())
+ atom = atom.evaluate_conditionals(use)
+ return atom
+
+#-----------------------------------------------------------------------------
+#
+# To add functionality to this tool, add a function below.
+#
+# The format for functions is:
+#
+# def function(argv):
+# """<list of options for this function>
+# <description of the function>
+# """
+# <code>
+#
+# "argv" is an array of the command line parameters provided after the command.
+#
+# Make sure you document the function in the right format. The documentation
+# is used to display help on the function.
+#
+# You do not need to add the function to any lists, this tool is introspective,
+# and will automaticly add a command by the same name as the function!
+#
+
+def has_version(argv):
+ """<root> <category/package>
+ Return code 0 if it's available, 1 otherwise.
+ """
+ if (len(argv) < 2):
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+
+ warnings = []
+
+ try:
+ atom = portage.dep.Atom(argv[1])
+ except portage.exception.InvalidAtom:
+ if atom_validate_strict:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
+ else:
+ atom = argv[1]
+ else:
+ if atom_validate_strict:
+ try:
+ atom = portage.dep.Atom(argv[1], eapi=eapi)
+ except portage.exception.InvalidAtom as e:
+ warnings.append(
+ portage._unicode_decode("QA Notice: %s: %s") % \
+ ('has_version', e))
+ atom = eval_atom_use(atom)
+
+ if warnings:
+ elog('eqawarn', warnings)
+
+ try:
+ mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
+ if mylist:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+ except KeyError:
+ sys.exit(1)
+ except portage.exception.InvalidAtom:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
+has_version.uses_root = True
+
+
+def best_version(argv):
+ """<root> <category/package>
+ Returns category/package-version (without .ebuild).
+ """
+ if (len(argv) < 2):
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+
+ warnings = []
+
+ try:
+ atom = portage.dep.Atom(argv[1])
+ except portage.exception.InvalidAtom:
+ if atom_validate_strict:
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
+ noiselevel=-1)
+ return 2
+ else:
+ atom = argv[1]
+ else:
+ if atom_validate_strict:
+ try:
+ atom = portage.dep.Atom(argv[1], eapi=eapi)
+ except portage.exception.InvalidAtom as e:
+ warnings.append(
+ portage._unicode_decode("QA Notice: %s: %s") % \
+ ('best_version', e))
+ atom = eval_atom_use(atom)
+
+ if warnings:
+ elog('eqawarn', warnings)
+
+ try:
+ mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom)
+ print(portage.best(mylist))
+ except KeyError:
+ sys.exit(1)
+best_version.uses_root = True
+
+
+def mass_best_version(argv):
+ """<root> [<category/package>]+
+ Returns category/package-version (without .ebuild).
+ """
+ if (len(argv) < 2):
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ try:
+ for pack in argv[1:]:
+ mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
+ print(pack+":"+portage.best(mylist))
+ except KeyError:
+ sys.exit(1)
+mass_best_version.uses_root = True
+
+def metadata(argv):
+ if (len(argv) < 4):
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ sys.exit(2)
+
+ root, pkgtype, pkgspec = argv[0:3]
+ metakeys = argv[3:]
+ type_map = {
+ "ebuild":"porttree",
+ "binary":"bintree",
+ "installed":"vartree"}
+ if pkgtype not in type_map:
+ print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
+ sys.exit(1)
+ trees = portage.db
+ if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]):
+ root = portage.settings["ROOT"] # contains the normalized $ROOT
+ try:
+ values = trees[root][type_map[pkgtype]].dbapi.aux_get(
+ pkgspec, metakeys)
+ writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
+ except KeyError:
+ print("Package not found: '%s'" % pkgspec, file=sys.stderr)
+ sys.exit(1)
+
+metadata.__doc__ = """
+<root> <pkgtype> <category/package> [<key>]+
+Returns metadata values for the specified package.
+Available keys: %s
+""" % ','.join(sorted(x for x in portage.auxdbkeys \
+if not x.startswith('UNUSED_')))
+
+metadata.uses_root = True
+
+def contents(argv):
+ """<root> <category/package>
+ List the files that are installed for a given package, with
+ one file listed on each line. All file names will begin with
+ <root>.
+ """
+ if len(argv) != 2:
+ print("ERROR: expected 2 parameters, got %d!" % len(argv))
+ return 2
+
+ root, cpv = argv
+ vartree = portage.db[root]["vartree"]
+ if not vartree.dbapi.cpv_exists(cpv):
+ sys.stderr.write("Package not found: '%s'\n" % cpv)
+ return 1
+ cat, pkg = portage.catsplit(cpv)
+ db = portage.dblink(cat, pkg, root, vartree.settings,
+ treetype="vartree", vartree=vartree)
+ writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
+ noiselevel=-1)
+contents.uses_root = True
+
+def owners(argv):
+ """<root> [<filename>]+
+ Given a list of files, print the packages that own the files and which
+ files belong to each package. Files owned by a package are listed on
+ the lines below it, indented by a single tab character (\\t). All file
+ paths must either start with <root> or be a basename alone.
+ Returns 1 if no owners could be found, and 0 otherwise.
+ """
+ if len(argv) < 2:
+ sys.stderr.write("ERROR: insufficient parameters!\n")
+ sys.stderr.flush()
+ return 2
+
+ from portage import catsplit, dblink
+ settings = portage.settings
+ root = settings["ROOT"]
+ vardb = portage.db[root]["vartree"].dbapi
+
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ files = []
+ orphan_abs_paths = set()
+ orphan_basenames = set()
+ for f in argv[1:]:
+ f = portage.normalize_path(f)
+ is_basename = os.sep not in f
+ if not is_basename and f[:1] != os.sep:
+ if cwd is None:
+ sys.stderr.write("ERROR: cwd does not exist!\n")
+ sys.stderr.flush()
+ return 2
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+ if not is_basename and not f.startswith(root):
+ sys.stderr.write("ERROR: file paths must begin with <root>!\n")
+ sys.stderr.flush()
+ return 2
+ if is_basename:
+ files.append(f)
+ orphan_basenames.add(f)
+ else:
+ files.append(f[len(root)-1:])
+ orphan_abs_paths.add(f)
+
+ owners = vardb._owners.get_owners(files)
+
+ msg = []
+ for pkg, owned_files in owners.items():
+ cpv = pkg.mycpv
+ msg.append("%s\n" % cpv)
+ for f in sorted(owned_files):
+ f_abs = os.path.join(root, f.lstrip(os.path.sep))
+ msg.append("\t%s\n" % (f_abs,))
+ orphan_abs_paths.discard(f_abs)
+ if orphan_basenames:
+ orphan_basenames.discard(os.path.basename(f_abs))
+
+ writemsg_stdout(''.join(msg), noiselevel=-1)
+
+ if orphan_abs_paths or orphan_basenames:
+ orphans = []
+ orphans.extend(orphan_abs_paths)
+ orphans.extend(orphan_basenames)
+ orphans.sort()
+ msg = []
+ msg.append("None of the installed packages claim these files:\n")
+ for f in orphans:
+ msg.append("\t%s\n" % (f,))
+ sys.stderr.write("".join(msg))
+ sys.stderr.flush()
+
+ if owners:
+ return 0
+ return 1
+
+owners.uses_root = True
+
+def is_protected(argv):
+ """<root> <filename>
+ Given a single filename, return code 0 if it's protected, 1 otherwise.
+ The filename must begin with <root>.
+ """
+ if len(argv) != 2:
+ sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv))
+ sys.stderr.flush()
+ return 2
+
+ root, filename = argv
+
+ err = sys.stderr
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ f = portage.normalize_path(filename)
+ if not f.startswith(os.path.sep):
+ if cwd is None:
+ err.write("ERROR: cwd does not exist!\n")
+ err.flush()
+ return 2
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+
+ if not f.startswith(root):
+ err.write("ERROR: file paths must begin with <root>!\n")
+ err.flush()
+ return 2
+
+ from portage.util import ConfigProtect
+
+ settings = portage.settings
+ protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
+ protect_mask = portage.util.shlex_split(
+ settings.get("CONFIG_PROTECT_MASK", ""))
+ protect_obj = ConfigProtect(root, protect, protect_mask)
+
+ if protect_obj.isprotected(f):
+ return 0
+ return 1
+
+is_protected.uses_root = True
+
+def filter_protected(argv):
+ """<root>
+ Read filenames from stdin and write them to stdout if they are protected.
+ All filenames are delimited by \\n and must begin with <root>.
+ """
+ if len(argv) != 1:
+ sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv))
+ sys.stderr.flush()
+ return 2
+
+ root, = argv
+ out = sys.stdout
+ err = sys.stderr
+ cwd = None
+ try:
+ cwd = os.getcwd()
+ except OSError:
+ pass
+
+ from portage.util import ConfigProtect
+
+ settings = portage.settings
+ protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", ""))
+ protect_mask = portage.util.shlex_split(
+ settings.get("CONFIG_PROTECT_MASK", ""))
+ protect_obj = ConfigProtect(root, protect, protect_mask)
+
+ protected = 0
+ errors = 0
+
+ for line in sys.stdin:
+ filename = line.rstrip("\n")
+ f = portage.normalize_path(filename)
+ if not f.startswith(os.path.sep):
+ if cwd is None:
+ err.write("ERROR: cwd does not exist!\n")
+ err.flush()
+ errors += 1
+ continue
+ f = os.path.join(cwd, f)
+ f = portage.normalize_path(f)
+
+ if not f.startswith(root):
+ err.write("ERROR: file paths must begin with <root>!\n")
+ err.flush()
+ errors += 1
+ continue
+
+ if protect_obj.isprotected(f):
+ protected += 1
+ out.write("%s\n" % filename)
+ out.flush()
+
+ if errors:
+ return 2
+
+ return 0
+
+filter_protected.uses_root = True
+
+def best_visible(argv):
+ """<root> [pkgtype] <atom>
+ Returns category/package-version (without .ebuild).
+ The pkgtype argument defaults to "ebuild" if unspecified,
+ otherwise it must be one of ebuild, binary, or installed.
+ """
+ if (len(argv) < 2):
+ writemsg("ERROR: insufficient parameters!\n", noiselevel=-1)
+ return 2
+
+ pkgtype = "ebuild"
+ if len(argv) > 2:
+ pkgtype = argv[1]
+ atom = argv[2]
+ else:
+ atom = argv[1]
+
+ type_map = {
+ "ebuild":"porttree",
+ "binary":"bintree",
+ "installed":"vartree"}
+
+ if pkgtype not in type_map:
+ writemsg("Unrecognized package type: '%s'\n" % pkgtype,
+ noiselevel=-1)
+ return 2
+
+ db = portage.db[portage.settings["ROOT"]][type_map[pkgtype]].dbapi
+
+ try:
+ atom = portage.dep_expand(atom, mydb=db, settings=portage.settings)
+ except portage.exception.InvalidAtom:
+ writemsg("ERROR: Invalid atom: '%s'\n" % atom,
+ noiselevel=-1)
+ return 2
+
+ root_config = RootConfig(portage.settings,
+ portage.db[portage.settings["ROOT"]], None)
+
+ try:
+ # reversed, for descending order
+ for cpv in reversed(db.match(atom)):
+ metadata = dict(zip(Package.metadata_keys,
+ db.aux_get(cpv, Package.metadata_keys, myrepo=atom.repo)))
+ pkg = Package(built=(pkgtype != "ebuild"), cpv=cpv,
+ installed=(pkgtype=="installed"), metadata=metadata,
+ root_config=root_config, type_name=pkgtype)
+ if pkg.visible:
+ writemsg_stdout("%s\n" % (pkg.cpv,), noiselevel=-1)
+ return os.EX_OK
+ except KeyError:
+ pass
+ return 1
+best_visible.uses_root = True
+
+
+def mass_best_visible(argv):
+ """<root> [<category/package>]+
+ Returns category/package-version (without .ebuild).
+ """
+ if (len(argv) < 2):
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ try:
+ for pack in argv[1:]:
+ mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack)
+ print(pack+":"+portage.best(mylist))
+ except KeyError:
+ sys.exit(1)
+mass_best_visible.uses_root = True
+
+
+def all_best_visible(argv):
+ """<root>
+ Returns all best_visible packages (without .ebuild).
+ """
+ if len(argv) < 1:
+ sys.stderr.write("ERROR: insufficient parameters!\n")
+ sys.stderr.flush()
+ return 2
+
+ #print portage.db[argv[0]]["porttree"].dbapi.cp_all()
+ for pkg in portage.db[argv[0]]["porttree"].dbapi.cp_all():
+ mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
+ if mybest:
+ print(mybest)
+all_best_visible.uses_root = True
+
+
+def match(argv):
+ """<root> <atom>
+ Returns a \\n separated list of category/package-version.
+ When given an empty string, all installed packages will
+ be listed.
+ """
+ if len(argv) != 2:
+ print("ERROR: expected 2 parameters, got %d!" % len(argv))
+ sys.exit(2)
+ root, atom = argv
+ if atom:
+ if atom_validate_strict and not portage.isvalidatom(atom):
+ portage.writemsg("ERROR: Invalid atom: '%s'\n" % atom,
+ noiselevel=-1)
+ return 2
+ results = portage.db[root]["vartree"].dbapi.match(atom)
+ else:
+ results = portage.db[root]["vartree"].dbapi.cpv_all()
+ results.sort()
+ for cpv in results:
+ print(cpv)
+match.uses_root = True
+
+def expand_virtual(argv):
+ """<root> <atom>
+ Returns a \\n separated list of atoms expanded from a
+ given virtual atom (GLEP 37 virtuals only),
+ excluding blocker atoms. Satisfied
+ virtual atoms are not included in the output, since
+ they are expanded to real atoms which are displayed.
+ Unsatisfied virtual atoms are displayed without
+ any expansion. The "match" command can be used to
+ resolve the returned atoms to specific installed
+ packages.
+ """
+ if len(argv) != 2:
+ writemsg("ERROR: expected 2 parameters, got %d!\n" % len(argv),
+ noiselevel=-1)
+ return 2
+
+ root, atom = argv
+
+ try:
+ results = list(expand_new_virt(
+ portage.db[root]["vartree"].dbapi, atom))
+ except portage.exception.InvalidAtom:
+ writemsg("ERROR: Invalid atom: '%s'\n" % atom,
+ noiselevel=-1)
+ return 2
+
+ results.sort()
+ for x in results:
+ if not x.blocker:
+ writemsg_stdout("%s\n" % (x,))
+
+ return os.EX_OK
+
+expand_virtual.uses_root = True
+
+def vdb_path(argv):
+ """
+ Returns the path used for the var(installed) package database for the
+ set environment/configuration options.
+ """
+ out = sys.stdout
+ out.write(os.path.join(portage.settings["EROOT"], portage.VDB_PATH) + "\n")
+ out.flush()
+ return os.EX_OK
+
+def gentoo_mirrors(argv):
+ """
+ Returns the mirrors set to use in the portage configuration.
+ """
+ print(portage.settings["GENTOO_MIRRORS"])
+
+
+def portdir(argv):
+ """
+ Returns the PORTDIR path.
+ """
+ print(portage.settings["PORTDIR"])
+
+
+def config_protect(argv):
+ """
+ Returns the CONFIG_PROTECT paths.
+ """
+ print(portage.settings["CONFIG_PROTECT"])
+
+
+def config_protect_mask(argv):
+ """
+ Returns the CONFIG_PROTECT_MASK paths.
+ """
+ print(portage.settings["CONFIG_PROTECT_MASK"])
+
+
+def portdir_overlay(argv):
+ """
+ Returns the PORTDIR_OVERLAY path.
+ """
+ print(portage.settings["PORTDIR_OVERLAY"])
+
+
+def pkgdir(argv):
+ """
+ Returns the PKGDIR path.
+ """
+ print(portage.settings["PKGDIR"])
+
+
+def distdir(argv):
+ """
+ Returns the DISTDIR path.
+ """
+ print(portage.settings["DISTDIR"])
+
+
+def envvar(argv):
+ """<variable>+
+ Returns a specific environment variable as exists prior to ebuild.sh.
+ Similar to: emerge --verbose --info | egrep '^<variable>='
+ """
+ verbose = "-v" in argv
+ if verbose:
+ argv.pop(argv.index("-v"))
+
+ if len(argv) == 0:
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+
+ for arg in argv:
+ if verbose:
+ print(arg +"='"+ portage.settings[arg] +"'")
+ else:
+ print(portage.settings[arg])
+
+def get_repos(argv):
+ """<root>
+ Returns all repos with names (repo_name file) argv[0] = $ROOT
+ """
+ if len(argv) < 1:
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ print(" ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories()))
+
+def get_repo_path(argv):
+ """<root> <repo_id>+
+ Returns the path to the repo named argv[1], argv[0] = $ROOT
+ """
+ if len(argv) < 2:
+ print("ERROR: insufficient parameters!")
+ sys.exit(2)
+ for arg in argv[1:]:
+ path = portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg)
+ if path is None:
+ path = ""
+ print(path)
+
+def list_preserved_libs(argv):
+ """<root>
+ Print a list of libraries preserved during a package update in the form
+ package: path. Returns 1 if no preserved libraries could be found,
+ 0 otherwise.
+ """
+
+ if len(argv) != 1:
+ print("ERROR: wrong number of arguments")
+ sys.exit(2)
+ mylibs = portage.db[argv[0]]["vartree"].dbapi._plib_registry.getPreservedLibs()
+ rValue = 1
+ msg = []
+ for cpv in sorted(mylibs):
+ msg.append(cpv)
+ for path in mylibs[cpv]:
+ msg.append(' ' + path)
+ rValue = 0
+ msg.append('\n')
+ writemsg_stdout(''.join(msg), noiselevel=-1)
+ return rValue
+list_preserved_libs.uses_root = True
+
+#-----------------------------------------------------------------------------
+#
+# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
+#
+
+if not portage.const._ENABLE_PRESERVE_LIBS:
+ del list_preserved_libs
+
+non_commands = frozenset(['elog', 'eval_atom_use',
+ 'exithandler', 'expand_new_virt', 'main',
+ 'usage', 'writemsg', 'writemsg_stdout'])
+commands = sorted(k for k, v in globals().items() \
+ if k not in non_commands and isinstance(v, types.FunctionType))
+
+def usage(argv):
+ print(">>> Portage information query tool")
+ print(">>> %s" % portage.VERSION)
+ print(">>> Usage: portageq <command> [<option> ...]")
+ print("")
+ print("Available commands:")
+
+ #
+ # Show our commands -- we do this by scanning the functions in this
+ # file, and formatting each functions documentation.
+ #
+ help_mode = '--help' in sys.argv
+ for name in commands:
+ # Drop non-functions
+ obj = globals()[name]
+
+ doc = obj.__doc__
+ if (doc == None):
+ print(" " + name)
+ print(" MISSING DOCUMENTATION!")
+ print("")
+ continue
+
+ lines = doc.lstrip("\n").split("\n")
+ print(" " + name + " " + lines[0].strip())
+ if (len(sys.argv) > 1):
+ if (not help_mode):
+ lines = lines[:-1]
+ for line in lines[1:]:
+ print(" " + line.strip())
+ if (len(sys.argv) == 1):
+ print("\nRun portageq with --help for info")
+
+atom_validate_strict = "EBUILD_PHASE" in os.environ
+eapi = None
+if atom_validate_strict:
+ eapi = os.environ.get('EAPI')
+
+ def elog(elog_funcname, lines):
+ cmd = "source '%s/isolated-functions.sh' ; " % \
+ os.environ["PORTAGE_BIN_PATH"]
+ for line in lines:
+ cmd += "%s %s ; " % (elog_funcname, portage._shell_quote(line))
+ subprocess.call([portage.const.BASH_BINARY, "-c", cmd])
+
+else:
+ def elog(elog_funcname, lines):
+ pass
+
+def main():
+
+ nocolor = os.environ.get('NOCOLOR')
+ if nocolor in ('yes', 'true'):
+ portage.output.nocolor()
+
+ if len(sys.argv) < 2:
+ usage(sys.argv)
+ sys.exit(os.EX_USAGE)
+
+ for x in sys.argv:
+ if x in ("-h", "--help"):
+ usage(sys.argv)
+ sys.exit(os.EX_OK)
+ elif x == "--version":
+ print("Portage", portage.VERSION)
+ sys.exit(os.EX_OK)
+
+ cmd = sys.argv[1]
+ function = globals().get(cmd)
+ if function is None or cmd not in commands:
+ usage(sys.argv)
+ sys.exit(os.EX_USAGE)
+ function = globals()[cmd]
+ uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
+ if uses_root:
+ if not os.path.isdir(sys.argv[2]):
+ sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
+ sys.stderr.write("Run portageq with --help for info\n")
+ sys.stderr.flush()
+ sys.exit(os.EX_USAGE)
+ os.environ["ROOT"] = sys.argv[2]
+
+ args = sys.argv[2:]
+ if args and sys.hexversion < 0x3000000 and not isinstance(args[0], unicode):
+ for i in range(len(args)):
+ args[i] = portage._unicode_decode(args[i])
+
+ try:
+ if uses_root:
+ args[0] = portage.settings["ROOT"]
+ retval = function(args)
+ if retval:
+ sys.exit(retval)
+ except portage.exception.PermissionDenied as e:
+ sys.stderr.write("Permission denied: '%s'\n" % str(e))
+ sys.exit(e.errno)
+ except portage.exception.ParseError as e:
+ sys.stderr.write("%s\n" % str(e))
+ sys.exit(1)
+ except portage.exception.AmbiguousPackageName as e:
+ # Multiple matches thrown from cpv_expand
+ pkgs = e.args[0]
+ # An error has occurred so we writemsg to stderr and exit nonzero.
+ portage.writemsg("You specified an unqualified atom that matched multiple packages:\n", noiselevel=-1)
+ for pkg in pkgs:
+ portage.writemsg("* %s\n" % pkg, noiselevel=-1)
+ portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
+ sys.exit(1)
+
+main()
+
+#-----------------------------------------------------------------------------
diff --git a/portage_with_autodep/bin/quickpkg b/portage_with_autodep/bin/quickpkg
new file mode 100755
index 0000000..09723f5
--- /dev/null
+++ b/portage_with_autodep/bin/quickpkg
@@ -0,0 +1,291 @@
+#!/usr/bin/python
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import errno
+import math
+import optparse
+import signal
+import sys
+import tarfile
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage import xpak
+from portage.dbapi.dep_expand import dep_expand
+from portage.dep import use_reduce
+from portage.exception import InvalidAtom, InvalidData, InvalidDependString, \
+ PackageSetNotFound, PermissionDenied
+from portage.util import ConfigProtect, ensure_dirs, shlex_split
+from portage.dbapi.vartree import dblink, tar_contents
+from portage.checksum import perform_md5
+from portage._sets import load_default_config, SETPREFIX
+
+def quickpkg_atom(options, infos, arg, eout):
+ settings = portage.settings
+ root = portage.settings["ROOT"]
+ trees = portage.db[root]
+ vartree = trees["vartree"]
+ vardb = vartree.dbapi
+ bintree = trees["bintree"]
+
+ include_config = options.include_config == "y"
+ include_unmodified_config = options.include_unmodified_config == "y"
+ fix_metadata_keys = ["PF", "CATEGORY"]
+
+ try:
+ atom = dep_expand(arg, mydb=vardb, settings=vartree.settings)
+ except ValueError as e:
+ # Multiple matches thrown from cpv_expand
+ eout.eerror("Please use a more specific atom: %s" % \
+ " ".join(e.args[0]))
+ del e
+ infos["missing"].append(arg)
+ return
+ except (InvalidAtom, InvalidData):
+ eout.eerror("Invalid atom: %s" % (arg,))
+ infos["missing"].append(arg)
+ return
+ if atom[:1] == '=' and arg[:1] != '=':
+ # dep_expand() allows missing '=' but it's really invalid
+ eout.eerror("Invalid atom: %s" % (arg,))
+ infos["missing"].append(arg)
+ return
+
+ matches = vardb.match(atom)
+ pkgs_for_arg = 0
+ for cpv in matches:
+ excluded_config_files = []
+ bintree.prevent_collision(cpv)
+ cat, pkg = portage.catsplit(cpv)
+ dblnk = dblink(cat, pkg, root,
+ vartree.settings, treetype="vartree",
+ vartree=vartree)
+ have_lock = False
+ try:
+ dblnk.lockdb()
+ have_lock = True
+ except PermissionDenied:
+ pass
+ try:
+ if not dblnk.exists():
+ # unmerged by a concurrent process
+ continue
+ iuse, use, restrict = vardb.aux_get(cpv,
+ ["IUSE","USE","RESTRICT"])
+ iuse = [ x.lstrip("+-") for x in iuse.split() ]
+ use = use.split()
+ try:
+ restrict = use_reduce(restrict, uselist=use, flat=True)
+ except InvalidDependString as e:
+ eout.eerror("Invalid RESTRICT metadata " + \
+ "for '%s': %s; skipping" % (cpv, str(e)))
+ del e
+ continue
+ if "bindist" in iuse and "bindist" not in use:
+ eout.ewarn("%s: package was emerged with USE=-bindist!" % cpv)
+ eout.ewarn("%s: it might not be legal to redistribute this." % cpv)
+ elif "bindist" in restrict:
+ eout.ewarn("%s: package has RESTRICT=bindist!" % cpv)
+ eout.ewarn("%s: it might not be legal to redistribute this." % cpv)
+ eout.ebegin("Building package for %s" % cpv)
+ pkgs_for_arg += 1
+ contents = dblnk.getcontents()
+ protect = None
+ if not include_config:
+ confprot = ConfigProtect(root,
+ shlex_split(settings.get("CONFIG_PROTECT", "")),
+ shlex_split(settings.get("CONFIG_PROTECT_MASK", "")))
+ def protect(filename):
+ if not confprot.isprotected(filename):
+ return False
+ if include_unmodified_config:
+ file_data = contents[filename]
+ if file_data[0] == "obj":
+ orig_md5 = file_data[2].lower()
+ cur_md5 = perform_md5(filename, calc_prelink=1)
+ if orig_md5 == cur_md5:
+ return False
+ excluded_config_files.append(filename)
+ return True
+ existing_metadata = dict(zip(fix_metadata_keys,
+ vardb.aux_get(cpv, fix_metadata_keys)))
+ category, pf = portage.catsplit(cpv)
+ required_metadata = {}
+ required_metadata["CATEGORY"] = category
+ required_metadata["PF"] = pf
+ update_metadata = {}
+ for k, v in required_metadata.items():
+ if v != existing_metadata[k]:
+ update_metadata[k] = v
+ if update_metadata:
+ vardb.aux_update(cpv, update_metadata)
+ xpdata = xpak.xpak(dblnk.dbdir)
+ binpkg_tmpfile = os.path.join(bintree.pkgdir,
+ cpv + ".tbz2." + str(os.getpid()))
+ ensure_dirs(os.path.dirname(binpkg_tmpfile))
+ tar = tarfile.open(binpkg_tmpfile, "w:bz2")
+ tar_contents(contents, root, tar, protect=protect)
+ tar.close()
+ xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata)
+ finally:
+ if have_lock:
+ dblnk.unlockdb()
+ bintree.inject(cpv, filename=binpkg_tmpfile)
+ binpkg_path = bintree.getname(cpv)
+ try:
+ s = os.stat(binpkg_path)
+ except OSError as e:
+ # Sanity check, shouldn't happen normally.
+ eout.eend(1)
+ eout.eerror(str(e))
+ del e
+ eout.eerror("Failed to create package: '%s'" % binpkg_path)
+ else:
+ eout.eend(0)
+ infos["successes"].append((cpv, s.st_size))
+ infos["config_files_excluded"] += len(excluded_config_files)
+ for filename in excluded_config_files:
+ eout.ewarn("Excluded config: '%s'" % filename)
+ if not pkgs_for_arg:
+ eout.eerror("Could not find anything " + \
+ "to match '%s'; skipping" % arg)
+ infos["missing"].append(arg)
+
+def quickpkg_set(options, infos, arg, eout):
+ root = portage.settings["ROOT"]
+ trees = portage.db[root]
+ vartree = trees["vartree"]
+
+ settings = vartree.settings
+ settings._init_dirs()
+ setconfig = load_default_config(settings, trees)
+ sets = setconfig.getSets()
+
+ set = arg[1:]
+ if not set in sets:
+ eout.eerror("Package set not found: '%s'; skipping" % (arg,))
+ infos["missing"].append(arg)
+ return
+
+ try:
+ atoms = setconfig.getSetAtoms(set)
+ except PackageSetNotFound as e:
+ eout.eerror("Failed to process package set '%s' because " % set +
+ "it contains the non-existent package set '%s'; skipping" % e)
+ infos["missing"].append(arg)
+ return
+
+ for atom in atoms:
+ quickpkg_atom(options, infos, atom, eout)
+
+def quickpkg_main(options, args, eout):
+ root = portage.settings["ROOT"]
+ trees = portage.db[root]
+ bintree = trees["bintree"]
+
+ try:
+ ensure_dirs(bintree.pkgdir)
+ except portage.exception.PortageException:
+ pass
+ if not os.access(bintree.pkgdir, os.W_OK):
+ eout.eerror("No write access to '%s'" % bintree.pkgdir)
+ return errno.EACCES
+
+ infos = {}
+ infos["successes"] = []
+ infos["missing"] = []
+ infos["config_files_excluded"] = 0
+ for arg in args:
+ if arg[0] == SETPREFIX:
+ quickpkg_set(options, infos, arg, eout)
+ else:
+ quickpkg_atom(options, infos, arg, eout)
+
+ if not infos["successes"]:
+ eout.eerror("No packages found")
+ return 1
+ print()
+ eout.einfo("Packages now in '%s':" % bintree.pkgdir)
+ units = {10:'K', 20:'M', 30:'G', 40:'T',
+ 50:'P', 60:'E', 70:'Z', 80:'Y'}
+ for cpv, size in infos["successes"]:
+ if not size:
+ # avoid OverflowError in math.log()
+ size_str = "0"
+ else:
+ power_of_2 = math.log(size, 2)
+ power_of_2 = 10*int(power_of_2/10)
+ unit = units.get(power_of_2)
+ if unit:
+ size = float(size)/(2**power_of_2)
+ size_str = "%.1f" % size
+ if len(size_str) > 4:
+ # emulate `du -h`, don't show too many sig figs
+ size_str = str(int(size))
+ size_str += unit
+ else:
+ size_str = str(size)
+ eout.einfo("%s: %s" % (cpv, size_str))
+ if infos["config_files_excluded"]:
+ print()
+ eout.ewarn("Excluded config files: %d" % infos["config_files_excluded"])
+ eout.ewarn("See --help if you would like to include config files.")
+ if infos["missing"]:
+ print()
+ eout.ewarn("The following packages could not be found:")
+ eout.ewarn(" ".join(infos["missing"]))
+ return 2
+ return os.EX_OK
+
+if __name__ == "__main__":
+ usage = "quickpkg [options] <list of package atoms or package sets>"
+ parser = optparse.OptionParser(usage=usage)
+ parser.add_option("--umask",
+ default="0077",
+ help="umask used during package creation (default is 0077)")
+ parser.add_option("--ignore-default-opts",
+ action="store_true",
+ help="do not use the QUICKPKG_DEFAULT_OPTS environment variable")
+ parser.add_option("--include-config",
+ type="choice",
+ choices=["y","n"],
+ default="n",
+ metavar="<y|n>",
+ help="include all files protected by CONFIG_PROTECT (as a security precaution, default is 'n')")
+ parser.add_option("--include-unmodified-config",
+ type="choice",
+ choices=["y","n"],
+ default="n",
+ metavar="<y|n>",
+ help="include files protected by CONFIG_PROTECT that have not been modified since installation (as a security precaution, default is 'n')")
+ options, args = parser.parse_args(sys.argv[1:])
+ if not options.ignore_default_opts:
+ default_opts = portage.settings.get("QUICKPKG_DEFAULT_OPTS","").split()
+ options, args = parser.parse_args(default_opts + sys.argv[1:])
+ if not args:
+ parser.error("no packages atoms given")
+ try:
+ umask = int(options.umask, 8)
+ except ValueError:
+ parser.error("invalid umask: %s" % options.umask)
+ # We need to ensure a sane umask for the packages that will be created.
+ old_umask = os.umask(umask)
+ eout = portage.output.EOutput()
+ def sigwinch_handler(signum, frame):
+ lines, eout.term_columns = portage.output.get_term_size()
+ signal.signal(signal.SIGWINCH, sigwinch_handler)
+ try:
+ retval = quickpkg_main(options, args, eout)
+ finally:
+ os.umask(old_umask)
+ signal.signal(signal.SIGWINCH, signal.SIG_DFL)
+ sys.exit(retval)
diff --git a/portage_with_autodep/bin/regenworld b/portage_with_autodep/bin/regenworld
new file mode 100755
index 0000000..6b5af4c
--- /dev/null
+++ b/portage_with_autodep/bin/regenworld
@@ -0,0 +1,144 @@
+#!/usr/bin/python
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from __future__ import print_function
+
+import sys
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+
+from portage import os
+from portage._sets.files import StaticFileSet, WorldSelectedSet
+
+import re
+import tempfile
+import textwrap
+
+__candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ")
+__noncandidatematcher__ = re.compile(" sync( |$)| clean( |$)| search( |$)|--oneshot|--fetchonly| unmerge( |$)")
+
+def issyspkg(pkgline):
+ return (pkgline[0] == "*")
+
+def iscandidate(logline):
+ return (__candidatematcher__.match(logline) \
+ and not __noncandidatematcher__.search(logline))
+
+def getpkginfo(logline):
+ logline = re.sub("^[0-9]+: \\*\\*\\* emerge ", "", logline)
+ logline = logline.strip()
+ logline = re.sub("(\\S+\\.(ebuild|tbz2))|(--\\S+)|inject ", "", logline)
+ return logline.strip()
+
+__uniqlist__ = []
+def isunwanted(pkgline):
+ if pkgline in ["world", "system", "depclean", "info", "regen", ""]:
+ return False
+ elif pkgline in __uniqlist__:
+ return False
+ elif not re.search("^[a-zA-Z<>=~]", pkgline):
+ return False
+ else:
+ __uniqlist__.append(pkgline)
+ return True
+
+root = portage.settings['ROOT']
+eroot = portage.settings['EROOT']
+world_file = os.path.join(eroot, portage.WORLD_FILE)
+
+# show a little description if we have arguments
+if len(sys.argv) >= 2 and sys.argv[1] in ["-h", "--help"]:
+ print("This script regenerates the portage world file by checking the portage")
+ print("logfile for all actions that you've done in the past. It ignores any")
+ print("arguments except --help. It is recommended that you make a backup of")
+ print("your existing world file (%s) before using this tool." % world_file)
+ sys.exit(0)
+
+worldlist = portage.grabfile(world_file)
+syslist = [x for x in portage.settings.packages if issyspkg(x)]
+
+logfile = portage.grabfile(os.path.join(eroot, "var/log/emerge.log"))
+biglist = [getpkginfo(x) for x in logfile if iscandidate(x)]
+tmplist = []
+for l in biglist:
+ tmplist += l.split()
+biglist = [x for x in tmplist if isunwanted(x)]
+#for p in biglist:
+# print(p)
+#sys.exit(0)
+
+# resolving virtuals
+realsyslist = []
+for mykey in syslist:
+ # drop the asterix
+ mykey = mykey[1:]
+ #print("candidate:",mykey)
+ mylist = portage.db[root]["vartree"].dbapi.match(mykey)
+ if mylist:
+ mykey=portage.cpv_getkey(mylist[0])
+ if mykey not in realsyslist:
+ realsyslist.append(mykey)
+
+for mykey in biglist:
+ #print("checking:",mykey)
+ try:
+ mylist = portage.db[root]["vartree"].dbapi.match(mykey)
+ except (portage.exception.InvalidAtom, KeyError):
+ if "--debug" in sys.argv:
+ print("* ignoring broken log entry for %s (likely injected)" % mykey)
+ except ValueError as e:
+ try:
+ print("* %s is an ambiguous package name, candidates are:\n%s" % (mykey, e))
+ except AttributeError:
+ # FIXME: Find out what causes this (bug #344845).
+ print("* %s is an ambiguous package name" % (mykey,))
+ continue
+ if mylist:
+ #print "mylist:",mylist
+ myfavkey=portage.cpv_getkey(mylist[0])
+ if (myfavkey not in realsyslist) and (myfavkey not in worldlist):
+ print("add to world:",myfavkey)
+ worldlist.append(myfavkey)
+
+if not worldlist:
+ pass
+else:
+ existing_set = WorldSelectedSet(eroot)
+ existing_set.load()
+
+ if not existing_set:
+ existing_set.replace(worldlist)
+ else:
+ old_world = existing_set._filename
+ fd, tmp_filename = tempfile.mkstemp(suffix=".tmp",
+ prefix=os.path.basename(old_world) + ".",
+ dir=os.path.dirname(old_world))
+ os.close(fd)
+
+ new_set = StaticFileSet(tmp_filename)
+ new_set.update(worldlist)
+
+ if existing_set.getAtoms() == new_set.getAtoms():
+ os.unlink(tmp_filename)
+ else:
+ new_set.write()
+
+ msg = "Please review differences between old and new files, " + \
+ "and replace the old file if desired."
+
+ portage.util.writemsg_stdout("\n",
+ noiselevel=-1)
+ for line in textwrap.wrap(msg, 65):
+ portage.util.writemsg_stdout("%s\n" % line,
+ noiselevel=-1)
+ portage.util.writemsg_stdout("\n",
+ noiselevel=-1)
+ portage.util.writemsg_stdout(" old: %s\n\n" % old_world,
+ noiselevel=-1)
+ portage.util.writemsg_stdout(" new: %s\n\n" % tmp_filename,
+ noiselevel=-1)
diff --git a/portage_with_autodep/bin/repoman b/portage_with_autodep/bin/repoman
new file mode 100755
index 0000000..f1fbc24
--- /dev/null
+++ b/portage_with_autodep/bin/repoman
@@ -0,0 +1,2672 @@
+#!/usr/bin/python -O
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# Next to do: dep syntax checking in mask files
+# Then, check to make sure deps are satisfiable (to avoid "can't find match for" problems)
+# that last one is tricky because multiple profiles need to be checked.
+
+from __future__ import print_function
+
+import calendar
+import copy
+import errno
+import formatter
+import io
+import logging
+import optparse
+import re
+import signal
+import stat
+import sys
+import tempfile
+import time
+import platform
+
+try:
+ from urllib.request import urlopen as urllib_request_urlopen
+except ImportError:
+ from urllib import urlopen as urllib_request_urlopen
+
+from itertools import chain
+from stat import S_ISDIR
+
+try:
+ import portage
+except ImportError:
+ from os import path as osp
+ sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ import portage
+portage._disable_legacy_globals()
+portage.dep._internal_warnings = True
+
+try:
+ import xml.etree.ElementTree
+ from xml.parsers.expat import ExpatError
+except ImportError:
+ msg = ["Please enable python's \"xml\" USE flag in order to use repoman."]
+ from portage.output import EOutput
+ out = EOutput()
+ for line in msg:
+ out.eerror(line)
+ sys.exit(1)
+
+from portage import os
+from portage import subprocess_getstatusoutput
+from portage import _encodings
+from portage import _unicode_encode
+from repoman.checks import run_checks
+from repoman import utilities
+from repoman.herdbase import make_herd_base
+from _emerge.Package import Package
+from _emerge.RootConfig import RootConfig
+from _emerge.userquery import userquery
+import portage.checksum
+import portage.const
+from portage import cvstree, normalize_path
+from portage import util
+from portage.exception import (FileNotFound, MissingParameter,
+ ParseError, PermissionDenied)
+from portage.manifest import Manifest
+from portage.process import find_binary, spawn
+from portage.output import bold, create_color_func, \
+ green, nocolor, red
+from portage.output import ConsoleStyleFile, StyleWriter
+from portage.util import cmp_sort_key, writemsg_level
+from portage.package.ebuild.digestgen import digestgen
+from portage.eapi import eapi_has_slot_deps, \
+ eapi_has_use_deps, eapi_has_strong_blocks, eapi_has_iuse_defaults, \
+ eapi_has_required_use, eapi_has_use_dep_defaults
+
+if sys.hexversion >= 0x3000000:
+ basestring = str
+
+util.initialize_logger()
+
+# 14 is the length of DESCRIPTION=""
+max_desc_len = 100
+allowed_filename_chars="a-zA-Z0-9._-+:"
+disallowed_filename_chars_re = re.compile(r'[^a-zA-Z0-9._\-+:]')
+pv_toolong_re = re.compile(r'[0-9]{19,}')
+bad = create_color_func("BAD")
+
+# A sane umask is needed for files that portage creates.
+os.umask(0o22)
+# Repoman sets it's own ACCEPT_KEYWORDS and we don't want it to
+# behave incrementally.
+repoman_incrementals = tuple(x for x in \
+ portage.const.INCREMENTALS if x != 'ACCEPT_KEYWORDS')
+repoman_settings = portage.config(local_config=False)
+repoman_settings.lock()
+
+if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") or \
+ repoman_settings.get('TERM') == 'dumb' or \
+ not sys.stdout.isatty():
+ nocolor()
+
+def warn(txt):
+ print("repoman: " + txt)
+
+def err(txt):
+ warn(txt)
+ sys.exit(1)
+
+def exithandler(signum=None, frame=None):
+ logging.fatal("Interrupted; exiting...")
+ if signum is None:
+ sys.exit(1)
+ else:
+ sys.exit(128 + signum)
+
+signal.signal(signal.SIGINT,exithandler)
+
+class RepomanHelpFormatter(optparse.IndentedHelpFormatter):
+ """Repoman needs it's own HelpFormatter for now, because the default ones
+ murder the help text."""
+
+ def __init__(self, indent_increment=1, max_help_position=24, width=150, short_first=1):
+ optparse.HelpFormatter.__init__(self, indent_increment, max_help_position, width, short_first)
+
+ def format_description(self, description):
+ return description
+
+class RepomanOptionParser(optparse.OptionParser):
+ """Add the on_tail function, ruby has it, optionParser should too
+ """
+
+ def __init__(self, *args, **kwargs):
+ optparse.OptionParser.__init__(self, *args, **kwargs)
+ self.tail = ""
+
+ def on_tail(self, description):
+ self.tail += description
+
+ def format_help(self, formatter=None):
+ result = optparse.OptionParser.format_help(self, formatter)
+ result += self.tail
+ return result
+
+
+def ParseArgs(argv, qahelp):
+ """This function uses a customized optionParser to parse command line arguments for repoman
+ Args:
+ argv - a sequence of command line arguments
+ qahelp - a dict of qa warning to help message
+ Returns:
+ (opts, args), just like a call to parser.parse_args()
+ """
+
+ if argv and sys.hexversion < 0x3000000 and not isinstance(argv[0], unicode):
+ argv = [portage._unicode_decode(x) for x in argv]
+
+ modes = {
+ 'commit' : 'Run a scan then commit changes',
+ 'ci' : 'Run a scan then commit changes',
+ 'fix' : 'Fix simple QA issues (stray digests, missing digests)',
+ 'full' : 'Scan directory tree and print all issues (not a summary)',
+ 'help' : 'Show this screen',
+ 'manifest' : 'Generate a Manifest (fetches files if necessary)',
+ 'manifest-check' : 'Check Manifests for missing or incorrect digests',
+ 'scan' : 'Scan directory tree for QA issues'
+ }
+
+ mode_keys = list(modes)
+ mode_keys.sort()
+
+ parser = RepomanOptionParser(formatter=RepomanHelpFormatter(), usage="%prog [options] [mode]")
+ parser.description = green(" ".join((os.path.basename(argv[0]), "1.2")))
+ parser.description += "\nCopyright 1999-2007 Gentoo Foundation"
+ parser.description += "\nDistributed under the terms of the GNU General Public License v2"
+ parser.description += "\nmodes: " + " | ".join(map(green,mode_keys))
+
+ parser.add_option('-a', '--ask', dest='ask', action='store_true', default=False,
+ help='Request a confirmation before commiting')
+
+ parser.add_option('-m', '--commitmsg', dest='commitmsg',
+ help='specify a commit message on the command line')
+
+ parser.add_option('-M', '--commitmsgfile', dest='commitmsgfile',
+ help='specify a path to a file that contains a commit message')
+
+ parser.add_option('-p', '--pretend', dest='pretend', default=False,
+ action='store_true', help='don\'t commit or fix anything; just show what would be done')
+
+ parser.add_option('-q', '--quiet', dest="quiet", action="count", default=0,
+ help='do not print unnecessary messages')
+
+ parser.add_option('-f', '--force', dest='force', default=False, action='store_true',
+ help='Commit with QA violations')
+
+ parser.add_option('--vcs', dest='vcs',
+ help='Force using specific VCS instead of autodetection')
+
+ parser.add_option('-v', '--verbose', dest="verbosity", action='count',
+ help='be very verbose in output', default=0)
+
+ parser.add_option('-V', '--version', dest='version', action='store_true',
+ help='show version info')
+
+ parser.add_option('-x', '--xmlparse', dest='xml_parse', action='store_true',
+ default=False, help='forces the metadata.xml parse check to be carried out')
+
+ parser.add_option('-i', '--ignore-arches', dest='ignore_arches', action='store_true',
+ default=False, help='ignore arch-specific failures (where arch != host)')
+
+ parser.add_option('-I', '--ignore-masked', dest='ignore_masked', action='store_true',
+ default=False, help='ignore masked packages (not allowed with commit mode)')
+
+ parser.add_option('-d', '--include-dev', dest='include_dev', action='store_true',
+ default=False, help='include dev profiles in dependency checks')
+
+ parser.add_option('--unmatched-removal', dest='unmatched_removal', action='store_true',
+ default=False, help='enable strict checking of package.mask and package.unmask files for unmatched removal atoms')
+
+ parser.add_option('--without-mask', dest='without_mask', action='store_true',
+ default=False, help='behave as if no package.mask entries exist (not allowed with commit mode)')
+
+ parser.add_option('--mode', type='choice', dest='mode', choices=list(modes),
+ help='specify which mode repoman will run in (default=full)')
+
+ parser.on_tail("\n " + green("Modes".ljust(20) + " Description\n"))
+
+ for k in mode_keys:
+ parser.on_tail(" %s %s\n" % (k.ljust(20), modes[k]))
+
+ parser.on_tail("\n " + green("QA keyword".ljust(20) + " Description\n"))
+
+ sorted_qa = list(qahelp)
+ sorted_qa.sort()
+ for k in sorted_qa:
+ parser.on_tail(" %s %s\n" % (k.ljust(20), qahelp[k]))
+
+ opts, args = parser.parse_args(argv[1:])
+
+ if opts.mode == 'help':
+ parser.print_help(short=False)
+
+ for arg in args:
+ if arg in modes:
+ if not opts.mode:
+ opts.mode = arg
+ break
+ else:
+ parser.error("invalid mode: %s" % arg)
+
+ if not opts.mode:
+ opts.mode = 'full'
+
+ if opts.mode == 'ci':
+ opts.mode = 'commit' # backwards compat shortcut
+
+ if opts.mode == 'commit' and not (opts.force or opts.pretend):
+ if opts.ignore_masked:
+ parser.error('Commit mode and --ignore-masked are not compatible')
+ if opts.without_mask:
+ parser.error('Commit mode and --without-mask are not compatible')
+
+ # Use the verbosity and quiet options to fiddle with the loglevel appropriately
+ for val in range(opts.verbosity):
+ logger = logging.getLogger()
+ logger.setLevel(logger.getEffectiveLevel() - 10)
+
+ for val in range(opts.quiet):
+ logger = logging.getLogger()
+ logger.setLevel(logger.getEffectiveLevel() + 10)
+
+ return (opts, args)
+
+qahelp={
+ "CVS/Entries.IO_error":"Attempting to commit, and an IO error was encountered access the Entries file",
+ "desktop.invalid":"desktop-file-validate reports errors in a *.desktop file",
+ "ebuild.invalidname":"Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)",
+ "ebuild.namenomatch":"Ebuild files that do not have the same name as their parent directory",
+ "changelog.ebuildadded":"An ebuild was added but the ChangeLog was not modified",
+ "changelog.missing":"Missing ChangeLog files",
+ "ebuild.notadded":"Ebuilds that exist but have not been added to cvs",
+ "ebuild.patches":"PATCHES variable should be a bash array to ensure white space safety",
+ "changelog.notadded":"ChangeLogs that exist but have not been added to cvs",
+ "dependency.unknown" : "Ebuild has a dependency that refers to an unknown package (which may be provided by an overlay)",
+ "file.executable":"Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do note need the executable bit",
+ "file.size":"Files in the files directory must be under 20 KiB",
+ "file.size.fatal":"Files in the files directory must be under 60 KiB",
+ "file.name":"File/dir name must be composed of only the following chars: %s " % allowed_filename_chars,
+ "file.UTF8":"File is not UTF8 compliant",
+ "inherit.autotools":"Ebuild inherits autotools but does not call eautomake, eautoconf or eautoreconf",
+ "inherit.deprecated":"Ebuild inherits a deprecated eclass",
+ "java.eclassesnotused":"With virtual/jdk in DEPEND you must inherit a java eclass",
+ "wxwidgets.eclassnotused":"Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass",
+ "KEYWORDS.dropped":"Ebuilds that appear to have dropped KEYWORDS for some arch",
+ "KEYWORDS.missing":"Ebuilds that have a missing or empty KEYWORDS variable",
+ "KEYWORDS.stable":"Ebuilds that have been added directly with stable KEYWORDS",
+ "KEYWORDS.stupid":"Ebuilds that use KEYWORDS=-* instead of package.mask",
+ "LICENSE.missing":"Ebuilds that have a missing or empty LICENSE variable",
+ "LICENSE.virtual":"Virtuals that have a non-empty LICENSE variable",
+ "DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable",
+ "DESCRIPTION.toolong":"DESCRIPTION is over %d characters" % max_desc_len,
+ "EAPI.definition":"EAPI is defined after an inherit call (must be defined before)",
+ "EAPI.deprecated":"Ebuilds that use features that are deprecated in the current EAPI",
+ "EAPI.incompatible":"Ebuilds that use features that are only available with a different EAPI",
+ "EAPI.unsupported":"Ebuilds that have an unsupported EAPI version (you must upgrade portage)",
+ "SLOT.invalid":"Ebuilds that have a missing or invalid SLOT variable value",
+ "HOMEPAGE.missing":"Ebuilds that have a missing or empty HOMEPAGE variable",
+ "HOMEPAGE.virtual":"Virtuals that have a non-empty HOMEPAGE variable",
+ "DEPEND.bad":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds)",
+ "RDEPEND.bad":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds)",
+ "PDEPEND.bad":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds)",
+ "DEPEND.badmasked":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds)",
+ "RDEPEND.badmasked":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds)",
+ "PDEPEND.badmasked":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds)",
+ "DEPEND.badindev":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds) in developing arch",
+ "RDEPEND.badindev":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds) in developing arch",
+ "PDEPEND.badindev":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds) in developing arch",
+ "DEPEND.badmaskedindev":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds) in developing arch",
+ "RDEPEND.badmaskedindev":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds) in developing arch",
+ "PDEPEND.badmaskedindev":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds) in developing arch",
+ "PDEPEND.suspect":"PDEPEND contains a package that usually only belongs in DEPEND.",
+ "DEPEND.syntax":"Syntax error in DEPEND (usually an extra/missing space/parenthesis)",
+ "RDEPEND.syntax":"Syntax error in RDEPEND (usually an extra/missing space/parenthesis)",
+ "PDEPEND.syntax":"Syntax error in PDEPEND (usually an extra/missing space/parenthesis)",
+ "DEPEND.badtilde":"DEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
+ "RDEPEND.badtilde":"RDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
+ "PDEPEND.badtilde":"PDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
+ "LICENSE.syntax":"Syntax error in LICENSE (usually an extra/missing space/parenthesis)",
+ "PROVIDE.syntax":"Syntax error in PROVIDE (usually an extra/missing space/parenthesis)",
+ "PROPERTIES.syntax":"Syntax error in PROPERTIES (usually an extra/missing space/parenthesis)",
+ "RESTRICT.syntax":"Syntax error in RESTRICT (usually an extra/missing space/parenthesis)",
+ "REQUIRED_USE.syntax":"Syntax error in REQUIRED_USE (usually an extra/missing space/parenthesis)",
+ "SRC_URI.syntax":"Syntax error in SRC_URI (usually an extra/missing space/parenthesis)",
+ "SRC_URI.mirror":"A uri listed in profiles/thirdpartymirrors is found in SRC_URI",
+ "ebuild.syntax":"Error generating cache entry for ebuild; typically caused by ebuild syntax error or digest verification failure",
+ "ebuild.output":"A simple sourcing of the ebuild produces output; this breaks ebuild policy.",
+ "ebuild.nesteddie":"Placing 'die' inside ( ) prints an error, but doesn't stop the ebuild.",
+ "variable.invalidchar":"A variable contains an invalid character that is not part of the ASCII character set",
+ "variable.readonly":"Assigning a readonly variable",
+ "variable.usedwithhelpers":"Ebuild uses D, ROOT, ED, EROOT or EPREFIX with helpers",
+ "LIVEVCS.stable":"This ebuild is a live checkout from a VCS but has stable keywords.",
+ "LIVEVCS.unmasked":"This ebuild is a live checkout from a VCS but has keywords and is not masked in the global package.mask.",
+ "IUSE.invalid":"This ebuild has a variable in IUSE that is not in the use.desc or its metadata.xml file",
+ "IUSE.missing":"This ebuild has a USE conditional which references a flag that is not listed in IUSE",
+ "IUSE.undefined":"This ebuild does not define IUSE (style guideline says to define IUSE even when empty)",
+ "LICENSE.invalid":"This ebuild is listing a license that doesnt exist in portages license/ dir.",
+ "KEYWORDS.invalid":"This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for which no valid profile was found",
+ "RDEPEND.implicit":"RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4)",
+ "RDEPEND.suspect":"RDEPEND contains a package that usually only belongs in DEPEND.",
+ "RESTRICT.invalid":"This ebuild contains invalid RESTRICT values.",
+ "digest.assumed":"Existing digest must be assumed correct (Package level only)",
+ "digest.missing":"Some files listed in SRC_URI aren't referenced in the Manifest",
+ "digest.unused":"Some files listed in the Manifest aren't referenced in SRC_URI",
+ "ebuild.nostable":"There are no ebuilds that are marked as stable for your ARCH",
+ "ebuild.allmasked":"All ebuilds are masked for this package (Package level only)",
+ "ebuild.majorsyn":"This ebuild has a major syntax error that may cause the ebuild to fail partially or fully",
+ "ebuild.minorsyn":"This ebuild has a minor syntax error that contravenes gentoo coding style",
+ "ebuild.badheader":"This ebuild has a malformed header",
+ "eprefixify.defined":"The ebuild uses eprefixify, but does not inherit the prefix eclass",
+ "manifest.bad":"Manifest has missing or incorrect digests",
+ "metadata.missing":"Missing metadata.xml files",
+ "metadata.bad":"Bad metadata.xml files",
+ "metadata.warning":"Warnings in metadata.xml files",
+ "portage.internal":"The ebuild uses an internal Portage function",
+ "virtual.oldstyle":"The ebuild PROVIDEs an old-style virtual (see GLEP 37)",
+ "usage.obsolete":"The ebuild makes use of an obsolete construct",
+ "upstream.workaround":"The ebuild works around an upstream bug, an upstream bug should be filed and tracked in bugs.gentoo.org"
+}
+
+qacats = list(qahelp)
+qacats.sort()
+
+qawarnings = set((
+"changelog.missing",
+"changelog.notadded",
+"dependency.unknown",
+"digest.assumed",
+"digest.unused",
+"ebuild.notadded",
+"ebuild.nostable",
+"ebuild.allmasked",
+"ebuild.nesteddie",
+"desktop.invalid",
+"DEPEND.badmasked","RDEPEND.badmasked","PDEPEND.badmasked",
+"DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
+"DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
+"DEPEND.badtilde", "RDEPEND.badtilde", "PDEPEND.badtilde",
+"DESCRIPTION.toolong",
+"EAPI.deprecated",
+"HOMEPAGE.virtual",
+"LICENSE.virtual",
+"KEYWORDS.dropped",
+"KEYWORDS.stupid",
+"KEYWORDS.missing",
+"IUSE.undefined",
+"PDEPEND.suspect",
+"RDEPEND.implicit",
+"RDEPEND.suspect",
+"RESTRICT.invalid",
+"SRC_URI.mirror",
+"ebuild.minorsyn",
+"ebuild.badheader",
+"ebuild.patches",
+"file.size",
+"inherit.autotools",
+"inherit.deprecated",
+"java.eclassesnotused",
+"wxwidgets.eclassnotused",
+"metadata.warning",
+"portage.internal",
+"usage.obsolete",
+"upstream.workaround",
+"virtual.oldstyle",
+"LIVEVCS.stable",
+"LIVEVCS.unmasked",
+))
+
+non_ascii_re = re.compile(r'[^\x00-\x7f]')
+
+missingvars = ["KEYWORDS", "LICENSE", "DESCRIPTION", "HOMEPAGE"]
+allvars = set(x for x in portage.auxdbkeys if not x.startswith("UNUSED_"))
+allvars.update(Package.metadata_keys)
+allvars = sorted(allvars)
+commitmessage=None
+for x in missingvars:
+ x += ".missing"
+ if x not in qacats:
+ logging.warn('* missingvars values need to be added to qahelp ("%s")' % x)
+ qacats.append(x)
+ qawarnings.add(x)
+
+valid_restrict = frozenset(["binchecks", "bindist",
+ "fetch", "installsources", "mirror",
+ "primaryuri", "strip", "test", "userpriv"])
+
+live_eclasses = frozenset([
+ "bzr",
+ "cvs",
+ "darcs",
+ "git",
+ "git-2",
+ "mercurial",
+ "subversion",
+ "tla",
+])
+
+suspect_rdepend = frozenset([
+ "app-arch/cabextract",
+ "app-arch/rpm2targz",
+ "app-doc/doxygen",
+ "dev-lang/nasm",
+ "dev-lang/swig",
+ "dev-lang/yasm",
+ "dev-perl/extutils-pkgconfig",
+ "dev-util/byacc",
+ "dev-util/cmake",
+ "dev-util/ftjam",
+ "dev-util/gperf",
+ "dev-util/gtk-doc",
+ "dev-util/gtk-doc-am",
+ "dev-util/intltool",
+ "dev-util/jam",
+ "dev-util/pkgconfig",
+ "dev-util/scons",
+ "dev-util/unifdef",
+ "dev-util/yacc",
+ "media-gfx/ebdftopcf",
+ "sys-apps/help2man",
+ "sys-devel/autoconf",
+ "sys-devel/automake",
+ "sys-devel/bin86",
+ "sys-devel/bison",
+ "sys-devel/dev86",
+ "sys-devel/flex",
+ "sys-devel/m4",
+ "sys-devel/pmake",
+ "virtual/linux-sources",
+ "x11-misc/bdftopcf",
+ "x11-misc/imake",
+])
+
+metadata_dtd_uri = 'http://www.gentoo.org/dtd/metadata.dtd'
+# force refetch if the local copy creation time is older than this
+metadata_dtd_ctime_interval = 60 * 60 * 24 * 7 # 7 days
+
+# file.executable
+no_exec = frozenset(["Manifest","ChangeLog","metadata.xml"])
+
+options, arguments = ParseArgs(sys.argv, qahelp)
+
+if options.version:
+ print("Portage", portage.VERSION)
+ sys.exit(0)
+
+# Set this to False when an extraordinary issue (generally
+# something other than a QA issue) makes it impossible to
+# commit (like if Manifest generation fails).
+can_force = True
+
+portdir, portdir_overlay, mydir = utilities.FindPortdir(repoman_settings)
+if portdir is None:
+ sys.exit(1)
+
+myreporoot = os.path.basename(portdir_overlay)
+myreporoot += mydir[len(portdir_overlay):]
+
+if options.vcs:
+ if options.vcs in ('cvs', 'svn', 'git', 'bzr', 'hg'):
+ vcs = options.vcs
+ else:
+ vcs = None
+else:
+ vcses = utilities.FindVCS()
+ if len(vcses) > 1:
+ print(red('*** Ambiguous workdir -- more than one VCS found at the same depth: %s.' % ', '.join(vcses)))
+ print(red('*** Please either clean up your workdir or specify --vcs option.'))
+ sys.exit(1)
+ elif vcses:
+ vcs = vcses[0]
+ else:
+ vcs = None
+
+# Note: We don't use ChangeLogs in distributed SCMs.
+# It will be generated on server side from scm log,
+# before package moves to the rsync server.
+# This is needed because we try to avoid merge collisions.
+check_changelog = vcs in ('cvs', 'svn')
+
+# Disable copyright/mtime check if vcs does not preserve mtime (bug #324075).
+vcs_preserves_mtime = vcs not in ('git',)
+
+vcs_local_opts = repoman_settings.get("REPOMAN_VCS_LOCAL_OPTS", "").split()
+vcs_global_opts = repoman_settings.get("REPOMAN_VCS_GLOBAL_OPTS")
+if vcs_global_opts is None:
+ if vcs in ('cvs', 'svn'):
+ vcs_global_opts = "-q"
+ else:
+ vcs_global_opts = ""
+vcs_global_opts = vcs_global_opts.split()
+
+if vcs == "cvs" and \
+ "commit" == options.mode and \
+ "RMD160" not in portage.checksum.hashorigin_map:
+ from portage.util import grablines
+ repo_lines = grablines("./CVS/Repository")
+ if repo_lines and \
+ "gentoo-x86" == repo_lines[0].strip().split(os.path.sep)[0]:
+ msg = "Please install " \
+ "pycrypto or enable python's ssl USE flag in order " \
+ "to enable RMD160 hash support. See bug #198398 for " \
+ "more information."
+ prefix = bad(" * ")
+ from textwrap import wrap
+ for line in wrap(msg, 70):
+ print(prefix + line)
+ sys.exit(1)
+ del repo_lines
+
+if options.mode == 'commit' and not options.pretend and not vcs:
+ logging.info("Not in a version controlled repository; enabling pretend mode.")
+ options.pretend = True
+
+# Ensure that PORTDIR_OVERLAY contains the repository corresponding to $PWD.
+repoman_settings = portage.config(local_config=False)
+repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
+ (repoman_settings.get('PORTDIR_OVERLAY', ''), portdir_overlay)
+# We have to call the config constructor again so
+# that config.repositories is initialized correctly.
+repoman_settings = portage.config(local_config=False, env=dict(os.environ,
+ PORTDIR_OVERLAY=repoman_settings['PORTDIR_OVERLAY']))
+
+root = '/'
+trees = {
+ root : {'porttree' : portage.portagetree(root, settings=repoman_settings)}
+}
+portdb = trees[root]['porttree'].dbapi
+
+# Constrain dependency resolution to the master(s)
+# that are specified in layout.conf.
+portdir_overlay = os.path.realpath(portdir_overlay)
+repo_info = portdb._repo_info[portdir_overlay]
+portdb.porttrees = list(repo_info.eclass_db.porttrees)
+portdir = portdb.porttrees[0]
+
+# Generate an appropriate PORTDIR_OVERLAY value for passing into the
+# profile-specific config constructor calls.
+env = os.environ.copy()
+env['PORTDIR'] = portdir
+env['PORTDIR_OVERLAY'] = ' '.join(portdb.porttrees[1:])
+
+logging.info('Setting paths:')
+logging.info('PORTDIR = "' + portdir + '"')
+logging.info('PORTDIR_OVERLAY = "%s"' % env['PORTDIR_OVERLAY'])
+
+# It's confusing if these warnings are displayed without the user
+# being told which profile they come from, so disable them.
+env['FEATURES'] = env.get('FEATURES', '') + ' -unknown-features-warn'
+
+categories = []
+for path in set([portdir, portdir_overlay]):
+ categories.extend(portage.util.grabfile(
+ os.path.join(path, 'profiles', 'categories')))
+repoman_settings.categories = tuple(sorted(
+ portage.util.stack_lists([categories], incremental=1)))
+del categories
+
+portdb.settings = repoman_settings
+root_config = RootConfig(repoman_settings, trees[root], None)
+# We really only need to cache the metadata that's necessary for visibility
+# filtering. Anything else can be discarded to reduce memory consumption.
+portdb._aux_cache_keys.clear()
+portdb._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"])
+
+reposplit = myreporoot.split(os.path.sep)
+repolevel = len(reposplit)
+
+# check if it's in $PORTDIR/$CATEGORY/$PN , otherwise bail if commiting.
+# Reason for this is if they're trying to commit in just $FILESDIR/*, the Manifest needs updating.
+# this check ensures that repoman knows where it is, and the manifest recommit is at least possible.
+if options.mode == 'commit' and repolevel not in [1,2,3]:
+ print(red("***")+" Commit attempts *must* be from within a vcs co, category, or package directory.")
+ print(red("***")+" Attempting to commit from a packages files directory will be blocked for instance.")
+ print(red("***")+" This is intended behaviour, to ensure the manifest is recommitted for a package.")
+ print(red("***"))
+ err("Unable to identify level we're commiting from for %s" % '/'.join(reposplit))
+
+startdir = normalize_path(mydir)
+repodir = startdir
+for x in range(0, repolevel - 1):
+ repodir = os.path.dirname(repodir)
+repodir = os.path.realpath(repodir)
+
+def caterror(mycat):
+ err(mycat+" is not an official category. Skipping QA checks in this directory.\nPlease ensure that you add "+catdir+" to "+repodir+"/profiles/categories\nif it is a new category.")
+
+class ProfileDesc(object):
+ __slots__ = ('abs_path', 'arch', 'status', 'sub_path', 'tree_path',)
+ def __init__(self, arch, status, sub_path, tree_path):
+ self.arch = arch
+ self.status = status
+ if sub_path:
+ sub_path = normalize_path(sub_path.lstrip(os.sep))
+ self.sub_path = sub_path
+ self.tree_path = tree_path
+ if tree_path:
+ self.abs_path = os.path.join(tree_path, 'profiles', self.sub_path)
+ else:
+ self.abs_path = tree_path
+
+ def __str__(self):
+ if self.sub_path:
+ return self.sub_path
+ return 'empty profile'
+
+profile_list = []
+valid_profile_types = frozenset(['dev', 'exp', 'stable'])
+
+# get lists of valid keywords, licenses, and use
+kwlist = set()
+liclist = set()
+uselist = set()
+global_pmasklines = []
+
+for path in portdb.porttrees:
+ try:
+ liclist.update(os.listdir(os.path.join(path, "licenses")))
+ except OSError:
+ pass
+ kwlist.update(portage.grabfile(os.path.join(path,
+ "profiles", "arch.list")))
+
+ use_desc = portage.grabfile(os.path.join(path, 'profiles', 'use.desc'))
+ for x in use_desc:
+ x = x.split()
+ if x:
+ uselist.add(x[0])
+
+ expand_desc_dir = os.path.join(path, 'profiles', 'desc')
+ try:
+ expand_list = os.listdir(expand_desc_dir)
+ except OSError:
+ pass
+ else:
+ for fn in expand_list:
+ if not fn[-5:] == '.desc':
+ continue
+ use_prefix = fn[:-5].lower() + '_'
+ for x in portage.grabfile(os.path.join(expand_desc_dir, fn)):
+ x = x.split()
+ if x:
+ uselist.add(use_prefix + x[0])
+
+ global_pmasklines.append(portage.util.grabfile_package(
+ os.path.join(path, 'profiles', 'package.mask'), recursive=1, verify_eapi=True))
+
+ desc_path = os.path.join(path, 'profiles', 'profiles.desc')
+ try:
+ desc_file = io.open(_unicode_encode(desc_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='r', encoding=_encodings['repo.content'], errors='replace')
+ except EnvironmentError:
+ pass
+ else:
+ for i, x in enumerate(desc_file):
+ if x[0] == "#":
+ continue
+ arch = x.split()
+ if len(arch) == 0:
+ continue
+ if len(arch) != 3:
+ err("wrong format: \"" + bad(x.strip()) + "\" in " + \
+ desc_path + " line %d" % (i+1, ))
+ elif arch[0] not in kwlist:
+ err("invalid arch: \"" + bad(arch[0]) + "\" in " + \
+ desc_path + " line %d" % (i+1, ))
+ elif arch[2] not in valid_profile_types:
+ err("invalid profile type: \"" + bad(arch[2]) + "\" in " + \
+ desc_path + " line %d" % (i+1, ))
+ profile_desc = ProfileDesc(arch[0], arch[2], arch[1], path)
+ if not os.path.isdir(profile_desc.abs_path):
+ logging.error(
+ "Invalid %s profile (%s) for arch %s in %s line %d",
+ arch[2], arch[1], arch[0], desc_path, i+1)
+ continue
+ if os.path.exists(
+ os.path.join(profile_desc.abs_path, 'deprecated')):
+ continue
+ profile_list.append(profile_desc)
+ desc_file.close()
+
+repoman_settings['PORTAGE_ARCHLIST'] = ' '.join(sorted(kwlist))
+repoman_settings.backup_changes('PORTAGE_ARCHLIST')
+
+global_pmasklines = portage.util.stack_lists(global_pmasklines, incremental=1)
+global_pmaskdict = {}
+for x in global_pmasklines:
+ global_pmaskdict.setdefault(x.cp, []).append(x)
+del global_pmasklines
+
+def has_global_mask(pkg):
+ mask_atoms = global_pmaskdict.get(pkg.cp)
+ if mask_atoms:
+ pkg_list = [pkg]
+ for x in mask_atoms:
+ if portage.dep.match_from_list(x, pkg_list):
+ return x
+ return None
+
+# Ensure that profile sub_path attributes are unique. Process in reverse order
+# so that profiles with duplicate sub_path from overlays will override
+# profiles with the same sub_path from parent repos.
+profiles = {}
+profile_list.reverse()
+profile_sub_paths = set()
+for prof in profile_list:
+ if prof.sub_path in profile_sub_paths:
+ continue
+ profile_sub_paths.add(prof.sub_path)
+ profiles.setdefault(prof.arch, []).append(prof)
+
+# Use an empty profile for checking dependencies of
+# packages that have empty KEYWORDS.
+prof = ProfileDesc('**', 'stable', '', '')
+profiles.setdefault(prof.arch, []).append(prof)
+
+for x in repoman_settings.archlist():
+ if x[0] == "~":
+ continue
+ if x not in profiles:
+ print(red("\""+x+"\" doesn't have a valid profile listed in profiles.desc."))
+ print(red("You need to either \"cvs update\" your profiles dir or follow this"))
+ print(red("up with the "+x+" team."))
+ print()
+
+if not liclist:
+ logging.fatal("Couldn't find licenses?")
+ sys.exit(1)
+
+if not kwlist:
+ logging.fatal("Couldn't read KEYWORDS from arch.list")
+ sys.exit(1)
+
+if not uselist:
+ logging.fatal("Couldn't find use.desc?")
+ sys.exit(1)
+
+scanlist=[]
+if repolevel==2:
+ #we are inside a category directory
+ catdir=reposplit[-1]
+ if catdir not in repoman_settings.categories:
+ caterror(catdir)
+ mydirlist=os.listdir(startdir)
+ for x in mydirlist:
+ if x == "CVS" or x.startswith("."):
+ continue
+ if os.path.isdir(startdir+"/"+x):
+ scanlist.append(catdir+"/"+x)
+ repo_subdir = catdir + os.sep
+elif repolevel==1:
+ for x in repoman_settings.categories:
+ if not os.path.isdir(startdir+"/"+x):
+ continue
+ for y in os.listdir(startdir+"/"+x):
+ if y == "CVS" or y.startswith("."):
+ continue
+ if os.path.isdir(startdir+"/"+x+"/"+y):
+ scanlist.append(x+"/"+y)
+ repo_subdir = ""
+elif repolevel==3:
+ catdir = reposplit[-2]
+ if catdir not in repoman_settings.categories:
+ caterror(catdir)
+ scanlist.append(catdir+"/"+reposplit[-1])
+ repo_subdir = scanlist[-1] + os.sep
+else:
+ msg = 'Repoman is unable to determine PORTDIR or PORTDIR_OVERLAY' + \
+ ' from the current working directory'
+ logging.critical(msg)
+ sys.exit(1)
+
+repo_subdir_len = len(repo_subdir)
+scanlist.sort()
+
+logging.debug("Found the following packages to scan:\n%s" % '\n'.join(scanlist))
+
+def dev_keywords(profiles):
+ """
+ Create a set of KEYWORDS values that exist in 'dev'
+ profiles. These are used
+ to trigger a message notifying the user when they might
+ want to add the --include-dev option.
+ """
+ type_arch_map = {}
+ for arch, arch_profiles in profiles.items():
+ for prof in arch_profiles:
+ arch_set = type_arch_map.get(prof.status)
+ if arch_set is None:
+ arch_set = set()
+ type_arch_map[prof.status] = arch_set
+ arch_set.add(arch)
+
+ dev_keywords = type_arch_map.get('dev', set())
+ dev_keywords.update(['~' + arch for arch in dev_keywords])
+ return frozenset(dev_keywords)
+
+dev_keywords = dev_keywords(profiles)
+
+stats={}
+fails={}
+
+# provided by the desktop-file-utils package
+desktop_file_validate = find_binary("desktop-file-validate")
+desktop_pattern = re.compile(r'.*\.desktop$')
+
+for x in qacats:
+ stats[x]=0
+ fails[x]=[]
+
+xmllint_capable = False
+metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd')
+
+def parsedate(s):
+ """Parse a RFC 822 date and time string.
+ This is required for python3 compatibility, since the
+ rfc822.parsedate() function is not available."""
+
+ s_split = []
+ for x in s.upper().split():
+ for y in x.split(','):
+ if y:
+ s_split.append(y)
+
+ if len(s_split) != 6:
+ return None
+
+ # %a, %d %b %Y %H:%M:%S %Z
+ a, d, b, Y, H_M_S, Z = s_split
+
+ # Convert month to integer, since strptime %w is locale-dependent.
+ month_map = {'JAN':1, 'FEB':2, 'MAR':3, 'APR':4, 'MAY':5, 'JUN':6,
+ 'JUL':7, 'AUG':8, 'SEP':9, 'OCT':10, 'NOV':11, 'DEC':12}
+ m = month_map.get(b)
+ if m is None:
+ return None
+ m = str(m).rjust(2, '0')
+
+ return time.strptime(':'.join((Y, m, d, H_M_S)), '%Y:%m:%d:%H:%M:%S')
+
+def fetch_metadata_dtd():
+ """
+ Fetch metadata.dtd if it doesn't exist or the ctime is older than
+ metadata_dtd_ctime_interval.
+ @rtype: bool
+ @returns: True if successful, otherwise False
+ """
+
+ must_fetch = True
+ metadata_dtd_st = None
+ current_time = int(time.time())
+ try:
+ metadata_dtd_st = os.stat(metadata_dtd)
+ except EnvironmentError as e:
+ if e.errno not in (errno.ENOENT, errno.ESTALE):
+ raise
+ del e
+ else:
+ # Trigger fetch if metadata.dtd mtime is old or clock is wrong.
+ if abs(current_time - metadata_dtd_st.st_ctime) \
+ < metadata_dtd_ctime_interval:
+ must_fetch = False
+
+ if must_fetch:
+ print()
+ print(green("***") + " the local copy of metadata.dtd " + \
+ "needs to be refetched, doing that now")
+ print()
+ try:
+ url_f = urllib_request_urlopen(metadata_dtd_uri)
+ msg_info = url_f.info()
+ last_modified = msg_info.get('last-modified')
+ if last_modified is not None:
+ last_modified = parsedate(last_modified)
+ if last_modified is not None:
+ last_modified = calendar.timegm(last_modified)
+
+ metadata_dtd_tmp = "%s.%s" % (metadata_dtd, os.getpid())
+ try:
+ local_f = open(metadata_dtd_tmp, mode='wb')
+ local_f.write(url_f.read())
+ local_f.close()
+ if last_modified is not None:
+ try:
+ os.utime(metadata_dtd_tmp,
+ (int(last_modified), int(last_modified)))
+ except OSError:
+ # This fails on some odd non-unix-like filesystems.
+ # We don't really need the mtime to be preserved
+ # anyway here (currently we use ctime to trigger
+ # fetch), so just ignore it.
+ pass
+ os.rename(metadata_dtd_tmp, metadata_dtd)
+ finally:
+ try:
+ os.unlink(metadata_dtd_tmp)
+ except OSError:
+ pass
+
+ url_f.close()
+
+ except EnvironmentError as e:
+ print()
+ print(red("!!!")+" attempting to fetch '%s', caught" % metadata_dtd_uri)
+ print(red("!!!")+" exception '%s' though." % (e,))
+ print(red("!!!")+" fetching new metadata.dtd failed, aborting")
+ return False
+
+ return True
+
+if options.mode == "manifest":
+ pass
+elif not find_binary('xmllint'):
+ print(red("!!! xmllint not found. Can't check metadata.xml.\n"))
+ if options.xml_parse or repolevel==3:
+ print(red("!!!")+" sorry, xmllint is needed. failing\n")
+ sys.exit(1)
+else:
+ if not fetch_metadata_dtd():
+ sys.exit(1)
+ #this can be problematic if xmllint changes their output
+ xmllint_capable=True
+
+if options.mode == 'commit' and vcs:
+ utilities.detect_vcs_conflicts(options, vcs)
+
+if options.mode == "manifest":
+ pass
+elif options.pretend:
+ print(green("\nRepoMan does a once-over of the neighborhood..."))
+else:
+ print(green("\nRepoMan scours the neighborhood..."))
+
+new_ebuilds = set()
+modified_ebuilds = set()
+modified_changelogs = set()
+mychanged = []
+mynew = []
+myremoved = []
+
+if vcs == "cvs":
+ mycvstree = cvstree.getentries("./", recursive=1)
+ mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./")
+ mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./")
+if vcs == "svn":
+ svnstatus = os.popen("svn status").readlines()
+ mychanged = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem and elem[:1] in "MR" ]
+ mynew = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A") ]
+elif vcs == "git":
+ mychanged = os.popen("git diff-index --name-only --relative --diff-filter=M HEAD").readlines()
+ mychanged = ["./" + elem[:-1] for elem in mychanged]
+
+ mynew = os.popen("git diff-index --name-only --relative --diff-filter=A HEAD").readlines()
+ mynew = ["./" + elem[:-1] for elem in mynew]
+elif vcs == "bzr":
+ bzrstatus = os.popen("bzr status -S .").readlines()
+ mychanged = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M" ]
+ mynew = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] == "NK" or elem[0:1] == "R" ) ]
+elif vcs == "hg":
+ mychanged = os.popen("hg status --no-status --modified .").readlines()
+ mychanged = ["./" + elem.rstrip() for elem in mychanged]
+ mynew = os.popen("hg status --no-status --added .").readlines()
+ mynew = ["./" + elem.rstrip() for elem in mynew]
+
+if vcs:
+ new_ebuilds.update(x for x in mynew if x.endswith(".ebuild"))
+ modified_ebuilds.update(x for x in mychanged if x.endswith(".ebuild"))
+ modified_changelogs.update(x for x in chain(mychanged, mynew) \
+ if os.path.basename(x) == "ChangeLog")
+
+have_pmasked = False
+have_dev_keywords = False
+dofail = 0
+arch_caches={}
+arch_xmatch_caches = {}
+shared_xmatch_caches = {"cp-list":{}}
+
+# Disable the "ebuild.notadded" check when not in commit mode and
+# running `svn status` in every package dir will be too expensive.
+
+check_ebuild_notadded = not \
+ (vcs == "svn" and repolevel < 3 and options.mode != "commit")
+
+# Build a regex from thirdpartymirrors for the SRC_URI.mirror check.
+thirdpartymirrors = []
+for v in repoman_settings.thirdpartymirrors().values():
+ thirdpartymirrors.extend(v)
+
+class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
+ """
+ Implements doctype() as required to avoid deprecation warnings with
+ >=python-2.7.
+ """
+ def doctype(self, name, pubid, system):
+ pass
+
+try:
+ herd_base = make_herd_base(os.path.join(repoman_settings["PORTDIR"], "metadata/herds.xml"))
+except (EnvironmentError, ParseError, PermissionDenied) as e:
+ err(str(e))
+except FileNotFound:
+ # TODO: Download as we do for metadata.dtd, but add a way to
+ # disable for non-gentoo repoman users who may not have herds.
+ herd_base = None
+
+for x in scanlist:
+ #ebuilds and digests added to cvs respectively.
+ logging.info("checking package %s" % x)
+ eadded=[]
+ catdir,pkgdir=x.split("/")
+ checkdir=repodir+"/"+x
+ checkdir_relative = ""
+ if repolevel < 3:
+ checkdir_relative = os.path.join(pkgdir, checkdir_relative)
+ if repolevel < 2:
+ checkdir_relative = os.path.join(catdir, checkdir_relative)
+ checkdir_relative = os.path.join(".", checkdir_relative)
+ generated_manifest = False
+
+ if options.mode == "manifest" or \
+ (options.mode != 'manifest-check' and \
+ 'digest' in repoman_settings.features) or \
+ options.mode in ('commit', 'fix') and not options.pretend:
+ auto_assumed = set()
+ fetchlist_dict = portage.FetchlistDict(checkdir,
+ repoman_settings, portdb)
+ if options.mode == 'manifest' and options.force:
+ portage._doebuild_manifest_exempt_depend += 1
+ try:
+ distdir = repoman_settings['DISTDIR']
+ mf = portage.manifest.Manifest(checkdir, distdir,
+ fetchlist_dict=fetchlist_dict)
+ mf.create(requiredDistfiles=None,
+ assumeDistHashesAlways=True)
+ for distfiles in fetchlist_dict.values():
+ for distfile in distfiles:
+ if os.path.isfile(os.path.join(distdir, distfile)):
+ mf.fhashdict['DIST'].pop(distfile, None)
+ else:
+ auto_assumed.add(distfile)
+ mf.write()
+ finally:
+ portage._doebuild_manifest_exempt_depend -= 1
+
+ repoman_settings["O"] = checkdir
+ try:
+ generated_manifest = digestgen(
+ mysettings=repoman_settings, myportdb=portdb)
+ except portage.exception.PermissionDenied as e:
+ generated_manifest = False
+ writemsg_level("!!! Permission denied: '%s'\n" % (e,),
+ level=logging.ERROR, noiselevel=-1)
+
+ if not generated_manifest:
+ print("Unable to generate manifest.")
+ dofail = 1
+
+ if options.mode == "manifest":
+ if not dofail and options.force and auto_assumed and \
+ 'assume-digests' in repoman_settings.features:
+ # Show which digests were assumed despite the --force option
+ # being given. This output will already have been shown by
+ # digestgen() if assume-digests is not enabled, so only show
+ # it here if assume-digests is enabled.
+ pkgs = list(fetchlist_dict)
+ pkgs.sort()
+ portage.writemsg_stdout(" digest.assumed" + \
+ portage.output.colorize("WARN",
+ str(len(auto_assumed)).rjust(18)) + "\n")
+ for cpv in pkgs:
+ fetchmap = fetchlist_dict[cpv]
+ pf = portage.catsplit(cpv)[1]
+ for distfile in sorted(fetchmap):
+ if distfile in auto_assumed:
+ portage.writemsg_stdout(
+ " %s::%s\n" % (pf, distfile))
+ continue
+ elif dofail:
+ sys.exit(1)
+
+ if not generated_manifest:
+ repoman_settings['O'] = checkdir
+ repoman_settings['PORTAGE_QUIET'] = '1'
+ if not portage.digestcheck([], repoman_settings, strict=1):
+ stats["manifest.bad"] += 1
+ fails["manifest.bad"].append(os.path.join(x, 'Manifest'))
+ repoman_settings.pop('PORTAGE_QUIET', None)
+
+ if options.mode == 'manifest-check':
+ continue
+
+ checkdirlist=os.listdir(checkdir)
+ ebuildlist=[]
+ pkgs = {}
+ allvalid = True
+ for y in checkdirlist:
+ if (y in no_exec or y.endswith(".ebuild")) and \
+ stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0o111:
+ stats["file.executable"] += 1
+ fails["file.executable"].append(os.path.join(checkdir, y))
+ if y.endswith(".ebuild"):
+ pf = y[:-7]
+ ebuildlist.append(pf)
+ cpv = "%s/%s" % (catdir, pf)
+ try:
+ myaux = dict(zip(allvars, portdb.aux_get(cpv, allvars)))
+ except KeyError:
+ allvalid = False
+ stats["ebuild.syntax"] += 1
+ fails["ebuild.syntax"].append(os.path.join(x, y))
+ continue
+ except IOError:
+ allvalid = False
+ stats["ebuild.output"] += 1
+ fails["ebuild.output"].append(os.path.join(x, y))
+ continue
+ if not portage.eapi_is_supported(myaux["EAPI"]):
+ allvalid = False
+ stats["EAPI.unsupported"] += 1
+ fails["EAPI.unsupported"].append(os.path.join(x, y))
+ continue
+ pkgs[pf] = Package(cpv=cpv, metadata=myaux,
+ root_config=root_config, type_name="ebuild")
+
+ # Sort ebuilds in ascending order for the KEYWORDS.dropped check.
+ pkgsplits = {}
+ for i in range(len(ebuildlist)):
+ ebuild_split = portage.pkgsplit(ebuildlist[i])
+ pkgsplits[ebuild_split] = ebuildlist[i]
+ ebuildlist[i] = ebuild_split
+ ebuildlist.sort(key=cmp_sort_key(portage.pkgcmp))
+ for i in range(len(ebuildlist)):
+ ebuildlist[i] = pkgsplits[ebuildlist[i]]
+ del pkgsplits
+
+ slot_keywords = {}
+
+ if len(pkgs) != len(ebuildlist):
+ # If we can't access all the metadata then it's totally unsafe to
+ # commit since there's no way to generate a correct Manifest.
+ # Do not try to do any more QA checks on this package since missing
+ # metadata leads to false positives for several checks, and false
+ # positives confuse users.
+ can_force = False
+ continue
+
+ for y in checkdirlist:
+ m = disallowed_filename_chars_re.search(y.strip(os.sep))
+ if m is not None:
+ stats["file.name"] += 1
+ fails["file.name"].append("%s/%s: char '%s'" % \
+ (checkdir, y, m.group(0)))
+
+ if not (y in ("ChangeLog", "metadata.xml") or y.endswith(".ebuild")):
+ continue
+ try:
+ line = 1
+ for l in io.open(_unicode_encode(os.path.join(checkdir, y),
+ encoding=_encodings['fs'], errors='strict'),
+ mode='r', encoding=_encodings['repo.content']):
+ line +=1
+ except UnicodeDecodeError as ue:
+ stats["file.UTF8"] += 1
+ s = ue.object[:ue.start]
+ l2 = s.count("\n")
+ line += l2
+ if l2 != 0:
+ s = s[s.rfind("\n") + 1:]
+ fails["file.UTF8"].append("%s/%s: line %i, just after: '%s'" % (checkdir, y, line, s))
+
+ if vcs in ("git", "hg") and check_ebuild_notadded:
+ if vcs == "git":
+ myf = os.popen("git ls-files --others %s" % \
+ (portage._shell_quote(checkdir_relative),))
+ if vcs == "hg":
+ myf = os.popen("hg status --no-status --unknown %s" % \
+ (portage._shell_quote(checkdir_relative),))
+ for l in myf:
+ if l[:-1][-7:] == ".ebuild":
+ stats["ebuild.notadded"] += 1
+ fails["ebuild.notadded"].append(
+ os.path.join(x, os.path.basename(l[:-1])))
+ myf.close()
+
+ if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded:
+ try:
+ if vcs == "cvs":
+ myf=open(checkdir+"/CVS/Entries","r")
+ if vcs == "svn":
+ myf = os.popen("svn status --depth=files --verbose " + checkdir)
+ if vcs == "bzr":
+ myf = os.popen("bzr ls -v --kind=file " + checkdir)
+ myl = myf.readlines()
+ myf.close()
+ for l in myl:
+ if vcs == "cvs":
+ if l[0]!="/":
+ continue
+ splitl=l[1:].split("/")
+ if not len(splitl):
+ continue
+ if splitl[0][-7:]==".ebuild":
+ eadded.append(splitl[0][:-7])
+ if vcs == "svn":
+ if l[:1] == "?":
+ continue
+ if l[:7] == ' >':
+ # tree conflict, new in subversion 1.6
+ continue
+ l = l.split()[-1]
+ if l[-7:] == ".ebuild":
+ eadded.append(os.path.basename(l[:-7]))
+ if vcs == "bzr":
+ if l[1:2] == "?":
+ continue
+ l = l.split()[-1]
+ if l[-7:] == ".ebuild":
+ eadded.append(os.path.basename(l[:-7]))
+ if vcs == "svn":
+ myf = os.popen("svn status " + checkdir)
+ myl=myf.readlines()
+ myf.close()
+ for l in myl:
+ if l[0] == "A":
+ l = l.rstrip().split(' ')[-1]
+ if l[-7:] == ".ebuild":
+ eadded.append(os.path.basename(l[:-7]))
+ except IOError:
+ if vcs == "cvs":
+ stats["CVS/Entries.IO_error"] += 1
+ fails["CVS/Entries.IO_error"].append(checkdir+"/CVS/Entries")
+ else:
+ raise
+ continue
+
+ mf = Manifest(checkdir, repoman_settings["DISTDIR"])
+ mydigests=mf.getTypeDigests("DIST")
+
+ fetchlist_dict = portage.FetchlistDict(checkdir, repoman_settings, portdb)
+ myfiles_all = []
+ src_uri_error = False
+ for mykey in fetchlist_dict:
+ try:
+ myfiles_all.extend(fetchlist_dict[mykey])
+ except portage.exception.InvalidDependString as e:
+ src_uri_error = True
+ try:
+ portdb.aux_get(mykey, ["SRC_URI"])
+ except KeyError:
+ # This will be reported as an "ebuild.syntax" error.
+ pass
+ else:
+ stats["SRC_URI.syntax"] = stats["SRC_URI.syntax"] + 1
+ fails["SRC_URI.syntax"].append(
+ "%s.ebuild SRC_URI: %s" % (mykey, e))
+ del fetchlist_dict
+ if not src_uri_error:
+ # This test can produce false positives if SRC_URI could not
+ # be parsed for one or more ebuilds. There's no point in
+ # producing a false error here since the root cause will
+ # produce a valid error elsewhere, such as "SRC_URI.syntax"
+ # or "ebuild.sytax".
+ myfiles_all = set(myfiles_all)
+ for entry in mydigests:
+ if entry not in myfiles_all:
+ stats["digest.unused"] += 1
+ fails["digest.unused"].append(checkdir+"::"+entry)
+ for entry in myfiles_all:
+ if entry not in mydigests:
+ stats["digest.missing"] += 1
+ fails["digest.missing"].append(checkdir+"::"+entry)
+ del myfiles_all
+
+ if os.path.exists(checkdir+"/files"):
+ filesdirlist=os.listdir(checkdir+"/files")
+
+ # recurse through files directory
+ # use filesdirlist as a stack, appending directories as needed so people can't hide > 20k files in a subdirectory.
+ while filesdirlist:
+ y = filesdirlist.pop(0)
+ relative_path = os.path.join(x, "files", y)
+ full_path = os.path.join(repodir, relative_path)
+ try:
+ mystat = os.stat(full_path)
+ except OSError as oe:
+ if oe.errno == 2:
+ # don't worry about it. it likely was removed via fix above.
+ continue
+ else:
+ raise oe
+ if S_ISDIR(mystat.st_mode):
+ # !!! VCS "portability" alert! Need some function isVcsDir() or alike !!!
+ if y == "CVS" or y == ".svn":
+ continue
+ for z in os.listdir(checkdir+"/files/"+y):
+ if z == "CVS" or z == ".svn":
+ continue
+ filesdirlist.append(y+"/"+z)
+ # Current policy is no files over 20 KiB, these are the checks. File size between
+ # 20 KiB and 60 KiB causes a warning, while file size over 60 KiB causes an error.
+ elif mystat.st_size > 61440:
+ stats["file.size.fatal"] += 1
+ fails["file.size.fatal"].append("("+ str(mystat.st_size//1024) + " KiB) "+x+"/files/"+y)
+ elif mystat.st_size > 20480:
+ stats["file.size"] += 1
+ fails["file.size"].append("("+ str(mystat.st_size//1024) + " KiB) "+x+"/files/"+y)
+
+ m = disallowed_filename_chars_re.search(
+ os.path.basename(y.rstrip(os.sep)))
+ if m is not None:
+ stats["file.name"] += 1
+ fails["file.name"].append("%s/files/%s: char '%s'" % \
+ (checkdir, y, m.group(0)))
+
+ if desktop_file_validate and desktop_pattern.match(y):
+ status, cmd_output = subprocess_getstatusoutput(
+ "'%s' '%s'" % (desktop_file_validate, full_path))
+ if os.WIFEXITED(status) and os.WEXITSTATUS(status) != os.EX_OK:
+ # Note: in the future we may want to grab the
+ # warnings in addition to the errors. We're
+ # just doing errors now since we don't want
+ # to generate too much noise at first.
+ error_re = re.compile(r'.*\s*error:\s*(.*)')
+ for line in cmd_output.splitlines():
+ error_match = error_re.match(line)
+ if error_match is None:
+ continue
+ stats["desktop.invalid"] += 1
+ fails["desktop.invalid"].append(
+ relative_path + ': %s' % error_match.group(1))
+
+ del mydigests
+
+ if check_changelog and "ChangeLog" not in checkdirlist:
+ stats["changelog.missing"]+=1
+ fails["changelog.missing"].append(x+"/ChangeLog")
+
+ musedict = {}
+ #metadata.xml file check
+ if "metadata.xml" not in checkdirlist:
+ stats["metadata.missing"]+=1
+ fails["metadata.missing"].append(x+"/metadata.xml")
+ #metadata.xml parse check
+ else:
+ metadata_bad = False
+
+ # read metadata.xml into memory
+ try:
+ _metadata_xml = xml.etree.ElementTree.parse(
+ os.path.join(checkdir, "metadata.xml"),
+ parser=xml.etree.ElementTree.XMLParser(
+ target=_MetadataTreeBuilder()))
+ except (ExpatError, SyntaxError, EnvironmentError) as e:
+ metadata_bad = True
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
+ del e
+ else:
+ # load USE flags from metadata.xml
+ try:
+ musedict = utilities.parse_metadata_use(_metadata_xml)
+ except portage.exception.ParseError as e:
+ metadata_bad = True
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
+
+ # Run other metadata.xml checkers
+ try:
+ utilities.check_metadata(_metadata_xml, herd_base)
+ except (utilities.UnknownHerdsError, ) as e:
+ metadata_bad = True
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
+ del e
+
+ #Only carry out if in package directory or check forced
+ if xmllint_capable and not metadata_bad:
+ # xmlint can produce garbage output even on success, so only dump
+ # the ouput when it fails.
+ st, out = subprocess_getstatusoutput(
+ "xmllint --nonet --noout --dtdvalid '%s' '%s'" % \
+ (metadata_dtd, os.path.join(checkdir, "metadata.xml")))
+ if st != os.EX_OK:
+ print(red("!!!") + " metadata.xml is invalid:")
+ for z in out.splitlines():
+ print(red("!!! ")+z)
+ stats["metadata.bad"]+=1
+ fails["metadata.bad"].append(x+"/metadata.xml")
+
+ del metadata_bad
+ muselist = frozenset(musedict)
+
+ changelog_path = os.path.join(checkdir_relative, "ChangeLog")
+ changelog_modified = changelog_path in modified_changelogs
+
+ allmasked = True
+ # detect unused local USE-descriptions
+ used_useflags = set()
+
+ for y in ebuildlist:
+ relative_path = os.path.join(x, y + ".ebuild")
+ full_path = os.path.join(repodir, relative_path)
+ ebuild_path = y + ".ebuild"
+ if repolevel < 3:
+ ebuild_path = os.path.join(pkgdir, ebuild_path)
+ if repolevel < 2:
+ ebuild_path = os.path.join(catdir, ebuild_path)
+ ebuild_path = os.path.join(".", ebuild_path)
+ if check_changelog and not changelog_modified \
+ and ebuild_path in new_ebuilds:
+ stats['changelog.ebuildadded'] += 1
+ fails['changelog.ebuildadded'].append(relative_path)
+
+ if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded and y not in eadded:
+ #ebuild not added to vcs
+ stats["ebuild.notadded"]=stats["ebuild.notadded"]+1
+ fails["ebuild.notadded"].append(x+"/"+y+".ebuild")
+ myesplit=portage.pkgsplit(y)
+ if myesplit is None or myesplit[0] != x.split("/")[-1] \
+ or pv_toolong_re.search(myesplit[1]) \
+ or pv_toolong_re.search(myesplit[2]):
+ stats["ebuild.invalidname"]=stats["ebuild.invalidname"]+1
+ fails["ebuild.invalidname"].append(x+"/"+y+".ebuild")
+ continue
+ elif myesplit[0]!=pkgdir:
+ print(pkgdir,myesplit[0])
+ stats["ebuild.namenomatch"]=stats["ebuild.namenomatch"]+1
+ fails["ebuild.namenomatch"].append(x+"/"+y+".ebuild")
+ continue
+
+ pkg = pkgs[y]
+
+ if pkg.invalid:
+ allvalid = False
+ for k, msgs in pkg.invalid.items():
+ for msg in msgs:
+ stats[k] = stats[k] + 1
+ fails[k].append("%s %s" % (relative_path, msg))
+ continue
+
+ myaux = pkg.metadata
+ eapi = myaux["EAPI"]
+ inherited = pkg.inherited
+ live_ebuild = live_eclasses.intersection(inherited)
+
+ for k, v in myaux.items():
+ if not isinstance(v, basestring):
+ continue
+ m = non_ascii_re.search(v)
+ if m is not None:
+ stats["variable.invalidchar"] += 1
+ fails["variable.invalidchar"].append(
+ ("%s: %s variable contains non-ASCII " + \
+ "character at position %s") % \
+ (relative_path, k, m.start() + 1))
+
+ if not src_uri_error:
+ # Check that URIs don't reference a server from thirdpartymirrors.
+ for uri in portage.dep.use_reduce( \
+ myaux["SRC_URI"], matchall=True, is_src_uri=True, eapi=eapi, flat=True):
+ contains_mirror = False
+ for mirror in thirdpartymirrors:
+ if uri.startswith(mirror):
+ contains_mirror = True
+ break
+ if not contains_mirror:
+ continue
+
+ stats["SRC_URI.mirror"] += 1
+ fails["SRC_URI.mirror"].append(
+ "%s: '%s' found in thirdpartymirrors" % \
+ (relative_path, mirror))
+
+ if myaux.get("PROVIDE"):
+ stats["virtual.oldstyle"]+=1
+ fails["virtual.oldstyle"].append(relative_path)
+
+ for pos, missing_var in enumerate(missingvars):
+ if not myaux.get(missing_var):
+ if catdir == "virtual" and \
+ missing_var in ("HOMEPAGE", "LICENSE"):
+ continue
+ if live_ebuild and missing_var == "KEYWORDS":
+ continue
+ myqakey=missingvars[pos]+".missing"
+ stats[myqakey]=stats[myqakey]+1
+ fails[myqakey].append(x+"/"+y+".ebuild")
+
+ if catdir == "virtual":
+ for var in ("HOMEPAGE", "LICENSE"):
+ if myaux.get(var):
+ myqakey = var + ".virtual"
+ stats[myqakey] = stats[myqakey] + 1
+ fails[myqakey].append(relative_path)
+
+ # 14 is the length of DESCRIPTION=""
+ if len(myaux['DESCRIPTION']) > max_desc_len:
+ stats['DESCRIPTION.toolong'] += 1
+ fails['DESCRIPTION.toolong'].append(
+ "%s: DESCRIPTION is %d characters (max %d)" % \
+ (relative_path, len(myaux['DESCRIPTION']), max_desc_len))
+
+ keywords = myaux["KEYWORDS"].split()
+ stable_keywords = []
+ for keyword in keywords:
+ if not keyword.startswith("~") and \
+ not keyword.startswith("-"):
+ stable_keywords.append(keyword)
+ if stable_keywords:
+ if ebuild_path in new_ebuilds:
+ stable_keywords.sort()
+ stats["KEYWORDS.stable"] += 1
+ fails["KEYWORDS.stable"].append(
+ x + "/" + y + ".ebuild added with stable keywords: %s" % \
+ " ".join(stable_keywords))
+
+ ebuild_archs = set(kw.lstrip("~") for kw in keywords \
+ if not kw.startswith("-"))
+
+ previous_keywords = slot_keywords.get(myaux["SLOT"])
+ if previous_keywords is None:
+ slot_keywords[myaux["SLOT"]] = set()
+ elif ebuild_archs and not live_ebuild:
+ dropped_keywords = previous_keywords.difference(ebuild_archs)
+ if dropped_keywords:
+ stats["KEYWORDS.dropped"] += 1
+ fails["KEYWORDS.dropped"].append(
+ relative_path + ": %s" % \
+ " ".join(sorted(dropped_keywords)))
+
+ slot_keywords[myaux["SLOT"]].update(ebuild_archs)
+
+ # KEYWORDS="-*" is a stupid replacement for package.mask and screws general KEYWORDS semantics
+ if "-*" in keywords:
+ haskeyword = False
+ for kw in keywords:
+ if kw[0] == "~":
+ kw = kw[1:]
+ if kw in kwlist:
+ haskeyword = True
+ if not haskeyword:
+ stats["KEYWORDS.stupid"] += 1
+ fails["KEYWORDS.stupid"].append(x+"/"+y+".ebuild")
+
+ """
+ Ebuilds that inherit a "Live" eclass (darcs,subversion,git,cvs,etc..) should
+ not be allowed to be marked stable
+ """
+ if live_ebuild:
+ bad_stable_keywords = []
+ for keyword in keywords:
+ if not keyword.startswith("~") and \
+ not keyword.startswith("-"):
+ bad_stable_keywords.append(keyword)
+ del keyword
+ if bad_stable_keywords:
+ stats["LIVEVCS.stable"] += 1
+ fails["LIVEVCS.stable"].append(
+ x + "/" + y + ".ebuild with stable keywords:%s " % \
+ bad_stable_keywords)
+ del bad_stable_keywords
+
+ if keywords and not has_global_mask(pkg):
+ stats["LIVEVCS.unmasked"] += 1
+ fails["LIVEVCS.unmasked"].append(relative_path)
+
+ if options.ignore_arches:
+ arches = [[repoman_settings["ARCH"], repoman_settings["ARCH"],
+ repoman_settings["ACCEPT_KEYWORDS"].split()]]
+ else:
+ arches=[]
+ for keyword in myaux["KEYWORDS"].split():
+ if (keyword[0]=="-"):
+ continue
+ elif (keyword[0]=="~"):
+ arches.append([keyword, keyword[1:], [keyword[1:], keyword]])
+ else:
+ arches.append([keyword, keyword, [keyword]])
+ allmasked = False
+ if not arches:
+ # Use an empty profile for checking dependencies of
+ # packages that have empty KEYWORDS.
+ arches.append(['**', '**', ['**']])
+
+ unknown_pkgs = {}
+ baddepsyntax = False
+ badlicsyntax = False
+ badprovsyntax = False
+ catpkg = catdir+"/"+y
+
+ inherited_java_eclass = "java-pkg-2" in inherited or \
+ "java-pkg-opt-2" in inherited
+ inherited_wxwidgets_eclass = "wxwidgets" in inherited
+ operator_tokens = set(["||", "(", ")"])
+ type_list, badsyntax = [], []
+ for mytype in ("DEPEND", "RDEPEND", "PDEPEND",
+ "LICENSE", "PROPERTIES", "PROVIDE"):
+ mydepstr = myaux[mytype]
+
+ token_class = None
+ if mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
+ token_class=portage.dep.Atom
+
+ try:
+ atoms = portage.dep.use_reduce(mydepstr, matchall=1, flat=True, \
+ is_valid_flag=pkg.iuse.is_valid_flag, token_class=token_class)
+ except portage.exception.InvalidDependString as e:
+ atoms = None
+ badsyntax.append(str(e))
+
+ if atoms and mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
+ if mytype in ("RDEPEND", "PDEPEND") and \
+ "test?" in mydepstr.split():
+ stats[mytype + '.suspect'] += 1
+ fails[mytype + '.suspect'].append(relative_path + \
+ ": 'test?' USE conditional in %s" % mytype)
+
+ for atom in atoms:
+ if atom == "||":
+ continue
+
+ if not atom.blocker and \
+ not portdb.cp_list(atom.cp) and \
+ not atom.cp.startswith("virtual/"):
+ unknown_pkgs.setdefault(atom.cp, set()).add(
+ (mytype, atom.unevaluated_atom))
+
+ is_blocker = atom.blocker
+
+ if mytype == "DEPEND" and \
+ not is_blocker and \
+ not inherited_java_eclass and \
+ atom.cp == "virtual/jdk":
+ stats['java.eclassesnotused'] += 1
+ fails['java.eclassesnotused'].append(relative_path)
+ elif mytype == "DEPEND" and \
+ not is_blocker and \
+ not inherited_wxwidgets_eclass and \
+ atom.cp == "x11-libs/wxGTK":
+ stats['wxwidgets.eclassnotused'] += 1
+ fails['wxwidgets.eclassnotused'].append(
+ relative_path + ": DEPENDs on x11-libs/wxGTK"
+ " without inheriting wxwidgets.eclass")
+ elif mytype in ("PDEPEND", "RDEPEND"):
+ if not is_blocker and \
+ atom.cp in suspect_rdepend:
+ stats[mytype + '.suspect'] += 1
+ fails[mytype + '.suspect'].append(
+ relative_path + ": '%s'" % atom)
+
+ if atom.operator == "~" and \
+ portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
+ stats[mytype + '.badtilde'] += 1
+ fails[mytype + '.badtilde'].append(
+ (relative_path + ": %s uses the ~ operator"
+ " with a non-zero revision:" + \
+ " '%s'") % (mytype, atom))
+
+ type_list.extend([mytype] * (len(badsyntax) - len(type_list)))
+
+ for m,b in zip(type_list, badsyntax):
+ stats[m+".syntax"] += 1
+ fails[m+".syntax"].append(catpkg+".ebuild "+m+": "+b)
+
+ badlicsyntax = len([z for z in type_list if z == "LICENSE"])
+ badprovsyntax = len([z for z in type_list if z == "PROVIDE"])
+ baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax
+ badlicsyntax = badlicsyntax > 0
+ badprovsyntax = badprovsyntax > 0
+
+ # uselist checks - global
+ myuse = []
+ default_use = []
+ for myflag in myaux["IUSE"].split():
+ flag_name = myflag.lstrip("+-")
+ used_useflags.add(flag_name)
+ if myflag != flag_name:
+ default_use.append(myflag)
+ if flag_name not in uselist:
+ myuse.append(flag_name)
+
+ # uselist checks - metadata
+ for mypos in range(len(myuse)-1,-1,-1):
+ if myuse[mypos] and (myuse[mypos] in muselist):
+ del myuse[mypos]
+
+ if default_use and not eapi_has_iuse_defaults(eapi):
+ for myflag in default_use:
+ stats['EAPI.incompatible'] += 1
+ fails['EAPI.incompatible'].append(
+ (relative_path + ": IUSE defaults" + \
+ " not supported with EAPI='%s':" + \
+ " '%s'") % (eapi, myflag))
+
+ for mypos in range(len(myuse)):
+ stats["IUSE.invalid"]=stats["IUSE.invalid"]+1
+ fails["IUSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])
+
+ # license checks
+ if not badlicsyntax:
+ # Parse the LICENSE variable, remove USE conditions and
+ # flatten it.
+ licenses = portage.dep.use_reduce(myaux["LICENSE"], matchall=1, flat=True)
+ # Check each entry to ensure that it exists in PORTDIR's
+ # license directory.
+ for lic in licenses:
+ # Need to check for "||" manually as no portage
+ # function will remove it without removing values.
+ if lic not in liclist and lic != "||":
+ stats["LICENSE.invalid"]=stats["LICENSE.invalid"]+1
+ fails["LICENSE.invalid"].append(x+"/"+y+".ebuild: %s" % lic)
+
+ #keyword checks
+ myuse = myaux["KEYWORDS"].split()
+ for mykey in myuse:
+ myskey=mykey[:]
+ if myskey[0]=="-":
+ myskey=myskey[1:]
+ if myskey[0]=="~":
+ myskey=myskey[1:]
+ if mykey!="-*":
+ if myskey not in kwlist:
+ stats["KEYWORDS.invalid"] += 1
+ fails["KEYWORDS.invalid"].append(x+"/"+y+".ebuild: %s" % mykey)
+ elif myskey not in profiles:
+ stats["KEYWORDS.invalid"] += 1
+ fails["KEYWORDS.invalid"].append(x+"/"+y+".ebuild: %s (profile invalid)" % mykey)
+
+ #restrict checks
+ myrestrict = None
+ try:
+ myrestrict = portage.dep.use_reduce(myaux["RESTRICT"], matchall=1, flat=True)
+ except portage.exception.InvalidDependString as e:
+ stats["RESTRICT.syntax"] = stats["RESTRICT.syntax"] + 1
+ fails["RESTRICT.syntax"].append(
+ "%s: RESTRICT: %s" % (relative_path, e))
+ del e
+ if myrestrict:
+ myrestrict = set(myrestrict)
+ mybadrestrict = myrestrict.difference(valid_restrict)
+ if mybadrestrict:
+ stats["RESTRICT.invalid"] += len(mybadrestrict)
+ for mybad in mybadrestrict:
+ fails["RESTRICT.invalid"].append(x+"/"+y+".ebuild: %s" % mybad)
+ #REQUIRED_USE check
+ required_use = myaux["REQUIRED_USE"]
+ if required_use:
+ if not eapi_has_required_use(eapi):
+ stats['EAPI.incompatible'] += 1
+ fails['EAPI.incompatible'].append(
+ relative_path + ": REQUIRED_USE" + \
+ " not supported with EAPI='%s'" % (eapi,))
+ try:
+ portage.dep.check_required_use(required_use, (),
+ pkg.iuse.is_valid_flag)
+ except portage.exception.InvalidDependString as e:
+ stats["REQUIRED_USE.syntax"] = stats["REQUIRED_USE.syntax"] + 1
+ fails["REQUIRED_USE.syntax"].append(
+ "%s: REQUIRED_USE: %s" % (relative_path, e))
+ del e
+
+ # Syntax Checks
+ relative_path = os.path.join(x, y + ".ebuild")
+ full_path = os.path.join(repodir, relative_path)
+ if not vcs_preserves_mtime:
+ if ebuild_path not in new_ebuilds and \
+ ebuild_path not in modified_ebuilds:
+ pkg.mtime = None
+ try:
+ # All ebuilds should have utf_8 encoding.
+ f = io.open(_unicode_encode(full_path,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='r', encoding=_encodings['repo.content'])
+ try:
+ for check_name, e in run_checks(f, pkg):
+ stats[check_name] += 1
+ fails[check_name].append(relative_path + ': %s' % e)
+ finally:
+ f.close()
+ except UnicodeDecodeError:
+ # A file.UTF8 failure will have already been recorded above.
+ pass
+
+ if options.force:
+ # The dep_check() calls are the most expensive QA test. If --force
+ # is enabled, there's no point in wasting time on these since the
+ # user is intent on forcing the commit anyway.
+ continue
+
+ for keyword,arch,groups in arches:
+
+ if arch not in profiles:
+ # A missing profile will create an error further down
+ # during the KEYWORDS verification.
+ continue
+
+ for prof in profiles[arch]:
+
+ if prof.status not in ("stable", "dev") or \
+ prof.status == "dev" and not options.include_dev:
+ continue
+
+ dep_settings = arch_caches.get(prof.sub_path)
+ if dep_settings is None:
+ dep_settings = portage.config(
+ config_profile_path=prof.abs_path,
+ config_incrementals=repoman_incrementals,
+ local_config=False,
+ _unmatched_removal=options.unmatched_removal,
+ env=env)
+ if options.without_mask:
+ dep_settings._mask_manager = \
+ copy.deepcopy(dep_settings._mask_manager)
+ dep_settings._mask_manager._pmaskdict.clear()
+ arch_caches[prof.sub_path] = dep_settings
+
+ xmatch_cache_key = (prof.sub_path, tuple(groups))
+ xcache = arch_xmatch_caches.get(xmatch_cache_key)
+ if xcache is None:
+ portdb.melt()
+ portdb.freeze()
+ xcache = portdb.xcache
+ xcache.update(shared_xmatch_caches)
+ arch_xmatch_caches[xmatch_cache_key] = xcache
+
+ trees["/"]["porttree"].settings = dep_settings
+ portdb.settings = dep_settings
+ portdb.xcache = xcache
+ # for package.use.mask support inside dep_check
+ dep_settings.setcpv(pkg)
+ dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
+ # just in case, prevent config.reset() from nuking these.
+ dep_settings.backup_changes("ACCEPT_KEYWORDS")
+
+ if not baddepsyntax:
+ ismasked = not ebuild_archs or \
+ pkg.cpv not in portdb.xmatch("list-visible", pkg.cp)
+ if ismasked:
+ if not have_pmasked:
+ have_pmasked = bool(dep_settings._getMaskAtom(
+ pkg.cpv, pkg.metadata))
+ if options.ignore_masked:
+ continue
+ #we are testing deps for a masked package; give it some lee-way
+ suffix="masked"
+ matchmode = "minimum-all"
+ else:
+ suffix=""
+ matchmode = "minimum-visible"
+
+ if not have_dev_keywords:
+ have_dev_keywords = \
+ bool(dev_keywords.intersection(keywords))
+
+ if prof.status == "dev":
+ suffix=suffix+"indev"
+
+ for mytype,mypos in [["DEPEND",len(missingvars)],["RDEPEND",len(missingvars)+1],["PDEPEND",len(missingvars)+2]]:
+
+ mykey=mytype+".bad"+suffix
+ myvalue = myaux[mytype]
+ if not myvalue:
+ continue
+
+ success, atoms = portage.dep_check(myvalue, portdb,
+ dep_settings, use="all", mode=matchmode,
+ trees=trees)
+
+ if success:
+ if atoms:
+ for atom in atoms:
+ if not atom.blocker:
+ # Don't bother with dependency.unknown
+ # for cases in which *DEPEND.bad is
+ # triggered.
+ unknown_pkgs.pop(atom.cp, None)
+
+ if not prof.sub_path:
+ # old-style virtuals currently aren't
+ # resolvable with empty profile, since
+ # 'virtuals' mappings are unavailable
+ # (it would be expensive to search
+ # for PROVIDE in all ebuilds)
+ atoms = [atom for atom in atoms if not \
+ (atom.cp.startswith('virtual/') and \
+ not portdb.cp_list(atom.cp))]
+
+ #we have some unsolvable deps
+ #remove ! deps, which always show up as unsatisfiable
+ atoms = [str(atom.unevaluated_atom) \
+ for atom in atoms if not atom.blocker]
+
+ #if we emptied out our list, continue:
+ if not atoms:
+ continue
+ stats[mykey]=stats[mykey]+1
+ fails[mykey].append("%s: %s(%s) %s" % \
+ (relative_path, keyword,
+ prof, repr(atoms)))
+ else:
+ stats[mykey]=stats[mykey]+1
+ fails[mykey].append("%s: %s(%s) %s" % \
+ (relative_path, keyword,
+ prof, repr(atoms)))
+
+ if not baddepsyntax and unknown_pkgs:
+ all_unknown = set()
+ all_unknown.update(*unknown_pkgs.values())
+ type_map = {}
+ for mytype, atom in all_unknown:
+ type_map.setdefault(mytype, set()).add(atom)
+ for mytype, atoms in type_map.items():
+ stats["dependency.unknown"] += 1
+ fails["dependency.unknown"].append("%s: %s: %s" %
+ (relative_path, mytype, ", ".join(sorted(atoms))))
+
+ # Check for 'all unstable' or 'all masked' -- ACCEPT_KEYWORDS is stripped
+ # XXX -- Needs to be implemented in dep code. Can't determine ~arch nicely.
+ #if not portage.portdb.xmatch("bestmatch-visible",x):
+ # stats["ebuild.nostable"]+=1
+ # fails["ebuild.nostable"].append(x)
+ if ebuildlist and allmasked and repolevel == 3:
+ stats["ebuild.allmasked"]+=1
+ fails["ebuild.allmasked"].append(x)
+
+ # check if there are unused local USE-descriptions in metadata.xml
+ # (unless there are any invalids, to avoid noise)
+ if allvalid:
+ for myflag in muselist.difference(used_useflags):
+ stats["metadata.warning"] += 1
+ fails["metadata.warning"].append(
+ "%s/metadata.xml: unused local USE-description: '%s'" % \
+ (x, myflag))
+
+if options.mode == "manifest":
+ sys.exit(dofail)
+
+#dofail will be set to 1 if we have failed in at least one non-warning category
+dofail=0
+#dowarn will be set to 1 if we tripped any warnings
+dowarn=0
+#dofull will be set if we should print a "repoman full" informational message
+dofull = options.mode != 'full'
+
+for x in qacats:
+ if not stats[x]:
+ continue
+ dowarn = 1
+ if x not in qawarnings:
+ dofail = 1
+
+if dofail or \
+ (dowarn and not (options.quiet or options.mode == "scan")):
+ dofull = 0
+
+# Save QA output so that it can be conveniently displayed
+# in $EDITOR while the user creates a commit message.
+# Otherwise, the user would not be able to see this output
+# once the editor has taken over the screen.
+qa_output = io.StringIO()
+style_file = ConsoleStyleFile(sys.stdout)
+if options.mode == 'commit' and \
+ (not commitmessage or not commitmessage.strip()):
+ style_file.write_listener = qa_output
+console_writer = StyleWriter(file=style_file, maxcol=9999)
+console_writer.style_listener = style_file.new_styles
+
+f = formatter.AbstractFormatter(console_writer)
+
+utilities.format_qa_output(f, stats, fails, dofull, dofail, options, qawarnings)
+
+style_file.flush()
+del console_writer, f, style_file
+qa_output = qa_output.getvalue()
+qa_output = qa_output.splitlines(True)
+
+def grouplist(mylist,seperator="/"):
+ """(list,seperator="/") -- Takes a list of elements; groups them into
+ same initial element categories. Returns a dict of {base:[sublist]}
+ From: ["blah/foo","spork/spatula","blah/weee/splat"]
+ To: {"blah":["foo","weee/splat"], "spork":["spatula"]}"""
+ mygroups={}
+ for x in mylist:
+ xs=x.split(seperator)
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] not in mygroups:
+ mygroups[xs[0]]=[seperator.join(xs[1:])]
+ else:
+ mygroups[xs[0]]+=[seperator.join(xs[1:])]
+ return mygroups
+
+suggest_ignore_masked = False
+suggest_include_dev = False
+
+if have_pmasked and not (options.without_mask or options.ignore_masked):
+ suggest_ignore_masked = True
+if have_dev_keywords and not options.include_dev:
+ suggest_include_dev = True
+
+if suggest_ignore_masked or suggest_include_dev:
+ print()
+ if suggest_ignore_masked:
+ print(bold("Note: use --without-mask to check " + \
+ "KEYWORDS on dependencies of masked packages"))
+
+ if suggest_include_dev:
+ print(bold("Note: use --include-dev (-d) to check " + \
+ "dependencies for 'dev' profiles"))
+ print()
+
+if options.mode != 'commit':
+ if dofull:
+ print(bold("Note: type \"repoman full\" for a complete listing."))
+ if dowarn and not dofail:
+ print(green("RepoMan sez:"),"\"You're only giving me a partial QA payment?\n I'll take it this time, but I'm not happy.\"")
+ elif not dofail:
+ print(green("RepoMan sez:"),"\"If everyone were like you, I'd be out of business!\"")
+ elif dofail:
+ print(bad("Please fix these important QA issues first."))
+ print(green("RepoMan sez:"),"\"Make your QA payment on time and you'll never see the likes of me.\"\n")
+ sys.exit(1)
+else:
+ if dofail and can_force and options.force and not options.pretend:
+ print(green("RepoMan sez:") + \
+ " \"You want to commit even with these QA issues?\n" + \
+ " I'll take it this time, but I'm not happy.\"\n")
+ elif dofail:
+ if options.force and not can_force:
+ print(bad("The --force option has been disabled due to extraordinary issues."))
+ print(bad("Please fix these important QA issues first."))
+ print(green("RepoMan sez:"),"\"Make your QA payment on time and you'll never see the likes of me.\"\n")
+ sys.exit(1)
+
+ if options.pretend:
+ print(green("RepoMan sez:"), "\"So, you want to play it safe. Good call.\"\n")
+
+ myunadded = []
+ if vcs == "cvs":
+ try:
+ myvcstree=portage.cvstree.getentries("./",recursive=1)
+ myunadded=portage.cvstree.findunadded(myvcstree,recursive=1,basedir="./")
+ except SystemExit as e:
+ raise # TODO propagate this
+ except:
+ err("Error retrieving CVS tree; exiting.")
+ if vcs == "svn":
+ try:
+ svnstatus=os.popen("svn status --no-ignore").readlines()
+ myunadded = [ "./"+elem.rstrip().split()[1] for elem in svnstatus if elem.startswith("?") or elem.startswith("I") ]
+ except SystemExit as e:
+ raise # TODO propagate this
+ except:
+ err("Error retrieving SVN info; exiting.")
+ if vcs == "git":
+ # get list of files not under version control or missing
+ myf = os.popen("git ls-files --others")
+ myunadded = [ "./" + elem[:-1] for elem in myf ]
+ myf.close()
+ if vcs == "bzr":
+ try:
+ bzrstatus=os.popen("bzr status -S .").readlines()
+ myunadded = [ "./"+elem.rstrip().split()[1].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("?") or elem[0:2] == " D" ]
+ except SystemExit as e:
+ raise # TODO propagate this
+ except:
+ err("Error retrieving bzr info; exiting.")
+ if vcs == "hg":
+ myunadded = os.popen("hg status --no-status --unknown .").readlines()
+ myunadded = ["./" + elem.rstrip() for elem in myunadded]
+
+ # Mercurial doesn't handle manually deleted files as removed from
+ # the repository, so the user need to remove them before commit,
+ # using "hg remove [FILES]"
+ mydeleted = os.popen("hg status --no-status --deleted .").readlines()
+ mydeleted = ["./" + elem.rstrip() for elem in mydeleted]
+
+
+ myautoadd=[]
+ if myunadded:
+ for x in range(len(myunadded)-1,-1,-1):
+ xs=myunadded[x].split("/")
+ if xs[-1]=="files":
+ print("!!! files dir is not added! Please correct this.")
+ sys.exit(-1)
+ elif xs[-1]=="Manifest":
+ # It's a manifest... auto add
+ myautoadd+=[myunadded[x]]
+ del myunadded[x]
+
+ if myautoadd:
+ print(">>> Auto-Adding missing Manifest(s)...")
+ if options.pretend:
+ if vcs == "cvs":
+ print("(cvs add "+" ".join(myautoadd)+")")
+ elif vcs == "svn":
+ print("(svn add "+" ".join(myautoadd)+")")
+ elif vcs == "git":
+ print("(git add "+" ".join(myautoadd)+")")
+ elif vcs == "bzr":
+ print("(bzr add "+" ".join(myautoadd)+")")
+ elif vcs == "hg":
+ print("(hg add "+" ".join(myautoadd)+")")
+ retval=0
+ else:
+ if vcs == "cvs":
+ retval=os.system("cvs add "+" ".join(myautoadd))
+ elif vcs == "svn":
+ retval=os.system("svn add "+" ".join(myautoadd))
+ elif vcs == "git":
+ retval=os.system("git add "+" ".join(myautoadd))
+ elif vcs == "bzr":
+ retval=os.system("bzr add "+" ".join(myautoadd))
+ elif vcs == "hg":
+ retval=os.system("hg add "+" ".join(myautoadd))
+ if retval:
+ writemsg_level("!!! Exiting on %s (shell) error code: %s\n" % \
+ (vcs, retval), level=logging.ERROR, noiselevel=-1)
+ sys.exit(retval)
+
+ if myunadded:
+ print(red("!!! The following files are in your local tree but are not added to the master"))
+ print(red("!!! tree. Please remove them from the local tree or add them to the master tree."))
+ for x in myunadded:
+ print(" ",x)
+ print()
+ print()
+ sys.exit(1)
+
+ if vcs == "hg" and mydeleted:
+ print(red("!!! The following files are removed manually from your local tree but are not"))
+ print(red("!!! removed from the repository. Please remove them, using \"hg remove [FILES]\"."))
+ for x in mydeleted:
+ print(" ",x)
+ print()
+ print()
+ sys.exit(1)
+
+ if vcs == "cvs":
+ mycvstree = cvstree.getentries("./", recursive=1)
+ mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./")
+ mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./")
+ myremoved=portage.cvstree.findremoved(mycvstree,recursive=1,basedir="./")
+ bin_blob_pattern = re.compile("^-kb$")
+ no_expansion = set(portage.cvstree.findoption(mycvstree, bin_blob_pattern,
+ recursive=1, basedir="./"))
+
+
+ if vcs == "svn":
+ svnstatus = os.popen("svn status").readlines()
+ mychanged = [ "./" + elem.split()[-1:][0] for elem in svnstatus if (elem[:1] in "MR" or elem[1:2] in "M")]
+ mynew = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A")]
+ myremoved = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D")]
+
+ # Subversion expands keywords specified in svn:keywords properties.
+ props = os.popen("svn propget -R svn:keywords").readlines()
+ expansion = dict(("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) \
+ for prop in props if " - " in prop)
+
+ elif vcs == "git":
+ mychanged = os.popen("git diff-index --name-only --relative --diff-filter=M HEAD").readlines()
+ mychanged = ["./" + elem[:-1] for elem in mychanged]
+
+ mynew = os.popen("git diff-index --name-only --relative --diff-filter=A HEAD").readlines()
+ mynew = ["./" + elem[:-1] for elem in mynew]
+
+ myremoved = os.popen("git diff-index --name-only --relative --diff-filter=D HEAD").readlines()
+ myremoved = ["./" + elem[:-1] for elem in myremoved]
+
+ if vcs == "bzr":
+ bzrstatus = os.popen("bzr status -S .").readlines()
+ mychanged = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M" ]
+ mynew = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] in "NK" or elem[0:1] == "R" ) ]
+ myremoved = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("-") ]
+ myremoved = [ "./" + elem.split()[-3:-2][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] == "K" or elem[0:1] == "R" ) ]
+ # Bazaar expands nothing.
+
+ if vcs == "hg":
+ mychanged = os.popen("hg status --no-status --modified .").readlines()
+ mychanged = ["./" + elem.rstrip() for elem in mychanged]
+ mynew = os.popen("hg status --no-status --added .").readlines()
+ mynew = ["./" + elem.rstrip() for elem in mynew]
+ myremoved = os.popen("hg status --no-status --removed .").readlines()
+ myremoved = ["./" + elem.rstrip() for elem in myremoved]
+
+ if vcs:
+ if not (mychanged or mynew or myremoved or (vcs == "hg" and mydeleted)):
+ print(green("RepoMan sez:"), "\"Doing nothing is not always good for QA.\"")
+ print()
+ print("(Didn't find any changed files...)")
+ print()
+ sys.exit(1)
+
+ # Manifests need to be regenerated after all other commits, so don't commit
+ # them now even if they have changed.
+ mymanifests = set()
+ myupdates = set()
+ for f in mychanged + mynew:
+ if "Manifest" == os.path.basename(f):
+ mymanifests.add(f)
+ else:
+ myupdates.add(f)
+ if vcs in ('git', 'hg'):
+ myupdates.difference_update(myremoved)
+ myupdates = list(myupdates)
+ mymanifests = list(mymanifests)
+ myheaders = []
+ mydirty = []
+
+ print("* %s files being committed..." % green(str(len(myupdates))), end=' ')
+ if vcs not in ('cvs', 'svn'):
+ # With git, bzr and hg, there's never any keyword expansion, so
+ # there's no need to regenerate manifests and all files will be
+ # committed in one big commit at the end.
+ print()
+ else:
+ if vcs == 'cvs':
+ headerstring = "'\$(Header|Id).*\$'"
+ elif vcs == "svn":
+ svn_keywords = dict((k.lower(), k) for k in [
+ "Rev",
+ "Revision",
+ "LastChangedRevision",
+ "Date",
+ "LastChangedDate",
+ "Author",
+ "LastChangedBy",
+ "URL",
+ "HeadURL",
+ "Id",
+ "Header",
+ ])
+
+ for myfile in myupdates:
+
+ # for CVS, no_expansion contains files that are excluded from expansion
+ if vcs == "cvs":
+ if myfile in no_expansion:
+ continue
+
+ # for SVN, expansion contains files that are included in expansion
+ elif vcs == "svn":
+ if myfile not in expansion:
+ continue
+
+ # Subversion keywords are case-insensitive in svn:keywords properties, but case-sensitive in contents of files.
+ enabled_keywords = []
+ for k in expansion[myfile]:
+ keyword = svn_keywords.get(k.lower())
+ if keyword is not None:
+ enabled_keywords.append(keyword)
+
+ headerstring = "'\$(%s).*\$'" % "|".join(enabled_keywords)
+
+ myout = subprocess_getstatusoutput("egrep -q "+headerstring+" "+myfile)
+ if myout[0] == 0:
+ myheaders.append(myfile)
+
+ print("%s have headers that will change." % green(str(len(myheaders))))
+ print("* Files with headers will cause the manifests to be changed and committed separately.")
+
+ logging.info("myupdates: %s", myupdates)
+ logging.info("myheaders: %s", myheaders)
+
+ commitmessage = options.commitmsg
+ if options.commitmsgfile:
+ try:
+ f = io.open(_unicode_encode(options.commitmsgfile,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='r', encoding=_encodings['content'], errors='replace')
+ commitmessage = f.read()
+ f.close()
+ del f
+ except (IOError, OSError) as e:
+ if e.errno == errno.ENOENT:
+ portage.writemsg("!!! File Not Found: --commitmsgfile='%s'\n" % options.commitmsgfile)
+ else:
+ raise
+ # We've read the content so the file is no longer needed.
+ commitmessagefile = None
+ if not commitmessage or not commitmessage.strip():
+ try:
+ editor = os.environ.get("EDITOR")
+ if editor and utilities.editor_is_executable(editor):
+ commitmessage = utilities.get_commit_message_with_editor(
+ editor, message=qa_output)
+ else:
+ commitmessage = utilities.get_commit_message_with_stdin()
+ except KeyboardInterrupt:
+ exithandler()
+ if not commitmessage or not commitmessage.strip():
+ print("* no commit message? aborting commit.")
+ sys.exit(1)
+ commitmessage = commitmessage.rstrip()
+ portage_version = getattr(portage, "VERSION", None)
+ if portage_version is None:
+ sys.stderr.write("Failed to insert portage version in message!\n")
+ sys.stderr.flush()
+ portage_version = "Unknown"
+ unameout = platform.system() + " "
+ if platform.system() in ["Darwin", "SunOS"]:
+ unameout += platform.processor()
+ else:
+ unameout += platform.machine()
+ commitmessage += "\n\n(Portage version: %s/%s/%s" % \
+ (portage_version, vcs, unameout)
+ if options.force:
+ commitmessage += ", RepoMan options: --force"
+ commitmessage += ")"
+
+ if options.ask and userquery('Commit changes?', True) != 'Yes':
+ print("* aborting commit.")
+ sys.exit(1)
+
+ if vcs in ('cvs', 'svn') and (myupdates or myremoved):
+ myfiles = myupdates + myremoved
+ if not myheaders and "sign" not in repoman_settings.features:
+ myfiles += mymanifests
+ fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
+ mymsg = os.fdopen(fd, "wb")
+ mymsg.write(_unicode_encode(commitmessage))
+ mymsg.close()
+
+ print()
+ print(green("Using commit message:"))
+ print(green("------------------------------------------------------------------------------"))
+ print(commitmessage)
+ print(green("------------------------------------------------------------------------------"))
+ print()
+
+ # Having a leading ./ prefix on file paths can trigger a bug in
+ # the cvs server when committing files to multiple directories,
+ # so strip the prefix.
+ myfiles = [f.lstrip("./") for f in myfiles]
+
+ commit_cmd = [vcs]
+ commit_cmd.extend(vcs_global_opts)
+ commit_cmd.append("commit")
+ commit_cmd.extend(vcs_local_opts)
+ commit_cmd.extend(["-F", commitmessagefile])
+ commit_cmd.extend(myfiles)
+
+ try:
+ if options.pretend:
+ print("(%s)" % (" ".join(commit_cmd),))
+ else:
+ retval = spawn(commit_cmd, env=os.environ)
+ if retval != os.EX_OK:
+ writemsg_level(("!!! Exiting on %s (shell) " + \
+ "error code: %s\n") % (vcs, retval),
+ level=logging.ERROR, noiselevel=-1)
+ sys.exit(retval)
+ finally:
+ try:
+ os.unlink(commitmessagefile)
+ except OSError:
+ pass
+
+ # Setup the GPG commands
+ def gpgsign(filename):
+ gpgcmd = repoman_settings.get("PORTAGE_GPG_SIGNING_COMMAND")
+ if gpgcmd is None:
+ raise MissingParameter("PORTAGE_GPG_SIGNING_COMMAND is unset!" + \
+ " Is make.globals missing?")
+ if "${PORTAGE_GPG_KEY}" in gpgcmd and \
+ "PORTAGE_GPG_KEY" not in repoman_settings:
+ raise MissingParameter("PORTAGE_GPG_KEY is unset!")
+ if "${PORTAGE_GPG_DIR}" in gpgcmd:
+ if "PORTAGE_GPG_DIR" not in repoman_settings:
+ repoman_settings["PORTAGE_GPG_DIR"] = \
+ os.path.expanduser("~/.gnupg")
+ logging.info("Automatically setting PORTAGE_GPG_DIR to '%s'" \
+ % repoman_settings["PORTAGE_GPG_DIR"])
+ else:
+ repoman_settings["PORTAGE_GPG_DIR"] = \
+ os.path.expanduser(repoman_settings["PORTAGE_GPG_DIR"])
+ if not os.access(repoman_settings["PORTAGE_GPG_DIR"], os.X_OK):
+ raise portage.exception.InvalidLocation(
+ "Unable to access directory: PORTAGE_GPG_DIR='%s'" % \
+ repoman_settings["PORTAGE_GPG_DIR"])
+ gpgvars = {"FILE": filename}
+ for k in ("PORTAGE_GPG_DIR", "PORTAGE_GPG_KEY"):
+ v = repoman_settings.get(k)
+ if v is not None:
+ gpgvars[k] = v
+ gpgcmd = portage.util.varexpand(gpgcmd, mydict=gpgvars)
+ if options.pretend:
+ print("("+gpgcmd+")")
+ else:
+ rValue = os.system(gpgcmd)
+ if rValue == os.EX_OK:
+ os.rename(filename+".asc", filename)
+ else:
+ raise portage.exception.PortageException("!!! gpg exited with '" + str(rValue) + "' status")
+
+ # When files are removed and re-added, the cvs server will put /Attic/
+ # inside the $Header path. This code detects the problem and corrects it
+ # so that the Manifest will generate correctly. See bug #169500.
+ # Use binary mode in order to avoid potential character encoding issues.
+ cvs_header_re = re.compile(br'^#\s*\$Header.*\$$')
+ attic_str = b'/Attic/'
+ attic_replace = b'/'
+ for x in myheaders:
+ f = open(_unicode_encode(x,
+ encoding=_encodings['fs'], errors='strict'),
+ mode='rb')
+ mylines = f.readlines()
+ f.close()
+ modified = False
+ for i, line in enumerate(mylines):
+ if cvs_header_re.match(line) is not None and \
+ attic_str in line:
+ mylines[i] = line.replace(attic_str, attic_replace)
+ modified = True
+ if modified:
+ portage.util.write_atomic(x, b''.join(mylines),
+ mode='wb')
+
+ manifest_commit_required = True
+ if vcs in ('cvs', 'svn') and (myupdates or myremoved):
+ myfiles = myupdates + myremoved
+ for x in range(len(myfiles)-1, -1, -1):
+ if myfiles[x].count("/") < 4-repolevel:
+ del myfiles[x]
+ mydone=[]
+ if repolevel==3: # In a package dir
+ repoman_settings["O"] = startdir
+ digestgen(mysettings=repoman_settings, myportdb=portdb)
+ elif repolevel==2: # In a category dir
+ for x in myfiles:
+ xs=x.split("/")
+ if len(xs) < 4-repolevel:
+ continue
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] in mydone:
+ continue
+ mydone.append(xs[0])
+ repoman_settings["O"] = os.path.join(startdir, xs[0])
+ if not os.path.isdir(repoman_settings["O"]):
+ continue
+ digestgen(mysettings=repoman_settings, myportdb=portdb)
+ elif repolevel==1: # repo-cvsroot
+ print(green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n")
+ for x in myfiles:
+ xs=x.split("/")
+ if len(xs) < 4-repolevel:
+ continue
+ if xs[0]==".":
+ xs=xs[1:]
+ if "/".join(xs[:2]) in mydone:
+ continue
+ mydone.append("/".join(xs[:2]))
+ repoman_settings["O"] = os.path.join(startdir, xs[0], xs[1])
+ if not os.path.isdir(repoman_settings["O"]):
+ continue
+ digestgen(mysettings=repoman_settings, myportdb=portdb)
+ else:
+ print(red("I'm confused... I don't know where I am!"))
+ sys.exit(1)
+
+ # Force an unsigned commit when more than one Manifest needs to be signed.
+ if repolevel < 3 and "sign" in repoman_settings.features:
+
+ fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
+ mymsg = os.fdopen(fd, "wb")
+ mymsg.write(_unicode_encode(commitmessage))
+ mymsg.write(b"\n (Unsigned Manifest commit)")
+ mymsg.close()
+
+ commit_cmd = [vcs]
+ commit_cmd.extend(vcs_global_opts)
+ commit_cmd.append("commit")
+ commit_cmd.extend(vcs_local_opts)
+ commit_cmd.extend(["-F", commitmessagefile])
+ commit_cmd.extend(f.lstrip("./") for f in mymanifests)
+
+ try:
+ if options.pretend:
+ print("(%s)" % (" ".join(commit_cmd),))
+ else:
+ retval = spawn(commit_cmd, env=os.environ)
+ if retval:
+ writemsg_level(("!!! Exiting on %s (shell) " + \
+ "error code: %s\n") % (vcs, retval),
+ level=logging.ERROR, noiselevel=-1)
+ sys.exit(retval)
+ finally:
+ try:
+ os.unlink(commitmessagefile)
+ except OSError:
+ pass
+ manifest_commit_required = False
+
+ signed = False
+ if "sign" in repoman_settings.features:
+ signed = True
+ myfiles = myupdates + myremoved + mymanifests
+ try:
+ if repolevel==3: # In a package dir
+ repoman_settings["O"] = "."
+ gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
+ elif repolevel==2: # In a category dir
+ mydone=[]
+ for x in myfiles:
+ xs=x.split("/")
+ if len(xs) < 4-repolevel:
+ continue
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] in mydone:
+ continue
+ mydone.append(xs[0])
+ repoman_settings["O"] = os.path.join(".", xs[0])
+ if not os.path.isdir(repoman_settings["O"]):
+ continue
+ gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
+ elif repolevel==1: # repo-cvsroot
+ print(green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n")
+ mydone=[]
+ for x in myfiles:
+ xs=x.split("/")
+ if len(xs) < 4-repolevel:
+ continue
+ if xs[0]==".":
+ xs=xs[1:]
+ if "/".join(xs[:2]) in mydone:
+ continue
+ mydone.append("/".join(xs[:2]))
+ repoman_settings["O"] = os.path.join(".", xs[0], xs[1])
+ if not os.path.isdir(repoman_settings["O"]):
+ continue
+ gpgsign(os.path.join(repoman_settings["O"], "Manifest"))
+ except portage.exception.PortageException as e:
+ portage.writemsg("!!! %s\n" % str(e))
+ portage.writemsg("!!! Disabled FEATURES='sign'\n")
+ signed = False
+
+ if vcs == 'git':
+ # It's not safe to use the git commit -a option since there might
+ # be some modified files elsewhere in the working tree that the
+ # user doesn't want to commit. Therefore, call git update-index
+ # in order to ensure that the index is updated with the latest
+ # versions of all new and modified files in the relevant portion
+ # of the working tree.
+ myfiles = mymanifests + myupdates
+ myfiles.sort()
+ update_index_cmd = ["git", "update-index"]
+ update_index_cmd.extend(f.lstrip("./") for f in myfiles)
+ if options.pretend:
+ print("(%s)" % (" ".join(update_index_cmd),))
+ else:
+ retval = spawn(update_index_cmd, env=os.environ)
+ if retval != os.EX_OK:
+ writemsg_level(("!!! Exiting on %s (shell) " + \
+ "error code: %s\n") % (vcs, retval),
+ level=logging.ERROR, noiselevel=-1)
+ sys.exit(retval)
+
+ if vcs in ['git', 'bzr', 'hg'] or manifest_commit_required or signed:
+
+ myfiles = mymanifests[:]
+ if vcs in ['git', 'bzr', 'hg']:
+ myfiles += myupdates
+ myfiles += myremoved
+ myfiles.sort()
+
+ fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
+ mymsg = os.fdopen(fd, "wb")
+ # strip the closing parenthesis
+ mymsg.write(_unicode_encode(commitmessage[:-1]))
+ if signed:
+ mymsg.write(_unicode_encode(
+ ", signed Manifest commit with key %s)" % \
+ repoman_settings["PORTAGE_GPG_KEY"]))
+ else:
+ mymsg.write(b", unsigned Manifest commit)")
+ mymsg.close()
+
+ commit_cmd = []
+ if options.pretend and vcs is None:
+ # substitute a bogus value for pretend output
+ commit_cmd.append("cvs")
+ else:
+ commit_cmd.append(vcs)
+ commit_cmd.extend(vcs_global_opts)
+ commit_cmd.append("commit")
+ commit_cmd.extend(vcs_local_opts)
+ if vcs == "hg":
+ commit_cmd.extend(["--logfile", commitmessagefile])
+ commit_cmd.extend(myfiles)
+ else:
+ commit_cmd.extend(["-F", commitmessagefile])
+ commit_cmd.extend(f.lstrip("./") for f in myfiles)
+
+ try:
+ if options.pretend:
+ print("(%s)" % (" ".join(commit_cmd),))
+ else:
+ retval = spawn(commit_cmd, env=os.environ)
+ if retval != os.EX_OK:
+ writemsg_level(("!!! Exiting on %s (shell) " + \
+ "error code: %s\n") % (vcs, retval),
+ level=logging.ERROR, noiselevel=-1)
+ sys.exit(retval)
+ finally:
+ try:
+ os.unlink(commitmessagefile)
+ except OSError:
+ pass
+
+ print()
+ if vcs:
+ print("Commit complete.")
+ else:
+ print("repoman was too scared by not seeing any familiar version control file that he forgot to commit anything")
+ print(green("RepoMan sez:"), "\"If everyone were like you, I'd be out of business!\"\n")
+sys.exit(0)
+
diff --git a/portage_with_autodep/bin/xpak-helper.py b/portage_with_autodep/bin/xpak-helper.py
new file mode 100755
index 0000000..4766d99
--- /dev/null
+++ b/portage_with_autodep/bin/xpak-helper.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+# Copyright 2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import optparse
+import sys
+import portage
+from portage import os
+
+def command_recompose(args):
+
+ usage = "usage: recompose <binpkg_path> <metadata_dir>\n"
+
+ if len(args) != 2:
+ sys.stderr.write(usage)
+ sys.stderr.write("2 arguments are required, got %s\n" % len(args))
+ return 1
+
+ binpkg_path, metadata_dir = args
+
+ if not os.path.isfile(binpkg_path):
+ sys.stderr.write(usage)
+ sys.stderr.write("Argument 1 is not a regular file: '%s'\n" % \
+ binpkg_path)
+ return 1
+
+ if not os.path.isdir(metadata_dir):
+ sys.stderr.write(usage)
+ sys.stderr.write("Argument 2 is not a directory: '%s'\n" % \
+ metadata_dir)
+ return 1
+
+ t = portage.xpak.tbz2(binpkg_path)
+ t.recompose(metadata_dir)
+ return os.EX_OK
+
+def main(argv):
+
+ if argv and sys.hexversion < 0x3000000 and not isinstance(argv[0], unicode):
+ for i, x in enumerate(argv):
+ argv[i] = portage._unicode_decode(x, errors='strict')
+
+ valid_commands = ('recompose',)
+ description = "Perform metadata operations on a binary package."
+ usage = "usage: %s COMMAND [args]" % \
+ os.path.basename(argv[0])
+
+ parser = optparse.OptionParser(description=description, usage=usage)
+ options, args = parser.parse_args(argv[1:])
+
+ if not args:
+ parser.error("missing command argument")
+
+ command = args[0]
+
+ if command not in valid_commands:
+ parser.error("invalid command: '%s'" % command)
+
+ if command == 'recompose':
+ rval = command_recompose(args[1:])
+ else:
+ raise AssertionError("invalid command: '%s'" % command)
+
+ return rval
+
+if __name__ == "__main__":
+ rval = main(sys.argv[:])
+ sys.exit(rval)