TechTalk: Who's Calling Please?

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

When your telephone rings and someone at the other end starts talking without identifying himself or herself, you have every bit of right to feel annoyed. It's only common courtesy to at least say, "My name is so-and-so." After that, the caller can start with the business at hand since the formalities have been complied with.

AS/400 programs aren't so polite. When program A calls program B, program A is ordering program B to run; yet program B has no direct way of knowing who called it. Sometimes this information would be useful. The Retrieve Previous Program (RTVPRVPGM) command shown in Figures 1a and 1b satisfies this need.

To give you an idea of its usefulness, you may have created a single program that performs one function nine times out of ten. The remaining time, it still performs the same function-with a slight alteration to accommodate different requirements. Granted, you probably should have created two different programs (that's what the basic tenets of modular programming would advise), but in real life this is not always practical.

If your CL program needs to know what program called it, include the RTVPRVPGM command in the CL program, as follows:

 RTVPRVPGM LEVELS(1) + RTNPGM(&CALLER) 

Variable &CALLER must be declared as a 10-character string. The LEVELS parameter indicates how many levels to go back in the program stack. You can put LEVELS(2) if you want to know the caller's caller's name, for instance.

If the program that needs the caller's name is written in RPG/400 you can call the program activated by the RTVPRVPGM command directly. Just include the code from 1c in your program.

If the program that needs the caller's name is written in RPG/400 you can call the program activated by the RTVPRVPGM command directly. Just include the code from Figure 1c in your program.

This utility does its work by sending an *INFO message to *PRV (the caller of PRV001CL) and obtaining the key of this message. Then the message is received by key and erased, obtaining the sender information structure in &SENDER. Part of the information structure is the name of the program that actually received the message-which will be the name of the program from which you used this utility command.

Next, we repeat the cycle, using the program name retrieved in the first cycle as the basis for another SNDPGMMSG to *PRV and RCV-MSG with the &SENDER option, which obtains the name of your program's caller. The process is repeated the number of times indicated by the LEVELS parameter. It's pretty simple and very efficient.

Now, if only we could do the same on the telephone, perhaps those pesky, malicious callers (who love to call at 3 a.m. just to hang up on you) would think twice about it!


TechTalk: Who's Calling Please?

Figure 1A Command RTVPRVPGM

 RTVPRVPGM: CMD PROMPT('Retrieve Previous Program') PARM KWD(LEVELS) TYPE(*DEC) LEN(3 0) DFT(1) + RANGE(1 100) PROMPT('Number of levels to + backtrack') PARM KWD(RTNPGM) TYPE(*CHAR) LEN(10) RTNVAL(*YES) + PROMPT('Program name (10)') 
TechTalk: Who's Calling Please?

Figure 1B CL program PRV001CL

 PRV001CL: + PGM PARM(&LEVELS &RTNPGM) DCL VAR(&CALLER) TYPE(*CHAR) LEN(10) DCL VAR(&COUNTER) TYPE(*DEC) LEN(3 0) DCL VAR(&LEVELS) TYPE(*DEC) LEN(3 0) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) DCL VAR(&RTNPGM) TYPE(*CHAR) LEN(10) DCL VAR(&SENDER) TYPE(*CHAR) LEN(80) MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR)) SNDPGMMSG MSG(X) TOPGMQ(*PRV *) MSGTYPE(*INFO) KEYVAR(&MSGKEY) RCVMSG PGMQ(*PRV *) MSGKEY(&MSGKEY) RMV(*YES) SENDER(&SENDER) CHGVAR VAR(&CALLER) VALUE(%SST(&SENDER 56 10)) LOOP: + SNDPGMMSG MSG(X) TOPGMQ(*PRV &CALLER) MSGTYPE(*INFO) + KEYVAR(&MSGKEY) RCVMSG PGMQ(*PRV &CALLER) MSGKEY(&MSGKEY) RMV(*YES) SENDER(&SENDER) CHGVAR VAR(&COUNTER) VALUE(&COUNTER + 1) IF COND(&COUNTER *EQ &LEVELS) THEN(DO) CHGVAR VAR(&RTNPGM) VALUE(%SST(&SENDER 56 10)) RETURN ENDDO ELSE CMD(DO) CHGVAR VAR(&CALLER) VALUE(%SST(&SENDER 56 10)) GOTO CMDLBL(LOOP) ENDDO ERROR: + RCVMSG MSGTYPE(*EXCP) MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + MSGFLIB(&MSGFLIB) SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) MSGDTA(&MSGDTA) + MSGTYPE(*ESCAPE) ENDPGM 
TechTalk: Who's Calling Please?

Figure 1C Using RTVPRVPGM in RPG/400

 Figure 1c: Using RTVPRVPGM in RPG/400 ... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 C CALL 'PRV001CL' C PARM 1 LEVELS 30 C PARM RTNPGM 10 
BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  •  

  • 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.

  • 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

  • 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: