226 lines
6.0 KiB
C
226 lines
6.0 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2011 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_string.h"
|
||
|
#include "gtm_iconv.h"
|
||
|
|
||
|
#include "gdsroot.h"
|
||
|
#include "gtm_facility.h"
|
||
|
#include "fileinfo.h"
|
||
|
#include "gdsbt.h"
|
||
|
#include "gdsfhead.h"
|
||
|
#include "gdsblk.h"
|
||
|
#include "min_max.h" /* needed for gdsblkops.h */
|
||
|
#include "gdsblkops.h"
|
||
|
#include "gdscc.h"
|
||
|
#include "cli.h"
|
||
|
#include "filestruct.h"
|
||
|
#include "jnl.h"
|
||
|
#include "io.h"
|
||
|
#include "iosp.h"
|
||
|
#include "util.h"
|
||
|
#include "dse.h"
|
||
|
|
||
|
/* Include prototypes */
|
||
|
#include "t_qread.h"
|
||
|
#include "t_write.h"
|
||
|
#include "t_end.h"
|
||
|
#include "t_begin_crit.h"
|
||
|
#include "gvcst_blk_build.h"
|
||
|
#include "ebc_xlat.h"
|
||
|
#include "t_abort.h"
|
||
|
#include "stringpool.h"
|
||
|
#include "gtm_conv.h"
|
||
|
#include "gtm_utf8.h"
|
||
|
|
||
|
GBLREF char *update_array, *update_array_ptr;
|
||
|
GBLREF gd_region *gv_cur_region;
|
||
|
GBLREF uint4 update_array_size;
|
||
|
GBLREF gd_addr *gd_header;
|
||
|
GBLREF srch_hist dummy_hist;
|
||
|
GBLREF sgmnt_addrs *cs_addrs;
|
||
|
GBLREF sgmnt_data_ptr_t cs_data;
|
||
|
GBLREF block_id patch_curr_blk;
|
||
|
GBLREF gtm_chset_t dse_over_chset;
|
||
|
#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
|
||
|
GBLREF iconv_t dse_over_cvtcd;
|
||
|
#endif
|
||
|
GBLREF cw_set_element cw_set[];
|
||
|
GBLREF unsigned char *non_tp_jfb_buff_ptr;
|
||
|
GBLREF UConverter *chset_desc[];
|
||
|
LITREF mstr chset_names[];
|
||
|
GBLREF spdesc stringpool;
|
||
|
|
||
|
void dse_over(void)
|
||
|
{
|
||
|
static char *data = NULL;
|
||
|
static int data_size;
|
||
|
block_id blk;
|
||
|
uchar_ptr_t lbp;
|
||
|
uint4 offset;
|
||
|
int data_len, size;
|
||
|
blk_segment *bs1, *bs_ptr;
|
||
|
int4 blk_seg_cnt, blk_size;
|
||
|
unsigned char *cvt_src_ptr, *cvt_dst_ptr;
|
||
|
unsigned int insize, outsize;
|
||
|
char chset_name[MAX_CHSET_NAME];
|
||
|
mstr chset_mstr;
|
||
|
unsigned short name_len = 0;
|
||
|
srch_blk_status blkhist;
|
||
|
mstr cvt_src;
|
||
|
int cvt_len;
|
||
|
|
||
|
error_def(ERR_DBRDONLY);
|
||
|
error_def(ERR_DSEBLKRDFAIL);
|
||
|
error_def(ERR_DSEFAIL);
|
||
|
|
||
|
if (gv_cur_region->read_only)
|
||
|
rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
|
||
|
CHECK_AND_RESET_UPDATE_ARRAY; /* reset update_array_ptr to update_array */
|
||
|
blk_size = cs_addrs->hdr->blk_size;
|
||
|
if (cli_present("BLOCK") == CLI_PRESENT)
|
||
|
{
|
||
|
if (!cli_get_hex("BLOCK", (uint4 *)&blk))
|
||
|
return;
|
||
|
if (blk < 0 || blk >= cs_addrs->ti->total_blks)
|
||
|
{
|
||
|
util_out_print("Error: invalid block number.",TRUE);
|
||
|
return;
|
||
|
}
|
||
|
patch_curr_blk = blk;
|
||
|
} else
|
||
|
blk = patch_curr_blk;
|
||
|
if (CLI_PRESENT == cli_present("OCHSET"))
|
||
|
{
|
||
|
name_len = SIZEOF(chset_name);
|
||
|
if (cli_get_str("OCHSET", chset_name, &name_len) && 0 != name_len)
|
||
|
{
|
||
|
chset_name[name_len] = 0;
|
||
|
#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
|
||
|
if ( (iconv_t)0 != dse_over_cvtcd )
|
||
|
{
|
||
|
ICONV_CLOSE_CD(dse_over_cvtcd);
|
||
|
}
|
||
|
if (!strcmp(chset_name, INSIDE_CH_SET))
|
||
|
dse_over_cvtcd = (iconv_t)0;
|
||
|
else
|
||
|
ICONV_OPEN_CD(dse_over_cvtcd, INSIDE_CH_SET, chset_name);
|
||
|
#else
|
||
|
chset_mstr.addr = chset_name;
|
||
|
chset_mstr.len = name_len;
|
||
|
SET_ENCODING(dse_over_chset, &chset_mstr);
|
||
|
get_chset_desc(&chset_names[dse_over_chset]);
|
||
|
#endif
|
||
|
}
|
||
|
} else
|
||
|
{
|
||
|
#ifdef KEEP_zOS_EBCDIC
|
||
|
if ((iconv_t)0 != dse_over_cvtcd )
|
||
|
{
|
||
|
ICONV_CLOSE_CD(dse_over_cvtcd);
|
||
|
dse_over_cvtcd = (iconv_t)0; /* default ASCII, no conversion */
|
||
|
}
|
||
|
#else
|
||
|
dse_over_chset = CHSET_M;
|
||
|
#endif
|
||
|
}
|
||
|
if (cli_present("OFFSET") != CLI_PRESENT)
|
||
|
{
|
||
|
util_out_print("Error: offset must be specified.", TRUE);
|
||
|
return;
|
||
|
}
|
||
|
if (!cli_get_hex("OFFSET", &offset))
|
||
|
return;
|
||
|
if (offset < SIZEOF(blk_hdr))
|
||
|
{
|
||
|
util_out_print("Error: offset too small.", TRUE);
|
||
|
return;
|
||
|
}
|
||
|
if (cli_present("DATA") != CLI_PRESENT)
|
||
|
{
|
||
|
util_out_print("Error: data must be specified.", TRUE);
|
||
|
return;
|
||
|
}
|
||
|
t_begin_crit(ERR_DSEFAIL);
|
||
|
blkhist.blk_num = blk;
|
||
|
if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
|
||
|
rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
|
||
|
|
||
|
size = ((blk_hdr_ptr_t)blkhist.buffaddr)->bsiz;
|
||
|
if (size < SIZEOF(blk_hdr))
|
||
|
size = SIZEOF(blk_hdr);
|
||
|
else if (size >= blk_size)
|
||
|
size = blk_size;
|
||
|
|
||
|
if (offset >= size)
|
||
|
{
|
||
|
util_out_print("Error: offset too large.", TRUE);
|
||
|
t_abort(gv_cur_region, cs_addrs);
|
||
|
return;
|
||
|
}
|
||
|
if (NULL == data)
|
||
|
{
|
||
|
data = malloc(MAX_LINE);
|
||
|
data_size = MAX_LINE;
|
||
|
}
|
||
|
if (FALSE == dse_data(&data[0], &data_len))
|
||
|
{
|
||
|
t_abort(gv_cur_region, cs_addrs);
|
||
|
return;
|
||
|
}
|
||
|
#if defined(KEEP_zOS_EBCDIC) || defined(VMS)
|
||
|
cvt_src_ptr = cvt_dst_ptr = (unsigned char *)data;
|
||
|
insize = outsize = (unsigned int)data_len;
|
||
|
if ((iconv_t)0 != dse_over_cvtcd)
|
||
|
ICONVERT(dse_over_cvtcd, &cvt_src_ptr, &insize, &cvt_dst_ptr, &outsize); /* in-place conversion */
|
||
|
#else
|
||
|
cvt_src.len = (unsigned int)data_len;
|
||
|
cvt_src.addr = data;
|
||
|
if (CHSET_M != dse_over_chset)
|
||
|
{
|
||
|
cvt_len = gtm_conv(chset_desc[dse_over_chset], chset_desc[CHSET_UTF8], &cvt_src, NULL, NULL);
|
||
|
if (cvt_len > data_size)
|
||
|
{
|
||
|
free(data);
|
||
|
data = malloc(cvt_len);
|
||
|
data_size = cvt_len;
|
||
|
}
|
||
|
memcpy(data, stringpool.free, cvt_len);
|
||
|
data_len = cvt_len;
|
||
|
}
|
||
|
#endif
|
||
|
if (offset + data_len > size)
|
||
|
{
|
||
|
util_out_print("Error: data will not fit in block at given offset.", TRUE);
|
||
|
t_abort(gv_cur_region, cs_addrs);
|
||
|
return;
|
||
|
}
|
||
|
lbp = (uchar_ptr_t)malloc(blk_size);
|
||
|
memcpy (lbp, blkhist.buffaddr, blk_size);
|
||
|
memcpy(lbp + offset, &data[0], data_len);
|
||
|
|
||
|
BLK_INIT(bs_ptr, bs1);
|
||
|
BLK_SEG(bs_ptr, (uchar_ptr_t)lbp + SIZEOF(blk_hdr), (int)((blk_hdr_ptr_t)lbp)->bsiz - SIZEOF(blk_hdr));
|
||
|
if (!BLK_FINI(bs_ptr, bs1))
|
||
|
{
|
||
|
util_out_print("Error: bad blk build.", TRUE);
|
||
|
free(lbp);
|
||
|
t_abort(gv_cur_region, cs_addrs);
|
||
|
return;
|
||
|
}
|
||
|
t_write(&blkhist, (unsigned char *)bs1, 0, 0, ((blk_hdr_ptr_t)lbp)->levl, TRUE, FALSE, GDS_WRITE_KILLTN);
|
||
|
BUILD_AIMG_IF_JNL_ENABLED(cs_data, non_tp_jfb_buff_ptr, cs_addrs->ti->curr_tn);
|
||
|
t_end(&dummy_hist, NULL, TN_NOT_SPECIFIED);
|
||
|
return;
|
||
|
}
|