0

I am running an FTP server with python 3.X on a windows 10 computer. I have a script where I can upload a whole directory into my server. This works with no issue. However when I try to download the respective folder/files I am given the error ftplib.error_perm: 550 Permission denied. I have checked that the current working directory (CWD) is correct and that the files do exist on the server. What could the issue be? Here are my server.py, download.py, and uploader.py scripts:

Server.py

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer


# The port the FTP ServerFiles will listen on.
# This must be greater than 1023 unless you run this script as root.
FTP_PORT = 2121
# The directory the FTP user will have full read/write access to.
FTP_DIRECTORY = "ServerFiles"


def main():
    authorizer = DummyAuthorizer()

    # Define a new user having full r/w permissions.
    authorizer.add_user('MirOS-Client', 'client@miros', FTP_DIRECTORY, perm='elradfmw')
    authorizer.add_user('MirOS-Admin', 'admin@miros$358', FTP_DIRECTORY, perm='elradfmw')

    handler = FTPHandler
    handler.authorizer = authorizer

    # Define a customized banner (string returned when client connects)
    handler.banner = "Connection secured to MirOS-Server."

    address = ('IPADDRESS', FTP_PORT)
    server = FTPServer(address, handler)

    server.max_cons = 256
    server.max_cons_per_ip = 5

    server.serve_forever()


if __name__ == '__main__':
    main()

Downloader.py

import ftplib

FTP_HOST = "IPADDRESS"
FTP_USER = "MirOS-Client"
FTP_PASS = "client@miros"

# Connecting to ServerFiles and logging in
ftp = ftplib.FTP()
ftp.connect(FTP_HOST, 2121)
ftp.login(FTP_USER,FTP_PASS)

# force UTF-8 encoding
ftp.encoding = "utf-8"
# the name of file you want to download from the FTP ServerFiles
print(ftplib.FTP.dir(ftp))
filename = "folder"
with open(filename, "wb") as file:
    # use FTP's RETR command to download the file
    ftp.retrbinary(f"RETR {filename}", file.write)


# quit and close the connection
ftp.quit()

Uploader.py

import ftplib
import os

# FTP ServerFiles credentials
FTP_HOST = "IPADDRESS"
FTP_USER = "MirOS-Admin"
FTP_PASS = "admin@miros$358"


def upload_dir(ftp, path):
    for name in os.listdir(path):
        local_path = os.path.join(path, name)
        if os.path.isfile(local_path):
            print(f"  uploading file {name} ...", end="")
            with open(local_path, 'rb') as file:
                ftp.storbinary(f'STOR {name}', file)
            print(" done.")
        elif os.path.isdir(local_path):
            print(f"making directory {name} ...", end="")
            try:
                ftp.mkd(name)
            except:
                print(" already exists.", end="")
            print(" navigating into ...", end="")
            ftp.cwd(name)
            print(" done.")
            upload_dir(ftp, local_path)
            print(f" navigating up ...", end="")
            ftp.cwd('..')
            print(" done.")


ftp = ftplib.FTP()
ftp.connect(FTP_HOST, 2121)
ftp.login(FTP_USER, FTP_PASS)

upload_dir(ftp, 'updatefiles')  # your local directory path

ftp.quit()

Any ideas??

Vulturu
  • 3
  • 3
  • From the wording of your question ("when I try to download the respective *folder*") and your code (`filename = "folder"`), it looks like you assume that `ftp.retrbinary` can download a *folder*. It cannot. It can download a file only (the same way the `ftp.storbinary` can upload a file only and your needed to take care of the directories in the `Uploader.py` yourself). See [Downloading a directory tree with ftplib](https://stackoverflow.com/q/2605119/850848). – Martin Prikryl Jun 29 '23 at 04:50

0 Answers0