Top Banner
COBOL for the Web • Page 1.1 COBOL for the Web "Copyright © 2003 by Verizon Service Corp. All Rights Reserved." June 2003 This documentation contains material that is the proprietary property of and confidential to Verizon Service Corp. Disclosure outside Verizon is prohibited except by license agreement or other Published by... Verizon Service Corp. 12470 Telecom Drive, DC R2A Temple Terrace, Florida 33637 Phone: 813-978-5250 Intranet: http://tels.verizon.com
75
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: COBOLforWeb

COBOL for the Web • Page 1.1

COBOL for the Web"Copyright © 2003 by Verizon Service Corp.

All Rights Reserved."

June 2003

This documentation contains material that is the proprietary property of and confidential to Verizon Service Corp.

Disclosure outside Verizon is prohibited except by license agreement or other confidentiality agreement.

Published by...Verizon Service Corp.

12470 Telecom Drive, DC R2ATemple Terrace, Florida 33637

Phone: 813-978-5250Intranet: http://tels.verizon.com

Page 2: COBOLforWeb

Document Conventions

CHARACTERISTIC: MEANING/EXAMPLE:

Bold type New terminology used the first time.

Words/lines of code or instructor notes within code examples.

Characters or commands that the student types.

Navigation buttons, menus, textboxes, etc., that appear on screen.

Shortcut text for menu navigation:

Insert Picture From File type file name

Italics type Placeholder for variable information and names.

Book titles.

UPPERCASE Acronyms or uppercase-sensitive code.

Mono-space

(Letter Gothic font)

Example programs, program fragments and names of user-defined functions.

File and folder names.

Screen text.

<Enter>, <F6>, <Ctrl+D> Indicates the key(s) to press:

Key1 + Key2 …means press Key1 and Key2 simultaneously

Key1, Key2 …means press Key1, then Key2

COBOL for the Web • Page 1.2

Page 3: COBOLforWeb

COBOL FOR THE WEB TABLE OF CONTENTS

1.0 OVERVIEW........................................................................................................................................ 4

2.0 COMPILE CONSIDERATIONS..............................................................................................................5

3.0 I/O..................................................................................................................................................... 63.1 DISPLAY...................................................................................................................................................................63.2 ACCEPT....................................................................................................................................................................73.3 UNIX/POSIX Functions..............................................................................................................................................83.4 Processing Line Sequential (HFS) Files in COBOL..................................................................................................10

3.4.1 Control Characters.........................................................................................................................................113.4.2 Allocating Line Sequential Files in JCL...........................................................................................................123.4.3 COBOL Source for Processing HFS Files.........................................................................................................17

3.5 Dynamic File Allocation Using an Environment Variable.......................................................................................223.5.1 Dataset Allocation.........................................................................................................................................233.5.2 Line-sequential (HFS) File Allocation.............................................................................................................26

4.0 CALLING REXX................................................................................................................................ 284.1 Getting the Address...............................................................................................................................................294.2 COBINPG................................................................................................................................................................304.3 Program COBWEB: COBOL as CGI Example...........................................................................................................32

5.0 NET.DATA COBOL FUNCTION BLOCK..............................................................................................395.1 The Function Block and Passing Parameters.........................................................................................................405.2 Net.Data Calling COBOL Example..........................................................................................................................42

COBOL for the Web • Page 1.3

Page 4: COBOLforWeb

1.0 Overview

Beginning with COBOL for OS/390, IBM has made several enhancements to COBOL to make it useful as a web (CGI) language:

Support for compiling, linking, and executing in the OS/390 UNIX System Services environment, with COBOL files able to reside in the HFS (hierarchical file system).

Toleration of fork(), exec(), and spawn(), and the ability to call UNIX/POSIX functions.

Enhanced input-output function, permitting dynamic file allocation by means of an environment variable named in SELECT . . . ASSIGN. When running under USS, ACCEPT can read from stdin and DISPLAY can write to stdout.

Support for line-sequential file organization for accessing HFS files that contain text data, with records delimited by the new-line character.

Beginning with DB2 UDB for OS/390 v. 7, Net.Data has been updated to allow the coding of a COBOL function block, meaning that a Net.Data macro can invoke a COBOL executable directly, including passing data back and forth.

This paper explains the basics of using COBOL as a web CGI program and the use of a COBOL function block in a Net.Data macro.

COBOL for the Web • Page 1.4

