コード例 #1
0
ファイル: trigger_parse.c プロジェクト: mihawk/fis-gtm
STATICFNDEF boolean_t process_options(char *option_str, uint4 option_len, boolean_t *isolation, boolean_t *noisolation,
			       boolean_t *consistency, boolean_t *noconsistency)
{
	char		local_options[MAX_OPTIONS_LEN];
	char		*ptr, *strtokptr;

	if (MAX_OPTIONS_LEN < option_len)
	{
		util_out_print_gtmio("Too many options", FLUSH);
		return FALSE;
	}
	memcpy(local_options, option_str, option_len);
	*isolation = *noisolation = *consistency = *noconsistency = FALSE;
	ptr = local_options;
	for ( ; 0 < option_len; ptr++, option_len--)
		*ptr = TOUPPER(*ptr);
	ptr = STRTOK_R(local_options, ",", &strtokptr);
	do
	{
		switch (*ptr)
		{
			case 'C':
				if (1 == STRLEN(ptr))
					*consistency = TRUE;
				else
				{
					assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_CONSISTENCY));
					*consistency = TRUE;
				}
				break;
			case 'I':
				if (1 == STRLEN(ptr))
					*isolation = TRUE;
				else
				{
					assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_ISOLATION));
					*isolation = TRUE;
				}
				break;
			case 'N':
				assert('O' == *(ptr + 1));
				if ('C' == *(ptr + 2))
				{
					assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_NOCONSISTENCY));
					*noconsistency = TRUE;
				} else
				{
					assert('I' == *(ptr + 2));
					assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_NOISOLATION));
					*noisolation = TRUE;
				}
				break;
			default:
				assert(FALSE);	/* Parsing should have found invalid command */
				break;
		}
	} while (ptr = STRTOK_R(NULL, ",", &strtokptr));
	return !((*isolation && *noisolation) || (*consistency && *noconsistency));
}
コード例 #2
0
ファイル: source_file.c プロジェクト: h4ck3rm1k3/FIS-GT.M
void	compile_source_file(unsigned short flen, char *faddr)
{
	plength		plen;
	mval		fstr, ret;
	int		i;
	unsigned char	*p;
	error_def	(ERR_FILEPARSE);
	error_def	(ERR_FILENOTFND);
	error_def	(ERR_ERRORSUMMARY);

	if (MAX_FBUFF < flen)
	{
		dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, flen, faddr);
		dollar_zcstatus = ERR_ERRORSUMMARY;
	} else
	{
		fstr.mvtype = MV_STR;
		fstr.str.addr = faddr;
		fstr.str.len = flen;
		ESTABLISH(source_ch);
		tt_so_do_once = FALSE;
		for (i = 0 ;  ; i++)
		{
			plen.p.pint = op_fnzsearch(&fstr, 0, &ret);
			if (!ret.str.len)
			{
				if (!i)
				{
					dec_err(VARLSTCNT(4) ERR_FILENOTFND, 2, fstr.str.len, fstr.str.addr);
					dollar_zcstatus = ERR_ERRORSUMMARY;
				}
				break;
			}
			assert(ret.mvtype == MV_STR);
			assert(ret.str.len <= MAX_FBUFF);
			source_name_len = ret.str.len;
			memcpy(source_file_name, ret.str.addr, source_name_len);
			source_file_name[source_name_len] = 0;
			p = &source_file_name[plen.p.pblk.b_dir];
			if ((plen.p.pblk.b_dir >= sizeof("/dev/") - 1) && !MEMCMP_LIT(source_file_name, "/dev/"))
				tt_so_do_once = TRUE;
			else if (plen.p.pblk.b_ext != 2
				 || ('M' != p[plen.p.pblk.b_name + 1]  &&  'm' != p[plen.p.pblk.b_name + 1]))
			{
				dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, source_name_len, source_file_name);
				dollar_zcstatus = ERR_ERRORSUMMARY;
				continue;
			}

			if (compiler_startup())
				dollar_zcstatus = ERR_ERRORSUMMARY;

			if (tt_so_do_once)
				break;
		}
		REVERT;
	}
}
コード例 #3
0
ファイル: cli_parse.c プロジェクト: CeperaCPP/fis-gtm
/*---------------------------
 * Check if option is negated
 *---------------------------
 */
int cli_check_negated(char **opt_str_ptr, CLI_ENTRY *pcmd_parm_ptr, CLI_ENTRY **pparm_ptr)
{
	int 		neg_flg;
	CLI_ENTRY	*pcmd_parms;
	char		*opt_str_tmp;

	pcmd_parms = pcmd_parm_ptr;
	opt_str_tmp = *opt_str_ptr;
	if (0 == MEMCMP_LIT(*opt_str_ptr, NO_STRING))
	{
		*opt_str_ptr += SIZEOF(NO_STRING) - 1;
		neg_flg = 1;
	} else
		neg_flg = 0;
	/* --------------------------------------------
	 * search qualifier table for qualifier string
	 * --------------------------------------------
	 */
	if (0 == (*pparm_ptr = find_cmd_param(*opt_str_ptr, pcmd_parms, FALSE)))
	{
		/* Check that the qualifier does not have the NO prefix */
		if (0 == (*pparm_ptr = find_cmd_param(opt_str_tmp, pcmd_parms, FALSE)))
		{
			SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Unrecognized option : %s", *opt_str_ptr);
			cli_lex_in_ptr->tp = 0;
			return (-1);
		} else
		{
			/* It was a valid qualifier with the prefix NO */
			*opt_str_ptr = opt_str_tmp;
			neg_flg = 0;
		}
	}
	/* ----------------------------------------------------
	 * if option is negated and it is not negatable, error
	 * ----------------------------------------------------
	 */
	if (!(*pparm_ptr)->negatable && neg_flg)
	{
		SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Option %s may not be negated", *opt_str_ptr);
		return (-1);
	}
	return neg_flg;
}
コード例 #4
0
ファイル: op_gvincr.c プロジェクト: shabiel/YottaDB
void	op_gvincr(mval *increment, mval *result)
{
	unsigned char	buff[MAX_ZWR_KEY_SZ], *end;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* If specified var name is global ^%Y*, the name is illegal to use in a SET or KILL command, only GETs are allowed */
	if ((RESERVED_NAMESPACE_LEN <= gv_currkey->end) && (0 == MEMCMP_LIT(gv_currkey->base, RESERVED_NAMESPACE)))
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PCTYRESERVED);
	if (gv_cur_region->read_only)
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region));
	if ((TREF(gv_last_subsc_null) || TREF(gv_some_subsc_null)) && (ALWAYS != gv_cur_region->null_subs))
		sgnl_gvnulsubsc();
	assert(gv_currkey->end + 1 <= gv_cur_region->max_key_size);
	MV_FORCE_NUM(increment);
	switch (gv_cur_region->dyn.addr->acc_meth)
	{
		case dba_bg:
		case dba_mm:
			gvcst_incr(increment, result);
			break;
		case dba_cm:
			gvcmx_increment(increment, result);
			break;
		case dba_usr:
			/* $INCR not supported for DDP/USR access method */
			if (0 == (end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE)))
				end = &buff[MAX_ZWR_KEY_SZ - 1];
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_UNIMPLOP, 0,
				      ERR_TEXT, 2, LEN_AND_LIT("GTCM DDP server does not support $INCREMENT"),
				      ERR_GVIS, 2, end - buff, buff,
				      ERR_TEXT, 2, REG_LEN_STR(gv_cur_region));
			break;
		default:
			assertpro(FALSE);
	}
	assert(MV_DEFINED(result));
}
コード例 #5
0
ファイル: mu_signal_process.c プロジェクト: 5HT/mumps
void mu_signal_process(char *command, int signal)
{
	unsigned short	slen;
	int		len, toprocess_id, save_errno;
	char		buff[256];
	error_def(ERR_MUPCLIERR);
	error_def(ERR_MUPIPSIG);

	slen = sizeof(buff);
	if (!cli_get_str("ID", buff, &slen))
		mupip_exit(ERR_MUPCLIERR);
	len = slen;
	toprocess_id = asc2i((uchar_ptr_t)buff, len);
	if (toprocess_id < 0)
	{
		util_out_print("Error converting !AD to a number", FLUSH, len, buff);
		mupip_exit(ERR_MUPCLIERR);
	} else
	{
		if (-1 == kill(toprocess_id, signal))
		{
			save_errno = errno;
			util_out_print("Error issuing !AD to process !UL: !AZ", FLUSH,
				       LEN_AND_STR(command), toprocess_id, STRERROR(errno));
		} else
		{
			util_out_print("!AD issued to process !UL", FLUSH, LEN_AND_STR(command), toprocess_id);
			if (!MEMCMP_LIT(command, STOP_STR))
			{
				send_msg(VARLSTCNT(9) ERR_MUPIPSIG, 7, LEN_AND_STR(command), signal, process_id, process_id,
					 toprocess_id, toprocess_id);
			}
		}
	}
	return;
}
コード例 #6
0
/* Note: Need condition handler to clean-up allocated structures and close intput file in the event of an error */
struct extcall_package_list *exttab_parse(mval *package)
{
	int		parameter_alloc_values[MAX_ACTUALS], parameter_count, ret_pre_alloc_val, i, fclose_res;
	int		len, keywordlen;
	boolean_t	is_input[MAX_ACTUALS], is_output[MAX_ACTUALS], got_status;
	mstr		callnam, rtnnam, clnuprtn;
	mstr 		val, trans;
	void_ptr_t	pakhandle;
	enum gtm_types	ret_tok, parameter_types[MAX_ACTUALS], pr;
	char		str_buffer[MAX_TABLINE_LEN], *tbp, *end;
	char		str_temp_buffer[MAX_TABLINE_LEN];
	FILE		*ext_table_file_handle;
	struct extcall_package_list	*pak;
	struct extcall_entry_list	*entry_ptr;

	/* First, construct package name environment variable */
	memcpy(str_buffer, PACKAGE_ENV_PREFIX, SIZEOF(PACKAGE_ENV_PREFIX));
	tbp = &str_buffer[SIZEOF(PACKAGE_ENV_PREFIX) - 1];
	if (package->str.len)
	{
		/* guaranteed by compiler */
		assert(package->str.len < MAX_NAME_LENGTH - SIZEOF(PACKAGE_ENV_PREFIX) - 1);
		*tbp++ = '_';
		memcpy(tbp, package->str.addr, package->str.len);
		tbp += package->str.len;
	}
	*tbp = 0;
	/* Now we have the environment name, lookup file name */
	ext_table_file_name = GETENV(str_buffer);
	if (NULL == ext_table_file_name)
	{
		/* Environment variable for the package not found */
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTENV, 2, LEN_AND_STR(str_buffer));
	}
	ext_table_file_handle = Fopen(ext_table_file_name, "r");
	if (NULL == ext_table_file_handle)
	{
		/* Package's external call table could not be found */
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTOPN, 2, LEN_AND_STR(ext_table_file_name));
	}
	ext_source_line_num = 0;
	/* Pick-up name of shareable library */
	tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle);
	if (NULL == tbp)
	{
		/* External call table is a null file */
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTNULLF, 2, package->str.len, package->str.addr);
	}
	STRNCPY_STR(str_temp_buffer, str_buffer, MAX_TABLINE_LEN);
	val.addr = str_temp_buffer;
	val.len = STRLEN(str_temp_buffer);
	/* Need to copy the str_buffer into another temp variable since
	 * TRANS_LOG_NAME requires input and output buffers to be different.
	 * If there is an env variable present in the pathname, TRANS_LOG_NAME
	 * expands it and return SS_NORMAL. Else it returns SS_NOLOGNAM.
	 * Instead of checking 2 return values, better to check against SS_LOG2LONG
	 * which occurs if the pathname is too long after any kind of expansion.
 	 */
	if (SS_LOG2LONG == TRANS_LOG_NAME(&val, &trans, str_buffer, SIZEOF(str_buffer), dont_sendmsg_on_log2long))
	{
		/* Env variable expansion in the pathname caused buffer overflow */
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, val.len, val.addr, SIZEOF(str_buffer) - 1);
	}
	pakhandle = fgn_getpak(str_buffer, INFO);
	if (NULL == pakhandle)
	{
		/* Unable to obtain handle to the shared library */
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCUNAVAIL, 2, package->str.len, package->str.addr);
	}
	pak = get_memory(SIZEOF(*pak));
	pak->first_entry = 0;
	put_mstr(&package->str, &pak->package_name);
	pak->package_handle = pakhandle;
	pak->package_clnup_rtn = NULL;
	len = STRLEN("GTMSHLIBEXIT");
	/* At this point, we have a valid package, pointed to by pak */
#	ifdef DEBUG_EXTCALL
	FPRINTF(stderr, "GT.M external call opened package name: %s\n", pak->package_name.addr);
#	endif
	for (;;)
	{
		star_found = FALSE;
		tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle);
		if (NULL == tbp)
			break;
		tbp = exttab_scan_space(str_buffer);
		/* Empty line? */
		if (!*tbp)
			continue;
		/* No, must be entryref or keyword */
		end = scan_ident(tbp);
		if (!end)
			ext_stx_error(ERR_ZCENTNAME, ext_table_file_name);
		keywordlen = end - tbp;
		end = exttab_scan_space(end);
		if ('=' == *end)
		{	/* Keyword before '=' has a string of size == STRLEN("GTMSHLIBEXIT") */
			if (keywordlen == len)
			{
				if (0 == MEMCMP_LIT(tbp, "GTMSHLIBEXIT"))
				{
					/* Skip past the '=' char */
					tbp = exttab_scan_space(end + 1);
					if (*tbp)
					{	/* We have a cleanup routine name */
						clnuprtn.addr = tbp;
						clnuprtn.len = scan_ident(tbp) - tbp;
						clnuprtn.addr[clnuprtn.len] = 0;
						pak->package_clnup_rtn =
						  (clnupfptr)fgn_getrtn(pak->package_handle, &clnuprtn, ERROR);
					} else
						ext_stx_error(ERR_ZCCLNUPRTNMISNG, ext_table_file_name);
					continue;
				}
			}
			ext_stx_error(ERR_ZCINVALIDKEYWORD, ext_table_file_name);
			continue;
		}
		if ('^' == *end)
		{
			end++;
			end = scan_ident(end);
			if (!end)
				ext_stx_error(ERR_ZCENTNAME, ext_table_file_name);
		}
		rtnnam.addr = tbp;
		rtnnam.len = INTCAST(end - tbp);
		tbp = exttab_scan_space(end);
		if (':' != *tbp++)
			ext_stx_error(ERR_ZCCOLON, ext_table_file_name);
		/* Get return type */
		ret_tok = scan_keyword(&tbp);
		/* Check for legal return type */
		switch (ret_tok)
		{
			case gtm_status:
			case gtm_void:
			case gtm_int:
			case gtm_uint:
			case gtm_long:
			case gtm_ulong:
			case gtm_char_star:
			case gtm_float_star:
			case gtm_string_star:
			case gtm_int_star:
			case gtm_uint_star:
			case gtm_long_star:
			case gtm_ulong_star:
			case gtm_double_star:
			case gtm_char_starstar:
			case gtm_pointertofunc:
			case gtm_pointertofunc_star:
			case gtm_jboolean:
			case gtm_jint:
			case gtm_jlong:
			case gtm_jfloat:
			case gtm_jdouble:
			case gtm_jstring:
			case gtm_jbyte_array:
			case gtm_jbig_decimal:
				break;
			default:
				ext_stx_error(ERR_ZCRTNTYP, ext_table_file_name);
		}
		got_status = (ret_tok == gtm_status);
		/* Get call name */
		if ('[' == *tbp)
		{
			if (star_found)
				ret_pre_alloc_val = scan_array_bound(&tbp,ret_tok);
			else
				ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name);
			/* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for the
			 * extra terminating NULL. Negative values would have been caught by scan_array_bound() above.
			 */
			if (ret_pre_alloc_val > MAX_STRLEN + 1)
				ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name);
		} else
			ret_pre_alloc_val = -1;
		/* Fix C9E12-002681 */
		if ('%' == *tbp)
			*tbp = '_';
		end = scan_ident(tbp);
		if (!end)
			ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name);
		callnam.addr = tbp;
		callnam.len = INTCAST(end - tbp);
		tbp = exttab_scan_space(end);
		tbp = exttab_scan_space(tbp);
		for (parameter_count = 0;(MAX_ACTUALS > parameter_count) && (')' != *tbp); parameter_count++)
		{
			star_found = FALSE;
			/* Must have comma if this is not the first parameter, otherwise '(' */
			if (((0 == parameter_count)?'(':',') != *tbp++)
				ext_stx_error(ERR_ZCRPARMNAME, ext_table_file_name);
			tbp = exttab_scan_space(tbp);
			/* Special case: () is ok */
			if ((0 == parameter_count) && (*tbp == ')'))
				break;
			/* Looking for an I, an O or an IO */
			is_input[parameter_count] = is_output[parameter_count] = FALSE;
			if ('I' == *tbp)
			{
				is_input[parameter_count] = TRUE;
				tbp++;
			}
			if ('O' == *tbp)
			{
				is_output[parameter_count] = TRUE;
				tbp++;
			}
			if (((FALSE == is_input[parameter_count]) && (FALSE == is_output[parameter_count]))
			    ||(':' != *tbp++))
				ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name);
			/* Scanned colon--now get type */
			pr = scan_keyword(&tbp);
			if (gtm_notfound == pr)
				ext_stx_error(ERR_ZCUNTYPE, ext_table_file_name);
			if (gtm_status == pr)
			{
				/* Only one type "status" allowed per call */
				if (got_status)
					ext_stx_error(ERR_ZCMLTSTATUS, ext_table_file_name);
				else
					got_status = TRUE;
			}
			parameter_types[parameter_count] = pr;
			if ('[' == *tbp)
			{
				if (star_found && !is_input[parameter_count])
					parameter_alloc_values[parameter_count] = scan_array_bound(&tbp, pr);
				else
					ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name);
				/* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for
				 * the extra terminating NULL. Negative values would have been caught by scan_array_bound() above.
				 */
				if (parameter_alloc_values[parameter_count] > MAX_STRLEN + 1)
					ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name);
			} else
				parameter_alloc_values[parameter_count] = -1;
			tbp = exttab_scan_space(tbp);
		}
		entry_ptr = get_memory(SIZEOF(*entry_ptr));
		entry_ptr->next_entry = pak->first_entry;
		pak->first_entry = entry_ptr;
		entry_ptr->return_type = ret_tok;
		entry_ptr->ret_pre_alloc_val = ret_pre_alloc_val;
		entry_ptr->argcnt = parameter_count;
		entry_ptr->input_mask = array_to_mask(is_input, parameter_count);
		entry_ptr->output_mask = array_to_mask(is_output, parameter_count);
		entry_ptr->parms = get_memory(parameter_count * SIZEOF(entry_ptr->parms[0]));
		entry_ptr->param_pre_alloc_size = get_memory(parameter_count * SIZEOF(intszofptr_t));
		entry_ptr->parmblk_size = (SIZEOF(void *) * parameter_count) + SIZEOF(intszofptr_t);
		for (i = 0 ; i < parameter_count; i++)
		{
			entry_ptr->parms[i] = parameter_types[i];
			assert(gtm_void != parameter_types[i]);
			entry_ptr->parmblk_size += parm_space_needed[parameter_types[i]];
			entry_ptr->param_pre_alloc_size[i] = parameter_alloc_values[i];
		}
		put_mstr(&rtnnam, &entry_ptr->entry_name);
		put_mstr(&callnam, &entry_ptr->call_name);

		/* The reason for passing INFO severity is that PROFILE has several routines listed in
		 * the external call table that are not in the shared library. PROFILE folks would
		 * rather see info/warning messages for such routines at shared library open time,
		 * than error out. These unimplemented routines, they say were not being called from
		 * the application and wouldn't cause any application failures. If we fail to open
		 * the shared libary, or we fail to locate a routine that is called from the
		 * application, we issue rts_error message (in extab_parse.c).
		 */
		entry_ptr->fcn = fgn_getrtn(pak->package_handle, &entry_ptr->call_name, INFO);
#		ifdef DEBUG_EXTCALL
		FPRINTF(stderr, "   package entry point: %s, address: %x\n", entry_ptr->entry_name.addr, entry_ptr->fcn);
#		endif
	}
	FCLOSE(ext_table_file_handle, fclose_res);
	return pak;
}
コード例 #7
0
ファイル: source_file.c プロジェクト: mihawk/fis-gtm
void	compile_source_file(unsigned short flen, char *faddr, boolean_t MFtIsReqd)
{
	plength		plen;
	mval		fstr, ret;
	int		i, rc;
	unsigned char	*p;
	boolean_t	wildcarded, dm_action;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (MAX_FBUFF < flen)
	{
		dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, flen, faddr);
		TREF(dollar_zcstatus) = ERR_ERRORSUMMARY;
	} else
	{
		object_file_des = FD_INVALID;
		fstr.mvtype = MV_STR;
		fstr.str.addr = faddr;
		fstr.str.len = flen;
		ESTABLISH(source_ch);
		tt_so_do_once = FALSE;
		zsrch_clr(STRM_COMP_SRC);	/* Clear any existing search cache */
		for (i = 0; ; i++)
		{
			plen.p.pint = op_fnzsearch(&fstr, STRM_COMP_SRC, 0, &ret);
			if (!ret.str.len)
			{
				if (!i)
				{
					dec_err(VARLSTCNT(4) ERR_FILENOTFND, 2, fstr.str.len, fstr.str.addr);
					TREF(dollar_zcstatus) = ERR_ERRORSUMMARY;
				}
				break;
			}
			assert(ret.mvtype == MV_STR);
			assert(ret.str.len <= MAX_FBUFF);
			source_name_len = ret.str.len;
			memcpy(source_file_name, ret.str.addr, source_name_len);
			source_file_name[source_name_len] = 0;
			p = &source_file_name[plen.p.pblk.b_dir];
			if ((plen.p.pblk.b_dir >= SIZEOF("/dev/") - 1) && !MEMCMP_LIT(source_file_name, "/dev/"))
				tt_so_do_once = TRUE;
			else if (MFtIsReqd && (plen.p.pblk.b_ext != 2 || ('M' != p[plen.p.pblk.b_name + 1]
									  &&  'm' != p[plen.p.pblk.b_name + 1])))
			{	/* M filetype is required but not present */
				dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, source_name_len, source_file_name);
				TREF(dollar_zcstatus) = ERR_ERRORSUMMARY;
				continue;
			}
			if (compiler_startup())
				TREF(dollar_zcstatus) = ERR_ERRORSUMMARY;
			if (FD_INVALID != object_file_des)
			{
				CLOSEFILE_RESET(object_file_des, rc);	/* resets "object_file_des" to FD_INVALID */
				if (-1 == rc)
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_OBJFILERR, 2,
							object_name_len, object_file_name, errno);
			}
			if (tt_so_do_once)
				break;
		}
		REVERT;
	}
}
コード例 #8
0
ファイル: op_zedit.c プロジェクト: CeperaCPP/fis-gtm
void op_zedit(mval *v, mval *p)
{
	char		*edt;
	char		es[MAX_FBUFF + 1], typ, *ptr;
	short		path_len, tslash;
	int		objcnt;
	int		waitid;
	unsigned int	childid, status;
#ifdef _BSD
	union wait	wait_status;
#endif
	bool		has_ext, exp_dir;
	parse_blk	pblk;
	mstr		src;
	zro_ent		*sp, *srcdir;
	struct		sigaction act, intr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (!editor.len)
	{
		edt = GETENV("EDITOR");
		if (!edt)
			edt = "editor";
		rts_error(VARLSTCNT(4) ERR_FILENOTFND, 2, LEN_AND_STR(edt));
	}
	MV_FORCE_STR(v);
	MV_FORCE_STR(p);
	src.len = v->str.len;
	src.addr = v->str.addr;
	if (0 == src.len)
		rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr);
	memset(&pblk, 0, SIZEOF(pblk));
	pblk.buffer = es;
	pblk.buff_size = MAX_FBUFF;
	status = parse_file(&src, &pblk);
	if (!(status & 1))
		rts_error(VARLSTCNT(5) ERR_ZEDFILSPEC, 2, src.len, src.addr, status);
	has_ext = 0 != (pblk.fnb & F_HAS_EXT);
	exp_dir = 0 != (pblk.fnb & F_HAS_DIR);
	if (!(pblk.fnb & F_HAS_NAME))
	{
		assert(!has_ext);
		rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, pblk.b_esl, pblk.buffer);
	}
	if (!exp_dir)
	{
		memmove(&es[0], pblk.l_name, pblk.b_name + pblk.b_ext);
		path_len = pblk.b_name + pblk.b_ext;
		ptr = es;
	} else
	{
		path_len = pblk.b_esl;
		ptr = pblk.l_name;
	}
	typ = 0;
	if (!has_ext)
	{
		if ('.' != *ptr)
		{
			typ = STR_LIT_LEN(DOTM);
			if (path_len + typ > MAX_FBUFF)
				rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es);
			memcpy(&es[path_len], DOTM, STR_LIT_LEN(DOTM));
			path_len += typ;
		}
	} else
	{
		if ((STR_LIT_LEN(DOTOBJ) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTOBJ))
			rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es);
		else if ((STR_LIT_LEN(DOTM) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTM))
			typ = STR_LIT_LEN(DOTM);
	}
	dollar_zsource.str.addr = es;
	dollar_zsource.str.len = path_len - typ;
	s2pool(&dollar_zsource.str);
	es[path_len] = 0;
	if (!exp_dir)
	{
		src.addr = es;
		src.len = path_len;
		srcdir = (zro_ent *)0;
		zro_search(0, 0, &src, &srcdir, TRUE);
		if (NULL == srcdir)
		{	/* find the first source directory */
			objcnt = (TREF(zro_root))->count;
			for (sp = TREF(zro_root) + 1;  (NULL == srcdir) && (0 < objcnt--); ++sp)
			{
				if (ZRO_TYPE_OBJECT == sp->type)
				{
					sp++;
					assert(ZRO_TYPE_COUNT == sp->type);
					if (0 != sp->count)
						srcdir  = sp + 1;
				} else
				{  /* shared library entries (ZRO_TYPE_OBJLIB) do not have source directories */
					assert(ZRO_TYPE_OBJLIB == sp->type);
				}
			}
		}
		if (srcdir && srcdir->str.len)
		{
			assert(ZRO_TYPE_SOURCE == srcdir->type);
			tslash = ('/' == srcdir->str.addr[srcdir->str.len - 1]) ? 0 : 1;
			if (path_len + srcdir->str.len + tslash >= SIZEOF(es))
				rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr);
			memmove(&es[ srcdir->str.len + tslash], &es[0], path_len);
			if (tslash)
				es[ srcdir->str.len ] = '/';
			memcpy(&es[0], srcdir->str.addr, srcdir->str.len);
			path_len += srcdir->str.len + tslash;
			es[ path_len ] = 0;
		}
	}

	flush_pio();
	if (tt == io_std_device.in->type)
		resetterm(io_std_device.in);
	/* ignore interrupts */
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = SIG_IGN;
	sigaction(SIGINT, &act, &intr);
	childid = fork();	/* BYPASSOK: we exec immediately, no FORK_CLEAN needed */
	if (childid)
	{
		waitid = (int)childid;
		for (;;)
		{
#ifdef _BSD
			WAIT(&wait_status, waitid);
#else
			WAIT((int *)&status, waitid);
#endif
			if (waitid == (int)childid)
				break;
			if (-1 == waitid)
				break;
		}
		if (-1 != waitid)
			dollar_zeditor = 0;
		else
			dollar_zeditor = errno;
		/* restore interrupt handler */
		sigaction(SIGINT, &intr, 0);
		if (tt == io_std_device.in->type)
			setterm(io_std_device.in);
	} else
	{
		EXECL(editor.addr, editor.addr, es, 0);
		exit(-1);
	}
}
コード例 #9
0
ファイル: repl_inst_dump.c プロジェクト: h4ck3rm1k3/fis-gtm
void	repl_inst_dump_jnlpoolctl(jnlpool_ctl_ptr_t jnlpool_ctl)
{
	char	*string;

	util_out_print("", TRUE);
	PRINT_DASHES;
	util_out_print(JNLPOOLCTL_TITLE_STRING, TRUE);
	PRINT_DASHES;
	PRINT_OFFSET_HEADER;

	assert(0 == offsetof(jnlpool_ctl_struct, jnlpool_id));	/* The following offsetof calculations depend on this */
	PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, label[0]), SIZEOF(jnlpool_ctl->jnlpool_id.label));
	util_out_print( PREFIX_JNLPOOLCTL "Label                                      !11AD", TRUE,
		GDS_LABEL_SZ - 1, jnlpool_ctl->jnlpool_id.label);

	PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, pool_type), SIZEOF(jnlpool_ctl->jnlpool_id.pool_type));
	string = (JNLPOOL_SEGMENT == jnlpool_ctl->jnlpool_id.pool_type) ? "JNLPOOL" :
			((RECVPOOL_SEGMENT == jnlpool_ctl->jnlpool_id.pool_type) ? "RECVPOOL" : "UNKNOWN");
	if (MEMCMP_LIT(string, "UNKNOWN"))
		util_out_print( PREFIX_JNLPOOLCTL "Type                            !R22AZ", TRUE, string);
	else
	{
		util_out_print( PREFIX_JNLPOOLCTL "Type                            !R22AZ [0x!XL]", TRUE,
			string, jnlpool_ctl->jnlpool_id.pool_type);
	}

	PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, now_running[0]), SIZEOF(jnlpool_ctl->jnlpool_id.now_running));
	util_out_print( PREFIX_JNLPOOLCTL "GT.M Version            !R30AZ", TRUE, jnlpool_ctl->jnlpool_id.now_running);

	PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, instfilename[0]), SIZEOF(jnlpool_ctl->jnlpool_id.instfilename));
	if (22 >= strlen(jnlpool_ctl->jnlpool_id.instfilename))
	{
		util_out_print( PREFIX_JNLPOOLCTL "Instance file name              !R22AZ",
			TRUE, jnlpool_ctl->jnlpool_id.instfilename);
	} else
		util_out_print( PREFIX_JNLPOOLCTL "Instance file name      !AZ", TRUE, jnlpool_ctl->jnlpool_id.instfilename);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, start_jnl_seqno), SIZEOF(jnlpool_ctl->start_jnl_seqno));
	util_out_print( PREFIX_JNLPOOLCTL "Start Journal Seqno               !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->start_jnl_seqno, &jnlpool_ctl->start_jnl_seqno);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnl_seqno), SIZEOF(jnlpool_ctl->jnl_seqno));
	util_out_print( PREFIX_JNLPOOLCTL "Journal Seqno                     !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->jnl_seqno, &jnlpool_ctl->jnl_seqno);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, last_triple_seqno), SIZEOF(jnlpool_ctl->last_triple_seqno));
	util_out_print( PREFIX_JNLPOOLCTL "Last Triple Seqno                 !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->last_triple_seqno, &jnlpool_ctl->last_triple_seqno);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnldata_base_off), SIZEOF(jnlpool_ctl->jnldata_base_off));
	util_out_print( PREFIX_JNLPOOLCTL "Journal Data Base Offset                    !10UL [0x!XL]", TRUE,
		jnlpool_ctl->jnldata_base_off, jnlpool_ctl->jnldata_base_off);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnlpool_size), SIZEOF(jnlpool_ctl->jnlpool_size));
	util_out_print( PREFIX_JNLPOOLCTL "Journal Pool Size (in bytes)                !10UL [0x!XL]", TRUE,
		jnlpool_ctl->jnlpool_size, jnlpool_ctl->jnlpool_size);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, early_write_addr), SIZEOF(jnlpool_ctl->early_write_addr));
	util_out_print( PREFIX_JNLPOOLCTL "Early Write Offset                !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->early_write_addr, &jnlpool_ctl->early_write_addr);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, write_addr), SIZEOF(jnlpool_ctl->write_addr));
	util_out_print( PREFIX_JNLPOOLCTL "Absolute Write Offset             !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->write_addr, &jnlpool_ctl->write_addr);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, write), SIZEOF(jnlpool_ctl->write));
	util_out_print( PREFIX_JNLPOOLCTL "Relative Write Offset                       !10UL [0x!XL]", TRUE,
		jnlpool_ctl->write, jnlpool_ctl->write);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, upd_disabled), SIZEOF(jnlpool_ctl->upd_disabled));
	PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Updates Disabled                !R22AZ", jnlpool_ctl->upd_disabled, -1);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, primary_is_dualsite), SIZEOF(jnlpool_ctl->primary_is_dualsite));
	PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Primary is Dual Site            !R22AZ", jnlpool_ctl->primary_is_dualsite, -1);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, secondary_is_dualsite), SIZEOF(jnlpool_ctl->secondary_is_dualsite));
	PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Secondary is Dual Site          !R22AZ", jnlpool_ctl->secondary_is_dualsite, -1);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, lastwrite_len), SIZEOF(jnlpool_ctl->lastwrite_len));
	util_out_print( PREFIX_JNLPOOLCTL "Last Write Length (in bytes)                !10UL [0x!XL]", TRUE,
		jnlpool_ctl->lastwrite_len, jnlpool_ctl->lastwrite_len);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, send_losttn_complete), SIZEOF(jnlpool_ctl->send_losttn_complete));
	PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Send LostTN Complete            !R22AZ", jnlpool_ctl->send_losttn_complete, -1);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, primary_instname[0]), SIZEOF(jnlpool_ctl->primary_instname));
	util_out_print( PREFIX_JNLPOOLCTL "Primary Instance Name             !R20AZ",
		TRUE, jnlpool_ctl->primary_instname);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, max_zqgblmod_seqno), SIZEOF(jnlpool_ctl->max_zqgblmod_seqno));
	util_out_print( PREFIX_JNLPOOLCTL "Zqgblmod Seqno                    !20@UQ [0x!16@XQ]", TRUE,
		&jnlpool_ctl->max_zqgblmod_seqno, &jnlpool_ctl->max_zqgblmod_seqno);

	PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, this_proto_ver), SIZEOF(jnlpool_ctl->this_proto_ver));
	util_out_print( PREFIX_JNLPOOLCTL "Source Server Protocol Version                     !3UL [0x!2XB]", TRUE,
			jnlpool_ctl->this_proto_ver, jnlpool_ctl->this_proto_ver);
}
コード例 #10
0
socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified)
{
	socket_struct		*socketptr;
	socket_struct		*prev_socketptr;
	socket_struct		*socklist_head;
	boolean_t		passive = FALSE;
	unsigned short		port;
	int			ii, save_errno, tmplen, errlen, sockaddrlen;
	char 			temp_addr[SA_MAXLITLEN], protocolstr[6], *adptr;
	const char		*errptr;
	struct addrinfo		*ai_ptr;
	struct addrinfo		hints, *addr_info_ptr = NULL;
#ifndef VMS
	struct sockaddr_un	*sa_un_ptr, sa_un_trans;
	mval			localpath;
	mstr			transpath;
	int			trans_status;
#endif
	enum socket_protocol	protocol;
	int			af;
	int			sd;
	int			errcode;
	char			host_buffer[NI_MAXHOST];
	char			port_buffer[NI_MAXSERV];
	int			port_buffer_len;
	int			colon_cnt, protooffset;
	char			*last_2colon = NULL;
	int			addrlen;
	GTM_SOCKLEN_TYPE	tmp_addrlen;

	if (0 > file_des)
	{	/* no socket descriptor yet */
		memset(&hints, 0, SIZEOF(hints));

		protooffset = colon_cnt = 0;
		sockaddrlen = STRLEN(sockaddr);
		for (ii = sockaddrlen - 1; 0 <= ii; ii--)
		{
			if (SEPARATOR == sockaddr[ii])
			{
				colon_cnt++;
				if (1 == colon_cnt)
					protooffset = ii + 1;
				else
				{
					last_2colon = &sockaddr[ii];
					break;
				}
			}
		}
		if (0 == colon_cnt)
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
			return NULL;
		}
		tmplen = sockaddrlen - protooffset;
		if (SIZEOF(protocolstr) <= tmplen)
		{	/* last piece just too big to be valid */
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
			return NULL;
		}
		lower_to_upper((uchar_ptr_t)protocolstr, (uchar_ptr_t)&sockaddr[protooffset], tmplen);
		if (((SIZEOF("TCP") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "TCP")))
			protocol = socket_tcpip;
#		ifndef VMS
		else if (((SIZEOF("LOCAL") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "LOCAL")))
			protocol = socket_local;
#		endif
		else
		{
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]);
			return NULL;
		}
		if (socket_tcpip == protocol)
		{
			if (1 == colon_cnt)
			{	/* for listening socket or broadcasting socket */
				if (!listen_specified || (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
				{
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC);
					return NULL;
				}
				passive = TRUE;
				/* We always first try using IPv6 address, if supported */
				af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET);
				if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
				{
					/* Try creating IPv4 socket */
					af = AF_INET;
					if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP)))
					{
						save_errno = errno;
						errptr = (char *)STRERROR(save_errno);
						errlen = STRLEN(errptr);
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno,
							errlen, errptr);
						return NULL;
					}
				}
				SERVER_HINTS(hints, af);
				port_buffer_len = 0;
				I2A(port_buffer, port_buffer_len, port);
				port_buffer[port_buffer_len]='\0';
				if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr)))
				{
					close(sd);
					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
					return NULL;
				}
				SOCKET_ALLOC(socketptr);
				socketptr->local.port = port;
				socketptr->temp_sd = sd;
				socketptr->sd = FD_INVALID;
				ai_ptr = &(socketptr->local.ai);
				memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo));
				SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr);
				ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr);
				ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen;
				ai_ptr->ai_next = NULL;
				freeaddrinfo(addr_info_ptr);
			} else
			{	/* connection socket */
				assert(2 == colon_cnt);
				if (listen_specified || (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, protocolstr) < 2))
				{
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
					return NULL;
				}
				/* for connection socket */
				SPRINTF(port_buffer, "%hu", port);
				addrlen = last_2colon - sockaddr;
				if ('[' == sockaddr[0])
				{
					if (NULL == memchr(sockaddr, ']', addrlen))
					{
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC);
						return NULL;
					}
					addrlen -= 2;
					memcpy(temp_addr, &sockaddr[1], addrlen);
				} else
					memcpy(temp_addr, sockaddr, addrlen);
				temp_addr[addrlen] = 0;
				CLIENT_HINTS(hints);
				if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr)))
				{
					RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode);
					return NULL;
				}
				/*  we will test all address families in iosocket_connect() */
				SOCKET_ALLOC(socketptr);
				socketptr->remote.ai_head = addr_info_ptr;
				socketptr->remote.port = port;
				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
			}
#		ifndef VMS
		} else if (socket_local == protocol)
		{	/* should we get_full_path first */
			/* check protooffset < sizeof sun_path */
			/* protooffset is after colon */
			SOCKET_ALLOC(socketptr);
			socketptr->protocol = socket_local;
			sa_un_ptr = malloc(SIZEOF(struct sockaddr_un));
			sa_un_ptr->sun_family = AF_UNIX;
			MV_INIT_STRING(&localpath, protooffset - 1, sockaddr);
			trans_status = TRANS_LOG_NAME(&localpath.str, &transpath, sa_un_trans.sun_path,
				(int)SIZEOF(sa_un_trans.sun_path), dont_sendmsg_on_log2long);
			if (SS_LOG2LONG == trans_status)
			{	/* if LOG2LONG, returned len not valid so report untranslated length */
				SOCKET_FREE(socketptr);
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ADDRTOOLONG, 4, localpath.str.len, localpath.str.addr,
					localpath.str.len, SIZEOF(sa_un_trans.sun_path));
				return NULL;
			}
			memcpy(sa_un_ptr->sun_path, transpath.addr, transpath.len);
			sa_un_ptr->sun_path[transpath.len] = '\0';
			if (listen_specified)
			{
				passive = TRUE;
				socketptr->local.sa = (struct sockaddr *)sa_un_ptr;
				socketptr->local.ai.ai_family = AF_UNIX;
				socketptr->local.ai.ai_socktype = SOCK_STREAM;
				socketptr->local.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
				if (-1 == (sd = socket(AF_UNIX, SOCK_STREAM, 0)))
				{
					save_errno = errno;
					SOCKET_FREE(socketptr);
					errptr = (char *)STRERROR(save_errno);
					errlen = STRLEN(errptr);
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr);
					return NULL;
				}
				socketptr->temp_sd = sd;
				socketptr->sd = FD_INVALID;
			} else
			{
				socketptr->remote.sa = (struct sockaddr *)sa_un_ptr;
				/* setup remote fields */
				socketptr->remote.ai.ai_family = AF_UNIX;
				socketptr->remote.ai.ai_socktype = SOCK_STREAM;
				socketptr->remote.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset;
				socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */
			}
#		endif
		} else
コード例 #11
0
ファイル: gvn2gds.c プロジェクト: shabiel/YottaDB
/* given the bounds of a particular subscript (assumed correct), we convert the subscript into
 * a form that mimics the GDS representation of that subscript
 */
boolean_t convert_key_to_db(mval *gvn, int start, int stop, gv_key *gvkey, unsigned char **key)
{
	mval 		tmpval, *mvptr, dollarcharmval;
	int 		isrc;
	char		strbuff[MAX_KEY_SZ + 1], *str, *str_top;
	char 		fnname[MAX_LEN_FOR_CHAR_FUNC], *c;
	boolean_t	is_zchar;
	int4		num;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	if (ISDIGIT_ASCII(gvn->str.addr[start]) ||
		'-' == gvn->str.addr[start] || '+' == gvn->str.addr[start] || '.' == gvn->str.addr[start])
	{	/* convert a number */
		tmpval.str.addr = &gvn->str.addr[start];
		tmpval.str.len 	= stop - start;
		tmpval.mvtype = MV_STR;
		mvptr = &tmpval;
		MV_FORCE_NUM(mvptr);
		if (MVTYPE_IS_NUM_APPROX(tmpval.mvtype))
			return FALSE;
		mval2subsc(&tmpval, gvkey, gv_cur_region->std_null_coll);
	} else
	{	/* It's a string. We need to accept strings, $CHAR args, and $ZCHAR args. */
		str = &strbuff[0];
		str_top = &strbuff[0] + MAX_KEY_SZ + 1;
		/* MV_NUM_APPROX needed by mval2subsc to skip val_iscan call */
		tmpval.mvtype = (MV_STR | MV_NUM_APPROX);
		for (isrc = start; isrc < stop; )
		{
			if ('_' == gvn->str.addr[isrc])
			{	/* We can skip this case, since we're already "appending"
				 * the strings on the lhs to the string on the rhs. */
				isrc++;
			} else if ('$' == gvn->str.addr[isrc])
			{	/* We determine if what comes after is a Char or a ZCHar,
				 * and copy over accordingly */
				c = &fnname[0];
				isrc++; /* skip the '$' */
				while ('(' != gvn->str.addr[isrc])
					*c++ = TOUPPER(gvn->str.addr[isrc++]);
				*c = '\0';
				assert(strlen(c) <= MAX_LEN_FOR_CHAR_FUNC - 1);
				if (!MEMCMP_LIT(fnname, "ZCHAR") || !MEMCMP_LIT(fnname, "ZCH"))
					is_zchar = TRUE;
				else if (!MEMCMP_LIT(fnname, "CHAR") || !MEMCMP_LIT(fnname, "C"))
					is_zchar = FALSE;
				else
					assert(FALSE);
				/* Parse the arguments */
				isrc++; /* skip the '(' */
				while (TRUE)
				{	/* Inside the argument list for $[Z]CHAR */
					/* STRTOUL will stop at the ',' or ')' */
					num = (int4)STRTOUL(&gvn->str.addr[isrc], NULL, 10);
#					ifdef UNICODE_SUPPORTED
					if (!is_zchar && is_gtm_chset_utf8)
						op_fnchar(2, &dollarcharmval, num);
					else
#					endif
						op_fnzchar(2, &dollarcharmval, num);
					assert(MV_IS_STRING(&dollarcharmval));
					if (dollarcharmval.str.len)
					{
						if (str + dollarcharmval.str.len > str_top)
							/* String overflows capacity. */
							return FALSE;
						memcpy(str, dollarcharmval.str.addr, dollarcharmval.str.len);
						str += dollarcharmval.str.len;
					}
					/* move on to the next argument */
					while (',' != gvn->str.addr[isrc] && ')' != gvn->str.addr[isrc])
						isrc++;
					if (',' == gvn->str.addr[isrc])
						isrc++;
					else
					{
						assert(')' == gvn->str.addr[isrc]);
						isrc++; /* skip ')' */
						break;
					}
				}
			} else if ('"' == gvn->str.addr[isrc])
			{	/* Assume valid string. */
				isrc++;
				while (isrc < stop && !('"' == gvn->str.addr[isrc] && '"' != gvn->str.addr[isrc+1]))
				{
					if (str == str_top)
						/* String overflows capacity. */
						return FALSE;
					if ('"' == gvn->str.addr[isrc] && '"' == gvn->str.addr[isrc+1])
					{
						*str++ = '"';
						isrc += 2;
					} else
						*str++ = gvn->str.addr[isrc++];
				}
				isrc++; /* skip over '"' */
			} else
				assert(FALSE);
		}
		tmpval.str.addr = strbuff;
		tmpval.str.len 	= str - strbuff;
		DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = TRUE;)
		mval2subsc(&tmpval, gvkey, gv_cur_region->std_null_coll);
		DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = FALSE;)
	}
コード例 #12
0
ファイル: gtm_main.c プロジェクト: mihawk/fis-gtm
int gtm_main (int argc, char **argv, char **envp)
#ifdef __osf__
# pragma pointer_size (restore)
#endif
{
	char			*ptr, *eq, **p;
	int             	eof, parse_ret;
	int			gtmcrypt_errno;
#	ifdef GTM_SOCKET_SSL_SUPPORT
	int			status;
	char			tlsid_env_name[MAX_TLSID_LEN * 2];
#	endif
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
	gtmenvp = envp;
	gtm_dist_ok_to_use = TRUE;
	common_startup_init(GTM_IMAGE);
	GTMTRIG_DBG_ONLY(ch_at_trigger_init = &mdb_condition_handler);
	err_init(stop_image_conditional_core);
	UNICODE_ONLY(gtm_strToTitle_ptr = &gtm_strToTitle);
	GTM_ICU_INIT_IF_NEEDED;	/* Note: should be invoked after err_init (since it may error out) and before CLI parsing */
	cli_lex_setup(argc, argv);
	/* put the arguments into buffer, then clean up the token buffer
	 * cli_gettoken() copies all arguments except the first one argv[0]
	 * into the buffer (cli_lex_in_ptr->in_str).
	 * i.e. command line: "/usr/library/V990/mumps -run somefile"
	 * the buffer cli_lex_in_ptr->in_str == "-run somefile"
	 */
	if (1 < argc)
		cli_gettoken(&eof);
	/* cli_gettoken() extracts the first token into cli_token_buf (in tok_extract())
	 * which should be done in parse_cmd(), So, reset the token buffer here to make
	 * parse_cmd() starts from the first token
	*/
	cli_token_buf[0] = '\0';
	/* insert the "MUMPS " in the parsing buffer the buffer is now:
	 * cli_lex_in_ptr->in_str == "MUMPS -run somefile"
	 * we didnot change argv[0]
	*/
	ptr = cli_lex_in_ptr->in_str;
	memmove(strlen("MUMPS ") + ptr, ptr, strlen(ptr) + 1);	/* BYPASSOK */
	MEMCPY_LIT(ptr, "MUMPS ");
	/* reset the argument buffer pointer, it's changed in cli_gettoken() call above
	 * do NOT reset to 0(NULL) to avoid fetching cmd line args into buffer again
	 * cli_lex_in_ptr->tp is the pointer to indicate current position in the buffer
	 * cli_lex_in_ptr->in_str
	 */
	cli_lex_in_ptr->tp = cli_lex_in_ptr->in_str;
	parse_ret = parse_cmd();
	if (parse_ret && (EOF != parse_ret))
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));
	if (cli_present("DIRECT_MODE"))
		invocation_mode = MUMPS_DIRECT;
	else if (cli_present("RUN"))
		invocation_mode = MUMPS_RUN;
	gtm_chk_dist(argv[0]);
	/* this should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup   */
	init_gtm();
#	ifdef GTM_TLS
	if (MUMPS_COMPILE != invocation_mode)
	{
		if ((NULL != (ptr = (char *)getenv(GTM_PASSWD_ENV))) && (0 == strlen(ptr)))
		{
			INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno);
			if (0 != gtmcrypt_errno)
			{
				CLEAR_CRYPTERR_MASK(gtmcrypt_errno);
				assert(!IS_REPEAT_MSG_MASK(gtmcrypt_errno));
				assert((ERR_CRYPTDLNOOPEN == gtmcrypt_errno) || (ERR_CRYPTINIT == gtmcrypt_errno));
				if (ERR_CRYPTDLNOOPEN == gtmcrypt_errno)
					gtmcrypt_errno = ERR_CRYPTDLNOOPEN2;
				else if (ERR_CRYPTINIT == gtmcrypt_errno)
					gtmcrypt_errno = ERR_CRYPTINIT2;
				gtmcrypt_errno = SET_CRYPTERR_MASK(gtmcrypt_errno);
				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, SIZEOF(GTMCRYPT_ERRLIT) - 1, GTMCRYPT_ERRLIT); /* BYPASSOK */
			}
		}
#		ifdef GTM_SOCKET_SSL_SUPPORT
		/* The below logic is for prefetching the password for TLS identifiers that may have been set in the environment.
		 * But, since SSL support for Socket devices is not yet implemented, this logic need not be enabled as of this
		 * writing. When SSL support for socket devices is implemented, the surrounding #ifdef can be removed.
		 */
		if (NULL != getenv("gtmcrypt_config"))
		{	/* Environment is configured for SSL/TLS (and/or encryption). Check if any environment variable of the form
			 * `gtmtls_passwd_*' is set to NULL string. If so, nudge the SSL/TLS library to read password(s) from the
			 * user.
			 */
			for (p = envp; *p; p++)
			{
				ptr = *p;
				if (0 == MEMCMP_LIT(ptr, GTMTLS_PASSWD_ENV_PREFIX))
				{	/* At least one environment variable of $gtmtls_passwd_* is found. */
					eq = strchr(ptr, '=');
					if (0 != strlen(eq + 1))
						break; /* Set to non-empty string. No need to initialize the library now. */
					/* Set to empty string. */
					if (NULL == tls_ctx)
					{
						if (SS_NORMAL != (status = gtm_tls_loadlibrary()))
						{
							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0,
									ERR_TEXT, 2, LEN_AND_STR(dl_err));
						}
						if (NULL == (tls_ctx = gtm_tls_init(GTM_TLS_API_VERSION,
											GTMTLS_OP_INTERACTIVE_MODE)))
						{
							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0,
									ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
						}
					}
					assert(NULL != tls_ctx);
					assert((MAX_TLSID_LEN * 2) > (int)(eq - ptr));
					memcpy(tlsid_env_name, ptr, (int)(eq - ptr));
					tlsid_env_name[(int)(eq - ptr)] = '\0';
					gtm_tls_prefetch_passwd(tls_ctx, tlsid_env_name);
				}
			}
		}
#		endif
	}
#	endif
	dm_start();
	return 0;
}
コード例 #13
0
ファイル: gdsfilext.c プロジェクト: shabiel/fis-gtm
uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
{
	sm_uc_ptr_t		old_base[2], mmap_retaddr;
	boolean_t		was_crit, is_mm;
	char			buff[DISK_BLOCK_SIZE];
	int			result, save_errno, status;
	uint4			new_bit_maps, bplmap, map, new_blocks, new_total, max_tot_blks, old_total;
	uint4			jnl_status;
	gtm_uint64_t		avail_blocks, mmap_sz;
	off_t			new_eof;
	trans_num		curr_tn;
	unix_db_info		*udi;
	inctn_opcode_t		save_inctn_opcode;
	int4			prev_extend_blks_to_upgrd;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;
	cache_rec_ptr_t         cr;
	DCL_THREADGBL_ACCESS;

	assert(!IS_DSE_IMAGE);
	assert((cs_addrs->nl == NULL) || (process_id != cs_addrs->nl->trunc_pid)); /* mu_truncate shouldn't extend file... */
	assert(!process_exiting);
	DEBUG_ONLY(old_base[0] = old_base[1] = NULL);
	assert(!gv_cur_region->read_only);
	udi = FILE_INFO(gv_cur_region);
	is_mm = (dba_mm == cs_addrs->hdr->acc_meth);
#	if !defined(MM_FILE_EXT_OK)
	if (!udi->grabbed_access_sem && is_mm)
		return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not allowed ? */
#	endif
	/* Both blocks and total blocks are unsigned ints so make sure we aren't asking for huge numbers that will
	   overflow and end up doing silly things.
	*/
	assert((blocks <= (MAXTOTALBLKS(cs_data) - cs_data->trans_hist.total_blks)) || WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR));
#	if defined(__sun) || defined(__hpux)
	cs_data->defer_allocate = TRUE;
#	endif
	if (!blocks && (cs_data->defer_allocate || (TRANS_IN_PROG_TRUE == trans_in_prog)))
		return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not enabled ? */
	bplmap = cs_data->bplmap;
	/* New total of non-bitmap blocks will be number of current, non-bitmap blocks, plus new blocks desired
	 * There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
	 *      and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
	 *      manner as every non-bitmap block must have an associated bitmap)
	 * Current number of bitmaps is (total number of current blocks + bplmap - 1) / bplmap.
	 * Subtract current number of bitmaps from number needed for expanded database to get number of new bitmaps needed.
	 */
	new_bit_maps = DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks
			- DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap) + blocks, bplmap - 1)
			- DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap);
	new_blocks = blocks + new_bit_maps;
	assert((0 < (int)new_blocks) || (!cs_data->defer_allocate && (0 == new_blocks)));
	if (new_blocks + cs_data->trans_hist.total_blks > MAXTOTALBLKS(cs_data))
	{
		assert(WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR));
		send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_TOTALBLKMAX);
		return (uint4)(NO_FREE_SPACE);
	}
	if (0 != (save_errno = disk_block_available(udi->fd, &avail_blocks, FALSE)))
	{
		send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno);
		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno);
	} else
	{
		if (!(gtmDebugLevel & GDL_IgnoreAvailSpace))
		{	/* Bypass this space check if debug flag above is on. Allows us to create a large sparce DB
			 * in space it could never fit it if wasn't sparse. Needed for some tests.
			 */
			avail_blocks = avail_blocks / (cs_data->blk_size / DISK_BLOCK_SIZE);
			if ((blocks * EXTEND_WARNING_FACTOR) > avail_blocks)
			{
				if (blocks > (uint4)avail_blocks)
				{
					SETUP_THREADGBL_ACCESS;
					if (!INST_FREEZE_ON_NOSPC_ENABLED(cs_addrs))
						return (uint4)(NO_FREE_SPACE);
					else
						send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_NOSPACEEXT), 4,
							DB_LEN_STR(gv_cur_region), new_blocks, (uint4)avail_blocks);
				} else
					send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, DB_LEN_STR(gv_cur_region),
						 (uint4)(avail_blocks - ((new_blocks <= avail_blocks) ? new_blocks : 0)));
			}
		}
	}
