Tag Archives: cobol

Finding the z/OS Sysname in CICS

Today I’ve got a simple but neat little tip to share. Have you ever had a need to know which z/OS system your CICS program is running in? I found myself in that situation today, needing a way to programmatically set the hostname in the URL in a CICS web application. The CICS web application could be running in any LPAR. The z/OS system running in each of our LPAR’s has a unique sysname, so if I could access that, I could determine the hostname for that z/OS.

Looking in SYS1.MACLIB(CVT), we see that z/OS has a control block called the CVT (Communications Vector Table) that contains the sysname 340 bytes into it. In the comments at the top of that member, we learn that there is a pointer to the CVT in the PSA (Prefixed Save Area) x’10’ bytes into it. The PSA is easy to find – it is at address 0. So, armed with this info, I wrote the sample code below, which you are welcome to use or incorporate into your own project. If you use this code, just define a PPT for it (if you do not use autoinstall for programs) and point a tranid to the program.

IDENTIFICATION  DIVISION.
PROGRAM-ID.     CVTTEST.

ENVIRONMENT  DIVISION.
DATA  DIVISION.
WORKING-STORAGE  SECTION.

01   WS-PSA-POINTER.
10   PSA-PTR-PIC9        PIC S9(8) COMP-5 VALUE  0.
10   PSA-PTR             REDEFINES PSA-PTR-PIC9 POINTER.

01   SEND-AREA.
10   FILLER              PIC X(1)  VALUE SPACE.
10   FILLER              PIC  X(11) VALUE 'CVTSNAME = '.
10   SA-CVTSNAME         PIC X(8)  VALUE  SPACES.

LINKAGE  SECTION.

01   PSA.
10   FILLER              PIC  X(16).
10   CVT-PTR             POINTER.

01   CVT.
10   FILLER              PIC  X(340).
10   CVTSNAME            PIC  X(8).

EJECT

PROCEDURE  DIVISION.

100-MAINLINE.

SET ADDRESS OF PSA TO  PSA-PTR.
SET ADDRESS OF CVT TO  CVT-PTR.

MOVE CVTSNAME TO  SA-CVTSNAME.

EXEC CICS SEND  FROM(SEND-AREA)
LENGTH(LENGTH OF  SEND-AREA)
END-EXEC.

999-RETURN.

EXEC CICS  RETURN
END-EXEC.

GOBACK.

SHARE 112 Review

There were plenty of great sessions at SHARE in Austin last week. I focused primarily on CICS sessions, and from Steve Ware‘s and Kathy Tyrrell’s Project Opening and Product Update through the Q-Box session featuring all of IBM’s CICS representatives, there was a lot of information to absorb. As speculated, there was quite a bit revealed about the upcoming CICS/TS 4.1 release. In case you did not attend SHARE in Austin but are considering attending in Denver, I’ll review some of the things that I thought made SHARE worth the trip. I can’t possibly give details on all of the sessions that I attended, but I’ll mention some of the highlights to give a flavor of what SHARE’s about.

John Tilling gave a CICS/TS 4.1 Technical Overview. In it, he revealed some details on event processing support, ATOM support, and that CICS Explorer, the GUI tool for defining resources, will be part of the CICS/TS 4.1. Where the beta version that was made available for CICS/TS 3.1 and 3.2 was read-0nly and required CPSM, CICS Explorer in 4.1 will be able to update and will not require CPSM. Matthew Webster gave an excellent demo of CICS Explorer in a later session.

I try to keep up with the latest trends in IT (I was involved in a project to serve information from CICS via web services before IBM started providing support for it), but I was behind some of the Web 2.0 technologies, such as REST, AJAX, JSON, etc. Dennis Weiand gave a really good presentation that explained a lot of these terms in easy-to-understand language, and talked about about how PHP can be used in CICS.

If you haven’t seen Ivan Gelb‘s CICS Performance Management and Best Practices session, I would highly recommend it. In fact, since Ivan keeps it current, I would recommend it even if you have seen it before. I saw some things I want to review to make sure we are meeting best practices in our shop.