Page 5: COBOLforWeb

2.0 Compile Considerations

Compiling for invocation via Net.Data COBOL function block:

Compile normally into a loadlib.

Concatenate loadlib to web server’s STEPLIB DD.

Compiling for direct invocation by web server as a CGI:

Compile into HFS cgi-bin directory (or directory where executables are stored).

In both cases:

Use the RENT compile option.

If you are calling UNIX/POSIX functions (e.g. getenv()), compile with the NODYNAM and NOCMPR2 compiler options. If the name of the function being called is longer than eight characters and/or in mixed or lower case, use the PGMNAME(LONGMIXED) compiler option (not valid when compiling into a PDS).

COBOL for the Web • Page 1.5

Page 6: COBOLforWeb

3.0 I/O

3.1 DISPLAY

COBOL executed under USS (which includes as a CGI invoked by a web server) can write directly to stdout (i.e. the browser) using the DISPLAY command.

This is the default setting for DISPLAY under USS, the OUTDD() compile option is not needed to direct output to stdout.

This does NOT work for COBOL executables being run via Net.Data. (See section 5 for more information on running COBOL via Net.Data.)

002400 PROCEDURE DIVISION. 002410 *The next three lines write the HTTP response header and002415 *a line of HTML code out to the browser. 002420 *The X’15’ is the newline character, which signifies to002430 *the browser the end of the header and start of the data. 002500 DISPLAY 'HTTP/1.0 200 OK '. 002600 DISPLAY 'Content-Type: text/html' X'15'. 002700 DISPLAY '<H1 ALIGN=CENTER>Hello World</H1>'

COBOL for the Web • Page 1.6

Page 7: COBOLforWeb

3.2 ACCEPT

COBOL executed under USS (which includes as a CGI invoked by a web server) can read directly from stdin (i.e. the browser) using the ACCEPT command.

This is the default setting for ACCEPT under USS.

This does NOT work for COBOL executables being run via Net.Data. (See section 5 for more information on running COBOL via Net.Data.)

003600 *If this program was invoked with METHOD=POST, the data from003610 *the form is available from stdin. The next line retrieves003620 *that data into WS-DATA-STRING-D.003700 ACCEPT WS-DATA-STRING-D

COBOL for the Web • Page 1.7

Page 8: COBOLforWeb

3.3 UNIX/POSIX Functions

COBOL executed under USS (which includes as a CGI invoked by a web server) can call standard UNIX/POSIX functions.

Traditional MVS load modules can also call UNIX/POSIX functions – they're part of the Language Environment.

Because these are C functions, arguments must be passed BY VALUE.

Character strings must be passed as BY VALUE pointers to strings.

Compiler option NODYNAM must be used when compiling COBOL that calls UNIX/POSIX functions.

Compiler option PGMNAME(LONGMIXED) must be used if function name is longer than eight characters and/or in mixed or lower case.

COBOL for the Web • Page 1.8

Page 9: COBOLforWeb

3.3 UNIX/POSIX Functions (continued)

001000 77 WS-PTR POINTER. 001100 77 WS-ENV-PTR POINTER. 001200 77 REQUEST-METHOD PIC X(14) VALUE 'REQUEST_METHOD'. 001300 77 QUERY-STRING PIC X(12) VALUE 'QUERY_STRING'. 001800 01 WS-DATA-STRING. 001900 05 WS-DATA-STRING-L PIC S9(4) COMP. 002000 05 WS-DATA-STRING-D PIC X(5000). 002100 LINKAGE SECTION. 002200 77 METHOD-STRING PIC X(4). 002300 01 DATA-STRING PIC X(5000). 002400 PROCEDURE DIVISION. 002800 SET WS-PTR TO ADDRESS OF REQUEST-METHOD. 002810 *DETERMINE IF PROGRAM CALLED WITH REQUEST METHOD GET OR POST. 002900 CALL 'GETENV' USING BY VALUE WS-PTR RETURNING WS-ENV-PTR. 002910 *OBJECT OF SET MUST BE LINKAGE VARIABLE IF NOT A POINTER. 003000 SET ADDRESS OF METHOD-STRING TO WS-ENV-PTR. 003100 IF METHOD-STRING(1:3) = 'GET' THEN 003200 SET WS-PTR TO ADDRESS OF QUERY-STRING 003210 *GET DATA FROM ENVIRONMENTAL VARIABLE QUERY_STRING.003300 CALL 'GETENV' USING BY VALUE WS-PTR RETURNING WS-ENV-PTR003400 SET ADDRESS OF DATA-STRING TO WS-ENV-PTR

