如何将链接部分数据传递到 COBOL 中另一个程序的链接部分
Posted
技术标签:
【中文标题】如何将链接部分数据传递到 COBOL 中另一个程序的链接部分【英文标题】:How to pass linkage section data to another program's linkage section in COBOL 【发布时间】:2016-08-15 13:47:54 【问题描述】:我正在开发一个 Wrapper/Bridge COBOL 程序,该程序处理程序调用并执行诸如日志记录、安全检查等横切操作。 主要动机是检查消费者程序的安全访问权限是否有权调用生产者程序。
设桥 COBOL 程序为 B1,生产者程序为 P1,消费者(客户端)为 C1。
当 C1 想呼叫 P1 时,它必须呼叫 B1。然后,B1 检查可访问性。如果 C1 有权访问,则 B1 使用 C1 的数据调用 P1。
C1 -> B1 -> P1
这里B1和P1的链接部分是一样的。程序正在使用 EXEC CICS LINK 相互调用。
COMMAREA,
COMMAREA1 (DataSet Name)
01 COMMAREA-STRUCT,
03 a-field
03 another-field
...
客户;
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
....
桥,
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
....
制作人;
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
...
当我在上面尝试时,我收到了 Bridge Program B1 的编译时警告; “引用了 COMMAREA-STRUCT 或其下属之一,但 COMMAREA-STRUCT 是一个没有可寻址性的 LINKAGE SECTION 项目。此引用在执行时不会成功解析。”
这是什么意思?我应该如何将 B1 的链接部分传递给 P1 的链接部分?
当我这样尝试时,我在运行时得到 EIBRESP:22 和 EIBRESP2:26(逗号长度错误)。
-- 编辑--
我想我应该提供更多细节;
主要动机; 实际上有两家公司,COM1 和 COM2 公司。 COM2 多年来一直是 COM1 的附属公司。 COM1 和 COM2 分别有 CICS1 和 CICS2。 COM2 客户端程序使用 COM1 生产者程序。 COM2 客户端从不直接调用 COM1 生产者。 COM2 客户端将数据放入 COMMAREA-STRUCT 并远程调用通用 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,应该检查可访问性(不知何故,我们应用了它),并且应该将来自客户端的所有数据不加任何修改地传递给 GCP。
当前日志记录操作没有任何优先级。我们稍后会关注部分公司。
因此,我非常感谢您的专家 cmets。
*我们不能使用 CALL,因为 B1 将在另一个 CICS 上并且无法访问 COM1 的 LOADLIB1,这就是为什么 B1 应该通过 EXEC CICS LINK 远程调用 GCP。
*不是通过commarea,而是通过频道对我来说听起来不错。我们将对此进行讨论。
*顺便说一下,我会检查 LENGHT OF 上的全字半字冲突。你是对的。
*关于安全检查,我们将讨论“EXEC CICS QUERY SECURITY”。
*如上所述,我们不能修改字帖。只有我们能改变的是,
EXEC CICS LINK PROGRAM (GCP)
到
EXEC CICS LINK PROGRAM (B1)
通过查找和替换在客户端上。因为有成千上万的客户。我们不想改变字帖和触摸它们。
鉴于这些细节,我认为问题变得更容易理解了。
【问题讨论】:
因此,请查看编译中的输出列表。查看 PROCEDURE DIVISION 标题。看到使用?这就是为什么您的 01 没有像@cschneid 详细说明的那样具有可寻址性的原因。客户端程序如何“登录”,为什么不给你访问控制和日志记录? 日志记录和安全性可能很有趣。EXEC CICS QUERY SECURITY
对于安全性可能是可取的(请咨询您的安全人员)。记录 - 到哪里? VSAM? DB2?你在记录什么?
感谢您的专家 cmets。我已经编辑了包含问题详细信息和我的回复的问题。
【参考方案1】:
在通过EXEC CICS LINK
调用的CICS COBOL 程序中,链接部分必须包含名称为DFHCOMMAREA
的01 级结构。预编译器或 COBOL 编译器的 CICS 协处理器将为过程部门生成适当的USING
,因此程序对DFHCOMMAREA
结构具有寻址能力。
DFHCOMMAREA
将包含您在向目标程序LINK
时调用COMMAREA-STRUCT
的内容。
处理您发现自己的情况的一种方法是修改您的字帖以删除 01 级结构名称,并要求所有客户在 COPY
语句之前编写自己的 01 级结构名称。在桥接程序和生产者程序中,这个 01 级结构名称将是 DFHCOMMAREA
。
处理这种情况的另一种方法是避开LINK
,转而使用动态CALL
。您必须将DFHEIBLK
作为CALL
的第一个参数。
处理这种情况的另一种方法是为一个或多个 CICS 容器避免使用逗号。与传递 LINK
上的 commarea 不同,您将传递一个通道,该通道将挂有一个或多个容器,其中包含您希望传递的数据。
需要注意的是,您正在使用 LENGTH OF
特殊寄存器作为逗号长度。特殊寄存器是全字,但逗号长度参数是半字。我怀疑这会让你很伤心,除非 IBM 生成代码来拦截该特定习语并将特殊寄存器移动到临时半字(不太可能但可能)。
更新:
根据您的附加信息,很明显您的任务是为现有程序(GCP)编写“替代品”。
一种实用的方法可能是创建一个新的字帖,我们称之为 COMAREA2,它是 COMAREA1 的副本,但没有嵌入的 01 级别结构名称。将COPY COMAREA2
语句紧跟在B1 程序中的DFHCOMMAREA
01 结构名称之后。
这并不理想,因为某处的文档必须明确说明对 COMAREA1 字帖的更改必须反映在 COMAREA2 中。像这样的手动过程当然会引入错误的可能性,但它确实让您不必修改任何 C1 或 P1 程序。
如果它适合您,更优雅,可以尝试......
COPY COMAREA1 REPLACING == 01 COMMAREA-STRUCT== BY ==*01 COMMAREA-STRUCT==.
...在您的 B1 课程中。这将消除对上述建议的 COMAREA2 字帖的需要。如果可行,您只需将 COPY
语句放在 DFHCOMMAREA
01 结构级别名称之后。
【讨论】:
预处理器/协处理器将正确处理“长度”。此外,如果未指定 LENGTH,则默认长度为... COMMAREA 字段的长度。 LENGTH 中指定的项目不直接使用,而是适当地按摩到一个半字。 @BillWoodger 我对此有困难的回忆,这就是我提到它的原因。显然那是很久以前的事了,或者我的记忆确实很模糊。 当你使用一个数据项来包含长度时,你将它设为 COMP(或 COMP-4 或 BINARY)然后想知道为什么在设置它时它会被截断(它需要是 COMP-5),但问题在于设置字段,而不是传递它。以上是关于如何将链接部分数据传递到 COBOL 中另一个程序的链接部分的主要内容,如果未能解决你的问题,请参考以下文章
如何将地理位置 lat lng 从函数传递到 React 中另一个函数的“ll”属性?
如何从从 Assembly 返回到 COBOL 的指针中寻址数据缓冲区
将语料库中的名称部分匹配到 Pandas 数据框中另一列中的名称