04
Mon, Nov
1 New Articles

Build Your Own Command Line

CL
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Recently, some of my users asked me to embed a command line into their AS/400 application. Fearing this was an abstruse job that only OS/400 could tackle, I consulted the API reference manuals with some misgivings. But my doubts cleared when I found a collection of APIs that gave me all the parts necessary to build a command line from scratch! Eventually, my users’ request gave me a fun project that resulted in linking request messages, command processing, and message subfiles into a useful utility.

A command line is the long input field at the bottom of menus and work-with lists where you can enter and execute CL commands. A standard command line also does the following:
• Saves the user’s entered commands into the job log as request messages
• Hides certain parameter values, such as passwords, from the job log
• Checks if the user profile specifies limited capabilities against running commands
• Displays messages returned from command execution on the screen’s message line
• Establishes a call stack entry resume point for option 2 (End request) on the System Request menu
• Runs System/36 commands if the System/36 environment is active
• Invokes the CL command prompter if the F4 key is pressed
• Retrieves previously executed commands, in descending order of execution, if the F9 key is pressed
• Displays trailing ellipsis dots on an F9’ed command if the command length exceeds the command line input field length

Perhaps you’re asking, “Why not just call the QCMD or QUSCMDLN API?” Answer: QCMD and QUSCMDLN don’t provide exit points that allow access to the command string before command execution. So if you want to integrate a command line into a custom screen, you must build the command line from scratch.

In this article, I show the six-stage evolution of a command line processing program. Figures 1 through 6 correspond to STAGE1 through STAGE6, and I use CL for each stage. The first stage is pretty basic. Subsequent stages add more and more things into the command line synergy, and my final stage includes a neat feature that IBM command

lines lack: the F8 key, used to retrieve previously executed commands in ascending order of execution.

Stage 1: The Command Line Shell

The shell of a command line processing program is a repeat-until loop. The following pseudo code outlines this type of program.

Repeat

If &COMMAND is not blank then

Execute &COMMAND

If no errors occurred during execution then

Move blanks to &COMMAND

Endif

Endif

Prompt user to type next &COMMAND
Until F3 or F12 is pressed

The variable &COMMAND is blank during the first repeat-until trip. This program first prompts the user to type a command; then, it executes the entered command during the next repeat-until trip. Placing the prompt for next command step below (rather than above) the command execution step will make the program code easier to write.

Figure 1 shows CL code for STAGE1, which implements this pseudo code. It uses display file SHELL (Figure 7) to create a command line screen (Figure 8). It calls the command executor, QCMDEXC, to process the command string in variable &COMMAND. Note the second parameter value to QCMDEXC is the command length
153. I use 153 because that is the DDS input field length. Later (in Stage 4), I’ll increase the command length to 6000 while leaving the DDS input field length at 153.

If no errors occur, STAGE1 clears the input field. But if the command execution fails and sends an escape message, the MONMSG CPF0000 is invoked and causes a branch around the statement that clears the input field. That way, the user can see the failed command string in the input field again. One exception to this is escape message CPF6801, which occurs after the user presses F3 or F12 on the CL command prompter. STAGE1 handles CPF6801 the same way it handles successful command execution—it erases the command string from the input field.

Stage 2: Add Message Filtering

Display file SHELL includes a single-output-operation type of message subfile. If the command line program loads its own program name into subfile field &PROGRAM and then executes the Send File (SNDF) command on the message subfile control record, OS/400 will display all messages sent to the program’s message queue in a scrollable area below the command line. To clear old messages from the message subfile before processing the next command line input (in a way that leaves these messages in the job log), the program implements the following technique called message filtering. Figure 2 shows CL code for STAGE2, which adds message filtering to the command line process. (New code added since STAGE1 is highlighted.)

The program sends itself a message of type *RQS, captures the resulting message key, and then immediately receives the same message with Receive Message (RCVMSG), specifying RMV(*NO). When the SNDF command executes, only the messages received since the last *RQS message appear in the subfile, but all types of messages received both before and after the last *RQS message remain in the job log. The program extracts its own program name from positions 56 to 65 of variable &SENDER to tell OS/400 which queue of program messages to load into the message subfile. At the bottom, the Remove Message (RMVMSG) command removes the *RQS message from the job log.

