C H A P T E R  11

Customizing Your Application Environment

Sun MTP supplies customizing tools, also called source files, that you can use to integrate third-party products and user-written routines. After you perform the customizing tasks, you need to rebuild the system executables. This chapter includes the following topics:

Sun MTP provides support for many third party products. The versions supported for each product depend on their availability and qualification. Qualification does not imply validation of all features of all products, nor does it guarantee performance characteristics. You must test and verify the features of your application with the appropriate version of the third party products. Before installing any version of third party products, contact your Sun Microsystems representative for qualification information.


Customization Tools

The following customization tools are located in the $UNIKIX/src directory:

When customizing your application environment, be aware of the following:


RDBMS User Exit Routines

The primary purpose of the RDBMS user exit routines is to provide implicit database commit and rollback capabilities for use with RDBMS software. These routines are located in the source file $UNIKIX/src/trans/kxusrexit.c. The following table describes the routines.

TABLE 11-1 RDBMS User Exits

User Exit Routine

Description

Transaction/Batch Server initialization

Performs a connect or login to the RDBMS software. This is useful when the RDBMS software requires an explicit connect or login operation. A single login is required for each database used by the application within each batch and transaction server.

Transaction/Batch Server termination

Disconnects or logs off from the RDBMS software. Under certain conditions, such as a transaction server failure, this exit cannot be invoked. In these situations, the RDBMS server software detects that the client process has terminated, cleans up the appropriate connections, and then performs an implicit rollback of work that was in progress at the time of the abnormal termination.

Transaction initialization

Executes logic prior to the execution of the transaction.

Transaction termination

Executes logic after transaction termination.

Database commitment

Executes an implicit commitment for each RDBMS that was used by the application. This makes it possible to maintain the database integrity of each RDBMS without coding explicit COMMIT statements within the application. Database commit processing for VSAM files is embedded within the Sun MTP executive and, therefore, does not require the execution of code within this user exit.

This user exit is invoked whenever a user SYNCPOINT verb or a database commit at transaction termination is executed.

Database rollback

Executes an implicit database rollback for each RDBMS that the application has used.

This user exit is invoked whenever a user SYNCPOINT ROLLBACK or database rollback at abnormal transaction termination is executed.


The kxusrexit.c module is considered the driver of the Sun MTP user exit mechanism. The entry points defined in this module are called directly from the executive at certain predetermined points. It is then the responsibility of kxusrexit.c to call the modules that are required by the application. Samples of the modules are in the $UNIKIX/src/rdbms directory.

Function Calls

You must process the modules using the appropriate RDBMS preprocessor before compilation, regardless of the programming language you use. This section describes the function calls that you can use in application programs to obtain information from Sun MTP for further logical checking.

kxsysinfo

Returns the following values from the SIT:

COBOL program example

CALL 'kxsysinfo'  USING  KIX-SYS-INFO.

Call this function from the Transaction/Batch Server Initialization or Termination user exits; for example, to connect to the database based on the retrieved information.

You can use the unique number returned for each Transaction/Batch Server to identify the socket or connect string for the database.

COBOL program for Sybase example:

call 'kxsysinfo' USING KIX-SYS-INFO.
MOVE KIX-SIT-SRV-NAME TO SERVER-NAME.
MOVE KIX-SIT-USR-NAME TO USERID.
MOVE KIX-SIT-USR-PASS TO USERPASS.
MOVE KIX-TRANIDX      TO CONNECT-NAME.
EXEC SQL  CONNECT :USERID IDENTIFIED BY:USERPASS
	AT :CONNECT-NAME
	USING :SERVER-NAME
END-EXEC.

In a COBOL program for Oracle that uses SQL*NET, you can use the number to identify a unique socket number for the connection.

kxtctinfo

Returns the following information:

COBOL program example:

CALL 'kxtctinfo'  USING  KIX-TCT-INFO.

Call this function from the Transaction Initialization or Termination user exits. It is used to implement database specific security. An example of this is illustrated in commented code for each RDBMS in Source Example - kxusrexit.c.

Refer to the Sun Mainframe Transaction Processing Software Developer's Guide for information about implementing security for an RDBMS.

kxsetmsg

Sets the user-specified message on the user terminal.

COBOL program example:

MOVE  'User not authorized to execute SQL
	programs' TO  KIX-MSG-STR.
CALL 'kxsetmsg' USING KIX-MSG-INFO.

Alternatively, the user can place a user-defined error message number in the KIX-MSGNO field of the KIX-MSG-INFO block, then invoke the message facility:

CALL 'kxsetmsg' USING KIX-MSG-INFO.

kxttyinfo

Returns the following information:

COBOL program example:

CALL 'kxttyinfo'  USING  KIX-TTY-INFO.

Call this function from the Transaction Initialization or Termination user exits.



Note - Before using the values returned by a call to this function, examine the device name to make sure it represents a valid device, such as /dev/pty/ttyu2.



The COBOL copybook $UNIKIX/src/rdbms/KXINFO.CPY, illustrated in the following example, has all the variables returned for each of the functions with their attributes.

CODE EXAMPLE 11-1 KXINFO.CPY Copybook (1 of 2)

*  User exit table contains TCT information, which users can  *
*  use in the COBOL program                                   *
*                                                             *
*  User code should call the 'kxtctinfo' during start         *
*  transaction user exit get the latest KIX-TCT-INFO record   *
*  updated.                                                   *
*                                                             *
*  example:-  call "kxtctinfo" using KIX-TCT-INFO             *
***************************************************************
 
 
 01  KIX-TCT-INFO.
     05  KIX-USRNAM                 PIC X(8).
     05  KIX-OPSEC                  PIC X(8).
     05  KIX-OPCLS                  PIC X(3).
     05  KIX-TRMID                  PIC X(4).
     05  KIX-LUNAME                 PIC X(8).
     05  KIX-OPID                   PIC X(3).
     05  KIX-TRANCD                 PIC X(4).
****************************************************************
*  User exit contains system application id from SIT table     *
*  which user can use in the cobol program.                    *
*                                                              *
*  User code should call the 'kxsysinfo' during allocate       *
*  transaction user exit gets the KIX-SYS-INFO record updated. *
*                                                              *
*  example:-  call "kxsysinfo" using KIX-SYS-INFO              *
****************************************************************
 
 
01  KIX-SYS-INFO.
     05  KIX-SITNAME                PIC X(8).
     05  KIX-SIT-SRV-NAME           PIC X(8).
     05  KIX-SIT-DB-NAME            PIC X(8).
     05  KIX-SIT-USR-NAME           PIC X(8).
     05  KIX-SIT-USR-PASS           PIC X(8).
     05  KIX-TRANIDX                PIC X(3).
*****************************************************************
*  User exit sets the user message and displays it on the terminal*
*                                                                 *
*  User code should call the 'kxsetmsg' any time in the program   *
*  to put the message in the queue. The message is printed once.  *
*  The next message is received on the buffer.                    *
*                                                                 *
*  example:-  call "kxsetmsg" using KIX-MSG-INFO                  *
*****************************************************************
 01  KIX-MSG-INFO.
     05  KIX-MSGNO                 PIC 9(4) VALUE 1098.
     05  KIX-MSG-ROUTINE           PIC X(20).
     05  KIX-MSG-STR               PIC X(60).