#	ifdef DEBUG
	if (WBTEST_ENABLED(WBTEST_MM_CONCURRENT_FILE_EXTEND) && dollar_tlevel && !MEMCMP_LIT(gv_cur_region->rname, "DEFAULT"))
	{
		SYSTEM("$gtm_dist/mumps -run $gtm_wbox_mrtn");
		assert(1 == cs_addrs->nl->wbox_test_seq_num);	/* should have been set by mubfilcpy */
		cs_addrs->nl->wbox_test_seq_num = 2;	/* signal mupip backup to stop sleeping in mubfilcpy */
	}
#	endif
	/* From here on, we need to use GDSFILEXT_CLNUP before returning to the caller */
	was_crit = cs_addrs->now_crit;
	assert(!cs_addrs->hold_onto_crit || was_crit);
	/* If we are coming from mupip_extend (which gets crit itself) we better have waited for any unfreezes to occur.
	 * If we are coming from online rollback (when that feature is available), we will come in holding crit and in
	 * 	the final retry. In that case too, we expect to have waited for unfreezes to occur in the caller itself.
	 * Therefore if we are coming in holding crit from MUPIP, we expect the db to be unfrozen so no need to wait for
	 * freeze.
	 * If we are coming from GT.M and final retry (in which case we come in holding crit) we expect to have waited
	 * 	for any unfreezes (by invoking tp_crit_all_regions) to occur (TP or non-TP) before coming into this
	 *	function. However, there is one exception. In the final retry, if tp_crit_all_regions notices that
	 *	at least one of the participating regions did ONLY READs, it will not wait for any freeze on THAT region
	 *	to complete before grabbing crit. Later, in the final retry, if THAT region did an update which caused
	 *	op_tcommit to invoke bm_getfree->gdsfilext, then we would have come here with a frozen region on which
	 *	we hold crit.
	 */
	assert(!was_crit || !cs_data->freeze || (dollar_tlevel && (CDB_STAGNATE <= t_tries)));
	/*
	 * If we are in the final retry and already hold crit, it is possible that csa->nl->wc_blocked is also set to TRUE
	 * (by a concurrent process in phase2 which encountered an error in the midst of commit and secshr_db_clnup
	 * finished the job for it). In this case we do NOT want to invoke wcs_recover as that will update the "bt"
	 * transaction numbers without correspondingly updating the history transaction numbers (effectively causing
	 * a cdb_sc_blkmod type of restart). Therefore do NOT call grab_crit (which unconditionally invokes wcs_recover)
	 * if we already hold crit.
	 */
	if (!was_crit)
	{
		for ( ; ; )
		{
			grab_crit(gv_cur_region);
			if (!cs_data->freeze && !IS_REPL_INST_FROZEN)
				break;
			rel_crit(gv_cur_region);
			while (cs_data->freeze || IS_REPL_INST_FROZEN)
				hiber_start(1000);
		}
	} else if (cs_data->freeze && dollar_tlevel)
	{	/* We don't want to continue with file extension as explained above. Hence return with an error code which
		 * op_tcommit will recognize (as a cdb_sc_needcrit/cdb_sc_instancefreeze type of restart) and restart accordingly.
		 */
		assert(CDB_STAGNATE <= t_tries);
		GDSFILEXT_CLNUP;
		return (uint4)FINAL_RETRY_FREEZE_PROG;
	}
	if (IS_REPL_INST_FROZEN && trans_in_prog)
	{
		assert(CDB_STAGNATE <= t_tries);
		GDSFILEXT_CLNUP;
		return (uint4)FINAL_RETRY_INST_FREEZE;
	}
	assert(cs_addrs->ti->total_blks == cs_data->trans_hist.total_blks);
	old_total = cs_data->trans_hist.total_blks;
	if (old_total != filesize)
	{	/* Somebody else has already extended it, since we are in crit, this is trust-worthy. However, in case of MM,
		 * we still need to remap the database
		 */
		assert((old_total > filesize) GTM_TRUNCATE_ONLY( || !is_mm));
		/* For BG, someone else could have truncated or extended - we have no idea */
		GDSFILEXT_CLNUP;
		return (SS_NORMAL);
	}
コード例 #14
0
ファイル: repl_inst_dump.c プロジェクト: h4ck3rm1k3/fis-gtm
void	repl_inst_dump_gtmsourcelocal(gtmsource_local_ptr_t gtmsourcelocal_ptr)
{
	int		idx;
	char		*string;
	boolean_t	first_time = TRUE;

	for (idx = 0; idx < NUM_GTMSRC_LCL; idx++, gtmsourcelocal_ptr++)
	{
		if (('\0' == gtmsourcelocal_ptr->secondary_instname[0])
				&& (0 == gtmsourcelocal_ptr->read_jnl_seqno)
				&& (0 == gtmsourcelocal_ptr->connect_jnl_seqno))
			continue;
		if (first_time)
		{
			util_out_print("", TRUE);
			first_time = FALSE;
			PRINT_DASHES;
			util_out_print(SOURCELOCAL_TITLE_STRING, TRUE);
			PRINT_DASHES;
		} else
			PRINT_DASHES;
		PRINT_OFFSET_HEADER;

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_instname[0]),
			SIZEOF(gtmsourcelocal_ptr->secondary_instname));
		util_out_print( PREFIX_SOURCELOCAL "Secondary Instance Name         !R16AZ", TRUE, idx,
			(char *)gtmsourcelocal_ptr->secondary_instname);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsource_pid), SIZEOF(gtmsourcelocal_ptr->gtmsource_pid));
		util_out_print( PREFIX_SOURCELOCAL "Source Server Pid                     !10UL", TRUE, idx,
			gtmsourcelocal_ptr->gtmsource_pid);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, mode), SIZEOF(gtmsourcelocal_ptr->mode));
		string = (GTMSOURCE_MODE_PASSIVE == gtmsourcelocal_ptr->mode) ? "PASSIVE" :
				((GTMSOURCE_MODE_ACTIVE == gtmsourcelocal_ptr->mode) ? "ACTIVE" : "UNKNOWN");
		if (MEMCMP_LIT(string, "UNKNOWN"))
			util_out_print( PREFIX_SOURCELOCAL "Source Server Mode        !R22AZ", TRUE, idx, string);
		else
		{
			util_out_print( PREFIX_SOURCELOCAL "Source Server Mode        !R22AZ [0x!XL]", TRUE, idx,
				string, gtmsourcelocal_ptr->mode);
		}

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsource_state), SIZEOF(gtmsourcelocal_ptr->gtmsource_state));
		string = ((0 <= gtmsourcelocal_ptr->gtmsource_state)
				&& (GTMSOURCE_NUM_STATES > gtmsourcelocal_ptr->gtmsource_state))
					? (char *)state_array[gtmsourcelocal_ptr->gtmsource_state] : "UNKNOWN";
		if (MEMCMP_LIT(string, "UNKNOWN"))
			util_out_print( PREFIX_SOURCELOCAL "Processing State          !R22AZ", TRUE, idx, string);
		else
		{
			util_out_print( PREFIX_SOURCELOCAL "Processing State          !R22AZ [0x!XL]", TRUE, idx,
				string, gtmsourcelocal_ptr->gtmsource_state);
		}

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsrc_lcl_array_index),
			SIZEOF(gtmsourcelocal_ptr->gtmsrc_lcl_array_index));
		util_out_print( PREFIX_SOURCELOCAL "Slot Index                       !15UL", TRUE, idx,
			gtmsourcelocal_ptr->gtmsrc_lcl_array_index);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, repl_zlib_cmp_level),
			SIZEOF(gtmsourcelocal_ptr->repl_zlib_cmp_level));
		util_out_print( PREFIX_SOURCELOCAL "Journal record Compression Level !15UL", TRUE, idx,
			gtmsourcelocal_ptr->repl_zlib_cmp_level);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, remote_proto_ver),
			SIZEOF(gtmsourcelocal_ptr->remote_proto_ver));
		util_out_print( PREFIX_SOURCELOCAL "Receiver Server Protocol Version             !3UL [0x!2XB]", TRUE, idx,
			gtmsourcelocal_ptr->remote_proto_ver, gtmsourcelocal_ptr->remote_proto_ver);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_state), SIZEOF(gtmsourcelocal_ptr->read_state));
		string = (READ_POOL == gtmsourcelocal_ptr->read_state) ? "POOL" :
				((READ_FILE == gtmsourcelocal_ptr->read_state) ? "FILE" : "UNKNOWN");
		if (MEMCMP_LIT(string, "UNKNOWN"))
			util_out_print( PREFIX_SOURCELOCAL "Currently Reading from     !R21AZ", TRUE, idx, string);
		else
		{
			util_out_print( PREFIX_SOURCELOCAL "Currently Reading from     !R21AZ [0x!XL]", TRUE, idx,
				string, gtmsourcelocal_ptr->read_state);
		}

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read), SIZEOF(gtmsourcelocal_ptr->read));
		util_out_print( PREFIX_SOURCELOCAL "Relative Read Offset                  !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->read, gtmsourcelocal_ptr->read);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_addr), SIZEOF(gtmsourcelocal_ptr->read_addr));
		util_out_print( PREFIX_SOURCELOCAL "Absolute Read Offset        !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsourcelocal_ptr->read_addr, &gtmsourcelocal_ptr->read_addr);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_jnl_seqno), SIZEOF(gtmsourcelocal_ptr->read_jnl_seqno));
		util_out_print( PREFIX_SOURCELOCAL "Resync Sequence Number      !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsourcelocal_ptr->read_jnl_seqno, &gtmsourcelocal_ptr->read_jnl_seqno);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_jnl_seqno),
			SIZEOF(gtmsourcelocal_ptr->connect_jnl_seqno));
		util_out_print( PREFIX_SOURCELOCAL "Connect Sequence Number     !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsourcelocal_ptr->connect_jnl_seqno, &gtmsourcelocal_ptr->connect_jnl_seqno);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, num_triples), SIZEOF(gtmsourcelocal_ptr->num_triples));
		util_out_print( PREFIX_SOURCELOCAL "Number of Triples                     !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->num_triples, gtmsourcelocal_ptr->num_triples);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, next_triple_num), SIZEOF(gtmsourcelocal_ptr->next_triple_num));
		util_out_print( PREFIX_SOURCELOCAL "Next Triple Number                    !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->next_triple_num, gtmsourcelocal_ptr->next_triple_num);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, next_triple_seqno),
			SIZEOF(gtmsourcelocal_ptr->next_triple_seqno));
		util_out_print( PREFIX_SOURCELOCAL "Next Triple Seqno           !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsourcelocal_ptr->next_triple_seqno, &gtmsourcelocal_ptr->next_triple_seqno);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, last_flush_resync_seqno),
			SIZEOF(gtmsourcelocal_ptr->last_flush_resync_seqno));
		util_out_print( PREFIX_SOURCELOCAL "Last Flush Resync Seqno     !20@UQ [0x!16@XQ]", TRUE, idx,
			&gtmsourcelocal_ptr->last_flush_resync_seqno, &gtmsourcelocal_ptr->last_flush_resync_seqno);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, send_new_triple), SIZEOF(gtmsourcelocal_ptr->send_new_triple));
		PRINT_BOOLEAN( PREFIX_SOURCELOCAL "Send New Triple                         !R8AZ",
			gtmsourcelocal_ptr->send_new_triple, idx);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, send_losttn_complete),
			SIZEOF(gtmsourcelocal_ptr->send_losttn_complete));
		PRINT_BOOLEAN( PREFIX_SOURCELOCAL "Send LostTN Complete                    !R8AZ",
			gtmsourcelocal_ptr->send_losttn_complete, idx);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_host[0]),
			SIZEOF(gtmsourcelocal_ptr->secondary_host));
		if (20 >= strlen(gtmsourcelocal_ptr->secondary_host))
		{
			util_out_print( PREFIX_SOURCELOCAL "Secondary HOSTNAME          !R20AZ",
				TRUE, idx, gtmsourcelocal_ptr->secondary_host);
		} else
		{
			util_out_print( PREFIX_SOURCELOCAL "Secondary HOSTNAME          !AZ",
				TRUE, idx, gtmsourcelocal_ptr->secondary_host);
		}

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_inet_addr),
			SIZEOF(gtmsourcelocal_ptr->secondary_inet_addr));
		util_out_print( PREFIX_SOURCELOCAL "Secondary INET Address                !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->secondary_inet_addr, gtmsourcelocal_ptr->secondary_inet_addr);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_port), SIZEOF(gtmsourcelocal_ptr->secondary_port));
		util_out_print( PREFIX_SOURCELOCAL "Secondary Port                        !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->secondary_port, gtmsourcelocal_ptr->secondary_port);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, log_interval), SIZEOF(gtmsourcelocal_ptr->log_interval));
		util_out_print( PREFIX_SOURCELOCAL "Log Interval                          !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->log_interval, gtmsourcelocal_ptr->log_interval);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, log_file[0]), SIZEOF(gtmsourcelocal_ptr->log_file));
		if (20 >= strlen(gtmsourcelocal_ptr->log_file))
			util_out_print( PREFIX_SOURCELOCAL "Log File                    !R20AZ",
				TRUE, idx, gtmsourcelocal_ptr->log_file);
		else
			util_out_print( PREFIX_SOURCELOCAL "Log File                    !AZ",
				TRUE, idx, gtmsourcelocal_ptr->log_file);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, changelog), SIZEOF(gtmsourcelocal_ptr->changelog));
		util_out_print( PREFIX_SOURCELOCAL "Changelog                             !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->changelog, gtmsourcelocal_ptr->changelog);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, statslog), SIZEOF(gtmsourcelocal_ptr->statslog));
		util_out_print( PREFIX_SOURCELOCAL "Statslog                              !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->statslog, gtmsourcelocal_ptr->statslog);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, statslog_file[0]), SIZEOF(gtmsourcelocal_ptr->statslog_file));
		if (20 >= strlen(gtmsourcelocal_ptr->log_file))
		{
			util_out_print( PREFIX_SOURCELOCAL "Statslog File               !R20AZ",
				TRUE, idx, gtmsourcelocal_ptr->statslog_file);
		} else
		{
			util_out_print( PREFIX_SOURCELOCAL "Statslog File               !AZ",
				TRUE, idx, gtmsourcelocal_ptr->statslog_file);
		}

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Hard Tries Count        !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Hard Tries Period       !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Soft Tries Period       !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Alert Period            !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Heartbeat Period        !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT]),
			SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT]));
		util_out_print( PREFIX_SOURCELOCAL "Connect Parms Heartbeat Max Wait      !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT],
			gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT]);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, shutdown), SIZEOF(gtmsourcelocal_ptr->shutdown));
		util_out_print( PREFIX_SOURCELOCAL "Shutdown State                        !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->shutdown, gtmsourcelocal_ptr->shutdown);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, shutdown_time), SIZEOF(gtmsourcelocal_ptr->shutdown_time));
		util_out_print( PREFIX_SOURCELOCAL "Shutdown Time in seconds              !10UL [0x!XL]", TRUE, idx,
			gtmsourcelocal_ptr->shutdown_time, gtmsourcelocal_ptr->shutdown_time);

		PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, filter_cmd[0]), SIZEOF(gtmsourcelocal_ptr->filter_cmd));
		if (20 >= strlen(gtmsourcelocal_ptr->filter_cmd))
		{
			util_out_print( PREFIX_SOURCELOCAL "Filter Command              !R20AZ",
				TRUE, idx, gtmsourcelocal_ptr->filter_cmd);
		} else
		{
			util_out_print( PREFIX_SOURCELOCAL "Filter Command              !AZ",
				TRUE, idx, gtmsourcelocal_ptr->filter_cmd);
		}
		PRINT_DASHES;
	}
}
コード例 #15
0
ファイル: go_load.c プロジェクト: duck57/fis-gtm-freebsd
void go_load(uint4 begin, uint4 end)
{
	char		*ptr;
	int		len, fmt, keylength, keystate;
	uint4	        iter, max_data_len, max_subsc_len, key_count, max_rec_size;
	mstr            src, des;
	unsigned char   *rec_buff, ch;
	boolean_t	utf8_extract, format_error = FALSE, hasht_ignored = FALSE, hasht_gbl = FALSE;
	char		*val_off;
	int 		val_len, val_off1, val_len1;
	boolean_t	is_setextract;

	gvinit();

	max_rec_size = DEFAULT_MAX_REC_SIZE;
	rec_buff = (unsigned char *)malloc(max_rec_size);

	fmt = MU_FMT_ZWR;	/* by default, the extract format is ZWR (not GO) */
	len = file_input_get(&ptr);
	if (mupip_error_occurred)
	{
		free(rec_buff);
		return;
	}
	if (len >= 0)
	{
		util_out_print("!AD", TRUE, len, ptr);
		utf8_extract = ((len >= STR_LIT_LEN(UTF8_NAME)) &&
				(0 == MEMCMP_LIT(ptr + len - STR_LIT_LEN("UTF-8"), "UTF-8"))) ? TRUE : FALSE;
		if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
		{ /* extract CHSET doesn't match $ZCHSET */
			if (utf8_extract)
				gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
			else
				gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
			mupip_error_occurred = TRUE;
			free(rec_buff);
			return;
		}
	} else
		mupip_exit(ERR_LOADFILERR);
	len = file_input_get(&ptr);
	if (mupip_error_occurred)
	{
		free(rec_buff);
		return;
	}
	if (len >= 0)
	{
		util_out_print("!AD", TRUE, len, ptr);
		fmt = (0 == memcmp(ptr + len - STR_LIT_LEN("ZWR"), "ZWR", STR_LIT_LEN("ZWR"))) ? MU_FMT_ZWR : MU_FMT_GO;
	} else
		mupip_exit(ERR_LOADFILERR);
	if (begin < 3)
		begin = 3;
	for (iter = 3; iter < begin; iter++)
	{
		len = file_input_get(&ptr);
		if (len < 0)	/* The IO device has signalled an end of file */
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			mupip_error_occurred = TRUE;
		}
		if (mupip_error_occurred)
		{
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			free(rec_buff);
			return;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	key_count = 0;
	for (iter = begin - 1; ; )
	{
		if (++iter > end)
			break;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? iter : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		if (0 > (len = file_input_get(&ptr)))
			break;
		if (mupip_error_occurred)
		{
		        mu_gvis();
			break;
		}
		if ('\n' == *ptr)
		{
			if ('\n' == *(ptr+1))
				break;
			ptr++;
		}
		if (0 == len)
			continue;
		if (MU_FMT_GO != fmt)
		{
			/* Determine if the ZWR has $extract format */
			if ('$' == *ptr)
			{
				keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, &val_off1, &val_len1);
				ptr = ptr + 4; /* Skip first 4 character '$','z','e','(' */
				is_setextract = TRUE;
			} else
			{
				/* Determine the ZWR key length. -1 (SIZEOF(=)) is needed since ZWR allows '^x(1,2)='*/
				keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, NULL, NULL);
				is_setextract = FALSE;
			}
			ISSUE_TRIGDATAIGNORE_IF_NEEDED(keylength, ptr, hasht_gbl);
			if (hasht_gbl)
			{
				hasht_gbl = FALSE;
				continue;
			}
			go_call_db(GO_PUT_SUB, ptr, keylength, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			assert(keylength < len - 1);
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			src.len = val_len;
			src.addr = val_off;
			des.len = 0;
			if (src.len > max_rec_size)
			{
			        max_rec_size = src.len;
				free(rec_buff);
				rec_buff = (unsigned char *)malloc(max_rec_size);
			}
			des.addr = (char *)rec_buff;
			if (FALSE == zwr2format(&src, &des))
			{
				util_out_print("Format error in record number !8UL: !/!AD", TRUE, iter, src.len, src.addr);
				format_error = TRUE;
				continue;
			}
			if (max_data_len < des.len)
			        max_data_len = des.len;
			(is_setextract) ? go_call_db(GO_SET_EXTRACT, des.addr, des.len, val_off1, val_len1)
					: go_call_db(GO_PUT_DATA, (char *)rec_buff, des.len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			key_count++;
		} else
		{
			ISSUE_TRIGDATAIGNORE_IF_NEEDED(len, ptr, hasht_gbl);
			if (hasht_gbl)
			{
				if (0 > (len = file_input_get(&ptr)))
					break;
				iter++;
				hasht_gbl = FALSE;
				continue;
			}
		        go_call_db(GO_PUT_SUB, ptr, len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			if (++iter > end)
			{
			        iter--;	/* Decrement as didn't load key */
				break;
			}
			if ((len = file_input_get(&ptr)) < 0)
			        break;
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				break;
			}
			stringpool.free = stringpool.base;
			if (max_data_len < len)
			        max_data_len = len;
			go_call_db(GO_PUT_DATA, ptr, len, 0, 0);
			if (mupip_error_occurred)
			{
			        mu_gvis();
				util_out_print("Error loading record number: !UL\n", TRUE, iter);
				mupip_error_occurred = FALSE;
				continue;
			}
			key_count++;
		}
	}
	free(rec_buff);
	file_input_close();
	if (mu_ctrly_occurred)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_LOADCTRLY);
		mupip_exit(ERR_MUNOFINISH);
	}
	util_out_print("LOAD TOTAL!_!_Key Cnt: !UL  Max Subsc Len: !UL  Max Data Len: !UL",TRUE,key_count,max_subsc_len,
			max_data_len);
	util_out_print("Last LOAD record number: !UL\n", TRUE, key_count ? (iter - 1) : 0);
	if (format_error)
		mupip_exit(ERR_LOADFILERR);
}
コード例 #16
0
ファイル: bin_load.c プロジェクト: duck57/fis-gtm-freebsd
void bin_load(uint4 begin, uint4 end)
{
	unsigned char	*ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop, *ptr_base;
	unsigned char	hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ],
			cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1], sn_key_str[MAX_KEY_SZ + 1], *sn_key_str_end;
	unsigned char	*end_buff;
	unsigned short	rec_len, next_cmpc, numsubs;
	int		len;
	int		current, last, length, max_blk_siz, max_key, status;
	int		tmp_cmpc, sn_chunk_number, expected_sn_chunk_number = 0, sn_hold_buff_pos, sn_hold_buff_size;
	uint4		iter, max_data_len, max_subsc_len, key_count, gblsize;
	ssize_t		rec_count, global_key_count, subsc_len,extr_std_null_coll, last_sn_error_offset=0,
				file_offset_base=0, file_offset=0;
	boolean_t	need_xlation, new_gvn, utf8_extract;
	boolean_t	is_hidden_subscript, ok_to_put = TRUE, putting_a_sn = FALSE, sn_incmp_gbl_already_killed = FALSE;
	rec_hdr		*rp, *next_rp;
	mval		v, tmp_mval;
	mstr		mstr_src, mstr_dest;
	collseq		*extr_collseq, *db_collseq, *save_gv_target_collseq;
	coll_hdr	extr_collhdr, db_collhdr;
	gv_key 		*tmp_gvkey = NULL;	/* null-initialize at start, will be malloced later */
	gv_key		*sn_gvkey = NULL; /* null-initialize at start, will be malloced later */
	gv_key		*sn_savekey = NULL; /* null-initialize at start, will be malloced later */
	char		std_null_coll[BIN_HEADER_NUMSZ + 1], *sn_hold_buff = NULL, *sn_hold_buff_temp = NULL;