The interval between the RCVMSG and RMVMSG commands enables option 2 (End request) on the System Request menu and establishes a call stack entry resume point should an End Request (ENDRQS) occur in the job. The program does not promote error messages to a prior program message queue. Because it doesn’t require a caller, this command line processor can run at the top of the call stack, meaning it can run as a routing entry program invoked by routing data, or as an initial group program invoked by the Transfer to Group Job (TFRGRPJOB) command.

For reasons that will become clear in Stage 6, the *RQS message text is ‘/* */’. The program sends itself this message via TOPGMQ(*SAME). It could also specify TOPGMQ(*EXT); however, OS/400 changes the message key when it receives a *RQS message from *EXT. The RCVMSG command’s KEYVAR parameter can capture a changed message key from *EXT.

Stage 3: Archive the Command

At this point, the program should start to archive commands into the job log as the user types them. Later (in Stage 6) it will retrieve the saved commands from the job log in order to implement the F9 and F8 keys. Figure 3 shows CL code for STAGE3, which adds message archiving. (New code added since STAGE2 is highlighted.) The program sends itself the user’s entered command as a message of type *RQS, captures the resulting message key, and then immediately receives the same message with RMV(*NO). This message remains permanently in the job log.

Stage 4: Enable 6000-byte Commands

So far, the program has used two message keys: one for message filtering, and one for message archiving. Stage 4 adds another key: a travelling message key. This is the key of the command string that is currently displayed in the input field. The travel key is always blank at this stage; however, it will come into play in Stage 6 when the F9 and F8 keys are enabled. I introduce it here because it lays the foundation to expand the command string length from 153 bytes to 6000 bytes.

Figure 4 shows CL code for STAGE4, which adds the travel key. (New code added since STAGE3 is highlighted.) This stage replaces variable &COMMAND with variable &BIG in some places. If the user presses the F4 key and if variable &TRAVELKEY contains a valid message key, then the program executes RCVMSG to retrieve a prior *RQS message (i.e., command) from the job log into 6000-byte variable &BIG. In this stage, the program never executes this RCVMSG because the travel key is always blank; but a later stage will begin to update the travel key, so this line of CL code has a purpose. Note that the call to QCMDEXC now uses the big 6000-byte message for the command string.

Stage 5: Replace QCMDEXC with QCAPCMD

The Process Command (QCAPCMD) API is a powerful tool that can do everything QCMDEXC can do, plus a lot more. Figure 9 lists the nine parameters for QCAPCMD. Parameter 1 is the command string, and parameter 2 is the command length. Parameter 3 is an options control block that defines how to handle the command. The layout of the options control block parameter is the CPOP0100 format. For more information on QCAPCMD, see OS/400 Program and CL Command APIs V4R3.

Figure 5 shows CL code for STAGE5, which uses QCAPCMD instead of QCMDEXC. (New code added since STAGE4 is highlighted.) STAGE5 specifies the following options in the options control block:
• Type of command processing is ‘2’ to check if the user profile has LMTCPB(*YES), to prompt for missing required parameters, to run System/36 environment commands, and to prompt or execute the command.
• Double-byte character set (DBCS) data handling is ‘0’ to ignore DBCS data.

• Prompter action is ‘2’ if the user pressed the Enter key, or ‘1’ if the user pressed the F4 key.
• Command string syntax is ‘0’ to use AS/400 syntax.
• Message key is variable &ARCHIVEKEY. If the user prompts the command, QCAPCMD changes the message in the job log identified by this message key. Changes include those from prompting, ordering of parameters, addition of keywords, and hiding of “hidden” parameters, such as passwords.

Stage 6: Handle F8=Retrieve and F9=Retrieve

Does the following situation sound familiar? I’m on an IBM command line and I press the F9 key several times to retrieve a prior command. But I press F9 too many times. Realizing I scrolled past my target command, I press the Field Exit key to start over, repeat the F9 rigmarole, scroll past my target command, press the Field Exit key, repeat the F9 rigmarole, scroll past my target, and...ugh! Wouldn’t it be nice if IBM command lines had an F8 key to retrieve prior commands in ascending order of execution, too? That way, after I press the F9 key too many times, I could just press the F8 key to scroll forward from the current command in the input field. Well, the final stage of my command line processing program adds both F9 and F8 functions.

Figure 6 shows CL code for STAGE6. (New code added since STAGE5 is highlighted). The following pseudo code outlines how STAGE6 retrieves prior request messages (i.e., commands) from the job log to implement the F9 and F8 keys.

Repeat

Select

