如何使用QTCP用户(COMMAND PROMPT)识别和使用其他用户的假脱机文件?

时间:2016-11-23 06:29:49

标签: ftp command-prompt ibm-midrange rpgle rpg

这里我使用(FTP Servername)命令从命令提示符连接到AS400计算机。
我使用命令提示符执行的每个操作都是在后台使用 QTCP 用户提交的。

以下是主要关注点:

  • 我有一个生成假脱机文件的命令,其名称我用于从命令提示符登录。
  • 我想使用该假脱机文件内容并复制到我的某个库中,所有这些都可以通过CPYSPLF命令完成,但如何使用 QTCP 用户执行相同操作。
  • 我的主要要求是使用命令提示符而不是AS400终端执行CL命令操作。

3 个答案:

答案 0 :(得分:2)

@ user2338816对使用QSPRILSP API提出了一个很好的观点。但是,如果这不能提供您所需要的,那么您可以使用列表假脱机文件(QUSLSPL)API来查找它。

在开始之前,请查看我在这篇文章中的回答:Programming IBM iSeries API QUSLSPL in C# 对于使用QUSLSPL API和用户空间有一个很好的入门,尽管它在C#中进行了讨论。以下是您在RPG IV中使用该API的方法:

首先,您需要对API调用进行原型设计。

列出假脱机文件

DQUSLSPL          PR                  EXTPGM('QUSLSPL')    
D UserSpaceName                       Like(UserSpace) CONST
D FormatName                     8    CONST                
D UserName                      10    CONST                
D QualOutQName                  20    CONST                
D FormType                      10    CONST                
D UsrDta                        10    CONST                
D ErrorCode                           Like(APIError)       
D QualJobName                   26    CONST                
D KeyFields                      1    CONST                
D KeyFieldsNum                  10i 0 CONST                
D ASP                           10i 0 CONST                
D JobSystemName                  8    CONST                
D StartCRDate                    7    CONST                
D StartCRTime                    6    CONST                
D EndCRDate                      7    CONST                
D EndCRTime                      6    CONST                

创建用户空间

DCreateUserSpace  PR                  ExtPgm('QUSCRTUS')   
D Name                                Like(UserSpace) CONST
D ExtendedAttrib                10    CONST                
D InitialSize                   10i 0 CONST                
D InitialValue                   1    CONST                
D PublicAuth                    10    CONST                
D Text                          50    CONST                
D Replace                       10    CONST                
D ErrorCode                           Like(APIError)       

从用户空间检索数据

DRtvUserSpace     PR                  ExtPgm('QUSRTVUS')   
D UserSpaceName                       Like(UserSpace) CONST
D StartingPos                   10i 0 CONST                
D LengthToReturn                10i 0 CONST                
D ReceiverVar                         Like(SPLF0300)       
D ErrorCode                           Like(APIError)       

删除用户空间

DDeleteUserSpace  PR                  ExtPgm('QUSDLTUS')   
D Name                                Like(UserSpace) CONST
D ErrorCode                           Like(APIError)       

我喜欢创建一个字段来存储用户空间名称,因此我不必一直输入:

DUserSpace        S             20    INZ('SPLFSPACE QTEMP     ')

调用API时,您需要以下API错误数据结构:

DAPIError         DS                  Qualified
D AEBytesProv                   10i 0 Inz(117) 
D AEBytesAvail                  10i 0 Inz(0)   
D AEExceptionID                  7             
D AEReserved                     1             
D AEExceptData                  80             

最后,这是一个数据结构,其中包含返回的每个假脱机文件的信息:

DSPLF0300         DS                  Qualified
D JobName                       10             
D UserName                      10             
D JobNumber                      6             
D SplfName                      10             
D SplfNumber                    10i 0          
D SplfStatus                    10i 0          
D DateCreated                    7             
D TimeCreated                    6             
D SplfSchedule                   1             
D SplfSystemName                10             
D UserData                      10             
D FormType                      10             
D OutQName                      10             
D OutQLib                       10             
D ASP                           10i 0          
D SplfSize                      10i 0          
D SplfSizeMult                  10i 0          
D TotalPages                    10i 0          
D CopiesLeft                    10i 0          
D Priority                       1             
D Reserved                       3             
D Internalppji                  10i 0          