*****************************************************************
*  User exit sets the UNIX tty information for the terminal     *
*                                                               *
*  User code should call the 'kxttyinfo' any time in the program*
*  to get the UNIX tty information.                             *
*                                                               *
*  example:-  call "kxttyinfo" using KIX-TTY-INFO               *
*****************************************************************
 
  
01  KIX-TTY-INFO.
     05  KIX-TTY-PID                 PIC 9(6).
     05  KIX-TTY-NAME                PIC X(20).
     05  KIX-TTY-TERMENV             PIC X(14).
 

The C header file $UNIKIX/src/rdbms/kxinfo.h, illustrated in the following example, has all the variables returned for each of the functions with their attributes.

CODE EXAMPLE 11-2 kxinfo.h C Header File

/* Structure for passing parameter information from tct table */
 
struct lextpar {
	char    cur_usrnam [8];
	char    cur_opsec  [8];
	char    cur_opcls  [3];
	char    cur_trmid  [4];
	char    cur_luname [8];
	char    cur_opid   [3];
	char    cur_trancd [4];
	} lextpar;
 
struct lsyspar {
	char    cur_sysname [8];
	/* Case 2240 */
	/* Added entries for RDBMS related variables */
	char    cur_svrname [8];
	char    cur_dbname  [8];
	char    cur_usrname [8];
	char    cur_usrpass [8];
	char    cur_tranidx [3];
	} lsyspar;
 
struct lmsgstr {
	char    cur_errno [4];
	char    cur_func  [20];
	char    cur_msg   [60];
	} lmsgstr;
 