When F8 key is pressed and &TRAVELKEY is blank

Retrieve first request message from job log

When F8 key is pressed and &TRAVELKEY is not blank

Retrieve next request message after &TRAVELKEY from job log

When F9 key is pressed and &TRAVELKEY is blank

Retrieve last request message from job log

When F9 key is pressed and &TRAVELKEY is not blank

Retrieve previous request message before &TRAVELKEY from job log

End Select

Extract new &TRAVELKEY from retrieved request message information
Until retrieved request message does not begin with ‘/*’
Or until &TRAVELKEY is blank

STAGE6 calls the Retrieve Request Message (QMHRTVRQ) API to retrieve prior commands from the job log. (For more information on QMHRTVRQ, see OS/400 Message Handling APIs V4R3.) Figure 10 shows the six parameters for QMHRTVRQ. The program uses the RTVQ0100 receiver variable format and four message types: *FIRST, *LAST, *NEXT, and *PRV. It appends trailing ellipsis dots if the retrieved command length exceeds the command line input field length. The program code skips over “CL comment” commands in the job log, so the user won’t see the ‘/* */’ messages from Stage 2 in the command line input field.

STAGE6 updates the travel key with the message key of the command string that is currently displayed in the input field. That way, if the user presses the F4 key on an F9’ed or F8’ed command, the program executes RCVMSG (added in STAGE4) to retrieve a full 6000-byte command string to send to the CL command prompter, instead of a truncated 153-byte command string with trailing ellipsis dots.

Further Enhancements

This completes the basic command line functions. From this point, you can add more things into the program to suit your application (for example, an initial copyright statement

in the message subfile). The program can send itself messages of type *INFO, display the message subfile, and then remove the *INFO messages from the job log using message keys.

You can add a menu above the command line, and then scan the command line input for a valid menu option number and use the found number to index into a table of commands to dynamically build a command string to pass to QCAPCMD API. The parameter values in your command table can contain PDM-like variables. (PDM-like variables are strings like “&N” that you must resolve into application-specific values at runtime.) You can use the QCAPCMD API options control block value of “8” for “type of command processing” to help you prompt and build a command table with PDM-like variables. With PDM-like variables, you don’t have to hardcode all the parameter values in your command table.

The CL command line processor in this article allows recursion. If you rewrite the command line processor in RPG, COBOL, or C, be aware that language recursion rules may limit how far a user can invoke the command line recursively.

If you understand these six stages, try to experiment with more menus and command lines of your own design. Be creative. Qualified users who can operate from a command line will no doubt be delighted if you can integrate this powerful feature into their everyday screens!

References

• OS/400 Message Handling APIs V4R3 (SC41-5862-02, CD-ROM QB3AMN02)
• OS/400 Program and CL Command APIs V4R3 (SC41-5870-02, CD-ROM QB3AMV02)

/**********/

/* STAGE1 */
/**********/

Pgm
Dclf File(Shell)

Top: /* execute command */
If (&Command = ' ') (Goto Wait)
Call QCMDEXC (&Command 153)
MonMsg CPF6801
MonMsg CPF0000 Exec(Goto Wait)
ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Rcvf RcdFmt(Line)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm /**********/

/* STAGE2 */
/**********/

Pgm
Dclf File(Shell)
Dcl &BoundryKey *char 4
Dcl &Sender *char 80

Top: /* set new request message boundary */
SndPgmMsg MsgType(*Rqs) KeyVar(&BoundryKey) ToPgmq(*Same) Msg('/* */')
RcvMsg MsgType(*Rqs) MsgKey(&BoundryKey) Rmv(*No) Sender(&Sender)
ChgVar &Program %sst(&Sender 56 10)

ChgVar &IN99 '1'

Execute: /* execute command */
If (&Command = ' ') (Goto Wait)
Call QCMDEXC (&Command 153)
MonMsg CPF6801

Figure 1: STAGE1 begins a basic command line shell.

MonMsg CPF0000 Exec(Goto Wait)
ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Sndf RcdFmt(MsgCtl)
Rcvf RcdFmt(Line)
RmvMsg MsgKey(&BoundryKey)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm /**********/

/* STAGE3 */
/**********/

Pgm
Dclf File(Shell)
Dcl &ArchiveKey *char 4
Dcl &BoundryKey *char 4
Dcl &Sender *char 80

