[ftputil] Bug in synchronize_times()?

Christopher Arndt chris.arndt at web.de
Sat Jul 2 23:12:18 CEST 2005


Hi,

I currently live in Galway, Ireland, so my timezone (GMT+DST) is one 
hour behind the one the FTP Server of my webspace provider uses (CST).

So I tried to use synchronize_time() with the result that ftputil thinks 
the files on my server are 1 _year_ behind and (logically) refuses to 
set such a big time shift.

Looking in the source code, I found that synchronize_times() uses the 
getmtime() method on a newly created file on the server, to determine 
the server's idea of the current time.

Looking in ftp_stat.py you'll find the culprit in line 295-298:

             if st_mtime > time.time() + self._host.time_shift() + 60.0:
                 # if it's in the future, use previous year
                 st_mtime = time.mktime( (year-1, month, day,
                            hour, minute, 0, 0, 0, -1) )

That is, getmtime() already tries to account for the timeshift, which is 
not set yet, by the time synchronize_times() uses getmtime() to 
determine the file's mtime!

Solution: either synchronize should employ it's own method of finding 
out the mtime of the newly created file (but that would mean a lot of 
code duplication) or the parse_line() method in the _Stat class should 
provide some means to switch of the time shift temporarily.


I also tried to devise another method of finding out the server's idea 
about it's local time by looking at the welcome message the server provides.

This is what the ProFTP server of my webspace provider gives:

220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 23:00. Server port: 21.
220-This is a private system - No anonymous login
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.


You can see, that he gives the local time, but no date year or 
whatsoever. This complicates the matter a bit, because you have to take 
into account, that it's still the previous or the next day.

So I came up with the following crude hack:

import ftputil, time

class MyFTPHost(ftputil.FTPHost):
     """FTP host class that tries to find out the server time
     from the welcome message.
     """


     def __init__(self, *args, **kwargs):
         ftputil.FTPHost.__init__(self, *args, **kwargs)
         ltime = time.time()
         stime = self._get_servertime(ltime)
         if stime:
             time_shift = stime - ltime
             # round to nearest minute
             self.set_time_shift(round(time_shift/60.)*60)

     def _get_servertime(self, ltime):
         """Should be called immediately after connect."""
         for line in self._session.getwelcome().split('\n'):
             line = line.lower()
             if line.find('local time') >= 0:
                 break
         else:
             return
         import re
         m = re.search('(\d\d):(\d\d)', line)
         if m:
             ltime = list(time.localtime(ltime))
             hour, minute = int(m.group(1)), int(m.group(2))
             if ltime[3] > 12 and abs(hour-ltime[3]) > 12:
                 ltime[2] += 1
             ltime[3] = hour
             ltime[4] = minute
             ltime[5] = 0
             ltime[8] = -1
             return time.mktime(tuple(ltime))

It kinda works for me, but will probably not with other FTP server.

Cheers, Chris


More information about the ftputil mailing list