X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fbup%2Fssh.py;h=de0448d003467f248572311b81b861e6d3560e46;hb=3eb23e4243379195f0e5cfff932ad3ec949b4f98;hp=cefa54385307ed290dd55c856c5fb6d50dcf90e0;hpb=dc79ae76c38e581164e0577c2c7b7bae2f0b37a7;p=bup.git diff --git a/lib/bup/ssh.py b/lib/bup/ssh.py index cefa543..de0448d 100644 --- a/lib/bup/ssh.py +++ b/lib/bup/ssh.py @@ -1,15 +1,21 @@ -import os, re, subprocess -from bup import helpers +"""SSH connection. +Connect to a remote host via SSH and execute a command on the host. +""" -def connect(rhost, subcmd): - 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 == '-': +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, stderr=None): + """Connect to 'rhost' and execute the bup subcommand 'subcmd' on it.""" + assert not re.search(br'[^\w-]', subcmd) + nicedir = re.sub(b':', b'_', path.exedir()) + if rhost == b'-': rhost = None if not rhost: - argv = ['bup', subcmd] + argv = [b'bup', subcmd] else: # WARNING: shell quoting security holes are possible here, so we # have to be super careful. We have to use 'sh -c' because @@ -18,18 +24,32 @@ def connect(rhost, subcmd): # 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) - force_tty = helpers.atoi(os.environ.get('BUP_FORCE_TTY')) - cmd = r""" - sh -c PATH=%s:'$PATH BUP_FORCE_TTY=%s bup %s' - """ % (escapedir, force_tty, subcmd) - argv = ['ssh', rhost, '--', cmd.strip()] + escapedir = re.sub(br'([^\w/])', br'\\\\\\\1', nicedir) + buglvl = helpers.atoi(environ.get(b'BUP_DEBUG')) + force_tty = helpers.atoi(environ.get(b'BUP_FORCE_TTY')) + cmd = b""" + sh -c PATH=%s:'$PATH BUP_DEBUG=%s BUP_FORCE_TTY=%s bup %s' + """ % (escapedir, buglvl, force_tty, subcmd) + argv = [b'ssh'] + if port: + 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 rhost: + env = environ + else: + envpath = environ.get(b'PATH') + env = environ.copy() + env[b'PATH'] = nicedir if not envpath else nicedir + b':' + envpath + if sys.version_info[0] < 3: + return subprocess.Popen(argv, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=stderr, + env=env, + preexec_fn=lambda: os.setsid()) + else: + return subprocess.Popen(argv, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=stderr, + env=env, + start_new_session=True)