예제 #1
0
 def do_LIST(self, path):
     try:
         _path = self.ftp_path(path)
         with self.config.vfs.check_access(path=_path,
                                           user=self._uid,
                                           perms="r"):
             listing = self.config.vfs.listdir(_path)
             if isinstance(listing, list):
                 # RFC 959 recommends the listing to be sorted.
                 listing.sort()
                 iterator = self.config.vfs.format_list(_path, listing)
                 self.respond("150 Here comes the directory listing.")
                 _list_data = get_data_from_iter(iterator)
                 # Push data to the data channel
                 self.push_data(_list_data.encode())
                 # start the command channel
                 self.start_data_channel()
                 self.respond(b"226 Directory send OK.")
     except FSOperationNotPermitted:
         self.respond(b"500 Operation not permitted.")
     except (
             OSError,
             fs.errors.FSError,
             FilesystemError,
             FTPPrivilegeException,
     ) as err:
         self._log_err(err)
         self.respond(b"550 LIST command failed.")
예제 #2
0
    def do_STAT(self, path):
        """If invoked without parameters, returns general status information about the FTP server process.
        If a parameter is given, acts like the LIST command, except that data is sent over the command
        channel (no PORT or PASV command is required).
        """
        # return STATus information about ftp data connection
        if not path:
            s = list()
            s.append('Connected to: {}:{}'.format(self.host, self.port))
            if self.authenticated:
                s.append('Logged in as: {}'.format(self.username))
            else:
                if not self.username:
                    s.append("Waiting for username.")
                else:
                    s.append("Waiting for password.")
            if self._current_type == 'a':
                _type = 'ASCII'
            else:
                _type = 'Binary'
            s.append("TYPE: {}; STRUcture: File; MODE: Stream".format(_type))
            if self._data_sock is not None and self._data_channel is False:
                s.append('Passive data channel waiting for connection.')
            elif self._data_channel is True:
                bytes_sent = self.metrics.data_channel_bytes_send + self.metrics.command_chanel_bytes_send
                bytes_recv = self.metrics.command_chanel_bytes_recv + self.metrics.data_channel_bytes_recv
                elapsed_time = self.metrics.get_elapsed_time()
                s.append('Data connection open:')
                s.append('Total bytes sent: {}'.format(bytes_sent))
                s.append('Total bytes received: {}'.format(bytes_recv))
                s.append('Transfer elapsed time: {} secs'.format(elapsed_time))
            else:
                s.append('Data connection closed.')

            self.respond('211-FTP server status:\r\n')
            self.respond(''.join([' {}\r\n'.format(item) for item in s]))
            self.respond('211 End of status.')
        # return directory LISTing over the command channel
        else:
            try:
                line = self.ftp_path(path)
                with self.config.vfs.check_access(path=line, user=self._uid, perms='r'):
                    if self.config.vfs.isdir(path):
                        listing = self.config.vfs.listdir(path)
                        # RFC 959 recommends the listing to be sorted.
                        listing.sort()
                        iterator = self.config.vfs.format_list(path, listing)
                    else:
                        basedir, filename = os.path.split(path)
                        self.config.stat(path)
                        iterator = self.config.vfs.format_list(basedir, [filename])
                    _status = '213-Status of "{}":\r\n'.format(line)
                    _status += get_data_from_iter(iterator)
                    _status += '213 End of status.'
                    self.respond(_status.encode())
            except FSOperationNotPermitted:
                self.respond(b'500 Operation not permitted.')
            except (OSError, FilesystemError, AssertionError, fs.errors.FSError, FTPPrivilegeException):
                self.respond(b'550 STAT command failed.')
예제 #3
0
 def do_LIST(self, path):
     try:
         _path = self.ftp_path(path)
         with self.config.vfs.check_access(path=_path, user=self._uid, perms='r'):
             listing = self.config.vfs.listdir(_path)
             if isinstance(listing, list):
                 # RFC 959 recommends the listing to be sorted.
                 listing.sort()
                 iterator = self.config.vfs.format_list(_path, listing)
                 self.respond('150 Here comes the directory listing.')
                 _list_data = get_data_from_iter(iterator)
                 # Push data to the data channel
                 self.push_data(_list_data.encode())
                 # start the command channel
                 self.start_data_channel()
                 self.respond(b'226 Directory send OK.')
     except FSOperationNotPermitted:
         self.respond(b'500 Operation not permitted.')
     except (OSError, fs.errors.FSError, FilesystemError, FTPPrivilegeException) as err:
         self._log_err(err)
         self.respond(b'550 LIST command failed.')
예제 #4
0
    def do_STAT(self, path):
        """If invoked without parameters, returns general status information about the FTP server process.
        If a parameter is given, acts like the LIST command, except that data is sent over the command
        channel (no PORT or PASV command is required).
        """
        # return STATus information about ftp data connection
        if not path:
            s = list()
            s.append("Connected to: {}:{}".format(self.host, self.port))
            if self.authenticated:
                s.append("Logged in as: {}".format(self.username))
            else:
                if not self.username:
                    s.append("Waiting for username.")
                else:
                    s.append("Waiting for password.")
            if self._current_type == "a":
                _type = "ASCII"
            else:
                _type = "Binary"
            s.append("TYPE: {}; STRUcture: File; MODE: Stream".format(_type))
            if self._data_sock is not None and self._data_channel is False:
                s.append("Passive data channel waiting for connection.")
            elif self._data_channel is True:
                bytes_sent = (self.metrics.data_channel_bytes_send +
                              self.metrics.command_chanel_bytes_send)
                bytes_recv = (self.metrics.command_chanel_bytes_recv +
                              self.metrics.data_channel_bytes_recv)
                elapsed_time = self.metrics.get_elapsed_time()
                s.append("Data connection open:")
                s.append("Total bytes sent: {}".format(bytes_sent))
                s.append("Total bytes received: {}".format(bytes_recv))
                s.append("Transfer elapsed time: {} secs".format(elapsed_time))
            else:
                s.append("Data connection closed.")

            self.respond("211-FTP server status:\r\n")
            self.respond("".join([" {}\r\n".format(item) for item in s]))
            self.respond("211 End of status.")
        # return directory LISTing over the command channel
        else:
            try:
                line = self.ftp_path(path)
                with self.config.vfs.check_access(path=line,
                                                  user=self._uid,
                                                  perms="r"):
                    if self.config.vfs.isdir(path):
                        listing = self.config.vfs.listdir(path)
                        # RFC 959 recommends the listing to be sorted.
                        listing.sort()
                        iterator = self.config.vfs.format_list(path, listing)
                    else:
                        basedir, filename = os.path.split(path)
                        self.config.stat(path)
                        iterator = self.config.vfs.format_list(
                            basedir, [filename])
                    _status = '213-Status of "{}":\r\n'.format(line)
                    _status += get_data_from_iter(iterator)
                    _status += "213 End of status."
                    self.respond(_status.encode())
            except FSOperationNotPermitted:
                self.respond(b"500 Operation not permitted.")
            except (
                    OSError,
                    FilesystemError,
                    AssertionError,
                    fs.errors.FSError,
                    FTPPrivilegeException,
            ):
                self.respond(b"550 STAT command failed.")