{ $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] = '') 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 = '' 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.