Exemple #1
0
void open_list_file(void)
{
	char charspace;
	uint4  status;
	char		*p, list_name[MAX_MIDENT_LEN + STR_LIT_LEN(LISTEXT)], fname[MAX_FBUFF + 1];
	mval		parms;
	mval		file;
	mstr		fstr;
	parse_blk	pblk;
	time_t		clock;

	lst_param.list_line = 1;
	lst_param.page = 0;

	memset(&pblk, 0, sizeof(pblk));
	assert(module_name.len <= MAX_MIDENT_LEN);
	pblk.def1_size = module_name.len;
	memcpy(&list_name[0], module_name.addr, pblk.def1_size);
	MEMCPY_LIT(&list_name[pblk.def1_size], LISTEXT);
	pblk.def1_size += STR_LIT_LEN(LISTEXT);
	pblk.def1_buf = list_name;
	pblk.buffer = &fname[0];
	pblk.buff_size = MAX_FBUFF;
	pblk.fop = F_SYNTAXO;
	fstr.len = (MV_DEFINED(&cmd_qlf.list_file) ? cmd_qlf.list_file.str.len : 0);
	fstr.addr = cmd_qlf.list_file.str.addr;
	if (!(status = parse_file(&fstr, &pblk)) & 1)
		rts_error(VARLSTCNT(1) status);

	file.mvtype = parms.mvtype = MV_STR;
	file.str.len = pblk.b_esl;
	file.str.addr = &fname[0];
	parms.str.len = sizeof(open_params_list);
	parms.str.addr = (char *)&open_params_list;
	(*op_open_ptr)(&file, &parms, 30, 0);
	parms.str.len = 1;
	charspace = (char)iop_eol;
	parms.str.addr = &charspace;
	dev_in_use = io_curr_device;
	op_use(&file,&parms);
	clock = time(0);
	p = GTM_CTIME(&clock);
	memcpy (print_time_buf, p + 4, sizeof(print_time_buf));
	list_head(0);
	return;
}
Exemple #2
0
/* Update header from v4.x to v5.0-000 */
void mu_upgrd_header(v15_sgmnt_data *v15_csd, sgmnt_data *csd)
{
	time_t	ctime;
	seq_num	v15_reg_seqno;

	memset(csd, 0, SIZEOF(sgmnt_data));
	MEMCPY_LIT(csd->label, GDS_LABEL);
	csd->blk_size = v15_csd->blk_size;
	csd->bplmap = v15_csd->bplmap;
	csd->start_vbn = v15_csd->start_vbn;
	csd->acc_meth = v15_csd->acc_meth;
	csd->max_bts = v15_csd->max_bts;
	csd->n_bts = v15_csd->n_bts;
	csd->bt_buckets = v15_csd->bt_buckets;
	if (v15_csd->reserved_bytes > BLK_HDR_INCREASE)
		csd->reserved_bytes = v15_csd->reserved_bytes - BLK_HDR_INCREASE;
	csd->max_rec_size = v15_csd->max_rec_size;
	csd->max_key_size = v15_csd->max_key_size;
	csd->lock_space_size = v15_csd->lock_space_size;
	csd->extension_size = v15_csd->extension_size;
	csd->def_coll = v15_csd->def_coll;
	csd->def_coll_ver = v15_csd->def_coll_ver;
	csd->std_null_coll = v15_csd->std_null_coll;					/* New in V5.0-FT01 */
	csd->null_subs = v15_csd->null_subs;
	csd->free_space = v15_csd->free_space;
	csd->mutex_spin_parms.mutex_hard_spin_count = v15_csd->mutex_spin_parms.mutex_hard_spin_count;
	csd->mutex_spin_parms.mutex_sleep_spin_count = v15_csd->mutex_spin_parms.mutex_sleep_spin_count;
	csd->mutex_spin_parms.mutex_spin_sleep_mask = v15_csd->mutex_spin_parms.mutex_spin_sleep_mask;
	csd->max_update_array_size = v15_csd->max_update_array_size;			/* New from V4.0-001G */
	csd->max_non_bm_update_array_size = v15_csd->max_non_bm_update_array_size;	/* New from V4.0-001G */
	csd->file_corrupt = v15_csd->file_corrupt;
	csd->minor_dbver = GDSMVCURR;					/* New in V5.0-000 */
	csd->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT;	/* New from V5.3-002 */
	csd->createinprogress = v15_csd->createinprogress;
	time(&ctime);
	assert(SIZEOF(ctime) >= SIZEOF(int4));
	csd->creation_time4 = (int4)ctime;/* No need to propagate previous value. Take only lower order 4-bytes of current time */
	csd->last_inc_backup = v15_csd->last_inc_backup;
	csd->last_com_backup = v15_csd->last_com_backup;
	csd->last_rec_backup = v15_csd->last_rec_backup;
	csd->reorg_restart_block = v15_csd->reorg_restart_block;		/* New from V4.2 */
	memcpy(csd->now_running, gtm_release_name, gtm_release_name_len + 1);	/* GT.M release name */
	VMS_ONLY(csd->owner_node = v15_csd->owner_node;)
Exemple #3
0
void init_callin_functable(void)
{
	unsigned char 	*env_top, *address_top;
	uint4 		address_len;
	int		save_errno;

	address_top = GTM64_ONLY(i2ascl)NON_GTM64_ONLY(i2asc)(gtmvectortable_address, (UINTPTR_T)(&callintogtm_vectortable[0]));
	*address_top = '\0';
	address_len = (uint4)(address_top - &gtmvectortable_address[0]);
	env_top = &gtmvectortable_env[0];
	MEMCPY_LIT(env_top, GTM_CALLIN_START_ENV);
	memcpy((env_top + strlen(GTM_CALLIN_START_ENV)), gtmvectortable_address, address_len);
	*(env_top + strlen(GTM_CALLIN_START_ENV) + address_len) = '\0';
	if (PUTENV((char *)gtmvectortable_env))
	{
		save_errno = errno;
		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("putenv"), CALLFROM, save_errno);
	}
}
Exemple #4
0
void iosocket_flush(io_desc *iod)
{
#ifdef C9A06001531
	/* pending change request C9A06001531 */

	d_socket_struct	*dsocketptr;
	socket_struct	*socketptr;
	int             on = 1, off = 0;
        char            *errptr;
        int4            errlen;

        error_def(ERR_SOCKWRITE);
        error_def(ERR_TEXT);
	error_def(ERR_CURRSOCKOFR);

	assert(gtmsocket == iod->type);

	dsocketptr = (d_socket_struct *)iod->dev_sp;
	socketptr = dsocketptr->socket[dsocketptr->current_socket];

	if (dsocketptr->current_socket >= dsocketptr->n_socket)
	{
		rts_error(VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket);
		return;
	}
        memcpy(dsocketptr->dollar_device, "0", SIZEOF("0"));
        if( -1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &on, SIZEOF(on)) ||
		(-1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &off, SIZEOF(off))))
        {
		errptr = (char *)STRERROR(errno);
                errlen = strlen(errptr);
                iod->dollar.za = 9;
		MEMCPY_LIT(dsocketptr->dollar_device, "1,");
                memcpy(&dsocketptr->dollar_device[SIZEOF("1,") - 1], errptr, errlen + 1);	/* we want the null */
		if (socketptr->ioerror)
			rts_error(VARLSTCNT(6) ERR_SOCKWRITE, 0, ERR_TEXT, 2, errlen, errptr);
		return;
        }

#endif
	return;
}
Exemple #5
0
void gtm_threadgbl_init(void)
{
	void	*lcl_gtm_threadgbl;

	if (SIZEOF(gtm_threadgbl_true_t) != size_gtm_threadgbl_struct)
	{	/* Size mismatch with gtm_threadgbl_deftypes.h - no error handling yet available so do
		 * the best we can.
		 */
		FPRINTF(stderr, "GTM-F-GTMASSERT gtm_threadgbl_true_t and gtm_threadgbl_t are different sizes\n");
		EXIT(ERR_GTMASSERT);
	}
	if (NULL != gtm_threadgbl)
	{	/* has already been initialized - don't re-init */
		FPRINTF(stderr, "GTM-F-GTMASSERT gtm_threadgbl is already initialized\n");
		EXIT(ERR_GTMASSERT);
	}
	gtm_threadgbl = lcl_gtm_threadgbl = malloc(size_gtm_threadgbl_struct);
	if (NULL == gtm_threadgbl)
	{	/* Storage was not allocated for some reason - no error handling yet still */
		perror("GTM-F-MEMORY Unable to allocate startup thread structure");
		EXIT(UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY));
	}
	memset(gtm_threadgbl, 0, size_gtm_threadgbl_struct);
	gtm_threadgbl_true = (gtm_threadgbl_true_t *)gtm_threadgbl;

	/* Add specific initializations if other than 0s here using the TREF() family of macros: */
	(TREF(director_ident)).addr = TADR(director_string);
	TREF(for_stack_ptr) = TADR(for_stack);
	(TREF(gtmprompt)).addr = TADR(prombuf);
	(TREF(gtmprompt)).len = SIZEOF(DEFAULT_PROMPT) - 1;
	TREF(lv_null_subs) = LVNULLSUBS_OK;	/* UNIX: set in gtm_env_init_sp(), VMS: set in gtm$startup() - init'd here
							 * in case alternative invocation methods bypass gtm_startup()
							 */
	MEMCPY_LIT(TADR(prombuf), DEFAULT_PROMPT);
	(TREF(replgbl)).jnl_release_timeout = DEFAULT_JNL_RELEASE_TIMEOUT;
	(TREF(window_ident)).addr = TADR(window_string);
	ASSERT_SAFE_TO_UPDATE_THREAD_GBLS;
	TREF(util_outbuff_ptr) = TADR(util_outbuff);	/* Point util_outbuff_ptr to the beginning of util_outbuff at first. */
	TREF(util_outptr) = TREF(util_outbuff_ptr);
	(TREF(source_buffer)).addr = (char *)&aligned_source_buffer;
	(TREF(source_buffer)).len = MAX_SRCLINE;
}
Exemple #6
0
void	mu_int_err(
		int err,
		boolean_t do_path,
		boolean_t do_range,
		unsigned char *bot,
		int has_bot,
		unsigned char *top,
		int has_top,
	      	unsigned int level)
{
	int		i, util_len;
	unsigned char	util_buff[MAX_UTIL_LEN];
	unsigned char 	span_key[MAX_KEY_SZ + 1];

	if (!mu_int_errknt)
		util_out_print("!/Block:Offset Level", TRUE);
	mu_int_errknt++;
	mu_int_plen--;
	util_len=0;
	MEMCPY_LIT(&util_buff[util_len], NEWLINE);
	util_len += SIZEOF(NEWLINE) - 1;
	i2hex_blkfill(mu_int_path[mu_int_plen], &util_buff[util_len], BLOCK_WINDOW);
	util_len += BLOCK_WINDOW;
	MEMCPY_LIT(&util_buff[util_len], TEXT1);	/* OFFSET_WINDOW + 1 spaces */
	util_len += SIZEOF(TEXT3) - 1;				/* Using TEXT1 to clear space? */
	i2hex_nofill(mu_int_offset[mu_int_plen], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW);
	util_len += OFFSET_WINDOW + 1;
	i2hex_blkfill(level, (uchar_ptr_t)&util_buff[util_len], LEVEL_WINDOW);
	util_len += LEVEL_WINDOW;
	MEMCPY_LIT(&util_buff[util_len], TEXT2);
	util_len += SIZEOF(TEXT2) - 1;
	util_buff[util_len] = 0;
	if(sndata->sn_type)
		gtm_putmsg(VARLSTCNT(5) err, 3, LEN_AND_STR((char*)util_buff),
				(SPAN_NODE == sndata->sn_type) ? (sndata->span_prev_blk + 2) : (sndata->span_blk_cnt));
	else
		gtm_putmsg(VARLSTCNT(4) err, 2, LEN_AND_STR((char*)util_buff));
	if (do_path)
	{
		if (!master_dir)
		{
			util_out_print("                   Directory Path:  ", FALSE);
			for (i = 0;  trees->path[i + 1];  i++)
			{
				util_len = i2hex_nofill(trees->path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW);
				MEMCPY_LIT(&util_buff[util_len], TEXT3);
				util_len += SIZEOF(TEXT3) - 1;
				util_len += i2hex_nofill(trees->offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW);
				MEMCPY_LIT(&util_buff[util_len], TEXT4);
				util_len += SIZEOF(TEXT4) - 1;
				util_buff[util_len] = 0;
				util_out_print((caddr_t)util_buff, FALSE);
			}
			util_len = i2hex_nofill(trees->path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW);
			MEMCPY_LIT(&util_buff[util_len], TEXT3);
			util_len += SIZEOF(TEXT3) - 1;
			util_len += i2hex_nofill(trees->offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW);
			util_buff[util_len] = 0;
			util_out_print((caddr_t)util_buff, TRUE);
			util_out_print("                   Path:  ", FALSE);
		} else
			util_out_print("                   Directory Path:  ", FALSE);
		for (i = 0;  i < mu_int_plen;  i++)
		{
			util_len = i2hex_nofill(mu_int_path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW);
			MEMCPY_LIT(&util_buff[util_len], TEXT3);
			util_len += SIZEOF(TEXT3) - 1;
			util_len += i2hex_nofill(mu_int_offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW);
			MEMCPY_LIT(&util_buff[util_len], TEXT4);
			util_len += SIZEOF(TEXT4) - 1;
			util_buff[util_len] = 0;
			util_out_print((caddr_t)util_buff, FALSE);
		}
		util_len = i2hex_nofill(mu_int_path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW);
		MEMCPY_LIT(&util_buff[util_len], TEXT3);
		util_len += SIZEOF(TEXT3) - 1;
		util_len += i2hex_nofill(mu_int_offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW);
		util_buff[util_len] = 0;
		util_out_print((caddr_t)util_buff, TRUE);
	}
	if (do_range && mu_int_err_ranges)
	{
		util_out_print("Keys from ", FALSE);
		if (has_bot)
		{
			util_out_print("^", FALSE);
			/* in the case bot is the leftmost key of the gvtree, it needs a second null to be a properly terminated
			 * real key for print_target. since it is a simple set, we unconditionally do it for every key */
			bot[has_bot] = 0;
			print_target(bot);
		} else
		{
			assert(master_dir);	/* for a global variable tree, we better have a non-zero begin key */
			util_out_print("^%", FALSE);
		}
		util_out_print(" to ", FALSE);
		if (has_top)
		{
			util_out_print("^", FALSE);
			print_target(top);
		} else
			util_out_print("the end", FALSE);
		util_out_print(" are suspect.", TRUE);
	}
	if (!level && sndata->sn_type)
	{
		if (1 == sndata->sn_type)
			util_out_print("Spanning Node ^", FALSE);
		else
			util_out_print("Spanning Node Chunk ^", FALSE);
		/* in the case bot is the leftmost key of the gvtree, it needs a second null to be a properly terminated
		 * real key for print_target. since it is a simple set, we unconditionally do it for every key
		 */
		sndata->span_node_buf[sndata->key_len] = 0;
		sndata->span_node_buf[sndata->key_len+1] = 0;
		print_target(sndata->span_node_buf);
		util_out_print(" is suspect.", TRUE);
	}
	return;
}
void op_zlink(mval *v, mval *quals)
{
	struct FAB		srcfab;
	struct NAM		srcnam, objnam;
	struct XABDAT		srcxab, objxab;
	boolean_t		compile, expdir, libr, obj_found, src_found;
	short			flen;
	unsigned short		type;
	unsigned char		srccom[MAX_FN_LEN], srcnamebuf[MAX_FN_LEN], objnamebuf[MAX_FN_LEN], objnamelen, srcnamelen,ver[6];
	unsigned char		objcom[MAX_FN_LEN], list_file[MAX_FN_LEN], ceprep_file[MAX_FN_LEN], *fname;
	zro_ent			*srcdir, *objdir;
	mstr			srcstr, objstr, version;
	mval			qualifier;
	unsigned		status, srcfnb;
	uint4			lcnt, librindx, qlf;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	MV_FORCE_STR(v);
	if (MAX_FN_LEN < v->str.len)
		rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, MIN(UCHAR_MAX, v->str.len), v->str.addr, ERR_FILENAMETOOLONG);
	version.len = 0;
	srcdir = objdir = 0;
	version.addr = ver;
	libr = FALSE;
	obj_fab = cc$rms_fab;
	if (quals)
	{
		MV_FORCE_STR(quals);
		srcfab = cc$rms_fab;
		srcfab.fab$l_fna = v->str.addr;
		srcfab.fab$b_fns = v->str.len;
		srcfab.fab$l_nam = &srcnam;
		srcnam = cc$rms_nam;
		srcnam.nam$l_esa = srcnamebuf;
		srcnam.nam$b_ess = SIZEOF(srcnamebuf);
		srcnam.nam$b_nop = NAM$M_SYNCHK;
		status = sys$parse(&srcfab);
		if (!(status & 1))
			rts_error(VARLSTCNT(9) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_FILEPARSE, 2, v->str.len, v->str.addr, status);
		if (srcnam.nam$l_fnb & NAM$M_WILDCARD)
			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_WILDCARD, 2, v->str.len, v->str.addr);
		srcfnb = srcnam.nam$l_fnb;
		expdir = (srcfnb & (NAM$M_NODE | NAM$M_EXP_DEV | NAM$M_EXP_DIR));
		if (srcfnb & NAM$M_EXP_VER)
		{
			memcpy(version.addr, srcnam.nam$l_ver, srcnam.nam$b_ver);
			version.len = srcnam.nam$b_ver;
		}
		if (expdir)
		{
			if (version.len)
				flen = srcnam.nam$b_esl - srcnam.nam$b_type - version.len;
			else
				flen = srcnam.nam$b_esl - srcnam.nam$b_type - 1; /* semicolon is put in by default */
			fname = srcnam.nam$l_esa;
		} else
		{
			flen = srcnam.nam$b_name;
			fname = srcnam.nam$l_name;
		}
		ENSURE_STP_FREE_SPACE(flen);
		memcpy(stringpool.free, fname, flen);
		dollar_zsource.str.addr = stringpool.free;
		dollar_zsource.str.len = flen;
		stringpool.free += flen;
		if (srcfnb & NAM$M_EXP_TYPE)
		{
			if ((SIZEOF(DOTOBJ) - 1 == srcnam.nam$b_type) &&
				!MEMCMP_LIT(srcnam.nam$l_type, DOTOBJ))
			{
				type = OBJ;
				objstr.addr = srcnam.nam$l_esa;
				objstr.len = srcnam.nam$b_esl;
			} else
			{
				type = SRC;
				memcpy(srcnamebuf, dollar_zsource.str.addr, flen);
				memcpy(&srcnamebuf[flen], srcnam.nam$l_type, srcnam.nam$b_type);
				memcpy(&srcnamebuf[flen + srcnam.nam$b_type],
					version.addr, version.len);
				srcnamelen = flen + srcnam.nam$b_type + version.len;
				srcnamebuf[srcnamelen] = 0;
				srcstr.addr = srcnamebuf;
				srcstr.len = srcnamelen;
				memcpy(objnamebuf, dollar_zsource.str.addr, flen);
				memcpy(&objnamebuf[flen], DOTOBJ, SIZEOF(DOTOBJ));
				objnamelen = flen + SIZEOF(DOTOBJ) - 1;
				objstr.addr = objnamebuf;
				objstr.len = objnamelen;
			}
		} else
		{
			type = NOTYPE;
			memcpy(srcnamebuf, dollar_zsource.str.addr, flen);
			memcpy(&srcnamebuf[flen], DOTM, SIZEOF(DOTM));
			srcnamelen = flen + SIZEOF(DOTM) - 1;
			memcpy(objnamebuf, dollar_zsource.str.addr, flen);
			MEMCPY_LIT(&objnamebuf[flen], DOTOBJ);
			memcpy(&objnamebuf[flen + SIZEOF(DOTOBJ) - 1], version.addr, version.len);
			objnamelen = flen + SIZEOF(DOTOBJ) + version.len - 1;
			objnamebuf[objnamelen] = 0;
			srcstr.addr = srcnamebuf;
			srcstr.len = srcnamelen;
			objstr.addr = objnamebuf;
			objstr.len = objnamelen;
		}
		if (!expdir)
		{
			if (OBJ == type)
			{
				zro_search(&objstr, &objdir, 0, 0);
				if (!objdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
			} else  if (SRC == type)
			{
				zro_search(&objstr, &objdir, &srcstr, &srcdir);
				if (!srcdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf,
						ERR_FILENOTFND, 2, srcnamelen, srcnamebuf);
			} else
			{
				zro_search(&objstr, &objdir, &srcstr, &srcdir);
				if (!objdir && !srcdir)
					rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr,
						ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr);
			}
		}
	} else
	{
		expdir = FALSE;
		type = NOTYPE;
		flen = v->str.len;
		memcpy(srcnamebuf, v->str.addr, flen);
		MEMCPY_LIT(&srcnamebuf[flen], DOTM);
		srcnamelen = flen + SIZEOF(DOTM) - 1;
		if ('%' == srcnamebuf[0])
			srcnamebuf[0] = '_';
		memcpy(objnamebuf, srcnamebuf, flen);
		MEMCPY_LIT(&objnamebuf[flen], DOTOBJ);
		objnamelen = flen + SIZEOF(DOTOBJ) - 1;
		srcstr.addr = srcnamebuf;
		srcstr.len = srcnamelen;
		objstr.addr = objnamebuf;
		objstr.len = objnamelen;
		zro_search(&objstr, &objdir, &srcstr, &srcdir);
		if (!objdir && !srcdir)
			rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr,
				ERR_FILENOTFND, 2, v->str.len, v->str.addr);
		qualifier.mvtype = MV_STR;
		qualifier.str = TREF(dollar_zcompile);
		quals = &qualifier;
	}
	if (OBJ == type)
	{
		obj_fab.fab$b_fac = FAB$M_GET;
		obj_fab.fab$b_shr = FAB$M_SHRGET;
		if (NULL != objdir)
		{
			if (ZRO_TYPE_OBJLIB == objdir->type)
				libr = TRUE;
			else
			{
				srcfab.fab$l_dna = objdir->str.addr;
				srcfab.fab$b_dns = objdir->str.len;
			}
		}
		for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
		{
			status = (FALSE == libr) ? sys$open(&srcfab): zl_olb(&objdir->str, &objstr, &librindx);
			if (RMS$_FLK != status)
				break;
			hiber_start(WAIT_FOR_FILE_TIME);
		}
		if (FALSE == (status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status);
		if (FALSE == ((FALSE == libr) ? incr_link(&srcfab, libr) : incr_link(&librindx, libr)))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_VERSION);
		status = (FALSE == libr) ? sys$close(&srcfab) : lbr$close(&librindx);
		if (FALSE == (status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status);
	} else	/* either NO type or SOURCE type */
	{
		src_found = obj_found = compile = FALSE;
		srcfab = obj_fab = cc$rms_fab;
		obj_fab.fab$l_xab = &objxab;
		srcxab = objxab = cc$rms_xabdat;
		obj_fab.fab$l_nam = &objnam;
		srcnam = objnam = cc$rms_nam;
		obj_fab.fab$l_fna = objnamebuf;
		obj_fab.fab$b_fns = objnamelen;
		obj_fab.fab$b_fac = FAB$M_GET;
		obj_fab.fab$b_shr = FAB$M_SHRGET;
		objnam.nam$l_esa = objcom;
		objnam.nam$b_ess = SIZEOF(objcom);
		srcfab.fab$l_nam = &srcnam;
		srcfab.fab$l_xab = &srcxab;
		srcfab.fab$l_fna = srcnamebuf;
		srcfab.fab$b_fns = srcnamelen;
		srcfab.fab$b_fac = FAB$M_GET;
		srcfab.fab$b_shr = FAB$M_SHRGET;
		srcnam.nam$l_esa = srccom;
		srcnam.nam$b_ess = SIZEOF(srccom);
		cmd_qlf.object_file.str.addr = objcom;
		cmd_qlf.object_file.str.len = 255;
		cmd_qlf.list_file.str.addr = list_file;
		cmd_qlf.list_file.str.len = 255;
		cmd_qlf.ceprep_file.str.addr = ceprep_file;
		cmd_qlf.ceprep_file.str.len = 255;
		if (srcdir && srcdir->str.len)
		{
			srcfab.fab$l_dna = srcdir->str.addr;
			srcfab.fab$b_dns = srcdir->str.len;
		}
		if (objdir && objdir->str.len)
		{
			if (ZRO_TYPE_OBJLIB == objdir->type)
				libr = TRUE;
			else
			{
				obj_fab.fab$l_dna = objdir->str.addr;
				obj_fab.fab$b_dns = objdir->str.len;
			}
		}
		if (SRC != type)
		{
			if (!expdir && !objdir)
				obj_found = FALSE;
			else  if (!libr)
			{
				for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
				{
					status = sys$open(&obj_fab);
					if (RMS$_FLK != status)
						break;
					hiber_start(WAIT_FOR_FILE_TIME);
				}
				if (!(status & 1))
				{
					if (RMS$_FNF == status)
						obj_found = FALSE;
					else
						rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status);
				} else
					obj_found = TRUE;
			} else
			{
				status = zl_olb(&objdir->str, &objstr, &librindx);
				if (status)
					obj_found = TRUE;
			}
		} else
			compile = TRUE;
		if (!expdir && !srcdir)
			src_found = FALSE;
		else
		{
			for (lcnt = 0;  lcnt < MAX_FILE_OPEN_TRIES;  lcnt++)
			{
				status = sys$open(&srcfab);
				if (RMS$_FLK != status)
					break;
				hiber_start(WAIT_FOR_FILE_TIME);
			}
			if (!(status & 1))
			{
				if ((RMS$_FNF == status) && (SRC != type))
					src_found = FALSE;
				else
					rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
			} else
			{
				src_found = TRUE;
				if (SRC == type)
				{
					status = sys$close(&srcfab);
					if (!(status & 1))
						rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
				}
			}
		}
		if (SRC != type)
		{
			if (src_found)
			{
				if (obj_found)
				{
					if (QUADCMP(&srcxab.xab$q_rdt, &objxab.xab$q_rdt))
					{
						status = sys$close(&obj_fab);
						obj_fab = cc$rms_fab;
						if (!(status & 1))
							rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status);
						compile = TRUE;
					}
				} else
					compile = TRUE;
				status = sys$close(&srcfab);
				if (!(status & 1))
					rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status);
			} else  if (!obj_found)
				rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, objnamelen, objnamebuf,
					ERR_FILENOTFND, 2, objnamelen, objnamebuf);
		}
		if (compile)
		{
			zl_cmd_qlf(&quals->str, &cmd_qlf);
			if (!MV_DEFINED(&cmd_qlf.object_file))
			{
				objnam.nam$b_nop = NAM$M_SYNCHK;
				status = sys$parse(&obj_fab);
				if (!(status & 1))
					rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna);
				cmd_qlf.object_file.mvtype = MV_STR;
				cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver;
			}
			qlf = cmd_qlf.qlf;
			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
			{
				cmd_qlf.qlf = glb_cmd_qlf.qlf;
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
			}
			zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa);
			if ((SRC == type) && !(qlf & CQ_OBJECT))
				return;
		}
		status = libr ? incr_link(&librindx, libr) : incr_link(&obj_fab, libr);
		if (!status)	/* due only to version mismatch, so recompile */
		{
			if (!libr)
			{
				status = sys$close(&obj_fab);
				obj_fab = cc$rms_fab;
			} else
				status = lbr$close(&librindx);
			if (!(status & 1))
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status);
			if (compile)
				GTMASSERT;
			if (!src_found)
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_VERSION);
			zl_cmd_qlf(&quals->str, &cmd_qlf);
			if (!MV_DEFINED(&cmd_qlf.object_file))
			{
				objnam.nam$b_nop = NAM$M_SYNCHK;
				status = sys$parse(&obj_fab);
				if (!(status & 1))
					rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna);
				cmd_qlf.object_file.mvtype = MV_STR;
				cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver;
			}
			if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type))
			{
				cmd_qlf.qlf = glb_cmd_qlf.qlf;
				rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT);
			}
			zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa);
			if (!incr_link(&obj_fab, libr))
				GTMASSERT;
		}
		if (!libr)
		{
			status = sys$close(&obj_fab);
			obj_fab = cc$rms_fab;
		} else
			status = lbr$close(&librindx);
		if (!(status & 1))
			rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status);
	}
	return;
}
Exemple #8
0
bool mubinccpy(backup_reg_list *list)
{
	static readonly mval	null_str = {MV_STR, 0, 0 , 0 , 0, 0};

	int			backup_socket;
	int4                    size, size1, bsize, bm_num, hint, lmsize, save_blks, rsize, match, timeout, outsize;
	uint4                   status, total_blks, bplmap, gds_ratio, blks_per_buff, counter, i, lcnt, read_size;
	uchar_ptr_t		bm_blk_buff, ptr1, ptr1_top, ptr, ptr_top;
	char_ptr_t		outptr, data_ptr;
	unsigned short		rd_iosb[4], port;
	enum db_acc_method	access;
	blk_hdr			*bp, *bptr;
	struct FAB		*fcb, temp_fab, mubincfab;
	struct RAB		temp_rab, mubincrab;
	inc_header		*outbuf;
	mval			val;
	mstr                    *file;
	sgmnt_data_ptr_t        header;
	char			*common, addr[SA_MAXLEN + 1];
	void			(*common_write)();
	void			(*common_close)();
	muinc_blk_hdr_ptr_t	sblkh_p;
	trans_num		blk_tn;
	block_id		blk_num_base, blk_num;
	boolean_t		is_bitmap_blk, backup_this_blk;
	enum db_ver		dummy_odbv;
	int4			blk_bsiz;

	error_def(ERR_BCKUPBUFLUSH);
	error_def(ERR_COMMITWAITSTUCK);
	error_def(ERR_DBCCERR);
	error_def(ERR_ERRCALL);

	assert(list->reg == gv_cur_region);
	assert(incremental);
	/* Make sure inc_header  can be same size on all platforms. Some platforms pad 8 byte aligned structures
	   that end on a 4 byte boundary and some do not. It is critical that this structure is the same size on
	   all platforms as it is sent across TCP connections when doing TCP backup.
	*/
	assert(0 == (SIZEOF(inc_header) % 8));

	/* ================= Initialization and some checks ======================== */

	header  =       list->backup_hdr;
	file    =       &(list->backup_file);

	if (!mubtomag)
		mubmaxblk = BACKUP_TEMPFILE_BUFF_SIZE;
	fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab;
	if (list->tn >= header->trans_hist.curr_tn)
	{
		util_out_print("!/TRANSACTION number is greater than or equal to current transaction,", TRUE);
		util_out_print("No blocks backed up from database !AD", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
		return TRUE;
	}

	/* =========== open backup destination and define common_write ================= */
	backup_write_errno = 0;
	backup_close_errno = 0;
	switch(list->backup_to)
	{
		case backup_to_file:
			/* open the file and define the common_write function */
			mubincfab = cc$rms_fab;
			mubincfab.fab$b_fac = FAB$M_PUT;
			mubincfab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF | FAB$M_POS & (~FAB$M_RWC) & (~FAB$M_RWO);
			mubincfab.fab$l_fna = file->addr;
			mubincfab.fab$b_fns = file->len;
			mubincfab.fab$l_alq = cs_addrs->hdr->start_vbn +
				STARTING_BLOCKS * cs_addrs->hdr->blk_size / DISK_BLOCK_SIZE;
			mubincfab.fab$w_mrs = mubmaxblk;
			mubincfab.fab$w_deq = EXTEND_SIZE;
			switch (status = sys$create(&mubincfab))
			{
				case RMS$_NORMAL:
				case RMS$_CREATED:
				case RMS$_SUPERSEDE:
				case RMS$_FILEPURGED:
					break;
				default:
					gtm_putmsg(status, 0, mubincfab.fab$l_stv);
					util_out_print("Error: Cannot create backup file !AD.",
						       TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna);
					return FALSE;
			}

			mubincrab = cc$rms_rab;
			mubincrab.rab$l_fab = &mubincfab;
			mubincrab.rab$l_rop = RAB$M_WBH;
			if (RMS$_NORMAL != (status = sys$connect(&mubincrab)))
			{
				gtm_putmsg(status, 0, mubincrab.rab$l_stv);
				util_out_print("Error: Cannot connect to backup file !AD.",
					       TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna);
				mubincfab.fab$l_fop |= FAB$M_DLT;
				sys$close(&mubincfab);
				return FALSE;
			}
			common = (char *)(&mubincrab);
			common_write = file_write;
			common_close = file_close;
			break;
		case backup_to_exec:
			util_out_print("Error: Backup to pipe is yet to be implemented.", TRUE);
			util_out_print("Error: Your request to backup database !AD to !AD is currently not valid.", TRUE,
				       fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr);
			return FALSE;
		case backup_to_tcp:
			iotcp_fillroutine();
			/* parse it first */
			switch (match = SSCANF(file->addr, "%[^:]:%hu", addr, &port))
			{
				case 1 :
					port = DEFAULT_BKRS_PORT;
				case 2 :
					break;
				default :
					util_out_print("ERROR: A hostname has to be specified to backup through a TCP connection.",
						       TRUE);
					return FALSE;
			}
			if ((0 == cli_get_int("NETTIMEOUT", &timeout)) || (0 > timeout))
				timeout = DEFAULT_BKRS_TIMEOUT;
			if (0 > (backup_socket = tcp_open(addr, port, timeout, FALSE)))
			{
				util_out_print("ERROR: Cannot open tcp connection due to the above error.", TRUE);
				return FALSE;
			}
			common_write = tcp_write;
			common_close = tcp_close;
			common = (char *)(&backup_socket);
			break;
		default :
			util_out_print("ERROR: Backup format !UL not supported.", TRUE, list->backup_to);
			util_out_print("Error: Your request to backup database !AD to !AD is not valid.", TRUE,
				       fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr);
			return FALSE;
	}

	/* ============================= write inc_header =========================================== */

	outptr = malloc(SIZEOF(inc_header));
	outbuf = (inc_header *)outptr;
	MEMCPY_LIT(&outbuf->label[0], INC_HEADER_LABEL);
	stringpool.free = stringpool.base;
	op_horolog(&val);
	stringpool.free = stringpool.base;
	op_fnzdate(&val, &mu_bin_datefmt, &null_str, &null_str, &val);
	memcpy(&outbuf->date[0], val.str.addr, val.str.len);
	memcpy(&outbuf->reg[0], gv_cur_region->rname, MAX_RN_LEN);
	outbuf->start_tn = list->tn;
	outbuf->end_tn = header->trans_hist.curr_tn;
	outbuf->db_total_blks = header->trans_hist.total_blks;
	outbuf->blk_size = header->blk_size;
	outbuf->blks_to_upgrd = header->blks_to_upgrd;
	COMMON_WRITE(common, outptr, SIZEOF(inc_header));
	free(outptr);

	if (mu_ctrly_occurred || mu_ctrlc_occurred)
	{
		error_mupip = TRUE;
		COMMON_CLOSE(common);
		util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
		return FALSE;
	}

	/* ============================ read/write appropriate blocks =============================== */

	bsize		= header->blk_size;
	gds_ratio	= bsize / DISK_BLOCK_SIZE;
	blks_per_buff	= BACKUP_READ_SIZE / bsize;
	read_size	= blks_per_buff * bsize;
	outsize		= SIZEOF(muinc_blk_hdr) + bsize;
	outptr		= (char_ptr_t)malloc(MAX(outsize, mubmaxblk));
	sblkh_p		= (muinc_blk_hdr_ptr_t)outptr;
	data_ptr	= (char_ptr_t)(sblkh_p + 1);
	bp		= (blk_hdr_ptr_t)mubbuf;
	bm_blk_buff	= (uchar_ptr_t)malloc(SIZEOF(blk_hdr) + (BLKS_PER_LMAP * BML_BITS_PER_BLK / BITS_PER_UCHAR));
	mubincrab.rab$l_rbf = outptr;
	save_blks	= 0;
	access = header->acc_meth;
	memset(sblkh_p, 0, SIZEOF(*sblkh_p));

	if (access == dba_bg)
		bp = mubbuf;
	else
	{
		ptr = cs_addrs->db_addrs[0] + (cs_addrs->hdr->start_vbn - 1) * DISK_BLOCK_SIZE;
		ptr_top = cs_addrs->db_addrs[1] + 1;
	}

	sblkh_p->use.bkup.ondsk_blkver = GDSNOVER;
	for (blk_num_base = 0; blk_num_base < header->trans_hist.total_blks; blk_num_base += blks_per_buff)
	{
		if (online && (0 != cs_addrs->shmpool_buffer->failed))
			break;
		if (header->trans_hist.total_blks - blk_num_base < blks_per_buff)
		{
			blks_per_buff = header->trans_hist.total_blks - blk_num_base;
			read_size = blks_per_buff * bsize;
		}

		if (access == dba_bg)
		{
			if ((SS$_NORMAL != (status = sys$qiow(EFN$C_ENF, fcb->fab$l_stv, IO$_READVBLK, &rd_iosb, 0, 0, bp,
							      read_size, cs_addrs->hdr->start_vbn + (gds_ratio * blk_num_base),
							      0, 0, 0)))
			    || (SS$_NORMAL != (status = rd_iosb[0])))
			{
				gtm_putmsg(VARLSTCNT(1) status);
				util_out_print("Error reading data from database !AD.", TRUE,
					       fcb->fab$b_fns, fcb->fab$l_fna);
				free(outptr);
				free(bm_blk_buff);
				error_mupip = TRUE;
				COMMON_CLOSE(common);
				return FALSE;
			}
		} else
		{
			assert(dba_mm == access);
			bp = ptr + blk_num_base * bsize;
		}

		bptr = (blk_hdr *)bp;
		/* The blocks we back up will be whatever version they are. There is no implicit conversion in this
		   part of the backup/restore. Since we aren't even looking at the blocks (and indeed some of these blocks
		   could potentially contain unintialized garbage data), we set the block version to GDSNOVER to signal
		   that the block version is unknown. The above applies to "regular" blocks but not to bitmap blocks which
		   we know are initialized. Because we have to read the bitmap blocks, they will be converted as necessary.
		*/
		for (i = 0;
		     i < blks_per_buff && ((blk_num_base + i) < header->trans_hist.total_blks);
		     i++, bptr = (blk_hdr *)((char *)bptr + bsize))
		{
			blk_num = blk_num_base + i;
			if (mu_ctrly_occurred  ||  mu_ctrlc_occurred)
			{
				free(outptr);
				free(bm_blk_buff);
				error_mupip = TRUE;
				COMMON_CLOSE(common);
				util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
				return FALSE;
			}
			/* Before we check if this block needs backing up, check if this is a new bitmap block or not. If it is,
			   we can fall through and back it up as normal. But if this is NOT a bitmap block, use the
			   existing bitmap to determine if this block has ever been allocated or not. If not, we don't want to
			   even look at this block. It could be uninitialized which will just make things run slower if we
			   go to read it and back it up.
			*/
			if (0 != ((BLKS_PER_LMAP - 1) & blk_num))
			{	/* Not a local bitmap block */
				if (!gvcst_blk_ever_allocated(bm_blk_buff + SIZEOF(blk_hdr),
							      ((blk_num * BML_BITS_PER_BLK)
							       % (BLKS_PER_LMAP * BML_BITS_PER_BLK))))
					continue;		/* Bypass never-set blocks to avoid conversion problems */
				is_bitmap_blk = FALSE;
				if (SIZEOF(v15_blk_hdr) <= (blk_bsiz = ((v15_blk_hdr_ptr_t)bptr)->bsiz))
				{	/* We have either a V4 block or uninitialized garbage */
					if (blk_bsiz > bsize)
						/* This is not a valid V4 block so ignore it */
						continue;
					blk_tn = ((v15_blk_hdr_ptr_t)bptr)->tn;
				} else
				{	/* Assume V5 block */
					if ((blk_bsiz = bptr->bsiz) > bsize)
						/* Not a valid V5 block either */
						continue;
					blk_tn = bptr->tn;
				}
			} else
			{	/* This is a bitmap block so save it into our bitmap block buffer. It is used as the
				   basis of whether or not we have to process a given block or not. We process allocated and
				   recycled blocks leaving free (never used) blocks alone as they have no data worth saving.
				   But after saving it, upgrade it to the current format if necessary.
				*/
				is_bitmap_blk = TRUE;
				memcpy(bm_blk_buff, bptr, BM_SIZE(header->bplmap));
				if (SIZEOF(v15_blk_hdr) <= ((v15_blk_hdr_ptr_t)bm_blk_buff)->bsiz)
				{	/* This is a V4 format block -- needs upgrading */
					status = gds_blk_upgrade(bm_blk_buff, bm_blk_buff, bsize, &dummy_odbv);
					if (SS_NORMAL != status)
					{
						free(outptr);
						free(bm_blk_buff);
						error_mupip = TRUE;
						COMMON_CLOSE(common);
						util_out_print("Error: Block 0x!XL is too large for automatic upgrade", TRUE,
							       sblkh_p->blkid);
						return FALSE;
					}
				}
				assert(BM_SIZE(header->bplmap) == ((blk_hdr_ptr_t)bm_blk_buff)->bsiz);
				assert(LCL_MAP_LEVL == ((blk_hdr_ptr_t)bm_blk_buff)->levl);
				assert(gvcst_blk_is_allocated(bm_blk_buff + SIZEOF(blk_hdr),
							      ((blk_num * BML_BITS_PER_BLK)
							       % (BLKS_PER_LMAP * BML_BITS_PER_BLK))));
				blk_bsiz = BM_SIZE(header->bplmap);
				blk_tn = ((blk_hdr_ptr_t)bm_blk_buff)->tn;
			}
			/* The conditions for backing up a block or ignoring it (in order of evaluation):

			   1) If blk is larger than size of db at time backup was initiated, we ignore the block.
			   2) Always backup blocks 0, 1, and 2 as these are the only blocks that can contain data
			      and still have a transaction number of 0.
			   3) For bitmap blocks, if blks_to_upgrd != 0 and the TN is 0 and the block number >=
			      last_blk_at_last_bkup, then backup the block. This way we get the correct version of
			      the bitmap block in the restore (otherwise have no clue what version to create them in
			      as bitmaps are created with a TN of 0 when before image journaling is enabled).
			   4) If the block TN is below our TN threshold, ignore the block.
			   5) Else if none of the above conditions, backup the block.
			*/
			if (online && (header->trans_hist.curr_tn <= blk_tn))
				backup_this_blk = FALSE;
			else if (3 > blk_num || (is_bitmap_blk && 0 != header->blks_to_upgrd && (trans_num)0 == blk_tn
						 && blk_num >= list->last_blk_at_last_bkup))
				backup_this_blk = TRUE;
			else if ((blk_tn < list->tn))
				backup_this_blk = FALSE;
			else
				backup_this_blk = TRUE;
			if (!backup_this_blk)
			{
				if (online)
					cs_addrs->nl->nbb = blk_num;
				continue; /* not applicable */
			}
			sblkh_p->blkid = blk_num;
			memcpy(data_ptr, bptr, blk_bsiz);
			sblkh_p->valid_data = TRUE;	/* Validation marker */
			COMMON_WRITE(common, outptr, outsize);
			if (online)
			{
				if (0 != cs_addrs->shmpool_buffer->failed)
					break;
				cs_addrs->nl->nbb = blk_num;
			}
			save_blks++;
		}
	}

	/* ============================= write saved information for online backup ========================== */

	if (online && (0 == cs_addrs->shmpool_buffer->failed))
	{
		/* -------- make sure everyone involved finishes -------- */
		cs_addrs->nl->nbb = BACKUP_NOT_IN_PROGRESS;
		/* By getting crit here, we ensure that there is no process still in transaction logic that sees
		   (nbb != BACKUP_NOT_IN_PRORESS). After rel_crit(), any process that enters transaction logic will
		   see (nbb == BACKUP_NOT_IN_PRORESS) because we just set it to that value. At this point, backup
		   buffer is complete and there will not be any more new entries in the backup buffer until the next
		   backup.
		*/
		grab_crit(gv_cur_region);
		assert(cs_data == cs_addrs->hdr);
		if (dba_bg == cs_data->acc_meth)
		{	/* Now that we have crit, wait for any pending phase2 updates to finish. Since phase2 updates happen
			 * outside of crit, we dont want them to keep writing to the backup temporary file even after the
			 * backup is complete and the temporary file has been deleted.
			 */
			if (cs_addrs->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(cs_addrs, NULL))
			{
				gtm_putmsg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1,
					cs_addrs->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(gv_cur_region));
				rel_crit(gv_cur_region);
				free(outptr);
				free(bm_blk_buff);
				error_mupip = TRUE;
				COMMON_CLOSE(common);
				return FALSE;
			}
		}
		if (debug_mupip)
		{
			util_out_print("MUPIP INFO:   Current Transaction # at end of backup is 0x!16@XQ", TRUE,
				&cs_data->trans_hist.curr_tn);
		}
		rel_crit(gv_cur_region);
		counter = 0;
		while (0 != cs_addrs->shmpool_buffer->backup_cnt)
		{
			if (0 != cs_addrs->shmpool_buffer->failed)
			{
				util_out_print("Process !UL encountered the following error.", TRUE,
					       cs_addrs->shmpool_buffer->failed);
				if (0 != cs_addrs->shmpool_buffer->backup_errno)
					gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
				free(outptr);
				free(bm_blk_buff);
				error_mupip = TRUE;
				COMMON_CLOSE(common);
				return FALSE;
			}
			backup_buffer_flush(gv_cur_region);
			if (++counter > MAX_BACKUP_FLUSH_TRY)
			{
				gtm_putmsg(VARLSTCNT(1) ERR_BCKUPBUFLUSH);
				free(outptr);
				free(bm_blk_buff);
				error_mupip = TRUE;
				COMMON_CLOSE(common);
				return FALSE;
			}
			if (counter & 0xF)
				wcs_sleep(counter);
			else
			{	/* Force shmpool recovery to see if it can find the lost blocks */
				if (!shmpool_lock_hdr(gv_cur_region))
				{
					gtm_putmsg(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region),
						   ERR_ERRCALL, 3, CALLFROM);
					free(outptr);
					free(bm_blk_buff);
					error_mupip = TRUE;
					COMMON_CLOSE(common);
					assert(FALSE);
					return FALSE;;
				}
				shmpool_abandoned_blk_chk(gv_cur_region, TRUE);
				shmpool_unlock_hdr(gv_cur_region);
			}
		}

		/* -------- Open the temporary file -------- */
		temp_fab = cc$rms_fab;
		temp_fab.fab$b_fac = FAB$M_GET;
		temp_fab.fab$l_fna = list->backup_tempfile;
		temp_fab.fab$b_fns = strlen(list->backup_tempfile);
		temp_rab = cc$rms_rab;
		temp_rab.rab$l_fab = &temp_fab;

		for (lcnt = 1;  MAX_OPEN_RETRY >= lcnt;  lcnt++)
		{
			if (RMS$_FLK != (status = sys$open(&temp_fab, NULL, NULL)))
				break;
			wcs_sleep(lcnt);
		}

		if (RMS$_NORMAL != status)
		{
			gtm_putmsg(status, 0, temp_fab.fab$l_stv);
			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
			free(outptr);
			free(bm_blk_buff);
			error_mupip = TRUE;
			COMMON_CLOSE(common);
			return FALSE;
		}

		if (RMS$_NORMAL != (status = sys$connect(&temp_rab)))
		{
			gtm_putmsg(status, 0, temp_rab.rab$l_stv);
			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
			free(outptr);
			free(bm_blk_buff);
			error_mupip = TRUE;
			COMMON_CLOSE(common);
			return FALSE;
		}

		/* -------- read and write every record in the temporary file -------- */
		while (1)
		{
			temp_rab.rab$w_usz = outsize;
			temp_rab.rab$l_ubf = outptr;
			status = sys$get(&temp_rab);
			if (RMS$_NORMAL != status)
			{
				if (RMS$_EOF == status)
					status = RMS$_NORMAL;
				break;
			}
			assert(outsize == temp_rab.rab$w_rsz);
			/* Still validly sized blk? */
			assert((outsize - SIZEOF(shmpool_blk_hdr)) >= ((blk_hdr_ptr_t)(outptr + SIZEOF(shmpool_blk_hdr)))->bsiz);
			COMMON_WRITE(common, outptr, temp_rab.rab$w_rsz);
		}

		if (RMS$_NORMAL != status)
		{
			gtm_putmsg(status, 0, temp_rab.rab$l_stv);
			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
			free(outptr);
			free(bm_blk_buff);
			error_mupip = TRUE;
			COMMON_CLOSE(common);
			return FALSE;
		}

		/* ---------------- Close the temporary file ----------------------- */
		if (RMS$_NORMAL != (status = sys$close(&temp_fab)))
		{
			gtm_putmsg(status, 0, temp_fab.fab$l_stv);
			util_out_print("WARNING:  DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna);
			free(outptr);
			free(bm_blk_buff);
			error_mupip = TRUE;
			COMMON_CLOSE(common);
			return FALSE;
		}
	}

	/* ============================= write end_msg and fileheader ======================================= */

	if ((!online) || (0 == cs_addrs->shmpool_buffer->failed))
	{
		MEMCPY_LIT(outptr, END_MSG);
		/* Although the write only need be of length SIZEOF(END_MSG) - 1 for file IO, if the write is going
		   to TCP we have to write all these records with common length so just write the "regular" sized
		   buffer. The extra garbage left over from the last write will be ignored as we key only on the
		   this end text.
		*/
		COMMON_WRITE(common, outptr, outsize);

		ptr1 = header;
		size1 = ROUND_UP(SIZEOF(sgmnt_data), DISK_BLOCK_SIZE);
		ptr1_top = ptr1 + size1;
		for (;ptr1 < ptr1_top ; ptr1 += size1)
		{
			if ((size1 = ptr1_top - ptr1) > mubmaxblk)
				size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE;
			COMMON_WRITE(common, ptr1, size1);
		}

		MEMCPY_LIT(outptr, HDR_MSG);
		COMMON_WRITE(common, outptr, SIZEOF(HDR_MSG));
		ptr1 = MM_ADDR(header);
		size1 = ROUND_UP(MASTER_MAP_SIZE(header), DISK_BLOCK_SIZE);
		ptr1_top = ptr1 + size1;
		for (;ptr1 < ptr1_top ; ptr1 += size1)
		{
			if ((size1 = ptr1_top - ptr1) > mubmaxblk)
				size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE;
			COMMON_WRITE(common, ptr1, size1);
		}

		MEMCPY_LIT(outptr, MAP_MSG);
		COMMON_WRITE(common, outptr, SIZEOF(MAP_MSG));
	}


	/* ================== close backup destination, output and return ================================== */

	if (online && (0 != cs_addrs->shmpool_buffer->failed))
	{
		util_out_print("Process !UL encountered the following error.", TRUE,
			       cs_addrs->shmpool_buffer->failed);
		if (0 != cs_addrs->shmpool_buffer->backup_errno)
			gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno);
		free(outptr);
		free(bm_blk_buff);
		error_mupip = TRUE;
		COMMON_CLOSE(common);
		return FALSE;
	}

	COMMON_CLOSE(common);
	free(outptr);
	free(bm_blk_buff);

	util_out_print("DB file !AD incrementally backed up in !AD", TRUE,
		       fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr);
	util_out_print("!UL blocks saved.", TRUE, save_blks);
	util_out_print("Transactions from 0x!16@XQ to 0x!16@XQ are backed up.", TRUE,
		       &cs_addrs->shmpool_buffer->inc_backup_tn, &header->trans_hist.curr_tn);
	cs_addrs->hdr->last_inc_backup = header->trans_hist.curr_tn;
	if (record)
		cs_addrs->hdr->last_rec_backup = header->trans_hist.curr_tn;
	file_backed_up = TRUE;
	return TRUE;
}
Exemple #9
0
xc_status_t gc_init_interface(int prompt_passwd)
{ 	/* zOS is special when it comes to dynamic linking.
	 * (1). Building DLL with UNRESOLVED symbols
	 * =========================================
	 * Unlike other Unix platforms, on zOS DLL cannot be built having unresolved symbols and expecting them to get resolved
	 * by the loader.
	 * In this particular scenario we have symbols gtm_malloc, gtm_is_file_identical, gtm_free, gtm_filename_to_id and
	 * gtm_xcfileid_free that are part of mupip executable.
	 * As an workaround we are using function pointers to call into the interface functions so that we don't have an link-time
	 * errors.
	 * At runtime we do an dlopen with NULL which returns handle to global space and dlsym sets the function pointers to point
	 * to the correct functions at runtime.
	 *
	 * (2). DLSYM on symbols that are already resolved from another DLL
	 * ================================================================
	 * When mumps calls into libgtmcrypt it has above mentioned symbols already resolved from libgtmshr.dll.
	 * On zOS, when we try to DLSYM using the handle returned by DLOPEN(NULL,..), DLSYM crashes while trying to find symbols
	 * that are already loaded from another DLL(libgtmshr.dll).
	 * As an work around we dlopen libgtmshr.dll when called from MUMPS.
	 */
#	ifdef __MVS__
	void			*handle = NULL;
	const char		*gtm_dist, *dlerr_ptr;
	char 			gtmshr_file[GTM_PATH_MAX];
	int			dir_len;

	if (!(gtm_dist = getenv(GTM_DIST)))
		UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_DIST);
	dir_len = STRLEN(gtm_dist);
	memcpy(&gtmshr_file[0], gtm_dist, dir_len);
	gtmshr_file[dir_len] = DIR_SEPARATOR;
	MEMCPY_LIT(&gtmshr_file[dir_len + 1], GTMSHR_IMAGENAME);
	gtmshr_file[dir_len + STR_LIT_LEN(GTMSHR_IMAGENAME) + 1] = '\0';
	/* prompt_passwd = TRUE implies plugin is invoked from MUMPS. We need to dlopen libgtmshr when invoked from MUMPS.
	 * Please refer comment (2) above.
	 */
	handle = dlopen(prompt_passwd ? gtmshr_file : NULL, GC_FLAGS);
	if (NULL == handle)
	{
		if (NULL == (dlerr_ptr = dlerror()))
		{
			UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. Unknown system error");
		} else
	 		UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. %s", dlerr_ptr);
		return GC_FAILURE;
	}
	DLSYM_ERR_AND_EXIT(gtm_is_file_identical_fptr_t, gtm_is_file_identical_fptr, GTM_IS_FILE_IDENTICAL_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_malloc_fptr_t, gtm_malloc_fptr, GTM_MALLOC_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_free_fptr_t, gtm_free_fptr, GTM_FREE_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_filename_to_id_fptr_t, gtm_filename_to_id_fptr, GTM_FILENAME_TO_ID_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_ci_fptr_t, gtm_ci_fptr, GTM_CI_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_zstatus_fptr_t, gtm_zstatus_fptr, GTM_ZSTATUS_FUNC);
	DLSYM_ERR_AND_EXIT(gtm_xcfileid_free_fptr_t, gtm_xcfileid_free_fptr, GTM_XCFILEID_FREE_FUNC);
