[PATCH 1 of 1] sshserver: add varargs capability
Sune Foldager
cryo at cyanite.org
Tue Feb 9 05:37:24 CST 2010
# HG changeset patch
# User Sune Foldager <cryo at cyanite.org>
# Date 1265715038 -3600
# Node ID 858b863d83543293e210468ec3e967985dd8c4c6
# Parent d216fa04e48a2aeeae138b8d4995ff25fbd771c2
sshserver: add varargs capability
The SSH wire protocol is fairly rigid, and allows only a fixed number of
arguments for its commands. This capability signals that commands in the form
command#argc are accepted, where argc is a non-negative integer (represented as
a decimal number) denoting the number of arguments the command has.
Future extensions to wire commands can use this to determine if certain
optional arguments were sent. Existing commands will work as before regardless
of the new command format being used or not.
diff --git a/mercurial/sshrepo.py b/mercurial/sshrepo.py
--- a/mercurial/sshrepo.py
+++ b/mercurial/sshrepo.py
@@ -23,6 +23,7 @@
class sshrepository(repo.repository):
def __init__(self, ui, path, create=0):
self._url = path
+ self._varargs = False
self.ui = ui
m = re.match(r'^ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?$', path)
@@ -86,6 +87,7 @@
if l.startswith("capabilities:"):
self.capabilities.update(l[:-1].split(":")[1].split())
break
+ self._varargs = 'varargs' in self.capabilities
def readerr(self):
while 1:
@@ -116,6 +118,8 @@
def do_cmd(self, cmd, **args):
self.ui.debug("sending %s command\n" % cmd)
+ if self._varargs:
+ cmd = '%s#%d' % (cmd, len(args))
self.pipeo.write("%s\n" % cmd)
for k, v in args.iteritems():
self.pipeo.write("%s %d\n" % (k, len(v)))
diff --git a/mercurial/sshserver.py b/mercurial/sshserver.py
--- a/mercurial/sshserver.py
+++ b/mercurial/sshserver.py
@@ -13,12 +13,13 @@
class sshserver(object):
- caps = 'unbundle lookup changegroupsubset branchmap'.split()
+ caps = 'unbundle lookup changegroupsubset branchmap varargs'.split()
def __init__(self, ui, repo):
self.ui = ui
self.repo = repo
self.lock = None
+ self.argv = None
self.fin = sys.stdin
self.fout = sys.stdout
@@ -30,6 +31,8 @@
util.set_binary(self.fout)
def getarg(self):
+ if self.argv:
+ return self.argv.popitem()
argline = self.fin.readline()[:-1]
arg, l = argline.split()
val = self.fin.read(int(l))
@@ -52,6 +55,11 @@
def serve_one(self):
cmd = self.fin.readline()[:-1]
if cmd:
+ self.argv = None
+ cmdargc = cmd.split('#', 1)
+ if len(cmdargc) == 2:
+ cmd, argc = cmdargc
+ self.argv = dict(self.getarg() for i in xrange(int(argc)))
impl = getattr(self, 'do_' + cmd, None)
if impl:
impl()
More information about the Mercurial-devel
mailing list