6 # This software may be used and distributed according to the terms of the |
6 # This software may be used and distributed according to the terms of the |
7 # GNU General Public License version 2 or any later version. |
7 # GNU General Public License version 2 or any later version. |
8 |
8 |
9 from i18n import _ |
9 from i18n import _ |
10 from node import bin, hex |
10 from node import bin, hex |
11 import streamclone, util, hook, pushkey |
11 import streamclone, util, hook, pushkey, wireproto |
12 import os, sys, tempfile, urllib, copy |
12 import os, sys, tempfile, urllib, copy |
13 |
13 |
14 class sshserver(object): |
14 class sshserver(object): |
15 |
15 |
16 caps = 'unbundle lookup changegroupsubset branchmap pushkey'.split() |
16 caps = 'unbundle lookup changegroupsubset branchmap pushkey'.split() |
67 self.lock.release() |
67 self.lock.release() |
68 sys.exit(0) |
68 sys.exit(0) |
69 |
69 |
70 def serve_one(self): |
70 def serve_one(self): |
71 cmd = self.fin.readline()[:-1] |
71 cmd = self.fin.readline()[:-1] |
72 if cmd: |
72 if cmd and not wireproto.dispatch(self.repo, self, cmd): |
73 impl = getattr(self, 'do_' + cmd, None) |
73 impl = getattr(self, 'do_' + cmd, None) |
74 if impl: |
74 if impl: |
75 r = impl() |
75 r = impl() |
76 if r is not None: |
76 if r is not None: |
77 self.respond(r) |
77 self.respond(r) |
78 else: self.respond("") |
78 else: self.respond("") |
79 return cmd != '' |
79 return cmd != '' |
80 |
80 |
81 def do_lookup(self): |
|
82 key = self.getarg('key') |
|
83 try: |
|
84 r = hex(self.repo.lookup(key)) |
|
85 success = 1 |
|
86 except Exception, inst: |
|
87 r = str(inst) |
|
88 success = 0 |
|
89 return "%s %s\n" % (success, r) |
|
90 |
|
91 def do_branchmap(self): |
|
92 branchmap = self.repo.branchmap() |
|
93 heads = [] |
|
94 for branch, nodes in branchmap.iteritems(): |
|
95 branchname = urllib.quote(branch) |
|
96 branchnodes = [hex(node) for node in nodes] |
|
97 heads.append('%s %s' % (branchname, ' '.join(branchnodes))) |
|
98 return '\n'.join(heads) |
|
99 |
|
100 def do_heads(self): |
|
101 h = self.repo.heads() |
|
102 return " ".join(map(hex, h)) + "\n" |
|
103 |
|
104 def do_hello(self): |
81 def do_hello(self): |
105 '''the hello command returns a set of lines describing various |
82 '''the hello command returns a set of lines describing various |
106 interesting things about the server, in an RFC822-like format. |
83 interesting things about the server, in an RFC822-like format. |
107 Currently the only one defined is "capabilities", which |
84 Currently the only one defined is "capabilities", which |
108 consists of a line in the form: |
85 consists of a line in the form: |
125 |
102 |
126 if self.lock: |
103 if self.lock: |
127 self.lock.release() |
104 self.lock.release() |
128 self.lock = None |
105 self.lock = None |
129 return "" |
106 return "" |
130 |
|
131 def do_branches(self): |
|
132 nodes = self.getarg('nodes') |
|
133 nodes = map(bin, nodes.split(" ")) |
|
134 r = [] |
|
135 for b in self.repo.branches(nodes): |
|
136 r.append(" ".join(map(hex, b)) + "\n") |
|
137 return "".join(r) |
|
138 |
|
139 def do_between(self): |
|
140 pairs = self.getarg('pairs') |
|
141 pairs = [map(bin, p.split("-")) for p in pairs.split(" ")] |
|
142 r = [] |
|
143 for b in self.repo.between(pairs): |
|
144 r.append(" ".join(map(hex, b)) + "\n") |
|
145 return "".join(r) |
|
146 |
107 |
147 def do_changegroup(self): |
108 def do_changegroup(self): |
148 nodes = [] |
109 nodes = [] |
149 roots = self.getarg('roots') |
110 roots = self.getarg('roots') |
150 nodes = map(bin, roots.split(" ")) |
111 nodes = map(bin, roots.split(" ")) |
242 self.fout.write(chunk) |
203 self.fout.write(chunk) |
243 self.fout.flush() |
204 self.fout.flush() |
244 except streamclone.StreamException, inst: |
205 except streamclone.StreamException, inst: |
245 self.fout.write(str(inst)) |
206 self.fout.write(str(inst)) |
246 self.fout.flush() |
207 self.fout.flush() |
247 |
|
248 def do_pushkey(self): |
|
249 namespace, key, old, new = self.getargs('namespace key old new') |
|
250 r = pushkey.push(self.repo, namespace, key, old, new) |
|
251 return '%s\n' % int(r) |
|
252 |
|
253 def do_listkeys(self): |
|
254 namespace = self.getarg('namespace') |
|
255 d = pushkey.list(self.repo, namespace).items() |
|
256 t = '\n'.join(['%s\t%s' % (k.encode('string-escape'), |
|
257 v.encode('string-escape')) for k, v in d]) |
|
258 return t |
|