How to identify and use spooled files of other user using QTCP user(COMMAND PROMPT)?

倾然丶 夕夏残阳落幕 提交于 2020-01-15 11:09:10

问题


Here i am connecting to an AS400 machine from command prompt using (FTP Servername) command.
Every action that i do using command prompt is being submitted with QTCP user in the background.

Here is the main concern:

  • I have a command that generates spool file with the name i used to login from command prompt.
  • I want to use that spool file content and copy to one of my library , and all these can be done with CPYSPLF command but how to do the same thing using QTCP user.
  • My main requirement here is to perform CL command operations using command prompt rather than AS400 terminal.

回答1:


@user2338816 makes a good point about using the QSPRILSP API. But if that doesn't provide what you need, here is how you can use the List Spooled Files (QUSLSPL) API to find it.

Before beginning, please review my answer from this post: Programming IBM iSeries API QUSLSPL in C# That has a good primer on using the QUSLSPL API and user spaces, although it talks in C#. So here is how you use that API in RPG IV:

To start with, you need to prototype out the calls to the APIs.

List Spooled Files

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                

Create User Space

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)       

Retrieve data from the user space

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)       

Delete User Space

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

I like to make a field to store the user space name so I don't have to keep typing it in:

DUserSpace        S             20    INZ('SPLFSPACE QTEMP     ')

When calling APIs, you'll need the following API error data structure:

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

Finally, here is a data structure with the information for each spooled file returned:

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          

The List Spooled Files API has more parameters than what was needed in that other answer and I used them in the prototype above. Because you can't specify the spooled file name as a parameter to search on, we can specify a creation date and time range to help limit the returned results.

So the actual coding is simple. You list all spooled files owned by QTCP for, say, the last 5 minutes. Look through the list and see which ones are named QPJOBLOG. Grab the most recent one.

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);                                  

My example uses 5 minutes, but that's probably too large of a timespan. Experiment to see what works for you.

All of this will have to go into a new program that will then return the information needed for the a CPYSPLF command. In fact, you can have this program build and execute a CPYSPLF command for you so your FTP script is simpler.




回答2:


There's still no example for the Retrieve Identity of Last Spooled File Created (QSPRILSP) API, so I'll add one. Compile something like this:

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

And in your CL, call it something like this:

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

Instead of @@TSTSPL, give the new program a meaningful name. That second set of example code can be compiled and you can call it in a FTP session to test if it calls the API example and returns the correct identifying info. (The SNDPGMMSG command simply puts a message into the FTP server joblog; you won't need it in your CL.)

If you run WRKOBJLCK against your user profile before you QUIT the FTP session, you can check the joblog to see if the message shows up. You can use the message to learn the job number of the your QPRTJOB job to verify that the spooled file from the example DSPMSGD command shows up there. It should be the most recent spooled file in that job. It should also be the most recent spooled file in a WRKSPLF list; and if you display its attributes, you should see the QPRTJOB name.




回答3:


This code snipit copies the last spoolfile created to qtemp and then to a stream file. &file is the name of the spoolfile 'QPRINT' for example. &TOSMF is the name of the stream file. I use this code all the time to send reports as email attachments.

/* 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)          


来源:https://stackoverflow.com/questions/40757520/how-to-identify-and-use-spooled-files-of-other-user-using-qtcp-usercommand-prom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!