How to pass linkage section data to another program's linkage section in COBOL
Asked Answered
R

1

7

I'm working on a Wrapper/Bridge COBOL program that handles program calls and performs cross-cutting operations like logging,security-check etc. Main motivation is checking the security access for consumer program whether it has access to call the producer program or not.

Let the bridge COBOL program be B1 and the producer program P1 and the consumer(client) C1.

When C1 wants to call P1, it have to make a call to B1. Then, B1 checks the accessibility. If C1 has access, then B1 calls P1 with C1's data.

C1 -> B1 -> P1 

In here the linkage section of B1 and P1 are the same. Programs are using EXEC CICS LINK to call each other.

The COMMAREA,

COMMAREA1 (DataSet Name)

01 COMMAREA-STRUCT, 
   03 a-field
   03 another-field      
    ...

The client;

IDENTIFICATION DIVISION.
PROGRAM-ID.  Client.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION

 /* fill CommareaStruct with some values. */
 ....
 /* call B1 Bridge */ 
   EXEC CICS LINK PROGRAM  (B1Bridge)      NOHANDLE
     COMMAREA (COMMAREA-STRUCT) 
     LENGTH (LENGTH OF COMMAREA-STRUCT) 
    END-EXEC
 ....

The Bridge,

IDENTIFICATION DIVISION.
PROGRAM-ID.  B1Bridge.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION
 ...
 /* access control */
 /* logging */
 ...
 /* pass data to P1*/
    EXEC CICS LINK PROGRAM  (P1)      NOHANDLE
       COMMAREA (COMMAREA-STRUCT) 
       LENGTH (LENGTH OF COMMAREA-STRUCT) 
     END-EXEC
....

The producer ;

IDENTIFICATION DIVISION.
PROGRAM-ID.  P1
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
COPY COMMAREA1
PROCEDURE DIVISION
....

*doing some business with data in COMMAREA1 
...

When I try above, I got a compile-time warning for Bridge Program B1 ; "COMMAREA-STRUCT or one of its subordinates was referenced, but COMMAREA-STRUCT was a LINKAGE SECTION item that did not have addressability. This reference will not be resolved succcessfully at execution."

What does it mean? How should I pass B1's linkage section to P1's linkage section?

When I try like this, I got EIBRESP:22 and EIBRESP2: 26 (commarea length error) at runtime.

-- Edit --

I think I should give more details;

Main motivation; Actually there are two companies that company COM1 and COM2. COM2 was an affiliate of COM1 for several years. COM1 and COM2 have CICS1 and CICS2 respectively. And COM2 client programs uses COM1 producer programs. COM2 clients never call the COM1 producers directly. COM2 clients put the data into COMMAREA-STRUCT and call a Generic Cobol Program (let it be GCP) remotely. COMMAREA-STRUCT has also "the producer program name" field that GCP figures out which program is wanted to be called. So, GCP exports the data from COMMAREA-STRUCT and maps to the fields of producer. GCP performs the mapping operations dynamically with addressing(not special for each producer). After the producer performs, GCP takes the result and passes back to the client via COMMAREA-STRUCT. The system was designed like that several years ago. There are thousands of clients of COM2 and thousands of producers of COM1.

enter image description here

Now, COM2 wants to apart from COM1. So COM1 don't want to give full access to all COM1 resources(producers) any more. Thus, COM1 wants to put a new cics in front of the CICS1 which will be a handler CICS that runs only B1 Bridge program locally. This also about network security and company-political decisions.

enter image description here To seperate the companies from each other in a little while, neither the clients nor the producers should be affected. So, problem should be solved in GCP-Bridge layer.

That's why, B1 Bridge should behave like GCP to the COM2 Clients, should check the accessibility(somehow, we applied it) and should pass all the data that coming from the clients to the GCP without any modification.

Currenty the logging operation does not have any priority. We focus on part the companies in a little while.

So I'm very appreciated for your expert comments.

*We can't use CALL because B1 will be on another CICS and can not access the LOADLIB1 of COM1 thats why B1 should call GCP remotly by EXEC CICS LINK.

