~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transport/sftp.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-04-22 07:28:09 UTC
  • mfrom: (1551.2.56 win32fixes)
  • Revision ID: pqm@pqm.ubuntu.com-20060422072809-b06e742274a4e9f4
Misc fixes for win32

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
from bzrlib.transport import (
45
45
    register_urlparse_netloc_protocol,
46
46
    Server,
47
 
    split_url,
48
47
    Transport,
49
48
    urlescape,
50
49
    )
66
65
register_urlparse_netloc_protocol('sftp')
67
66
 
68
67
 
69
 
def _ignore_sigint():
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>
73
 
    import signal
74
 
    signal.signal(signal.SIGINT, signal.SIG_IGN)
75
 
    
76
 
 
77
68
def os_specific_subprocess_params():
78
69
    """Get O/S specific subprocess parameters."""
79
70
    if sys.platform == 'win32':
81
72
        # win32
82
73
        return {}
83
74
    else:
84
 
        # We close fds other than the pipes as the child process does not need 
85
 
        # them to be open.
86
 
        #
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
92
 
        # goes away.  
93
 
        # <https://launchpad.net/products/bzr/+bug/5987>
94
 
        #
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,
99
82
                'close_fds': True,
100
83
                }
101
84
 
663
646
        return urlparse.urlunparse(('sftp', netloc, path, '', '', ''))
664
647
 
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
 
655
        if '@' in netloc:
 
656
            username, host = netloc.split('@', 1)
 
657
            if ':' in username:
 
658
                username, password = username.split(':', 1)
 
659
                password = urllib.unquote(password)
 
660
            username = urllib.unquote(username)
 
661
        else:
 
662
            host = netloc
 
663
 
 
664
        if ':' in host:
 
665
            host, port = host.rsplit(':', 1)
 
666
            try:
 
667
                port = int(port)
 
668
            except ValueError:
 
669
                # TODO: Should this be ConnectionError?
 
670
                raise TransportError('%s: invalid port number' % port)
 
671
        host = urllib.unquote(host)
 
672
 
 
673
        path = urllib.unquote(path)
668
674
 
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
997
1003
                return '1'
998
1004
            def get_hexdump(self):
999
1005
                return False
1000
 
            def close(self):
1001
 
                pass
1002
1006
 
1003
1007
        server = paramiko.SFTPServer(FakeChannel(), 'sftp', StubServer(self), StubSFTPServer,
1004
1008
                                     root=self._root, home=self._server_homedir)