MVS TOOLS AND TRICKS OF THE TRADE NOVEMBER 2005 Sam Golob MVS Systems Programmer P.O. Box 906 Tallman, New York 10982 Sam Golob is a Senior Systems Programmer. He also participates in library tours and book signings with his wife, author Courtney Taylor. Sam can be contacted at sbgolob@cbttape.org. Information about the CBT MVS Tapes can be found on the web, at http://www.cbttape.org. MAKING YOUR WORK SHORTER WITH TOOLS I recently had a task to perform, which I was able to "knock off" in about ten minutes, and which might have taken someone else considerably longer to do. The job was greatly shortened by the fact that I had written a tool several years ago, that broke this job into two steps--one automatic, and the other easy. Without this tool, I'd bet the job would have taken no less than an hour or longer. So today, I'd like to talk about several "sysprog jobs" which can be made much shorter, provided that we deploy a tool or two. All these tools are obtainable for free, and you can install them one at a time, to add to your arsenal. An excellent source for free tools is the enormous "CBT Tape" collection that can be found on the web. Just search in www.google.com for "CBT Tape", and you should get there. You don't have to be a "member of anything" or to have any special password, to be able to access and download tools from the CBT Tape collection. Now, we'll talk about a few types of tasks, where I've found I can save a lot of time using specialized tools that not everybody knows about. EXTRACTING SOFTWARE FROM SMPPTFIN FORMAT FILES I recently needed a newer version of some Assembly macros that are normally distributed in several system macro libraries. I didn't want to affect my system's SMP/E libraries by RECEIVE-ing the maintenance. In fact, the macro versions I wanted, weren't for the system level that the production system was at. I just needed to have these macros alone, so I could cleanly assemble a program using them. Since I was entitled to pull PTFs electronically, and I knew which numbers to get, I went and got them, but the only trouble was that for one macro, almost two million lines of data got shipped to me from IBM, in the form of an SMP/E SMPPTFIN-format sequential file. How was I to accurately (and quickly) pull this macro of perhaps 500 lines, from all of that data? I did know the PTF number that my macro was in, but it came shipped along with over 180 prereqs and coreqs. How could I make this job doable, and do it accurately? Fortunately there is a tool, on CBT Tape File 118, which can make a partitioned dataset out of an SMPPTFIN-format sequential file, with the sysmods (read PTFs) as separate members. The program, called SMPUPD, is admittedly a little kludgey, but if you have the work space on disk, it sure works great! SMPUPD simply makes a copy of the SMPPTFIN format file, but it adds IEBUPDTE ./ ADD cards before each PTF, with the PTF number as the member name. And after you have the copied file (which can be a temporary file), you just have to run that file into IBM's IEBUPDTE program and load up a pds with each PTF as a member name. It's very simple and mechanical, once a workable piece of JCL has been set up. The SMPUPD program (Assembler version) also has the added advantage that it prints very detailed statistics about the PTFs in the input, and how many lines each one has. If you want the statistics alone, you can do a dry run by executing SMPUPD with PARM=READ for read-only operation. So I took my two-million-line input, and made a pds out of it. Then, I just looked for the PTF number I wanted, as member name, and edited it. In no time, I had the macro that I wanted. If you want raw object code out of a PTF, you can get it this way, too. What you do with it afterwards, depends on your needs and your skills. I've used this technique in the past to linkedit the object deck and get displacement values out of it, to refit the zaps for a vendor product such as CA-1 tape management, ahead of time. It's quite obvious that circumventing SMP/E processing of SMPPTFIN files might be very useful at times, especially when software that is distributed by IBM as a PTF or other sysmod might be needed as an isolated program, rather than being part of your production system. You might need to experiment with a different version of a system program, that could have unknown bugs, without compromising the integrity of your main MVS machine. So in this way, by extracting the needed data from the PTF and putting it together yourself, you can accomplish your goal without much risk to the system, and without messing up the installation's SMP/E configuration. You can take this technique as far as your imagination will carry you, as long as you minimize the risks. USING THE PDS PACKAGE "FIND-REPLACE" FACILITY The amazing free "PDS Program package" from CBT Tape File 182 offers a "string find and string replace" capability that spans many pds members. This facility is so useful, and in my opinion, so under-used by the public, that I feel it is very much worth mentioning when it comes to learning about tools that can save you lots of time. We owe the PDS program largely to the labors of Bruce Leland and Steve Smith (in the past) and to John Kalinich (in the present) with many helpers along the way. If you want to find out A LOT about the PDS command package, refer to my series of articles about most of its subcommands, originally printed in "Technical Support" in 1988, and now available as members $PDSARTx, x=0,1,2,3 in CBT Tape File 182. I had spent perhaps 300 hours on the telephone, talking to Bruce Leland and Steve Smith, in gathering the information to write those articles. For people who have never used the PDS program package, it consists of a "TSO line mode" part and an "ISPF mode" part. To use the PDS program in TSO line mode, all you need is the load module. To use PDS in "ISPF mode" (called ISPMODE by the PDS program internally), you have to have the set of ISPF panels and messages available to your TSO session. The PDS program is set up at assembly time with a lot of options, one of which is to start ISPMODE automatically (although this can be turned off). If the PDS program load module was assembled that way, you can still execute it in line mode by entering: PDS dataset.name XISPMode where the XISPMODE keyword will tell PDS not to look for the ISPF stuff which is the panels and the messages. All the ISPF panels and messages are found in File 182, with instructions (in the $$$INST member) about how to put them in. The PDS program, properly installed, also can use some extra utilities which can be found in CBT File 296, as well as the VTOC command from CBT File 112. And it can call the REVIEW program from File 134 (source) or File 135 (load). For a quicker install, we have just included a separate member in File 182 (called UTILXMIT) which is a load library with all the load modules for the extra utilities that PDS can use, in TSO XMIT format. We will not discuss the many capabilities of the PDS command package here. (The PDS command has over 50 separate subcommands.) But we will concentrate on PDS's "FIND" and "REPLACE" (in place) facilities for now. I do have to add that PDSE support has been added to the PDS package recently, by John Kalinich and Greg Price, and that the new release number for free PDS, with the PDSE support, is PDS 8.6. The commercial version of PDS, called STARTOOL FDM, with VSAM support and many other extras, is marketed by Serena Software, Inc. The PDS command (in either line mode or ISPMODE) must always point at a dataset. This is a dataset which PDS is going to either examine or manipulate. If the dataset is a partitioned dataset, PDS has the distinguishing characteristic that it always keeps track of a subgroup of the pds members, and that all its actions will go against all the members included in that subgroup. Internally, the PDS command calls this group of members the "current member subgroup". The member subgroup can be defined either by means of a RULE using the MEMBERS subcommand (i.e. all members containing the string pattern ABC, defined by the rule /ABC), or it may be defined as a list of individual members, called a SUBLIST. For a particular pds, the "rule" definition can be converted to a sublist, by using the "SUBLIST" PDS subcommand. Since the current member group is referred to in the PDS package by using an asterisk "*" instead of the member name, the command "SUBLIST *" can be used to "convert the current member group definition into a list of member names" automatically. After this necessary introduction to the PDS package, we'll show you some of the time-saving operations that you can do, using its FIND and REPLACE subcommands. Once you know how to use these well, only your imagination will limit the amazing things you'll be able to do, and in no time flat. I have to mention here that all "string replacement" actions done by PDS's REPLACE subcommand, are done "in place", so that no dataset compression will be necessary afterwards. FIND and REPLACE also work with load modules, believe it or not. But with load modules, you have to replace all found strings with an equal length replacement string. If you also want to find strings in the IDR records of load modules, you have to use the PDS FIND and REPLACE subcommands with the DUMP option. It goes without saying, that all of these operations have to be done with great care and responsibility, because of their implications. PDS "FIND-REPLACE" WIZARDRY Let's start, and say that if you have a JCL pds, and you want to do a global change to a group of its members because a dataset name has changed at your installation, that the PDS package, in either line mode or ISPMODE, can do the job for you. For example, to discover which members contain the name of the dataset which has to be changed, just enter the PDS subcommand (the colon ":" in PDS stands for "all members") FIND : /old.dataset.name/ THEN(SUBLIST) and this command will cause PDS to look in ALL the pds members for the string "old.dataset.name" and the result will be a sublist of members, all of which contain the given string. Using a slash in the command is not absolutely necessary. The slash is used here to delimit the definition of the "find string". Actually, the FIND command just looks at the first character where a string is to be defined, and it considers that character as the delimiter. So if your string itself contains a slash, you might use another delimiter, such as a question mark "?" in specifying the string to be searched for. To change this string, in ALL the members containing it, to some other string, you use the REPLACE subcommand of the PDS command. And when you use the REPLACE command, you have to now specify TWO strings, the old string which needs to be found, and the new string you'll want to replace it with. In our case, if you've already found all occurrences of "old.dataset.name" and created a sublist using the above FIND subcommand, the proper REPLACE subcommand will read: REPLACE * /old.dataset.name/new.dataset.name/ As written, REPLACE will show you all the string occurrences, in all the members, that will be replaced. It will only be a dry run. To make the changes permanent, you add the WRITE parameter to the REPLACE subcommand: REPLACE * /old.dataset.name/new.dataset.name/ WRITE and the changes will be permanent, using "replace in place" logic. Since we're coming to the end of our space for this month, I'll mention one more trick before closing. Suppose that I have a system problem and the system produces an error message, say IEF999I. I can search SYS1.LINKLIB and SYS1.LPALIB to see which modules contain that message, using the PDS FIND command. Let's say that I've pointed PDS to SYS1.LINKLIB as follows: PDS 'SYS1.LINKLIB' Then, once this has been done, I use a FIND command to get occurrences of the message id: FIND : ?IEF999? where for illustrative purposes, I've now used a question mark as the delimiter instead of a slash. PDS will deliver a picture of all module pieces containing the string IEF999 (I've left the "I" off the search purposely). Or, I can also say: FIND : ?IEF999? THEN(SUBLIST) and I can examine each of the found members individually afterwards, once I know their names. The nice thing about this, is that once I know the module names which can produce this message, I can search IBM's knowledge base to determine if there are any PTFs against them. This method has often helped me to discover the solution to some tough looking problems. So I hope that I've given you a taste of some pretty nifty things you can do, if you have learned to use a few of the many free tools that are available on the CBT Tape collection (for example). Besides giving you something to think about, I hope that eventually, these techniques (and extensions of them) will be able to save you big gobs of time. I wish all of you the best of everything, and I hope to see you here again, next month.