#	else
	gtm_is_file_identical_fptr = &gtm_is_file_identical;
	gtm_malloc_fptr = &gtm_malloc;
	gtm_free_fptr = &gtm_free;
	gtm_filename_to_id_fptr = &gtm_filename_to_id;
	gtm_ci_fptr = &gtm_ci;
	gtm_zstatus_fptr = &gtm_zstatus;
	gtm_xcfileid_free_fptr = &gtm_xcfileid_free;
#	endif
	return GC_SUCCESS;
}
void lvzwr_out(lv_val *lvp)
{
	char 			buff;
	uchar_ptr_t		lastc;
	int			n, nsubs, sbs_depth;
	lv_val			*dst_lv, *res_lv, *lvpc;
	mstr 			one;
	mval 			*subscp, *val, outindx;
	ht_ent_addr		*tabent_addr;
	ht_ent_mname		*tabent_mname;
	boolean_t		htent_added, dump_container;
	zwr_alias_var		*newzav, *zav;
	mident_fixed		zwrt_varname;
	lvzwrite_datablk	*newzwrb;
	gparam_list		param_list;	/* for op_putindx call through callg */
	gvnh_reg_t		*gvnh_reg;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	val = &lvp->v;
	assert(lvzwrite_block);
	if (!merge_args)
	{	/* The cases that exist here are:
		 * 1) This is a container variable. If the lv_val it refers to has been printed, show that association.
		 *    Else, "create" a $ZWRTACxxx var/index that will define the value. Then before returning, cause
		 *    that container var to be dumped with the appropriate $ZWRTACxxx index as the var name.
		 * 2) This is an alias base variable. If first time seen, we print normally but record it and put a
		 *    ";#" tag on the end to signify it is an alias var (doesn't affect value). If we look it up and it
		 *    is not the first time this lv_val has been printed, then we instead print the statement needed to
		 *    alias it to the first seen var.
		 * 3) This is just a normal var needing to be printed normally.
		 */
		htent_added = FALSE;
		one.addr = &buff;
		one.len = 1;
		lvzwrite_block->zav_added = FALSE;
		if (lvp->v.mvtype & MV_ALIASCONT)
		{	/* Case 1 -- have an alias container */
			assert(curr_symval->alias_activity);
			assert(!LV_IS_BASE_VAR(lvp));	/* verify is subscripted var */
			lvpc = (lv_val *)lvp->v.str.addr;
			assert(lvpc);
			assert(LV_IS_BASE_VAR(lvpc));	/* Verify base var lv_val */
			if (tabent_addr = (ht_ent_addr *)lookup_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc))
			{	/* The value was found, we have  a reference we can print now */
				assert(HTENT_VALID_ADDR(tabent_addr, zwr_alias_var, zav));
				*one.addr = '*';
				zshow_output(zwr_output, &one);
				lvzwr_out_targkey(&one);
				*one.addr = '=';
				zshow_output(zwr_output, &one);
				zav = (zwr_alias_var *)tabent_addr->value;
				assert(0 < zav->zwr_var.len);
				zwr_output->flush = TRUE;
				zshow_output(zwr_output, (const mstr *)&zav->zwr_var);
				return;
			}
			/* This lv_val isn't known to us yet. Scan the hash curr_symval hash table to see if it is known as a
			 * base variable as we could have a "forward reference" here.
			 */
			tabent_mname = als_lookup_base_lvval(lvpc);
			/* note even though both paths below add a zav, not bothering to set zav_added because that flag is
			 * really only (currently) cared about in reference to processing a basevar so we wouldn't
			 * be in this code path anyway. Comment here to record potential usage if that changes.
			 */
			if (tabent_mname)
			{	/* Found a base var it can reference -- create a zwrhtab entry for it */
				assert(tabent_mname->key.var_name.len);
				newzav = als_getzavslot();
				newzav->zwr_var = tabent_mname->key.var_name;
				htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc, newzav, &tabent_addr);
				assert(htent_added);
				dump_container = FALSE;
			} else
			{	/* Unable to find lv_val .. must be "orphaned" so we generate a new $ZWRTAC var for it. The first
				 * check however is if this is the first $ZWRTAC var being generated for this $ZWR. If yes, generate
				 * a $ZWRTAC="" line to preceed it. This will be a flag to load to clear out all existing $ZWRTAC
				 * temp vars so there is no pollution between loads of ZWRitten data.
				 */
				if (0 == zwrtacindx++)
				{	/* Put out "dummy" statement that will clear all the $ZWRTAC vars for a clean slate */
					zwr_output->flush = TRUE;
					zshow_output(zwr_output, &dzwrtac_clean);
				}
				MEMCPY_LIT(zwrt_varname.c, DOLLAR_ZWRTAC);
				lastc = i2asc((uchar_ptr_t)zwrt_varname.c + STR_LIT_LEN(DOLLAR_ZWRTAC), zwrtacindx);
				newzav =  als_getzavslot();
				newzav->zwr_var.addr = zwrt_varname.c;
				newzav->zwr_var.len = INTCAST(((char *)lastc - &zwrt_varname.c[0]));
				s2pool(&newzav->zwr_var);
				htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc, newzav, &tabent_addr);
				assert(htent_added);
				dump_container = TRUE;
			}
			/* Note value_printed flag in newzav not set since we are NOT dumping the value at this point
			 * but only the association. Since the flag is not set, we *will* dump it when we get to that
			 * actual variable.
			 */
			*one.addr = '*';
			zshow_output(zwr_output, &one);
			lvzwr_out_targkey(&one);
			*one.addr = '=';
			zshow_output(zwr_output, &one);
			zwr_output->flush = TRUE;
			zshow_output(zwr_output, (const mstr *)&newzav->zwr_var);
			if (dump_container)
			{	/* We want to dump the entire container variable but the name doesn't match the var we are
				 * currently dumping so push a new lvzwrite_block onto the stack, fill it in for the current var
				 * and call lvzwr_var() to handle it. When done, dismantle the temp lvzwrite_block.
				 */
				newzwrb = (lvzwrite_datablk *)malloc(SIZEOF(lvzwrite_datablk));
				memset(newzwrb, 0, SIZEOF(lvzwrite_datablk));
				newzwrb->sub = (zwr_sub_lst *)malloc(SIZEOF(zwr_sub_lst) * MAX_LVSUBSCRIPTS);
				newzwrb->curr_name = &newzav->zwr_var;
				newzwrb->prev = lvzwrite_block;
				lvzwrite_block = newzwrb;
				lvzwr_var(lvpc, 0);
				assert(newzav->value_printed);
				assert(newzwrb == lvzwrite_block);
				free(newzwrb->sub);
				lvzwrite_block = newzwrb->prev;
				free(newzwrb);
			}
			return;
		} else if (LV_IS_BASE_VAR(lvp) && IS_ALIASLV(lvp))
		{	/* Case 2 -- alias base variable (only base vars have reference counts). Note this can occur with
			 * TP save/restore vars since we increment both trefcnt and crefcnt for these hidden copied references.
			 * Because of that, we can't assert alias_activity but otherwise it shouldn't affect processing.
			 */
			if (!(htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvp, NULL, &tabent_addr)))
			{	/* Entry already existed -- need to output association rather than values */
				assert(tabent_addr);
				zav = (zwr_alias_var *)tabent_addr->value;
				assert(zav);
				if (zav->value_printed)
				{	/* Value has already been output -- print association this time */
					*one.addr = '*';	/* Flag as creating an alias */
					zshow_output(zwr_output, &one);
					/* Now for (new) variable name */
					zshow_output(zwr_output, lvzwrite_block->curr_name);
					*one.addr = '=';
					zshow_output(zwr_output, &one);
					/* .. and the var name aliasing to (the first seen with this lv_val) */
					assert(zav->zwr_var.len);
					zwr_output->flush = TRUE;
					zshow_output(zwr_output, &zav->zwr_var);
					return;
				}
				/* Else the value for this entry has not yet been printed so let us fall into case 3
				 * and get that done. Also set the flag so we mark it as an alias. Note this can happen if
				 * a container value for a name is encountered before the base var it points to. We will
				 * properly resolve the entry but its value  won't have been printed until we actually encounter
				 * it in the tree.
				 */
				htent_added = TRUE;		/* to force the ;# tag at end of value printing */
				zav->value_printed = TRUE;	/* value will be output shortly below */
			} else
			{	/* Entry was added so is first appearance -- give it a value to hold onto and print it */
				newzav = als_getzavslot();
				newzav->zwr_var = *lvzwrite_block->curr_name;
				newzav->value_printed = TRUE;		/* or rather it will be shortly.. */
				tabent_addr->value = (void *)newzav;
				lvzwrite_block->zav_added = TRUE;
				/* Note fall into case 3 to print var and value if exists */
			}
		}
		/* Case 3 - everything else */
		if (!MV_DEFINED(val))
			return;
		MV_FORCE_STR(val);
		lvzwr_out_targkey(&one);
		*one.addr = '=';
		zshow_output(zwr_output, &one);
		mval_write(zwr_output, val, !htent_added);
		if (htent_added)
		{	/* output the ";#" tag to indicate this is an alias output */
			zwr_output->flush = TRUE;
			zshow_output(zwr_output, &semi_star);
		}
	} else
	{	/* MERGE assignment from local variable */
		nsubs = lvzwrite_block->curr_subsc;
		if (MARG1_IS_GBL(merge_args))
		{	/* Target is a global var : i.e. MERGE ^gvn1=lcl1.
			 * In this case, mglvnp->gblp[IND1]->gvkey_nsubs would have been initialized in op_merge.c already.
			 * Use that to check if the target node in ^gvn1 exceeds max # of subscripts.
			 */
			if (MAX_GVSUBSCRIPTS <= (mglvnp->gblp[IND1]->gvkey_nsubs + nsubs))
				rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
			memcpy(gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->end + 1);
			gv_currkey->end = mglvnp->gblp[IND1]->s_gv_currkey->end;
			for (n = 0; n < nsubs; n++)
			{
				subscp = ((zwr_sub_lst *)lvzwrite_block->sub)->subsc_list[n].actual;
				MV_FORCE_STR(subscp);
				mval2subsc(subscp, gv_currkey, gv_cur_region->std_null_coll);
				if (!subscp->str.len &&	(ALWAYS != gv_cur_region->null_subs))
					sgnl_gvnulsubsc();
			}
			MV_FORCE_STR(val);
			gvnh_reg = TREF(gd_targ_gvnh_reg);	/* set by op_gvname/op_gvextnam/op_gvnaked done before op_merge */
			/* If gvnh_reg corresponds to a spanning global, then determine
			 * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey.
			 */
			GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, (TREF(gd_targ_addr)), gv_currkey);
			/* For spanning globals, "gv_cur_region" points to the target region for ^gvn1 only now.
			 * So do the GVSUBOFLOW check (both for spanning and non-spanning globals) now.
			 */
			if (gv_currkey->end >= gv_cur_region->max_key_size)
				ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE);
			op_gvput(val);
		} else
		{	/* Target is a local var : pre-process target in case it is a container */
			assert(MARG1_IS_LCL(merge_args));
			dst_lv = mglvnp->lclp[IND1];
			if (!LV_IS_BASE_VAR(dst_lv))
			{
				LV_SBS_DEPTH(dst_lv, FALSE, sbs_depth);
				if (MAX_LVSUBSCRIPTS < (sbs_depth + nsubs))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS);
			}
			param_list.arg[0] = dst_lv;	/* this is already protected from stp_gcol by op_merge so no need to
							 * push this into the stack for stp_gcol protection. */
			for (n = 0 ; n < nsubs; n++)
			{	/* Note: no need to do push these mvals on the stack before calling op_putindx
				 * as lvzwrite_block->sub is already protected by stp_gcol_src.h.
				 */
				param_list.arg[n+1] = ((zwr_sub_lst *)lvzwrite_block->sub)->subsc_list[n].actual;
			}
			param_list.n = n + 1;
			dst_lv = (lv_val *)callg((callgfnptr)op_putindx, &param_list);
			MV_FORCE_STR(val);
			assert(!(MV_ALIASCONT & dst_lv->v.mvtype));	/* op_putindx would have already done DECR_AC_REF for us */
			dst_lv->v = *val;
			dst_lv->v.mvtype &= ~MV_ALIASCONT;	/* Make sure alias container property does not pass */
		}
	}
}
Exemple #11
0
sm_uc_ptr_t  dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr_t b_top)
{
	sm_uc_ptr_t	r_top, key_top, cptr0, cptr1, cptr_top, cptr_base = NULL, cptr_next = NULL;
	char		key_buf[MAX_KEY_SZ + 1], *temp_ptr, *temp_key, util_buff[MAX_UTIL_LEN];
	char		*prefix_str, *space_str, *dot_str, *format_str;
	unsigned char	cc;
	short int	size;
	int4		util_len, head;
	uint4 		ch;
	int		buf_len, field_width,fastate, chwidth = 0;
        ssize_t   	chlen;
	block_id	blk_id;
	boolean_t	rechdr_displayed = FALSE;
	sgmnt_addrs	*csa;

	if (rp >= b_top)
		return NULL;
	head = cli_present("HEADER");
	GET_SHORT(size, &((rec_hdr_ptr_t)rp)->rsiz);
	cc = ((rec_hdr_ptr_t)rp)->cmpc;
	if ((CLI_NEGATED != head) && !patch_is_fdmp)
	{
		MEMCPY_LIT(util_buff, "Rec:");
		util_len = SIZEOF("Rec:") - 1;
		util_len += i2hex_nofill(patch_rec_counter, (uchar_ptr_t)&util_buff[util_len], 4);
		MEMCPY_LIT(&util_buff[util_len], "  Blk ");
		util_len += SIZEOF("  Blk ") - 1;
		util_len += i2hex_nofill(blk, (uchar_ptr_t)&util_buff[util_len], 8);
		MEMCPY_LIT(&util_buff[util_len], "  Off ");
		util_len += SIZEOF("  Off ") - 1;
		util_len += i2hex_nofill((int)(rp - bp), (uchar_ptr_t)&util_buff[util_len], 4);
		MEMCPY_LIT(&util_buff[util_len], "  Size ");
		util_len += SIZEOF("  Size ") - 1;
		util_len += i2hex_nofill(size, (uchar_ptr_t)&util_buff[util_len], 4);
		MEMCPY_LIT(&util_buff[util_len], "  Cmpc ");
		util_len += SIZEOF("  Cmpc ") - 1;
		util_len += i2hex_nofill(cc, (uchar_ptr_t)&util_buff[util_len], 2);
		MEMCPY_LIT(&util_buff[util_len], "  ");
		util_len += SIZEOF("  ") - 1;
		util_buff[util_len] = 0;
		util_out_print(util_buff, FALSE);
	}
	r_top = rp + size;
	if (r_top > b_top)
		r_top = b_top;
	else  if (r_top < rp + SIZEOF(rec_hdr))
		r_top = rp + SIZEOF(rec_hdr);
	if (cc > patch_comp_count)
		cc = patch_comp_count;
	if (((blk_hdr_ptr_t)bp)->levl)
		key_top = r_top - SIZEOF(block_id);
	else
	{
		for (key_top = rp + SIZEOF(rec_hdr);  key_top < r_top;)
			if (!*key_top++ && !*key_top++)
				break;
	}
	size = key_top - rp - SIZEOF(rec_hdr);
	if (size > SIZEOF(patch_comp_key) - 2 - cc)
		size = SIZEOF(patch_comp_key) - 2 - cc;
	if (size < 0)
		size = 0;
	memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size);
	patch_comp_count = cc + size;
	patch_comp_key[patch_comp_count] = patch_comp_key[patch_comp_count + 1] = 0;
	if (patch_is_fdmp)
	{
		if (dse_fdmp(key_top, (int)(r_top - key_top)))
			patch_fdmp_recs++;
	} else
	{
		if (r_top - SIZEOF(block_id) >= key_top)
		{
			GET_LONG(blk_id, key_top);
			if ((((blk_hdr_ptr_t)bp)->levl) || (blk_id <= cs_addrs->ti->total_blks))
			{
				MEMCPY_LIT(util_buff, "Ptr ");
				util_len = SIZEOF("Ptr ") - 1;
				util_len += i2hex_nofill(blk_id, (uchar_ptr_t)&util_buff[util_len], SIZEOF(blk_id) * 2);
				MEMCPY_LIT(&util_buff[util_len], "  ");
				util_len += SIZEOF("  ") - 1;
				util_buff[util_len] = 0;
				util_out_print(util_buff, FALSE);
			}
		}
		util_out_print("Key ", FALSE);
		if (r_top == b_top
			&& ((blk_hdr_ptr_t)bp)->levl && !((rec_hdr_ptr_t)rp)->cmpc
			&& r_top - rp == SIZEOF(rec_hdr) + SIZEOF(block_id))
				util_out_print("*", FALSE);
		else  if (patch_comp_key[0])
		{
			util_out_print("^", FALSE);
			csa = cs_addrs;
			RETRIEVE_ROOT_VAL(patch_comp_key, key_buf, temp_ptr, temp_key, buf_len);
			INIT_ROOT_GVT(key_buf, buf_len, curr_gbl_root);
		}
		print_target((uchar_ptr_t)patch_comp_key);
		util_out_print(0, TRUE);
		if (CLI_PRESENT != head)
		{
			prefix_str = "           |";
			if (wide_out)
			{
				format_str = "   !AD";
				dot_str = "   .";
				space_str = "    ";
				field_width = 4;
			} else
			{
				format_str = "  !AD";
				dot_str = "  .";
				space_str = "   ";
				field_width = 3;
			}
			fastate = 0;
			for (cptr0 = rp;  cptr0 < r_top;  cptr0 += NUM_BYTES_PER_LINE)
			{
				if (util_interrupt)
				{ /* return, rather than signal ERR_CTRLC so that the calling routine
				     can deal with that signal and do the appropriate cleanup */
					return NULL;
				}
				util_len = 8;
				i2hex_blkfill((int)(cptr0 - bp), (uchar_ptr_t)util_buff, 8);
				MEMCPY_LIT(&util_buff[util_len], " : |");
				util_len += SIZEOF(" : |") - 1;
				util_buff[util_len] = 0;
				util_out_print(util_buff, FALSE);
				/* Dump hexadecimal byte values */
				for (cptr1 = cptr0;  cptr1 < (cptr0 + NUM_BYTES_PER_LINE);  cptr1++)
				{
					if (cptr1 < r_top)
					{
						i2hex_blkfill(*(sm_uc_ptr_t)cptr1, (uchar_ptr_t)util_buff, field_width);
						util_buff[field_width] = 0;
						util_out_print(util_buff, FALSE);
					} else
						util_out_print(space_str, FALSE);
				}
				util_out_print("|", TRUE);
				util_out_print(prefix_str, FALSE);
				/* Display character/wide-character glyphs */
				for (cptr1 = cptr0, cptr_top = cptr0 + NUM_BYTES_PER_LINE;  cptr1 < cptr_top;  cptr1++)
				{
					if (!rechdr_displayed && (cptr1 == (rp + SIZEOF(rec_hdr))))
						rechdr_displayed = TRUE;
					assert(rechdr_displayed || (cptr1 < (rp + SIZEOF(rec_hdr))));
					assert(!rechdr_displayed || (cptr1 >= (rp + SIZEOF(rec_hdr))));
					switch (fastate)
					{
					case 0: /* prints single-byte characters or intepret
						   multi-byte characters */
						if (cptr1 >= r_top)
							util_out_print(space_str, FALSE);
						else if (!gtm_utf8_mode || IS_ASCII(*cptr1) || !rechdr_displayed)
						{ /* single-byte characters */
							if (PRINTABLE(*(sm_uc_ptr_t)cptr1))
								util_out_print(format_str, FALSE, 1, cptr1);
							else
								util_out_print(dot_str, FALSE);
						}
#ifdef UNICODE_SUPPORTED
						else { /* multi-byte characters */
							cptr_next = UTF8_MBTOWC(cptr1, r_top, ch);
							chlen = cptr_next - cptr1;
							if (WEOF == ch || !U_ISPRINT(ch))
							{ /* illegal or non-printable characters */
								cptr1--;
								fastate = 1;
							} else
							{ /* multi-byte printable characters */
								cptr_base = cptr1;
								chwidth = UTF8_WCWIDTH(ch);
								assert(chwidth >= 0 && chwidth <= 2);
								cptr1--;
								fastate = 2;
							}
						}
#endif
						break;

					case 1: /* illegal or non-printable characters */
						util_out_print(dot_str, FALSE);
						if (--chlen <= 0)
							fastate = 0;
						break;

					case 2: /* printable multi-byte characters */
						if (chlen-- > 1) /* fill leading bytes with spaces */
							util_out_print(space_str, FALSE);
						else
						{
							util_out_print("!AD", FALSE, field_width - chwidth, space_str);
							if (0 < chwidth)
								util_out_print("!AD", FALSE, cptr_next - cptr_base, cptr_base);
							fastate = 0;
						}
						break;
					}
				}
				util_out_print("|", TRUE);
			}
		}
		if (CLI_NEGATED != head)
			util_out_print(0, TRUE);
	}
	return (r_top == b_top) ? NULL : r_top;
}
Exemple #12
0
void zshow_stack(zshow_out *output)
{
	boolean_t	line_reset;
	unsigned char	*addr;
	unsigned short	nocount_frames[MAX_INDR_PER_COUNTED], *nfp;
	stack_frame	*fp;
	mstr 		v;
	unsigned char	buff[MAX_ENTRYREF_LEN + SIZEOF(INDR_OVERFLOW)];

	v.addr = (char *)&buff[0];
	flush_pio();
	nfp = &nocount_frames[0];
	line_reset = FALSE;
	for (fp = frame_pointer; ; fp = fp->old_frame_pointer)
	{
		if (NULL == fp->old_frame_pointer)
		{	/* This frame is a base frame - endpoint or jump it? */
#		ifdef GTM_TRIGGER
			if (fp->type & SFT_TRIGR)
				/* Have a trigger baseframe, pick up stack continuation frame_pointer stored by base_frame() */
				fp = *(stack_frame **)(fp + 1);
			else
#		endif
				break;	/* Endpoint.. */
		}
		if (!(fp->type & SFT_COUNT) || (fp->type & SFT_ZINTR))
		{
			if (nfp < &nocount_frames[MAX_INDR_PER_COUNTED])
				/* If room in array, save indirect frame type */
				*nfp++ = fp->type;
			else
				nocount_frames[MAX_INDR_PER_COUNTED - 1] = 0xffff;	/* Indicate array overflow */
			if (fp->type & SFT_ZTRAP || fp->type & SFT_DEV_ACT || HAS_TRANS_CODE_ERR(fp))
				line_reset = TRUE;
		} else
		{
			if (HAS_TRANS_CODE_ERR(fp))
			{
				*nfp++ = (fp->flags & SFF_ZTRAP_ERR) ? SFT_ZTRAP : SFT_DEV_ACT;
				line_reset = TRUE;
			}
			if (line_reset && ADDR_IN_CODE(fp->mpc, fp->rvector))
			{
				addr = fp->mpc + 1;
				line_reset = FALSE;
			} else
				addr = fp->mpc;
			v.len = INTCAST(symb_line(addr, &buff[0], 0, fp->rvector) - &buff[0]);
			if (v.len == 0)
			{
				MEMCPY_LIT(&buff[0], UNK_LOC_MESS);
				v.len = SIZEOF(UNK_LOC_MESS) - 1;
			}
			if (nfp != &nocount_frames[0])
			{
				for (--nfp; nfp >= &nocount_frames[0]; nfp--)
				{
					switch(*nfp)
					{
						case SFT_ZBRK_ACT:
							MEMCPY_LIT(&buff[v.len], ZBRK_FRAME);
							v.len += SIZEOF(ZBRK_FRAME) - 1;
							break;
						case SFT_DEV_ACT:
							MEMCPY_LIT(&buff[v.len], DEVERR_FRAME);
							v.len += SIZEOF(DEVERR_FRAME) - 1;
							break;
						case SFT_ZTRAP:
							MEMCPY_LIT(&buff[v.len], ZTRAP_FRAME);
							v.len += SIZEOF(ZTRAP_FRAME) - 1;
							break;
						case SFT_DM:
							MEMCPY_LIT(&buff[v.len], DIR_MODE_MESS);
							v.len += SIZEOF(DIR_MODE_MESS) - 1;
							break;
						case (SFT_COUNT | SFT_ZINTR):
							MEMCPY_LIT(&buff[v.len], ZINTR_FRAME);
							v.len += SIZEOF(DIR_MODE_MESS) - 1;
							break;
						case 0xffff:
							MEMCPY_LIT(&buff[v.len], INDR_OVERFLOW);
							v.len += SIZEOF(INDR_OVERFLOW) - 1;
							break;
						default:
							break;
					}
					output->flush = TRUE;
					zshow_output(output, &v);
					v.len = 0;
				}
				nfp = &nocount_frames[0];
			} else
			{
				output->flush = TRUE;
				zshow_output(output, &v);
			}
		}
	}
	return;
}
Exemple #13
0
int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink)
{
	char		rtnname[GTM_PATH_MAX + 1], rtnname_template[GTM_PATH_MAX + 1];
	char		objname[GTM_PATH_MAX + 1];
	char		zcomp_parms[(GTM_PATH_MAX * 2) + SIZEOF(mident_fixed) + SIZEOF(OBJECT_PARM) + SIZEOF(NAMEOFRTN_PARM)];
	mstr		save_zsource;
	int		rtnfd, rc, lenrtnname, lenobjname, len, alphnum_len, retry, save_errno;
	char		*mident_suffix_p1, *mident_suffix_p2, *mident_suffix_top, *namesub1, *namesub2, *zcomp_parms_ptr;
	mval		zlfile, zcompprm;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	DBGTRIGR_ONLY(memcpy(rtnname, trigdsc->rtn_desc.rt_name.addr, trigdsc->rtn_desc.rt_name.len));
	DBGTRIGR_ONLY(rtnname[trigdsc->rtn_desc.rt_name.len] = 0);
	DBGTRIGR((stderr, "gtm_trigger_complink: (Re)compiling trigger %s\n", rtnname));
	ESTABLISH_RET(gtm_trigger_complink_ch, ((0 == error_condition) ? TREF(dollar_zcstatus) : error_condition ));
	 /* Verify there are 2 available chars for uniqueness */
	assert((MAX_MIDENT_LEN - TRIGGER_NAME_RESERVED_SPACE) >= (trigdsc->rtn_desc.rt_name.len));
	assert(NULL == trigdsc->rtn_desc.rt_adr);
	gtm_trigger_comp_prev_run_time = run_time;
	run_time = TRUE;	/* Required by compiler */
	/* Verify the routine name set by MUPIP TRIGGER and read by gvtr_db_read_hasht() is not in use */
	if (NULL != find_rtn_hdr(&trigdsc->rtn_desc.rt_name))
	{	/* Ooops .. need name to be more unique.. */
		/* Though variable definitions are conventionally done at the function entry, the reason alphanumeric_table
		 * definition is done here is to minimize the time taken to initialize the below table in the most common case
		 * (i.e. no trigger name collisions).
		 */
		char 		alphanumeric_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
							'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
							'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
							't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
							'8', '9', '\0'};
		alphnum_len = STR_LIT_LEN(alphanumeric_table);
		namesub1 = trigdsc->rtn_desc.rt_name.addr + trigdsc->rtn_desc.rt_name.len++;
		/* If WBTEST_HELPOUT_TRIGNAMEUNIQ is defined, set alphnum_len to 1. This way, we make the maximum
		 * possible combinations for the uniqe trigger names to be 3 which is significantly lesser than
		 * the actual number of combinations (62x62 = 3844). For eg., if ^a is a global having triggers defined
		 * in 4 global directories, then the possible unique trigger names are a#1# ; a#1#A ; a#1#AA.
		 */
		GTM_WHITE_BOX_TEST(WBTEST_HELPOUT_TRIGNAMEUNIQ, alphnum_len, 1);
		mident_suffix_top = (char *)alphanumeric_table + alphnum_len;
		/* Phase 1. See if any single character can add uniqueness */
		for (mident_suffix_p1 = (char *)alphanumeric_table; mident_suffix_p1 < mident_suffix_top; mident_suffix_p1++)
		{
			*namesub1 = *mident_suffix_p1;
			if (NULL == find_rtn_hdr(&trigdsc->rtn_desc.rt_name))
				break;
		}
		if (mident_suffix_p1 == mident_suffix_top)
		{	/* Phase 2. Phase 1 could not find uniqueness .. Find it with 2 char variations */
			namesub2 = trigdsc->rtn_desc.rt_name.addr + trigdsc->rtn_desc.rt_name.len++;
			for (mident_suffix_p1 = (char *)alphanumeric_table; mident_suffix_p1 < mident_suffix_top;
			     mident_suffix_p1++)
			{	/* First char loop */
				for (mident_suffix_p2 = (char *)alphanumeric_table; mident_suffix_p2 < mident_suffix_top;
				     mident_suffix_p2++)
				{	/* 2nd char loop */
					*namesub1 = *mident_suffix_p1;
					*namesub2 = *mident_suffix_p2;
					if (NULL == find_rtn_hdr(&trigdsc->rtn_desc.rt_name))
					{
						mident_suffix_p1 = mident_suffix_top + 1;	/* Break out of both loops */
						break;
					}
				}
			}
			if (mident_suffix_p1 == mident_suffix_top)
			{	/* Phase 3: Punt */
				assert(WBTEST_HELPOUT_TRIGNAMEUNIQ == gtm_white_box_test_case_number);
				rts_error(VARLSTCNT(5) ERR_TRIGNAMEUNIQ, 3, trigdsc->rtn_desc.rt_name.len - 2,
					  trigdsc->rtn_desc.rt_name.addr, alphnum_len * alphnum_len);
			}
		}
	}
	/* Write trigger execute string out to temporary file and compile it */
	assert(MAX_XECUTE_LEN >= trigdsc->xecute_str.str.len);
	rc = SNPRINTF(rtnname_template, GTM_PATH_MAX, "%s/trgtmpXXXXXX", DEFAULT_GTM_TMP);
	assert(0 < rc);					/* Note rc is return code aka length - we expect a non-zero length */
	assert(GTM_PATH_MAX >= rc);
	/* The mkstemp() routine is known to bogus-fail for no apparent reason at all especially on AIX 6.1. In the event
	 * this shortcoming plagues other platforms as well, we add a low-cost retry wrapper.
	 */
	retry = MAX_MKSTEMP_RETRIES;
	do
	{
		strcpy(rtnname, rtnname_template);
		rtnfd = mkstemp(rtnname);
	} while ((-1 == rtnfd) && (EEXIST == errno) && (0 < --retry));
	if (-1 == rtnfd)
	{
		save_errno = errno;
		assert(FALSE);
		rts_error(VARLSTCNT(12) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("mkstemp()"), CALLFROM,
			  ERR_TEXT, 2, RTS_ERROR_TEXT(rtnname), save_errno);
	}
	assert(0 < rtnfd);	/* Verify file descriptor */
	rc = 0;