#	ifdef GTM_CRYPT
	gtmcrypt_key_t			*encr_key_handles;
	char				*inbuf;
	int4				index;
	int				req_dec_blk_size, init_status, crypt_status;
	muext_hash_hdr_ptr_t		hash_array = NULL;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(4 == SIZEOF(coll_hdr));
	gvinit();
	v.mvtype = MV_STR;
	len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base);
	hdr_lvl = EXTR_HEADER_LEVEL(ptr);
	if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (V5_BIN_HEADER_SZ == len)) ||
			(('6' == hdr_lvl) && (BIN_HEADER_SZ == len)) ||
			(('7' == hdr_lvl) && (BIN_HEADER_SZ == len)) ||
			(('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len))))
	{
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* expecting the level in a single character */
	assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3));
	if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) ||
			*(BIN_HEADER_VERSION_ENCR) < hdr_lvl)
	{	/* ignore the level check */
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* check if extract was generated in UTF-8 mode */
	utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE;
	if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
	{ /* extract CHSET doesn't match $ZCHSET */
		if (utf8_extract)
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
		else
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
		mupip_exit(ERR_LDBINFMT);
	}
	if ('4' >= hdr_lvl)
	{	/* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte)
		 * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above.
		 */
		for (c = ptr, ctop = c + len; c < ctop; c++)
		{
			if ('\0' == *c)
				*c = ' ';
		}
	}
	util_out_print("Label = !AD\n", TRUE, len, ptr);
	new_gvn = FALSE;
	if (hdr_lvl > '3')
	{
		if (hdr_lvl > '5')
		{
			memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ);
			std_null_coll[BIN_HEADER_NUMSZ] = '\0';
		}
		else
		{
			memcpy(std_null_coll, ptr + V5_BIN_HEADER_NULLCOLLOFFSET, V5_BIN_HEADER_NUMSZ);
			std_null_coll[V5_BIN_HEADER_NUMSZ] = '\0';
		}
		extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10);
		if (0 != extr_std_null_coll && 1!= extr_std_null_coll)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field  in header"),
				ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
	} else
		extr_std_null_coll = 0;
#	ifdef GTM_CRYPT
	if ('7' <= hdr_lvl)
	{
		int	i, num_indexes;
		len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base);
		hash_array = (muext_hash_hdr *)malloc(len);
		/* store hashes of all the files used during extract into muext_hash_hdr structure */
		memcpy((char *)hash_array, ptr, len);
		num_indexes = len / GTMCRYPT_HASH_LEN;
		encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes);
		INIT_PROC_ENCRYPTION(crypt_status);
		GC_BIN_LOAD_ERR(crypt_status);
		for (index = 0; index < num_indexes; index++)
		{
			if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN))
				continue;
			GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status);
			GC_BIN_LOAD_ERR(crypt_status);
		}
	}
#	endif
	if ('2' < hdr_lvl)
	{
		len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base);
		if (SIZEOF(coll_hdr) != len)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
		extr_collhdr = *((coll_hdr *)(ptr));
		new_gvn = TRUE;
	} else
		gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
	if (begin < 2)
		begin = 2;
	for (iter = 2; iter < begin; iter++)
	{
		if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base)))
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			mupip_error_occurred = TRUE;
			return;
		} else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			iter--;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	global_key_count = key_count = 0;
	rec_count = begin - 1;
	extr_collseq = db_collseq = NULL;
	need_xlation = FALSE;
	assert(NULL == tmp_gvkey);	/* GVKEY_INIT macro relies on this */
	GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* tmp_gvkey will point to malloced memory after this */
	assert(NULL == sn_gvkey);	/* GVKEY_INIT macro relies on this */
	GVKEY_INIT(sn_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* sn_gvkey will point to malloced memory after this */
	assert(NULL == sn_savekey);	/* GVKEY_INIT macro relies on this */
	GVKEY_INIT(sn_savekey, DBKEYSIZE(MAX_KEY_SZ));	/* sn_gvkey will point to malloced memory after this */
	for (; !mupip_DB_full ;)
	{
		if (++rec_count > end)
			break;
		next_cmpc = 0;
		mupip_error_occurred = FALSE;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base)) || mupip_error_occurred)
			break;
		else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			new_gvn = TRUE;			/* next record will contain a new gvn */
			rec_count--;	/* Decrement as this record does not count as a record for loading purposes */
			continue;
		}
		rp = (rec_hdr*)(ptr);
#		ifdef GTM_CRYPT
		if ('7' <= hdr_lvl)
		{	/* Getting index value from the extracted file. It indicates which database file this record belongs to */
			GET_LONG(index, ptr);
			if (-1 != index) /* Indicates that the record is encrypted. */
			{
				req_dec_blk_size = len - SIZEOF(int4);
				inbuf = (char *)(ptr + SIZEOF(int4));
				GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status);
				GC_BIN_LOAD_ERR(crypt_status);
			}
			rp = (rec_hdr*)(ptr + SIZEOF(int4));
		}
#		endif
		btop = ptr + len;
		cp1 = (unsigned char*)(rp + 1);
		v.str.addr = (char*)cp1;
		while (*cp1++)
			;
		v.str.len =INTCAST((char*)cp1 - v.str.addr - 1);
		if (('2' >= hdr_lvl) || new_gvn)
		{
			if ((HASHT_GBLNAME_LEN == v.str.len) &&	(0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN)))
				continue;
			bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str);
			max_key = gv_cur_region->max_key_size;
			db_collhdr.act = gv_target->act;
			db_collhdr.ver = gv_target->ver;
			db_collhdr.nct = gv_target->nct;
		}
		GET_USHORT(rec_len, &rp->rsiz);
		if (EVAL_CMPC(rp) != 0 || v.str.len > rec_len || mupip_error_occurred)
		{
			bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
			mu_gvis();
			DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK;
			continue;
		}
		if (new_gvn)
		{
			global_key_count = 1;
			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver
				|| db_collhdr.nct != extr_collhdr.nct
				|| gv_cur_region->std_null_coll != extr_std_null_coll))
			{
				if (extr_collhdr.act)
				{
					if (extr_collseq = ready_collseq((int)extr_collhdr.act))
					{
						if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act,
								extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				if (db_collhdr.act)
				{
					if (db_collseq = ready_collseq((int)db_collhdr.act))
					{
						if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act,
								db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				need_xlation = TRUE;
			} else
				need_xlation = FALSE;
		}
		new_gvn = FALSE;
		for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
		{
			GET_USHORT(rec_len, &rp->rsiz);
			if (rec_len + (unsigned char *)rp > btop)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK;
				break;
			}
			cp1 =  (unsigned char*)(rp + 1);
			cp2 = gv_currkey->base + EVAL_CMPC(rp);
			current = 1;
			for (;;)
			{
				last = current;
				current = *cp2++ = *cp1++;
				if (0 == last && 0 == current)
					break;
				if (cp1 > (unsigned char *)rp + rec_len ||
				    cp2 > (unsigned char *)gv_currkey + gv_currkey->top)
				{
					gv_currkey->end = cp2 - gv_currkey->base - 1;
					gv_currkey->base[gv_currkey->end] = 0;
					gv_currkey->base[gv_currkey->end - 1] = 0;
					bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
					mu_gvis();
					DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK;
					break;
				}
			}
			if (mupip_error_occurred)
				break;
			gv_currkey->end = cp2 - gv_currkey->base - 1;
			if (need_xlation)
			{
				assert(hdr_lvl >= '3');
				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
				 	extr_std_null_coll != gv_cur_region->std_null_coll);
							/* gv_currkey would have been modified/translated in the earlier put */
				memcpy(gv_currkey->base, cmpc_str, next_cmpc);
				next_rp = (rec_hdr *)((unsigned char*)rp + rec_len);
				if ((unsigned char*)next_rp < btop)
				{
					next_cmpc = EVAL_CMPC(next_rp);
					assert(next_cmpc <= gv_currkey->end);
					memcpy(cmpc_str, gv_currkey->base, next_cmpc);
				} else
					next_cmpc = 0;
							/* length of the key might change (due to nct variation),
							 * so get a copy of the original key from the extract */
				memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1);
				gvkey_char_ptr = dup_key_str;
				while (*gvkey_char_ptr++)
					;
				gv_currkey->prev = 0;
				gv_currkey->end = gvkey_char_ptr - dup_key_str;
				assert(gv_keysize <= tmp_gvkey->top);
				while (*gvkey_char_ptr)
				{
						/* get next subscript (in GT.M internal subsc format) */
					subsc_len = 0;
					tmp_ptr = src_buff;
					while (*gvkey_char_ptr)
						*tmp_ptr++ = *gvkey_char_ptr++;
					subsc_len = tmp_ptr - src_buff;
					src_buff[subsc_len] = '\0';
					if (extr_collseq)
					{
						/* undo the extract time collation */
						TREF(transform) = TRUE;
						save_gv_target_collseq = gv_target->collseq;
						gv_target->collseq = extr_collseq;
					} else
						TREF(transform) = FALSE;
						/* convert the subscript to string format */
					end_buff = gvsub2str(src_buff, dest_buff, FALSE);
						/* transform the string to the current subsc format */
					TREF(transform) = TRUE;
					tmp_mval.mvtype = MV_STR;
                                	tmp_mval.str.addr = (char *)dest_buff;
                                	tmp_mval.str.len = INTCAST(end_buff - dest_buff);
					tmp_gvkey->prev = 0;
					tmp_gvkey->end = 0;
					if (extr_collseq)
						gv_target->collseq = save_gv_target_collseq;
					mval2subsc(&tmp_mval, tmp_gvkey);
						/* we now have the correctly transformed subscript */
					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
					gv_currkey->prev = gv_currkey->end;
					gv_currkey->end += tmp_gvkey->end;
					gvkey_char_ptr++;
				}
				if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev)
				{
					if (extr_std_null_coll == 0)
					{
						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
					} else
					{
						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
					}
				}
			}
			if (gv_currkey->end >= max_key)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK;
				continue;
			}
			/*
			 * Spanning node-related variables and their usage:
			 *
			 * expected_sn_chunk_number: 	0  - looking for spanning nodes (regular nodes are OK, too)
			 *				!0 - number of the next chunk needed (implies we are building
			 *					a spanning node's value)
			 *
			 * While building a spanning node's value:
			 * numsubs: the number of chunks needed to build the spanning node's value
			 * gblsize: the expected size of the completed value
			 * sn_chunk_number: The chunk number of the chunk from the current record from the extract
			 *
			 * Managing the value
			 * sn_hold_buff: buffer used to accumulate the spanning node's value
			 * sn_hold_buff_size: Allocated size of buffer
			 * sn_hold_buff_pos: amount of the buffer used; where to place the next chunk
			 * sn_hold_buff_temp: used when we have to increase the size of the buffer
			 *
			 * Controlling the placing of the key,value in the database:
			 * ok_to_put: means we are ready to place the key,value in the database, i.e., we have the full value
			 * 		(either of the spanning node or a regular node).
			 * putting_a_sn: we are placing a spanning node in the database, i.e, use the key from sn_gvkey and
			 * 		the value from sn_hold_buff.
			 */
			CHECK_HIDDEN_SUBSCRIPT(gv_currkey,is_hidden_subscript);
			if (!is_hidden_subscript && (max_subsc_len < (gv_currkey->end + 1)))
				max_subsc_len = gv_currkey->end + 1;
			v.str.addr = (char*)cp1;
			v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp));
			if (expected_sn_chunk_number && !is_hidden_subscript)
			{	/* we were expecting a chunk of an spanning node and we did not get one */
				DISPLAY_INCMP_SN_MSG;
				util_out_print("!_!_Expected chunk number : !UL but found a non-spanning node", TRUE,
						expected_sn_chunk_number + 1);
				if (sn_hold_buff_pos)
					DISPLAY_PARTIAL_SN_HOLD_BUFF;
				KILL_INCMP_SN_IF_NEEDED;
				sn_hold_buff_pos = 0;
				expected_sn_chunk_number = 0;
				ok_to_put = TRUE;
				putting_a_sn = FALSE;
				numsubs = 0;
			}
			if (is_hidden_subscript)
			{	/* it's a chunk and we were expecting one */
				sn_chunk_number = SPAN_GVSUBS2INT((span_subs *) &(gv_currkey->base[gv_currkey->end - 4]));
				if (!expected_sn_chunk_number && is_hidden_subscript && sn_chunk_number)
				{ /* we not expecting a payload chunk (as opposed to a control record) but we got one */
					DISPLAY_INCMP_SN_MSG;
					util_out_print("!_!_Not expecting a spanning node chunk but found chunk : !UL", TRUE,
							sn_chunk_number + 1);
					if (v.str.len)
						DISPLAY_VALUE("!_!_Errant Chunk :");
					continue;
				}
				if (0 == sn_chunk_number)
				{ 	/* first spanning node chunk, get ctrl info */
					if (0 != expected_sn_chunk_number)
					{
						DISPLAY_INCMP_SN_MSG;
						util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", TRUE,
								expected_sn_chunk_number + 1, sn_chunk_number + 1);
						if (sn_hold_buff_pos)
							DISPLAY_PARTIAL_SN_HOLD_BUFF;
						KILL_INCMP_SN_IF_NEEDED;
					}
					/* start building a new spanning node */
					sn_gvkey->end = gv_currkey->end - (SPAN_SUBS_LEN + 1);
					memcpy(sn_gvkey->base, gv_currkey->base, sn_gvkey->end);
					sn_gvkey->base[sn_gvkey->end] = 0;
					sn_gvkey->prev = gv_currkey->prev;
					sn_gvkey->top = gv_currkey->top;
					GET_NSBCTRL(v.str.addr, numsubs, gblsize);
					/* look for first payload chunk */
					expected_sn_chunk_number = 1;
					sn_hold_buff_pos = 0;
					ok_to_put = FALSE;
					sn_incmp_gbl_already_killed = FALSE;
				} else
				{	/* we only need to compare the key before the hidden subscripts */
					if ((expected_sn_chunk_number == sn_chunk_number)
							&& (sn_gvkey->end == gv_currkey->end - (SPAN_SUBS_LEN + 1))
							&& !memcmp(sn_gvkey->base,gv_currkey->base, sn_gvkey->end)
							&& ((sn_hold_buff_pos + v.str.len) <= gblsize))
					{
						if (NULL == sn_hold_buff)
						{
							sn_hold_buff_size = DEFAULT_SN_HOLD_BUFF_SIZE;
							sn_hold_buff = (char *)malloc(DEFAULT_SN_HOLD_BUFF_SIZE);
						}
						if ((sn_hold_buff_pos + v.str.len) > sn_hold_buff_size)
						{
							sn_hold_buff_size = sn_hold_buff_size * 2;
							sn_hold_buff_temp = (char *)malloc(sn_hold_buff_size);
							memcpy(sn_hold_buff_temp, sn_hold_buff, sn_hold_buff_pos);
							free (sn_hold_buff);
							sn_hold_buff = sn_hold_buff_temp;
						}
						memcpy(sn_hold_buff + sn_hold_buff_pos, v.str.addr, v.str.len);
						sn_hold_buff_pos += v.str.len;
						if (expected_sn_chunk_number == numsubs)
						{
							if (sn_hold_buff_pos != gblsize)
							{	/* we don't have the expected size even though 	*/
								/* we have all the expected chunks.		 		*/
								DISPLAY_INCMP_SN_MSG;
								util_out_print("!_!_Expected size : !UL actual size : !UL", TRUE,
										gblsize, sn_hold_buff_pos);
								if (sn_hold_buff_pos)
									DISPLAY_PARTIAL_SN_HOLD_BUFF;
								KILL_INCMP_SN_IF_NEEDED;
								expected_sn_chunk_number = 0;
								ok_to_put = FALSE;
								sn_hold_buff_pos = 0;
							}
							else
							{
								expected_sn_chunk_number = 0;
								ok_to_put = TRUE;
								putting_a_sn = TRUE;
							}

						}else
							expected_sn_chunk_number++;
					}else
					{
						DISPLAY_INCMP_SN_MSG;
						if ((sn_hold_buff_pos + v.str.len) <= gblsize)
							util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", /*BYPASSOK*/
								TRUE, expected_sn_chunk_number + 1, sn_chunk_number + 1);
						else
							util_out_print("!_!_Global value too large:  expected size : !UL actual size : !UL chunk number : !UL", TRUE, /*BYPASSOK*/
								gblsize, sn_hold_buff_pos + v.str.len, sn_chunk_number + 1);
						if (sn_hold_buff_pos)
							DISPLAY_PARTIAL_SN_HOLD_BUFF;
						if (v.str.len)
							DISPLAY_VALUE("!_!_Errant Chunk :");
						KILL_INCMP_SN_IF_NEEDED;
						sn_hold_buff_pos = 0;
						expected_sn_chunk_number = 0;
					}
				}
			} else
				ok_to_put = TRUE;
			if (ok_to_put)
			{
					if (putting_a_sn)
					{
						gv_currkey->base[gv_currkey->end - (SPAN_SUBS_LEN + 1)] = 0;
						gv_currkey->end -= (SPAN_SUBS_LEN + 1);
						v.str.addr = sn_hold_buff;
						v.str.len = sn_hold_buff_pos;
					}
					if (max_data_len < v.str.len)
						max_data_len = v.str.len;
					bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
					if (mupip_error_occurred)
					{
						if (!mupip_DB_full)
						{
							bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
							file_offset = file_offset_base + ((unsigned char *)rp - ptr_base);
							util_out_print("!_!_at File offset : [0x!XL]", TRUE, file_offset);
							DISPLAY_CURRKEY;
							DISPLAY_VALUE("!_!_Value :");
						}
						break;
					}
					if (putting_a_sn)
						putting_a_sn = FALSE;
					else
					{
						key_count++;
						global_key_count++;
					}
			}
		}
	}
	GTMCRYPT_ONLY(
		if (NULL != hash_array)
			free(hash_array);
	)
コード例 #17
0
ファイル: gdsfilext.c プロジェクト: shabiel/YottaDB
uint4	 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog)
{
	sm_uc_ptr_t		old_base[2], mmap_retaddr;
	boolean_t		was_crit, is_mm;
	int			result, save_errno, status;
	DEBUG_ONLY(int		first_save_errno);
	uint4			new_bit_maps, bplmap, map, new_blocks, new_total, max_tot_blks, old_total;
	uint4			jnl_status;
	gtm_uint64_t		avail_blocks, mmap_sz;
	off_t			new_eof, new_size;
	trans_num		curr_tn;
	unix_db_info		*udi;
	inctn_opcode_t		save_inctn_opcode;
	int4			prev_extend_blks_to_upgrd;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;
	cache_rec_ptr_t         cr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(!IS_DSE_IMAGE);
	assert((cs_addrs->nl == NULL) || (process_id != cs_addrs->nl->trunc_pid)); /* mu_truncate shouldn't extend file... */
	assert(!process_exiting);
	DEBUG_ONLY(old_base[0] = old_base[1] = NULL);
	assert(!gv_cur_region->read_only);
	udi = FILE_INFO(gv_cur_region);
	is_mm = (dba_mm == cs_addrs->hdr->acc_meth);
#	if !defined(MM_FILE_EXT_OK)
	if (!udi->grabbed_access_sem && is_mm)
		return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not allowed ? */
#	endif
	/* Both blocks and total blocks are unsigned ints so make sure we aren't asking for huge numbers that will
	   overflow and end up doing silly things.
	*/
	assert((blocks <= (MAXTOTALBLKS(cs_data) - cs_data->trans_hist.total_blks)) || WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR));
#	if defined(__sun) || defined(__hpux)
	cs_data->defer_allocate = TRUE;
#	endif
	if (!blocks && (cs_data->defer_allocate || (TRANS_IN_PROG_TRUE == trans_in_prog)))
		return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not enabled ? */
	bplmap = cs_data->bplmap;
	/* New total of non-bitmap blocks will be number of current, non-bitmap blocks, plus new blocks desired
	 * There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks
	 *      and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this
	 *      manner as every non-bitmap block must have an associated bitmap)
	 * Current number of bitmaps is (total number of current blocks + bplmap - 1) / bplmap.
	 * Subtract current number of bitmaps from number needed for expanded database to get number of new bitmaps needed.
	 */
	new_bit_maps = DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks
			- DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap) + blocks, bplmap - 1)
			- DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap);
	new_blocks = blocks + new_bit_maps;
	assert((0 < (int)new_blocks) || (!cs_data->defer_allocate && (0 == new_blocks)));
	if (new_blocks + cs_data->trans_hist.total_blks > MAXTOTALBLKS(cs_data))
	{
		assert(WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR));
		send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_TOTALBLKMAX);
		return (uint4)(NO_FREE_SPACE);
	}
	if (0 != (save_errno = disk_block_available(udi->fd, &avail_blocks, FALSE)))
	{
		send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno);
		rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno);
	} else
	{
		if (!(gtmDebugLevel & GDL_IgnoreAvailSpace))
		{	/* Bypass this space check if debug flag above is on. Allows us to create a large sparce DB
			 * in space it could never fit it if wasn't sparse. Needed for some tests.
			 */
			avail_blocks = avail_blocks / (cs_data->blk_size / DISK_BLOCK_SIZE);
			if ((blocks * EXTEND_WARNING_FACTOR) > avail_blocks)
			{
				if (blocks > (uint4)avail_blocks)
				{
					if (!INST_FREEZE_ON_NOSPC_ENABLED(cs_addrs))
						return (uint4)(NO_FREE_SPACE);
					else
						send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_NOSPACEEXT), 4,
							DB_LEN_STR(gv_cur_region), new_blocks, (uint4)avail_blocks);
				} else
					send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, DB_LEN_STR(gv_cur_region),
						 (uint4)(avail_blocks - ((new_blocks <= avail_blocks) ? new_blocks : 0)));
			}
		}
	}
#	ifdef DEBUG
	if (WBTEST_ENABLED(WBTEST_MM_CONCURRENT_FILE_EXTEND) && dollar_tlevel && !MEMCMP_LIT(gv_cur_region->rname, "DEFAULT"))
	{
		SYSTEM("$gtm_dist/mumps -run $gtm_wbox_mrtn");
		assert(1 == cs_addrs->nl->wbox_test_seq_num);	/* should have been set by mubfilcpy */
		cs_addrs->nl->wbox_test_seq_num = 2;	/* signal mupip backup to stop sleeping in mubfilcpy */
	}
#	endif
	/* From here on, we need to use GDSFILEXT_CLNUP before returning to the caller */
	was_crit = cs_addrs->now_crit;
	assert(!cs_addrs->hold_onto_crit || was_crit);
	/* If we are coming from mupip_extend (which gets crit itself) we better have waited for any unfreezes to occur.
	 * If we are coming from online rollback (when that feature is available), we will come in holding crit and in
	 * 	the final retry. In that case too, we expect to have waited for unfreezes to occur in the caller itself.
	 * Therefore if we are coming in holding crit from MUPIP, we expect the db to be unfrozen so no need to wait for
	 * freeze.
	 * If we are coming from GT.M and final retry (in which case we come in holding crit) we expect to have waited
	 * 	for any unfreezes (by invoking tp_crit_all_regions) to occur (TP or non-TP) before coming into this
	 *	function. However, there is one exception. In the final retry, if tp_crit_all_regions notices that
	 *	at least one of the participating regions did ONLY READs, it will not wait for any freeze on THAT region
	 *	to complete before grabbing crit. Later, in the final retry, if THAT region did an update which caused
	 *	op_tcommit to invoke bm_getfree->gdsfilext, then we would have come here with a frozen region on which
	 *	we hold crit.
	 */
	assert(!was_crit || !FROZEN_HARD(cs_data) || (dollar_tlevel && (CDB_STAGNATE <= t_tries)));
	/*
	 * If we are in the final retry and already hold crit, it is possible that csa->nl->wc_blocked is also set to TRUE
	 * (by a concurrent process in phase2 which encountered an error in the midst of commit and secshr_db_clnup
	 * finished the job for it). In this case we do NOT want to invoke wcs_recover as that will update the "bt"
	 * transaction numbers without correspondingly updating the history transaction numbers (effectively causing
	 * a cdb_sc_blkmod type of restart). Therefore do NOT call grab_crit (which unconditionally invokes wcs_recover)
	 * if we already hold crit.
	 */
	if (!was_crit)
	{
		for ( ; ; )
		{
			grab_crit(gv_cur_region);
			if (FROZEN_CHILLED(cs_data))
				DO_CHILLED_AUTORELEASE(cs_addrs, cs_data);
			if (!FROZEN(cs_data) && !IS_REPL_INST_FROZEN)
				break;
			rel_crit(gv_cur_region);
			while (FROZEN(cs_data) || IS_REPL_INST_FROZEN)
			{
				hiber_start(1000);
				if (FROZEN_CHILLED(cs_data) && CHILLED_AUTORELEASE(cs_data))
					break;
			}
		}
	} else if (FROZEN_HARD(cs_data) && dollar_tlevel)
	{	/* We don't want to continue with file extension as explained above. Hence return with an error code which
		 * op_tcommit will recognize (as a cdb_sc_needcrit/cdb_sc_instancefreeze type of restart) and restart accordingly.
		 */
		assert(CDB_STAGNATE <= t_tries);
		GDSFILEXT_CLNUP;
		return (uint4)FINAL_RETRY_FREEZE_PROG;
	} else
		WAIT_FOR_REGION_TO_UNCHILL(cs_addrs, cs_data);
	if (IS_REPL_INST_FROZEN && trans_in_prog)
	{
		assert(CDB_STAGNATE <= t_tries);
		GDSFILEXT_CLNUP;
		return (uint4)FINAL_RETRY_INST_FREEZE;
	}
	assert(cs_addrs->ti->total_blks == cs_data->trans_hist.total_blks);
	old_total = cs_data->trans_hist.total_blks;
	if (old_total != filesize)
	{	/* Somebody else has already extended it, since we are in crit, this is trust-worthy. However, in case of MM,
		 * we still need to remap the database
		 */
		assert((old_total > filesize) || !is_mm);
		/* For BG, someone else could have truncated or extended - we have no idea */
		GDSFILEXT_CLNUP;
		return (SS_NORMAL);
	}
	if (trans_in_prog && SUSPICIOUS_EXTEND)
	{
		if (!was_crit)
		{
			GDSFILEXT_CLNUP;
			return (uint4)(EXTEND_SUSPECT);
		}
		/* If free_blocks counter is not ok, then correct it. Do the check again. If still fails, then it means we held
		 * crit through bm_getfree into gdsfilext and still didn't get it right.
		 */
		assertpro(!is_free_blks_ctr_ok() && !SUSPICIOUS_EXTEND);
	}
	if (JNL_ENABLED(cs_data))
	{
		if (!jgbl.dont_reset_gbl_jrec_time)
			SET_GBL_JREC_TIME;	/* needed before jnl_ensure_open as that can write jnl records */
		jpc = cs_addrs->jnl;
		jbp = jpc->jnl_buff;
		/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order
		 * of jnl records. This needs to be done BEFORE the jnl_ensure_open as that could write
		 * journal records (if it decides to switch to a new journal file).
		 */
		ADJUST_GBL_JREC_TIME(jgbl, jbp);
		jnl_status = jnl_ensure_open(gv_cur_region, cs_addrs);
		if (jnl_status)
		{
			GDSFILEXT_CLNUP;
			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(cs_data), DB_LEN_STR(gv_cur_region));
			return (uint4)(NO_FREE_SPACE);	/* should have better return status */
		}
	}
	if (is_mm)
	{
		cs_addrs->nl->mm_extender_pid = process_id;
		status = wcs_wtstart(gv_cur_region, 0, NULL, NULL);
		cs_addrs->nl->mm_extender_pid = 0;
		assertpro(SS_NORMAL == status);
		old_base[0] = cs_addrs->db_addrs[0];
		old_base[1] = cs_addrs->db_addrs[1];
		cs_addrs->db_addrs[0] = NULL; /* don't rely on it until the mmap below */
#		ifdef _AIX
		status = shmdt(old_base[0] - BLK_ZERO_OFF(cs_data->start_vbn));
#		else
		status = munmap((caddr_t)old_base[0], (size_t)(old_base[1] - old_base[0]));
#		endif
		if (0 != status)
		{
			save_errno = errno;
			GDSFILEXT_CLNUP;
			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region),
					ERR_SYSCALL, 5, LEN_AND_STR(MEM_UNMAP_SYSCALL), CALLFROM, save_errno);
			return (uint4)(NO_FREE_SPACE);
		}
	} else
	{	/* Due to concurrency issues, it is possible some process had issued a disk read of the GDS block# corresponding
		 * to "old_total" right after a truncate wrote a GDS-block of zeros on disk (to signal end of the db file).
		 * If so, the global buffer containing this block needs to be invalidated now as part of the extend. If not, it is
		 * possible the EOF block on disk is now going to be overwritten by a properly initialized bitmap block (as part
		 * of the gdsfilext below) while the global buffer continues to have an incorrect copy of that bitmap block and
		 * this in turn would cause XXXX failures due to a bad bitmap block in shared memory. (GTM-7519)
		 */
		cr = db_csh_get((block_id)old_total);
		if ((NULL != cr) && ((cache_rec_ptr_t)CR_NOTVALID != cr))
		{
			assert((0 == cr->dirty) && (0 == cr->bt_index) && !cr->stopped);
			cr->cycle++;
			cr->blk = CR_BLKEMPTY;
		}
	}
	CHECK_TN(cs_addrs, cs_data, cs_data->trans_hist.curr_tn);	/* can issue rts_error TNTOOLARGE */
	new_total = old_total + new_blocks;
	new_eof = BLK_ZERO_OFF(cs_data->start_vbn) + ((off_t)new_total * cs_data->blk_size);
#	if !defined(__sun) && !defined(__hpux)
	if (!cs_data->defer_allocate)
	{
		new_size = new_eof + cs_data->blk_size;
		save_errno = posix_fallocate(udi->fd, 0, new_size);
		DEBUG_ONLY(first_save_errno = save_errno);
		if ((ENOSPC == save_errno) && IS_GTM_IMAGE)
			save_errno = extend_wait_for_fallocate(udi, new_size);
		if (0 != save_errno)
		{
			GDSFILEXT_CLNUP;
			assert(ENOSPC == save_errno);
			if (ENOSPC != save_errno)
				send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_PREALLOCATEFAIL, 2, DB_LEN_STR(gv_cur_region),
					     save_errno);
			return (uint4)(NO_FREE_SPACE);
		}
	}
#	endif
	save_errno = db_write_eof_block(udi, udi->fd, cs_data->blk_size, new_eof, &(TREF(dio_buff)));
	if ((ENOSPC == save_errno) && IS_GTM_IMAGE)
		save_errno = extend_wait_for_write(udi, cs_data->blk_size, new_eof);
	if (0 != save_errno)
	{
		GDSFILEXT_CLNUP;
		if (ENOSPC != save_errno)
			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno);
		return (uint4)(NO_FREE_SPACE);
	}
	if (WBTEST_ENABLED(WBTEST_FILE_EXTEND_INTERRUPT_1))
	{
		LONG_SLEEP(600);
		assert(FALSE);
	}
	/* Ensure the EOF and metadata get to disk BEFORE any bitmap writes. Otherwise, the file size could no longer reflect
	 * a proper extent and subsequent invocations of gdsfilext could corrupt the database.
	 */
	if (!IS_STATSDB_CSA(cs_addrs))
	{
		GTM_DB_FSYNC(cs_addrs, udi->fd, status);
		assert(0 == status);
		if (0 != status)
		{
			GDSFILEXT_CLNUP;
			send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_DBFILERR, 5,
						RTS_ERROR_LITERAL("fsync1()"), CALLFROM, status);
			return (uint4)(NO_FREE_SPACE);
		}
	}
	if (WBTEST_ENABLED(WBTEST_FILE_EXTEND_INTERRUPT_2))
	{
		LONG_SLEEP(600);
		assert(FALSE); /* Should be killed before that */
	}
	DEBUG_ONLY(prev_extend_blks_to_upgrd = cs_data->blks_to_upgrd;)
コード例 #18
0
ファイル: op_zlink.c プロジェクト: ChristopherEdwards/fis-gtm
void op_zlink(mval *v, mval *quals)
{
	struct FAB		srcfab;
	struct NAM		srcnam, objnam;
	struct XABDAT		srcxab, objxab;
	boolean_t		compile, expdir, libr, obj_found, src_found;
	short			flen;
	unsigned short		type;
	unsigned char		srccom[MAX_FN_LEN], srcnamebuf[MAX_FN_LEN], objnamebuf[MAX_FN_LEN], objnamelen, srcnamelen,ver[6];
	unsigned char		objcom[MAX_FN_LEN], list_file[MAX_FN_LEN], ceprep_file[MAX_FN_LEN], *fname;
	zro_ent			*srcdir, *objdir;
	mstr			srcstr, objstr, version;
	mval			qualifier;
	unsigned		status, srcfnb;
	uint4			lcnt, librindx, qlf;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	MV_FORCE_STR(v);
	if (MAX_FN_LEN < v->str.len)
		rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, MIN(UCHAR_MAX, v->str.len), v->str.addr, ERR_FILENAMETOOLONG);
	version.len = 0;
	srcdir = objdir = 0;
	version.addr = ver;
	libr = FALSE;
	obj_fab = cc$rms_fab;
	if (quals)
	{
		MV_FORCE_STR(quals);
		srcfab = cc$rms_fab;
		srcfab.fab$l_fna = v->str.addr;
		srcfab.fab$b_fns = v->str.len;
		srcfab.fab$l_nam = &srcnam;
		srcnam = cc$rms_nam;
		srcnam.nam$l_esa = srcnamebuf;
		srcnam.nam$b_ess = SIZEOF(srcnamebuf);
		srcnam.nam$b_nop = NAM$M_SYNCHK;
		status = sys$parse(&srcfab);
		if (!(status & 1))
			rts_error(VARLSTCNT(9) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_FILEPARSE, 2, v->str.len, v->str.addr, status);
		if (srcnam.nam$l_fnb & NAM$M_WILDCARD)
			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_WILDCARD, 2, v->str.len, v->str.addr);
		srcfnb = srcnam.nam$l_fnb;
		expdir = (srcfnb & (NAM$M_NODE | NAM$M_EXP_DEV | NAM$M_EXP_DIR));
		if (srcfnb & NAM$M_EXP_VER)
		{
			memcpy(version.addr, srcnam.nam$l_ver, srcnam.nam$b_ver);
			version.len = srcnam.nam$b_ver;
		}
		if (expdir)
		{
			if (version.len)
				flen = srcnam.nam$b_esl - srcnam.nam$b_type - version.len;
			else
				flen = srcnam.nam$b_esl - srcnam.nam$b_type - 1; /* semicolon is put in by default */
			fname = srcnam.nam$l_esa;
		} else
		{
			flen = srcnam.nam$b_name;
			fname = srcnam.nam$l_name;
		}
		ENSURE_STP_FREE_SPACE(flen);
		memcpy(stringpool.free, fname, flen);
		dollar_zsource.str.addr = stringpool.free;
		dollar_zsource.str.len = flen;
		stringpool.free += flen;
		if (srcfnb & NAM$M_EXP_TYPE)
		{
			if ((SIZEOF(DOTOBJ) - 1 == srcnam.nam$b_type) &&
				!MEMCMP_LIT(srcnam.nam$l_type, DOTOBJ))
			{
				type = OBJ;
				objstr.addr = srcnam.nam$l_esa;
				objstr.len = srcnam.nam$b_esl;
			} else
			{
				type = SRC;
				memcpy(srcnamebuf, dollar_zsource.str.addr, flen);
				memcpy(&srcnamebuf[flen], srcnam.nam$l_type, srcnam.nam$b_type);
				memcpy(&srcnamebuf[flen + srcnam.nam$b_type],
					version.addr, version.len);
				srcnamelen = flen + srcnam.nam$b_type + version.len;
				srcnamebuf[srcnamelen] = 0;
				srcstr.addr = srcnamebuf;
				srcstr.len = srcnamelen;
				memcpy(objnamebuf, dollar_zsource.str.addr, flen);
				memcpy(&objnamebuf[flen], DOTOBJ, SIZEOF(DOTOBJ));
				objnamelen = flen + SIZEOF(DOTOBJ) - 1;
				objstr.addr = objnamebuf;
				objstr.len = objnamelen;
			}
		} else
		{
			type = NOTYPE;
			memcpy(srcnamebuf, dollar_zsource.str.addr, flen);
			memcpy(&srcnamebuf[flen], DOTM, SIZEOF(DOTM));
			srcnamelen = flen + SIZEOF(DOTM) - 1;
			memcpy(objnamebuf, dollar_zsource.str.addr, flen);
			MEMCPY_LIT(&objnamebuf[flen], DOTOBJ);
			memcpy(&objnamebuf[flen + SIZEOF(DOTOBJ) - 1], version.addr, version.len);
			objnamelen = flen + SIZEOF(DOTOBJ) + version.len - 1;
			objnamebuf[objnamelen] = 0;
			srcstr.addr = srcnamebuf;
			srcstr.len = srcnamelen;
			objstr.addr = objnamebuf;
			objstr.len = objnamelen;
		}
		if (!expdir)
		{
			if (OBJ == type)
			{
				zro_search(&objstr, &objdir, 0, 0);
				if (!objdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
			} else  if (SRC == type)
			{
				zro_search(&objstr, &objdir, &srcstr, &srcdir);
				if (!srcdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf,
						ERR_FILENOTFND, 2, srcnamelen, srcnamebuf);
			} else
			{
				zro_search(&objstr, &objdir, &srcstr, &srcdir);
				if (!objdir && !srcdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
			}
		}
	} else
	{
		expdir = FALSE;
		type = NOTYPE;
		flen = v->str.len;
		memcpy(srcnamebuf, v->str.addr, flen);
		MEMCPY_LIT(&srcnamebuf[flen], DOTM);
		srcnamelen = flen + SIZEOF(DOTM) - 1;
		if ('%' == srcnamebuf[0])
			srcnamebuf[0] = '_';
		memcpy(objnamebuf, srcnamebuf, flen);
		MEMCPY_LIT(&objnamebuf[flen], DOTOBJ);
		objnamelen = flen + SIZEOF(DOTOBJ) - 1;
		srcstr.addr = srcnamebuf;
		srcstr.len = srcnamelen;
		objstr.addr = objnamebuf;
		objstr.len = objnamelen;
		zro_search(&objstr, &objdir, &srcstr, &srcdir);
		if (!objdir && !srcdir)
			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_FILENOTFND, 2, v->str.len, v->str.addr);
		qualifier.mvtype = MV_STR;
		qualifier.str = TREF(dollar_zcompile);
		quals = &qualifier;
	}
	if (OBJ == type)
	{
		obj_fab.fab$b_fac = FAB$M_GET;
		obj_fab.fab$b_shr = FAB$M_SHRGET;
		if (NULL != objdir)
		{
			if (ZRO_TYPE_OBJLIB == objdir->type)
				libr = TRUE;
			else
			{
				srcfab.fab$l_dna = objdir->str.addr;
				srcfab.fab$b_dns = objdir->str.len;
			}
		}
		for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
		{
			status = (FALSE == libr) ? sys$open(&srcfab): zl_olb(&objdir->str, &objstr, &librindx);
			if (RMS$_FLK != status)
				break;
			hiber_start(WAIT_FOR_FILE_TIME);
		}
		if (FALSE == (status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status);
		if (FALSE == ((FALSE == libr) ? incr_link(&srcfab, libr) : incr_link(&librindx, libr)))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_VERSION);
		status = (FALSE == libr) ? sys$close(&srcfab) : lbr$close(&librindx);
		if (FALSE == (status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status);
	} else	/* either NO type or SOURCE type */
	{
		src_found = obj_found = compile = FALSE;
		srcfab = obj_fab = cc$rms_fab;
		obj_fab.fab$l_xab = &objxab;
		srcxab = objxab = cc$rms_xabdat;
		obj_fab.fab$l_nam = &objnam;
		srcnam = objnam = cc$rms_nam;
		obj_fab.fab$l_fna = objnamebuf;
		obj_fab.fab$b_fns = objnamelen;
		obj_fab.fab$b_fac = FAB$M_GET;
		obj_fab.fab$b_shr = FAB$M_SHRGET;
		objnam.nam$l_esa = objcom;
		objnam.nam$b_ess = SIZEOF(objcom);
		srcfab.fab$l_nam = &srcnam;
		srcfab.fab$l_xab = &srcxab;
		srcfab.fab$l_fna = srcnamebuf;
		srcfab.fab$b_fns = srcnamelen;
		srcfab.fab$b_fac = FAB$M_GET;
		srcfab.fab$b_shr = FAB$M_SHRGET;
		srcnam.nam$l_esa = srccom;
		srcnam.nam$b_ess = SIZEOF(srccom);
		cmd_qlf.object_file.str.addr = objcom;
		cmd_qlf.object_file.str.len = 255;
		cmd_qlf.list_file.str.addr = list_file;
		cmd_qlf.list_file.str.len = 255;
		cmd_qlf.ceprep_file.str.addr = ceprep_file;
		cmd_qlf.ceprep_file.str.len = 255;
		if (srcdir && srcdir->str.len)
		{
			srcfab.fab$l_dna = srcdir->str.addr;
			srcfab.fab$b_dns = srcdir->str.len;
		}
		if (objdir && objdir->str.len)
		{
			if (ZRO_TYPE_OBJLIB == objdir->type)
				libr = TRUE;
			else
			{
				obj_fab.fab$l_dna = objdir->str.addr;
				obj_fab.fab$b_dns = objdir->str.len;
			}
		}
		if (SRC != type)
		{
			if (!expdir && !objdir)
				obj_found = FALSE;
			else  if (!libr)
			{
				for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
				{
					status = sys$open(&obj_fab);
					if (RMS$_FLK != status)
						break;
					hiber_start(WAIT_FOR_FILE_TIME);
				}
				if (!(status & 1))
				{
					if (RMS$_FNF == status)
						obj_found = FALSE;
					else
						rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status);
				} else
					obj_found = TRUE;
			} else
			{
				status = zl_olb(&objdir->str, &objstr, &librindx);
				if (status)
					obj_found = TRUE;
			}
		} else
			compile = TRUE;
		if (!expdir && !srcdir)
			src_found = FALSE;
		else
		{
			for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
			{
				status = sys$open(&srcfab);
				if (RMS$_FLK != status)
					break;
				hiber_start(WAIT_FOR_FILE_TIME);
			}
			if (!(status & 1))
			{
				if ((RMS$_FNF == status) && (SRC != type))
					src_found = FALSE;
				else
					rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
			} else
			{
				src_found = TRUE;
				if (SRC == type)
				{
					status = sys$close(&srcfab);
					if (!(status & 1))
						rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
				}
			}
		}
		if (SRC != type)
		{
			if (src_found)
			{
				if (obj_found)
				{
					if (QUADCMP(&srcxab.xab$q_rdt, &objxab.xab$q_rdt))
					{
						status = sys$close(&obj_fab);
						obj_fab = cc$rms_fab;
						if (!(status & 1))
							rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status);
						compile = TRUE;
					}
				} else
					compile = TRUE;
				status = sys$close(&srcfab);
				if (!(status & 1))
					rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
			} else  if (!obj_found)
				rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, objnamelen, objnamebuf,
					ERR_FILENOTFND, 2, objnamelen, objnamebuf);
		}
		if (compile)
		{
			zl_cmd_qlf(&quals->str, &cmd_qlf);
			if (!MV_DEFINED(&cmd_qlf.object_file))
			{
				objnam.nam$b_nop = NAM$M_SYNCHK;
				status = sys$parse(&obj_fab);
				if (!(status & 1))
					rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna);
				cmd_qlf.object_file.mvtype = MV_STR;
				cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver;
			}
			qlf = cmd_qlf.qlf;
			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
			{
				cmd_qlf.qlf = glb_cmd_qlf.qlf;
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
			}
			zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa);
			if ((SRC == type) && !(qlf & CQ_OBJECT))
				return;
		}
		status = libr ? incr_link(&librindx, libr) : incr_link(&obj_fab, libr);
		if (!status)	/* due only to version mismatch, so recompile */
		{
			if (!libr)
			{
				status = sys$close(&obj_fab);
				obj_fab = cc$rms_fab;
			} else
				status = lbr$close(&librindx);
			if (!(status & 1))
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status);
			if (compile)
				GTMASSERT;
			if (!src_found)
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_VERSION);
			zl_cmd_qlf(&quals->str, &cmd_qlf);
			if (!MV_DEFINED(&cmd_qlf.object_file))
			{
				objnam.nam$b_nop = NAM$M_SYNCHK;
				status = sys$parse(&obj_fab);
				if (!(status & 1))
					rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna);
				cmd_qlf.object_file.mvtype = MV_STR;
				cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver;
			}
			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
			{
				cmd_qlf.qlf = glb_cmd_qlf.qlf;
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
			}
			zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa);
			if (!incr_link(&obj_fab, libr))
				GTMASSERT;
		}
		if (!libr)
		{
			status = sys$close(&obj_fab);
			obj_fab = cc$rms_fab;
		} else
			status = lbr$close(&librindx);
		if (!(status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status);
	}
	return;
}
コード例 #19
0
ファイル: bin_load.c プロジェクト: CeperaCPP/fis-gtm
void bin_load(uint4 begin, uint4 end)
{
	unsigned char	*ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop;
	unsigned char	hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ],
			cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1];
	unsigned char	*end_buff;
	unsigned short	rec_len, next_cmpc;
	int		len;
	int		current, last, length, max_blk_siz, max_key, status;
	uint4		iter, max_data_len, max_subsc_len, key_count;
	ssize_t	        rec_count, global_key_count, subsc_len,extr_std_null_coll;
	boolean_t	need_xlation, new_gvn, utf8_extract;
	rec_hdr		*rp, *next_rp;
	mval		v, tmp_mval;
	mstr		mstr_src, mstr_dest;
	collseq		*extr_collseq, *db_collseq, *save_gv_target_collseq;
	coll_hdr	extr_collhdr, db_collhdr;
	gv_key 		*tmp_gvkey = NULL;	/* null-initialize at start, will be malloced later */
	char		std_null_coll[BIN_HEADER_NUMSZ + 1];
#	ifdef GTM_CRYPT
	gtmcrypt_key_t			*encr_key_handles;
	char				*inbuf;
	int4				index;
	int				req_dec_blk_size, init_status, crypt_status;
	muext_hash_hdr_ptr_t		hash_array = NULL;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(4 == SIZEOF(coll_hdr));
	gvinit();
	v.mvtype = MV_STR;
	len = file_input_bin_get((char **)&ptr);
	hdr_lvl = EXTR_HEADER_LEVEL(ptr);
	if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len))))
	{
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* expecting the level in a single character */
	assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3));
	if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION) < hdr_lvl)
	{	/* ignore the level check */
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* check if extract was generated in UTF-8 mode */
	utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE;
	if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
	{ /* extract CHSET doesn't match $ZCHSET */
		if (utf8_extract)
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
		else
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
		mupip_exit(ERR_LDBINFMT);
	}
	if ('4' >= hdr_lvl)
	{	/* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte)
		 * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above.
		 */
		for (c = ptr, ctop = c + len; c < ctop; c++)
		{
			if ('\0' == *c)
				*c = ' ';
		}
	}
	util_out_print("Label = !AD\n", TRUE, len, ptr);
	new_gvn = FALSE;
	if (hdr_lvl > '3')
	{
		memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ);
		std_null_coll[BIN_HEADER_NUMSZ] = '\0';
		extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10);
		if (0 != extr_std_null_coll && 1!= extr_std_null_coll)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field  in header"),
				ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
	} else
		extr_std_null_coll = 0;
#	ifdef GTM_CRYPT
	if ('5' <= hdr_lvl)
	{
		int	i, num_indexes;
		len = file_input_bin_get((char **)&ptr);
		hash_array = (muext_hash_hdr *)malloc(len);
		/* store hashes of all the files used during extract into muext_hash_hdr structure */
		memcpy((char *)hash_array, ptr, len);
		num_indexes = len / GTMCRYPT_HASH_LEN;
		encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes);
		INIT_PROC_ENCRYPTION(crypt_status);
		GC_BIN_LOAD_ERR(crypt_status);
		for (index = 0; index < num_indexes; index++)
		{
			if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN))
				continue;
			GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status);
			GC_BIN_LOAD_ERR(crypt_status);
		}
	}
#	endif
	if ('2' < hdr_lvl)
	{
		len = file_input_bin_get((char **)&ptr);
		if (SIZEOF(coll_hdr) != len)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
		extr_collhdr = *((coll_hdr *)(ptr));
		new_gvn = TRUE;
	} else
		gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
	if (begin < 2)
		begin = 2;
	for (iter = 2; iter < begin; iter++)
	{
		if (!(len = file_input_bin_get((char **)&ptr)))
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			mupip_error_occurred = TRUE;
			return;
		} else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			iter--;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	global_key_count = key_count = 0;
	rec_count = begin - 1;
	extr_collseq = db_collseq = NULL;
	need_xlation = FALSE;
	assert(NULL == tmp_gvkey);	/* GVKEY_INIT macro relies on this */
	GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ));	/* tmp_gvkey will point to malloced memory after this */
	for (; !mupip_DB_full ;)
	{
		if (++rec_count > end)
			break;
		next_cmpc = 0;
		mupip_error_occurred = FALSE;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		/* reset the stringpool for every record in order to avoid garbage collection */
		stringpool.free = stringpool.base;
		if (!(len = file_input_bin_get((char **)&ptr)) || mupip_error_occurred)
			break;
		else if (len == SIZEOF(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			new_gvn = TRUE;			/* next record will contain a new gvn */
			rec_count--;	/* Decrement as this record does not count as a record for loading purposes */
			continue;
		}
		rp = (rec_hdr*)(ptr);
#		ifdef GTM_CRYPT
		if ('5' <= hdr_lvl)
		{	/* Getting index value from the extracted file. It indicates which database file this record belongs to */
			GET_LONG(index, ptr);
			if (-1 != index) /* Indicates that the record is encrypted. */
			{
				req_dec_blk_size = len - SIZEOF(int4);
				inbuf = (char *)(ptr + SIZEOF(int4));
				GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status);
				GC_BIN_LOAD_ERR(crypt_status);
			}
			rp = (rec_hdr*)(ptr + SIZEOF(int4));
		}
#		endif
		btop = ptr + len;
		cp1 = (unsigned char*)(rp + 1);
		v.str.addr = (char*)cp1;
		while (*cp1++)
			;
		v.str.len =INTCAST((char*)cp1 - v.str.addr - 1);
		if (('2' >= hdr_lvl) || new_gvn)
		{
			if ((HASHT_GBLNAME_LEN == v.str.len) &&	(0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN)))
				continue;
			bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str);
			max_key = gv_cur_region->max_key_size;
			db_collhdr.act = gv_target->act;
			db_collhdr.ver = gv_target->ver;
			db_collhdr.nct = gv_target->nct;
		}
		GET_USHORT(rec_len, &rp->rsiz);
		if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred)
		{
			bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
			mu_gvis();
			util_out_print(0, TRUE);
			continue;
		}
		if (new_gvn)
		{
			global_key_count = 1;
			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver
				|| db_collhdr.nct != extr_collhdr.nct
				|| gv_cur_region->std_null_coll != extr_std_null_coll))
			{
				if (extr_collhdr.act)
				{
					if (extr_collseq = ready_collseq((int)extr_collhdr.act))
					{
						if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act,
								extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				if (db_collhdr.act)
				{
					if (db_collseq = ready_collseq((int)db_collhdr.act))
					{
						if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act,
								db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				need_xlation = TRUE;
			} else
				need_xlation = FALSE;
		}
		new_gvn = FALSE;
		for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
		{
			GET_USHORT(rec_len, &rp->rsiz);
			if (rec_len + (unsigned char *)rp > btop)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				break;
			}
			cp1 =  (unsigned char*)(rp + 1);
			cp2 = gv_currkey->base + rp->cmpc;
			current = 1;
			for (;;)
			{
				last = current;
				current = *cp2++ = *cp1++;
				if (0 == last && 0 == current)
					break;
				if (cp1 > (unsigned char *)rp + rec_len ||
				    cp2 > (unsigned char *)gv_currkey + gv_currkey->top)
				{
					bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
					mu_gvis();
					util_out_print(0, TRUE);
					break;
				}
			}
			if (mupip_error_occurred)
				break;
			gv_currkey->end = cp2 - gv_currkey->base - 1;
			if (need_xlation)
			{
				assert(hdr_lvl >= '3');
				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
				 	extr_std_null_coll != gv_cur_region->std_null_coll);
							/* gv_currkey would have been modified/translated in the earlier put */
				memcpy(gv_currkey->base, cmpc_str, next_cmpc);
				next_rp = (rec_hdr *)((unsigned char*)rp + rec_len);
				if ((unsigned char*)next_rp < btop)
				{
					next_cmpc = next_rp->cmpc;
					assert(next_cmpc <= gv_currkey->end);
					memcpy(cmpc_str, gv_currkey->base, next_cmpc);
				} else
					next_cmpc = 0;
							/* length of the key might change (due to nct variation),
							 * so get a copy of the original key from the extract */
				memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1);
				gvkey_char_ptr = dup_key_str;
				while (*gvkey_char_ptr++)
					;
				gv_currkey->prev = 0;
				gv_currkey->end = gvkey_char_ptr - dup_key_str;
				assert(gv_keysize <= tmp_gvkey->top);
				while (*gvkey_char_ptr)
				{
						/* get next subscript (in GT.M internal subsc format) */
					subsc_len = 0;
					tmp_ptr = src_buff;
					while (*gvkey_char_ptr)
						*tmp_ptr++ = *gvkey_char_ptr++;
					subsc_len = tmp_ptr - src_buff;
					src_buff[subsc_len] = '\0';
					if (extr_collseq)
					{
						/* undo the extract time collation */
						TREF(transform) = TRUE;
						save_gv_target_collseq = gv_target->collseq;
						gv_target->collseq = extr_collseq;
					} else
						TREF(transform) = FALSE;
						/* convert the subscript to string format */
					end_buff = gvsub2str(src_buff, dest_buff, FALSE);
						/* transform the string to the current subsc format */
					TREF(transform) = TRUE;
					tmp_mval.mvtype = MV_STR;
                                	tmp_mval.str.addr = (char *)dest_buff;
                                	tmp_mval.str.len = INTCAST(end_buff - dest_buff);
					tmp_gvkey->prev = 0;
					tmp_gvkey->end = 0;
					if (extr_collseq)
						gv_target->collseq = save_gv_target_collseq;
					mval2subsc(&tmp_mval, tmp_gvkey);
						/* we now have the correctly transformed subscript */
					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
					gv_currkey->prev = gv_currkey->end;
					gv_currkey->end += tmp_gvkey->end;
					gvkey_char_ptr++;
				}
				if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev)
				{
					if (extr_std_null_coll == 0)
					{
						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
					} else
					{
						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
					}
				}
			}
			if (gv_currkey->end >= max_key)
			{
				bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				continue;
			}
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			v.str.addr = (char*)cp1;
			v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp));
			if (max_data_len < v.str.len)
				max_data_len = v.str.len;
			bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
			if (mupip_error_occurred)
			{
				if (!mupip_DB_full)
				{
					bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count);
					util_out_print(0, TRUE);
				}
				break;
			}
			key_count++;
			global_key_count++;
		}
	}
	GTMCRYPT_ONLY(
		if (NULL != hash_array)
			free(hash_array);
	)
コード例 #20
0
ファイル: bin_load.c プロジェクト: 5HT/mumps
void bin_load(uint4 begin, uint4 end)
{
	unsigned char	*ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr;
	unsigned char	hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ],
			cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1];
	unsigned char	*end_buff;
	unsigned short	len, rec_len, next_cmpc;
	int		current, last, length, max_blk_siz, max_key, status;
	uint4		iter, max_data_len, max_subsc_len, key_count;
	ssize_t	        rec_count, global_key_count, subsc_len,extr_std_null_coll;
	boolean_t	need_xlation, new_gvn, utf8_extract;
	rec_hdr		*rp, *next_rp;
	mval		v, tmp_mval;
	mstr		mstr_src, mstr_dest;
	collseq		*extr_collseq, *db_collseq, *save_gv_target_collseq;
	coll_hdr	extr_collhdr, db_collhdr;
	gv_key 		*tmp_gvkey;
	char		std_null_coll[BIN_HEADER_NUMSZ + 1];

	error_def(ERR_GVIS);
	error_def(ERR_TEXT);
	error_def(ERR_LDBINFMT);
	error_def(ERR_LOADCTRLY);
	error_def(ERR_LOADEOF);
	error_def(ERR_MUNOFINISH);
	error_def(ERR_COLLTYPVERSION);
	error_def(ERR_COLLATIONUNDEF);
	error_def(ERR_OLDBINEXTRACT);
	error_def(ERR_LOADINVCHSET);

	tmp_gvkey = (gv_key *)malloc(sizeof(gv_key) + MAX_KEY_SZ - 1);
	assert(4 == sizeof(coll_hdr));
	gvinit();
	v.mvtype = MV_STR;
	len = mu_bin_get((char **)&ptr);
	hdr_lvl = EXTR_HEADER_LEVEL(ptr);
	if (!((hdr_lvl == '4' && len == BIN_HEADER_SZ) || (hdr_lvl < '4' && len == V3_BIN_HEADER_SZ)))
	{
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}
	/* assert the assumption that the level can be represented in a single character */
	assert(' ' == *(ptr + sizeof(BIN_HEADER_LABEL) - 3));

	if (0 != memcmp(ptr, BIN_HEADER_LABEL, sizeof(BIN_HEADER_LABEL) - 2) || hdr_lvl < '2' || *(BIN_HEADER_VERSION) < hdr_lvl)
	{				/* ignore the level check */
		rts_error(VARLSTCNT(1) ERR_LDBINFMT);
		mupip_exit(ERR_LDBINFMT);
	}

	/* check if extract was generated in UTF-8 mode */
	utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE;
	if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode))
	{ /* extract CHSET doesn't match $ZCHSET */
		if (utf8_extract)
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8"));
		else
			rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M"));
		mupip_exit(ERR_LDBINFMT);
	}

	util_out_print("Label = !AD\n", TRUE, len, ptr);
	new_gvn = FALSE;
	if (hdr_lvl > '3')
	{
		memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ);
		std_null_coll[BIN_HEADER_NUMSZ] = '\0';
		extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10);
		if (0 != extr_std_null_coll && 1!= extr_std_null_coll)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field  in header"),
				ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);

		}
	} else
		extr_std_null_coll = 0;
	if (hdr_lvl  > '2')
	{
		len = mu_bin_get((char **)&ptr);
		if (sizeof(coll_hdr) != len)
		{
			rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT);
			mupip_exit(ERR_LDBINFMT);
		}
		extr_collhdr = *((coll_hdr *)(ptr));
		new_gvn = TRUE;
	} else
		gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0');
	if (begin < 2)
		begin = 2;
	for (iter = 2; iter < begin; iter++)
	{
		if (!(len = mu_bin_get((char **)&ptr)))
		{
			gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin);
			util_out_print("Error reading record number: !UL\n", TRUE, iter);
			mupip_error_occurred = TRUE;
			return;
		} else if (len == sizeof(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			iter--;
		}
	}
	assert(iter == begin);
	util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin);
	max_data_len = 0;
	max_subsc_len = 0;
	key_count = 0;
	rec_count = begin - 1;
	extr_collseq = db_collseq = NULL;
	need_xlation = FALSE;

	for (; !mupip_DB_full ;)
	{
		if (++rec_count > end)
			break;
		next_cmpc = 0;
		mupip_error_occurred = FALSE;
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			util_out_print("!AD:!_  Key cnt: !UL  max subsc len: !UL  max data len: !UL", TRUE,
				LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len);
			util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0);
			mu_gvis();
			util_out_print(0, TRUE);
			mu_ctrlc_occurred = FALSE;
		}
		/* reset the stringpool for every record in order to avoid garbage collection */
		stringpool.free = stringpool.base;
		if (!(len = mu_bin_get((char **)&ptr)) || mupip_error_occurred)
			break;
		else if (len == sizeof(coll_hdr))
		{
			extr_collhdr = *((coll_hdr *)(ptr));
			assert(hdr_lvl > '2');
			new_gvn = TRUE;			/* next record will contain a new gvn */
			rec_count--;	/* Decrement as this record does not count as a record for loading purposes */
			continue;
		}
		global_key_count = 1;
		rp = (rec_hdr*)ptr;
		btop = ptr + len;
		cp1 = (unsigned char*)(rp + 1);
		v.str.addr = (char*)cp1;
		while (*cp1++) ;
		v.str.len =INTCAST((char*)cp1 - v.str.addr - 1);
		if (hdr_lvl <= '2' || new_gvn)
		{
			bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str);
			max_key = gv_cur_region->max_key_size;
			db_collhdr.act = gv_target->act;
			db_collhdr.ver = gv_target->ver;
			db_collhdr.nct = gv_target->nct;
		}
		GET_SHORT(rec_len, &rp->rsiz);
		if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred)
		{
			bin_call_db(ERR_COR, rec_count, global_key_count);
			mu_gvis();
			util_out_print(0, TRUE);
			continue;
		}
		if (new_gvn)
		{
			if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver
				|| db_collhdr.nct != extr_collhdr.nct
				|| gv_cur_region->std_null_coll != extr_std_null_coll))
			{
				if (extr_collhdr.act)
				{
					if (extr_collseq = ready_collseq((int)extr_collhdr.act))
					{
						if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act,
								extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				if (db_collhdr.act)
				{
					if (db_collseq = ready_collseq((int)db_collhdr.act))
					{
						if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver))
						{
							gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act,
								db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
							mupip_exit(ERR_COLLTYPVERSION);
						}
					} else
					{
						gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act,
							ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base);
						mupip_exit(ERR_COLLATIONUNDEF);
					}
				}
				need_xlation = TRUE;
			} else
				need_xlation = FALSE;
		}

		new_gvn = FALSE;
		for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len))
		{
			GET_SHORT(rec_len, &rp->rsiz);
			if (rec_len + (unsigned char *)rp > btop)
			{
				bin_call_db(ERR_COR, rec_count, global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				break;
			}
			cp1 =  (unsigned char*)(rp + 1);
			cp2 = gv_currkey->base + rp->cmpc;
			current = 1;
			for (;;)
			{
				last = current;
				current = *cp2++ = *cp1++;
				if (0 == last && 0 == current)
					break;
				if (cp1 > (unsigned char *) rp + rec_len ||
				    cp2 > (unsigned char *) gv_currkey + gv_currkey->top)
				{
					bin_call_db(ERR_COR, rec_count, global_key_count);
					mu_gvis();
					util_out_print(0, TRUE);
					break;
				}
			}
			if (mupip_error_occurred)
				break;
			gv_currkey->end = cp2 - gv_currkey->base - 1;
			if (need_xlation)
			{
				assert(hdr_lvl >= '3');
				assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct ||
				 	extr_std_null_coll != gv_cur_region->std_null_coll);
							/* gv_currkey would have been modified/translated in the earlier put */
				memcpy(gv_currkey->base, cmpc_str, next_cmpc);
				next_rp = (rec_hdr *)((unsigned char*)rp + rec_len);
				if ((unsigned char*)next_rp < btop)
				{
					next_cmpc = next_rp->cmpc;
					assert(next_cmpc <= gv_currkey->end);
					memcpy(cmpc_str, gv_currkey->base, next_cmpc);
				} else
					next_cmpc = 0;
							/* length of the key might change (due to nct variation),
							 * so get a copy of the original key from the extract */
				memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1);
				gvkey_char_ptr = dup_key_str;
				while (*gvkey_char_ptr++) ;
				gv_currkey->prev = 0;
				gv_currkey->end = gvkey_char_ptr - dup_key_str;
				tmp_gvkey->top = gv_keysize;
				while (*gvkey_char_ptr)
				{
						/* get next subscript (in GT.M internal subsc format) */
					subsc_len = 0;
					tmp_ptr = src_buff;
					while (*gvkey_char_ptr)
						*tmp_ptr++ = *gvkey_char_ptr++;
					subsc_len = tmp_ptr - src_buff;
					src_buff[subsc_len] = '\0';
					if (extr_collseq)
					{
						/* undo the extract time collation */
						transform = TRUE;
						save_gv_target_collseq = gv_target->collseq;
						gv_target->collseq = extr_collseq;
					} else
						transform = FALSE;
						/* convert the subscript to string format */
					end_buff = gvsub2str(src_buff, dest_buff, FALSE);
						/* transform the string to the current subsc format */
					transform = TRUE;
					tmp_mval.mvtype = MV_STR;
                                	tmp_mval.str.addr = (char *)dest_buff;
                                	tmp_mval.str.len = INTCAST(end_buff - dest_buff);
					tmp_gvkey->prev = 0;
					tmp_gvkey->end = 0;
					if (extr_collseq)
						gv_target->collseq = save_gv_target_collseq;
					mval2subsc(&tmp_mval, tmp_gvkey);
						/* we now have the correctly transformed subscript */
					tmp_key_ptr = gv_currkey->base + gv_currkey->end;
					memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1);
					gv_currkey->prev = gv_currkey->end;
					gv_currkey->end += tmp_gvkey->end;
					gvkey_char_ptr++;
				}
				if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev)
				{
					if (extr_std_null_coll == 0)
					{
						GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end);
					} else
					{
						STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end);
					}
				}
			}
			if (gv_currkey->end >= max_key)
			{
				bin_call_db(ERR_COR, rec_count, global_key_count);
				mu_gvis();
				util_out_print(0, TRUE);
				continue;
			}
			if (max_subsc_len < (gv_currkey->end + 1))
				max_subsc_len = gv_currkey->end + 1;
			v.str.addr = (char*)cp1;
			v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp) );
			if (max_data_len < v.str.len)
				max_data_len = v.str.len;
			bin_call_db(BIN_PUT, (INTPTR_T)&v, 0);
			if (mupip_error_occurred)
			{
				if (!mupip_DB_full)
				{
					bin_call_db(ERR_COR, rec_count, global_key_count);
					util_out_print(0, TRUE);
				}
				break;
			}
			key_count++;
			global_key_count++;
		}
	}
	free(tmp_gvkey);
	mu_load_close();
	util_out_print("LOAD TOTAL!_!_Key Cnt: !UL  Max Subsc Len: !UL  Max Data Len: !UL", TRUE, key_count, max_subsc_len,
			max_data_len);
	util_out_print("Last LOAD record number: !UL\n", TRUE, key_count ? (rec_count - 1) : 0);
	if (mu_ctrly_occurred)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_LOADCTRLY);
		mupip_exit(ERR_MUNOFINISH);
	}
}