COBOL for the Web • Page 1.9

Page 10: COBOLforWeb

003500 MOVE DATA-STRING TO WS-DATA-STRING-D 003600 ELSE 003700 ACCEPT WS-DATA-STRING-D 003800 END-IF.

COBOL for the Web • Page 1.10

Page 11: COBOLforWeb

3.4 Processing Line Sequential (HFS) Files in COBOL

Files maintained in the hierarchical file system (HFS).

Contain only printable characters and certain control characters as data.

Each record ends with an EBCDIC new-line character (X’15’) or return carriage (X’0D’), which is not included in the length of the record.

Because these are sequential files, records are placed one after another according to entry order.

COBOL for the Web • Page 1.11

Page 12: COBOLforWeb

3.4.1 Control Characters

The control characters shown below are the only characters other than printable characters that line-sequential files can contain.

HEX VALUE CONTROL CHARACTER

X’05’ Horizontal Tab

X’0B’ Vertical Tab

X’0C’ Form Feed

X’0D’ Carriage Return

X’0E’ DBCS Shift-out

X’0F’ DBCS shift-in

X’15’ New-line

X’16’ Backspace

X’2F’ Alarm

COBOL for the Web • Page 1.12

Page 13: COBOLforWeb

3.4.2 Allocating Line Sequential Files in JCL

The DD statement specifies PATH=’absolute-path-name’ with optional parameters of PATHOPTS, PATHMODE, and PATHDISP.

//MASTERFL DD PATH='/VZ/ttgttrg.trgfweb1.r00v00l0/docs/class/data', // PATHDISP=(KEEP,KEEP), // PATHOPTS=(ORDONLY,OCREAT), // PATHMODE=(SIRWXU,SIRGRP,SIXGRP,SIROTH,SIXOTH)

Note: Because an HFS is specific to the machine on which it exists (not shared DASD), a JES statement is needed to ensure that the job runs on the correct machine.

