66
65
register_urlparse_netloc_protocol('sftp')
70
# TODO: This should possibly ignore SIGHUP as well, but bzr currently
71
# doesn't handle it itself.
72
# <https://launchpad.net/products/bzr/+bug/41433/+index>
74
signal.signal(signal.SIGINT, signal.SIG_IGN)
77
68
def os_specific_subprocess_params():
78
69
"""Get O/S specific subprocess parameters."""
79
70
if sys.platform == 'win32':
84
# We close fds other than the pipes as the child process does not need
87
# We also set the child process to ignore SIGINT. Normally the signal
88
# would be sent to every process in the foreground process group, but
89
# this causes it to be seen only by bzr and not by ssh. Python will
90
# generate a KeyboardInterrupt in bzr, and we will then have a chance
91
# to release locks or do other cleanup over ssh before the connection
93
# <https://launchpad.net/products/bzr/+bug/5987>
95
# Running it in a separate process group is not good because then it
96
# can't get non-echoed input of a password or passphrase.
97
# <https://launchpad.net/products/bzr/+bug/40508>
98
return {'preexec_fn': _ignore_sigint,
75
# we close fds as the child process does not need them to be open.
76
# we set the process group so that signals from the keyboard like
77
# 'SIGINT' - KeyboardInterrupt - are not recieved in the child procecss
78
# if we do not do this, then the sftp/ssh subprocesses will terminate
79
# when a user hits CTRL-C, and we are unable to use them to unlock the
80
# remote branch/repository etc.
81
return {'preexec_fn': os.setpgrp,
663
646
return urlparse.urlunparse(('sftp', netloc, path, '', '', ''))
665
648
def _split_url(self, url):
666
(scheme, username, password, host, port, path) = split_url(url)
649
if isinstance(url, unicode):
650
url = url.encode('utf-8')
651
(scheme, netloc, path, params,
652
query, fragment) = urlparse.urlparse(url, allow_fragments=False)
667
653
assert scheme == 'sftp'
654
username = password = host = port = None
656
username, host = netloc.split('@', 1)
658
username, password = username.split(':', 1)
659
password = urllib.unquote(password)
660
username = urllib.unquote(username)
665
host, port = host.rsplit(':', 1)
669
# TODO: Should this be ConnectionError?
670
raise TransportError('%s: invalid port number' % port)
671
host = urllib.unquote(host)
673
path = urllib.unquote(path)
669
675
# the initial slash should be removed from the path, and treated
670
676
# as a homedir relative path (the path begins with a double slash
998
1004
def get_hexdump(self):
1003
1007
server = paramiko.SFTPServer(FakeChannel(), 'sftp', StubServer(self), StubSFTPServer,
1004
1008
root=self._root, home=self._server_homedir)