aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/archive-conf101
-rwxr-xr-xbin/chkcontents62
-rwxr-xr-xbin/clean_locks36
-rwxr-xr-xbin/dispatch-conf311
-rwxr-xr-xbin/dobin28
-rwxr-xr-xbin/doconfd15
-rwxr-xr-xbin/dodir8
-rwxr-xr-xbin/dodoc23
-rwxr-xr-xbin/doenvd15
-rwxr-xr-xbin/doexe26
-rwxr-xr-xbin/dohard13
-rwxr-xr-xbin/dohtml159
-rwxr-xr-xbin/doinfo21
-rwxr-xr-xbin/doinitd15
-rwxr-xr-xbin/doins53
-rwxr-xr-xbin/dojar54
-rwxr-xr-xbin/dolib41
-rwxr-xr-xbin/dolib.a7
-rwxr-xr-xbin/dolib.so7
-rwxr-xr-xbin/doman52
-rwxr-xr-xbin/domo26
-rwxr-xr-xbin/dopython23
-rwxr-xr-xbin/dosbin27
-rwxr-xr-xbin/dosed22
-rwxr-xr-xbin/dosym13
-rwxr-xr-xbin/ebuild61
-rwxr-xr-xbin/ebuild.sh1868
-rwxr-xr-xbin/emake14
-rwxr-xr-xbin/emerge3213
-rwxr-xr-xbin/emerge-webrsync141
-rwxr-xr-xbin/emerge.orig3227
-rwxr-xr-xbin/env-update11
-rwxr-xr-xbin/env-update.sh221
-rwxr-xr-xbin/etc-update407
-rwxr-xr-xbin/find-requires44
-rwxr-xr-xbin/fix-db.py175
-rwxr-xr-xbin/fixdbentries20
-rwxr-xr-xbin/fixpackages14
-rwxr-xr-xbin/fowners15
-rwxr-xr-xbin/fperms15
-rwxr-xr-xbin/md5check.py102
-rwxr-xr-xbin/md5check.sh31
-rwxr-xr-xbin/mirror.py167
-rwxr-xr-xbin/newbin13
-rwxr-xr-xbin/newconfd13
-rwxr-xr-xbin/newdoc13
-rwxr-xr-xbin/newenvd13
-rwxr-xr-xbin/newexe13
-rwxr-xr-xbin/newinitd13
-rwxr-xr-xbin/newins13
-rwxr-xr-xbin/newlib.a13
-rwxr-xr-xbin/newlib.so13
-rwxr-xr-xbin/newman13
-rwxr-xr-xbin/newsbin13
-rwxr-xr-xbin/pemerge.py44
-rwxr-xr-xbin/pkgmerge59
-rwxr-xr-xbin/pkgmerge.new84
-rwxr-xr-xbin/pkgname17
-rwxr-xr-xbin/portage_gpg_update.sh6
-rwxr-xr-xbin/portageq256
-rwxr-xr-xbin/prepall39
-rwxr-xr-xbin/prepalldocs33
-rwxr-xr-xbin/prepallinfo9
-rwxr-xr-xbin/prepallman12
-rwxr-xr-xbin/prepallstrip11
-rwxr-xr-xbin/prepinfo45
-rwxr-xr-xbin/preplib25
-rwxr-xr-xbin/preplib.so10
-rwxr-xr-xbin/prepman46
-rwxr-xr-xbin/prepstrip48
-rwxr-xr-xbin/quickpkg148
-rwxr-xr-xbin/regenworld93
-rwxr-xr-xbin/repoman1522
-rwxr-xr-xbin/xpak14
74 files changed, 13568 insertions, 0 deletions
diff --git a/bin/archive-conf b/bin/archive-conf
new file mode 100755
index 000000000..6e198f49f
--- /dev/null
+++ b/bin/archive-conf
@@ -0,0 +1,101 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/archive-conf,v 1.7 2004/10/04 13:57:36 vapier Exp $
+
+#
+# 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.
+#
+
+import os, sys, string
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage, 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 xrange(len(md5sum)):
+ hexform = hexform + "%02x" % ord(md5sum[ix])
+ return string.lower(hexform)
+
+ def perform_checksum(filename):
+ f = open(filename, 'rb')
+ blocksize=32768
+ data = f.read(blocksize)
+ size = 0L
+ 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 = 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 % (portage.root+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, e:
+ print >> sys.stderr, 'archive-conf: Unable to open %s: %s' % (file, e)
+ sys.exit(1)
+ lines = contents.readlines()
+ for line in lines:
+ items = string.split(line)
+ if items[0] == 'obj':
+ for conf in args:
+ if items[1] == conf:
+ stored = string.lower(items[2])
+ real = string.lower(perform_checksum(conf)[0])
+ if stored == real:
+ md5_match_hash[conf] = conf
+ todo_cnt -= 1
+ if todo_cnt == 0:
+ raise "Break"
+ except "Break":
+ pass
+
+ for conf in args:
+ archive = os.path.join(options['archive-dir'], conf.lstrip('/'))
+ if options['use-rcs'] == 'yes':
+ dispatch_conf.rcs_archive(archive, conf, md5_match_hash[conf], '')
+ dispatch_conf.rcs_archive_post_process(archive)
+ else:
+ dispatch_conf.file_archive(archive, conf, md5_match_hash[conf], '')
+ dispatch_conf.file_archive_post_process(archive)
+
+# run
+if len(sys.argv) > 1:
+ archive_conf()
+else:
+ print >> sys.stderr, 'Usage: archive-conf /CONFIG/FILE [/CONFIG/FILE...]'
diff --git a/bin/chkcontents b/bin/chkcontents
new file mode 100755
index 000000000..eebf868cd
--- /dev/null
+++ b/bin/chkcontents
@@ -0,0 +1,62 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/chkcontents,v 1.11 2004/10/04 13:56:50 vapier Exp $
+
+# Very simple program to compare the md5sums of a package as listed
+# in VDB_PATH/category/package/CONTENTS with the md5sums of the
+# actual programs on the system (and makes sure that symlinks point to
+# the right files).
+
+import string, os.path, os, sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+import portage
+
+def CONTENTScheck(path):
+ try:
+ contents = open(path, "r")
+ except IOError, e:
+ print "Unable to open %s: %s" % (path, e)
+ sys.exit(1)
+ lines = contents.readlines()
+ for line in lines:
+ items = string.split(line)
+ # items is a list w/ size depending on the type of item listed in item[0]
+ # if items[0] = 'dir' then items[1] is the path of a directory
+ # if items[0] = 'obj' then items[1] is the path of a file,
+ # items[2] is the file's md5sum,
+ # items[3] is the file's size
+ # if items[0] = 'sym' then items[1] is the path of a symbolic link,
+ # items[2] is '->'
+ # items[3] is the file the symlink should point to
+ # items[4] is the symlink mtime
+ if (items[0] == 'obj'):
+ md5stored = string.lower(items[2])
+ # fchksum.fmdft(file) returns the file's md5sum and the file's size
+ md5real = string.lower(portage.perform_checksum(items[1])[0])
+ if (md5stored != md5real):
+ if md5real:
+ print "%s has md5sum of %s instead of %s" % (items[1], md5real, md5stored)
+ else:
+ print "%s is missing!" % items[1]
+ elif (items[0] == 'sym'):
+ link = items[1]
+ target = items[3]
+ if (not os.path.islink(link)):
+ print "%s is not a symbolic link" % link
+ continue
+ actualtarget = os.readlink(link)
+ if (os.path.normpath(actualtarget) != os.path.normpath(target)):
+ print "%s points to %s, not %s" % (link, actualtarget, target)
+
+
+if __name__ == '__main__':
+ import sys
+ if (len(sys.argv) != 2 or sys.argv[1] == "--help"):
+ print "This program compares md5sums in the file VDB_PATH/category/package/CONTENTS"
+ print "with the md5sums of the actual files on the filesystem"
+ print "(and makes sure that symlinks point to the right files)."
+ print "\nUsage: chkcontents path/to/CONTENTS"
+ sys.exit(1)
+ CONTENTScheck(sys.argv[1])
+
diff --git a/bin/clean_locks b/bin/clean_locks
new file mode 100755
index 000000000..aa6669c16
--- /dev/null
+++ b/bin/clean_locks
@@ -0,0 +1,36 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/clean_locks,v 1.1 2004/09/26 10:44:31 carpaski Exp $
+
+import os,sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage_locks
+
+if not sys.argv[1:] or "--help" in sys.argv or "-h" in sys.argv:
+ 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 sys.argv[0]+" /usr/portage/distfiles/.locks"
+ print sys.argv[0]+" --force /usr/portage/distfiles/.locks"
+ print
+ sys.exit(1)
+
+force = False
+if "--force" in sys.argv[1:]:
+ force=True
+
+for x in sys.argv[1:]:
+ if x == "--force":
+ continue
+ for y in portage_locks.hardlock_cleanup(x, remove_all_locks=force):
+ print y
+ print
+
+
+
+ \ No newline at end of file
diff --git a/bin/dispatch-conf b/bin/dispatch-conf
new file mode 100755
index 000000000..2db6a329a
--- /dev/null
+++ b/bin/dispatch-conf
@@ -0,0 +1,311 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dispatch-conf,v 1.7.2.10 2005/05/12 15:20:22 jstubbs Exp $
+
+#
+# dispatch-conf -- Integrate modified configs, post-emerge
+#
+# Jeremy Wohl (http://igmus.org)
+#
+# TODO
+# dialog menus
+#
+
+from stat import *
+from random import *
+import os, shutil, sys, string, re, commands, atexit
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage, dispatch_conf
+
+FIND_EXTANT_CONFIGS = "find %s/ -iname '._cfg????_*' | sed -e 's://:/:g'"
+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(0077)
+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, e:
+ if e.errno != 17:
+ raise
+os.umask(oldmask)
+
+# Ensure the scratch dir is deleted
+def cleanup(mydir=SCRATCH_DIR):
+ shutil.rmtree(SCRATCH_DIR)
+atexit.register(cleanup)
+
+MANDATORY_OPTS = [ 'archive-dir', 'diff', 'replace-cvs', 'replace-wscomments', 'merge' ]
+
+class dispatch:
+ options = {}
+
+ def grind (self, config_paths):
+ confs = []
+ count = 0
+
+
+ self.options = dispatch_conf.read_config(MANDATORY_OPTS)
+
+ if self.options.has_key("log-file"):
+ if os.path.exists(self.options["log-file"]):
+ shutil.copyfile(self.options["log-file"], self.options["log-file"] + '.old')
+ os.remove(self.options["log-file"])
+ else:
+ self.options["log-file"] = "/dev/null"
+
+ #
+ # Build list of extant configs
+ #
+
+ for path in config_paths.split ():
+ if not os.path.exists (path):
+ continue
+
+ confs += self.massage (os.popen (FIND_EXTANT_CONFIGS % (path,)).readlines ())
+
+ if self.options['use-rcs'] == 'yes' and ((os.system( "which rcs >/dev/null 2>&1" ) == 256)
+ or (os.system( "which ci >/dev/null 2>&1" ) == 256)
+ or (os.system( "which co >/dev/null 2>&1" ) == 256)
+ or (os.system( "which rcsmerge >/dev/null 2>&1" ) == 256)):
+ print >> sys.stderr, 'dispatch-conf: Error finding all RCS utils and use-rcs=yes in config; fatal'
+ return False
+
+
+ #
+ # 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 = dispatch_conf.rcs_archive(archive, conf['current'], conf['new'], mrgconf)
+ else:
+ mrgfail = dispatch_conf.file_archive(archive, conf['current'], conf['new'], mrgconf)
+ if os.path.exists(archive + '.dist'):
+ unmodified = len(commands.getoutput(DIFF_CONTENTS % (conf['current'], archive + '.dist'))) == 0
+ else:
+ unmodified = 0
+ if os.path.exists(mrgconf):
+ if mrgfail or len(commands.getoutput(DIFF_CONTENTS % (conf['new'], mrgconf))) == 0:
+ os.unlink(mrgconf)
+ newconf = conf['new']
+ else:
+ newconf = mrgconf
+ else:
+ newconf = conf['new']
+
+ same_file = len(commands.getoutput (DIFF_CONTENTS % (conf ['current'], newconf))) == 0
+ same_cvs = len(commands.getoutput (DIFF_CVS_INTERP % (conf ['current'], newconf))) == 0
+ same_wsc = len(commands.getoutput (DIFF_WSCOMMENTS % (conf ['current'], newconf))) == 0
+
+ # 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 unmodified or same_cvs or same_wsc or conf ['dir'] in portage.settings ['CONFIG_PROTECT_MASK'].split ():
+ 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 = filter (f, confs)
+
+ #
+ # Interactively process remaining
+ #
+
+ 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:
+ if show_new_diff:
+ os.system((self.options['diff']) % (conf['new'], mrgconf))
+ show_new_diff = 0
+ else:
+ os.system((self.options['diff']) % (conf['current'], newconf))
+
+ 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: ',
+
+ c = getch ()
+
+ 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
+ os.system (self.options['merge'] % (merged, conf ['current'], newconf))
+ 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':
+ 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:
+ continue
+
+
+ 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:
+ shutil.copyfile(newconf, curconf)
+ os.remove(newconf)
+ except (IOError, os.error), why:
+ print >> sys.stderr, 'dispatch-conf: Error renaming %s to %s: %s; fatal' % \
+ (newconf, curconf, str(why))
+
+
+ def post_process(self, curconf):
+ archive = os.path.join(self.options['archive-dir'], curconf.lstrip('/'))
+ if self.options['use-rcs'] == 'yes':
+ dispatch_conf.rcs_archive_post_process(archive)
+ else:
+ 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 = {}
+
+ newconfigs.sort ()
+
+ for nconf in newconfigs:
+ nconf = nconf.rstrip ()
+ conf = re.sub (r'\._cfg\d+_', '', nconf)
+ dir = re.match (r'^(.+)/', nconf).group (1)
+
+ if h.has_key (conf):
+ mrgconf = re.sub(r'\._cfg', '._mrg', h[conf]['new'])
+ if os.path.exists(mrgconf):
+ os.unlink(mrgconf)
+ os.unlink(h[conf]['new'])
+
+ h [conf] = { 'current' : conf, 'dir' : dir, 'new' : nconf }
+
+ configs = h.values ()
+ configs.sort (lambda a, b: cmp(a ['current'], b ['current']))
+
+ 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...',
+
+ 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
+
+
+# run
+d = dispatch ()
+
+if len(sys.argv) > 1:
+ # for testing
+ d.grind (string.join (sys.argv [1:]))
+else:
+ d.grind (portage.settings ['CONFIG_PROTECT'])
diff --git a/bin/dobin b/bin/dobin
new file mode 100755
index 000000000..4c070d95b
--- /dev/null
+++ b/bin/dobin
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dobin,v 1.13 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+
+if [ ! -d "${D}${DESTTREE}/bin" ] ; then
+ install -d "${D}${DESTTREE}/bin" || exit 2
+fi
+
+for x in "$@" ; do
+ if [ -x "${x}" ] ; then
+ #if executable, use existing perms
+ install "${x}" "${D}${DESTTREE}/bin" || exit 3
+ else
+ #otherwise, use reasonable defaults
+ echo ">>> dobin: making ${x} executable..."
+ if [ "$USERLAND" == "GNU" ]; then
+ install -m0755 -o root -g root "${x}" "${D}${DESTTREE}/bin" || exit 4
+ else
+ install -m0755 -o root -g wheel "${x}" "${D}${DESTTREE}/bin" || exit 4
+ fi
+ fi
+done
diff --git a/bin/doconfd b/bin/doconfd
new file mode 100755
index 000000000..73d5cedcf
--- /dev/null
+++ b/bin/doconfd
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doconfd,v 1.2.2.1 2005/01/13 04:51:56 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "doconfd: at least one argument needed"
+ exit 1
+fi
+
+tmp_INSDESTTREE="${INSDESTTREE}"
+INSDESTTREE=/etc/conf.d/
+doins "$@"
+INSDESTTREE="${tmp_INSDESTTREE}"
+unset tmp_INSDESTTREE
diff --git a/bin/dodir b/bin/dodir
new file mode 100755
index 000000000..6df8f4031
--- /dev/null
+++ b/bin/dodir
@@ -0,0 +1,8 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dodir,v 1.5 2004/10/04 13:56:50 vapier Exp $
+
+for x in "$@" ; do
+ install -d ${DIROPTIONS} "${D}${x}"
+done
diff --git a/bin/dodoc b/bin/dodoc
new file mode 100755
index 000000000..a25aeddb9
--- /dev/null
+++ b/bin/dodoc
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dodoc,v 1.6.2.2 2005/05/15 11:04:21 jstubbs Exp $
+
+if [ $# -lt 1 ] ; then
+ echo "$0: at least one argument needed" 1>&2
+ exit 1
+fi
+
+dir="${D}usr/share/doc/${PF}/${DOCDESTTREE}"
+if [ ! -d "${dir}" ] ; then
+ install -d "${dir}"
+fi
+
+for x in "$@" ; do
+ if [ -s "${x}" ] ; then
+ install -m0644 "${x}" "${dir}"
+ gzip -f -9 "${dir}/${x##*/}"
+ elif [ ! -e "${x}" ] ; then
+ echo "dodoc: ${x} does not exist" 1>&2
+ fi
+done
diff --git a/bin/doenvd b/bin/doenvd
new file mode 100755
index 000000000..8a794d7f6
--- /dev/null
+++ b/bin/doenvd
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doenvd,v 1.2.2.1 2005/01/13 04:51:56 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "doenvd: at least one argument needed"
+ exit 1
+fi
+
+tmp_INSDESTTREE="${INSDESTTREE}"
+INSDESTTREE=/etc/env.d/
+doins "$@"
+INSDESTTREE="${tmp_INSDESTTREE}"
+unset tmp_INSDESTTREE
diff --git a/bin/doexe b/bin/doexe
new file mode 100755
index 000000000..9c2f41093
--- /dev/null
+++ b/bin/doexe
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doexe,v 1.10.2.1 2004/12/06 03:01:43 carpaski Exp $
+
+mynum=${#}
+if [ ${mynum} -lt 1 ] ; then
+ echo "doexe: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${D}${EXEDESTTREE}" ] ; then
+ install -d "${D}${EXEDESTTREE}"
+fi
+
+for x in "$@" ; do
+ if [ -L "${x}" ] ; then
+ cp "${x}" "${T}"
+ mysrc="${T}"/`/usr/bin/basename "${x}"`
+ elif [ -d "${x}" ] ; then
+ echo "doexe: warning, skipping directory ${x}"
+ continue
+ else
+ mysrc="${x}"
+ fi
+ install ${EXEOPTIONS} "${mysrc}" "${D}${EXEDESTTREE}"
+done
diff --git a/bin/dohard b/bin/dohard
new file mode 100755
index 000000000..7313e2f24
--- /dev/null
+++ b/bin/dohard
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dohard,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -ne 2 ] ; then
+ echo "${0}: two arguments needed"
+ exit 1
+fi
+
+mysrc="${1}"
+mydest="${2}"
+ln -f "${D}${mysrc}" "${D}${mydest}"
diff --git a/bin/dohtml b/bin/dohtml
new file mode 100755
index 000000000..50e13924a
--- /dev/null
+++ b/bin/dohtml
@@ -0,0 +1,159 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dohtml,v 1.14.2.1 2004/10/27 14:39:29 jstubbs Exp $
+
+#
+# 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 .html, .png, .jpg
+# or .css
+# 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
+#
+
+import os
+import string
+import sys
+import types
+
+def dodir(path):
+ os.system("install -d '%s'" % path)
+
+def dofile(src,dst):
+
+ os.system("install -m0644 '%s' '%s'" % (src, dst))
+
+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 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)
+
+class OptionsClass:
+ def __init__(self):
+ self.PF = ""
+ self.D = ""
+ self.DOCDESTTREE = ""
+
+ if os.environ.has_key("PF"):
+ self.PF = os.environ["PF"]
+ if os.environ.has_key("D"):
+ self.D = os.environ["D"]
+ if os.environ.has_key("DOCDESTTREE"):
+ self.DOCDESTTREE = os.environ["DOCDESTTREE"]
+
+ self.allowed_exts = [ 'png', 'gif', 'html', 'htm', 'jpg', 'css', 'js' ]
+ 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:", string.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:", string.join(opts.disallowed_dirs, ",")
+ 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 = string.split(sys.argv[x], ",")
+ 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 type(options.allowed_exts) == types.StringType:
+ options.allowed_exts = options.allowed_exts.split(",")
+
+ if options.verbose:
+ print "Allowed extensions:", options.allowed_exts
+ print "Document prefix : '" + options.doc_prefix + "'"
+ print "Allowed files :", options.allowed_files
+
+ for x in args:
+ basename = os.path.basename(x)
+ dirname = os.path.dirname(x)
+ install(basename, dirname, options)
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/doinfo b/bin/doinfo
new file mode 100755
index 000000000..a8d7f4d7e
--- /dev/null
+++ b/bin/doinfo
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doinfo,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "doinfo: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${D}usr/share/info" ] ; then
+ install -d "${D}usr/share/info"
+fi
+
+for x in "$@" ; do
+ if [ -e "${x}" ] ; then
+ install -m0644 "${x}" "${D}usr/share/info"
+ gzip -f -9 "${D}usr/share/info/${x##*/}"
+ else
+ echo "doinfo: ${x} does not exist"
+ fi
+done
diff --git a/bin/doinitd b/bin/doinitd
new file mode 100755
index 000000000..d4f725ab4
--- /dev/null
+++ b/bin/doinitd
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doinitd,v 1.2.2.1 2005/01/13 04:51:56 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "doinitd: at least one argument needed"
+ exit 1
+fi
+
+tmp_EXEDESTTREE="${EXEDESTTREE}"
+EXEDESTTREE=/etc/init.d/
+doexe "$@"
+EXEDESTTREE="${tmp_EXEDESTTREE}"
+unset tmp_EXEDESTTREE
diff --git a/bin/doins b/bin/doins
new file mode 100755
index 000000000..551905e93
--- /dev/null
+++ b/bin/doins
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doins,v 1.7.2.2 2004/12/17 22:25:13 carpaski Exp $
+
+if [ $# -lt 1 ] ; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+
+if [ "${1}" == "-r" ] ; then
+ DOINSRECUR=y
+ shift
+else
+ DOINSRECUR=n
+fi
+[ -z "${INSDEPTH}" ] && declare -i INSDEPTH=0
+if [ ${INSDEPTH} -gt 30 ] ; then
+ echo "${0}: sanity check ... 30 directories is too much :("
+ exit 1
+fi
+
+if [ "${INSDESTTREE%${D}*}" == "" ]; then
+ echo "-------------------------------------------------------" 1>&2
+ echo "You should not use \${D} with helpers." 1>&2
+ echo " --> ${INSDESTTREE}" 1>&2
+ echo "-------------------------------------------------------" 1>&2
+ #exit 1
+fi
+
+[ ! -d "${D}${INSDESTTREE}" ] && dodir "${INSDESTTREE}"
+
+for x in "$@" ; do
+ if [ -L "$x" ] ; then
+ cp "$x" "${T}"
+ mysrc="${T}/$(/usr/bin/basename "${x}")"
+ elif [ -d "$x" ] ; then
+ if [ "${DOINSRECUR}" == "n" ] ; then
+ continue
+ fi
+
+ mydir="${INSDESTTREE}/$(basename "${x}")"
+ find "${x}" -mindepth 1 -maxdepth 1 -exec \
+ env \
+ INSDESTTREE="${mydir}" \
+ INSDEPTH=$((INSDEPTH+1)) \
+ doins -r {} \;
+ continue
+ else
+ mysrc="${x}"
+ fi
+ install ${INSOPTIONS} "${mysrc}" "${D}${INSDESTTREE}"
+done
diff --git a/bin/dojar b/bin/dojar
new file mode 100755
index 000000000..77dadfee0
--- /dev/null
+++ b/bin/dojar
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dojar,v 1.8 2004/10/04 13:56:50 vapier Exp $
+# Author Karl Trygve Kalleberg <karltk@gentoo.org>
+
+#
+# Typical usage:
+# dojar foo.jar bar.jar
+# - installs foo.jar and bar.jar into /usr/share/${PN}/lib, and adds them
+# both to /usr/share/${PN}/classpath.env
+#
+# Detailed usage
+# dojar <list-of-jars>
+# - installs <list-of-jars> into /usr/share/${PN}/lib and adds each to
+# /usr/share/${PN}/classpath.env.
+#
+# The classpath.env file is currently merely a convenience for the user as
+# it allows him to:
+# export CLASSPATH=${CLASSPATH}:`cat /usr/share/foo/classpath.env`
+#
+# For many packages that set FOO_HOME, placing the jar files into
+# lib will allow the user to set FOO_HOME=/usr/share/foo and have the
+# scripts work as expected.
+#
+# Possibly a jarinto will be needed in the future.
+#
+
+if [ -z "$JARDESTTREE" ] ; then
+ JARDESTTREE="lib"
+fi
+
+jarroot="${DESTTREE}/share/${PN}/"
+jardest="${DESTTREE}/share/${PN}/${JARDESTTREE}/"
+pf="${D}${jarroot}/package.env"
+
+dodir "${jardest}"
+
+for i in $* ; do
+ bn="$(basename $i)"
+
+ if [ -f "$pf" ] ; then
+ oldcp=`grep "CLASSPATH=" "$pf" | sed "s/CLASSPATH=//"`
+ grep -v "CLASSPATH=" "$pf" > "${pf}.new"
+ echo "CLASSPATH=${oldcp}:${jardest}${bn}" >> "${pf}.new"
+ mv "${pf}.new" "$pf"
+ else
+ echo "DESCRIPTION=\"${DESCRIPTION}\"" > "$pf"
+ echo "CLASSPATH=${jardest}${bn}" >> "$pf"
+ fi
+
+ cp "$i" "${D}${jardest}/"
+ chmod 0444 "${D}${jardest}/${bn}"
+done
diff --git a/bin/dolib b/bin/dolib
new file mode 100755
index 000000000..51b2327d3
--- /dev/null
+++ b/bin/dolib
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dolib,v 1.8.2.2 2005/01/12 02:07:15 carpaski Exp $
+
+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
+libdir="${D}${DESTTREE}/${CONF_LIBDIR}"
+for X in 1 2 3; do
+ # The escaping is weird. It will break if you escape the last one.
+ libdir="${libdir//\/\///}"
+done
+
+
+if [ ${#} -lt 1 ] ; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${libdir}" ] ; then
+ install -d "${libdir}"
+fi
+
+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"
+ fi
+done
diff --git a/bin/dolib.a b/bin/dolib.a
new file mode 100755
index 000000000..f7cced1c6
--- /dev/null
+++ b/bin/dolib.a
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dolib.a,v 1.8 2004/10/10 10:07:20 carpaski Exp $
+
+exec env LIBOPTIONS="-m0644" \
+ dolib "$@"
diff --git a/bin/dolib.so b/bin/dolib.so
new file mode 100755
index 000000000..aa6df7db8
--- /dev/null
+++ b/bin/dolib.so
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dolib.so,v 1.12 2004/10/10 10:07:20 carpaski Exp $
+
+exec env LIBOPTIONS="-m0755" \
+ dolib "$@"
diff --git a/bin/doman b/bin/doman
new file mode 100755
index 000000000..5c23ea0d2
--- /dev/null
+++ b/bin/doman
@@ -0,0 +1,52 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/doman,v 1.13.2.2 2005/07/29 05:55:34 vapier Exp $
+
+if [ $# -lt 1 ] ; then
+ echo "$0: at least one argument needed" 1>&2
+ exit 1
+fi
+
+BASE="/usr/share"
+i18n=""
+
+for x in "$@" ; do
+ if [ "${x:0:6}" == "-i18n=" ] ; then
+ i18n="${x:6}/"
+ fi
+ if [ "${x}" == ".keep" ] ; then
+ continue
+ fi
+
+ suffix=${x##*.}
+
+ if [ "$suffix" == "gz" ] ; then
+ compressed="gz"
+ realname="${x%.*}"
+ suffix="${realname##*.}"
+ else
+ realname="$x"
+ compressed=""
+ fi
+
+ mandir=${i18n}man${suffix:0:1}
+
+ if echo ${mandir} | egrep -q 'man[0-9n](|f|p|pm)$' -; then
+ if [ -s "${x}" ] ; then
+ if [ ! -d "${D}${BASE}/man/${mandir}" ] ; then
+ install -d "${D}${BASE}/man/${mandir}"
+ fi
+
+ install -m0644 "${x}" "${D}${BASE}/man/${mandir}"
+
+ if [ -z "${compressed}" ] ; then
+ gzip -f -9 "${D}${BASE}/man/${mandir}/${x##*/}"
+ fi
+ else
+ echo "doman: ${x} does not exist" 1>&2
+ fi
+ else
+ echo "doman: '${x}' is probably not a man page; skipping" 1>&2
+ fi
+done
diff --git a/bin/domo b/bin/domo
new file mode 100755
index 000000000..ca3cf4b4e
--- /dev/null
+++ b/bin/domo
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/domo,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+mynum=${#}
+if [ ${mynum} -lt 1 ] ; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${D}${DESTTREE}/share/locale" ] ; then
+ install -d "${D}${DESTTREE}/share/locale/"
+fi
+
+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"
+ fi
+done
diff --git a/bin/dopython b/bin/dopython
new file mode 100755
index 000000000..a3ffab968
--- /dev/null
+++ b/bin/dopython
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dopython,v 1.8 2004/10/04 13:56:50 vapier Exp $
+
+import sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+from sys import *
+import portage
+import types
+mycommand=argv[1]+"("
+x=2
+while (x<len(argv)):
+ if x==(len(argv)-1):
+ mycommand=mycommand+'"'+argv[x]+'"'
+ else:
+ mycommand=mycommand+'"'+argv[x]+'",'
+ x=x+1
+mycommand=mycommand+")"
+exec("myresult="+mycommand)
+if type(myresult)==types.IntType:
+ exit(myresult)
diff --git a/bin/dosbin b/bin/dosbin
new file mode 100755
index 000000000..960d38758
--- /dev/null
+++ b/bin/dosbin
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dosbin,v 1.11 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -lt 1 ] ; then
+ echo "${0}: at least one argument needed"
+ exit 1
+fi
+if [ ! -d "${D}${DESTTREE}/sbin" ] ; then
+ install -d "${D}${DESTTREE}/sbin" || exit 2
+fi
+
+for x in "$@" ; do
+ if [ -x "${x}" ] ; then
+ #if executable, use existing perms
+ install -m0755 "${x}" "${D}${DESTTREE}/sbin" || exit 3
+ else
+ #otherwise, use reasonable defaults
+ echo ">>> dosbin: making ${x} executable..."
+ if [ "$USERLAND" == "GNU" ]; then
+ install -m0755 -o root -g root "${x}" "${D}${DESTTREE}/sbin" || exit 4
+ else
+ install -m0755 -o root -g wheel "${x}" "${D}${DESTTREE}/sbin" || exit 4
+ fi
+ fi
+done
diff --git a/bin/dosed b/bin/dosed
new file mode 100755
index 000000000..2c53b22d3
--- /dev/null
+++ b/bin/dosed
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dosed,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+mysed="s:${D}::g"
+
+for x in "$@" ; do
+ y="${D}${x}"
+ if [ -a "${y}" ] ; then
+ if [ -f "${y}" ] ; then
+ mysrc="${T}/${y##*/}"
+ cp "${y}" "${mysrc}"
+ sed -e "${mysed}" "${mysrc}" > "${y}"
+ else
+ echo "${y} is not a regular file!"
+ exit 1
+ fi
+ else
+ mysed="${x}"
+ fi
+done
diff --git a/bin/dosym b/bin/dosym
new file mode 100755
index 000000000..ca8cb713f
--- /dev/null
+++ b/bin/dosym
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/dosym,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -ne 2 ] ; then
+ echo "${0}: two arguments needed"
+ exit 1
+fi
+
+target="${1}"
+linkname="${2}"
+ln -snf "${target}" "${D}${linkname}"
diff --git a/bin/ebuild b/bin/ebuild
new file mode 100755
index 000000000..2c4ed713d
--- /dev/null
+++ b/bin/ebuild
@@ -0,0 +1,61 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/ebuild,v 1.18.2.3 2005/05/07 04:32:59 ferringb Exp $
+
+import os,sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+import portage_util
+
+def getroot():
+ try:
+ a=os.environ["ROOT"]
+ if a == '/':
+ return '/'
+ except SystemExit, e:
+ raise # Needed else we can't exit.
+ except:
+ return '/'
+ return os.path.normpath(a)+'/'
+
+os.environ["PORTAGE_CALLER"]="ebuild"
+
+if len(sys.argv)<=2:
+ print "expecting two arguments."
+ sys.exit(1)
+
+import getopt
+
+debug=0
+
+opts,pargs=getopt.getopt(sys.argv[1:],'',['debug'])
+for opt in opts:
+ if opt[0]=='--debug':
+ debug=1
+
+if "merge" in pargs:
+ print "Disabling noauto in features... merge disables it. (qmerge doesn't)"
+ os.environ["FEATURES"] = os.environ.get("FEATURES", "") + " -noauto"
+
+import portage
+
+for x in pargs[1:]:
+ try:
+ tmpsettings = portage.config(clone=portage.settings)
+
+ if x in ['clean','config']:
+ cleanup=1
+ else:
+ cleanup=0
+ a=portage.doebuild(pargs[0],x,getroot(),tmpsettings,debug=debug,cleanup=cleanup)
+ except KeyboardInterrupt:
+ print "(interrupted by user -- ctrl-C?)"
+ a=1
+ except IOError:
+ a=1
+ print "ebuild: this ebuild generated output during the depend phase (bad)"
+ if a == None:
+ portage_util.writemsg("Could not run the required binary?\n")
+ sys.exit(127)
+ if a:
+ sys.exit(a)
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
new file mode 100755
index 000000000..3271859ea
--- /dev/null
+++ b/bin/ebuild.sh
@@ -0,0 +1,1868 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/ebuild.sh,v 1.201.2.42 2005/08/20 17:24:30 jstubbs Exp $
+
+export SANDBOX_PREDICT="${SANDBOX_PREDICT}:/proc/self/maps:/dev/console:/usr/lib/portage/pym:/dev/random"
+export SANDBOX_WRITE="${SANDBOX_WRITE}:/dev/shm:${PORTAGE_TMPDIR}"
+export SANDBOX_READ="${SANDBOX_READ}:/dev/shm:${PORTAGE_TMPDIR}"
+
+if [ ! -z "${PORTAGE_GPG_DIR}" ]; then
+ SANDBOX_PREDICT="${SANDBOX_PREDICT}:${PORTAGE_GPG_DIR}"
+fi
+
+if [ "$*" != "depend" ] && [ "$*" != "clean" ] && [ "$*" != "nofetch" ]; then
+ if [ -f "${T}/environment" ]; then
+ source "${T}/environment" &>/dev/null
+ fi
+fi
+
+if [ -n "$#" ]; then
+ ARGS="${*}"
+fi
+
+declare -rx EBUILD_PHASE="$*"
+
+# 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
+
+# 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 die='diefunc "$FUNCNAME" "$LINENO" "$?"'
+alias assert='_pipestatus="${PIPESTATUS[*]}"; [[ "${_pipestatus// /}" -eq 0 ]] || diefunc "$FUNCNAME" "$LINENO" "$_pipestatus"'
+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'
+
+OCC="$CC"
+OCXX="$CXX"
+source /etc/profile.env &>/dev/null
+if [ -f "${PORTAGE_BASHRC}" ]; then
+ source "${PORTAGE_BASHRC}"
+fi
+[ ! -z "$OCC" ] && export CC="$OCC"
+[ ! -z "$OCXX" ] && export CXX="$OCXX"
+
+export PATH="/sbin:/usr/sbin:/usr/lib/portage/bin:/bin:/usr/bin:${ROOTPATH}"
+[ ! -z "$PREROOTPATH" ] && export PATH="${PREROOTPATH%%:}:$PATH"
+
+if [ -e /etc/init.d/functions.sh ]; then
+ source /etc/init.d/functions.sh &>/dev/null
+elif [ -e /etc/rc.d/config/functions ]; then
+ source /etc/rc.d/config/functions &>/dev/null
+else
+ #Mac OS X
+ source /usr/lib/portage/bin/functions.sh &>/dev/null
+fi
+
+# the sandbox is disabled by default except when overridden in the relevant stages
+export SANDBOX_ON="0"
+
+# sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex, bug #60147)
+addread()
+{
+ export SANDBOX_READ="$SANDBOX_READ:$1"
+}
+
+addwrite()
+{
+ export SANDBOX_WRITE="$SANDBOX_WRITE:$1"
+}
+
+adddeny()
+{
+ export SANDBOX_DENY="$SANDBOX_DENY:$1"
+}
+
+addpredict()
+{
+ export SANDBOX_PREDICT="$SANDBOX_PREDICT:$1"
+}
+
+
+# source the existing profile.bashrc's.
+save_IFS
+IFS=$'\n'
+for dir in ${PROFILE_PATHS}; do
+ # Must unset it so that it doesn't mess up assumptions in the RCs.
+ unset IFS
+ if [ -f "${dir}/profile.bashrc" ]; then
+ source "${dir}/profile.bashrc"
+ fi
+done
+restore_IFS
+
+
+esyslog() {
+ # Custom version of esyslog() to take care of the "Red Star" bug.
+ # MUST follow functions.sh to override the "" parameter problem.
+ return 0
+}
+
+
+use() {
+ if useq ${1}; then
+ return 0
+ fi
+ return 1
+}
+
+usev() {
+ if useq ${1}; then
+ echo "${1}"
+ return 0
+ fi
+ return 1
+}
+
+useq() {
+ local u="${1}"
+ local neg=0
+ if [ "${u:0:1}" == "!" ]; then
+ u="${u:1}"
+ neg=1
+ fi
+ local x
+
+ # Make sure we have this USE flag in IUSE
+ if ! hasq "${u}" ${IUSE} ${E_IUSE} && ! hasq "${u}" ${PORTAGE_ARCHLIST} selinux; then
+ echo "QA Notice: USE Flag '${u}' not in IUSE for ${CATEGORY}/${PF}" >&2
+ fi
+
+ for x in ${USE}; do
+ if [ "${x}" == "${u}" ]; then
+ if [ ${neg} -eq 1 ]; then
+ return 1
+ else
+ return 0
+ fi
+ fi
+ done
+ if [ ${neg} -eq 1 ]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+has() {
+ if hasq "$@"; then
+ return 0
+ fi
+ return 1
+}
+
+hasv() {
+ if hasq "$@"; then
+ echo "${1}"
+ return 0
+ fi
+ return 1
+}
+
+hasq() {
+ local x
+
+ local me=$1
+ shift
+
+ # All the TTY checks really only help out depend. Which is nice.
+ # Logging kills all this anyway. Everything becomes a pipe. --NJ
+ for x in "$@"; do
+ if [ "${x}" == "${me}" ]; then
+ return 0
+ fi
+ done
+ return 1
+}
+
+has_version() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ echo -n "QA Notice: has_version() in global scope: " >&2
+ if [ ${ECLASS_DEPTH} -gt 0 ]; then
+ echo "eclass ${ECLASS}" >&2
+ else
+ echo "${CATEGORY}/${PF}" >&2
+ fi
+ fi
+ # return shell-true/shell-false if exists.
+ # Takes single depend-type atoms.
+ if /usr/lib/portage/bin/portageq 'has_version' "${ROOT}" "$1"; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+portageq() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ echo -n "QA Notice: portageq in global scope: " >&2
+ if [ ${ECLASS_DEPTH} -gt 0 ]; then
+ echo "eclass ${ECLASS}" >&2
+ else
+ echo "${CATEGORY}/${PF}" >&2
+ fi
+ fi
+ /usr/lib/portage/bin/portageq "$@"
+}
+
+
+# ----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
+# ----------------------------------------------------------------------------
+
+
+best_version() {
+ if [ "${EBUILD_PHASE}" == "depend" ]; then
+ echo -n "QA Notice: best_version() in global scope: " >&2
+ if [ ${ECLASS_DEPTH} -gt 0 ]; then
+ echo "eclass ${ECLASS}" >&2
+ else
+ echo "${CATEGORY}/${PF}" >&2
+ fi
+ fi
+ # returns the best/most-current match.
+ # Takes single depend-type atoms.
+ /usr/lib/portage/bin/portageq 'best_version' "${ROOT}" "$1"
+}
+
+use_with() {
+ if [ -z "$1" ]; then
+ echo "!!! use_with() called without a parameter." >&2
+ echo "!!! use_with <USEFLAG> [<flagname> [value]]" >&2
+ return 1
+ fi
+
+ local UW_SUFFIX=""
+ if [ ! -z "${3}" ]; then
+ UW_SUFFIX="=${3}"
+ fi
+
+ local UWORD="$2"
+ if [ -z "${UWORD}" ]; then
+ UWORD="$1"
+ fi
+
+ if useq $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
+
+ local UE_SUFFIX=""
+ if [ ! -z "${3}" ]; then
+ UE_SUFFIX="=${3}"
+ fi
+
+ local UWORD="$2"
+ if [ -z "${UWORD}" ]; then
+ UWORD="$1"
+ fi
+
+ if useq $1; then
+ echo "--enable-${UWORD}${UE_SUFFIX}"
+ else
+ echo "--disable-${UWORD}"
+ fi
+ return 0
+}
+
+diefunc() {
+ local funcname="$1" lineno="$2" exitcode="$3"
+ shift 3
+ echo >&2
+ echo "!!! ERROR: $CATEGORY/$PF failed." >&2
+ echo "!!! Function $funcname, Line $lineno, Exitcode $exitcode" >&2
+ echo "!!! ${*:-(no error message)}" >&2
+ echo "!!! If you need support, post the topmost build error, NOT this status message." >&2
+ echo >&2
+ exit 1
+}
+
+#if no perms are specified, dirs/files will have decent defaults
+#(not secretive, but not stupid)
+umask 022
+export DESTTREE=/usr
+export INSDESTTREE=""
+export EXEDESTTREE=""
+export DOCDESTTREE=""
+export INSOPTIONS="-m0644"
+export EXEOPTIONS="-m0755"
+export LIBOPTIONS="-m0644"
+export DIROPTIONS="-m0755"
+export MOPREFIX=${PN}
+
+check_KV()
+{
+ if [ -z "${KV}" ]; then
+ eerror ""
+ eerror "Could not determine your kernel version."
+ eerror "Make sure that you have /usr/src/linux symlink."
+ eerror "And that said kernel has been configured."
+ eerror "You can also simply run the following command"
+ eerror "in the kernel referenced by /usr/src/linux:"
+ eerror " make include/linux/version.h"
+ eerror ""
+ die
+ fi
+}
+
+# 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\n" | tr "\n" "\0" | $XARGS -0 -n100 touch || die "Failed to recursive create .keep files"
+ else
+ for x in "$@"; do
+ touch "${D}/${x}/.keep" || die "Failed to create .keep in ${D}/${x}"
+ done
+ fi
+}
+
+strip_duplicate_slashes () {
+ if [ -n "${1}" ]; then
+ local removed="${1/\/\///}"
+ [ "${removed}" != "${removed/\/\///}" ] && removed=$(strip_duplicate_slashes "${removed}")
+ echo ${removed}
+ fi
+}
+
+econf() {
+ local LOCAL_EXTRA_ECONF="${EXTRA_ECONF}"
+
+ if [ -z "${ECONF_SOURCE}" ]; then
+ ECONF_SOURCE="."
+ fi
+ if [ -x "${ECONF_SOURCE}/configure" ]; then
+ if [ -e /usr/share/gnuconfig/ ]; then
+ local x
+ for x in $(find "${WORKDIR}" -type f '(' -name config.guess -o -name config.sub ')') ; do
+ echo " * econf: updating ${x/${WORKDIR}\/} with /usr/share/gnuconfig/${x##*/}"
+ cp -f /usr/share/gnuconfig/${x##*/} ${x}
+ done
+ fi
+
+ if [ ! -z "${CBUILD}" ]; then
+ LOCAL_EXTRA_ECONF="--build=${CBUILD} ${LOCAL_EXTRA_ECONF}"
+ fi
+
+ if [ ! -z "${CTARGET}" ]; then
+ LOCAL_EXTRA_ECONF="--target=${CTARGET} ${LOCAL_EXTRA_ECONF}"
+ 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.
+ LIBDIR_VAR="LIBDIR_${ABI}"
+ if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
+ CONF_LIBDIR="${!LIBDIR_VAR}"
+ fi
+ unset LIBDIR_VAR
+ if [ -n "${CONF_LIBDIR}" ] && [ "${*/--libdir}" == "$*" ]; then
+ if [ "${*/--exec-prefix}" != "$*" ]; then
+ local args="$(echo $*)"
+ local -a pref=($(echo ${args/*--exec-prefix[= ]}))
+ CONF_PREFIX=${pref}
+ [ "${CONF_PREFIX:0:1}" != "/" ] && CONF_PREFIX="/${CONF_PREFIX}"
+ elif [ "${*/--prefix}" != "$*" ]; then
+ local args="$(echo $*)"
+ local -a pref=($(echo ${args/*--prefix[= ]}))
+ CONF_PREFIX=${pref}
+ [ "${CONF_PREFIX:0:1}" != "/" ] && CONF_PREFIX="/${CONF_PREFIX}"
+ else
+ CONF_PREFIX="/usr"
+ fi
+ export CONF_PREFIX
+ [ "${CONF_LIBDIR:0:1}" != "/" ] && CONF_LIBDIR="/${CONF_LIBDIR}"
+
+ CONF_LIBDIR_RESULT="${CONF_PREFIX}${CONF_LIBDIR}"
+ for X in 1 2 3; do
+ # The escaping is weird. It will break if you escape the last one.
+ CONF_LIBDIR_RESULT="${CONF_LIBDIR_RESULT//\/\///}"
+ done
+
+ LOCAL_EXTRA_ECONF="--libdir=${CONF_LIBDIR_RESULT} ${LOCAL_EXTRA_ECONF}"
+ fi
+
+ echo "${ECONF_SOURCE}/configure" \
+ --prefix=/usr \
+ --host=${CHOST} \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --datadir=/usr/share \
+ --sysconfdir=/etc \
+ --localstatedir=/var/lib \
+ "$@" \
+ ${LOCAL_EXTRA_ECONF}
+
+ if ! "${ECONF_SOURCE}/configure" \
+ --prefix=/usr \
+ --host=${CHOST} \
+ --mandir=/usr/share/man \
+ --infodir=/usr/share/info \
+ --datadir=/usr/share \
+ --sysconfdir=/etc \
+ --localstatedir=/var/lib \
+ "$@" \
+ ${LOCAL_EXTRA_ECONF}; then
+
+ if [ -s config.log ]; then
+ echo
+ echo "!!! Please attach the config.log to your bug report:"
+ echo "!!! ${PWD}/config.log"
+ fi
+ die "econf failed"
+ fi
+ else
+ die "no configure script found"
+ fi
+}
+
+einstall() {
+ # CONF_PREFIX is only set if they didn't pass in libdir above.
+ 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:-unset}" != "unset" ]; then
+ EI_DESTLIBDIR="${D}/${CONF_PREFIX}/${CONF_LIBDIR}"
+ EI_DESTLIBDIR="$(strip_duplicate_slashes ${EI_DESTLIBDIR})"
+ EXTRA_EINSTALL="libdir=${EI_DESTLIBDIR} ${EXTRA_EINSTALL}"
+ unset EI_DESTLIBDIR
+ fi
+
+ if [ -f ./[mM]akefile -o -f ./GNUmakefile ] ; then
+ if [ ! -z "${PORTAGE_DEBUG}" ]; then
+ 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 \
+ ${EXTRA_EINSTALL} \
+ "$@" install
+ fi
+ 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 \
+ ${EXTRA_EINSTALL} \
+ "$@" install || die "einstall failed"
+ else
+ die "no Makefile found"
+ fi
+}
+
+pkg_setup()
+{
+ return
+}
+
+pkg_nofetch()
+{
+ [ -z "${SRC_URI}" ] && return
+
+ echo "!!! The following are listed in SRC_URI for ${PN}:"
+ for MYFILE in `echo ${SRC_URI}`; do
+ echo "!!! $MYFILE"
+ done
+}
+
+src_unpack() {
+ if [ "${A}" != "" ]; then
+ unpack ${A}
+ fi
+}
+
+src_compile() {
+ if [ -x ./configure ]; then
+ econf
+ fi
+ if [ -f Makefile ] || [ -f GNUmakefile ] || [ -f makefile ]; then
+ emake || die "emake failed"
+ fi
+}
+
+src_test()
+{
+ addpredict /
+ if make check -n &> /dev/null; then
+ echo ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ if ! make check; then
+ hasq test $FEATURES && die "Make check failed. See above for details."
+ hasq test $FEATURES || eerror "Make check failed. See above for details."
+ fi
+ elif make test -n &> /dev/null; then
+ echo ">>> Test phase [test]: ${CATEGORY}/${PF}"
+ if ! make test; then
+ hasq test $FEATURES && die "Make test failed. See above for details."
+ hasq test $FEATURES || eerror "Make test failed. See above for details."
+ fi
+ else
+ echo ">>> Test phase [none]: ${CATEGORY}/${PF}"
+ fi
+ SANDBOX_PREDICT="${SANDBOX_PREDICT%:/}"
+}
+
+src_install()
+{
+ return
+}
+
+pkg_preinst()
+{
+ return
+}
+
+pkg_postinst()
+{
+ return
+}
+
+pkg_prerm()
+{
+ return
+}
+
+pkg_postrm()
+{
+ return
+}
+
+pkg_config()
+{
+ eerror "This ebuild does not have a config function."
+}
+
+# Used to generate the /lib/cpp and /usr/bin/cc wrappers
+gen_wrapper() {
+ cat > $1 << END
+#!/bin/sh
+
+$2 "\$@"
+END
+
+ chmod 0755 $1
+}
+
+dyn_setup()
+{
+ pkg_setup
+}
+
+dyn_unpack() {
+ trap "abort_unpack" SIGINT SIGQUIT
+ local newstuff="no"
+ if [ -e "${WORKDIR}" ]; then
+ local x
+ local checkme
+ for x in ${AA}; do
+ echo ">>> Checking ${x}'s mtime..."
+ if [ "${DISTDIR}/${x}" -nt "${WORKDIR}" ]; then
+ echo ">>> ${x} has been updated; recreating WORKDIR..."
+ newstuff="yes"
+ rm -rf "${WORKDIR}"
+ break
+ fi
+ done
+ if [ "${EBUILD}" -nt "${WORKDIR}" ]; then
+ echo ">>> ${EBUILD} has been updated; recreating WORKDIR..."
+ newstuff="yes"
+ rm -rf "${WORKDIR}"
+ elif [ ! -f "${BUILDDIR}/.unpacked" ]; then
+ echo ">>> Not marked as unpacked; recreating WORKDIR..."
+ newstuff="yes"
+ rm -rf "${WORKDIR}"
+ fi
+ fi
+ if [ -e "${WORKDIR}" ]; then
+ if [ "$newstuff" == "no" ]; then
+ echo ">>> WORKDIR is up-to-date, keeping..."
+ return 0
+ fi
+ fi
+
+ install -m0700 -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'"
+ [ -d "$WORKDIR" ] && cd "${WORKDIR}"
+ echo ">>> Unpacking source..."
+ src_unpack
+ touch "${BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in BUILDIR"
+ echo ">>> Source unpacked."
+ cd "$BUILDDIR"
+ trap SIGINT SIGQUIT
+}
+
+dyn_clean() {
+ if [ "$USERLAND" == "BSD" ] && type -p chflags &>/dev/null; then
+ chflags -R noschg,nouchg,nosappnd,nouappnd,nosunlnk,nouunlnk \
+ "${BUILDDIR}"
+ fi
+
+ if [ "$USERLAND" == "Darwin" ] && type -p chflags &>/dev/null; then
+ chflags -R noschg,nouchg,nosappnd,nouappnd "${BUILDDIR}"
+ fi
+
+ rm -rf "${BUILDDIR}/image"
+
+ if ! hasq keeptemp $FEATURES; then
+ rm -rf "${T}"
+ else
+ mv "${T}/environment" "${T}/environment.keeptemp"
+ fi
+
+ if ! hasq keepwork $FEATURES; then
+ rm -rf "${BUILDDIR}/.unpacked"
+ rm -rf "${BUILDDIR}/.compiled"
+ rm -rf "${BUILDDIR}/.tested"
+ rm -rf "${BUILDDIR}/.installed"
+ rm -rf "${BUILDDIR}/.packaged"
+ rm -rf "${BUILDDIR}/build-info"
+ rm -rf "${WORKDIR}"
+ fi
+
+ if [ -f "${BUILDDIR}/.unpacked" ]; then
+ find "${BUILDDIR}" -type d ! -regex "^${WORKDIR}" | sort -r | tr "\n" "\0" | $XARGS -0 rmdir &>/dev/null
+ fi
+
+ if [ -z "$(find "${BUILDDIR}" -mindepth 1 -maxdepth 1)" ]; then
+ rmdir "${BUILDDIR}"
+ fi
+ true
+}
+
+into() {
+ if [ $1 == "/" ]; then
+ export DESTTREE=""
+ else
+ export DESTTREE=$1
+ if [ ! -d "${D}${DESTTREE}" ]; then
+ install -d "${D}${DESTTREE}"
+ fi
+ fi
+}
+
+insinto() {
+ if [ "$1" == "/" ]; then
+ export INSDESTTREE=""
+ else
+ export INSDESTTREE=$1
+ if [ ! -d "${D}${INSDESTTREE}" ]; then
+ install -d "${D}${INSDESTTREE}"
+ fi
+ fi
+}
+
+exeinto() {
+ if [ "$1" == "/" ]; then
+ export EXEDESTTREE=""
+ else
+ export EXEDESTTREE="$1"
+ if [ ! -d "${D}${EXEDESTTREE}" ]; then
+ install -d "${D}${EXEDESTTREE}"
+ fi
+ fi
+}
+
+docinto() {
+ if [ "$1" == "/" ]; then
+ export DOCDESTTREE=""
+ else
+ export DOCDESTTREE="$1"
+ if [ ! -d "${D}usr/share/doc/${PF}/${DOCDESTTREE}" ]; then
+ install -d "${D}usr/share/doc/${PF}/${DOCDESTTREE}"
+ fi
+ fi
+}
+
+insopts() {
+ INSOPTIONS=""
+ for x in $*; do
+ #if we have a debug build, let's not strip anything
+ if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
+ continue
+ else
+ INSOPTIONS="$INSOPTIONS $x"
+ fi
+ done
+ export INSOPTIONS
+}
+
+diropts() {
+ DIROPTIONS=""
+ for x in $*; do
+ DIROPTIONS="${DIROPTIONS} $x"
+ done
+ export DIROPTIONS
+}
+
+exeopts() {
+ EXEOPTIONS=""
+ for x in $*; do
+ #if we have a debug build, let's not strip anything
+ if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
+ continue
+ else
+ EXEOPTIONS="$EXEOPTIONS $x"
+ fi
+ done
+ export EXEOPTIONS
+}
+
+libopts() {
+ LIBOPTIONS=""
+ for x in $*; do
+ #if we have a debug build, let's not strip anything
+ if hasq nostrip $FEATURES $RESTRICT && [ "$x" == "-s" ]; then
+ continue
+ else
+ LIBOPTIONS="$LIBOPTIONS $x"
+ fi
+ done
+ export LIBOPTIONS
+}
+
+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_compile() {
+ abort_handler "src_compile" $1
+ rm -f "${BUILDDIR}/.compiled"
+ exit 1
+}
+
+abort_unpack() {
+ abort_handler "src_unpack" $1
+ rm -f "${BUILDDIR}/.unpacked"
+ rm -rf "${BUILDDIR}/work"
+ exit 1
+}
+
+abort_package() {
+ abort_handler "dyn_package" $1
+ rm -f "${BUILDDIR}/.packaged"
+ rm -f "${PKGDIR}"/All/${PF}.t*
+ exit 1
+}
+
+abort_test() {
+ abort_handler "dyn_test" $1
+ rm -f "${BUILDDIR}/.tested"
+ exit 1
+}
+
+abort_install() {
+ abort_handler "src_install" $1
+ rm -rf "${BUILDDIR}/image"
+ exit 1
+}
+
+dyn_compile() {
+ trap "abort_compile" SIGINT SIGQUIT
+ [ "${CFLAGS-unset}" != "unset" ] && export CFLAGS
+ [ "${CXXFLAGS-unset}" != "unset" ] && export CXXFLAGS
+ [ "${LIBCFLAGS-unset}" != "unset" ] && export LIBCFLAGS
+ [ "${LIBCXXFLAGS-unset}" != "unset" ] && export LIBCXXFLAGS
+ [ "${LDFLAGS-unset}" != "unset" ] && export LDFLAGS
+ [ "${ASFLAGS-unset}" != "unset" ] && export ASFLAGS
+
+ [ "${CCACHE_DIR-unset}" != "unset" ] && export CCACHE_DIR
+ [ "${CCACHE_SIZE-unset}" != "unset" ] && export CCACHE_SIZE
+
+ [ "${DISTCC_DIR-unset}" == "unset" ] && export DISTCC_DIR="${PORTAGE_TMPDIR}/.distcc"
+ [ ! -z "${DISTCC_DIR}" ] && addwrite "${DISTCC_DIR}"
+
+ if hasq noauto $FEATURES &>/dev/null && [ ! -f ${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
+
+ echo -ne "\a"; sleep 0.25 &>/dev/null; echo -ne "\a"; sleep 0.25 &>/dev/null
+ echo -ne "\a"; sleep 0.25 &>/dev/null; echo -ne "\a"; sleep 0.25 &>/dev/null
+ echo -ne "\a"; sleep 0.25 &>/dev/null; echo -ne "\a"; sleep 0.25 &>/dev/null
+ echo -ne "\a"; sleep 0.25 &>/dev/null; echo -ne "\a"; sleep 0.25 &>/dev/null
+
+ echo -ne "\a"; sleep 0,25 &>/dev/null; echo -ne "\a"; sleep 0,25 &>/dev/null
+ echo -ne "\a"; sleep 0,25 &>/dev/null; echo -ne "\a"; sleep 0,25 &>/dev/null
+ echo -ne "\a"; sleep 0,25 &>/dev/null; echo -ne "\a"; sleep 0,25 &>/dev/null
+ echo -ne "\a"; sleep 0,25 &>/dev/null; echo -ne "\a"; sleep 0,25 &>/dev/null
+ sleep 3
+ fi
+
+ cd "${BUILDDIR}"
+ if [ ! -e "build-info" ]; then
+ mkdir build-info
+ fi
+ cp "${EBUILD}" "build-info/${PF}.ebuild"
+
+ if [ ${BUILDDIR}/.compiled -nt "${WORKDIR}" ]; then
+ echo ">>> It appears that ${PN} is already compiled; skipping."
+ echo ">>> (clean to force compilation)"
+ trap SIGINT SIGQUIT
+ return
+ fi
+ if [ -d "${S}" ]; then
+ cd "${S}"
+ fi
+ #our custom version of libtool uses $S and $D to fix
+ #invalid paths in .la files
+ export S D
+ #some packages use an alternative to $S to build in, cause
+ #our libtool to create problematic .la files
+ export PWORKDIR="$WORKDIR"
+ src_compile
+ #|| abort_compile "fail"
+ cd "${BUILDDIR}"
+ touch .compiled
+ cd build-info
+
+ echo "$ASFLAGS" > ASFLAGS
+ echo "$CATEGORY" > CATEGORY
+ echo "$CBUILD" > CBUILD
+ echo "$CC" > CC
+ echo "$CDEPEND" > CDEPEND
+ echo "$CFLAGS" > CFLAGS
+ echo "$CHOST" > CHOST
+ echo "$CTARGET" > CTARGET
+ echo "$CXX" > CXX
+ echo "$CXXFLAGS" > CXXFLAGS
+ echo "$DEPEND" > DEPEND
+ echo "$EXTRA_ECONF" > EXTRA_ECONF
+ echo "$EXTRA_EINSTALL" > EXTRA_EINSTALL
+ echo "$EXTRA_EMAKE" > EXTRA_MAKE
+ echo "$FEATURES" > FEATURES
+ echo "$INHERITED" > INHERITED
+ echo "$IUSE" > IUSE
+ echo "$PKGUSE" > PKGUSE
+ echo "$LDFLAGS" > LDFLAGS
+ echo "$LIBCFLAGS" > LIBCFLAGS
+ echo "$LIBCXXFLAGS" > LIBCXXFLAGS
+ echo "$LICENSE" > LICENSE
+ echo "$PDEPEND" > PDEPEND
+ echo "$PF" > PF
+ echo "$PROVIDE" > PROVIDE
+ echo "$RDEPEND" > RDEPEND
+ echo "$RESTRICT" > RESTRICT
+ echo "$SLOT" > SLOT
+ echo "$USE" > USE
+
+ set > environment
+ export -p | sed 's:declare -rx:declare -x:' >> environment
+ bzip2 -9 environment
+
+ cp "${EBUILD}" "${PF}.ebuild"
+ if hasq nostrip $FEATURES $RESTRICT; then
+ touch DEBUGBUILD
+ fi
+ trap SIGINT SIGQUIT
+}
+
+dyn_package() {
+ trap "abort_package" SIGINT SIGQUIT
+ cd "${BUILDDIR}/image"
+ tar cpvf - ./ | bzip2 -f > ../bin.tar.bz2 || die "Failed to create tarball"
+ cd ..
+ xpak build-info inf.xpak
+ tbz2tool join bin.tar.bz2 inf.xpak "${PF}.tbz2"
+ mv "${PF}.tbz2" "${PKGDIR}/All" || die "Failed to move tbz2 to ${PKGDIR}/All"
+ rm -f inf.xpak bin.tar.bz2
+ if [ ! -d "${PKGDIR}/${CATEGORY}" ]; then
+ install -d "${PKGDIR}/${CATEGORY}"
+ fi
+ ln -sf "../All/${PF}.tbz2" "${PKGDIR}/${CATEGORY}/${PF}.tbz2" || die "Failed to create symlink in ${PKGDIR}/${CATEGORY}"
+ echo ">>> Done."
+ cd "${BUILDDIR}"
+ touch .packaged || die "Failed to 'touch .packaged' in ${BUILDDIR}"
+ trap SIGINT SIGQUIT
+}
+
+
+dyn_test() {
+ if [ ${BUILDDIR}/.tested -nt "${WORKDIR}" ]; then
+ echo ">>> It appears that ${PN} has already been tested; skipping."
+ return
+ fi
+ trap "abort_test" SIGINT SIGQUIT
+ if [ -d "${S}" ]; then
+ cd "${S}"
+ fi
+ if hasq maketest $RESTRICT || hasq test $RESTRICT; then
+ ewarn "Skipping make test/check due to ebuild restriction."
+ echo ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}"
+ elif ! hasq test $FEATURES; then
+ echo ">>> Test phase [not enabled]: ${CATEGORY}/${PF}"
+ else
+ echo ">>> Test phase [enabled]: ${CATEGORY}/${PF}"
+ src_test
+ fi
+
+ cd "${BUILDDIR}"
+ touch .tested || die "Failed to 'touch .tested' in ${BUILDDIR}"
+ trap SIGINT SIGQUIT
+}
+
+
+
+dyn_install() {
+ trap "abort_install" SIGINT SIGQUIT
+ rm -rf "${BUILDDIR}/image"
+ mkdir "${BUILDDIR}/image"
+ if [ -d "${S}" ]; then
+ cd "${S}"
+ fi
+ echo
+ echo ">>> 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
+ #some packages uses an alternative to $S to build in, cause
+ #our libtool to create problematic .la files
+ export PWORKDIR="$WORKDIR"
+ src_install
+ #|| abort_install "fail"
+ prepall
+ cd "${D}"
+
+ declare -i UNSAFE=0
+ for i in $(find "${D}/" -type f -perm -2002); do
+ ((UNSAFE++))
+ echo "UNSAFE SetGID: $i"
+ done
+ for i in $(find "${D}/" -type f -perm -4002); do
+ ((UNSAFE++))
+ echo "UNSAFE SetUID: $i"
+ done
+
+ if type -p scanelf > /dev/null ; then
+ # Make sure we disallow insecure RUNPATH/RPATH's
+ # Don't want paths that point to the tree where the package was built
+ # (older, broken libtools would do this). Also check for null paths
+ # because the loader will search $PWD when it finds null paths.
+ f=$(scanelf -qyRF '%r %p' "${D}" | grep -E "(${BUILDDIR}|: |::|^ )")
+ if [[ -n ${f} ]] ; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain insecure RUNPATH's"
+ echo " Please file a bug about this at http://bugs.gentoo.org/"
+ echo " For more information on this issue, kindly review:"
+ echo " http://bugs.gentoo.org/81745"
+ echo "${f}"
+ echo -ne '\a\n'
+ die "Insecure binaries detected"
+ fi
+
+ # Check for setid binaries but are not built with BIND_NOW
+ f=$(scanelf -qyRF '%b %p' "${D}")
+ if [[ -n ${f} ]] ; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files are setXid, dyn linked, and using lazy bindings"
+ echo " This combination is generally discouraged. Try re-emerging the package:"
+ echo " LDFLAGS='-Wl,-z,now' emerge ${PN}"
+ echo "${f}"
+ echo -ne '\a\n'
+ [[ ${FEATURES/stricter} != "${FEATURES}" ]] \
+ && die "Aborting due to lazy bindings"
+ sleep 1
+ fi
+
+ # TEXTREL's are baaaaaaaad
+ f=$(scanelf -qyRF '%t %p' "${D}")
+ if [[ -n ${f} ]] ; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain runtime text relocations"
+ echo " Text relocations require a lot of extra work to be preformed by the"
+ echo " dynamic linker which will cause serious performance impact on IA-32"
+ echo " and might not function properly on other architectures hppa for example."
+ echo " If you are a programmer please take a closer look at this package and"
+ echo " consider writing a patch which addresses this problem."
+ echo "${f}"
+ echo -ne '\a\n'
+ [[ ${FEATURES/stricter} != "${FEATURES}" ]] \
+ && die "Aborting due to textrels"
+ sleep 1
+ fi
+
+ # Check for files with executable stacks
+ f=$(scanelf -qyRF '%e %p' "${D}")
+ if [[ -n ${f} ]] ; then
+ echo -ne '\a\n'
+ echo "QA Notice: the following files contain executable stacks"
+ echo " Files with executable stacks will not work properly (or at all!)"
+ echo " on some architectures/operating systems. A bug should be filed"
+ echo " at http://bugs.gentoo.org/ to make sure the file is fixed."
+ echo "${f}"
+ echo -ne '\a\n'
+ [[ ${FEATURES/stricter} != "${FEATURES}" ]] \
+ && die "Aborting due to +x stack"
+ sleep 1
+ fi
+
+ # Save NEEDED information
+ scanelf -qyRF '%p %n' "${D}" | sed -e 's:^:/:' > "${BUILDDIR}"/build-info/NEEDED
+ fi
+
+ if [[ ${UNSAFE} > 0 ]] ; then
+ die "There are ${UNSAFE} unsafe files. Portage will not install them."
+ fi
+
+ # dumps perms to stdout. if error, no perms dumped.
+ function stat_perms() {
+ local f
+ # only define do_stat if it hasn't been already
+ if ! type -p do_stat &> /dev/null; then
+ if ! type -p stat &>/dev/null; then
+ do_stat() {
+ # Generic version -- Octal result
+ python -c "import os,stat; print '%o' % os.stat('$1')[stat.ST_MODE]"
+ }
+ else
+ if [ "${USERLAND}" == "BSD" ] || [ "${USERLAND}" == "Darwin" ]; then
+ do_stat() {
+ # BSD version -- Octal result
+ $(type -p stat) -f '%p' "$1"
+ }
+ else
+ do_stat() {
+ # Linux version -- Hex result converted to Octal
+ f=$($(type -p stat) -c '%f' "$1") || return $?
+ printf '%o' "0x$f"
+ }
+ fi
+ fi
+ fi
+
+ f=$(do_stat "$@") || return
+ f="${f:2:4}"
+ echo $f
+ }
+
+ local file s
+ local count=0
+ find "${D}/" -user portage | while read file; do
+ count=$(( $count + 1 ))
+ [[ ! -L "${file}" ]] && s=$(stat_perms "$file")
+ if [ -z "${s}" ]; then
+ ewarn "failed stat_perm'ing $file. User intervention during install isn't wise..."
+ continue
+ fi
+ chown root "$file"
+ [[ ! -L "${file}" ]] && chmod "$s" "$file"
+ done
+ if (( $count > 0 )); then
+ ewarn "$count files were installed with user portage!"
+ fi
+
+ count=0
+ find "${D}/" -group portage | while read file; do
+ count=$(( $count + 1 ))
+ [[ ! -L "${file}" ]] && s=$(stat_perms "$file")
+ if [ -z "${s}" ]; then
+ echo "failed stat_perm'ing '$file' . User intervention during install isn't wise..."
+ continue
+ fi
+ chgrp 0 "${file}"
+ [[ ! -L "${file}" ]] && chmod "$s" "$file"
+ done
+ if (( $count > 0 )); then
+ ewarn "$count files were installed with group portage!"
+ fi
+
+ unset -f stat_perms
+
+ # Portage regenerates this on the installed system.
+ if [ -f "${D}/usr/share/info/dir.gz" ]; then
+ rm -f "${D}/usr/share/info/dir.gz"
+ fi
+
+ if hasq multilib-strict ${FEATURES} && [ -x /usr/bin/file -a -x /usr/bin/find -a \
+ -n "${MULTILIB_STRICT_DIRS}" -a -n "${MULTILIB_STRICT_DENY}" ]; then
+ MULTILIB_STRICT_EXEMPT=${MULTILIB_STRICT_EXEMPT:-"(perl5|gcc|gcc-lib)"}
+ for dir in ${MULTILIB_STRICT_DIRS}; do
+ [ -d "${D}/${dir}" ] || continue
+ for file in $(find ${D}/${dir} -type f | egrep -v "^${D}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
+ file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" && die "File ${file} matches a file type that is not allowed in ${dir}"
+ done
+ done
+ fi
+
+ touch "${BUILDDIR}/.installed"
+ echo ">>> Completed installing ${PF} into ${D}"
+ echo
+ cd ${BUILDDIR}
+ trap SIGINT SIGQUIT
+}
+
+dyn_preinst() {
+ # set IMAGE depending if this is a binary or compile merge
+ [ "${EMERGE_FROM}" == "binary" ] && IMAGE=${PKG_TMPDIR}/${PF}/bin \
+ || IMAGE=${D}
+
+ pkg_preinst
+
+ # hopefully this will someday allow us to get rid of the no* feature flags
+ # we don't want globbing for initial expansion, but afterwards, we do
+ local shopts=$-
+ set -o noglob
+ for no_inst in ${INSTALL_MASK}; do
+ set +o noglob
+ einfo "Removing ${no_inst}"
+ # normal stuff
+ rm -Rf ${IMAGE}/${no_inst} >&/dev/null
+
+ # we also need to handle globs (*.a, *.h, etc)
+ find "${IMAGE}" -name ${no_inst} -exec rm -fR {} \; >&/dev/null
+ done
+ # set everything back the way we found it
+ set +o noglob
+ set -${shopts}
+
+ # remove man pages
+ if hasq noman $FEATURES; then
+ rm -fR "${IMAGE}/usr/share/man"
+ fi
+
+ # remove info pages
+ if hasq noinfo $FEATURES; then
+ rm -fR "${IMAGE}/usr/share/info"
+ fi
+
+ # remove docs
+ if hasq nodoc $FEATURES; then
+ rm -fR "${IMAGE}/usr/share/doc"
+ fi
+
+ # remove share dir if unnessesary
+ if hasq nodoc $FEATURES -o hasq noman $FEATURES -o hasq noinfo $FEATURES; then
+ rmdir "${IMAGE}/usr/share" &> /dev/null
+ fi
+
+ # Smart FileSystem Permissions
+ if hasq sfperms $FEATURES; then
+ for i in $(find ${IMAGE}/ -type f -perm -4000); do
+ ebegin ">>> SetUID: [chmod go-r] $i "
+ chmod go-r "$i"
+ eend $?
+ done
+ for i in $(find ${IMAGE}/ -type f -perm -2000); do
+ ebegin ">>> SetGID: [chmod o-r] $i "
+ chmod o-r "$i"
+ eend $?
+ done
+ fi
+
+ # total suid control.
+ if hasq suidctl $FEATURES > /dev/null ; then
+ sfconf=/etc/portage/suidctl.conf
+ echo ">>> Preforming suid scan in ${IMAGE}"
+ for i in $(find ${IMAGE}/ -type f \( -perm -4000 -o -perm -2000 \) ); do
+ if [ -s "${sfconf}" ]; then
+ suid="`grep ^${i/${IMAGE}/}$ ${sfconf}`"
+ if [ "${suid}" = "${i/${IMAGE}/}" ]; then
+ echo "- ${i/${IMAGE}/} is an approved suid file"
+ else
+ echo ">>> Removing sbit on non registered ${i/${IMAGE}/}"
+ for x in 5 4 3 2 1 0; do echo -ne "\a"; sleep 0.25 ; done
+ echo -ne "\a"
+ chmod ugo-s "${i}"
+ grep ^#${i/${IMAGE}/}$ ${sfconf} > /dev/null || {
+ # sandbox prevents us from writing directly
+ # to files outside of the sandbox, but this
+ # can easly be bypassed using the addwrite() function
+ addwrite "${sfconf}"
+ echo ">>> Appending commented out entry to ${sfconf} for ${PF}"
+ ls_ret=`ls -ldh "${i}"`
+ echo "## ${ls_ret%${IMAGE}*}${ls_ret#*${IMAGE}}" >> ${sfconf}
+ echo "#${i/${IMAGE}/}" >> ${sfconf}
+ # no delwrite() eh?
+ # delwrite ${sconf}
+ }
+ fi
+ else
+ echo "suidctl feature set but you are lacking a ${sfconf}"
+ fi
+ done
+ fi
+
+ # SELinux file labeling (needs to always be last in dyn_preinst)
+ if useq selinux; then
+ # only attempt to label if setfiles is executable
+ # and 'context' is available on selinuxfs.
+ if [ -f /selinux/context -a -x /usr/sbin/setfiles ]; then
+ echo ">>> Setting SELinux security labels"
+ if [ -f ${POLICYDIR}/file_contexts/file_contexts ]; then
+ cp -f "${POLICYDIR}/file_contexts/file_contexts" "${T}"
+ else
+ make -C "${POLICYDIR}" FC=${T}/file_contexts "${T}/file_contexts"
+ fi
+
+ addwrite /selinux/context
+ /usr/sbin/setfiles -r "${IMAGE}" "${T}/file_contexts" "${IMAGE}" \
+ || die "Failed to set SELinux security labels."
+ else
+ # nonfatal, since merging can happen outside a SE kernel
+ # like during a recovery situation
+ echo "!!! Unable to set SELinux security labels"
+ fi
+ fi
+ trap SIGINT SIGQUIT
+}
+
+dyn_spec() {
+ tar czf "/usr/src/redhat/SOURCES/${PF}.tar.gz" "${O}/${PF}.ebuild" "${O}/files" || 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() {
+ dyn_spec
+ rpmbuild -bb "${PF}.spec" || die "Failed to integrate rpm spec file"
+ install -D "/usr/src/redhat/RPMS/i386/${PN}-${PV}-${PR}.i386.rpm" "${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || die "Failed to move rpm"
+}
+
+dyn_help() {
+ echo
+ echo "Portage"
+ echo "Copyright 1999-2004 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 " setup : execute package specific setup actions"
+ echo " fetch : download source archive(s) and patches"
+ echo " digest : creates a digest and a manifest file for the package"
+ echo " manifest : creates a manifest file for the package"
+ echo " unpack : unpack/patch sources (auto-fetch if needed)"
+ echo " compile : compile sources (auto-fetch/unpack if needed)"
+ echo " test : test package (auto-fetch/unpack/compile if needed)"
+ echo " preinst : execute pre-install instructions"
+ echo " postinst : execute post-install instructions"
+ echo " install : installs the package to the temporary install directory"
+ echo " qmerge : merge image into live filesystem, recording files in db"
+ echo " merge : does 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 tarball package in ${PKGDIR}/All"
+ echo " rpm : builds 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 hasq nostrip $FEATURES $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
+ [ -z "$T" ] && return 0
+
+ while [ "$1" ]; do
+
+ # extra user-configurable targets
+ if [ "$ECLASS_DEBUG_OUTPUT" == "on" ]; then
+ echo "debug: $1"
+ elif [ -n "$ECLASS_DEBUG_OUTPUT" ]; then
+ echo "debug: $1" >> $ECLASS_DEBUG_OUTPUT
+ fi
+
+ # default target
+ echo "$1" >> "${T}/eclass-debug.log"
+ # let the portage user own/write to this file
+ chmod g+w "${T}/eclass-debug.log" &>/dev/null
+
+ shift
+ done
+}
+
+# The following 2 functions are debug-print() wrappers
+
+debug-print-function() {
+ str="$1: entering function"
+ shift
+ debug-print "$str, parameters: $*"
+}
+
+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
+
+ local location
+ local PECLASS
+
+ local B_IUSE
+ local B_DEPEND
+ local B_RDEPEND
+ local B_CDEPEND
+ local B_PDEPEND
+ while [ "$1" ]; do
+ location="${ECLASSDIR}/${1}.eclass"
+
+ # PECLASS is used to restore the ECLASS var after recursion.
+ PECLASS="$ECLASS"
+ export ECLASS="$1"
+
+ if [ "$EBUILD_PHASE" != "depend" ]; then
+ if ! hasq $ECLASS $INHERITED; then
+ echo
+ echo "QA Notice: ECLASS '$ECLASS' inherited illegally in $CATEGORY/$PF" >&2
+ echo
+ 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"
+
+ #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_DEPEND B_RDEPEND B_CDEPEND B_PDEPEND
+ [ "${IUSE-unset}" != "unset" ] && B_IUSE="${IUSE}"
+ [ "${DEPEND-unset}" != "unset" ] && B_DEPEND="${DEPEND}"
+ [ "${RDEPEND-unset}" != "unset" ] && B_RDEPEND="${RDEPEND}"
+ [ "${CDEPEND-unset}" != "unset" ] && B_CDEPEND="${CDEPEND}"
+ [ "${PDEPEND-unset}" != "unset" ] && B_PDEPEND="${PDEPEND}"
+ unset IUSE DEPEND RDEPEND CDEPEND PDEPEND
+ #turn on glob expansion
+ set +f
+
+ source "$location" || export ERRORMSG="died sourcing $location in inherit()"
+ [ -z "${ERRORMSG}" ] || die "${ERRORMSG}"
+
+ #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-unset}" != "unset" ] && export E_IUSE="${E_IUSE} ${IUSE}"
+ [ "${DEPEND-unset}" != "unset" ] && export E_DEPEND="${E_DEPEND} ${DEPEND}"
+ [ "${RDEPEND-unset}" != "unset" ] && export E_RDEPEND="${E_RDEPEND} ${RDEPEND}"
+ [ "${CDEPEND-unset}" != "unset" ] && export E_CDEPEND="${E_CDEPEND} ${CDEPEND}"
+ [ "${PDEPEND-unset}" != "unset" ] && export E_PDEPEND="${E_PDEPEND} ${PDEPEND}"
+
+ [ "${B_IUSE-unset}" != "unset" ] && IUSE="${B_IUSE}"
+ [ "${B_IUSE-unset}" != "unset" ] || unset IUSE
+
+ [ "${B_DEPEND-unset}" != "unset" ] && DEPEND="${B_DEPEND}"
+ [ "${B_DEPEND-unset}" != "unset" ] || unset DEPEND
+
+ [ "${B_RDEPEND-unset}" != "unset" ] && RDEPEND="${B_RDEPEND}"
+ [ "${B_RDEPEND-unset}" != "unset" ] || unset RDEPEND
+
+ [ "${B_CDEPEND-unset}" != "unset" ] && CDEPEND="${B_CDEPEND}"
+ [ "${B_CDEPEND-unset}" != "unset" ] || unset CDEPEND
+
+ [ "${B_PDEPEND-unset}" != "unset" ] && PDEPEND="${B_PDEPEND}"
+ [ "${B_PDEPEND-unset}" != "unset" ] || unset PDEPEND
+
+ #turn on glob expansion
+ set +f
+
+ hasq $1 $INHERITED || export INHERITED="$INHERITED $1"
+
+ export ECLASS="$PECLASS"
+
+ shift
+ done
+ ECLASS_DEPTH=$(($ECLASS_DEPTH - 1))
+}
+
+# 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
+ echo "EXPORT_FUNCTIONS without a defined ECLASS" >&2
+ exit 1
+ fi
+ while [ "$1" ]; do
+ debug-print "EXPORT_FUNCTIONS: ${1} -> ${ECLASS}_${1}"
+ eval "$1() { ${ECLASS}_$1 "\$@" ; }" > /dev/null
+ shift
+ done
+}
+
+# adds all parameters to E_DEPEND and E_RDEPEND, which get added to DEPEND
+# and RDEPEND after the ebuild has been processed. This is important to
+# allow users to use DEPEND="foo" without frying dependencies added by an
+# earlier inherit. It also allows RDEPEND to work properly, since a lot
+# of ebuilds assume that an unset RDEPEND gets its value from DEPEND.
+# Without eclasses, this is true. But with them, the eclass may set
+# RDEPEND itself (or at least used to) which would prevent RDEPEND from
+# getting its value from DEPEND. This is a side-effect that made eclasses
+# have unreliable dependencies.
+
+newdepend() {
+ debug-print-function newdepend $*
+ debug-print "newdepend: E_DEPEND=$E_DEPEND E_RDEPEND=$E_RDEPEND"
+
+ while [ -n "$1" ]; do
+ case $1 in
+ "/autotools")
+ do_newdepend DEPEND sys-devel/autoconf sys-devel/automake sys-devel/make
+ ;;
+ "/c")
+ do_newdepend DEPEND sys-devel/gcc virtual/libc
+ do_newdepend RDEPEND virtual/libc
+ ;;
+ *)
+ do_newdepend DEPEND $1
+ ;;
+ esac
+ shift
+ done
+}
+
+newrdepend() {
+ debug-print-function newrdepend $*
+ do_newdepend RDEPEND $1
+}
+
+newcdepend() {
+ debug-print-function newcdepend $*
+ do_newdepend CDEPEND $1
+}
+
+newpdepend() {
+ debug-print-function newpdepend $*
+ do_newdepend PDEPEND $1
+}
+
+do_newdepend() {
+ # This function does a generic change determining whether we're in an
+ # eclass or not. If we are, we change the E_* variables for deps.
+ debug-print-function do_newdepend $*
+ [ -z "$1" ] && die "do_newdepend without arguments"
+
+ # Grab what we're affecting... Figure out if we're affecting eclasses.
+ [[ ${ECLASS_DEPTH} > 0 ]] && TARGET="E_$1"
+ [[ ${ECLASS_DEPTH} > 0 ]] || TARGET="$1"
+ shift # $1 was a variable name.
+
+ while [ -n "$1" ]; do
+ # This bit of evil takes TARGET and uses it to evaluate down to a
+ # variable. This is a sneaky way to make this infinately expandable.
+ # The normal translation of this would look something like this:
+ # E_DEPEND="${E_DEPEND} $1" :::::: Cool, huh? :)
+ eval export ${TARGET}=\"\${${TARGET}} \$1\"
+ shift
+ done
+}
+
+# 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}"
+}
+
+# === === === === === === === === === === === === === === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === functions end, main part begins === === === === ===
+# === === === === === === === === === === === === === === === === === ===
+
+if [ "$*" != "depend" ] && [ "$*" != "clean" ]; then
+ cd ${PORTAGE_TMPDIR} &> /dev/null
+ cd ${BUILD_PREFIX} &> /dev/null
+
+ if [ "$(id -nu)" == "portage" ] ; then
+ export USER=portage
+ fi
+
+ if hasq distcc ${FEATURES} &>/dev/null; then
+ if [ -d /usr/lib/distcc/bin ]; then
+ #We can enable distributed compile support
+ if [ -z "${PATH/*distcc*/}" ]; then
+ # Remove the other reference.
+ remove_path_entry "distcc"
+ fi
+ export PATH="/usr/lib/distcc/bin:${PATH}"
+ [ ! -z "${DISTCC_LOG}" ] && addwrite "$(dirname ${DISTCC_LOG})"
+ elif which distcc &>/dev/null; then
+ export CC="distcc $CC"
+ export CXX="distcc $CXX"
+ fi
+ fi
+
+ if hasq ccache ${FEATURES} &>/dev/null; then
+ #We can enable compiler cache support
+ if [ -z "${PATH/*ccache*/}" ]; then
+ # Remove the other reference.
+ remove_path_entry "ccache"
+ fi
+
+ if [ -d /usr/lib/ccache/bin ]; then
+ export PATH="/usr/lib/ccache/bin:${PATH}"
+ elif [ -d /usr/bin/ccache ]; then
+ export PATH="/usr/bin/ccache:${PATH}"
+ fi
+
+ [ -z "${CCACHE_DIR}" ] && export CCACHE_DIR="/root/.ccache"
+
+ addread "${CCACHE_DIR}"
+ addwrite "${CCACHE_DIR}"
+
+ [ -n "${CCACHE_SIZE}" ] && ccache -M ${CCACHE_SIZE} &> /dev/null
+ fi
+
+ # XXX: Load up the helper functions.
+# for X in /usr/lib/portage/bin/functions/*.sh; do
+# source ${X} || die "Failed to source ${X}"
+# done
+
+else
+
+killparent() {
+ trap INT
+ kill ${PORTAGE_MASTER_PID}
+}
+trap "killparent" INT
+
+fi # "$*"!="depend" && "$*"!="clean"
+
+export SANDBOX_ON="1"
+export S=${WORKDIR}/${P}
+
+unset E_IUSE E_DEPEND E_RDEPEND E_CDEPEND E_PDEPEND
+
+declare -r T P PN PV PVR PR A D EBUILD EMERGE_FROM O PPID FILESDIR
+declare -r PORTAGE_TMPDIR
+
+# Turn of extended glob matching so that g++ doesn't get incorrectly matched.
+shopt -u extglob
+
+QA_INTERCEPTORS="javac java-config python python-config perl grep egrep fgrep sed gcc g++ cc bash awk nawk gawk pkg-config"
+# level the QA interceptors if we're in depend
+if hasq "depend" "$@"; 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
+ FUNC_SRC="${BIN}() {
+ echo -n \"QA Notice: ${BIN} in global scope: \" >&2
+ if [ \$ECLASS_DEPTH -gt 0 ]; then
+ echo \"eclass \${ECLASS}\" >&2
+ else
+ echo \"\${CATEGORY}/\${PF}\" >&2
+ fi
+ ${BODY}
+ }";
+ eval "$FUNC_SRC" || echo "error creating QA interceptor ${BIN}" >&2
+ done
+ unset src bin_path body
+fi
+source ${EBUILD} || die "error sourcing ebuild"
+if ! hasq depend $EBUILD_PHASE; then
+ RESTRICT="${PORTAGE_RESTRICT}"
+ unset PORTAGE_RESTRICT
+fi
+[ -z "${ERRORMSG}" ] || die "${ERRORMSG}"
+
+# Expand KEYWORDS
+# We need to turn off pathname expansion for -* in KEYWORDS and
+# we need to escape ~ to avoid tilde expansion
+set -f
+KEYWORDS="`eval echo ${KEYWORDS//~/\\~}`"
+set +f
+
+hasq nostrip ${RESTRICT} && export DEBUGBUILD=1
+
+#a reasonable default for $S
+if [ "$S" = "" ]; then
+ export S=${WORKDIR}/${P}
+fi
+
+#wipe the interceptors. we don't want saved.
+if hasq "depend" "$@"; then
+ unset -f $QA_INTERCEPTORS
+ unset QA_INTERCEPTORS
+fi
+
+#some users have $TMP/$TMPDIR to a custom dir in their home ...
+#this will cause sandbox errors with some ./configure
+#scripts, so set it to $T.
+export TMP="${T}"
+export TMPDIR="${T}"
+
+# Note: this next line is not the same as export RDEPEND=${RDEPEND:-${DEPEND}}
+# That will test for unset *or* NULL (""). We want just to set for unset...
+
+#turn off glob expansion from here on in to prevent *'s and ? in the DEPEND
+#syntax from getting expanded :) Fixes bug #1473
+#check eclass rdepends also. bug #58819
+set -f
+if [ "${RDEPEND-unset}" == "unset" ] && [ "${E_RDEPEND-unset}" == "unset" ] ; then
+ export RDEPEND="${DEPEND} ${E_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"
+CDEPEND="$CDEPEND $E_CDEPEND"
+PDEPEND="$PDEPEND $E_PDEPEND"
+
+unset E_IUSE E_DEPEND E_RDEPEND E_CDEPEND E_PDEPEND
+
+if [ "${EBUILD_PHASE}" != "depend" ]; then
+ # Lock the dbkey variables after the global phase
+ declare -r DEPEND RDEPEND SLOT SRC_URI RESTRICT HOMEPAGE LICENSE DESCRIPTION
+ declare -r KEYWORDS INHERITED IUSE CDEPEND PDEPEND PROVIDE
+fi
+
+set +f
+
+for myarg in $*; do
+ case $myarg in
+ nofetch)
+ pkg_nofetch
+ exit 1
+ ;;
+ prerm|postrm|postinst|config)
+ export SANDBOX_ON="0"
+ if [ "$PORTAGE_DEBUG" != "1" ]; then
+ pkg_${myarg}
+ #Allow non-zero return codes since they can be caused by &&
+ else
+ set -x
+ pkg_${myarg}
+ #Allow non-zero return codes since they can be caused by &&
+ set +x
+ fi
+ ;;
+ unpack|compile|test|clean|install)
+ if [ "${SANDBOX_DISABLED="0"}" == "0" ]; then
+ export SANDBOX_ON="1"
+ else
+ export SANDBOX_ON="0"
+ fi
+ if [ "$PORTAGE_DEBUG" != "1" ]; then
+ dyn_${myarg}
+ #Allow non-zero return codes since they can be caused by &&
+ else
+ set -x
+ dyn_${myarg}
+ #Allow non-zero return codes since they can be caused by &&
+ set +x
+ fi
+ export SANDBOX_ON="0"
+ ;;
+ help|clean|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" ]; then
+ dyn_${myarg}
+ else
+ set -x
+ dyn_${myarg}
+ set +x
+ fi
+ ;;
+ package|rpm)
+ export SANDBOX_ON="0"
+ if [ "$PORTAGE_DEBUG" != "1" ]; then
+ dyn_${myarg}
+ else
+ set -x
+ dyn_${myarg}
+ set +x
+ fi
+ ;;
+ depend)
+ export SANDBOX_ON="0"
+ set -f
+
+ # Handled in portage.py now
+ #dbkey=${PORTAGE_CACHEDIR}/${CATEGORY}/${PF}
+
+ if [ ! -d "${dbkey%/*}" ]; then
+ install -d -g ${PORTAGE_GID} -m2775 "${dbkey%/*}"
+ fi
+
+ # Make it group writable. 666&~002==664
+ umask 002
+
+ #the extra `echo` commands remove newlines
+ echo `echo "$DEPEND"` > $dbkey
+ echo `echo "$RDEPEND"` >> $dbkey
+ echo `echo "$SLOT"` >> $dbkey
+ echo `echo "$SRC_URI"` >> $dbkey
+ echo `echo "$RESTRICT"` >> $dbkey
+ echo `echo "$HOMEPAGE"` >> $dbkey
+ echo `echo "$LICENSE"` >> $dbkey
+ echo `echo "$DESCRIPTION"` >> $dbkey
+ echo `echo "$KEYWORDS"` >> $dbkey
+ echo `echo "$INHERITED"` >> $dbkey
+ echo `echo "$IUSE"` >> $dbkey
+ echo `echo "$CDEPEND"` >> $dbkey
+ echo `echo "$PDEPEND"` >> $dbkey
+ echo `echo "$PROVIDE"` >> $dbkey
+ echo `echo "$UNUSED_01"` >> $dbkey
+ echo `echo "$UNUSED_02"` >> $dbkey
+ echo `echo "$UNUSED_03"` >> $dbkey
+ echo `echo "$UNUSED_04"` >> $dbkey
+ echo `echo "$UNUSED_05"` >> $dbkey
+ echo `echo "$UNUSED_06"` >> $dbkey
+ echo `echo "$UNUSED_07"` >> $dbkey
+ echo `echo "$UNUSED_08"` >> $dbkey
+ set +f
+ #make sure it is writable by our group:
+ exit 0
+ ;;
+ *)
+ export SANDBOX_ON="1"
+ echo "Please specify a valid command."
+ echo
+ dyn_help
+ exit 1
+ ;;
+ esac
+
+ #if [ $? -ne 0 ]; then
+ # exit 1
+ #fi
+done
+
+if [ "$myarg" != "clean" ]; then
+ # Save current environment and touch a success file. (echo for success)
+ umask 002
+ set | egrep -v "^SANDBOX_" > "${T}/environment" 2>/dev/null
+ chown portage:portage "${T}/environment" &>/dev/null
+ chmod g+w "${T}/environment" &>/dev/null
+fi
+
+exit 0
diff --git a/bin/emake b/bin/emake
new file mode 100755
index 000000000..44fe83402
--- /dev/null
+++ b/bin/emake
@@ -0,0 +1,14 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/emake,v 1.9.2.1 2005/05/18 15:19:52 jstubbs Exp $
+#
+# 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 /etc/make.globals. We don't source
+# /etc/make.globals here because emake is only called from an
+# ebuild.
+
+${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
diff --git a/bin/emerge b/bin/emerge
new file mode 100755
index 000000000..5ae171963
--- /dev/null
+++ b/bin/emerge
@@ -0,0 +1,3213 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/emerge,v 1.345.2.38 2005/08/13 17:25:26 ferringb Exp $
+
+import os,sys
+os.environ["PORTAGE_CALLER"]="emerge"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+
+import emergehelp,xpak,string,re,commands,time,shutil,traceback,atexit,signal,socket,types
+from stat import *
+from output import *
+
+import portage_util
+import portage_locks
+import portage_exception
+
+
+spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")",
+ "Thank you for using Gentoo. :)",
+ "Are you actually trying to read this?",
+ "How many times have you stared at this?",
+ "We are generating the cache right now",
+ "You are paying too much attention.",
+ "A theory is better than its explanation.",
+ "Phasers locked on target, Captain.",
+ "Thrashing is just virtual crashing.",
+ "To be is to program.",
+ "Real Users hate Real Programmers.",
+ "When all else fails, read the instructions.",
+ "Functionality breeds Contempt.",
+ "The future lies ahead.",
+ "3.1415926535897932384626433832795028841971694",
+ "Sometimes insanity is the only alternative.",
+ "Inaccuracy saves a world of explanation.",
+ ]
+
+
+def update_basic_spinner():
+ global spinner, spinpos
+ spinpos = (spinpos+1) % 500
+ if (spinpos % 100) == 0:
+ if spinpos == 0:
+ sys.stdout.write(". ")
+ else:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+
+def update_scroll_spinner():
+ global spinner, spinpos
+ if(spinpos >= len(spinner)):
+ sys.stdout.write(darkgreen(" \b\b\b"+spinner[len(spinner)-1-(spinpos%len(spinner))]))
+ else:
+ sys.stdout.write(green("\b "+spinner[spinpos]))
+ sys.stdout.flush()
+ spinpos = (spinpos+1) % (2*len(spinner))
+
+def update_twirl_spinner():
+ global spinner, spinpos
+ spinpos = (spinpos+1) % len(spinner)
+ sys.stdout.write("\b\b "+spinner[spinpos])
+ sys.stdout.flush()
+
+spinpos = 0
+spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
+update_spinner = update_twirl_spinner
+if "candy" in portage.settings.features:
+ spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)]
+ update_spinner = update_scroll_spinner
+if not sys.stdout.isatty() or ("--nospinner" in sys.argv):
+ update_spinner = update_basic_spinner
+
+
+if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]):
+ nocolor()
+
+def normpath(mystr):
+ if mystr and (mystr[0]=='/'):
+ return os.path.normpath("///"+mystr)
+ else:
+ return os.path.normpath(mystr)
+
+def userquery(prompt, responses=None, colours=None):
+ """Displays a prompt and a set of responses, then waits for a response
+ which is checked against the responses and the first to match is
+ returned.
+
+ prompt: a String.
+ responses: a List of Strings.
+ colours: a List of Functions taking and returning a String, used to
+ process the responses for display. Typically these will be functions
+ like red() but could be e.g. lambda x: "DisplayString".
+ If responses is omitted, defaults to ["Yes", "No"], [green, red].
+ If only colours is omitted, defaults to [bold, ...].
+
+ Returns a member of the List responses. (If called without optional
+ arguments, returns "Yes" or "No".)
+ KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
+ printed."""
+ if responses is None:
+ responses, colours = ["Yes", "No"], [green, red]
+ elif colours is None:
+ colours=[bold]
+ colours=(colours*len(responses))[:len(responses)]
+ print bold(prompt),
+ try:
+ while True:
+ response=raw_input("["+string.join([colours[i](responses[i]) for i in range(len(responses))],"/")+"] ")
+ for key in responses:
+ if response.upper()==key[:len(response)].upper():
+ return key
+ print "Sorry, response '%s' not understood." % response,
+ except (EOFError, KeyboardInterrupt):
+ print "Interrupted."
+ sys.exit(1)
+
+def sorted_versions(verlist):
+ ret = []
+ for ver in verlist:
+ verparts = ver.split("-")
+ if len(verparts) == 2:
+ verrev = int(verparts[1][1:])
+ else:
+ verrev = 0
+ x = 0
+ while x < len(ret):
+ retparts = ret[x].split("-")
+ verdiff = portage.vercmp(retparts[0], verparts[0])
+ if verdiff > 0:
+ break
+ elif verdiff == 0:
+ if len(retparts) == 2:
+ retrev = int(retparts[1][1:])
+ else:
+ retrev = 0
+ if retrev >= verrev:
+ break
+ x += 1
+ ret.insert(x, ver)
+ return ret
+
+if portage.settings.has_key("PORTAGE_NICENESS"):
+ try:
+ os.nice(int(portage.settings["PORTAGE_NICENESS"]))
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception,e:
+ print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'"
+ print "!!!",e
+
+#Freeze the portdbapi for enhanced performance:
+portage.portdb.freeze()
+
+# Kill noauto as it will break merges otherwise.
+while 'noauto' in portage.features:
+ del portage.features[portage.features.index('noauto')]
+
+#number of ebuilds merged
+merged=0
+params=["selective", "deep", "self", "recurse", "empty"]
+actions=[
+"clean", "config", "depclean",
+"info", "inject", "metadata",
+"prune", "regen", "rsync", "search",
+"sync", "system", "unmerge", "world",
+]
+options=[
+"--ask",
+"--buildpkg", "--buildpkgonly",
+"--changelog", "--columns",
+"--debug", "--deep",
+"--digest",
+"--emptytree",
+"--fetchonly", "--fetch-all-uri",
+"--getbinpkg", "--getbinpkgonly",
+"--help", "--noconfmem",
+"--newuse", "--nocolor",
+"--nodeps", "--noreplace",
+"--nospinner", "--oneshot",
+"--onlydeps", "--pretend",
+"--quiet", "--resume",
+"--searchdesc", "--selective",
+"--skipfirst",
+"--tree",
+"--update", "--upgradeonly",
+"--usepkg", "--usepkgonly",
+"--verbose", "--version"
+]
+
+shortmapping={
+"1":"--oneshot",
+"a":"--ask",
+"b":"--buildpkg", "B":"--buildpkgonly",
+"c":"--clean", "C":"--unmerge",
+"d":"--debug", "D":"--deep",
+"e":"--emptytree",
+"f":"--fetchonly", "F":"--fetch-all-uri",
+"g":"--getbinpkg", "G":"--getbinpkgonly",
+"h":"--help",
+"i":"--inject",
+"k":"--usepkg", "K":"--usepkgonly",
+"l":"--changelog",
+"n":"--noreplace", "N":"--newuse",
+"o":"--onlydeps", "O":"--nodeps",
+"p":"--pretend", "P":"--prune",
+"q":"--quiet",
+"s":"--search", "S":"--searchdesc",
+'t':"--tree",
+"u":"--update", "U":"--upgradeonly",
+"v":"--verbose", "V":"--version"
+}
+
+myaction=None
+myopts=[]
+myfiles=[]
+edebug=0
+
+# process short actions
+tmpcmdline=sys.argv[1:]
+#tmpcmdline.extend(portage.settings["EMERGE_OPTS"].split())
+cmdline=[]
+for x in tmpcmdline:
+ if x[0:1]=="-"and x[1:2]!="-":
+ for y in x[1:]:
+ if shortmapping.has_key(y):
+ if shortmapping[y] in cmdline:
+ print
+ print "*** Warning: Redundant use of",shortmapping[y]
+ else:
+ cmdline.append(shortmapping[y])
+ else:
+ print "!!! Error: -"+y+" is an invalid short action or option."
+ sys.exit(1)
+ else:
+ cmdline.append(x)
+
+# process the options and command arguments
+for x in cmdline:
+ if not x:
+ continue
+ if len(x)>=2 and x[0:2]=="--":
+ if x in options:
+ myopts.append(x)
+ elif x[2:] in actions:
+ if x[2:]=="rsync" or x=="rsync":
+ # "emerge --rsync"
+ print
+ print red("*** '--rsync' has been deprecated.")
+ print red("*** Please use '--sync' instead.")
+ print
+ x="--sync"
+ if myaction:
+ if myaction not in ["system", "world"]:
+ myaction="--"+myaction
+ print
+ print red("!!!")+green(" Multiple actions requested... Please choose one only.")
+ print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
+ print
+ sys.exit(1)
+ myaction=x[2:]
+ else:
+ print "!!! Error:",x,"is an invalid option."
+ sys.exit(1)
+ elif (not myaction) and (x in actions):
+ if x not in ["system", "world"]:
+ #print red("*** Deprecated use of action '"+x+"'")
+ if x=="rsync":
+ # "emerge rsync"
+ print
+ print red("*** 'rsync' will now install the package rsync.")
+ print red("*** To sync the tree, please use '--sync' instead.")
+ print
+ myfiles.append(x)
+ continue
+ if myaction:
+ print
+ print red("!!!")+green(" Multiple actions requested... Please choose one only.")
+ print red("!!! '")+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
+ print
+ sys.exit(1)
+ myaction=x
+ elif x[-1]=="/":
+ # this little conditional helps tab completion
+ myfiles.append(x[:-1])
+ else:
+ myfiles.append(x)
+
+
+if "moo" in myfiles:
+ print """
+
+ Gentoo (""" + os.uname()[0] + """)
+
+ _______________________
+< Have you mooed today? >
+ -----------------------
+ \ ^__^
+ \ (oo)\_______
+ (__)\ )\/\
+ ||----w |
+ || ||
+
+"""
+
+if (myaction in ["world", "system"]) and myfiles:
+ print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
+ sys.exit(1)
+
+for x in myfiles:
+ if (x[-7:] == ".ebuild" or x[-5:] == ".tbz2") and os.path.exists(os.path.abspath(x)):
+ print "emerging by path implies --oneshot... adding --oneshot to options."
+ print red("\n*** emerging by path is broken and may not always work!!!\n")
+ break
+
+if ("--tree" in myopts) and ("--columns" in myopts):
+ print "emerge: can't specify both of \"--tree\" and \"--columns\"."
+ sys.exit(1)
+
+# Always create packages if FEATURES=buildpkg
+# Imply --buildpkg if --buildpkgonly
+if ("buildpkg" in portage.features) or ("--buildpkgonly" in myopts):
+ if "--buildpkg" not in myopts:
+ myopts.append("--buildpkg")
+
+# --tree only makes sense with --pretend
+if "--tree" in myopts and not (("--pretend" in myopts) or ("--ask" in myopts)):
+ print ">>> --tree implies --pretend... adding --pretend to options."
+ myopts.append("--pretend")
+
+# Also allow -S to invoke search action (-sS)
+if ("--searchdesc" in myopts):
+ if myaction and myaction != "search":
+ myfiles.append(myaction)
+ if "--search" not in myopts:
+ myopts.append("--search")
+ myaction = "search"
+
+# Always try and fetch binary packages if FEATURES=getbinpkg
+if ("getbinpkg" in portage.features):
+ myopts.append("--getbinpkg")
+
+if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts):
+ myopts.append("--usepkgonly")
+
+if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts):
+ myopts.append("--getbinpkg")
+
+if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts):
+ myopts.append("--usepkg")
+
+# Also allow -K to apply --usepkg/-k
+if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts):
+ myopts.append("--usepkg")
+
+# Print deprecation warning for -U
+if ("--upgradeonly" in myopts):
+ print
+ print red("*** Warning: --upgradeonly is a deprecated option in portage-"+portage.VERSION)
+ print red("*** and will likely be removed in a future version.")
+ print
+ # Also allow -U to apply --update/-u
+ if not ("--update" in myopts):
+ print ">>> --upgradeonly implies --update... adding --update to options."
+ myopts.append("--update")
+
+# Also allow -l to apply --pretend/-p, but if already in --ask mode
+if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)):
+ print ">>> --changelog implies --pretend... adding --pretend to options."
+ myopts.append("--pretend")
+
+# Allow -p to remove --ask
+if ("--pretend" in myopts) and ("--ask" in myopts):
+ print ">>> --pretend disables --ask... removing --ask from options."
+ myopts.remove("--ask")
+
+# forbid --ask when not in a terminal
+# note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
+if ("--ask" in myopts) and (not sys.stdin.isatty()):
+ portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n")
+ sys.exit(1)
+
+# Set so that configs will be merged regardless of remembered status
+if ("--noconfmem" in myopts):
+ portage.settings.unlock()
+ portage.settings["NOCONFMEM"]="1"
+ portage.settings.backup_changes("NOCONFMEM")
+ portage.settings.lock()
+
+# Set various debug markers... They should be merged somehow.
+if ("--debug" in myopts):
+ portage.settings.unlock()
+ portage.settings["PORTAGE_DEBUG"]="1"
+ portage.settings.backup_changes("PORTAGE_DEBUG")
+ portage.debug=1
+ portage.settings.lock()
+
+if ("--resume" in myopts):
+ if "--verbose" in myopts:
+ print "* --verbose is currently broken with --resume. Disabling..."
+ myopts.remove("--verbose")
+ if "--tree" in myopts:
+ print "* --tree is currently broken with --resume. Disabling..."
+ myopts.remove("--tree")
+
+# Set color output
+if ("--nocolor" in myopts) and (sys.stdout.isatty()):
+ nocolor()
+
+CLEAN_DELAY = 5
+EMERGE_WARNING_DELAY = 10
+if portage.settings["CLEAN_DELAY"]:
+ CLEAN_DELAY = string.atoi("0"+portage.settings["CLEAN_DELAY"])
+if portage.settings["EMERGE_WARNING_DELAY"]:
+ EMERGE_WARNING_DELAY = string.atoi("0"+portage.settings["EMERGE_WARNING_DELAY"])
+
+if "inject" == myaction:
+ print
+ print red("*** --inject has been deprecated.")
+ print red("*** If you manage a piece of software yourself, add it's name and")
+ print red("*** version (eg foo/bar-1.0) to /etc/portage/profile/package.provided.")
+ print red("*** If you want to prevent portage from upgrading a package, add it to")
+ print red("*** /etc/portage/package.mask prepending it with '>' (eg >foo/bar-1.0)")
+ print red("*** For more information on fine-grained portage control, please see")
+ print red("*** the portage man page.")
+ print
+
+def emergelog(mystr,short_msg=None):
+ if "notitles" not in portage.features:
+ if short_msg:
+ xtermTitle(short_msg)
+ else:
+ xtermTitle(mystr)
+ try:
+ #seems odd opening a file each write...
+ if not os.path.exists("/var/log/emerge.log"):
+ mylogfile=open("/var/log/emerge.log", "w")
+ os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+ os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid)
+ else:
+ mylogfile=open("/var/log/emerge.log", "a")
+
+ l=portage_locks.lockfile(mylogfile)
+ # seek because we may have gotten held up by the lock.
+ # if so, we may not be positioned at the end of the file.
+ mylogfile.seek(0,2)
+ mylogfile.write(str(time.time())[:10]+": "+mystr+"\n")
+ mylogfile.flush()
+ portage_locks.unlockfile(l)
+ mylogfile.close()
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if edebug:
+ print "emergelog():",e
+ pass
+
+def emergeexit():
+ """This gets out final log message in before we quit."""
+ if "--pretend" not in myopts:
+ emergelog(" *** terminating.")
+ if "notitles" not in portage.features:
+ xtermTitleReset()
+atexit.register(emergeexit)
+
+def emergeexitsig(signum, frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ portage.portageexit()
+ portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum})
+ sys.exit(100+signum)
+signal.signal(signal.SIGINT, emergeexitsig)
+
+def countdown(secs=5, doing="Starting"):
+ if secs:
+ print ">>> Waiting",secs,"seconds before starting..."
+ print ">>> (Control-C to abort)...\n"+doing+" in: ",
+ ticks=range(secs)
+ ticks.reverse()
+ for sec in ticks:
+ sys.stdout.write(red(str(sec+1)+" "))
+ sys.stdout.flush()
+ time.sleep(1)
+ print
+
+# formats a size given in bytes nicely
+def format_size(mysize):
+ if type(mysize) not in [types.IntType,types.LongType]:
+ return str(mysize)
+ mystr=str(mysize/1024)
+ mycount=len(mystr)
+ while (mycount > 3):
+ mycount-=3
+ mystr=mystr[:mycount]+","+mystr[mycount:]
+ return mystr+" kB"
+
+
+def getgccversion():
+ """
+ rtype: C{str}
+ return: the current in-use gcc version
+ """
+
+ gcc_env_dir = os.path.join('/', 'etc', 'env.d', 'gcc')
+ gcc_config_config = os.path.join(gcc_env_dir, 'config')
+ gcc_ver_command = 'gcc -dumpversion'
+ gcc_ver_prefix = 'gcc-'
+
+ gcc_not_found_error = red(
+ "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
+ "!!! to update the environment of this terminal and possibly\n" +
+ "!!! other terminals also."
+ )
+
+ gcc_distcc_broken_error = green(
+ '!!! Relying on the shell to locate gcc, this may break\n' +
+ '!!! DISTCC, installing gcc-config and setting your current gcc\n' +
+ '!!! profile will fix this'
+ )
+
+ def fallback():
+
+ print >>sys.stderr, gcc_distcc_broken_error
+
+ gccout = commands.getstatusoutput(gcc_ver_command)
+
+ if gccout[0] != 0:
+ print >>sys.stderr, gcc_not_found_error
+ gccver = "[unavailable]"
+ else:
+ gccver = gcc_ver_prefix + gccout[1]
+
+ return gccver
+
+ if os.path.isfile(gcc_config_config):
+ try:
+ gccver_str = open(gcc_config_config).read().strip()
+ gccver = gcc_ver_prefix + string.join(gccver_str.split('-')[4:], '-')
+ except IndexError:
+ gccver = fallback()
+
+ else:
+ import glob
+ dir_l = glob.glob(os.path.join(gcc_env_dir, '*-*'))
+
+ if len(dir_l) == 1:
+ try:
+ gccver = gcc_ver_prefix + dir_l[0].split('-')[-1]
+ except IndexError:
+ gccver = fallback()
+
+ else:
+ # There was no "config" file in /etc/env.d/gcc and there was more
+ # than one profile in /etc/env.d/gcc so we can't actively
+ # determine what version of gcc we are using so we fall back on the
+ # old way that breaks distcc
+
+ gccver = fallback()
+
+ return gccver
+
+def getportageversion():
+ try:
+ import re
+ profilever = os.path.normpath("///"+os.readlink("/etc/make.profile"))
+ basepath = os.path.normpath("///"+portage.settings["PORTDIR"]+"/profiles")
+ if re.match(basepath,profilever):
+ profilever = profilever[len(basepath)+1:]
+ else:
+ profilever = "!"+profilever
+ del basepath
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ profilever="unavailable"
+ libcver=[]
+ libclist = portage.vardbapi(portage.root).match("virtual/libc")
+ libclist += portage.vardbapi(portage.root).match("virtual/glibc")
+ libclist = portage_util.unique_array(libclist)
+ for x in libclist:
+ xs=portage.catpkgsplit(x)
+ if libcver:
+ libcver+=","+string.join(xs[1:], "-")
+ else:
+ libcver=string.join(xs[1:], "-")
+ if libcver==[]:
+ libcver="unavailable"
+
+ gccver = getgccversion()
+ unameout=os.uname()[2]+" "+os.uname()[4]
+
+ return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
+
+def help():
+ # Move all the help stuff out of this file.
+ emergehelp.help(myaction,myopts,havecolor)
+
+# check if root user is the current user for the actions where emerge needs this
+if ("--pretend" in myopts) or ("--fetchonly" in myopts or "--fetch-all-uri" in myopts) or (myaction=="search"):
+ if not portage.secpass:
+ if portage.wheelgid==portage.portage_gid:
+ print "emerge: wheel group membership required for \"--pretend\" and search."
+ print "emerge: wheel group use is being deprecated. Please update group and passwd to"
+ print " include the portage user as noted above, and then use group portage."
+ else:
+ print "emerge: portage group membership required for \"--pretend\" and search."
+ sys.exit(1)
+elif "--version" in myopts:
+ print getportageversion()
+ sys.exit(0)
+elif "--help" in myopts:
+ help()
+ sys.exit(0)
+elif portage.secpass!=2:
+ if myaction in ["search", "info", "regen"]:
+ pass
+ elif (not myaction) and (not myfiles):
+ pass
+ elif ("--pretend" in myopts) and (myaction in ["world","system","clean","prune","unmerge"]):
+ pass
+ else:
+ if "--debug" in myopts:
+ print "myaction",myaction
+ print "myopts",myopts
+ print "emerge: root access required."
+ sys.exit(1)
+
+if not "--pretend" in myopts:
+ emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
+ myelogstr=""
+ if myopts:
+ myelogstr=string.join(myopts, " ")
+ if myaction:
+ myelogstr+=" "+myaction
+ if myfiles:
+ myelogstr+=" "+string.join(myfiles, " ")
+ emergelog(" *** emerge "+myelogstr)
+
+#configure emerge engine parameters
+#
+# self: include _this_ package regardless of if it is merged.
+# selective: exclude the package if it is merged
+# recurse: go into the dependencies
+# empty: pretend nothing is merged
+myparams=["self","recurse"]
+add=[]
+sub=[]
+if "--update" in myopts:
+ add.extend(["selective","empty"])
+if "--emptytree" in myopts:
+ add.extend(["empty"])
+ sub.extend(["selective"])
+if "--nodeps" in myopts:
+ sub.extend(["recurse"])
+if "--noreplace" in myopts:
+ add.extend(["selective"])
+if "--deep" in myopts:
+ add.extend(["deep"])
+if "--selective" in myopts:
+ add.extend(["selective"])
+if myaction in ["world","system"]:
+ add.extend(["selective"])
+elif myaction in ["depclean"]:
+ add.extend(["empty"])
+ sub.extend(["selective"])
+for x in add:
+ if (x not in myparams) and (x not in sub):
+ myparams.append(x)
+for x in sub:
+ if x in myparams:
+ myparams.remove(x)
+
+# search functionality
+class search:
+
+ #
+ # class constants
+ #
+ VERSION_SHORT=1
+ VERSION_RELEASE=2
+
+ #
+ # public interface
+ #
+ def __init__(self):
+ """Searches the available and installed packages for the supplied search key.
+ The list of available and installed packages is created at object instantiation.
+ This makes successive searches faster."""
+ self.installcache = portage.db["/"]["vartree"]
+
+ def execute(self,searchkey):
+ """Performs the search for the supplied search key"""
+ global myopts
+ match_category = 0
+ self.searchkey=searchkey
+ self.packagematches = []
+ if "--searchdesc" in myopts:
+ self.searchdesc=1
+ self.matches = {"pkg":[], "desc":[]}
+ else:
+ self.searchdesc=0
+ self.matches = {"pkg":[]}
+ print "Searching... ",
+
+ if self.searchkey[0] == '@':
+ match_category = 1
+ self.searchkey = self.searchkey[1:]
+ if self.searchkey=="*":
+ #hack for people who aren't regular expression gurus
+ self.searchkey==".*"
+ if re.search("\+\+", self.searchkey):
+ #hack for people who aren't regular expression gurus
+ self.searchkey=re.sub("\+\+","\+\+",self.searchkey)
+ self.searchre=re.compile(self.searchkey.lower(),re.I)
+ for package in portage.portdb.cp_all():
+ update_spinner()
+
+ if match_category:
+ match_string = package[:]
+ else:
+ match_string = package.split("/")[-1]
+
+ masked=0
+ if self.searchre.search(match_string):
+ if not portage.portdb.xmatch("match-visible",package):
+ masked=1
+ self.matches["pkg"].append([package,masked])
+ elif self.searchdesc: # DESCRIPTION searching
+ full_package = portage.portdb.xmatch("bestmatch-visible",package)
+ if not full_package:
+ #no match found; we don't want to query description
+ full_package=portage.best(portage.portdb.xmatch("match-all",package))
+ if not full_package:
+ continue
+ else:
+ masked=1
+ try:
+ full_desc = portage.portdb.aux_get(full_package,["DESCRIPTION"])[0]
+ except KeyError:
+ print "emerge: search: aux_get() failed, skipping"
+ continue
+ if self.searchre.search(full_desc):
+ self.matches["desc"].append([full_package,masked])
+ self.mlen=0
+ for mtype in self.matches.keys():
+ self.matches[mtype].sort()
+ self.mlen += len(self.matches[mtype])
+
+ def output(self):
+ """Outputs the results of the search."""
+ print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]"
+ print "[ Applications found : "+white(str(self.mlen))+" ]"
+ print " "
+ for mtype in self.matches.keys():
+ for match,masked in self.matches[mtype]:
+ if mtype=="pkg":
+ catpack=match
+ full_package = portage.portdb.xmatch("bestmatch-visible",match)
+ if not full_package:
+ #no match found; we don't want to query description
+ masked=1
+ full_package=portage.best(portage.portdb.xmatch("match-all",match))
+ else:
+ full_package = match
+ match = portage.pkgsplit(match)[0]
+
+ if full_package:
+ try:
+ desc, homepage, license = portage.portdb.aux_get(full_package,["DESCRIPTION","HOMEPAGE","LICENSE"])
+ except KeyError:
+ print "emerge: search: aux_get() failed, skipping"
+ continue
+ if masked:
+ print green("*")+" "+white(match)+" "+red("[ Masked ]")
+ else:
+ print green("*")+" "+white(match)
+ myversion = self.getVersion(full_package, search.VERSION_RELEASE)
+
+ mysum = [0,0]
+ mycat = match.split("/")[0]
+ mypkg = match.split("/")[1]
+
+ mydigest = portage.db["/"]["porttree"].dbapi.finddigest(mycat+"/"+mypkg + "-" + myversion)
+
+ try:
+ myfile = open(mydigest,"r")
+ for line in myfile.readlines():
+ mysum[0] += int(line.split(" ")[3])
+ myfile.close()
+ mystr = str(mysum[0]/1024)
+ mycount=len(mystr)
+ while (mycount > 3):
+ mycount-=3
+ mystr=mystr[:mycount]+","+mystr[mycount:]
+ mysum[0]=mystr+" kB"
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if edebug:
+ print "!!! Exception:",e
+ mysum[0]=" [no/bad digest]"
+
+ if "--quiet" not in myopts:
+ print " ", darkgreen("Latest version available:"),myversion
+ print " ", self.getInstallationStatus(mycat+'/'+mypkg)
+ print " ", darkgreen("Size of downloaded files:"),mysum[0]
+ print " ", darkgreen("Homepage:")+" ",homepage
+ print " ", darkgreen("Description:"),desc
+ print " ", darkgreen("License:")+" ",license
+ print
+ print
+ #
+ # private interface
+ #
+ def getInstallationStatus(self,package):
+ installed_package = self.installcache.dep_bestmatch(package)
+ result = ""
+ version = self.getVersion(installed_package,search.VERSION_RELEASE)
+ if len(version) > 0:
+ result = darkgreen("Latest version installed:")+" "+version
+ else:
+ result = darkgreen("Latest version installed:")+" [ Not Installed ]"
+ return result
+
+ def getVersion(self,full_package,detail):
+ if len(full_package) > 1:
+ package_parts = portage.catpkgsplit(full_package)
+ if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
+ result = package_parts[2]+ "-" + package_parts[3]
+ else:
+ result = package_parts[2]
+ else:
+ result = ""
+ return result
+
+
+#build our package digraph
+def getlist(mode):
+ if mode=="system":
+ mylines=portage.settings.packages
+ elif mode=="world":
+ try:
+ myfile=open(portage.root+portage.WORLD_FILE,"r")
+ mylines=myfile.readlines()
+ myfile.close()
+ except OSError:
+ print "!!! Couldn't open "+pfile+"; exiting."
+ sys.exit(1)
+ except IOError:
+ #world file doesn't exist
+ mylines=[]
+ mynewlines=[]
+ for x in mylines:
+ myline=string.join(string.split(x))
+ if not len(myline):
+ continue
+ elif myline[0]=="#":
+ continue
+ elif mode=="system":
+ if myline[0]!="*":
+ continue
+ myline=myline[1:]
+ mynewlines.append(myline.strip())
+ return mynewlines
+
+def genericdict(mylist):
+ mynewdict={}
+ for x in mylist:
+ mynewdict[portage.dep_getkey(x)]=x
+ return mynewdict
+
+olddbapi=None
+class depgraph:
+
+ def __init__(self,myaction,myopts):
+ global olddbapi
+ self.pkgsettings = portage.config(clone=portage.settings)
+ if not self.pkgsettings["ARCH"]:
+ portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"))
+ portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"))
+ sys.exit(9)
+ self.applied_useflags = {}
+
+ self.missingbins=[]
+ self.myaction=myaction
+ self.digraph=portage.digraph()
+ self.orderedkeys=[]
+ self.outdatedpackages=[]
+ self.mydbapi={}
+ self.mydbapi["/"] = portage.fakedbapi()
+ if "empty" not in myparams:
+ for pkg in portage.db["/"]["vartree"].getallcpv():
+ self.mydbapi["/"].cpv_inject(pkg)
+ if portage.root != "/":
+ self.mydbapi[portage.root] = portage.fakedbapi()
+ if "empty" not in myparams:
+ for pkg in portage.db[portage.root]["vartree"].getallcpv():
+ self.mydbapi[portage.root].cpv_inject(pkg)
+
+ if "--usepkg" in myopts:
+ portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts))
+
+ def create(self,mybigkey,myparent=None,addme=1,myuse=None):
+ """creates the actual digraph of packages to merge. return 1 on success, 0 on failure
+ mybigkey = specification of package to merge; myparent = parent package (one depending on me);
+ addme = should I be added to the tree? (for the --onlydeps mode)"""
+ #stuff to add:
+ #SLOT-aware emerge
+ #IUSE-aware emerge
+ #"no downgrade" emerge
+ #print "mybigkey:",mybigkey
+
+ jbigkey=string.join(mybigkey)
+ if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
+ #this conditional is needed to prevent infinite recursion on already-processed deps
+ return 1
+
+ update_spinner()
+
+ mytype,myroot,mykey=mybigkey
+ # select the correct /var database that we'll be checking against
+ vardbapi=portage.db[myroot]["vartree"].dbapi
+
+ if addme:
+ # if the package is already on the system, we add a "nomerge"
+ # directive, otherwise we add a "merge" directive.
+ if mytype=="blocks":
+ # we've encountered a "blocks" node. We will totally ignore this
+ # node and not add it to our digraph if it doesn't apply to us.
+ if "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
+ mybigkey.append(myparent.split()[2])
+ self.digraph.addnode(string.join(mybigkey),myparent)
+ return 1
+
+ if myuse == None:
+ self.pkgsettings.setcpv(mykey)
+ myuse=string.split(self.pkgsettings["USE"], " ")
+
+ self.applied_useflags[mykey] = myuse
+
+ merging=1
+ if addme:
+ # this is where we add the node to the list of packages to merge
+ if not myparent:
+ # command-line specified or part of a world list...
+ if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)):
+ # the package is on the system, so don't merge it.
+ merging=0
+ elif ("selective" in myparams) and vardbapi.cpv_exists(mykey):
+ merging=0
+
+ if (merging==0 and mytype=="ebuild" and "--newuse" in myopts and vardbapi.cpv_exists(mykey)):
+ iuses=string.split(portage.portdb.aux_get(mykey, ["IUSE"])[0])
+ old_use=string.split(vardbapi.aux_get(mykey, ["USE"])[0])
+ now_use=string.split(self.pkgsettings["USE"])
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ merging=1
+ break
+ else:
+ #onlydeps mode; don't merge
+ merging=2
+ if merging==1:
+ mybigkey.append("merge")
+ else:
+ mybigkey.append("nomerge")
+
+ # whatever the case, we need to add the node to our digraph so
+ # that children can depend upon it.
+ self.digraph.addnode(string.join(mybigkey),myparent)
+ if ("deep" not in myparams) and (not merging):
+ return 1
+ elif "recurse" not in myparams:
+ return 1
+
+ edepend={}
+ if mytype=="binary":
+ mypkgparts=portage.catpkgsplit(mykey)
+ tbz2name = string.split(mykey, "/")[1]+".tbz2"
+ if tbz2name in portage.db[portage.root]["bintree"].invalids:
+ sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
+ sys.exit(1)
+ if portage.db[portage.root]["bintree"].isremote(mykey):
+ edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
+ edepend["DEPEND"] =""
+ edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
+ edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
+ edepend["CDEPEND"]=string.join(string.split(edepend["CDEPEND"])," ")
+ edepend["SLOT"] =string.strip(edepend["SLOT"])
+ #portage.db[portage.root]["bintree"].gettbz2(mykey)
+ else: # It's local.
+ mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
+ edepend["DEPEND"] =""
+ edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
+ edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
+ edepend["CDEPEND"]=string.join(mytbz2.getelements("CDEPEND")," ")
+ edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2])
+ elif mytype=="ebuild":
+ try:
+ mymeta = ["DEPEND","RDEPEND","PDEPEND","CDEPEND"]
+ myfoo = portage.portdb.aux_get(mykey, mymeta)
+ for index in range(0,len(mymeta)):
+ edepend[mymeta[index]] = myfoo[index]
+ except (KeyError,IOError):
+ print "emerge: create(): aux_get() error on",mykey+"; aborting..."
+ sys.exit(1)
+ mydep={}
+ mp=string.join(mybigkey)
+
+ if myroot=="/":
+ mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
+ if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
+ return 0
+ else:
+ mydep["/"]=edepend["DEPEND"]
+ mydep[myroot]=edepend["RDEPEND"]
+ if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
+ return 0
+ if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
+ return 0
+
+ if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
+ # Post Depend -- Add to the list without a parent, as it depends
+ # on a package being present AND must be built after that package.
+ if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
+ return 0
+
+ return 1
+
+ def select_files(self,myfiles):
+ "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
+ myfavorites=[]
+ for x in myfiles:
+ if x[-5:]==".tbz2":
+ if not os.path.exists(x):
+ if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
+ x=self.pkgsettings["PKGDIR"]+"/All/"+x
+ elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
+ x=self.pkgsettings["PKGDIR"]+"/"+x
+ else:
+ print "\n\n!!! Binary package '"+str(x)+"' does not exist."
+ print "!!! Please ensure the tbz2 exists as specified.\n"
+ sys.exit(1)
+ mytbz2=xpak.tbz2(x)
+ mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.basename(x)[:-5]
+ if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
+ print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
+ sys.exit(1)
+ if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts):
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+ elif x[-7:]==".ebuild":
+ x = os.path.realpath(x)
+ mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.basename(x)[:-7]
+ ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
+ if ebuild_path:
+ if os.path.realpath(ebuild_path) != x:
+ print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
+ sys.exit(1)
+ if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
+ print red("\n*** You are emerging a masked package. It is MUCH better to use")
+ print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
+ print red("*** page for details.")
+ countdown(EMERGE_WARNING_DELAY, "Continuing...")
+ else:
+ print red("\n*** "+x+" does not exist")
+ sys.exit(1)
+ if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts):
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+ else:
+ try:
+ mykey=portage.dep_expand(x,mydb=portage.portdb)
+ except ValueError, errpkgs:
+ print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
+ print "!!! one of the following fully-qualified ebuild names instead:\n"
+ for i in errpkgs[0]:
+ print " " + green(i)
+ print
+ sys.exit(1)
+
+ # select needs to return 0 on dep_check failure
+
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ try:
+ self.mysd = self.select_dep(portage.root,mykey,arg=x)
+ except portage_exception.MissingSignature, e:
+ portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
+ portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
+ portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
+ portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF A TAMPERED FILES -- CHECK CAREFULLY.\n")
+ portage.writemsg("!!! Affected file: %s\n" % (e))
+ sys.exit(1)
+ except portage_exception.InvalidSignature, e:
+ portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
+ portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
+ portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
+ portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF A TAMPERED FILES -- CHECK CAREFULLY.\n")
+ portage.writemsg("!!! Affected file: %s\n" % (e))
+ sys.exit(1)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if "--debug" in myopts:
+ raise
+ print "\n\n!!! Problem in",mykey,"dependencies."
+ print "!!!",str(e),e.__module__
+ sys.exit(1)
+
+ if not self.mysd:
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+
+ missing=0
+ if "--usepkgonly" in myopts:
+ for x in self.digraph.dict.keys():
+ xs=string.split(x," ")
+ if (xs[0] != "binary") and (xs[3]=="merge"):
+ if missing == 0:
+ print
+ missing += 1
+ print "Missing binary for:",xs[2]
+
+ # We're true here unless we are missing binaries.
+ return (not missing,myfavorites)
+
+ def is_newer_ver_installed(self,myroot,pkg,pkgver):
+ "if there is a version of pkg installed newer than pkgver, return it"
+ vardbapi=portage.db[myroot]["vartree"].dbapi
+
+ matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
+ if matches:
+ myslot=portage.db["/"]["porttree"].getslot(pkgver)
+ for match in matches:
+ if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
+ curslot=portage.db[myroot]["vartree"].getslot(match)
+ if curslot == myslot:
+ return match
+
+ def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None):
+ "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
+ if "--debug" in myopts:
+ print
+ print "Parent: ",myparent
+ print "Depstring:",depstring
+ if not arg:
+ #processing dependencies
+ mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkg" in myopts))
+ #mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse)
+
+ if not mycheck[0]:
+ mymerge=[]
+ else:
+ mymerge=mycheck[1]
+
+ else:
+ #we're processing a command-line argument; unconditionally merge it even if it's already merged
+ mymerge=[depstring]
+
+ # dep_check has been run so we can now add our parent to our
+ # build state to update virtuals and other settings. This
+ # happens after the package is added to the tree so that a
+ # package can depend on a virtual which it satisfies.
+ if myparent:
+ myp = myparent.split()
+ if myp[3]=="merge":
+ self.mydbapi[myroot].cpv_inject(myp[2])
+ if myp[0]=="binary":
+ self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
+ else:
+ self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
+
+ if not mymerge:
+ return 1
+
+ if "--debug" in myopts:
+ print "Candidates:",mymerge
+ for x in mymerge:
+ myk=None
+ binpkguseflags=None
+ if x[0]=="!":
+ # if this package is myself, don't append it to block list.
+ if "--debug" in myopts:
+ print "Myparent",myparent
+ if (myparent):
+ if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
+ # myself, so exit.
+ continue
+ # adding block
+ myk=["blocks",myroot,x[1:]]
+ else:
+ #We are not processing a blocker but a normal dependency
+ myeb=None
+ myeb_matches = portage.portdb.xmatch("match-visible",x)
+ if ("--usepkgonly" not in myopts):
+ myeb=portage.best(myeb_matches)
+
+ myeb_pkg=None
+ if ("--usepkg" in myopts):
+ # The next line assumes the binarytree has been populated.
+ # XXX: Need to work out how we use the binary tree with roots.
+ myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
+ if ("--usepkgonly" not in myopts):
+ # Remove any binary package entries that are masked in the portage tree (#55871)
+ for idx in range(len(myeb_pkg_matches)-1,-1,-1):
+ if myeb_pkg_matches[idx] not in myeb_matches:
+ del myeb_pkg_matches[idx]
+ myeb_pkg = portage.best(myeb_pkg_matches)
+
+ if not myeb_pkg:
+ myeb_pkg = None
+ elif ("--newuse" in myopts):
+ iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
+ old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
+ self.pkgsettings.setcpv(myeb_pkg)
+ now_use=string.split(self.pkgsettings["USE"])
+ self.pkgsettings.reset()
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ myeb_pkg = None
+ break
+
+ if (not myeb) and (not myeb_pkg):
+ if not arg:
+ xinfo='"'+x+'"'
+ else:
+ xinfo='"'+arg+'"'
+ if myparent:
+ xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"])")
+ alleb=portage.portdb.xmatch("match-all",x)
+ if alleb:
+ if "--usepkgonly" not in myopts:
+ print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
+ print "!!! One of the following masked packages is required to complete your request:"
+ oldcomment = ""
+ for p in alleb:
+ mreasons = portage.getmaskingstatus(p)
+ print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
+ comment = portage.getmaskingreason(p)
+ if comment and comment != oldcomment:
+ print comment
+ oldcomment = comment
+ print
+ print "For more information, see MASKED PACKAGES section in the emerge man page or "
+ print "section 2.2 \"Software Availability\" in the Gentoo Handbook."
+ if myparent:
+ print "!!! "+red(xfrom)
+ print
+ else:
+ print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
+ print "!!! Either add a suitable binary package or compile from an ebuild."
+ else:
+ print "\nemerge: there are no ebuilds to satisfy "+xinfo+"."
+ print
+ return 0
+
+ if "--debug" in myopts:
+ print "ebuild:",myeb
+ print "binpkg:",myeb_pkg
+
+ if myeb and myeb_pkg:
+ myeb_s = portage.catpkgsplit(myeb)
+ myeb_s = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
+ myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
+ myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
+
+ if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
+ myeb = None
+ else:
+ myeb_pkg = None
+
+ if "--upgradeonly" in myopts:
+ # Check that there isn't a newer version of this package already installed
+ cand = None
+ try:
+ # XXX: This can throw an exception if the ebuild doesn't exist
+ if myeb:
+ cand=self.is_newer_ver_installed(myroot,x,myeb)
+ elif myeb_pkg:
+ cand=self.is_newer_ver_installed(myroot,x,myeb_pkg)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Warning: "+str(e)
+ if cand:
+ myeb=cand
+
+ if myeb:
+ myk=["ebuild",myroot,myeb]
+ elif myeb_pkg:
+ binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
+ myk=["binary",myroot,myeb_pkg]
+ else:
+ sys.stderr.write("!!! Confused... Don't know what I'm using for dependency info. :(\n")
+ sys.exit(1)
+
+ #if "--usepkg" in myopts:
+ # #If we want to use packages, see if we have a pre-built one...
+ # mypk=portage.db["/"]["bintree"].dbapi.match(x)
+ # if myeb in mypk:
+ # #Use it only if it's exactly the version we want.
+ # myk=["binary",myroot,myeb]
+ # else:
+ # myk=["ebuild",myroot,myeb]
+ #else:
+ # myk=["ebuild",myroot,myeb]
+ if myparent:
+ #we are a dependency, so we want to be unconditionally added
+ if not self.create(myk,myparent,myuse=binpkguseflags):
+ return 0
+ else:
+ #if mysource is not set, then we are a command-line dependency and should not be added
+ #if --onlydeps is specified.
+ if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags):
+ return 0
+
+ if "--debug" in myopts:
+ print "Exiting...",myparent
+ return 1
+
+
+ def altlist(self):
+ mygraph=self.digraph.copy()
+ dolist=["/"]
+ retlist=[]
+ for x in portage.db.keys():
+ portage.db[x]["merge"]=[]
+ if x not in dolist:
+ dolist.append(x)
+ while (not mygraph.empty()):
+ mycurkey=mygraph.firstzero()
+ if not mycurkey:
+ print "!!! Error: circular dependencies:"
+ print
+ for x in mygraph.dict.keys():
+ for y in mygraph.dict[x][1]:
+ print y,"depends on",x
+ print
+ sys.exit(1)
+ splitski=string.split(mycurkey)
+ #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
+ #These lines remove already-merged things from our alt-list
+ #if "--update" in myopts:
+ # if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
+ # portage.db["/"]["merge"].append(splitski)
+ #else:
+ portage.db[splitski[1]]["merge"].append(splitski)
+ mygraph.delnode(mycurkey)
+ for x in dolist:
+ for y in portage.db[x]["merge"]:
+ retlist.append(y)
+ return retlist
+
+ def xcreate(self,mode="system"):
+ global syslist
+ if mode=="system":
+ mylist=syslist
+ else:
+ #world mode
+ worldlist=getlist("world")
+ sysdict=genericdict(syslist)
+ worlddict=genericdict(worldlist)
+ #we're effectively upgrading sysdict to contain all new deps from worlddict
+ for x in worlddict.keys():
+ #only add the world node if the package is:
+ #actually installed -- this prevents the remerging of already unmerged packages when we do a world --update;
+ #actually available -- this prevents emerge from bombing out due to no match being found (we want a silent ignore)
+ if "empty" in myparams:
+ if portage.db["/"]["vartree"].dbapi.match(x):
+ sysdict[x]=worlddict[x]
+ elif portage.db[portage.root]["vartree"].dbapi.match(x):
+ #package is installed
+ sysdict[x]=worlddict[x]
+ else:
+ print "\n*** Package in world file is not installed: "+x
+ mylist = sysdict.keys()
+
+ for mydep in mylist:
+ myeb=portage.portdb.xmatch("bestmatch-visible",mydep)
+ if not myeb:
+ #this is an unavailable world entry; just continue
+ continue
+
+ if "--upgradeonly" in myopts:
+ cand=self.is_newer_ver_installed(portage.root,mydep,myeb)
+ if cand:
+ myeb=cand
+
+ #THIS NEXT BUNCH OF CODE NEEDS TO BE REPLACED TO SUPPORT WORLD ANTI-DEPS
+ #if mydep2[0]=="!":, etc.
+ binpkguseflags = None
+ if "--usepkg" in myopts:
+ mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
+ if myeb==mypk:
+ myk=["binary",portage.root,mypk]
+ binpkguseflags=portage.db[portage.root]["bintree"].get_use(mypk)
+ if ("--newuse" in myopts):
+ iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(mypk, ["IUSE"])[0])
+ old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(mypk, ["USE"])[0])
+ self.pkgsettings.setcpv(mypk)
+ now_use=string.split(self.pkgsettings["USE"])
+ self.pkgsettings.reset()
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ myk=["ebuild",portage.root,myeb]
+ binpkguseflags=None
+ break
+ elif "--usepkgonly" in myopts:
+ if not mypk:
+ self.missingbins += [myeb]
+ myk=["binary",portage.root,myeb]
+ else:
+ myk=["binary",portage.root,mypk]
+ else:
+ myk=["ebuild",portage.root,myeb]
+ else:
+ myk=["ebuild",portage.root,myeb]
+
+ if not self.create(myk,myuse=binpkguseflags):
+ print
+ print "!!! Problem with",myk[0],myk[2]
+ print "!!! Possibly a DEPEND/*DEPEND problem."
+ print
+ return 0
+ return 1
+
+ def match(self,mydep,myroot=portage.root,mykey=None):
+ # support mutual exclusive deps
+ mydep2=mydep
+ if mydep2[0]=="!":
+ mydep2=mydep[1:]
+
+ if mydep[0]=="!":
+ #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
+ myk="blocks "+myroot+" "+mydep2
+ else:
+ myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
+ if not myeb:
+ if not mykey:
+ print "\n!!! Error: couldn't find match for",mydep
+ else:
+ print "\n!!! Error: couldn't find match for",mydep,"in",mykey
+ print
+ sys.exit(1)
+
+ if "--usepkg" in myopts:
+ mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
+ if myeb==mypk:
+ myk="binary "+portage.root+" "+mypk
+ else:
+ myk="ebuild "+myroot+" "+myeb
+ else:
+ myk="ebuild "+myroot+" "+myeb
+
+ return myk
+
+ def display(self,mylist):
+ changelogs=[]
+ p=[]
+ totalsize=0
+
+ if "--verbose" in myopts:
+ overlays = string.split(portage.settings['PORTDIR_OVERLAY'])
+
+ if "--tree" in myopts:
+ mylist.reverse()
+ mygraph=self.digraph.copy()
+
+ i = 0
+ while i < len(mylist):
+ if mylist[i][-1]=="nomerge":
+ if not ("--tree" in myopts):
+ # we don't care about this elements
+ mylist.pop(i)
+ continue
+ if (i == (len(mylist) - 1)) \
+ or (mygraph.depth(string.join(mylist[i])) \
+ >= mygraph.depth(string.join(mylist[i+1]))):
+ # end of a useless branch (may be the last one)
+ # -> delete the element and test the previous one
+ mylist.pop(i)
+ if i > 0:
+ i -= 1
+ continue
+ # the branch continues, or we've found a good element.
+ # -> let's see what's next, if anything
+ i += 1
+
+ display_overlays=False
+ # files to fetch list - avoids counting a same file twice
+ # in size display (verbose mode)
+ myfetchlist=[]
+ for x in mylist:
+ fetch=" "
+
+ if x[0]=="blocks":
+ addl=""+red("B")+" "+fetch+" "
+ resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
+ print "["+x[0]+" "+addl+"]",red(resolved),
+ if resolved!=x[2]:
+ if x[3]:
+ print red("(\""+x[2]+"\" is blocking "+x[3]+")")
+ else:
+ print red("(\""+x[2]+"\")")
+ else:
+ if x[3]:
+ print red("(is blocking "+x[3]+")")
+ else:
+ print
+ else:
+ if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
+ fetch = red("F")
+ if portage.portdb.fetch_check(x[2], portage.settings):
+ fetch = green("f")
+
+ #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
+ #param is used for -u, where you still *do* want to see when something is being upgraded.
+ myoldbest=""
+ if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
+ addl=" "+yellow("R")+fetch+" "
+ elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
+ if x[0] == "binary":
+ mynewslot=portage.db["/"]["bintree"].getslot(x[2])
+ elif x[0] == "ebuild":
+ mynewslot=portage.db["/"]["porttree"].getslot(x[2])
+ myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
+ myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
+ if myinslotlist:
+ myoldbest=portage.best(myinslotlist)
+ addl=" "+fetch
+ if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
+ # Downgrade in slot
+ addl+=turquoise("U")+blue("D")
+ else:
+ # Update in slot
+ addl+=turquoise("U")+" "
+ else:
+ # New slot, mark it new.
+ addl=" "+green("NS")+fetch+" "
+
+ if "--changelog" in myopts:
+ changelogs.extend(self.calc_changelog(
+ portage.portdb.findname(x[2]),
+ portage.db["/"]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
+ x[2]
+ ))
+ else:
+ addl=" "+green("N")+" "+fetch+" "
+
+ verboseadd=""
+ if "--verbose" in myopts:
+ # iuse verbose
+ try:
+ if x[0] == "binary":
+ iuse_split = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
+ elif x[0] == "ebuild":
+ iuse_split = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
+ else:
+ iuse_split = []
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ portage.writemsg("!!! Error getting IUSE (report this to bugs.gentoo.org)\n")
+ portage.writemsg("!!! %s\n" % x)
+ iuse_split = []
+ iuse_split.sort()
+ old_use=None
+ if myoldbest:
+ pkg=myoldbest
+ else:
+ pkg=x[2]
+ if portage.db["/"]["vartree"].dbapi.cpv_exists(pkg):
+ try:
+ old_use=string.split(portage.db["/"]["vartree"].dbapi.aux_get(pkg, ["USE"])[0])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ iuse=""
+ now_use=self.applied_useflags[x[2]]
+ for ebuild_iuse in portage_util.unique_array(iuse_split):
+ usechange=""
+ if old_use:
+ if (old_use.count(ebuild_iuse) and not now_use.count(ebuild_iuse)) or (not old_use.count(ebuild_iuse) and now_use.count(ebuild_iuse)):
+ usechange="*"
+
+ if ebuild_iuse in self.applied_useflags[x[2]]:
+ if usechange == "*":
+ iuse=green("+"+ebuild_iuse)
+ else:
+ iuse=red("+"+ebuild_iuse)
+ elif ebuild_iuse in portage.settings.usemask:
+ iuse=blue("(-"+ebuild_iuse+")")
+ else:
+ iuse=blue("-"+ebuild_iuse)
+ verboseadd+=iuse+usechange+" "
+
+ # size verbose
+ mysize=0
+ if x[0] == "ebuild" and x[-1]!="nomerge":
+ myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
+ if myfilesdict==None:
+ myfilesdict="[empty/missing/bad digest]"
+ else:
+ for myfetchfile in myfilesdict.keys():
+ if myfetchfile not in myfetchlist:
+ mysize+=myfilesdict[myfetchfile]
+ myfetchlist.append(myfetchfile)
+ totalsize+=mysize
+ verboseadd+=format_size(mysize)+" "
+
+ # overlay verbose
+ # XXX: Invalid binaries have caused tracebacks here. 'if file_name'
+ # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
+ file_name=portage.portdb.findname(x[2])
+ if file_name: # It might not exist in the tree
+ dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
+ if (overlays.count(dir_name)>0):
+ verboseadd+=teal("["+str(overlays.index(os.path.normpath(dir_name))+1)+"]")+" "
+ display_overlays=True
+ else:
+ verboseadd += "[No ebuild?]"
+
+ xs=portage.pkgsplit(x[2])
+ if xs[2]=="r0":
+ xs[2]=""
+ else:
+ xs[2]="-"+xs[2]
+
+ if self.pkgsettings.has_key("COLUMNWIDTH"):
+ mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
+ else:
+ mywidth=130
+ oldlp=mywidth-30
+ newlp=oldlp-30
+
+ indent=""
+ if ("--tree" in myopts):
+ indent=" "*mygraph.depth(string.join(x))
+
+ if myoldbest:
+ myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
+ if myoldbest[-3:]=="-r0":
+ myoldbest=myoldbest[:-3]
+ myoldbest=blue("["+myoldbest+"]")
+
+ if x[1]!="/":
+ if "--columns" in myopts:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
+ if (newlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(newlp-nc_len(myprint)))
+ myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
+ if (oldlp-nc_len(myprint)) > 0:
+ myprint=myprint+" "*(oldlp-nc_len(myprint))
+ myprint=myprint+myoldbest
+ myprint=myprint+darkgreen(" to "+x[1])+" "+verboseadd
+ else:
+ myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+" "+darkgreen("to "+x[1])+" "+verboseadd
+ else:
+ if "--columns" in myopts:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
+ if (newlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(newlp-nc_len(myprint)))
+ myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
+ if (oldlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(oldlp-nc_len(myprint)))
+ myprint=myprint+myoldbest+" "+verboseadd
+ else:
+ if x[3]=="nomerge":
+ myprint=darkblue("[nomerge ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
+ else:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
+ p.append(myprint)
+
+ if ("--tree" not in myopts):
+ mysplit=portage.pkgsplit(x[2])
+
+ # XXX mysplit _can_ be None.... Why?
+ if mysplit and (len(mysplit)==3):
+ if "--emptytree" not in myopts:
+ if mysplit[0]=="sys-apps/portage":
+ if ((mysplit[1]+mysplit[2]) != portage.VERSION) and \
+ ("livecvsportage" not in portage.settings.features):
+ if mylist.index(x)<len(mylist)-1:
+ p.append(red("*** Portage will stop merging at this point and reload itself,"))
+ p.append(red(" recalculate dependencies, and complete the merge."))
+ if "--update" not in myopts:
+ p.append(darkgreen(" You may avoid the remerging of packages by updating portage on its own."))
+ print
+ else:
+ if mysplit[0]=="sys-apps/portage" and ("--emptytree" in myopts):
+ if mysplit[1]+mysplit[2]!=portage.VERSION:
+ p.append(red("***")+" Please update portage to the above version before proceeding.")
+ p.append(" Failure to do so may result in failed or improper merges.")
+ p.append(" A simple '"+green("emerge -u portage")+"' is sufficient.")
+ p.append("")
+ del mysplit
+
+ for x in p:
+ print x
+
+ if "--verbose" in myopts:
+ print
+ print "Total size of downloads: "+format_size(totalsize)
+ if overlays and display_overlays:
+ print "Portage overlays:"
+ y=0
+ for x in overlays:
+ y=y+1
+ print " "+teal("["+str(y)+"]"),x
+
+ if "--changelog" in myopts:
+ print
+ for revision,text in changelogs:
+ print bold('*'+revision)
+ sys.stdout.write(text)
+
+ def calc_changelog(self,ebuildpath,current,next):
+ current = '-'.join(portage.catpkgsplit(current)[1:])
+ if current.endswith('-r0'): current = current[:-3]
+ next = '-'.join(portage.catpkgsplit(next)[1:])
+ if next.endswith('-r0'): next = next[:-3]
+ changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
+ try:
+ changelog = open(changelogpath).read()
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ return []
+ divisions = self.find_changelog_tags(changelog)
+ #print 'XX from',current,'to',next
+ #for div,text in divisions: print 'XX',div
+ # skip entries for all revisions above the one we are about to emerge
+ for i in range(len(divisions)):
+ if divisions[i][0]==next:
+ divisions = divisions[i:]
+ break
+ # find out how many entries we are going to display
+ for i in range(len(divisions)):
+ if divisions[i][0]==current:
+ divisions = divisions[:i]
+ break
+ else:
+ # couldnt find the current revision in the list. display nothing
+ return []
+ return divisions
+
+ def find_changelog_tags(self,changelog):
+ divs = []
+ release = None
+ while 1:
+ match = re.search(r'^\*\ ?([-a-zA-Z0-9_.]*)(?:\ .*)?\n',changelog,re.M)
+ if match is None:
+ if release is not None:
+ divs.append((release,changelog))
+ return divs
+ if release is not None:
+ divs.append((release,changelog[:match.start()]))
+ changelog = changelog[match.end():]
+ release = match.group(1)
+ if release.endswith('.ebuild'):
+ release = release[:-7]
+ if release.endswith('-r0'):
+ release = release[:-3]
+
+ def outdated(self):
+ return self.outdatedpackages
+
+ def merge(self,mylist):
+ returnme=0
+ mymergelist=[]
+
+ #check for blocking dependencies
+ if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
+ for x in mylist:
+ if x[0]=="blocks":
+ print "\n!!! Error: the "+x[2]+" package conflicts with another package."
+ print "!!! both can't be installed on the same system together."
+ print "!!! Please use 'emerge --pretend' to determine blockers."
+ print
+ if ("--pretend" not in myopts):
+ sys.exit(1)
+
+ #buildsyspkg: I need mysysdict also on resume (moved from the else block)
+ mysysdict=genericdict(syslist)
+ if ("--resume" in myopts):
+ # We're resuming.
+ print green("*** Resuming merge...")
+ emergelog(" *** Resuming merge...")
+ mymergelist=portage.mtimedb["resume"]["mergelist"][:]
+ if ("--skipfirst" in myopts) and mymergelist:
+ del portage.mtimedb["resume"]["mergelist"][0]
+ del mymergelist[0]
+ else:
+ myfavs=portage.grabfile(portage.root+portage.WORLD_FILE)
+ myfavdict=genericdict(myfavs)
+ for x in range(len(mylist)):
+ if mylist[x][3]!="nomerge":
+ # Add to the mergelist
+ mymergelist.append(mylist[x])
+ else:
+ myfavkey=portage.cpv_getkey(mylist[x][2])
+ if "--onlydeps" in myopts:
+ continue
+ # Add to the world file. Since we won't be able to later.
+ if (not "--fetchonly" in myopts) and (myfavkey in favorites):
+ #don't record if already in system profile or already recorded
+ if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
+ #we don't have a favorites entry for this package yet; add one
+ myfavdict[myfavkey]=myfavkey
+ print ">>> Recording",myfavkey,"in \"world\" favorites file..."
+ if not "--fetchonly" in myopts:
+ portage.writedict(myfavdict,portage.root+portage.WORLD_FILE,writekey=0)
+
+ portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
+
+ # We need to yank the harmful-to-new-builds settings from features.
+ myorigfeat=self.pkgsettings["FEATURES"]
+ myfeat=myorigfeat.split()
+ while ("keeptemp" in myfeat):
+ del myfeat[myfeat.index("keeptemp")]
+ while ("keepwork" in myfeat):
+ del myfeat[myfeat.index("keepwork")]
+
+ self.pkgsettings["FEATURES"]=string.join(myfeat)
+
+ mergecount=0
+ for x in mymergelist:
+ mergecount+=1
+ myroot=x[1]
+ pkgindex=2
+ if x[0]=="blocks":
+ pkgindex=3
+ y=portage.portdb.findname(x[pkgindex])
+ if not "--pretend" in myopts:
+ print ">>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
+ emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
+
+ self.pkgsettings["EMERGE_FROM"] = x[0][:]
+ self.pkgsettings.backup_changes("EMERGE_FROM")
+
+ #buildsyspkg: Check if we need to _force_ binary package creation
+ issyspkg = ("buildsyspkg" in myfeat) \
+ and x[0] != "blocks" \
+ and mysysdict.has_key(portage.cpv_getkey(x[2])) \
+ and not ("--buildpkg" in myopts)
+ if x[0] in ["ebuild","blocks"]:
+ if (x[0]=="blocks") and ("--fetchonly" not in myopts):
+ raise Exception, "Merging a blocker"
+ elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
+ if ("--fetch-all-uri" in myopts):
+ retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1)
+ else:
+ retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1)
+ if (retval == None) or retval:
+ print
+ print "!!! Fetch for",y,"failed, continuing..."
+ print
+ returnme=1
+ continue
+ elif "--buildpkg" in myopts or issyspkg:
+ #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
+ if issyspkg:
+ print ">>> This is a system package, let's pack a rescue tarball."
+ #emergelog(">>> This is a system package, let's pack a rescue tarball.")
+ #create pkg, then merge pkg
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ #dynamically update our database
+ if "--buildpkgonly" not in myopts:
+ portage.db[portage.root]["bintree"].inject(x[2])
+ mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+
+ self.pkgsettings["EMERGE_FROM"] = "binary"
+ self.pkgsettings.backup_changes("EMERGE_FROM")
+
+ retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
+ if retval==None:
+ sys.exit(1)
+ else:
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ #dynamically update our database
+ elif x[0]=="binary":
+ #merge the tbz2
+ mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
+ if portage.db[portage.root]["bintree"].isremote(x[2]):
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
+ emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
+ portage.db[portage.root]["bintree"].gettbz2(x[2])
+
+ if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
+ continue
+
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
+ retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
+ if retval==None:
+ sys.exit(1)
+ #need to check for errors
+ if "--buildpkgonly" not in myopts:
+ portage.db[x[1]]["vartree"].inject(x[2])
+ myfavkey=portage.cpv_getkey(x[2])
+ if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites:
+ myfavs=portage.grabfile(myroot+portage.WORLD_FILE)
+ myfavdict=genericdict(myfavs)
+ mysysdict=genericdict(syslist)
+ #don't record if already in system profile or already recorded
+ if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
+ #we don't have a favorites entry for this package yet; add one
+ myfavdict[myfavkey]=myfavkey
+ print ">>> Recording",myfavkey,"in \"world\" favorites file..."
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
+ portage.writedict(myfavdict,myroot+portage.WORLD_FILE,writekey=0)
+
+ if ("noclean" not in portage.features) and (x[0] != "binary"):
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean Post"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+
+ if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ # Clean the old package that we have merged over top of it.
+ if self.pkgsettings["AUTOCLEAN"]=="yes":
+ xsplit=portage.pkgsplit(x[2])
+ emergelog(" >>> AUTOCLEAN: "+xsplit[0])
+ retval=unmerge("clean", [xsplit[0]])
+ if not retval:
+ emergelog(" --- AUTOCLEAN: Nothing unmerged.")
+
+ # Figure out if we need a restart.
+ mysplit=portage.pkgsplit(x[2])
+ if mysplit[0]=="sys-apps/portage":
+ myver=mysplit[1]+"-"+mysplit[2]
+ if myver[-3:]=='-r0':
+ myver=myver[:-3]
+ if (myver != portage.VERSION) and \
+ ("livecvsportage" not in portage.settings.features):
+ if len(mymergelist) > mergecount:
+ myargv=sys.argv
+ myr=0
+ for myra in range(len(myargv)):
+ if myargv[myr][0:len("portage")]=="portage":
+ del myargv[myr]
+ myr-=1
+ if myargv[myr][0:len("sys-apps/portage")]=="sys-apps/portage":
+ del myargv[myr]
+ myr-=1
+ myr+=1
+ emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
+ portage.portageexit()
+ # Remove --ask from options before restarting
+ mynewargv=[]
+ badlongopts = ["--ask","--tree","--changelog"]
+ badshortopts = ["a","t","l"]
+ for arg in myargv:
+ if arg[0:2] == "--":
+ if arg in badlongopts:
+ continue
+ mynewargv += [arg]
+ elif arg[0] == "-":
+ myarg = "-"
+ for ch in arg[1:]:
+ if ch in badshortopts:
+ continue
+ myarg += ch
+ mynewargv += [myarg]
+ else:
+ mynewargv += [arg]
+ os.execv("/usr/lib/portage/bin/emerge", mynewargv)
+
+ if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
+
+ # Unsafe for parallel merges
+ del portage.mtimedb["resume"]["mergelist"][0]
+
+ emergelog(" *** Finished. Cleaning up...")
+
+ # We're out of the loop... We're done. Delete the resume data.
+ if portage.mtimedb.has_key("resume"):
+ del portage.mtimedb["resume"]
+
+ if ("--pretend" not in myopts):
+ if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ if (mergecount>0):
+ if retval:
+ portage.env_update()
+
+ #by doing an exit this way, --fetchonly can continue to try to
+ #fetch everything even if a particular download fails.
+ if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
+ if returnme:
+ print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n"
+ sys.exit(returnme)
+ else:
+ sys.exit(0)
+
+def unmerge(unmerge_action, unmerge_files):
+ candidate_catpkgs=[]
+ global_unmerge=0
+
+ realsyslist = getlist("system")
+ syslist = []
+ for x in realsyslist:
+ mycp = portage.dep_getkey(x)
+ if mycp in portage.settings.virtuals:
+ syslist.extend(portage.settings.virtuals[mycp])
+ syslist.append(mycp)
+
+ global myopts
+ mysettings = portage.config(clone=portage.settings)
+
+ if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
+ if "unmerge"==unmerge_action:
+ print
+ print bold("emerge unmerge")+" can only be used with specific package names, not with "+bold("world")+" or"
+ print bold("system")+" targets."
+ print
+ return 0
+ else:
+ global_unmerge=1
+
+ localtree=portage.db[portage.root]["vartree"]
+ # process all arguments and add all valid db entries to candidate_catpkgs
+ if global_unmerge:
+ if not unmerge_files or "world" in unmerge_files:
+ candidate_catpkgs.extend(localtree.getallnodes())
+ elif "system" in unmerge_files:
+ candidate_catpkgs.extend(getlist("system"))
+ else:
+ #we've got command-line arguments
+ if not unmerge_files:
+ print "\nNo packages to unmerge have been provided.\n"
+ return 0
+ for x in unmerge_files:
+ arg_parts=x.split('/')
+ if (x[0] not in [".","/"]) and (arg_parts[-1][-7:] != ".ebuild"):
+ #possible cat/pkg or dep; treat as such
+ candidate_catpkgs.append(x)
+ elif unmerge_action in ["prune","clean"]:
+ print "\n!!! Prune and clean do not accept individual ebuilds as arguments;\n skipping.\n"
+ continue
+ else:
+ # it appears that the user is specifying an installed ebuild and we're in "unmerge" mode, so it's
+ # ok.
+ if not os.path.exists(x):
+ print "\n!!! The path '"+x+"' doesn't exist.\n"
+ return 0
+
+ absx = os.path.abspath(x)
+ sp_absx = absx.split("/")
+ if sp_absx[-1][-7:] == ".ebuild":
+ del sp_absx[-1]
+ absx = string.join(sp_absx,"/")
+
+ sp_absx_len = len(sp_absx)
+
+ vdb_path = portage.root+portage.VDB_PATH
+ vdb_len = len(vdb_path)
+
+ sp_vdb = vdb_path.split("/")
+ sp_vdb_len = len(sp_vdb)
+
+ if not os.path.exists(absx+"/CONTENTS"):
+ print "!!! Not a valid db dir: "+str(absx)
+ return 0
+
+ if sp_absx_len <= sp_vdb_len:
+ # The Path is shorter... so it can't be inside the vdb.
+ print spabsx
+ print absx
+ print "\n!!!",x,"cannot be inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
+ return 0
+
+ for idx in range(0,sp_vdb_len):
+ if (idx >= sp_absx_len) or (sp_vdb[idx] != sp_absx[idx]):
+ print sp_absx
+ print absx
+ print "\n!!!",x,"is not inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
+ return 0
+
+ print "="+string.join(sp_absx[sp_vdb_len:],"/")
+ candidate_catpkgs.append("="+string.join(sp_absx[sp_vdb_len:],"/"))
+
+ if ("--pretend" in myopts) or ("--ask" in myopts):
+ print darkgreen("\n>>> These are the packages that I would unmerge:")
+
+ pkgmap={}
+ numselected=0
+ for x in candidate_catpkgs:
+ #cycle through all our candidate deps and determine what will and will not get unmerged
+ try:
+ mymatch=localtree.dep_match(x)
+ except KeyError:
+ mymatch=None
+ except ValueError, errpkgs:
+ print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
+ print "!!! one of the following fully-qualified ebuild names instead:\n"
+ for i in errpkgs[0]:
+ print " " + green(i)
+ print
+ sys.exit(1)
+
+ if not mymatch and x[0] not in "<>=~":
+ #add a "=" if missing
+ mymatch=localtree.dep_match("="+x)
+ if not mymatch:
+ print "\n--- Couldn't find " + white(x) + " to "+unmerge_action+"."
+ continue
+ mykey=portage.key_expand(portage.dep_getkey(mymatch[0]),portage.db["/"]["vartree"].dbapi)
+ if not pkgmap.has_key(mykey):
+ pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
+ if unmerge_action=="unmerge":
+ for y in mymatch:
+ if y not in pkgmap[mykey]["selected"]:
+ pkgmap[mykey]["selected"].append(y)
+ numselected=numselected+len(mymatch)
+
+ else:
+ #unmerge_action in ["prune", clean"]
+ slotmap={}
+ for mypkg in mymatch:
+ if unmerge_action=="clean":
+ myslot=localtree.getslot(mypkg)
+ else:
+ #since we're pruning, we don't care about slots and put all the pkgs in together
+ myslot=0
+ if not slotmap.has_key(myslot):
+ slotmap[myslot]={}
+ slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg
+ for myslot in slotmap.keys():
+ counterkeys=slotmap[myslot].keys()
+ counterkeys.sort()
+ if not counterkeys:
+ continue
+ counterkeys.sort()
+ pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
+ del counterkeys[-1]
+ #be pretty and get them in order of merge:
+ for ckey in counterkeys:
+ pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
+ numselected=numselected+1
+ #ok, now the last-merged package is protected, and the rest are selected
+ if global_unmerge and not numselected:
+ print "\n>>> No outdated packages were found on your system.\n"
+ return 0
+
+ if not numselected:
+ print "\n>>>",unmerge_action+": No packages selected for removal.\n"
+ return 0
+
+ for x in pkgmap.keys():
+ for y in localtree.dep_match(x):
+ if y not in pkgmap[x]["omitted"] and \
+ y not in pkgmap[x]["selected"] and \
+ y not in pkgmap[x]["protected"]:
+ pkgmap[x]["omitted"].append(y)
+ if global_unmerge and not pkgmap[x]["selected"]:
+ #avoid cluttering the preview printout with stuff that isn't getting unmerged
+ continue
+ if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
+ print red("\a\n\n!!! '%s' is part of your system profile. '%s'" % (mykey))
+ print yellow("\a!!! Unmerging it may be damaging to your system.\n")
+ if "--pretend" not in myopts and "--ask" not in myopts:
+ global EMERGE_WARNING_DELAY
+ countdown(EMERGE_WARNING_DELAY,red("Press Ctrl-C to Stop"))
+ print "\n "+white(x)
+ for mytype in ["selected","protected","omitted"]:
+ print string.rjust(mytype,12)+":",
+ if pkgmap[x][mytype]:
+ for mypkg in pkgmap[x][mytype]:
+ mysplit=portage.catpkgsplit(mypkg)
+ if mysplit[3]=="r0":
+ myversion=mysplit[2]
+ else:
+ myversion=mysplit[2]+"-"+mysplit[3]
+ if mytype=="selected":
+ print red(myversion),
+ else:
+ print green(myversion),
+ else:
+ print "none",
+ print
+
+ print "\n>>>",red("'Selected'"),"packages are slated for removal."
+ print ">>>",green("'Protected'"),"and",green("'omitted'"),"packages will not be removed.\n"
+
+ if "--pretend" in myopts:
+ #we're done... return
+ return 0
+ if "--ask" in myopts:
+ if userquery("Do you want me to unmerge these packages?")=="No":
+ # enter pretend mode for correct formatting of results
+ myopts+=["--pretend"]
+ print
+ print "Quitting."
+ print
+ return 0
+ #the real unmerging begins, after a short delay....
+
+ global CLEAN_DELAY
+ countdown(CLEAN_DELAY, ">>> Unmerging")
+
+ for x in pkgmap.keys():
+ for y in pkgmap[x]["selected"]:
+ print ">>> Unmerging "+y+"..."
+ emergelog("=== Unmerging... ("+y+")")
+ mysplit=string.split(y,"/")
+ #unmerge...
+ retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,mysettings,unmerge_action not in ["clean","prune"])
+ if retval:
+ emergelog(" !!! unmerge FAILURE: "+y)
+ else:
+ emergelog(" >>> unmerge success: "+y)
+ #run ldconfig, etc...
+ portage.env_update()
+ if not numselected:
+ return 0
+ else:
+ return 1
+
+
+def chk_updated_info_files(retval):
+ root=portage.root
+
+ infodirs=[]
+ infodirs.extend(string.split(portage.settings["INFOPATH"], ":"))
+ infodirs.extend(string.split(portage.settings["INFODIR"], ":"))
+
+ print
+ if os.path.exists("/usr/bin/install-info"):
+ regen_infodirs=[]
+ for z in infodirs:
+ if z=='':
+ continue
+ inforoot=normpath(root+z)
+ if os.path.isdir(inforoot):
+ try:
+ infomtime=os.stat(inforoot)[ST_MTIME]
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ infomtime=0
+
+ if not portage.mtimedb.has_key("info"):
+ portage.mtimedb["info"]={}
+ if portage.mtimedb["info"].has_key(inforoot):
+ if portage.mtimedb["info"][inforoot]==infomtime:
+ pass
+ else:
+ portage.mtimedb["info"][inforoot]=infomtime
+ regen_infodirs.append(inforoot)
+ else:
+ regen_infodirs.append(inforoot)
+
+ if not regen_infodirs:
+ print " "+green("*")+" GNU info directory index is up-to-date."
+ else:
+ print " "+green("*")+" Regenerating GNU info directory index..."
+
+ icount=0
+ badcount=0
+ for inforoot in regen_infodirs:
+ if inforoot=='':
+ continue
+ try:
+ os.rename(inforoot+"/dir",inforoot+"/dir.old")
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ if not os.path.isdir(inforoot):
+ continue
+ errmsg = ""
+ for x in os.listdir(inforoot):
+ if (x[0] == ".") or (x in ["dir","dir.old"]) or (os.path.isdir(inforoot+"/"+x)):
+ continue
+ myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1]
+ existsstr="already exists, for file `"
+ if myso!="":
+ if re.search(existsstr,myso):
+ # Already exists... Don't increment the count for this.
+ pass
+ elif myso[:44]=="install-info: warning: no info dir entry in ":
+ # This info file doesn't contain a DIR-header: install-info produces this
+ # (harmless) warning (the --quiet switch doesn't seem to work).
+ # Don't increment the count for this.
+ pass
+ else:
+ badcount=badcount+1
+ errmsg += myso + "\n"
+ icount=icount+1
+
+ #update mtime so we can potentially avoid regenerating.
+ portage.mtimedb["info"][inforoot]=os.stat(inforoot)[ST_MTIME]
+
+ if badcount:
+ print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
+ print errmsg
+ else:
+ print " "+green("*")+" Processed",icount,"info files."
+
+
+def post_emerge(retval=0):
+ global myopts
+ os.chdir("/")
+ if "--pretend" in myopts:
+ sys.exit(retval)
+
+ emergelog(" *** exiting successfully.")
+
+ if "noinfo" not in portage.settings.features:
+ chk_updated_info_files(retval)
+
+ chk_updated_cfg_files()
+ sys.exit(retval)
+
+
+def chk_updated_cfg_files():
+ if portage.settings["CONFIG_PROTECT"]:
+ #number of directories with some protect files in them
+ procount=0
+ for x in string.split(portage.settings["CONFIG_PROTECT"]):
+ if os.path.isdir(x):
+ a=commands.getstatusoutput("cd "+x+"; find . -iname '._cfg????_*'")
+ if a[0]!=0:
+ print " "+red("*")+" error scanning",x
+ else:
+ files=string.split(a[1])
+ if files:
+ procount=procount+1
+ print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating."
+ if procount:
+ #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
+ print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
+ print
+
+# general options that should be taken into account before any action
+if "--debug" in myopts:
+ edebug=1
+
+if myaction in ["sync","rsync","metadata"] and (not "--help" in myopts):
+ if "--pretend" in myopts:
+ print "emerge: \"sync\" actions do not support \"--pretend.\""
+ sys.exit(1)
+
+ emergelog(" === "+str(myaction))
+ myportdir=portage.settings["PORTDIR"]
+ if myportdir[-1]=="/":
+ myportdir=myportdir[:-1]
+ if not os.path.exists(myportdir):
+ print ">>>",myportdir,"not found, creating it."
+ os.makedirs(myportdir,0755)
+ syncuri=string.rstrip(portage.settings["SYNC"])
+ os.umask(0022)
+ if myaction == "metadata":
+ if "--ask" in myopts:
+ if userquery("Are you sure?") == "No":
+ sys.exit(1)
+ print "skipping sync"
+ updatecache_flg = True
+ tmpservertimestampfile = None
+ elif syncuri[:8]=="rsync://":
+ if not os.path.exists("/usr/bin/rsync"):
+ print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
+ print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
+ sys.exit(1)
+ mytimeout=180
+ if portage.settings.has_key("RSYNC_TIMEOUT"):
+ try:
+ mytimeout=int(portage.settings["RSYNC_TIMEOUT"])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ rsync_flags = [
+ "--recursive", # Recurse directories
+ "--links", # Consider symlinks
+ "--safe-links", # Ignore links outside of tree
+ "--perms", # Preserve permissions
+ "--times", # Preserive mod times
+ "--compress", # Compress the data transmitted
+ "--force", # Force deletion on non-empty dirs
+ "--whole-file", # Don't do block transfers, only entire files
+ "--delete", # Delete files that aren't in the master tree
+ "--delete-after", # Delete only after everything else is done
+ "--stats", # Show final statistics about what was transfered
+ "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
+ "--exclude='/distfiles'", # Exclude distfiles from consideration
+ "--exclude='/local'", # Exclude local from consideration
+ "--exclude='/packages'", # Exclude packages from consideration
+ ]
+
+ if "--quiet" in myopts:
+ rsync_flags.append("--quiet") # Shut up a lot
+ else:
+ rsync_flags.append("--progress") # Progress meter for each file
+
+ if "--verbose" in myopts:
+ rsync_flags.append("--verbose") # More noise? Not really sure what
+
+ if "--debug" in myopts:
+ rsync_flags.append("--checksum") # Force checksum on all files
+
+ if portage.settings.has_key("RSYNC_EXCLUDEFROM"):
+ if os.path.exists(portage.settings["RSYNC_EXCLUDEFROM"]):
+ rsync_flags.append("--exclude-from="+portage.settings["RSYNC_EXCLUDEFROM"])
+ else:
+ print "!!! RSYNC_EXCLUDEFROM specified, but file does not exist."
+
+ if portage.settings.has_key("RSYNC_RATELIMIT"):
+ rsync_flags.append("--bwlimit="+portage.settings["RSYNC_RATELIMIT"])
+
+ rsynccommand = "/usr/bin/rsync " + string.join(rsync_flags, " ")
+
+ servertimestampdir = portage.settings.depcachedir+"/"
+ servertimestampfile = portage.settings.depcachedir+"/timestamp.chk"
+ tmpservertimestampdir = portage.settings["PORTAGE_TMPDIR"]+"/"
+ tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk"
+
+ # We only use the backup if a timestamp exists in the portdir.
+ content=None
+ if os.path.exists(myportdir+"/metadata/timestamp.chk"):
+ content=portage.grabfile(servertimestampfile)
+ if (not content):
+ content=portage.grabfile(myportdir+"/metadata/timestamp.chk")
+
+ if (content):
+ try:
+ mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000"))
+ except ValueError:
+ mytimestamp=0
+ else:
+ mytimestamp=0
+
+ if not os.path.exists(servertimestampdir):
+ os.mkdir(servertimestampdir)
+ os.chown(servertimestampdir, os.getuid(), portage.portage_gid)
+ os.chmod(servertimestampdir, 02775)
+
+ #exitcode=0
+ try:
+ maxretries=int(portage.settings["RSYNC_RETRIES"])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ maxretries=3 #default number of retries
+
+ retries=0
+ hostname, port=re.split("rsync://([^:/]*)(:[0-9]+)?", syncuri)[1:3];
+ if port==None:
+ port=""
+ updatecache_flg=True
+
+ ips=[]
+ while (1):
+ if ips:
+ del ips[0]
+ if ips==[]:
+ try:
+ ips=socket.gethostbyname_ex(hostname)[2]
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Notice:",str(e)
+ dosyncuri=syncuri
+
+ if ips:
+ try:
+ dosyncuri=string.replace(syncuri, "//"+hostname+port+"/", "//"+ips[0]+port+"/", 1)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Notice:",str(e)
+ dosyncuri=syncuri
+
+ if (retries==0):
+ if "--ask" in myopts:
+ if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ emergelog(">>> starting rsync with "+dosyncuri)
+ if "--quiet" not in myopts:
+ print ">>> starting rsync with "+dosyncuri+"..."
+ else:
+ emergelog(">>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri))
+ print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
+
+ if "--quiet" not in myopts:
+ print ">>> checking server timestamp ..."
+ mycommand=rsynccommand+" "+dosyncuri+"/metadata/timestamp.chk "+tmpservertimestampdir
+ exitcode=portage.spawn(mycommand,portage.settings,free=1)
+ if (exitcode==0):
+ try:
+ servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000"))
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ servertimestamp = 0
+
+ if (servertimestamp != 0) and (servertimestamp == mytimestamp):
+ emergelog(">>> Cancelling sync -- Already current.")
+ print
+ print ">>>"
+ print ">>> Timestamps on the server and in the local repository are the same."
+ print ">>> Cancelling all further sync action. You are already up to date."
+ print ">>>"
+ print
+ sys.exit(0)
+ elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
+ emergelog(">>> Server out of date: %s" % dosyncuri)
+ print
+ print ">>>"
+ print ">>> SERVER OUT OF DATE: %s" % dosyncuri
+ print ">>>"
+ print
+ elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
+ # actual sync
+ mycommand=rsynccommand+" "+dosyncuri+"/ "+myportdir
+ exitcode=portage.spawn(mycommand,portage.settings,free=1)
+ if exitcode in [0,1,2,3,4,11,14,20,21]:
+ break
+ elif exitcode in [0,1,2,3,4,11,14,20,21]:
+ break
+
+ retries=retries+1
+
+ if retries<=maxretries:
+ print ">>> retry ..."
+ time.sleep(11)
+ else:
+ # over retries
+ # exit loop
+ updatecache_flg=False
+ break
+
+ if (exitcode==0):
+ emergelog("=== Sync completed with %s" % dosyncuri)
+ elif (exitcode>0):
+ print
+ if exitcode==1:
+ print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure")
+ print darkred("!!!")+green(" that your SYNC statement is proper.")
+ print darkred("!!!")+green(" SYNC="+portage.settings["SYNC"])
+ elif exitcode==11:
+ print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally")
+ print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption")
+ print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate")
+ print darkred("!!!")+green(" and try again after the problem has been fixed.")
+ print darkred("!!!")+green(" PORTDIR="+portage.settings["PORTDIR"])
+ elif exitcode==20:
+ print darkred("!!!")+green(" Rsync was killed before it finished.")
+ else:
+ print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep")
+ print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable")
+ print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a")
+ print darkred("!!!")+green(" temporary problem unless complications exist with your network")
+ print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.")
+ print
+ sys.exit(exitcode)
+ elif syncuri[:6]=="cvs://":
+ if not os.path.exists("/usr/bin/cvs"):
+ print "!!! /usr/bin/cvs does not exist, so rsync support is disabled."
+ print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
+ sys.exit(1)
+ cvsroot=syncuri[6:]
+ cvsdir=os.path.dirname(myportdir)
+ if not os.path.exists(myportdir+"/CVS"):
+ #initial checkout
+ print ">>> starting initial cvs checkout with "+syncuri+"..."
+ if not portage.spawn("cd "+cvsdir+"; cvs -d "+cvsroot+" login",portage.settings,free=1):
+ print "!!! cvs login error; exiting."
+ sys.exit(1)
+ if os.path.exists(cvsdir+"/gentoo-x86"):
+ print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
+ sys.exit(1)
+ if not portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",portage.settings,free=1):
+ print "!!! cvs checkout error; exiting."
+ sys.exit(1)
+ if cvsdir!=myportdir:
+ portage.movefile(cvsdir,portage.settings["PORTDIR"])
+ sys.exit(0)
+ else:
+ #cvs update
+ print ">>> starting cvs update with "+syncuri+"..."
+ sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",portage.settings,free=1))
+ else:
+ print "!!! rsync setting: ",syncuri,"not recognized; exiting."
+ sys.exit(1)
+
+ try: # Prevent users from affecting ebuild.sh.
+ os.close(sys.stdin.fileno())
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
+ if "--quiet" not in myopts:
+ print "\n>>> Updating Portage cache: ",
+ os.umask(0002)
+ cachedir = os.path.normpath(portage.settings.depcachedir)
+ if cachedir in ["/", "/bin", "/dev", "/etc", "/home",
+ "/lib", "/opt", "/proc", "/root", "/sbin",
+ "/sys", "/tmp", "/usr", "/var"]:
+ print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM."
+ print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir)
+ sys.exit(73)
+ if not os.path.exists(cachedir):
+ os.mkdir(cachedir)
+
+ # Potentially bad
+ #if os.path.exists(cachedir+"/"+myportdir):
+ # portage.spawn("rm -Rf "+cachedir+"/"+myportdir+"/*",portage.settings,free=1)
+
+ # save timestamp.chk for next timestamp check.
+ try:
+ if tmpservertimestampfile != None:
+ portage.movefile(tmpservertimestampfile, servertimestampfile)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "!!! Failed to save current timestamp."
+ print "!!!",e
+
+ portage.portdb.flush_cache()
+
+ try:
+ os.umask(002)
+ os.chown(cachedir, os.getuid(), portage.portage_gid)
+ os.chmod(cachedir, 02775)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ # we don't make overlay trees cache here, plus we don't trust portage.settings.categories
+ porttree_root = portage.portdb.porttree_root
+ pdb = portage.portdbapi(porttree_root, portage.config(config_profile_path=portage.settings.profile_path[:], \
+ config_incrementals=portage.settings.incrementals[:]))
+ cp_list = pdb.cp_all()
+ if len(cp_list) == 0:
+ print "no metadata to transfer, exiting"
+ sys.exit(0)
+ cp_list.sort()
+ pcnt=0
+ pcntstr=""
+ pcntcount=len(cp_list)/100.0
+ nextupdate=pcntcount
+ current=1
+
+ def cleanse_cache(pdb, cat, saves, porttree_root=porttree_root):
+ if len(saves):
+ d={}
+ for v in saves:
+ d[portage.catsplit(v)[1]] = True
+ for pv in pdb.auxdb[porttree_root][cat].keys():
+ if pv not in d:
+ pdb.auxdb[porttree_root][cat].del_key(pv)
+ else:
+ try:
+ pdb.auxdb[porttree_root][cat].clear()
+ del pdb.auxdb[porttree_root][cat]
+ except KeyError:
+ pass
+
+ savelist = []
+ catlist = []
+ oldcat = portage.catsplit(cp_list[0])[0]
+ for cp in cp_list:
+ current += 1
+ if current >= nextupdate:
+ pcnt += 1
+ nextupdate += pcntcount
+ if "--quiet" not in myopts:
+ pcntstr = str(pcnt)
+ sys.stdout.write("\b"*(len(pcntstr)+1)+pcntstr+"%")
+ sys.stdout.flush()
+ cat = portage.catsplit(cp)[0]
+ if cat != oldcat:
+ catlist.append(oldcat)
+ cleanse_cache(pdb, oldcat, savelist)
+ savelist = []
+ oldcat = cat
+ mymatches = pdb.xmatch("match-all", cp)
+ savelist.extend(mymatches)
+ for cpv in mymatches:
+ try: pdb.aux_get(cpv, ["IUSE"],metacachedir=myportdir+"/metadata/cache",debug=("cachedebug" in portage.features))
+ except SystemExit: raise
+ except Exception, e: print "\nFailed cache update:",cpv,e
+ catlist.append(oldcat)
+ catlist.append("local")
+ cleanse_cache(pdb, oldcat, savelist)
+ filelist = portage.listdir(cachedir+"/"+myportdir)
+ for x in filelist:
+ found = False
+ for y in catlist:
+ if x.startswith(y):
+ found = True
+ break
+ if not found:
+ portage.spawn("cd /; rm -Rf "+cachedir+"/"+myportdir+"/"+x,portage.settings,free=1,droppriv=1)
+
+
+ sys.stdout.write("\n\n")
+ sys.stdout.flush()
+
+ portage.portageexit()
+ reload(portage)
+ mybestpv=portage.portdb.xmatch("bestmatch-visible","sys-apps/portage")
+ mypvs=portage.best(portage.db[portage.root]["vartree"].dbapi.match("sys-apps/portage"))
+
+ chk_updated_cfg_files()
+
+ if(mybestpv != mypvs):
+ print
+ print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
+ print red(" * ")+"that you update portage now, before any other packages are updated."
+ print red(" * ")+"Please do so and then update "+bold("ALL")+" of your configuration files."
+ print
+elif myaction=="regen":
+ emergelog(" === regen")
+ #regenerate cache entries
+ print "Regenerating cache entries... "
+ try:
+ os.close(sys.stdin.fileno())
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ sys.stdout.flush()
+ mynodes=portage.portdb.cp_all()
+ for x in mynodes:
+ mymatches=portage.portdb.xmatch("match-all",x)
+ if not "--quiet" in myopts:
+ print "processing",x
+ for y in mymatches:
+ try:
+ foo=portage.portdb.aux_get(y,["DEPEND"],debug=1)
+ except SystemExit, e:
+ # sys.exit is an exception... And consequently, we can't catch it.
+ raise
+ except Exception, e:
+ print "\n error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
+ print "done!"
+# HELP action
+elif "config"==myaction:
+ if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
+ print red("!!! config can only take a single package atom at this time\n")
+ sys.exit(1)
+
+ print
+ pkgs = portage.db[portage.root]["vartree"].dbapi.match(myfiles[0])
+ if len(pkgs) == 0:
+ print "No packages found.\n"
+ sys.exit(0)
+ elif len(pkgs) > 1:
+ if "--ask" in myopts:
+ options = []
+ print "Please select a package to configure:"
+ idx = 0
+ for pkg in pkgs:
+ idx += 1
+ options.append(str(idx))
+ print options[-1]+") "+pkg
+ print "X) Cancel"
+ options.append("X")
+ idx = userquery("Selection?", options)
+ if idx == "X":
+ sys.exit(0)
+ pkg = pkgs[int(idx)-1]
+ else:
+ print "The following packages available:"
+ for pkg in pkgs:
+ print "* "+pkg
+ print "\nPlease use a specific atom or the --ask option."
+ sys.exit(1)
+ else:
+ pkg = pkgs[0]
+
+ print
+ if "--ask" in myopts:
+ if userquery("Ready to configure "+pkg+"?") == "No":
+ sys.exit(0)
+ else:
+ print "Configuring pkg..."
+ print
+ ebuildpath = portage.db[portage.root]["vartree"].dbapi.findname(pkg)
+ mysettings = portage.config(clone=portage.settings)
+ portage.doebuild(ebuildpath,"config",portage.root,mysettings,debug=("--debug" in myopts),cleanup=True)
+ print
+
+# INFO action
+elif "info"==myaction:
+ unameout=commands.getstatusoutput("uname -mrp")[1]
+ print getportageversion()
+ print "================================================================="
+ print "System uname: "+unameout
+ if os.path.exists("/etc/gentoo-release"):
+ os.system("cat /etc/gentoo-release")
+ else:
+ print "Unknown Host Operating System"
+
+ output=commands.getstatusoutput("distcc --version")
+ if not output[0]:
+ print str(string.split(output[1],"\n",1)[0]),
+ if "distcc" in portage.features:
+ print "[enabled]"
+ else:
+ print "[disabled]"
+
+ output=commands.getstatusoutput("ccache -V")
+ if not output[0]:
+ print str(string.split(output[1],"\n",1)[0]),
+ if "ccache" in portage.features:
+ print "[enabled]"
+ else:
+ print "[disabled]"
+
+ myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
+ "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"]
+ myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs")
+ myvars = portage_util.unique_array(myvars)
+ myvars.sort()
+
+ for x in myvars:
+ if portage.isvalidatom(x):
+ pkg_matches = portage.db["/"]["vartree"].dbapi.match(x)
+ pkgs = []
+ for y in pkg_matches:
+ mycpv = portage.catpkgsplit(y)
+ if(mycpv[3] != "r0"):
+ pkgs += [mycpv[2] + "-" + mycpv[3]]
+ else:
+ pkgs += [mycpv[2]]
+ if not pkgs:
+ pkgs = "[Not Present]"
+ else:
+ pkgs = ", ".join(sorted_versions(pkgs))
+ print "%-20s %s" % (x+":", pkgs)
+ else:
+ print "%-20s %s" % (x+":", "[NOT VALID]")
+
+ libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",")
+
+ if "--verbose" in myopts:
+ myvars=portage.settings.keys()
+ else:
+ myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
+ 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
+ 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
+ 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES']
+
+ myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars"))
+
+ myvars = portage_util.unique_array(myvars)
+ unset_vars = []
+ myvars.sort()
+ for x in myvars:
+ if portage.settings.has_key(x):
+ print x+'="'+portage.settings[x]+'"'
+ else:
+ unset_vars.append(x)
+ if unset_vars:
+ print "Unset: "+", ".join(unset_vars)
+ print
+
+ if "--debug" in myopts:
+ for x in dir(portage):
+ module = getattr(portage, x)
+ if "cvs_id_string" in dir(module):
+ print "%s: %s" % (str(x), str(module.cvs_id_string))
+
+# SEARCH action
+elif "search"==myaction:
+ if not myfiles:
+ print "emerge: no search terms provided."
+ else:
+ searchinstance = search()
+ for mysearch in myfiles:
+ try:
+ searchinstance.execute(mysearch)
+ except re.error, comment:
+ print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
+ sys.exit(1)
+ searchinstance.output()
+elif "inject"==myaction:
+ if not myfiles:
+ print "emerge: please specify at least one cat/pkg-ver to inject."
+ sys.exit(1)
+ if "--pretend" in myopts:
+ print "emerge: the \"inject\" action does not support \"--pretend.\""
+ sys.exit(1)
+ for x in myfiles:
+ if x[0] in [">","<","=","!"]:
+ print "!!! '"+x+"' is an invalid specification."
+ print "!!! Must be 'category/package-version' with no other symbols."
+ print
+ continue
+ mycps=portage.catpkgsplit(x)
+ if (not mycps) or (mycps[0]=="null"):
+ print "!!!",x,"is not a specific cat/pkg-version, skipping..."
+ continue
+ if portage.db["/"]["vartree"].exists_specific(x):
+ print "!!! Not injecting",x+"; Package already exists."
+ else:
+ if "--ask" in myopts:
+ if userquery("Do you want to inject the package %s?" % x)=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ portage.db["/"]["vartree"].dbapi.cpv_inject(x)
+ print ">>> Injected",x+"."
+ emergelog(" === inject: "+x)
+elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
+ if 1==unmerge(myaction, myfiles):
+ post_emerge()
+
+elif "depclean"==myaction:
+ # Kill packages that aren't explicitly merged or are required as a
+ # dependency of another package. World file is explicit.
+
+ print
+ print red("*** WARNING ***")+" : DEPCLEAN CAN SERIOUSLY IMPAIR YOUR SYSTEM. USE CAUTION."
+ print red("*** WARNING ***")+" : (Cancel: CONTROL-C) -- ALWAYS VERIFY ALL PACKAGES IN THE"
+ print red("*** WARNING ***")+" : CANDIDATE LIST FOR SANITY BEFORE ALLOWING DEPCLEAN TO"
+ print red("*** WARNING ***")+" : UNMERGE ANY PACKAGES."
+ print red("*** WARNING ***")+" :"
+ print red("*** WARNING ***")+" : USE FLAGS MAY HAVE AN EXTREME EFFECT ON THE OUTPUT."
+ print red("*** WARNING ***")+" : SOME LIBRARIES MAY BE USED BY PACKAGES BUT ARE NOT"
+ print red("*** WARNING ***")+" : CONSIDERED TO BE A DEPEND DUE TO USE FLAG SETTINGS."
+ print red("*** WARNING ***")+" : emerge --update --deep --newuse world TO VERIFY"
+ print red("*** WARNING ***")+" : SANITY IN THIS REGARD."
+ print red("*** WARNING ***")+" :"
+ print red("*** WARNING ***")+" : Packages in the list that are desired may be added"
+ print red("*** WARNING ***")+" : directly to the world file to cause them to be ignored"
+ print red("*** WARNING ***")+" : by depclean and maintained in the future. BREAKAGES DUE"
+ print red("*** WARNING ***")+" : TO UNMERGING AN ==IN-USE LIBRARY== MAY BE REPAIRED BY"
+ print red("*** WARNING ***")+" : MERGING *** THE PACKAGE THAT COMPLAINS *** ABOUT THE"
+ print red("*** WARNING ***")+" : MISSING LIBRARY."
+ print
+ if ("--pretend" not in myopts) and ("--ask" not in myopts):
+ countdown(EMERGE_WARNING_DELAY, ">>> Depclean")
+ emergelog(" >>> depclean")
+
+ mydepgraph=depgraph(myaction,myopts)
+ syslist=getlist("system")
+ worldlist=getlist("world")
+
+ print "Calculating",myaction,"dependencies ",
+ if not mydepgraph.xcreate("world"):
+ print "\n!!! Failed to create deptree."
+ sys.exit(1)
+ print "\b\b ... done!"
+
+ if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
+ sys.stderr.write(red("The following binaries are not available for merging...\n"))
+ for x in mydepgraph.missingbins:
+ sys.stderr.write(" "+str(x)+"\n")
+ sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
+ sys.exit(1)
+
+ alldeps=mydepgraph.digraph.allnodes()
+ myvarlist=portage.vardbapi(portage.root).cp_all()
+
+ if not syslist:
+ print "!!! You have no system list. Cannot determine system from world."
+ if not worldlist:
+ print "!!! You have no world file. Cannot determine explicit merges."
+ if not myvarlist:
+ print "!!! You have no installed package tree (%s). This is a problem." % portage.VDB_PATH
+ if not alldeps:
+ print "!!! You have no dependencies. Impossible. Bug."
+
+ if not (syslist and worldlist and myvarlist and alldeps):
+ print
+ sys.exit(1)
+
+ reallist=[]
+ for x in alldeps:
+ myparts=portage.catpkgsplit(string.split(x)[2])
+ if not myparts:
+ sys.stderr.write(
+ red("!!! There appears to be a problem with the following package:\n")+
+ red("!!! "+str(string.split(x)[2])+"\n\n")+
+ "!!! Please ensure that blocking/conflicting packages are not merged."+
+ "!!! 'emerge -p "+str(string.split(x)[2])+"\n\n")
+ if ("--pretend" not in myopts) and ("--ask" not in myopts):
+ countdown(EMERGE_WARNING_DELAY, "*** Continuing")
+ continue
+
+ catpack=myparts[0]+"/"+myparts[1]
+ if catpack not in reallist:
+ reallist.append(catpack)
+
+ cleanlist=[]
+ for x in myvarlist:
+ if x not in reallist:
+ if x not in cleanlist:
+ cleanlist.append(x)
+
+ for x in syslist+worldlist:
+ myparts = portage.catpkgsplit(x)
+ if myparts:
+ if myparts[0][0] in ('<','>','='):
+ myparts[0] = myparts[0][1:]
+ if myparts[0][0] in ('<','>','='):
+ myparts[0] = myparts[0][1:]
+ catpack=myparts[0]+"/"+myparts[1]
+ else:
+ catpack=x
+ if catpack in cleanlist:
+ cleanlist.remove(catpack)
+
+ #print "\n\n\nCleaning: "
+ #for x in cleanlist:
+ # print x
+ #print
+
+ if len(cleanlist):
+ unmerge("unmerge", cleanlist)
+
+ print
+ print "Packages installed: "+str(len(myvarlist))
+ print "Packages in world: "+str(len(worldlist))
+ print "Packages in system: "+str(len(syslist))
+ print "Unique package names: "+str(len(reallist))
+ print "Required packages: "+str(len(alldeps))
+ if "--pretend" in myopts:
+ print "Number to remove: "+str(len(cleanlist))
+ else:
+ print "Number removed: "+str(len(cleanlist))
+ post_emerge()
+
+# "update", "system", or just process files:
+else:
+ favorites=[]
+ syslist=getlist("system")
+ if (("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts)) or ("--ask" in myopts):
+ if "--tree" in myopts:
+ print
+ print darkgreen("These are the packages that I would merge, in reverse order:")
+ print
+ else:
+ print
+ print darkgreen("These are the packages that I would merge, in order:")
+ print
+
+ if ("--resume" in myopts) and portage.mtimedb.has_key("resume"):
+ myresumeopts=portage.mtimedb["resume"]["myopts"][:]
+
+ while "--skipfirst" in myresumeopts:
+ myresumeopts.remove("--skipfirst")
+ while "--ask" in myresumeopts:
+ myresumeopts.remove("--ask")
+
+ for myopt in myopts:
+ if myopt not in myresumeopts:
+ myresumeopts.append(myopt)
+ myopts=myresumeopts
+ mydepgraph=depgraph("resume",myopts)
+ if "--resume" not in myopts:
+ myopts+=["--resume"]
+ else:
+ if ("--resume" in myopts):
+ del myopts[myopts.index("--resume")]
+ print darkgreen("emerge: It seems we have nothing to resume...")
+ sys.exit(0)
+
+ mydepgraph=depgraph(myaction,myopts)
+ if myaction in ["system","world"]:
+ print "Calculating",myaction,"dependencies ",
+ sys.stdout.flush()
+ if not mydepgraph.xcreate(myaction):
+ print "!!! Depgraph creation failed."
+ sys.exit(1)
+ print "\b\b ...done!"
+ else:
+ if not myfiles:
+ print "emerge: please tell me what to do."
+ help()
+ sys.exit(1)
+ #we don't have any files to process; skip this step and exit
+ print "Calculating dependencies ",
+ sys.stdout.flush()
+ retval,favorites=mydepgraph.select_files(myfiles)
+ if not retval:
+ sys.exit(1)
+ print "\b\b ...done!"
+
+ if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
+ sys.stderr.write(red("The following binaries are not available for merging...\n"))
+
+ if mydepgraph.missingbins:
+ for x in mydepgraph.missingbins:
+ sys.stderr.write(" "+str(x)+"\n")
+ sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
+ sys.exit(1)
+
+ if "--ask" in myopts:
+ if "--resume" in myopts:
+ mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
+ prompt="Do you want me to resume merging these packages?"
+ else:
+ mydepgraph.display(mydepgraph.altlist())
+ mergecount=0
+ for x in mydepgraph.altlist():
+ if x[3]!="nomerge":
+ mergecount+=1
+ #check for blocking dependencies
+ if x[0]=="blocks":
+ print "\n!!! Error: The above package list contains packages which cannot be installed"
+ print "!!! on the same system."
+ print
+ sys.exit(1)
+ if mergecount==0:
+ if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
+ prompt="Nothing to merge; do you want me to auto-clean packages?"
+ else:
+ print
+ print "Nothing to merge; quitting."
+ print
+ sys.exit(0)
+ elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
+ prompt="Do you want me to fetch the source files for these packages?"
+ else:
+ prompt="Do you want me to merge these packages?"
+ print
+ if userquery(prompt)=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ # Don't ask again (e.g. when auto-cleaning packages after merge)
+ myopts.remove("--ask")
+
+ if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
+ if ("--resume" in myopts):
+ mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
+ else:
+ mydepgraph.display(mydepgraph.altlist())
+ else:
+ if ("--buildpkgonly" in myopts):
+ if not mydepgraph.digraph.hasallzeros():
+ print "\n!!! --buildpkgonly requires all dependencies to be merged."
+ print "!!! Cannot merge requested packages. Merge deps and try again.\n"
+ sys.exit(1)
+
+ if ("--resume" in myopts):
+ favorites=portage.mtimedb["resume"]["favorites"]
+ mydepgraph.merge(portage.mtimedb["resume"]["mergelist"])
+ else:
+ portage.mtimedb["resume"]={}
+ portage.mtimedb["resume"]["myopts"]=myopts
+ portage.mtimedb["resume"]["favorites"]=favorites
+ if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
+ for pkgline in mydepgraph.altlist():
+ if pkgline[0]=="ebuild" and pkgline[3]=="merge":
+ y=portage.portdb.findname(pkgline[2])
+ tmpsettings = portage.config(clone=portage.settings)
+ retval=portage.doebuild(y,"digest",portage.root,tmpsettings,edebug,("--pretend" in myopts))
+ mydepgraph.merge(mydepgraph.altlist())
+
+ if portage.mtimedb.has_key("resume"):
+ del portage.mtimedb["resume"]
+ if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
+ print ">>> Auto-cleaning packages ..."
+ unmerge("clean", ["world"])
+ post_emerge()
diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
new file mode 100755
index 000000000..024af23e8
--- /dev/null
+++ b/bin/emerge-webrsync
@@ -0,0 +1,141 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/Attic/emerge-webrsync,v 1.8.2.4 2005/02/26 11:22:38 carpaski Exp $
+# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
+# Rewritten from the old, Perl-based emerge-webrsync script
+
+GENTOO_MIRRORS="${GENTOO_MIRRORS} $(/usr/lib/portage/bin/portageq gentoo_mirrors)"
+PORTDIR="$(/usr/lib/portage/bin/portageq portdir)"
+FETCHCOMMAND="$(/usr/lib/portage/bin/portageq envvar FETCHCOMMAND)"
+USERLAND="$(/usr/lib/portage/bin/portageq envvar USERLAND)"
+DISTDIR="$(/usr/lib/portage/bin/portageq envvar PORTAGE_TMPDIR)/emerge-webrsync"
+
+if [ ! -d $DISTDIR ] ; then
+ mkdir -p $DISTDIR
+fi
+
+cd "$DISTDIR"
+
+found=0
+if [ "$1" == "-v" ] ; then
+ wgetops=
+else
+ #this sucks. probably better to do 1> /dev/null
+ #that said, waiting on the refactoring.
+ if [ "${FETCHCOMMAND/wget}" != "${FETCHCOMMAND}" ]; then
+ wgetops="-q"
+ elif [ "${FETCHCOMMAND/curl}" != "${FETCHCOMMAND}" ]; then
+ wgetops="-s -f"
+ fi
+fi
+
+if type -p md5sum > /dev/null; then
+ md5_com='md5sum -c "${FILE}.md5sum"'
+elif type -p md5 > /dev/null; then
+ md5_com='[ "$(md5 -q ${FILE})" == "$(cut -d \ -f 1 ${FILE}.md5sum)" ]'
+else
+ echo "warning, unable to do md5 verification of the snapshot!"
+ echo "no suitable md5/md5sum binary was found!"
+ md5_com='true'
+fi
+
+sync_local() {
+ echo Syncing local tree...
+ if ! tar jxf $FILE; then
+ echo "Tar failed to extract the image. Please review the output."
+ echo "Executed command: tar jxf $FILE"
+ exit 1
+ fi
+ rm -f $FILE
+ # Make sure user and group file ownership is root
+ chown -R 0:0 portage
+ cd portage
+ rsync -av --progress --stats --delete --delete-after \
+ --exclude='/distfiles' --exclude='/packages' \
+ --exclude='/local' . ${PORTDIR%%/}
+ cd ..
+ echo "cleaning up"
+ rm -rf portage
+ echo "transferring metadata/cache"
+ emerge metadata
+}
+
+echo "Fetching most recent snapshot"
+
+declare -i attempts=-1
+while (( $attempts < 40 )) ; do
+ attempts=$(( attempts + 1 ))
+
+ #this too, sucks. it works in the interim though.
+ if [ "$USERLAND" == "BSD" ] || [ "$USERLAND" == "Darwin" ] ; then
+ daysbefore=$(expr $(date +"%s") - 86400 \* $attempts)
+ day=$(date -r $daysbefore +"%d")
+ month=$(date -r $daysbefore +"%m")
+ year=$(date -r $daysbefore +"%Y")
+ else
+ day=$(date -d "-$attempts day" +"%d")
+ month=$(date -d "-$attempts day" +"%m")
+ year=$(date -d "-$attempts day" +"%Y")
+ fi
+
+ FILE_ORIG="portage-${year}${month}${day}.tar.bz2"
+
+ echo "Attempting to fetch file dated: ${year}${month}${day}"
+
+ got_md5=0
+
+ if [ ! -e "${FILE_ORIG}.md5sum" ]; then
+ FILE="${FILE_ORIG}.md5sum"
+ for i in $GENTOO_MIRRORS ; do
+ URI="${i}/snapshots/${FILE}"
+ if (eval "$FETCHCOMMAND $wgetops") && [ -s "${FILE}" ]; then
+ got_md5=1
+ break
+ fi
+ done
+ else
+ got_md5=1
+ fi
+ FILE="${FILE_ORIG}"
+
+ if (($got_md5 == 0 )); then
+ echo " --- No md5sum present on the mirror. (Not yet available.)"
+ continue
+ elif [ -s "${FILE}" ]; then
+ if eval "$md5_com"; then
+ echo " === snapshot $FILE is correct, using it"
+ sync_local
+ echo
+ echo " === Snapshot has beed sync'd"
+ echo
+ exit 0
+ else
+ rm $FILE
+ fi
+ fi
+
+ for i in $GENTOO_MIRRORS ; do
+ URI="${i}/snapshots/$FILE"
+ rm -f "$FILE"
+ if (eval "$FETCHCOMMAND $wgetops") && [ -s "$FILE" ]; then
+ if ! eval "$md5_com"; then
+ echo "md5 failed on $FILE"
+ rm ${FILE}
+ continue
+ else
+ sync_local
+ echo
+ echo " *** Completed websync, please now perform a normal rsync if possible."
+ echo " Update is current as of the of YYYYMMDD: ${year}${month}${day}"
+ echo
+ exit 0
+ fi
+ fi
+
+ done
+done
+
+rm -rf portage
+
+exit 1
diff --git a/bin/emerge.orig b/bin/emerge.orig
new file mode 100755
index 000000000..c66f32eae
--- /dev/null
+++ b/bin/emerge.orig
@@ -0,0 +1,3227 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/emerge,v 1.345.2.33 2005/06/02 00:57:52 vapier Exp $
+
+import os,sys
+os.environ["PORTAGE_CALLER"]="emerge"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+
+import emergehelp,xpak,string,re,commands,time,shutil,traceback,atexit,signal,socket,types
+from stat import *
+from output import *
+
+import portage_util
+import portage_locks
+import portage_exception
+
+
+spinner_msgs = ["Gentoo Rocks ("+os.uname()[0]+")",
+ "Thank you for using Gentoo. :)",
+ "Are you actually trying to read this?",
+ "How many times have you stared at this?",
+ "We are generating the cache right now",
+ "You are paying too much attention.",
+ "A theory is better than its explanation.",
+ "Phasers locked on target, Captain.",
+ "Thrashing is just virtual crashing.",
+ "To be is to program.",
+ "Real Users hate Real Programmers.",
+ "When all else fails, read the instructions.",
+ "Functionality breeds Contempt.",
+ "The future lies ahead.",
+ "3.1415926535897932384626433832795028841971694",
+ "Sometimes insanity is the only alternative.",
+ "Inaccuracy saves a world of explanation.",
+ ]
+
+
+def update_basic_spinner():
+ global spinner, spinpos
+ spinpos = (spinpos+1) % 500
+ if (spinpos % 100) == 0:
+ if spinpos == 0:
+ sys.stdout.write(". ")
+ else:
+ sys.stdout.write(".")
+ sys.stdout.flush()
+
+def update_scroll_spinner():
+ global spinner, spinpos
+ if(spinpos >= len(spinner)):
+ sys.stdout.write(darkgreen(" \b\b\b"+spinner[len(spinner)-1-(spinpos%len(spinner))]))
+ else:
+ sys.stdout.write(green("\b "+spinner[spinpos]))
+ sys.stdout.flush()
+ spinpos = (spinpos+1) % (2*len(spinner))
+
+def update_twirl_spinner():
+ global spinner, spinpos
+ spinpos = (spinpos+1) % len(spinner)
+ sys.stdout.write("\b\b "+spinner[spinpos])
+ sys.stdout.flush()
+
+spinpos = 0
+spinner = "/-\\|/-\\|/-\\|/-\\|\\-/|\\-/|\\-/|\\-/|"
+update_spinner = update_twirl_spinner
+if "candy" in portage.settings.features:
+ spinner = spinner_msgs[int(time.time()*100)%len(spinner_msgs)]
+ update_spinner = update_scroll_spinner
+if not sys.stdout.isatty() or ("--nospinner" in sys.argv):
+ update_spinner = update_basic_spinner
+
+
+if (not sys.stdout.isatty()) or (portage.settings["NOCOLOR"] in ["yes","true"]):
+ nocolor()
+
+def normpath(mystr):
+ if mystr and (mystr[0]=='/'):
+ return os.path.normpath("///"+mystr)
+ else:
+ return os.path.normpath(mystr)
+
+def userquery(prompt, responses=None, colours=None):
+ """Displays a prompt and a set of responses, then waits for a response
+ which is checked against the responses and the first to match is
+ returned.
+
+ prompt: a String.
+ responses: a List of Strings.
+ colours: a List of Functions taking and returning a String, used to
+ process the responses for display. Typically these will be functions
+ like red() but could be e.g. lambda x: "DisplayString".
+ If responses is omitted, defaults to ["Yes, "No"], [green, red].
+ If only colours is omitted, defaults to [bold, ...].
+
+ Returns a member of the List responses. (If called without optional
+ arguments, returns "Yes" or "No".)
+ KeyboardInterrupt is converted to SystemExit to avoid tracebacks being
+ printed."""
+ if responses is None:
+ responses, colours = ["Yes", "No"], [green, red]
+ elif colours is None:
+ colours=[bold]
+ colours=(colours*len(responses))[:len(responses)]
+ print bold(prompt),
+ try:
+ while True:
+ response=raw_input("["+string.join([colours[i](responses[i]) for i in range(len(responses))],"/")+"] ")
+ for key in responses:
+ if response.upper()==key[:len(response)].upper():
+ return key
+ print "Sorry, response '%s' not understood." % response,
+ except (EOFError, KeyboardInterrupt):
+ print "Interrupted."
+ sys.exit(1)
+
+def sorted_versions(verlist):
+ ret = []
+ for ver in verlist:
+ verparts = ver.split("-")
+ if len(verparts) == 2:
+ verrev = int(verparts[1][1:])
+ else:
+ verrev = 0
+ x = 0
+ while x < len(ret):
+ retparts = ret[x].split("-")
+ verdiff = portage.vercmp(retparts[0], verparts[0])
+ if verdiff > 0:
+ break
+ elif verdiff == 0:
+ if len(retparts) == 2:
+ retrev = int(retparts[1][1:])
+ else:
+ retrev = 0
+ if retrev >= verrev:
+ break
+ x += 1
+ ret.insert(x, ver)
+ return ret
+
+if portage.settings.has_key("PORTAGE_NICENESS"):
+ try:
+ os.nice(int(portage.settings["PORTAGE_NICENESS"]))
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception,e:
+ print "!!! Failed to change nice value to '"+str(portage.settings["PORTAGE_NICENESS"])+"'"
+ print "!!!",e
+
+#Freeze the portdbapi for enhanced performance:
+portage.portdb.freeze()
+
+# Kill noauto as it will break merges otherwise.
+while 'noauto' in portage.features:
+ del portage.features[portage.features.index('noauto')]
+
+#number of ebuilds merged
+merged=0
+params=["selective", "deep", "self", "recurse", "empty"]
+actions=[
+"clean", "config", "depclean",
+"info", "inject", "metadata",
+"prune", "regen", "rsync", "search",
+"sync", "system", "unmerge", "world",
+]
+options=[
+"--ask",
+"--buildpkg", "--buildpkgonly",
+"--changelog", "--columns",
+"--debug", "--deep",
+"--digest",
+"--emptytree",
+"--fetchonly", "--fetch-all-uri",
+"--getbinpkg", "--getbinpkgonly",
+"--help", "--noconfmem",
+"--newuse", "--nocolor",
+"--nodeps", "--noreplace",
+"--nospinner", "--oneshot",
+"--onlydeps", "--pretend",
+"--quiet", "--resume",
+"--searchdesc", "--selective",
+"--skipfirst",
+"--tree",
+"--update", "--upgradeonly",
+"--usepkg", "--usepkgonly",
+"--verbose", "--version"
+]
+
+shortmapping={
+"1":"--oneshot",
+"a":"--ask",
+"b":"--buildpkg", "B":"--buildpkgonly",
+"c":"--clean", "C":"--unmerge",
+"d":"--debug", "D":"--deep",
+"e":"--emptytree",
+"f":"--fetchonly", "F":"--fetch-all-uri",
+"g":"--getbinpkg", "G":"--getbinpkgonly",
+"h":"--help",
+"i":"--inject",
+"k":"--usepkg", "K":"--usepkgonly",
+"l":"--changelog",
+"n":"--noreplace", "N":"--newuse",
+"o":"--onlydeps", "O":"--nodeps",
+"p":"--pretend", "P":"--prune",
+"q":"--quiet",
+"s":"--search", "S":"--searchdesc",
+'t':"--tree",
+"u":"--update", "U":"--upgradeonly",
+"v":"--verbose", "V":"--version"
+}
+
+myaction=None
+myopts=[]
+myfiles=[]
+edebug=0
+
+# process short actions
+tmpcmdline=sys.argv[1:]
+#tmpcmdline.extend(portage.settings["EMERGE_OPTS"].split())
+cmdline=[]
+for x in tmpcmdline:
+ if x[0:1]=="-"and x[1:2]!="-":
+ for y in x[1:]:
+ if shortmapping.has_key(y):
+ if shortmapping[y] in cmdline:
+ print
+ print "*** Warning: Redundant use of",shortmapping[y]
+ else:
+ cmdline.append(shortmapping[y])
+ else:
+ print "!!! Error: -"+y+" is an invalid short action or option."
+ sys.exit(1)
+ else:
+ cmdline.append(x)
+
+# process the options and command arguments
+for x in cmdline:
+ if not x:
+ continue
+ if len(x)>=2 and x[0:2]=="--":
+ if x in options:
+ myopts.append(x)
+ elif x[2:] in actions:
+ if x[2:]=="rsync" or x=="rsync":
+ # "emerge --rsync"
+ print
+ print red("*** '--rsync' has been deprecated.")
+ print red("*** Please use '--sync' instead.")
+ print
+ x="--sync"
+ if myaction:
+ if myaction not in ["system", "world"]:
+ myaction="--"+myaction
+ print
+ print red("!!!")+green(" Multiple actions requested... Please choose one only.")
+ print red("!!!")+" '"+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
+ print
+ sys.exit(1)
+ myaction=x[2:]
+ else:
+ print "!!! Error:",x,"is an invalid option."
+ sys.exit(1)
+ elif (not myaction) and (x in actions):
+ if x not in ["system", "world"]:
+ #print red("*** Deprecated use of action '"+x+"'")
+ if x=="rsync":
+ # "emerge rsync"
+ print
+ print red("*** 'rsync' will now install the package rsync.")
+ print red("*** To sync the tree, please use '--sync' instead.")
+ print
+ myfiles.append(x)
+ continue
+ if myaction:
+ print
+ print red("!!!")+green(" Multiple actions requested... Please choose one only.")
+ print red("!!! '")+darkgreen(myaction)+"' "+red("or")+" '"+darkgreen(x)+"'"
+ print
+ sys.exit(1)
+ myaction=x
+ elif x[-1]=="/":
+ # this little conditional helps tab completion
+ myfiles.append(x[:-1])
+ else:
+ myfiles.append(x)
+
+
+if "moo" in myfiles:
+ print """
+
+ Gentoo (""" + os.uname()[0] + """)
+
+ _______________________
+< Have you mooed today? >
+ -----------------------
+ \ ^__^
+ \ (oo)\_______
+ (__)\ )\/\
+ ||----w |
+ || ||
+
+"""
+
+if (myaction in ["world", "system"]) and myfiles:
+ print "emerge: please specify a package class (\"world\" or \"system\") or individual packages, but not both."
+ sys.exit(1)
+
+for x in myfiles:
+ if (x[-7:] == ".ebuild" or x[-5:] == ".tbz2") and os.path.exists(os.path.abspath(x)):
+ print "emerging by path implies --oneshot... adding --oneshot to options."
+ print red("\n*** emerging by path is broken and may not always work!!!\n")
+ break
+
+if ("--tree" in myopts) and ("--columns" in myopts):
+ print "emerge: can't specify both of \"--tree\" and \"--columns\"."
+ sys.exit(1)
+
+# Always create packages if FEATURES=buildpkg
+# Imply --buildpkg if --buildpkgonly
+if ("buildpkg" in portage.features) or ("--buildpkgonly" in myopts):
+ if "--buildpkg" not in myopts:
+ myopts.append("--buildpkg")
+
+# --tree only makes sense with --pretend
+if "--tree" in myopts and not (("--pretend" in myopts) or ("--ask" in myopts)):
+ print ">>> --tree implies --pretend... adding --pretend to options."
+ myopts.append("--pretend")
+
+# Also allow -S to invoke search action (-sS)
+if ("--searchdesc" in myopts):
+ if myaction and myaction != "search":
+ myfiles.append(myaction)
+ if "--search" not in myopts:
+ myopts.append("--search")
+ myaction = "search"
+
+# Always try and fetch binary packages if FEATURES=getbinpkg
+if ("getbinpkg" in portage.features):
+ myopts.append("--getbinpkg")
+
+if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts):
+ myopts.append("--usepkgonly")
+
+if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts):
+ myopts.append("--getbinpkg")
+
+if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts):
+ myopts.append("--usepkg")
+
+# Also allow -K to apply --usepkg/-k
+if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts):
+ myopts.append("--usepkg")
+
+# Print deprecation warning for -U
+if ("--upgradeonly" in myopts):
+ print
+ print red("*** Warning: --upgradeonly is a deprecated option in portage-"+portage.VERSION)
+ print red("*** and will likely be removed in a future version.")
+ print
+ # Also allow -U to apply --update/-u
+ if not ("--update" in myopts):
+ print ">>> --upgradeonly implies --update... adding --update to options."
+ myopts.append("--update")
+
+# Also allow -l to apply --pretend/-p, but if already in --ask mode
+if ("--changelog" in myopts) and not (("--pretend" in myopts) or ("--ask" in myopts)):
+ print ">>> --changelog implies --pretend... adding --pretend to options."
+ myopts.append("--pretend")
+
+# Allow -p to remove --ask
+if ("--pretend" in myopts) and ("--ask" in myopts):
+ print ">>> --pretend disables --ask... removing --ask from options."
+ myopts.remove("--ask")
+
+# forbid --ask when not in a terminal
+# note: this breaks `emerge --ask | tee logfile`, but that doesn't work anyway.
+if ("--ask" in myopts) and (not sys.stdin.isatty()):
+ portage.writemsg("!!! \"--ask\" should only be used in a terminal. Exiting.\n")
+ sys.exit(1)
+
+# Set so that configs will be merged regardless of remembered status
+if ("--noconfmem" in myopts):
+ portage.settings.unlock()
+ portage.settings["NOCONFMEM"]="1"
+ portage.settings.backup_changes("NOCONFMEM")
+ portage.settings.lock()
+
+# Set various debug markers... They should be merged somehow.
+if ("--debug" in myopts):
+ portage.settings.unlock()
+ portage.settings["PORTAGE_DEBUG"]="1"
+ portage.settings.backup_changes("PORTAGE_DEBUG")
+ portage.debug=1
+ portage.settings.lock()
+
+if ("--resume" in myopts):
+ if "--verbose" in myopts:
+ print "* --verbose is currently broken with --resume. Disabling..."
+ myopts.remove("--verbose")
+ if "--tree" in myopts:
+ print "* --tree is currently broken with --resume. Disabling..."
+ myopts.remove("--tree")
+
+# Set color output
+if ("--nocolor" in myopts) and (sys.stdout.isatty()):
+ nocolor()
+
+CLEAN_DELAY = 5
+EMERGE_WARNING_DELAY = 10
+if portage.settings["CLEAN_DELAY"]:
+ CLEAN_DELAY = string.atoi("0"+portage.settings["CLEAN_DELAY"])
+if portage.settings["EMERGE_WARNING_DELAY"]:
+ EMERGE_WARNING_DELAY = string.atoi("0"+portage.settings["EMERGE_WARNING_DELAY"])
+
+if "inject" == myaction:
+ print
+ print red("*** --inject has been deprecated.")
+ print red("*** If you manage a piece of software yourself, add it's name and")
+ print red("*** version (eg foo/bar-1.0) to /etc/portage/profile/package.provided.")
+ print red("*** If you want to prevent portage from upgrading a package, add it to")
+ print red("*** /etc/portage/package.mask prepending it with '>' (eg >foo/bar-1.0)")
+ print red("*** For more information on fine-grained portage control, please see")
+ print red("*** the portage man page.")
+ print
+
+def emergelog(mystr,short_msg=None):
+ if "notitles" not in portage.features:
+ if short_msg:
+ xtermTitle(short_msg)
+ else:
+ xtermTitle(mystr)
+ try:
+ #seems odd opening a file each write...
+ if not os.path.exists("/var/log/emerge.log"):
+ mylogfile=open("/var/log/emerge.log", "w")
+ os.chmod("/var/log/emerge.log", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
+ os.chown("/var/log/emerge.log", portage.portage_uid, portage.portage_gid)
+ else:
+ mylogfile=open("/var/log/emerge.log", "a")
+
+ l=portage_locks.lockfile(mylogfile)
+ # seek because we may have gotten held up by the lock.
+ # if so, we may not be positioned at the end of the file.
+ mylogfile.seek(0,2)
+ mylogfile.write(str(time.time())[:10]+": "+mystr+"\n")
+ mylogfile.flush()
+ portage_locks.unlockfile(l)
+ mylogfile.close()
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if edebug:
+ print "emergelog():",e
+ pass
+
+def emergeexit():
+ """This gets out final log message in before we quit."""
+ if "--pretend" not in myopts:
+ emergelog(" *** terminating.")
+ if "notitles" not in portage.features:
+ xtermTitleReset()
+atexit.register(emergeexit)
+
+def emergeexitsig(signum, frame):
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
+ portage.portageexit()
+ portage_util.writemsg("\n\nExiting on signal %(signal)s\n" % {"signal":signum})
+ sys.exit(100+signum)
+signal.signal(signal.SIGINT, emergeexitsig)
+
+def countdown(secs=5, doing="Starting"):
+ if secs:
+ print ">>> Waiting",secs,"seconds before starting..."
+ print ">>> (Control-C to abort)...\n"+doing+" in: ",
+ ticks=range(secs)
+ ticks.reverse()
+ for sec in ticks:
+ sys.stdout.write(red(str(sec+1)+" "))
+ sys.stdout.flush()
+ time.sleep(1)
+ print
+
+# formats a size given in bytes nicely
+def format_size(mysize):
+ if type(mysize) not in [types.IntType,types.LongType]:
+ return str(mysize)
+ mystr=str(mysize/1024)
+ mycount=len(mystr)
+ while (mycount > 3):
+ mycount-=3
+ mystr=mystr[:mycount]+","+mystr[mycount:]
+ return mystr+" kB"
+
+
+def getgccversion():
+ """
+ rtype: C{str}
+ return: the current in-use gcc version
+ """
+
+ gcc_env_dir = os.path.join('/', 'etc', 'env.d', 'gcc')
+ gcc_config_config = os.path.join(gcc_env_dir, 'config')
+ gcc_ver_command = 'gcc -dumpversion'
+ gcc_ver_prefix = 'gcc-'
+
+ gcc_not_found_error = red(
+ "!!! No gcc found. You probably need to 'source /etc/profile'\n" +
+ "!!! to update the environment of this terminal and possibly\n" +
+ "!!! other terminals also."
+ )
+
+ gcc_distcc_broken_error = green(
+ '!!! Relying on the shell to locate gcc, this may break\n' +
+ '!!! DISTCC, installing gcc-config and setting your current gcc\n' +
+ '!!! profile will fix this'
+ )
+
+ def fallback():
+
+ print >>sys.stderr, gcc_distcc_broken_error
+
+ gccout = commands.getstatusoutput(gcc_ver_command)
+
+ if gccout[0] != 0:
+ print >>sys.stderr, gcc_not_found_error
+ gccver = "[unavailable]"
+ else:
+ gccver = gcc_ver_prefix + gccout[1]
+
+ return gccver
+
+ if os.path.isfile(gcc_config_config):
+ try:
+ gccver_str = open(gcc_config_config).read().strip()
+ gccver = gcc_ver_prefix + string.join(gccver_str.split('-')[4:], '-')
+ except IndexError:
+ gccver = fallback()
+
+ else:
+ import glob
+ dir_l = glob.glob(os.path.join(gcc_env_dir, '*-*'))
+
+ if len(dir_l) == 1:
+ try:
+ gccver = gcc_ver_prefix + dir_l[0].split('-')[-1]
+ except IndexError:
+ gccver = fallback()
+
+ else:
+ # There was no "config" file in /etc/env.d/gcc and there was more
+ # than one profile in /etc/env.d/gcc so we can't actively
+ # determine what version of gcc we are using so we fall back on the
+ # old way that breaks distcc
+
+ gccver = fallback()
+
+ return gccver
+
+def getportageversion():
+ try:
+ import re
+ profilever = os.path.normpath("///"+os.readlink("/etc/make.profile"))
+ basepath = os.path.normpath("///"+portage.settings["PORTDIR"]+"/profiles")
+ if re.match(basepath,profilever):
+ profilever = profilever[len(basepath)+1:]
+ else:
+ profilever = "!"+profilever
+ del basepath
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ profilever="unavailable"
+ libcver=[]
+ libclist = portage.vardbapi(portage.root).match("virtual/libc")
+ libclist += portage.vardbapi(portage.root).match("virtual/glibc")
+ libclist = portage_util.unique_array(libclist)
+ for x in libclist:
+ xs=portage.catpkgsplit(x)
+ if libcver:
+ libcver+=","+string.join(xs[1:], "-")
+ else:
+ libcver=string.join(xs[1:], "-")
+ if libcver==[]:
+ libcver="unavailable"
+
+ gccver = getgccversion()
+ unameout=os.uname()[2]+" "+os.uname()[4]
+
+ return "Portage " + portage.VERSION +" ("+profilever+", "+gccver+", "+libcver+", "+unameout+")"
+
+def help():
+ # Move all the help stuff out of this file.
+ emergehelp.help(myaction,myopts,havecolor)
+
+# check if root user is the current user for the actions where emerge needs this
+if ("--pretend" in myopts) or ("--fetchonly" in myopts or "--fetch-all-uri" in myopts) or (myaction=="search"):
+ if not portage.secpass:
+ if portage.wheelgid==portage.portage_gid:
+ print "emerge: wheel group membership required for \"--pretend\" and search."
+ print "emerge: wheel group use is being deprecated. Please update group and passwd to"
+ print " include the portage user as noted above, and then use group portage."
+ else:
+ print "emerge: portage group membership required for \"--pretend\" and search."
+ sys.exit(1)
+elif "--version" in myopts:
+ print getportageversion()
+ sys.exit(0)
+elif "--help" in myopts:
+ help()
+ sys.exit(0)
+elif portage.secpass!=2:
+ if myaction in ["search", "info", "regen"]:
+ pass
+ elif (not myaction) and (not myfiles):
+ pass
+ elif ("--pretend" in myopts) and (myaction in ["world","system","clean","prune","unmerge"]):
+ pass
+ else:
+ if "--debug" in myopts:
+ print "myaction",myaction
+ print "myopts",myopts
+ print "emerge: root access required."
+ sys.exit(1)
+
+if not "--pretend" in myopts:
+ emergelog("Started emerge on: "+time.strftime("%b %d, %Y %H:%M:%S", time.localtime()))
+ myelogstr=""
+ if myopts:
+ myelogstr=string.join(myopts, " ")
+ if myaction:
+ myelogstr+=" "+myaction
+ if myfiles:
+ myelogstr+=" "+string.join(myfiles, " ")
+ emergelog(" *** emerge "+myelogstr)
+
+#configure emerge engine parameters
+#
+# self: include _this_ package regardless of if it is merged.
+# selective: exclude the package if it is merged
+# recurse: go into the dependencies
+# empty: pretend nothing is merged
+myparams=["self","recurse"]
+add=[]
+sub=[]
+if "--update" in myopts:
+ add.extend(["selective","empty"])
+if "--emptytree" in myopts:
+ add.extend(["empty"])
+ sub.extend(["selective"])
+if "--nodeps" in myopts:
+ sub.extend(["recurse"])
+if "--noreplace" in myopts:
+ add.extend(["selective"])
+if "--deep" in myopts:
+ add.extend(["deep"])
+if "--selective" in myopts:
+ add.extend(["selective"])
+if myaction in ["world","system"]:
+ add.extend(["selective"])
+elif myaction in ["depclean"]:
+ add.extend(["empty"])
+ sub.extend(["selective"])
+for x in add:
+ if (x not in myparams) and (x not in sub):
+ myparams.append(x)
+for x in sub:
+ if x in myparams:
+ myparams.remove(x)
+
+# search functionality
+class search:
+
+ #
+ # class constants
+ #
+ VERSION_SHORT=1
+ VERSION_RELEASE=2
+
+ #
+ # public interface
+ #
+ def __init__(self):
+ """Searches the available and installed packages for the supplied search key.
+ The list of available and installed packages is created at object instantiation.
+ This makes successive searches faster."""
+ self.installcache = portage.db["/"]["vartree"]
+
+ def execute(self,searchkey):
+ """Performs the search for the supplied search key"""
+ global myopts
+ match_category = 0
+ self.searchkey=searchkey
+ self.packagematches = []
+ if "--searchdesc" in myopts:
+ self.searchdesc=1
+ self.matches = {"pkg":[], "desc":[]}
+ else:
+ self.searchdesc=0
+ self.matches = {"pkg":[]}
+ print "Searching... ",
+
+ if self.searchkey[0] == '@':
+ match_category = 1
+ self.searchkey = self.searchkey[1:]
+ if self.searchkey=="*":
+ #hack for people who aren't regular expression gurus
+ self.searchkey==".*"
+ if re.search("\+\+", self.searchkey):
+ #hack for people who aren't regular expression gurus
+ self.searchkey=re.sub("\+\+","\+\+",self.searchkey)
+ self.searchre=re.compile(self.searchkey.lower(),re.I)
+ for package in portage.portdb.cp_all():
+ update_spinner()
+
+ if match_category:
+ match_string = package[:]
+ else:
+ match_string = package.split("/")[-1]
+
+ masked=0
+ if self.searchre.search(match_string):
+ if not portage.portdb.xmatch("match-visible",package):
+ masked=1
+ self.matches["pkg"].append([package,masked])
+ elif self.searchdesc: # DESCRIPTION searching
+ full_package = portage.portdb.xmatch("bestmatch-visible",package)
+ if not full_package:
+ #no match found; we don't want to query description
+ full_package=portage.best(portage.portdb.xmatch("match-all",package))
+ if not full_package:
+ continue
+ else:
+ masked=1
+ try:
+ full_desc = portage.portdb.aux_get(full_package,["DESCRIPTION"])[0]
+ except KeyError:
+ print "emerge: search: aux_get() failed, skipping"
+ continue
+ if self.searchre.search(full_desc):
+ self.matches["desc"].append([full_package,masked])
+ self.mlen=0
+ for mtype in self.matches.keys():
+ self.matches[mtype].sort()
+ self.mlen += len(self.matches[mtype])
+
+ def output(self):
+ """Outputs the results of the search."""
+ print "\b\b \n[ Results for search key : "+white(self.searchkey)+" ]"
+ print "[ Applications found : "+white(str(self.mlen))+" ]"
+ print " "
+ for mtype in self.matches.keys():
+ for match,masked in self.matches[mtype]:
+ if mtype=="pkg":
+ catpack=match
+ full_package = portage.portdb.xmatch("bestmatch-visible",match)
+ if not full_package:
+ #no match found; we don't want to query description
+ masked=1
+ full_package=portage.best(portage.portdb.xmatch("match-all",match))
+ else:
+ full_package = match
+ match = portage.pkgsplit(match)[0]
+
+ if full_package:
+ try:
+ desc, homepage, license = portage.portdb.aux_get(full_package,["DESCRIPTION","HOMEPAGE","LICENSE"])
+ except KeyError:
+ print "emerge: search: aux_get() failed, skipping"
+ continue
+ if masked:
+ print green("*")+" "+white(match)+" "+red("[ Masked ]")
+ else:
+ print green("*")+" "+white(match)
+ myversion = self.getVersion(full_package, search.VERSION_RELEASE)
+
+ mysum = [0,0]
+ mycat = match.split("/")[0]
+ mypkg = match.split("/")[1]
+
+ mydigest = portage.db["/"]["porttree"].dbapi.finddigest(mycat+"/"+mypkg + "-" + myversion)
+
+ try:
+ myfile = open(mydigest,"r")
+ for line in myfile.readlines():
+ mysum[0] += int(line.split(" ")[3])
+ myfile.close()
+ mystr = str(mysum[0]/1024)
+ mycount=len(mystr)
+ while (mycount > 3):
+ mycount-=3
+ mystr=mystr[:mycount]+","+mystr[mycount:]
+ mysum[0]=mystr+" kB"
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if edebug:
+ print "!!! Exception:",e
+ mysum[0]=" [no/bad digest]"
+
+ if "--quiet" not in myopts:
+ print " ", darkgreen("Latest version available:"),myversion
+ print " ", self.getInstallationStatus(mycat+'/'+mypkg)
+ print " ", darkgreen("Size of downloaded files:"),mysum[0]
+ print " ", darkgreen("Homepage:")+" ",homepage
+ print " ", darkgreen("Description:"),desc
+ print " ", darkgreen("License:")+" ",license
+ print
+ print
+ #
+ # private interface
+ #
+ def getInstallationStatus(self,package):
+ installed_package = self.installcache.dep_bestmatch(package)
+ result = ""
+ version = self.getVersion(installed_package,search.VERSION_RELEASE)
+ if len(version) > 0:
+ result = darkgreen("Latest version installed:")+" "+version
+ else:
+ result = darkgreen("Latest version installed:")+" [ Not Installed ]"
+ return result
+
+ def getVersion(self,full_package,detail):
+ if len(full_package) > 1:
+ package_parts = portage.catpkgsplit(full_package)
+ if detail == search.VERSION_RELEASE and package_parts[3] != 'r0':
+ result = package_parts[2]+ "-" + package_parts[3]
+ else:
+ result = package_parts[2]
+ else:
+ result = ""
+ return result
+
+
+#build our package digraph
+def getlist(mode):
+ if mode=="system":
+ mylines=portage.settings.packages
+ elif mode=="world":
+ try:
+ myfile=open(portage.root+portage.WORLD_FILE,"r")
+ mylines=myfile.readlines()
+ myfile.close()
+ except OSError:
+ print "!!! Couldn't open "+pfile+"; exiting."
+ sys.exit(1)
+ except IOError:
+ #world file doesn't exist
+ mylines=[]
+ mynewlines=[]
+ for x in mylines:
+ myline=string.join(string.split(x))
+ if not len(myline):
+ continue
+ elif myline[0]=="#":
+ continue
+ elif mode=="system":
+ if myline[0]!="*":
+ continue
+ myline=myline[1:]
+ mynewlines.append(myline.strip())
+
+ # Remove everything that is package.provided from our list
+ for myatom in mynewlines[:]:
+ mykey = portage.dep_getkey(myatom)
+ if portage.settings.pprovideddict.has_key(mykey) and \
+ portage.match_from_list(myatom, portage.settings.pprovideddict[mykey]):
+ mynewlines.remove(myatom)
+
+ return mynewlines
+
+def genericdict(mylist):
+ mynewdict={}
+ for x in mylist:
+ mynewdict[portage.dep_getkey(x)]=x
+ return mynewdict
+
+olddbapi=None
+class depgraph:
+
+ def __init__(self,myaction,myopts):
+ global olddbapi
+ self.pkgsettings = portage.config(clone=portage.settings)
+ if not self.pkgsettings["ARCH"]:
+ portage.writemsg(red("\a!!! ARCH is not set... Are you missing the /etc/make.profile symlink?\n"))
+ portage.writemsg(red("\a!!! Is the symlink correct? Is your portage tree complete?\n\n"))
+ sys.exit(9)
+ self.applied_useflags = {}
+
+ self.missingbins=[]
+ self.myaction=myaction
+ self.digraph=portage.digraph()
+ self.orderedkeys=[]
+ self.outdatedpackages=[]
+ self.mydbapi={}
+ self.mydbapi["/"] = portage.fakedbapi()
+ if "empty" not in myparams:
+ for pkg in portage.db["/"]["vartree"].getallcpv():
+ self.mydbapi["/"].cpv_inject(pkg)
+ if portage.root != "/":
+ self.mydbapi[portage.root] = portage.fakedbapi()
+ if "empty" not in myparams:
+ for pkg in portage.db[portage.root]["vartree"].getallcpv():
+ self.mydbapi[portage.root].cpv_inject(pkg)
+
+ if "--usepkg" in myopts:
+ portage.db["/"]["bintree"].populate(("--getbinpkg" in myopts), ("--getbinpkgonly" in myopts))
+
+ def create(self,mybigkey,myparent=None,addme=1,myuse=None):
+ """creates the actual digraph of packages to merge. return 1 on success, 0 on failure
+ mybigkey = specification of package to merge; myparent = parent package (one depending on me);
+ addme = should I be added to the tree? (for the --onlydeps mode)"""
+ #stuff to add:
+ #SLOT-aware emerge
+ #IUSE-aware emerge
+ #"no downgrade" emerge
+ #print "mybigkey:",mybigkey
+
+ jbigkey=string.join(mybigkey)
+ if self.digraph.hasnode(jbigkey+" merge") or self.digraph.hasnode(jbigkey+" nomerge"):
+ #this conditional is needed to prevent infinite recursion on already-processed deps
+ return 1
+
+ update_spinner()
+
+ mytype,myroot,mykey=mybigkey
+ # select the correct /var database that we'll be checking against
+ vardbapi=portage.db[myroot]["vartree"].dbapi
+
+ if addme:
+ # if the package is already on the system, we add a "nomerge"
+ # directive, otherwise we add a "merge" directive.
+ if mytype=="blocks":
+ # we've encountered a "blocks" node. We will totally ignore this
+ # node and not add it to our digraph if it doesn't apply to us.
+ if "--buildpkgonly" not in myopts and myparent and (self.mydbapi[myroot].match(mykey) or vardbapi.match(mykey)):
+ mybigkey.append(myparent.split()[2])
+ self.digraph.addnode(string.join(mybigkey),myparent)
+ return 1
+
+ if myuse == None:
+ self.pkgsettings.setcpv(mykey)
+ myuse=string.split(self.pkgsettings["USE"], " ")
+
+ self.applied_useflags[mykey] = myuse
+
+ merging=1
+ if addme:
+ # this is where we add the node to the list of packages to merge
+ if not myparent:
+ # command-line specified or part of a world list...
+ if ("self" not in myparams) or (("selective" in myparams) and vardbapi.cpv_exists(mykey)):
+ # the package is on the system, so don't merge it.
+ merging=0
+ elif ("selective" in myparams) and vardbapi.cpv_exists(mykey):
+ merging=0
+
+ if (merging==0 and mytype=="ebuild" and "--newuse" in myopts and vardbapi.cpv_exists(mykey)):
+ iuses=string.split(portage.portdb.aux_get(mykey, ["IUSE"])[0])
+ old_use=string.split(vardbapi.aux_get(mykey, ["USE"])[0])
+ now_use=string.split(self.pkgsettings["USE"])
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ merging=1
+ break
+ else:
+ #onlydeps mode; don't merge
+ merging=2
+ if merging==1:
+ mybigkey.append("merge")
+ else:
+ mybigkey.append("nomerge")
+
+ # whatever the case, we need to add the node to our digraph so
+ # that children can depend upon it.
+ self.digraph.addnode(string.join(mybigkey),myparent)
+ if ("deep" not in myparams) and (not merging):
+ return 1
+ elif "recurse" not in myparams:
+ return 1
+
+ edepend={}
+ if mytype=="binary":
+ mypkgparts=portage.catpkgsplit(mykey)
+ tbz2name = string.split(mykey, "/")[1]+".tbz2"
+ if tbz2name in portage.db[portage.root]["bintree"].invalids:
+ sys.stderr.write("\nINVALID PACKAGE (is required to continue): "+str(mykey)+"\n")
+ sys.exit(1)
+ if portage.db[portage.root]["bintree"].isremote(mykey):
+ edepend = portage.db[portage.root]["bintree"].remotepkgs[tbz2name]
+ edepend["DEPEND"] =""
+ edepend["RDEPEND"]=string.join(string.split(edepend["RDEPEND"])," ")
+ edepend["PDEPEND"]=string.join(string.split(edepend["PDEPEND"])," ")
+ edepend["SLOT"] =string.strip(edepend["SLOT"])
+ #portage.db[portage.root]["bintree"].gettbz2(mykey)
+ else: # It's local.
+ mytbz2=xpak.tbz2(portage.db[portage.root]["bintree"].getname(mykey))
+ edepend["DEPEND"] =""
+ edepend["RDEPEND"]=string.join(mytbz2.getelements("RDEPEND")," ")
+ edepend["PDEPEND"]=string.join(mytbz2.getelements("PDEPEND")," ")
+ edepend["SLOT"] =mytbz2.getfile("SLOT",mypkgparts[2])
+ elif mytype=="ebuild":
+ try:
+ mymeta = ["DEPEND","RDEPEND","PDEPEND"]
+ myfoo = portage.portdb.aux_get(mykey, mymeta)
+ for index in range(0,len(mymeta)):
+ edepend[mymeta[index]] = myfoo[index]
+ if "--buildpkgonly" in myopts:
+ edepend["RDEPEND"] = ""
+ except (KeyError,IOError):
+ print "emerge: create(): aux_get() error on",mykey+"; aborting..."
+ sys.exit(1)
+ mydep={}
+ mp=string.join(mybigkey)
+
+ if myroot=="/":
+ mydep["/"]=edepend["DEPEND"]+" "+edepend["RDEPEND"]
+ if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
+ return 0
+ else:
+ mydep["/"]=edepend["DEPEND"]
+ mydep[myroot]=edepend["RDEPEND"]
+ if not self.select_dep("/",mydep["/"],myparent=mp,myuse=myuse):
+ return 0
+ if not self.select_dep(myroot,mydep[myroot],myparent=mp,myuse=myuse):
+ return 0
+
+ if edepend.has_key("PDEPEND") and edepend["PDEPEND"]:
+ # Post Depend -- Add to the list without a parent, as it depends
+ # on a package being present AND must be built after that package.
+ if not self.select_dep(myroot,edepend["PDEPEND"],myuse=myuse):
+ return 0
+
+ return 1
+
+ def select_files(self,myfiles):
+ "given a list of .tbz2s, .ebuilds and deps, create the appropriate depgraph and return a favorite list"
+ myfavorites=[]
+ for x in myfiles:
+ if x[-5:]==".tbz2":
+ if not os.path.exists(x):
+ if os.path.exists(self.pkgsettings["PKGDIR"]+"/All/"+x):
+ x=self.pkgsettings["PKGDIR"]+"/All/"+x
+ elif os.path.exists(self.pkgsettings["PKGDIR"]+"/"+x):
+ x=self.pkgsettings["PKGDIR"]+"/"+x
+ else:
+ print "\n\n!!! Binary package '"+str(x)+"' does not exist."
+ print "!!! Please ensure the tbz2 exists as specified.\n"
+ sys.exit(1)
+ mytbz2=xpak.tbz2(x)
+ mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.basename(x)[:-5]
+ if os.path.realpath(portage.db["/"]["bintree"].getname(mykey)) != os.path.realpath(x):
+ print red("\n*** You need to adjust PKGDIR to emerge this package.\n")
+ sys.exit(1)
+ if not self.create(["binary",portage.root,mykey],None,"--onlydeps" not in myopts):
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+ elif x[-7:]==".ebuild":
+ x = os.path.realpath(x)
+ mykey=os.path.basename(os.path.normpath(x+"/../.."))+"/"+os.path.basename(x)[:-7]
+ ebuild_path = portage.db["/"]["porttree"].dbapi.findname(mykey)
+ if ebuild_path:
+ if os.path.realpath(ebuild_path) != x:
+ print red("\n*** You need to adjust PORTDIR or PORTDIR_OVERLAY to emerge this package.\n")
+ sys.exit(1)
+ if mykey not in portage.db["/"]["porttree"].dbapi.xmatch("match-visible", portage.dep_getkey(mykey)):
+ print red("\n*** You are emerging a masked package. It is MUCH better to use")
+ print red("*** /etc/portage/package.* to accomplish this. See portage(5) man")
+ print red("*** page for details.")
+ countdown(EMERGE_WARNING_DELAY, "Continuing...")
+ else:
+ print red("\n*** "+x+" does not exist")
+ sys.exit(1)
+ if not self.create(["ebuild",portage.root,mykey],None,"--onlydeps" not in myopts):
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+ else:
+ try:
+ mykey=portage.dep_expand(x,mydb=portage.portdb)
+ except ValueError, errpkgs:
+ print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
+ print "!!! one of the following fully-qualified ebuild names instead:\n"
+ for i in errpkgs[0]:
+ print " " + green(i)
+ print
+ sys.exit(1)
+
+ # select needs to return 0 on dep_check failure
+
+ sys.stdout.flush()
+ sys.stderr.flush()
+
+ try:
+ self.mysd = self.select_dep(portage.root,mykey,arg=x)
+ except portage_exception.MissingSignature, e:
+ portage.writemsg("\n\n!!! A missing gpg signature is preventing portage from calculating the\n")
+ portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
+ portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
+ portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF A TAMPERED FILES -- CHECK CAREFULLY.\n")
+ portage.writemsg("!!! Affected file: %s\n" % (e))
+ sys.exit(1)
+ except portage_exception.InvalidSignature, e:
+ portage.writemsg("\n\n!!! An invalid gpg signature is preventing portage from calculating the\n")
+ portage.writemsg("!!! required dependencies. This is a security feature enabled by the admin\n")
+ portage.writemsg("!!! to aid in the detection of malicious intent.\n\n")
+ portage.writemsg("!!! THIS IS A POSSIBLE INDICATION OF A TAMPERED FILES -- CHECK CAREFULLY.\n")
+ portage.writemsg("!!! Affected file: %s\n" % (e))
+ sys.exit(1)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ if "--debug" in myopts:
+ raise
+ print "\n\n!!! Problem in",mykey,"dependencies."
+ print "!!!",str(e),e.__module__
+ sys.exit(1)
+
+ if not self.mysd:
+ return (0,myfavorites)
+ elif not "--oneshot" in myopts:
+ myfavorites.append(mykey)
+
+ missing=0
+ if "--usepkgonly" in myopts:
+ for x in self.digraph.dict.keys():
+ xs=string.split(x," ")
+ if (xs[0] != "binary") and (xs[3]=="merge"):
+ if missing == 0:
+ print
+ missing += 1
+ print "Missing binary for:",xs[2]
+
+ # We're true here unless we are missing binaries.
+ return (not missing,myfavorites)
+
+ def is_newer_ver_installed(self,myroot,pkg,pkgver):
+ "if there is a version of pkg installed newer than pkgver, return it"
+ vardbapi=portage.db[myroot]["vartree"].dbapi
+
+ matches=portage.db[myroot]["vartree"].dbapi.match(pkg)
+ if matches:
+ myslot=portage.db["/"]["porttree"].getslot(pkgver)
+ for match in matches:
+ if portage.pkgcmp(portage.catpkgsplit(pkgver)[1:], portage.catpkgsplit(match)[1:]) < 0:
+ curslot=portage.db[myroot]["vartree"].getslot(match)
+ if curslot == myslot:
+ return match
+
+ def select_dep(self,myroot,depstring,myparent=None,arg=None,myuse=None):
+ "given a dependency string, create the appropriate depgraph and return 1 on success and 0 on failure"
+ if "--debug" in myopts:
+ print
+ print "Parent: ",myparent
+ print "Depstring:",depstring
+ if not arg:
+ #processing dependencies
+ mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse,use_binaries=("--usepkg" in myopts))
+ #mycheck=portage.dep_check(depstring,self.mydbapi[myroot],self.pkgsettings,myuse=myuse)
+
+ if not mycheck[0]:
+ mymerge=[]
+ else:
+ mymerge=mycheck[1]
+
+ else:
+ #we're processing a command-line argument; unconditionally merge it even if it's already merged
+ mymerge=[depstring]
+
+ # dep_check has been run so we can now add our parent to our
+ # build state to update virtuals and other settings. This
+ # happens after the package is added to the tree so that a
+ # package can depend on a virtual which it satisfies.
+ if myparent:
+ myp = myparent.split()
+ if myp[3]=="merge":
+ self.mydbapi[myroot].cpv_inject(myp[2])
+ if myp[0]=="binary":
+ self.pkgsettings.setinst(myp[2],portage.db["/"]["bintree"].dbapi)
+ else:
+ self.pkgsettings.setinst(myp[2],portage.db[myroot]["porttree"].dbapi)
+
+ if not mymerge:
+ return 1
+
+ if "--debug" in myopts:
+ print "Candidates:",mymerge
+ for x in mymerge:
+ myk=None
+ binpkguseflags=None
+ if x[0]=="!":
+ # if this package is myself, don't append it to block list.
+ if "--debug" in myopts:
+ print "Myparent",myparent
+ if (myparent):
+ if myparent.split()[2] in portage.portdb.xmatch("match-all", x[1:]):
+ # myself, so exit.
+ continue
+ # adding block
+ myk=["blocks",myroot,x[1:]]
+ else:
+ #We are not processing a blocker but a normal dependency
+ myeb=None
+ myeb_matches = portage.portdb.xmatch("match-visible",x)
+ if ("--usepkgonly" not in myopts):
+ myeb=portage.best(myeb_matches)
+
+ myeb_pkg=None
+ if ("--usepkg" in myopts):
+ # The next line assumes the binarytree has been populated.
+ # XXX: Need to work out how we use the binary tree with roots.
+ myeb_pkg_matches=portage.db["/"]["bintree"].dbapi.match(x)
+ if ("--usepkgonly" not in myopts):
+ # Remove any binary package entries that are masked in the portage tree (#55871)
+ for idx in range(len(myeb_pkg_matches)-1,-1,-1):
+ if myeb_pkg_matches[idx] not in myeb_matches:
+ del myeb_pkg_matches[idx]
+ myeb_pkg = portage.best(myeb_pkg_matches)
+
+ if not myeb_pkg:
+ myeb_pkg = None
+ elif ("--newuse" in myopts):
+ iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["IUSE"])[0])
+ old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(myeb_pkg, ["USE"])[0])
+ self.pkgsettings.setcpv(myeb_pkg)
+ now_use=string.split(self.pkgsettings["USE"])
+ self.pkgsettings.reset()
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ myeb_pkg = None
+ break
+
+ if (not myeb) and (not myeb_pkg):
+ if not arg:
+ xinfo='"'+x+'"'
+ else:
+ xinfo='"'+arg+'"'
+ if myparent:
+ xfrom = '(dependency required by '+green('"'+myparent.split()[2]+'"')+red(' ['+myparent.split()[0]+"])")
+ alleb=portage.portdb.xmatch("match-all",x)
+ if alleb:
+ if "--usepkgonly" not in myopts:
+ print "\n!!! "+red("All ebuilds that could satisfy ")+green(xinfo)+red(" have been masked.")
+ print "!!! One of the following masked packages is required to complete your request:"
+ oldcomment = ""
+ for p in alleb:
+ mreasons = portage.getmaskingstatus(p)
+ print "- "+p+" (masked by: "+string.join(mreasons, ", ")+")"
+ comment = portage.getmaskingreason(p)
+ if comment and comment != oldcomment:
+ print comment
+ oldcomment = comment
+ print
+ print "For more information, see MASKED PACKAGES section in the emerge man page or "
+ print "section 2.2 \"Software Availability\" in the Gentoo Handbook."
+ if myparent:
+ print "!!! "+red(xfrom)
+ print
+ else:
+ print "\n!!! "+red("There are no packages available to satisfy: ")+green(xinfo)
+ print "!!! Either add a suitable binary package or compile from an ebuild."
+ else:
+ print "\nemerge: there are no ebuilds to satisfy "+xinfo+"."
+ if myparent:
+ print xfrom
+ print
+ return 0
+
+ if "--debug" in myopts:
+ print "ebuild:",myeb
+ print "binpkg:",myeb_pkg
+
+ if myeb and myeb_pkg:
+ myeb_s = portage.catpkgsplit(myeb)
+ myeb_s = [myeb_s[0]+"/"+myeb_s[1], myeb_s[2], myeb_s[3]]
+ myeb_pkg_s = portage.catpkgsplit(myeb_pkg)
+ myeb_pkg_s = [myeb_pkg_s[0]+"/"+myeb_pkg_s[1], myeb_pkg_s[2], myeb_pkg_s[3]]
+
+ if portage.pkgcmp(myeb_s, myeb_pkg_s) == 0: # pkg is same version as ebuild
+ myeb = None
+ else:
+ myeb_pkg = None
+
+ if "--upgradeonly" in myopts:
+ # Check that there isn't a newer version of this package already installed
+ cand = None
+ try:
+ # XXX: This can throw an exception if the ebuild doesn't exist
+ if myeb:
+ cand=self.is_newer_ver_installed(myroot,x,myeb)
+ elif myeb_pkg:
+ cand=self.is_newer_ver_installed(myroot,x,myeb_pkg)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Warning: "+str(e)
+ if cand:
+ myeb=cand
+
+ if myeb:
+ myk=["ebuild",myroot,myeb]
+ elif myeb_pkg:
+ binpkguseflags=portage.db[portage.root]["bintree"].get_use(myeb_pkg)
+ myk=["binary",myroot,myeb_pkg]
+ else:
+ sys.stderr.write("!!! Confused... Don't know what I'm using for dependency info. :(\n")
+ sys.exit(1)
+
+ #if "--usepkg" in myopts:
+ # #If we want to use packages, see if we have a pre-built one...
+ # mypk=portage.db["/"]["bintree"].dbapi.match(x)
+ # if myeb in mypk:
+ # #Use it only if it's exactly the version we want.
+ # myk=["binary",myroot,myeb]
+ # else:
+ # myk=["ebuild",myroot,myeb]
+ #else:
+ # myk=["ebuild",myroot,myeb]
+ if myparent:
+ #we are a dependency, so we want to be unconditionally added
+ if not self.create(myk,myparent,myuse=binpkguseflags):
+ return 0
+ else:
+ #if mysource is not set, then we are a command-line dependency and should not be added
+ #if --onlydeps is specified.
+ if not self.create(myk,myparent,"--onlydeps" not in myopts,myuse=binpkguseflags):
+ return 0
+
+ if "--debug" in myopts:
+ print "Exiting...",myparent
+ return 1
+
+
+ def altlist(self):
+ mygraph=self.digraph.copy()
+ dolist=["/"]
+ retlist=[]
+ for x in portage.db.keys():
+ portage.db[x]["merge"]=[]
+ if x not in dolist:
+ dolist.append(x)
+ while (not mygraph.empty()):
+ mycurkey=mygraph.firstzero()
+ if not mycurkey:
+ print "!!! Error: circular dependencies:"
+ print
+ for x in mygraph.dict.keys():
+ for y in mygraph.dict[x][1]:
+ print y,"depends on",x
+ print
+ sys.exit(1)
+ splitski=string.split(mycurkey)
+ #I'm not sure of the significance of the following lines (vestigal?) so I'm commenting 'em out.
+ #These lines remove already-merged things from our alt-list
+ #if "--update" in myopts:
+ # if not portage.db["/"]["vartree"].exists_specific(splitski[2]):
+ # portage.db["/"]["merge"].append(splitski)
+ #else:
+ portage.db[splitski[1]]["merge"].append(splitski)
+ mygraph.delnode(mycurkey)
+ for x in dolist:
+ for y in portage.db[x]["merge"]:
+ retlist.append(y)
+ return retlist
+
+ def xcreate(self,mode="system"):
+ global syslist
+ if mode=="system":
+ mylist=syslist
+ else:
+ #world mode
+ worldlist=getlist("world")
+ sysdict=genericdict(syslist)
+ worlddict=genericdict(worldlist)
+ #we're effectively upgrading sysdict to contain all new deps from worlddict
+ for x in worlddict.keys():
+ #only add the world node if the package is:
+ #actually installed -- this prevents the remerging of already unmerged packages when we do a world --update;
+ #actually available -- this prevents emerge from bombing out due to no match being found (we want a silent ignore)
+ if "empty" in myparams:
+ if portage.db["/"]["vartree"].dbapi.match(x):
+ sysdict[x]=worlddict[x]
+ elif portage.db[portage.root]["vartree"].dbapi.match(x):
+ #package is installed
+ sysdict[x]=worlddict[x]
+ else:
+ print "\n*** Package in world file is not installed: "+x
+ mylist = sysdict.keys()
+
+ for mydep in mylist:
+ myeb=portage.portdb.xmatch("bestmatch-visible",mydep)
+ if not myeb:
+ #this is an unavailable world entry; just continue
+ continue
+
+ if "--upgradeonly" in myopts:
+ cand=self.is_newer_ver_installed(portage.root,mydep,myeb)
+ if cand:
+ myeb=cand
+
+ #THIS NEXT BUNCH OF CODE NEEDS TO BE REPLACED TO SUPPORT WORLD ANTI-DEPS
+ #if mydep2[0]=="!":, etc.
+ binpkguseflags = None
+ if "--usepkg" in myopts:
+ mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
+ if myeb==mypk:
+ myk=["binary",portage.root,mypk]
+ binpkguseflags=portage.db[portage.root]["bintree"].get_use(mypk)
+ if ("--newuse" in myopts):
+ iuses=string.split(portage.db["/"]["bintree"].dbapi.aux_get(mypk, ["IUSE"])[0])
+ old_use=string.split(portage.db["/"]["bintree"].dbapi.aux_get(mypk, ["USE"])[0])
+ self.pkgsettings.setcpv(mypk)
+ now_use=string.split(self.pkgsettings["USE"])
+ self.pkgsettings.reset()
+ for x in iuses:
+ if (old_use.count(x) and not now_use.count(x)) or (not old_use.count(x) and now_use.count(x)):
+ myk=["ebuild",portage.root,myeb]
+ binpkguseflags=None
+ break
+ elif "--usepkgonly" in myopts:
+ if not mypk:
+ self.missingbins += [myeb]
+ myk=["binary",portage.root,myeb]
+ else:
+ myk=["binary",portage.root,mypk]
+ else:
+ myk=["ebuild",portage.root,myeb]
+ else:
+ myk=["ebuild",portage.root,myeb]
+
+ if not self.create(myk,myuse=binpkguseflags):
+ print
+ print "!!! Problem with dependencies under ",myk[0],myk[2]
+ print "!!! Possibly a DEPEND/*DEPEND problem."
+ print
+ return 0
+ return 1
+
+ def match(self,mydep,myroot=portage.root,mykey=None):
+ # support mutual exclusive deps
+ mydep2=mydep
+ if mydep2[0]=="!":
+ mydep2=mydep[1:]
+
+ if mydep[0]=="!":
+ #add our blocker; it will be ignored later if necessary (if we are remerging the same pkg, for example)
+ myk="blocks "+myroot+" "+mydep2
+ else:
+ myeb=portage.db[portage.root]["porttree"].dep_bestmatch(mydep2)
+ if not myeb:
+ if not mykey:
+ print "\n!!! Error: couldn't find match for",mydep
+ else:
+ print "\n!!! Error: couldn't find match for",mydep,"in",mykey
+ print
+ sys.exit(1)
+
+ if "--usepkg" in myopts:
+ mypk=portage.db[portage.root]["bintree"].dep_bestmatch(mydep)
+ if myeb==mypk:
+ myk="binary "+portage.root+" "+mypk
+ else:
+ myk="ebuild "+myroot+" "+myeb
+ else:
+ myk="ebuild "+myroot+" "+myeb
+
+ return myk
+
+ def display(self,mylist):
+ changelogs=[]
+ p=[]
+ totalsize=0
+
+ if "--verbose" in myopts:
+ overlays = string.split(portage.settings['PORTDIR_OVERLAY'])
+
+ if "--tree" in myopts:
+ mylist.reverse()
+ mygraph=self.digraph.copy()
+
+ i = 0
+ while i < len(mylist):
+ if mylist[i][-1]=="nomerge":
+ if not ("--tree" in myopts):
+ # we don't care about this elements
+ mylist.pop(i)
+ continue
+ if (i == (len(mylist) - 1)) \
+ or (mygraph.depth(string.join(mylist[i])) \
+ >= mygraph.depth(string.join(mylist[i+1]))):
+ # end of a useless branch (may be the last one)
+ # -> delete the element and test the previous one
+ mylist.pop(i)
+ if i > 0:
+ i -= 1
+ continue
+ # the branch continues, or we've found a good element.
+ # -> let's see what's next, if anything
+ i += 1
+
+ display_overlays=False
+ # files to fetch list - avoids counting a same file twice
+ # in size display (verbose mode)
+ myfetchlist=[]
+ for x in mylist:
+ fetch=" "
+
+ if x[0]=="blocks":
+ addl=""+red("B")+" "+fetch+" "
+ resolved=portage.db[x[1]]["vartree"].resolve_key(x[2])
+ print "["+x[0]+" "+addl+"]",red(resolved),
+ if resolved!=x[2]:
+ if x[3]:
+ print red("(\""+x[2]+"\" is blocking "+x[3]+")")
+ else:
+ print red("(\""+x[2]+"\")")
+ else:
+ if x[3]:
+ print red("(is blocking "+x[3]+")")
+ else:
+ print
+ else:
+ if (x[0]!="binary") and ("fetch" in string.split(portage.portdb.aux_get(x[2],["RESTRICT"])[0])):
+ fetch = red("F")
+ if portage.portdb.fetch_check(x[2], portage.settings):
+ fetch = green("f")
+
+ #we need to use "--emptrytree" testing here rather than "empty" param testing because "empty"
+ #param is used for -u, where you still *do* want to see when something is being upgraded.
+ myoldbest=""
+ if (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific(x[2]):
+ addl=" "+yellow("R")+fetch+" "
+ elif (not "--emptytree" in myopts) and portage.db[x[1]]["vartree"].exists_specific_cat(x[2]):
+ if x[0] == "binary":
+ mynewslot=portage.db["/"]["bintree"].getslot(x[2])
+ elif x[0] == "ebuild":
+ mynewslot=portage.db["/"]["porttree"].getslot(x[2])
+ myoldlist=portage.db[x[1]]["vartree"].dbapi.match(portage.pkgsplit(x[2])[0])
+ myinslotlist=filter((lambda p: portage.db[portage.root]["vartree"].getslot(p)==mynewslot),myoldlist)
+ if myinslotlist:
+ myoldbest=portage.best(myinslotlist)
+ addl=" "+fetch
+ if portage.pkgcmp(portage.pkgsplit(x[2]), portage.pkgsplit(myoldbest)) < 0:
+ # Downgrade in slot
+ addl+=turquoise("U")+blue("D")
+ else:
+ # Update in slot
+ addl+=turquoise("U")+" "
+ else:
+ # New slot, mark it new.
+ addl=" "+green("NS")+fetch+" "
+
+ if "--changelog" in myopts:
+ changelogs.extend(self.calc_changelog(
+ portage.portdb.findname(x[2]),
+ portage.db["/"]["vartree"].dep_bestmatch('/'.join(portage.catpkgsplit(x[2])[:2])),
+ x[2]
+ ))
+ else:
+ addl=" "+green("N")+" "+fetch+" "
+
+ verboseadd=""
+ if "--verbose" in myopts:
+ # iuse verbose
+ try:
+ if x[0] == "binary":
+ iuse_split = string.split(portage.db["/"]["bintree"].dbapi.aux_get(x[2],["IUSE"])[0])
+ elif x[0] == "ebuild":
+ iuse_split = string.split(portage.portdb.aux_get(x[2],["IUSE"])[0])
+ else:
+ iuse_split = []
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ portage.writemsg("!!! Error getting IUSE (report this to bugs.gentoo.org)\n")
+ portage.writemsg("!!! %s\n" % x)
+ iuse_split = []
+ iuse_split.sort()
+ old_use=None
+ if myoldbest:
+ pkg=myoldbest
+ else:
+ pkg=x[2]
+ if portage.db["/"]["vartree"].dbapi.cpv_exists(pkg):
+ try:
+ old_use=string.split(portage.db["/"]["vartree"].dbapi.aux_get(pkg, ["USE"])[0])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ iuse=""
+ now_use=self.applied_useflags[x[2]]
+ for ebuild_iuse in portage_util.unique_array(iuse_split):
+ usechange=""
+ if old_use:
+ if (old_use.count(ebuild_iuse) and not now_use.count(ebuild_iuse)) or (not old_use.count(ebuild_iuse) and now_use.count(ebuild_iuse)):
+ usechange="*"
+
+ if ebuild_iuse in self.applied_useflags[x[2]]:
+ if usechange == "*":
+ iuse=green("+"+ebuild_iuse)
+ else:
+ iuse=red("+"+ebuild_iuse)
+ elif ebuild_iuse in portage.settings.usemask:
+ iuse=blue("(-"+ebuild_iuse+")")
+ else:
+ iuse=blue("-"+ebuild_iuse)
+ verboseadd+=iuse+usechange+" "
+
+ # size verbose
+ mysize=0
+ if x[0] == "ebuild" and x[-1]!="nomerge":
+ myfilesdict=portage.portdb.getfetchsizes(x[2], useflags=self.applied_useflags[x[2]], debug=edebug)
+ if myfilesdict==None:
+ myfilesdict="[empty/missing/bad digest]"
+ else:
+ for myfetchfile in myfilesdict.keys():
+ if myfetchfile not in myfetchlist:
+ mysize+=myfilesdict[myfetchfile]
+ myfetchlist.append(myfetchfile)
+ totalsize+=mysize
+ verboseadd+=format_size(mysize)+" "
+
+ # overlay verbose
+ # XXX: Invalid binaries have caused tracebacks here. 'if file_name'
+ # x = ['binary', '/', 'sys-apps/pcmcia-cs-3.2.7.2.6', 'merge']
+ file_name=portage.portdb.findname(x[2])
+ if file_name: # It might not exist in the tree
+ dir_name=os.path.abspath(os.path.dirname(file_name)+"/../..")
+ if (overlays.count(dir_name)>0):
+ verboseadd+=teal("["+str(overlays.index(os.path.normpath(dir_name))+1)+"]")+" "
+ display_overlays=True
+ else:
+ verboseadd += "[No ebuild?]"
+
+ xs=portage.pkgsplit(x[2])
+ if xs[2]=="r0":
+ xs[2]=""
+ else:
+ xs[2]="-"+xs[2]
+
+ if self.pkgsettings.has_key("COLUMNWIDTH"):
+ mywidth=int(self.pkgsettings.settings["COLUMNWIDTH"])
+ else:
+ mywidth=130
+ oldlp=mywidth-30
+ newlp=oldlp-30
+
+ indent=""
+ if ("--tree" in myopts):
+ indent=" "*mygraph.depth(string.join(x))
+
+ if myoldbest:
+ myoldbest=portage.pkgsplit(myoldbest)[1]+"-"+portage.pkgsplit(myoldbest)[2]
+ if myoldbest[-3:]=="-r0":
+ myoldbest=myoldbest[:-3]
+ myoldbest=blue("["+myoldbest+"]")
+
+ if x[1]!="/":
+ if "--columns" in myopts:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
+ if (newlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(newlp-nc_len(myprint)))
+ myprint=myprint+"["+darkblue(xs[1]+xs[2])+"] "
+ if (oldlp-nc_len(myprint)) > 0:
+ myprint=myprint+" "*(oldlp-nc_len(myprint))
+ myprint=myprint+myoldbest
+ myprint=myprint+darkgreen(" to "+x[1])+" "+verboseadd
+ else:
+ myprint="["+x[0]+" "+addl+"] "+darkgreen(x[2])+" "+myoldbest+" "+darkgreen("to "+x[1])+" "+verboseadd
+ else:
+ if "--columns" in myopts:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(xs[0])
+ if (newlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(newlp-nc_len(myprint)))
+ myprint=myprint+green(" ["+xs[1]+xs[2]+"] ")
+ if (oldlp-nc_len(myprint)) > 0:
+ myprint=myprint+(" "*(oldlp-nc_len(myprint)))
+ myprint=myprint+myoldbest+" "+verboseadd
+ else:
+ if x[3]=="nomerge":
+ myprint=darkblue("[nomerge ] "+indent+x[2]+" "+myoldbest+" ")+verboseadd
+ else:
+ myprint="["+x[0]+" "+addl+"] "+indent+darkgreen(x[2])+" "+myoldbest+" "+verboseadd
+ p.append(myprint)
+
+ if ("--tree" not in myopts):
+ mysplit=portage.pkgsplit(x[2])
+
+ # XXX mysplit _can_ be None.... Why?
+ if mysplit and (len(mysplit)==3):
+ if "--emptytree" not in myopts:
+ if mysplit[0]=="sys-apps/portage":
+ if ((mysplit[1]+mysplit[2]) != portage.VERSION) and \
+ ("livecvsportage" not in portage.settings.features):
+ if mylist.index(x)<len(mylist)-1:
+ p.append(red("*** Portage will stop merging at this point and reload itself,"))
+ p.append(red(" recalculate dependencies, and complete the merge."))
+ if "--update" not in myopts:
+ p.append(darkgreen(" You may avoid the remerging of packages by updating portage on its own."))
+ print
+ else:
+ if mysplit[0]=="sys-apps/portage" and ("--emptytree" in myopts):
+ if mysplit[1]+mysplit[2]!=portage.VERSION:
+ p.append(red("***")+" Please update portage to the above version before proceeding.")
+ p.append(" Failure to do so may result in failed or improper merges.")
+ p.append(" A simple '"+green("emerge -u portage")+"' is sufficient.")
+ p.append("")
+ del mysplit
+
+ for x in p:
+ print x
+
+ if "--verbose" in myopts:
+ print
+ print "Total size of downloads: "+format_size(totalsize)
+ if overlays and display_overlays:
+ print "Portage overlays:"
+ y=0
+ for x in overlays:
+ y=y+1
+ print " "+teal("["+str(y)+"]"),x
+
+ if "--changelog" in myopts:
+ print
+ for revision,text in changelogs:
+ print bold('*'+revision)
+ sys.stdout.write(text)
+
+ def calc_changelog(self,ebuildpath,current,next):
+ current = '-'.join(portage.catpkgsplit(current)[1:])
+ if current.endswith('-r0'): current = current[:-3]
+ next = '-'.join(portage.catpkgsplit(next)[1:])
+ if next.endswith('-r0'): next = next[:-3]
+ changelogpath = os.path.join(os.path.split(ebuildpath)[0],'ChangeLog')
+ try:
+ changelog = open(changelogpath).read()
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ return []
+ divisions = self.find_changelog_tags(changelog)
+ #print 'XX from',current,'to',next
+ #for div,text in divisions: print 'XX',div
+ # skip entries for all revisions above the one we are about to emerge
+ for i in range(len(divisions)):
+ if divisions[i][0]==next:
+ divisions = divisions[i:]
+ break
+ # find out how many entries we are going to display
+ for i in range(len(divisions)):
+ if divisions[i][0]==current:
+ divisions = divisions[:i]
+ break
+ else:
+ # couldnt find the current revision in the list. display nothing
+ return []
+ return divisions
+
+ def find_changelog_tags(self,changelog):
+ divs = []
+ release = None
+ while 1:
+ match = re.search(r'^\*\ ?([-a-zA-Z0-9_.]*)(?:\ .*)?\n',changelog,re.M)
+ if match is None:
+ if release is not None:
+ divs.append((release,changelog))
+ return divs
+ if release is not None:
+ divs.append((release,changelog[:match.start()]))
+ changelog = changelog[match.end():]
+ release = match.group(1)
+ if release.endswith('.ebuild'):
+ release = release[:-7]
+ if release.endswith('-r0'):
+ release = release[:-3]
+
+ def outdated(self):
+ return self.outdatedpackages
+
+ def merge(self,mylist):
+ returnme=0
+ mymergelist=[]
+
+ #check for blocking dependencies
+ if ("--fetchonly" not in myopts) and ("--buildpkgonly" not in myopts):
+ for x in mylist:
+ if x[0]=="blocks":
+ print "\n!!! Error: the "+x[2]+" package conflicts with another package."
+ print "!!! both can't be installed on the same system together."
+ print "!!! Please use 'emerge --pretend' to determine blockers."
+ print
+ if ("--pretend" not in myopts):
+ sys.exit(1)
+
+ #buildsyspkg: I need mysysdict also on resume (moved from the else block)
+ mysysdict=genericdict(syslist)
+ if ("--resume" in myopts):
+ # We're resuming.
+ print green("*** Resuming merge...")
+ emergelog(" *** Resuming merge...")
+ mymergelist=portage.mtimedb["resume"]["mergelist"][:]
+ if ("--skipfirst" in myopts) and mymergelist:
+ del portage.mtimedb["resume"]["mergelist"][0]
+ del mymergelist[0]
+ else:
+ myfavs=portage.grabfile(portage.root+portage.WORLD_FILE)
+ myfavdict=genericdict(myfavs)
+ for x in range(len(mylist)):
+ if mylist[x][3]!="nomerge":
+ # Add to the mergelist
+ mymergelist.append(mylist[x])
+ else:
+ myfavkey=portage.cpv_getkey(mylist[x][2])
+ if "--onlydeps" in myopts:
+ continue
+ # Add to the world file. Since we won't be able to later.
+ if (not "--fetchonly" in myopts) and (myfavkey in favorites):
+ #don't record if already in system profile or already recorded
+ if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
+ #we don't have a favorites entry for this package yet; add one
+ myfavdict[myfavkey]=myfavkey
+ print ">>> Recording",myfavkey,"in \"world\" favorites file..."
+ if not "--fetchonly" in myopts:
+ portage.writedict(myfavdict,portage.root+portage.WORLD_FILE,writekey=0)
+
+ portage.mtimedb["resume"]["mergelist"]=mymergelist[:]
+
+ # We need to yank the harmful-to-new-builds settings from features.
+ myorigfeat=self.pkgsettings["FEATURES"]
+ myfeat=myorigfeat.split()
+ while ("keeptemp" in myfeat):
+ del myfeat[myfeat.index("keeptemp")]
+ while ("keepwork" in myfeat):
+ del myfeat[myfeat.index("keepwork")]
+
+ self.pkgsettings["FEATURES"]=string.join(myfeat)
+
+ mergecount=0
+ if "--fetchonly" in myopts:
+ mynewmergelist = []
+ for x in mymergelist:
+ if x[0] != "blocks":
+ mynewmergelist.append(x)
+ mymergelist = mynewmergelist
+ for x in mymergelist:
+ mergecount+=1
+ myroot=x[1]
+ pkgindex=2
+ if x[0]=="blocks":
+ pkgindex=3
+ y=portage.portdb.findname(x[pkgindex])
+ if not "--pretend" in myopts:
+ print ">>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+")",x[pkgindex],"to",x[1]
+ emergelog(" >>> emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" to "+x[1])
+
+ self.pkgsettings["EMERGE_FROM"] = x[0][:]
+ self.pkgsettings.backup_changes("EMERGE_FROM")
+
+ #buildsyspkg: Check if we need to _force_ binary package creation
+ issyspkg = ("buildsyspkg" in myfeat) \
+ and x[0] != "blocks" \
+ and mysysdict.has_key(portage.cpv_getkey(x[2])) \
+ and not ("--buildpkg" in myopts)
+ if x[0] in ["ebuild","blocks"]:
+ if (x[0]=="blocks") and ("--fetchonly" not in myopts):
+ raise Exception, "Merging a blocker"
+ elif ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
+ if x[0] == "blocks":
+ continue
+ if ("--fetch-all-uri" in myopts):
+ retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1,fetchall=1)
+ else:
+ retval=portage.doebuild(y,"fetch",myroot,self.pkgsettings,edebug,("--pretend" in myopts),fetchonly=1)
+ if (retval == None) or retval:
+ print
+ print "!!! Fetch for",y,"failed, continuing..."
+ print
+ returnme=1
+ continue
+ elif "--buildpkg" in myopts or issyspkg:
+ #buildsyspkg: Sounds useful to display something, but I don't know if we should also log it
+ if issyspkg:
+ print ">>> This is a system package, let's pack a rescue tarball."
+ #emergelog(">>> This is a system package, let's pack a rescue tarball.")
+ #create pkg, then merge pkg
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Packaging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"package",myroot,self.pkgsettings,edebug)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ #dynamically update our database
+ if "--buildpkgonly" not in myopts:
+ portage.db[portage.root]["bintree"].inject(x[2])
+ mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+
+ self.pkgsettings["EMERGE_FROM"] = "binary"
+ self.pkgsettings.backup_changes("EMERGE_FROM")
+
+ retval=portage.pkgmerge(mytbz2,myroot,self.pkgsettings)
+ if retval==None:
+ sys.exit(1)
+ else:
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Compile"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Compiling/Merging ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"merge",myroot,self.pkgsettings,edebug)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+ #dynamically update our database
+ elif x[0]=="binary":
+ #merge the tbz2
+ mytbz2=portage.db[portage.root]["bintree"].getname(x[2])
+ if portage.db[portage.root]["bintree"].isremote(x[2]):
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Fetch"
+ emergelog(" --- ("+str(mergecount)+" of "+str(len(mymergelist))+") Fetching Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
+ portage.db[portage.root]["bintree"].gettbz2(x[2])
+
+ if ("--fetchonly" in myopts) or ("--fetch-all-uri" in myopts):
+ continue
+
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Merge Binary"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Merging Binary ("+x[pkgindex]+"::"+mytbz2+")", short_msg=short_msg)
+ retval=portage.pkgmerge(mytbz2,x[1],self.pkgsettings)
+ if retval==None:
+ sys.exit(1)
+ #need to check for errors
+ if "--buildpkgonly" not in myopts:
+ portage.db[x[1]]["vartree"].inject(x[2])
+ myfavkey=portage.cpv_getkey(x[2])
+ if "--fetchonly" not in myopts and "--fetch-all-uri" not in myopts and myfavkey in favorites:
+ myfavs=portage.grabfile(myroot+portage.WORLD_FILE)
+ myfavdict=genericdict(myfavs)
+ mysysdict=genericdict(syslist)
+ #don't record if already in system profile or already recorded
+ if (not mysysdict.has_key(myfavkey)) and (not myfavdict.has_key(myfavkey)):
+ #we don't have a favorites entry for this package yet; add one
+ myfavdict[myfavkey]=myfavkey
+ print ">>> Recording",myfavkey,"in \"world\" favorites file..."
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Updating world file ("+x[pkgindex]+")")
+ portage.writedict(myfavdict,myroot+portage.WORLD_FILE,writekey=0)
+
+ if ("noclean" not in portage.features) and (x[0] != "binary"):
+ short_msg = "emerge: ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[pkgindex]+" Clean Post"
+ emergelog(" === ("+str(mergecount)+" of "+str(len(mymergelist))+") Post-Build Cleaning ("+x[pkgindex]+"::"+y+")", short_msg=short_msg)
+ retval=portage.doebuild(y,"clean",myroot,self.pkgsettings,edebug,cleanup=1)
+ if (retval == None):
+ portage_util.writemsg("Unable to run required binary.\n")
+ sys.exit(127)
+ if retval:
+ sys.exit(retval)
+
+ if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ # Clean the old package that we have merged over top of it.
+ if self.pkgsettings["AUTOCLEAN"]=="yes":
+ xsplit=portage.pkgsplit(x[2])
+ emergelog(" >>> AUTOCLEAN: "+xsplit[0])
+ retval=unmerge("clean", [xsplit[0]])
+ if not retval:
+ emergelog(" --- AUTOCLEAN: Nothing unmerged.")
+
+ # Figure out if we need a restart.
+ mysplit=portage.pkgsplit(x[2])
+ if mysplit[0]=="sys-apps/portage":
+ myver=mysplit[1]+"-"+mysplit[2]
+ if myver[-3:]=='-r0':
+ myver=myver[:-3]
+ if (myver != portage.VERSION) and \
+ ("livecvsportage" not in portage.settings.features):
+ if len(mymergelist) > mergecount:
+ myargv=sys.argv
+ myr=0
+ for myra in range(len(myargv)):
+ if myargv[myr][0:len("portage")]=="portage":
+ del myargv[myr]
+ myr-=1
+ if myargv[myr][0:len("sys-apps/portage")]=="sys-apps/portage":
+ del myargv[myr]
+ myr-=1
+ myr+=1
+ emergelog(" *** RESTARTING emerge via exec() after change of portage version.")
+ portage.portageexit()
+ # Remove --ask from options before restarting
+ mynewargv=[]
+ badlongopts = ["--ask","--tree","--changelog"]
+ badshortopts = ["a","t","l"]
+ for arg in myargv:
+ if arg[0:2] == "--":
+ if arg in badlongopts:
+ continue
+ mynewargv += [arg]
+ elif arg[0] == "-":
+ myarg = "-"
+ for ch in arg[1:]:
+ if ch in badshortopts:
+ continue
+ myarg += ch
+ mynewargv += [myarg]
+ else:
+ mynewargv += [arg]
+ os.execv("/usr/lib/portage/bin/emerge", mynewargv)
+
+ if ("--pretend" not in myopts) and ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ emergelog(" ::: completed emerge ("+str(mergecount)+" of "+str(len(mymergelist))+") "+x[2]+" to "+x[1])
+
+ # Unsafe for parallel merges
+ del portage.mtimedb["resume"]["mergelist"][0]
+
+ emergelog(" *** Finished. Cleaning up...")
+
+ # We're out of the loop... We're done. Delete the resume data.
+ if portage.mtimedb.has_key("resume"):
+ del portage.mtimedb["resume"]
+
+ if ("--pretend" not in myopts):
+ if ("--fetchonly" not in myopts) and ("--fetch-all-uri" not in myopts):
+ if (mergecount>0):
+ if retval:
+ portage.env_update()
+
+ #by doing an exit this way, --fetchonly can continue to try to
+ #fetch everything even if a particular download fails.
+ if "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
+ if returnme:
+ print "\n\n!!! Some fetch errors were encountered. Please see above for details.\n\n"
+ sys.exit(returnme)
+ else:
+ sys.exit(0)
+
+def unmerge(unmerge_action, unmerge_files):
+ candidate_catpkgs=[]
+ global_unmerge=0
+
+ realsyslist = getlist("system")
+ syslist = []
+ for x in realsyslist:
+ mycp = portage.dep_getkey(x)
+ if mycp in portage.settings.virtuals:
+ syslist.extend(portage.settings.virtuals[mycp])
+ syslist.append(mycp)
+
+ global myopts
+ mysettings = portage.config(clone=portage.settings)
+
+ if not unmerge_files or "world" in unmerge_files or "system" in unmerge_files:
+ if "unmerge"==unmerge_action:
+ print
+ print bold("emerge unmerge")+" can only be used with specific package names, not with "+bold("world")+" or"
+ print bold("system")+" targets."
+ print
+ return 0
+ else:
+ global_unmerge=1
+
+ localtree=portage.db[portage.root]["vartree"]
+ # process all arguments and add all valid db entries to candidate_catpkgs
+ if global_unmerge:
+ if not unmerge_files or "world" in unmerge_files:
+ candidate_catpkgs.extend(localtree.getallnodes())
+ elif "system" in unmerge_files:
+ candidate_catpkgs.extend(getlist("system"))
+ else:
+ #we've got command-line arguments
+ if not unmerge_files:
+ print "\nNo packages to unmerge have been provided.\n"
+ return 0
+ for x in unmerge_files:
+ arg_parts=x.split('/')
+ if (x[0] not in [".","/"]) and (arg_parts[-1][-7:] != ".ebuild"):
+ #possible cat/pkg or dep; treat as such
+ candidate_catpkgs.append(x)
+ elif unmerge_action in ["prune","clean"]:
+ print "\n!!! Prune and clean do not accept individual ebuilds as arguments;\n skipping.\n"
+ continue
+ else:
+ # it appears that the user is specifying an installed ebuild and we're in "unmerge" mode, so it's
+ # ok.
+ if not os.path.exists(x):
+ print "\n!!! The path '"+x+"' doesn't exist.\n"
+ return 0
+
+ absx = os.path.abspath(x)
+ sp_absx = absx.split("/")
+ if sp_absx[-1][-7:] == ".ebuild":
+ del sp_absx[-1]
+ absx = string.join(sp_absx,"/")
+
+ sp_absx_len = len(sp_absx)
+
+ vdb_path = portage.root+portage.VDB_PATH
+ vdb_len = len(vdb_path)
+
+ sp_vdb = vdb_path.split("/")
+ sp_vdb_len = len(sp_vdb)
+
+ if not os.path.exists(absx+"/CONTENTS"):
+ print "!!! Not a valid db dir: "+str(absx)
+ return 0
+
+ if sp_absx_len <= sp_vdb_len:
+ # The Path is shorter... so it can't be inside the vdb.
+ print spabsx
+ print absx
+ print "\n!!!",x,"cannot be inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
+ return 0
+
+ for idx in range(0,sp_vdb_len):
+ if (idx >= sp_absx_len) or (sp_vdb[idx] != sp_absx[idx]):
+ print sp_absx
+ print absx
+ print "\n!!!",x,"is not inside "+(portage.root+portage.VDB_PATH)+"; aborting.\n"
+ return 0
+
+ print "="+string.join(sp_absx[sp_vdb_len:],"/")
+ candidate_catpkgs.append("="+string.join(sp_absx[sp_vdb_len:],"/"))
+
+ if ("--pretend" in myopts) or ("--ask" in myopts):
+ print darkgreen("\n>>> These are the packages that I would unmerge:")
+
+ pkgmap={}
+ numselected=0
+ for x in candidate_catpkgs:
+ #cycle through all our candidate deps and determine what will and will not get unmerged
+ try:
+ mymatch=localtree.dep_match(x)
+ except KeyError:
+ mymatch=None
+ except ValueError, errpkgs:
+ print "\n\n!!! The short ebuild name \"" + x + "\" is ambiguous. Please specify"
+ print "!!! one of the following fully-qualified ebuild names instead:\n"
+ for i in errpkgs[0]:
+ print " " + green(i)
+ print
+ sys.exit(1)
+
+ if not mymatch and x[0] not in "<>=~":
+ #add a "=" if missing
+ mymatch=localtree.dep_match("="+x)
+ if not mymatch:
+ print "\n--- Couldn't find " + white(x) + " to "+unmerge_action+"."
+ continue
+ mykey=portage.key_expand(portage.dep_getkey(mymatch[0]),portage.db["/"]["vartree"].dbapi)
+ if not pkgmap.has_key(mykey):
+ pkgmap[mykey]={"protected":[], "selected":[], "omitted":[] }
+ if unmerge_action=="unmerge":
+ for y in mymatch:
+ if y not in pkgmap[mykey]["selected"]:
+ pkgmap[mykey]["selected"].append(y)
+ numselected=numselected+len(mymatch)
+
+ else:
+ #unmerge_action in ["prune", clean"]
+ slotmap={}
+ for mypkg in mymatch:
+ if unmerge_action=="clean":
+ myslot=localtree.getslot(mypkg)
+ else:
+ #since we're pruning, we don't care about slots and put all the pkgs in together
+ myslot=0
+ if not slotmap.has_key(myslot):
+ slotmap[myslot]={}
+ slotmap[myslot][localtree.dbapi.cpv_counter(mypkg)]=mypkg
+ for myslot in slotmap.keys():
+ counterkeys=slotmap[myslot].keys()
+ counterkeys.sort()
+ if not counterkeys:
+ continue
+ counterkeys.sort()
+ pkgmap[mykey]["protected"].append(slotmap[myslot][counterkeys[-1]])
+ del counterkeys[-1]
+ #be pretty and get them in order of merge:
+ for ckey in counterkeys:
+ pkgmap[mykey]["selected"].append(slotmap[myslot][ckey])
+ numselected=numselected+1
+ #ok, now the last-merged package is protected, and the rest are selected
+ if global_unmerge and not numselected:
+ print "\n>>> No outdated packages were found on your system.\n"
+ return 0
+
+ if not numselected:
+ print "\n>>>",unmerge_action+": No packages selected for removal.\n"
+ return 0
+
+ for x in pkgmap.keys():
+ for y in localtree.dep_match(x):
+ if y not in pkgmap[x]["omitted"] and \
+ y not in pkgmap[x]["selected"] and \
+ y not in pkgmap[x]["protected"]:
+ pkgmap[x]["omitted"].append(y)
+ if global_unmerge and not pkgmap[x]["selected"]:
+ #avoid cluttering the preview printout with stuff that isn't getting unmerged
+ continue
+ if not (pkgmap[x]["protected"] or pkgmap[x]["omitted"]) and (x in syslist):
+ print red("\a\n\n!!! '%s' is part of your system profile. '%s'" % (mykey))
+ print yellow("\a!!! Unmerging it may be damaging to your system.\n")
+ if "--pretend" not in myopts and "--ask" not in myopts:
+ global EMERGE_WARNING_DELAY
+ countdown(EMERGE_WARNING_DELAY,red("Press Ctrl-C to Stop"))
+ print "\n "+white(x)
+ for mytype in ["selected","protected","omitted"]:
+ print string.rjust(mytype,12)+":",
+ if pkgmap[x][mytype]:
+ for mypkg in pkgmap[x][mytype]:
+ mysplit=portage.catpkgsplit(mypkg)
+ if mysplit[3]=="r0":
+ myversion=mysplit[2]
+ else:
+ myversion=mysplit[2]+"-"+mysplit[3]
+ if mytype=="selected":
+ print red(myversion),
+ else:
+ print green(myversion),
+ else:
+ print "none",
+ print
+
+ print "\n>>>",red("'Selected'"),"packages are slated for removal."
+ print ">>>",green("'Protected'"),"and",green("'omitted'"),"packages will not be removed.\n"
+
+ if "--pretend" in myopts:
+ #we're done... return
+ return 0
+ if "--ask" in myopts:
+ if userquery("Do you want me to unmerge these packages?")=="No":
+ # enter pretend mode for correct formatting of results
+ myopts+=["--pretend"]
+ print
+ print "Quitting."
+ print
+ return 0
+ #the real unmerging begins, after a short delay....
+
+ global CLEAN_DELAY
+ countdown(CLEAN_DELAY, ">>> Unmerging")
+
+ for x in pkgmap.keys():
+ for y in pkgmap[x]["selected"]:
+ print ">>> Unmerging "+y+"..."
+ emergelog("=== Unmerging... ("+y+")")
+ mysplit=string.split(y,"/")
+ #unmerge...
+ retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,mysettings,unmerge_action not in ["clean","prune"])
+ if retval:
+ emergelog(" !!! unmerge FAILURE: "+y)
+ else:
+ emergelog(" >>> unmerge success: "+y)
+ #run ldconfig, etc...
+ portage.env_update()
+ if not numselected:
+ return 0
+ else:
+ return 1
+
+
+def chk_updated_info_files(retval):
+ root=portage.root
+
+ infodirs=[]
+ infodirs.extend(string.split(portage.settings["INFOPATH"], ":"))
+ infodirs.extend(string.split(portage.settings["INFODIR"], ":"))
+
+ print
+ if os.path.exists("/usr/bin/install-info"):
+ regen_infodirs=[]
+ for z in infodirs:
+ if z=='':
+ continue
+ inforoot=normpath(root+z)
+ if os.path.isdir(inforoot):
+ try:
+ infomtime=os.stat(inforoot)[ST_MTIME]
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ infomtime=0
+
+ if not portage.mtimedb.has_key("info"):
+ portage.mtimedb["info"]={}
+ if portage.mtimedb["info"].has_key(inforoot):
+ if portage.mtimedb["info"][inforoot]==infomtime:
+ pass
+ else:
+ portage.mtimedb["info"][inforoot]=infomtime
+ regen_infodirs.append(inforoot)
+ else:
+ regen_infodirs.append(inforoot)
+
+ if not regen_infodirs:
+ print " "+green("*")+" GNU info directory index is up-to-date."
+ else:
+ print " "+green("*")+" Regenerating GNU info directory index..."
+
+ icount=0
+ badcount=0
+ for inforoot in regen_infodirs:
+ if inforoot=='':
+ continue
+ try:
+ os.rename(inforoot+"/dir",inforoot+"/dir.old")
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ if not os.path.isdir(inforoot):
+ continue
+ errmsg = ""
+ for x in os.listdir(inforoot):
+ if (x[0] == ".") or (x in ["dir","dir.old"]) or (os.path.isdir(inforoot+"/"+x)):
+ continue
+ myso=commands.getstatusoutput("LANG=C LANGUAGE=C /usr/bin/install-info --dir-file="+inforoot+"/dir "+inforoot+"/"+x)[1]
+ existsstr="already exists, for file `"
+ if myso!="":
+ if re.search(existsstr,myso):
+ # Already exists... Don't increment the count for this.
+ pass
+ elif myso[:44]=="install-info: warning: no info dir entry in ":
+ # This info file doesn't contain a DIR-header: install-info produces this
+ # (harmless) warning (the --quiet switch doesn't seem to work).
+ # Don't increment the count for this.
+ pass
+ else:
+ badcount=badcount+1
+ errmsg += myso + "\n"
+ icount=icount+1
+
+ #update mtime so we can potentially avoid regenerating.
+ portage.mtimedb["info"][inforoot]=os.stat(inforoot)[ST_MTIME]
+
+ if badcount:
+ print " "+yellow("*")+" Processed",icount,"info files;",badcount,"errors."
+ print errmsg
+ else:
+ print " "+green("*")+" Processed",icount,"info files."
+
+
+def post_emerge(retval=0):
+ global myopts
+ os.chdir("/")
+ if "--pretend" in myopts:
+ sys.exit(retval)
+
+ emergelog(" *** exiting successfully.")
+
+ if "noinfo" not in portage.settings.features:
+ chk_updated_info_files(retval)
+
+ chk_updated_cfg_files()
+ sys.exit(retval)
+
+
+def chk_updated_cfg_files():
+ if portage.settings["CONFIG_PROTECT"]:
+ #number of directories with some protect files in them
+ procount=0
+ for x in string.split(portage.settings["CONFIG_PROTECT"]):
+ if os.path.isdir(x):
+ a=commands.getstatusoutput("cd "+x+"; find . -iname '._cfg????_*'")
+ if a[0]!=0:
+ print " "+red("*")+" error scanning",x
+ else:
+ files=string.split(a[1])
+ if files:
+ procount=procount+1
+ print " "+yellow("* IMPORTANT:")+"",len(files),"config files in",x,"need updating."
+ if procount:
+ #print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
+ print " "+yellow("*")+" Type "+green("emerge --help config")+" to learn how to update config files."
+ print
+
+# general options that should be taken into account before any action
+if "--debug" in myopts:
+ edebug=1
+
+if myaction in ["sync","rsync","metadata"] and (not "--help" in myopts):
+ if "--pretend" in myopts:
+ print "emerge: \"sync\" actions do not support \"--pretend.\""
+ sys.exit(1)
+
+ emergelog(" === "+str(myaction))
+ myportdir=portage.settings["PORTDIR"]
+ if myportdir[-1]=="/":
+ myportdir=myportdir[:-1]
+ if not os.path.exists(myportdir):
+ print ">>>",myportdir,"not found, creating it."
+ os.makedirs(myportdir,0755)
+ syncuri=string.rstrip(portage.settings["SYNC"])
+ os.umask(0022)
+ if myaction == "metadata":
+ if "--ask" in myopts:
+ if userquery("Are you sure?") == "No":
+ sys.exit(1)
+ print "skipping sync"
+ updatecache_flg = True
+ tmpservertimestampfile = None
+ elif syncuri[:8]=="rsync://":
+ if not os.path.exists("/usr/bin/rsync"):
+ print "!!! /usr/bin/rsync does not exist, so rsync support is disabled."
+ print "!!! Type \"emerge net-misc/rsync\" to enable rsync support."
+ sys.exit(1)
+ mytimeout=180
+ if portage.settings.has_key("RSYNC_TIMEOUT"):
+ try:
+ mytimeout=int(portage.settings["RSYNC_TIMEOUT"])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ rsync_flags = [
+ "--recursive", # Recurse directories
+ "--links", # Consider symlinks
+ "--safe-links", # Ignore links outside of tree
+ "--perms", # Preserve permissions
+ "--times", # Preserive mod times
+ "--compress", # Compress the data transmitted
+ "--force", # Force deletion on non-empty dirs
+ "--whole-file", # Don't do block transfers, only entire files
+ "--delete", # Delete files that aren't in the master tree
+ "--delete-after", # Delete only after everything else is done
+ "--stats", # Show final statistics about what was transfered
+ "--timeout="+str(mytimeout), # IO timeout if not done in X seconds
+ "--exclude='/distfiles'", # Exclude distfiles from consideration
+ "--exclude='/local'", # Exclude local from consideration
+ "--exclude='/packages'", # Exclude packages from consideration
+ ]
+
+ if "--quiet" in myopts:
+ rsync_flags.append("--quiet") # Shut up a lot
+ else:
+ rsync_flags.append("--progress") # Progress meter for each file
+
+ if "--verbose" in myopts:
+ rsync_flags.append("--verbose") # More noise? Not really sure what
+
+ if "--debug" in myopts:
+ rsync_flags.append("--checksum") # Force checksum on all files
+
+ if portage.settings.has_key("RSYNC_EXCLUDEFROM"):
+ if os.path.exists(portage.settings["RSYNC_EXCLUDEFROM"]):
+ rsync_flags.append("--exclude-from="+portage.settings["RSYNC_EXCLUDEFROM"])
+ else:
+ print "!!! RSYNC_EXCLUDEFROM specified, but file does not exist."
+
+ if portage.settings.has_key("RSYNC_RATELIMIT"):
+ rsync_flags.append("--bwlimit="+portage.settings["RSYNC_RATELIMIT"])
+
+ rsynccommand = "/usr/bin/rsync " + string.join(rsync_flags, " ")
+
+ servertimestampdir = portage.settings.depcachedir+"/"
+ servertimestampfile = portage.settings.depcachedir+"/timestamp.chk"
+ tmpservertimestampdir = portage.settings["PORTAGE_TMPDIR"]+"/"
+ tmpservertimestampfile = portage.settings["PORTAGE_TMPDIR"]+"/timestamp.chk"
+
+ # We only use the backup if a timestamp exists in the portdir.
+ content=None
+ if os.path.exists(myportdir+"/metadata/timestamp.chk"):
+ content=portage.grabfile(servertimestampfile)
+ if (not content):
+ content=portage.grabfile(myportdir+"/metadata/timestamp.chk")
+
+ if (content):
+ try:
+ mytimestamp=time.mktime(time.strptime(content[0], "%a, %d %b %Y %H:%M:%S +0000"))
+ except ValueError:
+ mytimestamp=0
+ else:
+ mytimestamp=0
+
+ if not os.path.exists(servertimestampdir):
+ os.mkdir(servertimestampdir)
+ os.chown(servertimestampdir, os.getuid(), portage.portage_gid)
+ os.chmod(servertimestampdir, 02775)
+
+ #exitcode=0
+ try:
+ maxretries=int(portage.settings["RSYNC_RETRIES"])
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ maxretries=3 #default number of retries
+
+ retries=0
+ hostname, port=re.split("rsync://([^:/]*)(:[0-9]+)?", syncuri)[1:3];
+ if port==None:
+ port=""
+ updatecache_flg=True
+
+ ips=[]
+ while (1):
+ if ips:
+ del ips[0]
+ if ips==[]:
+ try:
+ ips=socket.gethostbyname_ex(hostname)[2]
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Notice:",str(e)
+ dosyncuri=syncuri
+
+ if ips:
+ try:
+ dosyncuri=string.replace(syncuri, "//"+hostname+port+"/", "//"+ips[0]+port+"/", 1)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "Notice:",str(e)
+ dosyncuri=syncuri
+
+ if (retries==0):
+ if "--ask" in myopts:
+ if userquery("Do you want to sync your Portage tree with the mirror at\n" + blue(dosyncuri) + bold("?"))=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ emergelog(">>> starting rsync with "+dosyncuri)
+ if "--quiet" not in myopts:
+ print ">>> starting rsync with "+dosyncuri+"..."
+ else:
+ emergelog(">>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri))
+ print "\n\n>>> Starting retry %d of %d with %s" % (retries,maxretries,dosyncuri)
+
+ if "--quiet" not in myopts:
+ print ">>> checking server timestamp ..."
+ mycommand=rsynccommand+" "+dosyncuri+"/metadata/timestamp.chk "+tmpservertimestampdir
+ exitcode=portage.spawn(mycommand,portage.settings,free=1)
+ if (exitcode==0):
+ try:
+ servertimestamp = time.mktime(time.strptime(portage.grabfile(tmpservertimestampfile)[0], "%a, %d %b %Y %H:%M:%S +0000"))
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ servertimestamp = 0
+
+ if (servertimestamp != 0) and (servertimestamp == mytimestamp):
+ emergelog(">>> Cancelling sync -- Already current.")
+ print
+ print ">>>"
+ print ">>> Timestamps on the server and in the local repository are the same."
+ print ">>> Cancelling all further sync action. You are already up to date."
+ print ">>>"
+ print
+ sys.exit(0)
+ elif (servertimestamp != 0) and (servertimestamp < mytimestamp):
+ emergelog(">>> Server out of date: %s" % dosyncuri)
+ print
+ print ">>>"
+ print ">>> SERVER OUT OF DATE: %s" % dosyncuri
+ print ">>>"
+ print
+ elif (servertimestamp == 0) or (servertimestamp > mytimestamp):
+ # actual sync
+ mycommand=rsynccommand+" "+dosyncuri+"/ "+myportdir
+ exitcode=portage.spawn(mycommand,portage.settings,free=1)
+ if exitcode in [0,1,2,3,4,11,14,20,21]:
+ break
+ elif exitcode in [0,1,2,3,4,11,14,20,21]:
+ break
+
+ retries=retries+1
+
+ if retries<=maxretries:
+ print ">>> retry ..."
+ time.sleep(11)
+ else:
+ # over retries
+ # exit loop
+ updatecache_flg=False
+ break
+
+ if (exitcode==0):
+ emergelog("=== Sync completed with %s" % dosyncuri)
+ elif (exitcode>0):
+ print
+ if exitcode==1:
+ print darkred("!!!")+green(" Rsync has reported that there is a syntax error. Please ensure")
+ print darkred("!!!")+green(" that your SYNC statement is proper.")
+ print darkred("!!!")+green(" SYNC="+portage.settings["SYNC"])
+ elif exitcode==11:
+ print darkred("!!!")+green(" Rsync has reported that there is a File IO error. Normally")
+ print darkred("!!!")+green(" this means your disk is full, but can be caused by corruption")
+ print darkred("!!!")+green(" on the filesystem that contains PORTDIR. Please investigate")
+ print darkred("!!!")+green(" and try again after the problem has been fixed.")
+ print darkred("!!!")+green(" PORTDIR="+portage.settings["PORTDIR"])
+ elif exitcode==20:
+ print darkred("!!!")+green(" Rsync was killed before it finished.")
+ else:
+ print darkred("!!!")+green(" Rsync has not successfully finished. It is recommended that you keep")
+ print darkred("!!!")+green(" trying or that you use the 'emerge-webrsync' option if you are unable")
+ print darkred("!!!")+green(" to use rsync due to firewall or other restrictions. This should be a")
+ print darkred("!!!")+green(" temporary problem unless complications exist with your network")
+ print darkred("!!!")+green(" (and possibly your system's filesystem) configuration.")
+ print
+ sys.exit(exitcode)
+ elif syncuri[:6]=="cvs://":
+ if not os.path.exists("/usr/bin/cvs"):
+ print "!!! /usr/bin/cvs does not exist, so rsync support is disabled."
+ print "!!! Type \"emerge dev-util/cvs\" to enable CVS support."
+ sys.exit(1)
+ cvsroot=syncuri[6:]
+ cvsdir=os.path.dirname(myportdir)
+ if not os.path.exists(myportdir+"/CVS"):
+ #initial checkout
+ print ">>> starting initial cvs checkout with "+syncuri+"..."
+ if not portage.spawn("cd "+cvsdir+"; cvs -d "+cvsroot+" login",portage.settings,free=1):
+ print "!!! cvs login error; exiting."
+ sys.exit(1)
+ if os.path.exists(cvsdir+"/gentoo-x86"):
+ print "!!! existing",cvsdir+"/gentoo-x86 directory; exiting."
+ sys.exit(1)
+ if not portage.spawn("cd "+cvsdir+"; cvs -z0 -d "+cvsroot+" co -P gentoo-x86",portage.settings,free=1):
+ print "!!! cvs checkout error; exiting."
+ sys.exit(1)
+ if cvsdir!=myportdir:
+ portage.movefile(cvsdir,portage.settings["PORTDIR"])
+ sys.exit(0)
+ else:
+ #cvs update
+ print ">>> starting cvs update with "+syncuri+"..."
+ sys.exit(portage.spawn("cd "+myportdir+"; cvs -z0 -q update -dP",portage.settings,free=1))
+ else:
+ print "!!! rsync setting: ",syncuri,"not recognized; exiting."
+ sys.exit(1)
+
+ try: # Prevent users from affecting ebuild.sh.
+ os.close(sys.stdin.fileno())
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+
+ if os.path.exists(myportdir+"/metadata/cache") and updatecache_flg:
+ if "--quiet" not in myopts:
+ print "\n>>> Updating Portage cache: ",
+ os.umask(0002)
+ cachedir = os.path.normpath(portage.settings.depcachedir)
+ if cachedir in ["/", "/bin", "/dev", "/etc", "/home",
+ "/lib", "/opt", "/proc", "/root", "/sbin",
+ "/sys", "/tmp", "/usr", "/var"]:
+ print "!!! PORTAGE_CACHEDIR IS SET TO A PRIMARY ROOT DIRECTORY ON YOUR SYSTEM."
+ print "!!! This is ALMOST CERTAINLY NOT what you want: "+str(cachedir)
+ sys.exit(73)
+ if not os.path.exists(cachedir):
+ os.mkdir(cachedir)
+
+ # Potentially bad
+ #if os.path.exists(cachedir+"/"+myportdir):
+ # portage.spawn("rm -Rf "+cachedir+"/"+myportdir+"/*",portage.settings,free=1)
+
+ # save timestamp.chk for next timestamp check.
+ try:
+ if tmpservertimestampfile != None:
+ portage.movefile(tmpservertimestampfile, servertimestampfile)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except Exception, e:
+ print "!!! Failed to save current timestamp."
+ print "!!!",e
+
+ portage.portdb.flush_cache()
+
+ try:
+ os.umask(002)
+ os.chown(cachedir, os.getuid(), portage.portage_gid)
+ os.chmod(cachedir, 02775)
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ # we don't make overlay trees cache here.
+ backup_porttrees=portage.portdb.porttrees
+ porttree_root = portage.portdb.porttree_root
+ portage.portdb.porttrees=[porttree_root]
+ cp_list=portage.portdb.cp_all()
+ cp_list.sort()
+ pcnt=0
+ pcntstr=""
+ pcntcount=len(cp_list)/100.0
+ nextupdate=pcntcount
+ current=1
+ def cleanse_cache(cat, saves, porttree_root=porttree_root):
+ if len(saves):
+ d={}
+ for v in saves:
+ d[portage.catsplit(v)[1]] = True
+ for pv in portage.db["/"]["porttree"].dbapi.auxdb[porttree_root][cat].keys():
+ if pv not in d:
+ portage.db["/"]["porttree"].dbapi.auxdb[porttree_root][cat].del_key(pv)
+ else:
+ portage.db["/"]["porttree"].dbapi.auxdb[porttree_root][cat].clear()
+ del portage.db["/"]["porttree"].dbapi.auxdb[porttree_root][cat]
+ savelist = []
+ catlist = []
+ oldcat = portage.catsplit(cp_list[0])[0]
+ for cp in cp_list:
+ current += 1
+ if current >= nextupdate:
+ pcnt += 1
+ nextupdate += pcntcount
+ if "--quiet" not in myopts:
+ pcntstr = str(pcnt)
+ sys.stdout.write("\b"*(len(pcntstr)+1)+pcntstr+"%")
+ sys.stdout.flush()
+ cat = portage.catsplit(cp)[0]
+ if cat != oldcat:
+ catlist.append(oldcat)
+ cleanse_cache(oldcat, savelist)
+ savelist = []
+ oldcat = cat
+ mymatches = portage.db["/"]["porttree"].dbapi.xmatch("match-all", cp)
+ savelist.extend(mymatches)
+ for cpv in mymatches:
+ try: portage.db["/"]["porttree"].dbapi.aux_get(cpv, ["IUSE"],metacachedir=myportdir+"/metadata/cache",debug=("cachedebug" in portage.features))
+ except SystemExit: raise
+ except Exception, e: print "\nFailed cache update:",cpv,e
+ catlist.append(oldcat)
+ catlist.append("local")
+ cleanse_cache(oldcat, savelist)
+ filelist = portage.listdir(cachedir+"/"+myportdir)
+ for x in filelist:
+ found = False
+ for y in catlist:
+ if x.startswith(y):
+ found = True
+ break
+ if not found:
+ portage.spawn("cd /; rm -Rf "+cachedir+"/"+myportdir+"/"+x,portage.settings,free=1,droppriv=1)
+
+
+ portage.portdb.porttrees=backup_porttrees
+ sys.stdout.write("\n\n")
+ sys.stdout.flush()
+
+ portage.portageexit()
+ reload(portage)
+ mybestpv=portage.portdb.xmatch("bestmatch-visible","sys-apps/portage")
+ mypvs=portage.best(portage.db[portage.root]["vartree"].dbapi.match("sys-apps/portage"))
+
+ chk_updated_cfg_files()
+
+ if(mybestpv != mypvs):
+ print
+ print red(" * ")+bold("An update to portage is available.")+" It is _highly_ recommended"
+ print red(" * ")+"that you update portage now, before any other packages are updated."
+ print red(" * ")+"Please do so and then update "+bold("ALL")+" of your configuration files."
+ print
+elif myaction=="regen":
+ emergelog(" === regen")
+ #regenerate cache entries
+ print "Regenerating cache entries... "
+ try:
+ os.close(sys.stdin.fileno())
+ except SystemExit, e:
+ raise # Needed else can't exit
+ except:
+ pass
+ sys.stdout.flush()
+ mynodes=portage.portdb.cp_all()
+ for x in mynodes:
+ mymatches=portage.portdb.xmatch("match-all",x)
+ if not "--quiet" in myopts:
+ print "processing",x
+ for y in mymatches:
+ try:
+ foo=portage.portdb.aux_get(y,["DEPEND"],debug=1)
+ except SystemExit, e:
+ # sys.exit is an exception... And consequently, we can't catch it.
+ raise
+ except Exception, e:
+ print "\n error processing %(cpv)s, continuing... (%(e)s)" % {"cpv":y,"e":str(e)}
+ print "done!"
+# HELP action
+elif "config"==myaction:
+ if len(myfiles) != 1 or "system" in myfiles or "world" in myfiles:
+ print red("!!! config can only take a single package atom at this time\n")
+ sys.exit(1)
+
+ print
+ pkgs = portage.db[portage.root]["vartree"].dbapi.match(myfiles[0])
+ if len(pkgs) == 0:
+ print "No packages found.\n"
+ sys.exit(0)
+ elif len(pkgs) > 1:
+ if "--ask" in myopts:
+ options = []
+ print "Please select a package to configure:"
+ idx = 0
+ for pkg in pkgs:
+ idx += 1
+ options.append(str(idx))
+ print options[-1]+") "+pkg
+ print "X) Cancel"
+ options.append("X")
+ idx = userquery("Selection?", options)
+ if idx == "X":
+ sys.exit(0)
+ pkg = pkgs[int(idx)-1]
+ else:
+ print "The following packages available:"
+ for pkg in pkgs:
+ print "* "+pkg
+ print "\nPlease use a specific atom or the --ask option."
+ sys.exit(1)
+ else:
+ pkg = pkgs[0]
+
+ print
+ if "--ask" in myopts:
+ if userquery("Ready to configure "+pkg+"?") == "No":
+ sys.exit(0)
+ else:
+ print "Configuring pkg..."
+ print
+ ebuildpath = portage.db[portage.root]["vartree"].dbapi.findname(pkg)
+ mysettings = portage.config(clone=portage.settings)
+ portage.doebuild(ebuildpath,"config",portage.root,mysettings,debug=("--debug" in myopts),cleanup=True)
+ print
+
+# INFO action
+elif "info"==myaction:
+ unameout=commands.getstatusoutput("uname -mrp")[1]
+ print getportageversion()
+ print "================================================================="
+ print "System uname: "+unameout
+ if os.path.exists("/etc/gentoo-release"):
+ os.system("cat /etc/gentoo-release")
+ else:
+ print "Unknown Host Operating System"
+
+ output=commands.getstatusoutput("distcc --version")
+ if not output[0]:
+ print str(string.split(output[1],"\n",1)[0]),
+ if "distcc" in portage.features:
+ print "[enabled]"
+ else:
+ print "[disabled]"
+
+ output=commands.getstatusoutput("ccache -V")
+ if not output[0]:
+ print str(string.split(output[1],"\n",1)[0]),
+ if "ccache" in portage.features:
+ print "[enabled]"
+ else:
+ print "[disabled]"
+
+ myvars = ["sys-devel/autoconf", "sys-devel/automake", "virtual/os-headers",
+ "sys-devel/binutils", "sys-devel/libtool", "dev-lang/python"]
+ myvars += portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_pkgs")
+ myvars = portage_util.unique_array(myvars)
+ myvars.sort()
+
+ for x in myvars:
+ if portage.isvalidatom(x):
+ pkg_matches = portage.db["/"]["vartree"].dbapi.match(x)
+ pkgs = []
+ for y in pkg_matches:
+ mycpv = portage.catpkgsplit(y)
+ if(mycpv[3] != "r0"):
+ pkgs += [mycpv[2] + "-" + mycpv[3]]
+ else:
+ pkgs += [mycpv[2]]
+ if not pkgs:
+ pkgs = "[Not Present]"
+ else:
+ pkgs = ", ".join(sorted_versions(pkgs))
+ print "%-20s %s" % (x+":", pkgs)
+ else:
+ print "%-20s %s" % (x+":", "[NOT VALID]")
+
+ libtool_vers = string.join(portage.db["/"]["vartree"].dbapi.match("sys-devel/libtool"), ",")
+
+ if "--verbose" in myopts:
+ myvars=portage.settings.keys()
+ else:
+ myvars = ['GENTOO_MIRRORS', 'CONFIG_PROTECT', 'CONFIG_PROTECT_MASK',
+ 'PORTDIR', 'DISTDIR', 'PKGDIR', 'PORTAGE_TMPDIR',
+ 'PORTDIR_OVERLAY', 'USE', 'CHOST', 'CFLAGS', 'CXXFLAGS',
+ 'ACCEPT_KEYWORDS', 'SYNC', 'FEATURES']
+
+ myvars.extend(portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars"))
+
+ myvars = portage_util.unique_array(myvars)
+ unset_vars = []
+ myvars.sort()
+ for x in myvars:
+ if portage.settings.has_key(x):
+ print x+'="'+portage.settings[x]+'"'
+ else:
+ unset_vars.append(x)
+ if unset_vars:
+ print "Unset: "+", ".join(unset_vars)
+ print
+
+ if "--debug" in myopts:
+ for x in dir(portage):
+ module = getattr(portage, x)
+ if "cvs_id_string" in dir(module):
+ print "%s: %s" % (str(x), str(module.cvs_id_string))
+
+# SEARCH action
+elif "search"==myaction:
+ if not myfiles:
+ print "emerge: no search terms provided."
+ else:
+ searchinstance = search()
+ for mysearch in myfiles:
+ try:
+ searchinstance.execute(mysearch)
+ except re.error, comment:
+ print "\n!!! Regular expression error in \"%s\": %s" % ( mysearch, comment )
+ sys.exit(1)
+ searchinstance.output()
+elif "inject"==myaction:
+ if not myfiles:
+ print "emerge: please specify at least one cat/pkg-ver to inject."
+ sys.exit(1)
+ if "--pretend" in myopts:
+ print "emerge: the \"inject\" action does not support \"--pretend.\""
+ sys.exit(1)
+ for x in myfiles:
+ if x[0] in [">","<","=","!"]:
+ print "!!! '"+x+"' is an invalid specification."
+ print "!!! Must be 'category/package-version' with no other symbols."
+ print
+ continue
+ mycps=portage.catpkgsplit(x)
+ if (not mycps) or (mycps[0]=="null"):
+ print "!!!",x,"is not a specific cat/pkg-version, skipping..."
+ continue
+ if portage.db["/"]["vartree"].exists_specific(x):
+ print "!!! Not injecting",x+"; Package already exists."
+ else:
+ if "--ask" in myopts:
+ if userquery("Do you want to inject the package %s?" % x)=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ portage.db["/"]["vartree"].dbapi.cpv_inject(x)
+ print ">>> Injected",x+"."
+ emergelog(" === inject: "+x)
+elif "unmerge"==myaction or "prune"==myaction or "clean"==myaction:
+ if 1==unmerge(myaction, myfiles):
+ post_emerge()
+
+elif "depclean"==myaction:
+ # Kill packages that aren't explicitly merged or are required as a
+ # dependency of another package. World file is explicit.
+
+ print
+ print red("*** WARNING ***")+" : DEPCLEAN CAN SERIOUSLY IMPAIR YOUR SYSTEM. USE CAUTION."
+ print red("*** WARNING ***")+" : (Cancel: CONTROL-C) -- ALWAYS VERIFY ALL PACKAGES IN THE"
+ print red("*** WARNING ***")+" : CANDIDATE LIST FOR SANITY BEFORE ALLOWING DEPCLEAN TO"
+ print red("*** WARNING ***")+" : UNMERGE ANY PACKAGES."
+ print red("*** WARNING ***")+" :"
+ print red("*** WARNING ***")+" : USE FLAGS MAY HAVE AN EXTREME EFFECT ON THE OUTPUT."
+ print red("*** WARNING ***")+" : SOME LIBRARIES MAY BE USED BY PACKAGES BUT ARE NOT"
+ print red("*** WARNING ***")+" : CONSIDERED TO BE A DEPEND DUE TO USE FLAG SETTINGS."
+ print red("*** WARNING ***")+" : emerge --update --deep --newuse world TO VERIFY"
+ print red("*** WARNING ***")+" : SANITY IN THIS REGARD."
+ print red("*** WARNING ***")+" :"
+ print red("*** WARNING ***")+" : Packages in the list that are desired may be added"
+ print red("*** WARNING ***")+" : directly to the world file to cause them to be ignored"
+ print red("*** WARNING ***")+" : by depclean and maintained in the future. BREAKAGES DUE"
+ print red("*** WARNING ***")+" : TO UNMERGING AN ==IN-USE LIBRARY== MAY BE REPAIRED BY"
+ print red("*** WARNING ***")+" : MERGING *** THE PACKAGE THAT COMPLAINS *** ABOUT THE"
+ print red("*** WARNING ***")+" : MISSING LIBRARY."
+ print
+ if ("--pretend" not in myopts) and ("--ask" not in myopts):
+ countdown(EMERGE_WARNING_DELAY, ">>> Depclean")
+ emergelog(" >>> depclean")
+
+ mydepgraph=depgraph(myaction,myopts)
+ syslist=getlist("system")
+ worldlist=getlist("world")
+
+ print "Calculating",myaction,"dependencies ",
+ if not mydepgraph.xcreate("world"):
+ print "\n!!! Failed to create deptree."
+ sys.exit(1)
+ print "\b\b ... done!"
+
+ if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
+ sys.stderr.write(red("The following binaries are not available for merging...\n"))
+ for x in mydepgraph.missingbins:
+ sys.stderr.write(" "+str(x)+"\n")
+ sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
+ sys.exit(1)
+
+ alldeps=mydepgraph.digraph.allnodes()
+ myvarlist=portage.vardbapi(portage.root).cp_all()
+
+ if not syslist:
+ print "!!! You have no system list. Cannot determine system from world."
+ if not worldlist:
+ print "!!! You have no world file. Cannot determine explicit merges."
+ if not myvarlist:
+ print "!!! You have no installed package tree (%s). This is a problem." % portage.VDB_PATH
+ if not alldeps:
+ print "!!! You have no dependencies. Impossible. Bug."
+
+ if not (syslist and worldlist and myvarlist and alldeps):
+ print
+ sys.exit(1)
+
+ reallist=[]
+ for x in alldeps:
+ myparts=portage.catpkgsplit(string.split(x)[2])
+ if not myparts:
+ sys.stderr.write(
+ red("!!! There appears to be a problem with the following package:\n")+
+ red("!!! "+str(string.split(x)[2])+"\n\n")+
+ "!!! Please ensure that blocking/conflicting packages are not merged."+
+ "!!! 'emerge -p "+str(string.split(x)[2])+"\n\n")
+ if ("--pretend" not in myopts) and ("--ask" not in myopts):
+ countdown(EMERGE_WARNING_DELAY, "*** Continuing")
+ continue
+
+ catpack=myparts[0]+"/"+myparts[1]
+ if catpack not in reallist:
+ reallist.append(catpack)
+
+ cleanlist=[]
+ for x in myvarlist:
+ if x not in reallist:
+ if x not in cleanlist:
+ cleanlist.append(x)
+
+ for x in syslist+worldlist:
+ myparts = portage.catpkgsplit(x)
+ if myparts:
+ if myparts[0][0] in ('<','>','='):
+ myparts[0] = myparts[0][1:]
+ if myparts[0][0] in ('<','>','='):
+ myparts[0] = myparts[0][1:]
+ catpack=myparts[0]+"/"+myparts[1]
+ else:
+ catpack=x
+ if catpack in cleanlist:
+ cleanlist.remove(catpack)
+
+ #print "\n\n\nCleaning: "
+ #for x in cleanlist:
+ # print x
+ #print
+
+ if len(cleanlist):
+ unmerge("unmerge", cleanlist)
+
+ print
+ print "Packages installed: "+str(len(myvarlist))
+ print "Packages in world: "+str(len(worldlist))
+ print "Packages in system: "+str(len(syslist))
+ print "Unique package names: "+str(len(reallist))
+ print "Required packages: "+str(len(alldeps))
+ if "--pretend" in myopts:
+ print "Number to remove: "+str(len(cleanlist))
+ else:
+ print "Number removed: "+str(len(cleanlist))
+ post_emerge()
+
+# "update", "system", or just process files:
+else:
+ favorites=[]
+ syslist=getlist("system")
+ if (("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts)) or ("--ask" in myopts):
+ if "--tree" in myopts:
+ print
+ print darkgreen("These are the packages that I would merge, in reverse order:")
+ print
+ else:
+ print
+ print darkgreen("These are the packages that I would merge, in order:")
+ print
+
+ if ("--resume" in myopts) and portage.mtimedb.has_key("resume"):
+ myresumeopts=portage.mtimedb["resume"]["myopts"][:]
+
+ while "--skipfirst" in myresumeopts:
+ myresumeopts.remove("--skipfirst")
+ while "--ask" in myresumeopts:
+ myresumeopts.remove("--ask")
+
+ for myopt in myopts:
+ if myopt not in myresumeopts:
+ myresumeopts.append(myopt)
+ myopts=myresumeopts
+ mydepgraph=depgraph("resume",myopts)
+ if "--resume" not in myopts:
+ myopts+=["--resume"]
+ else:
+ if ("--resume" in myopts):
+ del myopts[myopts.index("--resume")]
+ print darkgreen("emerge: It seems we have nothing to resume...")
+ sys.exit(0)
+
+ mydepgraph=depgraph(myaction,myopts)
+ if myaction in ["system","world"]:
+ print "Calculating",myaction,"dependencies ",
+ sys.stdout.flush()
+ if not mydepgraph.xcreate(myaction):
+ print "!!! Depgraph creation failed."
+ sys.exit(1)
+ print "\b\b ...done!"
+ else:
+ if not myfiles:
+ print "emerge: please tell me what to do."
+ help()
+ sys.exit(1)
+ #we don't have any files to process; skip this step and exit
+ print "Calculating dependencies ",
+ sys.stdout.flush()
+ retval,favorites=mydepgraph.select_files(myfiles)
+ if not retval:
+ sys.exit(1)
+ print "\b\b ...done!"
+
+ if ("--usepkgonly" in myopts) and mydepgraph.missingbins:
+ sys.stderr.write(red("The following binaries are not available for merging...\n"))
+
+ if mydepgraph.missingbins:
+ for x in mydepgraph.missingbins:
+ sys.stderr.write(" "+str(x)+"\n")
+ sys.stderr.write("\nThese are required by '--usepkgonly' -- Terminating.\n\n")
+ sys.exit(1)
+
+ if "--ask" in myopts:
+ if "--resume" in myopts:
+ mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
+ prompt="Do you want me to resume merging these packages?"
+ else:
+ mydepgraph.display(mydepgraph.altlist())
+ mergecount=0
+ hasblocks = False
+ for x in mydepgraph.altlist():
+ if x[3]!="nomerge":
+ mergecount+=1
+ #check for blocking dependencies
+ if x[0]=="blocks":
+ hasblocks = True
+ if mergecount==0:
+ if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
+ prompt="Nothing to merge; do you want me to auto-clean packages?"
+ else:
+ print
+ print "Nothing to merge; quitting."
+ print
+ sys.exit(0)
+ elif "--fetchonly" in myopts or "--fetch-all-uri" in myopts:
+ prompt="Do you want me to fetch the source files for these packages?"
+ elif hasblocks:
+ print "\n!!! Error: The above package list contains packages which cannot be installed"
+ print "!!! on the same system."
+ print
+ sys.exit(1)
+ else:
+ prompt="Do you want me to merge these packages?"
+ print
+ if userquery(prompt)=="No":
+ print
+ print "Quitting."
+ print
+ sys.exit(0)
+ # Don't ask again (e.g. when auto-cleaning packages after merge)
+ myopts.remove("--ask")
+
+ if ("--pretend" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
+ if ("--resume" in myopts):
+ mydepgraph.display(portage.mtimedb["resume"]["mergelist"])
+ else:
+ mydepgraph.display(mydepgraph.altlist())
+ else:
+ if ("--buildpkgonly" in myopts):
+ if not mydepgraph.digraph.hasallzeros():
+ print "\n!!! --buildpkgonly requires all dependencies to be merged."
+ print "!!! Cannot merge requested packages. Merge deps and try again.\n"
+ sys.exit(1)
+
+ if ("--resume" in myopts):
+ favorites=portage.mtimedb["resume"]["favorites"]
+ mydepgraph.merge(portage.mtimedb["resume"]["mergelist"])
+ else:
+ portage.mtimedb["resume"]={}
+ portage.mtimedb["resume"]["myopts"]=myopts
+ portage.mtimedb["resume"]["favorites"]=favorites
+ if ("--digest" in myopts) and not ("--fetchonly" in myopts or "--fetch-all-uri" in myopts):
+ for pkgline in mydepgraph.altlist():
+ if pkgline[0]=="ebuild" and pkgline[3]=="merge":
+ y=portage.portdb.findname(pkgline[2])
+ tmpsettings = portage.config(clone=portage.settings)
+ retval=portage.doebuild(y,"digest",portage.root,tmpsettings,edebug,("--pretend" in myopts))
+ mydepgraph.merge(mydepgraph.altlist())
+
+ if portage.mtimedb.has_key("resume"):
+ del portage.mtimedb["resume"]
+ if portage.settings["AUTOCLEAN"] and "yes"==portage.settings["AUTOCLEAN"]:
+ print ">>> Auto-cleaning packages ..."
+ unmerge("clean", ["world"])
+ post_emerge()
diff --git a/bin/env-update b/bin/env-update
new file mode 100755
index 000000000..a60428767
--- /dev/null
+++ b/bin/env-update
@@ -0,0 +1,11 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/env-update,v 1.9 2004/10/04 13:56:50 vapier Exp $
+
+import os,sys
+os.environ["PORTAGE_CALLER"] = "env-update"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+portage.env_update()
diff --git a/bin/env-update.sh b/bin/env-update.sh
new file mode 100755
index 000000000..5edc2da6b
--- /dev/null
+++ b/bin/env-update.sh
@@ -0,0 +1,221 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/env-update.sh,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+############################################
+############################################
+# ENVIRONMENT SETUP
+############################################
+
+if [[ ${EUID} -ne 0 ]] ; then
+ echo "$0: must be root."
+ exit 1
+fi
+
+# Make sure our environment is sane
+if [[ ! -z "${MAKELINKS}" ]] ; then
+ export MAKELINKS=0
+else
+ export MAKELINKS=1
+fi
+export ROOT="${ROOT:=/}"
+[[ ${ROOT} == */ ]] || export ROOT="${ROOT}/"
+
+export ENVDIR="${ROOT}etc/env.d"
+mkdir -p ${ENVDIR}
+chmod 755 ${ENVDIR}
+specials="
+ KDEDIRS PATH CLASSPATH LDPATH MANPATH INFODIR INFOPATH ROOTPATH
+ CONFIG_PROTECT CONFIG_PROTECT_MASK PRELINK_PATH PYTHONPATH
+ PRELINK_PATH_MASK ADA_INCLUDE_PATH ADA_OBJECTS_PATH"
+colon_separated="
+ ADA_INCLUDE_PATH ADA_OBJECTS_PATH LDPATH PATH MANPATH ROOTPATH
+ PRELINK_PATH PRELINK_PATH_MASK PYTHON_PATH"
+
+export LDSOCONF="${ROOT}etc/ld.so.conf"
+
+export PRELINKCONF="${ROOT}etc/prelink.conf"
+defaultprelinkpaths=":/bin:/sbin:/usr/bin:/usr/sbin:/lib:/usr/lib"
+
+export PROFILEENV="${ROOT}etc/profile.env"
+export CSHENV="${ROOT}etc/csh.env"
+
+# make sure we aren't tricked with previous 'my_envd_' variables
+unset $(set | grep '^my_envd_' | cut -d= -f1)
+
+############################################
+############################################
+# ENV.D PARSING
+############################################
+
+do_has() {
+ local x
+ local me="$1"
+ shift
+
+ for x in "$@" ; do
+ [[ ${x} == ${me} ]] && return 0
+ done
+ return 1
+}
+has() {
+ local ret
+ local ifs="${IFS}"
+ unset IFS
+ do_has $1 ${!2}
+ ret=$?
+ export IFS="${ifs}"
+ return ${ret}
+}
+is_special() {
+ has $1 specials
+}
+is_colon_separated() {
+ has $1 colon_separated
+}
+
+for envd in $(ls ${ENVDIR} | sort) ; do
+ # make sure file is a vaild env'd entry and not a backup file
+ num="${envd:0:2}"
+ if [[ ! -z ${num//[0-9]} ]] ; then
+ continue
+ elif [[ ${envd} == *~ || ${envd} == *.bak ]] ; then
+ continue
+ fi
+
+ # use bash to make sure the file is valid
+ envd="${ENVDIR}/${envd}"
+ if ! (source "${envd}") ; then
+ echo "!!! Error parsing ${envd}!"
+ exit 1
+ fi
+
+ # parse env.d entries
+ cnfvars="$(grep '^[[:alpha:]_][[:alnum:]_]*=' "${envd}")"
+ export IFS=$'\n'
+ for cnfv in ${cnfvars} ; do
+ var="${cnfv/=*}"
+ val="${cnfv:${#var}+1}"
+ if [ "${val:0:1}" == "\"" ] ; then
+ val="${val:1:${#val}-2}"
+ fi
+ myvar="my_envd_${var}"
+ if is_special ${var} ; then
+ if [[ ! -z "${!myvar}" ]] ; then
+ if is_colon_separated ${var} ; then
+ sep=":"
+ else
+ sep=" "
+ fi
+ else
+ sep=""
+ fi
+ export ${myvar}="${!myvar}${sep}${val}"
+ else
+ export ${myvar}="${val}"
+ fi
+ done
+ unset IFS
+done
+
+############################################
+############################################
+# LD.SO.CONF HANDLING
+############################################
+
+# create a : sep list from ld.so.conf
+export OLD_LDPATH=""
+if [ -s "${LDSOCONF}" ] ; then
+ while read line ; do
+ if [[ "${line:0:1}" == "#" ]] ; then
+ continue
+ fi
+ export OLD_LDPATH="${OLD_LDPATH}:${line}"
+ done < ${LDSOCONF}
+ export OLD_LDPATH="${OLD_LDPATH:1}"
+fi
+
+# has the ldpath changed ? if so, recreate
+if [[ "${OLD_LDPATH}" != "${my_envd_LDPATH}" ]] ; then
+ cat << EOF > ${LDSOCONF}
+# ld.so.conf autogenerated by env-update; make all changes to
+# contents of /etc/env.d directory
+${my_envd_LDPATH//:/
+}
+EOF
+fi
+
+############################################
+############################################
+# HANDLE PRELINK PATHS
+############################################
+
+if prelink --version >& /dev/null ; then
+ # we assume LDPATH and PATH aren't empty ... if they were, we got other problems
+ envdprelinkcheckpaths="${my_envd_LDPATH}:${my_envd_PATH}"
+ if [[ ! -z "${my_envd_PRELINK_PATH}" ]] ; then
+ envdprelinkcheckpaths="${envdprelinkcheckpaths}:${my_envd_PRELINK_PATH}"
+ fi
+
+ if [[ ! -z "${my_envd_PRELINK_PATH_MASK}" ]] ; then
+ export prelink_mask=":${PRELINK_PATH_MASK}:"
+ envdprelinkpaths=""
+ export IFS=":"
+ for dir in ${envdprelinkcheckpaths} ; do
+ if [[ ${dir:0-1} == / ]] ; then
+ noslashdir="${dir:0:${#dir}-1}"
+ else
+ dir="${dir}/"
+ noslashdir="${dir}"
+ fi
+ if [[ ${prelink_mask/:${dir}:/} == ${prelink_mask} \
+ && ${prelink_mask/:${noslashdir}:/} == ${prelink_mask} ]] ; then
+ envdprelinkpaths="${envdprelinkpaths}:${dir}"
+ fi
+ done
+ unset IFS
+ else
+ envdprelinkpaths=":${envdprelinkcheckpaths}"
+ fi
+
+ cat << EOF > ${PRELINKCONF}
+# prelink.conf autogenerated by env-update; make all changes to
+# contents of /etc/env.d directory
+${defaultprelinkpaths//:/
+-l }
+${envdprelinkpaths//:/
+-h }
+EOF
+fi
+unset my_envd_LDPATH
+
+############################################
+############################################
+# RUN EXTERNAL PROGRAMS NOW
+############################################
+
+echo ">>> Regenerating ${ROOT}etc/ld.so.cache..."
+if [[ ${MAKELINKS} -eq 0 ]] ; then
+ (cd / ; /sbin/ldconfig -X -r ${ROOT} >& /dev/null)
+else
+ (cd / ; /sbin/ldconfig -r ${ROOT} >& /dev/null)
+fi
+
+cat << EOF > ${PROFILEENV}
+# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.
+# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES
+# GO INTO /etc/profile NOT /etc/profile.env
+
+$(set | grep '^my_envd_' | sed -e 's:^my_envd_:export :')
+EOF
+
+cat << EOF > ${CSHENV}
+# THIS FILE IS AUTOMATICALLY GENERATED BY env-update.
+# DO NOT EDIT THIS FILE. CHANGES TO STARTUP PROFILES
+# GO INTO /etc/csh.cshrc NOT /etc/csh.env
+
+$(set | grep '^my_envd_' | sed -e 's:^my_envd_\([[:alpha:]_][[:alnum:]_]*\)=:setenv \1 :')
+EOF
+
+[[ ${ROOT} == / ]] && /sbin/depscan.sh
diff --git a/bin/etc-update b/bin/etc-update
new file mode 100755
index 000000000..e8ea9376b
--- /dev/null
+++ b/bin/etc-update
@@ -0,0 +1,407 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/etc-update,v 1.23.2.5 2005/05/29 12:40:08 jstubbs Exp $
+
+# 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>
+
+export PORTAGE_CALLER="etc-update"
+
+eval $(python -c 'import portage; print "export PORTAGE_TMPDIR="+portage.settings["PORTAGE_TMPDIR"]; print "export USERLAND="+portage.settings["USERLAND"]')
+
+if [ "$USERLAND" == "BSD" ] ; then
+ function sed() { gsed "$@"; }
+elif [ "$USERLAND" == "Darwin" ] && [ -x /bin/gsed ]; then
+ function sed() { gsed "$@"; }
+fi
+
+function get_config() {
+ item=$1
+
+ # First strip off comment lines, then grab the configuration
+ # item. If there's more than one of the same configuration item,
+ # then allow the last setting to take precedence.
+ cut -d'#' -f1-1 /etc/etc-update.conf | \
+ sed -ne "s/^ *$item *= *\([\"']\{0,1\}\)\(.*\)\1/\2/p" |sed -e '$p;d'
+}
+
+function 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
+
+ for path in ${CONFIG_PROTECT}; do if [ -d ${path} ]; then
+ ofile=""
+ for file in `find ${path}/ -iname "._cfg????_*" |
+ sed -e "s:\(^.*/\)\(\._cfg[0-9]*_\)\(.*$\):\1\2\3\%\2\%\3:" |
+ sort -t'%' -k3 -k2 | 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
+ if [[ "${rpath}" == "${mpath}"* ]]; then
+ mv ${rpath}/${rfile} ${rpath}/${rfile:10}
+ break
+ fi
+ done
+ [ ! -f ${file} ] && continue
+
+
+ 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: ${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
+ fi; done
+
+}
+
+function sel_file() {
+ local -i isfirst=0
+ until [ -f ${TMP}/files/${input} ] || [ ${input} == -1 ] || [ ${input} == -3 ]; do
+ for file in `ls ${TMP}/files|sort -n`; do
+ if (( ${isfirst} == 0 )); then
+ isfirst=${file}
+ fi
+ echo -n "${file}${PAR} "
+ if (( ${mode} == 0 )); then
+ for word in `cat ${TMP}/files/${file}`; do
+ echo ${word}
+ done
+ else
+ head -n1 ${TMP}/files/${file}
+ fi
+ done > ${TMP}/menuitems
+
+ if [ "${OVERWRITE_ALL}" == "yes" ]; then
+ input=0
+ else
+ 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 or -5 if you're unsure what to do)"
+ echo " (-1 to exit) (-3 to auto merge all remaining files)"
+ echo -n " (-5 to auto-merge AND not use 'mv -i'): "
+ read input
+ else
+ dialog --title "${title}" --menu "${my_title}" \
+ 0 0 0 `echo "-1 Exit";cat ${TMP}/menuitems` \
+ 2> ${TMP}/input
+ input=`cat ${TMP}/input`
+ fi
+ if (( ${input} == -5 )); then
+ input=-3
+ export mv_opts=""
+ fi
+ if (( ${input} == -3 )); then
+ input=0
+ export OVERWRITE_ALL="yes"
+ fi
+ fi # -3 automerge
+ if (( ${input} == 0 )); then
+ input=${isfirst}
+ fi
+ done
+}
+
+function do_file() {
+ echo
+ local -i my_input
+ local -i fcount=0
+ until (( `cat ${TMP}/files/${input}|wc -l` < 2 )); do
+ my_input=0
+ if (( `cat ${TMP}/files/${input}|wc -l` == 2 )); then
+ my_input=1
+ fi
+ until (( ${my_input} > 0 )) && (( ${my_input} < `cat ${TMP}/files/${input}|wc -l` )); do
+ fcount=0
+
+ if [ "${OVERWRITE_ALL}" == "yes" ]; then
+ my_input=0
+ else
+ for line in `cat ${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): "
+ read my_input
+ else
+ dialog --title "${title}" --menu "${my_title}" \
+ 0 0 0 `cat ${TMP}/menuitems;echo "${fcount} Exit"` \
+ 2> ${TMP}/input
+ my_input=`cat ${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=`cat ${TMP}/files/${input} | sed -e "${fcount}p;d"`
+ ofile=`head -n1 ${TMP}/files/${input}`
+
+ do_cfg "${file}" "${ofile}"
+
+ cat ${TMP}/files/${input}|sed -e "${fcount}!p;d" > ${TMP}/files/sed
+ mv ${TMP}/files/sed ${TMP}/files/${input}
+
+ if (( ${my_input} == -1 )); then
+ break
+ fi
+ done
+ echo
+ rm ${TMP}/files/${input}
+ count=${count}-1
+}
+
+function do_cfg() {
+
+ local file="${1}"
+ local ofile="${2}"
+ local -i my_input=0
+
+ until (( ${my_input} == -1 )) || [ ! -f ${file} ]; do
+ if [ "${OVERWRITE_ALL}" == "yes" ]; then
+ my_input=1
+ else
+ showdiffcmd=$(echo "${diff_command}" |
+ sed -e "s:%file1:${ofile}:" -e "s:%file2:${file}:")
+
+ if [ "${using_editor}" == 0 ]; then
+ (
+ echo "Showing differences between ${ofile} and ${file}"
+ ${showdiffcmd}
+ ) | ${pager}
+ else
+ echo "Beginning of differences between ${ofile} and ${file}"
+ ${showdiffcmd}
+ 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 "1) Replace original with update
+2) Delete update, keeping original as is
+3) Interactively merge original with update
+4) Show differences again
+Please select from the menu above (-1 to ignore this update): "
+ read my_input
+ fi
+
+ case ${my_input} in
+ 1) echo "Replacing ${ofile} with ${file}"
+ mv ${mv_opts} ${file} ${ofile}
+ my_input=-1
+ continue
+ ;;
+ 2) echo "Deleting ${file}"
+ rm ${rm_opts} ${file}
+ continue
+ ;;
+ 3) do_merge "${file}" "${ofile}"
+ my_input=${?}
+# [ ${my_input} == 255 ] && my_input=-1
+ continue
+ ;;
+ 4) continue
+ ;;
+ *) continue
+ ;;
+ esac
+ done
+}
+
+function do_merge() {
+
+ local file="${1}"
+ local ofile="${2}"
+ local mfile="${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
+
+ 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): "
+ read my_input
+ case ${my_input} in
+ 1) echo "Replacing ${ofile} with ${mfile}"
+ chmod --reference=${ofile} ${mfile}
+ mv ${mv_opts} ${mfile} ${ofile}
+ rm ${rm_opts} ${file}
+ return 255
+ ;;
+ 2) ( echo "Showing differences between ${ofile} and ${mfile}"
+ `echo "${diff_command}" | \
+ sed -e "s:%file1:${ofile}:" \
+ -e "s:%file2:${mfile}:"` ) | ${pager}
+ 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
+}
+
+function die() {
+ trap "" term
+ trap "" kill
+ echo "Exiting: ${1}"
+ rm -rf ${TMP}
+ exit ${2}
+}
+
+#
+# Run the script
+#
+scriptname=`basename $0`
+
+trap die term
+
+TMP="${PORTAGE_TMPDIR}/$$"
+rm -rf ${TMP} 2> /dev/null
+mkdir ${TMP} || die "failed mkdir command!" 1
+
+# I need the CONFIG_PROTECT value
+CONFIG_PROTECT=$(/usr/lib/portage/bin/portageq config_protect)
+CONFIG_PROTECT_MASK=$(/usr/lib/portage/bin/portageq config_protect_mask)
+
+# load etc-config's configuration
+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"
+
+#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 -i input=0
+declare title="Gentoolkit'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/bin/find-requires b/bin/find-requires
new file mode 100755
index 000000000..44bc51dae
--- /dev/null
+++ b/bin/find-requires
@@ -0,0 +1,44 @@
+#!/bin/sh
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/find-requires,v 1.5 2004/10/04 13:56:50 vapier Exp $
+
+# note this works for both a.out and ELF executables
+# it also auto-generates requirment lines for shell scripts
+
+ulimit -c 0
+
+filelist=`sed "s/['\"]/\\\&/g"`
+exelist=`echo $filelist | $XARGS file | grep ":.*executable" | cut -d: -f1 `
+scriptlist=`echo $filelist | $XARGS file | egrep ":.* (commands|script) " | cut -d: -f1 `
+liblist=`echo $filelist | $XARGS file | grep ":.*shared object" | cut -d : -f1 `
+
+for f in $exelist; do
+ if [ -x $f ]; then
+ ldd $f | awk '/=>/ { print $1 }'
+ fi
+done | sort -u | sed "s/['\"]/\\\&/g" | $XARGS -n 1 basename | grep -v 'libNoVersion.so' | sort -u
+
+for f in $liblist; do
+ ldd $f | awk '/=>/ { print $1 }'
+done | sort -u | sed "s/['\"]/\\\&/g" | $XARGS -n 1 basename | grep -v 'libNoVersion.so' | sort -u
+
+for f in $scriptlist; do
+ if [ -x $f ]; then
+ head -1 $f | sed -e 's/^\#\![ ]*//' | cut -d" " -f1
+ fi
+done | sort -u
+
+#for f in $liblist $exelist ; do
+# objdump -p $f | awk '
+# BEGIN { START=0; LIBNAME=""; }
+# /Version References:/ { START=1; }
+# /required from/ && (START==1) {
+# sub(/:/, "", $3);
+# LIBNAME=$3;
+# }
+# (START==1) && (LIBNAME!="") && ($4~/^GLIBC_*/) { print LIBNAME "(" $4 ")"; }
+# /^$/ { START=0; }
+# '
+#done | sort -u
+
diff --git a/bin/fix-db.py b/bin/fix-db.py
new file mode 100755
index 000000000..d185580fa
--- /dev/null
+++ b/bin/fix-db.py
@@ -0,0 +1,175 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/fix-db.py,v 1.8 2004/10/11 04:01:00 jstubbs Exp $
+
+import os,sys,re
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+from stat import *
+from output import *
+from portage import lockfile,unlockfile,VDB_PATH,root
+
+
+mylog = open("/var/log/emerge_fix-db.log", "a")
+def writemsg(msg):
+ if msg[-1] != '\n':
+ msg += "\n"
+ sys.stderr.write(msg)
+ sys.stderr.flush()
+ mylog.write(msg)
+ mylog.flush()
+
+def fix_global_counter(value):
+ myf = open("/var/cache/edb/counter")
+ newvalue = value+1000
+ myf.write(str(newvalue))
+ myf.flush()
+ myf.close()
+ return newvalue
+
+bad = {}
+counters = {}
+times = {}
+
+try:
+ real_counter = long(open("/var/cache/edb/counter").read())
+except SystemExit, e:
+ raise # This needs to be propogated
+except:
+ writemsg("ERROR: Real counter is invalid.\n")
+ real_counter = 0
+
+vardbdir = root+VDB_PATH+"/"
+for cat in os.listdir(vardbdir):
+ catdir = vardbdir+cat+"/"
+ if not os.path.isdir(catdir):
+ writemsg("Invalid file: '%s'\n" % catdir[:-1])
+ continue
+ for pkg in os.listdir(catdir):
+ pkgdir = catdir+pkg+"/"
+ catpkg = cat+"/"+pkg
+
+ if not os.path.isdir(catdir):
+ writemsg("Invalid file: '%s'\n" % pkgdir)
+ continue
+
+ bad[catpkg] = []
+
+ pkgdirlist = os.listdir(pkgdir)
+ if not pkgdirlist:
+ writemsg("ERROR: Package directory is empty for '%s'\n" % catpkg)
+ writemsg(" Deleting this directory. Remerge if you want it back.\n")
+ os.rmdir(pkgdir)
+ del bad[catpkg]
+ continue
+
+ if "CONTENTS" not in pkgdirlist:
+ bad[catpkg] += ["CONTENTS is missing"]
+ times[catpkg] = -1
+ writemsg("ERROR: Contents file is missing from the package directory.\n")
+ writemsg(" '%s' is corrupt and should be deleted.\n" % catpkg)
+ else:
+ times[catpkg] = None
+ for line in open(pkgdir+"CONTENTS").readlines():
+ mysplit = line.split()
+ if mysplit[0] == "obj":
+ try:
+ times[catpkg] = long(mysplit[-1])
+ except SystemExit, e:
+ raise # This needs to be propogated
+ except:
+ times[catpkg] = -1
+ bad[catpkg] += ["CONTENTS is corrupt"]
+ writemsg("ERROR: Corrupt CONTENTS file in '%s'\n" % catpkg)
+ writemsg(" This package should be deleted.\n")
+ break
+ if times[catpkg] == None:
+ times[catpkg] = os.stat(pkgdir+"CONTENTS")[ST_MTIME]
+
+ if "COUNTER" not in pkgdirlist:
+ bad[catpkg] += ["COUNTER is missing"]
+ writemsg("ERROR: COUNTER file missing from '%s'.\n" % catpkg)
+ counters[catpkg] = -1
+ else:
+ try:
+ counters[catpkg] = long(open(pkgdir+"COUNTER").read().strip())
+ if counters[catpkg] > real_counter:
+ writemsg("ERROR: Global counter is lower than the '%s' COUNTER." % catpkg)
+ real_counter = fix_global_counter(counters[catpkg])
+ except SystemExit, e:
+ raise # This needs to be propogated
+ except:
+ bad[catpkg] += ["COUNTER is corrupt"]
+ counters[catpkg] = -1
+
+ if "SLOT" not in pkgdirlist:
+ writemsg("ERROR: SLOT file missing from '%s'.\n" % catpkg)
+ writemsg(" RE-MERGE this exact package version or unmerge and remerge.\n")
+ bad[catpkg] += ["SLOT is missing"]
+ else:
+ myslot = open(pkgdir+"SLOT").read()
+ if myslot and myslot[-1]=="\n":
+ #writemsg("WARN: SLOT file has a newline. '%s'\n" % catpkg)
+ myslot = myslot[:-1]
+ if not myslot:
+ bad[catpkg] += ["SLOT is empty"]
+ writemsg("ERROR: SLOT file is empty for '%s'.\n" % catpkg)
+ writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n")
+ elif re.search("[^-a-zA-Z0-9\._]", myslot):
+ bad[catpkg] += ["SLOT is corrupt"]
+ writemsg("ERROR: SLOT file is corrupt for '%s'.\n" % catpkg)
+ writemsg(" RE-MERGE this exact package version or unmerge and remerge it.\n")
+ elif myslot.strip() != myslot:
+ writemsg("WARN: SLOT file has invalid characters. '%s'\n" % catpkg)
+ bad[catpkg] += ["SLOT is invalid"]
+
+ if not bad[catpkg]:
+ del bad[catpkg]
+
+
+actions = {}
+writemsg("\n\n")
+for catpkg in bad.keys():
+ bad[catpkg].sort()
+
+ mystr = ""
+ for x in bad[catpkg]:
+ mystr += " "+str(x)+"\n"
+
+ if bad[catpkg] == ["CONTENTS is missing", "SLOT is missing"]:
+ writemsg("%s: (possibly injected)\n%s\n" % (green(catpkg), mystr))
+ actions[catpkg] = ["ignore"]
+ elif bad[catpkg] == ["SLOT is empty"]:
+ writemsg("%s: (old package) []\n%s\n" % (yellow(catpkg), mystr))
+ actions[catpkg] = ["remerge"]
+ else:
+ writemsg("%s: (damaged/invalid) []\n%s\n" % (red(catpkg), mystr))
+ actions[catpkg] = ["merge exact"]
+
+if (len(sys.argv) > 1) and (sys.argv[1] == "--fix"):
+ writemsg("These are only directions, at the moment.")
+ for catpkg in actions.keys():
+ action = actions[catpkg]
+ writemsg("We will now '%s' '%s'..." % (action, catpkg))
+ #if action ==
+else:
+ #writemsg("Run with '--fix' to attempt automatic correction.")
+ pass
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bin/fixdbentries b/bin/fixdbentries
new file mode 100755
index 000000000..a9c3e1844
--- /dev/null
+++ b/bin/fixdbentries
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/fixdbentries,v 1.3 2004/10/04 13:56:50 vapier Exp $
+
+# Script to adjust the contents of the DB entries after a package move.
+# Fairly straight forward... ./movedbentry 'from/here' 'to/here' /over/here
+
+VAR=$1
+NEW=$2
+SPATH=$3
+
+grep -FrZl "${VAR}" "${SPATH}" |
+sed "s#${SPATH}[^\d000]\+/CONTENTS\d000##g" |
+$XARGS -0 sed -i -e "
+s#${VAR}\$#${NEW}#g;
+s#${VAR}\([[:space:]]\)#${NEW}\1#g;
+s#${VAR}\(-[^a-zA-Z]\)#${NEW}\1#g;
+s#${VAR}\([^a-zA-Z0-9-]\)#${NEW}\1#g
+"
diff --git a/bin/fixpackages b/bin/fixpackages
new file mode 100755
index 000000000..f8d1948ac
--- /dev/null
+++ b/bin/fixpackages
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/fixpackages,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+import os,sys
+os.environ["PORTAGE_CALLER"]="fixpackages"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+
+print
+print "Done."
+print
diff --git a/bin/fowners b/bin/fowners
new file mode 100755
index 000000000..cc13372a7
--- /dev/null
+++ b/bin/fowners
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/fowners,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -lt 2 ] ; then
+ echo "${0}: at least two arguments needed"
+ exit 1
+fi
+
+OWNER="${1}"
+shift
+for FILE in $*; do
+ chown "${OWNER}" "${D}${FILE}"
+done
diff --git a/bin/fperms b/bin/fperms
new file mode 100755
index 000000000..ce72126e2
--- /dev/null
+++ b/bin/fperms
@@ -0,0 +1,15 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/fperms,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+if [ ${#} -lt 2 ] ; then
+ echo "${0}: at least two arguments needed"
+ exit 1
+fi
+
+PERM="${1}"
+shift
+for FILE in $*; do
+ chmod "${PERM}" "${D}${FILE}"
+done
diff --git a/bin/md5check.py b/bin/md5check.py
new file mode 100755
index 000000000..e64d54a96
--- /dev/null
+++ b/bin/md5check.py
@@ -0,0 +1,102 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/md5check.py,v 1.4 2004/10/10 10:07:20 carpaski Exp $
+
+import os,sys,string
+os.environ["PORTAGE_CALLER"]="mirror"
+os.environ["FEATURES"]="mirror cvs"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+from threading import *
+from output import red,green,blue,bold
+from random import shuffle
+from time import sleep
+
+
+def cstrip(mystr,mychars):
+ newstr = ""
+ for x in mystr:
+ if x not in mychars:
+ newstr += x
+ return newstr
+
+md5_list = {}
+bn_list = []
+col_list = []
+
+hugelist = []
+for mycp in portage.db["/"]["porttree"].dbapi.cp_all():
+ hugelist += portage.db["/"]["porttree"].dbapi.cp_list(mycp)
+hugelist.sort()
+
+for mycpv in hugelist:
+ pv = string.split(mycpv, "/")[-1]
+
+ newuri = portage.db["/"]["porttree"].dbapi.aux_get(mycpv,["SRC_URI"])[0]
+ newuri = string.split(newuri)
+
+ digestpath = portage.db["/"]["porttree"].dbapi.findname(mycpv)
+ digestpath = os.path.dirname(digestpath)+"/files/digest-"+pv
+ md5sums = portage.digestParseFile(digestpath)
+
+ if md5sums == None:
+ portage.writemsg("Missing digest: %s\n" % mycpv)
+ md5sums = {}
+
+ for x in md5sums.keys():
+ if x[0] == '/':
+ del md5sums[x]
+
+ #portage.writemsg("\n\ndigestpath: %s\n" % digestpath)
+ #portage.writemsg("md5sums: %s\n" % md5sums)
+ #portage.writemsg("newuri: %s\n" % newuri)
+
+ bn_list = []
+ for x in newuri:
+ if not x:
+ continue
+ if (x in [")","(",":","||"]) or (x[-1] == "?"):
+ # ignore it. :)
+ continue
+ x = cstrip(x,"()|?")
+ if not x:
+ continue
+
+ mybn = os.path.basename(x)
+ if mybn not in bn_list:
+ bn_list += [mybn]
+ else:
+ continue
+
+ if mybn not in md5sums.keys():
+ portage_util.writemsg("Missing md5sum: %s in %s\n" % (mybn, mycpv))
+ else:
+ if mybn in md5_list.keys():
+ if (md5_list[mybn]["MD5"] != md5sums[mybn]["MD5"]) or \
+ (md5_list[mybn]["size"] != md5sums[mybn]["size"]):
+
+ # This associates teh md5 with each file. [md5/size]
+ md5joins = string.split(md5_list[mybn][2],",")
+ md5joins = string.join(md5joins," ["+md5_list[mybn][0]+"/"+md5_list[mybn][1]+"],")
+ md5joins += " ["+md5_list[mybn][0]+"/"+md5_list[mybn][1]+"]"
+
+ portage.writemsg("Colliding md5: %s of %s [%s/%s] and %s\n" % (mybn,mycpv,md5sums[mybn][0],md5sums[mybn][1],md5joins))
+ col_list += [mybn]
+ else:
+ md5_list[mybn][2] += ","+mycpv
+ else:
+ md5_list[mybn] = md5sums[mybn]+[mycpv]
+ del md5sums[mybn]
+
+ #portage.writemsg(str(bn_list)+"\n")
+ for x in md5sums.keys():
+ if x not in bn_list:
+ portage.writemsg("Extra md5sum: %s in %s\n" % (x, mycpv))
+
+
+print col_list
+print
+print str(len(md5_list.keys()))+" unique distfile md5s."
+print str(len(bn_list))+" unique distfile names."
diff --git a/bin/md5check.sh b/bin/md5check.sh
new file mode 100755
index 000000000..a4f9f3fda
--- /dev/null
+++ b/bin/md5check.sh
@@ -0,0 +1,31 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/md5check.sh,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+# pipe in the data.
+
+sort -u - > md5check.tmp
+grep '^Extra' md5check.tmp > md5check.tmp.extra
+grep '^Missing' md5check.tmp > md5check.tmp.missing
+grep '^Coll' md5check.tmp > md5check.tmp.colliding
+
+sed -i "
+s:^Col:\nCol:
+s:,:\n :g
+s: of :\n :g
+s: and :\n :g" md5check.tmp.colliding
+sed -i "s/^[^ ]\+ md5sum: \(.*\) in \(.*\)$/ \2: \1/g" md5check.tmp.missing
+sed -i "s/^[^ ]\+ md5sum: \(.*\) in \(.*\)$/ \2: \1/g" md5check.tmp.extra
+
+#echo "Colliding files:" > md5check.colliding
+#sort -u md5check.tmp.colliding >> md5check.colliding
+cp md5check.tmp.colliding md5check.colliding
+
+echo "Missing from digest:" > md5check.missing
+sort -u md5check.tmp.missing >> md5check.missing
+
+echo "Extra files in digest:" > md5check.extra
+sort -u md5check.tmp.extra >> md5check.extra
+
+rm md5check.tmp*
diff --git a/bin/mirror.py b/bin/mirror.py
new file mode 100755
index 000000000..1e08574a4
--- /dev/null
+++ b/bin/mirror.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/mirror.py,v 1.3 2004/10/10 10:07:20 carpaski Exp $
+
+# Defines the number of threads carrying out the downloading.
+maxsems=5
+
+import os,sys,string
+os.environ["PORTAGE_CALLER"]="mirror"
+os.environ["FEATURES"]="mirror cvs"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+from threading import *
+from output import red,green,blue,bold
+from random import shuffle
+from time import sleep
+
+
+def cstrip(mystr,mychars):
+ newstr = ""
+ for x in mystr:
+ if x not in mychars:
+ newstr += x
+ return newstr
+
+class fetcher(Thread):
+ def __init__(self, filename, urilist, dest, md5sum):
+ self.filename = filename
+ self.myurilist = urilist
+ self.myuri = None
+ self.mydest = dest
+ self.destpath = self.mydest+"/"+self.filename
+ self.md5sum = md5sum
+ self.result = None
+ Thread.__init__(self)
+
+ def fetch(self):
+ #print "Started",self.filename
+ sys.stderr.write(".")
+ sys.stderr.flush()
+ portage.spawn("wget -q -P "+str(self.mydest)+" "+self.myuri, free=1)
+
+ def finished(self):
+ if os.path.exists(self.destpath) and self.md5sum:
+ ok,reason = portage_checksum.verify_all(self.destpath, md5sum)
+ if not ok:
+ portage_util.writemsg("Failed verification:" + reason + "\n")
+ return 1
+ return 0
+
+ def delete(self):
+ if os.path.exists(self.destpath):
+ #print "Unlink:",self.destpath
+ os.unlink(self.destpath)
+
+ def run(self):
+ if not self.finished():
+ self.delete()
+
+ while not self.finished():
+ if self.myurilist:
+ self.myuri = self.myurilist.pop(0)+"/"+self.filename
+ self.fetch()
+ else:
+ self.delete()
+ self.result = 0
+ #print "Failed:",self.filename
+ return 1
+
+ #print "Finished:",self.filename
+ self.result = 1
+ return 0
+
+
+uri_list = {}
+fetchers = []
+fetcher_sem = BoundedSemaphore(value=maxsems)
+failures = 0
+successes = 0
+
+def clean_fetchers():
+ global fetcher_sem,fetchers,uri_list,failures,successes,maxsems
+ while len(fetchers) == maxsems:
+ for x in fetchers:
+ if not x.isAlive():
+ failures += (x.result == 0)
+ successes += (x.result == 1)
+ if x.filename in uri_list.keys():
+ del uri_list[x.filename]
+ del fetchers[fetchers.index(x)]
+ fetcher_sem.release()
+ if len(fetchers) == maxsems:
+ sleep(1)
+
+
+def start_fetcher(fname, urilist, dest, md5sum):
+ global fetcher_sem,fetchers,uri_list,failures,successes
+ fetcher_sem.acquire()
+ fetchers.append(fetcher(fname, urilist, dest, md5sum))
+ fetchers[-1].start()
+
+
+tpm = portage.thirdpartymirrors
+destdir = portage.settings["DISTDIR"][:]
+
+hugelist = []
+for mycp in portage.db["/"]["porttree"].dbapi.cp_all():
+ hugelist += portage.db["/"]["porttree"].dbapi.cp_list(mycp)
+shuffle(hugelist)
+
+mycount = -1
+for mycpv in hugelist:
+ pv = string.split(mycpv, "/")[-1]
+
+ clean_fetchers()
+
+ mycount += 1
+ if ((mycount % 20) == 0):
+ sys.stdout.write("\nCompleted: %s\n" % mycount)
+ sys.stdout.flush()
+ newuri = portage.db["/"]["porttree"].dbapi.aux_get(mycpv,["SRC_URI"])[0]
+ newuri = string.split(newuri)
+
+ digestpath = portage.db["/"]["porttree"].dbapi.findname(mycpv)
+ digestpath = os.path.dirname(digestpath)+"/files/digest-"+pv
+ md5sums = portage.digestParseFile(digestpath)
+
+ for x in newuri:
+ clean_fetchers()
+ if not x:
+ continue
+ if (x in [")","(",":","||"]) or (x[-1] == "?"):
+ # ignore it. :)
+ continue
+ x = cstrip(x,"()|?")
+ if not x:
+ continue
+ mybn = os.path.basename(x)
+ mydn = os.path.dirname(x)
+ if mybn not in uri_list.keys():
+ if (len(mybn) > len("mirror://")) and (mybn[:len("mirror://")] == "mirror://"):
+ mysite = string.split(x[len("mirror://"):], "/")[0]
+ shuffle(tpm[mysite])
+ uri_list[mybn] = tpm[mysite][:]
+ else:
+ uri_list[mybn] = [os.path.dirname(x)]
+ clean_fetchers()
+ if (not md5sums) or (mybn not in md5sums.keys()):
+ start_fetcher(mybn, uri_list[mybn], destdir, None)
+ else:
+ start_fetcher(mybn, uri_list[mybn], destdir, md5sums[mybn])
+ else:
+ break
+
+sys.stderr.write("\n\nWaiting last set\n")
+sys.stderr.flush()
+while fetchers:
+ if fetchers[0].isAlive():
+ fetchers[0].join()
+ clean_fetchers()
+
+print
+print
+print "Successes:",successes
+print "Failures: ",failures
diff --git a/bin/newbin b/bin/newbin
new file mode 100755
index 000000000..6c7904cd8
--- /dev/null
+++ b/bin/newbin
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newbin,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dobin "${T}/${2}"
diff --git a/bin/newconfd b/bin/newconfd
new file mode 100755
index 000000000..662b40ede
--- /dev/null
+++ b/bin/newconfd
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newconfd,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doconfd "${T}/${2}"
diff --git a/bin/newdoc b/bin/newdoc
new file mode 100755
index 000000000..a3c43a2ff
--- /dev/null
+++ b/bin/newdoc
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newdoc,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dodoc "${T}/${2}"
diff --git a/bin/newenvd b/bin/newenvd
new file mode 100755
index 000000000..0ceec650f
--- /dev/null
+++ b/bin/newenvd
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newenvd,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doenvd "${T}/${2}"
diff --git a/bin/newexe b/bin/newexe
new file mode 100755
index 000000000..a2585b3f5
--- /dev/null
+++ b/bin/newexe
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newexe,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doexe "${T}/${2}"
diff --git a/bin/newinitd b/bin/newinitd
new file mode 100755
index 000000000..cb23dd798
--- /dev/null
+++ b/bin/newinitd
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newinitd,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doinitd "${T}/${2}"
diff --git a/bin/newins b/bin/newins
new file mode 100755
index 000000000..965ff94b3
--- /dev/null
+++ b/bin/newins
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newins,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Error: Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doins "${T}/${2}"
diff --git a/bin/newlib.a b/bin/newlib.a
new file mode 100755
index 000000000..3ec62a3e9
--- /dev/null
+++ b/bin/newlib.a
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newlib.a,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Error: Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dolib.a "${T}/${2}"
diff --git a/bin/newlib.so b/bin/newlib.so
new file mode 100755
index 000000000..aa9f9a174
--- /dev/null
+++ b/bin/newlib.so
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newlib.so,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Error: Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dolib.so "${T}/${2}"
diff --git a/bin/newman b/bin/newman
new file mode 100755
index 000000000..227411a56
--- /dev/null
+++ b/bin/newman
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newman,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+doman "${T}/${2}"
diff --git a/bin/newsbin b/bin/newsbin
new file mode 100755
index 000000000..eadfba220
--- /dev/null
+++ b/bin/newsbin
@@ -0,0 +1,13 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/newsbin,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+if [ -z "${T}" ] || [ -z "${2}" ] ; then
+ echo "Nothing defined to do."
+ exit 1
+fi
+
+rm -rf "${T}/${2}"
+cp "${1}" "${T}/${2}"
+dosbin "${T}/${2}"
diff --git a/bin/pemerge.py b/bin/pemerge.py
new file mode 100755
index 000000000..08de6eda3
--- /dev/null
+++ b/bin/pemerge.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python -O
+
+import profile,time,sys,os
+sys.path = ["/usr/lib/portage/bin","/usr/lib/portage/pym"]+sys.path
+
+def clock():
+ return time.time()
+profile.time.clock = clock
+
+profile.run("import emerge", os.getcwd()+"/prof")
+
+class StatsProcesser:
+ def __init__(self, stats):
+ self.output = []
+ self.last = ""
+ import sys
+ sys.stdout = self
+ stats.print_stats()
+ sys.stdout = sys.__stdout__
+ funcs = ["?"]
+ for line in self.output:
+ spline = line.split()
+ if len(spline) == 6 and spline[0][0].isdigit():
+ func = spline[5][spline[5].index("(")+1:-1]
+ print line
+ if func not in funcs:
+ funcs.append(func)
+ func = "\\(" + func + "\\)"
+ stats.print_callers(func)
+
+ def write(self, text):
+ new = self.last + text
+ new = new.split("\n")
+ if len(new) > 1:
+ self.output += new[:-1]
+ self.last = new[-1]
+
+import pstats
+p = pstats.Stats("prof")
+dir(p)
+p.sort_stats("time")
+p.print_stats()
+
+sp = StatsProcesser(p)
diff --git a/bin/pkgmerge b/bin/pkgmerge
new file mode 100755
index 000000000..2bbb5f680
--- /dev/null
+++ b/bin/pkgmerge
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/pkgmerge,v 1.8 2004/10/04 13:56:50 vapier Exp $
+
+import sys,os,string
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage,xpak
+
+#build our package digraph
+
+def digraph_create(digraph,mykey,myprovides=None):
+ mytbz2=xpak.tbz2(bintree.getname(mykey))
+ mydep=mytbz2.getelements("RDEPEND")
+ digraph.addnode(mykey,myprovides)
+ mycheck=roottree.depcheck(string.join(mydep," "))
+ if mycheck[0]==0:
+ print "!!! Error: RDEPEND string formatted incorrectly:",mydep
+ return None
+ for x in mycheck[1]:
+ mymatch=bintree.dep_bestmatch(x)
+ if mymatch=="":
+ print "!!! Error: can't resolve dependency --",x
+ return None
+ if not digraph_create(digraph,mymatch,mykey):
+ return None
+ return 1
+
+#main program loop
+myvirtuals=portage.getvirtuals(portage.root)
+roottree=portage.vartree(portage.root,myvirtuals)
+bintree=portage.binarytree("/",myvirtuals)
+pretend=0
+if len(sys.argv)>=2:
+ if sys.argv[1]=="--pretend":
+ print "These are the packages that I would merge, in order:"
+ pretend=1
+ del sys.argv[1]
+ elif sys.argv[1]=="--help":
+ print "Usage: pkgmerge [--pretend] pkg1.tbz2 [pkg2.tbz2]..."
+ sys.exit(1)
+for mypkg in sys.argv[1:]:
+ digraph=portage.digraph()
+ mytbz2=xpak.tbz2(mypkg)
+ mykey=mytbz2.getelements("CATEGORY")[0]+"/"+os.path.basename(mypkg)[:-5]
+ digraph_create(digraph,mykey)
+ while not digraph.empty():
+ mykey=digraph.firstzero()
+ if not mykey:
+ print "!!! Error: circular dependencies"
+ sys.exit(1)
+ mytbz2=bintree.getname(mykey)
+ if pretend:
+ print mytbz2
+ else:
+ portage.pkgmerge(mytbz2,portage.settings["ROOT"])
+ digraph.delnode(mykey)
+
diff --git a/bin/pkgmerge.new b/bin/pkgmerge.new
new file mode 100755
index 000000000..66dbe1676
--- /dev/null
+++ b/bin/pkgmerge.new
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/pkgmerge.new,v 1.7 2004/10/04 13:56:50 vapier Exp $
+
+import os,string,sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage,xpak
+
+#beautiful directed graph functions
+
+def dig_addnode(digraph,mykey,myprovides):
+ if not digraph.has_key(mykey):
+ if myprovides==None:
+ digraph[mykey]=[0,[]]
+ else:
+ digraph[mykey]=[0,[myprovides]]
+ digraph[myprovides][0]=digraph[myprovides][0]+1
+ return
+ digraph[mykey]=[digraph[mykey][0],digraph[mykey][1].append(myprovides)]
+
+def dig_delnode(digraph,mykey):
+ if not digraph.has_key(mykey):
+ return
+ for x in digraph[mykey][1]:
+ digraph[x][0]=digraph[x][0]-1
+ del digraph[mykey]
+
+def dig_firstzero(digraph):
+ for x in digraph.keys():
+ if digraph[x][0]==0:
+ return x
+ return None
+
+#build our package digraph
+
+def digraph_create(digraph,mykey,myprovides=None):
+ mytbz2=xpak.tbz2(bintree.getname(mykey))
+ mydep=mytbz2.getelements("RDEPEND")
+ dig_addnode(digraph,mykey,myprovides)
+ mycheck=roottree.depcheck(string.join(mydep," "))
+ if mycheck[0]==0:
+ print "!!! Error: RDEPEND string formatted incorrectly:",mydep
+ return None
+ for x in mycheck[1]:
+ mymatch=bintree.dep_bestmatch(x)
+ if mymatch=="":
+ print "!!! Error: can't resolve dependency --",x
+ return None
+ if not digraph_create(digraph,mymatch,mykey):
+ return None
+ return 1
+
+#main program loop
+myvirtuals=portage.getvirtual(portage.root)
+roottree=portage.vartree(portage.root,myvirtuals)
+bintree=portage.binarytree("/",myvirtuals)
+pretend=0
+if len(sys.argv)>=2:
+ if sys.argv[1]=="--pretend":
+ print "These are the packages that I would merge, in order:"
+ pretend=1
+ del sys.argv[1]
+ elif sys.argv[1]=="--help":
+ print "Usage: pkgmerge [--pretend] pkg1.tbz2 [pkg2.tbz2]..."
+ sys.exit(1)
+for mypkg in sys.argv[1:]:
+ digraph={}
+ mytbz2=xpak.tbz2(mypkg)
+ mykey=mytbz2.getelements("CATEGORY")[0]+"/"+mypkg[:-5]
+ digraph_create(digraph,mykey)
+ while (len(digraph)):
+ mykey=dig_firstzero(digraph)
+ if not mykey:
+ print "!!! Error: circular dependencies"
+ sys.exit(1)
+ mytbz2=bintree.getname(mykey)
+ if pretend:
+ print mytbz2
+ else:
+ portage.pkgmerge(mytbz2)
+ dig_delnode(digraph,mykey)
+
diff --git a/bin/pkgname b/bin/pkgname
new file mode 100755
index 000000000..22be6f1da
--- /dev/null
+++ b/bin/pkgname
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/pkgname,v 1.8 2004/10/04 13:56:50 vapier Exp $
+
+import sys
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage
+
+a=portage.pkgsplit(sys.argv[1])
+if a:
+ print a[0],a[1],a[2][1:]
+ sys.exit(0)
+else:
+ print '!!! Error: package name is invalid.'
+ sys.exit(1)
diff --git a/bin/portage_gpg_update.sh b/bin/portage_gpg_update.sh
new file mode 100755
index 000000000..a20d9bc1b
--- /dev/null
+++ b/bin/portage_gpg_update.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/portage_gpg_update.sh,v 1.2 2004/10/04 13:56:50 vapier Exp $
+
+wget -O - http://www.gentoo.org/proj/en/devrel/roll-call/userinfo.xml | sed 's:.*\(0x[0-9a-fA-F]\+\)[^0-9a-fA-F].*:\1:gp;d' | xargs gpg -vvv --no-default-keyring --no-permission-warning --homedir /usr/portage/metadata --keyring "gentoo.gpg" --keyserver subkeys.pgp.net --recv-keys &> gpg.log
diff --git a/bin/portageq b/bin/portageq
new file mode 100755
index 000000000..6bd6c402e
--- /dev/null
+++ b/bin/portageq
@@ -0,0 +1,256 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/portageq,v 1.13.2.1 2005/04/12 12:23:41 jstubbs Exp $
+
+import sys, os
+os.environ["PORTAGE_CALLER"] = "portageq"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import portage,types,string
+
+
+#-----------------------------------------------------------------------------
+#
+# 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)
+ try:
+ mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
+ if mylist:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+ except KeyError:
+ sys.exit(1)
+
+
+def best_version(argv):
+ """<root> <category/package>
+ Returns category/package-version (without .ebuild).
+ """
+ if (len(argv) < 2):
+ print "ERROR: insufficient parameters!"
+ sys.exit(2)
+ try:
+ mylist=portage.db[argv[0]]["vartree"].dbapi.match(argv[1])
+ print portage.best(mylist)
+ except KeyError:
+ sys.exit(1)
+
+
+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)
+
+
+def best_visible(argv):
+ """<root> [<category/package>]+
+ Returns category/package-version (without .ebuild).
+ """
+ if (len(argv) < 2):
+ print "ERROR: insufficient parameters!"
+ sys.exit(2)
+ try:
+ mylist=portage.db[argv[0]]["porttree"].dbapi.match(argv[1])
+ print portage.best(mylist)
+ except KeyError:
+ sys.exit(1)
+
+
+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)
+
+
+def all_best_visible(argv):
+ """<root>
+ Returns all best_visible packages (without .ebuild).
+ """
+ if (len(argv) < 1):
+ print "ERROR: insufficient parameters!"
+
+ #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
+
+def match(argv):
+ """<root> <category/package>
+ Returns \n seperated list of category/package-version
+ """
+ if (len(argv) < 2):
+ print "ERROR: insufficient parameters!"
+ sys.exit(2)
+ try:
+ print string.join(portage.db[argv[0]]["vartree"].dbapi.match(argv[1]),"\n")
+ except KeyError:
+ sys.exit(1)
+
+
+def vdb_path(argv):
+ """
+ Returns the path used for the var(installed) package database for the
+ set environment/configuration options.
+ """
+ print portage.root+portage.VDB_PATH
+
+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 as defined in the portage configuration.
+ """
+ print portage.settings["PORTDIR"]
+
+
+def config_protect(argv):
+ """
+ Returns the CONFIG_PROTECT paths as defined in the portage configuration.
+ """
+ print portage.settings["CONFIG_PROTECT"]
+
+
+def config_protect_mask(argv):
+ """
+ Returns the CONFIG_PROTECT_MASK paths as defined in the portage configuration.
+ """
+ print portage.settings["CONFIG_PROTECT_MASK"]
+
+
+def portdir_overlay(argv):
+ """
+ Returns the PORTDIR_OVERLAY path as defined in the portage configuration.
+ """
+ print portage.settings["PORTDIR_OVERLAY"]
+
+
+def pkgdir(argv):
+ """
+ Returns the PKGDIR path as defined in the portage configuration.
+ """
+ print portage.settings["PKGDIR"]
+
+
+def distdir(argv):
+ """
+ Returns the DISTDIR path as defined in the portage configuration.
+ """
+ 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>='
+ """
+ print portage.settings[argv[0]]
+
+
+#-----------------------------------------------------------------------------
+#
+# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
+#
+
+def usage():
+ rev="$Revision: 1.13.2.1 $"
+ ver=string.split(rev, ' ')[1]
+ print ">>> Portage information query tool -- version "+ver
+ 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.
+ #
+ for name in globals().keys():
+ # Drop python stuff, modules, and our own support functions.
+ if (name in ("usage", "__doc__", "__name__", "main", "os", "portage", "sys", "__builtins__", "types", "string")):
+ continue
+
+ # Drop non-functions
+ obj = globals()[name]
+ if (type(obj) != types.FunctionType):
+ continue
+
+ doc = obj.__doc__
+ if (doc == None):
+ print " "+name
+ print " MISSING DOCUMENTATION!"
+ print ""
+ continue
+
+ lines = string.split(doc, '\n')
+ print " "+name+" "+string.strip(lines[0])
+ for line in lines[1:]:
+ print " "+string.strip(line)
+
+
+def main():
+ if (len(sys.argv) < 2):
+ usage()
+ sys.exit()
+
+ cmd = sys.argv[1]
+ try:
+ function = globals()[cmd]
+ function(sys.argv[2:])
+ except KeyError:
+ usage()
+ sys.exit()
+
+main()
+
+
+#-----------------------------------------------------------------------------
diff --git a/bin/prepall b/bin/prepall
new file mode 100755
index 000000000..3826f74fe
--- /dev/null
+++ b/bin/prepall
@@ -0,0 +1,39 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepall,v 1.10 2004/10/14 23:31:33 ferringb Exp $
+
+prepallman
+prepallinfo
+prepallstrip
+
+#this should help to ensure that all (most?) shared libraries are executable
+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
+ echo "making executable: /${j/${D}/}"
+ chmod +x "${j}"
+ done
+done
+
+# Move aclocals
+for i in `find "${D}"/ -name "aclocal" -type d 2>/dev/null` ; do
+ [ -z "${i}" ] && continue
+
+ # Strip double '/'
+ dir1="`echo "${i}" | sed -e 's:/\{2,\}:/:g'`"
+ dir2="`echo "${D}/usr/share/aclocal" | sed -e 's:/\{2,\}:/:g'`"
+
+ [ "${dir1}" == "${dir2}" ] && continue
+
+ echo "moving aclocal: /${i/${D}/}"
+ install -d "${D}"usr/share/aclocal
+ mv "${i}"/* "${D}"usr/share/aclocal
+ rm -fr "${i}"
+done
diff --git a/bin/prepalldocs b/bin/prepalldocs
new file mode 100755
index 000000000..26ac80ca4
--- /dev/null
+++ b/bin/prepalldocs
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepalldocs,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+z="`find "${D}"usr/share/doc \( -type f -or -type l \) -not -name "*.gz" -not -name "*.js" 2>/dev/null`"
+
+for y in ${z} ; do
+ if [ -L "${y}" ] ; then
+ # Symlink ...
+ mylink="${y}"
+ linkto="`readlink "${y}"`"
+
+ if [ "${linkto##*.}" != "gz" ] ; then
+ linkto="${linkto}.gz"
+ fi
+ if [ "${mylink##*.}" != "gz" ] ; then
+ mylink="${mylink}.gz"
+ fi
+
+ echo "fixing doc symlink: ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [ "${y}" != "${mylink}" ] ; then
+ echo "removing old symlink: ${y##*/}"
+ rm -f "${y}"
+ fi
+ else
+ if [ "${y##*.}" != "gz" ] ; then
+ echo "gzipping doc: ${y##*/}"
+ gzip -f -9 "${y}"
+ fi
+ fi
+done
diff --git a/bin/prepallinfo b/bin/prepallinfo
new file mode 100755
index 000000000..134e8326e
--- /dev/null
+++ b/bin/prepallinfo
@@ -0,0 +1,9 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepallinfo,v 1.6 2004/10/04 13:56:50 vapier Exp $
+
+[ ! -d "${D}usr/share/info" ] && exit 0
+
+echo "info:"
+prepinfo
diff --git a/bin/prepallman b/bin/prepallman
new file mode 100755
index 000000000..26486fda7
--- /dev/null
+++ b/bin/prepallman
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepallman,v 1.10 2004/10/04 13:56:50 vapier Exp $
+
+echo "man:"
+for x in "${D}"opt/*/man "${D}"usr/share/man "${D}"usr/local/man "${D}"usr/X11R6/man ; do
+ if [ -d "${x}" ]
+ then
+ prepman "`echo "${x}" | sed -e "s:${D}::" -e "s:/man[/]*$::"`"
+ fi
+done
diff --git a/bin/prepallstrip b/bin/prepallstrip
new file mode 100755
index 000000000..57994738e
--- /dev/null
+++ b/bin/prepallstrip
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepallstrip,v 1.12 2004/10/04 13:56:50 vapier Exp $
+
+if [ "${FEATURES//*nostrip*/true}" == "true" ] || [ "${RESTRICT//*nostrip*/true}" == "true" ] ; then
+ exit 0
+fi
+
+echo "prepallstrip:"
+prepstrip "${D}"
diff --git a/bin/prepinfo b/bin/prepinfo
new file mode 100755
index 000000000..65bfba32c
--- /dev/null
+++ b/bin/prepinfo
@@ -0,0 +1,45 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepinfo,v 1.6.2.1 2005/05/29 12:40:08 jstubbs Exp $
+
+if [ -z "$1" ] ; then
+ z="${D}usr/share/info"
+else
+ if [ -d "${D}$1/share/info" ] ; then
+ z="${D}$1/share/info"
+ else
+ z="${D}$1/info"
+ fi
+fi
+
+[ ! -d "${z}" ] && exit 0
+
+rm -f "${z}"/{dir,dir.info,dir.info.gz}
+
+for x in `find "${z}"/ -mindepth 1 -maxdepth 1 \( -type f -or -type l \) 2>/dev/null` ; do
+ if [ -L "${x}" ] ; then
+ # Symlink ...
+ mylink="${x}"
+ linkto="`readlink "${x}"`"
+
+ if [ "${linkto##*.}" != "gz" ] ; then
+ linkto="${linkto}.gz"
+ fi
+ if [ "${mylink##*.}" != "gz" ] ; then
+ mylink="${mylink}.gz"
+ fi
+
+ echo "fixing GNU info symlink: ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [ "${x}" != "${mylink}" ] ; then
+ echo "removing old symlink: ${x##*/}"
+ rm -f "${x}"
+ fi
+ else
+ if [ "${x##*.}" != "gz" ] ; then
+ echo "gzipping GNU info page: ${x##*/}"
+ gzip -f -9 "${x}"
+ fi
+ fi
+done
diff --git a/bin/preplib b/bin/preplib
new file mode 100755
index 000000000..2a4312606
--- /dev/null
+++ b/bin/preplib
@@ -0,0 +1,25 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/preplib,v 1.7.2.1 2005/01/02 09:36:02 jstubbs Exp $
+
+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/bin/preplib.so b/bin/preplib.so
new file mode 100755
index 000000000..13d67d9c9
--- /dev/null
+++ b/bin/preplib.so
@@ -0,0 +1,10 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/preplib.so,v 1.10.2.1 2004/12/06 03:01:43 carpaski Exp $
+
+for x in "$@" ; do
+ if [ -d "${D}${x}" ] ; then
+ ldconfig -n -N "${D}${x}"
+ fi
+done
diff --git a/bin/prepman b/bin/prepman
new file mode 100755
index 000000000..2042c4d3d
--- /dev/null
+++ b/bin/prepman
@@ -0,0 +1,46 @@
+#!/bin/bash
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepman,v 1.10.2.3 2005/05/29 12:40:08 jstubbs Exp $
+
+if [ -z "$1" ] ; then
+ z="${D}usr/share/man"
+else
+ z="${D}$1/man"
+fi
+
+[ ! -d "${z}" ] && exit 0
+
+for x in `find "${z}"/ -type d 2>/dev/null` ; do
+ for y in `find "${x}"/ -mindepth 1 -maxdepth 1 \( -type f -or -type l \) ! -name '.keep' 2>/dev/null` ; do
+ if [ -L "${y}" ] ; then
+ # Symlink ...
+ mylink="${y}"
+ linkto="`readlink "${y}"`"
+
+ # Do NOT change links to directories
+ if [ -d "${z}/${linkto}" ] ; then
+ continue
+ fi
+
+ if [ "${linkto##*.}" != "gz" ] && [ "${linkto##*.}" != "bz2" ]; then
+ linkto="${linkto}.gz"
+ fi
+ if [ "${mylink##*.}" != "gz" ] && [ "${mylink##*.}" != "bz2" ]; then
+ mylink="${mylink}.gz"
+ fi
+
+ echo "fixing man page symlink: ${mylink##*/}"
+ ln -snf "${linkto}" "${mylink}"
+ if [ "${y}" != "${mylink}" ] ; then
+ echo "removing old symlink: ${y##*/}"
+ rm -f "${y}"
+ fi
+ else
+ if [ "${y##*.}" != "gz" ] && [ "${y##*.}" != "bz2" ] && [ ! -d "${y}" ]; then
+ echo "gzipping man page: ${y##*/}"
+ gzip -f -9 "${y}"
+ fi
+ fi
+ done
+done
diff --git a/bin/prepstrip b/bin/prepstrip
new file mode 100755
index 000000000..f5a51a378
--- /dev/null
+++ b/bin/prepstrip
@@ -0,0 +1,48 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/prepstrip,v 1.23.2.3 2005/08/15 02:58:20 vapier Exp $
+
+if [ "${FEATURES//*nostrip*/true}" == "true" ] || [ "${RESTRICT//*nostrip*/true}" == "true" ] ; then
+ echo "nostrip"
+ STRIP="/bin/false"
+ PORTAGE_STRIP_FLAGS=""
+else
+ STRIP="${STRIP:-${CHOST}-strip}"
+ type -p ${STRIP} > /dev/null || STRIP=strip
+ PORTAGE_STRIP_FLAGS=${PORTAGE_STRIP_FLAGS:---strip-unneeded}
+fi
+
+banner=1
+retval=0
+
+for x in "$@" ; do
+ if [ -d "${x}" ]; then
+ # We only want files. So make a pass for each directory and call again.
+ find "${x}" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 -or -name '*.so' -or -name '*.so.*' \) -print0 |
+ $XARGS -0 -n500 prepstrip
+ else
+ if [ ${banner} -eq 1 ] ; then
+ echo "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
+ banner=0
+ fi
+
+ f=$(file "${x}") || continue
+ [ -z "${f}" ] && continue
+
+ if [ -z "${f/*current ar archive*/}" ]; then
+ echo " ${x:${#D}:${#x}}"
+ ${STRIP} -g "${x}"
+ fi
+ if [ -z "${f/*SB executable*/}" ]; then
+ echo " ${x:${#D}:${#x}}"
+ ${STRIP} "${x}"
+ fi
+ if [ -z "${f/*SB shared object*/}" ]; then
+ echo " ${x:${#D}:${#x}}"
+ ${STRIP} ${PORTAGE_STRIP_FLAGS} "${x}"
+ fi
+ fi
+done
+
+exit ${retval}
diff --git a/bin/quickpkg b/bin/quickpkg
new file mode 100755
index 000000000..f5baa4cbe
--- /dev/null
+++ b/bin/quickpkg
@@ -0,0 +1,148 @@
+#!/bin/bash
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/quickpkg,v 1.13.2.6 2005/08/10 22:08:48 vapier Exp $
+
+# This script tries to quickly create a Gentoo binary package using the
+# VDB_PATH/category/pkg/* files
+#
+# Resulting tbz2 file will be created in ${PKGDIR} ...
+# default is /usr/portage/packages/All/
+
+if [ "`whoami`" != "root" ] ; then
+ echo "You must run this as root"
+ exit 1
+fi
+
+export PORTAGE_DB=$(portageq vdb_path)
+if [ -z "$1" ] || [ $1 == "-h" ] || [ $1 == "--help" ] ; then
+ echo "QUICKPKG ver 1.2"
+ echo "USAGE: quickpkg <list of pkgs>"
+ echo " a pkg can be of the form:"
+ echo " - ${PORTAGE_DB}/<CATEGORY>/<PKG-VERSION>/"
+ echo " - single depend-type atom ..."
+ echo " if portage can emerge it, quickpkg can make a package"
+ echo " for exact definitions of depend atoms, see ebuild(5)"
+ echo
+ echo "EXAMPLE:"
+ echo " quickpkg ${PORTAGE_DB}/net-www/apache-1.3.27-r1"
+ echo " package up apache, just version 1.3.27-r1"
+ echo " quickpkg apache"
+ echo " package up apache, all versions of apache installed"
+ echo " quickpkg =apache-1.3.27-r1"
+ echo " package up apache, just version 1.3.27-r1"
+ exit 1
+fi
+
+export PKGDIR=$(portageq envvar PKGDIR)
+export PORTAGE_TMPDIR=$(portageq envvar PORTAGE_TMPDIR)
+
+source /sbin/functions.sh
+
+# here we make a package given a little info
+# $1 = package-name w/version
+# $2 = category
+do_pkg() {
+ mkdir -p "${PORTAGE_TMPDIR}/portage-pkg" || exit 1
+ chmod 0750 "${PORTAGE_TMPDIR}/portage-pkg"
+ MYDIR="${PORTAGE_TMPDIR}/portage-pkg/$1"
+ SRCDIR="${PORTAGE_DB}/$2/$1"
+ LOG="${PORTAGE_TMPDIR}/portage-pkg/$1-quickpkglog"
+
+ ebegin "Building package for $1"
+ (
+ # clean up temp directory
+ rm -rf "${MYDIR}"
+
+ # get pkg info files
+ mkdir -p "${MYDIR}"/temp
+ cp "${SRCDIR}"/* "${MYDIR}"/temp/
+
+ # create filelist and a basic tbz2
+ gawk '{
+ if ($1 != "dir") {
+ if ($1 == "obj")
+ NF=NF-2
+ else if ($1 == "sym")
+ NF=NF-3
+ print
+ }
+ }' "${SRCDIR}"/CONTENTS | cut -f2- -d" " - > "${MYDIR}"/filelist
+ tar vjcf "${MYDIR}"/bin.tar.bz2 --files-from="${MYDIR}"/filelist --no-recursion
+
+ # join together the basic tbz2 and the pkg info files
+ xpak "${MYDIR}"/temp "${MYDIR}"/inf.xpak
+ tbz2tool join "${MYDIR}"/bin.tar.bz2 "${MYDIR}"/inf.xpak "${MYDIR}"/$1.tbz2
+
+ # move the final binary package to PKGDIR
+ [ -d "${PKGDIR}"/All ] || mkdir -p "${PKGDIR}"/All
+ [ -d "${PKGDIR}/$2" ] || mkdir -p "${PKGDIR}/$2"
+ mv "${MYDIR}"/$1.tbz2 "${PKGDIR}"/All
+ ( cd "${PKGDIR}/$2" && ln -s ../All/$1.tbz2 )
+
+ # cleanup again
+ rm -rf "${MYDIR}"
+ ) >& "${LOG}"
+
+ if [ -e "${PKGDIR}/All/$1.tbz2" ] ; then
+ rm -f "${LOG}"
+ PKGSTATS="${PKGSTATS}"$'\n'"$(einfo $1: $(du -h "${PKGDIR}/All/$1.tbz2" | gawk '{print $1}'))"
+ eend 0
+ else
+ cat ${LOG}
+ PKGSTATS="${PKGSTATS}"$'\n'"$(ewarn $1: not created)"
+ eend 1
+ fi
+}
+
+# here we parse the parameters given to use on the cmdline
+export PKGERROR=""
+export PKGSTATS=""
+for x in "$@" ; do
+
+ # they gave us full path
+ if [ -e "${x}"/CONTENTS ] ; then
+ x=$(readlink -f $x)
+ pkg=$(echo ${x} | cut -d/ -f6)
+ cat=$(echo ${x} | cut -d/ -f5)
+ do_pkg "${pkg}" "${cat}"
+
+ # lets figure out what they want
+ else
+ DIRLIST=$(portageq match / "${x}")
+ if [ -z "${DIRLIST}" ] ; then
+ eerror "Could not find anything to match '${x}'; skipping"
+ export PKGERROR="${PKGERROR} ${x}"
+ continue
+ fi
+
+ for d in ${DIRLIST} ; do
+ pkg=$(echo ${d} | cut -d/ -f2)
+ cat=$(echo ${d} | cut -d/ -f1)
+ if [ -f "${PORTAGE_DB}/${cat}/${pkg}/CONTENTS" ] ; then
+ do_pkg ${pkg} ${cat}
+ elif [ -d "${PORTAGE_DB}/${cat}/${pkg}" ] ; then
+ ewarn "Package '${cat}/${pkg}' was injected; skipping"
+ else
+ eerror "Unhandled case (${cat}/${pkg}) !"
+ eerror "Please file a bug at http://bugs.gentoo.org/"
+ exit 10
+ fi
+ done
+ fi
+
+done
+
+if [ -z "${PKGSTATS}" ] ; then
+ eerror "No packages found"
+ exit 1
+else
+ echo $'\n'"$(einfo Packages now in ${PKGDIR}:)${PKGSTATS}"
+fi
+if [ ! -z "${PKGERROR}" ] ; then
+ ewarn "The following packages could not be found:"
+ ewarn "${PKGERROR}"
+ exit 2
+fi
+
+exit 0
diff --git a/bin/regenworld b/bin/regenworld
new file mode 100755
index 000000000..2e7f7f841
--- /dev/null
+++ b/bin/regenworld
@@ -0,0 +1,93 @@
+#!/usr/bin/python
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/regenworld,v 1.10.2.1 2005/01/11 03:40:57 carpaski Exp $
+
+import sys
+sys.path.insert(0, "/usr/lib/portage/pym")
+
+import portage, string, re
+
+__candidatematcher__ = re.compile("^[0-9]+: \\*\\*\\* emerge ")
+__noncandidatematcher__ = re.compile(" sync( |$)| clean( |$)| search( |$)|--oneshot| 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
+
+# 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." % portage.WORLD_FILE
+ sys.exit(0)
+
+worldlist = portage.grabfile(portage.WORLD_FILE)
+syslist = portage.settings.packages
+syslist = filter(issyspkg, syslist)
+
+logfile = portage.grabfile("/var/log/emerge.log")
+biglist = filter(iscandidate, logfile)
+biglist = map(getpkginfo, biglist)
+tmplist = []
+for l in biglist:
+ tmplist += l.split()
+biglist = filter(isunwanted, tmplist)
+#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["/"]["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["/"]["vartree"].dbapi.match(mykey)
+ except KeyError:
+ if "--debug" in sys.argv:
+ print "* ignoring broken log entry for %s (likely injected)" % mykey
+ except ValueError, e:
+ print "* %s is an ambigous package name, candidates are:\n%s" % (mykey, e)
+ 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)
+
+myfile=open(portage.WORLD_FILE, "w")
+myfile.write(string.join(worldlist, '\n')+'\n')
+myfile.close()
diff --git a/bin/repoman b/bin/repoman
new file mode 100755
index 000000000..40607d7a6
--- /dev/null
+++ b/bin/repoman
@@ -0,0 +1,1522 @@
+#!/usr/bin/python -O
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/repoman,v 1.98.2.23 2005/06/18 01:00:43 vapier Exp $
+
+# 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.
+
+import os,sys,shutil
+exename=os.path.basename(sys.argv[0])
+os.environ["PORTAGE_CALLER"]="repoman"
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+version="1.2"
+
+import string,signal,re,pickle,tempfile
+
+import portage
+import portage_checksum
+import portage_const
+import portage_dep
+import cvstree
+import time
+from output import *
+#bold, darkgreen, darkred, green, red, turquoise, yellow
+
+from commands import getstatusoutput
+from fileinput import input
+from grp import getgrnam
+from stat import *
+
+
+def err(txt):
+ print exename+": "+txt
+ sys.exit(1)
+
+def exithandler(signum=None,frame=None):
+ sys.stderr.write("\n"+exename+": Interrupted; exiting...\n")
+ sys.exit(1)
+ os.kill(0,signal.SIGKILL)
+signal.signal(signal.SIGINT,exithandler)
+
+REPOROOTS=["gentoo-x86"]
+modes=["scan","fix","full","help","commit","last","lfull"]
+shortmodes={"ci":"commit"}
+modeshelp={
+"scan" :"Scan current directory tree for QA issues (default)",
+"fix" :"Fix those issues that can be fixed (stray digests, missing digests)",
+"full" :"Scan current directory tree for QA issues (full listing)",
+"help" :"Show this screen",
+"commit":"Scan current directory tree for QA issues; if OK, commit via cvs",
+"last" :"Remember report from last run",
+"lfull" :"Remember report from last run (full listing)"
+}
+options=["--pretend","--help","--commitmsg","--commitmsgfile","--verbose","--xmlparse","--ignore-other-arches","--include-masked"]
+shortoptions={"-m":"--commitmsg","-M":"--commitmsgfile","-p":"--pretend","-v":"--verbose","-x":"--xmlparse","-I":"--ignore-other-arches"}
+optionshelp={
+"--pretend":"Don't actually perform commit or fix steps; just show what would be done (always enabled when not started in a CVS tree).",
+"--help" :"Show this screen",
+"--commitmsg" :"Adds a commit message via the command line.",
+"--commitmsgfile":"Adds a commit message from a file given on the command line.",
+"--ignore-other-arches": "Instructs repoman to ignore arches that are not relevent to the committing arch. REPORT/FIX issues you work around.",
+"--verbose":"Displays every package name while checking",
+"--xmlparse":"Forces the metadata.xml parse check to be carried out",
+"--include-masked":"Includes masked packages in scans at category or tree level"
+}
+
+qahelp={
+ "CVS/Entries.IO_error":"Attempting to commit, and an IO error was encountered access the Entries file",
+ "digest.partial":"Digest files do not contain all corresponding URI elements",
+ "digest.assumed":"Existing digest must be assumed correct (Package level only)",
+ "digest.unused":"Digest entry has no matching SRC_URI entry",
+ "digest.fail":"Digest does not match the specified local file",
+ "digest.stray":"Digest files that do not have a corresponding ebuild",
+ "digest.missing":"Digest files that are missing (ebuild exists, digest doesn't)",
+ "digest.disjointed":"Digests not added to cvs when the matching ebuild has been added",
+ "digest.notadded":"Digests that exist but have not been added to cvs",
+ "digest.unmatch":"Digests which are incomplete (please check if your USE/ARCH includes all files)",
+ "ebuild.invalidname":"Ebuild files with a non-parseable or syntactically incorrect name",
+ "ebuild.namenomatch":"Ebuild files that do not have the same name as their parent directory",
+ "changelog.missing":"Missing ChangeLog files",
+ "ebuild.disjointed":"Ebuilds not added to cvs when the matching digest has been added",
+ "ebuild.notadded":"Ebuilds that exist but have not been added to cvs",
+ "changelog.notadded":"ChangeLogs that exist but have not been added to cvs",
+ "filedir.missing":"Package lacks a files directory",
+ "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 20k",
+ "KEYWORDS.missing":"Ebuilds that have a missing KEYWORDS variable",
+ "LICENSE.missing":"Ebuilds that have a missing LICENSE variable",
+ "DESCRIPTION.missing":"Ebuilds that have a missing DESCRIPTION variable",
+ "SLOT.missing":"Ebuilds that have a missing SLOT variable",
+ "HOMEPAGE.missing":"Ebuilds that have a missing 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",
+ "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)",
+ "LICENSE.syntax":"Syntax error in LICENSE (usually an extra/missing space/parenthesis)",
+ "ebuild.syntax":"Error generating cache entry for ebuild; typically caused by ebuild syntax error",
+ "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.readonly":"Assigning a readonly variable",
+ "IUSE.invalid":"This build has a variable in IUSE that is not in the use.desc or use.local.desc file",
+ "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",
+ "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",
+ "metadata.missing":"Missing metadata.xml files",
+ "metadata.bad":"Bad metadata.xml files",
+ "virtual.versioned":"PROVIDE contains virtuals with versions",
+ "virtual.exists":"PROVIDE contains existing package names",
+ "virtual.unavailable":"PROVIDE contains a virtual which contains no profile default"
+}
+
+qacats = qahelp.keys()
+qacats.sort()
+
+qawarnings=[
+"changelog.missing",
+"changelog.notadded",
+"ebuild.notadded",
+"ebuild.nostable",
+"ebuild.allmasked",
+"ebuild.nesteddie",
+"digest.assumed",
+"digest.notadded",
+"digest.disjointed",
+"digest.missing",
+"digest.unused",
+"DEPEND.badmasked","RDEPEND.badmasked","PDEPEND.badmasked",
+"DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
+"DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
+"IUSE.invalid",
+"ebuild.minorsyn",
+"ebuild.badheader",
+"file.size",
+"metadata.missing",
+"metadata.bad",
+"virtual.versioned"
+]
+
+missingvars=["KEYWORDS","LICENSE","DESCRIPTION","HOMEPAGE","SLOT"]
+allvars=portage.auxdbkeys
+commitmessage=None
+commitmessagefile=None
+for x in missingvars:
+ x += ".missing"
+ if x not in qacats:
+ print "* missingvars values need to be added to qahelp ("+x+")"
+ qacats.append(x)
+ qawarnings.append(x)
+
+
+def err(txt):
+ print exename+": "+txt
+ sys.exit(1)
+
+ven_cat = r'[\w0-9-]+' # Category
+ven_nam = r'([+a-z0-9-]+(?:[+_a-z0-9-]*[+a-z0-9-]+)*)' # Name
+ven_ver = r'((?:\d+\.)*\d+[a-z]?)' # Version
+ven_suf = r'(_(alpha\d*|beta\d*|pre\d*|rc\d*|p\d+))?' # Suffix
+ven_rev = r'(-r\d+)?' # Revision
+
+ven_string=ven_cat+'/'+ven_nam+'-'+ven_ver+ven_suf+ven_rev
+valid_ebuild_name_re=re.compile(ven_string+'$', re.I)
+valid_ebuild_filename_re=re.compile(ven_string+'\.ebuild$', re.I)
+
+repoman_settings = portage.config(clone=portage.settings)
+
+def valid_ebuild_name(name):
+ """(name) --- Checks to ensure that the package name meets portage specs.
+ Return 1 if valid, 0 if not."""
+ # Handle either a path to the ebuild, or cat/pkg-ver string
+ if (len(name) > 7) and (name[-7:] == ".ebuild"):
+ if valid_ebuild_filename_re.match(name):
+ return 1
+ else:
+ if valid_ebuild_name_re.match(name):
+ return 1
+ return 0
+
+
+def help():
+ print
+ print green(exename+" "+version)
+ print " \"Quality is job zero.\""
+ print " Copyright 1999-2005 Gentoo Foundation"
+ print " Distributed under the terms of the GNU General Public License v2"
+ print
+ print bold(" Usage:"),turquoise(exename),"[",green("option"),"] [",green("mode"),"]"
+ print bold(" Modes:"),turquoise("scan (default)"),
+ for x in modes[1:]:
+ print "|",turquoise(x),
+ print "\n"
+ print " "+green(string.ljust("Option",20)+" Description")
+ for x in options:
+ print " "+string.ljust(x,20),optionshelp[x]
+ print
+ print " "+green(string.ljust("Mode",20)+" Description")
+ for x in modes:
+ print " "+string.ljust(x,20),modeshelp[x]
+ print
+ print " "+green(string.ljust("QA keyword",20)+" Description")
+ for x in qacats:
+ print " "+string.ljust(x,20),qahelp[x]
+ print
+ sys.exit(1)
+
+def last():
+ try:
+ #Retrieve and unpickle stats and fails from saved files
+ savedf=open('/var/cache/edb/repo.stats','r')
+ stats = pickle.load(savedf)
+ savedf.close()
+ savedf=open('/var/cache/edb/repo.fails','r')
+ fails = pickle.load(savedf)
+ savedf.close()
+ except SystemExit, e:
+ raise # Need to propogate this
+ except:
+ err("Error retrieving last repoman run data; exiting.")
+
+ #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=0
+
+ print
+ print green("RepoMan remembers...")
+ print
+ for x in qacats:
+ if stats[x]:
+ dowarn=1
+ if x not in qawarnings:
+ dofail=1
+ else:
+ if mymode!="lfull":
+ continue
+ print " "+string.ljust(x,20),
+ if stats[x]==0:
+ print green(`stats[x]`)
+ continue
+ elif x in qawarnings:
+ print yellow(`stats[x]`)
+ else:
+ print red(`stats[x]`)
+ if mymode!="lfull":
+ if stats[x]<12:
+ for y in fails[x]:
+ print " "+y
+ else:
+ dofull=1
+ else:
+ for y in fails[x]:
+ print " "+y
+ print
+ if dofull:
+ print bold("Note: type \"repoman lfull\" for a complete listing of repomans last run.")
+ print
+ if dowarn and not dofail:
+ print green("RepoMan sez:"),"\"You only gave me a partial QA payment last time?\nI took it, but I wasn't happy.\""
+ elif not dofail:
+ print green("RepoMan sez:"),"\"If everyone were like you, I'd be out of business!\""
+ print
+ sys.exit(1)
+
+mymode=None
+myoptions=[]
+if len(sys.argv)>1:
+ x=1
+ while x < len(sys.argv):
+ if sys.argv[x] in shortmodes.keys():
+ sys.argv[x]=shortmodes[sys.argv[x]]
+ if sys.argv[x] in modes:
+ if mymode==None:
+ mymode=sys.argv[x]
+ else:
+ err("Please specify either \""+mymode+"\" or \""+sys.argv[x]+"\", but not both.")
+ elif sys.argv[x] in options+shortoptions.keys():
+ optionx=sys.argv[x]
+ if optionx in shortoptions.keys():
+ optionx = shortoptions[optionx]
+ if (optionx=="--commitmsg") and (len(sys.argv)>=(x+1)):
+ commitmessage=sys.argv[x+1]
+ x=x+1
+ elif (optionx=="--commitmsgfile") and (len(sys.argv)>=(x+1)):
+ commitmessagefile=sys.argv[x+1]
+ x=x+1
+ elif optionx not in myoptions:
+ myoptions.append(optionx)
+ else:
+ err("\""+sys.argv[x]+"\" is not a valid mode or option.")
+ x=x+1
+if mymode==None:
+ mymode="scan"
+if mymode=="help" or ("--help" in myoptions):
+ help()
+if mymode=="last" or (mymode=="lfull"):
+ last()
+if mymode=="commit" and "--include-masked" not in myoptions:
+ myoptions.append("--include-masked")
+
+isCvs=False
+myreporoot=None
+if os.path.isdir("CVS"):
+ repoman_settings["PORTDIR_OVERLAY"]=""
+ if "cvs" not in portage.features:
+ print
+ print
+ print red('!!! You do not have ')+bold('FEATURES="cvs" ')+red("enabled...")
+ print red("!!! ")+bold("Adding \"cvs\" to FEATURES")
+ print
+ os.environ["FEATURES"]=repoman_settings["FEATURES"]+" cvs"
+
+ try:
+ isCvs=True
+ myrepofile=open("CVS/Repository")
+ myreporoot=myrepofile.readline()[:-1]
+ myrepofile.close()
+ myrepofile=open("CVS/Root")
+ myreporootpath=string.split(myrepofile.readline()[:-1], ":")[-1]
+ myrepofile.close()
+ if myreporootpath == myreporoot[:len(myreporootpath)]:
+ # goofy os x cvs co.
+ myreporoot = myreporoot[len(myreporootpath):]
+ while myreporoot and myreporoot[0] == '/':
+ myreporoot = myreporoot[1:]
+ except SystemExit, e:
+ raise # Need to propogate this
+ except:
+ err("Error grabbing repository information; exiting.")
+ myreporootpath=os.path.normpath(myreporootpath)
+ if myreporootpath=="/space/cvsroot":
+ print
+ print
+ print red("You're using the wrong cvsroot. For Manifests to be correct, you must")
+ print red("use the same base cvsroot path that the servers use. Please try the")
+ print red("following script to remedy this:")
+ print
+ print "cd my_cvs_tree"
+ print
+ print "rm -Rf [a-z]*"
+ print "cvs up"
+ print
+ if portage.userland=="BSD" or portage.userland=="Darwin":
+ print "find ./ -type f -regex '.*/CVS/Root$' -print0 | xargs -0 sed \\"
+ else:
+ print "find ./ -type f -regex '.*/CVS/Root$' -print0 | xargs -0r sed \\"
+ fi
+ print " -i 's:/space/cvsroot$:/home/cvsroot:'"
+ print
+ print red("You must clear and re-update your tree as all header tags will cause")
+ print red("problems in manifests for all rsync and /home/cvsroot users.")
+ print
+ print "You should do this to any other gentoo trees your have as well,"
+ print "excluding the deletions. 'gentoo-src' should be /home/cvsroot."
+ print
+ sys.exit(123)
+
+if not "--pretend" in myoptions and not isCvs:
+ print
+ print darkgreen("Not in a CVS repository; enabling pretend mode.")
+ myoptions.append("--pretend");
+
+
+def have_profile_dir(path, maxdepth=3):
+ while path != "/" and maxdepth:
+ if os.path.exists(path + "/profiles/package.mask"):
+ return path
+ path = os.path.normpath(path + "/..")
+ maxdepth -= 1
+
+portdir=None
+portdir_overlay=None
+mydir=os.getcwd()
+if mydir[-1] != "/":
+ mydir += "/"
+
+for overlay in repoman_settings["PORTDIR_OVERLAY"].split():
+ if overlay[-1] != "/":
+ overlay += "/"
+ if mydir[:len(overlay)] == overlay:
+ portdir_overlay = overlay
+ subdir = mydir[len(overlay):]
+ if subdir and subdir[-1] != "/":
+ subdir += "/"
+ if have_profile_dir(mydir, subdir.count("/")):
+ portdir = portdir_overlay
+ break
+
+if not portdir_overlay:
+ if (repoman_settings["PORTDIR"]+"/")[:len(mydir)] == mydir:
+ portdir_overlay = repoman_settings["PORTDIR"]
+ else:
+ portdir_overlay = have_profile_dir(mydir)
+ portdir = portdir_overlay
+
+if not portdir_overlay:
+ print darkred("Unable to determine PORTDIR.")
+ sys.exit(1)
+
+if not portdir:
+ portdir = repoman_settings["PORTDIR"]
+
+if portdir[-1] == "/":
+ portdir = portdir[:-1]
+if portdir_overlay[-1] == "/":
+ portdir_overlay = portdir_overlay[:-1]
+
+os.environ["PORTDIR"] = portdir
+if portdir_overlay != portdir:
+ os.environ["PORTDIR_OVERLAY"] = portdir_overlay
+else:
+ os.environ["PORTDIR_OVERLAY"] = ""
+
+print "\nSetting paths:"
+print "PORTDIR = \""+os.environ["PORTDIR"]+"\""
+print "PORTDIR_OVERLAY = \""+os.environ["PORTDIR_OVERLAY"]+"\""
+
+
+reload(portage)
+repoman_settings = portage.config(clone=portage.settings)
+
+if not myreporoot:
+ myreporoot = os.path.basename(portdir_overlay)
+ myreporoot += mydir[len(portdir_overlay):-1]
+
+if isCvs:
+ reporoot=None
+ for x in REPOROOTS:
+ if myreporoot[0:len(x)]==x:
+ reporoot=myreporoot
+ if not reporoot:
+ err("Couldn't recognize repository type. Supported repositories:\n"+repr(REPOROOTS))
+reposplit=string.split(myreporoot,"/")
+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 ensure that repoman knows where it is, and the manifest recommit is at least possible.
+if mymode == "commit" and repolevel not in [1,2,3]:
+ print red("***")+" Commit attempts *must* be from within a cvs 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 recommited for a package."
+ print red("***")
+ err("Unable to identify level we're commiting from for %s" % string.join(reposplit,'/'))
+
+if repolevel == 3 and "--include-masked" not in myoptions:
+ myoptions.append("--include-masked")
+
+startdir=os.getcwd()
+
+for x in range(0,repolevel-1):
+ os.chdir("..")
+repodir=os.getcwd()
+os.chdir(startdir)
+
+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.")
+print
+if "--pretend" in myoptions:
+ print green("RepoMan does a once-over of the neighborhood...")
+else:
+ print green("RepoMan scours the neighborhood...")
+
+# retreive local USE list
+luselist={}
+try:
+ mylist=portage.grabfile(portdir+"/profiles/use.local.desc")
+ for mypos in range(0,len(mylist)):
+ mysplit=mylist[mypos].split()[0]
+ myuse=string.split(mysplit,":")
+ if len(myuse)==2:
+ if not luselist.has_key(myuse[0]):
+ luselist[myuse[0]] = []
+ luselist[myuse[0]].append(myuse[1])
+except SystemExit, e:
+ raise # Need to propogate this
+except:
+ err("Couldn't read from use.local.desc")
+
+# setup a uselist from portage
+uselist=[]
+try:
+ uselist=portage.grabfile(portdir+"/profiles/use.desc")
+ for l in range(0,len(uselist)):
+ uselist[l]=string.split(uselist[l])[0]
+except SystemExit, e:
+ raise # Need to propogate this
+except:
+ err("Couldn't read USE flags from use.desc")
+
+# retrieve a list of current licenses in portage
+liclist=portage.listdir(portdir+"/licenses")
+if not liclist:
+ err("Couldn't find licenses?")
+
+# retrieve list of offical keywords
+try:
+ kwlist=portage.grabfile(portdir+"/profiles/arch.list")
+except SystemExit, e:
+ raise # Need to propogate this
+except:
+ err("Couldn't read KEYWORDS from arch.list")
+if not kwlist:
+ kwlist=["alpha","arm","hppa","mips","ppc","sparc","x86"]
+
+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":
+ continue
+ if os.path.isdir(startdir+"/"+x):
+ scanlist.append(catdir+"/"+x)
+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":
+ continue
+ if os.path.isdir(startdir+"/"+x+"/"+y):
+ scanlist.append(x+"/"+y)
+elif repolevel==3:
+ catdir = reposplit[-2]
+ if catdir not in repoman_settings.categories:
+ caterror(catdir)
+ scanlist.append(catdir+"/"+reposplit[-1])
+
+profiles={}
+descfile=portdir+"/profiles/profiles.desc"
+if os.path.exists(descfile):
+ for x in portage.grabfile(descfile):
+ if x[0]=="#":
+ continue
+ arch=string.split(x)
+ if len(arch)!=3:
+ print "wrong format: \""+red(x)+"\" in "+descfile
+ continue
+ if not os.path.isdir(portdir+"/profiles/"+arch[1]):
+ print "Invalid "+arch[2]+" profile ("+arch[1]+") for arch "+arch[0]
+ continue
+ if profiles.has_key(arch[0]):
+ profiles[arch[0]]+= [[arch[1], arch[2]]]
+ else:
+ profiles[arch[0]] = [[arch[1], arch[2]]]
+
+ for x in portage.archlist:
+ if x[0] == "~":
+ continue
+ if not profiles.has_key(x):
+ 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
+else:
+ print red("profiles.desc does not exist: "+descfile)
+ print red("You need to do \"cvs update\" in profiles dir.")
+ print
+ sys.exit(1)
+
+
+stats={}
+fails={}
+#objsadded records all object being added to cvs
+objsadded=[]
+for x in qacats:
+ stats[x]=0
+ fails[x]=[]
+xmllint_capable = False
+if getstatusoutput('which xmllint')[0] != 0:
+ print red("!!! xmllint not found. Can't check metadata.xml.\n")
+ if "--xmlparse" in myoptions or repolevel==3:
+ print red("!!!")+" sorry, xmllint is needed. failing\n"
+ sys.exit(1)
+else:
+ #hardcoded paths/urls suck. :-/
+ must_fetch=1
+ backup_exists=0
+ try:
+ # if it's been over a week since fetching (or the system clock is fscked), grab an updated copy of metadata.dtd
+ # clock is fscked or it's been a week. time to grab a new one.
+ ct=os.stat(portage.CACHE_PATH + '/metadata.dtd')[ST_CTIME]
+ if abs(time.time() - ct) > (60*60*24*7):
+ # don't trap the exception, we're watching for errno 2 (file not found), anything else is a bug.
+ backup_exists=1
+ else:
+ must_fetch=0
+
+ except (OSError,IOError), e:
+ if e.errno != 2:
+ print red("!!!")+" caught exception '%s' for %s/metadata.dtd, bailing" % (str(e), portage.CACHE_PATH)
+ sys.exit(1)
+
+ if must_fetch:
+ print
+ print green("***")+" the local copy of metadata.dtd needs to be refetched, doing that now"
+ print
+ try:
+ if os.path.exists(repoman_settings["DISTDIR"]+'/metadata.dtd'):
+ os.remove(repoman_settings["DISTDIR"]+'/metadata.dtd')
+ val=portage.fetch(['http://www.gentoo.org/dtd/metadata.dtd'],repoman_settings,fetchonly=0, \
+ try_mirrors=0)
+ if val:
+ if backup_exists:
+ os.remove(portage.CACHE_PATH+'/metadata.dtd')
+ shutil.copy(repoman_settings["DISTDIR"]+'/metadata.dtd',portage.CACHE_PATH+'/metadata.dtd')
+ os.chown(portage.CACHE_PATH+'/metadata.dtd',os.getuid(),portage.portage_gid)
+ os.chmod(portage.CACHE_PATH+'/metadata.dtd',0664)
+
+
+ except SystemExit, e:
+ raise # Need to propogate this
+ except Exception,e:
+ print
+ print red("!!!")+" attempting to fetch 'http://www.gentoo.org/dtd/metadata.dtd', caught"
+ print red("!!!")+" exception '%s' though." % str(e)
+ val=0
+ if not val:
+ print red("!!!")+" fetching new metadata.dtd failed, aborting"
+ sys.exit(1)
+ #this can be problematic if xmllint changes their output
+ xmllint_capable=True
+
+
+arch_caches={}
+for x in scanlist:
+ #ebuilds and digests added to cvs respectively.
+ if "--verbose" in myoptions:
+ print "checking package " + x
+ eadded=[]
+ dadded=[]
+ cladded=0
+ catdir,pkgdir=x.split("/")
+ checkdir=repodir+"/"+x
+ checkdirlist=os.listdir(checkdir)
+ ebuildlist=[]
+ for y in checkdirlist:
+ if y[-7:]==".ebuild":
+ ebuildlist.append(y[:-7])
+ if y in ["Manifest","ChangeLog","metadata.xml"]:
+ if os.stat(checkdir+"/"+y)[0] & 0x0248:
+ stats["file.executable"] += 1
+ fails["file.executable"].append(checkdir+"/"+y)
+ digestlist=[]
+ if isCvs:
+ try:
+ mystat=os.stat(checkdir+"/files")[0]
+ if len(ebuildlist) and not S_ISDIR(mystat):
+ raise Exception
+ except SystemExit, e:
+ raise # Need to propogate this
+ except:
+ stats["filedir.missing"] += 1
+ fails["filedir.missing"].append(checkdir)
+ continue
+ try:
+ myf=open(checkdir+"/CVS/Entries","r")
+ myl=myf.readlines()
+ for l in myl:
+ if l[0]!="/":
+ continue
+ splitl=l[1:].split("/")
+ if not len(splitl):
+ continue
+ objsadded.append(splitl[0])
+ if splitl[0][-7:]==".ebuild":
+ eadded.append(splitl[0][:-7])
+ if splitl[0]=="ChangeLog":
+ cladded=1
+ except IOError:
+ if mymode=="commit":
+ stats["CVS/Entries.IO_error"] += 1
+ fails["CVS/Entries.IO_error"].append(checkdir+"/CVS/Entries")
+ continue
+
+ try:
+ myf=open(checkdir+"/files/CVS/Entries","r")
+ myl=myf.readlines()
+ for l in myl:
+ if l[0]!="/":
+ continue
+ splitl=l[1:].split("/")
+ if not len(splitl):
+ continue
+ objsadded.append(splitl[0])
+ if splitl[0][:7]=="digest-":
+ dadded.append(splitl[0][7:])
+ except IOError:
+ if mymode=="commit":
+ stats["CVS/Entries.IO_error"] += 1
+ fails["CVS/Entries.IO_error"].append(checkdir+"/files/CVS/Entries")
+ continue
+
+ if os.path.exists(checkdir+"/files"):
+ filesdirlist=os.listdir(checkdir+"/files")
+ for y in filesdirlist:
+ if y[:7]=="digest-":
+ if y[7:] not in dadded:
+ #digest not added to cvs
+ stats["digest.notadded"]=stats["digest.notadded"]+1
+ fails["digest.notadded"].append(x+"/files/"+y)
+ if y[7:] in eadded:
+ stats["digest.disjointed"]=stats["digest.disjointed"]+1
+ fails["digest.disjointed"].append(x+"/files/"+y)
+
+ if os.stat(checkdir+"/files/"+y)[0] & 0x0248:
+ stats["file.executable"] += 1
+ fails["file.executable"].append(x+"/files/"+y)
+
+ mydigests=portage.digestParseFile(checkdir+"/files/"+y)
+
+ mykey = catdir + "/" + y[7:]
+ if y[7:] not in ebuildlist:
+ #stray digest
+ if mymode=="fix":
+ if "--pretend" in myoptions:
+ print "(cd "+repodir+"/"+x+"/files; cvs rm -f "+y+")"
+ else:
+ os.system("(cd "+repodir+"/"+x+"/files; cvs rm -f "+y+")")
+ else:
+ stats["digest.stray"]=stats["digest.stray"]+1
+ fails["digest.stray"].append(x+"/files/"+y)
+ else:
+ # We have an ebuild
+ myuris,myfiles = portage.db["/"]["porttree"].dbapi.getfetchlist(mykey,all=True)
+ for entry in mydigests.keys():
+ if entry not in myfiles:
+ stats["digest.unused"] += 1
+ fails["digest.unused"].append(y+"::"+entry)
+ uri_dict = {}
+ for myu in myuris:
+ myubn = os.path.basename(myu)
+ if myubn not in uri_dict:
+ uri_dict[myubn] = [myu]
+ else:
+ uri_dict[myubn] += [myu]
+
+ for myf in uri_dict:
+ myff = repoman_settings["DISTDIR"] + "/" + myf
+ if not mydigests.has_key(myf):
+ uri_settings = portage.config(clone=repoman_settings)
+ if mymode == "fix":
+ if not portage.fetch(uri_dict[myf], uri_settings):
+ stats["digest.unmatch"] += 1
+ fails["digest.unmatch"].append(y+"::"+myf)
+ else:
+ eb_name,eb_location = portage.db["/"]["porttree"].dbapi.findname2(mykey)
+ portage.doebuild(eb_name, "digest", "/", uri_settings)
+ else:
+ stats["digest.partial"] += 1
+ fails["digest.partial"].append(y+"::"+myf)
+ else:
+ if os.path.exists(myff):
+ if not portage_checksum.verify_all(myff, mydigests[myf]):
+ stats["digest.fail"] += 1
+ fails["digest.fail"].append(y+"::"+myf)
+ elif repolevel == 3:
+ stats["digest.assumed"] += 1
+ fails["digest.assumed"].append(y+"::"+myf)
+
+ # 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)
+ try:
+ mystat = os.stat(checkdir+"/files/"+y)
+ except OSError, 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):
+ for z in os.listdir(checkdir+"/files/"+y):
+ filesdirlist.append(y+"/"+z)
+ # current policy is no files over 20k, this is the check.
+ elif mystat.st_size > 20480:
+ stats["file.size"] += 1
+ fails["file.size"].append("("+ str(mystat.st_size/1024) + "K) "+x+"/files/"+y)
+
+ if "ChangeLog" not in checkdirlist:
+ stats["changelog.missing"]+=1
+ fails["changelog.missing"].append(x+"/ChangeLog")
+
+ #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:
+ #Only carry out if in package directory or check forced
+ if xmllint_capable:
+ st=getstatusoutput("xmllint --nonet --noout --dtdvalid %s/metadata.dtd %s/metadata.xml" % (portage.CACHE_PATH, checkdir))
+ if st[0] != 0:
+ for z in st[1].split("\n"):
+ print red("!!! ")+z
+ stats["metadata.bad"]+=1
+ fails["metadata.bad"].append(x+"/metadata.xml")
+
+ allmasked = True
+
+ for y in ebuildlist:
+ if os.stat(checkdir+"/"+y+".ebuild")[0] & 0x0248:
+ stats["file.executable"] += 1
+ fails["file.executable"].append(x+"/"+y+".ebuild")
+ if y not in eadded:
+ #ebuild not added to cvs
+ stats["ebuild.notadded"]=stats["ebuild.notadded"]+1
+ fails["ebuild.notadded"].append(x+"/"+y+".ebuild")
+ if y in dadded:
+ stats["ebuild.disjointed"]=stats["ebuild.disjointed"]+1
+ fails["ebuild.disjointed"].append(x+"/"+y+".ebuild")
+ if not os.path.exists(checkdir+"/files/digest-"+y):
+ if mymode=="fix":
+ if "--pretend" in myoptions:
+ print "You will need to run:"
+ print " /usr/sbin/ebuild "+repodir+"/"+x+"/"+y+".ebuild digest"
+ else:
+ retval=os.system("/usr/sbin/ebuild "+repodir+"/"+x+"/"+y+".ebuild digest")
+ if retval:
+ print "!!! Exiting on ebuild digest (shell) error code:",retval
+ sys.exit(retval)
+ else:
+ stats["digest.missing"]=stats["digest.missing"]+1
+ fails["digest.missing"].append(x+"/files/digest-"+y)
+ myesplit=portage.pkgsplit(y)
+ if myesplit==None or not valid_ebuild_name(x.split("/")[0]+"/"+y):
+ 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
+ try:
+ myaux=portage.db["/"]["porttree"].dbapi.aux_get(catdir+"/"+y,allvars,strict=1)
+ except KeyError:
+ stats["ebuild.syntax"]=stats["ebuild.syntax"]+1
+ fails["ebuild.syntax"].append(x+"/"+y+".ebuild")
+ continue
+ except IOError:
+ stats["ebuild.output"]=stats["ebuild.output"]+1
+ fails["ebuild.output"].append(x+"/"+y+".ebuild")
+ continue
+
+ mynewaux = {}
+ for idx in range(len(allvars)):
+ if idx < len(myaux):
+ mynewaux[allvars[idx]] = myaux[idx]
+ else:
+ mynewaux[allvars[idx]] = ""
+ myaux = mynewaux
+
+ # Test for negative logic and bad words in the RESTRICT var.
+ #for x in myaux[allvars.index("RESTRICT")].split():
+ # if x.startswith("no"):
+ # print "Bad RESTRICT value: %s" % x
+
+ myaux["PROVIDE"] = portage_dep.use_reduce(portage_dep.paren_reduce(myaux["PROVIDE"]), matchall=1)
+ myaux["PROVIDE"] = " ".join(portage.flatten(myaux["PROVIDE"]))
+ for myprovide in myaux["PROVIDE"].split():
+ prov_cp = portage.dep_getkey(myprovide)
+ if prov_cp != myprovide:
+ stats["virtual.versioned"]+=1
+ fails["virtual.versioned"].append(x+"/"+y+".ebuild: "+myprovide)
+ prov_pkg = portage.dep_getkey(portage.best(portage.db["/"]["porttree"].dbapi.xmatch("match-all", prov_cp)))
+ if prov_cp == prov_pkg:
+ stats["virtual.exists"]+=1
+ fails["virtual.exists"].append(x+"/"+y+".ebuild: "+prov_cp)
+
+ for pos in range(0,len(missingvars)):
+ if not myaux[missingvars[pos]]:
+ myqakey=missingvars[pos]+".missing"
+ stats[myqakey]=stats[myqakey]+1
+ fails[myqakey].append(x+"/"+y+".ebuild")
+
+ if "--ignore-other-arches" in myoptions:
+ arches=[[repoman_settings["ARCH"], repoman_settings["ARCH"], portage.groups]]
+ 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
+
+ baddepsyntax = False
+ badlicsyntax = False
+ catpkg = catdir+"/"+y
+ for mytype in ["DEPEND","RDEPEND","PDEPEND","LICENSE"]:
+ mydepstr = myaux[mytype]
+ if (string.find(mydepstr, " ?") != -1):
+ stats[mytype+".syntax"] += 1
+ fails[mytype+".syntax"].append(catpkg+".ebuild "+mytype+": '?' preceded by space")
+ if mytype != "LICENSE":
+ baddepsyntax = True
+ else:
+ badlicsyntax = True
+ try:
+ # Missing closing parenthesis will result in a ValueError
+ mydeplist=portage_dep.paren_reduce(mydepstr)
+ # Missing opening parenthesis will result in a final "" element
+ if "" in mydeplist or "(" in mydeplist:
+ raise ValueError
+ except ValueError:
+ stats[mytype+".syntax"] += 1
+ fails[mytype+".syntax"].append(catpkg+".ebuild "+mytype+": Mismatched parenthesis")
+ if mytype != "LICENSE":
+ baddepsyntax = True
+ else:
+ badlicsyntax = True
+
+ for keyword,arch,groups in arches:
+ portage.groups=groups
+
+ if not profiles.has_key(arch):
+ # A missing profile will create an error further down
+ # during the KEYWORDS verification.
+ continue
+
+ for prof in profiles[arch]:
+
+ profdir = portdir+"/profiles/"+prof[0]
+
+ portage.profiledir=profdir
+
+ if arch_caches.has_key(prof[0]):
+ dep_settings, portage.portdb, portage.db["/"]["porttree"] = arch_caches[prof[0]]
+ else:
+ os.environ["ACCEPT_KEYWORDS"]="-~"+arch
+ dep_settings=portage.config(config_profile_path=profdir, config_incrementals=portage_const.INCREMENTALS)
+ portage.portdb=portage.portdbapi(portdir, dep_settings)
+ portage.db["/"]["porttree"]=portage.portagetree("/",dep_settings.getvirtuals("/"))
+ arch_caches[prof[0]]=[dep_settings, portage.portdb, portage.db["/"]["porttree"]]
+
+ for myprovide in myaux["PROVIDE"].split():
+ prov_cp = portage.dep_getkey(myprovide)
+ if prov_cp not in dep_settings.virtuals:
+ stats["virtual.unavailable"]+=1
+ fails["virtual.unavailable"].append(x+"/"+y+".ebuild: "+keyword+"("+prof[0]+") "+prov_cp)
+
+ if not baddepsyntax:
+ ismasked = (catdir+"/"+y not in portage.db["/"]["porttree"].dbapi.xmatch("list-visible",x))
+ if ismasked:
+ if "--include-masked" not in myoptions:
+ continue
+ #we are testing deps for a masked package; give it some lee-way
+ suffix="masked"
+ matchmode="match-all"
+ else:
+ suffix=""
+ matchmode="match-visible"
+
+ if prof[1] == "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
+ try:
+ mydep=portage.dep_check(myvalue,portage.db["/"]["porttree"].dbapi,dep_settings,use="all",mode=matchmode)
+ except KeyError, e:
+ stats[mykey]=stats[mykey]+1
+ fails[mykey].append(x+"/"+y+".ebuild: "+keyword+"("+prof[0]+") "+repr(e[0]))
+ continue
+
+ if mydep[0]==1:
+ if mydep[1]!=[]:
+ #we have some unsolvable deps
+ #remove ! deps, which always show up as unsatisfiable
+ d=0
+ while d<len(mydep[1]):
+ if mydep[1][d][0]=="!":
+ del mydep[1][d]
+ else:
+ d += 1
+ #if we emptied out our list, continue:
+ if not mydep[1]:
+ continue
+ stats[mykey]=stats[mykey]+1
+ fails[mykey].append(x+"/"+y+".ebuild: "+keyword+"("+prof[0]+") "+repr(mydep[1]))
+ else:
+ stats[mykey]=stats[mykey]+1
+ fails[mykey].append(x+"/"+y+".ebuild: "+keyword+"("+prof[0]+") "+repr(mydep[1]))
+
+ # this check needs work, it won't catch (\ndie)
+ if not os.system("egrep '^[^#]*\([^)]*\<die\>' "+checkdir+"/"+y+".ebuild >/dev/null 2>&1"):
+ stats["ebuild.nesteddie"]=stats["ebuild.nesteddie"]+1
+ fails["ebuild.nesteddie"].append(x+"/"+y+".ebuild")
+ # uselist checks - global
+ myuse = myaux["IUSE"].split()
+ for mypos in range(len(myuse)-1,-1,-1):
+ if myuse[mypos] and (myuse[mypos] in uselist):
+ del myuse[mypos]
+ # uselist checks - local
+ mykey = portage.dep_getkey(catpkg)
+ if luselist.has_key(mykey):
+ for mypos in range(len(myuse)-1,-1,-1):
+ if myuse[mypos] and (myuse[mypos] in luselist[mykey]):
+ del myuse[mypos]
+ 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:
+ myuse = myaux["LICENSE"]
+ # Parse the LICENSE variable, remove USE conditions and
+ # flatten it.
+ myuse=portage_dep.use_reduce(portage_dep.paren_reduce(myuse), matchall=1)
+ myuse=portage.flatten(myuse)
+ # Check each entry to ensure that it exists in PORTDIR's
+ # license directory.
+ for mypos in range(0,len(myuse)):
+ # Need to check for "||" manually as no portage
+ # function will remove it without removing values.
+ if myuse[mypos] not in liclist and myuse[mypos] != "||":
+ stats["LICENSE.invalid"]=stats["LICENSE.invalid"]+1
+ fails["LICENSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])
+
+ #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 not profiles.has_key(myskey):
+ stats["KEYWORDS.invalid"] += 1
+ fails["KEYWORDS.invalid"].append(x+"/"+y+".ebuild: %s (profile invalid)" % mykey)
+
+ #syntax checks
+ myear = time.gmtime(os.stat(checkdir+"/"+y+".ebuild")[ST_MTIME])[0]
+ gentoo_copyright = re.compile(r'^# Copyright ((1999|200\d)-)?' + str(myear) + r' Gentoo Foundation')
+ gentoo_license = re.compile(r'^# Distributed under the terms of the GNU General Public License v2$')
+ cvs_header = re.compile(r'^#\s*\$Header.*\$$')
+ ignore_line = re.compile(r'(^$)|(^(\t)*#)')
+ leading_spaces = re.compile(r'^[\S\t]')
+ trailing_whitespace = re.compile(r'.*([\S]$)')
+ readonly_assignment = re.compile(r'^\s*(export\s+)?(A|P|PV|PN|PR|PVR|PF|D|WORKDIR|FILESDIR|FEATURES|USE)=')
+ continuation_symbol = re.compile(r'(.*[ ]+[\\][ ].*)')
+ line_continuation_quoted = re.compile(r'(\"|\')(([\w ,:;#\[\]\.`=/|\$\^\*{}()\'-])|(\\.))*\1')
+ line_continuation = re.compile(r'([^#]*\S)(\s+|\t)\\$')
+ linenum=0
+ for line in input(checkdir+"/"+y+".ebuild"):
+ linenum += 1
+ # Gentoo copyright check
+ if linenum == 1:
+ match = gentoo_copyright.match(line)
+ if not match:
+ myerrormsg = "Copyright header Error. Possibly date related."
+ stats["ebuild.badheader"] +=1
+ fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ # Gentoo license check
+ elif linenum == 2:
+ match = gentoo_license.match(line)
+ if not match:
+ myerrormsg = "Gentoo License Error."
+ stats["ebuild.badheader"] +=1
+ fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ # CVS Header check
+ elif linenum == 3:
+ match = cvs_header.match(line)
+ if not match:
+ myerrormsg = "CVS Header Error."
+ stats["ebuild.badheader"] +=1
+ fails["ebuild.badheader"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ else:
+ match = ignore_line.match(line)
+ if not match:
+ # Excluded Blank lines and full line comments. Good!
+ # Leading Spaces Check
+ match = leading_spaces.match(line)
+ if not match:
+ #Line has got leading spaces. Bad!
+ myerrormsg = "Leading Space Syntax Error. Line %d" % linenum
+ stats["ebuild.minorsyn"] +=1
+ fails["ebuild.minorsyn"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ # Trailing whitespace check
+ match = trailing_whitespace.match(line)
+ if not match:
+ #Line has got trailing whitespace. Bad!
+ myerrormsg = "Trailing whitespace Syntax Error. Line %d" % linenum
+ stats["ebuild.minorsyn"] +=1
+ fails["ebuild.minorsyn"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ # Readonly variable assignment check
+ match = readonly_assignment.match(line)
+ if match:
+ # invalid assignment, very bad!
+ myerrormsg = "Readonly variable assignment to %s on line %d" % (match.group(2), linenum)
+ stats["variable.readonly"] += 1
+ fails["variable.readonly"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+ # Line continuation check
+ match = continuation_symbol.match(line)
+ if match:
+ #Excluded lines not even containing a " \" match. Good!
+ line = re.sub(line_continuation_quoted,"\"\"",line)
+ #line has been edited to collapsed "" and '' quotes to "". Good!
+ match = continuation_symbol.match(line)
+ if match:
+ #Again exclude lines not even containing a " \" match. Good!
+ #This repetition is done for a slight performance increase
+ match = line_continuation.match(line)
+ if not match:
+ #Line has a line continuation error. Bad!
+ myerrormsg = "Line continuation (\"\\\") Syntax Error. Line %d" % linenum
+ stats["ebuild.majorsyn"] +=1
+ fails["ebuild.majorsyn"].append(x+"/"+y+".ebuild: %s" % myerrormsg)
+
+ # 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 allmasked and repolevel == 3:
+ stats["ebuild.allmasked"]+=1
+ fails["ebuild.allmasked"].append(x)
+
+#Pickle and save results for instant reuse in last and lfull
+savef=open('/var/cache/edb/repo.stats','w')
+pickle.dump(stats,savef)
+savef.close()
+savef=open('/var/cache/edb/repo.fails','w')
+pickle.dump(fails,savef)
+savef.close()
+if not (os.stat('/var/cache/edb/repo.stats')[ST_GID] == getgrnam('portage')[2]):
+ os.chown('/var/cache/edb/repo.stats',os.geteuid(),getgrnam('portage')[2])
+ os.chmod('/var/cache/edb/repo.stats',0664)
+if not (os.stat('/var/cache/edb/repo.fails')[ST_GID] == getgrnam('portage')[2]):
+ os.chown('/var/cache/edb/repo.fails',os.geteuid(),getgrnam('portage')[2])
+ os.chmod('/var/cache/edb/repo.fails',0664)
+print
+#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=0
+for x in qacats:
+ if not isCvs and (string.find(x, "notadded") != -1):
+ stats[x] = 0
+ if stats[x]:
+ dowarn=1
+ if x not in qawarnings:
+ dofail=1
+ else:
+ continue
+ print " "+string.ljust(x,30),
+ if stats[x]==0:
+ print green(`stats[x]`)
+ continue
+ elif x in qawarnings:
+ print yellow(`stats[x]`)
+ else:
+ print red(`stats[x]`)
+ if mymode!="full":
+ if stats[x]<12:
+ for y in fails[x]:
+ print " "+y
+ else:
+ dofull=1
+ else:
+ for y in fails[x]:
+ print " "+y
+print
+
+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=string.split(x,seperator)
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] not in mygroups.keys():
+ mygroups[xs[0]]=[string.join(xs[1:],seperator)]
+ else:
+ mygroups[xs[0]]+=[string.join(xs[1:],seperator)]
+ return mygroups
+
+if mymode!="commit":
+ if dofull:
+ print bold("Note: type \"repoman full\" for a complete listing.")
+ print
+ if dowarn and not dofail:
+ print green("RepoMan sez:"),"\"You're only giving me a partial QA payment?\nI'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!\""
+ print
+else:
+ if dofail:
+ print turquoise("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 "--pretend" in myoptions:
+ print green("RepoMan sez:"), "\"So, you want to play it safe. Good call.\"\n"
+
+ if fails["digest.missing"]:
+ print green("Creating missing digests...")
+ for x in fails["digest.missing"]:
+ xs=string.split(x,"/")
+ del xs[-2]
+ myeb=string.join(xs[:-1],"/")+"/"+xs[-1][7:]
+ if "--pretend" in myoptions:
+ print "(ebuild "+portdir+"/"+myeb+".ebuild digest)"
+ else:
+ retval=os.system("ebuild "+portdir+"/"+myeb+".ebuild digest")
+ if retval:
+ print "!!! Exiting on ebuild digest (shell) error code:",retval
+ sys.exit(retval)
+
+ mycvstree=cvstree.getentries("./",recursive=1)
+ if isCvs and not mycvstree:
+ print "!!! It seems we don't have a cvs tree?"
+ sys.exit(3)
+
+ myunadded=cvstree.findunadded(mycvstree,recursive=1,basedir="./")
+ myautoadd=[]
+ if myunadded:
+ for x in range(len(myunadded)-1,-1,-1):
+ xs=string.split(myunadded[x],"/")
+ 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]
+ elif len(xs[-1])>=7:
+ if xs[-1][:7]=="digest-":
+ del xs[-2]
+ myeb=string.join(xs[:-1]+[xs[-1][7:]],"/")+".ebuild"
+ if os.path.exists(myeb):
+ # Ebuild exists for digest... So autoadd it.
+ myautoadd+=[myunadded[x]]
+ del myunadded[x]
+
+ if myautoadd:
+ print ">>> Auto-Adding missing digests..."
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs add "+string.join(myautoadd)+")"
+ retval=0
+ else:
+ retval=os.system("/usr/bin/cvs add "+string.join(myautoadd))
+ if retval:
+ print "!!! Exiting on cvs (shell) error code:",retval
+ sys.exit(retval)
+
+ if myunadded:
+ print red("!!! The following files are in your cvs tree but are not added to the master")
+ print red("!!! tree. Please remove them from the cvs tree or add them to the master tree.")
+ for x in myunadded:
+ print " ",x
+ print
+ print
+ sys.exit(1)
+
+ mymissing=None
+ if mymissing:
+ print "The following files are obviously missing from your cvs tree"
+ print "and are being fetched so we can continue:"
+ for x in mymissing:
+ print " ",x
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs -q up "+string.join(mymissing)+")"
+ retval=0
+ else:
+ retval=os.system("/usr/bin/cvs -q up "+string.join(mymissing))
+ if retval:
+ print "!!! Exiting on cvs (shell) error code:",retval
+ sys.exit(retval)
+ del mymissing
+
+ retval=["",""]
+ if isCvs:
+ print "Performing a "+green("cvs -n up")+" with a little magic grep to check for updates."
+ retval=getstatusoutput("/usr/bin/cvs -n up 2>&1 | egrep '^[^\?] .*' | egrep -v '^. .*/digest-[^/]+|^cvs server: .* -- ignored$'")
+
+ mylines=string.split(retval[1], "\n")
+ myupdates=[]
+ for x in mylines:
+ if not x:
+ continue
+ if x[0] not in "UPMAR": # Updates,Patches,Modified,Added,Removed
+ print red("!!! Please fix the following issues reported from cvs: ")+green("(U,P,M,A,R are ok)")
+ print red("!!! Note: This is a pretend/no-modify pass...")
+ print retval[1]
+ print
+ sys.exit(1)
+ elif x[0] in ["U","P"]:
+ myupdates+=[x[2:]]
+
+ if myupdates:
+ print green("Fetching trivial updates...")
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs up "+string.join(myupdates)+")"
+ retval=0
+ else:
+ retval=os.system("/usr/bin/cvs up "+string.join(myupdates))
+ if retval!=0:
+ print "!!! cvs exited with an error. Terminating."
+ sys.exit(retval)
+
+ if isCvs:
+ mycvstree=cvstree.getentries("./",recursive=1)
+ mychanged=cvstree.findchanged(mycvstree,recursive=1,basedir="./")
+ mynew=cvstree.findnew(mycvstree,recursive=1,basedir="./")
+ myremoved=cvstree.findremoved(mycvstree,recursive=1,basedir="./")
+ if not (mychanged or mynew or myremoved):
+ print
+ print green("RepoMan sez:"), "\"Doing nothing is not always good for QA.\"\n"
+ print
+ print "(Didn't find any changed files...)"
+ print
+ sys.exit(0)
+
+ myupdates=mychanged+mynew
+ myheaders=[]
+ mydirty=[]
+ headerstring="'\$(Header|Id)"
+ headerstring+=".*\$'"
+ for myfile in myupdates:
+ myout=getstatusoutput("egrep -q "+headerstring+" "+myfile)
+ if myout[0]==0:
+ myheaders.append(myfile)
+
+ print "*",green(str(len(myupdates))),"files being committed...",green(str(len(myheaders))),"have headers that will change."
+ print "*","Files with headers will cause the manifests to be made and recommited."
+ print "myupdates:",myupdates
+ print "myheaders:",myheaders
+ print
+ unlinkfile=0
+ if not (commitmessage or commitmessagefile):
+ print "Please enter a CVS commit message at the prompt:"
+ while not commitmessage:
+ try:
+ commitmessage=raw_input(green("> "))
+ except KeyboardInterrupt:
+ exithandler()
+ try:
+ commitmessage+="\n(Portage version: "+str(portage.VERSION)+")"
+ except:
+ print "Failed to insert portage version in message!"
+ commitmessage+="\n(Portage version: Unknown)"
+ if not commitmessagefile:
+ unlinkfile=1
+ commitmessagefile=tempfile.mktemp(".repoman.msg")
+ if os.path.exists(commitmessagefile):
+ os.unlink(commitmessagefile)
+ mymsg=open(commitmessagefile,"w")
+ mymsg.write(commitmessage)
+ mymsg.close()
+
+ print
+ print green("Using commit message:")
+ print green("------------------------------------------------------------------------------")
+ print commitmessage
+ print green("------------------------------------------------------------------------------")
+ print
+
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs -q commit -F "+commitmessagefile+")"
+ retval=0
+ else:
+ retval=os.system("/usr/bin/cvs -q commit -F "+commitmessagefile)
+ if retval:
+ print "!!! Exiting on cvs (shell) error code:",retval
+ sys.exit(retval)
+
+ # Setup the GPG commands
+ def gpgsign(filename):
+ gpgcmd = "gpg --sign --clearsign --yes "
+ gpgcmd+= "--default-key "+repoman_settings["PORTAGE_GPG_KEY"]
+ if repoman_settings.has_key("PORTAGE_GPG_DIR"):
+ gpgcmd += " --homedir "+repoman_settings["PORTAGE_GPG_DIR"]
+ rValue = os.system(gpgcmd+" "+filename)
+ if rValue == 0:
+ os.rename(filename+".asc", filename)
+ else:
+ print "!!! gpg exited with '" + str(rValue) + "' status"
+ return rValue
+
+ if myheaders or myupdates or myremoved or mynew:
+ myfiles=myheaders+myupdates+myremoved+mynew
+ 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"]="./"
+ portage.digestgen([],repoman_settings,manifestonly=1)
+ elif repolevel==2: # In a category dir
+ for x in myfiles:
+ xs=string.split(x,"/")
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] in mydone:
+ continue
+ mydone.append(xs[0])
+ repoman_settings["O"]="./"+xs[0]
+ portage.digestgen([],repoman_settings,manifestonly=1)
+ elif repolevel==1: # repo-cvsroot
+ print green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n"
+ for x in myfiles:
+ xs=string.split(x,"/")
+ if xs[0]==".":
+ xs=xs[1:]
+ if string.join(xs[:2],"/") in mydone:
+ continue
+ mydone.append(string.join(xs[:2],"/"))
+ repoman_settings["O"]="./"+string.join(xs[:2],"/")
+ portage.digestgen([],repoman_settings,manifestonly=1)
+ else:
+ print red("I'm confused... I don't know where I am!")
+ sys.exit(1)
+
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs -q commit -F "+commitmessagefile+")"
+ else:
+ mymsg=open(commitmessagefile,"w")
+ mymsg.write(commitmessage)
+ mymsg.write("\n (Unsigned Manifest commit)")
+ mymsg.close()
+ retval=os.system("/usr/bin/cvs -q commit -F "+commitmessagefile)
+ if retval:
+ print "!!! Exiting on cvs (shell) error code:",retval
+ sys.exit(retval)
+
+ if "sign" in portage.features:
+ mydone=[]
+ if repolevel==3: # In a package dir
+ repoman_settings["O"]="./"
+ while(gpgsign(repoman_settings["O"]+"/Manifest")):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+ elif repolevel==2: # In a category dir
+ for x in myfiles:
+ xs=string.split(x,"/")
+ if xs[0]==".":
+ xs=xs[1:]
+ if xs[0] in mydone:
+ continue
+ mydone.append(xs[0])
+ repoman_settings["O"]="./"+xs[0]
+ while(gpgsign(repoman_settings["O"]+"/Manifest")):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+ elif repolevel==1: # repo-cvsroot
+ print green("RepoMan sez:"), "\"You're rather crazy... doing the entire repository.\"\n"
+ for x in myfiles:
+ xs=string.split(x,"/")
+ if xs[0]==".":
+ xs=xs[1:]
+ if string.join(xs[:2],"/") in mydone:
+ continue
+ mydone.append(string.join(xs[:2],"/"))
+ repoman_settings["O"]="./"+string.join(xs[:2],"/")
+ while(gpgsign(repoman_settings["O"]+"/Manifest")):
+ portage.writemsg("!!! YOU MUST sign the Manifest.\n")
+ portage.writemsg("!!! You can also disable this for the time being by removing FEATURES='sign'")
+ time.sleep(3)
+
+ if "--pretend" in myoptions:
+ print "(/usr/bin/cvs -q commit -F "+commitmessagefile+")"
+ else:
+ mymsg=open(commitmessagefile,"w")
+ mymsg.write(commitmessage)
+ mymsg.write("\n (Signed Manifest commit)")
+ mymsg.close()
+ retval=os.system("/usr/bin/cvs -q commit -F "+commitmessagefile)
+ if retval:
+ print "!!! Exiting on cvs (shell) error code:",retval
+ sys.exit(retval)
+
+ if unlinkfile:
+ os.unlink(commitmessagefile)
+ print
+ if isCvs:
+ print "CVS commit complete."
+ else:
+ print "repoman was too scared by not seeing any familiar cvs 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/bin/xpak b/bin/xpak
new file mode 100755
index 000000000..03228c14a
--- /dev/null
+++ b/bin/xpak
@@ -0,0 +1,14 @@
+#!/usr/bin/python -O
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/bin/xpak,v 1.10 2004/10/04 13:56:50 vapier Exp $
+
+import sys
+if len(sys.argv)!=3:
+ print "xpak: expecting three arguments."
+ sys.exit(1)
+
+sys.path = ["/usr/lib/portage/pym"]+sys.path
+
+import xpak
+xpak.xpak(sys.argv[1],sys.argv[2])