X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbup%2Fssh.py;h=ae560908fc7439c8dd11eb16284d5974dd523745;hb=6a097ab641b0a7584a15982e48b34e0882db4cb2;hp=f91e16dcb34bc9ce1d755704b2c1a8f96db439b3;hpb=72eab171e4c8314d39a43ac59274da2d90dd0d7c;p=bup.git diff --git a/lib/bup/ssh.py b/lib/bup/ssh.py index f91e16d..ae56090 100644 --- a/lib/bup/ssh.py +++ b/lib/bup/ssh.py @@ -1,48 +1,36 @@ """SSH connection. Connect to a remote host via SSH and execute a command on the host. """ -import os -import sys -import re -import subprocess -from bup import helpers +from __future__ import absolute_import, print_function +import sys, os, re, subprocess +from bup import helpers, path +from bup.compat import environ -def connect(rhost, port, subcmd): +def connect(rhost, port, subcmd, stderr=None): """Connect to 'rhost' and execute the bup subcommand 'subcmd' on it.""" - assert(not re.search(r'[^\w-]', subcmd)) - main_exe = os.environ.get('BUP_MAIN_EXE') or sys.argv[0] - nicedir = os.path.split(os.path.abspath(main_exe))[0] - nicedir = re.sub(r':', "_", nicedir) - if rhost == '-': - rhost = None - if not rhost: - argv = ['bup', subcmd] + assert not re.search(br'[^\w-]', subcmd) + if rhost is None or rhost == b'-': + argv = [path.exe(), subcmd] else: - # WARNING: shell quoting security holes are possible here, so we - # have to be super careful. We have to use 'sh -c' because - # csh-derived shells can't handle PATH= notation. We can't - # set PATH in advance, because ssh probably replaces it. We - # can't exec *safely* using argv, because *both* ssh and 'sh -c' - # allow shellquoting. So we end up having to double-shellquote - # stuff here. - escapedir = re.sub(r'([^\w/])', r'\\\\\\\1', nicedir) - buglvl = helpers.atoi(os.environ.get('BUP_DEBUG')) - force_tty = helpers.atoi(os.environ.get('BUP_FORCE_TTY')) - cmd = r""" - sh -c PATH=%s:'$PATH BUP_DEBUG=%s BUP_FORCE_TTY=%s bup %s' - """ % (escapedir, buglvl, force_tty, subcmd) - argv = ['ssh'] + buglvl = helpers.atoi(environ.get(b'BUP_DEBUG')) + force_tty = helpers.atoi(environ.get(b'BUP_FORCE_TTY')) + cmd = b""" + sh -c 'BUP_DEBUG=%d BUP_FORCE_TTY=%d bup %s' + """ % (buglvl, force_tty, subcmd) + argv = [b'ssh'] if port: - argv.extend(('-p', port)) - argv.extend((rhost, '--', cmd.strip())) + argv.extend((b'-p', port)) + argv.extend((rhost, b'--', cmd.strip())) #helpers.log('argv is: %r\n' % argv) - def setup(): - # runs in the child process - if not rhost: - os.environ['PATH'] = ':'.join([nicedir, - os.environ.get('PATH', '')]) - os.setsid() - return subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - preexec_fn=setup) + if sys.version_info[0] < 3: + return subprocess.Popen(argv, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=stderr, + preexec_fn=lambda: os.setsid()) + else: + return subprocess.Popen(argv, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=stderr, + start_new_session=True)