1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
/****************************************************************
* *
* Copyright (c) 2001-2020 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* 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_unistd.h"
#include <errno.h>
#include "parse_file.h"
#include "gtm_stdlib.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 "stringpool.h"
#include "gtm_string.h"
#include "iosp.h"
#include "gvcmy_open.h"
#include "gvcmy_close.h"
#include "trans_log_name.h"
#include "gvcmz.h"
#include "copy.h"
#include "error.h"
#include "op.h"
#include "gvt_inline.h"
GBLREF spdesc stringpool;
error_def(ERR_BADSRVRNETMSG);
error_def(ERR_INVNETFILNM);
error_def(ERR_LOGTOOLONG);
error_def(ERR_NETDBOPNERR);
error_def(ERR_REMOTEDBNOSPGBL);
error_def(ERR_SYSCALL);
#define GTCM_ENVVAR_PFX "GTCM_"
#define GTCM_ENVVAR_PFXLEN (SIZEOF(GTCM_ENVVAR_PFX) - 1)
void gvcmy_open(gd_region *reg, parse_blk *pb)
{
struct CLB *clb_ptr;
link_info *li;
unsigned char *ptr, *top, *fn, *libuff;
char *trans_name;
bool new = FALSE;
int len;
int4 status;
cmi_descriptor node;
mstr task1, task2;
unsigned char buff[256], lbuff[MAX_HOST_NAME_LEN + GTCM_ENVVAR_PFXLEN];
short temp_short;
MSTR_DEF(task, 0, NULL);
DCL_THREADGBL_ACCESS; /* needed by TREF usage inside SET_REGION_OPEN_TRUE macro */
SETUP_THREADGBL_ACCESS; /* needed by TREF usage inside SET_REGION_OPEN_TRUE macro */
ESTABLISH(gvcmy_open_ch);
if (reg->is_spanned)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REMOTEDBNOSPGBL, 2, REG_LEN_STR(reg));
if (!pb->b_node)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVNETFILNM);
fn = (unsigned char *)pb->l_dir;
top = fn + pb->b_esl - pb->b_node; /* total length except node gives end of string */
/*
The "task" value for unix comes from a logical of the form GTCM_<hostname>. This value
has the form of "<hostname or ip:>portnum". If the optional hostname or ip is specified
as part of the value, it will override the node value from the global directory. That
processing is handled down in the CMI layer.
*/
node.addr = pb->l_node;
node.len = pb->b_node - 1;
memcpy(lbuff, GTCM_ENVVAR_PFX, GTCM_ENVVAR_PFXLEN);
memcpy(lbuff + GTCM_ENVVAR_PFXLEN, node.addr, node.len);
task1.addr = (char *)lbuff;
task1.len = node.len + (int)GTCM_ENVVAR_PFXLEN;
lbuff[task1.len] = '\0';
task2.addr = (char *)buff;
task2.len = 0;
if (NULL != (trans_name = GETENV((const char *)lbuff)))
{
status = SS_NORMAL;
task2.len = STRLEN(trans_name);
if (SIZEOF(buff) > task2.len)
memcpy(task2.addr, trans_name, task2.len);
else
status = SS_LOG2LONG;
} else
status = SS_NOLOGNAM;
if (SS_NOLOGNAM != status)
{
if (SS_NORMAL != status)
{
if (SS_LOG2LONG == status)
rts_error_csa(CSA_ARG(NULL)
VARLSTCNT(5) ERR_LOGTOOLONG, 3, task1.len, task1.addr, SIZEOF(buff) - 1);
else
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
}
task.addr = (char *)task2.addr;
task.len = task2.len;
}
clb_ptr = cmu_getclb(&node, &task);
if (!clb_ptr) /* If link not open */
{
new = TRUE;
clb_ptr = gvcmz_netopen(clb_ptr, &node, &task);
} else
{
assert(((link_info *)clb_ptr->usr)->lnk_active);
len = (int)(top - fn + 2 + S_HDRSIZE);
if (len < CM_MINBUFSIZE)
len = CM_MINBUFSIZE;
ENSURE_STP_FREE_SPACE(len);
clb_ptr->mbf = stringpool.free;
clb_ptr->mbl = len;
}
li = (link_info *)clb_ptr->usr;
clb_ptr->cbl = top - fn + 2 + S_HDRSIZE;
*clb_ptr->mbf = CMMS_S_INITREG;
ptr = clb_ptr->mbf + 1;
temp_short = top - fn;
CM_PUT_SHORT(ptr, temp_short, li->convert_byteorder);
ptr += SIZEOF(short);
memcpy(ptr, fn, top - fn);
status = cmi_write(clb_ptr);
if (CMI_ERROR(status))
{
if (new)
gvcmy_close(clb_ptr);
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
}
status = cmi_read(clb_ptr);
if (CMI_ERROR(status))
{
if (new)
gvcmy_close(clb_ptr);
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, status);
}
if (CMMS_T_REGNUM != *clb_ptr->mbf)
{
if (CMMS_E_ERROR != *clb_ptr->mbf)
{
if (new)
gvcmy_close(clb_ptr);
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_NETDBOPNERR, 0, ERR_BADSRVRNETMSG);
}
gvcmz_errmsg(clb_ptr, new);
}
ptr = clb_ptr->mbf + 1;
reg->cmx_regnum = *ptr++;
reg->null_subs = *ptr++;
CM_GET_SHORT(reg->max_rec_size, ptr, li->convert_byteorder);
ptr += SIZEOF(short);
if (reg->max_rec_size + CM_BUFFER_OVERHEAD > li->buffer_size)
{
if (li->buffered_count)
{
assert(li->buffer);
libuff = malloc(reg->max_rec_size);
memcpy(libuff, li->buffer, li->buffer_used);
free(li->buffer);
li->buffer = libuff;
} else if (li->buffer)
{
free(li->buffer);
li->buffer = 0;
}
li->buffer_size = reg->max_rec_size + CM_BUFFER_OVERHEAD;
}
CM_GET_SHORT(reg->max_key_size, ptr, li->convert_byteorder);
ptr += SIZEOF(short);
reg->std_null_coll = (li->server_supports_std_null_coll) ? *ptr++ : 0;
/* From level 210 (GT.M V5), server will send null subscript collation info into CMMS_S_INITREG message */
reg->dyn.addr->cm_blk = clb_ptr;
REG_ACC_METH(reg) = dba_cm;
SET_REGION_OPEN_TRUE(reg, WAS_OPEN_FALSE);
clb_ptr->mbl = li->buffer_size;
if (clb_ptr->mbl < CM_MINBUFSIZE)
clb_ptr->mbl = CM_MINBUFSIZE;
REVERT;
return;
}
|