X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=cmd%2Fbup;h=c98d7e7eb62a368a6db7f826762dc9e903e50507;hb=a74f980a79911b14bc5572921f6c9ff94990fc2e;hp=e442541bffb505572a9d0bc737b14eafa68a3970;hpb=3fa656946d28bb8cac061b745e2edc26bc2d56ae;p=bup.git diff --git a/cmd/bup b/cmd/bup index e442541..c98d7e7 100755 --- a/cmd/bup +++ b/cmd/bup @@ -16,43 +16,30 @@ exec "$script_home/bup-python" "$0" ${1+"$@"} # end of bup preamble from __future__ import absolute_import, print_function -import errno, re, sys, os, subprocess, signal, getopt +import errno, getopt, os, re, select, signal, subprocess, sys +from subprocess import PIPE + +from bup.compat import environ, restore_lc_env +from bup.io import path_msg if sys.version_info[0] != 2 \ - and not os.environ.get('BUP_ALLOW_UNEXPECTED_PYTHON_VERSION') == 'true': + and not environ.get(b'BUP_ALLOW_UNEXPECTED_PYTHON_VERSION') == b'true': print('error: bup may crash with python versions other than 2, or eat your data', file=sys.stderr) sys.exit(2) -from subprocess import PIPE -from sys import stderr, stdout -import select - -argv = sys.argv -exe = os.path.realpath(argv[0]) -exepath = os.path.split(exe)[0] or '.' - -# fix the PYTHONPATH to include our lib dir -if os.path.exists("%s/../bup/." % exepath): - # Everything is relative to exepath (i.e. LIBDIR/cmd/) - cmdpath = exepath - libpath = os.path.join(exepath, '..') - resourcepath = libpath -else: - # running from the src directory without being installed first - cmdpath = exepath - libpath = os.path.join(exepath, '../lib') - resourcepath = libpath -sys.path[:0] = [libpath] -os.environ['PYTHONPATH'] = libpath + ':' + os.environ.get('PYTHONPATH', '') -os.environ['BUP_MAIN_EXE'] = os.path.abspath(exe) -os.environ['BUP_RESOURCE_PATH'] = resourcepath - - -from bup import compat, helpers -from bup.compat import add_ex_tb, add_ex_ctx, wrap_main +restore_lc_env() + +from bup import compat, path, helpers +from bup.compat import add_ex_tb, add_ex_ctx, argv_bytes, wrap_main from bup.helpers import atoi, columnate, debug1, log, merge_dict, tty_width +from bup.io import byte_stream, path_msg + +cmdpath = path.cmddir() +# We manipulate the subcmds here as strings, but they must be ASCII +# compatible, since we're going to be looking for exactly +# b'bup-SUBCMD' to exec. def usage(msg=""): log('Usage: bup [-?|--help] [-d BUP_DIR] [--debug] [--profile] ' @@ -77,9 +64,9 @@ def usage(msg=""): log('Other available commands:\n') cmds = [] - for c in sorted(os.listdir(cmdpath) + os.listdir(exepath)): - if c.startswith('bup-') and c.find('.') < 0: - cname = c[4:] + for c in sorted(os.listdir(cmdpath)): + if c.startswith(b'bup-') and c.find(b'.') < 0: + cname = c[4:].decode('iso-8859-1') if cname not in common: cmds.append(c[4:]) log(columnate(cmds, ' ')) @@ -92,76 +79,79 @@ def usage(msg=""): sys.exit(99) -if len(argv) < 2: +if len(sys.argv) < 2: usage() # Handle global options. try: optspec = ['help', 'version', 'debug', 'profile', 'bup-dir='] - global_args, subcmd = getopt.getopt(argv[1:], '?VDd:', optspec) + global_args, subcmd = getopt.getopt(sys.argv[1:], '?VDd:', optspec) except getopt.GetoptError as ex: usage('error: %s' % ex.msg) +subcmd = [argv_bytes(x) for x in subcmd] help_requested = None do_profile = False +bup_dir = None for opt in global_args: if opt[0] in ['-?', '--help']: help_requested = True elif opt[0] in ['-V', '--version']: - subcmd = ['version'] + subcmd = [b'version'] elif opt[0] in ['-D', '--debug']: helpers.buglvl += 1 - os.environ['BUP_DEBUG'] = str(helpers.buglvl) + environ[b'BUP_DEBUG'] = b'%d' % helpers.buglvl elif opt[0] in ['--profile']: do_profile = True elif opt[0] in ['-d', '--bup-dir']: - os.environ['BUP_DIR'] = opt[1] + bup_dir = argv_bytes(opt[1]) else: usage('error: unexpected option "%s"' % opt[0]) +if bup_dir: + bup_dir = argv_bytes(bup_dir) + # Make BUP_DIR absolute, so we aren't affected by chdir (i.e. save -C, etc.). -if 'BUP_DIR' in os.environ: - os.environ['BUP_DIR'] = os.path.abspath(os.environ['BUP_DIR']) +if bup_dir: + environ[b'BUP_DIR'] = os.path.abspath(bup_dir) if len(subcmd) == 0: if help_requested: - subcmd = ['help'] + subcmd = [b'help'] else: usage() -if help_requested and subcmd[0] != 'help': - subcmd = ['help'] + subcmd +if help_requested and subcmd[0] != b'help': + subcmd = [b'help'] + subcmd -if len(subcmd) > 1 and subcmd[1] == '--help' and subcmd[0] != 'help': - subcmd = ['help', subcmd[0]] + subcmd[2:] +if len(subcmd) > 1 and subcmd[1] == b'--help' and subcmd[0] != b'help': + subcmd = [b'help', subcmd[0]] + subcmd[2:] subcmd_name = subcmd[0] if not subcmd_name: usage() -def subpath(s): - sp = os.path.join(exepath, 'bup-%s' % s) - if not os.path.exists(sp): - sp = os.path.join(cmdpath, 'bup-%s' % s) - return sp +def subpath(subcmd): + return os.path.join(cmdpath, b'bup-' + subcmd) subcmd[0] = subpath(subcmd_name) if not os.path.exists(subcmd[0]): - usage('error: unknown command "%s"' % subcmd_name) + usage('error: unknown command "%s"' % path_msg(subcmd_name)) -already_fixed = atoi(os.environ.get('BUP_FORCE_TTY')) -if subcmd_name in ['mux', 'ftp', 'help']: +already_fixed = atoi(environ.get(b'BUP_FORCE_TTY')) +if subcmd_name in [b'mux', b'ftp', b'help']: already_fixed = True fix_stdout = not already_fixed and os.isatty(1) fix_stderr = not already_fixed and os.isatty(2) if fix_stdout or fix_stderr: - tty_env = merge_dict(os.environ, - {'BUP_FORCE_TTY': str((fix_stdout and 1 or 0) - + (fix_stderr and 2 or 0))}) + tty_env = merge_dict(environ, + {b'BUP_FORCE_TTY': (b'%d' + % ((fix_stdout and 1 or 0) + + (fix_stderr and 2 or 0)))}) else: - tty_env = os.environ + tty_env = environ sep_rx = re.compile(br'([\r\n])') @@ -241,15 +231,19 @@ def filter_output(src_out, src_err, dest_out, dest_err): def run_subcmd(subcmd): - c = (do_profile and [sys.executable, '-m', 'cProfile'] or []) + subcmd + c = (do_profile and [sys.executable, b'-m', b'cProfile'] or []) + subcmd if not (fix_stdout or fix_stderr): os.execvp(c[0], c) + sys.stdout.flush() + sys.stderr.flush() + out = byte_stream(sys.stdout) + err = byte_stream(sys.stderr) p = None try: p = subprocess.Popen(c, - stdout=PIPE if fix_stdout else sys.stdout, - stderr=PIPE if fix_stderr else sys.stderr, + stdout=PIPE if fix_stdout else out, + stderr=PIPE if fix_stderr else err, env=tty_env, bufsize=4096, close_fds=True) # Assume p will receive these signals and quit, which will # then cause us to quit. @@ -258,8 +252,8 @@ def run_subcmd(subcmd): filter_output(fix_stdout and p.stdout.fileno() or None, fix_stderr and p.stderr.fileno() or None, - fix_stdout and sys.stdout.fileno() or None, - fix_stderr and sys.stderr.fileno() or None) + fix_stdout and out.fileno() or None, + fix_stderr and err.fileno() or None) return p.wait() except BaseException as ex: add_ex_tb(ex)