119 lines
3.0 KiB
Python
119 lines
3.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
|
|
@author: Fabio Erculiani <lxnay@sabayon.org>
|
|
@contact: lxnay@sabayon.org
|
|
@copyright: Fabio Erculiani
|
|
@license: GPL-2
|
|
|
|
B{Entropy Infrastructure Toolkit}.
|
|
|
|
"""
|
|
import os
|
|
import sys
|
|
import argparse
|
|
|
|
from entropy.i18n import _
|
|
from entropy.const import etpConst, const_convert_to_unicode
|
|
from entropy.output import print_error
|
|
import entropy.tools
|
|
|
|
from entropy.exceptions import OnlineMirrorError
|
|
from _entropy.eit.commands.descriptor import EitCommandDescriptor
|
|
|
|
|
|
def handle_exception(exc_class, exc_instance, exc_tb):
|
|
|
|
# restore original exception handler, to avoid loops
|
|
uninstall_exception_handler()
|
|
entropy.tools.kill_threads()
|
|
|
|
if exc_class is KeyboardInterrupt:
|
|
os._exit(1)
|
|
|
|
if exc_class is OnlineMirrorError:
|
|
print_error("Mirror error: %s" % (
|
|
exc_instance,))
|
|
os._exit(1)
|
|
|
|
# always slap exception data (including stack content)
|
|
entropy.tools.print_exception(tb_data=exc_tb, all_frame_data=True)
|
|
|
|
def install_exception_handler():
|
|
sys.excepthook = handle_exception
|
|
|
|
def uninstall_exception_handler():
|
|
sys.excepthook = sys.__excepthook__
|
|
|
|
def main():
|
|
|
|
install_exception_handler()
|
|
|
|
descriptors = EitCommandDescriptor.obtain()
|
|
args_map = {}
|
|
catch_all = None
|
|
for descriptor in descriptors:
|
|
klass = descriptor.get_class()
|
|
if klass.CATCH_ALL:
|
|
catch_all = klass
|
|
args_map[klass.NAME] = klass
|
|
for alias in klass.ALIASES:
|
|
args_map[alias] = klass
|
|
|
|
args = sys.argv[1:]
|
|
# convert args to unicode, to avoid passing
|
|
# raw string stuff down to entropy layers
|
|
def _to_unicode(arg):
|
|
try:
|
|
return const_convert_to_unicode(
|
|
arg, enctype=etpConst['conf_encoding'])
|
|
except UnicodeDecodeError:
|
|
print_error("invalid argument: %s" % (arg,))
|
|
raise SystemExit(1)
|
|
args = list(map(_to_unicode, args))
|
|
|
|
is_bashcomp = False
|
|
if "--bashcomp" in args:
|
|
is_bashcomp = True
|
|
args.remove("--bashcomp")
|
|
# the first eit, because bash does:
|
|
# argv -> eit --bashcomp eit add
|
|
# and we need to drop --bashcomp and
|
|
# argv[2]
|
|
args.pop(0)
|
|
|
|
cmd = None
|
|
last_arg = None
|
|
if args:
|
|
last_arg = args[-1]
|
|
cmd = args[0]
|
|
args = args[1:]
|
|
cmd_class = args_map.get(cmd)
|
|
|
|
if cmd_class is None:
|
|
cmd_class = catch_all
|
|
|
|
cmd_obj = cmd_class(args)
|
|
if is_bashcomp:
|
|
try:
|
|
cmd_obj.bashcomp(last_arg)
|
|
except NotImplementedError:
|
|
pass
|
|
raise SystemExit(0)
|
|
|
|
# non-root users not allowed
|
|
allowed = True
|
|
if os.getuid() != 0 and \
|
|
cmd_class is not catch_all:
|
|
if not cmd_class.ALLOW_UNPRIVILEGED:
|
|
cmd_class = catch_all
|
|
allowed = False
|
|
|
|
func, func_args = cmd_obj.parse()
|
|
if allowed:
|
|
exit_st = func(*func_args)
|
|
raise SystemExit(exit_st)
|
|
else:
|
|
print_error(_("superuser access required"))
|
|
raise SystemExit(1)
|