List Spooled Files API的参数多于其他答案所需的参数,我在上面的原型中使用了它们。由于您无法将假脱机文件名指定为要搜索的参数,因此我们可以指定创建日期和时间范围,以帮助限制返回的结果。

所以实际编码很简单。您列出了QTCP拥有的所有假脱机文件,比如最近5分钟。查看列表,看看哪些名为QPJOBLOG。抓住最近的一个。

DCounter          S             10i 0                                     
DStartPoint       S             10i 0                                     
DFiveMinutesAgo   S               Z                                       
DDateStart        S              7                                        
DTimeStart        S              6                                        

DLastSPLF         DS                  Qualified                           
D Job                           26                                        
D SplfName                      10                                        
D SplfNumber                    10i 0                                     
D Date                           7                                        
D Time                           6                                        

 /free                                                                    
  FiveMinutesAgo = %TimeStamp()-%Minutes(5);                              
  DateStart=%Char(%Date(FiveMinutesAgo):*CYMD0);                          
  TimeStart=%Char(%Time(FiveMinutesAgo):*HMS0);                           
  CreateUserSpace(UserSpace:*Blank:1:x'00':'*ALL':*Blank:'*YES':APIError);
  QUSLSPL(UserSpace:'SPLF0300':'QTCP':'*ALL':'*ALL':'*ALL':APIError:  
          *Blanks:*Blank:0:0:'*CURRENT':DateStart:TimeStart:'*LAST':      
          *Blanks);                                                       
  RtvUserSpace(UserSpace:1:%Len(ListInfo):ListInfo:APIError);             
  Counter = 0;                                                          
  StartPoint = ListInfo.ListDataOfs+1;                                  

  DoW Counter<ListInfo.ListEntryCount;                                  
    RtvUserSpace(UserSpace:StartPoint:%Len(SPLF0300):SPLF0300:APIError);
    If SPLF0300.SplfName='QPJOBLOG' And                                 
       SPLF0300.DateCreated>=LastSplf.Date And                          
       SPLF0300.TimeCreated>=LastSplf.Time;                             
      LastSplf.Job = SPLF0300.JobName +                                 
                     SPLF0300.UserName +                                
                     SPLF0300.JobNumber;                                
      LastSplf.SplfName = SPLF0300.SplfName;                            
      LastSplf.SplfNumber = SPLF0300.SplfNumber;                        
      LastSplf.Date = SPLF0300.DateCreated;                             
      LastSplf.Time = SPLF0300.TimeCreated;                             
    EndIf;                                                              
    StartPoint=StartPoint+ListInfo.EntrySize;                           
    Counter=Counter+1;                                                  
  EndDo;                                                                

  DeleteUserSpace(UserSpace:APIError);                                  

我的例子使用5分钟,但这可能太长了一次。试验看哪些适合你。

所有这些都必须进入一个新程序,然后返回CPYSPLF命令所需的信息。实际上,您可以为此程序构建并执行CPYSPLF命令,以便您的FTP脚本更简单。

答案 1 :(得分:2)

仍然没有创建最后假脱机文件的检索标识(QSPRILSP)API的示例,因此我将添加一个。编译这样的东西:

