#!/usr/bin/python -O # Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 from __future__ import print_function import sys # This block ensures that ^C interrupts are handled quietly. try: import signal def exithandler(signum, frame): signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGTERM, signal.SIG_IGN) sys.exit(1) signal.signal(signal.SIGINT, exithandler) signal.signal(signal.SIGTERM, exithandler) except KeyboardInterrupt: sys.exit(1) import os import types # Avoid sandbox violations after python upgrade. pym_path = os.path.join(os.path.dirname( os.path.dirname(os.path.realpath(__file__))), "pym") if os.environ.get("SANDBOX_ON") == "1": sandbox_write = os.environ.get("SANDBOX_WRITE", "").split(":") if pym_path not in sandbox_write: sandbox_write.append(pym_path) os.environ["SANDBOX_WRITE"] = \ ":".join(filter(None, sandbox_write)) del sandbox_write try: import portage except ImportError: sys.path.insert(0, pym_path) import portage del pym_path from portage import os from portage.util import writemsg, writemsg_stdout def eval_atom_use(atom): if 'USE' in os.environ: use = frozenset(os.environ['USE'].split()) atom = atom.evaluate_conditionals(use) return atom #----------------------------------------------------------------------------- # # To add functionality to this tool, add a function below. # # The format for functions is: # # def function(argv): # """ # # """ # # # "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): """ Return code 0 if it's available, 1 otherwise. """ if (len(argv) < 2): print("ERROR: insufficient parameters!") sys.exit(2) try: atom = portage.dep.Atom(argv[1]) except portage.exception.InvalidAtom: if atom_validate_strict: portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1], noiselevel=-1) return 2 else: atom = argv[1] else: atom = eval_atom_use(atom) try: mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom) if mylist: sys.exit(0) else: sys.exit(1) except KeyError: sys.exit(1) has_version.uses_root = True def best_version(argv): """ Returns category/package-version (without .ebuild). """ if (len(argv) < 2): print("ERROR: insufficient parameters!") sys.exit(2) try: atom = portage.dep.Atom(argv[1]) except portage.exception.InvalidAtom: if atom_validate_strict: portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1], noiselevel=-1) return 2 else: atom = argv[1] else: atom = eval_atom_use(atom) try: mylist = portage.db[argv[0]]["vartree"].dbapi.match(atom) print(portage.best(mylist)) except KeyError: sys.exit(1) best_version.uses_root = True def mass_best_version(argv): """ []+ Returns category/package-version (without .ebuild). """ if (len(argv) < 2): print("ERROR: insufficient parameters!") sys.exit(2) try: for pack in argv[1:]: mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack) print(pack+":"+portage.best(mylist)) except KeyError: sys.exit(1) mass_best_version.uses_root = True def metadata(argv): """ []+ Returns metadata values for the specified package. """ if (len(argv) < 4): print("ERROR: insufficient parameters!", file=sys.stderr) sys.exit(2) root, pkgtype, pkgspec = argv[0:3] metakeys = argv[3:] type_map = { "ebuild":"porttree", "binary":"bintree", "installed":"vartree"} if pkgtype not in type_map: print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr) sys.exit(1) trees = portage.db if os.path.realpath(root) == os.path.realpath(portage.settings["ROOT"]): root = portage.settings["ROOT"] # contains the normalized $ROOT try: values = trees[root][type_map[pkgtype]].dbapi.aux_get( pkgspec, metakeys) writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1) except KeyError: print("Package not found: '%s'" % pkgspec, file=sys.stderr) sys.exit(1) metadata.uses_root = True def contents(argv): """ List the files that are installed for a given package, with one file listed on each line. All file names will begin with . """ if len(argv) != 2: print("ERROR: expected 2 parameters, got %d!" % len(argv)) return 2 root, cpv = argv vartree = portage.db[root]["vartree"] if not vartree.dbapi.cpv_exists(cpv): sys.stderr.write("Package not found: '%s'\n" % cpv) return 1 cat, pkg = portage.catsplit(cpv) db = portage.dblink(cat, pkg, root, vartree.settings, treetype="vartree", vartree=vartree) writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())), noiselevel=-1) contents.uses_root = True def owners(argv): """ []+ Given a list of files, print the packages that own the files and which files belong to each package. Files owned by a package are listed on the lines below it, indented by a single tab character (\\t). All file paths must either start with or be a basename alone. Returns 1 if no owners could be found, and 0 otherwise. """ if len(argv) < 2: sys.stderr.write("ERROR: insufficient parameters!\n") sys.stderr.flush() return 2 from portage import catsplit, dblink settings = portage.settings root = settings["ROOT"] vardb = portage.db[root]["vartree"].dbapi cwd = None try: cwd = os.getcwd() except OSError: pass files = [] for f in argv[1:]: f = portage.normalize_path(f) is_basename = os.sep not in f if not is_basename and f[:1] != os.sep: if cwd is None: sys.stderr.write("ERROR: cwd does not exist!\n") sys.stderr.flush() return 2 f = os.path.join(cwd, f) f = portage.normalize_path(f) if not is_basename and not f.startswith(root): sys.stderr.write("ERROR: file paths must begin with !\n") sys.stderr.flush() return 2 if is_basename: files.append(f) else: files.append(f[len(root)-1:]) owners = vardb._owners.get_owners(files) msg = [] for pkg, owned_files in owners.items(): cpv = pkg.mycpv msg.append("%s\n" % cpv) for f in sorted(owned_files): msg.append("\t%s\n" % \ os.path.join(root, f.lstrip(os.path.sep))) writemsg_stdout(''.join(msg), noiselevel=-1) if owners: return 0 sys.stderr.write("None of the installed packages claim the file(s).\n") sys.stderr.flush() return 1 owners.uses_root = True def is_protected(argv): """ Given a single filename, return code 0 if it's protected, 1 otherwise. The filename must begin with . """ if len(argv) != 2: sys.stderr.write("ERROR: expected 2 parameters, got %d!\n" % len(argv)) sys.stderr.flush() return 2 root, filename = argv err = sys.stderr cwd = None try: cwd = os.getcwd() except OSError: pass f = portage.normalize_path(filename) if not f.startswith(os.path.sep): if cwd is None: err.write("ERROR: cwd does not exist!\n") err.flush() return 2 f = os.path.join(cwd, f) f = portage.normalize_path(f) if not f.startswith(root): err.write("ERROR: file paths must begin with !\n") err.flush() return 2 from portage.util import ConfigProtect settings = portage.settings protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")) protect_mask = portage.util.shlex_split( settings.get("CONFIG_PROTECT_MASK", "")) protect_obj = ConfigProtect(root, protect, protect_mask) if protect_obj.isprotected(f): return 0 return 1 is_protected.uses_root = True def filter_protected(argv): """ Read filenames from stdin and write them to stdout if they are protected. All filenames are delimited by \\n and must begin with . """ if len(argv) != 1: sys.stderr.write("ERROR: expected 1 parameter, got %d!\n" % len(argv)) sys.stderr.flush() return 2 root, = argv out = sys.stdout err = sys.stderr cwd = None try: cwd = os.getcwd() except OSError: pass from portage.util import ConfigProtect settings = portage.settings protect = portage.util.shlex_split(settings.get("CONFIG_PROTECT", "")) protect_mask = portage.util.shlex_split( settings.get("CONFIG_PROTECT_MASK", "")) protect_obj = ConfigProtect(root, protect, protect_mask) protected = 0 errors = 0 for line in sys.stdin: filename = line.rstrip("\n") f = portage.normalize_path(filename) if not f.startswith(os.path.sep): if cwd is None: err.write("ERROR: cwd does not exist!\n") err.flush() errors += 1 continue f = os.path.join(cwd, f) f = portage.normalize_path(f) if not f.startswith(root): err.write("ERROR: file paths must begin with !\n") err.flush() errors += 1 continue if protect_obj.isprotected(f): protected += 1 out.write("%s\n" % filename) out.flush() if errors: return 2 return 0 filter_protected.uses_root = True def best_visible(argv): """ []+ 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]) visible=portage.best(mylist) if visible: print(visible) sys.exit(0) else: sys.exit(1) except KeyError: sys.exit(1) best_visible.uses_root = True def mass_best_visible(argv): """ []+ Returns category/package-version (without .ebuild). """ if (len(argv) < 2): print("ERROR: insufficient parameters!") sys.exit(2) try: for pack in argv[1:]: mylist=portage.db[argv[0]]["porttree"].dbapi.match(pack) print(pack+":"+portage.best(mylist)) except KeyError: sys.exit(1) mass_best_visible.uses_root = True def all_best_visible(argv): """ 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) all_best_visible.uses_root = True def match(argv): """ Returns a \\n separated list of category/package-version. When given an empty string, all installed packages will be listed. """ if len(argv) != 2: print("ERROR: expected 2 parameters, got %d!" % len(argv)) sys.exit(2) root, atom = argv if atom: if atom_validate_strict and not portage.isvalidatom(atom): portage.writemsg("ERROR: Invalid atom: '%s'\n" % atom, noiselevel=-1) return 2 results = portage.db[root]["vartree"].dbapi.match(atom) else: results = portage.db[root]["vartree"].dbapi.cpv_all() results.sort() for cpv in results: print(cpv) match.uses_root = True def vdb_path(argv): """ Returns the path used for the var(installed) package database for the set environment/configuration options. """ out = sys.stdout out.write(os.path.join(portage.settings["ROOT"], portage.VDB_PATH) + "\n") out.flush() return os.EX_OK def gentoo_mirrors(argv): """ Returns the mirrors set to use in the portage configuration. """ print(portage.settings["GENTOO_MIRRORS"]) def portdir(argv): """ Returns the PORTDIR path. """ print(portage.settings["PORTDIR"]) def config_protect(argv): """ Returns the CONFIG_PROTECT paths. """ print(portage.settings["CONFIG_PROTECT"]) def config_protect_mask(argv): """ Returns the CONFIG_PROTECT_MASK paths. """ print(portage.settings["CONFIG_PROTECT_MASK"]) def portdir_overlay(argv): """ Returns the PORTDIR_OVERLAY path. """ print(portage.settings["PORTDIR_OVERLAY"]) def pkgdir(argv): """ Returns the PKGDIR path. """ print(portage.settings["PKGDIR"]) def distdir(argv): """ Returns the DISTDIR path. """ print(portage.settings["DISTDIR"]) def envvar(argv): """+ Returns a specific environment variable as exists prior to ebuild.sh. Similar to: emerge --verbose --info | egrep '^=' """ verbose = "-v" in argv if verbose: argv.pop(argv.index("-v")) if len(argv) == 0: print("ERROR: insufficient parameters!") sys.exit(2) for arg in argv: if verbose: print(arg +"='"+ portage.settings[arg] +"'") else: print(portage.settings[arg]) def get_repos(argv): """ Returns all repos with names (repo_name file) argv[0] = $ROOT """ if len(argv) < 1: print("ERROR: insufficient parameters!") sys.exit(2) print(" ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories())) def get_repo_path(argv): """ + Returns the path to the repo named argv[1], argv[0] = $ROOT """ if len(argv) < 2: print("ERROR: insufficient parameters!") sys.exit(2) for arg in argv[1:]: print(portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg)) def list_preserved_libs(argv): """ Print a list of libraries preserved during a package update in the form package: path. Returns 0 if no preserved libraries could be found, 1 otherwise. """ if len(argv) != 1: print("ERROR: wrong number of arguments") sys.exit(2) mylibs = portage.db[argv[0]]["vartree"].dbapi.plib_registry.getPreservedLibs() rValue = 0 msg = [] for cpv in sorted(mylibs): msg.append(cpv) for path in mylibs[cpv]: msg.append(' ' + path) rValue = 1 msg.append('\n') writemsg_stdout(''.join(msg), noiselevel=-1) return rValue list_preserved_libs.uses_root = True #----------------------------------------------------------------------------- # # DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED! # def usage(argv): print(">>> Portage information query tool") print(">>> %s" % portage.VERSION) print(">>> Usage: portageq [