I also try to catch some non-CICS sessions while at SHARE. I thought John Eells’ New Facilities and Features Beyond 1.10 had a lot of good information. z/OS 1.11 will be GA in September, and this session gave some insight about DS8000 support, extended format sequential files, performance improvements, and much more. z/OS 1.10 is the last to support the old LDAP server, so if you are still running it, it’s time to start converting to the new one.

Liam Doherty and Peter Van Dyke from IBM’s ISPF development facility in Perth gave quite a few sessions. We are lucky they are able to take the time to come this distance to make these presentations. While most speakers did not have handouts, Liam and Peter gave out CD’s with all the vital info from their presentations. SHARE is going “green” and not providing speakers the facilities to make copies of their handouts, so be sure to be ready to take lots of notes while you are there if you get to attend SHARE in Denver. A DVD with the proceedings will be sent in 6-8 weeks, but that’s time to forget a lot of the details if you don’t take good notes!

There is far more information available at SHARE than I have time to hit upon in a quick blog post. There are many sessions on z/Linux, COBOL, Assembler, JES, TCP/IP, VM, personal development – I can’t even begin to list all of the categories of sessions. If you have any chance at being able to attend SHARE in Denver in August, I would highly recommend that you visit the SHARE web site and start making plans.

CICS Access to RACF, Part 2

I admit that I’m a little overdue to post this follow-up to my post about accessing RACF info from a COBOL program in CICS. But when I posted it, I had no idea that was going to be the single most viewed entry on my blog site. So I’ve finally had enough people asking about the teaser with which I ended that post, promising to show how to access the list of groups to which the user is connected, that I’ve been shamed into following thr0ugh. The latest episode of “One Way Out” has ended, so it’s time to quit goofing off and meet that obligation …

Some of this will be a repeat of my original post, but I’ll quickly cover those things so new blogees won’t necessarily have to chase it down. First, to access the ACEE (the RACF control block that has so much RACF info on the user), we’ll need a pointer defined in working storage to point to the control block – something like this:

77  WS-ACEE-ADDR-POINTER USAGE IS POINTER.

And, while we are defining things in working storage, let’s set up a table to contain the groups to which our CICS user is connected:

01  GROUPS-AREA.
    05 WS-GROUPS PIC X(8 ) OCCURS 10 TIMES.

The occurs number is arbitrary. I picked 10 because that would seem to be large enough to cover the list of groups for most users, but if your shop uses groups more extensively, perhaps not. Code a bigger value, or devise a much more clever scheme … I’m not going to spend time on it because that’s not important for what I’m showing here.

We’ll also need somewhere to count the groups as we find them:

77  WS-GROUP-CNT PIC S9(4) COMP VALUE 1.

The IBM-provided record layout for the ACEE is in SYS1.MACLIB(IHQAACEE). But we are not interested in every field listed, so let’s dumb-down the record layout into a data structure in the linkage section, replacing what we are not interested in with FILLER, like this:

01 ACEE.
   05 FILLER PIC   X(021).
   05 ACEEUSRI PIC X(008).
   05 FILLER PIC   X(001).
   05 ACEEGRPN PIC X(008).
   05 FILLER PIC   X(062).
   05 ACEEUNAM-POINTER USAGE IS POINTER.
   05 FILLER PIC   X(012).
   05 ACEECGRP-POINTER USAGE IS POINTER.

There are a couple of pointers in that data structure … We saw in my original post that the first one points to an area of storage containing the user name (as defined in RACF). We’ll ignore it, as we are only interested in the second one at this time – it points to our list of groups, which we will define with the following data structure in the linkage section:

01 ACEE-GROUP-TABLE.
   05 FILLER   PIC X(008).
   05 CGRPNUM  PIC S9(4) COMP.
   05 FILLER   PIC X(022).
   05 CGRPENT  OCCURS 10 TIMES DEPENDING ON CGRPNUM.
      10 CGRPNAME PIC X(008).
      10 FILLER   PIC X(016).

CGRPNUM is going to contain the number of entries in this list. I chose to have it occur up to 10 times because that was the arbitrary value I chose in my table to contain the groups in working storage.