/*JOBPARM SYSAFF=(system name) such as C7 or TS73.

COBOL for the Web • Page 1.13

Page 14: COBOLforWeb

3.4.2 Allocating Line Sequential Files in JCL (continued)

PATH identifies a file in an HFS:

Can contain symbolic parameters.

Is case sensitive.

Do not code on the following DD statements:

o JOBCAT and JOBLIBo STEPCAT and STEPLIBo SYSABENDo SYSMDUMP or SYSUDUMP

PATHDISP specifies the disposition of an HFS file.

Job step ends normally (first positional parameter).

Job step ends abnormally (second positional parameter).

Values are:

o KEEP

o DELETE

KEEP is the default for first positin. Second position defaults to value of first position.

COBOL for the Web • Page 1.14

Page 15: COBOLforWeb

3.4.2 Allocating Line Sequential Files in JCL (continued)

PATHOPTS specifies the access and status for the HFS file.

You can specify up to 7 options in any order separated by commas, but code only one access option.

Access options:

ORDONLY

Opens the file for reading

OWRONLY

Opens the file for writing

ORDWR Opens the file for reading and writing

Status options:

OAPPEND

Appends data to the end of the file

OCREAT If the file does not exist, creates it (directories will NOT be created); if the file exists, uses it (if OEXCL is not also specified)

OEXCL If the file does not exist, creates it; if the file already exists, abends; OEXCL is ignored if OCREAT is not also specified

OTRUN Specifies that the system is to truncate the file length to zero if the file exists, the file is a

COBOL for the Web • Page 1.15

Page 16: COBOLforWeb

C regular file, and the file successfully opened with ORDWR or OWRONLY

There are other values that are beyond the scope of this discussion.

COBOL for the Web • Page 1.16

Page 17: COBOLforWeb

3.4.2 Allocating Line Sequential Files in JCL (continued)

PATHMODE specifies the file access attributes (permissions) when creating a new file.

Values:

COBOL for the Web • Page 1.17

Page 18: COBOLforWeb

3.4.2 Allocating Line Sequential Files in JCL (continued)

14 options in any order separated by commas can be specified.

If PATHMODE is omitted when creating a file, permissions are set to 000.

PATHMODE is ignored if the file already exists.

COBOL for the Web • Page 1.18

SIRUSR Owner level read

SIWUSR Owner level write

SIXUSR Owner level search a directory or execute a file

SIRWXU Owner level read/write/search a directory or read/write/execute a file

SIRGRP Group level read

SIWGRP Group level write

SIXGRP Group level search a directory or execute a file

SIRWXG Group level read/write/search a directory or read/write/execute a file

SIROTH Other level read

SIWOTH Other level write

SIXOTH Other level search a directory or execute a file

SIRWXO Other level read/write/search a directory or read/write/execute a file

Page 19: COBOLforWeb

3.4.3 COBOL Source for Processing HFS Files

To define a line-sequential file in a COBOL program, use the FILE-CONTROL in the ENVIRONMENT DIVISION as follows:

FILE-CONTROL. SELECT MASTER-FILE ASSIGN MASTERFL ORGANIZATION IS LINE SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS M-STATUS. SELECT REPORT-FILE ASSIGN REPORTFL ORGANIZATION IS LINE SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS M-STATUS.

The ACCESS phrase and the FILE STATUS phrase are optional.

The ASSIGN assignment-name clause must not include an organization field (S- or AS-) before the external name.

There are no changes to the corresponding FD statements.

COBOL for the Web • Page 1.19

Page 20: COBOLforWeb

3.4.3 COBOL Source for Processing HFS Files (continued)

OPEN statement:

A line-sequential file can be opened as INPUT, OUTPUT, or EXTEND.

A line-sequential file cannot be opened as I-O.

EXTEND permits opening the file for output operations. The EXTEND is allowed for sequential file access only if the new data is written in ascending sequence.

OPEN INPUT MASTER-FILE OUTPUT REPORT-FILE1 EXTEND REPORT-FILE2

COBOL for the Web • Page 1.20

Page 21: COBOLforWeb

3.4.3 COBOL Source for Processing HFS Files (continued)

READ statement:

Characters in the file record are read one at a time into the record area until one of the following occurs:

o A record delimiter (EBCDIC new-line character) is encountered.

The delimiter is discarded.

Any remaining spaces in the record area are padded with blanks.

The next READ statement reads from the first character of the next record.

o The record area is filled.

COBOL for the Web • Page 1.21

Page 22: COBOLforWeb

3.4.3 COBOL Source for Processing HFS Files (continued)

WRITE statement:

To add records to a line-sequential file, open the file as EXTEND. Records will be added immediately after the last record in the file.

The new-line character is added to end of each output record after removing any trailing blanks.

Records written to line-sequential files must contain only USAGE DISPLAY and DISPLAY-1 items. External decimal data items must be unsigned or declared with the SEPARATE CHARACTER phrase, if signed.

CLOSE statement:

Disconnects your program from a line-sequential file. To ensure that the file cannot be opened again while the program is running, code CLOSE WITH LOCK clause.

CLOSE MASTER-FILE REPORT-FILE WITH LOCK.

COBOL for the Web • Page 1.22

Page 23: COBOLforWeb

3.4.3 COBOL Source for Processing HFS Files (continued)

Coding Not Supported for Line Sequential Files

APPLY WRITE ONLY clauseCODE-SET clauseDATA RECORDS clauseLABEL RECORDS clauseLINAGE clauseOPEN I-O optionPADDING CHARACTER clauseRECORD CONTAINS 0 clauseRECORD CONTAINS X TO Y CHARACTERS clauseRECORD DELIMITER clauseRECORDING MODE clauseRERUN clauseRESERVE clauseREVERSED phrase of OPEN statementREWRITE statementVALUE OF clause of file description entryWRITE…AFTER ADVANCINGWRITE…AT END-OF-PAGEWRITE…BEFORE ADVANCING

COBOL for the Web • Page 1.23

Page 24: COBOLforWeb

3.5 Dynamic File Allocation Using an Environment Variable

Sequential datasets and line-sequential (HFS) files can be dynamically allocated in COBOL source code by using the putenv() function to establish an environment variable that identifies a physical dataset or file.

DD statement in execution JCL is not needed.

Environment variable name is the DD name used in the SELECT… ASSIGN TO statement.

Open, read or write, and close just like a dataset or file allocated in JCL.

File Status 98 results from:

Not a valid PATH or DSN option.

Dynamic allocation fails.

File Status 35 results from:

System cannot find the environment variable.

The COBOL run time de-allocates all dynamic allocations at run unit termination.

If there is both a JCL DD allocation and a dynamic allocation for the same DD name, the JCL allocation will take precedence.

COBOL for the Web • Page 1.24

Page 25: COBOLforWeb

3.5.1 Dataset Allocation

For a sequential dataset, the environment variable must contain:

Dataset name fully qualified.

Options following DSN – any order and separated by a comma or by one or more blanks.

Coded in WORKING STORAGE.

Cannot use a temporary dataset starting with &&.

COBOL for the Web • Page 1.25

Page 26: COBOLforWeb

3.5.1 Dataset Allocation (continued)

Syntax for dataset allocation parameters: DSN (data set name)

(member-name) NEW TRACKS

OLD CYL

SHR

MOD

SPACE(nnn,mmm) VOL(volumn-serial) UNIT(type)

KEEP STORCLASS(storage-class) MGMTCLAS(management-class) DATACLAS(data-class)

DELETE

CATALOG

UNCATALOG

COBOL for the Web • Page 1.26

Page 27: COBOLforWeb

3.5.1 Dataset Allocation (continued)

000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. 'DYNAMALL'. 000300 ENVIRONMENT DIVISION. 000400 CONFIGURATION SECTION. 000500 SOURCE-COMPUTER. IBM-370. 000600 OBJECT-COMPUTER. IBM-370. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 SELECT FILE-IN ASSIGN TO INFILE. 001000 DATA DIVISION. 001100 FILE SECTION. 001200 FD FILE-IN 001300 RECORD CONTAINS 80 CHARACTERS. 001400 01 RECORD-IN PIC X(80). 001500 WORKING-STORAGE SECTION. 001600 77 WS-PTR POINTER. 001700 77 INPUT-FILE PIC X(48) VALUE 001800 'INFILE=DSN(TTGTTRG.TRGF0000.WEBS390.MESSAGE) SHR'. 001900 PROCEDURE DIVISION. 002000 SET WS-PTR TO ADDRESS OF INPUT-FILE. 002100 CALL 'PUTENV' USING BY VALUE WS-PTR. 002200 OPEN INPUT FILE-IN. 002300 READ FILE-IN.

COBOL for the Web • Page 1.27

Page 28: COBOLforWeb

002400 DISPLAY RECORD-IN. 002500 CLOSE FILE-IN. 002600 GOBACK.

COBOL for the Web • Page 1.28

Page 29: COBOLforWeb

3.5.2 Line-sequential (HFS) File Allocation

For a line-sequential file, the environment variable must contain:

File name fully qualified.

No other options.

Coded in WORKING STORAGE.

COBOL for the Web • Page 1.29

Page 30: COBOLforWeb

3.5.2 Line-sequential (HFS) File Allocation (continued)

000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. 'DYNAMALH'. 000300 ENVIRONMENT DIVISION. 000400 CONFIGURATION SECTION. 000500 SOURCE-COMPUTER. IBM-370. 000600 OBJECT-COMPUTER. IBM-370. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 SELECT FILE-IN ASSIGN TO INFILE 001000 ORGANIZATION IS LINE SEQUENTIAL. 001100 DATA DIVISION. 001200 FILE SECTION. 001300 FD FILE-IN 001400 RECORD CONTAINS 80 CHARACTERS. 001500 01 RECORD-IN PIC X(80). 001600 WORKING-STORAGE SECTION. 001700 77 WS-PTR POINTER. 001800 77 INPUT-FILE PIC X(58) VALUE 001900 'INFILE=PATH(/VZ/ttgttrg.trgfweb1.r00v00l0/text/cgimsg.txt)'.002000 PROCEDURE DIVISION. 002100 SET WS-PTR TO ADDRESS OF INPUT-FILE.002200 CALL 'PUTENV' USING BY VALUE WS-PTR.002300 OPEN INPUT FILE-IN. 002400 READ FILE-IN. 002500 DISPLAY RECORD-IN. 002600 CLOSE FILE-IN.

COBOL for the Web • Page 1.30

Page 31: COBOLforWeb

002700 GOBACK.

COBOL for the Web • Page 1.31

Page 32: COBOLforWeb

4.0 Calling REXX

COBOL isn't the greatest when it comes to string manipulation.

Drawback for web work, since data from the browser is URL-encoded

name=Bill+Smith&birthdate=01%2f30%2f1962

and must be de-encoded to

name=Bill Smith birthdate=01/30/1962

The TeLS training department has a REXX that does the de-encoding and returns a string

name="Bill Smith";birthdate="01/30/1962"

It would be useful for a COBOL program to be able to call the REXX and pass the URL-encoded string, and receive the de-encoded string back. The COBOL could UNSTRING the data returned by the REXX into working storage variables fairly easily.

Unfortunately, the ways COBOL and REXX pass data are somewhat different, especially when it comes to REXX passing information back to the calling COBOL program.

Basically, the REXX can't just hand something back; it has to put the data directly into the working storage location, meaning it has to know the address in memory of the working storage variable.

That address has to be given to REXX in numeric form (cannot just pass a pointer).

COBOL for the Web • Page 1.32

Page 33: COBOLforWeb

4.1 Getting the Address

In COBOL you can create a pointer variable and set it to the address of a variable in working storage.

But passing a pointer to a REXX won't work.

A pointer cannot be moved into a PIC 9 field.

To get around this, call program ADDROF

Can be found in TTGTTRG.SORCELIB.COBWEB on the C7 machine in Tampa.

Pass it the name of the field in working storage for which you need the address, and a variable into which it will put that address.

ADDROF:

LINKAGE SECTION. 77 ITEM USAGE POINTER. 77 PTR USAGE POINTER. PROCEDURE DIVISION USING BY VALUE ITEM BY REFERENCE PTR. SET PTR TO ITEM. GOBACK.

While you cannot set a pointer to the address of a variable and then move that pointer to a PIC 9 field all in the same COBOL program, you CAN accomplish the same thing by calling ADDROF and let the LE handle the conversion between pointer and PIC 9.

COBOL for the Web • Page 1.33

Page 34: COBOLforWeb

4.2 COBINPG

COBINPG is a stripped down version of the CGIINPG REXX that you may have learned about in the class S/390 Web Hosting I.

Get a copy from TTGTTRG.EXEC.COBWEB.REXX on the C7 machine in Tampa.

It receives a URL-encoded string and returns a de-encoded version of the data.

When passing COBOL variables to a REXX, the COBOL variables must have a length component and a data component or the REXX will not read them correctly.

COBOL for the Web • Page 1.34

Page 35: COBOLforWeb

4.2 COBINPG (continued)

COBINPG main procedure:

/* receive decimal address into variable @p1 */ @p1 = arg(1); /* receive URL-encoded string into variable query_string */ query_string = arg(2); @p1 = @p1 + 0 /* by adding zero, REXX recognizes @p1 as numeric */ /* Initialize sets up the ASCII-code-to-EBCDIC-character conversion table */ call Initialize /* ProcessParms parses through query_string, making all of the appropriate substitutions, and populates a variable called parmsData with the data in a var1="value1";var2="value2"; format */ call ProcessParms /* get the length of parmsData, convert it from decimal to character, and force a size of two positions (with a leading 0 if needed) – this will populate the length component of the working storage variable */ parmsLength = d2c(length(parmsData),2); /* storage is an external subroutine that will go to the address in the first parameter and bring back the amount of data specified in the second parameter. If a third parameter is specified, it will put the data in the third parameter in the address of the first parameter. The first parameter must be in readable hex, hence the d2x function. */ call storage d2x(@p1),,parmsLength||parmsData; return

