6

I am attempting to use python to connect to a server and upload some files from my local directory to /var/www/html but every time I try to do this I get this error:

Error: ftplib.error_perm: 553 Could not create file.

I have already did a chown and a chmod -R 777 to the path. I am using vsftpd and already set write enabled. Does anyone have any ideas?

Code:

ftp = FTP('ipaddress')
ftp.login(user='user', passwd = 'user')
ftp.cwd('/var/www/html')
for root, dirs, files in os.walk(path):
    for fname in files:
        full_fname = os.path.join(root, fname)
        ftp.storbinary('STOR' + fname, open(full_fname, 'rb'))
user3702643
  • 1,465
  • 5
  • 21
  • 48

3 Answers3

6

I had a similar problem also getting the error 553: Could not create file. What (update: partially) solved it for me was changing this line from:

ftp.storbinary('STOR' + fname, open(full_fname, 'rb'))

to:

ftp.storbinary('STOR ' + '/' + fname, open(full_fname, 'rb'))

Notice that there is a space just after the 'STOR ' and I added a forward slash ('/') just before the filename to indicate that i'd like the file stored in the FTP root directory

UPDATE: [2016-06-03] Actually this only solved part of the problem. I realized later that it was a permissions problem. The FTP root directory allowed writing by the FTP user but i had manually created folders within this directory using another user thus the new directories did not allow the FTP user to write to these directories.

Possible solutions:

  1. Change the permissions on the directories such that the FTP user is the owner of these directories, or is at least able to read and write to them.
  2. Create the directories using the ftp.mkd(dir_name) function, then change directory using the ftp.cwd(dir_name) function and then use the appropriate STOR function (storlines or storbinary) to write the file to the current directory.

    • As far as my understanding goes, the STOR command seems to only take a filename as a parameter (not a file path), that's why you need to make sure you are in the correct 'working directory' before using the STOR function (Remember the space after the STOR command)

      ftp.storbinary('STOR ' + fname, open(full_fname, 'rb'))

Irvin H.
  • 602
  • 1
  • 10
  • 17
  • i found the doing a `ftp.cwd('/path/to/files/')` before attempting the file download helped solve my problem with i was getting this 553 error on `ftp.retrbinary` – beep_check Mar 03 '21 at 19:24
0

Does path == '/var/www/html'? That's a local path. You need an FTP path.

The local path /var/www/html is not generally accessible by FTP. When you connect to the FTP server, the file system presented to you begins at, often, your user's home directory /home/user.

Since it sounds like you're running the ftp server (vsftpd) on the remote machine, the simplest solution might be something like:

user@server:~$ ln -s /var/www/html /home/user/html

Then you could call ftp.cwd('html'), and ftp.nlst() to get the remote directory listing, and navigate it from there.

Also, don't forget to put a space character in the 'STOR' string (should be 'STOR ').

Best of luck!

Andy Kubiak
  • 169
  • 6
  • Sorry I left out a line there. I do a "ftp.cwd('/var/www/html')" once im logged into the server and also a ftp.nlst() so i know im in the correct path. I shall try out the ln -s and see if it works. Thanks! – user3702643 Jul 24 '15 at 14:58
0

I'm sure at this point you have found a solution, but I just stumbled across this thread while I was looking for a solution. I ended up using the following:

# Handles FTP transfer to server
def upload(ftp, dir, file):
    # Test if directory exists. If not, create it
    if dir.split('/')[-1] not in ftp.nlst('/'.join(dir.split('/')[:-1])):
        print("Creating directory: " + dir)
        ftp.mkd(dir)
    # Check if file extension is text format
    ext = path.splitext(file)[1]
    if ext.lower() in (".txt", ".htm", ".html"):
        ftp.storlines("STOR " + dir + '/' + file, open(dir + '/' + file, "rb"))
    else:
        ftp.storbinary("STOR " + dir + '/' + file, open(dir + '/' + file, "rb"), 1024)
KDumont
  • 66
  • 6