]> arthur.barton.de Git - bup.git/blob - cmd-server.py
Refactored client stuff into client.py; now cmd-save and cmd-init use it too.
[bup.git] / cmd-server.py
1 #!/usr/bin/env python2.5
2 import sys, struct, mmap
3 import options, git
4 from helpers import *
5
6
7 def init_dir(conn, arg):
8     git.init_repo(arg)
9     log('bup server: bupdir initialized: %r\n' % git.repodir)
10     conn.ok()
11
12
13 def set_dir(conn, arg):
14     git.check_repo_or_die(arg)
15     log('bup server: bupdir is %r\n' % git.repodir)
16     conn.ok()
17
18     
19 def list_indexes(conn, junk):
20     git.check_repo_or_die()
21     for f in os.listdir(git.repo('objects/pack')):
22         if f.endswith('.idx'):
23             conn.write('%s\n' % f)
24     conn.ok()
25
26
27 def send_index(conn, name):
28     git.check_repo_or_die()
29     assert(name.find('/') < 0)
30     assert(name.endswith('.idx'))
31     idx = git.PackIndex(git.repo('objects/pack/%s' % name))
32     conn.write(struct.pack('!I', len(idx.map)))
33     conn.write(idx.map)
34     conn.ok()
35     
36             
37 def receive_objects(conn, junk):
38     git.check_repo_or_die()
39     w = git.PackWriter()
40     while 1:
41         ns = conn.read(4)
42         if not ns:
43             w.abort()
44             raise Exception('object read: expected length header, got EOF\n')
45         n = struct.unpack('!I', ns)[0]
46         #log('expecting %d bytes\n' % n)
47         if not n:
48             log('bup server: received %d object%s.\n' 
49                 % (w.count, w.count!=1 and "s" or ''))
50             w.close()
51             return
52         buf = conn.read(n)  # object sizes in bup are reasonably small
53         #log('read %d bytes\n' % n)
54         if len(buf) < n:
55             w.abort()
56             raise Exception('object read: expected %d bytes, got %d\n'
57                             % (n, len(buf)))
58         w._raw_write(buf)
59     w.close()
60     conn.ok()
61
62
63 optspec = """
64 bup server
65 """
66 o = options.Options('bup server', optspec)
67 (opt, flags, extra) = o.parse(sys.argv[1:])
68
69 if extra:
70     log('bup server: no arguments expected\n')
71     o.usage()
72
73 log('bup server: reading from stdin.\n')
74
75 commands = {
76     'init-dir': init_dir,
77     'set-dir': set_dir,
78     'list-indexes': list_indexes,
79     'send-index': send_index,
80     'receive-objects': receive_objects,
81 }
82
83 # FIXME: this protocol is totally lame and not at all future-proof.
84 # (Especially since we abort completely as soon as *anything* bad happens)
85 conn = Conn(sys.stdin, sys.stdout)
86 lr = linereader(conn)
87 for _line in lr:
88     line = _line.strip()
89     if not line:
90         continue
91     log('bup server: command: %r\n' % line)
92     words = line.split(' ', 1)
93     cmd = words[0]
94     rest = len(words)>1 and words[1] or ''
95     if cmd == 'quit':
96         break
97     else:
98         cmd = commands.get(cmd)
99         if cmd:
100             cmd(conn, rest)
101         else:
102             raise Exception('unknown server command: %r\n' % line)
103
104 log('bup server: done\n')