Chapter 3. The ADDRESS Statement

This is a very important chapter.  Take the time to carefully read and assimilate it.

This chapter is common to both the Advanced REXX Telecourse and the CMS Pipelines Telecourse.  If you don't know anything about CMS Pipelines yet, then you can ignore the paragraphs dealing with CMS Pipelines.


Justification for this Chapter.

It is obviously important that tools used by the VM community perform well, are reliable and secure.  Too often we see REXX procedures without an address command statement, or pipelines using the CMS device driver stage.  In both cases, performance is wasted and the procedures are subject to breaking in an unpredictable manner.

In this article, we would like to explain the consequences of not using the address command or using then CMS device driver stage instead of the COMMAND device driver stage.

In order to fully understand all the implications, it is mandatory that we first review how CMS resolves commands, the so-called CMS Search Order.

CMS Command Search Order.

CMS commands (procedures or object modules) can be found on CMS minidisks, or in storage.  Let's first review how commands, and REXX procedures in particular, can reside in storage.

An exec can be loaded in the users' private storage by issuing the command

    EXECLOAD fn [ft [fm [execname [exectype]]]]

The advantage is then that the file does not need to be loaded from disk each time the procedure is invoked, thus resulting in reduced disk I/O.  A logical consequence is that CMS will always use the copy in storage (if it exists) instead of the one residing on a minidisk.

Since CMS Release 5, the so-called installation segment (alias the INSTSEG), permits the systems programmer to load frequently used procedures in a shared segment.  The default name of the shared segment is CMSINST.  Typically, you'll find procedures like FILELIST and RDRLIST in the segment, together with their accompanying XEDIT macros. 

In this case, not only the load from disk is avoided, but all users on the system use the same copy in storage, because it is a shared segment, resulting both in less disk I/O and less paging. 

But, in order to allow a user to execute a private (maybe enhanced) version of a procedure from its own minidisks or from its private storage (EXECLOADed procedures) this procedure should take precedence over the version residing in the INSTSEG segment. 

A filemode is therefore associated with the INSTSEG segment, to let it be part of the search order based on the filemode.  The default filemode is S, which can be changed via the SET INSTSEG ON mode  command. 

So, with the INSTSEG segment defaulting to filemode S, CMS uses the following search order when looking for an EXEC:

  1. is the procedure EXECLOADed ?
  2. is it on any of the accessed minidisks with modes A to R ?
  3. is it defined in the INSTSEG ?
  4. is it on any of the accessed minidisks with modes S to Z ?

CMS Release 6 introduced the logical shared segments. These shared segments can contain modules, EXECs, text decks, or any other associated object, such as data files.  The user can get access to the contents of the shared segment by issuing the SEGMENT LOAD segname  command.

Once this command is issued, MODULEs contained in the segment are considered to be NUCXLOADed.  For procedures, (EXEC, XEDIT, etc...), it further depends on what is specified when the segment is built.  One can choose to make the exec part of the INSTSEG, or to consider it as simply EXECLOADed.  Of course, this choice influences the search order as we have just seen. 

Thus, when you enter a command in the CMS environment, CMS uses the following search order to locate the command for execution :

  1. Search for an exec with the specified command name using the order as explained above. 
  2. Search for a translation or synonym of the specified command name.  If found, search for an exec with the valid translation or synonym by repeating step one. 
  3. Search for a module with the specified command name :
    1. Search for a nucleus extension module (NUCXLOADed or part of a logical segment). 
    2. Search for a module in the transient area. 
    3. Search for a nucleus-resident module. 
    4. Search the table of active (open) files for a file with the specified command name and a file type MODULE.  If more than one open file is found, use the one opened first. 
    5. Search for a file with the specified command name and a file type of MODULE on any currently accessed disk or SFS directory, using the standard CMS search order (A to Z). 
  4. Search for a translation or synonym of the specified command name.  If found, search for a module with the valid translation or synonym by repeating Step 3. 

