'Receive files or directory trees from the server.
The semantics of src_pattern and dst_path are similar to those of scp.
For example, the following are OK:
src_pattern=\'C:\foo.txt\', dst_path=\'/tmp\'
(downloads a single file)
src_pattern=\'C:\Windows\', dst_path=\'/tmp\'
(downloads a directory tree recursively)
src_pattern=\'C:\Windows\*\', dst_path=\'/tmp\'
(downloads all files and directory trees under C:\Windows)
The following is not OK:
src_pattern=\'C:\Windows\', dst_path=\'/tmp/*\'
(wildcards are only allowed in src_pattern)
:param src_pattern: A path or wildcard pattern specifying the files or
directories, in the server\'s filesystem, that will be sent to
the client
:param dst_path: A path in the local filesystem where the files will
be saved
:param timeout: Time duration in seconds to wait for the transfer to
complete
:raise FileTransferTimeoutError: Raised if timeout expires
:raise FileTransferServerError: Raised if something goes wrong and the
server sends an informative error message to the client
:note: Other exceptions can be raised.'

def download(self, src_pattern, dst_path, timeout=600):

    dst_path = os.path.abspath(dst_path)
    end_time = (time.time() + timeout)
    file_count = 0
    dir_count = 0
    try:
        try:
            self._send_msg(RSS_SET_PATH)
            self._send_packet(src_pattern)
        except FileTransferError:
            self._handle_transfer_error()
        while True:
            msg = self._receive_msg()
            if (msg == RSS_CREATE_FILE):
                filename = self._receive_packet()
                if os.path.isdir(dst_path):
                    dst_path = os.path.join(dst_path, filename)
                self._receive_file_chunks(dst_path, (end_time - time.time()))
                dst_path = os.path.dirname(dst_path)
                file_count += 1
            elif (msg == RSS_CREATE_DIR):
                dirname = self._receive_packet()
                if os.path.isdir(dst_path):
                    dst_path = os.path.join(dst_path, dirname)
                if (not os.path.isdir(dst_path)):
                    os.mkdir(dst_path)
                dir_count += 1
            elif (msg == RSS_LEAVE_DIR):
                dst_path = os.path.dirname(dst_path)
            elif (msg == RSS_DONE):
                if ((not file_count) and (not dir_count)):
                    raise FileTransferNotFoundError(('Pattern    %s    does    not    match    any    files    or    directories    that    could    be    downloaded' % src_pattern))
                break
            elif (msg == RSS_ERROR):
                errmsg = self._receive_packet()
                raise FileTransferServerError(errmsg)
            else:
                raise FileTransferProtocolError('Received    unexpected    msg')
    except Exception:
        self.close()
        raise
