Esempio n. 1
0
/*
 * This function reads command line parameters and forms a configuration for mupip size invocation.
 * It later executes mupip size on each global based on the configuration
 *
 * MUPIP SIZE interface is described in GTM-7292
 */
void mupip_size(void)
{
	boolean_t		restrict_reg = FALSE;
	char 			buff[MAX_LINE], cli_buff[MAX_LINE];
	char 			*p_end;						/* used for strtol validation */
	glist			exclude_gl_head, gl_head, *gl_ptr;
	int4			reg_max_rec, reg_max_key, reg_max_blk;
	mupip_size_cfg_t	mupip_size_cfg = { impsample, 1000, 1, 0 };	/* configuration default values */
	uint4			status = EXIT_NRM;
	unsigned short		BUFF_LEN = SIZEOF(buff), n_len;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	mu_outofband_setup();
	error_mupip = FALSE;
	memset(mu_int_adj, 0, ARRAYSIZE(mu_int_adj));
	memset(mu_int_adj_prev, 0, ARRAYSIZE(mu_int_adj_prev));
	/* Region qualifier */
	grlist = NULL;
	if (CLI_PRESENT == cli_present("REGION"))
	{
		restrict_reg = TRUE;
		gvinit();							/* init gd_header (needed to call mu_getlst) */
		mu_getlst("REGION", SIZEOF(tp_region));
	}
	mupip_size_check_error();
	/* SELECT qualifier */
	memset(cli_buff, 0, SIZEOF(cli_buff));
	n_len = SIZEOF(cli_buff);
	if (CLI_PRESENT != cli_present("SELECT"))
	{
		n_len = 1;
		cli_buff[0] = '*';
	}
	else if (FALSE == cli_get_str("SELECT", cli_buff, &n_len))
	{
		n_len = 1;
		cli_buff[0] = '*';
	}
	/* gv_select will select globals for this clause*/
	gv_select(cli_buff, n_len, FALSE, "SELECT", &gl_head, &reg_max_rec, &reg_max_key, &reg_max_blk, restrict_reg);
	if (!gl_head.next)
	{
		error_mupip = TRUE;
		gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSELECT);
	}
	mupip_size_check_error();
	if (CLI_PRESENT == cli_present("ADJACENCY"))
	{
		assert(SIZEOF(muint_adj) == SIZEOF(int4));
		if (0 == cli_get_int("ADJACENCY", (int4 *)&muint_adj))
		{
			error_mupip = TRUE;
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_MUPCLIERR);
		}
	} else
		muint_adj = DEFAULT_ADJACENCY;
	/* HEURISTIC qualifier */
	if (cli_present("HEURISTIC.SCAN") == CLI_PRESENT)
	{
		mupip_size_cfg.heuristic = scan;
		if (cli_present("HEURISTIC.LEVEL"))
		{
			boolean_t valid = TRUE;
			if (cli_get_str("HEURISTIC.LEVEL", buff, &BUFF_LEN))
			{
				mupip_size_cfg.level = strtol(buff, &p_end, 10);
				valid = (*p_end == '\0');
			}
			else
				valid = FALSE;
			if (!valid || mupip_size_cfg.level <= -MAX_BT_DEPTH || MAX_BT_DEPTH <= mupip_size_cfg.level)
			{
				error_mupip = TRUE;
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.LEVEL"));
			}
		}
		/* else level is already initialized with default value */
	} else if (cli_present("HEURISTIC.ARSAMPLE") == CLI_PRESENT || cli_present("HEURISTIC.IMPSAMPLE") == CLI_PRESENT)
	{
		if (cli_present("HEURISTIC.ARSAMPLE") == CLI_PRESENT)
			mupip_size_cfg.heuristic = arsample;
		else if (cli_present("HEURISTIC.IMPSAMPLE") == CLI_PRESENT)
			mupip_size_cfg.heuristic = impsample;
		if (cli_present("HEURISTIC.SAMPLES"))
		{
			boolean_t valid = cli_get_int("HEURISTIC.SAMPLES", &(mupip_size_cfg.samples));
			if (!valid || mupip_size_cfg.samples <= 0){
				error_mupip = TRUE;
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SAMPLES"));
			}
		}
		/* else samples is already initialized with default value */
		/* undocumented SEED parameter used for testing sampling method */
		if (cli_present("HEURISTIC.SEED"))
		{
			boolean_t valid = cli_get_int("HEURISTIC.SEED", &(mupip_size_cfg.seed));
			if (!valid){
				error_mupip = TRUE;
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_MUSIZEINVARG, 2, LEN_AND_LIT("HEURISTIC.SEED"));
			}
		}
		/* else seed will be based on the time */
	}
	mupip_size_check_error();
	/* run mupip size on each global */
	for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next)
	{
		util_out_print("!/Global: !AD (region !AD)", FLUSH,
			GNAME(gl_ptr).len, GNAME(gl_ptr).addr, REG_LEN_STR(gl_ptr->reg));
		switch (mupip_size_cfg.heuristic)
		{
		case scan:
			status |= mu_size_scan(gl_ptr, mupip_size_cfg.level);
			break;
		case arsample:
			status |= mu_size_arsample(gl_ptr, mupip_size_cfg.samples, mupip_size_cfg.seed);
			break;
		case impsample:
			status |= mu_size_impsample(gl_ptr, mupip_size_cfg.samples, mupip_size_cfg.seed);
			break;
		default:
			assertpro(FALSE && mupip_size_cfg.heuristic);
			break;
		}
		if (mu_ctrlc_occurred || mu_ctrly_occurred)
			mupip_exit(ERR_MUNOFINISH);
	}
	mupip_exit(status ==  EXIT_NRM ? SS_NORMAL : ERR_MUNOFINISH);
}
Esempio n. 2
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);
}