如何将链接段数据传递给COBOL中的另一个程序的链接部分

Tun*_*ren 5 cobol mainframe cics

我正在开发一个处理程序调用的Wrapper/Bridge COBOL程序,并执行日志记录,安全检查等交叉操作.主要动机是检查消费者程序的安全访问权限是否有权调用生产者程序.

让桥COBOL程序为B1,生产者程序P1和消费者(客户)C1.

当C1想要拨打P1时,它必须拨打B1电话.然后,B1检查可访问性.如果C1有权访问,则B1用C1的数据调用P1.

C1 -> B1 -> P1 
Run Code Online (Sandbox Code Playgroud)

在这里,B1和P1的连接部分是相同的.程序正在使用EXEC CICS LINK相互调用.

COMMAREA,

COMMAREA1 (DataSet Name)

01 COMMAREA-STRUCT, 
   03 a-field
   03 another-field      
    ...
Run Code Online (Sandbox Code Playgroud)

客户端;

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
 ....
Run Code Online (Sandbox Code Playgroud)

大桥,

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
....
Run Code Online (Sandbox Code Playgroud)

制片人;

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 
...
Run Code Online (Sandbox Code Playgroud)

当我尝试上面的时候,我得到了Bridge Program B1的编译时警告; "引用了COMMAREA-STRUCT或其中一个下属,但是COMMAREA-STRUCT是一个没有可寻址性的LINKAGE SECTION项目.这个引用在执行时不会成功解决."

这是什么意思?我应该如何将B1的连接部分传递给P1的连接部分?

当我这样尝试时,我在运行时得到了EIBRESP:22和EIBRESP2:26(commarea长度错误).

- 编辑 -

我想我应该提供更多细节;

主要动机; 实际上有两家公司是COM1和COM2公司.COM2多年来一直是COM1的附属公司.COM1和COM2分别具有CICS1和CICS2.COM2客户端程序使用COM1生成器程序.COM2客户端从不直接调用COM1生成器.COM2客户端将数据放入COMMAREA-STRUCT并远程调用Generic Cobol程序(让它成为GCP).COMMAREA-STRUCT还有"生产者程序名称"字段,GCP确定要调用哪个程序.因此,GCP从COMMAREA-STRUCT导出数据并映射到生产者的字段.GCP通过寻址动态执行映射操作(对每个生产者都不是特殊的).生成器执行后,GCP获取结果并通过COMMAREA-STRUCT传递回客户端.该系统的设计与几年前类似.COM2有成千上万的客户端和COM1的数千个生产者.

在此输入图像描述

现在,COM2希望与COM1分开.因此COM1不希望再提供对所有COM1资源(生产者)的完全访问权限.因此,COM1希望在CICS1前放置一个新的cics,它将是一个只在本地运行B1 Bridge程序的处理程序CICS.这也涉及网络安全和公司政治决策.

在此输入图像描述 要在一段时间内将公司彼此分开,客户和生产者都不应受到影响.因此,问题应该在GCP-Bridge层解决.

这就是为什么,B1 Bridge应该像COM2客户端一样行事,应该检查可访问性(不知何故,我们应用它)并且应该将来自客户端的所有数据传递给GCP而不做任何修改.

当前日志记录操作没有任何优先级.我们在一段时间内专注于公司的一部分.

所以我非常感谢您的专家评论.

*我们不能使用CALL,因为B1将在另一个CICS上,并且无法访问COM1的LOADLIB1,这就是为什么B1应该由EXEC CICS LINK远程调用GCP.

*传递频道听起来不错,而不是传递commarea.我们将讨论它.

*顺便说一句,我将检查LENGHT OF上的全字半字冲突.你是对的.

*为了安全检查,我们将讨论"EXEC CICS QUERY SECURITY".

*如上所述,我们无法修改副本.只有我们可以改变的是,

 EXEC CICS LINK PROGRAM (GCP) 
Run Code Online (Sandbox Code Playgroud)

 EXEC CICS LINK PROGRAM (B1) 
Run Code Online (Sandbox Code Playgroud)

通过查找和替换客户端.因为有成千上万的客户.我们不想更改副本并触摸它们.

根据这些细节,我认为问题变得更容易理解.

csc*_*eid 8

在通过a调用的CICS COBOL程序中EXEC CICS LINK,链接部分必须包含具有名称的01级结构DFHCOMMAREA.预编译器或COBOL编译器的CICS协处理器将为USING程序部门生成适当的程序,以便程序具有对DFHCOMMAREA结构的可寻址性.

DFHCOMMAREA将包含COMMAREA-STRUCTLINK在目标程序中调用的内容.

处理您自己发现的情况的一种方法是修改您的副本以删除01级结构名称,并要求所有客户端在COPY语句之前编写自己的01级结构名称.在桥和生产者程序中,这个01级结构名称将是DFHCOMMAREA.

处理这种情况的另一种方法是避免LINK动态CALL.你必须包括DFHEIBLK作为的第一个参数CALL.

处理这种情况的另一种方法是避免使用commarea获取一个或多个CICS容器.LINK您可以通过一个通道而不是传递commarea ,通道将有一个或多个容器挂起,包含您希望传递的数据.

需要注意的是,您使用的是LENGTH OFcommarea长度的特殊寄存器.特殊寄存器是全字,但是commarea长度参数是半字.我怀疑这会让你感到悲伤,除非IBM生成代码来拦截那个特定的习惯用法并将特殊寄存器移到临时半字(不太可能但可能).

更新:

从您的附加信息中可以明显看出,您的任务是为现有程序(GCP)编写"替代品".

一种实用的方法可能是创建一个新的副本,我们称之为COMAREA2,它是COMAREA1的副本,但没有嵌入的01级结构名称.将COPY COMAREA2语句DFHCOMMAREA放在B1程序中的01结构名称后面.

这并不理想,因为某处的文档必须明确表示COMAREA1副本的更改必须反映在COMAREA2中.像这样的手动过程当然会引入错误的可能性,但它确实可以让你不得不修改任何C1或P1程序.

更优雅,只要它适合你,就会尝试......

COPY COMAREA1 REPLACING == 01 COMMAREA-STRUCT== BY ==*01 COMMAREA-STRUCT==.
Run Code Online (Sandbox Code Playgroud)

...在您的B1计划中.这将消除对上面提出的COMAREA2字帖的需求.如果这有效,您只需将COPY语句放在DFHCOMMAREA01结构级别名称之后.

  • 预处理器/协处理器将正确处理"长度".此外,如果未指定LENGTH,则默认长度为...仍然是COMMAREA字段的长度.LENGTH中指定的项目不是直接使用,而是适当地按摩到半个字. (2认同)