Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 486
Tunceren Avatar asked Aug 15 '16 13:08

Tunceren


People also ask

How do you pass data from one program to another in COBOL?

Call verb is used to transfer the control from one program to another program. The program that contains the CALL verb is the Calling Program and the program being called is known as the Called Program. Calling program execution will halt until the called program finishes the execution.

How do you code a linkage section in COBOL?

Code the same number of data-names in the identifier list of the called program as the number of arguments in the calling program. Synchronize by position, because the compiler passes the first argument from the calling program to the first identifier of the called program, and so on.

How many ways we can pass data to subprogram from subprogram in COBOL?

You can choose among three ways of passing data between programs: BY REFERENCE , BY CONTENT , or BY VALUE . The subprogram refers to and processes the data items in the storage of the calling program rather than working on a copy of the data.

How do you pass parm from JCL to proc?

PARM always pass the data from job step to current processing program by providing the data at the step where the program running. If JCL needs to pass more than one sub parameter, those should be separated by comma (,) which are enclosed in parentheses/quotes. PARM parameter can pass maximum 100 characters.


1 Answers

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.

like image 190
cschneid Avatar answered Nov 09 '22 20:11

cschneid