*Instead of passing commarea, passing the channel sounds good to me. We will discuss on it.

*By the way, i will check fullword-halfword conflict on LENGHT OF. You are right.

*For the security check, we will discuss on "EXEC CICS QUERY SECURITY".

*As mentioned above, we can not modify copy-books. Only we can change is,

 EXEC CICS LINK PROGRAM (GCP) 

to

 EXEC CICS LINK PROGRAM (B1) 

on the clients by find&replace. Because there are thousands of clients. We don't want to change copy-book and touch them.

In lights of these details, I think the problem becomes more understandable.

Rambort answered 15/8, 2016 at 13:47 Comment(3)
So, look at your output listing from the compile. Look at the PROCEDURE DIVISION header. See the USING? That is why your 01 has not got addressability as @cschneid has detailed. How does the client program "log on", and why doesn't that give you the access control and logging?Elsworth
Logging and security can be interesting. EXEC CICS QUERY SECURITY may be advisable for security (check with your security folks). Logging - to where? VSAM? DB2? What are you logging?Paulinepauling
Thanks for your expert comments. I've edited the question that consist of details of the problem and my replies.Rambort
P
10

In a CICS COBOL program invoked via an EXEC CICS LINK, the Linkage Section must contain an 01 level structure with the name DFHCOMMAREA. The precompiler or the COBOL compiler's CICS coprocessor will generate the appropriate USING for the Procedure Division so the program has addressability to the DFHCOMMAREA structure.

DFHCOMMAREA will contain the contents of what you are calling COMMAREA-STRUCT when you LINK to the target program.

One way to deal with the situation in which you find yourself is to modify your copybook to remove the 01 level structure name and require all clients to code their own 01 level structure name just prior to the COPY statement. In the bridge and producer programs this 01 level structure name would be DFHCOMMAREA.

Another way to deal with this situation is to eschew LINK in favor of a dynamic CALL. You would have to include DFHEIBLK as the first parameter of the CALL.

Yet another way to deal with this situation is to eschew commarea for one or more CICS containers. Instead of passing the commarea on the LINK you would pass a channel, the channel would have one or more containers hanging off of it, containing the data you wish to pass.

Something to beware of, you are using the LENGTH OF special register for your commarea length. The special register is a fullword, but the commarea length parameter is a halfword. I suspect that will cause you grief, unless IBM generates code to intercept that particular idiom and move the special register to a temporary halfword (unlikely but possible).

Update:

From your additional information it is apparent your task is to write a "drop-in replacement" for an existing program (the GCP).

A pragmatic approach might be to create a new copybook, let's call it COMAREA2, which is a copy of COMAREA1 but without the embedded 01 level structure name. Place the COPY COMAREA2 statement immediately after the DFHCOMMAREA 01 structure name in the B1 program.

This isn't ideal, as documentation somewhere must make it plain that changes to the COMAREA1 copybook must be reflected in COMAREA2. A manual process like this of course introduces the possibility of error, but it does nicely get you around having to modify any of the C1 or P1 programs.

More elegant, provided it works for you, would be to try...

COPY COMAREA1 REPLACING == 01 COMMAREA-STRUCT== BY ==*01 COMMAREA-STRUCT==.

...in your B1 program. This would remove the need for the COMAREA2 copybook proposed above. Provided this works, you would simply place the COPY statement after the DFHCOMMAREA 01 structure level name.

Paulinepauling answered 15/8, 2016 at 14:57 Comment(3)
The pre-/co-processor will deal with the "length" correctly. Also, if LENGTH is not specified, the default length is... the length of the COMMAREA field anyway. The item specified in LENGTH is not used directly, but is appropriately massaged to a half-word.Elsworth
@BillWoodger I have a dim recollection of having difficulty with this, that's why I mentioned it. Apparently that was either a long time ago or my recollection is dim indeed.Paulinepauling
There's the issue of when you use a data item to contain the length, you make it COMP (or COMP-4 or BINARY) and then wonder why it got truncated when setting it (it would need to be COMP-5) but the issue is with setting the field, not with it getting passed on.Elsworth

© 2022 - 2024 — McMap. All rights reserved.