COBOL for the Web • Page 1.35

Page 36: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example

WORKING-STORAGE SECTION. 77 WS-BIN-PTR PIC S9(9) BINARY. 77 WS-PTR POINTER. 77 WS-ENV-PTR POINTER. 77 REQUEST-METHOD PIC X(14) VALUE 'REQUEST_METHOD'. 77 QUERY-STRING PIC X(12) VALUE 'QUERY_STRING'. 01 VAR-LEN PIC 9(4) BINARY. 01 WS-ADDRESS. 05 WS-ADDRESS-L PIC S9(4) COMP VALUE 9. 05 WS-ADDRESS-D PIC 9(09). 01 WS-DATA-STRING. 05 WS-DATA-STRING-L PIC S9(4) COMP. 05 WS-DATA-STRING-D PIC X(5000). LINKAGE SECTION. 77 METHOD-STRING PIC X(4). 01 DATA-STRING PIC X(5000). PROCEDURE DIVISION.* write out HTTP response header info DISPLAY 'HTTP/1.0 200 OK '. DISPLAY 'Content-Type: text/html' X'15'. * write out web page title DISPLAY '<H1 ALIGN=CENTER>Hello World</H1>' * determine the value of the environment variable request_method.

COBOL for the Web • Page 1.36

Page 37: COBOLforWeb

