240 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|   $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.0    12/8/2004 8:45:02 AM  JPMugaas
 | |
| }
 | |
| 
 | |
| unit IdFTPListParseUnisysClearPath;
 | |
| 
 | |
| {
 | |
|   Unisys ClearPath (MCP and OS/2)
 | |
|   DIRECTORY_FORMAT=NATIVE
 | |
| 
 | |
|   Much of this is based on:
 | |
| 
 | |
|   ClearPath Enterprise Servers
 | |
|   FTP Services for ClearPath
 | |
|   OS 2200 User's Guide
 | |
|   ClearPath OS 2200 Release 8.0 January 2003
 | |
|   © 2003 Unisys Corporation.
 | |
|   All rights reserved.
 | |
| 
 | |
|   and
 | |
| 
 | |
|   ClearPath Enterprise Servers
 | |
|   TCP/IP Distributed Systems Services Operations Guide
 | |
|   ClearPath MCP Release 9.0 April 2004
 | |
|   © 2004 Unisys Corporation.
 | |
|   All rights reserved.
 | |
| 
 | |
|   With a sample showing a multiline response from:
 | |
| 
 | |
|   http://article.gmane.org/gmane.text.xml.cocoon.devel/24912
 | |
| 
 | |
|   This parses data in this form:
 | |
|   ===
 | |
|   Report for: (UC)A ON PACK
 | |
|   A                       SEQDATA    84 03/08/1998  15:32
 | |
|   A/B                     SEQDATA    84 06/09/1998  12:03
 | |
|   A/B/C                   SEQDATA    84 06/09/1998  12:03
 | |
|   A/C                     SEQDATA    84 06/09/1998  12:03
 | |
|   A/C/C                   SEQDATA    84 06/09/1998  12:04
 | |
|   A/C/C/D                 SEQDATA    84 06/09/1998  12:04
 | |
|             6 Files     504 Octets
 | |
|   ===
 | |
| 
 | |
|   The parserm only support DIRECTORY_FORMAT=NATIVE which is the default on that server.
 | |
|   DIRECTORY_FORMAT=STANDARD does not need be supported because that is probably listed
 | |
|   in Unix format. If not, we'll deal with it given some data samples.
 | |
| }
 | |
| 
 | |
| interface
 | |
| 
 | |
| {$i IdCompilerDefines.inc}
 | |
| 
 | |
| uses
 | |
|   Classes,
 | |
|   IdFTPList, IdFTPListParseBase, IdFTPListTypes;
 | |
| 
 | |
| type
 | |
|   TIdUnisysClearPathFTPListItem = class(TIdCreationDateFTPListItem)
 | |
|   protected
 | |
|     FFileKind : String;
 | |
|   public
 | |
|     property FileKind : String read FFileKind write FFileKind;
 | |
|   end;
 | |
| 
 | |
|   TIdFTPLPUnisysClearPath = class(TIdFTPListBaseHeader)
 | |
|   protected
 | |
|     class function IsContinuedLine(const AData: String): Boolean;
 | |
|     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 ParseListing(AListing : TStrings; ADir : TIdFTPListItems) : 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 "IdFTPListParseUnisysClearPath"'}
 | |
|   {$ENDIF}
 | |
| 
 | |
| implementation
 | |
| 
 | |
| uses
 | |
|   IdGlobal, IdFTPCommon, IdGlobalProtocols, IdStrings, SysUtils;
 | |
| 
 | |
| { TIdFTPLPUnisysClearPath }
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.GetIdent: String;
 | |
| begin
 | |
|   Result := 'Unisys Clearpath'; {Do not localize}
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.IsContinuedLine(const AData: String): Boolean;
 | |
| begin
 | |
|   Result := TextStartsWith(AData, ' '); {Do not localize}
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.IsFooter(const AData: String): Boolean;
 | |
| var
 | |
|   s : TStrings;
 | |
| begin
 | |
|   Result := False;
 | |
|   s := TStringList.Create;
 | |
|   try
 | |
|     SplitDelimitedString(AData, s, True);
 | |
|     if s.Count = 4 then
 | |
|     begin
 | |
|       if (s[1] = 'Files') or (s[1] = 'File') then begin {Do not localize}
 | |
