restemplate/indy/Protocols/IdFTPListParseNCSAForDOS.pas

200 lines
5.3 KiB
Plaintext
Raw Normal View History

{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.6 12/5/2004 5:06:30 PM JPMugaas
Tightened the detection for NCSA Telnet FTP Server for DOS. The parser was
causing problems with SuperTCP because the formats are similar. By
preventing SuperTCP from being detected, LongFilenames were not parsed in
SuperTCP running on Windows 2000.
Rev 1.5 10/26/2004 9:51:14 PM JPMugaas
Updated refs.
Rev 1.4 6/5/2004 4:45:22 PM JPMugaas
Reports SizeAvail=False for directories in a list. As per the dir format.
Rev 1.3 4/19/2004 5:05:58 PM JPMugaas
Class rework Kudzu wanted.
Rev 1.2 2004.02.03 5:45:32 PM czhower
Name changes
Rev 1.1 10/19/2003 3:36:04 PM DSiders
Added localization comments.
Rev 1.0 2/19/2003 10:13:38 PM JPMugaas
Moved parsers to their own classes.
}
unit IdFTPListParseNCSAForDOS;
interface
{$i IdCompilerDefines.inc}
uses
Classes,
IdFTPList, IdFTPListParseBase;
type
TIdNCSAforDOSFTPListItem = class(TIdFTPListItem);
TIdFTPLPNCSAforDOS = class(TIdFTPListBaseHeader)
protected
class function MakeNewItem(AOwner : TIdFTPListItems) : TIdFTPListItem; override;
class function IsHeader(const AData: String): Boolean; override;
class function IsFooter(const AData : String): Boolean; override;
class function ParseLine(const AItem : TIdFTPListItem; const APath : String = ''): Boolean; override;
public
class function CheckListing(AListing : TStrings; const ASysDescript : String = ''; const ADetails : Boolean = True): Boolean; override;
class function GetIdent : String; override;
end;
// RLebeau 2/14/09: this forces C++Builder to link to this unit so
// RegisterFTPListParser can be called correctly at program startup...
{$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT}
{$HPPEMIT LINKUNIT}
{$ELSE}
{$HPPEMIT '#pragma link "IdFTPListParseNCSAForDOS"'}
{$ENDIF}
implementation
uses
IdGlobal, IdFTPCommon, IdGlobalProtocols, SysUtils;
{ TIdFTPLPNCSAforDOS }
class function TIdFTPLPNCSAforDOS.CheckListing(AListing: TStrings;
const ASysDescript: String; const ADetails: Boolean): Boolean;
var
s : TStrings;
LData : String;
i : Integer;
begin
Result := False;
if AListing.Count > 0 then
begin
//we have to loop through because there is a similar format
//in SuperTCP but that one has an additional field with spaces
//for long filenames.
for i := 0 to AListing.Count-2 do
begin
LData := AListing[i];
s := TStringList.Create;
try
SplitDelimitedString(LData, s, True);
if s.Count = 4 then
begin
Result := ((s[1] = '<DIR>') or IsNumeric(s[1])) and {do not localize}
IsMMDDYY(s[2], '-') and IsHHMMSS(s[3], ':') and {do not localize}
ExcludeQVNET(LData);
end;
finally
FreeAndNil(s);
end;
if not Result then begin
Break;
end;
end;
Result := IsFooter(AListing[AListing.Count-1]);
end;
end;
class function TIdFTPLPNCSAforDOS.GetIdent: String;
begin
Result := 'NCSA for MS-DOS (CU/TCP)'; {do not localize}
end;
class function TIdFTPLPNCSAforDOS.IsFooter(const AData: String): Boolean;
var
LWords : TStrings;
begin
Result := False;
LWords := TStringList.Create;
try
SplitDelimitedString(ReplaceAll(AData, '-', ' '), LWords, True);
while LWords.Count > 2 do begin
LWords.Delete(0);
end;
if LWords.Count = 2 then begin
Result := (LWords[0] = 'Bytes') and (LWords[1] = 'Available'); {do not localize}
end;
finally
FreeAndNil(LWords);
end;
end;
class function TIdFTPLPNCSAforDOS.IsHeader(const AData: String): Boolean;
begin
Result := False;
end;
class function TIdFTPLPNCSAforDOS.MakeNewItem(AOwner: TIdFTPListItems): TIdFTPListItem;
begin
Result := TIdNCSAforDOSFTPListItem.Create(AOwner);
end;
class function TIdFTPLPNCSAforDOS.ParseLine(const AItem: TIdFTPListItem;
const APath: String): Boolean;
var
LBuf, LPt : String;
begin
LBuf := AItem.Data;
{filename - note that a space is illegal in MS-DOS so this should be safe}
AItem.FileName := Fetch(LBuf);
{type or size}
LBuf := Trim(LBuf);
LPt := Fetch(LBuf);
if LPt = '<DIR>' then {do not localize}
begin
AItem.ItemType := ditDirectory;
AItem.SizeAvail := False;
end else
begin
AItem.ItemType := ditFile;
AItem.Size := IndyStrToInt64(LPt, 0);
end;
//time stamp
if LBuf <> '' then
begin
LBuf := Trim(LBuf);
LPt := Fetch(LBuf);
if LPt <> '' then
begin
//Date
AItem.ModifiedDate := DateMMDDYY(LPt);
LBuf := Trim(LBuf);
LPt := Fetch(LBuf);
if LPt <> '' then begin
AItem.ModifiedDate := AItem.ModifiedDate + TimeHHMMSS(LPt);
end;
end;
end;
Result := True;
end;
initialization
RegisterFTPListParser(TIdFTPLPNCSAforDOS);
finalization
UnRegisterFTPListParser(TIdFTPLPNCSAforDOS);
end.