fis-gtm/sr_unix_gnp/gtcm_ch.c

165 lines
4.7 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_time.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "cmidef.h"
#include "hashtab_mname.h" /* needed for cmmdef.h */
#include "cmmdef.h"
#include "error.h"
#include "fao_parm.h"
#include "gtm_fcntl.h"
#include "cmi.h"
#include "preemptive_ch.h"
#include "gtm_string.h"
#include "gtm_stdio.h"
#include "copy.h"
#include "min_max.h"
#include "gtcm_write_ast.h"
#include "io.h"
#include "gtmio.h"
#include "have_crit.h"
#include "iosp.h"
#include "util.h"
#include "send_msg.h"
#include "gtmmsg.h"
#include "gtcm_open_cmerrlog.h"
GBLDEF bool gtcm_errfile = FALSE;
GBLDEF bool gtcm_firsterr = TRUE;
GBLDEF FILE *gtcm_errfs = NULL;
GBLREF connection_struct *curr_entry;
GBLREF bool undef_inhibit;
static short szero = 0;
error_def(ERR_JNLFILOPN);
error_def(ERR_SERVERERR);
CONDITION_HANDLER(gtcm_ch)
{
unsigned char msgnum, sevmsgbuf[2048];
unsigned char *tempptr, *mbfptr, *endptr, *msgptr;
err_ctl *fac;
int i, msglen, len, rc, orig_severity;
bool first;
now_t now; /* for GET_CUR_TIME macro */
char time_str[CTIME_BEFORE_NL + 2], *time_ptr; /* for GET_CUR_TIME macro */
short short_len;
START_CH;
undef_inhibit = FALSE; /* reset undef_inhibit to the default value in case it got reset temporarily and there was an error.
* currently, only $INCREMENT temporarily resets this (in gtcmtr_increment.c)
*/
if (gtcm_firsterr)
gtcm_open_cmerrlog();
msgnum = 1;
msglen = (int)(TREF(util_outptr) - TREF(util_outbuff_ptr));
if (0 == msglen)
{ /* gtm_putmsg_list has already flushed message. Get length another way.
Also reduce msg length by <\n> on it's end which we don't want to send.
*/
msglen = STRLEN(TREF(util_outbuff_ptr)) - 1;
} else
{ /* msg yet to be flushed. Properly terminate it in the buffer */
*(TREF(util_outptr)) = '\n';
*(TREF(util_outptr) + 1) = 0;
}
msgptr = (unsigned char *)TREF(util_outbuff_ptr);
assert(msglen);
if (gtcm_errfile)
{
GET_CUR_TIME;
time_str[CTIME_BEFORE_NL] = 0;
FPRINTF(gtcm_errfs, "%s: %s", time_str, TREF(util_outbuff_ptr));
FFLUSH(gtcm_errfs);
}
orig_severity = SEVERITY;
/* Don't let severe error message cause client to necessarily die. Reflect error using ERR_SERVERERR */
if (4 <= SEVERITY)
{
memcpy(sevmsgbuf, TREF(util_outbuff_ptr), msglen);
util_out_print(NULL, OPER); /* write msg to operator log */
gtm_putmsg_noflush(VARLSTCNT(4) ERR_SERVERERR, 2, msglen, sevmsgbuf);
msglen = (int)(TREF(util_outptr) - TREF(util_outbuff_ptr));
}
if (curr_entry)
{
mbfptr = curr_entry->clb_ptr->mbf;
endptr = mbfptr + curr_entry->clb_ptr->mbl;
*mbfptr++ = CMMS_E_ERROR;
*mbfptr++ = 0; /* Msg continue indicator */
*mbfptr++ = msgnum++;
PUT_SHORT(mbfptr, szero); /* Room for msg length */
mbfptr += SIZEOF(short);
PUT_LONG(mbfptr, SIGNAL);
mbfptr += SIZEOF(int4);
PUT_LONG(mbfptr, SEVERITY);
mbfptr += SIZEOF(int4);
do
{
assert(msglen);
len = MIN(msglen, (int)(endptr - mbfptr));
memcpy(mbfptr, msgptr, msglen);
mbfptr += len;
msgptr += len;
msglen -= len;
if (msglen)
{
/* Need to finish this msg off and start a new one */
curr_entry->clb_ptr->cbl = mbfptr - curr_entry->clb_ptr->mbf;
curr_entry->clb_ptr->ast = 0;
tempptr = curr_entry->clb_ptr->mbf + 1;
*tempptr++ = 1;
tempptr++;
short_len = (short)len;
assert((int)short_len == len); /* short <- int assignment lossy? */
PUT_SHORT(tempptr, short_len);
cmi_write(curr_entry->clb_ptr);
mbfptr = curr_entry->clb_ptr->mbf;
*mbfptr++ = CMMS_E_ERROR;
*mbfptr++ = 0;
*mbfptr++ = msgnum++;
PUT_SHORT(mbfptr, szero); /* Room for msg length */
mbfptr += SIZEOF(short);
}
} while(msglen);
if (mbfptr > curr_entry->clb_ptr->mbf + 3)
{
curr_entry->clb_ptr->cbl = mbfptr - curr_entry->clb_ptr->mbf;
curr_entry->clb_ptr->ast = gtcm_write_ast;
tempptr = curr_entry->clb_ptr->mbf + 3;
short_len = (short)len;
assert((int)short_len == len); /* short <- int assignment lossy? */
PUT_SHORT(tempptr, short_len);
cmi_write(curr_entry->clb_ptr);
}
}
if (SUCCESS == orig_severity || INFO == orig_severity || ERR_JNLFILOPN == arg)
{
CONTINUE;
}
if (WARNING == orig_severity || ERROR == orig_severity)
{
preemptive_ch(orig_severity);
UNWIND(x,y);
}
NEXTCH;
}