Skip to content

Commit

Permalink
Bug 2065 – Scripting command "ls" in FTP session displays timestamps …
Browse files Browse the repository at this point in the history
…without year even if the server (notably IIS) provided the year, if it did not provide seconds

https://winscp.net/tracker/2065

Source commit: 4d719f707f54a5ce7d1ff2ad327a1159ccb3fefe
  • Loading branch information
martinprikryl committed Mar 26, 2022
1 parent eb4ab60 commit 1917297
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 12 deletions.
1 change: 1 addition & 0 deletions source/components/UnixDirView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,7 @@ TDateTime __fastcall TUnixDirView::ItemFileTime(TListItem * Item,
break;

case mfMDHM:
case mfYMDHM:
Precision = tpMinute;
break;

Expand Down
8 changes: 3 additions & 5 deletions source/core/FtpFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4344,9 +4344,7 @@ void __fastcall TFTPFileSystem::RemoteFileTimeToDateTimeAndPrecision(const TRemo
DateTime = DateTime +
EncodeTimeVerbose((unsigned short)Source.Hour, (unsigned short)Source.Minute,
(unsigned short)Source.Second, 0);
// not exact as we got year as well, but it is most probably
// guessed by FZAPI anyway
ModificationFmt = Source.HasSeconds ? mfFull : mfMDHM;
ModificationFmt = Source.HasSeconds ? mfFull : (Source.HasYear ? mfYMDHM : mfMDHM);

// With IIS, the Utc should be false only for MDTM
if (FWindowsServer && !Source.Utc)
Expand Down Expand Up @@ -4469,11 +4467,11 @@ bool __fastcall TFTPFileSystem::HandleListData(const wchar_t * Path,
catch (Exception & E)
{
UnicodeString EntryData =
FORMAT(L"%s/%s/%s/%s/%s/%s/%s/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d",
FORMAT(L"%s/%s/%s/%s/%s/%s/%s/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d/%d",
(Entry->Name, Entry->Permissions, Entry->HumanPerm, Entry->Owner, Entry->Group, Entry->OwnerGroup, IntToStr(Entry->Size),
int(Entry->Dir), int(Entry->Link), Entry->Time.Year, Entry->Time.Month, Entry->Time.Day,
Entry->Time.Hour, Entry->Time.Minute, int(Entry->Time.HasTime),
int(Entry->Time.HasSeconds), int(Entry->Time.HasDate)));
int(Entry->Time.HasYear), int(Entry->Time.HasSeconds), int(Entry->Time.HasDate)));
throw ETerminal(&E, FMTLOAD(LIST_LINE_ERROR, (EntryData)), HELP_LIST_LINE_ERROR);
}

Expand Down
12 changes: 10 additions & 2 deletions source/core/RemoteFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ TDateTime __fastcall ReduceDateTimePrecision(TDateTime DateTime,
DecodeTime(DateTime, H, N, S, MS);
switch (Precision)
{
case mfYMDHM:
case mfMDHM:
S = 0;
MS = 0;
Expand Down Expand Up @@ -433,6 +434,7 @@ UnicodeString __fastcall UserModificationStr(TDateTime DateTime,
return L"";
case mfMDY:
return FormatDateTime(L"ddddd", DateTime);
case mfYMDHM:
case mfMDHM:
return FormatDateTime(L"ddddd t", DateTime);
case mfFull:
Expand All @@ -459,6 +461,10 @@ UnicodeString __fastcall ModificationStr(TDateTime DateTime,
return FORMAT(L"%3s %2d %2d:%2.2d",
(EngShortMonthNames[Month-1], Day, Hour, Min));

case mfYMDHM:
return FORMAT(L"%3s %2d %2d:%2.2d %4d",
(EngShortMonthNames[Month-1], Day, Hour, Min, Year));

default:
DebugFail();
// fall thru
Expand Down Expand Up @@ -1012,7 +1018,7 @@ bool __fastcall TRemoteFile::IsTimeShiftingApplicable()
//---------------------------------------------------------------------------
bool __fastcall TRemoteFile::IsTimeShiftingApplicable(TModificationFmt ModificationFmt)
{
return (ModificationFmt == mfMDHM) || (ModificationFmt == mfFull);
return (ModificationFmt == mfMDHM) || (ModificationFmt == mfYMDHM) || (ModificationFmt == mfFull);
}
//---------------------------------------------------------------------------
void __fastcall TRemoteFile::ShiftTimeInSeconds(__int64 Seconds)
Expand Down Expand Up @@ -1294,7 +1300,9 @@ void __fastcall TRemoteFile::SetListingStr(UnicodeString value)
FModification = EncodeDateVerbose(Year, Month, Day) + EncodeTimeVerbose(Hour, Min, Sec, 0);
// adjust only when time is known,
// adjusting default "midnight" time makes no sense
if ((FModificationFmt == mfMDHM) || (FModificationFmt == mfFull))
if ((FModificationFmt == mfMDHM) ||
DebugAlwaysFalse(FModificationFmt == mfYMDHM) ||
(FModificationFmt == mfFull))
{
DebugAssert(Terminal != NULL);
FModification = AdjustDateTimeFromUnix(FModification,
Expand Down
2 changes: 1 addition & 1 deletion source/core/RemoteFiles.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <vector>
#include <map>
//---------------------------------------------------------------------------
enum TModificationFmt { mfNone, mfMDHM, mfMDY, mfFull };
enum TModificationFmt { mfNone, mfMDHM, mfYMDHM, mfMDY, mfFull };
//---------------------------------------------------------------------------
#define SYMLINKSTR L" -> "
#define ROOTDIRECTORY L"/"
Expand Down
1 change: 1 addition & 0 deletions source/core/WebDAVFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,7 @@ void __fastcall TWebDAVFileSystem::ParsePropResultSet(TRemoteFile * File,
EncodeDateVerbose((unsigned short)Year, (unsigned short)Month, (unsigned short)Day) +
EncodeTimeVerbose((unsigned short)Hour, (unsigned short)Min, (unsigned short)Sec, 0);
File->Modification = ConvertTimestampFromUTC(Modification);
// Should use mfYMDHM or mfMDY when appropriate according to Filled
File->ModificationFmt = mfFull;
}
else
Expand Down
1 change: 1 addition & 0 deletions source/filezilla/FileZillaIntf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ void __fastcall CopyFileTime(TRemoteFileTime & Dest, const t_directory::t_dirent
Dest.Second = Source.second;
Dest.HasTime = Source.hastime;
Dest.HasDate = Source.hasdate;
Dest.HasYear = Source.hasyear;
Dest.HasSeconds = Source.hasseconds;
Dest.Utc = Source.utc;
}
Expand Down
1 change: 1 addition & 0 deletions source/filezilla/FileZillaIntf.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct TRemoteFileTime
int Minute;
int Second;
bool HasTime;
bool HasYear;
bool HasSeconds;
bool HasDate;
bool Utc;
Expand Down
1 change: 1 addition & 0 deletions source/filezilla/FtpControlSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4416,6 +4416,7 @@ bool CFtpControlSocket::HandleMdtm(int code, t_directory::t_direntry::t_date & d
date.minute = m;
date.second = s;
date.hastime = true;
date.hasyear = true;
date.hasseconds = hasseconds;
date.hasdate = true;
date.utc = true;
Expand Down
18 changes: 15 additions & 3 deletions source/filezilla/FtpListResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ bool CFtpListResult::ParseShortDate(const char *str, int len, t_directory::t_dir
}

date.hasdate = TRUE;
date.hasyear = TRUE;
return true;
}

Expand Down Expand Up @@ -803,6 +804,7 @@ BOOL CFtpListResult::parseAsVMS(const char *line, const int linelen, t_directory
p++;

dir.date.year = static_cast<int>(strntoi64(p, tokenlen - (p - str)));
dir.date.hasyear = TRUE;

//Get time
str = GetNextToken(line, linelen, tokenlen, pos, 0);
Expand Down Expand Up @@ -1169,6 +1171,7 @@ bool CFtpListResult::parseMlsdDateTime(const CString value, t_directory::t_diren
if (result)
{
date.year = Year;
date.hasyear = TRUE;
date.month = Month;
date.day = Day;
date.hour = Hours;
Expand All @@ -1185,7 +1188,7 @@ void CFtpListResult::GuessYearIfUnknown(t_directory::t_direntry::t_date & Date)
// others use one year as limit. IIS shows time for files from the current year (jan-dec).
// So there is no support for files with time
// dated in the near future. Under normal conditions there should not be such files.
if (!Date.year)
if (!Date.year) // might use direntry.date.hasyear now?
{
CTime curtime = CTime::GetCurrentTime();
int curday = curtime.GetDay();
Expand All @@ -1201,6 +1204,7 @@ void CFtpListResult::GuessYearIfUnknown(t_directory::t_direntry::t_date & Date)
{
Date.year = curyear - 1;
}
// year is guessed, not setting hasyear
}
}

Expand Down Expand Up @@ -1492,6 +1496,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
else if (p-smonth == 4) //2002-10-14
{
direntry.date.year = static_cast<int>(strntoi64(smonth, p-smonth));
direntry.date.hasyear = TRUE;
sday = pos2 + 1;
sdaylen = smonthlen - (pos2 - smonth) - 1;
smonthlen = pos2-smonth - (p-smonth) - 1;
Expand All @@ -1513,6 +1518,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
else if (p-smonth) //14-10-2002 or 01-jun-99
{
direntry.date.year = static_cast<int>(strntoi64(pos2+1, tokenlen - (pos2-smonth) - 1));
direntry.date.hasyear = TRUE;
sday = smonth;
sdaylen = p - smonth;
smonthlen = pos2-smonth - (p-smonth) - 1;
Expand Down Expand Up @@ -1554,6 +1560,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
else if (p-smonth==4)
{
direntry.date.year = static_cast<int>(strntoi64(smonth, p-smonth));
direntry.date.hasyear = TRUE;
sday = pos2 + 1;
sdaylen = smonthlen - (pos2 - smonth) - 1;
smonthlen = pos2-smonth - (p-smonth) - 1;
Expand All @@ -1575,6 +1582,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
else if (p-smonth==2)
{
direntry.date.year = static_cast<int>(strntoi64(pos2+1, tokenlen - (pos2-smonth) - 1));
direntry.date.hasyear = TRUE;
sday = smonth;
sdaylen = p - smonth;
smonthlen = pos2-smonth - (p-smonth) - 1;
Expand Down Expand Up @@ -1677,6 +1685,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
{
gotYear = true;
direntry.date.year = year;
direntry.date.hasyear = TRUE;
}
else
{
Expand Down Expand Up @@ -1767,12 +1776,13 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
return false;
}
}
else if (!direntry.date.year)
else if (!direntry.date.year) // might use direntry.date.hasyear now?
{
//No delimiters -> year

direntry.date.hastime = FALSE;
direntry.date.year = static_cast<int>(strntoi64(stimeyear, stimeyearlen));
direntry.date.hasyear = TRUE;
}
else
{
Expand All @@ -1781,7 +1791,7 @@ BOOL CFtpListResult::parseAsUnix(const char *line, const int linelen, t_director
}
}

if (!direntry.date.year) //Year 0? Really ancient file, this is invalid!
if (!direntry.date.year) //Year 0? Really ancient file, this is invalid! might use direntry.date.hasyear now?
{
return FALSE;
}
Expand Down Expand Up @@ -1927,6 +1937,7 @@ void CFtpListResult::TimeTToDate(time_t TimeT, t_directory::t_direntry::t_date &
{
tm * sTime = gmtime(&TimeT);
Date.year = sTime->tm_year + 1900;
Date.hasyear = TRUE;
Date.month = sTime->tm_mon+1;
Date.day = sTime->tm_mday;
Date.hour = sTime->tm_hour;
Expand Down Expand Up @@ -2105,6 +2116,7 @@ BOOL CFtpListResult::parseAsOther(const char *line, const int linelen, t_directo
return FALSE;

direntry.date.year = static_cast<int>(strntoi64(str, tokenlen));
direntry.date.hasyear = TRUE;
if (direntry.date.year < 50)
direntry.date.year += 2000;
else if (direntry.date.year < 1000)
Expand Down
2 changes: 1 addition & 1 deletion source/filezilla/structures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ t_directory::t_direntry::t_direntry()
t_directory::t_direntry::t_date::t_date()
{
year=month=day=hour=minute=second=0;
hasdate=hastime=hasseconds=utc=FALSE;
hasdate=hastime=hasyear=hasseconds=utc=FALSE;
}
1 change: 1 addition & 0 deletions source/filezilla/structures.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class t_directory
t_date();
int year,month,day,hour,minute,second;
bool hastime;
bool hasyear; // ignored and assumed true when hasseconds
bool hasseconds;
bool hasdate;
bool utc;
Expand Down

0 comments on commit 1917297

Please sign in to comment.