pgm    ( +
         &pSplFName   +
         &pJobName    +
         &pUserName   +
         &pJobNbr     +
         &pSplFNbr    +
       )

   dcl   &pSplFName   *char    10
   dcl   &pJobName    *char    10
   dcl   &pUserName   *char    10
   dcl   &pJobNbr     *char     6
   dcl   &pSplFNbr    *int


   dcl   &szRcvVar    *int            value( 70 )

   dcl   &errCod      *char   128
   dcl   &errRtn      *int            stg( *defined ) defvar( &errCod    1 )
   dcl   &errAvl      *int            stg( *defined ) defvar( &errCod    5 )
   dcl   &errMsgID    *char     7     stg( *defined ) defvar( &errCod    9 )
   dcl   &errMsgDta   *char    80     stg( *defined ) defvar( &errCod   17 )

   dcl   &fSPRL0100   *char    70
   dcl   &bytRtn      *int            stg( *defined ) defvar( &fSPRL0100   1 )
   dcl   &bytAvl      *int            stg( *defined ) defvar( &fSPRL0100   5 )
   dcl   &splFName    *char    10     stg( *defined ) defvar( &fSPRL0100   9 )
   dcl   &jobName     *char    10     stg( *defined ) defvar( &fSPRL0100  19 )
   dcl   &userName    *char    10     stg( *defined ) defvar( &fSPRL0100  29 )
   dcl   &jobNbr      *char     6     stg( *defined ) defvar( &fSPRL0100  39 )
   dcl   &splFNbr     *int            stg( *defined ) defvar( &fSPRL0100  45 )
   dcl   &jobSysName  *char     8     stg( *defined ) defvar( &fSPRL0100  49 )
   dcl   &splFCrtDat  *char     7     stg( *defined ) defvar( &fSPRL0100  57 )
   dcl   &rsv01       *char     1     stg( *defined ) defvar( &fSPRL0100  64 )
   dcl   &splFCrtTim  *char     6     stg( *defined ) defvar( &fSPRL0100  65 )



   call QSPRILSP   ( +
                     &fSPRL0100   +
                     &szRcvVar    +
                     'SPRL0100'   +
                     &errCod      +
                   )


   chgvar     &pSplFName       &splFName
   chgvar     &pJobName        &jobName
   chgvar     &pUserName       &userName
   chgvar     &pJobNbr         &jobNbr
   chgvar     &pSplFNbr        &splFNbr


   return

endpgm

在你的CL中,称之为:

pgm    ( +
       )


   dcl   &splFName    *char    10
   dcl   &jobName     *char    10
   dcl   &userName    *char    10
   dcl   &jobNbr      *char     6
   dcl   &splFNbr     *int


   dspmsgd     CPF9898 output( *PRINT )

   call @@TSTSPL   ( +
                     &splFName    +
                     &jobName     +
                     &userName    +
                     &jobNbr      +
                     &splFNbr     +
                   )

   sndpgmmsg  msgid( CPF9897 ) msgf( QSYS/QCPFMSG ) +
                msgdta( &splFName *bcat &jobName *bcat &jobNbr ) +
                topgmq( *EXT ) +
                msgtype( *INFO )


   return

endpgm

而不是@@ TSTSPL,为新程序赋予有意义的名称。可以编译第二组示例代码,您可以在FTP会话中调用它来测试它是否调用API示例并返回正确的标识信息。 (SNDPGMMSG命令只是将消息放入FTP服务器作业日志;您的CL中不需要它。)

如果在退出FTP会话之前针对用户配置文件运行WRKOBJLCK,则可以检查作业日志以查看是否显示该消息。您可以使用该消息来了解QPRTJOB作业的作业编号,以验证示例DSPMSGD命令中的假脱机文件是否显示在那里。它应该是该作业中最新的假脱机文件。它也应该是WRKSPLF列表中最新的假脱机文件;如果显示其属性,则应该看到QPRTJOB名称。

答案 2 :(得分:1)

此代码片段将创建的最后一个假脱机文件复制到qtemp,然后再复制到流文件。 &amp; file是假脱机文件'QPRINT'的名称。 &amp; TOSMF是流文件的名称。我一直使用此代码将报告作为电子邮件附件发送。

/* delete the ifs file this is a good check for authority */        
/* if the object can't be deleted you probably can't replace it */  
             RMVLNK     OBJLNK(&TOSTMF)                             
             MONMSG     MSGID(CPFA0A9)  /*object not found */       

/* make sure the spool file exists by holding it */                 
/* cpf returns to caller if the spool file doesn't exist */         
             HLDSPLF    FILE(&FILE) SPLNBR(*LAST)                   
             MONMSG     MSGID(CPF3337)  /*already held */           

    DLTF       FILE(QTEMP/QSPOOL)                               
    MONMSG     MSGID(CPF2105)   /*object not found */           
    CRTPF      FILE(QTEMP/QSPOOL) RCDLEN(132)                   
    CPYSPLF    FILE(&FILE) TOFILE(QTEMP/QSPOOL) SPLNBR(*LAST)   
    CPYTOSTMF  +                                                
                 FROMMBR('/qsys.lib/qtemp.lib/qspool.file/qsp+  
                 ool.mbr') TOSTMF(&TOSTMF) +                    
                 STMFOPT(*REPLACE) STMFCCSID(*PCASCII)