[ftputil] Ftputil seems broken with link

Stefan Schwarzer sschwarzer at sschwarzer.net
Sun Apr 26 10:23:52 CEST 2009


Hi Nicola,

thanks for your report.

On 2009-04-26 00:55, MailingList SVR wrote:
> ftputil seems unable to follow links, go for example to:
>
> ftp.heanet.ie with an anonymous user,
>
> >>> conn.path.islink('/pub/apache')
> True
> >>> conn.listdir('/pub/apache')
> ['/pub/apache']
>
> so listdir doesn't follow the link. Is there a workaround ?

I can't reproduce this with my local FTP test server:

>>> h = ftputil.FTPHost("localhost", 'ftptest', ...)
>>> h.path.islink("blah")
True
>>> h.listdir("blah")
['second dir', 'some file', 'some_file']

The server is PureFTPd version 1.0.21-11.2ubuntu1. This server
setup is used for all the tests in the file _test_real_ftp.py.
Here, I only added the link.

In your specific case, I can repeat the behavior, though.

Since ftputil just displays the directory contents it gets from
the server, I think the result has something to do with the
server. Let's examine the situation:

>>> h = ftputil.FTPHost("ftp.heanet.ie", "anonymous", "sschwarzer at sschwarzer.net")
>>> stat_result = h.lstat("/pub/apache")
>>> stat_result._st_name
'apache'
>>> stat_result._st_target
'./www.apache.org'

(_st_name and _st_target have a leading underscore because
"native" stat result objects don't have those attributes either.
When I introduced the "stat-ing", I wanted to keep ftputil as
similar as possible to Python's native file system interface, so
I didn't disclose the attributes. ftputil uses them internally,
though.)

If the link is resolved manually (the workaround you asked for),
this causes a traceback:

>>> stat_result = h.lstat("/pub/apache")
>>> h.path.join("/pub/apache", stat_result._st_target)
'/pub/apache/./www.apache.org'
>>> h.listdir(h.path.join("/pub/apache", stat_result._st_target))
Traceback (most recent call last):
  File "<ipython console>", line 1, in <module>
  File "ftputil.py", line 805, in listdir
    return self._stat.listdir(path)
  File "ftp_stat.py", line 565, in listdir
    return self.__call_with_parser_retry(self._real_listdir, path)
  File "ftp_stat.py", line 543, in __call_with_parser_retry
    result = method(*args, **kwargs)
  File "ftp_stat.py", line 406, in _real_listdir
    path)
PermanentError: 550 /pub/apache/www.apache.org: no such directory or wrong directory parser used
Debugging info: ftputil 2.4, Python 2.5.2 (linux2)

I guess the selected parser, hinted at in the message, is ok
because I can list the root directory on the server and can get
the stat result for /pub/apache.

So I assume the link on the server points to a non-existent or
otherwise invalid directory and the server upon the listdir call
decides to just return the path of the link.

> thanks

You're welcome. :-)

Best regards,
Stefan



More information about the ftputil mailing list