|         Result := (s[3] = 'Octets') or (s[3] = 'Octet');  {Do not localize}
 | |
|       end;
 | |
|     end;
 | |
|   finally
 | |
|     FreeAndNil(s);
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.IsHeader(const AData: String): Boolean;
 | |
| var
 | |
|   s : TStrings;
 | |
| begin
 | |
|   Result := False;
 | |
|   s := TStringList.Create;
 | |
|   try
 | |
|     SplitDelimitedString(AData, s, True);
 | |
|     if s.Count > 2 then begin
 | |
|       Result := (s[0] = 'Report') and (s[1] = 'for:');
 | |
|     end;
 | |
|   finally
 | |
|     FreeAndNil(s);
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.MakeNewItem(AOwner: TIdFTPListItems): TIdFTPListItem;
 | |
| begin
 | |
|   Result := TIdUnisysClearPathFTPListItem.Create(AOwner);
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.ParseLine(const AItem: TIdFTPListItem;
 | |
|   const APath: String): Boolean;
 | |
| var
 | |
|   s : TStrings;
 | |
|   LI : TIdUnisysClearPathFTPListItem;
 | |
| begin
 | |
|   Result := False;
 | |
|   LI := AItem as TIdUnisysClearPathFTPListItem;
 | |
|   LI.ItemType := ditFile;
 | |
|   s := TStringList.Create;
 | |
|   try
 | |
|     SplitDelimitedString(LI.Data, s, True);
 | |
|     if s.Count > 4 then
 | |
|     begin
 | |
|       LI.FileName := s[0];
 | |
|       LI.FileKind := s[1];
 | |
|       //size
 | |
|       if IsNumeric(s[2]) then
 | |
|       begin
 | |
|         LI.Size := IndyStrToInt(s[2], 0);
 | |
|         AItem.SizeAvail := True;
 | |
|         //creation date
 | |
|         if IsMMDDYY(s[3], '/') then {Do not localize}
 | |
|         begin
 | |
|           LI.CreationDate := DateMMDDYY(s[3]);
 | |
|           if IsHHMMSS(s[4], ':') then {Do not localize}
 | |
|           begin
 | |
|             LI.CreationDate := LI.CreationDate + TimeHHMMSS(s[4]);
 | |
|             Result := True;
 | |
|           end;
 | |
|         end;
 | |
|       end;
 | |
|       s.Clear;
 | |
|       //remove path from localFileName
 | |
|       SplitDelimitedString(LI.FileName, s, True, '/'); {Do not localize}
 | |
|       if s.Count > 0 then begin
 | |
|         LI.LocalFileName := s[s.Count-1];
 | |
|       end else begin
 | |
|         Result := False;
 | |
|       end;
 | |
|     end;
 | |
|   finally
 | |
|     FreeAndNil(s);
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| class function TIdFTPLPUnisysClearPath.ParseListing(AListing: TStrings;
 | |
|   ADir: TIdFTPListItems): Boolean;
 | |
| var
 | |
|   i : Integer;
 | |
|   LItem : TIdFTPListItem;
 | |
| begin
 | |
|   for i := 0  to AListing.Count-1 do
 | |
|   begin
 | |
|     if not IsWhiteString(AListing[i]) then
 | |
|     begin
 | |
|       if not (IsHeader(AListing[i]) or IsFooter(AListing[i])) then
 | |
|       begin
 | |
|         if (not IsContinuedLine(AListing[i])) then //needed because some VMS computers return entries with multiple lines
 | |
|         begin
 | |
|           LItem := MakeNewItem(ADir);
 | |
|           LItem.Data := UnfoldLines(AListing[i], i, AListing);
 | |
|           Result := ParseLine(LItem);
 | |
|           if not Result then begin
 | |
|             FreeAndNil(LItem);
 | |
|             Exit;
 | |
|           end;
 | |
|         end;
 | |
|       end;
 | |
|     end;
 | |
|   end;
 | |
|   Result := True;
 | |
| end;
 | |
| 
 | |
| initialization
 | |
|   RegisterFTPListParser(TIdFTPLPUnisysClearPath);
 | |
| finalization
 | |
|   UnRegisterFTPListParser(TIdFTPLPUnisysClearPath);
 | |
| 
 | |
| end.
 |