CPICERRS.H

/***************************************************************************** 
*
* MODULE NAME: CPICERRS.H
*
* COPYRIGHTS:
* This module contains code made available by IBM
* Corporation on an AS IS basis. Any one receiving the
* module is considered to be licensed under IBM copyrights
* to use the IBM-provided source code in any way he or she
* deems fit, including copying it, compiling it, modifying
* it, and redistributing it, with or without
* modifications. No license under any IBM patents or
* patent applications is to be implied from this copyright
* license.
*
* A user of the module should understand that IBM cannot
* provide technical support for the module and will not be
* responsible for any consequences of use of the program.
*
* Any notices, including this one, are not to be removed
* from the module without the prior written consent of
* IBM.
*
* AUTHOR: Peter J. Schwaller
* VNET: PJS at RALVM6 Tie Line: 444-4376
* Internet: pjs@ralvm6.vnet.ibm.com (919) 254-4376
*
* John Q. Walker
* VNET: JOHNQ at RALVM6 Tie Line: 444-4414
* Internet: johnq@ralvm6.vnet.ibm.com (919) 254-4414
*
* AVAILABILITY:
* These sample programs and source are also available on
* CompuServe through the APPC Information Exchange. To get
* to the APPC forum just type 'GO APPC' from any CompuServe
* prompt. The samples are available in the Sample Programs
* library section. Just search on the keyword CPICPGMS to
* find all the samples in this series.
*
* Updates for the sample programs and support for many more
* CPI-C platforms will also be made available on CompuServe.
*
* RELATED FILES:
* Use CPICERR.C
*
* CHANGE HISTORY:
* Date Description
* 08/05/92 Version 2.31 of APING, ATELL and AREXEC released to CompuServe.
* This version was also distributed at the APPC/APPN Platform
* Developer's Conference held in Raleigh, NC.
* 08/13/92 Changed cpicerr_handle_rc() to a macro referencing
* cpicerr_handle_rc_extended(). The macro adds the current
* source file and line number to improve source code debugging.
* 11/04/92 Changed version from char to unsigned char.
* 11/15/92 Changed reply structure to include 2 byte indicator.
* 11/17/92 Added send/receipt of operating system string.
* Added cpicerr_exchange_version_plus() to return the string.
*
*****************************************************************************/

/*****************************************************************************
*
* OVERVIEW OF CPICERR CALLS
*
* cpicerr_new() Creates a CPICERR object.
* This must be done before any other
* cpicerr calls can be used.
*
* These calls set values in the cpicerr object structure and affect how
* cpicerr_handle_rc reacts to errors.
*
* cpicerr_set_log_file_name() What filename to use for logging
* cpicerr_set_log_file_path() Where the filename is
* cpicerr_set_program_name() String - Output as part of log info
* cpicerr_set_program_info() String - Output as part of log info
* cpicerr_set_major_version() 8 bit int - see cpicerr_exchange_version
* cpicerr_set_minor_version() 8 bit int - see cpicerr_exchange_version
* cpicerr_set_conv_id() Used to extract conversation state info
* cpicerr_set_exit_level() Level of error on which to exit
* cpicerr_set_show_level() Level of error on which to show errors
* cpicerr_set_log_level() Level of error on which to log errors
*
* cpicerr_handle_rc() Should be called by the program for all
* UNEXPECTED return codes.
* Functions performed are:
* Classification of the return code
* Showing partial info to end user
* Logging complete info to disk
* This is a macro that actually expands
* to cpicerr_handle_rc_extended().
*
* cpicerr_destroy() Destroys the CPICERR object.
*
*
* cpicerr_classify_rc() These are internal calls used by
* cpicerr_show_rc() other cpicerr_handle_rc.
* cpicerr_log_cpicerr()
* cpicerr_get_message()
* cpicerr_set_rc_info()
* cpicerr_show_product_info()
*
*****************************************************************************/

#ifndef INCL_CPICERR
#define INCL_CPICERR


/*
* Include the C standard I/O library for the FILE structure definition.
*/
#include <stdio.h>

/*
* Collection of routines with special ported version for each platform
* The only thing that is used from CPICDEFS.H is the correct setting
* of the SHORT_IDENTIFIERS identifier.
*/
#include "cpicdefs.h"

