The Retrieve User Space Initialization command has a special purpose
to work with the system provided APIs in a CL program to provide
lists (e.g. lists of members or objects) in user spaces.
The steps required to use a list are:
1. Create a user space (See the QUSCRTUS program or the TAA tool
CRTUSRSPC).
2. Fill the space with a list by using a CALL to a system program
such as QUSLOBJ.
3. Retrieve the initialization information from the list (See the
QUSRTVUS program or the command provided by this tool
RTVUSRSPCI).
4. Retrieve one entry at a time from the list (See the QUSRTVUS
program or the TAA tool RTVUSRSPCE).
5. In some cases, the entry you receive is only enough to
identify the job, the object etc. that you really want
information on. In this case you must do another call to
retrieve the specific information.
Many functions that want to use an API list use a CL program to begin
processing. The first three steps can be done from CL. Step 4 and 5
(retrieving of an entry and specific information) can be done from
either CL or a HLL program. Depending on what is to be done with the
information, you can use either either approach.
For example, if you are going to perform a CL command on each entry
of the list, it is probably easier to perform the retrieve step in
CL. If you are going to print the information, it is probably easier
to use a HLL program.
Each of the API list functions produces a standard heading set of
information in the user space. Following this information is the
list. The offset of where the list starts and the length of each
entry may change on a future release. The heading area contains an
offset to where the list starts and the length of each entry. To
protect your program against future release changes, this information
should be accessed as an initialization step rather than hard coding
the offset and entry length into your program.
The purpose of RTVUSRSPCI is to access the initialization information
and return it so it is ready to be used in the next step. The next
step can be either in CL or the values may be passed to a HLL
program.
The initialization information you need to process a list is:
** The offset (start position) to where the list starts.
** The number of entries in the list.
** The length of each entry (Each entry is normally multiple
fields. These are passed as a data structure. The entry
length is the length of the data structure).
A typical command is entered as:
RTVUSRSPCI USRSPC(QTEMP/SPACE1) STRPOS(&STRPOS) +
NBRENT(&NBRENT) ENTLEN(&ENTLEN)
The last three parameters are 'return values' where the information
is passed back to your CL program.
The RTVUSRSPCI command calls the QUSRTVUS program with the proper
parameters to access the information needed for initialization.
A few important points:
** The STRPOS field must be declared as *CHAR LEN(4). It holds a
binary value. Unlike the QUSRTVUS program, the value returned
is not the offset, but the actual start position. You do not
need to add 1 to the value to begin processing.
** The NBRENT field must be declared as *DEC LEN(9 0). It is
returned in decimal format to allow a simple count and compare
in CL or a HLL to determine when the end of list has occurred.
** The ENTLEN field must be declared as *CHAR LEN(4). It holds a
binary value which describes the length of each entry.
CL Example
----------
The following shows the code necessary to produce and process a list.
CL is used for the entire example. The example, shows the structure
of what needs to be done for any list, but the function performed is
not very practical. A list of *JOBQ objects in the QGPL library are
accessed and a message is sent for each one found. In this example,
Step 5 (retrieve specific information) is not needed because the list
entry itself contains all the necessary information.
PGM
DCL &ENTLEN *CHAR LEN(4)
DCL &NBRENT *DEC LEN(9 0)
DCL &FULLSPACE *CHAR LEN(20)
DCL &FULLOBJ *CHAR LEN(20)
DCL &OBJ *CHAR LEN(10)
DCL &LIB *CHAR LEN(10)
DCL &SPACE *CHAR LEN(10)
DCL &SPACEL *CHAR LEN(10)
DCL &OBJTYPE *CHAR LEN(10)
DCL &STRPOS *CHAR LEN(4)
DCL &RTNVAR *CHAR LEN(1000)
DCL &COUNT *DEC LEN(9 0)
/* Create space using TAA command */
CHGVAR &SPACE 'SPACE2'
CHGVAR &SPACEL 'QTEMP'
CRTUSRSPC USRSPC(&SPACEL/&SPACE)
/* Next two CHGVARs build up 20 byte */
/* variables as needed for the CALL */
/* to QUSLOBJ */
CHGVAR &FULLSPACE (&SPACE *CAT &SPACEL)
CHGVAR &FULLOBJ ('*ALL QGPL')
/* Call to QUSLOBJ is the API to fill */
/* the space with an object list. It */
/* requests the *JOBQ objects in QGPL. */
/* OBJL0100 is the format name of the */
/* list produced. */
CALL QUSLOBJ PARM(&FULLSPACE 'OBJL0100' +
&FULLOBJ '*JOBQ')
/* Retrieve the initialization values */
/* as described in this tool */
RTVUSRSPCI USRSPC(&SPACEL/&SPACE) STRPOS(&STRPOS) +
NBRENT(&NBRENT) ENTLEN(&ENTLEN)
LOOP: /* Start processing loop */
/* Count and check for total in list */
CHGVAR &COUNT (&COUNT + 1)
IF (&COUNT *LE &NBRENT) DO /* Process entry */
/* Retrieve the entry using TAA command */
/* The &STRPOS value is initially set */
/* by the RTVUSRSPCI command. On each */
/* use of RTVUSRSPCE, the next &STRPOS */
/* value is automatically returned. */
/* The ENTLEN is the same for each use */
RTVUSRSPCE USRSPC(&SPACEL/&SPACE) ENTLEN(&ENTLEN) +
STRPOS(&STRPOS) RTNVAR(&RTNVAR)
/* Extract individual fields from RTNVAR */
/* The format of each list differs. */
/* See the list data section for the */
/* API that you are using */
CHGVAR &OBJ %SST(&RTNVAR 1 10)
CHGVAR &LIB %SST(&RTNVAR 11 10)
CHGVAR &OBJTYPE %SST(&RTNVAR 21 10)
/* This example only sends a message */
SNDPGMMSG MSG(&OBJ *CAT &LIB *CAT &OBJTYPE)
GOTO LOOP
ENDDO /* Process entry */
/* RTVUSRSPCE defaults to return with LR */
/* off to allow faster access. When the */
/* loop is complete, use SETLR(*ON) or */
/* RCLRSC */
RTVUSRSPCE USRSPC(&SPACEL/&SPACE) ENTLEN(&ENTLEN) +
STRPOS(&STRPOS) RTNVAR(&RTNVAR) SETLR(*ON)
ENDPGM
In this example, Step 5 was not needed because the entry retrieved by
RTVUSRSPCE contains all the necessary information to send a message.
If this were not the case, another call would have to be done using
the information received by RTVUSRSPCE.
For example, assume that you want the detail information for all of
the spooled files for a specific user. After RTVUSRSPCE is executed,
the identifying information about one spooled file is known. You
would then do a call to QUSRSPLA to retrieve the details of the
spooled file (e.g. page length, the form type). It is possible that
the spooled file will no longer exist. After the list of spooled
files was generated, it is possible that the spooled file was printed
or deleted by the time the call to QUSRSPLA is done. You can monitor
for this condition.
RPG Example
-----------
If you need a HLL program to process the list entries, the first
three steps (Creating the space, filling the space with a list and
retrieving the initialization values) can still be done in CL.
Assume you have copied all of the previous CL statements down to the
label LOOP.
Instead of performing the processing loop function in CL, you would
call a HLL program with the information retrieved from RTVUSRSPCI
such as:
CALL PGM(RPGPGM) PARM(&FULLSPACE &NBRENT +
&ENTLEN &STRPOS)
The following is the complete RPG program. It prints one line per
entry in the list.
FQPRINT O F 132 OF PRINTER
I* DS for the entry length
IDSLEN DS
I B 1 40ENTLN
I* DS for the start position
IDSSTR DS
I B 1 40STRPS
I* DS for the makeup of each list entry
I* The information is hard coded to assist in understanding.
I* The information could have been copied in using PSOBJL0100
I* member in QATTRPG. See the LIST DS provided
I* in the described member.
IDSRCV DS
I 1 10 OBJECT
I 11 20 LIB
I 21 30 OBJTYP
C *ENTRY PLIST Parm list
C PARM USRSPC 20 User space
C PARM NBRENT 90 Nbr of entrs
C PARM DSLEN DS entry len
C PARM DSSTR DS str pos
C* Do for the number of entries passed in
C DO NBRENT Do nbr of
C CALL 'QUSRTVUS' Call extract
C PARM USRSPC User space
C PARM STRPS Start pos
C PARM ENTLN Entry length
C PARM DSRCV Data struct
C* Print a line for each entry
C EXCPTPRINT Print a line
C* Bump for next start position
C ADD ENTLN STRPS Bump
C END Do nbr of
C* End of program
C SETON LR Set LR
C RETRN Return
OQPRINT E 1 PRINT
O OBJECT 10
O LIB 22
O OBJTYP 34
See the previous discussion in the CL example about the handling of
Step 5 and how it may be necessary to monitor for a situation where
the specific information cannot be received because the job or
spooled file etc. is no longer in the system. In RPG, you monitor
by specifying an indicator on the call and then looking in the status
area. You would need to add the following to your program:
I* DS for exception status conditions
IEXPSTS SDS
I 40 46 MSGID
.
.
C CALL 'xxxxxxxx' 42 Job info
.
.
C* Check for error on CALL
C 42 DO Call error
C MSGID IFEQ 'xxxxxxx' Specific err
C* Your processing such as ignore the condition
C ELSE Other error
C* Your processing for other errors such as SETON Hx and return
C END Other error
C END Call error
RTVUSRSPCI Command parameters *CMD
-----------------------------
USRSPC The qualified name of the user space to be created.
STRPOS Start position. This is a return variable and must
be declared as *CHAR LEN(4). It will contain the
offset plus 1 in binary. This means that it is
ready to use as the start position of the first
entry in any list.
NBRENT Number of entries. This is a return variable and
must be declared as *DEC LEN(9 0). It will contain
the number of entries in the list. It is your
responsibility to stop processing the list when the
total number of entries has been processed.
ENTLEN Entry length. This must be declared as *CHAR LEN(4)
and will be passed back as a binary value.
Restrictions
------------
Because RTVUSRSPCI has return variables, it can only be executed in a
CL program.
Prerequisites
-------------
None.
Implementation
--------------
None, the tool is ready to use.
Objects used by the tool
------------------------
Object Type Attribute Src member Src file
------ ---- --------- ---------- ----------
RTVUSRSPCI *CMD TAASPCB QATTCMD
TAASPCBR *PGM RPG TAASPCBR QATTRPG
Note that there is no CL program. The RPGLE program is the command
processing program.
|