3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
8 from __future__ import absolute_import
9 from subprocess import PIPE
10 import sys, os, struct, getopt, subprocess, signal
12 from bup import options, ssh, path
13 from bup.compat import argv_bytes
14 from bup.helpers import DemuxConn, log
15 from bup.io import byte_stream
19 bup on <hostname> index ...
20 bup on <hostname> save ...
21 bup on <hostname> split ...
22 bup on <hostname> get ...
24 o = options.Options(optspec, optfunc=getopt.getopt)
25 (opt, flags, extra) = o.parse(sys.argv[1:])
27 o.fatal('arguments expected')
29 class SigException(Exception):
30 def __init__(self, signum):
32 Exception.__init__(self, 'signal %d received' % signum)
33 def handler(signum, frame):
34 raise SigException(signum)
36 signal.signal(signal.SIGTERM, handler)
37 signal.signal(signal.SIGINT, handler)
40 out = byte_stream(sys.stdout)
47 hp = argv_bytes(extra[0]).split(b':')
49 (hostname, port) = (hp[0], None)
52 argv = [argv_bytes(x) for x in extra[1:]]
53 p = ssh.connect(hostname, port, b'on--server', stderr=PIPE)
56 argvs = b'\0'.join([b'bup'] + argv)
57 p.stdin.write(struct.pack('!I', len(argvs)) + argvs)
59 sp = subprocess.Popen([path.exe(), b'server'],
60 stdin=p.stdout, stdout=p.stdin)
63 # Demultiplex remote client's stderr (back to stdout/stderr).
64 dmc = DemuxConn(p.stderr.fileno(), open(os.devnull, "wb"))
65 for line in iter(dmc.readline, b''):
69 # if we get a signal while waiting, we have to keep waiting, just
70 # in case our child doesn't die.
76 except SigException as e:
77 log('\nbup on: %s\n' % e)
78 os.kill(p.pid, e.signum)
80 except SigException as e:
83 log('\nbup on: %s\n' % e)