* this is needed so that you know whether to get URL-encoded info* from stdin or query_string environment variable. SET WS-PTR TO ADDRESS OF REQUEST-METHOD. CALL 'GETENV' USING BY VALUE WS-PTR RETURNING WS-ENV-PTR.

COBOL for the Web • Page 1.37

Page 38: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

SET ADDRESS OF METHOD-STRING TO WS-ENV-PTR. IF METHOD-STRING(1:3) = 'GET' THEN SET WS-PTR TO ADDRESS OF QUERY-STRING CALL 'GETENV' USING BY VALUE WS-PTR RETURNING WS-ENV-PTR SET ADDRESS OF DATA-STRING TO WS-ENV-PTR MOVE DATA-STRING TO WS-DATA-STRING-D ELSE ACCEPT WS-DATA-STRING-D END-IF. * URL-encoded data is now in ws-data-string-d. this bit of code * calculates its length and populates the length component of* of ws-data-string so that it can be passed to the COBINPG REXX. MOVE 0 TO WS-DATA-STRING-L INSPECT WS-DATA-STRING-D TALLYING WS-DATA-STRING-L FOR CHARACTERS BEFORE INITIAL X'00' * use ADDROF to get the address of ws-data-string. CALL 'ADDROF' USING WS-DATA-STRING, WS-BIN-PTR. * put ws-data-string's address in the data component of ws-address. MOVE WS-BIN-PTR TO WS-ADDRESS-D.* call COBINPG to read the URL-encoded string from ws-data-string, * do the appropriate substituting, and then return its output right* back into ws-data-string. CALL 'COBINPG' USING WS-ADDRESS, WS-DATA-STRING.