Top: /* set new request message boundary */
SndPgmMsg MsgType(*Rqs) KeyVar(&BoundryKey) ToPgmq(*Same) Msg('/* */')
RcvMsg MsgType(*Rqs) MsgKey(&BoundryKey) Rmv(*No) Sender(&Sender)
ChgVar &Program %sst(&Sender 56 10)

ChgVar &IN99 '1'

Archive: /* archive command into the job log */
If (&Command = ' ') (Goto Wait)
SndPgmMsg MsgType(*Rqs) KeyVar(&ArchiveKey) ToPgmq(*Same) Msg(&Command)
RcvMsg MsgType(*Rqs) MsgKey(&ArchiveKey) Rmv(*No)

Execute: /* execute command */
Call QCMDEXC (&Command 153)
MonMsg CPF6801
MonMsg CPF0000 Exec(Goto Wait)
ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Sndf RcdFmt(MsgCtl)
Rcvf RcdFmt(Line)
RmvMsg MsgKey(&BoundryKey)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm /**********/

/* STAGE4 */
/**********/

Pgm
Dclf File(Shell)
Dcl &ArchiveKey *char 4
Dcl &Big *char 6000
Dcl &BoundryKey *char 4
Dcl &Sender *char 80
Dcl &TravelKey *char 4

Top: /* set new request message boundary */
SndPgmMsg MsgType(*Rqs) KeyVar(&BoundryKey) ToPgmq(*Same) Msg('/* */')
RcvMsg MsgType(*Rqs) MsgKey(&BoundryKey) Rmv(*No) Sender(&Sender)
ChgVar &Program %sst(&Sender 56 10)

ChgVar &IN99 '1'

Full: /* try to get full 6000-byte command */
ChgVar &Big &Command
If (&Big = ' ') (ChgVar &TravelKey ' ')
If (&IN04 = '1' *and &TravelKey *NE ' ') Do
RcvMsg MsgType(*Rqs) MsgKey(&TravelKey) Rmv(*No) Msg(&Big)
If (%sst(&Command 1 150) *NE %sst(&Big 1 150)) (Chgvar &Big &Command)
Enddo

Archive: /* archive command into job log */
If (&Big = ' ') (Goto Wait)
SndPgmMsg MsgType(*Rqs) KeyVar(&ArchiveKey) ToPgmq(*Same) Msg(&Big)
RcvMsg MsgType(*Rqs) MsgKey(&ArchiveKey) Rmv(*No)

Execute: /* execute command */
ChgVar &TravelKey ' '
Call QCMDEXC (&Big 6000)
MonMsg CPF6801

Figure 2: STAGE2 adds message filtering.

Figure 3: STAGE3 adds message archiving.

MonMsg CPF0000 Exec(Goto Wait)
ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Sndf RcdFmt(MsgCtl)
Rcvf RcdFmt(Line)
RmvMsg MsgKey(&BoundryKey)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm

Figure 4: STAGE4 adds a travelling message key.

/**********/

/* STAGE5 */
/**********/

Pgm
Dclf File(Shell)
Dcl &ArchiveKey *char 4
Dcl &Big *char 6000
Dcl &BoundryKey *char 4
Dcl &Sender *char 80
Dcl &TravelKey *char 4
Dcl &Option *char 20value(X'0000000200000000000000000000000000000000')

Top: /* set new request message boundary */
SndPgmMsg MsgType(*Rqs) KeyVar(&BoundryKey) ToPgmq(*Same) Msg('/* */')
RcvMsg MsgType(*Rqs) MsgKey(&BoundryKey) Rmv(*No) Sender(&Sender)
ChgVar &Program %sst(&Sender 56 10)

ChgVar &IN99 '1'

Full: /* try to get full 6000-byte command */
ChgVar &Big &Command
If (&Big = ' ') (ChgVar &TravelKey ' ')
If (&IN04 = '1' *and &TravelKey *NE ' ') Do
RcvMsg MsgType(*Rqs) MsgKey(&TravelKey) Rmv(*No) Msg(&Big)
If (%sst(&Command 1 150) *NE %sst(&Big 1 150)) (Chgvar &Big &Command)
Enddo

Archive: /* archive command into job log */
If (&Big = ' ') (Goto Wait)
SndPgmMsg MsgType(*Rqs) KeyVar(&ArchiveKey) ToPgmq(*Same) Msg(&Big)
RcvMsg MsgType(*Rqs) MsgKey(&ArchiveKey) Rmv(*No)