struct lttystr {
	char    cur_termpid [6];
	char    cur_ttyname [20];
	char    cur_termenv [14];
 

Source Example - kxusrexit.c

The kxusrexit.c example is included to illustrate the structure and purpose of the module.

The developer can implement conditional code, such as checking for the return codes and taking the necessary actions. In the source example, the driver program, which calls the specific user exits, checks for the return code and sets its return code as one of the following:

Return Code

Label

Execution Statement

0

KXSUCCESS

Continue execution

1

KXFAILURE

Terminate transaction

-1

KXABORT

Terminate Transaction Server


The execution statement is the action taken by the Transaction and Batch Servers when the return code is passed to it. A KXABORT occurs when the source module program fails to allocate (connect or use) a database. A KXFAILURE occurs when the database fails to execute the BEGIN TRANSACTION function; this is a transaction failure.

Optionally, the developer can check for the severity of the error in the RDBMS user module or in kxusrexit.c, then decide to abort or terminate the transaction. In kxusrexit.c, there are conditional codes for each RDBMS.

In the makefile, the RDBMSFLAG variable is set to the required database, which directs the compiler to include the specific code. If you are including more than one RDBMS, the RDBMSFLAG variable can contain one or more values.

The kxusrexit.c program also includes the following lines, which you can use to enable trace messages for every transaction:

/**************************************************************/
/* To enable TRACEMSG after every transaction                 */
/* uncomment the following code                               */
/**************************************************************/
/* #define TRACEMSG 1                                         */

The trace message returns the status for every successful transaction at all stages (begin, end, commit, or rollback).

The code in the following subsections is surrounded by a conditional statement for the RDBMS. The primary purpose of these functions is to call the RDBMS functions, which should be located in a separate module.



Note - You must not change any part of the kxusrexit.c code, except for the code documented in the following subsections.



kxusrexit.c - Oracle RDBMS Functions

The functions KXORALGN, KXORALGF, KXORABTRN, KXORAETRN, KXORASAVE, and KXORAUNDO are defined in the KXORACLE.pco program, located in the $UNIKIX/src/rdbms directory.

Oracle code is included by setting the RDBMSFLAG in the makefile to -DORACLE.

CODE EXAMPLE 11-3 Oracle User Exit (1 of 2)
/*****************************************************************/
/* The following code is specific to the support of ORACLE       */
/* databases. The routines called by the functions below can be  */
/* found in the KXORACLE.pco source file which is located in the */
/* $UNIKIX/src directory.                                        */
/*	 
/******************************************************************/
#ifdef ORACLE
/******************************************************************/
/*     ORACLE          allocate/open function                     */
/******************************************************************/
static int oracle_allocate() {
	dbms_rcode =KXORALGN();
	return(dbms_rcode);
}
/******************************************************************/
/*     ORACLE          deallocate/close function                  */
/******************************************************************/
static int oracle_deallocate() {
	dbms_rcode =KXORALGF();
	return(dbms_rcode);
}
/******************************************************************/
/*     ORACLE          start_txn function                         */
/******************************************************************/
static int oracle_start_txn() {	 
	dbms_rcode =KXORABTRN();
	return(dbms_rcode);
}
/******************************************************************/
/*     ORACLE          end of txn function                        */
/******************************************************************/
static int oracle_end_txn() {
	dbms_rcode =KXORAETRN();
	return(dbms_rcode);
}
/******************************************************************/
/*     ORACLE          commit function                            */
/******************************************************************/
static int oracle_commit() {
	dbms_rcode =KXORASAVE();
	return(dbms_rcode);
}
/******************************************************************/
/*     ORACLE          rollback function                          */
/******************************************************************/
static int oracle_rollback() {
	dbms_rcode =
	KXORAUNDO();
	return(dbms_rcode);
}
#endif           /* End ORACLE code */

kxusrexit.c - DB2 RDBMS Functions

DB2 database code is included by setting the RDBMSFLAG in the makefile to
-DDBTWO.

CODE EXAMPLE 11-4 DB2 User Exit (1 of 2)
/******************************************************************/
/* The following code is specific to the support of db2 databases.*/
/* The routines called by the functions below can be found in     */
/* the KXDB2.cbl source file, located in the $UNIKIX/src          */
/* directory.                                                     */
/******************************************************************/
#ifdef DBTWO
/******************************************************************/
/*     DB2        allocate/open function                          */
/******************************************************************/
static int dbtwo_allocate() {
      strcpy(CurFunc,"dbtwo_allocate\n");  /*  Do not change */
      dbms_rcode = KXDB2LGN();
      return(dbms_rcode);
}
/******************************************************************/
/*     DB2         deallocate/close function                      */
/******************************************************************/
static int dbtwo_deallocate() {
      strcpy(CurFunc,"dbtwo_deallocate\n");  /*  Do not change */
      dbms_rcode = KXDB2LGF();
      return(dbms_rcode);
}
/******************************************************************/
/*     DB2         start_txn function                             */
/******************************************************************/
static int dbtwo_start_txn() {
      strcpy(CurFunc,"dbtwo_start_txn\n");  /*  Do not change */
      dbms_rcode = KXDB2BTRN();
      return(dbms_rcode);
}
/******************************************************************/
/*     DB2         end of txn function                            */
/******************************************************************/
static int dbtwo_end_txn() {
      strcpy(CurFunc,"dbtwo_end_txn\n");  /*  Do not change */
      dbms_rcode = KXDB2ETRN();
      return(dbms_rcode);
}
/******************************************************************/
/*     DB2         commit function                                */
/******************************************************************/
static int dbtwo_commit() {
      strcpy(CurFunc,"dbtwo_commit\n");  /*  Do not change */
      dbms_rcode = KXDB2SAVE();
      return(dbms_rcode);
}
/******************************************************************/
/*     DB2         rollback function                              */
/******************************************************************/
static int dbtwo_rollback() {
      strcpy(CurFunc,"dbtwo_rollback\n");  /*  Do not change */
      dbms_rcode = KXDB2UNDO();
      return(dbms_rcode);
}
#endif           /* End db2  code */

kxusrexit.c - Sybase RDBMS Functions

The Sybase user exit functions KXSYBLGN, KXSYBLGF, KXSYBBTRN, KXSYBETRN, KXSYBSAVE, and KXSYBUNDO are defined in the KXSYBASE.cop program, located in the $UNIKIX/src/rdbms directory.

Sybase database code is included by setting the RDBMSFLAG in the makefile to
-DSYBASE.

See also CODE EXAMPLE 11-6, which describes the use of the
-DSYBASE10 flag.

CODE EXAMPLE 11-5 Sybase User Exit (1 of 2)
/******************************************************************/
/*                                                                */
/*The following code is specific to the support of SYBASE databases.*/
/*The routines called by the functions below can be found in the   */
/*KXSYBASE.cop source file which is located in the $UNIKIX/src     */
/*directory.                                                        */
/*                                                                  */
/******************************************************************/
#ifdef SYBASE
/******************************************************************/
/*     SYBASE          allocate/open function                     */
/******************************************************************/
static int sybase_allocate() {
		 dbms_rcode =KXSYBLGN();
		 return(dbms_rcode);
}
/******************************************************************/
/*     SYBASE          deallocate/close function                  */
/******************************************************************/
static int sybase_deallocate() {
		 dbms_rcode =KXSYBLGF();
		 return(dbms_rcode);
}
/******************************************************************/
/*     SYBASE          start_txn function                         */
/******************************************************************/
static int sybase_start_txn() {
		 dbms_rcode =KXSYBBTRN();
		 return(dbms_rcode);
}
/******************************************************************/
/*     SYBASE          end of txn function                        */
/******************************************************************/
static int sybase_end_txn() {
		 dbms_rcode =KXSYBETRN();
		 return(dbms_rcode);
}
/******************************************************************/
/*     SYBASE          commit function                            */
/******************************************************************/
static int sybase_commit() {
		 dbms_rcode =KXSYBSAVE();
		 return(dbms_rcode);
}
/******************************************************************/
/*     SYBASE          rollback function                          */
/******************************************************************/
static int sybase_rollback() {
		 dbms_rcode =KXSYBUNDO();
		 return(dbms_rcode);
}

Sybase System 10 and Later

Unlike Oracle, Sybase has additional code to include all the Sybase ESQL/COBOL functions within the executable. This code is specific to the release of Sybase 4.9.x and the ESQL/COBOL compiler.

The following code is surrounded by conditional definition for Sybase system 10, which is not included if the -DSYBASE10 value is set in the RDBMSFLAG of the makefile.

CODE EXAMPLE 11-6 User Exit for Sybase System 10 and Later (1 of 3)
#ifndef SYBASE10
/**************************************************************/
/* Do not remove the following function definition; it is     */
/* required to satisfy SYBASE object syntax                   */
/**************************************************************/
void sybase_null_func()
{
int void_number;
void_number = sql_put_tds_vsn();
void_number = sqlchkxact();
void_number = sqlallrel();
void_number = sqlbadassert();
void_number = sqlbind();
void_number = sqlca();         /* Comment this function in 4.9.2 */
void_number = sqlcancel();
void_number = sqlchkfetch();
void_number = sqlcobvalchk();
void_number = sqlconvert ();
void_number = sqlcstring ();
void_number = sqlcurcloseconn ();
void_number = sqlcurfind ();
void_number = sqlcurisopenconn ();
void_number = sqlcurset ();
void_number = sqldispnum ();
void_number = sqldynexec ();
void_number = sqldyngetexpct ();
void_number = sqlerror ();
void_number = sqlexecarg ();
void_number = sqlexecdo ();
void_number = sqlexecinit ();
void_number = sqlfetchfree ();
void_number = sqlfetchsuspend ();
void_number = sqlfindconn ();
void_number = sqlflogin ();
void_number = sqlgetcmd ();
void_number = sqlgetdbtype ();
void_number = sqlgetexpct ();
void_number = sqlgetfetch ();
void_number = sqlgetfetchqual ();
void_number = sqlgetstype ();
void_number = sqlgetsvargs ();
void_number = sqlimmexec ();
void_number = sqlinitca ();
void_number = sqllinkv ();
void_number = sqllogin ();
void_number = sqlmakcur ();
void_number = sqlmem ();
void_number = sqlmkcmd ();
void_number = sqlnewconn ();
void_number = sqlnext1 ();
void_number = sqlnextr ();
void_number = sqlnprocrow ();
void_number = sqlnullstr ();
void_number = sqloproc ();
void_number = sqlpproc ();
void_number = sqlrelease ();
void_number = sqlrproc ();
void_number = sqlrterr ();
void_number = sqlrtlibstr ();
void_number = sqlrtlibvsn ();
void_number = sqlsetbadassert ();
void_number = sqlsetcmd ();
void_number = sqlsetcurbind ();
void_number = sqlseterr ();
void_number = sqlstproc ();
void_number = sqlulinkv ();
void_number = sqluxact ();
void_number = sqlwarn ();
void_number = sqlwarning ();
void_number = sqlxact ();
void_number = sqlxactcmd ();
void_number = sqlxactuse ();
void_number = sqlxcmd ();
}

These dummy function definitions are used to satisfy undefined conditions. Use the ones that are appropriate to the release of Sybase you are using.

int sql_put_tds_vsn()
{
        return -1;
}
 
int sqlchkxact()
{
        return -1;
}
 
#endif           /* End SYBASE10 Check */
#endif           /* End SYBASE code */
 

User Module Source Examples

The following RDBMS user source modules are located in the $UNIKIX/src/rdbms directory.

TABLE 11-2 RDBMS User Modules

RDBMS

COBOL

C

PL/I

Oracle

KXORACLE.pco

kxoracle.pc

KXORAPLI.ppl

DB2

KXDB27.sqb

kxdb2.sqc

-

Sybase

KXSYBASE.cop

kxsybase.cp

-


You can change the source module to meet your site requirements. The following table maps the RDBMS functions to the user exit functions defined in TABLE 11-1.

TABLE 11-3 Mapping RDBMS Functions to User Exit Functions

User Exit Function

Oracle

DB2

Sybase

Process initialization

KXORALGN

KXDB2LGN

KXSYBLGN

Process termination

KXORALGF

KXDB2LGF

KXSYBLGF

Transaction initialization

KXORABTRN

KXDB2BTRN

KXSYBBTRAN

Transaction termination

KXORAETRN

KXDB2ETRN

KXSYBETRN

Database commit

KXORASAVE

KXDB2SAVE

KXSYBSAVE

Database rollback

KXORAUNDO

KXDB2UNDO

KXSYBUNDO


The source examples illustrate the use of the callable functions that are described earlier in the chapter.



caution icon

Caution - The use of the kxsysinfo, kxtctinfo, kxsetmsg, and kxttyinfo functions is limited to the context of the user exit function as shown. If you use these functions outside of this context, unpredictable results might occur.

Use care when modifying these statements because the source modules use RDBMS-specific API and language statements.



After making the necessary changes, you must execute the kixinstall utility to generate the object binary. kixinstall will process the source module through the RDBMS pre-compiler and language compiler and generate the object binary.


Customizing the Conversion Tables

The kixmakecnv utility creates a conversion table file. The conversion table file, $UNIKIX/lib/cnvtbl, contains conversion tables for lowercase-to-uppercase translation, ASCII-to-EBCDIC translation, and EBCDIC-to-ASCII translation. The file provided contains U.S. English translation tables. This file is loaded by each region process that performs conversions.

The following procedure describes how to modify the conversion table file to support languages other than U.S. English.


procedure icon  To Modify the Conversion Table File

1. Change to the $UNIKIX/src/convert directory.

2. Use an editor to modify the conversion tables contained in the source file kxcnvtbl.c.

The ASCII-EBCDIC and EBCDIC-ASCII tables must be reversible so that can 3270 data streams can be correctly interpreted or created. This means that any character translated from ASCII to EBCDIC, then from EBCDIC to ASCII, must result in the original character.

3. Save the file.

4. Compile and link a new version of kixmakecnv:

$ cd $UNIKIX/src/convert
$ cc -o kixmakecnv kixmakecnv.c kxcnvtbl.c

5. Create a new $UNIKIX/lib/cnvtbl file containing the conversion tables specified in kxcnvtbl.c:

$ kixmakecnv


Customizing the Sockets User Exit

The sockets user exit kxusrexit_in_socket, located in the $UNIKIX/src/socket/kxsktxit.c file, provides a flexible way to support different message formats that can flow into a region. The sockets user exit is called when a socket request is made. The exit reads the initial socket data and returns the details of the message to the transaction processor.

You can customize this user exit to perform the following functions:

The kxusrexit_in_socket() user exit must provide the following output parameters:

Transaction Id

Upon return from the function, this 4-character field must contain a transaction identifier that is defined in the PCT. Required.

Data Buffer

Upon return from the function, points to the data that is passed to the application program in the socket record's CLIENT-IN-DATA field. If no data is passed, this field is NULL.

Data Length

Upon return from the function, contains the number of bytes placed in the data buffer. The transaction processor extracts these bytes from the data buffer, NULL pads to the next word boundary, if required, and then places the data in the COMMAREA that is supplied to the application program. The maximum data length is 32,732 bytes; the default length is 35.

If no data is to be passed, this field should be zero (0).

Start Type

Upon return from the function, this field is either KC, TD or IC.

KC: Immediately schedules the transaction. This is the default.

TD: Transient data. The socket record is written to a queue whose name matches the Transaction Id output parameter. Define this queue as an Intrapartition queue; it can have a trigger transaction of the same name as the queue and a trigger level of 1.

IC: Interval control. The transaction specified in the Transaction ID output parameter is scheduled to start at a time determined by the Interval parameter.

Interval

Upon return from the function, this field should contain a time value in the format HHMMSS. This value specifies the time that must elapse before the transaction specified in the Transaction ID output parameter is started. This is field is required only if the Start Type is IC. The default value is "000000".


The following example shows a representative sample of the code in the kxuserexit_in_socket() user exit.

CODE EXAMPLE 11-7 Socket User Exit
/* Since the default initial socket message has no way of telling
the receiver how much data is being sent (i.e. there is no leading
length indicator in the data nor is there any trailing pattern to
look for), we attempt to receive all the data in one go. If the
length of data being received can be determined, 'recv' should be
coded to be in a loop till all data is received or an error
condition occurs.
*/
length_received = recv (psocket_fd, read_buffer,
                                    sizeof(read_buffer), 0);
if (length_received < 0)
	{
	kxerror1(E_2327,E_PRINT+E_PRINTF, "unikixtrans", errno);
	return(-1);
	}
if (length_received == 0) /*possibly, the client has gone away or*/
	{                              /*closed the connection*/
	return(-2);
	}
first_comma = memchr (read_buffer, ',', length_received);
if (first_comma == 0)	     /*only transid specified */
	{len_transid = length_received;
	}
else
	{len_transid = first_comma - read_buffer;
	}
/* Validate transid */
if ((len_transid > LEN_TRANID) || (len_transid == 0))
	{
	kxerror (E_2328,E_PRINT+E_PRINTF, "unikixtran");
	return(-1);
	}
memcpy (ptransid, read_buffer, len_transid);

Refer to the Sun Mainframe Transaction Processing Software Developer's Guide for more information about socket support.


Customizing the SSL User Exit

The SSL client certificate verification user exit resides in the shared library $UNIKIX/lib/libkxsslxit.so. This user exit allows you to write code that accepts or rejects a client certificate based, for example, on your own certificate revocation check.

The source code for the user exit and a makefile to build the shared library are located in the $UNIKIX/src/socket directory. The source file is kxsslxit.c and the makefile is makefile.xit. You can modify the source file to customize the user exit for your environment and use the makefile to build a new shared library.

The function in the shared library that performs the client certificate verification is Exit_VerifyCertificate(). During the SSL handshake, unikixssl calls this function passing in a pointer (CERTCertificate *cert) to the client certificate. The function returns SECSuccess if the client certificate is accepted, or SECFailure if the client certificate is rejected.


procedure icon  To Customize the SSL User Exit

1. Back up the existing $UNIKIX/lib/libkxsslxit.so shared library; for example:

$ mv $UNIKIX/lib/libkxsslxit.so $UNIKIX/lib/libkxsslxit.so.bak

2. Change directory to the location of the SSL user exit source file:

$ cd $UNIKIX/src/socket

3. Open the source file kxsslxit.c and make your changes to the Exit_VerifyCertificate() function.

4. Save the file.

5. Build the shared library:

$ make -f makefile.xit

This creates libkxsslxit.so in the $UNIKIX/src/socket directory.

6. Copy the new shared library to the $UNIKIX/lib directory:

$ cp libkxsslxit.so $UNIKIX/lib

7. You can perform a check to determine where unikixssl is finding the shared library.

$ cd $UNIKIX/bin
$ ldd unikixssl

The output shows the list of shared libraries unikixssl uses and their locations. Make sure that libkxsslxit.so is listed in $UNIKIX/lib.


Customizing the ISC User Exits

This section describes the following routines:

Translation Routine for Transaction Routing

During transaction routing, Sun MTP allows the translation of characters in the USERAREA, COMMAREA or the terminal input/output area (TIOA) to the desired code set. The translation routine, by default, assumes display data in the USERAREA and COMMAREA. For any transaction code, the routine converts both areas from ASCII to EBCDIC on transmission and from EBCDIC to ASCII on receipt. The translation table is the same translation table used by the 3270 datastream. The translation tables are located at asc2ebcd and ebcd2asc within the $UNIKIX/src/convert/kxcnvtbl.c source file.

The kxusrxlt.c conversion routine is passed arguments that identify the following:

If there is non-display data in either the COMMAREA or USERAREA, the user can modify the user translation routine to handle the non-display data. For example, the user might want to copy the binary data fields as is rather than convert them.


procedure icon  To Copy the Binary Fields

1. Change to the $UNIKIX/src/convert directory.

2. Make a backup copy of the user conversion module, $UNIKIX/src/convert/kxusrxlt.c.

3. Open the original module in an editor.

4. The default conversion is from EBCDIC to ASCII. If there is no need for conversion, use the memcpy routines that are commented out in kxusrxlt.c.

5. If binary fields are embedded in the data that needs conversion, access the Data Conversion Templates (CVT) screen from the Table Manager - Extended Tables menu to define the area as a record.

6. Call the kxcvt routine in kxusrxlt.c with the resource name you defined in the CVT.

7. Save the updated contents of $UNIKIX/src/convert/kxusrxlt.c back to disk.

8. Type the following commands to compile the updated module and rebuild all executables that are dependent on it:

$ cd $UNIKIX/src
$ make unikixtran

The kxusrxlt.c user exit has sample translation code for a specific transaction (the code is disabled by a condition in an if statement).

Translation Routine for Other ISC Types

As records are passed between a Sun MTP region and a remote system, the region uses the CVT to convert any data passed between the two systems from ASCII to EBCDIC on transmission, and from EBCDIC to ASCII on receipt. The CVT defines the structure of a particular record, allowing Sun MTP routines to correctly convert only the fields in the record that need conversion. For complex record structures, it might be necessary to use the CVT user exit. The kxcvtxlt.c user exit has sample translation code for a specific transaction (the code is disabled by a condition in an if statement).

A sample CVT user exit that you can modify to work with specific records is located in $UNIKIX/src/convert/kxcvtxlt.c. The exit is called by coding a template entry in the CVT with a type from 50 to 80.

The exit is passed arguments that identify the following:


procedure icon  To Modify the User Exit

1. Change to the $UNIKIX/src/convert directory.

2. Make a backup copy of the user exit $UNIKIX/src/convert/kxcvtxlt.c.

3. Open the original module in an editor.

4. Change the exit so that it correctly converts the particular record.

5. Save the updated contents of $UNIKIX/src/convert/kxcvtxlt.c back to disk.

6. Issue these commands to compile the updated module and rebuild all executables that are dependent upon it:

$ cd $UNIKIX/src
$ make unikixtran

Terminal Not Found Exit

In Sun MTP and CICS, you can use a START command or Transient Data Automatic Transaction Initiation (TDATI) to start a transaction on a specified terminal. If the terminal does not exist, the START command fails with a TERMIDERR, and the TDATI queues the request until the terminal logs on.

Transaction routed terminals might not exist on Sun MTP when the START request is issued. Rather than reject the request, an exit is provided to inform Sun MTP of the region on which the terminal resides. The START request is passed to the remote system, which either executes it immediately (if the terminal is available) or queues it.

This exit uses the DefaultTOR field in the SIT. The sample exit checks the DefaultTOR field and ships the request to that system if it is set. If it is not set, the request either fails with a TERMIDERR error or is queued.

The sample Terminal Not Found exit is located in $UNIKIX/src/terminal/kxtnfxit.c. The exit is passed arguments that identify the following:

Using the passed arguments, store either the sysid or the netname of the system to which to ship the request in a return field. The values in these fields must point to a TCT-System Entries table entry. The sysid must match an entry in the SysID field and the netname must match an entry in the Ptnr_LU Name field. After storing the information, return with one of the following values:


procedure icon  To Modify the Terminal Not Found Exit

1. Change to the $UNIKIX/src/terminal directory.

2. Make a backup copy of the user exit $UNIKIX/src/terminal/kxtnfxit.c.

3. Open the original module in an editor.

4. Change the exit so that it correctly ships ATI requests to the required remote systems.

5. Save the updated contents of $UNIKIX/src/terminal/kxtnfxit.c back to disk.

6. Issue the following command to compile the updated module, and rebuild all executables that depend on it:

$ make unikixtran 


Security User Exit Routines

When a Sun MTP region is configured with Sun MTP Secure, there are certain predetermined points at which security exit routines are invoked. The purpose of these routines is to provide for user name-based security checking by an external security manager or by user-written security exit routines.

The default security user exits are located in the source file $UNIKIX/src/security/kxsec_exits.c. The accompanying definitions required for the Sun MTP resource types and permissions are located in the file $UNIKIX/src/security/security.h.



caution icon

Caution - Do not modify the default kxsec_exits.c source file, because remaking it could result in a security breach. Instead, use the file kxsec_exitsTMPL.c to create your own security user exits.



The entry points defined in the user exit module are called directly from the Sun MTP executive when external security is enabled for this region (KIXSEC=YES). It is the responsibility of these entry points to examine the security request and return the appropriate response. The executive then takes the appropriate action, such as continuing with the operation that has passed security validation or terminating the operation that failed security validation.

Read Chapter 8 before designing and implementing your own security user exits. It describes the resource types and default user names that must be provided for in the security checking done by your security user exits.

The security user exits are as follows:

Security manager status

Reports to the Sun MTP executive that it is enabled as the external security manager. Sun MTP then employs the remaining entry points to do all security validation checks. If it is not enabled (the default in the kxsec_exits.c module), transaction security key checking is used. If external security is enabled, this entry point must return TRUE; if not, it must return FALSE.

User login

Validates the user name/password, and optionally updates with a new password once validated. This entry point is called whenever a user needs to be validated to submit transactions to the region: when a local terminal is connected; when a remote system transaction request is received; and when the CSSN/CESN transaction is entered. If the user is validated, this entry point must return TRUE; if rejected, it must return FALSE.

This entry point can optionally use existing SNT entries to validate the user name and password in lieu of or in addition to its own validation rules. This SNT validation is provided by calling the kxchksntpw() function described in Validating the User Name and Password Using the SNT.

User logout

Registers that the user name is logging off the region. This entry point is called whenever the CSSF/CESF transaction is entered. If successful, this entry point must return TRUE; if unsuccessful, it must return FALSE.

Resource access

Verifies that the requested resource can be accessed by the indicated user name with the requested permissions. This entry point is called whenever a transaction requests the use of a resource for which security checking is enabled (KIXxxxSEC=YES). For details on the resource types and the permissions requested for each access request, see Administering Resource Security. The environment variables to enable/disable security checking for each resource type are listed the Sun Mainframe Transaction Processing Software Configuration Guide.

Example: If KIXFCTSEC=YES for the region, a WRITE request against VSAM file PRODDATA requests access to the KIX-FILES resource type named PRODDATA with write access permission for that user name. If allowed, this entry point must return TRUE; if rejected, it must return FALSE.

Start/stop caching and clear cache of resource validation results

Retains results of security validation checking for a transaction to optimize repeated calls for the same resource/permission within that transaction. For example, a transaction might perform several READ requests to the same VSAM file. After this read permission has been established, subsequent READ requests the transaction makes to the same VSAM file might also be permitted without revalidating each request. Optional.

The start caching entry point is called when the transaction server starts; this signals the user exit that it can begin to retain the results of each resource validation request from that transaction server. The clear cache entry point is called when each transaction completes, signaling the user exit to discard any retained results so that resource requests for the next transaction are again validated and retained. The stop caching entry point is not currently called by Sun MTP, but could be used in the future to disable any further caching of results in that server.

The security user exit should use local static storage for these retained results. It is not necessary nor desirable to use shared memory, since the retained results do not need to be visible outside the local transaction server process that enables the caching.



Note - The security user exits are also called from other Sun MTP server processes (for example, unikixmain) that do not support caching of validation requests. Those servers do not call these start caching or clear cache entry points and expect each resource request to be fully validated for security. The security user exits must not retain any information about prior calls unless the start caching entry point is called in that server process (and the stop caching entry point has not yet been called).



You must adhere to certain restrictions when writing code in these security exits. Sun MTP calls each of these functions from several of its own system servers during region startup, as well as during transaction execution. Specifically, unikixmain calls these entry points early in the startup processing before normal CICS or batch VSAM API services are available to be called. Therefore, the security user exit code must be able to load its own security rules without requiring any such services. For example, the security rules could be hard-coded tables in the user exit, or could be read from a line-sequential file into a buffer local to the security user exit.

The restrictions on CICS API usage in the security user exit are due to the fact that the security hooks extend beyond transaction usage. The following table lists the servers and processes that have these security hooks and the calls they make.

TABLE 11-4 Sun MTP Processes With Security Hooks

Server/process

Calls

unikixtran

login, logout, all resources

unikixCEMT (CEMT transaction)

resource (KIX-COMMANDS, UNIX-APPLS)

unikixmain

login (KIXSECDFLTUSER), resource (UNIX-APPLS)

unikixstrt

login user name in printer TCTs

unikixvsam

resource (KIX-FILES)

rtsvsam (Sun MBM)

resource (KIX-FILES)

sortx (Sun MBM)

resource (KIX-FILES)

kixfile

resource (KIX-FILES)

unikixbld

resource (KIX-FILES)

unikixFMS (CFMS transaction)

resource (KIX-FILES)

unikixRED (CRED transaction)

resource (KIX-FILES)

unikixrcv

resource (KIX-FILES)

dfhusdup

resource (KIX-FILES)


Security User Exit Functions and Parameters

The source code shown in this section is located in the default kxsec_exits.c module. The comments describe the parameters passed on each entry point function.

CODE EXAMPLE 11-8 Security User Exit Source Code (1 of 6)
/*********************************************************************/
 
#include "security.h"
 
/********************************************************************
 * Name of Function: kxsec_mgrstatus
 *
 * DESCRIPTION:
 * 	This function is called to determine whether the external
 * 	security manager is operational or not
 *
 * INPUTS:
 * 	None
 *
 * OUTPUTS:
 * 	Return Codes:
 * 	  TRUE      -External security manager is operational and ready
 * 	  FALSE     -External security manager is not currently operational
 *
 * CAVEATS:
 ********************************************************************/
boolean kxsec_mgrstatus()
{
	return FALSE;
}
 
/**********************************************************************
 * Name of Function: kxsec_login
 *
 * DESCRIPTION:
 *	This function is called to log on the indicated userid.
 *
 * INPUTS:
 *	username          - the name of the user being logged on
 *	username_length   - the number of characters in that user name
 *	password          - the password for that user
 *	password_length   - the number of characters in that password
 *	newpw             - the new password for that user, if supplied
 *	newpw_length      - the number of characters in that new password, zero 
 *	                     if not supplied
 * OUTPUTS:
 *	Return Codes:
 *	  TRUE      - User is successfully logged on and password updated if
 *	               new password was supplied
 *	  FALSE     - User was not successfully logged on; either userid or
 *	               password was invalid
 *
 
 * CAVEATS:
 ********************************************************************/
 
boolean kxsec_login(
	           char *username, int username_length,
	           char *password, int password_length,
	           char *newpw, int newpw_length)
{
	return TRUE;
}
 
/**********************************************************************
 * Name of Function: kxsec_logout
 *
 * DESCRIPTION:
 *	This function is called to log off the indicated userid.
 *
 * INPUTS:
 *	username          - the name of the user to be logged off
 *	username_length   - the number of characters in that user name
 *
 * OUTPUTS:
 *	Return Codes:
 *	  TRUE       - User is successfully logged off
 *	  FALSE      - User was not successfully logged off
 *
 * CAVEATS:
 
 ********************************************************************/
 
boolean kxsec_logout(
	           char *username, int username_length)
{
	return TRUE;
}
 
/**********************************************************************
 * Name of Function: kxsec_logout
 *
 * DESCRIPTION:
 *	This function is called to log off the indicated userid.
 *
 * INPUTS:
 *	username           - the name of the user to be logged off
 *	username_length    - the number of characters in that user name
 *
 * OUTPUTS:
 *	Return Codes:
 *	  TRUE      - User is successfully logged off
 *	  FALSE     - User was not successfully logged off
 *
 * CAVEATS:
 ********************************************************************/
 
boolean kxsec_logout(
	   char *username, int username_length)
{
	return TRUE;
}
 
/**********************************************************************
 * Name of Function: kxsec_rescheck
 *
 * DESCRIPTION:
 *	This function is called to check for permission to a Sun MTP asset
 *	by the indicated userid.
 *
 * INPUTS:
 *	asset_type - the Sun MTP asset type, e.g. KIX_FILES
 *	asset_name - the name of the Sun MTP asset, e.g. the dataset name
 *	asset_name_length - the number of characters in that asset name
 *	username - the name of the user for whom access is being checked
 *	username_length - the number of characters in that user name
 *	access_type - the permission being requested, e.g. WriteAccess
 *
 * OUTPUTS:
 *	Return Codes:
 *	  TRUE      - User is granted the requested permission to the asset
 *	  FALSE     - User is denied the requested permission to the asset
 *
 * CAVEATS:
 *
 **********************************************************************/
 
boolean kxsec_rescheck(
	       enum asset_type asset_type_req,
	       char *asset_name, int asset_name_length,
	       char *username, int username_length,
	       enum access_type access_type_req)
{
	return TRUE;
}
 
/**********************************************************************
 * Name of Function: kxsec_docache
 *
 * DESCRIPTION:
 *	This function is called to enable caching of results from asset
 *	checking done by this process. This eliminates multiple calls to
 *	an external security manager for the same asset / permission.
 *
 * INPUTS:
 *	None
 *
 * OUTPUTS:
 *	None
 *
 * CAVEATS:
 *
 *********************************************************************/
void kxsec_docache()
{
	return;
}
 
 
/**********************************************************************
 * Name of Function: kxsec_clearcache
 *
 * DESCRIPTION:
 *	This function is called to clear the cache of results from asset
 *	checking done by this process. This is done whenever the cached
 *	results must be refreshed from the external security manager.
 *
 * INPUTS:
 *	None
 *
 * OUTPUTS:
 *	None
 *
 * CAVEATS:
 *
 *********************************************************************/
 
void kxsec_clearcache()
{
	return;
}
 
/**********************************************************************
 * Name of Function: kxsec_dontcache
 *
 * DESCRIPTION:
 *	This function is called to disable caching of results from asset
 *	checking by this process. This call is only needed if caching is
 *	explicitly enabled by calling kxsec_docache(), since the default
 *	is that caching is disabled.
 *
 * INPUTS:
 *	None
 *
 * OUTPUTS:
 *	None
 *
 * CAVEATS:
 *
 **********************************************************************/
 
void kxsec_dontcache()
{
	return;
} 
 

Validating the User Name and Password Using the SNT

You can call the kxchksntpw() function from your security user exit code in lieu of, or in addition to, your own user name and password validation rules. This function locates the SNT entry for the requested user name and compares the requested password with the required password in that entry. If the passwords match, kxchksntpw validates the request, returns that indication and updates the SNT entry with the new password requested if one was provided. If the passwords do not match or the user name does not match any SNT entry, kxchksntpw rejects the request and returns that indication.

Inputs to the kxchksntpw() function are as follows:

Return codes output from the kxchksntpw() function are as follows:

The following code shows how to call the kxchksntpw() function in C:

if (kxchksntpw (username, password, result, newpw, newpw_length))
		{                 /* other processing              */
		return TRUE;      /* username & password valid     */
		}
	else
		{                 /* other processing              */
		return FALSE;     /* username or password invalid  */
		}


procedure icon  To Create a New Security User Exit Routine

1. Change to the $UNIKIX/src/security directory.

2. Make a backup copy of the kxsec_exits.c file.

3. Using the editor of your choice, make the necessary changes to the $UNIKIX/src/security/kxsec_exits.c file.

4. To compile and build the object file, type the following command:

$ make kxsec_exits.o

5. If you are finished using the customizing tools and are ready to rebuild the Sun MTP executables, go to Rebuilding Sun MTP Executables.

You have now changed the default security user exit routines.


Customizing Record Processing Routines

You can create customized input and output record processing routines either by modifying the templates or creating new routines.

The source files for all templates reside in the $UNIKIX/src/record directory. The line, record and recordv routines are written in C language, and the mfrcd routine is written in COBOL. The procedures for creating the two types of record processing routines differ and are explained later in this section.

The executable files are located in the following directories:

If you modify these routines, place the customized versions of the executables in the $UNIKIX/local/bin directory, because the region searches this directory before the $UNIKIX/bin/build directory.

The preset variables within the $UNIKIX/src/makefile file to use when customizing record processing routines are as follows:

USERSRCDIR

Set to $UNIKIX/src; the default home of source and object files.

USERRECORD

Set to $USERSRCDIR/record.

BINDIR

Set to $UNIKIX/local/bin; the default home of customized executable files.



procedure icon  To Modify an Existing Record Processing Routine

1. Using an editor, make the necessary changes to the appropriate file; for example, linein.c.

2. To compile and build the executables, type:

$ cd $UNIKIX/src
$ make line.in

3. Because Sun MTP normally uses internal versions of the line, record and recordv routines, you must rename your customized version in $UNIKIX/local/bin to a new name. For example:

$ cd $UNIKIX/local/bin
$ mv line.in myline.in



Note - You do not need to perform this step for mfrcrd routines.



4. Notify the region to use your customized routine:

a. Execute unikixbld -r format.

Type your routine name as the format argument, for example, myline. Do not use the extension.

b. Using the Record Editor:

Do not include the .in extension.

Do not include the .out extension.

Creating a New Record Processing Routine

To fully support an entirely new record processing type, you must create two executables. If starting from the COBOL source, you must also create two shell scripts for the new record input and output formats.

The following procedure creates two new record processing routines (myrecord.in and myrecord.out) for a new record format called myrecord.


procedure icon  To Create a New Record Processing Routine

1. In the file $UNIKIX/src/makefile there are three variables that you must update to contain the path names of the user modules being added.

a. The source files are located by the USERSOURCES environment variable and should reside in the $USERRECORD directory, for example:

USERSOURCES = \
	$(USERRECORD)/myrecordin.c \ 
	$(USERRECORD)/myrecordout.c

b. The object files are located by the USEROBJECTS environment variable, and should reside in the $USERRECORD directory, for example:

USEROBJECTS = \
	$(USERRECORD)/myrecordin.o \
	$(USERRECORD)/myrecordout.o

c. The executable files are located by the USEREXECUTABLES environment variable, and should reside in the $BINDIR directory, for example:

USEREXECUTABLES = \
	$(BINDIR)/myrecord.in \
	$(BINDIR)/myrecord.out

2. Add targets to the $UNIKIX/src/makefile for the executable files that you added to the system.

For example, for the myrecord.in executable, add the following lines:

$(BINDIR)/myrecord.in myrecord.out
	rm -f $@
	$(CC) $(CFLAGS) -o $@ $?

3. Copy the existing templates.

For example, to copy line from their existing files to the myrecord source files, type the following commands:

$ cp $UNIKIX/src/record/linein.c $UNIKIX/src/record/myrecordin.c
$ cp $UNIKIX/src/record/lineout.c $UNIKIX/src/record/myrecordout.c

4. Using an editor, make your changes to the myrecord source files.

5. For COBOL user modules, there is an additional set of shell script files that you must customize.

Copy the existing template script files to the myrecord script files:

$ cp $UNIKIX/src/record/mfrcd.in $UNIKIX/src/record/myrecord.in
$ cp $UNIKIX/src/record/mfrcd.out $UNIKIX/src/record/myrecord.out

6. Compile the myrecord source files using the following commands:

$ cd $UNIKIX/src
$ make myrecord.in
$ make myrecord.out

7. Edit the following script files to execute the executables created in Step 6.

$UNIKIX/local/bin/myrecordin
$UNIKIX/local/bin/myrecordout

8. The executable files are located by the USEREXECUTABLES environment variable, and should reside in the $BINDIR directory, so add the script files to the $USEREXECUTABLES definition:

USEREXECUTABLES = \
	$(BINDIR)/myrecordin \
	$(BINDIR)/myrecordout \
	$(BINDIR)/myrecord.in \            *defined in Step 1
	$(BINDIR)/myrecord.out             *defined in Step 1

9. Copy target entries for COBOL from the entry for mfrcdin and mfrcd.in with appropriate name changes.

10. Compile the myrecord source files using the following commands:

$ cd $UNIKIX/src
$ make myrecordin
$ make myrecordout
$ make myrecord.in
$ make myrecord.out


Recovery Processor User Exit

The primary purpose of the recovery processor user exit is to mark ESDS dataset records with a special tag that indicates that the record was logically deleted. Sun MTP will not delete the record; the user application must determine whether the record should be deleted and process the dataset accordingly.

The source functions are located in $UNIKIX/src/recovery/kxesdsxlt.c and are called during transaction back out operations.

Recovery Backout Function Calls

The implicit function kxesds_backout_user_exit is called during dynamic transaction backout with the following information if a transaction performed write operations on an ESDS dataset.

Record Buffer

Pointer to data record which needs to marked as deleted (character pointer)

Length

Length of record (Integer)

Dataset Name

Name of the dataset as defined in the FCT (character pointer)

Return Code

Return code to be passed back to recovery processor (Integer)


You can modify the function and add proprietary source lines to modify the contents of the record buffer that would indicate a logical delete for the user application.

The source module provides examples of how the data record can be modified. You can write your own logic to meet the needs of your environment. You can also use conditional logic to examine the value of record_dataset (that is, the ESDS dataset name).

Return Code From the Backout Function

The initial value for the return code is set to 0. After successfully modifying the record_buffer contents, the return code needs to be set to the value 4 so that the updated data buffer contents can be changed on the ESDS file physically. If the return code value is other than 4, the updated contents, if any, will not be posted to the ESDS file and the record's original contents before entering the back out function will be preserved.

Customizing the Recovery Process

After you modify the kxesdsxlt.c source file, you must rebuild the recovery processor (unikixrcv).


procedure icon  To Rebuild the Recovery Processor

1. Change to the directory where the customized kxesdsxlt.c source file is located:

$ cd $UNIKIX/src

2. Compile the kxesdsxlt.c source file and re-link the unikixrcv executable using the makefile in the $UNIKIX/src directory.

$ make unikixrcv

This will place the updated unikixrcv module in the directory specified in the BINDIR environment variable in the makefile. This is usually the $UNIKIX/local/bin directory.

3. Restart the region to put the change into effect.


Rebuilding Sun MTP Executables

You must rebuild the executables for a region when:

Building Executables Using the make Command

This section describes the user makefile and the make facility delivered with the software. Use the make facility when the region needs rebuilding.

The purpose of the make facility is to predefine the executables, commands and rules that are necessary to build the customizable components. This allows you to modify the source, then type one command that identifies the modified source modules, and the steps that must be performed to create an appropriate executable. The user makefile is located in the $UNIKIX/src directory.

An experienced user can modify the makefile manually, but the kixinstall utility automates the process of customizing the makefile to support RDBMS products, user routines and optional, third-party products.

The default options for the makefile produced by the kixinstall utility builds all executables, the Sun MTP Transaction and Batch Servers and all the record processing routines. By default, these executables are created in the $UNIKIX/local/bin directory.

Refer to the Sun Mainframe Transaction Processing Software Installation Guide and the Sun Mainframe Transaction Processing Software Reference Guide for information about using kixinstall.

Building All Executables

To build all executables, Transaction and Batch Servers and all record processing routines type these commands:

$ cd $UNIKIX/src
$ make clean
$ make all

If you modified the value of the BINDIR environment variable in $UNIKIX/src/makefile, the executables are created in that directory. Otherwise, they are created in $UNIKIX/local/bin.

Building Selected Executables

To build selected executables, run make with the name of the executable. For example, build only unikixtran by typing the following commands:

$ cd $UNIKIX/src
$ make unikixtran

If you modified the value of $BINDIR in $UNIKIX/src/makefile, the new unikixtran is created in that directory. Otherwise, it is created in $UNIKIX/local/bin.

Binding User-written C Functions

To call user-written C functions from application programs, you must bind them with the Transaction or Batch Server. To facilitate this task, the $UNIKIX/lib directory contains two files, unikixtran.o and unikixvsam.o, which are used to create a new Transaction Server and Batch Server, respectively.

If the Transaction and Batch Servers are bound with a COBOL runtime system, the user application program is created in .int, .gnt or .o format. The .int and .gnt formats do not require any form of binding with other COBOL subroutines or the language runtime routines to execute; however, the .o format does.

Building or Rebuilding Executables Using kixinstall

For a complete description of how to build executables using kixinstall, refer to the Sun Mainframe Transaction Processing Software Installation Guide.


procedure icon  To Integrate User-written Modules

1. Change to the $UNIKIX/src directory.

2. Run the kixinstall command to display the Configuration Utility menu.