#if defined(SHORT_IDENTIFIERS)
/*
* The C/370 compiler requires that identifier be unique in the 1st 8 chars.
* If any new functions are added to this file, they should also be added to
* this list, with a unique mapping.
*/
# define cpicerr_build_reply_image cebri
# define cpicerr_conv_types ceconv_type
# define cpicerr_classify_rc cecr
# define cpicerr_create_reply cecrep
# define cpicerr_destroy cedestroy
# define cpicerr_destroy_reply cedr
# define cpicerr_extract_reply_image ceeri
# define cpicerr_exchange_version ceev
# define cpicerr_exchange_version_plus ceevp
# define cpicerr_get_message cegm
# define cpicerr_handle_rc_extended cehre
# define cpicerr_log_cpicerr celf
# define cpicerr_set_major_version cemajor
# define cpicerr_set_minor_version ceminor
# define cpicerr_new cenew
# define cpicerr_recv_appl_error cerae
# define cpicerr_return_codes cerc
# define cpicerr_rc_classes cercclass
# define cpicerr_send_appl_error cesae
# define cpicerr_set_conv_id cesci
# define cpicerr_set_error_reply ceser
# define cpicerr_set_rc_info cesetr
# define cpicerr_set_log_file_name ceslfn
# define cpicerr_set_log_file_path ceslfp
# define cpicerr_set_log_level cesll
# define cpicerr_set_program_info cespi
# define cpicerr_set_program_name cespn
# define cpicerr_show_product_info cespri
# define cpicerr_show_rc cesr
# define cpicerr_show_reply cesrep
# define cpicerr_set_show_level cessl
# define cpicerr_states_conv cestate
# define cpicerr_set_exit_level cesxl
# define cpicerr_sync_levels cesync
# define cpicerr_verbs_long cvlong
# define cpicerr_verbs_short cvshort
#endif

/* Needed for the time_t structure used within the CPICINIT structure */
#include <time.h>

/*
* Specify the maximum sizes for a variety of CPI-C fields.
* The +1 is added to allow room for the C null terminator for strings.
*/
#define MAX_LU_ALIAS (8+1)
#define MAX_PLU_ALIAS (8+1)
#define MAX_TP_NAME (64+1)
#define MAX_SYM_DEST_NAME (8+1)
#define MAX_FQPLU_NAME (17+1)
#define MAX_DESTINATION (17+1)
#define MAX_MODE_NAME (8+1)
#define MAX_USERID (8+1)
#define MAX_PASSWORD (8+1)



#define MAX_MESSAGE_TEXT_LENGTH (2048)


/*****************************************************************************
* These values are used to break the CPI-C return codes down into classes.
* They are organized from errors that can be ignored, to fatal errors
* which cannot be recovered from.
*
* The values ALL_ERRORS and NO_ERRORS are used as extremes for the
* cpicerr_set_exit_level() and cpicerr_set_show_level() calls, and are
* not actual classification values.
*****************************************************************************/
typedef enum {
RC_OK = 0,
ALL_ERRORS,
CONTINUE ,
RETRY_VERB ,
SECURITY_NOT_VALID,
ERROR_RECEIVED ,
RETRY_CONV ,
RETRY_CONV_BO ,
BACKOUT_RECEIVED ,
UNRECOVERABLE ,
UNRECOVERABLE_BO ,
NO_ERRORS
} CPIC_RC_HANDLING;

/*
* Since CPI-C does not provide actual values that correspond to each CPI-C
* call, we have to invent our own so that we can put the call names into
* our message lists.
*/
typedef enum {
MSG_CMACCP,
MSG_CMALLC,
MSG_CMCFM ,
MSG_CMCFMD,
MSG_CMDEAL,
MSG_CMECS ,
MSG_CMECT ,
MSG_CMEMN ,
MSG_CMEPLN,
MSG_CMESL ,
MSG_CMFLUS,
MSG_CMINIT,
MSG_CMPTR ,
MSG_CMRCV ,
MSG_CMRTS ,
MSG_CMSCT ,
MSG_CMSDT ,
MSG_CMSED ,
MSG_CMSEND,
MSG_CMSERR,
MSG_CMSF ,
MSG_CMSLD ,
MSG_CMSMN ,
MSG_CMSPLN,
MSG_CMSPTR,
MSG_CMSRC ,
MSG_CMSRT ,
MSG_CMSSL ,
MSG_CMSST ,
MSG_CMSTPN,
MSG_CMTRTS,
MSG_XCSCSU,
MSG_XCSCST,
MSG_XCSCSP,
MSG_XCECST,
MSG_XCECSU,
MSG_XCMSSI,
MSG_XCMESI,
MSG_XCMDSI
} CPIC_VERB_INDEX;


/*****************************************************************************
*
* CPICERR_REPLY
*
* This structure is a reusable reply format. This can be used either
* as part of a data reply, or as an error reply after a send_error()
* call. See CPICERR.C for complete details of how this structure
* is formatted on a CPI-C conversation.
*****************************************************************************/

typedef enum next_state {
NEXT_SEND,
NEXT_RECEIVE,
NEXT_DEALLOCATE,
NEXT_DEALLOCATE_AND_EXIT
} NEXT_STATE;