If the command is not known to CMS -that is, all of the above fails - it is passed to CP, provided IMPCP has not been set OFF.  If CP does not recognize the command either, you get the typical Unknown CP/CMS command, and the return code is set to -3.

For example, if you enter the command : x sauces cookbook, CMS would search as follows :

  1. First, look for X EXEC.  Here, assume that X EXEC is not found. 
  2. Then, look up the translation and synonym tables.  CMS will normally discover that X is a synonym for XEDIT.  CMS then repeats step one, searching for XEDIT EXEC this time.  Again, assume that an XEDIT EXEC is not found. 
  3. Next, CMS searches for a CMS command with the name X.  It would not be found either. 
  4. CMS again looks up the translation and synonym tables and finds that X is a synonym for XEDIT.  Then, CMS repeats step 3, but searches for XEDIT.  The XEDIT command would be found as an internal command and processed.  The file will thus be edited. 

For more information on the CMS command search order, see the VM/ESA: CMS Command Reference.  For additional information on searching for a translation or synonym, see the SET TRANSLATE or SYNONYM command in the VM/ESA: CMS Application Development Guide

As you can see from the above, the search process can be quite long and elaborated.  In your daily work you probably don't realize what really happens in your system. 

However, if you are responsible for developing programs or procedures that will be used by a large number of users, you must be concerned by aspects such as performance, reliability and security

This is where the address statement of REXX and the CMS and COMMAND device drivers of CMS Pipelines come into play.  We'll thereby have to make a distinction between different environments where procedures are used. 

For example, it makes a difference if a procedure is called from the CMS environment.  By this we mean that the command is addressed to CMS directly.  Most of the time, it will be from the Ready; prompt, but it can also be from the XEDIT command line, provided the command is prefixed with the keyword CMS.  In both cases, we issue a call for a CMS command, or a CMS EXEC procedure.

If, from the XEDIT command line, we call a command without the CMS prefix, the we probably call for an XEDIT subcommand or XEDIT macro, one with a filetype XEDIT.

The CMS EXECs.

As just stated, these procedures are executed from the CMS environment.  Their filetype is EXEC.  Let's discuss now how commands inside those procedures are handled and searched for.

Default situation.

If no address statement is coded in these REXX procedures, the default addressing is address CMS.  This means that, all CP or CMS commands encountered in the procedure, are passed to CMS as if they were entered directly at the terminal (or from the CMS environment). 

The consequences are as follows :

  1. The statements can be coded in mixed case.  CMS will translate them internally to uppercase before execution (just as you can enter commands in mixed case at the terminal). 
  2. The full command resolution, described earlier, applies. 

Note If CMS does not recognize the command, it is passed to CP, which may also not recognize the command.  In that case the procedure gets the -3 return code.  For this reason, REXX procedures should include a trace N (with N for Negative return codes), either than trace Off.

From the above, we can conclude 2 extremely important facts :

  1. The time to launch the command will be longer, because of the long command resolution of CMS (leading to performance loss).
  2. You are never certain which command actually gets executed.  Indeed, if there is an EXEC procedure on any of your accessed minidisks, that has the name of the CMS command you intended to execute, this EXEC will take precedence because of the search order of CMS. 

Danger Conclusion: Your procedure is not foolproof.

For example, you want to execute a RENAME command in your procedure, but somehow you have access to a RENAME EXEC which does an ERASE... Result : your procedure will execute the RENAME procedure, actually resulting in an ERASE !

This looks silly as example, but is perfectly feasible.  In fact, if you want to create a virus on your VM system, this is one of the possibilities you have...  Be prepared to have excellent backups !

System personnel frequently hear users complaining, saying things like

my procedure worked OK yesterday, but now it doesn't work anymore, what have YOU changed to the system ?

And the answer is, yesterday the user had not accessed your tools disk containing the RENAME EXEC, whereas today he got the access... 

Yet another problem that you may encounter is, for example, that you can no longer use the CP LINK command with a password in the procedure.  This happens if, at system generation, an option was set by which passwords are refused as parameter to the command. 

