|
@@ -1,5 +1,5 @@
|
|
{==============================================================================|
|
|
{==============================================================================|
|
|
-| Project : Ararat Synapse | 004.000.000 |
|
|
|
|
|
|
+| Project : Ararat Synapse | 004.001.000 |
|
|
|==============================================================================|
|
|
|==============================================================================|
|
|
| Content: FTP client |
|
|
| Content: FTP client |
|
|
|==============================================================================|
|
|
|==============================================================================|
|
|
@@ -34,10 +34,12 @@
|
|
|==============================================================================|
|
|
|==============================================================================|
|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
|
| The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
|
|
| Portions created by Lukas Gebauer are Copyright (c) 1999-2010. |
|
|
| Portions created by Lukas Gebauer are Copyright (c) 1999-2010. |
|
|
|
|
+| Portions created by Jan Fiala are Copyright (c) 2019. |
|
|
| All Rights Reserved. |
|
|
| All Rights Reserved. |
|
|
|==============================================================================|
|
|
|==============================================================================|
|
|
| Contributor(s): |
|
|
| Contributor(s): |
|
|
| Petr Esner <[email protected]> |
|
|
| Petr Esner <[email protected]> |
|
|
|
|
+| Jan Fiala |
|
|
|==============================================================================|
|
|
|==============================================================================|
|
|
| History: see HISTORY.HTM from distribution package |
|
|
| History: see HISTORY.HTM from distribution package |
|
|
| (Found at URL: http://www.ararat.cz/synapse/) |
|
|
| (Found at URL: http://www.ararat.cz/synapse/) |
|
|
@@ -67,6 +69,9 @@ interface
|
|
|
|
|
|
uses
|
|
uses
|
|
SysUtils, Classes,
|
|
SysUtils, Classes,
|
|
|
|
+ {$IfDef POSIX}
|
|
|
|
+ ,System.Generics.Collections, System.Generics.Defaults
|
|
|
|
+ {$EndIf}
|
|
blcksock, synautil, synaip, synsock;
|
|
blcksock, synautil, synaip, synsock;
|
|
|
|
|
|
const
|
|
const
|
|
@@ -122,12 +127,18 @@ type
|
|
property Permission: string read FPermission write FPermission;
|
|
property Permission: string read FPermission write FPermission;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+ {$IFDEF POSIX}
|
|
|
|
+ TFTPRecList = TList<TFTPListRec>;
|
|
|
|
+ {$ELSE}
|
|
|
|
+ TFTPRecList = TList;
|
|
|
|
+ {$ENDIF}
|
|
|
|
+
|
|
{:@abstract(This is TList of TFTPListRec objects.)
|
|
{:@abstract(This is TList of TFTPListRec objects.)
|
|
This object is used for holding lististing of all files information in listed
|
|
This object is used for holding lististing of all files information in listed
|
|
directory on FTP server.}
|
|
directory on FTP server.}
|
|
TFTPList = class(TObject)
|
|
TFTPList = class(TObject)
|
|
protected
|
|
protected
|
|
- FList: TList;
|
|
|
|
|
|
+ FList: TFTPRecList;
|
|
FLines: TStringList;
|
|
FLines: TStringList;
|
|
FMasks: TStringList;
|
|
FMasks: TStringList;
|
|
FUnparsedLines: TStringList;
|
|
FUnparsedLines: TStringList;
|
|
@@ -173,9 +184,13 @@ type
|
|
@link(TFTPListRec).}
|
|
@link(TFTPListRec).}
|
|
procedure ParseLines; virtual;
|
|
procedure ParseLines; virtual;
|
|
|
|
|
|
|
|
+ {:try to parse MLSD directory listing in @link(lines) to list of
|
|
|
|
+ @link(TFTPListRec).}
|
|
|
|
+ procedure ParseMLSDLines; virtual;
|
|
|
|
+
|
|
{:By this property you have access to list of @link(TFTPListRec).
|
|
{:By this property you have access to list of @link(TFTPListRec).
|
|
This is for compatibility only. Please, use @link(Items) instead.}
|
|
This is for compatibility only. Please, use @link(Items) instead.}
|
|
- property List: TList read FList;
|
|
|
|
|
|
+ property List: TFTPRecList read FList;
|
|
|
|
|
|
{:By this property you have access to list of @link(TFTPListRec).}
|
|
{:By this property you have access to list of @link(TFTPListRec).}
|
|
property Items[Index: Integer]: TFTPListRec read GetListItem; default;
|
|
property Items[Index: Integer]: TFTPListRec read GetListItem; default;
|
|
@@ -229,6 +244,7 @@ type
|
|
FIsDataTLS: Boolean;
|
|
FIsDataTLS: Boolean;
|
|
FTLSonData: Boolean;
|
|
FTLSonData: Boolean;
|
|
FFullSSL: Boolean;
|
|
FFullSSL: Boolean;
|
|
|
|
+ FUseMLSDList: Boolean;
|
|
function Auth(Mode: integer): Boolean; virtual;
|
|
function Auth(Mode: integer): Boolean; virtual;
|
|
function Connect: Boolean; virtual;
|
|
function Connect: Boolean; virtual;
|
|
function InternalStor(const Command: string; RestoreAt: int64): Boolean; virtual;
|
|
function InternalStor(const Command: string; RestoreAt: int64): Boolean; virtual;
|
|
@@ -446,6 +462,9 @@ type
|
|
{:If @true (default), then try to use SSL/TLS on data transfers too.
|
|
{:If @true (default), then try to use SSL/TLS on data transfers too.
|
|
If @false, then SSL/TLS is used only for control connection.}
|
|
If @false, then SSL/TLS is used only for control connection.}
|
|
property TLSonData: Boolean read FTLSonData write FTLSonData;
|
|
property TLSonData: Boolean read FTLSonData write FTLSonData;
|
|
|
|
+
|
|
|
|
+ {:Enable MLSD support for directory list.}
|
|
|
|
+ property UseMLSDList: Boolean read FUseMLSDList write FUseMLSDList;
|
|
end;
|
|
end;
|
|
|
|
|
|
{:A very useful function, and example of use can be found in the TFtpSend object.
|
|
{:A very useful function, and example of use can be found in the TFtpSend object.
|
|
@@ -497,6 +516,7 @@ begin
|
|
FIsTLS := False;
|
|
FIsTLS := False;
|
|
FIsDataTLS := False;
|
|
FIsDataTLS := False;
|
|
FTLSonData := True;
|
|
FTLSonData := True;
|
|
|
|
+ UseMLSDList := false;
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TFTPSend.Destroy;
|
|
destructor TFTPSend.Destroy;
|
|
@@ -986,7 +1006,10 @@ begin
|
|
if NameList then
|
|
if NameList then
|
|
x := FTPCommand('NLST' + Directory)
|
|
x := FTPCommand('NLST' + Directory)
|
|
else
|
|
else
|
|
- x := FTPCommand('LIST' + Directory);
|
|
|
|
|
|
+ if FUseMLSDList then
|
|
|
|
+ x := FTPCommand('MLSD' + Directory)
|
|
|
|
+ else
|
|
|
|
+ x := FTPCommand('LIST' + Directory);
|
|
if (x div 100) <> 1 then
|
|
if (x div 100) <> 1 then
|
|
Exit;
|
|
Exit;
|
|
Result := DataRead(FDataStream);
|
|
Result := DataRead(FDataStream);
|
|
@@ -994,7 +1017,10 @@ begin
|
|
begin
|
|
begin
|
|
FDataStream.Position := 0;
|
|
FDataStream.Position := 0;
|
|
FFTPList.Lines.LoadFromStream(FDataStream);
|
|
FFTPList.Lines.LoadFromStream(FDataStream);
|
|
- FFTPList.ParseLines;
|
|
|
|
|
|
+ if FUseMLSDList then
|
|
|
|
+ FFTPList.ParseMLSDLines
|
|
|
|
+ else
|
|
|
|
+ FFTPList.ParseLines;
|
|
end;
|
|
end;
|
|
FDataStream.Position := 0;
|
|
FDataStream.Position := 0;
|
|
end;
|
|
end;
|
|
@@ -1217,13 +1243,13 @@ end;
|
|
constructor TFTPList.Create;
|
|
constructor TFTPList.Create;
|
|
begin
|
|
begin
|
|
inherited Create;
|
|
inherited Create;
|
|
- FList := TList.Create;
|
|
|
|
|
|
+ FList := TFTPRecList.Create;
|
|
FLines := TStringList.Create;
|
|
FLines := TStringList.Create;
|
|
FMasks := TStringList.Create;
|
|
FMasks := TStringList.Create;
|
|
FUnparsedLines := TStringList.Create;
|
|
FUnparsedLines := TStringList.Create;
|
|
//various UNIX
|
|
//various UNIX
|
|
- FMasks.add('pppppppppp $!!!S*$TTT$DD$hh mm ss$YYYY$n*');
|
|
|
|
- FMasks.add('pppppppppp $!!!S*$DD$TTT$hh mm ss$YYYY$n*');
|
|
|
|
|
|
+ FMasks.add('pppppppppp $!!!S*$TTT$DD$hh:mm:ss$YYYY$n*'); //Fiala - pridany dvojtecky do casu
|
|
|
|
+ FMasks.add('pppppppppp $!!!S*$DD$TTT$hh:mm:ss$YYYY$n*'); //Fiala - pridany dvojtecky do casu
|
|
FMasks.add('pppppppppp $!!!S*$TTT$DD$UUUUU$n*'); //mostly used UNIX format
|
|
FMasks.add('pppppppppp $!!!S*$TTT$DD$UUUUU$n*'); //mostly used UNIX format
|
|
FMasks.add('pppppppppp $!!!S*$DD$TTT$UUUUU$n*');
|
|
FMasks.add('pppppppppp $!!!S*$DD$TTT$UUUUU$n*');
|
|
//MacOS
|
|
//MacOS
|
|
@@ -1240,8 +1266,20 @@ begin
|
|
FMasks.add('DD MM YYYY hh mmH $ d!n*');
|
|
FMasks.add('DD MM YYYY hh mmH $ d!n*');
|
|
//VMS
|
|
//VMS
|
|
FMasks.add('v*$ DD TTT YYYY hh mm');
|
|
FMasks.add('v*$ DD TTT YYYY hh mm');
|
|
|
|
+ FMasks.add('v*$DD TTT YYYY hh mm ss');
|
|
|
|
+ FMasks.add('v*$D TTT YYYY hh mm'); //Fiala
|
|
|
|
+ FMasks.add('v*$!DD TTT YYYY hh mm ss');
|
|
|
|
+ //sample: ABB.DIR;1 1/35 18-SEP-2007 10:46:39 [STEVEH] (RWE,RWE,RWE,RWE)
|
|
|
|
+ FMasks.add('v*\$!DD TTT YYYY hh mm ss');
|
|
|
|
+ //sample: DELMAS.SQL;7 0/0 6-DEC-2007 10:43:44 [STEVEH] (RWED,RWED,RWED,RWED)
|
|
|
|
+ FMasks.add('v*$!D TTT YYYY hh mm ss'); //Fiala
|
|
|
|
+ FMasks.add('v*\$!D TTT YYYY hh mm ss'); //Fiala
|
|
|
|
+ FMasks.add('v*$!D TTT YYYY hh mm ss'); //Fiala
|
|
|
|
+ FMasks.add('n*$ YYYY MM DD hh mm$S*'); //Fiala
|
|
|
|
+ //sample: STANS_DIFF.DIR;1 1 13-APR-2006 13:27 [AGR4] (RWE,RWE,RE,E)
|
|
FMasks.add('v*$!DD TTT YYYY hh mm');
|
|
FMasks.add('v*$!DD TTT YYYY hh mm');
|
|
- FMasks.add('n*$ YYYY MM DD hh mm$S*');
|
|
|
|
|
|
+// FMasks.add('n*$ YYYY MM DD hh mm$S*');
|
|
|
|
+ FMasks.add('$!: :n*');
|
|
//AS400
|
|
//AS400
|
|
FMasks.add('!S*$MM DD YY hh mm ss !n*');
|
|
FMasks.add('!S*$MM DD YY hh mm ss !n*');
|
|
FMasks.add('!S*$DD MM YY hh mm ss !n*');
|
|
FMasks.add('!S*$DD MM YY hh mm ss !n*');
|
|
@@ -1272,9 +1310,35 @@ begin
|
|
//BullGCOS8
|
|
//BullGCOS8
|
|
FMasks.add(' $S* MM DD YY hh mm ss !n*');
|
|
FMasks.add(' $S* MM DD YY hh mm ss !n*');
|
|
FMasks.add('d $S* MM DD YY !n*');
|
|
FMasks.add('d $S* MM DD YY !n*');
|
|
|
|
+ //IBM AIXs
|
|
|
|
+ // sample: -rw---- 1 ITINERA DAT 58 JAN 09 2008 TSITIS009VAJ_COB
|
|
|
|
+ FMasks.add('ppppppp $!!!S*$TTT$DD$YYYY$n*'); //Fiala
|
|
|
|
+
|
|
|
|
+ FMasks.add('pppppppppp SSSSSSSSSS DD !YYYY n*'); //Fiala
|
|
|
|
+ FMasks.add('pppppppppp SSSSSSSSSS DD !hh mm n*'); //Fiala
|
|
|
|
+ // drwxr-xr-x 10 hol prog 45056 20 8 10:00 adis30161
|
|
|
|
+ FMasks.add('pppppppppp SSSSSSSSSS DD MM!hh mm n*'); //Fiala
|
|
|
|
+ // drwxr-xr-x 2 hol prog 4096 20 1 2005 bin
|
|
|
|
+ FMasks.add('pppppppppp SSSSSSSSSS DD MM YYYY n*'); //Fiala
|
|
|
|
+
|
|
|
|
+ //IBM VM //Fiala
|
|
|
|
+ // MQ_REPTS TESTVIEW V 72 139 1 2009-01-28 11:58:07 -
|
|
|
|
+ // NEW DIR - - - 2009-11-04 18:31:50 -
|
|
|
|
+ FMasks.add('n*.$n*$ SSSSSSSSSS YYYY-MM-DD hh:mm:ss -');
|
|
|
|
+ FMasks.add('nnnnnnnnnnnnnnnnn d - - - YYYY-MM-DD hh:mm:ss -');
|
|
|
|
+ //sample: Migrated $SRC.AFLG
|
|
|
|
+ FMasks.add(' dxx n*'); //Fiala
|
|
|
|
+ //VMS - new untouched files (name only)
|
|
|
|
+ // ADR10AI2
|
|
|
|
+ FMasks.Add('n*§'); //Fiala
|
|
|
|
+ //IBM VM
|
|
|
|
+ // MQ_REPTS TESTVIEW V 72 139 1 2009-01-28 11:58:07 -
|
|
|
|
+ // NEW DIR - - - 2009-11-04 18:31:50 -
|
|
|
|
+ FMasks.add('nnnnnnnnnnnnnnnnn x SSSSSSSSSS YYYY-MM-DD hh:mm:ss -');
|
|
|
|
+ FMasks.add('nnnnnnnnnnnnnnnnn d - - - YYYY-MM-DD hh:mm:ss -');
|
|
//BullGCOS7
|
|
//BullGCOS7
|
|
- FMasks.add(' TTT DD YYYY n*');
|
|
|
|
- FMasks.add(' d n*');
|
|
|
|
|
|
+// FMasks.add(' TTT DD YYYY n*');
|
|
|
|
+// FMasks.add(' d n*');
|
|
end;
|
|
end;
|
|
|
|
|
|
destructor TFTPList.Destroy;
|
|
destructor TFTPList.Destroy;
|
|
@@ -1366,16 +1430,17 @@ begin
|
|
IMask := 1;
|
|
IMask := 1;
|
|
Result := 1;
|
|
Result := 1;
|
|
LastMaskC := ' ';
|
|
LastMaskC := ' ';
|
|
|
|
+ Value := TrimRight(Value); //Fiala
|
|
while Imask <= Length(mask) do
|
|
while Imask <= Length(mask) do
|
|
begin
|
|
begin
|
|
- if (Mask[Imask] <> '*') and (Ivalue > Length(Value)) then
|
|
|
|
|
|
+ if not (Mask[Imask] in ['*', '\', '§']) and (Ivalue > Length(Value)) then //Fiala
|
|
begin
|
|
begin
|
|
Result := 0;
|
|
Result := 0;
|
|
Exit;
|
|
Exit;
|
|
end;
|
|
end;
|
|
MaskC := Mask[Imask];
|
|
MaskC := Mask[Imask];
|
|
- if Ivalue > Length(Value) then
|
|
|
|
- Exit;
|
|
|
|
|
|
+// if Ivalue > Length(Value) then
|
|
|
|
+// Exit;
|
|
c := Value[Ivalue];
|
|
c := Value[Ivalue];
|
|
case MaskC of
|
|
case MaskC of
|
|
'n':
|
|
'n':
|
|
@@ -1422,6 +1487,8 @@ begin
|
|
Result := 0;
|
|
Result := 0;
|
|
Exit;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
+ 'y': //Fiala
|
|
|
|
+ if c <> ' ' then Result := 0;
|
|
'*':
|
|
'*':
|
|
begin
|
|
begin
|
|
s := '';
|
|
s := '';
|
|
@@ -1474,6 +1541,12 @@ begin
|
|
end;
|
|
end;
|
|
Dec(IValue);
|
|
Dec(IValue);
|
|
end;
|
|
end;
|
|
|
|
+ '§': //Fiala
|
|
|
|
+ if IValue < Length(Value) then
|
|
|
|
+ begin
|
|
|
|
+ Result := 0;
|
|
|
|
+ Break;
|
|
|
|
+ end;
|
|
'$':
|
|
'$':
|
|
begin
|
|
begin
|
|
while IValue <= Length(Value) do
|
|
while IValue <= Length(Value) do
|
|
@@ -1512,6 +1585,12 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
+ ':': //Fiala
|
|
|
|
+ if c <> ':' then
|
|
|
|
+ begin
|
|
|
|
+ Result := 0;
|
|
|
|
+ Exit;
|
|
|
|
+ end;
|
|
'\':
|
|
'\':
|
|
begin
|
|
begin
|
|
Value := NextValue;
|
|
Value := NextValue;
|
|
@@ -1530,6 +1609,7 @@ var
|
|
x, n: integer;
|
|
x, n: integer;
|
|
begin
|
|
begin
|
|
Result := false;
|
|
Result := false;
|
|
|
|
+ if (Trim(FileName) = '') and (Trim(VMSFileName) = '') then Exit; //Fiala
|
|
if FileName <> '' then
|
|
if FileName <> '' then
|
|
begin
|
|
begin
|
|
if pos('?', VMSFilename) > 0 then
|
|
if pos('?', VMSFilename) > 0 then
|
|
@@ -1540,15 +1620,15 @@ begin
|
|
if VMSFileName <> '' then
|
|
if VMSFileName <> '' then
|
|
if pos(';', VMSFilename) <= 0 then
|
|
if pos(';', VMSFilename) <= 0 then
|
|
Exit;
|
|
Exit;
|
|
- if (FileName = '') and (VMSFileName = '') then
|
|
|
|
- Exit;
|
|
|
|
|
|
+// if (FileName = '') and (VMSFileName = '') then
|
|
|
|
+// Exit;
|
|
if Permissions <> '' then
|
|
if Permissions <> '' then
|
|
begin
|
|
begin
|
|
- if length(Permissions) <> 10 then
|
|
|
|
|
|
+ if (length(Permissions) <> 10) and (length(Permissions) <> 7) then //Fiala
|
|
Exit;
|
|
Exit;
|
|
- for n := 1 to 10 do
|
|
|
|
- if not(Permissions[n] in
|
|
|
|
- ['a', 'b', 'c', 'd', 'h', 'l', 'p', 'r', 's', 't', 'w', 'x', 'y', '-']) then
|
|
|
|
|
|
+ for n := 1 to length(Permissions) do //Fiala
|
|
|
|
+ if not (Permissions[n] in
|
|
|
|
+ ['a', 'b', 'c', 'd', 'h', 'l', 'p', 'r', 's', 't', 'w', 'x', 'y', '-', 'S']) then //Fiala
|
|
Exit;
|
|
Exit;
|
|
end;
|
|
end;
|
|
if Day <> '' then
|
|
if Day <> '' then
|
|
@@ -1690,6 +1770,9 @@ begin
|
|
{$ENDIF}
|
|
{$ENDIF}
|
|
|
|
|
|
DecodeDate(Date,myear,mmonth,mday);
|
|
DecodeDate(Date,myear,mmonth,mday);
|
|
|
|
+ myear := YearOf(Date); //Fiala
|
|
|
|
+ mMonth := 1; //Fiala
|
|
|
|
+ mDay := 1; //Fiala
|
|
mhours := 0;
|
|
mhours := 0;
|
|
mminutes := 0;
|
|
mminutes := 0;
|
|
mseconds := 0;
|
|
mseconds := 0;
|
|
@@ -1718,9 +1801,13 @@ begin
|
|
YearTime := TrimSP(YearTime);
|
|
YearTime := TrimSP(YearTime);
|
|
mhours := StrToIntDef(Separateleft(YearTime, ':'), 0);
|
|
mhours := StrToIntDef(Separateleft(YearTime, ':'), 0);
|
|
mminutes := StrToIntDef(SeparateRight(YearTime, ':'), 0);
|
|
mminutes := StrToIntDef(SeparateRight(YearTime, ':'), 0);
|
|
- if (Encodedate(myear, mmonth, mday)
|
|
|
|
- + EncodeTime(mHours, mminutes, 0, 0)) > now then
|
|
|
|
- Dec(mYear);
|
|
|
|
|
|
+ try { osetreni spatneho formatu data } //Fiala
|
|
|
|
+ if (Encodedate(myear, mmonth, mday) //tohle kvuli spatnemu casu na FTP serveru
|
|
|
|
+ + EncodeTime(mHours, mminutes, 0, 0)) > now then
|
|
|
|
+ Dec(mYear);
|
|
|
|
+ except //Fiala
|
|
|
|
+ mYear := YearOf(Date()); //Fiala
|
|
|
|
+ end;
|
|
end
|
|
end
|
|
else
|
|
else
|
|
myear := StrToIntDef(YearTime, 0);
|
|
myear := StrToIntDef(YearTime, 0);
|
|
@@ -1737,6 +1824,10 @@ begin
|
|
if mHours <> 12 then
|
|
if mHours <> 12 then
|
|
mHours := MHours + 12;
|
|
mHours := MHours + 12;
|
|
end;
|
|
end;
|
|
|
|
+ { osetrime prechodne roky } //Fiala
|
|
|
|
+ if (mday = 29) and (mmonth = 2) and not IsLeapYear(myear) then
|
|
|
|
+ Dec(Mday);
|
|
|
|
+
|
|
Value.FileTime := Encodedate(myear, mmonth, mday)
|
|
Value.FileTime := Encodedate(myear, mmonth, mday)
|
|
+ EncodeTime(mHours, mminutes, mseconds, 0);
|
|
+ EncodeTime(mHours, mminutes, mseconds, 0);
|
|
if Permissions <> '' then
|
|
if Permissions <> '' then
|
|
@@ -1961,4 +2052,50 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TFTPList.ParseMLSDLines;
|
|
|
|
+var
|
|
|
|
+ flr: TFTPListRec;
|
|
|
|
+ i: Integer;
|
|
|
|
+ s: string;
|
|
|
|
+ ye,mo,da,ho,mi,se: Word;
|
|
|
|
+
|
|
|
|
+ function GetPart(const ALine, AName: string): string;
|
|
|
|
+ var
|
|
|
|
+ i, j: Integer;
|
|
|
|
+ begin
|
|
|
|
+ i := Pos(AnsiUpperCase(AName), AnsiUpperCase(ALine));
|
|
|
|
+ i := i + Length(AName);
|
|
|
|
+ j := PosEx(';', ALine, i);
|
|
|
|
+ if j < 1 then j := MaxInt;
|
|
|
|
+ Result := Copy(ALine, i, j-i);
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+begin
|
|
|
|
+ for i := 0 to Lines.Count - 1 do
|
|
|
|
+ begin
|
|
|
|
+ s := GetPart(Lines[i], 'modify=');
|
|
|
|
+ ye := StrToIntDef(Copy(s, 1, 4), 1970);
|
|
|
|
+ mo := StrToIntDef(Copy(s, 5, 2), 1);
|
|
|
|
+ da := StrToIntDef(Copy(s, 7, 2), 1);
|
|
|
|
+ ho := StrToIntDef(Copy(s, 9, 2), 0);
|
|
|
|
+ mi := StrToIntDef(Copy(s, 11, 2), 0);
|
|
|
|
+ se := StrToIntDef(Copy(s, 13, 2), 0);
|
|
|
|
+
|
|
|
|
+ flr := TFTPListRec.create;
|
|
|
|
+ flr.OriginalLine := Lines[i];
|
|
|
|
+ { osetrime kraviny, protoze autori FTP serveru nerespektuji RFC, tykajici se MLSD prikazu }
|
|
|
|
+ try
|
|
|
|
+ flr.FFileTime := EncodeDateTime(ye,mo,da,ho,mi,se, 0);
|
|
|
|
+ except
|
|
|
|
+ flr.FFileTime := EncodeDateTime(1970,1,1,0,0,0, 0);
|
|
|
|
+ end;
|
|
|
|
+ flr.FDirectory := AnsiSameText(GetPart(Lines[i], 'type='), 'dir') or AnsiSameText(GetPart(Lines[i], 'type='), 'cdir');
|
|
|
|
+ flr.FFileSize := StrToInt64Def(GetPart(Lines[i], 'size='), 0);
|
|
|
|
+ flr.FPermission := GetPart(Lines[i], 'mode=');
|
|
|
|
+ s := flr.FPermission;
|
|
|
|
+ flr.FFileName := GetPart(Lines[i], '; ');
|
|
|
|
+ Flist.Add(flr);
|
|
|
|
+ end;
|
|
|
|
+end;
|
|
|
|
+
|
|
end.
|
|
end.
|