Skip to content

COUSR01C

Source: cbl/COUSR01C.cbl

Type: CICS transaction program

Purpose

COUSR01C is a CICS transaction (CU01) that implements the "Add User" screen for the CardDemo application's user administration function. It lets an administrator enter a new user's first name, last name, user ID, password, and user type, then adds that user as a record in the USRSEC security file. It provides field-level validation and on-screen feedback (success, duplicate ID, or write failure) before returning control to the calling program or the sign-on screen.

How it works

Processing is driven by MAIN-PARA, which behaves differently depending on how the transaction was invoked:

  • First entry (EIBCALEN = 0): no commarea was passed in, so the program sets the return target to COSGN00C and performs RETURN-TO-PREV-SCREEN to XCTL back out immediately (this looks like a safety/entry guard rather than a normal path).

  • Subsequent entry with commarea: the incoming commarea is copied into CARDDEMO-COMMAREA.

  • If this is the first real display of the screen (NOT CDEMO-PGM-REENTER), the program initializes the output map, sets the cursor to the first-name field, and calls SEND-USRADD-SCREEN to paint the blank Add-User screen.

  • On re-entry (user pressed a key), it calls RECEIVE-USRADD-SCREEN to read the entered data, then branches on EIBAID: ENTER → PROCESS-ENTER-KEY (validate and add the user). PF3 → sets return target to COADM01C and performs RETURN-TO-PREV-SCREEN (back to the admin menu). PF4 → CLEAR-CURRENT-SCREEN (blanks all input fields and redisplays). Any other key → flags an error, resets cursor, shows "invalid key" message, and redisplays via SEND-USRADD-SCREEN.

At the end of every path, MAIN-PARA issues EXEC CICS RETURN with TRANSID(WS-TRANID) and the commarea, keeping the transaction conversational (pseudo-conversational CICS pattern).

PROCESS-ENTER-KEY validates each input field in order — First Name, Last Name, User ID, Password, User Type — and stops at the first blank field found, setting an error flag, positioning the cursor there, and redisplaying the screen with a message. If all required fields are populated, it moves the input values into the SEC-USER-DATA record (SEC-USR-ID, SEC-USR-FNAME, SEC-USR-LNAME, SEC-USR-PWD, SEC-USR-TYPE) and performs WRITE-USER-SEC-FILE.

WRITE-USER-SEC-FILE issues a CICS WRITE to the USRSEC file keyed on SEC-USR-ID, then evaluates the response code: - NORMAL → clears the fields, sets a green success message ("User has been added..."), and redisplays. - DUPKEY/DUPREC → sets an error flag and message "User ID already exist...", repositions cursor to User ID field, and redisplays (user not added). - Any other response → generic "Unable to Add User..." error, cursor reset to First Name, redisplays.

SEND-USRADD-SCREEN always calls POPULATE-HEADER-INFO first (to refresh title, transaction/program name, current date/time in the map header) before sending the BMS map COUSR1A (mapset COUSR01) with the current message text.

CLEAR-CURRENT-SCREEN and INITIALIZE-ALL-FIELDS blank the input fields and message, then redisplay the screen — used for the PF4 "clear" action and also reused internally after a successful add.

Inputs & outputs

No SQL tables are used (parser confirms sql_tables: []) — persistence is entirely through the CICS USRSEC file, not DB2.

Things to know

  • No file-not-found/system-error handling beyond a generic message: WRITE-USER-SEC-FILE's WHEN OTHER branch catches every non-NORMAL, non-duplicate response with a single "Unable to Add User..." message; the actual RESP/REAS codes are only available via a commented-out DISPLAY statement, so diagnosing real failures (e.g., file not open, storage full) requires uncommenting debug code or adding logging.

  • Entry guard oddity: when EIBCALEN = 0, the program immediately routes back to COSGN00C rather than initializing a fresh Add-User screen. This means COUSR01C expects to always be invoked with a populated commarea (e.g., via XCTL from a menu); direct/transaction-only invocation effectively bounces the user to sign-on.

  • Password stored in plain text: SEC-USR-PWD is moved directly from the input field with no masking, hashing, or encryption logic visible in this program.

  • No format/content validation beyond "not empty": fields like USERIDI, PASSWDI, and USRTYPEI are only checked for spaces/low-values — there's no length, character-set, or valid-user-type validation (e.g., no check that user type is a recognized code) before the write.

  • Hard-coded literals: transaction ID 'CU01', program name 'COUSR01C', file name 'USRSEC ', and fallback return program 'COSGN00C' / admin menu 'COADM01C' are all hard-coded in working storage/logic rather than configurable.

  • Duplicate detection relies on file-level key collision: DUPKEY/DUPREC responses from the WRITE are the only mechanism preventing duplicate user IDs — there is no explicit read-before-write existence check in this program.

  • Cursor/error-flag pattern: error handling sets WS-ERR-FLG and moves -1 to the relevant field's length attribute to reposition the BMS cursor, a common CICS/BMS convention but easy to miss if unfamiliar with COBOL/CICS map field naming (xxxxL, xxxxI, xxxxO suffixes for length, input, output).

  • Pseudo-conversational design: because every path ends in EXEC CICS RETURN with a TRANSID, this program relies on CICS pseudo-conversational processing and the CDEMO-PGM-REENTER flag in the commarea to distinguish first display from user response — this is standard CICS practice but a common source of confusion for non-mainframe developers expecting a single continuously-running process.