COBOL for the Web • Page 1.38

Page 39: COBOLforWeb

DISPLAY 'WS-DATA-STRING-D: ' WS-DATA-STRING-D(1:WS-DATA-STRING-L). GOBACK.

COBOL for the Web • Page 1.39

Page 40: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

COBWEB was compiled directly into the cgi-bin directory.

A web page was created with two forms on it.

The first form calls COBWEB with METHOD=GET.

The second form calls COBWEB with METHOD=POST.

The following screen prints show that COBWEB can handle being called with either method.

Once the data has been returned by COBINPG, you can use UNSTRING to pull it apart and populate appropriate variables in working storage.

Alternatively, you could change your copy of COBINPG to return individual values directly into individual working storage variables – pass it the URL-encoded string and as many addresses as there are variables in the string, the REXX can populate each address as it parses the URL-encoded string and does its conversions.

COBOL for the Web • Page 1.40

Page 41: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

COBOL for the Web • Page 1.41

Page 42: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

COBOL for the Web • Page 1.42

Page 43: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

COBOL for the Web • Page 1.43

Page 44: COBOLforWeb

4.3 Program COBWEB: COBOL as CGI Example (continued)

COBOL for the Web • Page 1.44

Page 45: COBOLforWeb

5.0 Net.Data COBOL Function Block

Include the following in your db2www.ini file:

ENVIRONMENT (DTW_COBOL) coboldll ( )

Net.Data strings together all arguments being passed to the COBOL program (separated by HEX low values) into a single parameter.

The default size of that parameter is 512 bytes.

To change the default size in the db2www.ini file, add:

DTW_COBOL_PARAMETER_BUFFER_SIZE number_of_bytes

The loadlib containing your COBOL executables must be concatenated to the STEPLIB DD of your web server started task.

COBOL for the Web • Page 1.45

Page 46: COBOLforWeb

5.1 The Function Block and Passing Parameters

Example:

%function (DTW_COBOL) callCOBOL (in fname, inout lname, out message) returns(newmsg) { %EXEC {COBND %} %}

Be sure to specify a status for the parameters:

in – the parameter receives a value from the corresponding parameter in the function call statement. The value will be passed to the COBOL program, but the parameter will NOT receive a value back from the COBOL program.

inout – the parameter receives a value from the corresponding parameter in the function call statement. The value will be passed to the COBOL program. The parameter will also receive a value back from the COBOL program, which is then copied into the corresponding parameter in the function call statement.