#	ifdef GEN_TRIGCOMPFAIL_ERROR
	{	/* Used ONLY to generate an error in a trigger compile by adding some junk in a previous line */
		DOWRITERC(rtnfd, ERROR_CAUSING_JUNK, strlen(ERROR_CAUSING_JUNK), rc); /* BYPASSOK */
		if (0 != rc)
		{
			UNLINK(rtnname);
			rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
		}
	}
#	endif
	DOWRITERC(rtnfd, trigdsc->xecute_str.str.addr, trigdsc->xecute_str.str.len, rc);
	if (0 != rc)
	{
		UNLINK(rtnname);
		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
	}
	if (NULL == memchr(trigdsc->xecute_str.str.addr, '\n', trigdsc->xecute_str.str.len))
	{
		DOWRITERC(rtnfd, NEWLINE, strlen(NEWLINE), rc);			/* BYPASSOK */
		if (0 != rc)
		{
			UNLINK(rtnname);
			rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc);
		}
	}
	CLOSEFILE(rtnfd, rc);
	if (0 != rc)
	{
		UNLINK(rtnname);
		rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, rc);
	}
	assert(MAX_MIDENT_LEN > trigdsc->rtn_desc.rt_name.len);
	zcomp_parms_ptr = zcomp_parms;
	lenrtnname = STRLEN(rtnname);
	MEMCPY_LIT(zcomp_parms_ptr, NAMEOFRTN_PARM);
	zcomp_parms_ptr += STRLEN(NAMEOFRTN_PARM);
	memcpy(zcomp_parms_ptr, trigdsc->rtn_desc.rt_name.addr, trigdsc->rtn_desc.rt_name.len);
	zcomp_parms_ptr += trigdsc->rtn_desc.rt_name.len;
	MEMCPY_LIT(zcomp_parms_ptr, OBJECT_PARM);
	zcomp_parms_ptr += STRLEN(OBJECT_PARM);
	strcpy(objname, rtnname);		/* Make copy of rtnname to become object name */
	strcat(objname, OBJECT_FTYPE);		/* Turn into object file reference */
	lenobjname = lenrtnname + STRLEN(OBJECT_FTYPE);
	memcpy(zcomp_parms_ptr, objname, lenobjname);
	zcomp_parms_ptr += lenobjname;
	*zcomp_parms_ptr++ = ' ';
	memcpy(zcomp_parms_ptr, rtnname, lenrtnname);
	zcomp_parms_ptr += lenrtnname;
	*zcomp_parms_ptr = '\0';		/* Null tail */
	len = INTCAST(zcomp_parms_ptr - zcomp_parms);
	assert((SIZEOF(zcomp_parms) - 1) > len);	/* Verify no overflow */
	zcompprm.mvtype = MV_STR;
	zcompprm.str.addr = zcomp_parms;
	zcompprm.str.len = len;
	/* Backup dollar_zsource so trigger doesn't show */
	PUSH_MV_STENT(MVST_MSAV);
	mv_chain->mv_st_cont.mvs_msav.v = dollar_zsource;
	mv_chain->mv_st_cont.mvs_msav.addr = &dollar_zsource;
	TREF(trigger_compile) = TRUE;		/* Set flag so compiler knows this is a special trigger compile */
	op_zcompile(&zcompprm, FALSE);	/* Compile but don't require a .m file extension */
	TREF(trigger_compile) = FALSE;	/* compile_source_file() establishes handler so always returns */
	if (0 != TREF(dollar_zcstatus))
	{	/* Someone err'd.. */
		run_time = gtm_trigger_comp_prev_run_time;
		REVERT;
		UNLINK(objname);	/* Remove files before return error */
		UNLINK(rtnname);
		return ERR_TRIGCOMPFAIL;
	}
	if (dolink)
	{	/* Link is optional as MUPIP TRIGGER doesn't need link */
		zlfile.mvtype = MV_STR;
		zlfile.str.addr = objname;
		zlfile.str.len = lenobjname;
		/* Specifying literal_null for a second arg (as opposed to NULL or 0) allows us to specify
		 * linking the object file (no compilation or looking for source). The 2nd arg is parms for
		 * recompilation and is non-null in an explicit zlink which we need to emulate.
		 */
#		ifdef GEN_TRIGLINKFAIL_ERROR
		UNLINK(objname);				/* delete object before it can be used */
#		endif
		op_zlink(&zlfile, (mval *)&literal_null);	/* need cast due to "extern const" attributes */
		/* No return here if link fails for some reason */
		trigdsc->rtn_desc.rt_adr = find_rtn_hdr(&trigdsc->rtn_desc.rt_name);
		if (NULL == trigdsc->rtn_desc.rt_adr)
			GTMASSERT;	/* Can't find routine we just put there? Catastrophic if happens */
		/* Replace the randomly generated source name with the constant "GTM Trigger" */
		trigdsc->rtn_desc.rt_adr->src_full_name.addr = GTM_TRIGGER_SOURCE_NAME;
		trigdsc->rtn_desc.rt_adr->src_full_name.len = STRLEN(GTM_TRIGGER_SOURCE_NAME);
		trigdsc->rtn_desc.rt_adr->trigr_handle = trigdsc;       /* Back pointer to trig def */
	}
	if (MVST_MSAV == mv_chain->mv_st_type && &dollar_zsource == mv_chain->mv_st_cont.mvs_msav.addr)
	{       /* Top mv_stent is one we pushed on there - restore dollar_zsource and get rid of it */
		dollar_zsource = mv_chain->mv_st_cont.mvs_msav.v;
		POP_MV_STENT();
	} else
		assert(FALSE); 	/* This mv_stent should be the one we just pushed */
	/* Remove temporary files created */
	UNLINK(objname);	/* Delete the object file first since rtnname is the unique key */
	UNLINK(rtnname);	/* Delete the source file */
	run_time = gtm_trigger_comp_prev_run_time;
	REVERT;
	return 0;
}
void open_list_file(void)
{
	char charspace;
	uint4 status;
	unsigned char	list_name[MAX_MIDENT_LEN + STR_LIT_LEN(LISTEXT)], fname[255];
	struct FAB	fab;
	struct NAM	nam;

#ifdef __ALPHA
# pragma member_alignment save
# pragma nomember_alignment
#endif
	static readonly struct{
	unsigned char	newversion;
	unsigned char	wrap;
	unsigned char	width;
	int4		v_width;
	unsigned char	eol;
	}open_params_list = {
	(unsigned char)iop_newversion,	(unsigned char)iop_wrap,
	(unsigned char)iop_recordsize,	(int4)132,
	(unsigned char)iop_eol
	};
#ifdef __ALPHA
# pragma member_alignment restore
#endif

	mval params;
	mval file;
	struct dsc$descriptor_s print_time_d
		= { SIZEOF(print_time_buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, print_time_buf };

	lst_param.list_line = 1;
	lst_param.page = 0;

	fab = cc$rms_fab;
	nam = cc$rms_nam;
	fab.fab$l_dna = &list_name[0];
	assert(module_name.len <= MAX_MIDENT_LEN);
	fab.fab$b_dns = module_name.len;
	memcpy(&list_name[0], module_name.addr, fab.fab$b_dns);
	MEMCPY_LIT(&list_name[fab.fab$b_dns], LISTEXT);
	fab.fab$b_dns += STR_LIT_LEN(LISTEXT);
	if (MV_DEFINED(&cmd_qlf.list_file))
	{
		fab.fab$b_fns = cmd_qlf.list_file.str.len;
		fab.fab$l_fna = cmd_qlf.list_file.str.addr;
	}
	nam.nam$l_esa = &fname[0];
	nam.nam$b_ess = SIZEOF(fname);
	nam.nam$b_nop = (NAM$M_SYNCHK);
	fab.fab$l_nam = &nam;
	fab.fab$l_fop = FAB$M_NAM;
	if ((status = sys$parse(&fab,0,0)) != RMS$_NORMAL)
	{	rts_error(VARLSTCNT(1) status);
	}

	file.mvtype = params.mvtype = MV_STR;
	file.str.len = nam.nam$b_esl;
	file.str.addr = &fname[0];
	params.str.len = SIZEOF(open_params_list);
	params.str.addr = &open_params_list;
	(*op_open_ptr)(&file, &params, 30, 0);
	params.str.len = 1;
	charspace = (char) iop_eol;
	params.str.addr = &charspace;
	dev_in_use = io_curr_device;
	op_use(&file,&params);
	lib$date_time(&print_time_d);
	list_head(0);
	return;
}
Exemple #15
0
STATICFNDEF boolean_t process_delim(char *delim_str, uint4 *delim_len)
{
	int		char_count;
	mstr		dst;
	int		dst_len;
	char		*dst_ptr;
	char		dst_string[MAX_DELIM_LEN + 1];
	uint4		len;
	char		*ptr;
	char		*ptr1;
	int		q_len;
	char		src_string[MAX_DELIM_LEN + 1];
	mstr		src;
	char		*src_ptr;

	if (MAX_DELIM_LEN < *delim_len)
	{
		util_out_print_gtmio("Delimiter too long", FLUSH);
		return FALSE;
	}
	ptr = delim_str;
	len = *delim_len;
	src_ptr = src_string;
	dst_len = 0;
	/* If ", scan to end quote
	 * If $, look for char --> c or zchar --> zch
	 * If _, leave it
	 */
	while (0 < len)
	{
		switch (*ptr)
		{
			case '"':
				PROCESS_STRING(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN);
				break;
			case '$':
				UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN);
				if (0 == len)
				{
					util_out_print_gtmio("Invalid entry in delimiter", FLUSH);
					return FALSE;
				}
				if ((3 < len) && ('C' == lower_to_upper_table[*ptr])
						&& ('H' == lower_to_upper_table[*(ptr + 1)])
						&& ('A' == lower_to_upper_table[*(ptr + 2)])
						&& ('R' == lower_to_upper_table[*(ptr + 3)]))
				{
					if (MAX_DELIM_LEN < ++dst_len)
					{
						util_out_print_gtmio("Trigger definition too long", FLUSH);
						return FALSE;
					}
					*src_ptr++ = 'C';
					ptr += 4;
					len -= 4;
				} else if ((4 < len) && ('Z' == lower_to_upper_table[*ptr])
						&& ('C' == lower_to_upper_table[*(ptr + 1)])
						&& ('H' == lower_to_upper_table[*(ptr + 2)])
						&& ('A' == lower_to_upper_table[*(ptr + 3)])
						&& ('R' == lower_to_upper_table[*(ptr + 4)]))
				{
					if (MAX_DELIM_LEN < (dst_len + 3))
					{
						util_out_print_gtmio("Trigger definition too long", FLUSH);
						return FALSE;
					}
					MEMCPY_LIT(src_ptr, "ZCH");
					src_ptr += 3;
					dst_len += 3;
					ptr += 5;
					len -= 5;
				} else
				{
					UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN);
				}
				break;
			default:
				UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN);
				break;
		}
	}
	*src_ptr = '\0';
	src.addr = src_string;
	src.len = (mstr_len_t)(src_ptr - src_string);
	dst.addr = dst_string;
	dst.len = 0;
	if (!zwr2format(&src, &dst))
	{
		util_out_print_gtmio("Invalid delimiter", FLUSH);
		return FALSE;
	}
	if (MAX_DELIM_LEN < dst.len)
	{
		util_out_print_gtmio("Delimiter too long", FLUSH);
		return FALSE;
	}
	memcpy(delim_str, dst_string, dst.len);
	*delim_len = dst.len;
	return TRUE;
}
Exemple #16
0
void mucregini(int4 blk_init_size)
{
	int4			status;
	int4			i;
	th_index_ptr_t 		th;
	collseq			*csp;
	uint4			ustatus;
	mstr 			jnlfile, jnldef, tmpjnlfile;
	time_t			ctime;

	MEMCPY_LIT(cs_data->label, GDS_LABEL);
	cs_data->desired_db_format = GDSVCURR;
	cs_data->fully_upgraded = TRUE;
	cs_data->db_got_to_v5_once = TRUE;	/* no V4 format blocks that are non-upgradeable */
	cs_data->minor_dbver = GDSMVCURR;
	cs_data->certified_for_upgrade_to = GDSVCURR;
	cs_data->creation_db_ver = GDSVCURR;
	cs_data->creation_mdb_ver = GDSMVCURR;
	cs_data->master_map_len = MASTER_MAP_SIZE_DFLT;
	cs_data->bplmap = BLKS_PER_LMAP;
	assert(BLK_SIZE <= MAX_DB_BLK_SIZE);
	cs_data->blk_size = BLK_SIZE;
	i = cs_data->trans_hist.total_blks;
	cs_data->trans_hist.free_blocks = i - DIVIDE_ROUND_UP(i, BLKS_PER_LMAP) - 2;
	cs_data->max_rec_size = gv_cur_region->max_rec_size;
	cs_data->max_key_size = gv_cur_region->max_key_size;
	cs_data->null_subs = gv_cur_region->null_subs;
	cs_data->std_null_coll = gv_cur_region->std_null_coll;
#ifdef UNIX
	cs_data->freeze_on_fail = gv_cur_region->freeze_on_fail;
	cs_data->mumps_can_bypass = gv_cur_region->mumps_can_bypass;
#endif
	cs_data->reserved_bytes = gv_cur_region->dyn.addr->reserved_bytes;
	cs_data->clustered = FALSE;
	cs_data->file_corrupt = 0;
	if (gv_cur_region->dyn.addr->lock_space)
		cs_data->lock_space_size = gv_cur_region->dyn.addr->lock_space * OS_PAGELET_SIZE;
	else
		cs_data->lock_space_size = DEF_LOCK_SIZE;
	cs_data->staleness[0] = -300000000;	/* staleness timer = 30 seconds */
	cs_data->staleness[1] = -1;
	cs_data->ccp_quantum_interval[0] = -20000000;	/* 2 sec */
	cs_data->ccp_quantum_interval[1] = -1;
	cs_data->ccp_response_interval[0] = -600000000;	/* 1 min */
	cs_data->ccp_response_interval[1] = -1;
	cs_data->ccp_tick_interval[0] = -1000000;	/* 1/10 sec */
	cs_data->ccp_tick_interval[1] = -1;
	cs_data->last_com_backup = 1;
	cs_data->last_inc_backup = 1;
	cs_data->last_rec_backup = 1;
	cs_data->defer_time = gv_cur_region->dyn.addr->defer_time;
	cs_data->jnl_alq = gv_cur_region->jnl_alq;
	if (cs_data->jnl_state && !cs_data->jnl_alq)
		cs_data->jnl_alq = JNL_ALLOC_DEF;
	cs_data->jnl_deq = gv_cur_region->jnl_deq;
	cs_data->jnl_before_image = gv_cur_region->jnl_before_image;
	cs_data->jnl_state = gv_cur_region->jnl_state;
	cs_data->epoch_interval = JNL_ALLOWED(cs_data) ? DEFAULT_EPOCH_INTERVAL : 0;
	cs_data->alignsize = JNL_ALLOWED(cs_data) ? (DISK_BLOCK_SIZE * JNL_DEF_ALIGNSIZE) : 0;
	ROUND_UP_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, gv_cur_region->jnl_buffer_size, cs_data);
#ifdef UNIX
	if (JNL_ALLOWED(cs_data))
	{
		if (cs_data->jnl_alq + cs_data->jnl_deq > gv_cur_region->jnl_autoswitchlimit)
		{
			cs_data->autoswitchlimit = gv_cur_region->jnl_autoswitchlimit;
			cs_data->jnl_alq = cs_data->autoswitchlimit;
		} else
			cs_data->autoswitchlimit = ALIGNED_ROUND_DOWN(gv_cur_region->jnl_autoswitchlimit,
							cs_data->jnl_alq, cs_data->jnl_deq);
	}
	else
		cs_data->autoswitchlimit = 0;
	assert(!(MAX_IO_BLOCK_SIZE % DISK_BLOCK_SIZE));
	if (cs_data->jnl_alq + cs_data->jnl_deq > cs_data->autoswitchlimit)
		cs_data->jnl_alq = cs_data->autoswitchlimit;
#else
	cs_data->autoswitchlimit = JNL_ALLOWED(cs_data) ? ALIGNED_ROUND_DOWN(JNL_ALLOC_MAX, cs_data->jnl_alq, cs_data->jnl_deq) : 0;
#endif
	if (!cs_data->jnl_buffer_size)
		ROUND_UP_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, JNL_BUFFER_DEF, cs_data);
	if (JNL_ALLOWED(cs_data))
		if (cs_data->jnl_buffer_size < JNL_BUFF_PORT_MIN(cs_data))
		{
			ROUND_UP_MIN_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, cs_data);
		} else if (cs_data->jnl_buffer_size > JNL_BUFFER_MAX)
		{
			ROUND_DOWN_MAX_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, cs_data);
		}
	cs_data->def_coll = gv_cur_region->def_coll;
	if (cs_data->def_coll)
	{
		if (csp = ready_collseq((int)(cs_data->def_coll)))
		{
			cs_data->def_coll_ver = (csp->version)(cs_data->def_coll);
			if (!do_verify(csp, cs_data->def_coll, cs_data->def_coll_ver))
			{
				gtm_putmsg(VARLSTCNT(4) ERR_COLLTYPVERSION, 2, cs_data->def_coll, cs_data->def_coll_ver);
				mupip_exit(ERR_MUNOACTION);
			}
		} else
		{
			gtm_putmsg(VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, cs_data->def_coll);
			mupip_exit(ERR_MUNOACTION);
		}
	}
	/* mupip_set_journal() relies on cs_data->jnl_file_len being 0 if cs_data->jnl_state is jnl_notallowed.
	 * Note that even though gv_cur_region->jnl_state is jnl_notallowed, gv_cur_region->jnl_file_len can be non-zero
	 */
	cs_data->jnl_file_len = JNL_ALLOWED(cs_data) ? gv_cur_region->jnl_file_len : 0;
	cs_data->reg_seqno = 1;
	VMS_ONLY(
		cs_data->resync_seqno = 1;
		cs_data->old_resync_seqno = 1;
		cs_data->resync_tn = 1;
	)
Exemple #17
0
void	gtm_getmsg (int4 msgnum, mstr *msgbuf)
{
	short int	m_len, faclen, taglen, j, sever;
	char		*cp;
	const char 	*top, *msgp, *fac;
	char		outbuf[32];
	char_ptr_t	tag;
	const err_msg	*msg;
	const err_ctl	*ctl;

	ctl = err_check(msgnum);
	if (ctl != 0)
	{
		assert((msgnum & FACMASK(ctl->facnum)) && (MSGMASK(msgnum, ctl->facnum) <= ctl->msg_cnt));
		j = MSGMASK(msgnum, ctl->facnum);
		msg = ctl->fst_msg + j - 1;
		msgp = msg->msg;
		tag = (char_ptr_t)msg->tag;
		fac = ctl->facname;
		sever = SEVMASK(msgnum);
	} else
	{
		sever = ERROR;
		tag = (char_ptr_t)outbuf;
		if ((MAX_SYSERR > msgnum) && (msgnum > 0))
		{
			assert(NULL != STRERROR(1));	/* OSF/1 check; can happen with 64-bit pointers and bad declaration */
			cp = (char *)tag;
			MEMCPY_LIT(cp, ERR_TAG);
			cp += strlen(ERR_TAG);
			cp = (char *)i2asc((uchar_ptr_t)cp, msgnum);
			*cp = '\0';
			msgp = STRERROR(msgnum);
		} else
		{
			tag = "UNKNOWN";
			msgp = "Unknown system error !SL";
		}
		fac = "SYSTEM";
	}
	m_len = strlen(msgp);
	if (!dec_nofac)
	{
		m_len += (faclen = strlen(fac));
		m_len += 4;	/* %-<sev>- */
		m_len += (taglen = strlen((const char *)tag));
		m_len += 2;	/* ,  */
	}
	m_len = m_len > msgbuf->len - 1 ? msgbuf->len - 1 : m_len;
	cp = msgbuf->addr;
	top = cp + m_len;
	if (!dec_nofac)
	{
		if (cp < top)
			*cp++ = '%';

		j = faclen > top-cp ? top-cp : faclen;
		if (j)
		{
			memcpy(cp, fac, j);
			cp += j;
		}
		if (cp < top)
			*cp++ = '-';
		if (cp < top)
		{
			switch(sever)
			{
			case SUCCESS:	*cp++ = 'S'; break;
			case INFO:	*cp++ = 'I'; break;
			case WARNING:	*cp++ = 'W'; break;
			case ERROR:	*cp++ = 'E'; break;
			case SEVERE:	*cp++ = 'F'; break;
			default:	*cp++ = 'U'; break;
			}
		}
		if (cp < top)
			*cp++ = '-';
		j = taglen > top-cp ? top-cp : taglen;
		if (j)
		{
			memcpy(cp, tag, j);
			cp += j;
		}
		if (cp < top)
			*cp++ = ',';
		if (cp < top)
			*cp++ = ' ';
	}

	memcpy(cp, msgp, top - cp);
	cp += top - cp;
	msgbuf->len = m_len;
	*cp++ = 0;
}
Exemple #18
0
int gtm_main (int argc, char **argv, char **envp)
#ifdef __osf__
# pragma pointer_size (restore)
#endif
{
	char			*ptr, *eq, **p;
	int             	eof, parse_ret;
	int			gtmcrypt_errno;
#	ifdef GTM_SOCKET_SSL_SUPPORT
	int			status;
	char			tlsid_env_name[MAX_TLSID_LEN * 2];
#	endif
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
	gtmenvp = envp;
	gtm_dist_ok_to_use = TRUE;
	common_startup_init(GTM_IMAGE);
	GTMTRIG_DBG_ONLY(ch_at_trigger_init = &mdb_condition_handler);
	err_init(stop_image_conditional_core);
	UNICODE_ONLY(gtm_strToTitle_ptr = &gtm_strToTitle);
	GTM_ICU_INIT_IF_NEEDED;	/* Note: should be invoked after err_init (since it may error out) and before CLI parsing */
	cli_lex_setup(argc, argv);
	/* put the arguments into buffer, then clean up the token buffer
	 * cli_gettoken() copies all arguments except the first one argv[0]
	 * into the buffer (cli_lex_in_ptr->in_str).
	 * i.e. command line: "/usr/library/V990/mumps -run somefile"
	 * the buffer cli_lex_in_ptr->in_str == "-run somefile"
	 */
	if (1 < argc)
		cli_gettoken(&eof);
	/* cli_gettoken() extracts the first token into cli_token_buf (in tok_extract())
	 * which should be done in parse_cmd(), So, reset the token buffer here to make
	 * parse_cmd() starts from the first token
	*/
	cli_token_buf[0] = '\0';
	/* insert the "MUMPS " in the parsing buffer the buffer is now:
	 * cli_lex_in_ptr->in_str == "MUMPS -run somefile"
	 * we didnot change argv[0]
	*/
	ptr = cli_lex_in_ptr->in_str;
	memmove(strlen("MUMPS ") + ptr, ptr, strlen(ptr) + 1);	/* BYPASSOK */
	MEMCPY_LIT(ptr, "MUMPS ");
	/* reset the argument buffer pointer, it's changed in cli_gettoken() call above
	 * do NOT reset to 0(NULL) to avoid fetching cmd line args into buffer again
	 * cli_lex_in_ptr->tp is the pointer to indicate current position in the buffer
	 * cli_lex_in_ptr->in_str
	 */
	cli_lex_in_ptr->tp = cli_lex_in_ptr->in_str;
	parse_ret = parse_cmd();
	if (parse_ret && (EOF != parse_ret))
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str));
	if (cli_present("DIRECT_MODE"))
		invocation_mode = MUMPS_DIRECT;
	else if (cli_present("RUN"))
		invocation_mode = MUMPS_RUN;
	gtm_chk_dist(argv[0]);
	/* this should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup   */
	init_gtm();
#	ifdef GTM_TLS
	if (MUMPS_COMPILE != invocation_mode)
	{
		if ((NULL != (ptr = (char *)getenv(GTM_PASSWD_ENV))) && (0 == strlen(ptr)))
		{
			INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno);
			if (0 != gtmcrypt_errno)
			{
				CLEAR_CRYPTERR_MASK(gtmcrypt_errno);
				assert(!IS_REPEAT_MSG_MASK(gtmcrypt_errno));
				assert((ERR_CRYPTDLNOOPEN == gtmcrypt_errno) || (ERR_CRYPTINIT == gtmcrypt_errno));
				if (ERR_CRYPTDLNOOPEN == gtmcrypt_errno)
					gtmcrypt_errno = ERR_CRYPTDLNOOPEN2;
				else if (ERR_CRYPTINIT == gtmcrypt_errno)
					gtmcrypt_errno = ERR_CRYPTINIT2;
				gtmcrypt_errno = SET_CRYPTERR_MASK(gtmcrypt_errno);
				GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, SIZEOF(GTMCRYPT_ERRLIT) - 1, GTMCRYPT_ERRLIT); /* BYPASSOK */
			}
		}
#		ifdef GTM_SOCKET_SSL_SUPPORT
		/* The below logic is for prefetching the password for TLS identifiers that may have been set in the environment.
		 * But, since SSL support for Socket devices is not yet implemented, this logic need not be enabled as of this
		 * writing. When SSL support for socket devices is implemented, the surrounding #ifdef can be removed.
		 */
		if (NULL != getenv("gtmcrypt_config"))
		{	/* Environment is configured for SSL/TLS (and/or encryption). Check if any environment variable of the form
			 * `gtmtls_passwd_*' is set to NULL string. If so, nudge the SSL/TLS library to read password(s) from the
			 * user.
			 */
			for (p = envp; *p; p++)
			{
				ptr = *p;
				if (0 == MEMCMP_LIT(ptr, GTMTLS_PASSWD_ENV_PREFIX))
				{	/* At least one environment variable of $gtmtls_passwd_* is found. */
					eq = strchr(ptr, '=');
					if (0 != strlen(eq + 1))
						break; /* Set to non-empty string. No need to initialize the library now. */
					/* Set to empty string. */
					if (NULL == tls_ctx)
					{
						if (SS_NORMAL != (status = gtm_tls_loadlibrary()))
						{
							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0,
									ERR_TEXT, 2, LEN_AND_STR(dl_err));
						}
						if (NULL == (tls_ctx = gtm_tls_init(GTM_TLS_API_VERSION,
											GTMTLS_OP_INTERACTIVE_MODE)))
						{
							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0,
									ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error()));
						}
					}
					assert(NULL != tls_ctx);
					assert((MAX_TLSID_LEN * 2) > (int)(eq - ptr));
					memcpy(tlsid_env_name, ptr, (int)(eq - ptr));
					tlsid_env_name[(int)(eq - ptr)] = '\0';
					gtm_tls_prefetch_passwd(tls_ctx, tlsid_env_name);
				}
			}
		}
#		endif
	}
#	endif
	dm_start();
	return 0;
}
gtcm_server()
{
	static readonly int4	reptim[2] = {-100000, -1};	/* 10ms */
       	static readonly int4	wait[2] =  {-1000000, -1};	/* 100ms */
	void		gtcm_ch(), gtcm_exi_handler(), gtcm_init_ast(), gtcm_int_unpack(), gtcm_mbxread_ast(),
			gtcm_neterr(), gtcm_read_ast(), gtcm_remove_from_action_queue(), gtcm_shutdown_ast(), gtcm_write_ast(),
			la_freedb();
	bool		gtcm_link_accept();
	bool		alid;
	char		buff[512];
	char		*h = NULL;
	char		*la_getdb();
	char		nbuff[256];
	char		*pak = NULL;
	char		reply;
	unsigned short	outlen;
	int4		closewait[2] = {0, -1};
	int4		inid = 0, mdl = 0, nid = 0, days = 0;
	int4		lic_status;
	int4		lic_x;
	int4		lm_mdl_nid();
	uint4		status;
	int		i, receive(), value;
	mstr		name1, name2;
	struct NTD	*cmu_ntdroot();
	connection_struct *prev_curr_entry;
	struct	dsc$descriptor_s	dprd;
	struct	dsc$descriptor_s	dver;
	$DESCRIPTOR(node_name, nbuff);
	$DESCRIPTOR(proc_name, "GTCM_SERVER");
	$DESCRIPTOR(timout, buff);
	DCL_THREADGBL_ACCESS;

	GTM_THREADGBL_INIT;
        assert(0 == EMPTY_QUEUE);       /* check so dont need gdsfhead everywhere */
	common_startup_init(GTCM_GNP_SERVER_IMAGE); /* Side-effect: Sets skip_dbtriggers to TRUE for non-trigger platforms */
	gtm_env_init();	/* read in all environment variables */
	name1.addr = "GTCMSVRNAM";
	name1.len = SIZEOF("GTCMSVRNAM") - 1;
	status = trans_log_name(&name1, &name2, nbuff);
	if (SS$_NORMAL == status)
	{
		proc_name.dsc$a_pointer = nbuff;
		proc_name.dsc$w_length = node_name.dsc$w_length = name2.len;
	} else if (SS$_NOLOGNAM == status)
	{
		MEMCPY_LIT(nbuff, "GTCMSVR");
		node_name.dsc$w_length = SIZEOF("GTCMSVR") - 1;
	} else
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
	sys$setprn(&proc_name);
	status = lib$get_foreign(&timout, 0, &outlen, 0);
	if ((status & 1) && (6 > outlen))
	{
		for (i = 0;  i < outlen;  i++)
		{
			value = value * 10;
			if (buff[i] <= '9' && buff[i] >= '0')
				value += buff[i] - 48;
			else
				break;
		}
		if (outlen && (i == outlen))
		{
			cm_timeout = TRUE;
			closewait[0] = value * -10000000;
		}
	}
	dprd.dsc$w_length = cm_prd_len;
	dprd.dsc$b_dtype  = DSC$K_DTYPE_T;
	dprd.dsc$b_class  = DSC$K_CLASS_S;
	dprd.dsc$a_pointer= cm_prd_name;
	dver.dsc$w_length = cm_ver_len;
	dver.dsc$b_dtype  = DSC$K_DTYPE_T;
	dver.dsc$b_class  = DSC$K_CLASS_S;
	dver.dsc$a_pointer= cm_ver_name;
	ast_init();
	licensed = TRUE;
	lkid = 2;
#	ifdef NOLICENSE
	lid = 1;
#	else
	/* this code used to be scattered to discourage reverse engineering, but since it now disabled, that seems pointless */
	lic_status = ((NULL == (h = la_getdb(LMDB))) ? LP_NOCNFDB : SS$_NORMAL);
	lic_status = ((1 == (lic_status & 1)) ? lm_mdl_nid(&mdl, &nid, &inid) : lic_status);
	lic_status = ((1 == (lic_status & 1)) ? lp_licensed(h, &dprd, &dver, mdl, nid, &lid, &lic_x, &days, pak) : lic_status);
	if (LP_NOCNFDB != lic_status)
		la_freedb(h);
	if (1 == (lic_status & 1))
	{
		licensed = TRUE;
		if (days < 14)
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WILLEXPIRE);
	} else
	{
		licensed = FALSE;
		sys$exit(lic_status);
	}
#	endif
	gtcm_ast_avail = astq_dyn_avail - GTCM_AST_OVRHD;
	stp_init(STP_INITSIZE);
	rts_stringpool = stringpool;
	cache_init();
	procnum = 0;
	get_proc_info(0, TADR(login_time), &image_count);
        memset(proc_to_clb, 0, SIZEOF(proc_to_clb));
	status = cmi_init(&node_name, 0, 0, gtcm_init_ast, gtcm_link_accept);
	if (!(status & 1))
	{
		rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ((status ^ 3) | 4));
		sys$exit(status);
	}
	ntd_root = cmu_ntdroot();
	ntd_root->mbx_ast =  gtcm_mbxread_ast;
	ntd_root->err = gtcm_neterr;
	gtcm_connection = FALSE;
	lib$establish(gtcm_ch);
	gtcm_exi_blk.exit_hand = &gtcm_exi_handler;
	gtcm_exi_blk.arg_cnt = 1;
	gtcm_exi_blk.cond_val = &gtcm_exi_condition;
	sys$dclexh(&gtcm_exi_blk);
	INVOKE_INIT_SECSHR_ADDRS;
	initialize_pattern_table();
	assert(run_time); /* Should have been set by common_startup_init */
	while (!cm_shutdown)
	{
		if (blkdlist)
			gtcml_chkreg();

		assert(!lib$ast_in_prog());
		status = sys$dclast(&gtcm_remove_from_action_queue, 0, 0);
		if (SS$_NORMAL != status)
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0);
		if (INTERLOCK_FAIL == curr_entry)
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) CMERR_CMINTQUE);
		if (EMPTY_QUEUE != curr_entry)
		{
			switch (*curr_entry->clb_ptr->mbf)
			{
				case CMMS_L_LKCANALL:
					reply = gtcmtr_lkcanall();
					break;
				case CMMS_L_LKCANCEL:
					reply = gtcmtr_lkcancel();
					break;
				case CMMS_L_LKREQIMMED:
					reply = gtcmtr_lkreqimmed();
					break;
				case CMMS_L_LKREQNODE:
					reply = gtcmtr_lkreqnode();
					break;
				case CMMS_L_LKREQUEST:
					reply = gtcmtr_lkrequest();
					break;
				case CMMS_L_LKRESUME:
					reply = gtcmtr_lkresume();
					break;
				case CMMS_L_LKACQUIRE:
					reply = gtcmtr_lkacquire();
					break;
				case CMMS_L_LKSUSPEND:
					reply = gtcmtr_lksuspend();
					break;
				case CMMS_L_LKDELETE:
					reply = gtcmtr_lkdelete();
					break;
				case CMMS_Q_DATA:
					reply = gtcmtr_data();
					break;
				case CMMS_Q_GET:
					reply = gtcmtr_get();
					break;
				case CMMS_Q_KILL:
					reply = gtcmtr_kill();
					break;
				case CMMS_Q_ORDER:
					reply = gtcmtr_order();
					break;
				case CMMS_Q_PREV:
					reply = gtcmtr_zprevious();
					break;
				case CMMS_Q_PUT:
					reply = gtcmtr_put();
					break;
				case CMMS_Q_QUERY:
					reply = gtcmtr_query();
					break;
				case CMMS_Q_ZWITHDRAW:
					reply = gtcmtr_zwithdraw();
					break;
				case CMMS_S_INITPROC:
					reply = gtcmtr_initproc();
					break;
				case CMMS_S_INITREG:
					reply = gtcmtr_initreg();
					break;
				case CMMS_S_TERMINATE:
					reply = gtcmtr_terminate(TRUE);
					break;
				case CMMS_E_TERMINATE:
					reply = gtcmtr_terminate(FALSE);
					break;
				case CMMS_U_LKEDELETE:
					reply = gtcmtr_lke_clearrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf);
					break;
				case CMMS_U_LKESHOW:
					reply = gtcmtr_lke_showrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf);
					break;
				case CMMS_B_BUFRESIZE:
					reply = CM_WRITE;
					value = *(unsigned short *)(curr_entry->clb_ptr->mbf + 1);
					if (value > curr_entry->clb_ptr->mbl)
					{
						free(curr_entry->clb_ptr->mbf);
						curr_entry->clb_ptr->mbf = malloc(value);
					}
					*curr_entry->clb_ptr->mbf = CMMS_C_BUFRESIZE;
					curr_entry->clb_ptr->mbl = value;
					curr_entry->clb_ptr->cbl = 1;
					break;
				case CMMS_B_BUFFLUSH:
					reply = gtcmtr_bufflush();
					break;
				case CMMS_Q_INCREMENT:
					reply = gtcmtr_increment();
					break;
				default:
					reply = FALSE;
					if (SS$_NORMAL == status)
                                                rts_error_csa(CSA_ARG(NULL)
							VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf);
					break;
			}
			if (curr_entry)		/* curr_entry can be NULL if went through gtcmtr_terminate */
			{
				status = sys$gettim(&curr_entry->lastact[0]);
				if (SS$_NORMAL != status)
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
				/* curr_entry is used by gtcm_mbxread_ast to determine if it needs to defer the interrupt message */
				prev_curr_entry = curr_entry;
				if (CM_WRITE == reply)
				{	/* if ast == gtcm_write_ast, let it worry */
					curr_entry->clb_ptr->ast = gtcm_write_ast;
					curr_entry = EMPTY_QUEUE;
					cmi_write(prev_curr_entry->clb_ptr);
				} else
				{
					curr_entry = EMPTY_QUEUE;
					if (1 == (prev_curr_entry->int_cancel.laflag & 1))
					{  /* valid interrupt cancel msg, handle in gtcm_mbxread_ast */
						status = sys$dclast(gtcm_int_unpack, prev_curr_entry, 0);
						if (SS$_NORMAL != status)
							rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status);
					} else  if (CM_READ == reply)
					{
						prev_curr_entry->clb_ptr->ast = gtcm_read_ast;
						cmi_read(prev_curr_entry->clb_ptr);
					}
				}
			}
		} else  if (1 < astq_dyn_avail)
		{
#			ifdef GTCM_REPTIM
			/* if reptim is not needed - and smw doesn't know why it would be - remove this	*/
			status = sys$schdwk(0, 0, &wait[0], &reptim[0]);
#			else
			status = sys$schdwk(0, 0, &wait[0], 0);
#			endif
			sys$hiber();
			sys$canwak(0, 0);
		}
		if (cm_timeout && (0 == gtcm_users))
                        sys$setimr(efn_ignore, closewait, gtcm_shutdown_ast, &cm_shutdown, 0);
	}
}
Exemple #20
0
/* Update header from v4.x to v5.0-000 */
void mu_upgrd_header(v15_sgmnt_data *v15_csd, sgmnt_data *csd)
{
	time_t	ctime;
	seq_num	v15_reg_seqno;

	error_def(ERR_MUINFOUINT8);

	memset(csd, 0, SIZEOF(sgmnt_data));
	MEMCPY_LIT(csd->label, GDS_LABEL);
	csd->blk_size = v15_csd->blk_size;
	csd->bplmap = v15_csd->bplmap;
	csd->start_vbn = v15_csd->start_vbn;
	csd->acc_meth = v15_csd->acc_meth;
	csd->max_bts = v15_csd->max_bts;
	csd->n_bts = v15_csd->n_bts;
	csd->bt_buckets = v15_csd->bt_buckets;
	if (v15_csd->reserved_bytes > BLK_HDR_INCREASE)
		csd->reserved_bytes = v15_csd->reserved_bytes - BLK_HDR_INCREASE;
	csd->max_rec_size = v15_csd->max_rec_size;
	csd->max_key_size = v15_csd->max_key_size;
	csd->lock_space_size = v15_csd->lock_space_size;
	csd->extension_size = v15_csd->extension_size;
	csd->def_coll = v15_csd->def_coll;
	csd->def_coll_ver = v15_csd->def_coll_ver;
	csd->std_null_coll = v15_csd->std_null_coll;					/* New in V5.0-FT01 */
	csd->null_subs = v15_csd->null_subs;
	csd->free_space = v15_csd->free_space;
	csd->mutex_spin_parms.mutex_hard_spin_count = v15_csd->mutex_spin_parms.mutex_hard_spin_count;
	csd->mutex_spin_parms.mutex_sleep_spin_count = v15_csd->mutex_spin_parms.mutex_sleep_spin_count;
	csd->mutex_spin_parms.mutex_spin_sleep_mask = v15_csd->mutex_spin_parms.mutex_spin_sleep_mask;
	csd->max_update_array_size = v15_csd->max_update_array_size;			/* New from V4.0-001G */
	csd->max_non_bm_update_array_size = v15_csd->max_non_bm_update_array_size;	/* New from V4.0-001G */
	csd->file_corrupt = v15_csd->file_corrupt;
	csd->minor_dbver = GDSMVCURR;					/* New in V5.0-000 */
	csd->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT;	/* New from V5.3-002 */
	csd->createinprogress = v15_csd->createinprogress;
	time(&ctime);
	assert(SIZEOF(ctime) >= SIZEOF(int4));
	csd->creation_time4 = (int4)ctime;/* No need to propagate previous value. Take only lower order 4-bytes of current time */
	csd->last_inc_backup = v15_csd->last_inc_backup;
	csd->last_com_backup = v15_csd->last_com_backup;
	csd->last_rec_backup = v15_csd->last_rec_backup;
	csd->reorg_restart_block = v15_csd->reorg_restart_block;		/* New from V4.2 */
	memcpy(csd->now_running, gtm_release_name, gtm_release_name_len + 1);	/* GT.M release name */
	csd->owner_node = v15_csd->owner_node;
	csd->image_count = v15_csd->image_count;
	csd->kill_in_prog = 0;
	csd->abandoned_kills = v15_csd->kill_in_prog;	/* assert to 0 ??? */
	csd->blks_to_upgrd = v15_csd->trans_hist.total_blks - v15_csd->trans_hist.free_blocks;	/* New in V5.0-000 */
	assert(csd->blks_to_upgrd);
	csd->tn_upgrd_blks_0 = 0;								/* New in V5.0-000 */
	csd->fully_upgraded = FALSE;								/* New in V5.0-000 */
	csd->desired_db_format = GDSVCURR;							/* New in V5.0-000 */
	csd->desired_db_format_tn = v15_csd->trans_hist.curr_tn - 1;				/* New in V5.0-000 */
	csd->reorg_db_fmt_start_tn = 0;								/* New in V5.0-000 */
	csd->certified_for_upgrade_to = v15_csd->certified_for_upgrade_to;			/* New in V5.0-000 */
	csd->master_map_len = MASTER_MAP_SIZE_V4;						/* New in V5.0-000 */
	csd->reorg_upgrd_dwngrd_restart_block = 0;						/* New in V5.0-000 */
	csd->creation_db_ver = v15_csd->creation_db_ver;	/* Retain creation major/minor version */
	csd->creation_mdb_ver = v15_csd->creation_mdb_ver;
	csd->trans_hist.early_tn = v15_csd->trans_hist.early_tn;
	csd->trans_hist.curr_tn = v15_csd->trans_hist.curr_tn;	/* INCREMENT_CURR_TN comment added to note curr_tn set is done */
	csd->max_tn = MAX_TN_V5;		/* New in V5.0-000 */
	SET_TN_WARN(csd, csd->max_tn_warn);	/* New in V5.0-000 */
	csd->trans_hist.last_mm_sync = v15_csd->trans_hist.last_mm_sync;
	csd->trans_hist.mm_tn = v15_csd->trans_hist.mm_tn;
	csd->trans_hist.lock_sequence = v15_csd->trans_hist.lock_sequence;
	csd->trans_hist.total_blks = v15_csd->trans_hist.total_blks;
	csd->trans_hist.free_blocks = v15_csd->trans_hist.free_blocks;
	csd->flush_time[0] = v15_csd->flush_time[0];
	csd->flush_time[1] = v15_csd->flush_time[1];
	csd->flush_trigger = v15_csd->flush_trigger;
	csd->n_wrt_per_flu = v15_csd->n_wrt_per_flu;
	csd->wait_disk_space = v15_csd->wait_disk_space;
	csd->defer_time = v15_csd->defer_time;
#ifdef UNIX
	csd->semid = INVALID_SEMID;
	csd->shmid = INVALID_SHMID;
	csd->gt_sem_ctime.ctime = 0;
	csd->gt_shm_ctime.ctime = 0;
#endif
	/* Note none of the counter fields are being carried over. An upgrade or downgrade will
	   implicitly set them to zero by not initializing them.
	*/
	csd->staleness[0] = v15_csd->staleness[0];
	csd->staleness[1] = v15_csd->staleness[1];
	csd->ccp_tick_interval[0] = v15_csd->ccp_tick_interval[0];
	csd->ccp_tick_interval[1] = v15_csd->ccp_tick_interval[1];
	csd->ccp_quantum_interval[0] = v15_csd->ccp_quantum_interval[0];
	csd->ccp_quantum_interval[1] = v15_csd->ccp_quantum_interval[1];
	csd->ccp_response_interval[0] = v15_csd->ccp_response_interval[0];
	csd->ccp_response_interval[1] = v15_csd->ccp_response_interval[1];
	csd->ccp_jnl_before = v15_csd->ccp_jnl_before;
	csd->clustered = v15_csd->clustered;
	csd->unbacked_cache = v15_csd->unbacked_cache;
	csd->rc_srv_cnt = v15_csd->rc_srv_cnt;
	csd->dsid = v15_csd->dsid;
	csd->rc_node = v15_csd->rc_node;
	v15_reg_seqno = csd->reg_seqno = v15_csd->reg_seqno;
	csd->repl_state = v15_csd->repl_state;
	VMS_ONLY(
		csd->resync_seqno = v15_csd->resync_seqno;
		csd->resync_tn = v15_csd->resync_tn;
		csd->old_resync_seqno = v15_csd->old_resync_seqno;
		/* resync_seqno should never be greater the region's reg_seqno. Ensure that this is indeed the case. In PRO,
		 * fix the fields to be at most the value of the region's reg_seqno if they are found to be greater than
		 * reg_seqno
		 */
		assert((csd->resync_seqno <= v15_reg_seqno) && (csd->old_resync_seqno <= v15_reg_seqno));
		if (csd->resync_seqno > v15_reg_seqno)
			csd->resync_seqno = v15_reg_seqno;
		if (csd->old_resync_seqno > v15_reg_seqno)
			csd->old_resync_seqno = v15_reg_seqno;

		assert(0 != csd->reg_seqno || (0 == csd->resync_seqno && 0 == csd->resync_tn && repl_closed == csd->repl_state));
		assert(0 != csd->resync_seqno || (0 == csd->reg_seqno && 0 == csd->resync_tn && repl_closed == csd->repl_state));
		assert(0 != csd->resync_tn || (0 == csd->reg_seqno && 0 == csd->resync_seqno && repl_closed == csd->repl_state));
		if (0 == csd->reg_seqno || 0 == csd->resync_seqno || 0 == csd->resync_tn)
		{	/* This can happen for pre-replication versions */
			csd->reg_seqno = 1;
			csd->resync_seqno = 1;
			csd->resync_tn = 1;
			csd->old_resync_seqno = 1;
			csd->repl_state = repl_closed;
		}
	)
Exemple #21
0
STATICFNDEF boolean_t process_dollar_char(char **src_ptr, int *src_len, boolean_t have_star, char **d_ptr, int *dst_len)
{
	int		char_count;
	char		*char_ptr;
	int		len;
	char		*dst_ptr;
	char		dst_string[MAX_DCHAR_LEN];
	int		lcl_dst_len;
	mstr		m_dst;
	mstr		m_src;
	char		*ptr;
	int		q_len;
	char		*tmp_dst_ptr;

	tmp_dst_ptr = dst_ptr = *d_ptr;
	ptr = *src_ptr;
	len = *src_len;
	lcl_dst_len = *dst_len;
	assert('$' == *ptr);
	UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN);
	if (0 == len)
		return FALSE;
	switch (*ptr)
	{
		case 'c':
		case 'C':
			UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN);
			if ((0 < len) && ('(' == *ptr))
				break;
			else if ((3 < len) && ('H' == lower_to_upper_table[*ptr])
					&& ('A' == lower_to_upper_table[*(ptr + 1)])
					&& ('R' == lower_to_upper_table[*(ptr + 2)]) && ('(' == *(ptr + 3)))
			{
				ptr += 3;
				len -= 3;
				break;
			}
			else
				return FALSE;
			break;
		case 'z':
		case 'Z':
			UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN);
			if ((2 < len) && ('C' == lower_to_upper_table[*ptr])
					&& ('H' == lower_to_upper_table[*(ptr + 1)]) && ('(' == *(ptr + 2)))
			{
				ptr += 2;
				len -= 2;
			}
			else if ((4 < len) && ('C' == lower_to_upper_table[*ptr])
					&& ('H' == lower_to_upper_table[*(ptr + 1)])
					&& ('A' == lower_to_upper_table[*(ptr + 2)])
					&& ('R' == lower_to_upper_table[*(ptr + 3)]) && ('(' == *(ptr + 4)))
			{
				ptr += 4;
				len -= 4;
			}
			else
				return FALSE;
			if (MAX_GVSUBS_LEN < lcl_dst_len + 2)
			{
				util_out_print_gtmio("Subscript too long", FLUSH);
				return FALSE;
			}
			MEMCPY_LIT(dst_ptr, "CH");
			dst_ptr += 2;
			lcl_dst_len += 2;
			break;
		default:
			return FALSE;
	}
	assert('(' == *ptr);
	UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN);
	while ((0 < len) && (')' != *ptr))
	{
		UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN);
	}
	q_len = 0;
	if (!have_star)
	{
		if (MAX_GVSUBS_LEN < ++lcl_dst_len)
		{
			util_out_print_gtmio("$[Z]CHAR expression too long", FLUSH);
			return FALSE;
		}
		*dst_ptr++ = *ptr++;
		*dst_ptr = '\0';
		m_src.addr = tmp_dst_ptr;
		m_src.len = (mstr_len_t)(dst_ptr - tmp_dst_ptr);
		m_dst.addr = dst_string;
		m_dst.len = 0;
		if (!zwr2format(&m_src, &m_dst))
			return FALSE;
		lcl_dst_len = *dst_len;		/* Reset length because we're creating the final version now */
		if (MAX_GVSUBS_LEN < ++lcl_dst_len)
		{
			util_out_print_gtmio("Subscript too long", FLUSH);
			return FALSE;
		}
		*tmp_dst_ptr++ = '"';
		char_ptr = m_dst.addr;
		if (MAX_GVSUBS_LEN < (lcl_dst_len + m_dst.len))
		{
			util_out_print_gtmio("Subscript too long", FLUSH);
			return FALSE;
		}
		for (char_count = 0; m_dst.len > char_count; char_count++)
		{
			if ('"' == *char_ptr)
			{
				if (MAX_GVSUBS_LEN < ++lcl_dst_len)
				{
					util_out_print_gtmio("Subscript too long", FLUSH);
					return FALSE;
				}
				*tmp_dst_ptr++ = '"';
				q_len++;
			}
			*tmp_dst_ptr++ = *char_ptr++;
			lcl_dst_len++;
		}
		if (MAX_GVSUBS_LEN < ++lcl_dst_len)
		{
			util_out_print_gtmio("Subscript too long", FLUSH);
			return FALSE;
		}
		*tmp_dst_ptr++ = '"';
		dst_ptr = tmp_dst_ptr;
	}
	else
		ptr++;
	assert(!have_star || ((dst_ptr == *d_ptr) && (lcl_dst_len == *dst_len)));
	*src_ptr = ptr;
	*src_len = len + 2 + q_len;	/* Allow for the open and close quotes and any internal quotes */
	*d_ptr = dst_ptr;
	*dst_len = lcl_dst_len;
	return TRUE;
}
int4 mur_cre_file_extfmt(jnl_ctl_list *jctl, int recstat)
{
	fi_type			*file_info;
	char			*ptr, rename_fn[MAX_FN_LEN];
	int			rename_fn_len, base_len, fn_exten_size, extrlen, tmplen;
	uint4			status;
	mval			op_val, op_pars;
	boolean_t		is_stdout;	/* Output will go STDOUT? */
	static readonly	char 	*fn_exten[] = {EXT_MJF, EXT_BROKEN, EXT_LOST};
	static readonly	char 	*ext_file_type[] = {STR_JNLEXTR, STR_BRKNEXTR, STR_LOSTEXTR};
	static readonly unsigned char		open_params_list[]=
	{
		(unsigned char)iop_m,
		(unsigned char)iop_newversion,
		(unsigned char)iop_noreadonly,
		(unsigned char)iop_nowrap,
		(unsigned char)iop_stream,
		(unsigned char)iop_eol
	};

	assert(GOOD_TN == recstat || BROKEN_TN == recstat || LOST_TN == recstat);
	assert(0 == GOOD_TN);
	assert(1 == BROKEN_TN);
	assert(2 == LOST_TN);
	assert(GOOD_TN != recstat || mur_options.extr[GOOD_TN]);
	/* Argument journal -extract=-stdout ? */
	is_stdout = mur_options.extr_fn[recstat]
		&& (0 == STRNCASECMP(mur_options.extr_fn[recstat], JNL_STDO_EXTR, SIZEOF(JNL_STDO_EXTR)));
	/* If we need to write to stdout, we can bypass file renaming stuff */
	if(!is_stdout)
	{
		ptr = (char *)&jctl->jnl_fn[jctl->jnl_fn_len];
		while (DOT != *ptr)	/* we know journal file name alway has a DOT */
			ptr--;
		base_len = (int)(ptr - (char *)&jctl->jnl_fn[0]);
		file_info = (void *)malloc(SIZEOF(fi_type));
		if (0 == mur_options.extr_fn_len[recstat])
		{
			mur_options.extr_fn[recstat] = malloc(MAX_FN_LEN);
			mur_options.extr_fn_len[recstat] = base_len;
			memcpy(mur_options.extr_fn[recstat], jctl->jnl_fn, base_len);
			fn_exten_size = STRLEN(fn_exten[recstat]);
			memcpy(mur_options.extr_fn[recstat] + base_len, fn_exten[recstat], fn_exten_size);
			mur_options.extr_fn_len[recstat] += fn_exten_size;
		}
		file_info->fn_len = mur_options.extr_fn_len[recstat];
		file_info->fn = mur_options.extr_fn[recstat];
		murgbl.file_info[recstat] = file_info;
		if (RENAME_FAILED == rename_file_if_exists(file_info->fn, file_info->fn_len, rename_fn, &rename_fn_len, &status))
			return status;
		op_pars.mvtype = MV_STR;
		op_pars.str.len = SIZEOF(open_params_list);
		op_pars.str.addr = (char *)open_params_list;
		op_val.mvtype = MV_STR;
		op_val.str.len = file_info->fn_len;
		op_val.str.addr = (char *)file_info->fn;
		if ((status = (*op_open_ptr)(&op_val, &op_pars, 0, NULL)) == 0)
		{
			gtm_putmsg(VARLSTCNT(5) ERR_FILENOTCREATE, 2, file_info->fn_len, file_info->fn, errno);
			return ERR_FILENOTCREATE;
		}
	}
	/* Write file version info for the file created here. See C9B08-001729 */
	if (!mur_options.detail)
	{
		MEMCPY_LIT(murgbl.extr_buff, JNL_EXTR_LABEL);
		extrlen = STR_LIT_LEN(JNL_EXTR_LABEL);
	} else
	{
		MEMCPY_LIT(murgbl.extr_buff, JNL_DET_EXTR_LABEL);
		extrlen = STR_LIT_LEN(JNL_DET_EXTR_LABEL);
	}
	if (LOST_TN == recstat)
	{
		if (mur_options.update)
		{
			if (mur_options.rollback)
				ptr = " ROLLBACK";
			else
				ptr = " RECOVER";
		} else
			ptr = " EXTRACT";
		tmplen = STRLEN(ptr);
		memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen);
		extrlen += tmplen;
		if (mur_options.rollback)
		{
			if (mur_options.fetchresync_port && murgbl.was_rootprimary)
				ptr = " PRIMARY ";
			else
				ptr = " SECONDARY ";
			tmplen = STRLEN(ptr);
			memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen);
			extrlen += tmplen;
			assert(NULL != jnlpool.repl_inst_filehdr);
			ptr = (char *)&jnlpool.repl_inst_filehdr->inst_info.this_instname[0];
			tmplen = STRLEN(ptr);
			memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen);
			extrlen += tmplen;
		}
	}
	if (gtm_utf8_mode)
	{
		murgbl.extr_buff[extrlen++] = ' ';
		MEMCPY_LIT(&murgbl.extr_buff[extrlen], UTF8_NAME);
		extrlen += STR_LIT_LEN(UTF8_NAME);
	}
	murgbl.extr_buff[extrlen++] = '\\';
	jnlext_write((is_stdout ? NULL : file_info), murgbl.extr_buff, extrlen);
	if (!is_stdout) /* We wrote to stdout so it doesn't make a sense to print a message about file creation. */
		gtm_putmsg(VARLSTCNT(6) ERR_FILECREATE, 4, LEN_AND_STR(ext_file_type[recstat]), file_info->fn_len, file_info->fn);
	return SS_NORMAL;
}
Exemple #23
0
/* Downgrade header from v5.0-000 to v4.x */
void mu_dwngrd_header(sgmnt_data *csd, v15_sgmnt_data *v15_csd)
{
	time_t	temp_time;
	error_def(ERR_MUINFOUINT8);

	memset(v15_csd, 0, SIZEOF(v15_sgmnt_data));
	MEMCPY_LIT(v15_csd->label, GDS_LABEL_GENERIC);
	MEMCPY_LIT((v15_csd->label + SIZEOF(GDS_LABEL_GENERIC) - 1), GDS_V40);
	v15_csd->blk_size = csd->blk_size;
	v15_csd->bplmap = csd->bplmap;
	v15_csd->start_vbn = csd->start_vbn;
	v15_csd->acc_meth = csd->acc_meth;
	v15_csd->max_bts = csd->max_bts;
	v15_csd->n_bts = csd->n_bts;
	v15_csd->bt_buckets = csd->bt_buckets;
	v15_csd->reserved_bytes = csd->reserved_bytes + BLK_HDR_INCREASE;
	v15_csd->max_rec_size = csd->max_rec_size;
	v15_csd->max_key_size = csd->max_key_size;
	v15_csd->lock_space_size = csd->lock_space_size;
	v15_csd->extension_size = csd->extension_size;
	v15_csd->def_coll = csd->def_coll;
	v15_csd->def_coll_ver = csd->def_coll_ver;
	v15_csd->std_null_coll = csd->std_null_coll;
	v15_csd->null_subs = csd->null_subs;
	v15_csd->free_space = csd->free_space;
	v15_csd->mutex_spin_parms.mutex_hard_spin_count = csd->mutex_spin_parms.mutex_hard_spin_count;
	v15_csd->mutex_spin_parms.mutex_sleep_spin_count = csd->mutex_spin_parms.mutex_sleep_spin_count;
	v15_csd->mutex_spin_parms.mutex_spin_sleep_mask = csd->mutex_spin_parms.mutex_spin_sleep_mask;
	v15_csd->max_update_array_size = csd->max_update_array_size;	/* This is filler for some early V4 versions */
	v15_csd->max_non_bm_update_array_size = csd->max_non_bm_update_array_size;/* This is filler for some early V4 versions */
	v15_csd->file_corrupt = csd->file_corrupt;
	v15_csd->createinprogress = csd->createinprogress;
	time(&temp_time);	/* No need to propagate previous value */
	v15_csd->creation.date_time = (v15_time_t)temp_time;
	v15_csd->last_inc_backup = (v15_trans_num)csd->last_inc_backup;
	v15_csd->last_com_backup = (v15_trans_num)csd->last_com_backup;
	v15_csd->last_rec_backup = (v15_trans_num)csd->last_rec_backup;
	v15_csd->reorg_restart_block = csd->reorg_restart_block;
	memcpy(v15_csd->now_running, gtm_release_name, gtm_release_name_len + 1);	/* GT.M release name */
	v15_csd->owner_node = csd->owner_node;
	v15_csd->image_count = csd->image_count;
	v15_csd->kill_in_prog = (csd->kill_in_prog + csd->abandoned_kills);
	v15_csd->trans_hist.curr_tn = (v15_trans_num) csd->trans_hist.curr_tn;
	v15_csd->trans_hist.early_tn = (v15_trans_num) csd->trans_hist.early_tn;
	v15_csd->trans_hist.last_mm_sync = (v15_trans_num) csd->trans_hist.last_mm_sync;
	v15_csd->trans_hist.header_open_tn = (v15_trans_num) csd->trans_hist.curr_tn;
	v15_csd->trans_hist.mm_tn = (v15_trans_num) csd->trans_hist.mm_tn;
	v15_csd->trans_hist.lock_sequence = csd->trans_hist.lock_sequence;
	v15_csd->trans_hist.total_blks = csd->trans_hist.total_blks;
	v15_csd->trans_hist.free_blocks = csd->trans_hist.free_blocks;
	v15_csd->flush_time[0] = csd->flush_time[0];
	v15_csd->flush_time[1] = csd->flush_time[1];
	v15_csd->flush_trigger = csd->flush_trigger;
	v15_csd->n_wrt_per_flu = csd->n_wrt_per_flu;
	v15_csd->wait_disk_space = csd->wait_disk_space;
	v15_csd->defer_time = csd->defer_time;
#ifdef UNIX
	v15_csd->semid = INVALID_SEMID;
	v15_csd->shmid = INVALID_SHMID;
	v15_csd->gt_sem_ctime.ctime = 0;
	v15_csd->gt_shm_ctime.ctime = 0;
#endif
	/* Note none of the counter fields are being carried over. An upgrade or downgrade will
	   implicitly set them to zero by not initializing them.
	*/
	v15_csd->staleness[0] = csd->staleness[0];
	v15_csd->staleness[1] = csd->staleness[1];
	v15_csd->ccp_tick_interval[0] = csd->ccp_tick_interval[0];
	v15_csd->ccp_tick_interval[1] = csd->ccp_tick_interval[1];
	v15_csd->ccp_quantum_interval[0] = csd->ccp_quantum_interval[0];
	v15_csd->ccp_quantum_interval[1] = csd->ccp_quantum_interval[1];
	v15_csd->ccp_response_interval[0] = csd->ccp_response_interval[0];
	v15_csd->ccp_response_interval[1] = csd->ccp_response_interval[1];
	v15_csd->ccp_jnl_before = csd->ccp_jnl_before;
	v15_csd->clustered = csd->clustered;
	v15_csd->unbacked_cache = csd->unbacked_cache;
	v15_csd->rc_srv_cnt = csd->rc_srv_cnt;
	v15_csd->dsid = csd->dsid;
	v15_csd->rc_node = csd->rc_node;

	v15_csd->reg_seqno = csd->reg_seqno;
	VMS_ONLY(
		v15_csd->resync_seqno = csd->resync_seqno;
		v15_csd->old_resync_seqno = csd->old_resync_seqno;
		v15_csd->resync_tn = csd->resync_tn;
	)
Exemple #24
0
void mu_extract(void)
{
	int 				stat_res, truncate_res;
	int				reg_max_rec, reg_max_key, reg_max_blk, reg_std_null_coll;
	int				iter, format, local_errno, int_nlen;
	boolean_t			freeze = FALSE, logqualifier, success;
	char				format_buffer[FORMAT_STR_MAX_SIZE],  ch_set_name[MAX_CHSET_NAME], cli_buff[MAX_LINE],
					label_buff[LABEL_STR_MAX_SIZE], gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */
	glist				gl_head, *gl_ptr;
	gd_region			*reg, *region_top;
	mu_extr_stats			global_total, grand_total;
	uint4				item_code, devbufsiz, maxfield;
	unsigned short			label_len, n_len, ch_set_len, buflen;
	unsigned char			*outbuf, *outptr, *chptr, *leadptr;
	struct stat                     statbuf;
	mval				val, curr_gbl_name, op_val, op_pars;
	mstr				chset_mstr;
	gtm_chset_t 			saved_out_set;
	static unsigned char		ochset_set = FALSE;
	static readonly unsigned char	open_params_list[] =
	{
		(unsigned char)iop_noreadonly,
		(unsigned char)iop_nowrap,
		(unsigned char)iop_stream,
		(unsigned char)iop_eol
	};
	static readonly unsigned char no_param = (unsigned char)iop_eol;
	coll_hdr	extr_collhdr;

	error_def(ERR_NOSELECT);
	error_def(ERR_GTMASSERT);
	error_def(ERR_EXTRACTCTRLY);
	error_def(ERR_EXTRACTFILERR);
	error_def(ERR_MUPCLIERR);
	error_def(ERR_MUNOACTION);
	error_def(ERR_MUNOFINISH);
	error_def(ERR_RECORDSTAT);
	error_def(ERR_NULLCOLLDIFF);

        /* Initialize all local character arrays to zero before using */

        memset(cli_buff, 0, sizeof(cli_buff));
        memset(outfilename, 0, sizeof(outfilename));
        memset(label_buff, 0, sizeof(label_buff));
        memset(format_buffer, 0, sizeof(format_buffer));
	active_device = io_curr_device.out;

	mu_outofband_setup();

	if (CLI_PRESENT == cli_present("OCHSET"))
	{
		ch_set_len = sizeof(ch_set_name);
		if (cli_get_str("OCHSET", ch_set_name, &ch_set_len))
		{
			if (0 == ch_set_len)
				mupip_exit(ERR_MUNOACTION);	/* need to change to OPCHSET error when added */
			ch_set_name[ch_set_len] = '\0';
#ifdef KEEP_zOS_EBCDIC
			if ( (iconv_t)0 != active_device->output_conv_cd)
				ICONV_CLOSE_CD(active_device->output_conv_cd);
			if (DEFAULT_CODE_SET != active_device->out_code_set)
				ICONV_OPEN_CD(active_device->output_conv_cd, INSIDE_CH_SET, ch_set_name);
#else
			chset_mstr.addr = ch_set_name;
			chset_mstr.len = ch_set_len;
			SET_ENCODING(active_device->ochset, &chset_mstr);
			get_chset_desc(&chset_names[active_device->ochset]);
#endif
			ochset_set = TRUE;
		}
	}
	logqualifier = (CLI_NEGATED != cli_present("LOG"));
	if (CLI_PRESENT == cli_present("FREEZE"))
		freeze = TRUE;

	n_len = sizeof(format_buffer);
	if (FALSE == cli_get_str("FORMAT", format_buffer, &n_len))
	{
		n_len = sizeof("ZWR") - 1;
		memcpy(format_buffer, "ZWR", n_len);
	}
	int_nlen = n_len;
	lower_to_upper((uchar_ptr_t)format_buffer, (uchar_ptr_t)format_buffer, int_nlen);
	if (0 == memcmp(format_buffer, "ZWR", n_len))
	        format = MU_FMT_ZWR;
	else if (0 == memcmp(format_buffer, "GO", n_len))
	{
		if (gtm_utf8_mode)
		{
			util_out_print("Extract error: GO format is not supported in UTF-8 mode. Use ZWR format.", TRUE);
			mupip_exit(ERR_MUPCLIERR);
		}
	        format = MU_FMT_GO;
	} else if (0 == memcmp(format_buffer, "BINARY", n_len))
		format = MU_FMT_BINARY;
	else
	{
		util_out_print("Extract error: bad format type", TRUE);
		mupip_exit(ERR_MUPCLIERR);
	}
	n_len = sizeof(cli_buff);
	if (FALSE == cli_get_str((char *)select_text, cli_buff, &n_len))
	{
		n_len = 1;
		cli_buff[0] = '*';
	}
	/* gv_select will select globals */
        gv_select(cli_buff, n_len, freeze, (char *)select_text, &gl_head, &reg_max_rec, &reg_max_key, &reg_max_blk);
 	if (!gl_head.next)
        {
                rts_error(VARLSTCNT(1) ERR_NOSELECT);
                mupip_exit(ERR_NOSELECT);
        }
	/* For binary format, check whether all regions have same null collation order */
	if (MU_FMT_BINARY == format)
	{
		for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions, reg_std_null_coll = -1;
			reg < region_top ; reg++)
		{
			if (reg->open)
			{
				if (reg_std_null_coll != reg->std_null_coll)
				{
					if (reg_std_null_coll == -1)
						reg_std_null_coll = reg->std_null_coll;
					else
					{
						rts_error(VARLSTCNT(1) ERR_NULLCOLLDIFF);
						mupip_exit(ERR_NULLCOLLDIFF);
					}
				}
			}
		}
		assert(-1 != reg_std_null_coll);
	}
	grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0;
	global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0;

	n_len = sizeof(outfilename);
	if (FALSE == cli_get_str("FILE", outfilename, &n_len))
	{
		rts_error(VARLSTCNT(1) ERR_MUPCLIERR);
		mupip_exit(ERR_MUPCLIERR);
	}
	if (-1 == Stat((char *)outfilename, &statbuf))
        {
		if (ENOENT != errno)
		{
			local_errno = errno;
			perror("Error opening output file");
			mupip_exit(local_errno);
		}
	}
	else
	{
		util_out_print("Error opening output file: !AD -- File exists", TRUE, n_len, outfilename);
		mupip_exit(ERR_MUNOACTION);
	}
	op_pars.mvtype = MV_STR;
	op_pars.str.len = sizeof(open_params_list);
	op_pars.str.addr = (char *)open_params_list;
	op_val.mvtype = MV_STR;
	op_val.str.len = filename_len = n_len;
	op_val.str.addr = (char *)outfilename;
	(*op_open_ptr)(&op_val, &op_pars, 0, 0);
	ESTABLISH(mu_extract_handler);
	op_use(&op_val, &op_pars);
	if (MU_FMT_BINARY == format)
	{
		/* binary header label format:
		 *	fixed length text, fixed length date & time,
		 *	fixed length max blk size, fixed length max rec size, fixed length max key size, fixed length std_null_coll
		 *	32-byte padded user-supplied string
		 */
		outbuf = (unsigned char *)malloc(sizeof(BIN_HEADER_LABEL) + sizeof(BIN_HEADER_DATEFMT) - 1 +
				4 * BIN_HEADER_NUMSZ + BIN_HEADER_LABELSZ);
		outptr = outbuf;

		MEMCPY_LIT(outptr, BIN_HEADER_LABEL);
		outptr += STR_LIT_LEN(BIN_HEADER_LABEL);

		stringpool.free = stringpool.base;
		op_horolog(&val);
		stringpool.free = stringpool.base;
		op_fnzdate(&val, (mval *)&mu_bin_datefmt, &null_str, &null_str, &val);
		memcpy(outptr, val.str.addr, val.str.len);
		outptr += val.str.len;

		WRITE_NUMERIC(reg_max_blk);
		WRITE_NUMERIC(reg_max_rec);
		WRITE_NUMERIC(reg_max_key);
		WRITE_NUMERIC(reg_std_null_coll);

		if (gtm_utf8_mode)
		{
			MEMCPY_LIT(outptr, UTF8_NAME);
			label_len = STR_LIT_LEN(UTF8_NAME);
			outptr[label_len++] = ' ';
		} else
			label_len = 0;
		buflen = sizeof(label_buff);
		if (FALSE == cli_get_str("LABEL", label_buff, &buflen))
		{
			MEMCPY_LIT(&outptr[label_len], EXTR_DEFAULT_LABEL);
			buflen = STR_LIT_LEN(EXTR_DEFAULT_LABEL);
		} else
			memcpy(&outptr[label_len], label_buff, buflen);
		label_len += buflen;
		if (label_len > BIN_HEADER_LABELSZ)
		{ /* Label size exceeds the space, so truncate the label and back off to
		     the valid beginning (i.e. to the leading byte) of the last character
		     that can entirely fit in the space */
			label_len = BIN_HEADER_LABELSZ;
			chptr = &outptr[BIN_HEADER_LABELSZ];
			UTF8_LEADING_BYTE(chptr, outptr, leadptr);
			assert(chptr - leadptr < 4);
			if (leadptr < chptr)
				label_len -= (chptr - leadptr);
		}
		outptr += label_len;
		for (iter = label_len;  iter < BIN_HEADER_LABELSZ;  iter++)
			*outptr++ = ' ';

		label_len = outptr - outbuf;
		if (!ochset_set)
		{
#ifdef KEEP_zOS_EBCDIC
			/* extract ascii header for binary by default */
			/* Do we need to restore it somewhere? */
			saved_out_set = (io_curr_device.out)->out_code_set;
			(io_curr_device.out)->out_code_set = DEFAULT_CODE_SET;
#else
			saved_out_set = (io_curr_device.out)->ochset;
			(io_curr_device.out)->ochset = CHSET_M;
#endif
		}
		op_val.str.addr = (char *)(&label_len);
		op_val.str.len = sizeof(label_len);
		op_write(&op_val);
		op_val.str.addr = (char *)outbuf;
		op_val.str.len = label_len;
		op_write(&op_val);
	} else
	{
		assert((MU_FMT_GO == format) || (MU_FMT_ZWR == format));
		label_len = sizeof(label_buff);
		if (FALSE == cli_get_str("LABEL", label_buff, &label_len))
		{
			MEMCPY_LIT(label_buff, EXTR_DEFAULT_LABEL);
			label_len = STR_LIT_LEN(EXTR_DEFAULT_LABEL);
		}
		if (gtm_utf8_mode)
		{
			label_buff[label_len++] = ' ';
			MEMCPY_LIT(&label_buff[label_len], UTF8_NAME);
			label_len += STR_LIT_LEN(UTF8_NAME);
		}
		label_buff[label_len++] = '\n';
		op_val.mvtype = MV_STR;
		op_val.str.len = label_len;
		op_val.str.addr = label_buff;
		op_write(&op_val);
		stringpool.free = stringpool.base;
		op_horolog(&val);
		stringpool.free = stringpool.base;
		op_fnzdate(&val, &datefmt, &null_str, &null_str, &val);
		op_val = val;
		op_val.mvtype = MV_STR;
		op_write(&op_val);
		if (MU_FMT_ZWR == format)
		{
			op_val.str.addr = " ZWR";
			op_val.str.len = sizeof(" ZWR") - 1;
			op_write(&op_val);
		}
		op_wteol(1);
	}
	REVERT;

	ESTABLISH(mu_extract_handler1);
	success = TRUE;
	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
	{
		if (mu_ctrly_occurred)
			break;
		if (mu_ctrlc_occurred)
		{
			gbl_name_buff[0]='^';
			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
			gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
			mu_ctrlc_occurred = FALSE;
		}
		gv_bind_name(gd_header, &gl_ptr->name.str);
		if (MU_FMT_BINARY == format)
		{
			label_len = sizeof(extr_collhdr);
			op_val.mvtype = MV_STR;
			op_val.str.addr = (char *)(&label_len);
			op_val.str.len = sizeof(label_len);
			op_write(&op_val);
			extr_collhdr.act = gv_target->act;
			extr_collhdr.nct = gv_target->nct;
			extr_collhdr.ver = gv_target->ver;
			op_val.str.addr = (char *)(&extr_collhdr);
			op_val.str.len = sizeof(extr_collhdr);
			op_write(&op_val);
		}
		/* Note: Do not change the order of the expression below.
		 * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all.
		 * We want mu_extr_gblout() to be called irrespective of the value of success */
		success = mu_extr_gblout(&gl_ptr->name, &global_total, format) && success;
		if (logqualifier)
		{
			gbl_name_buff[0]='^';
			memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len);
			gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff,
				global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen);
			mu_ctrlc_occurred = FALSE;
		}
		grand_total.recknt += global_total.recknt;
		if (grand_total.reclen < global_total.reclen)
			grand_total.reclen = global_total.reclen;
		if (grand_total.keylen < global_total.keylen)
			grand_total.keylen = global_total.keylen;
		if (grand_total.datalen < global_total.datalen)
			grand_total.datalen = global_total.datalen;

	}
	op_val.mvtype = op_pars.mvtype = MV_STR;
	op_val.str.addr = (char *)outfilename;;
	op_val.str.len = filename_len;
	op_pars.str.len = sizeof(no_param);
	op_pars.str.addr = (char *)&no_param;
	op_close(&op_val, &op_pars);
	REVERT;
	if (mu_ctrly_occurred)
	{
		gtm_putmsg(VARLSTCNT(1) ERR_EXTRACTCTRLY);
		mupip_exit(ERR_MUNOFINISH);
	}
	gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT(gt_lit),
		grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen);
	if (MU_FMT_BINARY == format)
	{
		/*      truncate the last newline charactor flushed by op_close */
		STAT_FILE((char *)outfilename, &statbuf, stat_res);
		if (-1 == stat_res)
			rts_error(VARLSTCNT(1) errno);
		TRUNCATE_FILE((const char *)outfilename, statbuf.st_size - 1, truncate_res);
		if (-1 == truncate_res)
			rts_error(VARLSTCNT(1) errno);
	}
	mupip_exit(success ? SS_NORMAL : ERR_MUNOFINISH);
}
Exemple #25
0
char	*jnl2ext(char *jnl_buff, char *ext_buff)
{
    char		*curr, *val_ptr, *ptr, rectype, key_buff[sizeof(gv_key) + MAX_KEY_SZ + 7];
    jnl_record	*rec;
    gv_key		*key;
    jnl_string	*keystr;
    int		val_extr_len, val_len, rec_len;

    rec = (jnl_record *)jnl_buff;
    rectype = rec->prefix.jrec_type;
    rec_len = rec->prefix.forwptr;
    if (rec_len != REC_LEN_FROM_SUFFIX(jnl_buff, rec_len))
    {
        assert(FALSE);
        return ext_buff;
    }
    if (!IS_REPLICATED(rectype))
    {
        assert(FALSE);
        return ext_buff;
    }
    curr = ext_buff;
    if (IS_TUPD(rectype))
    {
        if (FALSE == first_tstart)
        {
            GET_SHORTP(curr, &muext_code[MUEXT_TSTART][0]);
            curr += 2;
            DELIMIT_CURR;
            MEMCPY_LIT(curr, ZERO_TIME_DELIM);
            curr += STR_LIT_LEN(ZERO_TIME_DELIM);
            curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_kill.prefix.tn);
            DELIMIT_CURR;
            MEMCPY_LIT(curr, PIDS_DELIM);
            curr += STR_LIT_LEN(PIDS_DELIM);
            curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_kill.token_seq.jnl_seqno);
            *curr++ = '\n';
            *curr = '\0';
            first_tstart = TRUE;
        }
        num_tstarts++;
    } else if (JRT_TCOM == rectype)
    {
        num_tcommits++;
        if (num_tcommits == num_tstarts)
        {
            num_tcommits = num_tstarts = 0;
            first_tstart = FALSE;
            GET_SHORTP(curr, &muext_code[MUEXT_TCOMMIT][0]);
            curr += 2;
            DELIMIT_CURR;
            MEMCPY_LIT(curr, ZERO_TIME_DELIM);
            curr += STR_LIT_LEN(ZERO_TIME_DELIM);
            curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_tcom.prefix.tn);
            DELIMIT_CURR;
            MEMCPY_LIT(curr, PIDS_DELIM);
            curr += STR_LIT_LEN(PIDS_DELIM);
            curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_tcom.token_seq.jnl_seqno);
            DELIMIT_CURR;
            curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_tcom.participants);
            *curr++ = '\n';
            *curr = '\0';
            return curr;
        }
        return ext_buff;
    }
    if (IS_SET(rectype))
        GET_SHORTP(curr, &muext_code[MUEXT_SET][0]);
    else if (IS_KILL(rectype))
        GET_SHORTP(curr, &muext_code[MUEXT_KILL][0]);
    else if (IS_ZKILL(rectype))
        GET_SHORTP(curr, &muext_code[MUEXT_ZKILL][0]);
    else /* if (JRT_NULL == rectype) */
    {
        assert(JRT_NULL == rectype);
        GET_SHORTP(curr, &muext_code[MUEXT_NULL][0]);
    }
    curr += 2;
    DELIMIT_CURR;
    MEMCPY_LIT(curr, ZERO_TIME_DELIM);
    curr += STR_LIT_LEN(ZERO_TIME_DELIM);
    curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_kill.prefix.tn);
    DELIMIT_CURR;
    MEMCPY_LIT(curr, PIDS_DELIM);
    curr += STR_LIT_LEN(PIDS_DELIM);
    curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_kill.token_seq.jnl_seqno);
    if (rectype == JRT_NULL)
    {
        *curr++ = '\n';
        *curr='\0';
        return curr;
    }
    assert(IS_SET_KILL_ZKILL(rectype));
    DELIMIT_CURR;
    keystr = (jnl_string *)&rec->jrec_kill.mumps_node;
    ptr = (char *)ROUND_UP((uint4)key_buff, 8);
    key = (gv_key *)ptr;
    key->top = MAX_KEY_SZ;
    key->end = keystr->length;
    if (key->end > key->top)
    {
        assert(FALSE);
        return ext_buff;
    }
    memcpy(key->base, &keystr->text[0], keystr->length);
    key->base[key->end] = 0;
    curr = (char *)format_targ_key((uchar_ptr_t)curr, MAX_ZWR_KEY_SZ, key, TRUE);
    if (IS_SET(rectype))
    {
        *curr++ = '=';
        val_ptr = &keystr->text[keystr->length];
        GET_MSTR_LEN(val_len, val_ptr);
        val_ptr += sizeof(mstr_len_t);
        format2zwr((sm_uc_ptr_t)val_ptr, val_len, (uchar_ptr_t)curr, &val_extr_len);
        curr += val_extr_len;
    }
    *curr++ = '\n';
    *curr='\0';
    return curr;
}
Exemple #26
0
void dse_maps(void)
{
	block_id		blk, bml_blk;
	blk_segment		*bs1, *bs_ptr;
	int4			blk_seg_cnt, blk_size;		/* needed for BLK_INIT, BLK_SEG and BLK_FINI macros */
	sm_uc_ptr_t		bp;
	char			util_buff[MAX_UTIL_LEN];
	int4			bml_size, bml_list_size, blk_index, bml_index;
	int4			total_blks, blks_in_bitmap;
	int4			bplmap, dummy_int;
	unsigned char		*bml_list;
	cache_rec_ptr_t		cr, dummy_cr;
	bt_rec_ptr_t		btr;
	int			util_len;
	uchar_ptr_t		blk_ptr;
	boolean_t		was_crit;
	uint4			jnl_status;
	srch_blk_status		blkhist;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;
	sgmnt_addrs		*csa;
	sgmnt_data_ptr_t	csd;

	if (CLI_PRESENT == cli_present("BUSY") || CLI_PRESENT == cli_present("FREE") ||
		CLI_PRESENT == cli_present("MASTER") || CLI_PRESENT == cli_present("RESTORE_ALL"))
	{
	if (gv_cur_region->read_only)
		rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
	}
	CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
	csa = cs_addrs;
	assert(&FILE_INFO(gv_cur_region)->s_addrs == csa);
	was_crit = csa->now_crit;
	if (csa->critical)
		crash_count = csa->critical->crashcnt;
	csd = csa->hdr;
	bplmap = csd->bplmap;
	if (CLI_PRESENT == cli_present("BLOCK"))
	{
		if (!cli_get_hex("BLOCK", (uint4 *)&blk))
			return;
		if (blk < 0 || blk >= csa->ti->total_blks)
		{
			util_out_print("Error: invalid block number.", TRUE);
			return;
		}
		patch_curr_blk = blk;
	}
	else
		blk = patch_curr_blk;
	if (CLI_PRESENT == cli_present("FREE"))
	{
		if (0 == bplmap)
		{
			util_out_print("Cannot perform map updates:  bplmap field of file header is zero.", TRUE);
			return;
		}
		if (blk / bplmap * bplmap == blk)
		{
			util_out_print("Cannot perform action on a map block.", TRUE);
			return;
		}
		bml_blk = blk / bplmap * bplmap;
		bm_setmap(bml_blk, blk, FALSE);
		return;
	}
	if (CLI_PRESENT == cli_present("BUSY"))
	{
		if (0 == bplmap)
		{
			util_out_print("Cannot perform map updates:  bplmap field of file header is zero.", TRUE);
			return;
		}
		if (blk / bplmap * bplmap == blk)
		{
			util_out_print("Cannot perform action on a map block.", TRUE);
			return;
		}
		bml_blk = blk / bplmap * bplmap;
		bm_setmap(bml_blk, blk, TRUE);
		return;
	}
	blk_size = csd->blk_size;
	if (CLI_PRESENT == cli_present("MASTER"))
	{
		if (0 == bplmap)
		{
			util_out_print("Cannot perform maps updates:  bplmap field of file header is zero.", TRUE);
			return;
		}
		if (!was_crit)
			grab_crit(gv_cur_region);
		bml_blk = blk / bplmap * bplmap;
		if (dba_mm == csd->acc_meth)
			bp = MM_BASE_ADDR(csa) + (off_t)bml_blk * blk_size;
		else
		{
			assert(dba_bg == csd->acc_meth);
			if (!(bp = t_qread(bml_blk, &dummy_int, &dummy_cr)))
				rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
		}
		if ((csa->ti->total_blks / bplmap) * bplmap == bml_blk)
			total_blks = (csa->ti->total_blks - bml_blk);
		else
			total_blks = bplmap;
		if (NO_FREE_SPACE == bml_find_free(0, bp + SIZEOF(blk_hdr), total_blks))
			bit_clear(bml_blk / bplmap, csa->bmm);
		else
			bit_set(bml_blk / bplmap, csa->bmm);
		if (bml_blk > csa->nl->highest_lbm_blk_changed)
			csa->nl->highest_lbm_blk_changed = bml_blk;
		if (!was_crit)
			rel_crit(gv_cur_region);
		return;
	}
	if (CLI_PRESENT == cli_present("RESTORE_ALL"))
	{
		if (0 == bplmap)
		{
			util_out_print("Cannot perform maps updates:  bplmap field of file header is zero.", TRUE);
			return;
		}
		total_blks = csa->ti->total_blks;
		assert(ROUND_DOWN2(blk_size, 2 * SIZEOF(int4)) == blk_size);
		bml_size = BM_SIZE(bplmap);
		bml_list_size = (total_blks + bplmap - 1) / bplmap * bml_size;
		bml_list = (unsigned char *)malloc(bml_list_size);
		for (blk_index = 0, bml_index = 0;  blk_index < total_blks; blk_index += bplmap, bml_index++)
			bml_newmap((blk_hdr_ptr_t)(bml_list + bml_index * bml_size), bml_size, csa->ti->curr_tn);
		if (!was_crit)
		{
			grab_crit(gv_cur_region);
			csa->hold_onto_crit = TRUE;	/* need to do this AFTER grab_crit */
		}
		blk = get_dir_root();
		assert(blk < bplmap);
		csa->ti->free_blocks = total_blks - DIVIDE_ROUND_UP(total_blks, bplmap);
		bml_busy(blk, bml_list + SIZEOF(blk_hdr));
		csa->ti->free_blocks =  csa->ti->free_blocks - 1;
		dse_m_rest(blk, bml_list, bml_size, &csa->ti->free_blocks, TRUE);
		for (blk_index = 0, bml_index = 0;  blk_index < total_blks; blk_index += bplmap, bml_index++)
		{
			t_begin_crit(ERR_DSEFAIL);
			CHECK_TN(csa, csd, csd->trans_hist.curr_tn);	/* can issue rts_error TNTOOLARGE */
			CWS_RESET;
			CHECK_AND_RESET_UPDATE_ARRAY;	/* reset update_array_ptr to update_array */
			assert(csa->ti->early_tn == csa->ti->curr_tn);
			blk_ptr = bml_list + bml_index * bml_size;
			blkhist.blk_num = blk_index;
			if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr)))
				rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL);
			BLK_INIT(bs_ptr, bs1);
			BLK_SEG(bs_ptr, blk_ptr + SIZEOF(blk_hdr), bml_size - SIZEOF(blk_hdr));
			BLK_FINI(bs_ptr, bs1);
			t_write(&blkhist, (unsigned char *)bs1, 0, 0, LCL_MAP_LEVL, TRUE, FALSE, GDS_WRITE_KILLTN);
			BUILD_AIMG_IF_JNL_ENABLED(csd, csa->ti->curr_tn);
			t_end(&dummy_hist, NULL, csa->ti->curr_tn);
		}
		/* Fill in master map */
		for (blk_index = 0, bml_index = 0;  blk_index < total_blks; blk_index += bplmap, bml_index++)
		{
			blks_in_bitmap = (blk_index + bplmap <= total_blks) ? bplmap : total_blks - blk_index;
			assert(1 < blks_in_bitmap);	/* the last valid block in the database should never be a bitmap block */
			if (NO_FREE_SPACE != bml_find_free(0, (bml_list + bml_index * bml_size) + SIZEOF(blk_hdr), blks_in_bitmap))
				bit_set(blk_index / bplmap, csa->bmm);
			else
				bit_clear(blk_index / bplmap, csa->bmm);
			if (blk_index > csa->nl->highest_lbm_blk_changed)
				csa->nl->highest_lbm_blk_changed = blk_index;
		}
		if (!was_crit)
		{
			csa->hold_onto_crit = FALSE;	/* need to do this before the rel_crit */
			rel_crit(gv_cur_region);
		}
		if (unhandled_stale_timer_pop)
			process_deferred_stale();
		free(bml_list);
		csd->kill_in_prog = csd->abandoned_kills = 0;
		return;
	}
	MEMCPY_LIT(util_buff, "!/Block ");
	util_len = SIZEOF("!/Block ") - 1;
	util_len += i2hex_nofill(blk, (uchar_ptr_t)&util_buff[util_len], 8);
	memcpy(&util_buff[util_len], " is marked !AD in its local bit map.!/",
		SIZEOF(" is marked !AD in its local bit map.!/") - 1);
	util_len += SIZEOF(" is marked !AD in its local bit map.!/") - 1;
	util_buff[util_len] = 0;
	if (!was_crit)
		grab_crit(gv_cur_region);
	util_out_print(util_buff, TRUE, 4, dse_is_blk_free(blk, &dummy_int, &dummy_cr) ? "free" : "busy");
	if (!was_crit)
		rel_crit(gv_cur_region);
	return;
}