CICS commands

RETURN, SEND, RECEIVE, WRITE

Copybooks

COCOM01Y, COTTL01Y, COUSR01, CSDAT01Y, CSMSG01Y, CSUSR01Y, DFHAID, DFHBMSCA

Unresolved conditions

Numeric comparisons with no matching 88-level condition-name anywhere in this program or the copybooks it COPYs — no meaning found in the source export, not guessed.

Field Value Line
EIBCALEN 0 78

Paragraph flow

flowchart TD
    MAIN_PARA["MAIN-PARA"]
    PROCESS_ENTER_KEY["PROCESS-ENTER-KEY"]
    RETURN_TO_PREV_SCREEN["RETURN-TO-PREV-SCREEN"]
    SEND_USRADD_SCREEN["SEND-USRADD-SCREEN"]
    RECEIVE_USRADD_SCREEN["RECEIVE-USRADD-SCREEN"]
    POPULATE_HEADER_INFO["POPULATE-HEADER-INFO"]
    WRITE_USER_SEC_FILE["WRITE-USER-SEC-FILE"]
    CLEAR_CURRENT_SCREEN["CLEAR-CURRENT-SCREEN"]
    INITIALIZE_ALL_FIELDS["INITIALIZE-ALL-FIELDS"]
    CLEAR_CURRENT_SCREEN --> INITIALIZE_ALL_FIELDS
    CLEAR_CURRENT_SCREEN --> SEND_USRADD_SCREEN
    MAIN_PARA --> CLEAR_CURRENT_SCREEN
    MAIN_PARA --> PROCESS_ENTER_KEY
    MAIN_PARA --> RECEIVE_USRADD_SCREEN
    MAIN_PARA --> RETURN_TO_PREV_SCREEN
    MAIN_PARA --> SEND_USRADD_SCREEN
    PROCESS_ENTER_KEY --> SEND_USRADD_SCREEN
    PROCESS_ENTER_KEY --> WRITE_USER_SEC_FILE
    SEND_USRADD_SCREEN --> POPULATE_HEADER_INFO
    WRITE_USER_SEC_FILE --> INITIALIZE_ALL_FIELDS
    WRITE_USER_SEC_FILE --> SEND_USRADD_SCREEN

Paragraphs

Paragraph Line Performs
MAIN-PARA 71 RETURN-TO-PREV-SCREEN, SEND-USRADD-SCREEN, RECEIVE-USRADD-SCREEN, PROCESS-ENTER-KEY, RETURN-TO-PREV-SCREEN, CLEAR-CURRENT-SCREEN
PROCESS-ENTER-KEY 115 SEND-USRADD-SCREEN, SEND-USRADD-SCREEN, SEND-USRADD-SCREEN, SEND-USRADD-SCREEN, SEND-USRADD-SCREEN, WRITE-USER-SEC-FILE
RETURN-TO-PREV-SCREEN 165
SEND-USRADD-SCREEN 184 POPULATE-HEADER-INFO
RECEIVE-USRADD-SCREEN 201
POPULATE-HEADER-INFO 214
WRITE-USER-SEC-FILE 238 INITIALIZE-ALL-FIELDS, SEND-USRADD-SCREEN, SEND-USRADD-SCREEN, SEND-USRADD-SCREEN
CLEAR-CURRENT-SCREEN 279 INITIALIZE-ALL-FIELDS, SEND-USRADD-SCREEN
INITIALIZE-ALL-FIELDS 287