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) if rhost is None or rhost == b'-': argv = [path.exe(), subcmd] else: 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((b'-p', port)) argv.extend((rhost, b'--', cmd.strip())) #helpers.log('argv is: %r\n' % argv) 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)
def connect(rhost, port, subcmd): """Connect to 'rhost' and execute the bup subcommand 'subcmd' on it.""" assert(not re.search(r'[^\w-]', subcmd)) nicedir = re.sub(r':', "_", path.exedir()) if rhost == '-': rhost = None if not rhost: argv = ['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 # 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'] if port: argv.extend(('-p', port)) argv.extend((rhost, '--', 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)
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 == '-': rhost = None if not rhost: argv = ['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 # 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) 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()] #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)
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 = [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 # 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(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) 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)
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)) nicedir = re.sub(r':', "_", path.exedir()) if rhost == '-': rhost = None if not rhost: argv = ['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 # 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'] if port: argv.extend(('-p', port)) argv.extend((rhost, '--', 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, stderr=stderr, preexec_fn=setup)
def __init__(self, remote, create=False): self._busy = self.conn = None self.sock = self.p = self.pout = self.pin = None is_reverse = environ.get(b'BUP_SERVER_REVERSE') if is_reverse: assert(not remote) remote = b'%s:' % is_reverse (self.protocol, self.host, self.port, self.dir) = parse_remote(remote) # The b'None' here matches python2's behavior of b'%s' % None == 'None', # python3 will (as of version 3.7.5) do the same for str ('%s' % None), # but crashes instead when doing b'%s' % None. cachehost = b'None' if self.host is None else self.host cachedir = b'None' if self.dir is None else self.dir self.cachedir = git.repo(b'index-cache/%s' % re.sub(br'[^@\w]', b'_', b'%s:%s' % (cachehost, cachedir))) if is_reverse: self.pout = os.fdopen(3, 'rb') self.pin = os.fdopen(4, 'wb') self.conn = Conn(self.pout, self.pin) else: if self.protocol in (b'ssh', b'file'): try: # FIXME: ssh and file shouldn't use the same module self.p = ssh.connect(self.host, self.port, b'server') self.pout = self.p.stdout self.pin = self.p.stdin self.conn = Conn(self.pout, self.pin) except OSError as e: reraise(ClientError('connect: %s' % e)) elif self.protocol == b'bup': self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.host, atoi(self.port) or 1982)) self.sockw = self.sock.makefile('wb') self.conn = DemuxConn(self.sock.fileno(), self.sockw) self._available_commands = self._get_available_commands() self._require_command(b'init-dir') self._require_command(b'set-dir') if self.dir: self.dir = re.sub(br'[\r\n]', ' ', self.dir) if create: self.conn.write(b'init-dir %s\n' % self.dir) else: self.conn.write(b'set-dir %s\n' % self.dir) self.check_ok() self.sync_indexes()
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 subcmd[0] = subpath(subcmd_name) if not os.path.exists(subcmd[0]): usage('error: unknown command "%s"' % subcmd_name) already_fixed = atoi(os.environ.get('BUP_FORCE_TTY')) if subcmd_name in ['mux', 'ftp', 'help']: already_fixed = True fix_stdout = not already_fixed and os.isatty(1) fix_stderr = not already_fixed and os.isatty(2) def force_tty(): if fix_stdout or fix_stderr: amt = (fix_stdout and 1 or 0) + (fix_stderr and 2 or 0) os.environ['BUP_FORCE_TTY'] = str(amt) sep_rx = re.compile(r'([\r\n])') def print_clean_line(dest, content, width, sep=None): """Write some or all of content, followed by sep, to the dest fd after
import os, sys from bup import options, _helpers from bup.helpers import atoi, handle_ctrl_c, log, parse_num optspec = """ bup random [-S seed] <numbytes> -- S,seed= optional random number seed [1] f,force print random data to stdout even if it's a tty v,verbose print byte counter to stderr """ o = options.Options(optspec) (opt, flags, extra) = o.parse(sys.argv[1:]) if len(extra) != 1: o.fatal("exactly one argument expected") total = parse_num(extra[0]) handle_ctrl_c() if opt.force or (not os.isatty(1) and not atoi(os.environ.get('BUP_FORCE_TTY')) & 1): _helpers.write_random(sys.stdout.fileno(), total, opt.seed, opt.verbose and 1 or 0) else: log('error: not writing binary data to a terminal. Use -f to force.\n') sys.exit(1)
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 subcmd[0] = subpath(subcmd_name) if not os.path.exists(subcmd[0]): usage('error: unknown command "%s"' % subcmd_name) already_fixed = atoi(os.environ.get('BUP_FORCE_TTY')) if subcmd_name in ['mux', 'ftp', 'help']: already_fixed = True fix_stdout = not already_fixed and os.isatty(1) fix_stderr = not already_fixed and os.isatty(2) def force_tty(): if fix_stdout or fix_stderr: amt = (fix_stdout and 1 or 0) + (fix_stderr and 2 or 0) os.environ['BUP_FORCE_TTY'] = str(amt) sep_rx = re.compile(r'([\r\n])')
from __future__ import absolute_import import os, sys from bup import options, _helpers from bup.helpers import atoi, handle_ctrl_c, log, parse_num optspec = """ bup random [-S seed] <numbytes> -- S,seed= optional random number seed [1] f,force print random data to stdout even if it's a tty v,verbose print byte counter to stderr """ o = options.Options(optspec) (opt, flags, extra) = o.parse(sys.argv[1:]) if len(extra) != 1: o.fatal("exactly one argument expected") total = parse_num(extra[0]) handle_ctrl_c() if opt.force or (not os.isatty(1) and not atoi(os.environ.get('BUP_FORCE_TTY')) & 1): _helpers.write_random(sys.stdout.fileno(), total, opt.seed, opt.verbose and 1 or 0) else: log('error: not writing binary data to a terminal. Use -f to force.\n') sys.exit(1)