Пример #1
0
void op_fnstack1(int level, mval *result)
{
 	int		cur_zlevel;

	result->mvtype = MV_STR;
	cur_zlevel = dollar_zlevel();

	if (-1 == level)
	{
		if (!dollar_ecode.index)
		{
			MV_FORCE_MVAL(result, cur_zlevel - 1);
		} else if ((1 < dollar_ecode.index) || (error_frame != dollar_ecode.first_ecode_error_frame))
			MV_FORCE_MVAL(result, dollar_stack.index - 1);
		else
		{	/* we are in first ECODE error-handler */
			if (cur_zlevel > dollar_stack.index)
			{
				MV_FORCE_MVAL(result, cur_zlevel - 1);
			} else
			{
				MV_FORCE_MVAL(result, dollar_stack.index - 1);
			}
		}
	} else if (0 > level)
		result->str.len = 0;
	else if (0 == level)
		get_command_line(result, FALSE);	/* FALSE to indicate we want actual (not processed) command line */
	else if (!dollar_stack.index)
	{
		if (level < cur_zlevel)
			get_frame_creation_info(level, cur_zlevel, result);
		else
			result->str.len = 0;
	} else if (level < dollar_stack.index)
		get_dollar_stack_info(level, DOLLAR_STACK_MODE, result);
	else if (!dollar_stack.incomplete && (1 == dollar_ecode.index)
			&& (error_frame == dollar_ecode.first_ecode_error_frame) && (level < cur_zlevel))
		get_frame_creation_info(level, cur_zlevel, result);
	else
		result->str.len = 0;
	return;
}
Пример #2
0
/*
 * -----------------------------------------------
 * op_fnqlength()
 * MUMPS QLength function
 *
 * Arguments:
 *	src	- Pointer to Source Name string mval
 *	dst	- destination buffer to save the piece in
 * Return:
 *	none
 * -----------------------------------------------
 */
void op_fnqlength(mval *src, mval *dst)
{
	int	dummy1;
	int	dummy2;
	int	subscripts = -2; /* no interest in finding a particular component */
	error_def(ERR_NOCANONICNAME);

	if (!is_canonic_name(src, &subscripts, &dummy1, &dummy2))
		rts_error(VARLSTCNT(4) ERR_NOCANONICNAME, 2, src->str.len, src->str.addr);
        MV_FORCE_MVAL(dst, subscripts);		/* is_canonic_name has to parse anyway, so take count from it */
	return;
}
Пример #3
0
void	zsrch_clr (int indx)
{
	lv_val	*tmp;
	mval	x;

	MV_FORCE_MVAL(&x, indx);

	op_kill(zsrch_dir1);
	op_kill(zsrch_dir2);
	tmp = op_srchindx(VARLSTCNT(2) zsrch_var, &x);
	op_kill(tmp);
}
Пример #4
0
void ztrap_save_ctxt(void)
{
	int level;
	error_def(ERR_STACKOFLOW);
	error_def(ERR_STACKCRIT);

	level = dollar_zlevel();
	if (level == MV_FORCE_INT(&ztrap_pop2level))
		return;

	PUSH_MV_STENT(MVST_MSAV);
	mv_chain->mv_st_cont.mvs_msav.v = ztrap_pop2level;
	mv_chain->mv_st_cont.mvs_msav.addr = &ztrap_pop2level;
	MV_FORCE_MVAL(&ztrap_pop2level, level);
	return;
}
Пример #5
0
/* Routine to compute the display width of a string */
void op_fnzwidth(mval* src, mval* dst)
{
	unsigned char	*srctop, *srcptr, *nextptr;
	int 		width;

	MV_FORCE_STR(src);

	srcptr = (unsigned char *)src->str.addr;
#ifdef	UNICODE_SUPPORTED
	if (!gtm_utf8_mode)
	{
#endif
		width = src->str.len;
		for (srctop = srcptr + src->str.len; srcptr < srctop; ++srcptr)
		{ /* All non-control characters are printable. Control characters are ignored (=0 width) in width calculations. */
			if ((pattern_typemask[*srcptr] & PATM_C))
				width -= 1;
		}
#ifdef	UNICODE_SUPPORTED
	} else
		width = gtm_wcswidth(srcptr, src->str.len, TRUE, 0);	/* TRUE => strict checking of BADCHARs */
#endif
	MV_FORCE_MVAL(dst, width);
}
Пример #6
0
void op_fnlength(mval *src, mval *dest)
{
	MV_FORCE_STR(src);
	MV_FORCE_LEN(src);
	MV_FORCE_MVAL(dest, (int)src->str.char_len);
}
Пример #7
0
void trigger_delete_all(void)
{
	int			count;
	char			count_str[MAX_DIGITS_IN_INT + 1];
	sgmnt_addrs		*csa;
	mval			curr_gbl_name;
	int			cycle;
	mstr			gbl_name;
	mname_entry		gvent;
	gv_namehead		*hasht_tree, *gvt;
	mval			*mv_count_ptr;
	mval			*mv_cycle_ptr;
	mval			mv_indx;
	gd_region		*reg;
	int			reg_indx;
	int4			result;
	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
	gv_key			*save_gv_currkey;
	gd_region		*save_gv_cur_region;
	gv_namehead		*save_gv_target;
	sgm_info		*save_sgm_info_ptr;
	int			trig_indx;
	mval			trigger_cycle;
	mval			trigger_count;
	mval			val;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(0 < dollar_tlevel);
	/* Before we delete any triggers, verify that none of the triggers have been fired in this transaction. If they have,
	 * this creates an un-commitable transaction that will end in a TPFAIL error. Since that error indicates database
	 * damage, we'd rather detect this avoidable condition and give a descriptive error instead (TRIGMODINTP).
	 */
	for (gvt = gv_target_list; NULL != gvt; gvt = gvt->next_gvnh)
	{
		if (gvt->trig_local_tn == local_tn)
			rts_error(VARLSTCNT(1) ERR_TRIGMODINTP);
	}
	SWITCH_TO_DEFAULT_REGION;
	INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
	if (0 != gv_target->root)
	{
		/* kill ^#t("#TRHASH") */
		BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH));
		gvcst_kill(TRUE);
		/* kill ^#t("#TNAME") */
		BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME));
		gvcst_kill(TRUE);
	}
	for (reg_indx = 0, reg = gd_header->regions; reg_indx < gd_header->n_regions; reg_indx++, reg++)
	{
		if (!reg->open)
			gv_init_reg(reg);
		if (!reg->read_only)
		{
			gv_cur_region = reg;
			change_reg();
			csa = cs_addrs;
			SETUP_TRIGGER_GLOBAL;
			INITIAL_HASHT_ROOT_SEARCH_IF_NEEDED;
			/* There might not be any ^#t in this region, so check */
			if (0 != gv_target->root)
			{	/* Kill all descendents of ^#t(trigvn, indx) where trigvn is any global with a trigger,
				 * but skip the "#XYZ" entries. setup ^#t(trigvn,"$") as the PREV key for op_gvorder
				 */
				BUILD_HASHT_SUB_CURRKEY(LITERAL_MAXHASHVAL, STRLEN(LITERAL_MAXHASHVAL));
				TREF(gv_last_subsc_null) = FALSE; /* We know its not null, but prior state is unreliable */
				while (TRUE)
				{
					op_gvorder(&curr_gbl_name);
					/* quit:$length(curr_gbl_name)=0 */
					if (0 == curr_gbl_name.str.len)
						break;
					/* $get(^#t(curr_gbl_name,#COUNT)) */
					BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len,
						LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT));
					if (gvcst_get(&trigger_count))
					{
						mv_count_ptr = &trigger_count;
						count = MV_FORCE_INT(mv_count_ptr);
						/* $get(^#t(curr_gbl_name,#CYCLE)) */
						BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len,
							LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE));
						if (!gvcst_get(&trigger_cycle))
							assert(FALSE); /* Found #COUNT, there must be #CYCLE */
						mv_cycle_ptr = &trigger_cycle;
						cycle = MV_FORCE_INT(mv_cycle_ptr);
						/* kill ^#t(curr_gbl_name) */
						BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len);
						gvcst_kill(TRUE);
						cycle++;
						MV_FORCE_MVAL(&trigger_cycle, cycle);
						/* set ^#t(curr_gbl_name,#CYCLE)=trigger_cycle */
						SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(curr_gbl_name.str.addr, curr_gbl_name.str.len,
							LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE), trigger_cycle, result);
						assert(PUT_SUCCESS == result);
					} /* else there is no #COUNT, then no triggers, leave #CYCLE alone */
					/* get ready for op_gvorder() call for next trigger under ^#t */
					BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len);
				}
				csa->incr_db_trigger_cycle = TRUE;
				if (dollar_ztrigger_invoked)
				{	/* increment db_dztrigger_cycle so that next gvcst_put/gvcst_kill in this transaction,
					 * on this region, will re-read. See trigger_update.c for a comment on why it is okay
					 * for db_dztrigger_cycle to be incremented more than once in the same transaction
					 */
					csa->db_dztrigger_cycle++;
				}
			}
		}
	}
	util_out_print_gtmio("All existing triggers deleted", FLUSH);
}
Пример #8
0
int4 trigger_delete(char *trigvn, int trigvn_len, mval *trigger_count, int index)
{
	int			count;
	mval			*mv_cnt_ptr;
	mval			mv_val;
	mval			*mv_val_ptr;
	int			num_len;
	char			*ptr1;
	int4			result;
	int4			retval;
	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
	gv_key			*save_gv_currkey;
	stringkey		kill_hash, set_hash;
	int			sub_indx;
	char			tmp_trig_str[MAX_BUFF_SIZE];
	int4			trig_len;
	char			trig_name[MAX_TRIGNAME_LEN];
	int			trig_name_len;
	int			tmp_len;
	char			*tt_val[NUM_SUBS];
	uint4			tt_val_len[NUM_SUBS];
	mval			trigger_value;
	mval			trigger_index;
	mval			xecute_index;
	uint4			xecute_idx;
	uint4			used_trigvn_len;
	mval			val;
	char			val_str[MAX_DIGITS_IN_INT + 1];
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	mv_val_ptr = &mv_val;
	MV_FORCE_MVAL(&trigger_index, index);
	count = MV_FORCE_INT(trigger_count);
	/* build up array of values - needed for comparison in hash stuff */
	ptr1 = tmp_trig_str;
	memcpy(ptr1, trigvn, trigvn_len);
	ptr1 += trigvn_len;
	*ptr1++ = '\0';
	tmp_len = trigvn_len + 1;
	for (sub_indx = 0; sub_indx < NUM_SUBS; sub_indx++)
	{
		BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[sub_indx],
						 STRLEN(trigger_subs[sub_indx]));
		trig_len = gvcst_get(&trigger_value) ? trigger_value.str.len : 0;
		if (0 == trig_len)
		{
			tt_val[sub_indx] = NULL;
			tt_val_len[sub_indx] = 0;
			continue;
		}
		if (TRIGNAME_SUB == sub_indx)
		{
			trig_name_len = trig_len;
			assert(MAX_TRIGNAME_LEN >= trig_len);
			memcpy(trig_name, trigger_value.str.addr, trig_name_len);
			tt_val[sub_indx] = NULL;
			tt_val_len[sub_indx] = 0;
			continue;
		}
		tt_val[sub_indx] = ptr1;
		tt_val_len[sub_indx] = trig_len;
		tmp_len += trig_len;
		if (0 < trig_len)
		{
			if (MAX_BUFF_SIZE <= tmp_len)
				return VAL_TOO_LONG;
			memcpy(ptr1, trigger_value.str.addr, trig_len);
			ptr1 += trig_len;
		}
		*ptr1++ = '\0';
		tmp_len++;
	}
	/* Get trigger name, set hash value, and kill hash values from trigger before we delete it.
	 * The values will be used in clean ups associated with the deletion
	 */
	/* $get(^#t(GVN,trigger_index,"LHASH") for deletion in  cleanup_trigger_hash */
	BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[LHASH_SUB],
		STRLEN(trigger_subs[LHASH_SUB]));
	if (gvcst_get(mv_val_ptr))
		kill_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr);
	else {
		util_out_print_gtmio("The LHASH for global ^!AD does not exist", FLUSH, trigvn_len, trigvn);
		kill_hash.hash_code = 0;
	}
	/* $get(^#t(GVN,trigger_index,"BHASH") for deletion in  cleanup_trigger_hash */
	BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, trigger_index, trigger_subs[BHASH_SUB],
		STRLEN(trigger_subs[BHASH_SUB]));
	if (gvcst_get(mv_val_ptr))
		set_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr);
	else {
		util_out_print_gtmio("The BHASH for global ^!AD does not exist", FLUSH, trigvn_len, trigvn);
		set_hash.hash_code = 0;
	}
	/* kill ^#t(GVN,trigger_index) */
	BUILD_HASHT_SUB_MSUB_CURRKEY(trigvn, trigvn_len, trigger_index);
	gvcst_kill(TRUE);
	assert(0 == gvcst_data());
	if (1 == count)
	{ /* This is the last trigger for "trigvn" - clean up trigger name, remove #LABEL and #COUNT */
		assert(1 == index);
		BUILD_HASHT_SUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHLABEL, STRLEN(LITERAL_HASHLABEL));
		gvcst_kill(TRUE);
		BUILD_HASHT_SUB_SUB_CURRKEY(trigvn, trigvn_len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT));
		gvcst_kill(TRUE);
		cleanup_trigger_name(trigvn, trigvn_len, trig_name, trig_name_len);
		cleanup_trigger_hash(trigvn, trigvn_len, tt_val, tt_val_len, &set_hash, &kill_hash, TRUE, 0);
	} else
	{
		cleanup_trigger_hash(trigvn, trigvn_len, tt_val, tt_val_len, &set_hash, &kill_hash, TRUE, index);
		cleanup_trigger_name(trigvn, trigvn_len, trig_name, trig_name_len);
		if (index != count)
		{	/* Shift the last trigger (index is #COUNT value) to the just deleted trigger's index.
			 * This way count is always accurate and can still be used as the index for new triggers.
			 * Note - there is no dependence on the trigger order, or this technique wouldn't work.
			 */
			ptr1 = tmp_trig_str;
			memcpy(ptr1, trigvn, trigvn_len);
			ptr1 += trigvn_len;
			*ptr1++ = '\0';
			for (sub_indx = 0; sub_indx < NUM_TOTAL_SUBS; sub_indx++)
			{
				/* $get(^#t(GVN,trigger_count,sub_indx) */
				BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[sub_indx],
								STRLEN(trigger_subs[sub_indx]));
				if (gvcst_get(&trigger_value))
				{
					trig_len = trigger_value.str.len;
					/* set ^#t(GVN,trigger_index,sub_indx)=^#t(GVN,trigger_count,sub_indx) */
					SET_TRIGGER_GLOBAL_SUB_MSUB_SUB_MVAL(trigvn, trigvn_len, trigger_index,
						trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), trigger_value, result);
					assert(PUT_SUCCESS == result);
				} else if (XECUTE_SUB == sub_indx)
				{ /* multi line trigger broken up because it exceeds record size */
					for (xecute_idx = 0; ; xecute_idx++)
					{
						i2mval(&xecute_index, xecute_idx);
						BUILD_HASHT_SUB_MSUB_SUB_MSUB_CURRKEY(trigvn, trigvn_len, *trigger_count,
							trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), xecute_index);
						if (!gvcst_get(&trigger_value))
							break;
						SET_TRIGGER_GLOBAL_SUB_MSUB_SUB_MSUB_MVAL(trigvn, trigvn_len, trigger_index,
							trigger_subs[sub_indx], STRLEN(trigger_subs[sub_indx]), xecute_index,
							trigger_value, result);
						assert(PUT_SUCCESS == result);
					}
					assert (xecute_idx >= 2); /* multi-line trigger, indices 0, 1 and 2 MUST be defined */
				} else
				{
					/* in PRO this is a nasty case that will result in an access violation
					 * because data that should be present is not. In the next go around
					 * with trigger installation this case should be handled better */
					assert(!((TRIGNAME_SUB == sub_indx) || (CMD_SUB == sub_indx) ||
						 (CHSET_SUB == sub_indx))); /* these should not be zero length */
					trig_len = 0;
				}
				if (NUM_SUBS > sub_indx)
				{
					tt_val[sub_indx] = ptr1;
					tt_val_len[sub_indx] = trig_len;
					if (0 < trig_len)
					{
						memcpy(ptr1, trigger_value.str.addr, trig_len);
						ptr1 += trig_len;
					}
					*ptr1++ = '\0';
				}
			}
			/* $get(^#t(GVN,trigger_count,"LHASH") for update_trigger_hash_value */
			BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[LHASH_SUB],
							 STRLEN(trigger_subs[LHASH_SUB]));
			if (!gvcst_get(mv_val_ptr))
				return PUT_SUCCESS;
			kill_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr);
			/* $get(^#t(GVN,trigger_count,"BHASH") for update_trigger_hash_value */
			BUILD_HASHT_SUB_MSUB_SUB_CURRKEY(trigvn, trigvn_len, *trigger_count, trigger_subs[BHASH_SUB],
							 STRLEN(trigger_subs[BHASH_SUB]));
			if (!gvcst_get(mv_val_ptr))
				return PUT_SUCCESS;
			set_hash.hash_code = (uint4)MV_FORCE_INT(mv_val_ptr);
			/* update hash values from above */
			if (VAL_TOO_LONG == (retval = update_trigger_hash_value(trigvn, trigvn_len, tt_val, tt_val_len,
					&set_hash, &kill_hash, count, index)))
				return VAL_TOO_LONG;
			/* fix the value ^#t("#TNAME",^#t(GVN,index,"#TRIGNAME")) to point to the correct "index" */
			if (VAL_TOO_LONG == (retval = update_trigger_name_value(trigvn_len, tt_val[TRIGNAME_SUB],
					tt_val_len[TRIGNAME_SUB], index)))
				return VAL_TOO_LONG;
			/* kill ^#t(GVN,COUNT) which was just shifted to trigger_index */
			BUILD_HASHT_SUB_MSUB_CURRKEY(trigvn, trigvn_len, *trigger_count);
			gvcst_kill(TRUE);
		}
		/* Update #COUNT */
		count--;
		MV_FORCE_MVAL(trigger_count, count);
		SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(trigvn, trigvn_len, LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT), *trigger_count,
			result);
		assert(PUT_SUCCESS == result);		/* Size of count can only get shorter or stay the same */
	}
	trigger_incr_cycle(trigvn, trigvn_len);
	return PUT_SUCCESS;
}
Пример #9
0
short rc_fnd_file(rc_xdsid *xdsid)
{
	gv_namehead	*g;
	short		dsid, node;
	gd_binding	*map;
	char		buff[1024], *cp, *cp1;
	mstr		fpath1, fpath2;
	mval		v;
	int		i, keysize;
	int             len, node2;

	GET_SHORT(dsid, &xdsid->dsid.value);
	GET_SHORT(node, &xdsid->node.value);
	if (!dsid_list)
	{
		/*	open special database, set up entry */
		dsid_list = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list));
		dsid_list->dsid = RC_NSPACE_DSID;
		dsid_list->next = NULL;
		fpath1.addr = RC_NSPACE_PATH;
		fpath1.len = SIZEOF(RC_NSPACE_PATH);
		if (SS_NORMAL != TRANS_LOG_NAME(&fpath1, &fpath2, buff, SIZEOF(buff), do_sendmsg_on_log2long))
		{
			char msg[256];
			SPRINTF(msg, "Invalid DB filename, \"%s\"", fpath1.addr);
			gtcm_rep_err(msg, errno);
			return RC_BADFILESPEC;
		}
		if (fpath2.len > MAX_FN_LEN)
			return RC_BADFILESPEC;
		dsid_list->fname = (char *)malloc(fpath2.len + 1);
		memcpy(dsid_list->fname, fpath2.addr, fpath2.len);
		*((char*)(dsid_list->fname + fpath2.len)) = 0;
		gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region));
		memset(gv_cur_region, 0, SIZEOF(gd_region));
		gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment));
		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
		memcpy(gv_cur_region->dyn.addr->fname, fpath2.addr, fpath2.len);
		gv_cur_region->dyn.addr->fname_len = fpath2.len;
		gv_cur_region->dyn.addr->acc_meth = dba_bg;
		ESTABLISH_RET(rc_fnd_file_ch1, RC_SUCCESS);
		gvcst_init(gv_cur_region);
		REVERT;
		change_reg();
		/* check to see if this DB has the reserved bytes field set
		 * correctly.  Global pages must always have some extra unused
		 * space left in them (RC_RESERVED bytes) so that the page
		 * will fit into the client buffer when unpacked by the
		 * client.
		 */
		if (cs_data->reserved_bytes < RC_RESERVED)
		{
			OMI_DBG((omi_debug,
			"Unable to access database file:  \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n",
			fpath2.addr));
			free(dsid_list->fname);
			dsid_list->fname = NULL;
			free(dsid_list);
			dsid_list = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		gv_keysize = DBKEYSIZE(gv_cur_region->max_key_size);
		GVKEY_INIT(gv_currkey, gv_keysize);
		GVKEY_INIT(gv_altkey, gv_keysize);
		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (gv_keysize - 1));
		g = cs_addrs->dir_tree;
		g->first_rec = (gv_key*)(g->clue.base + gv_keysize);
		g->last_rec = (gv_key*)(g->first_rec->base + gv_keysize);
		g->clue.top = g->last_rec->top = g->first_rec->top = gv_keysize;
		g->clue.prev = g->clue.end = 0;
		g->root = DIR_ROOT;
		dsid_list->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
		dsid_list->gda->n_maps = 3;
		dsid_list->gda->n_regions = 1;
		dsid_list->gda->n_segments = 1;
		dsid_list->gda->maps = (gd_binding*)((char*)dsid_list->gda + SIZEOF(gd_addr));
		dsid_list->gda->max_rec_size = gv_cur_region->max_rec_size;
		map = dsid_list->gda->maps;
		map ++;
		memset(map->name, 0, SIZEOF(map->name));
		map->name[0] = '%';
		map->reg.addr = gv_cur_region;
		map++;
		map->reg.addr = gv_cur_region;
		memset(map->name, -1, SIZEOF(map->name));
		dsid_list->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
		init_hashtab_mname(dsid_list->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
		change_reg();
		if (rc_overflow->top < cs_addrs->hdr->blk_size)
		{
			if (rc_overflow->buff)
				free(rc_overflow->buff);
			rc_overflow->top = cs_addrs->hdr->blk_size;
			rc_overflow->buff = (char*)malloc(rc_overflow->top);
			if (rc_overflow_size < rc_overflow->top)
				rc_overflow_size = rc_overflow->top;
		}
	}
	for (fdi_ptr = dsid_list; fdi_ptr && (fdi_ptr->dsid != dsid); fdi_ptr = fdi_ptr->next)
		;
	if (!fdi_ptr)
	{	/*	need to open new database, add to list, set fdi_ptr */
		gd_header = dsid_list->gda;
		gv_currkey->end = 0;
		v.mvtype = MV_STR;
		v.str.len = RC_NSPACE_GLOB_LEN-1;
		v.str.addr = RC_NSPACE_GLOB;
		GV_BIND_NAME_AND_ROOT_SEARCH(gd_header, &v.str);
		if (!gv_target->root)	/* No namespace global */
			return RC_UNDEFNAMSPC;
		v.mvtype = MV_STR;
		v.str.len = SIZEOF(RC_NSPACE_DSI_SUB)-1;
		v.str.addr = RC_NSPACE_DSI_SUB;
		mval2subsc(&v,gv_currkey);
		node2 = node;
		MV_FORCE_MVAL(&v,node2);
		mval2subsc(&v,gv_currkey);
		i = dsid / 256;
		MV_FORCE_MVAL(&v,i);
		mval2subsc(&v,gv_currkey);
		if (gvcst_get(&v))
			return RC_UNDEFNAMSPC;
		for (cp = v.str.addr, i = 1; i < RC_FILESPEC_PIECE; i++)
			for (; *cp++ != RC_FILESPEC_DELIM; )
				;
		for (cp1 = cp; *cp1++ != RC_FILESPEC_DELIM; )
			;
		cp1--;
		len = (int)(cp1 - cp);
		if (len > MAX_FN_LEN)
			return RC_BADFILESPEC;
		fdi_ptr = (rc_dsid_list *)malloc(SIZEOF(rc_dsid_list));
		fdi_ptr->fname = (char *)malloc(len+1);
		fdi_ptr->dsid = dsid;
		memcpy(fdi_ptr->fname, cp, len);
		*(fdi_ptr->fname + (len)) = 0;
		gv_cur_region = (gd_region *)malloc(SIZEOF(gd_region));
		memset(gv_cur_region, 0, SIZEOF(gd_region));
		gv_cur_region->dyn.addr = (gd_segment *)malloc(SIZEOF(gd_segment));
		memset(gv_cur_region->dyn.addr, 0, SIZEOF(gd_segment));
		memcpy(gv_cur_region->dyn.addr->fname, cp, len);
		gv_cur_region->dyn.addr->fname_len = len;
		gv_cur_region->dyn.addr->acc_meth = dba_bg;
		ESTABLISH_RET(rc_fnd_file_ch2, RC_SUCCESS);
		gvcst_init(gv_cur_region);
		REVERT;
		change_reg();
		/* check to see if this DB has the reserved bytes field set
		 * correctly.  Global pages must always have some extra unused
		 * space left in them (RC_RESERVED bytes) so that the page
		 * will fit into the client buffer when unpacked by the
		 * client.
		 */
		if (cs_data->reserved_bytes < RC_RESERVED)
		{
			OMI_DBG((omi_debug,
			"Unable to access database file:  \"%s\"\nReserved_bytes field in the file header is too small for GT.CM\n",
			fdi_ptr->fname));
			free(dsid_list->fname);
			dsid_list->fname = NULL;
			free(dsid_list);
			dsid_list = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		assert(!cs_addrs->hold_onto_crit);	/* this ensures we can safely do unconditional grab_crit and rel_crit */
		grab_crit(gv_cur_region);
		cs_data->rc_srv_cnt++;
		if (!cs_data->dsid)
		{
			cs_data->dsid = dsid;
			cs_data->rc_node = node;
		} else if (cs_data->dsid != dsid || cs_data->rc_node != node)
		{
			cs_data->rc_srv_cnt--;
			rel_crit(gv_cur_region);
			OMI_DBG((omi_debug, "Dataset ID/RC node mismatch"));
			OMI_DBG((omi_debug, "DB file:  \"%s\"\n", dsid_list->fname));
			OMI_DBG((omi_debug, "Stored DSID:  %d\tRC Node:  %d\n", cs_data->dsid, cs_data->rc_node));
			OMI_DBG((omi_debug, "RC Rq DSID:  %d\tRC Node:  %d\n", dsid,node));
			free(fdi_ptr->fname);
			fdi_ptr->fname = NULL;
			free(fdi_ptr);
			fdi_ptr = NULL;
			free(gv_cur_region->dyn.addr);
			gv_cur_region->dyn.addr = NULL;
			free(gv_cur_region);
			gv_cur_region = NULL;
			return RC_FILEACCESS;
		}
		rel_crit(gv_cur_region);
		keysize = DBKEYSIZE(gv_cur_region->max_key_size);
		GVKEYSIZE_INCREASE_IF_NEEDED(keysize);
		cs_addrs->dir_tree = (gv_namehead *)malloc(SIZEOF(gv_namehead) + 2 * SIZEOF(gv_key) + 3 * (keysize - 1));
		g = cs_addrs->dir_tree;
		g->first_rec = (gv_key*)(g->clue.base + keysize);
		g->last_rec = (gv_key*)(g->first_rec->base + keysize);
		g->clue.top = g->last_rec->top = g->first_rec->top = keysize;
		g->clue.prev = g->clue.end = 0;
		g->root = DIR_ROOT;
		fdi_ptr->gda = (gd_addr*)malloc(SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding));
		fdi_ptr->gda->n_maps = 3;
		fdi_ptr->gda->n_regions = 1;
		fdi_ptr->gda->n_segments = 1;
		fdi_ptr->gda->maps = (gd_binding*)((char*)fdi_ptr->gda + SIZEOF(gd_addr));
		fdi_ptr->gda->max_rec_size = gv_cur_region->max_rec_size;
		map = fdi_ptr->gda->maps;
		map ++;
		memset(map->name, 0, SIZEOF(map->name));
		map->name[0] = '%';
		map->reg.addr = gv_cur_region;
		map++;
		map->reg.addr = gv_cur_region;
		memset(map->name, -1, SIZEOF(map->name));
		fdi_ptr->gda->tab_ptr = (hash_table_mname *)malloc(SIZEOF(hash_table_mname));
		init_hashtab_mname(fdi_ptr->gda->tab_ptr, 0, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
		fdi_ptr->next = dsid_list->next;
		dsid_list->next = fdi_ptr;
	}
	gv_cur_region = fdi_ptr->gda->maps[1].reg.addr;
	change_reg();
	if (rc_overflow->top < cs_addrs->hdr->blk_size)
	{
		if (rc_overflow->buff)
			free(rc_overflow->buff);
		rc_overflow->top = cs_addrs->hdr->blk_size;
		rc_overflow->buff = (char*)malloc(rc_overflow->top);
		if (rc_overflow_size < rc_overflow->top)
			rc_overflow_size = rc_overflow->top;
	}
	if (!rc_overflow -> top)
	{
		rc_overflow -> top = rc_overflow_size;
		rc_overflow->buff = (char *)malloc(rc_overflow->top);
	}
	gd_header = fdi_ptr->gda;
	return RC_SUCCESS;
}
Пример #10
0
int m_merge(void)
{
	int		type;
	boolean_t	used_glvn_slot;
	mval		mv;
	opctype 	put_oc;
	oprtype 	mopr, control_slot;
	triple		*obp, *ref, *restart, *s1, *sub, tmpchain;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	used_glvn_slot = FALSE;
	sub = NULL;
	restart = newtriple(OC_RESTARTPC);	/* Here is where a restart should pick up */
	dqinit(&tmpchain, exorder);
	/* Left Hand Side of EQUAL sign */
	switch (TREF(window_token))
	{
		case TK_IDENT:
			if (!lvn(&mopr, OC_PUTINDX, 0))
				return FALSE;
			if (OC_PUTINDX == mopr.oprval.tref->opcode)
			{	/* we insert left hand side argument into tmpchain. */
				sub = mopr.oprval.tref;
				put_oc = OC_PUTINDX;
				dqdel(mopr.oprval.tref, exorder);
				dqins(tmpchain.exorder.bl, exorder, mopr.oprval.tref);
			}
			ref = maketriple(OC_MERGE_LVARG);
			ref->operand[0] = put_ilit(MARG1_LCL);
			ref->operand[1] = mopr;
			dqins(tmpchain.exorder.bl, exorder, ref);
			break;
		case TK_CIRCUMFLEX:
			s1 = (TREF(curtchain))->exorder.bl;
			if (!gvn())
				return FALSE;
			assert(OC_GVRECTARG != (TREF(curtchain))->opcode);	/* we count on gvn not having been shifted */
			for (sub = (TREF(curtchain))->exorder.bl; sub != s1; sub = sub->exorder.bl)
			{
				put_oc = sub->opcode;
				if (OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc)
					break;
			}
			assert((OC_GVNAME == put_oc) || (OC_GVNAKED == put_oc) || (OC_GVEXTNAM == put_oc));
			/* we insert left hand side argument into tmpchain. */
			dqdel(sub, exorder);
			dqins(tmpchain.exorder.bl ,exorder, sub);
			ref = maketriple(OC_MERGE_GVARG);
			ref->operand[0] = put_ilit(MARG1_GBL);
			dqins(tmpchain.exorder.bl, exorder, ref);
			break;
		case TK_ATSIGN:
			if (!indirection(&mopr))
				return FALSE;
			if (TK_EQUAL != TREF(window_token))
			{
				ref = newtriple(OC_COMMARG);
				ref->operand[0] = mopr;
				ref->operand[1] = put_ilit((mint) indir_merge);
				return TRUE;
			}
			type = MARG1_LCL | MARG1_GBL;
			memset(&mv, 0, SIZEOF(mval));	/* Initialize so unused fields don't cause object hash differences */
			MV_FORCE_MVAL(&mv, type);
			MV_FORCE_STRD(&mv);
			if (TREF(side_effect_handling))
			{	/* save and restore the variable lookup for true left-to-right evaluation */
				used_glvn_slot = TRUE;
				INSERT_INDSAVGLVN(control_slot, mopr, ANY_SLOT, 0);	/* 0 flag to defer global reference */
				ref = maketriple(OC_INDMERGE2);
				ref->operand[0] = control_slot;
			} else
			{	/* quick and dirty old way */
				ref = maketriple(OC_INDMERGE);
				ref->operand[0] = put_lit(&mv);
				ref->operand[1] = mopr;
			}
			/* we insert left hand side argument into tmpchain. */
			dqins(tmpchain.exorder.bl, exorder, ref);
			break;
		default:
			stx_error(ERR_VAREXPECTED);
			return FALSE;
	}
	if (TREF(window_token) != TK_EQUAL)
	{
		stx_error(ERR_EQUAL);
		return FALSE;
	}
	advancewindow();
	/* Right Hand Side of EQUAL sign */
	TREF(temp_subs) = FALSE;
	switch (TREF(window_token))
	{
		case TK_IDENT:
			if (!lvn(&mopr, OC_M_SRCHINDX, 0))
				return FALSE;
			ref = newtriple(OC_MERGE_LVARG);
			ref->operand[0] = put_ilit(MARG2_LCL);
			ref->operand[1] = mopr;
			break;
		case TK_CIRCUMFLEX:
			if (!gvn())
				return FALSE;
			ref = newtriple(OC_MERGE_GVARG);
			ref->operand[0] = put_ilit(MARG2_GBL);
			break;
		case TK_ATSIGN:
			TREF(temp_subs) = TRUE;
			if (!indirection(&mopr))
			{
				stx_error(ERR_VAREXPECTED);
				return FALSE;
			}
			type = MARG2_LCL | MARG2_GBL;
			memset(&mv, 0, SIZEOF(mval));	/* Initialize so unused fields don't cause object hash differences */
			MV_FORCE_MVAL(&mv, type);
			MV_FORCE_STRD(&mv);
			ref = maketriple(OC_INDMERGE);
			ref->operand[0] =  put_lit(&mv);
			ref->operand[1] = mopr;
			ins_triple(ref);
			break;
		default:
			stx_error(ERR_VAREXPECTED);
			return FALSE;
	}
	/*
	 * Make sure that during runtime right hand side argument is processed first.
	 * This is specially important if global naked variable is used .
	 */
	obp = (TREF(curtchain))->exorder.bl;
	dqadd(obp, &tmpchain, exorder);
	if (TREF(temp_subs) && TREF(side_effect_handling) && sub)
		create_temporaries(sub, put_oc);
	TREF(temp_subs) = FALSE;
	if (used_glvn_slot)
	{
		ref = newtriple(OC_GLVNPOP);
		ref->operand[0] = control_slot;
	}
	ref = newtriple(OC_MERGE);
	return TRUE;
}
Пример #11
0
int m_merge(void)
{
	error_def(ERR_VAREXPECTED);
	error_def(ERR_RPARENMISSING);
	error_def(ERR_EQUAL);

	opctype 	put_oc;
	oprtype 	mopr;
	triple		*sub, *ref,  *obp, *s1, *restart, tmpchain;
	mval		mv;
	int		type;

	restart = newtriple(OC_RESTARTPC);	/* Here is where a restart should pick up */

	dqinit(&tmpchain, exorder);
	/* Left Hand Side of EQUAL sign */
	switch (window_token)
	{
        case TK_IDENT:
                if (!lvn(&mopr, OC_PUTINDX, 0))
                        return FALSE;
		if (OC_PUTINDX == mopr.oprval.tref->opcode);
		{
			/* we insert left hand side argument into tmpchain. */
			dqdel(mopr.oprval.tref, exorder);
			dqins(tmpchain.exorder.bl, exorder, mopr.oprval.tref);
		}
		ref = maketriple(OC_MERGE_LVARG);
		ref->operand[0] = put_ilit(MARG1_LCL);
		ref->operand[1] = mopr;
		dqins(tmpchain.exorder.bl, exorder, ref);
                break;
        case TK_CIRCUMFLEX:
		s1 = curtchain->exorder.bl;
                if (!gvn())
                        return FALSE;
		for (sub = curtchain->exorder.bl; sub != s1; sub = sub->exorder.bl)
		{
			put_oc = sub->opcode;
			if (OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc)
				break;
		}
		assert(OC_GVNAME == put_oc || OC_GVNAKED == put_oc || OC_GVEXTNAM == put_oc);
		/* we insert left hand side argument into tmpchain. */
		dqdel(sub, exorder);
		dqins(tmpchain.exorder.bl ,exorder, sub);
		ref = maketriple(OC_MERGE_GVARG);
		ref->operand[0] = put_ilit(MARG1_GBL);
		dqins(tmpchain.exorder.bl, exorder, ref);
                break;
        case TK_ATSIGN:
                if (!indirection(&mopr))
                        return FALSE;
		if (window_token != TK_EQUAL)
		{
			ref = newtriple(OC_COMMARG);
			ref->operand[0] = mopr;
                	ref->operand[1] = put_ilit((mint) indir_merge);
			ins_triple(ref);
			return TRUE;
		}
		type = MARG1_LCL | MARG1_GBL;
		MV_FORCE_MVAL(&mv, type);
		MV_FORCE_STR(&mv);
                ref = maketriple(OC_INDMERGE);
                ref->operand[0] = put_lit(&mv);
                ref->operand[1] = mopr;
		/* we insert left hand side argument into tmpchain. */
		dqins(tmpchain.exorder.bl, exorder, ref);
                break;
	default:
		stx_error(ERR_VAREXPECTED);
		return FALSE;
	}

	if (window_token != TK_EQUAL)
	{
		stx_error(ERR_EQUAL);
		return FALSE;
	}
	advancewindow();

	/* Right Hand Side of EQUAL sign */
	switch (window_token)
	{
        case TK_IDENT:
                if (!lvn(&mopr, OC_M_SRCHINDX, 0))
                        return FALSE;
		ref = newtriple(OC_MERGE_LVARG);
		ref->operand[0] = put_ilit(MARG2_LCL);
		ref->operand[1] = mopr;
		break;
        case TK_CIRCUMFLEX:
                if (!gvn())
                        return FALSE;
		ref = newtriple(OC_MERGE_GVARG);
		ref->operand[0] = put_ilit(MARG2_GBL);
		break;
        case TK_ATSIGN:
                if (!indirection(&mopr))
		{
			stx_error(ERR_VAREXPECTED);
                        return FALSE;
		}
		type = MARG2_LCL | MARG2_GBL;
		MV_FORCE_MVAL(&mv, type);
		MV_FORCE_STR(&mv);
                ref = maketriple(OC_INDMERGE);
                ref->operand[0] =  put_lit(&mv);
                ref->operand[1] = mopr;
                ins_triple(ref);
		break;
	default:
		stx_error(ERR_VAREXPECTED);
		return FALSE;
	}
	/*
	 * Make sure that during runtime right hand side argument is processed first.
	 * This is specially important if global naked variable is used .
	 */
	obp = curtchain->exorder.bl;
	dqadd(obp, &tmpchain, exorder);
	ref = newtriple(OC_MERGE);
	return TRUE;
}
Пример #12
0
/* routine to convert external return values to mval's */
static void	extarg2mval(void *src, enum xc_types typ, mval *dst)
{
	int			str_len;
	int4			s_int_num;
	uint4			uns_int_num;
	char			*cp;
	struct extcall_string	*sp;
	error_def(ERR_ZCSTATUSRET);
	error_def(ERR_MAXSTRLEN);

	switch(typ)
	{
	case xc_notfound:
		break;
	case xc_void:
		break;
	case xc_status:
		s_int_num = (int4)src;
		if (0 != s_int_num)
			dec_err(VARLSTCNT(1) ERR_ZCSTATUSRET,0,s_int_num);
		MV_FORCE_MVAL(dst, s_int_num);
		break;
	case xc_long:
		s_int_num = (int4)src;
		MV_FORCE_MVAL(dst, s_int_num);
		break;
	case xc_ulong:
		uns_int_num = (uint4)src;
		MV_FORCE_ULONG_MVAL(dst, uns_int_num);
		break;
	case xc_long_star:
		s_int_num = *((int4 *)src);
		MV_FORCE_MVAL(dst, s_int_num);
		break;
	case xc_ulong_star:
		uns_int_num = *((uint4 *)src);
		MV_FORCE_ULONG_MVAL(dst, uns_int_num);
		break;
	case xc_string_star:
		sp = (struct extcall_string *)src;
		dst->mvtype = MV_STR;
		if (sp->len > MAX_STRLEN)
			rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
		dst->str.len = sp->len;
		if ((0 < sp->len) && (NULL != sp->addr))
		{
			dst->str.addr = sp->addr;
			s2pool(&dst->str);
		}
		break;
	case xc_float_star:
		double2mval(dst, (double)*((float *)src));
		break;
	case xc_char_star:
		cp = (char *)src;
		assert(((int)cp < (int)stringpool.base) || ((int)cp > (int)stringpool.top));
		dst->mvtype = MV_STR;
		str_len = strlen(cp);
		if (str_len > MAX_STRLEN)
			rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
		dst->str.len = str_len;
		dst->str.addr = cp;
		s2pool(&dst->str);
		break;
	case xc_char_starstar:
		if (!src)
			dst->mvtype = 0;
		else
			extarg2mval(*((char **)src), xc_char_star, dst);
		break;
	case xc_double_star:
		double2mval(dst, *((double *)src));
		break;
	default:
		rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
		break;
	}
	return;
}
Пример #13
0
void op_fnztrnlnm(mval *name,mval *table,int4 ind,mval *mode,mval *case_blind,mval *item,mval *ret)
{
	struct dsc$descriptor	lname, ltable;
	uint4		attribute, status, retlen, mask, full_mask;
	char			acmode;
	short int		*item_code, pass, index;
	bool			full;
	char			buff[256], result[MAX_RESULT_SIZE];
	char			i, slot, last_slot;
	char			def_table[] = "LNM$DCL_LOGICAL";

	struct
	{
		item_list_3	item[3];
		int4		terminator;
	} item_list;
	error_def(ERR_BADTRNPARAM);

	if(!name->str.len || MAX_LOGNAM_LENGTH < name->str.len || MAX_LOGNAM_LENGTH < table->str.len)
		rts_error(VARLSTCNT(1) SS$_IVLOGNAM);
	memset(&item_list,0,SIZEOF(item_list));
	item_list.item[0].item_code = 0;
	item_list.item[0].buffer_address = result;
	item_list.item[0].buffer_length = MAX_RESULT_SIZE;
	item_list.item[0].return_length_address = &retlen;
	item_code = &item_list.item[0].item_code;

	lname.dsc$w_length = name->str.len;
	lname.dsc$a_pointer = name->str.addr;
	lname.dsc$b_dtype = DSC$K_DTYPE_T;
	lname.dsc$b_class = DSC$K_CLASS_S;

	if (table->str.len)
	{	ltable.dsc$w_length = table->str.len;
		ltable.dsc$a_pointer = table->str.addr;
	}else
	{	ltable.dsc$a_pointer = def_table;
		ltable.dsc$w_length = strlen(def_table);
	}
	ltable.dsc$b_dtype = DSC$K_DTYPE_T;
	ltable.dsc$b_class = DSC$K_CLASS_S;

	if(ind)
	{	item_list.item[0].item_code = LNM$_INDEX;
		item_list.item[0].buffer_address = &ind;
		item_list.item[1].item_code = 0;
		item_list.item[1].buffer_address = result;
		item_list.item[1].buffer_length = MAX_RESULT_SIZE;
		item_list.item[1].return_length_address = &retlen;
		item_code = &item_list.item[1].item_code;
	}

	attribute = LNM$M_CASE_BLIND;
	if (case_blind->str.len)
	{
		if (case_blind->str.len > 14)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, case_blind->str.len), case_blind->str.addr);
		lower_to_upper(buff,case_blind->str.addr,case_blind->str.len);
		if (case_blind->str.len == 14 && !memcmp(buff,"CASE_SENSITIVE",14))
			attribute = 0;
		else if (case_blind->str.len != 10 || memcmp(buff,"CASE_BLIND",10))
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,case_blind->str.len,case_blind->str.addr);
	}

	acmode = NOVALUE;
	if (mode->str.len)
	{
		if (mode->str.len > 14)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, mode->str.len), mode->str.addr);
		lower_to_upper(buff,mode->str.addr,mode->str.len);
		switch (buff[0])
		{
		case 'U':
			if ( mode->str.len = 4 && !memcmp(buff, "USER", 4))
				acmode = PSL$C_USER;
		case 'S':
			if ( mode->str.len = 10 && !memcmp(buff, "SUPERVISOR", 10))
				acmode = PSL$C_SUPER;
		case 'K':
			if ( mode->str.len = 6 && !memcmp(buff, "KERNEL", 6))
				acmode = PSL$C_KERNEL;
		case 'E':
			if ( mode->str.len = 9 && !memcmp(buff, "EXECUTIVE", 9))
				acmode = PSL$C_EXEC;
		}
		if (acmode == NOVALUE)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,mode->str.len,mode->str.addr);
	}

	full = FALSE;
	*item_code = NOVALUE;
	if (item->str.len)
	{	if (item->str.len > 12)
			rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2,
				MIN(SHRT_MAX, item->str.len), item->str.addr);
		lower_to_upper(buff,item->str.addr,item->str.len);
		if ((i = buff[0] - 'A') < MIN_INDEX || i > MAX_INDEX)
		{	rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, item->str.len, item->str.addr);
		}
		if ( trnlnm_index[i].len)
		{	slot = trnlnm_index[i].index;
			last_slot = trnlnm_index[i].len;
			for (; slot < last_slot; slot++)
			{	if (item->str.len == trnlnm_table[slot].len &&
					!memcmp(trnlnm_table[slot].name, buff, item->str.len))
				{	if (trnlnm_table[slot].item_code == FULL_VALUE)
					{	if (ind)
							index = 2;
						else
							index = 1;
						*item_code = LNM$_STRING;
						item_list.item[index].buffer_address = &full_mask;
						item_list.item[index].buffer_length = SIZEOF(full_mask);
						item_list.item[index].item_code = LNM$_ATTRIBUTES;
						item_code = &item_list.item[index].item_code;
						full = TRUE;
					}else
					{	*item_code = trnlnm_table[slot].item_code;
					}
					break;
				}
			}
		}
		if (*item_code == NOVALUE)
		{	rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,item->str.len,item->str.addr);
		}
	}else
	{	*item_code = LNM$_STRING;
	}
	for ( pass = 0 ; ; pass++ )
	{	retlen = 0;
		status = sys$trnlnm(&attribute, &ltable, &lname, acmode == NOVALUE ? 0 : &acmode, &item_list);
		if (status & 1)
		{	if (*item_code == LNM$_STRING || *item_code == LNM$_TABLE)
			{	ret->mvtype = MV_STR;
				ENSURE_STP_FREE_SPACE(retlen);
				ret->str.addr = stringpool.free;
				ret->str.len = retlen;
				memcpy(ret->str.addr, result, retlen);
				stringpool.free += retlen;
				return;
			}else if (*item_code == LNM$_LENGTH || *item_code == LNM$_MAX_INDEX)
			{
				MV_FORCE_MVAL(ret,*(int4 *)result) ;
				n2s(ret);
				return;
			}else if (*item_code == LNM$_ACMODE)
			{	ret->mvtype = MV_STR;
				switch(*result)
				{	case PSL$C_USER:
						ENSURE_STP_FREE_SPACE(4);
						ret->str.addr = stringpool.free;
						ret->str.len = 4;
						memcpy(ret->str.addr, "USER", 4);
						stringpool.free += 4;
						return;
					case PSL$C_SUPER:
						ENSURE_STP_FREE_SPACE(5);
						ret->str.addr = stringpool.free;
						ret->str.len = 5;
						memcpy(ret->str.addr, "SUPER", 5);
						stringpool.free += 5;
						return;
					case PSL$C_EXEC:
						ENSURE_STP_FREE_SPACE(9);
						ret->str.addr = stringpool.free;
						ret->str.len = 9;
						memcpy(ret->str.addr, "EXECUTIVE", 9);
						stringpool.free += 9;
						return;
					case PSL$C_KERNEL:
						ENSURE_STP_FREE_SPACE(6);
						ret->str.addr = stringpool.free;
						ret->str.len = 6;
						memcpy(ret->str.addr, "KERNEL", 6);
						stringpool.free += 6;
						return;
					default:
						GTMASSERT;
				}
			}else
			{	assert(*item_code == LNM$_ATTRIBUTES);
				if (full)
				{	if (!retlen)	/* If the logical name exists, but has no entry for the specified index, */
					{		/* then the return status will be normal as the TERMINAL attribute will  */
							/* be filled in, but there will be no equivalence name, thus retlen == 0 */
						ret->mvtype = MV_STR;
						if (!pass)
						{	ret->str.len = 0;
							return;
						}
						ENSURE_STP_FREE_SPACE(lname.dsc$w_length);
						ret->str.addr = stringpool.free;
						ret->str.len = lname.dsc$w_length;
						memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length);
						stringpool.free += lname.dsc$w_length;
						return;
					}
					if(full_mask & LNM$M_TERMINAL)
					{	ret->mvtype = MV_STR;
						ENSURE_STP_FREE_SPACE(retlen);
						ret->str.addr = stringpool.free;
						ret->str.len = retlen;
						memcpy(ret->str.addr, result, retlen);
						stringpool.free += retlen;
						return;
					}
					memcpy(buff,result,retlen);
					lname.dsc$w_length = retlen;
					lname.dsc$a_pointer = buff;
				}else
				{	mask = attr_tab[slot];
					if (mask == NOVALUE)
						GTMASSERT;
					MV_FORCE_MVAL(ret,( *((int4*)result) & mask ? 1 : 0 )) ;
					n2s(ret);
					return;
				}
			}
		}else if (status == SS$_NOLOGNAM)
		{	ret->mvtype = MV_STR;
			if (full && pass > 0)
			{
				ENSURE_STP_FREE_SPACE(lname.dsc$w_length);
				ret->str.addr = stringpool.free;
				ret->str.len = lname.dsc$w_length;
				memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length);
				stringpool.free += lname.dsc$w_length;
			}else
			{	ret->str.len = 0;
			}
			return;
		}else
		{	rts_error(VARLSTCNT(1) status);
		}
	}
	MV_FORCE_MVAL(ret, 0) ;
	return;
}
Пример #14
0
void op_fnzbitfind(mval *dst, mval *bitstr, int truthval, int pos)
{
	int str_len, find_bit;
	unsigned char *byte_1, *byte_n, byte_0;
	int m, n, mp, np, i, i1, j;
	static const unsigned char mask[8] = {0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1};
	error_def(ERR_INVBITSTR);

	MV_FORCE_STR(bitstr);

	if (!bitstr->str.len)
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);

	byte_1 = (unsigned char *)bitstr->str.addr;
	str_len = (bitstr->str.len -1) * 8;
	if (*byte_1 > 7)
	{
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);
	}
	if (pos < 1)
	{
		pos = 1; /* It is the way it works in DATA TREE */
	}
	else if (pos > str_len - *byte_1)
	{
		find_bit = 0;
		MV_FORCE_MVAL(dst, find_bit);
		return; /* It is the way it works in DATA TREE */
	}
	np = (pos + 7)/8;
	mp = pos % 8;
	if (mp == 0)
		mp = 8;
	n = (str_len - *byte_1 + 7)/8 - 1;
	m = (str_len - *byte_1) % 8;
	if (m == 0)
		m = 8;
	byte_n = byte_1 + np;
	find_bit = 0;
	if (truthval)
	{
		if (np == n + 1)
			i1 = m;
		else
			i1 = 8;
		for (i = mp - 1; i < i1; i++)
		{
			if (byte_0 = *byte_n & mask[i])
			{
				find_bit = i + 2 + (np - 1)*8;
				MV_FORCE_MVAL(dst, find_bit);
				return;
			}
		}
		if (np == n + 1)
		{
			MV_FORCE_MVAL(dst, find_bit);
			return;
		}
		for(j = 1; j <= n - np; j++)
		{
			byte_n++;
			for (i = 0; i < 8; i++)
			{
				if (byte_0 = *byte_n & mask[i])
				{
					find_bit = i + 2 + (np + j - 1)*8;
					MV_FORCE_MVAL(dst, find_bit);
					return;
				}
			}
		}
		byte_n++;
		for (i = 0; i < m; i++)
		{
			if (byte_0 = *byte_n & mask[i])
			{
				find_bit = i + 2 + n*8;
				MV_FORCE_MVAL(dst, find_bit);
				return;
			}
		}
	}
	else
	{
		if (np == n + 1)
			i1 = m;
		else
			i1 = 8;
		for (i = mp - 1; i < i1; i++)
		{
			if (!(byte_0 = *byte_n & mask[i]))
			{
				find_bit = i + 2 + (np - 1)*8;
				MV_FORCE_MVAL(dst, find_bit);
				return;
			}
		}
		if (np == n + 1)
		{
			MV_FORCE_MVAL(dst, find_bit);
			return;
		}
		for(j = 1; j <= n - np; j++)
		{
			byte_n++;
			for (i = 0; i < 8; i++)
			{
				if (!(byte_0 = *byte_n & mask[i]))
				{
					find_bit = i + 2 + (np + j - 1)*8;
					MV_FORCE_MVAL(dst, find_bit);
					return;
				}
			}
		}
		byte_n++;
		for (i = 0; i < m; i++)
		{
			if (!(byte_0 = *byte_n & mask[i]))
			{
				find_bit = i + 2 + n*8;
				MV_FORCE_MVAL(dst, find_bit);
				return;
			}
		}
	}
	MV_FORCE_MVAL(dst, find_bit);
	return;
}
Пример #15
0
int m_zwrite(void)
{
	int4		pcount;			/* parameter count */
	triple *ref,*ref1,*head,*last,*count;
	opctype op;
	oprtype name,limit;
	mval	mv;
	mint code;
	mint subscount;
	char c;
	bool pat;
	error_def(ERR_VAREXPECTED);
	error_def(ERR_RPARENMISSING);
	error_def(ERR_ZWRSPONE);
	error_def(ERR_COMMA);

	subscount = 0;
	count = 0;
	pat = FALSE;
	if (window_token == TK_CIRCUMFLEX)
	{
		advancewindow();
		op = OC_GVZWRITE;
	}
	else
	{	op = OC_LVZWRITE;
	}
	switch(window_token)
	{
	case TK_SPACE:
	case TK_EOL:
		if (op == OC_GVZWRITE)
		{
			stx_error(ERR_VAREXPECTED);
			return FALSE;
		}
		else
		{	 op = OC_LVPATWRITE;
		}
		head = maketriple(op);
		head->operand[0] = put_ilit((mint)3);
		ref1 = newtriple(OC_PARAMETER);
		head->operand[1] = put_tref(ref1);
		ref1->operand[0] = put_ilit(0);			/* shows not from zshow */
		ref = newtriple(OC_PARAMETER);
		ref1->operand[1] = put_tref(ref);
		ref->operand[0] = put_str((char *)pat_everything,sizeof_pat_everything);
		MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ;
		ref->operand[1] = put_lit(&mv);
		ins_triple(head);
		return TRUE;
	case TK_IDENT:
		name = put_str(&window_ident.c[0],mid_len(&window_ident));
		advancewindow();
		break;
	case TK_LPAREN:
		if (op != OC_GVZWRITE) /* naked reference */
		{
			stx_error(ERR_VAREXPECTED);
			return FALSE;
		}
		name = put_str(&window_ident.c[0], 0);
		break;
	case TK_ATSIGN:
		if (!indirection(&name))
			return FALSE;
		if (op == OC_LVZWRITE && window_token != TK_LPAREN)
		{
			ref = maketriple(OC_COMMARG);
			ref->operand[0] = name;
			ref->operand[1] = put_ilit(indir_zwrite);
			ins_triple(ref);
			return TRUE;
		}
		ref = newtriple(OC_INDPAT);
		ref->operand[0] = name;
		name = put_tref(ref);
		break;
	case TK_QUESTION:
		advancewindow();
		source_column = last_source_column;
		if (!compile_pattern(&name,FALSE))
			return FALSE;
		if (op == OC_LVZWRITE)
			op = OC_LVPATWRITE;
		pat = TRUE;
		break;
	default:
		stx_error(ERR_VAREXPECTED);
		return FALSE;
	}
	head = maketriple(op);
	last = newtriple(OC_PARAMETER);
	head->operand[1] = put_tref(last);
	pcount = 1;
	if (op == OC_LVPATWRITE || op == OC_GVZWRITE)
	{
		pcount++;
		last->operand[0] = put_ilit((op == OC_GVZWRITE ? pat : 0));
		ref = newtriple(OC_PARAMETER);
		last->operand[1] = put_tref(ref);
		last = ref;
		if (op == OC_GVZWRITE)
		{
			pcount++;
			count = last;
			ref = newtriple(OC_PARAMETER);
			last->operand[1] = put_tref(ref);
			last = ref;
		}
	}
	last->operand[0] = name;
	if (window_token != TK_LPAREN)
	{
		pcount++;
		if (pat)
		{
			MV_FORCE_MVAL(&mv,ZWRITE_END) ;
		}
		else
		{	subscount++ ;
			MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ;
		}
		last->operand[1] = put_lit(&mv);
		head->operand[0] = put_ilit(pcount);
		if (count)
			count->operand[0] = put_ilit(subscount);
		ins_triple(head);
		return TRUE;
	}
	advancewindow();
	for(;;)
	{
		ref = newtriple(OC_PARAMETER);
		last->operand[1] = put_tref(ref);
		switch (window_token)
		{
			case TK_RPAREN:
				dqdel(ref,exorder);
				advancewindow();
				MV_FORCE_MVAL(&mv,ZWRITE_END) ;
				last->operand[1] = put_lit(&mv);
				pcount++;
				head->operand[0] = put_ilit((mint)pcount);
				if (count)
					count->operand[0] = put_ilit(subscount);
				ins_triple(head);
				return TRUE;
			case TK_ASTERISK:
				dqdel(ref,exorder);
				advancewindow();
				if (window_token != TK_RPAREN)
				{
					stx_error(ERR_RPARENMISSING);
					return FALSE;
				}
				advancewindow();
				MV_FORCE_MVAL(&mv,ZWRITE_ASTERISK) ;
				last->operand[1] = put_lit(&mv);
				pcount++;
				subscount++;
				head->operand[0] = put_ilit((mint)pcount);
				if (count)
					count->operand[0] = put_ilit(subscount);
				ins_triple(head);
				return TRUE;
			case TK_QUESTION:
				advancewindow();
				source_column = last_source_column;
				if (!compile_pattern(&limit,FALSE))
					return FALSE;
				if (window_token != TK_COMMA && window_token != TK_RPAREN)
				{	stx_error(ERR_ZWRSPONE);
					return FALSE;
				}
				if (window_token == TK_COMMA)
					advancewindow();
				subscount++;
				MV_FORCE_MVAL(&mv,ZWRITE_PATTERN) ;
				ref->operand[0] = put_lit(&mv);
				pcount++;
				ref1 = newtriple(OC_PARAMETER);
				ref->operand[1] = put_tref(ref1);
				ref1->operand[0] = limit;
				last = ref1;
				pcount++;
				continue;
			case TK_COLON:
				if ((c = director_token) != TK_RPAREN)
				{
					if (c != TK_COMMA)
					{
						advancewindow();
						MV_FORCE_MVAL(&mv,ZWRITE_UPPER) ;
						ref->operand[0] = put_lit(&mv);
						pcount++;
						subscount++;
						break;
					}
					advancewindow();
				}
				/* caution: fall through */
			case TK_COMMA:
				advancewindow();
				MV_FORCE_MVAL(&mv,ZWRITE_ALL) ;
				ref->operand[0] = put_lit(&mv);
				pcount++;
				subscount++;
				last = ref;
				continue;
			default:
				if (!expr(&limit))
					return FALSE;
				subscount++;
				last = newtriple(OC_PARAMETER);
				ref->operand[1] = put_tref(last);
				last->operand[0] = limit;
				pcount++;
				if ((c = window_token) == TK_COLON)
				{
					code = ZWRITE_LOWER;
					advancewindow();
					c = window_token;
				}
				else
					code = ZWRITE_VAL;
				switch (c)
				{
				case TK_COMMA:
					advancewindow();
					/* caution: fall through */
				case TK_RPAREN:
					MV_FORCE_MVAL(&mv,code) ;
					ref->operand[0] = put_lit(&mv);
					pcount++;
					continue;
				default:
					if (code == ZWRITE_VAL)
					{
						stx_error(ERR_COMMA);
						return FALSE;
					}
					MV_FORCE_MVAL(&mv,ZWRITE_BOTH) ;
					ref->operand[0] = put_lit(&mv);
					pcount++;
					ref = last;
					break;
				}
				break;
		}
		if (!expr(&limit))
			return FALSE;
		last = newtriple(OC_PARAMETER);
		ref->operand[1] = put_tref(last);
		last->operand[0] = limit;
		pcount++;
		if (window_token == TK_COMMA)
		{
			advancewindow();
		}
	}
}
Пример #16
0
unsigned char *set_zstatus(mstr *src, int arg, unsigned char **ctxtp, boolean_t need_rtsloc)
{
	unsigned char	*b_line;	/* beginning of line (used to restart line) */
	mval		val;		/* pointer to dollar_zstatus */
	unsigned char	zstatus_buff[2*OUT_BUFF_SIZE];
	unsigned char	*zstatus_bptr, *zstatus_iter;
	int		save_arg;
	size_t		util_len ;
	mval		*status_loc;
	boolean_t 	trans_frame;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	b_line = 0;
	if (!need_rtsloc)
	 	trans_frame = FALSE;
	else
	{	/* get the line address of the last "known" MUMPS code that was executed.  MUMPS
		 * indirection consitutes MUMPS code that is "unknown" is the sense that there is no
		 * line address for it.
		 */
		trans_frame = !(SFT_DM & frame_pointer->type) && ((!(frame_pointer->type & SFT_COUNT
			|| 0 == frame_pointer->type)) || (SFT_ZINTR & frame_pointer->type));
		if (trans_frame)
		{
			save_arg = arg;
			SET_ERR_CODE(frame_pointer, arg);
		}
		src->len = INTCAST(get_symb_line((unsigned char*)src->addr, &b_line, ctxtp) - (unsigned char*)src->addr);
	}
	MV_FORCE_MVAL(&val, arg);
	n2s(&val);
	memcpy(zstatus_buff, val.str.addr, val.str.len);
	zstatus_bptr = zstatus_buff + val.str.len;
	*zstatus_bptr++ = ',';
	if (0 != b_line)
	{
		memcpy(zstatus_bptr, src->addr, src->len);
		zstatus_bptr += src->len;
		*zstatus_bptr++ = ',';
	}
	zstatus_iter = zstatus_bptr;
	util_len = TREF(util_outptr)  - TREF(util_outbuff_ptr);
	if (trans_frame)
	{	/* currently no inserted message (arg) needs arguments.  The following code needs
		 * to be changed if any new parametered message is added.
		 */
		*(TREF(util_outbuff_ptr)) = '-';
		memcpy(&zstatus_buff[OUT_BUFF_SIZE], TREF(util_outbuff_ptr), util_len); /* save original message */
		util_out_print(NULL, RESET); /* clear any pending msgs and reset util_out_buff */
		gtm_putmsg_noflush(VARLSTCNT(1) arg);

		memcpy(zstatus_bptr, TREF(util_outbuff_ptr), TREF(util_outptr) - TREF(util_outbuff_ptr));
		zstatus_bptr += (TREF(util_outptr) - TREF(util_outbuff_ptr));
		*zstatus_bptr++ = ',';
		memcpy(zstatus_bptr, &zstatus_buff[OUT_BUFF_SIZE], util_len);

		/* restore original message into util_outbuf */
		memcpy(TREF(util_outbuff_ptr), &zstatus_buff[OUT_BUFF_SIZE], util_len);
		*(TREF(util_outbuff_ptr)) = '%';
		TREF(util_outptr) = TREF(util_outbuff_ptr) + util_len;
		arg = save_arg;
	} else
		memcpy(zstatus_bptr, TREF(util_outbuff_ptr), util_len);
	zstatus_bptr += util_len;
	for (; zstatus_iter < zstatus_bptr; zstatus_iter++)
	{
		if ('\n' == *zstatus_iter)
			*zstatus_iter = ',';
	}
	status_loc = (NULL == zyerr_frame) ? &dollar_zstatus : &dollar_zerror;
	status_loc->str.len = INTCAST(zstatus_bptr - zstatus_buff);
	status_loc->str.addr = (char *)zstatus_buff;
	s2pool(&status_loc->str);
	status_loc->mvtype = MV_STR;
        /* If this is a MEMORY issue, setting the ecode is of dubious worth since we are not going
         * to drive any handlers and it can definitely be expensive in terms of memory use as ecode_add()
         * (further down the pike) is likely to load the text of the module into storage if it can. So we bypass
         * ecode setting for these two fatal errors. 02/2008 se
	 */
	if (ERR_MEMORY != arg)
		ecode_set(arg);
	return (b_line);
}
Пример #17
0
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v)
{
	unsigned char	*ptr;
	short		len, temp_short;
	int4		status, max_reply_len;
	struct CLB	*lnk;
	unsigned char	buff[MAX_ZWR_KEY_SZ], *end;

	error_def(ERR_BADSRVRNETMSG);
	error_def(ERR_UNIMPLOP);
	error_def(ERR_TEXT);
	error_def(ERR_GVIS);

	lnk = gv_cur_region->dyn.addr->cm_blk;
	if (!((link_info *)lnk->usr)->server_supports_long_names && (PRE_V5_MAX_MIDENT_LEN < strlen((char *)gv_currkey->base)))
	{
		end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE);
		rts_error(VARLSTCNT(14) ERR_UNIMPLOP, 0,
					ERR_TEXT, 2,
					LEN_AND_LIT("GT.CM server does not support global names longer than 8 characters"),
					ERR_GVIS, 2, end - buff, buff,
					ERR_TEXT, 2, DB_LEN_STR(gv_cur_region));
	}
	lnk->ast = 0;	/* all database queries are sync */
	lnk->cbl = 1 + /* HDR */
		   gv_currkey->end + /* key */
		   sizeof(unsigned short) + /* gv_key.top */
		   sizeof(unsigned short) + /* gv_key.end */
		   sizeof(unsigned short) + /* gv_key.prev */
		   sizeof(unsigned char) + /* gv_key.base */
		   sizeof(unsigned char) + /* regnum */
		   sizeof(unsigned short); /* size for variable len SUBSC */
	/* the current GT.CM maximum message buffer length is bounded by the size of a short which is 64K. but the
	 * calculation below of lnk->cbl and max_reply_len takes into account the fact that the value that is sent in as
	 * input or read in from the server side can be at most MAX_DBSTRLEN in size. therefore, there is a dependency
	 * that MAX_DBSTRLEN always be less than the GT.CM maximum message buffer length. to ensure this is always the
	 * case, the following assert is added so that whenever MAX_DBSTRLEN is increased, we will fail this assert
	 * and reexamine the code below.
	 */
	assert(sizeof(lnk->cbl) == 2);	/* assert it is a short. when it becomes a uint4 the assert can be removed
					 * if the macro CM_MAX_BUF_LEN (used below) is changed appropriately */
	assert(MAX_DBSTRLEN == (32 * 1024 - 1));
	if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code)
	{
		if (CMMS_Q_INCREMENT == query_code)
		{ /* 1-byte boolean value of "undef_inhibit" passed to the server for $INCREMENT
		   although, effective V5.0-000, undef_inhibit is no longer relevant as $INCREMENT()
		   implicitly does a $GET() on the global. We keep this byte to ensure compatibility
		   with V5.0-FT01 */
			lnk->cbl++;
		}
		assert((uint4)lnk->cbl + sizeof(unsigned short) + (uint4)MAX_DBSTRLEN <= (uint4)CM_MAX_BUF_LEN);
		lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */
	}
	if ((CMMS_Q_GET == query_code)
			|| (CMMS_Q_INCREMENT == query_code)
			|| (CMMS_Q_QUERY == query_code) && ((link_info *)lnk->usr)->query_is_queryget)
		max_reply_len = lnk->mbl + SIZEOF(unsigned short) + MAX_DBSTRLEN; /* can't predict the length of data value */
	else
		max_reply_len = lnk->mbl;
	assert(max_reply_len <= (int4)CM_MAX_BUF_LEN);
	if (stringpool.top < stringpool.free + max_reply_len)
		stp_gcol(max_reply_len);
	lnk->mbf = stringpool.free;
	ptr = lnk->mbf;
	*ptr++ = query_code;
	/* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */
	temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1;
	CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	*ptr++ = gv_cur_region->cmx_regnum;
	CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	memcpy(ptr, gv_currkey->base, gv_currkey->end + 1);
	if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code)
	{
		ptr += gv_currkey->end + 1;
		temp_short = (short)v->str.len;
		assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */
		CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		memcpy(ptr,v->str.addr, v->str.len);
		if (CMMS_Q_INCREMENT == query_code)
		{ /* UNDEF flag is no longer relevant, but set the flag to ensure compatibility with V5.0-FT01 */
			assert(sizeof(undef_inhibit) == 1);
			ptr[v->str.len] = (unsigned char)undef_inhibit;
		}
	}
	status = cmi_write(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	status = cmi_read(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	ptr = lnk->mbf;
	if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code)
	{
		if (reply_code != *ptr)
		{
			if (*ptr != CMMS_E_ERROR)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk,FALSE);
		}
		return;
	}
	if (reply_code != *ptr)
	{
		if ((CMMS_R_UNDEF != *ptr) || ((CMMS_Q_GET != query_code) && (CMMS_Q_INCREMENT != query_code)))
		{
			if (CMMS_E_ERROR != *ptr)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk, FALSE);
		}
		if (CMMS_Q_INCREMENT == query_code)
			v->mvtype = 0;	/* set the result to be undefined */
		return;
	}
	ptr++;
	if (CMMS_R_DATA == reply_code)
	{
		CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		if (1 != temp_short)
			rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
		ptr += sizeof(short);
		status = *ptr;	/* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */
		MV_FORCE_MVAL(v, status);
		return;
	}
	if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER)
	{
		CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		if (1 == len)
		{
			MV_FORCE_MVAL(v, 0);
		} else
		{
			if (*ptr++ != gv_cur_region->cmx_regnum)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			/* memcpy(gv_altkey, ptr, len - 1); */
			CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) -
						     sizeof(unsigned short));
			ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short));
			MV_FORCE_MVAL(v, 1);
		}
		if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget)
		{
			if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget)
				v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */
			return;
		}
	}
	assert(CMMS_R_GET == reply_code
		|| CMMS_R_INCREMENT == reply_code
		|| CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len);
	CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(unsigned short);
	assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */
	v->mvtype = MV_STR;
	v->str.len = len;
	v->str.addr = (char *)stringpool.free;	/* we don't need the reply msg anymore, can overwrite reply */
	memcpy(v->str.addr, ptr, len);		/* so that we don't leave a gaping hole in the stringpool */
	stringpool.free += len;
	return;
}
Пример #18
0
void op_fnorder(lv_val *src, mval *key, mval *dst)
{
	int			cur_subscr;
	mval			tmp_sbs;
	int             	length;
	sbs_blk			*num, *str;
	boolean_t		found, is_neg;
	int4			i;
	lv_val			**lv;
	lv_sbs_tbl		*tbl;
	sbs_search_status	status;
	boolean_t		is_fnnext;

	is_fnnext = in_op_fnnext;
	in_op_fnnext = FALSE;
	found = FALSE;
	if (src)
	{
		if (tbl = src->ptrs.val_ent.children)
		{
			MV_FORCE_DEFINED(key);
			num = tbl->num;
			str = tbl->str;
			assert(tbl->ident == MV_SBS);
			if ((MV_IS_STRING(key) && key->str.len == 0) || (is_fnnext && MV_IS_INT(key) && key->m[1] == MINUS_ONE))
			{ /* With GT.M collation , if last subscript is null, $o returns the first subscript in that level */
				if (tbl->int_flag)
				{
					assert(num);
					for (i = 0, lv = &num->ptr.lv[0]; i < SBS_NUM_INT_ELE; i++, lv++)
					{
						if (*lv)
						{
							MV_FORCE_MVAL(dst,i);
							found = TRUE;
							break;
						}
					}
				} else if (num)
				{
					assert(num->cnt);
					MV_ASGN_FLT2MVAL((*dst),num->ptr.sbs_flt[0].flt);
					found = TRUE;
				}
			} else
			{
				if (MV_IS_CANONICAL(key))
				{
					MV_FORCE_NUM(key);
					if (tbl->int_flag)
					{
						assert(num);
						is_neg = (key->mvtype & MV_INT) ? key->m[1] < 0 : key->sgn;
						if (is_neg)
							i = 0;
						else
						{
							if (!is_fnnext && (1 == numcmp(key, (mval *)&SBS_MVAL_INT_ELE)))
								i = SBS_NUM_INT_ELE;
							else
							{
								i =  MV_FORCE_INT(key);
								i++;
							}
						}
						for (lv = &num->ptr.lv[i]; i < SBS_NUM_INT_ELE; i++, lv++)
						{
							if (*lv)
							{
								MV_FORCE_MVAL(dst,i);
								found = TRUE;
								break;
							}
						}
					} else if (num && lv_nxt_num_inx(num, key, &status))
					{
						MV_ASGN_FLT2MVAL((*dst),((sbs_flt_struct*)status.ptr)->flt);
						found = TRUE;
					}
				} else
				{
					if (local_collseq)
					{
						ALLOC_XFORM_BUFF(&key->str);
						tmp_sbs.mvtype = MV_STR;
						tmp_sbs.str.len = max_lcl_coll_xform_bufsiz;
						assert(NULL != lcl_coll_xform_buff);
						tmp_sbs.str.addr = lcl_coll_xform_buff;
						do_xform(local_collseq, XFORM, &key->str,
								&tmp_sbs.str, &length);
						tmp_sbs.str.len = length;
						s2pool(&(tmp_sbs.str));
						key = &tmp_sbs;
					}
					if (str && lv_nxt_str_inx(str, &key->str, &status))
					{
						dst->mvtype = MV_STR;
						dst->str = ((sbs_str_struct *)status.ptr)->str;
					} else
					{
						if (!is_fnnext)
						{
							dst->mvtype = MV_STR;
							dst->str.len = 0;
						} else
							MV_FORCE_MVAL(dst, -1);
					}
					found = TRUE;
				}
			}
			if (!found && str)
			{	/* We are here because
				 * a. key is "" and there is no numeric subscript, OR
				 * b. key is numeric and it is >= the largest numeric subscript at this level implying a switch from
				 *    numeric to string subscripts
				 * Either case, return the first string subscript. However, for STDNULLCOLL, skip to the next
				 * subscript should the first subscript be ""
				 */
				assert(str->cnt);
				dst->mvtype = MV_STR;
				dst->str = str->ptr.sbs_str[0].str;
				found = TRUE;
				if (local_collseq_stdnull && 0 == dst->str.len)
				{
					assert(lv_null_subs);
					if (lv_nxt_str_inx(str, &dst->str, &status))
					{
						dst->str = ((sbs_str_struct*)status.ptr)->str;
					} else
						found = FALSE;
				}
			}
		}
	}
	if (!found)
	{
		if (!is_fnnext)
		{
			dst->mvtype = MV_STR;
			dst->str.len = 0;
		} else
			MV_FORCE_MVAL(dst, -1);
	} else if (dst->mvtype == MV_STR && local_collseq)
	{
		ALLOC_XFORM_BUFF(&dst->str);
		assert(NULL != lcl_coll_xform_buff);
		tmp_sbs.str.addr = lcl_coll_xform_buff;
		tmp_sbs.str.len = max_lcl_coll_xform_bufsiz;
		do_xform(local_collseq, XBACK,
				&dst->str, &tmp_sbs.str, &length);
		tmp_sbs.str.len = length;
		s2pool(&(tmp_sbs.str));
		dst->str = tmp_sbs.str;
	}
}
Пример #19
0
void op_fnzlength(mval *src, mval *dest)
{
	MV_FORCE_STR(src);
	MV_FORCE_MVAL(dest, src->str.len);
}
void zshow_devices(zshow_out *output)
{
	static readonly char filchar_text[] = "CHARACTERS";
	static readonly char filesc_text[] = "ESCAPES";
	static readonly char terminal_text[] = "TERMINAL ";
	static readonly char magtape_text[] =  "MAGTAPE ";
	static readonly char rmsfile_text[] =  "RMS ";
	static readonly char mailbox_text[] =  "MAILBOX ";
	static readonly char dollarc_text[] = "$C(";
	static readonly char equal_text[] = {'='};
	static readonly char comma_text[] = {','};
	static readonly char quote_text[] = {'"'};
	static readonly char lparen_text[] = {'('};
	static readonly char rparen_text[] = {')'};
	static readonly char devop[] = "OPEN ";
	static readonly char devcl[] = "CLOSED ";
	static readonly char largerecord[] = "BIGRECORD ";
	static readonly char rfm_tab[][7] = {"UDF   ", "FIXED ", "VAR   ", "VFC   ", "STM   ", "STMLF ", "STMCR "};
	bool		first;
	int4		i, j, ii, jj;
	io_log_name	*l;		/* logical name pointer		*/
	mval		v;
	mval		m;
	struct FAB	*f;
	struct RAB	*r;
	d_mb_struct	*mb_ptr;
	d_mt_struct	*mt_ptr;
	d_rm_struct	*rm_ptr;
	d_tt_struct	*tt_ptr;
	d_socket_struct	*dsocketptr;
	socket_struct	*socketptr;
	io_termmask	*mask_out;
	unsigned char	delim_buff_sm[MAX_DELIM_LEN];
	unsigned short	delim_len_sm;
	char		delim_mstr_buff[(MAX_DELIM_LEN * MAX_ZWR_EXP_RATIO) + 11];
	mstr		delim;
	int		delim_len;
	static readonly char space8_text[] = "        "; 	/* starting from here, for gtmsocket only */
	static readonly char lb_text[] = {'['};
	static readonly char rb_text[] = {']'};
	static readonly char at_text[] = {'@'};
	static readonly char delimiter_text[] = "DELIMITER ";
	static readonly char nodelimiter_text[] = "NODELIMITER ";
	static readonly char local_text[] = "LOCAL=";
	static readonly char remote_text[] = "REMOTE=";
	static readonly char total_text[] = "TOTAL=";
	static readonly char current_text[] = "CURRENT=";
	static readonly char passive_text[] = "PASSIVE ";
	static readonly char active_text[] = "ACTIVE ";
	static readonly char socket_text[] = "SOCKET";
	static readonly char descriptor_text[] = "DESC=";
	static readonly char trap_text[] = "TRAP ";
	static readonly char notrap_text[] = "NOTRAP ";
	static readonly char zdelay_text[] = "ZDELAY ";
	static readonly char znodelay_text[] = "ZNODELAY ";
	static readonly char zbfsize_text[] = "ZBFSIZE=";
	static readonly char zibfsize_text[] = "ZIBFSIZE=";
	static readonly char port_text[] = "PORT=";
	static readonly char zsh_socket_state[][10] =
					{	"CONNECTED"
						,"LISTENING"
						,"BOUND"
						,"CREATED"
					};
	static readonly char morereadtime_text[] = "MOREREADTIME=";

	v.mvtype = MV_STR;
	for (l = io_root_log_name;  l != 0;  l = l->next)
	{
		if (l->dollar_io[0] != IO_ESC && l->iod->trans_name == l)
		{
			v.str.addr = &l->dollar_io[0];
			v.str.len = l->len;
			zshow_output(output, &v.str);
			ZS_ONE_OUT(&v, space_text);
			if (l->iod->state == dev_open)
			{
				ZS_STR_OUT(&v, devop);
				switch(l->iod->type)
				{
				case tt:
					ZS_STR_OUT(&v, terminal_text);
					tt_ptr = (d_tt_struct *)l->iod->dev_sp;
					if (!ctrlc_on && io_std_device->out == l->iod) /* and standard input */
						ZS_PARM_SP(&v, zshow_nocene);
					if ((int4)(tt_ptr->item_list[0].addr) & TRM$M_TM_CVTLOW)
						ZS_PARM_SP(&v, zshow_conv);
					if (tt_ptr->enbld_outofbands.mask)
					{
						ZS_PARM_EQU(&v, zshow_ctra);
						ZS_STR_OUT(&v, dollarc_text);
						first = TRUE;
						for (i = 1, j = 0;  j < 32;  j++, i = i * 2)
						{
							if (i & tt_ptr->enbld_outofbands.mask)
							{
								if (!first)
									ZS_ONE_OUT(&v, comma_text);
								else
									first = FALSE;
								MV_FORCE_MVAL(&m, j);
								mval_write(output, &m, FALSE);
							}
						}
						ZS_ONE_OUT(&v, rparen_text);
						ZS_ONE_OUT(&v, space_text);
					}
					if ((int4)(tt_ptr->term_char) & TT$M_NOECHO)
						ZS_PARM_SP(&v, zshow_noecho);
					if ((int4)(tt_ptr->ext_cap) & TT2$M_EDITING)
						ZS_PARM_SP(&v, zshow_edit);
					else
						ZS_PARM_SP(&v, zshow_noedit);
					if (!((int4)(tt_ptr->term_char) & TT$M_ESCAPE))
						ZS_PARM_SP(&v, zshow_noesca);
					if (tt_ptr->in_buf_sz != TTDEF_BUF_SZ)
					{
						ZS_PARM_EQU(&v, zshow_field);
						MV_FORCE_MVAL(&m, tt_ptr->in_buf_sz);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (tt_ptr->term_char & TT$M_HOSTSYNC)
						ZS_PARM_SP(&v, zshow_host);
					else
						ZS_PARM_SP(&v, zshow_nohost);
					if (tt_ptr->ext_cap & TT2$M_INSERT)
						ZS_PARM_SP(&v, zshow_inse);
					else
						ZS_PARM_SP(&v, zshow_noinse);
					if (tt_ptr->ext_cap & TT2$M_PASTHRU)
						ZS_PARM_SP(&v, zshow_past);
					else
						ZS_PARM_SP(&v, zshow_nopast);
					if (tt_ptr->term_char & TT$M_READSYNC)
						ZS_PARM_SP(&v, zshow_reads);
					else
						ZS_PARM_SP(&v, zshow_noreads);
					if (tt_ptr->term_char & TT$M_TTSYNC)
						ZS_PARM_SP(&v, zshow_ttsy);
					else
						ZS_PARM_SP(&v, zshow_nottsy);
					if (tt_ptr->term_char & TT$M_NOTYPEAHD)
						ZS_PARM_SP(&v, zshow_notype);
					else
						ZS_PARM_SP(&v, zshow_type);
					if (!l->iod->wrap)
						ZS_PARM_SP(&v, zshow_nowrap);
					mask_out = tt_ptr->item_list[2].addr;
					if (mask_out->mask[0] != TERM_MSK)
					{
						ZS_PARM_EQU(&v, zshow_term);
						ZS_STR_OUT(&v, dollarc_text);
						first = TRUE;
						for (i = 0;  i < 8;  i++)
						{
							for (j = 0;  j < 32;  j++)
								if (mask_out->mask[i] & (1 << j))
								{
									if (!first)
										ZS_ONE_OUT(&v, comma_text);
									else
										first = FALSE;
									MV_FORCE_MVAL(&m, i * 32 + j);
									mval_write(output, &m, FALSE);
								}
						}
						ZS_ONE_OUT(&v, rparen_text);
						ZS_ONE_OUT(&v, space_text);
					}
					ZS_PARM_EQU(&v, zshow_width);
					MV_FORCE_MVAL(&m, l->iod->width);
					mval_write(output, &m, FALSE);
					ZS_ONE_OUT(&v, space_text);
					ZS_PARM_EQU(&v, zshow_leng);
					MV_FORCE_MVAL(&m, l->iod->pair.out->length);
					mval_write(output, &m, FALSE);
					ZS_ONE_OUT(&v, space_text);
					if (l->iod->write_filter)
					{
						bool twoparms = FALSE;

						ZS_PARM_EQU(&v, zshow_fil);
						if (l->iod->write_filter & CHAR_FILTER)
						{
							if (l->iod->write_filter & ESC1)
							{
								twoparms = TRUE;
								ZS_ONE_OUT(&v, lparen_text);
							}
							ZS_STR_OUT(&v, filchar_text);
							if (twoparms)
							{
								ZS_ONE_OUT(&v, comma_text);
								ZS_ONE_OUT(&v, space_text);
							}
						}
						if (l->iod->write_filter & ESC1)
							ZS_STR_OUT(&v, filesc_text);
						if (twoparms)
							ZS_ONE_OUT(&v, rparen_text);
						ZS_ONE_OUT(&v, space_text);
					}
					break;
				case mt:
					ZS_STR_OUT(&v, magtape_text);
					mt_ptr = (d_tt_struct *)l->iod->dev_sp;
					if (mt_ptr->block_sz != MTDEF_BUF_SZ)
					{
						ZS_PARM_EQU(&v, zshow_bloc);
						MV_FORCE_MVAL(&m, mt_ptr->block_sz);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (mt_ptr->record_sz != MTDEF_REC_SZ)
					{
						ZS_PARM_EQU(&v, zshow_rec);
						MV_FORCE_MVAL(&m, mt_ptr->record_sz);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (mt_ptr->read_only)
						ZS_PARM_SP(&v, zshow_read);
					if (mt_ptr->ebcdic)
						ZS_PARM_SP(&v, zshow_ebcd);
					if (mt_ptr->fixed)
						ZS_PARM_SP(&v, zshow_fixed);
					if (mt_ptr->read_mask & IO$M_DATACHECK)
						ZS_PARM_SP(&v, zshow_rchk);
					if (mt_ptr->write_mask & IO$M_DATACHECK)
						ZS_PARM_SP(&v, zshow_wchk);
					if (!l->iod->wrap)
						ZS_PARM_SP(&v, zshow_nowrap);
					break;
				case rm:
					ZS_STR_OUT(&v, rmsfile_text);
					rm_ptr = (d_rm_struct *)l->iod->dev_sp;
					f = &rm_ptr->f;
					r = &rm_ptr->r;
					if (r->rab$l_rop & RAB$M_CVT)
						ZS_PARM_SP(&v, zshow_conv);
					if (f->fab$l_alq != 0)
					{
						ZS_PARM_EQU(&v, zshow_allo);
						MV_FORCE_MVAL(&m, f->fab$l_alq);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (f->fab$l_fop & FAB$M_DLT)
						ZS_PARM_SP(&v, zshow_dele);
					if (f->fab$w_deq != 0)
					{
						ZS_PARM_EQU(&v, zshow_exte);
						MV_FORCE_MVAL(&m, f->fab$w_deq);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					assert(FAB$C_MAXRFM == (SIZEOF(rfm_tab)/SIZEOF(rfm_tab[0]) - 1));
					if (FAB$C_MAXRFM >= rm_ptr->b_rfm && FAB$C_RFM_DFLT != rm_ptr->b_rfm)
						ZS_STR_OUT(&v, rfm_tab[rm_ptr->b_rfm]);
					if (rm_ptr->largerecord)
						ZS_STR_OUT(&v, largerecord);
					if (f->fab$b_fac == FAB$M_GET)
						ZS_PARM_SP(&v, zshow_read);
					if (rm_ptr->l_mrs != DEF_RM_WIDTH)
					{
						ZS_PARM_EQU(&v, zshow_rec);
						MV_FORCE_MVAL(&m, rm_ptr->l_mrs);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
/* smw should we add width aka usz */
					if (f->fab$b_shr & FAB$M_SHRGET)
						ZS_PARM_SP(&v, zshow_shar);
	/*
					if (f->fab$l_fop & FAB$M_SPL)
						ZS_PARM_SP(&v, zshow_spo);
					if (f->fab$l_fop & FAB$M_SCF)
						ZS_PARM_SP(&v, zshow_sub);
	*/
					if (!l->iod->wrap)
						ZS_PARM_SP(&v, zshow_nowrap);
					if (f->fab$l_xab)
					{
/* smw need to handle other XABs and uic as octal */
						struct XABPRO	*xabpro;
						uic_struct uic;

						ZS_PARM_EQU(&v, zshow_uic);
						ZS_ONE_OUT(&v, quote_text);
						xabpro = f->fab$l_xab;
						memcpy(&uic, &xabpro->xab$l_uic, SIZEOF(int4));
						MV_FORCE_MVAL(&m, uic.grp);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, comma_text);
						MV_FORCE_MVAL(&m, uic.mem);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, quote_text);
						ZS_ONE_OUT(&v, space_text);
					}
					break;
				case mb:
					ZS_STR_OUT(&v, mailbox_text);
					mb_ptr = (d_mb_struct *)l->iod->dev_sp;
					if (!(mb_ptr->write_mask & IO$M_NOW))
						ZS_PARM_SP(&v, zshow_wait);
					if (mb_ptr->prmflg)
						ZS_PARM_SP(&v, zshow_prmmbx);
					if (mb_ptr->maxmsg != DEF_MB_MAXMSG)
					{
						ZS_PARM_EQU(&v, zshow_bloc);
						MV_FORCE_MVAL(&m, mb_ptr->maxmsg);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (mb_ptr->promsk & IO_RD_ONLY)
						ZS_PARM_SP(&v, zshow_read);
					if (mb_ptr->del_on_close)
						ZS_PARM_SP(&v, zshow_dele);
					if (mb_ptr->promsk & IO_SEQ_WRT)
						ZS_PARM_SP(&v, zshow_write);
					if (l->iod->width != DEF_MB_MAXMSG)
					{
						ZS_PARM_EQU(&v, zshow_width);
						MV_FORCE_MVAL(&m, l->iod->width);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					if (!l->iod->wrap)
						ZS_PARM_SP(&v, zshow_nowrap);
					if (l->iod->length != DEF_MB_LENGTH)
					{
						ZS_PARM_EQU(&v, zshow_leng);
						MV_FORCE_MVAL(&m, l->iod->length);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
					}
					break;
				case gtmsocket:
					delim.addr = delim_mstr_buff;
					delim_len = 0;
					ZS_STR_OUT(&v, socket_text);
					dsocketptr = (d_socket_struct *)l->iod->dev_sp;
					ZS_ONE_OUT(&v, space_text);
					ZS_STR_OUT(&v, total_text);
					MV_FORCE_MVAL(&m, (int)dsocketptr->n_socket);
					mval_write(output, &m, FALSE);
					ZS_ONE_OUT(&v, space_text);
					ZS_STR_OUT(&v, current_text);
					MV_FORCE_MVAL(&m, (int)dsocketptr->current_socket);
					mval_write(output, &m, FALSE);
					output->flush = TRUE;
					zshow_output(output, 0);
					for(ii = 0; ii < dsocketptr->n_socket; ii++)
					{
						/* output each socket */
						socketptr = dsocketptr->socket[ii];
						ZS_STR_OUT(&v, space8_text);
		/* socket handle */		ZS_STR_OUT(&v, socket_text);
						ZS_ONE_OUT(&v, lb_text);
						MV_FORCE_MVAL(&m, ii);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, rb_text);
						ZS_ONE_OUT(&v, equal_text);
						v.str.addr = socketptr->handle;
						v.str.len = socketptr->handle_len;
						zshow_output(output, &v.str);
						ZS_ONE_OUT(&v, space_text);
		/* socket descriptor */		ZS_STR_OUT(&v, descriptor_text);
						MV_FORCE_MVAL(&m, socketptr->sd);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
		/* socket state */		ZS_STR_OUT(&v, zsh_socket_state[socketptr->state]);
						ZS_ONE_OUT(&v, space_text);
		/* socket type */		if (socketptr->passive)
						{
							ZS_STR_OUT(&v, passive_text);
						} else
						{
							ZS_STR_OUT(&v, active_text);
						}
						ZS_ONE_OUT(&v, space_text);
		/* error trapping */		if (socketptr->ioerror)
						{
							ZS_STR_OUT(&v, trap_text);
						} else
						{
							ZS_STR_OUT(&v, notrap_text);
						}
						ZS_ONE_OUT(&v, space_text);
		/* address + port */		if (socketptr->passive)
						{
							ZS_STR_OUT(&v, port_text);
							MV_FORCE_MVAL(&m, (int)socketptr->local.port);
							mval_write(output, &m, FALSE);
						} else
						{
							ZS_STR_OUT(&v, remote_text);
							if (NULL != socketptr->remote.saddr_ip)
							{
								v.str.addr = socketptr->remote.saddr_ip;
								v.str.len = strlen(socketptr->remote.saddr_ip);
							} else
							{
								v.str.addr = "";
								v.str.len = 0;
							}
							zshow_output(output, &v.str);
							ZS_ONE_OUT(&v, at_text);
							MV_FORCE_MVAL(&m, (int)socketptr->remote.port);
							mval_write(output, &m, FALSE);
							ZS_ONE_OUT(&v, space_text);
							/* to be added later ...
								ZS_STR_OUT(&v, local_text);
								v.str.addr = socketptr->local.saddr_ip;
								v.str.len = strlen(socketptr->local.saddr_ip);
								zshow_output(output, &v.str);
								ZS_ONE_OUT(&v, at_text);
								MV_FORCE_MVAL(&m, (int)socketptr->local.port);
								mval_write(output, &m, FALSE);
							*/
						}
						ZS_ONE_OUT(&v, space_text);
						output->flush = TRUE;
						zshow_output(output, 0);
						ZS_STR_OUT(&v, space8_text);
						ZS_STR_OUT(&v, space8_text);
		/* zdelay */			if (socketptr->nodelay)
						{
							ZS_STR_OUT(&v, znodelay_text);
						} else
						{
							ZS_STR_OUT(&v, zdelay_text);
						}
						ZS_ONE_OUT(&v, space_text);
		/* zbfsize */			ZS_STR_OUT(&v, zbfsize_text);
						MV_FORCE_MVAL(&m, socketptr->buffer_size);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
		/* izbfsize */			ZS_STR_OUT(&v, zibfsize_text);
						MV_FORCE_MVAL(&m, socketptr->bufsiz);
						mval_write(output, &m, FALSE);
						ZS_ONE_OUT(&v, space_text);
		/* delimiters */		if (socketptr->n_delimiter > 0)
						{
							output->flush = TRUE;
							zshow_output(output, 0);
							ZS_STR_OUT(&v, space8_text);
							ZS_STR_OUT(&v, space8_text);
							ZS_STR_OUT(&v, delimiter_text);
							for (jj = 0; jj < socketptr->n_delimiter; jj++)
							{
								delim_len_sm = socketptr->delimiter[jj].len;
								memcpy(delim_buff_sm, socketptr->delimiter[jj].addr, delim_len_sm);
								format2zwr(delim_buff_sm, delim_len_sm, (uchar_ptr_t)delim.addr,
									&delim_len);
								delim.len = (unsigned short) delim_len;
								assert(SIZEOF(delim_mstr_buff) >= delim_len);
								zshow_output(output, &delim);
								ZS_ONE_OUT(&v, space_text);
							}
						} else
						{
							ZS_STR_OUT(&v, nodelimiter_text);
						}
		/* readmoretime */		if (DEFAULT_MOREREAD_TIMEOUT != socketptr->moreread_timeout)
						{
							ZS_STR_OUT(&v, morereadtime_text);
							MV_FORCE_MVAL(&m, socketptr->moreread_timeout);
							mval_write(output, &m, FALSE);
						}
						output->flush = TRUE;
						zshow_output(output, 0);
					}
				default:
					v.str.len = 0;
					break;
				}
				if (l->iod->error_handler.len)
				{
					ZS_PARM_EQU(&v, zshow_exce);
					ZS_ONE_OUT(&v, quote_text);
					v.str = l->iod->error_handler;
					zshow_output(output, &v.str);
					output->flush = TRUE;
					ZS_ONE_OUT(&v, quote_text);
				} else
				{
					output->flush = TRUE;
					zshow_output(output, 0);
				}
			}
			else
			{
				output->flush = TRUE;
				ZS_STR_OUT(&v, devcl);
			}
		}
	}
}
Пример #21
0
void trigger_delete_all(char *trigger_rec, uint4 len, uint4 *trig_stats)
{
	int			count;
	sgmnt_addrs		*csa;
	mval			curr_gbl_name;
	int			cycle;
	mval			*mv_count_ptr;
	mval			*mv_cycle_ptr;
	gd_region		*reg, *reg_top;
	int4			result;
	gd_region		*lgtrig_reg;
	mval			trigger_cycle;
	mval			trigger_count;
	boolean_t		this_db_updated;
	uint4			triggers_deleted;
	mval			trigjrec;
	boolean_t		jnl_format_done;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	assert(0 < dollar_tlevel);
	jnl_format_done = FALSE;
	lgtrig_reg = NULL;
	trigjrec.mvtype = MV_STR;
	trigjrec.str.len = len;
	trigjrec.str.addr = trigger_rec;
	triggers_deleted = 0;
	for (reg = gd_header->regions, reg_top = reg + gd_header->n_regions; reg < reg_top; reg++)
	{
		GVTR_SWITCH_REG_AND_HASHT_BIND_NAME(reg);
		csa = cs_addrs;
		if (NULL == csa)	/* not BG or MM access method */
			continue;
		/* gv_target now points to ^#t in region "reg" */
		/* To write the LGTRIG logical jnl record, choose some region that has journaling enabled */
		if (!reg->read_only && !jnl_format_done && JNL_WRITE_LOGICAL_RECS(csa))
			lgtrig_reg = reg;
		if (!gv_target->root)
			continue;
		/* kill ^#t("#TNAME") */
		BUILD_HASHT_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME));
		if (0 != gvcst_data())
		{	/* Issue error if we dont have permissions to touch ^#t global */
			if (reg->read_only)
				rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(reg));
			gvcst_kill(TRUE);
		}
		/* Kill all descendents of ^#t(trigvn, ...) where trigvn is any global with a trigger,
		 * but skip the ^#t("#...",...) entries. Setup ^#t("$") as the key for op_gvorder
		 */
		BUILD_HASHT_SUB_CURRKEY(LITERAL_MAXHASHVAL, STRLEN(LITERAL_MAXHASHVAL));
		TREF(gv_last_subsc_null) = FALSE; /* We know its not null, but prior state is unreliable */
		this_db_updated = FALSE;
		while (TRUE)
		{
			op_gvorder(&curr_gbl_name);
			/* quit:$length(curr_gbl_name)=0 */
			if (0 == curr_gbl_name.str.len)
				break;
			/* $get(^#t(curr_gbl_name,#COUNT)) */
			BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len,
							LITERAL_HASHCOUNT, STRLEN(LITERAL_HASHCOUNT));
			if (gvcst_get(&trigger_count))
			{
				/* Now that we know there is something to kill, check if we have permissions to touch ^#t global */
				if (reg->read_only)
					rts_error_csa(CSA_ARG(csa) VARLSTCNT(4) ERR_TRIGMODREGNOTRW, 2, REG_LEN_STR(reg));
				mv_count_ptr = &trigger_count;
				count = MV_FORCE_UINT(mv_count_ptr);
				/* $get(^#t(curr_gbl_name,#CYCLE)) */
				BUILD_HASHT_SUB_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len,
					LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE));
				if (!gvcst_get(&trigger_cycle))
				{	/* Found #COUNT, there must be #CYCLE */
					if (CDB_STAGNATE > t_tries)
						t_retry(cdb_sc_triggermod);
					assert(WBTEST_HELPOUT_TRIGDEFBAD == gtm_white_box_test_case_number);
					rts_error_csa(CSA_ARG(csa) VARLSTCNT(12) ERR_TRIGDEFBAD, 6,
							curr_gbl_name.str.len, curr_gbl_name.str.addr,
							curr_gbl_name.str.len, curr_gbl_name.str.addr, LEN_AND_LIT("\"#CYCLE\""),
							ERR_TEXT, 2, RTS_ERROR_TEXT("#CYCLE field is missing"));
				}
				mv_cycle_ptr = &trigger_cycle;
				cycle = MV_FORCE_UINT(mv_cycle_ptr);
				if (!jnl_format_done && JNL_WRITE_LOGICAL_RECS(csa))
				{
					jnl_format(JNL_LGTRIG, NULL, &trigjrec, 0);
					jnl_format_done = TRUE;
				}
				/* kill ^#t(curr_gbl_name) */
				BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len);
				gvcst_kill(TRUE);
				/* Note : ^#t(curr_gbl_name,"#TRHASH") is also killed as part of the above */
				cycle++;
				MV_FORCE_MVAL(&trigger_cycle, cycle);
				/* set ^#t(curr_gbl_name,#CYCLE)=trigger_cycle */
				SET_TRIGGER_GLOBAL_SUB_SUB_MVAL(curr_gbl_name.str.addr, curr_gbl_name.str.len,
					LITERAL_HASHCYCLE, STRLEN(LITERAL_HASHCYCLE), trigger_cycle, result);
				assert(PUT_SUCCESS == result);
				this_db_updated = TRUE;
				triggers_deleted += count;
			} /* else there is no #COUNT, then no triggers, leave #CYCLE alone */
			/* get ready for op_gvorder() call for next trigger under ^#t */
			BUILD_HASHT_SUB_CURRKEY(curr_gbl_name.str.addr, curr_gbl_name.str.len);
		}
		if (this_db_updated)
		{
			csa->incr_db_trigger_cycle = TRUE;
			if (dollar_ztrigger_invoked)
			{	/* increment db_dztrigger_cycle so that next gvcst_put/gvcst_kill in this transaction,
				 * on this region, will re-read. See trigger_update.c for a comment on why it is okay
				 * for db_dztrigger_cycle to be incremented more than once in the same transaction
				 */
				csa->db_dztrigger_cycle++;
			}
		}
	}
	if (!jnl_format_done && (NULL != lgtrig_reg))
	{	/* There was no journaled region that had a ^#t update, but found at least one journaled region
		 * so write a LGTRIG logical jnl record there.
		 */
		GVTR_SWITCH_REG_AND_HASHT_BIND_NAME(lgtrig_reg);
		csa = cs_addrs;
		JNLPOOL_INIT_IF_NEEDED(csa, csa->hdr, csa->nl);	/* see previous usage for comment on why it is needed */
		assert(dollar_tlevel);
		T_BEGIN_SETORKILL_NONTP_OR_TP(ERR_TRIGLOADFAIL);	/* needed to set update_trans TRUE on this region
									 * even if NO db updates happen to ^#t nodes. */
		jnl_format(JNL_LGTRIG, NULL, &trigjrec, 0);
		jnl_format_done = TRUE;
	}
	if (triggers_deleted)
	{
		util_out_print_gtmio("All existing triggers (count = !UL) deleted", FLUSH, triggers_deleted);
		trig_stats[STATS_DELETED] += triggers_deleted;
		trig_stats[STATS_NOERROR_TRIGFILE]++;
	} else
	{
		util_out_print_gtmio("No matching triggers found for deletion", FLUSH);
		trig_stats[STATS_UNCHANGED_TRIGFILE]++;
	}
}
Пример #22
0
int op_fnzsearch (mval *file, mint indx, mval *ret)
{
	struct stat	statbuf;
	int		stat_res;
	parse_blk	pblk;
	plength		*plen, pret;
	char		buf1[MAX_FBUFF + 1]; /* buffer to hold translated name */
	mval		sub;
	mstr		tn;
	lv_val		*ind_tmp;
	error_def(ERR_INVSTRLEN);

	MV_FORCE_STR(file);
	if (file->str.len > MAX_FBUFF)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF);

	MV_FORCE_MVAL(&ind_val, indx);
	ind_var = op_srchindx(VARLSTCNT(2) zsrch_var, &ind_val);
	if (ind_var)
	{
		assert(ind_var->v.mvtype & MV_STR);
		if (file->str.len != ind_var->v.str.len  ||  memcmp(file->str.addr, ind_var->v.str.addr, file->str.len))
		{
			op_kill(ind_var);
			ind_var = (lv_val*) 0;
		}
	}
	if (ind_var)
	{
		for (;;)
		{
			pret.p.pint = pop_top(ind_var, ret);	/* get next element off the top */
			if (!ret->str.len)
				break;

			memcpy(buf1, ret->str.addr, ret->str.len);
			buf1[ret->str.len] = 0;
			STAT_FILE(buf1, &statbuf, stat_res);
			if (-1 == stat_res)
			{
				if (errno == ENOENT)
					continue;
				rts_error(VARLSTCNT(1) errno);
			}
			break;
		}
	} else
	{
		memset(&pblk, 0, sizeof(pblk));
		pblk.buffer = buf1;
		pblk.buff_size = MAX_FBUFF;
		if (!(parse_file(&file->str, &pblk) & 1))
		{
			ret->mvtype = MV_STR;
			ret->str.len = 0;
		} else
		{
			assert(!ind_var);
			buf1[pblk.b_esl] = 0;
			/* establish new search context */
			ind_var = op_putindx(VARLSTCNT(2) zsrch_var, &ind_val);
			ind_var->v = *file;	/* zsrch_var(indx)=original spec */
			if (!(pblk.fnb & F_WILD))
			{
				sub.mvtype = MV_STR;
				sub.str.len = pblk.b_esl;
				sub.str.addr =  buf1;
				s2pool(&sub.str);
				ind_tmp = op_putindx(VARLSTCNT(2) ind_var, &sub);
				ind_tmp->v.mvtype = MV_STR; ind_tmp->v.str.len = 0;
				plen = (plength *)&ind_tmp->v.m[1];
				plen->p.pblk.b_esl = pblk.b_esl;
				plen->p.pblk.b_dir = pblk.b_dir;
				plen->p.pblk.b_name = pblk.b_name;
				plen->p.pblk.b_ext = pblk.b_ext;
			} else
				dir_srch(&pblk);

			for (;;)
			{
				pret.p.pint = pop_top(ind_var, ret);	/* get next element off the top */
				if (!ret->str.len)
					break;

				memcpy(buf1, ret->str.addr, ret->str.len);
				buf1[ret->str.len] = 0;
				STAT_FILE(buf1, &statbuf, stat_res);
				if (-1 == stat_res)
				{
					if (errno == ENOENT)
						continue;
					rts_error(VARLSTCNT(1) errno);
				}
				break;
			}
		}
	}
	assert(pret.p.pblk.b_esl == ret->str.len);
	return pret.p.pint;
}
Пример #23
0
void op_svget(int varnum, mval *v)
{
	io_log_name	*tl;
	int 		count;
	gtm_uint64_t	ucount;
	char		*c1, *c2;
	mval		*mvp;
#	ifdef UNIX
	d_rm_struct	*d_rm;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
#	if defined(UNIX) && defined(DEBUG)
	if (gtm_white_box_test_case_enabled && (WBTEST_HUGE_ALLOC == gtm_white_box_test_case_number))
	{
		if (1 == gtm_white_box_test_case_count)
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xffff;
		else if (2 == gtm_white_box_test_case_count)
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff;
		else if (3 == gtm_white_box_test_case_count)
		{
#			ifdef GTM64
			if (8 == SIZEOF(size_t))
				totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta
					= totalUsed = totalUsedGta = 0xfffffffffffffff;
			else
#			endif
				totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff;
		} else
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed
				= totalUsedGta = GTM64_ONLY(SIZEOF(size_t)) NON_GTM64_ONLY(SIZEOF(size_t) > 4 ? 4 : SIZEOF(size_t));
	}
#	endif
	switch (varnum)
	{
		case SV_HOROLOG:
			op_horolog(v);
			break;
		case SV_ZGBLDIR:
			v->mvtype = MV_STR;
			v->str = dollar_zgbldir.str;
			break;
		case SV_PRINCIPAL:
			tl = dollar_principal ? dollar_principal : io_root_log_name->iod->trans_name;
			v->str.addr = tl->dollar_io;
			v->str.len = tl->len;
			/*** The following should be in the I/O code ***/
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			v->mvtype = MV_STR;
			break;
		case SV_ZIO:
			v->mvtype = MV_STR;
			/* NOTE:	This is **NOT** equivalent to :
			 *		io_curr_log_name->dollar_io
			 */
			v->str.addr = io_curr_device.in->trans_name->dollar_io;
			v->str.len = io_curr_device.in->trans_name->len;
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			break;
		case SV_JOB:
			*v = dollar_job;
			break;
		case SV_REFERENCE:
			get_reference(v);
			break;
		case SV_SYSTEM:
			*v = dollar_system;
			break;
		case SV_STORAGE:
			/* double2mval(v, getstorage()); Causes issues with unaligned stack on x86_64 - remove until fixed */
			i2mval(v, getstorage());
			break;
		case SV_TLEVEL:
			count = (int)dollar_tlevel;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_TRESTART:
			MV_FORCE_MVAL(v, (int)((MAX_VISIBLE_TRESTART < dollar_trestart) ? MAX_VISIBLE_TRESTART : dollar_trestart));
			break;
		case SV_X:
			count = (int)io_curr_device.out->dollar.x;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_Y:
			count = (int)io_curr_device.out->dollar.y;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZA:
			count = (int)io_curr_device.in->dollar.za;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZB:
			c1 = (char *)io_curr_device.in->dollar.zb;
			c2 = c1 + SIZEOF(io_curr_device.in->dollar.zb);
			ENSURE_STP_FREE_SPACE(SIZEOF(io_curr_device.in->dollar.zb));
			v->mvtype = MV_STR;
			v->str.addr = (char *)stringpool.free;
			while (c1 < c2 && *c1)
				*stringpool.free++ = *c1++;
			v->str.len = INTCAST((char *)stringpool.free - v->str.addr);
			break;
		case SV_ZC:	/****THESE ARE DUMMY VALUES ONLY!!!!!!!!!!!!!!!!!****/
			MV_FORCE_MVAL(v, 0);
			break;
		case SV_ZCMDLINE:
			get_command_line(v, TRUE);	/* TRUE to indicate we want $ZCMDLINE
							   (i.e. processed not actual command line) */
			break;
		case SV_ZEOF:
#			ifdef UNIX
			if (rm == io_curr_device.in->type)
			{
				d_rm = (d_rm_struct *)io_curr_device.in->dev_sp;
				if (RM_READ != d_rm->lastop)
				{
					*v = literal_zero;
					break;
				}
			}
#			endif
			*v = io_curr_device.in->dollar.zeof ? literal_one : literal_zero;
			break;
		case SV_ZQUIT:
			*v = dollar_zquit_anyway ? literal_one : literal_zero;
			break;
		case SV_IO:
			v->str.addr = io_curr_device.in->name->dollar_io;
			v->str.len = io_curr_device.in->name->len;
			/*** The following should be in the I/O code ***/
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			v->mvtype = MV_STR;
			break;
		case SV_PROMPT:
			v->mvtype = MV_STR;
			v->str.addr = (TREF(gtmprompt)).addr;
			v->str.len = (TREF(gtmprompt)).len;
			s2pool(&v->str);
			break;
		case SV_ZCOMPILE:
			v->mvtype = MV_STR;
			v->str = TREF(dollar_zcompile);
			s2pool(&(v->str));
			break;
		case SV_ZDIR:
			setzdir(NULL, v);
			if (v->str.len != dollar_zdir.str.len || 0 != memcmp(v->str.addr, dollar_zdir.str.addr, v->str.len))
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4, v->str.len, v->str.addr,
					   dollar_zdir.str.len, dollar_zdir.str.addr);
			SKIP_DEVICE_IF_NOT_NEEDED(v);
			s2pool(&(v->str));
			break;
		case SV_ZSTEP:
			*v = dollar_zstep;
			break;
		case SV_ZMODE:
			*v = TREF(dollar_zmode);
			break;
		case SV_ZMAXTPTIME:
			i2mval(v, TREF(dollar_zmaxtptime));
			break;
		case SV_ZPOS:
			getzposition(v);
			break;
		case SV_ZPROC:
			getzprocess();
			*v = dollar_zproc;
			break;
		case SV_ZLEVEL:
			count = dollar_zlevel();
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZROUTINES:
			if (!TREF(zro_root))
				zro_init();
			v->mvtype = MV_STR;
			v->str = TREF(dollar_zroutines);
			s2pool(&(v->str));
			break;
		case SV_ZSOURCE:
			v->mvtype = MV_STR;
			v->str = dollar_zsource.str;
			break;
		case SV_ZSTATUS:
			*v = dollar_zstatus;
			s2pool(&(v->str));
			break;
		case SV_ZTRAP:
			v->mvtype = MV_STR;
			v->str = dollar_ztrap.str;
			assert(!v->str.len || !ztrap_explicit_null);
			s2pool(&(v->str));
			break;
		case SV_DEVICE:
			get_dlr_device(v);
			break;
		case SV_KEY:
			get_dlr_key(v);
			break;
		case SV_ZVERSION:
			v->mvtype = MV_STR;
			v->str.addr = (char *)gtm_release_name;
			v->str.len = gtm_release_name_len;
			break;
		case SV_ZSYSTEM:
			MV_FORCE_MVAL(v, dollar_zsystem);
			break;
		case SV_ZCSTATUS:
			/* Maintain the external $ZCSTATUS == 1 for SUCCESS on UNIX while internal good is 0 */
			MV_FORCE_MVAL(v, UNIX_ONLY((0 == TREF(dollar_zcstatus)) ? 1 : ) TREF(dollar_zcstatus));
			break;
		case SV_ZEDITOR:
			MV_FORCE_MVAL(v, dollar_zeditor);
			break;
		case SV_QUIT:
			MV_FORCE_MVAL(v, dollar_quit());
			break;
		case SV_ECODE:
			ecode_get(-1, v);
			break;
		case SV_ESTACK:
			count = (dollar_zlevel() - 1) - dollar_estack_delta.m[0];
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ETRAP:
			v->mvtype = MV_STR;
			v->str = dollar_etrap.str;
			assert(!v->str.len || !ztrap_explicit_null);
			s2pool(&(v->str));
			break;
		case SV_STACK:
			count = (dollar_zlevel() - 1);
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZERROR:
			v->mvtype = MV_STR;
			v->str = dollar_zerror.str;
			s2pool(&(v->str));
			break;
		case SV_ZYERROR:
			v->mvtype = MV_STR;
			v->str = dollar_zyerror.str;
			s2pool(&(v->str));
			break;
		case SV_ZINTERRUPT:
			v->mvtype = MV_STR;
			v->str = dollar_zinterrupt.str;
			s2pool(&(v->str));
			break;
		case SV_ZININTERRUPT:
			MV_FORCE_MVAL(v, dollar_zininterrupt);
			break;
		case SV_ZJOB:
			MV_FORCE_UMVAL(v, dollar_zjob);
			break;
		case SV_ZDATE_FORM:
			MV_FORCE_MVAL(v, TREF(zdate_form));
			break;
		case SV_ZTEXIT:
			*v = dollar_ztexit;
			break;
		case SV_ZALLOCSTOR:
			ucount = (gtm_uint64_t)totalAlloc + (gtm_uint64_t)totalAllocGta;
			ui82mval(v, ucount);
			break;
		case SV_ZREALSTOR:
			ucount = (gtm_uint64_t)totalRmalloc + (gtm_uint64_t)totalRallocGta;
			ui82mval(v, ucount);
			break;
		case SV_ZUSEDSTOR:
			ucount = (gtm_uint64_t)totalUsed + (gtm_uint64_t)totalUsedGta;
			ui82mval(v, ucount);
			break;
		case SV_ZCHSET:
			v->mvtype = MV_STR;
			v->str = dollar_zchset;
			break;
		case SV_ZPATNUMERIC:
			v->mvtype = MV_STR;
			v->str = dollar_zpatnumeric;
			break;
		case SV_ZTNAME:
		case SV_ZTCODE:		/* deprecated */
#			ifdef GTM_TRIGGER
			if (NULL == dollar_ztname)
				memcpy(v, &literal_null, SIZEOF(mval));
			else
			{
				v->mvtype = MV_STR;
				v->str.addr = dollar_ztname->addr;
				v->str.len = dollar_ztname->len;
			}
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTDATA:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but it might be numeric and need conversion to a string */
			assert(!dollar_ztdata || MV_DEFINED(dollar_ztdata));
			if (NULL != dollar_ztdata)
				MV_FORCE_STR(dollar_ztdata);
			memcpy(v, (NULL != dollar_ztdata) ? dollar_ztdata : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTDELIM:
#			ifdef GTM_TRIGGER
			assert(!dollar_ztdelim || MV_DEFINED(dollar_ztdelim));
			if (NULL == dollar_ztdelim || !(MV_STR & dollar_ztdelim->mvtype) || (0 == dollar_ztdelim->str.len))
				memcpy(v, &literal_null, SIZEOF(mval));
			else
				memcpy(v, dollar_ztdelim, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTOLDVAL:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but it might be numeric and need conversion to a string */
			assert(!dollar_ztoldval || MV_DEFINED(dollar_ztoldval));
			if (NULL != dollar_ztoldval)
				MV_FORCE_STR(dollar_ztoldval);
			memcpy(v, (NULL != dollar_ztoldval) ? dollar_ztoldval : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTRIGGEROP:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but assert it's a string */
			assert(!dollar_ztriggerop || (MV_STR & dollar_ztriggerop->mvtype));
			memcpy(v, (NULL != dollar_ztriggerop) ? dollar_ztriggerop : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTUPDATE:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but if there were no delims involved, the value will be undefined, and
			 * we return a "literal_null".
			 */
			memcpy(v, ((NULL != dollar_ztupdate && (MV_STR & dollar_ztupdate->mvtype)) ? dollar_ztupdate
				   : &literal_null), SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTVALUE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			assert(!dollar_ztvalue || MV_DEFINED(dollar_ztvalue));
			if (NULL != dollar_ztvalue)
				MV_FORCE_STR(dollar_ztvalue);
			memcpy(v, (NULL != dollar_ztvalue) ? dollar_ztvalue : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTWORMHOLE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			mvp = &dollar_ztwormhole;
			if (MV_DEFINED(mvp))
			{
				MV_FORCE_STR(mvp);
				memcpy(v, mvp, SIZEOF(mval));
			} else
				memcpy(v, &literal_null, SIZEOF(mval));
			ztwormhole_used = TRUE;
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTSLATE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			assert(MV_DEFINED((&dollar_ztslate)));
			mvp = &dollar_ztslate;
			MV_FORCE_STR(mvp);
			memcpy(v, mvp, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTLEVEL:
#			ifdef GTM_TRIGGER
			MV_FORCE_MVAL(v, gtm_trigger_depth);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZONLNRLBK:
#			ifdef UNIX
			count = TREF(dollar_zonlnrlbk);
			MV_FORCE_MVAL(v, count);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZCLOSE:
#			ifdef UNIX
			count = TREF(dollar_zclose);
			MV_FORCE_MVAL(v, count);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZKEY:
			get_dlr_zkey(v);
			break;
		default:
			assertpro(FALSE);
	}
}
Пример #24
0
int op_fnzsearch(mval *file, mint indx, mval *ret)
{
	struct stat	statbuf;
	int		stat_res;
	parse_blk	pblk;
	plength		*plen, pret;
	char		buf1[MAX_FBUFF + 1]; /* buffer to hold translated name */
	mval		sub;
	mstr		tn;
	lv_val		*ind_tmp;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	ESTABLISH_RET(fnzsrch_ch, -1);
	TREF(fnzsearch_nullsubs_sav) = TREF(lv_null_subs);
	TREF(lv_null_subs) = LVNULLSUBS_OK;	/* $ZSearch processing depends on this */
	MV_FORCE_STR(file);
	if (file->str.len > MAX_FBUFF)
		rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, file->str.len, MAX_FBUFF);
	MV_FORCE_MVAL(((mval *)TADR(fnzsearch_sub_mval)), indx);
	TREF(fnzsearch_lv_vars) = op_srchindx(VARLSTCNT(2) TREF(zsearch_var), (mval *)TADR(fnzsearch_sub_mval));
	if (TREF(fnzsearch_lv_vars))
	{
		assert((TREF(fnzsearch_lv_vars))->v.mvtype & MV_STR);
		if ((file->str.len != (TREF(fnzsearch_lv_vars))->v.str.len)
			|| memcmp(file->str.addr, (TREF(fnzsearch_lv_vars))->v.str.addr, file->str.len))
		{
			op_kill(TREF(fnzsearch_lv_vars));
			TREF(fnzsearch_lv_vars) = NULL;
		}
	}
	if (TREF(fnzsearch_lv_vars))
	{
		for (;;)
		{
			pret.p.pint = pop_top(TREF(fnzsearch_lv_vars), ret);	/* get next element off the top */
			if (!ret->str.len)
				break;
			memcpy(buf1, ret->str.addr, ret->str.len);
			buf1[ret->str.len] = 0;
			STAT_FILE(buf1, &statbuf, stat_res);
			if (-1 == stat_res)
			{
				if (errno == ENOENT)
					continue;
				rts_error(VARLSTCNT(1) errno);
			}
			break;
		}
	} else
	{
		memset(&pblk, 0, SIZEOF(pblk));
		pblk.buffer = buf1;
		pblk.buff_size = MAX_FBUFF;
		if (!(parse_file(&file->str, &pblk) & 1))
		{
			ret->mvtype = MV_STR;
			ret->str.len = 0;
		} else
		{
			assert(!TREF(fnzsearch_lv_vars));
			buf1[pblk.b_esl] = 0;
			/* establish new search context */
			TREF(fnzsearch_lv_vars) = op_putindx(VARLSTCNT(2) TREF(zsearch_var), TADR(fnzsearch_sub_mval));
			(TREF(fnzsearch_lv_vars))->v = *file;	/* zsearch_var(indx)=original spec */
			if (!(pblk.fnb & F_WILD))
			{
				sub.mvtype = MV_STR;
				sub.str.len = pblk.b_esl;
				sub.str.addr =  buf1;
				s2pool(&sub.str);
				ind_tmp = op_putindx(VARLSTCNT(2) TREF(fnzsearch_lv_vars), &sub);
				ind_tmp->v.mvtype = MV_STR; ind_tmp->v.str.len = 0;
				plen = (plength *)&ind_tmp->v.m[1];
				plen->p.pblk.b_esl = pblk.b_esl;
				plen->p.pblk.b_dir = pblk.b_dir;
				plen->p.pblk.b_name = pblk.b_name;
				plen->p.pblk.b_ext = pblk.b_ext;
			} else
				dir_srch(&pblk);
			for (;;)
			{
				pret.p.pint = pop_top(TREF(fnzsearch_lv_vars), ret);	/* get next element off the top */
				if (!ret->str.len)
					break;
				memcpy(buf1, ret->str.addr, ret->str.len);
				buf1[ret->str.len] = 0;
				STAT_FILE(buf1, &statbuf, stat_res);
				if (-1 == stat_res)
				{
					if (errno == ENOENT)
						continue;
					rts_error(VARLSTCNT(1) errno);
				}
				break;
			}
		}
	}
	assert((0 == ret->str.len) || (pret.p.pblk.b_esl == ret->str.len));
	TREF(lv_null_subs) = TREF(fnzsearch_nullsubs_sav);
	REVERT;
	return pret.p.pint;
}
Пример #25
0
void op_fnorder(lv_val *src, mval *key, mval *dst)
{
	mval		tmp_sbs;
	int             length;
	boolean_t	is_canonical, is_fnnext, get_first;
	lvTree		*lvt;
	lvTreeNode	*node;
	uint4		mvt;	/* Local copy of mvtype, bit ands use a int4, so do conversion once */
	mstr		*str;
	int4		intval;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	is_fnnext = TREF(in_op_fnnext);
	TREF(in_op_fnnext) = FALSE;
	if (src && (lvt = LV_GET_CHILD(src)))	/* caution: assignment */
	{
		MV_FORCE_DEFINED(key);
		/* If last subscript is null, $ORDER returns the first subscript in that level.
		 * With the obsoleted $NEXT function, a subscript of -1 also triggers the same behavior.
		 */
		get_first = FALSE;
		if (MV_IS_STRING(key) && (0 == key->str.len))
			get_first = TRUE;
		else if (is_fnnext)
		{
			mvt = key->mvtype;
			if (!(mvt & (MV_NM | MV_NUM_APPROX)))
			{	/* Not currently in numeric form.  Is it cannonical? */
				if (val_iscan(key))
				{	/* Yes, convert it to numeric */
					(void)s2n(key);
					mvt = key->mvtype;
					if (!(mvt & MV_NM))
						rts_error(VARLSTCNT(1) ERR_NUMOFLOW);
				} else	/* No, not numeric.  Note the fact for future reference */
					mvt = key->mvtype |= MV_NUM_APPROX;
			}
			if (MV_IS_TRUEINT(key, &intval) && (MINUS_ONE == key->m[1]))
				get_first = TRUE;
		}
		if (get_first)
			node = lvAvlTreeFirst(lvt);
		else
		{
			is_canonical = MV_IS_CANONICAL(key);
			if (!is_canonical)
			{
				assert(!TREE_KEY_SUBSCR_IS_CANONICAL(key->mvtype));
				if (TREF(local_collseq))
				{
					ALLOC_XFORM_BUFF(key->str.len);
					tmp_sbs.mvtype = MV_STR;
					tmp_sbs.str.len = TREF(max_lcl_coll_xform_bufsiz);
					assert(NULL != TREF(lcl_coll_xform_buff));
					tmp_sbs.str.addr = TREF(lcl_coll_xform_buff);
					do_xform(TREF(local_collseq), XFORM, &key->str, &tmp_sbs.str, &length);
					tmp_sbs.str.len = length;
					s2pool(&(tmp_sbs.str));
					key = &tmp_sbs;
				}
			} else
			{	/* Need to set canonical bit before calling tree search functions.
				 * But input mval could be read-only so cannot modify that even if temporarily.
				 * So take a copy of the mval and modify that instead.
				 */
				tmp_sbs = *key;
				key = &tmp_sbs;
				MV_FORCE_NUM(key);
				TREE_KEY_SUBSCR_SET_MV_CANONICAL_BIT(key);	/* used by the lvTreeKeyNext function */
			}
			node = lvAvlTreeKeyNext(lvt, key);
		}
		/* If STDNULLCOLL, skip to the next subscript should the current subscript be "" */
		if (TREF(local_collseq_stdnull) && (NULL != node) && LV_NODE_KEY_IS_NULL_SUBS(node))
		{
			assert(LVNULLSUBS_OK == TREF(lv_null_subs));
			node = lvAvlTreeNext(node);
		}
	} else
		node = NULL;
	if (NULL == node)
	{
		if (!is_fnnext)
		{
			dst->mvtype = MV_STR;
			dst->str.len = 0;
		} else
			MV_FORCE_MVAL(dst, -1);
	} else
	{
		LV_NODE_GET_KEY(node, dst); /* Get node key into "dst" depending on the structure type of "node" */
		/* Code outside lv_tree.c does not currently know to make use of MV_CANONICAL bit so reset it
		 * until the entire codebase gets fixed to maintain MV_CANONICAL bit accurately at which point,
		 * this RESET can be removed */
		TREE_KEY_SUBSCR_RESET_MV_CANONICAL_BIT(dst);
		if (TREF(local_collseq) && MV_IS_STRING(dst))
		{
			ALLOC_XFORM_BUFF(dst->str.len);
			assert(NULL != TREF(lcl_coll_xform_buff));
			tmp_sbs.str.addr = TREF(lcl_coll_xform_buff);
			tmp_sbs.str.len = TREF(max_lcl_coll_xform_bufsiz);
			do_xform(TREF(local_collseq), XBACK, &dst->str, &tmp_sbs.str, &length);
			tmp_sbs.str.len = length;
			s2pool(&(tmp_sbs.str));
			dst->str = tmp_sbs.str;
		}
	}
}
Пример #26
0
STATICFNDEF int4 update_trigger_hash_value(char *trigvn, int trigvn_len, char **values, uint4 *value_len, stringkey *set_hash,
					   stringkey *kill_hash, int old_trig_index, int new_trig_index)
{
	sgmnt_addrs		*csa;
	int			hash_index;
	mval			key_val;
	uint4			len;
	mval			mv_hash;
	mval			mv_hash_indx;
	int			num_len;
	char			*ptr;
	int4			result;
	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
	gv_key			*save_gv_currkey;
	gd_region		*save_gv_cur_region;
	gv_namehead		*save_gv_target;
	sgm_info		*save_sgm_info_ptr;
	char			tmp_str[MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT];
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	SAVE_TRIGGER_REGION_INFO;
	SWITCH_TO_DEFAULT_REGION;
	assert(0 != gv_target->root);
	if (NULL != strchr(values[CMD_SUB], 'S'))
	{
		if (search_trigger_hash(trigvn, trigvn_len, set_hash, old_trig_index, &hash_index))
		{
			MV_FORCE_UMVAL(&mv_hash, set_hash->hash_code);
			MV_FORCE_MVAL(&mv_hash_indx, hash_index);
			BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx);
			if (!gvcst_get(&key_val))
			{	/* There has to be a #TRHASH entry */
				assert(FALSE);
				rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""),
					set_hash->str.len, set_hash->str.addr);
			}
			assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len);
			len = STRLEN(key_val.str.addr);
			memcpy(tmp_str, key_val.str.addr, len);
			ptr = tmp_str + len;
			*ptr++ = '\0';
			num_len = 0;
			I2A(ptr, num_len, new_trig_index);
			len += num_len + 1;
			SET_TRIGGER_GLOBAL_SUB_MSUB_MSUB_STR(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx,
				tmp_str, len, result);
			if (PUT_SUCCESS != result)
			{
				RESTORE_TRIGGER_REGION_INFO;
				return result;
			}
		} else
		{	/* There has to be an entry with the old hash value, we just looked it up */
			assert(FALSE);
			rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""),
				set_hash->str.len, set_hash->str.addr);
		}
	}
	if (search_trigger_hash(trigvn, trigvn_len, kill_hash, old_trig_index, &hash_index))
	{
		MV_FORCE_UMVAL(&mv_hash, kill_hash->hash_code);
		MV_FORCE_MVAL(&mv_hash_indx, hash_index);
		BUILD_HASHT_SUB_MSUB_MSUB_CURRKEY(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx);
		if (!gvcst_get(&key_val))
		{	/* There has to be a #TRHASH entry */
			assert(FALSE);
			rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""),
				kill_hash->str.len, kill_hash->str.addr);
		}
		assert((MAX_MIDENT_LEN + 1 + MAX_DIGITS_IN_INT) >= key_val.str.len);
		len = STRLEN(key_val.str.addr);
		memcpy(tmp_str, key_val.str.addr, len);
		ptr = tmp_str + len;
		*ptr++ = '\0';
		num_len = 0;
		I2A(ptr, num_len, new_trig_index);
		len += num_len + 1;
		SET_TRIGGER_GLOBAL_SUB_MSUB_MSUB_STR(LITERAL_HASHTRHASH, STRLEN(LITERAL_HASHTRHASH), mv_hash, mv_hash_indx,
			tmp_str, len, result);
		if (PUT_SUCCESS != result)
		{
			RESTORE_TRIGGER_REGION_INFO;
			return result;
		}
	} else
	{	/* There has to be an entry with the old hash value, we just looked it up */
		assert(FALSE);
		rts_error(VARLSTCNT(8) ERR_TRIGDEFBAD, 6, trigvn_len, trigvn, LEN_AND_LIT("\"#TRHASH\""), kill_hash->str.len,
			kill_hash->str.addr);
	}
	RESTORE_TRIGGER_REGION_INFO;
	return PUT_SUCCESS;
}
Пример #27
0
void zshow_locks(zshow_out *output)
{
	static readonly char zal[] = "ZAL ";
	static readonly char lck[] = "LOCK ";
	static readonly char lvl[] = " LEVEL=";
	mval v;
	mlk_pvtblk *temp;

	for (temp = mlk_pvt_root; temp; temp = temp->next)
	{
		if (!temp->granted)
			continue;

		if (temp->nodptr && (temp->nodptr->owner != process_id
			|| temp->sequence != temp->nodptr->sequence))
			continue;

		output->flush = FALSE;
		if (temp->level && temp->zalloc)
		{
			v.str.addr = &zal[0];
			v.str.len = sizeof(zal) - 1;
			zshow_output(output,&v.str);
			zshow_format_lock(output,temp);
			output->flush = TRUE;
			v.str.len = 0;
			zshow_output(output,&v.str);
			output->flush = FALSE;
			v.str.addr = &lck[0];
			v.str.len = sizeof(lck) - 1;
			zshow_output(output,&v.str);
			zshow_format_lock(output,temp);
			v.str.addr = &lvl[0];
			v.str.len = sizeof(lvl) - 1;
			zshow_output(output,&v.str);
			MV_FORCE_MVAL(&v,temp->level) ;
			mval_write(output,&v,TRUE);
		}
		else if (temp->level)
		{
			v.str.addr = &lck[0];
			v.str.len = sizeof(lck) - 1;
			zshow_output(output,&v.str);
			zshow_format_lock(output,temp);
			v.str.addr = &lvl[0];
			v.str.len = sizeof(lvl) - 1;
			zshow_output(output,&v.str);
			MV_FORCE_MVAL(&v,temp->level) ;
			mval_write(output,&v,TRUE);
		}else if (temp->zalloc)
		{
			v.str.addr = &zal[0];
			v.str.len = sizeof(zal) - 1;
			zshow_output(output,&v.str);
			zshow_format_lock(output,temp);
			output->flush = TRUE;
			v.str.len = 0;
			zshow_output(output,&v.str);
		}
 	}
}
Пример #28
0
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v)
{
	unsigned char	*ptr;
	short		len, temp_short;
	int4		status, max_reply_len;
	struct CLB	*lnk;
	error_def(ERR_BADSRVRNETMSG);

	lnk = gv_cur_region->dyn.addr->cm_blk;
	lnk->ast = 0;	/* all database queries are sync */
	lnk->cbl = 1 + /* HDR */
		   gv_currkey->end + /* key */
		   sizeof(unsigned short) + /* gv_key.top */
		   sizeof(unsigned short) + /* gv_key.end */
		   sizeof(unsigned short) + /* gv_key.prev */
		   sizeof(unsigned char) + /* gv_key.base */
		   sizeof(unsigned char) + /* regnum */
		   sizeof(unsigned short); /* size for variable len SUBSC */
	if (CMMS_Q_PUT == query_code)
		lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */
	if (CMMS_Q_GET == query_code || CMMS_Q_QUERY == query_code && ((link_info *)lnk->usr)->query_is_queryget)
		max_reply_len = lnk->mbl + sizeof(unsigned short) + MAX_STRLEN; /* can't predict the length of data value */
	else
		max_reply_len = lnk->mbl;
	if (stringpool.top < stringpool.free + max_reply_len)
		stp_gcol(max_reply_len);
	lnk->mbf = stringpool.free;
	ptr = lnk->mbf;
	*ptr++ = query_code;
	/* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */
	temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1;
	CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	*ptr++ = gv_cur_region->cmx_regnum;
	CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	memcpy(ptr, gv_currkey->base, gv_currkey->end + 1);
	if (query_code == CMMS_Q_PUT)
	{
		ptr += gv_currkey->end + 1;
		temp_short = (short)v->str.len;
		assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */
		CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		memcpy(ptr,v->str.addr, v->str.len);
	}
	status = cmi_write(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code)
	{
		status = cmi_read(lnk);
		if (CMI_ERROR(status))
		{
			((link_info *)(lnk->usr))->neterr = TRUE;
			gvcmz_error(query_code, status);
			return;
		}
		ptr = lnk->mbf;
		if (reply_code != *ptr)
		{
			if (*ptr != CMMS_E_ERROR)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk,FALSE);
		}
		return;
	}
	status = cmi_read(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	ptr = lnk->mbf;
	if (reply_code != *ptr)
	{
		if (CMMS_R_UNDEF != *ptr || CMMS_Q_GET != query_code)
		{
			if (CMMS_E_ERROR != *ptr)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk, FALSE);
		}
		return;
	}
	ptr++;
	if (CMMS_R_DATA == reply_code)
	{
		CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		if (1 != temp_short)
			rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
		ptr += sizeof(short);
		status = *ptr;	/* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */
		MV_FORCE_MVAL(v, status);
		return;
	}
	if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER)
	{
		CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		if (1 == len)
		{
			MV_FORCE_MVAL(v, 0);
		} else
		{
			if (*ptr++ != gv_cur_region->cmx_regnum)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			/* memcpy(gv_altkey, ptr, len - 1); */
			CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) -
						     sizeof(unsigned short));
			ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short));
			MV_FORCE_MVAL(v, 1);
		}
		if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget)
		{
			if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget)
				v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */
			return;
		}
	}
	assert(CMMS_R_GET == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len);
	CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(unsigned short);
	assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */
	v->mvtype = MV_STR;
	v->str.len = len;
	v->str.addr = (char *)stringpool.free;	/* we don't need the reply msg anymore, can overwrite reply */
	memcpy(v->str.addr, ptr, len);		/* so that we don't leave a gaping hole in the stringpool */
	stringpool.free += len;
	return;
}
Пример #29
0
void op_indtext(mval *lab, mint offset, mval *rtn, mval *dst)
{
	bool		rval;
	mstr		*obj, object;
	mval		mv_off;
	oprtype		opt;
	triple		*ref;
	icode_str	indir_src;

	error_def(ERR_INDMAXNEST);
	error_def(ERR_STACKOFLOW);
	error_def(ERR_STACKCRIT);

	MV_FORCE_STR(lab);
	indir_src.str.len = lab->str.len;
	indir_src.str.len += SIZEOF("+^") - 1;
	indir_src.str.len += MAX_NUM_SIZE;
	indir_src.str.len += rtn->str.len;
	ENSURE_STP_FREE_SPACE(indir_src.str.len);
	DBG_MARK_STRINGPOOL_UNEXPANDABLE; /* Now that we have ensured enough space in the stringpool, we dont expect any more
					   * garbage collections or expansions until we are done with the below initialization.
					   */
	/* Push an mval pointing to the complete entry ref on to the stack so the string is valid even
	 * if garbage collection occurs before cache_put() */
	PUSH_MV_STENT(MVST_MVAL);
	mv_chain->mv_st_cont.mvs_mval.mvtype = 0;	/* so stp_gcol (if invoked below) does not get confused by this otherwise
							 * incompletely initialized mval in the M-stack */
	mv_chain->mv_st_cont.mvs_mval.str.addr = (char *)stringpool.free;
	memcpy(stringpool.free, lab->str.addr, lab->str.len);
	stringpool.free += lab->str.len;
	*stringpool.free++ = '+';
	MV_FORCE_MVAL(&mv_off, offset);
	MV_FORCE_STRD(&mv_off); /* goes at stringpool.free. we already made enough space in the stp_gcol() call */
	*stringpool.free++ = '^';
	memcpy(stringpool.free, rtn->str.addr, rtn->str.len);
	stringpool.free += rtn->str.len;
	mv_chain->mv_st_cont.mvs_mval.str.len = INTCAST(stringpool.free - (unsigned char*)mv_chain->mv_st_cont.mvs_mval.str.addr);
	mv_chain->mv_st_cont.mvs_mval.mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */
	DBG_MARK_STRINGPOOL_EXPANDABLE;	/* Now that we are done with stringpool.free initializations, mark as free for expansion */

	indir_src.str = mv_chain->mv_st_cont.mvs_mval.str;
	indir_src.code = indir_text;
	if (NULL == (obj = cache_get(&indir_src)))
	{
		comp_init(&indir_src.str);
		rval = f_text(&opt, OC_FNTEXT);
		if (!comp_fini(rval, &object, OC_IRETMVAL, &opt, indir_src.str.len))
		{
			assert(mv_chain->mv_st_type == MVST_MVAL);
			POP_MV_STENT();
			return;
		}
		indir_src.str.addr = mv_chain->mv_st_cont.mvs_mval.str.addr;
		cache_put(&indir_src, &object);
		*ind_result_sp++ = dst;
		if (ind_result_sp >= ind_result_top)
			rts_error(VARLSTCNT(1) ERR_INDMAXNEST);
		assert(mv_chain->mv_st_type == MVST_MVAL);
		POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */
		comp_indr(&object);
		return;
	}
	*ind_result_sp++ = dst;
	if (ind_result_sp >= ind_result_top)
		rts_error(VARLSTCNT(1) ERR_INDMAXNEST);
	assert(mv_chain->mv_st_type == MVST_MVAL);
	POP_MV_STENT(); /* unwind the mval entry before the new frame gets added by comp_indir below */
	comp_indr(obj);
	return;
}
Пример #30
0
STATICFNDEF void cleanup_trigger_name(char *trigvn, int trigvn_len, char *trigger_name, int trigger_name_len)
{
	sgmnt_addrs		*csa;
	mname_entry		gvent;
	gv_namehead		*hasht_tree;
	int4			result;
	char			save_currkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
	char			save_altkey[SIZEOF(gv_key) + DBKEYSIZE(MAX_KEY_SZ)];
	gv_key			*save_gv_altkey;
	gv_key			*save_gv_currkey;
	gd_region		*save_gv_cur_region;
	gv_namehead		*save_gv_target;
	gv_namehead		*save_gvtarget;
	sgm_info		*save_sgm_info_ptr;
	char			trunc_name[MAX_TRIGNAME_LEN + 1];
	uint4			used_trigvn_len;
	mval			val;
	mval			*val_ptr;
	char			val_str[MAX_DIGITS_IN_INT + 1];
	int			var_count;
	boolean_t		is_auto_name;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* assume user defined name or auto gen name whose GVN < 21 chars */
	is_auto_name = FALSE;
	if (!trigger_user_name(trigger_name, trigger_name_len))
	{	/* auto gen name uses #TNCOUNT and #SEQNO under #TNAME */
		is_auto_name = TRUE;
		used_trigvn_len = MIN(trigvn_len, MAX_AUTO_TRIGNAME_LEN);
		memcpy(trunc_name, trigvn, used_trigvn_len);
	}
	SAVE_TRIGGER_REGION_INFO;
	SWITCH_TO_DEFAULT_REGION;
	if (0 != gv_target->root)
	{
		if (is_auto_name)
		{
			/* $get(^#t("#TNAME",<trunc_name>,"#TNCOUNT")) */
			BUILD_HASHT_SUB_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trunc_name,
							used_trigvn_len, LITERAL_HASHTNCOUNT, STRLEN(LITERAL_HASHTNCOUNT));
			if (gvcst_get(&val))
			{	 /* only long autogenerated names have a #TNCOUNT entry */
				val_ptr = &val;
				var_count = MV_FORCE_INT(val_ptr);
				if (1 == var_count)
				{
					/* kill ^#t("#TNAME",<trunc_name>) to kill #TNCOUNT and #SEQNO */
					BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trunc_name,
								    used_trigvn_len);
					gvcst_kill(TRUE);
				} else
				{
					var_count--;
					MV_FORCE_MVAL(&val, var_count);
					/* set ^#t("#TNAME",GVN,"#TNCOUNT")=var_count */
					SET_TRIGGER_GLOBAL_SUB_SUB_SUB_MVAL(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME),
									trunc_name, used_trigvn_len, LITERAL_HASHTNCOUNT,
									STRLEN(LITERAL_HASHTNCOUNT), val, result);
					assert(PUT_SUCCESS == result);		/* The count size can only decrease */
				}
			}
		}
		/* kill ^#t("#TNAME",<trigger_name>,:) or zkill ^#t("#TNAME",<trigger_name>) if is_auto_name==FALSE */
		BUILD_HASHT_SUB_SUB_CURRKEY(LITERAL_HASHTNAME, STRLEN(LITERAL_HASHTNAME), trigger_name,
					    trigger_name_len - 1);
		gvcst_kill(is_auto_name);
	}
	RESTORE_TRIGGER_REGION_INFO;
}