]> arthur.barton.de Git - bup.git/blob - cmd/on-cmd.py
f76ad3e1e06a71fd07de06db586f1827d92d1a97
[bup.git] / cmd / on-cmd.py
1 #!/bin/sh
2 """": # -*-python-*-
3 bup_python="$(dirname "$0")/bup-python" || exit $?
4 exec "$bup_python" "$0" ${1+"$@"}
5 """
6 # end of bup preamble
7 import sys, os, struct, getopt, subprocess, signal
8 from subprocess import PIPE
9 from bup import options, ssh, path
10 from bup.helpers import *
11
12 optspec = """
13 bup on <hostname> index ...
14 bup on <hostname> save ...
15 bup on <hostname> split ...
16 """
17 o = options.Options(optspec, optfunc=getopt.getopt)
18 (opt, flags, extra) = o.parse(sys.argv[1:])
19 if len(extra) < 2:
20     o.fatal('arguments expected')
21
22 class SigException(Exception):
23     def __init__(self, signum):
24         self.signum = signum
25         Exception.__init__(self, 'signal %d received' % signum)
26 def handler(signum, frame):
27     raise SigException(signum)
28
29 signal.signal(signal.SIGTERM, handler)
30 signal.signal(signal.SIGINT, handler)
31
32 try:
33     sp = None
34     p = None
35     ret = 99
36
37     hp = extra[0].split(':')
38     if len(hp) == 1:
39         (hostname, port) = (hp[0], None)
40     else:
41         (hostname, port) = hp
42     argv = extra[1:]
43     p = ssh.connect(hostname, port, 'on--server', stderr=PIPE)
44
45     try:
46         argvs = '\0'.join(['bup'] + argv)
47         p.stdin.write(struct.pack('!I', len(argvs)) + argvs)
48         p.stdin.flush()
49         sp = subprocess.Popen([path.exe(), 'server'],
50                               stdin=p.stdout, stdout=p.stdin)
51         p.stdin.close()
52         p.stdout.close()
53         # Demultiplex remote client's stderr (back to stdout/stderr).
54         dmc = DemuxConn(p.stderr.fileno(), open(os.devnull, "w"))
55         for line in iter(dmc.readline, ""):
56             sys.stdout.write(line)
57     finally:
58         while 1:
59             # if we get a signal while waiting, we have to keep waiting, just
60             # in case our child doesn't die.
61             try:
62                 ret = p.wait()
63                 if sp:
64                     sp.wait()
65                 break
66             except SigException as e:
67                 log('\nbup on: %s\n' % e)
68                 os.kill(p.pid, e.signum)
69                 ret = 84
70 except SigException as e:
71     if ret == 0:
72         ret = 99
73     log('\nbup on: %s\n' % e)
74
75 sys.exit(ret)