#!/usr/bin/python -O
+# Copyright 2005-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
-import sys
-from copy import copy
-from optparse import OptionParser, OptionValueError
-
-
-
-import os, portage, portage_const
-class WorldHandler(object):
-
- def name():
- return "world"
- name = staticmethod(name)
-
- def __init__(self):
- self.invalid = []
- self.not_installed = []
- self.unavailable = []
- self.okay = []
- self.found = os.access(portage_const.WORLD_FILE, os.R_OK)
-
- for atom in open(portage_const.WORLD_FILE).read().split():
- if not portage.isvalidatom(atom):
- self.invalid.append(atom)
- elif not portage.db["/"]["vartree"].dbapi.match(atom):
- self.not_installed.append(atom)
- elif not portage.db["/"]["porttree"].dbapi.match(atom):
- self.unavailable.append(atom)
- else:
- self.okay.append(atom)
-
- def check(self):
- errors = []
- if self.found:
- errors += map(lambda x: "'%s' is not a valid atom" % x, self.invalid)
- errors += map(lambda x: "'%s' is not installed" % x, self.not_installed)
- errors += map(lambda x: "'%s' has no ebuilds available" % x, self.unavailable)
- else:
- errors.append(portage_const.WORLD_FILE + " could not be opened for reading")
- return errors
-
- def fix(self):
- errors = []
- try:
- open(portage_const.WORLD_FILE, "w").write("\n".join(self.okay))
- except OSError:
- errors.append(portage_const.WORLD_FILE + " could not be opened for writing")
- return errors
-
-
-modules = {"world" : WorldHandler}
-
-
-module_names = modules.keys()
-module_names.sort()
-module_names.insert(0, "all")
+"""System health checks and maintenance utilities.
+"""
+from __future__ import print_function
-def exclusive(option, value, empty, parser, var=None):
- if not var:
- raise ValueError("var not specified to exclusive()")
- if getattr(parser, var, ""):
- raise OptionValueError("%s and %s are exclusive options" % (getattr(parser, var), value))
- setattr(parser, var, value)
-
-
-usage = "usage: emaint [options] " + " | ".join(module_names)
-parser = OptionParser(usage=usage)
-parser.add_option("-c", "--check", help="check for problems",
- action="callback", callback=exclusive, callback_kwargs={"var":"action"})
-parser.add_option("-f", "--fix", help="attempt to fix problems",
- action="callback", callback=exclusive, callback_kwargs={"var":"action"})
-parser.action = None
-
-
-(options, args) = parser.parse_args()
-if len(args) != 1:
- parser.error("Incorrect number of arguments")
-if args[0] not in module_names:
- parser.error("%s target is not a known target" % args[0])
-
-if parser.action:
- action = parser.action
-else:
- print "Defaulting to --check"
- action = "--check"
-
-if args[0] == "all":
- tasks = modules.values()
-else:
- tasks = [modules[args[0]]]
-
-
-if action == "--check":
- status = "Checking %s for problems"
- func = "check"
-else:
- status = "Attempting to fix %s"
- func = "fix"
-
-
-for task in tasks:
- print status % task.name()
- inst = task()
- result = getattr(inst, func)()
- if result:
- print
- print "\n".join(result)
- print "\n"
-
+import sys
+import errno
+# 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)
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+except KeyboardInterrupt:
+ sys.exit(1)
+
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
+from portage.emaint.main import emaint_main
+
+try:
+ emaint_main(sys.argv[1:])
+except IOError as e:
+ if e.errno == errno.EACCES:
+ print("\nemaint: Need superuser access")
+ sys.exit(1)
+ else:
+ raise