Question 10 Why is it that you can't solve this problem by stacking the password ?

Using ADDRESS COMMAND.

If you use the statement address command in your REXX procedure, then things change completely :

  1. The commands passed to CMS or CP must be coded using uppercase (as neither CMS nor CP will translate them for you anymore, and they only understand uppercase commands.  Remark that we speak about the commands, not the parameters, which can in some cases be coded using mixed-case characters.  Commands such as EXECIO and PIPE use upper case parts of the parameters internally in order to recognize keywords, but leave other parameters unchanged.
  2. If a procedure is to be called, the procedure name has to be preceded by the keyword EXEC
  3. If a CP command has to be executed, it has to be preceded by the keyword CP (do you remember the EXEC1 and EXEC2 days ?). 

Hence, with the address command you loose something (stricter coding rules) but you gain a lot :

  1. The performance of the procedure is augmented.  Indeed, CMS will limit its search order to steps three and four.  On the other hand, as a CP command needs to be prefixed by the CP keyword, it's clear to CMS that it can pass the command directly to CP and its execution is not influenced by the IMPCP setting.  CP is indeed an ordinary CMS command whose sole purpose is to call a CP service.
  2. An even more important advantage is that your procedure now becomes foolproof.  Indeed, because you need to be explicit about whether you want to execute an EXEC, a CMS command or a CP command, it's impossible to fall into the same trap as described earlier with the RENAME EXEC. 
  3. Because most commands know whether they are called by another program and not from the terminal, they will not display error messages (e.g. ERASE will not display File not found), but will return an appropriate return code instead.  The use of set cmstype ht/rt is no longer required. 
  4. At the same time, our problem with the LINK passwords is solved too.  The password can now be included on the LINK command (footnote).

One last remark here.  Only very recently we discovered that a user-defined synonym can still interfere with our procedure.  Indeed, if you look back at the CMS search order, you'll see that CMS also looks for synonyms or translated commands in step four. 

For example, suppose the user has defined LIST to be a synonym of FLIST, with possible abbreviation to one character, while on the other hand, we in our procedure have coded something like

    address command
    'L * * F (STACK'

then, because of the CMS search order, the users' synonym gets executed and thus results in the FLIST command that does not understand the STACK option. 

If you want to be absolutely certain that the LISTFILE command gets executed (and thus that synonyms are bypassed), then you have to code the CMS commands without abbreviation, as follows:

    address command
    'LISTFILE * * F (STACK'   /* instead of 'L * * F (STACK' */
    'QUERY DISK (STACK'       /* instead of 'Q DISK (STACK'  */

Now, even if the user defines LISTFILE as to be a synonym of FLIST, the real CMS LISTFILE command will be executed, as step three will result in an immediate match, and synonyms are ignored.  This is not fully explained in the chapter about CMS search order in the manuals. 

Remember To make your procedures better performing and safer, code an address command at the beginning of it. 

Then :

  1. Commands, and in most cases the parameters too, must be specified with uppercase characters ;
  2. CP commands must be prefixed by the CP keyword ;
  3. A call to an external procedure must be prefixed with the EXEC keyword ;
  4. CMS commands should not be abbreviated. 
  5. You can omit most of the set cmstype ht commands because error messages are suppressed.  Remember that with HT you suppress almost all messages, even the more severe ones, while address command only suppresses the less important ones (such as File not found ).

Note that coding address ' ' is absolutely equivalent to address command, it's just a useful short notation. 

The only instance where address CMS is justified is when your procedure accepts commands from the user and has to execute it.  Most users do not always make the distinction between the different environments.


XEDIT macros.

The default environment for an XEDIT macro (filetype XEDIT) is XEDIT itself.  It means that an implicit address XEDIT is used. 

This is good, but sometimes you may want to execute a CMS or CP command in an XEDIT macro.  Then the rules described above still apply, but there is an extra player in the game - XEDIT itself. 

If you enter a command on XEDIT's command line (or code it in an XEDIT macro), without being explicit about the environment you want to address, then XEDIT will take this command for itself first.  If XEDIT does not understand the command, then it passes it along to CMS - this is only true if IMPCMSCP (Implied CMS and CP) is set ON (which is the default, but the user may have changed it).  From there on, CMS treats the command as with an address CMS, hence not foolproof any more.  If it's not recognized by CMS, it will pass it to the CP level (depending on the IMPCP setting). 

Now, let's take the example of the SET command.  XEDIT, CMS and CP all have some form of SET command.  So, if we aren't explicit in our command, then XEDIT will take it for itself.  If the parameters are not recognized by XEDIT (because we actually wanted to execute a CMS or CP SET command), then XEDIT will return a bad return code. 

So, on the XEDIT command line, we all have learned to use the CP or CMS prefixes in order to address the correct environment if the command is not exclusive to a specific environment. 

In our XEDIT macros, we can temporarily switch from the implied address XEDIT status to the address COMMAND status.  This can be done in 2 ways :

  1. Code an address command on a separate statement, followed by one or more CMS or CP commands, and finally an address XEDIT statement to return to the XEDIT environment, like in this example:
         address command
         'CP SPOOL CONSOLE START'
         'ERASE TEMP FILE A'
         address 'XEDIT'
    
  2. Prefix each CMS or CP command with an address command.  This is useful if you have only one non-XEDIT command to issue.  Thus, something like this :
         address command 'CP SPOOL CONSOLE START'
    

While we're on the subject, remember that XEDIT also makes a distinction between basic commands and macros.  Furthermore, XEDIT also allows defining synonyms for its commands.  So, we can have similar problems in XEDIT - executing macros when we want a basic command - as we had with CMS.  This time however, we can control the execution of the commands or macros by explicitly using either the COMMAND or MACRO prefix in our statements.  Note that the COMMAND prefix here has nothing to do with our address command, it's entirely an XEDIT built-in command.  For example:

      'COMMAND DELETE 2'
      'MACRO ALL /this/ ! /that/'

An alternative to this, although not so easy to control and to code, is to use the SET MACRO ON/OFF and SET SYNONYM ON/OFF commands to control the execution of macros, synonyms or commands.  Also, don't forget to restore the settings before returning to the user.

Remember

For XEDIT macros :

  1. Control the execution of XEDIT commands or macros via the COMMAND or MACRO prefix. 
  2. direct a command to CMS or CP (incidentally, also the call to a CMS EXEC) by temporarily switching to address command.

One further remark here, again in favour of the address command, is that XEDIT truncates all commands to 255 characters.  With an address command, REXX does not send the commands to XEDIT, and thus, truncation does not occur.  CMS Pipelines, for example, can become very large strings.


Other environments, SUBCOMs.

More and more products include an interface to REXX, allowing procedures to use the functions of the products.  Examples are ISPF, SQL, GDDM, CPI-C, and many others (also on other platforms like OS/2). 

In most cases, these products define themselves as sub-environments (or to use the exact term, sub-commands or SUBCOMs) to CMS.  So, just as for XEDIT, they define their proper environment that can be 'reached' by REXX via the address statement. 

So for example, to address ISPF, you would use an address ISPEXEC statement, while CPI-C would be reached via an address CPICOMM statement. 


And what about CMS Pipelines ?

Most of what we've said above applies also somehow to CMS Pipelines.  First of all, PIPE is a regular CMS command, so use address command whenever it is appropriate.

CMS Pipelines provides the CMS, COMMAND and CP device drivers to execute CMS or CP commands. 

We will discuss these stages in more detail later.  Just remember now that these drivers execute the commands and, instead of displaying the result to the terminal, pump the results into the pipeline. 

MoreInfo

So, what's the magic ?  For CMS commands, the CMS or COMMAND stages intercept the CMS terminal output before it reaches the screen and pump the lines into the pipeline.  For CP commands, the CP device driver issues a regular diagnose x'8', but asks CP to return the results in a buffer instead of displaying it at the terminal (just like REXX does it via the diag() function). 

What to use ? COMMAND, CMS or CP device drivers.

As both REXX and CMS Pipelines use the same internal interface to pass commands to CMS, it is not a surprise that the CMS device driver has the same drawbacks as REXX's address CMS, and that the COMMAND device driver behaves as with an address COMMAND in REXX. 

It's a shame that both REXX and CMS Pipelines manuals are still primarily showing address CMS and CMS stages.  We presume this is because they want to open to the broadest public  who may not know the difference between CP and CMS commands or procedures.

So, let's repeat once more the advantages of the COMMAND driver :

  1. No full command resolution (thus, you have to use the EXEC prefix to execute EXEC procedures) leading to better performance and more foolproof pipelines (fewer leaking pipelines, less chance that the user has to call a plumber to fix it, etc). 
  2. Commands and parameters are not translated to uppercase, so you must code them in the proper format (commands certainly in upper case, parameters can sometimes be in mixed case). 
  3. Minor error messages are eliminated in many cases.  Headers are also often suppressed.

This last item is much more important for CMS Pipelines than it is for REXX procedures.  These drivers pump the output of the commands into the pipeline, and so will the error messages if you don't choose the right option.  But more on this later.

Remember

  1. Use the COMMAND stage to execute CMS commands.  Use the CMS stage only when you execute commands a user feeds to your procedure. 
  2. To intercept output from CP commands in your pipelines, you must use the CP device driver.  CMS or COMMAND can issue CP commands, but then the output goes to the terminal, not into the pipeline. 
  3. If you have used REXX for a long time, you will be used to the fact that the CMS command 'QUERY xxx (STACK' does not return a header, whereas for example, the stage 'COMMAND QUERY xxx  does.  Never assume that the output you get when executing a command from the terminal will be the same as when you issue it with a COMMAND stage.  So, use a little PIPE to test :
        PIPE COMMAND LISTDIR ! TAKE 5 ! CONSOLE
    

A typical pipeline using COMMAND looks like this :

Coding pipelines in REXX procedures.


   /* Coding pipelines */
   address command                           /* hope you're convinced now */
   'PIPE'                      , /* need uppercase due to address command */
      '!command LISTFILE * * A', /* pipeline parameters can be lowercase, */
                                 /* but parameters of COMMAND stage must  */
                                 /* be coded in uppercase again...        */
      '!specs w2 1'            , /* pipe parameter, thus can be lowercase */
      '!console'               , /* pipe parameter, thus can be lowercase */
   exit rc

The example shows that you can create a mess.  We personally prefer to follow our coding style that says

code all commands and their parameters with upper case characters (unless lower case is important), and code all REXX statements and variables with mixed case characters.

In the previous example we would therefore code the whole pipeline in uppercase. 

But, on the other hand, pipelines can become rather long and complex, and then use of mixed case can enhance readability.  It's not possible to give an absolute rule, and it can be a matter of taste. 


How to get the error messages ?

We have one last problem to solve.  We said that due to the COMMAND stage, many CMS commands will not produce error messages.  But there may be cases where we would like to get these error messages in the pipeline anyway, to display them at the terminal to inform the user. 

Do we have to revert to the CMS stage to get the error message back ?

No, there is another useful CMS command - namely CMDCALL.  This command takes other CMS commands as parameters and lets CMS execute these commands as if they came from the terminal (and thus error messages and headers are produced as normal). 

If we combine the COMMAND stage (or address command as a matter of fact), with this CMDCALL command, as follows:

   pipe command CMDCALL LISTDIR ! > LISTDIR OUTPUT A

then :

  1. Because of the COMMAND stage, we are certain to execute the LISTDIR command and not a synonym or homonym procedure,
  2. Because the CMDCALL, LISTDIR thinks it is executed from the terminal and thus issues error messages, as you would get if the command was issued from the CMS environment. 

However, in this case, the output is pumped into the next pipeline stage, from where you can further process it.  For example:

    'PIPE COMMAND CMDCALL LISTDIR' somedir,
         '!VAR EMSG',                      /* any error message ? */
         '!DROP',                          /* drop the header     */
         '!STEM DIR.'                      /* save result...      */
    if rc<>0 then do
       say 'Unable to list directory' somedir
       say 'Error message is:'
       say emsg
       exit rc
    end
    do i=1 to dir.0
       ....
    end

CMS Pipeline REXX stages - a special case

Pipe stages written in REXX have a default addressing so that PIPE subcommands can be recognized (e.g. PEEKTO, OUTPUT, etc.). 


General Conclusions.

An illustration of everything we have said in this article will probably further help you understand the different options.  The procedure below will accept any command as parameter and execute it once for all of the following cases:

  1. address CMS cmd
  2. address COMMAND cmd
  3. address COMMAND 'CMDCALL' cmd
  4. 'PIPE CMS' cmd '! CONSOLE'
  5. 'PIPE COMMAND' cmd '!CONSOLE'
  6. 'PIPE COMMAND CMDCALL' cmd '!CONSOLE'

This procedure might also be useful in order to analyse the returned information (headers, error messages, etc.):

Analyze results of commands - TCMD EXEC ©

 /* TCMD EXEC - Analyze results of commands */
 parse upper arg cmd

 Say '*** Case 1 : Result of "address CMS' cmd'" ***'
 address CMS cmd
 Say 'Retcode:' rc

 Say '*** Case 2 : Result of "address COMMAND' cmd'" ***'
 address COMMAND cmd
 Say 'Retcode:' rc

 Say '*** Case 3 : Result of "address COMMAND CMDCALL' cmd'" ***'
 address COMMAND 'CMDCALL' cmd
 Say 'Retcode:' rc

 address command
 Say '*** Case 4 : Result of "PIPE CMS' cmd'!CONSOLE" ***'
 'PIPE CMS' cmd'!CONSOLE'
 Say 'Retcode:' rc

 Say '*** Case 5 : Result of "PIPE COMMAND' cmd'!CONSOLE" ***'
 'PIPE COMMAND' cmd'!CONSOLE'
 Say 'Retcode:' rc

 Say '*** Case 6 : Result of "PIPE COMMAND CMDCALL' cmd'!CONSOLE" ***'
 'PIPE COMMAND CMDCALL' cmd'!CONSOLE'
 Say 'Retcode:' rc

A sample output can be seen below :

> tcmd erase no file
*** Case 1 : Result of "address CMS ERASE NO FILE" ***
DMSERS002E File NO FILE not found
Retcode: 28
*** Case 2 : Result of "address COMMAND ERASE NO FILE" ***
Retcode: 28
*** Case 3 : Result of "address COMMAND CMDCALL ERASE NO FILE" ***
DMSERS002E File NO FILE not found
Retcode: 28
*** Case 4 : Result of "PIPE CMS ERASE NO FILE!CONSOLE" ***
DMSERS002E File NO FILE not found
Retcode: 28
*** Case 5 : Result of "PIPE COMMAND ERASE NO FILE!CONSOLE" ***
Retcode: 28
*** Case 6 : Result of "PIPE COMMAND CMDCALL ERASE NO FILE!CONSOLE" ***
DMSERS002E File NO FILE not found
Retcode: 28
Ready;

Only cases one, three, four and six display the error messages.  In cases one and four, an ERASE EXEC could break your procedure.

> tcmd state no file w
*** Case 1 : Result of "address CMS STATE NO FILE W" ***
DMSSTT069E Filemode W not accessed
Retcode: 36
*** Case 2 : Result of "address COMMAND STATE NO FILE W" ***
Retcode: 36
*** Case 3 : Result of "address COMMAND CMDCALL STATE NO FILE W" ***
DMSSTT069E Filemode W not accessed
Retcode: 36
*** Case 4 : Result of "PIPE CMS STATE NO FILE W!CONSOLE" ***
DMSSTT069E Filemode W not accessed
Retcode: 36
*** Case 5 : Result of "PIPE COMMAND STATE NO FILE W!CONSOLE" ***
Retcode: 36
*** Case 6 : Result of "PIPE COMMAND CMDCALL STATE NO FILE W!CONSOLE" ***
DMSSTT069E Filemode W not accessed
Retcode: 36
Ready;

The same remarks apply here as in the first run.

> tcmd Listfile profile exec
*** Case 1 : Result of "address CMS LISTFILE PROFILE EXEC" ***
PROFILE  EXEC     A0
Retcode: 0
*** Case 2 : Result of "address COMMAND LISTFILE PROFILE EXEC" ***
PROFILE  EXEC     A0
Retcode: 0
*** Case 3 : Result of "address COMMAND CMDCALL LISTFILE PROFILE EXEC" ***
PROFILE  EXEC     A0
Retcode: 0
*** Case 4 : Result of "PIPE CMS LISTFILE PROFILE EXEC!CONSOLE" ***
PROFILE  EXEC     A0
Retcode: 0
*** Case 5 : Result of "PIPE COMMAND LISTFILE PROFILE EXEC!CONSOLE" ***
PROFILE  EXEC     A0
Retcode: 0
*** Case 6 : Result of "PIPE COMMAND CMDCALL LISTFILE PROFILE EXEC!CONSOLE" ***
PROFILE  EXEC     A0
Retcode: 0
Ready;

The all produce the same result, but we were lucky that there wasn't a Listfile EXEC procedure... 

> tcmd access .telecour t
*** Case 1 : Result of "address CMS ACCESS .TELECOUR T" ***
Retcode: 0
*** Case 2 : Result of "address COMMAND ACCESS .TELECOUR T" ***
Retcode: 0
*** Case 3 : Result of "address COMMAND CMDCALL ACCESS .TELECOUR T" ***
Retcode: 0
*** Case 4 : Result of "PIPE CMS ACCESS .TELECOUR T!CONSOLE" ***
Retcode: 0
*** Case 5 : Result of "PIPE COMMAND ACCESS .TELECOUR T!CONSOLE" ***
Retcode: 0
*** Case 6 : Result of "PIPE COMMAND CMDCALL ACCESS .TELECOUR T!CONSOLE" ***
Retcode: 0
Ready;

This gives the same output in all cases, but, if we issue the same command with an invalid directory name, then we get:

> tcmd listdir .wrongdir
*** Case 1 : Result of "address CMS LISTDIR .WRONGDIR" ***
DMSJLD1184E Directory IECSYSU:MAINT.WRONGDIR not found or you are not authorized for it
Retcode: 28
*** Case 2 : Result of "address COMMAND LISTDIR .WRONGDIR" ***
Retcode: 28
*** Case 3 : Result of "address COMMAND CMDCALL LISTDIR .WRONGDIR" ***
DMSJLD1184E Directory IECSYSU:MAINT.WRONGDIR not found or you are not authorized for it
Retcode: 28
*** Case 4 : Result of "PIPE CMS LISTDIR .WRONGDIR!CONSOLE" ***
DMSJLD1184E Directory IECSYSU:MAINT.WRONGDIR not found or you are not authorized for it
Retcode: 28
*** Case 5 : Result of "PIPE COMMAND LISTDIR .WRONGDIR!CONSOLE" ***
Retcode: 28
*** Case 6 : Result of "PIPE COMMAND CMDCALL LISTDIR .WRONGDIR!CONSOLE" ***
DMSJLD1184E Directory IECSYSU:MAINT.WRONGDIR not found or you are not authorized for it
Retcode: 28
Ready;

Having said all this, we now have a clear conscience !

This concludes Lesson 1.  You are now ready to proceed with the coding exercises for this lesson.


Footnotes:

(1) The question remains, why would you define a password if you hard-code it in readable format in your procedure anyway ? Even compiling your EXEC will not completely hide the password. 
Back to text