typedef enum reply_response {
REPLY_POSITIVE_COMPLETE = 1,
REPLY_POSITIVE_INTERMEDIATE = 2,
REPLY_NEGATIVE_TRANSIENT = 3,
REPLY_NEGATIVE_PERMANENT = 4
} REPLY_RESPONSE;

typedef struct cpicerr_reply {
unsigned short length;
unsigned short buffer_length;
char * buffer;
} CPICERR_REPLY;

/*
* The format of the reply buffer is:
* Offset Length Field
* ------ ------ -----
* 0 2 Reply Indicator (0xFF01)
* 2 1 response
* 3 1 reserved (must be 0)
* 4 2 message category
* 6 4 primary code
* 10 4 secondary code
* The following two fields are optional:
* 12 2 primary message length
* 14 x primary message text
* The following two fields are optional and should follow the primary message:
* 14+x 2 secondary message length
* 16+x y secondary message text
*/


#define CPICERR_REPLY_INDICATOR_VALUE (0xFF01)
#define CPICERR_REPLY_MIN_LENGTH (14)

/* offsets into the reply buffer for each field */
#define CPICERR_REPLY_INDICATOR (0)
#define CPICERR_REPLY_RESPONSE (2)
#define CPICERR_REPLY_RESERVED (3)
#define CPICERR_REPLY_CATEGORY (4)
#define CPICERR_REPLY_PRIMARY (6)
#define CPICERR_REPLY_SECONDARY (10)
#define CPICERR_REPLY_PRIMARY_LENGTH (14)
#define CPICERR_REPLY_PRIMARY_TEXT (16)

/*****************************************************************************
*
* CPICERR
*
* This structure contains all of the information necessary to for all
* cpicerr calls. All of the fields which need to be changed by the
* application program should be modified through the cpicerr_set...()
* calls. The application program should never have to access the
* cpicerr structure directly.
*
* When an unexpected return code occurs, this structure is used to
* determine what error processing should occur, including:
* display of minimal error information
* logging of complete error information
* where to log the data
*
* If a field is added to this structure, be sure to add the correct
* initialization values for the field in the cpicerr_new() function.
*****************************************************************************/

typedef struct error_handler_cpicerr {
char * program_name; /* program's name */
char * program_info; /* program information */
CPIC_VERB_INDEX verb_index; /* index of the failing verb */
CM_RETURN_CODE conv_rc; /* return code from CPI-C */
CM_CONVERSATION_STATE conversation_state;
CM_CONVERSATION_TYPE conversation_type;
CM_SYNC_LEVEL sync_level;
char * log_file_path; /* path for the log file */
char * log_file_name; /* where to log errors */
unsigned char conversation_id[8]; /* CPI-C Conversation ID */
int conv_id_set; /* Was conv_id set? */
CM_INT32 mode_name_length; /* mode_name length */
CM_INT32 partner_LU_name_length; /* partner_LU_name length */
unsigned char mode_name[MAX_MODE_NAME]; /* mode_name */
unsigned char partner_LU_name[MAX_FQPLU_NAME]; /* partner_LU_name */
CPIC_RC_HANDLING exit_level; /* should we exit on an error? */
CPIC_RC_HANDLING show_level; /* should we show errors? */
CPIC_RC_HANDLING log_level; /* should we log errors? */
unsigned char major_version; /* Major version number */
unsigned char minor_version; /* Minor version number */
time_t program_start_time; /* time of cpicerr init */
time_t program_error_time; /* time of error report */
int handle_error; /* should cpicerr process all */
/* ERROR_RECEIVED ret codes? */
} CPICERR;


/*****************************************************************************
* The following are the structures and constants used for handling all of
* message strings in CPICERR.
*****************************************************************************/

/*
* The cpicerr_message structure contains an index and the text message
* associated with that index. In most cases, the index will be an actual
* CPI-C return value. For example,
* index = CM_SEND_STATE, message = "Send state"
*/
typedef struct cpicerr_message {
CM_INT32 index;
char * message;
} CPICERR_MESSAGE;


/*
* This enum gives each list a label and a value to make it easier to
* process all of the lists.
*/
typedef enum cpicerr_message_type {
CPIC_SYNC_LEVELS = 1,
CPIC_CONV_TYPES = 2,
CPIC_STATES_CONV = 3,
CPIC_RC_CLASSES = 4,
CPIC_RETURN_CODES = 5,
CPIC_VERBS_SHORT = 6,
CPIC_VERBS_LONG = 7
} CPICERR_MESSAGE_TYPE;