Execute: /* execute command */
ChgVar &TravelKey ' '
ChgVar %sst(&Option 5 7) ('020' || &ArchiveKey)
If (&IN04 = '1') (ChgVar %sst(&Option 6 1) '1')
Call QCAPCMD (&Big X'00001770' &Option X'00000014'CPOP0100 ' ' X'00000000' ' ' X'00000000')
MonMsg CPF6801
MonMsg CPF0000 Exec(Goto Wait)

ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Sndf RcdFmt(MsgCtl)
Rcvf RcdFmt(Line)
RmvMsg MsgKey(&BoundryKey)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm /**********/

/* STAGE6 */
/**********/

Pgm
Dclf File(Shell)
Dcl &ArchiveKey *char 4
Dcl &Big *char 6000
Dcl &BoundryKey *char 4
Dcl &Length *dec 5
Dcl &Sender *char 80
Dcl &TravelKey *char 4
Dcl &Type *char 10
Dcl &Option *char 20value(X'0000000200000000000000000000000000000000')

Top: /* set new request message boundary */
SndPgmMsg MsgType(*Rqs) KeyVar(&BoundryKey) ToPgmq(*Same) Msg('/* */')
RcvMsg MsgType(*Rqs) MsgKey(&BoundryKey) Rmv(*No) Sender(&Sender)

Figure 5: STAGE5 adds QCAPCMD API to prompt/execute a command.

ChgVar &Program %sst(&Sender 56 10)
ChgVar &IN99 '1'

Full: /* try to get full 6000-byte command */
ChgVar &Big &Command
If (&Big = ' ') (ChgVar &TravelKey ' ')
If (&IN04 = '1' *and &TravelKey *NE ' ') Do
RcvMsg MsgType(*Rqs) MsgKey(&TravelKey) Rmv(*No) Msg(&Big)
If (%sst(&Command 1 150) *NE %sst(&Big 1 150)) (Chgvar &Big &Command)
Enddo

F8_or_F9: /* retrieve prior requests */

If (&IN08 = '1' *and &TravelKey = ' ') (ChgVar &Type '*FIRST')
Else If (&IN08 = '1') (ChgVar &Type '*NEXT ')
Else If (&IN09 = '1' *and &TravelKey = ' ') (ChgVar &Type '*LAST ')
Else If (&IN09 = '1') (ChgVar &Type '*PRV ')
Else (Goto Archive)
Call QMHRTVRQ (&Big X'00001770' RTVQ0100 &Type &TravelKey X'00000000')
If (%bin(&Big 5 4) = 0 *and &TravelKey = ' ') (Goto Wait)
ChgVar &TravelKey ' '
If (%bin(&Big 5 4) = 0) (Goto F8_or_F9) /* now try *FIRST or *LAST */
ChgVar &TravelKey %sst(&Big 9 4)
ChgVar &Length %bin(&Big 33 4)
Chgvar &Big %sst(&Big 41 &Length)

Chgvar &Command &Big
If (%sst(&Command 1 2) = '/*') (Goto F8_or_F9) /* ignore comments */
If (&Length > 153) (ChgVar %sst(&Command 151 3) '...') /* ellipsis */
Goto Wait

Archive: /* archive command into job log */
If (&Big = ' ') (Goto Wait)
SndPgmMsg MsgType(*Rqs) KeyVar(&ArchiveKey) ToPgmq(*Same) Msg(&Big)
RcvMsg MsgType(*Rqs) MsgKey(&ArchiveKey) Rmv(*No)

Execute: /* execute command */
ChgVar &TravelKey ' '
ChgVar %sst(&Option 5 7) ('020' || &ArchiveKey)
If (&IN04 = '1') (ChgVar %sst(&Option 6 1) '1')
Call QCAPCMD (&Big X'00001770' &Option X'00000014'CPOP0100 ' ' X'00000000' ' ' X'00000000')
MonMsg CPF6801
MonMsg CPF0000 Exec(Goto Wait)

ChgVar &Command ' '

Wait: /* prompt for next command */
Sndf RcdFmt(Line)
Sndf RcdFmt(MsgCtl)
Rcvf RcdFmt(Line)
RmvMsg MsgKey(&BoundryKey)
If (&IN03 *NE '1' *and &IN12 *NE '1') (Goto Top)
EndPgm A DSPSIZ(24 80 *DS3) INDARA

A R LINE BLINK