  FIGURE 11-1 Configuration Utility Main Menu

Screen shot showing the Configuration Utility main menu.

3. Select R on the main menu and press Return to remove the current configuration.

This sets the default configuration.



Note - Select option D at any time to display the current configuration.



4. To add or change user-specific objects, select 5 on the main menu and press Return.

This opens a file in the vi editor. See FIGURE 11-2.

  FIGURE 11-2 User-Specific Objects Screen

Screen shot showing the User-Specific Objects screen.

5. Type the names, or path names relative to $UNIKIX/src, of the objects you want to integrate.

6. When you are done, press the Esc key and type :wq.

The main menu is displayed.

7. To add user-specific linker and compiler options, select 6 on the main menu and press Return.

This opens a file in the vi editor.

  FIGURE 11-3 Specifying User-Specific Linker and Compiler Options

Screen shot showing the User-Specific Linker/Compiler Options screen.

8. Type in the linker and compiler options you want applied to the user-specific objects you specified in Step 5.

Refer to the C compiler documentation or the COBOL documentation for the cob command for information about the linker and compiler options.

9. To end the session, press the Esc key and type :wq. The main menu is displayed.

10. To build the configuration file, select B on the main menu and press Return.

The Build Current Configuration screen is displayed. This selection builds the configuration file based on your previous selections.

11. When the build is complete, press Return to display the main menu.

12. Type Q to exit the Configuration Utility.

After you exit, the following message is displayed:

#Sun MTP Configuration successfully completed.
#
#Logfile was /tmp/kixinstall.log.#####

This is the path name of the log file that was created during this configuration session. View the file using a text editor. You can send a copy of this file to your authorized service provider if you are experiencing any problems.

13. Refer to the Sun Mainframe Transaction Processing Software Installation Guide for additional steps that you must perform whenever you rebuild your system with kixinstall.


procedure icon  To Build a New Online Transaction Server

The makefile, by default, creates the new transaction server in the $UNIKIX/local/bin directory.

1. If the following two directories do not exist, create them as follows:

$ mkdir $UNIKIX/local
$ mkdir $UNIKIX/local/bin

2. Create a new version of the transaction server (unikixtran) using the following commands:

$ cd $UNIKIX/src
$ make unikixtran

3. Start the region.

If you changed the BINDIR environment variable in the makefile and made the new version in a directory other than $UNIKIX/bin or $UNIKIX/local/bin, you must start the region with the -l option and specify the directory as its argument. For example:

$ unikixmain -l /usr/workdir ....

Refer to the Sun Mainframe Transaction Processing Software Reference Guide for more information about the command-line options for unikixmain.

Building a New Batch COBOL Runtime System

This section provides the steps for making new batch COBOL runtime systems:


procedure icon  To Build a Standard Batch COBOL Runtime System

The makefile, by default, creates the runtime system in the $UNIKIX/local/bin directory.

1. If the following two directories do not exist, create them as follows:

$ mkdir $UNIKIX/local
$ mkdir $UNIKIX/local/bin

2. Change to the $UNIKIX/src directory or the directory specified during the kixinstall session.

3. Create a new version of the runtime system, unikixvsam:

$ make unikixvsam

4. If you created the runtime system in $UNIKIX/local/bin and you are going to run COBOL programs with CBCH, you can start the region as usual.

If, however, you modify the BINDIR environment variable in the makefile or specify a different target directory for executables during the kixinstall, you must start the region with the -l option. Refer to the Sun Mainframe Transaction Processing Software Reference Guide for more information about the command-line options for unikixmain.


procedure icon  To Build a Sun MBM COBOL Runtime System

The makefile, by default, creates the runtime system in the $UNIKIX/local/bin directory.

1. If the following two directories do not exist, create them as follows:

$ mkdir $UNIKIX/local
$ mkdir $UNIKIX/local/bin

If you modify $BINDIR in the makefile or select a different target directory for executables during the kixinstall session, the makefile creates the new version in that directory.

2. Change to the $UNIKIX/src directory or the directory specified during the kixinstall session.

3. Create a new version of the runtime system, rtsvsam:

$ make rtsvsam

The following is an example of the output:

rm -f /tmp/company1/bin/rtsvsam_*
rm -f /tmp/company1/bin/RUNB
(sh RTSVSAM/inst_rtsvsam "SOL" "y" "y" \
.
.
.
+ cob -xD -o /tmp/company1/bin/rtsvsam_yy ./RTSVSAM/CPR.o ./RTSVSAM/COB.o
	./RTSVSAM/CCFinit.o ./RTSVSAM/CCFextfh.o cobwrap.o coberror.o
	./RTSVSAM/kxpassrem.o ./RTSVSAM/kxpassubs.o ./RTSVSAM/ebmlsfile.o
	./RTSVSAM/runb.o /tmp/company1/kxusrexit.o /tmp/company1/cvlwrupr.o
	/tmp/company1/kxusrxlt.o /tmp/company1/kxcvtxlt.o /tmp/company1/kxcnvtbl.o
	/net/haven/home/ebm81/KIX/lib/libbsec.a -lcurses -lsocket -lnsl -lm 
+ set +x 
#
# Sun MBM COBOL Runtime System /tmp/company1/bin/RUNB Installed.
# To be effective set RUNBDIR in your setup file:
# setenv RUNBDIR /tmp/company1/bin
#
# Add the RUNBDIR pathname to the RUNBPATH in your setup file.
#

4. Set the RUNBDIR and RUNBPATH environment variables in the Sun MBM subsystem's user setup file to the directory where the COBOL runtime system was created.

5. Submit the job using the unikixjob command.

Refer to the Sun Mainframe Batch Manager Software User's Guide for information about the unikixjob command.