⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idftplistparsemvs.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence                                   }
{ Team Coherence is Copyright 2002 by Quality Software Components      }
{                                                                      }
{ For further information / comments, visit our WEB site at            }
{ http://www.TeamCoherence.com                                         }
{**********************************************************************}
{}
{ $Log:  16182: IdFTPListParseMVS.pas
{
{   Rev 1.7    10/26/2004 9:46:36 PM  JPMugaas
{ Updated refs.
}
{
{   Rev 1.6    6/8/2004 12:42:22 PM  JPMugaas
{ Fixed an Invalid Type Cast problem.
}
{
{   Rev 1.5    4/19/2004 5:05:36 PM  JPMugaas
{ Class rework Kudzu wanted.
}
{
{   Rev 1.4    2004.02.03 5:45:24 PM  czhower
{ Name changes
}
{
    Rev 1.3    10/19/2003 3:36:02 PM  DSiders
  Added localization comments.
}
{
{   Rev 1.2    4/7/2003 04:03:58 PM  JPMugaas
{ User can now descover what output a parser may give.
}
{
{   Rev 1.1    2/19/2003 05:53:20 PM  JPMugaas
{ Minor restructures to remove duplicate code and save some work with some
{ formats.  The Unix parser had a bug that caused it to give a False positive
{ for Xercom MicroRTOS.
}
{
{   Rev 1.0    2/19/2003 06:04:36 AM  JPMugaas
{ IBM MVS parser has been ported to new design.
}
unit IdFTPListParseMVS;

interface
uses classes, IdFTPList, IdFTPListParseBase, IdFTPListTypes, IdTStrings;
{
This should work with IBM MVS, OS/390, and z/OS.

Note that in z/OS, there is no need for a parser for the HFS (hierarchical file
system) because the server would present a Unix-like list for that file system.

}
type
  TIdJESJobStatus = (IdJESNotApplicable, IdJESReceived, IdJESHold, IdJESRunning, IdJESOuptutAvailable);

  TIdMVSFTPListItem = class(TIdRecFTPListItem)
  protected
    FBlockSize : Integer;
    FMigrated : Boolean;
    FVolume : String;
    FUnit : String;
    FOrg : String; //data set organization
        FMVSNumberExtents: Integer;
    FMVSNumberTracks: Integer;
  public
    constructor Create(AOwner: TCollection); override;
    property Migrated : Boolean read FMigrated write FMigrated;
    property BlockSize : Integer read FBlockSize write FBlockSize;
    property RecLength;
    property RecFormat;
    property NumberRecs;
    property Volume : String read FVolume write FVolume;
    //can't be unit because that's a reserved word
    property Units : String read FUnit write FUnit;
    property Org : String read FOrg write FOrg; //data set organization
    property NumberExtents: Integer read FMVSNumberExtents write FMVSNumberExtents;
    property NumberTracks: Integer read FMVSNumberTracks write FMVSNumberTracks;
  end;
  TIdMVSJESFTPListItem = class(TIdOwnerFTPListItem)
  protected
    FMVSJobStatus : TIdJESJobStatus;
    FMVSJobSpoolFiles : Integer;
  public
    constructor Create(AOwner: TCollection); override;
    property JobStatus : TIdJESJobStatus read FMVSJobStatus write FMVSJobStatus;
    property JobSpoolFiles : Integer read FMVSJobSpoolFiles write FMVSJobSpoolFiles;
  end;
  TIdMVSJESIntF2FTPListItem = class(TIdOwnerFTPListItem)
  protected
    FJobStatus : TIdJESJobStatus;
    FJobSpoolFiles : Integer;
    FDetails : TIdStrings;
    procedure SetDetails(AValue : TIdStrings);
  public
    constructor Create(AOwner: TCollection); override;
    destructor Destroy; override;
    property Details : TIdStrings read FDetails write SetDetails;
    property JobStatus : TIdJESJobStatus read FJobStatus write FJobStatus;
    property JobSpoolFiles : Integer read FJobSpoolFiles write FJobSpoolFiles;
  end;

  TIdFTPLPMVS = class(TIdFTPListBaseHeader)
  protected
    class function MakeNewItem(AOwner : TIdFTPListItems)  : TIdFTPListItem; override;
    class function IsHeader(const AData: String): Boolean; override;
    class function ParseLine(const AItem : TIdFTPListItem; const APath : String=''): Boolean; override;
  public
    class function GetIdent : String; override;
  end;
  TIdFTPLPMVSPartitionedDataSet = class(TIdFTPListBaseHeader)
  protected
    class function IsHeader(const AData: String): Boolean;  override;
    class function ParseLine(const AItem : TIdFTPListItem; const APath : String=''): Boolean; override;
  public
    class function GetIdent : String; override;
  end;
  //Jes queues
  TIdFTPLPMVSJESInterface1 = class(TIdFTPListBase)
  protected
    class function MakeNewItem(AOwner : TIdFTPListItems)  : TIdFTPListItem; override;
    class function IsMVS_JESNoJobsMsg(const AData: String): Boolean; virtual;
    class function ParseLine(const AItem : TIdFTPListItem; const APath : String=''): Boolean; override;
  public
    class function GetIdent : String; override;
    class function CheckListing(AListing : TIdStrings; const ASysDescript : String =''; const ADetails : Boolean = True): boolean; override;
    class function ParseListing(AListing : TIdStrings; ADir : TIdFTPListItems) : boolean; override;
  end;
  TIdFTPLPMVSJESInterface2 = class(TIdFTPListBase)
  protected
    class function MakeNewItem(AOwner : TIdFTPListItems)  : TIdFTPListItem; override;
    class function IsMVS_JESIntF2Header(const AData: String): Boolean;
    class function ParseLine(const AItem : TIdFTPListItem; const APath : String=''): Boolean; override;
  public
    class function GetIdent : String; override;
    class function CheckListing(AListing : TIdStrings; const ASysDescript : String =''; const ADetails : Boolean = True): boolean; override;
    class function ParseListing(AListing : TIdStrings; ADir : TIdFTPListItems) : boolean; override;
  end;

implementation

uses
  IdGlobal, IdFTPCommon, IdGlobalProtocols, IdStrings, SysUtils;

{ TIdFTPLPMVS }

class function TIdFTPLPMVS.GetIdent: String;
begin
  Result := 'MVS';  {do not localize}
end;

class function TIdFTPLPMVS.IsHeader(const AData: String): Boolean;
//Volume Unit    Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname
//Volume Unit  Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname
//Volume Unit     Date  Ext Used Recfm Lrecl BlkSz Dsorg Dsname
var lvolp, lunp, lrefp, lextp, lusedp,
    lrecp, lBlkSz, lDsorg, lDsnp : Integer;

{Note that this one is a little more difficult because I could not find
 a MVS machine that accepts anonymous FTP.  So I have to do the best I can
 with some old posts where people had posted dir structures they got from FTP.}
begin
  lvolp := IndyPos('Volume',AData);  {Do not translate}
  lunp := IndyPos('Unit',AData);    {Do not translate}
  lrefp := IndyPos('Referred',AData);  {Do not translate}
  if lrefp = 0 then
  begin
    lrefp := IndyPos('Date',AData);  {Do not translate}
  end;
  lextp := IndyPos('Ext',AData);     {Do not translate}
  lusedp := IndyPos('Used',AData);   {Do not translate}
  lrecp := IndyPos('Lrecl',AData);   {Do not translate}
  lBlkSz := IndyPos('BlkSz',AData);   {Do not translate}
  lDsorg := IndyPos('Dsorg',AData);    {Do not translate}
  lDsnp := IndyPos('Dsname',AData);   {Do not translate}
  Result := (lvolp <> 0) and (lunp > lvolp) and
            (lrefp > lunp) and (lextp > lrefp) and
            (lusedp > lextp) and (lrecp > lusedp) and
            (lBlkSz > lrecp) and (lDsorg > lBlkSz) and
            (lDsnp > lDsorg);
end;

class function TIdFTPLPMVS.MakeNewItem(
  AOwner: TIdFTPListItems): TIdFTPListItem;
begin
  Result :=  TIdMVSFTPListItem.Create(AOwner);
end;

class function TIdFTPLPMVS.ParseLine(const AItem: TIdFTPListItem;
  const APath: String): Boolean;
{Much of this is based on a thread at:

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=utf-8&selm=DLspv2.G2w%40epsilon.com&rnum=2

and

http://www.snee.com/bob/opsys/part6mvs.pdf

Note:  Thread concerning MVS Data Set Size
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=utf-8&threadm=jcmorris.767551300%40mwunix&rnum=15&prev=/groups%3Fq%3DMVS%2BRecfm%2BV%26start%3D10%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3Dutf-8%26selm%3Djcmorris.767551300%2540mwunix%26rnum%3D15
http://groups.google.com/groups?q=MVS+Recfm+V&start=10&hl=en&lr=&ie=UTF-8&oe=utf-8&selm=jcmorris.767551300%40mwunix&rnum=15

http://www.isc.ucsb.edu/tsg/ftp-to-mvs.html
http://www.lsu.edu/ocs/tsc/os390doc/mvsftp.html
}

  function IsMVSMigrated(const AData : String) : Boolean;
  begin
    Result := (Copy(AData,1,8) = 'Migrated') or {do not localize}
      ( Copy(AData,1,6) = 'MIGRAT');  {do not localize}
  end;

  function IsPseudoDir(const AData : String) : Boolean;
  begin
  //In newer implementations, a directory mode is available, see if
  //item is a Pseudo-directory
    Result := (Copy(AData,1,16)='Pseudo Directory');  {do not localize}
  end;

  function CanGetAttributes(const AData : String) : Boolean;
  begin
    Result := (IsMVSMigrated(AData)=False) and ( Copy(AData,1,5) <> 'Error')  {do not localize}
      and (IsPseudoDir(AData)=False);
  end;

var i : Integer;
    s : TIdStrings;
    LI : TIdMVSFTPListItem;
//NOTE:  File Size is not supported at all
//because the file size is calculated with something like this:
//      BlkSz * Blks/Trk * Trks
//but you can not get MVS DEVINFO macro so you do not have enough information
//to work with.
begin
  LI := AItem as TIdMVSFTPListItem;
  if IsMVSMigrated(AItem.Data) then
  begin
    LI.Migrated := True;
  end;
  if IsPseudoDir(AItem.Data) then
  begin
    LI.ItemType :=  ditDirectory;
  end;
  if CanGetAttributes(AItem.Data) then
  begin
    s := TIdStringList.Create;
    try
      SplitColumns(AItem.Data,s);
      if s.Count >0 then
      begin
        LI.Volume := s[0];
      end;
      if s.Count >1 then
      begin
        LI.Units := s[1];
      end;
      if s.Count >2 then
      begin
        //Sometimes, the Referred Column will contain a date.
        //e.g. **NONE**
        //Documented in: Communications Server for z/OS V1R2 TCP/IP Implementation Guide Volume 2: UNIX Applications
        //URL: http://www.redbooks.ibm.com/pubs/pdfs/redbooks/sg245228.pdf
        if IsNumeric(s[2][1]) then
        begin
          LI.ModifiedDate :=  MVSDate(s[2]);
        end;
      end;
      if s.Count >3 then
      begin
        LI.NumberExtents := StrToIntDef(s[3],0);
      end;
      if s.Count >4 then
      begin
        LI.NumberTracks := StrToIntDef(s[4],0);
      end;
      if s.Count >5 then
      begin
        LI.RecFormat := s[5];
      end;
      if s.Count >6 then
      begin
        LI.RecLength := StrToIntDef(s[6],0);
      end;
      if s.Count >7 then
      begin
        LI.BlockSize := StrToIntDef(s[7],0);
      end;
      if s.Count >8 then
      begin
        LI.Org := s[8];
        if (LI.Org = 'PO') then {do not localize}
        begin
          LI.ItemType :=  ditDirectory;
        end
        else
        begin
          LI.ItemType :=  ditFile;
        end;
      end;
    finally
      FreeAndNil(s);
    end;
  end;
  //Note that spaces are illegal in MVS file names (Data set namess)
  //http://www.snee.com/bob/opsys/part6mvs.pdf
  //but for filenames enclosed in '', we should tolorate spaces.
  if (AItem.Data<>'') and (AItem.Data[Length(AItem.Data)]='''') then
  begin
    i := IndyPos('''',AItem.Data)+1;
    AItem.FileName := Copy(AItem.Data,i,Length(AItem.Data)-i-1);
  end
  else
  begin
    i := RPos(' ',AItem.Data) +1;
    AItem.FileName := Copy(AItem.Data,i,Length(AItem.Data));
  end;
  Result := True;
end;

{ TIdFTPLPMVSPartitionedDataSet }

class function TIdFTPLPMVSPartitionedDataSet.GetIdent: String;
begin
  Result := 'MVS:  Partitioned Data Set'; {do not localize}
end;

class function TIdFTPLPMVSPartitionedDataSet.IsHeader(
  const AData: String): Boolean;
//Name     VV.MM  Created     Changed     Size  Init   Mod   Id
//
//or
//
//Name      Size   TTR   Alias-of AC --------- Attributes --------- Amode Rmode
//if there are loaded moduals

var LPName,
  LPSize : Integer;

begin
  LPName := IndyPos('Name', AData); {do not localize}
  LPSize := IndyPos('Size', AData); {do not localize}
  Result := (LPName>0) and (LPSize > LPName);
end;

class function TIdFTPLPMVSPartitionedDataSet.ParseLine(
  const AItem: TIdFTPListItem; const APath: String): Boolean;
//MVS Particianed data sets must be treated differently than
//the regular MVS catalog.
var s : TIdStrings;

//NOTE:  File Size is not supported at all.  Size is usually size in records, not bytes
//  This is based on stuff at:
// http://publibz.boulder.ibm.com:80/cgi-bin/bookmgr_OS390/BOOKS/F1AA2032/1.5.15?SHELF=&DT=20001127174124
// and
// http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=utf-8&selm=DLspv2.G2w%40epsilon.com&rnum=2

//From Google: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=4e7k0p%24t1v%40blackice.winternet.com&rnum=6&prev=/groups%3Fq%3DMVS%2BPartitioned%2Bdata%2Bset%2Bdirectory%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D4e7k0p%2524t1v%2540blackice.winternet.com%26rnum%3D6

{
From: Ralph Goers (rgoer@rgoer.candle.com)
Subject: Re: FTP -- VM, MVS, VMS Questions 

 	
View this article only	
Newsgroups: comp.os.os2.networking.tcp-ip
Date: 1996/01/27 
	

In message <4e7k0p$t1v@blackice.winternet.com> - frickson@gibbon.com (John C. F

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -