Opened 10 years ago

Closed 9 years ago

#35 closed defect (fixed)

Ftputil broken with some links

Reported by: ftputiluser Owned by: schwa
Priority: major Milestone: 2.4.2
Component: Library Version: 2.4
Keywords: listdir, link, ./ Cc:

Description (last modified by schwa)

Ftputil is broken with links that start with ./

An example is ftp.heanet.ie

>>> conn.path.islink('/pub/apache') 
True 
>>> conn.listdir('/pub/apache')
['/pub/apache']

/pub/apache is a link to ./www.apache.org

lrwxrwxrwx   1 ftp      ftp            16 Jul  1  2008 /pub/apache -> ./www.apache.org

The content is the following:

ftp> ls pub/apache/                                                                  
200 PORT command successful                                                          
150 Opening ASCII mode data connection for file list                                 
-rw-rw-r--   1 ftp      ftp          1069 Oct 10  2001 404.html                      
drwxrwxr-x   5 ftp      ftp           231 Dec 24  2006 ads                           
drwxrwxr-x   3 ftp      ftp          1459 Mar 20  2006 ca                            
drwxrwxr-x   9 ftp      ftp          1773 Dec 22  2006 dev                           
drwxrwxr-x  70 ftp      ftp          1806 Apr 28 18:19 dist                          
drwxrwxr-x   4 ftp      ftp           104 Dec 11  2006 dyn                           
drwxrwxr-x   3 ftp      ftp            48 Dec 11  2006 errors                        
-rw-rw-r--   1 ftp      ftp          3638 Feb 14  2005 favicon-a.ico                 
-rw-rw-r--   1 ftp      ftp          3638 Feb 13  2005 favicon-c.ico                 
-rw-rw-r--   1 ftp      ftp           766 Sep 24  2001 favicon-old.ico               
-rw-rw-r--   1 ftp      ftp          3638 Aug 19  2005 favicon.ico                   
drwxrwxr-x   8 ftp      ftp           971 Dec 21  2006 foundation
drwxrwxr-x   3 ftp      ftp           109 Dec 11  2006 history
drwxrwxr-x   3 ftp      ftp          1112 Jun 22  2006 images
drwxrwxr-x   3 ftp      ftp           935 Sep 24  2001 images-old
-rw-rw-r--   1 ftp      ftp         14489 Dec 21  2006 index.html
-rw-rw-r--   1 ftp      ftp         14633 Jul  9  2006 index.html.save
drwxrwxr-x   3 ftp      ftp           226 Dec 24  2006 info
drwxrwxr-x   3 ftp      ftp            81 Dec 11  2006 jcp
drwxrwxr-x   3 ftp      ftp           143 Dec 11  2006 legal
drwxrwxr-x   5 ftp      ftp           578 Dec 11  2006 licenses
lrwxrwxrwx   1 ftp      ftp            39 May 25  2008 mail -> /home/apmail/public-arch/www.apache.org
drwxrwxr-x   4 ftp      ftp           250 Dec 28  2006 mirrors
-rw-rw-r--   1 ftp      ftp         92186 Apr 17  2003 mlists.html
-rw-rw-r--   1 ftp      ftp           784 Dec 19  2004 phf_abuse_log.cgi
-rw-rw-r--   1 ftp      ftp            47 May 16  2006 robots.txt
drwxrwxr-x   3 ftp      ftp            49 Jan 25  2005 style
226 Transfer complete

ftputil should detect all the kinds of valid links and list the dir contents,

regards Nicola

Change History (5)

comment:1 Changed 10 years ago by schwa

  • Description modified (diff)
  • Status changed from new to assigned

comment:2 Changed 10 years ago by schwa

  • Description modified (diff)
  • Keywords listdir link ./ added
  • Version set to 2.4

comment:3 Changed 9 years ago by schwa

  • Milestone set to 2.4.2
  • Resolution set to fixed
  • Status changed from assigned to closed

It seems this bug is implicitly fixed by the change which already fixed bug #33. :-)

comment:4 Changed 9 years ago by ftputiluser

  • Resolution fixed deleted
  • Status changed from closed to reopened

Link to link are not yet correctly managed :-)

conn=ftputil.FTPHost('mirror3.mirror.garr.it','anonymous','p@p.com')

conn.path.isdir('/mirrors/zebra/')
---------------------------------------------------------------------------
PermanentError                            Traceback (most recent call last)