So much for the data definitions – let’s now go get the data! In the procedure division, we’ll need to use the CICS API that allows us to address the ACEE:

EXEC CICS ADDRESS ACEE (WS-ACEE-ADDR-POINTER)
END-EXEC.

Now that we have the address of the ACEE, we can now access that control block, and once we have it, we can access the list of groups, just by setting pointers:

SET ADDRESS OF ACEE TO WS-ACEE-ADDR-POINTER.
SET ADDRESS OF ACEE-GROUP-TABLE TO ACEECGRP-POINTER.

All that’s left to do is run the list, getting our groups:

PERFORM 200-GET-GROUP THROUGH 200-EXIT
UNTIL WS-GROUP-CNT IS GREATER THAN CGRPNUM
OR    WS-GROUP-CNT IS GREATER THAN 10.

That defines our loop (again, with my arbitrary limit of 10), so now let’s set up what gets done in the loop – move the value from the control block to our working storage table and increment to point to the next group:

200-GET-GROUP.
    MOVE CGRPNAME (WS-GROUP-CNT) TO WS-GROUPS (WS-GROUP-CNT).
    ADD 1 TO WS-GROUP-CNT.
200-EXIT.

That is it! Like on our first example, the COBOL coding is not the hard part … The only hard part is knowing where the information is – and I hope I have helped exposed that with these examples. Browse through the assembler definition of the ACEE – you may see some other information that can help you get a job done!

New Section in COBOL Compile Listings

Enterprise COBOL for z/OS 4.1 offers several new features, including enhanced DB2 support (mostly for DB2 V9) and the ability to take advantage of the z/OS XML System Services parser. But what caught my eye was something that every shop can take advantage of. There is a new section in COBOL compiler listings that shows from which library each copybook was pulled, and even when each was created and last changed. To find this section, do a “find” on “COPY/BASIS” while viewing the listing. Be sure that the compile was done with the XREF option set on. This new feature should help if there is any confusion regarding where a copybook came from that was used in the compiling of a program.

CICS Access to RACF

CICS doesn’t supply much  access directly to RACF info via the API. But there is a supported way to obtain a lot of RACF information about the current user. And it can be done in plain ol’ COBOL.

EXEC CICS ADDRESS ACEE will provide access to the RACF ACEE control block. (ACEE stands for Access Control Environment Element. Maybe it will come up in a trivia question some day. Probably not. The important thing to know is that it is a block of storage containing RACF information which can be addressed from application programs.) From there, it is possible to easily obtain the user’s primary RACF group and the user’s name (as it is recorded in RACF).

The layout of the ACEE control block is documented in SYS1.MACLIB(IHAACEE). Unfortunately, there is not a COBOL copybook provided, so to access this information in a COBOL program, we have to code our own storage definitions. The following are based on SYS1.MACLIB(IHAACEE):

01 ACEE.
   05 FILLER PIC    X(021).
   05 ACEEUSRI PIC  X(008).
   05 FILLER PIC    X(001).
   05 ACEEGRPN PIC  X(008).
   05 FILLER PIC    X(062).
   05 ACEEUNAM-POINTER USAGE IS  POINTER.
01  ACEE-USER-NAME.
   05 FILLER PIC    X(001).
   05 ACEEUNAM PIC  X(020).

And we need a piece of miscellaneous working storage to hold a pointer:

77  WS-ACEE-ADDR-POINTER USAGE IS  POINTER.

Now, if we execute the following, we’ll have the address of the ACEE control block in that pointer:

EXEC CICS
ADDRESS ACEE  (WS-ACEE-ADDR-POINTER)
END-EXEC.

And then the following commands will make the RACF information addressable by our storage definitions:

SET ADDRESS OF ACEE TO WS-ACEE-ADDR-POINTER.
SET ADDRESS OF ACEE-USER-NAME TO ACEEUNAM-POINTER.

Now we have the user’s RACF id in ACEEUSRI, the user’s primary RACF group in ACEEGRPN, and the user’s name in ACEEUNAM. Very simple – just a matter of knowing how to address the information.

In a future post, we’ll continue this and see how we can obtain all of the RACF groups to which the user’s RACF id is connected.