A CF03(03 'exit')

A CF04(04 'prompt')

A CF08(08 'retrieve')

A CF09(09 'retrieve')

A CF12(12 'cancel')

A 1 32'Sample Command Line' DSPATR(HI)

A 20 2'Type command, press Enter.'

A 21 2'===>'

A COMMAND 153A B 21 7DSPATR(UL) CHECK(LC)

A 23 2'F3=Exit F4=Prompt F8=RetrieveA F9=Retrieve F12=Cancel'

A COLOR(BLU)

A R MSGSFL SFL SFLMSGRCD(24)

A MSGKEY SFLMSGKEY

A PROGRAM SFLPGMQ(10)

A R MSGCTL SFLCTL(MSGSFL) OVERLAY SFLDSP

A SFLDSPCTL SFLINZ SFLSIZ(25)

A SFLPAG(1) RETKEY RETCMDKEY

A 99 SFLEND

A PROGRAM SFLPGMQ(10)

Figure 6: STAGE6 adds F8=Retrieve and F9=Retrieve functions.

Figure 7: Display file SHELL contains a command line screen and a message subfile.




Figure 8: This is a picture of display file SHELL.



Build_Your_Own_Command_Line09-00.png 900x672

Parameter Description Type Length

1 Source command string Input Char(*) 2 Length of source command string Input Binary(4) 3 Options control block Input Char(*)

Offset Type CPOP0100 Format 0 Binary(4) Type of command processing:

0 Command running 1 Command syntax check 2 Command line running, with limited user checking, prompting for missing required parameters, and

System/36 command capability 3 Command line syntax check, with limited user checking 4 CL program statements (SEU member type of CLP)

5 CL input stream (SEU member type of CL) 6 Command definition statements (SEU member type of CMD) 7 Binder definition statements (SEU member type of BND)

8 User-defined program statements allowing PDM-like variables 9 ILE CL program statements (SEU member type of CLLE)

4 Char(1) DBCS data handling

0 Ignore DBCS data 1 Handle DBCS data 5 Char(1) Prompter action

0 Never prompt the command, even if selective prompting characters are present in the command string 1 Always prompt the command, even if selective prompting characters are not present in the command string 2 Prompt the command if selective prompting characters are present in the command string
3 Display command help
6 Char(1) Command string syntax

0 Use AS/400 syntax 1 Use System/38 syntax 7 Char(4) Message key of a prior request message to be replaced by the changed command string 11 Char(9) Reserved, must be binary zeros

4 Options control block length Input Binary(4)

20 minimum value for CPOP0100 format 5 Options control block format Input Char(8)

CPOP0100 only valid value 6 Changed command string Output Char(*) 7 Length available for changed command string input Binary(4) 8 Length of changed command string available to return Output Binary(4) 9 Error code I/O Char(*)

Figure 9: This is the parameter format for the Process Command (QCAPCMD) API.

Parameter Description Type Length

1 Message information Output Char(*)

Offset Type RTVQ0100 Format 0 Binary(4) Bytes returned
4 Binary(4) Bytes available
8 Char(4) Message key
12 Char(20) Reserved
32 Binary(4) Length of request message text returned 36 Binary(4) Length of request message text available 40 Char(*) Request message text

Offset Type RTVQ0200 Format 0 Binary(4) Bytes returned
4 Binary(4) Bytes available
8 Char(4) Message key
12 Char(10) Program or service program name 22 Char(1) Receiving call stack entry type

0 OPM program 1 ILE procedure name 2 long ILE procedure name 23 Char(10) Module name
33 Char(256) Procedure name
289 Char(11) Reserved
300 Binary(4) Offset to long procedure name 304 Binary(4) Length of long procedure name 308 Binary(4) Length of request message returned 312 Binary(4) Length of request message text available 316 Char(*) Request message text
* Char(*) Long procedure name
2 Length of message information Input Binary(4) 3 Format name Input Char(8)

RTVQ0100 Basic request message information RTVQ0200 All request message information
4 Message type Input Char(10)

*FIRST Retrieve the first request message in the current job *LAST Retrieve the last request message in the current job *NEXT Retrieve the request message after the message indicated by message key parameter *PRV Retrieve the request message before the message indicated by message key parameter 5 Message key Input Char(4) 6 Error code I/O Char(*)

Figure 10: This is the parameter format for the Retrieve Request Message (QMHRTVRQ) API.

BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: