]> arthur.barton.de Git - bup.git/blob - cmd/on--server-cmd.py
Makefile: fix test pattern to include t/test.sh
[bup.git] / cmd / on--server-cmd.py
1 #!/usr/bin/env python
2 import sys, os, struct
3 from bup import options, helpers
4
5 optspec = """
6 bup on--server
7 --
8     This command is run automatically by 'bup on'
9 """
10 o = options.Options(optspec)
11 (opt, flags, extra) = o.parse(sys.argv[1:])
12 if extra:
13     o.fatal('no arguments expected')
14
15 # get the subcommand's argv.
16 # Normally we could just pass this on the command line, but since we'll often
17 # be getting called on the other end of an ssh pipe, which tends to mangle
18 # argv (by sending it via the shell), this way is much safer.
19 buf = sys.stdin.read(4)
20 sz = struct.unpack('!I', buf)[0]
21 assert(sz > 0)
22 assert(sz < 1000000)
23 buf = sys.stdin.read(sz)
24 assert(len(buf) == sz)
25 argv = buf.split('\0')
26 argv = [argv[0], 'mux', '--'] + argv
27
28 # stdin/stdout are supposedly connected to 'bup server' that the caller
29 # started for us (often on the other end of an ssh tunnel), so we don't want
30 # to misuse them.  Move them out of the way, then replace stdout with
31 # a pointer to stderr in case our subcommand wants to do something with it.
32 #
33 # It might be nice to do the same with stdin, but my experiments showed that
34 # ssh seems to make its child's stderr a readable-but-never-reads-anything
35 # socket.  They really should have used shutdown(SHUT_WR) on the other end
36 # of it, but probably didn't.  Anyway, it's too messy, so let's just make sure
37 # anyone reading from stdin is disappointed.
38 #
39 # (You can't just leave stdin/stdout "not open" by closing the file
40 # descriptors.  Then the next file that opens is automatically assigned 0 or 1,
41 # and people *trying* to read/write stdin/stdout get screwed.)
42 os.dup2(0, 3)
43 os.dup2(1, 4)
44 os.dup2(2, 1)
45 fd = os.open('/dev/null', os.O_RDONLY)
46 os.dup2(fd, 0)
47 os.close(fd)
48
49 os.environ['BUP_SERVER_REVERSE'] = helpers.hostname()
50 os.execvp(argv[0], argv)
51 sys.exit(99)