/*
* The CPICERR_MESSAGE_LIST structure is what actually ties a
* CPICERR_MESSAGE_TYPE value to the CPICERR_MESSAGE list that it relates
* to. A table is defined in CPICERR.C that allows the cpicerr_get_message
* routine to correlate a message label to its corresponding message list.
*/
typedef struct cpicerr_message_list {
CPICERR_MESSAGE_TYPE type;
CPICERR_MESSAGE * list;
} CPICERR_MESSAGE_LIST;

/*
* The following value is used to mark the end of CPICERR_MESSAGE lists.
*/
#define MAX_MESSAGE 32767


/*
* Set the size of the buffer used by the cpicerr_exchange_version() call.
*/
#define EXCHANGE_BUFFER_SIZE 128


/*
* If these CPI-C calls are not supported, these values will be returned
* instead of a valid CPI-C values. In the message tables, the values
* below will result in a message of "XXX not supported". This allows
* us to differentiate between a call not being available on a platform,
* and an unrecognized value returned on a call.
*/
#define CMECS_NOT_SUPPORTED (CM_CONVERSATION_STATE) 99



/*
* Used by the cpicerr_exchange_version() routine. Future flows may
* be prefaced with new "command values" taken from this list.
*/
typedef enum cpicerr_command {
CPICERR_EXCHANGE_VERSION = 1,
CPICERR_EXCHANGE_OPSYS_STRING = 2
} CPICERR_COMMAND;


/*****************************************************************************
* Function prototypes for routines that can be called via an application
* program. See CPICERR.C for a full description of each function and
* how to use it.
*****************************************************************************/
CPICERR *
cpicerr_new(void);

void cpicerr_show_reply( CPICERR_REPLY * reply);
CPICERR_REPLY *
cpicerr_create_reply( unsigned int primary_message_buffer_size,
unsigned int secondary_message_buffer_size);
void cpicerr_destroy_reply( CPICERR_REPLY * reply);
unsigned int
cpicerr_build_reply_image(CPICERR_REPLY * reply,
char * reply_buffer,
unsigned int reply_buffer_length);
unsigned int
cpicerr_extract_reply_image(CPICERR_REPLY * reply,
char * reply_buffer,
unsigned int reply_buffer_length);
void cpicerr_set_error_reply( CPICERR_REPLY * reply,
REPLY_RESPONSE response,
unsigned int message_category,
unsigned long primary_code,
char * primary_message_text,
unsigned long secondary_code,
char * secondary_message_text);
int cpicerr_recv_appl_error( CPICERR * cpicerr,
CPICERR_REPLY * reply);
int cpicerr_send_appl_error( CPICERR * cpicerr,
NEXT_STATE next_state,
CPICERR_REPLY * reply);
int cpicerr_set_program_name( CPICERR * cpicerr,
char * program_name);
int cpicerr_set_program_info( CPICERR * cpicerr,
char * program_info);
int cpicerr_set_major_version(CPICERR * cpicerr,
unsigned char major_version);
int cpicerr_set_minor_version(CPICERR * cpicerr,
unsigned char minor_version);
int cpicerr_set_conv_id( CPICERR * cpicerr,
unsigned char * cm_conv_id);
int cpicerr_set_log_file_name(CPICERR * cpicerr,
char * log_file_name);
int cpicerr_set_log_file_path(CPICERR * cpicerr,
char * log_file_path);
int cpicerr_set_exit_level( CPICERR * cpicerr,
CPIC_RC_HANDLING exit_level);
int cpicerr_set_show_level( CPICERR * cpicerr,
CPIC_RC_HANDLING show_level);
int cpicerr_set_log_level( CPICERR * cpicerr,
CPIC_RC_HANDLING log_level);
CPIC_RC_HANDLING
cpicerr_handle_rc_extended( CPICERR * cpicerr,
CPIC_VERB_INDEX verb_index,
CM_RETURN_CODE conv_rc,
char * file_name,
int file_line);
/*
* Provide an alternative interface for handling unexpected CPI-C
* return codes. This macro saves the programming from having
* to type the __FILE__ and __LINE__ macros for each call.
*/
#define cpicerr_handle_rc(x,y,z) \
cpicerr_handle_rc_extended(x,y,z, __FILE__, __LINE__)

int cpicerr_exchange_version( CPICERR * cpicerr,
unsigned char * cm_conv_id,
CM_INT32 conv_state,
unsigned char * partner_major_version,
unsigned char * partner_minor_version);
int cpicerr_exchange_version_plus(
CPICERR * cpicerr,
unsigned char * cm_conv_id,
CM_INT32 conv_state,
unsigned char * partner_major_version,
unsigned char * partner_minor_version,
unsigned char * opsys_string,
unsigned int opsys_string_length);
void cpicerr_destroy( CPICERR * cpicerr);



#endif