out – the parameter does not receive a value from the calling statement, nor does it pass data to the COBOL program. It receives a value from the COBOL program, which is then copied into the corresponding parameter in the function call statement.

The returns parameter receives a value from the COBOL program and returns it as the value of the function.

COBOL for the Web • Page 1.46

Page 47: COBOLforWeb

5.1 The Function Block and Passing Parameters

The %EXEC command inside the COBOL function block is where you specify the name of the COBOL load module.

Keep in mind that Net.Data will take all values being passed to the COBOL program and string them together (separated by a HEX low-value) into one parameter, and pass that one parameter to the COBOL program.

Net.Data then receives a single parameter back from the COBOL program and parses out the included values (again, delimited by HEX low-values) into the inout, out, and returns (if present) parameters coded on the function statement.

The single parameter passed between the Net.Data macro and the COBOL program is the only way for the COBOL program to communicate with the Net.Data macro; ACCEPT and DISPLAY will not receive or display data from stdin or stdout when the program is called from a Net.Data macro.

COBOL for the Web • Page 1.47

Page 48: COBOLforWeb

5.2 Net.Data Calling COBOL Example

Net.Data macro:

%define message = "COBOL not yet called." %function (DTW_COBOL) callCOBOL (in fname, inout lname, out message) returns(newmsg) { %EXEC {COBND %} %} %html (start) { <h1> <form method="post" action="report"> First name: <input type=text name=fname maxlength=24><br>Last name: <input type=text name=lname maxlength=24><br> <input type=submit value="Run that COBOL!"></form> </h1> %}

%html (report) { <h3>Values prior to call:<br> fname: $(fname)<br>

COBOL for the Web • Page 1.48

Page 49: COBOLforWeb

lname: $(lname)<br> message: $(message)<p> Federal law mandates that all introductory-level training must

COBOL for the Web • Page 1.49

Page 50: COBOLforWeb

5.2 Net.Data Calling COBOL Example (continued)

include the following: @callCOBOL(fname,lname,message) <p>Values after the call:<br> fname: $(fname)<br> lname: $(lname)<br> message: $(message)<p> %}

COBOL for the Web • Page 1.50

Page 51: COBOLforWeb

5.2 Net.Data Calling COBOL Example (continued)

COBOL source code:

000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. COBND. 000300 ENVIRONMENT DIVISION. 000400 CONFIGURATION SECTION. 000500 SOURCE-COMPUTER. IBM-370. 000600 OBJECT-COMPUTER. IBM-370. 000700 DATA DIVISION. 000800 WORKING-STORAGE SECTION. 000900 77 WS-FNAME PIC X(25). 001000 77 WS-LNAME PIC X(25). 001100 77 WS-MESSAGE PIC X(100). 001200 77 WS-NEWMSG PIC X(100). 001300 77 WS-DELIM PIC X(01) VALUE X'00'. 001400 LINKAGE SECTION. 001500 77 LS-ALL-VALUES PIC X(512). 001600 PROCEDURE DIVISION USING LS-ALL-VALUES. 001700 UNSTRING LS-ALL-VALUES DELIMITED BY X'00'001800 INTO WS-FNAME WS-LNAME. 001900 INITIALIZE LS-ALL-VALUES. 002000 MOVE Z'Smith' TO WS-LNAME. 002100 MOVE Z'The COBOL load module has executed!' TO WS-MESSAGE.002200 STRING WS-LNAME DELIMITED BY X'00'

COBOL for the Web • Page 1.51

Page 52: COBOLforWeb

002300 WS-DELIM DELIMITED BY SIZE 002400 WS-MESSAGE DELIMITED BY X'00'

COBOL for the Web • Page 1.52

Page 53: COBOLforWeb

5.2 Net.Data Calling COBOL Example (continued)

002500 WS-DELIM DELIMITED BY SIZE 002600 'Hello World (Especially for ' DELIMITED BY SIZE 002700 WS-FNAME DELIMITED BY ' ' 002800 '!)' DELIMITED BY SIZE 002900 WS-DELIM DELIMITED BY SIZE 003000 INTO LS-ALL-VALUES. 003100 GOBACK.

COBOL for the Web • Page 1.53

Page 54: COBOLforWeb

5.2 Net.Data Calling COBOL Example (continued)

COBOL for the Web • Page 1.54

Page 55: COBOLforWeb

5.2 Net.Data Calling COBOL Example (continued)

COBOL for the Web • Page 1.55