/home/nicola/workspace/FtpManager/<ipython console> 

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_path.pyc in isdir(self, path)
    142             return True                                                   
    143         try:                                                              
--> 144             stat_result = self._host.stat(                                
    145                           path, _exception_for_missing_path=False)                                       
    146             if stat_result is None:                                                                      

/home/nicola/workspace/FtpManager/extlib/ftputil/ftputil.pyc in stat(self, path, _exception_for_missing_path)
    822         _not_ intended for use by ftputil clients.)                                                  
    823         """                                                                                          
--> 824         return self._stat.stat(path, _exception_for_missing_path)                                    
    825                                                                                                      
    826     def walk(self, top, topdown=True, onerror=None):                                                 

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_stat.pyc in stat(self, path, _exception_for_missing_path)
    584         the server (e. g. timeout).                                                                   
    585         """                                                                                           
    586         return self.__call_with_parser_retry(self._real_stat, path,                                   
--> 587                                              _exception_for_missing_path)                             
    588                                                                                                          

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_stat.pyc in __call_with_parser_retry(self, method, *args, **kwargs)                                                                                                          
    541         #  parser - which is wrong.                                                                      
    542         try:                                                                                             
--> 543             result = method(*args, **kwargs)                                                             
    544             # if a `listdir` call didn't find anything, we can't                                         
    545             #  say anything about the usefulness of the parser                                           

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_stat.pyc in _real_stat(self, path, _exception_for_missing_path)                                                                                                              
    506         while True:                                                                                      
    507             # stat the link if it is one, else the file/directory                                        
--> 508             lstat_result = self._real_lstat(path, _exception_for_missing_path)                           
    509             if lstat_result is None:                                                                     
    510                 return None                                                                              

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_stat.pyc in _real_lstat(self, path, _exception_for_missing_path)                                                                                                             
    458         #  we want to collect as many stat results in the cache as                                       
    459         #  possible                                                                                      
--> 460         lines = self._host_dir(dirname)                                                                  
    461         for line in lines:                                                                               
    462             if self._parser.ignores_line(line):                                                          

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_stat.pyc in _host_dir(self, path)
    388         when applied to `path`.                                               
    389         """                                                                   
--> 390         return self._host._dir(path)                                          
    391                                                                               
    392     def _real_listdir(self, path):                                            

/home/nicola/workspace/FtpManager/extlib/ftputil/ftputil.pyc in _dir(self, path)
    779             return lines                                                
    780         lines = self._robust_ftp_command(_FTPHost_dir_command, path,
--> 781                                          descend_deeply=True)
    782         return lines
    783

/home/nicola/workspace/FtpManager/extlib/ftputil/ftputil.pyc in _robust_ftp_command(self, command, path, descend_deeply)
    562             if descend_deeply:
    563                 # invoke the command in (not: on) the deepest directory
--> 564                 self.chdir(path)
    565                 # workaround for some servers that give recursive
    566                 #  listings when called with a dot as path; see issue #33,

/home/nicola/workspace/FtpManager/extlib/ftputil/ftputil.pyc in chdir(self, path)
    585     def chdir(self, path):
    586         """Change the directory on the host."""
--> 587         ftp_error._try_with_oserror(self._session.cwd, path)
    588         self._current_dir = self.path.normpath(self.path.join(
    589                                                # use "old" current dir

/home/nicola/workspace/FtpManager/extlib/ftputil/ftp_error.pyc in _try_with_oserror(callee, *args, **kwargs)
    150             raise CommandNotImplementedError(*exc.args)
    151         else:
--> 152             raise PermanentError(*exc.args)
    153     except ftplib.all_errors:
    154         exc = sys.exc_info()[1]

PermanentError: 550 /mirrors/1: No such file or directory
Debugging info: ftputil 2.4.2b, Python 2.4.3 (linux2)

regards Nicola

comment:5 Changed 9 years ago by schwa

  • Resolution set to fixed
  • Status changed from reopened to closed

Hi Nicola,

I can reproduce the traceback. However, its background is different from the original description. The target of the link /mirrors/zebra doesn't exist at all, so isdir should return False instead of causing a traceback. The behavior of FTPHost.listdir to cause a PermanentError on the other hand would be correct. In contrast, the example in the original description shows a traceback even upon a listdir call on an existing target.

I've added another ticket, #39, which is more specific and "reclose" this bug for now. :-)

Stefan

Note: See TracTickets for help on using tickets.