Пример #1
0
/*
 * --------------------------------------------------
 * See if the qualifier given by 'entry' is negated
 * on the command line
 *
 * Return:
 *	TRUE	- Negated
 *	FALSE	- otherwise
 * --------------------------------------------------
 */
boolean_t cli_negated(char *entry) 		/* entity */
{
	CLI_ENTRY	*pparm;
	char		local_str[MAX_LINE];

	strncpy(local_str, entry, SIZEOF(local_str) - 1);
	cli_strupper(local_str);
	if (pparm = get_parm_entry(local_str))
		return (pparm->negated);
	return (FALSE);
}
Пример #2
0
/*
 * ---------------------------------------------------------
 * Find entry in the qualifier table
 *
 * Arguments:
 *	str	- parameter string
 *	pparm	- pointer to parameter table for this command
 *
 * Return:
 *	if found, index into command table array,
 *	else -1
 * ---------------------------------------------------------
 */
int 	find_entry(char *str, CLI_ENTRY *pparm)
{
	int 		match_ind, res, str_len;
	boolean_t 	len_match;
	int 		ind;
	char 		*sp;

	ind = 0;
	match_ind = -1;
	len_match = FALSE;
	cli_strupper(str);

	str_len = strlen(str);
	while (0 < strlen(sp = (pparm + ind)->name))
	{
		/* As the table is parsed as long as the string in question is lexically smaller
		   than the entry in the table, we go on checking the next entry.
		   If a match is found, the lengths of the two strings (the table entry and the
		   string in question) are compared.
		   When the next entry is checked,
		   if it is not a match, the previous entry is the correct match;
		   if it is a match again (a longer entry), if the first match was a length-match
		   as well, the first entry is the match returned. otherwise an error is returned
		   since we cannot make a decision (does SE match SET or SEP). */

		if (0 == (res = STRNCMP_STR(sp, str, str_len)))
		{
			if (-1 != match_ind)
			{
				if (FALSE == len_match)
					return (-1);
				break;
			} else
			{
				if (str_len == strlen(sp))
					len_match = TRUE;
				match_ind = ind;
			}
		} else
		{
			if (0 < res)
				break;
		}
		ind++;
	}
	if (-1 != match_ind && gpqual_root && 0 == STRNCMP_STR(gpqual_root->name, str, MAX_OPT_LEN))
		return (-1);
	return (match_ind);
}
Пример #3
0
/*
 * ------------------------------------------------------------
 * Get the command parameter value
 *
 * Arguments:
 *	entry		- parameter string to search for
 *	val_buf		- if parameter is present, it is copied to
 *			  this buffer.
 *
 * Return:
 *	0 - not present
 *	<> 0 - ok
 * ------------------------------------------------------------
 */
bool cli_get_value(char *entry, char val_buf[])
{
	CLI_ENTRY	*pparm;
	char		local_str[MAX_LINE];

	strncpy(local_str, entry, SIZEOF(local_str) - 1);
	cli_strupper(local_str);
	if (NULL == (pparm = get_parm_entry(local_str)))
		return (FALSE);
	if (!pparm->present || NULL == pparm->pval_str)
		return (FALSE);
	else
		strcpy(val_buf, pparm->pval_str);
	return (TRUE);
}
Пример #4
0
/*
 * ------------------------------------------------------------
 * See if command parameter is present on the command line
 *
 * Arguments:
 *	entry	- parameter string to search for
 *
 * Return:
 *	0 - not present (i.e. CLI_ABSENT)
 *	<> 0 - present  (either CLI_PRESENT or CLI_NEGATED)
 * ------------------------------------------------------------
 */
int cli_present(char *entry)
{
	CLI_ENTRY	*pparm;
	char		local_str[MAX_LINE];

	strncpy(local_str, entry, SIZEOF(local_str) - 1);

	cli_strupper(local_str);
	if (pparm = get_parm_entry(local_str))
	{
		if (pparm->negated)
			return (CLI_NEGATED);
		if ((CLI_PRESENT == pparm->present) || (CLI_DEFAULT == pparm->present))
			return (CLI_PRESENT);
	}

	return (CLI_ABSENT);
}
Пример #5
0
int gtmrecv_get_opt(void)
{
	boolean_t	autorollback, cmplvl_status, filter, log, log_interval_specified, plaintext_fallback;
	char		statslog_val[4]; /* "ON" or "OFF" */
	gtm_int64_t	buffsize;
	int		status;
	uint4		n_readers, n_helpers;
	unsigned short 	filter_cmd_len, instfilename_len, instname_len, log_file_len, statslog_val_len, tlsid_len;

	gtmrecv_options.start = (CLI_PRESENT == cli_present("START"));
	gtmrecv_options.shut_down = (CLI_PRESENT == cli_present("SHUTDOWN"));
	gtmrecv_options.checkhealth = (CLI_PRESENT == cli_present("CHECKHEALTH"));
	gtmrecv_options.statslog = (CLI_PRESENT == cli_present("STATSLOG"));
	gtmrecv_options.showbacklog = (CLI_PRESENT == cli_present("SHOWBACKLOG"));
	gtmrecv_options.changelog = (CLI_PRESENT == cli_present("CHANGELOG"));
	gtmrecv_options.updateonly = (CLI_PRESENT == cli_present("UPDATEONLY"));
	gtmrecv_options.updateresync = (CLI_PRESENT == cli_present("UPDATERESYNC"));
	gtmrecv_options.reuse_specified = (CLI_PRESENT == cli_present("REUSE"));
	gtmrecv_options.resume_specified = (CLI_PRESENT == cli_present("RESUME"));
	gtmrecv_options.initialize_specified = (CLI_PRESENT == cli_present("INITIALIZE"));
	if (gtmrecv_options.updateresync)
	{
		instfilename_len = SIZEOF(gtmrecv_options.updresync_instfilename) - 1;	/* keep 1 byte for trailing NULL */
		/* Treat -UPDATERESYNC (with no value) as if -UPDATERESYNC="" was specified */
		if (!cli_get_str("UPDATERESYNC", gtmrecv_options.updresync_instfilename, &instfilename_len))
		{
			instfilename_len = 0;
			if (gtmrecv_options.reuse_specified)
			{
				util_out_print("Error: REUSE qualifier not allowed if UPDATERESYNC qualifier has no value", TRUE);
				return (-1);
			}
		} else if (gtmrecv_options.reuse_specified)
		{
			instname_len = SIZEOF(gtmrecv_options.reuse_instname) - 1;	/* keep 1 byte for trailing NULL */
			if (!cli_get_str("REUSE", gtmrecv_options.reuse_instname, &instname_len))
			{
				util_out_print("Error parsing REUSE qualifier", TRUE);
				return (-1);
			} else
			{
				assert(SIZEOF(gtmrecv_options.reuse_instname) > instname_len);
				gtmrecv_options.reuse_instname[instname_len] = '\0';
			}
		}
		assert(SIZEOF(gtmrecv_options.updresync_instfilename) > instfilename_len);
		gtmrecv_options.updresync_instfilename[instfilename_len] = '\0';
		if (gtmrecv_options.resume_specified)
		{
			if (!cli_get_int("RESUME", &gtmrecv_options.resume_strm_num))
			{
				util_out_print("Error parsing RESUME qualifier", TRUE);
				return (-1);
			}
			if ((0 >= gtmrecv_options.resume_strm_num) || (MAX_SUPPL_STRMS <= gtmrecv_options.resume_strm_num))
			{
				util_out_print("RESUME qualifier should specify a stream number between 1 and 15 (both inclusive)",
					TRUE);
				return (-1);
			}
		}
	}
	gtmrecv_options.noresync = (CLI_PRESENT == cli_present("NORESYNC"));
	gtmrecv_options.helpers = (CLI_PRESENT == cli_present("HELPERS"));
	gtmrecv_options.listen_port = 0; /* invalid port; indicates listenport not specified */
	if (gtmrecv_options.start && CLI_PRESENT == cli_present("LISTENPORT"))
	{
		if (!cli_get_int("LISTENPORT", &gtmrecv_options.listen_port))
		{
			util_out_print("Error parsing LISTENPORT qualifier", TRUE);
			return (-1);
		}
		if (CLI_PRESENT == cli_present("BUFFSIZE"))
		{		/* use a big conversion so we have a signed number for comparison */
			if (!cli_get_int64("BUFFSIZE", &buffsize))
			{
				util_out_print("Error parsing BUFFSIZE qualifier", TRUE);
				return(-1);
			}
			if (MIN_RECVPOOL_SIZE > buffsize)
				gtmrecv_options.buffsize = MIN_RECVPOOL_SIZE;
			else if ((gtm_int64_t)MAX_RECVPOOL_SIZE < buffsize)
				gtmrecv_options.buffsize = (uint4)MAX_RECVPOOL_SIZE;
			else
				gtmrecv_options.buffsize = (uint4)buffsize;
		} else
			gtmrecv_options.buffsize = DEFAULT_RECVPOOL_SIZE;
		/* Check if -autorollback is specified (default is -noautorollback) */
		autorollback = cli_present("AUTOROLLBACK");
		gtmrecv_options.autorollback = autorollback ? (CLI_NEGATED != autorollback) : FALSE;
		if (gtmrecv_options.autorollback)
			gtmrecv_options.autorollback_verbose = cli_present("AUTOROLLBACK.VERBOSE");
		/* Check if compression level is specified */
		if (cmplvl_status = (CLI_PRESENT == cli_present("CMPLVL")))
		{
			if (!cli_get_int("CMPLVL", &gtmrecv_options.cmplvl))
			{
				util_out_print("Error parsing CMPLVL qualifier", TRUE);
				return(-1);
			}
			if (GTM_CMPLVL_OUT_OF_RANGE(gtmrecv_options.cmplvl))
				gtmrecv_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
			/* CMPLVL qualifier should override any value specified in the environment variable gtm_zlib_cmp_level */
			gtm_zlib_cmp_level = gtmrecv_options.cmplvl;
		} else
			gtmrecv_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
		if (filter = (CLI_PRESENT == cli_present("FILTER")))
		{
			filter_cmd_len = MAX_FILTER_CMD_LEN;
	    		if (!cli_get_str("FILTER", gtmrecv_options.filter_cmd, &filter_cmd_len))
			{
				util_out_print("Error parsing FILTER qualifier", TRUE);
				return (-1);
			}
		} else
			gtmrecv_options.filter_cmd[0] = '\0';

		gtmrecv_options.stopsourcefilter = (CLI_PRESENT == cli_present("STOPSOURCEFILTER"));
		/* Check if SSL/TLS secure communication is requested. */
#		ifdef GTM_TLS
		if (CLI_PRESENT == cli_present("TLSID"))
		{
			tlsid_len = MAX_TLSID_LEN;
			if (!cli_get_str("TLSID", repl_tls.id, &tlsid_len))
			{
				util_out_print("Error parsing TLSID qualifier", TRUE);
				return -1;
			}
			assert(0 < tlsid_len);
			/* Check if plaintext-fallback mode is specified. Default option is NOPLAINTEXTFALLBACK. */
			if (CLI_PRESENT == (plaintext_fallback = cli_present("PLAINTEXTFALLBACK")))
				repl_tls.plaintext_fallback = (plaintext_fallback != CLI_NEGATED);
			else
				repl_tls.plaintext_fallback = FALSE;
		}
#		endif
	}
	if ((gtmrecv_options.start && 0 != gtmrecv_options.listen_port) || gtmrecv_options.statslog || gtmrecv_options.changelog)
	{
		log = (CLI_PRESENT == cli_present("LOG"));
		log_interval_specified = (CLI_PRESENT == cli_present("LOG_INTERVAL"));
		if (log)
		{
			log_file_len = MAX_FN_LEN + 1;
			if (!cli_get_str("LOG", gtmrecv_options.log_file, &log_file_len))
			{
				util_out_print("Error parsing LOG qualifier", TRUE);
				return (-1);
			}
		} else
			gtmrecv_options.log_file[0] = '\0';
		gtmrecv_options.rcvr_log_interval = gtmrecv_options.upd_log_interval = 0;
		if (log_interval_specified
		    && 0 == cli_parse_two_numbers("LOG_INTERVAL", GTMRECV_LOGINTERVAL_DELIM, &gtmrecv_options.rcvr_log_interval,
							&gtmrecv_options.upd_log_interval))
			return (-1);
		if (gtmrecv_options.start)
		{
			if (0 == gtmrecv_options.rcvr_log_interval)
				gtmrecv_options.rcvr_log_interval = LOGTRNUM_INTERVAL;
			if (0 == gtmrecv_options.upd_log_interval)
				gtmrecv_options.upd_log_interval = LOGTRNUM_INTERVAL;
		} /* For changelog, interval == 0 implies don't change log interval already established */
		  /* We ignore interval specification for statslog, Vinaya 2005/02/07 */
	}
	if (gtmrecv_options.shut_down)
	{
		if (CLI_PRESENT == (status = cli_present("TIMEOUT")))
		{
			if (!cli_get_int("TIMEOUT", &gtmrecv_options.shutdown_time))
			{
				util_out_print("Error parsing TIMEOUT qualifier", TRUE);
				return (-1);
			}
			if (DEFAULT_SHUTDOWN_TIMEOUT < gtmrecv_options.shutdown_time || 0 > gtmrecv_options.shutdown_time)
			{
				gtmrecv_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
				util_out_print("shutdown TIMEOUT changed to !UL", TRUE, gtmrecv_options.shutdown_time);
			}
		} else if (CLI_NEGATED == status)
			gtmrecv_options.shutdown_time = -1;
		else /* TIMEOUT not specified */
			gtmrecv_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
	}
	if (gtmrecv_options.statslog)
	{
		statslog_val_len = 4; /* max(strlen("ON"), strlen("OFF")) + 1 */
		if (!cli_get_str("STATSLOG", statslog_val, &statslog_val_len))
		{
			util_out_print("Error parsing STATSLOG qualifier", TRUE);
			return (-1);
		}
		cli_strupper(statslog_val);
		if (0 == STRCMP(statslog_val, "ON"))
			gtmrecv_options.statslog = TRUE;
		else if (0 == STRCMP(statslog_val, "OFF"))
			gtmrecv_options.statslog = FALSE;
		else
		{
			util_out_print("Invalid value for STATSLOG qualifier, should be either ON or OFF", TRUE);
			return (-1);
		}
	}
	gtmrecv_options.n_readers = gtmrecv_options.n_writers = 0;
	if (gtmrecv_options.helpers && gtmrecv_options.start)
	{ /* parse the helpers qualifier to find out how many readers and writes have to be started */
		if (0 == (status = cli_parse_two_numbers("HELPERS", UPD_HELPERS_DELIM, &n_helpers, &n_readers)))
			return (-1);
		if (!(status & CLI_2NUM_FIRST_SPECIFIED))
			n_helpers = DEFAULT_UPD_HELPERS;
		if (MIN_UPD_HELPERS > n_helpers || MAX_UPD_HELPERS < n_helpers)
		{
			util_out_print("Invalid number of helpers; must be in the range [!UL,!UL]", TRUE, MIN_UPD_HELPERS,
					MAX_UPD_HELPERS);
			return (-1);
		}
		if (!(status & CLI_2NUM_SECOND_SPECIFIED))
			n_readers = (int)(n_helpers * ((float)DEFAULT_UPD_HELP_READERS)/DEFAULT_UPD_HELPERS); /* may round down */
		if (n_readers > n_helpers)
		{
			n_readers = n_helpers;
			util_out_print("Number of readers exceeds number of helpers, reducing number of readers to number of "
					"helpers", TRUE);
		}
		gtmrecv_options.n_readers = n_readers;
		gtmrecv_options.n_writers = n_helpers - n_readers;
	}
	return (0);
}
int gtmsource_get_opt(void)
{
	char		*connect_parm_token_str, *connect_parm;
	char		*connect_parms_str, tmp_connect_parms_str[GTMSOURCE_CONN_PARMS_LEN + 1];
	char		secondary_sys[MAX_SECONDARY_LEN], *c, inst_name[MAX_FN_LEN + 1];
	char		statslog_val[SIZEOF("OFF")]; /* "ON" or "OFF" */
	char		update_val[SIZEOF("DISABLE")]; /* "ENABLE" or "DISABLE" */
	char		freeze_val[SIZEOF("OFF")]; /* "ON" or "OFF" */
	char		freeze_comment[SIZEOF(gtmsource_options.freeze_comment)];
	int		tries, index = 0, timeout_status, connect_parms_index, status, renegotiate_interval;
	struct hostent	*sec_hostentry;
	unsigned short	log_file_len, filter_cmd_len;
	unsigned short	secondary_len, inst_name_len, statslog_val_len, update_val_len, connect_parms_str_len;
	unsigned short	freeze_val_len, freeze_comment_len, tlsid_len;
	int		errcode;
	int		port_len;
	char		*ip_end;
	mstr		log_nam, trans_name;
	boolean_t	secondary, dotted_notation, log, log_interval_specified, connect_parms_badval, plaintext_fallback;

	memset((char *)&gtmsource_options, 0, SIZEOF(gtmsource_options));
	gtmsource_options.start = (CLI_PRESENT == cli_present("START"));
	gtmsource_options.shut_down = (CLI_PRESENT == cli_present("SHUTDOWN"));
	gtmsource_options.activate = (CLI_PRESENT == cli_present("ACTIVATE"));
	gtmsource_options.deactivate = (CLI_PRESENT == cli_present("DEACTIVATE"));
	gtmsource_options.checkhealth = (CLI_PRESENT == cli_present("CHECKHEALTH"));
	gtmsource_options.statslog = (CLI_PRESENT == cli_present("STATSLOG"));
	gtmsource_options.showbacklog = (CLI_PRESENT == cli_present("SHOWBACKLOG"));
	gtmsource_options.changelog = (CLI_PRESENT == cli_present("CHANGELOG"));
	gtmsource_options.stopsourcefilter = (CLI_PRESENT == cli_present("STOPSOURCEFILTER"));
	gtmsource_options.needrestart = (CLI_PRESENT == cli_present("NEEDRESTART"));
	gtmsource_options.losttncomplete = (CLI_PRESENT == cli_present("LOSTTNCOMPLETE"));
	gtmsource_options.jnlpool = (CLI_PRESENT == cli_present("JNLPOOL"));
	secondary = (CLI_PRESENT == cli_present("SECONDARY"));
	gtmsource_options.rootprimary = ROOTPRIMARY_UNSPECIFIED; /* to indicate unspecified state */
	if ((CLI_PRESENT == cli_present("ROOTPRIMARY")) || (CLI_PRESENT == cli_present("UPDOK")))
		gtmsource_options.rootprimary = ROOTPRIMARY_SPECIFIED;
	else if ((CLI_PRESENT == cli_present("PROPAGATEPRIMARY")) || (CLI_PRESENT == cli_present("UPDNOTOK")))
		gtmsource_options.rootprimary = PROPAGATEPRIMARY_SPECIFIED;
	else
	{	/* Neither ROOTPRIMARY (or UPDOK) nor PROPAGATEPRIMARY (or UPDNOTOK) specified. Assume default values.
		 * Assume ROOTPRIMARY for -START -SECONDARY (active source server start) and -ACTIVATE commands.
		 * Assume PROPAGATEPRIMARY for -START -PASSIVE (passive source server start) and -DEACTIVATE commands.
		 */
		if ((gtmsource_options.start && secondary) || gtmsource_options.activate)
			gtmsource_options.rootprimary = ROOTPRIMARY_SPECIFIED;
		if ((gtmsource_options.start && !secondary) || gtmsource_options.deactivate)
			gtmsource_options.rootprimary = PROPAGATEPRIMARY_SPECIFIED;
	}
	gtmsource_options.instsecondary = (CLI_PRESENT == cli_present("INSTSECONDARY"));
	if (gtmsource_options.instsecondary)
	{	/* -INSTSECONDARY is specified in the command line. */
		inst_name_len = SIZEOF(inst_name);;
		if (!cli_get_str("INSTSECONDARY", &inst_name[0], &inst_name_len))
		{
			util_out_print("Error parsing INSTSECONDARY qualifier", TRUE);
			return(-1);
		}
	} else
	{	/* Check if environment variable "gtm_repl_instsecondary" is defined.
		 * Do that only if any of the following qualifiers is present as these are the only ones that honour it.
		 * 	Mandatory : START, ACTIVATE, DEACTIVATE, STOPSOURCEFILTER, CHANGELOG, STATSLOG, NEEDRESTART,
		 *	Optional  : CHECKHEALTH, SHOWBACKLOG or SHUTDOWN
		 */
		if (gtmsource_options.start || gtmsource_options.activate || gtmsource_options.deactivate
			|| gtmsource_options.stopsourcefilter || gtmsource_options.changelog
			|| gtmsource_options.statslog || gtmsource_options.needrestart
			|| gtmsource_options.checkhealth || gtmsource_options.showbacklog || gtmsource_options.shut_down)
		{
			log_nam.addr = GTM_REPL_INSTSECONDARY;
			log_nam.len = SIZEOF(GTM_REPL_INSTSECONDARY) - 1;
			trans_name.addr = &inst_name[0];
			if (SS_NORMAL == (status = TRANS_LOG_NAME(&log_nam, &trans_name, inst_name, SIZEOF(inst_name),
									do_sendmsg_on_log2long)))
			{
				gtmsource_options.instsecondary = TRUE;
				inst_name_len = trans_name.len;
			} else if (!gtmsource_options.checkhealth && !gtmsource_options.showbacklog && !gtmsource_options.shut_down)
			{
				if (SS_LOG2LONG == status)
					gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, log_nam.len, log_nam.addr,
						SIZEOF(inst_name) - 1);
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_REPLINSTSECUNDF);
				return (-1);
			}
		}
	}
	if (gtmsource_options.instsecondary)
	{	/* Secondary instance name specified either through -INSTSECONDARY or "gtm_repl_instsecondary" */
		inst_name[inst_name_len] = '\0';
		if ((MAX_INSTNAME_LEN <= inst_name_len) || (0 == inst_name_len))
		{
			gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_REPLINSTSECLEN, 2, inst_name_len, inst_name);
			return (-1);
		}
		assert((inst_name_len + 1) <= MAX_INSTNAME_LEN);
		memcpy(gtmsource_options.secondary_instname, inst_name, inst_name_len + 1);	/* copy terminating '\0' as well */
	}
	if (gtmsource_options.start || gtmsource_options.activate)
	{
		if (secondary)
		{
			secondary_len = MAX_SECONDARY_LEN;
			if (!cli_get_str("SECONDARY", secondary_sys, &secondary_len))
			{
				util_out_print("Error parsing SECONDARY qualifier", TRUE);
				return(-1);
			}
			/* Parse secondary_sys into secondary_host
			 * and secondary_port */
			c = secondary_sys;
			dotted_notation = TRUE;
			if ('[' == *c)
			{
				ip_end = strchr(++c, ']');
				if (NULL == ip_end || 0 == (index = ip_end - c))
				{
					util_out_print("Invalid IP address !AD", TRUE,
						LEN_AND_STR(secondary_sys));
					return(-1);
				}
				memcpy(gtmsource_options.secondary_host, c, index);
				gtmsource_options.secondary_host[index] = '\0';
				c = ip_end + 1;
			} else
			{
				while(*c && (':' != *c))
					gtmsource_options.secondary_host[index++] = *c++;
				gtmsource_options.secondary_host[index] = '\0';
			}
			if (':' != *c)
			{
				util_out_print("Secondary port number should be specified", TRUE);
				return(-1);
			}
			port_len = strlen(++c);
			errno = 0;
			if (((0 == (gtmsource_options.secondary_port = ATOI(c))) && (0 != errno))
				|| (0 >= gtmsource_options.secondary_port))
			{
				util_out_print("Error parsing secondary port number !AD", TRUE, LEN_AND_STR(c));
				return(-1);
			}
		}
		if (CLI_PRESENT == cli_present("CONNECTPARAMS"))
		{
			connect_parms_str_len = GTMSOURCE_CONN_PARMS_LEN + 1;
			if (!cli_get_str("CONNECTPARAMS", tmp_connect_parms_str, &connect_parms_str_len))
			{
				util_out_print("Error parsing CONNECTPARAMS qualifier", TRUE);
				return(-1);
			}
#ifdef VMS
			/* strip the quotes around the string. (DCL doesn't do it) */
			assert('"' == tmp_connect_parms_str[0]);
			assert('"' == tmp_connect_parms_str[connect_parms_str_len - 1]);
			connect_parms_str = &tmp_connect_parms_str[1];
			tmp_connect_parms_str[connect_parms_str_len - 1] = '\0';
#else
			connect_parms_str = &tmp_connect_parms_str[0];
#endif
			for (connect_parms_index =
					GTMSOURCE_CONN_HARD_TRIES_COUNT,
			     connect_parms_badval = FALSE,
			     connect_parm_token_str = connect_parms_str;
			     !connect_parms_badval &&
			     connect_parms_index < GTMSOURCE_CONN_PARMS_COUNT &&
			     (connect_parm = strtok(connect_parm_token_str,
						    GTMSOURCE_CONN_PARMS_DELIM))
			     		   != NULL;
			     connect_parms_index++,
			     connect_parm_token_str = NULL)

			{
				errno = 0;
				if ((0 == (gtmsource_options.connect_parms[connect_parms_index] = ATOI(connect_parm))
						&& 0 != errno) || 0 >= gtmsource_options.connect_parms[connect_parms_index])
					connect_parms_badval = TRUE;
			}
			if (connect_parms_badval)
			{
				util_out_print("Error parsing or invalid value parameter in CONNECTPARAMS", TRUE);
				return(-1);
			}
			if (GTMSOURCE_CONN_PARMS_COUNT != connect_parms_index)
			{
				util_out_print(
					"All CONNECTPARAMS - HARD TRIES, HARD TRIES PERIOD, "
					"SOFT TRIES PERIOD, "
					"ALERT TIME, HEARTBEAT INTERVAL, "
					"MAX HEARBEAT WAIT should be specified", TRUE);
				return(-1);
			}
		} else
		{
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT] = REPL_CONN_HARD_TRIES_COUNT;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD] = REPL_CONN_HARD_TRIES_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD] = REPL_CONN_SOFT_TRIES_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD] = REPL_CONN_ALERT_ALERT_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD] = REPL_CONN_HEARTBEAT_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] = REPL_CONN_HEARTBEAT_MAX_WAIT;
		}
		if (gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]<
				gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD])
			gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD] =
				gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD];
		if (gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] <
				gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD])
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] =
				gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD];
	}
	if (gtmsource_options.start || gtmsource_options.statslog || gtmsource_options.changelog || gtmsource_options.activate)
	{
		log = (cli_present("LOG") == CLI_PRESENT);
		log_interval_specified = (CLI_PRESENT == cli_present("LOG_INTERVAL"));
		if (log)
		{
			log_file_len = MAX_FN_LEN + 1;
			if (!cli_get_str("LOG", gtmsource_options.log_file, &log_file_len))
			{
				util_out_print("Error parsing LOG qualifier", TRUE);
				return(-1);
			}
		} else
			gtmsource_options.log_file[0] = '\0';
		gtmsource_options.src_log_interval = 0;
		if (log_interval_specified)
		{
			if (!cli_get_num("LOG_INTERVAL", (int4 *)&gtmsource_options.src_log_interval))
			{
				util_out_print("Error parsing LOG_INTERVAL qualifier", TRUE);
				return (-1);
			}
		}
		if (gtmsource_options.start && 0 == gtmsource_options.src_log_interval)
			gtmsource_options.src_log_interval = LOGTRNUM_INTERVAL;
		/* For changelog/activate, interval == 0 implies don't change log interval already established */
		/* We ignore interval specification for statslog, Vinaya 2005/02/07 */
	}
	if (gtmsource_options.start)
	{
		assert(secondary || CLI_PRESENT == cli_present("PASSIVE"));
		gtmsource_options.mode = ((secondary) ? GTMSOURCE_MODE_ACTIVE : GTMSOURCE_MODE_PASSIVE);
		if (CLI_PRESENT == cli_present("BUFFSIZE"))
		{
			if (!cli_get_int("BUFFSIZE", &gtmsource_options.buffsize))
			{
				util_out_print("Error parsing BUFFSIZE qualifier", TRUE);
				return(-1);
			}
			if (MIN_JNLPOOL_SIZE > gtmsource_options.buffsize)
				gtmsource_options.buffsize = MIN_JNLPOOL_SIZE;
		} else
			gtmsource_options.buffsize = DEFAULT_JNLPOOL_SIZE;
		/* Round up buffsize to the nearest (~JNL_WRT_END_MASK + 1) multiple */
		gtmsource_options.buffsize = ((gtmsource_options.buffsize + ~JNL_WRT_END_MASK) & JNL_WRT_END_MASK);
		if (CLI_PRESENT == cli_present("FILTER"))
		{
			filter_cmd_len = MAX_FILTER_CMD_LEN;
	    		if (!cli_get_str("FILTER", gtmsource_options.filter_cmd, &filter_cmd_len))
			{
				util_out_print("Error parsing FILTER qualifier", TRUE);
				return(-1);
			}
		} else
			gtmsource_options.filter_cmd[0] = '\0';
		/* Check if compression level is specified */
		if (CLI_PRESENT == cli_present("CMPLVL"))
		{
			if (!cli_get_int("CMPLVL", &gtmsource_options.cmplvl))
			{
				util_out_print("Error parsing CMPLVL qualifier", TRUE);
				return(-1);
			}
			if (GTM_CMPLVL_OUT_OF_RANGE(gtmsource_options.cmplvl))
				gtmsource_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
			/* CMPLVL qualifier should override any value specified in the environment variable gtm_zlib_cmp_level */
			gtm_zlib_cmp_level = gtmsource_options.cmplvl;
		} else
			gtmsource_options.cmplvl = ZLIB_CMPLVL_MIN;	/* no compression in this case */
		/* Check if SSL/TLS secure communication is requested. */
#		ifdef GTM_TLS
		if (CLI_PRESENT == cli_present("TLSID"))
		{
			tlsid_len = MAX_TLSID_LEN;
			if (!cli_get_str("TLSID", repl_tls.id, &tlsid_len))
			{
				util_out_print("Error parsing TLSID qualifier", TRUE);
				return -1;
			}
			assert(0 < tlsid_len);
			if (CLI_PRESENT == cli_present("RENEGOTIATE_INTERVAL"))
			{
				if (!cli_get_int("RENEGOTIATE_INTERVAL", &renegotiate_interval))
				{
					util_out_print("Error parsing RENEGOTIATE_INTERVAL qualifier", TRUE);
					return -1;
				}
				if (0 > renegotiate_interval)
				{
					util_out_print("Negative values are not allowed for RENEGOTIATE_INTERVAL qualifier", TRUE);
					return -1;
				} else if ((0 < renegotiate_interval) && (renegotiate_interval < MIN_RENEGOTIATE_TIMEOUT))
					renegotiate_interval = MIN_RENEGOTIATE_TIMEOUT;
				renegotiate_interval = renegotiate_interval * 60;	   /* Convert to seconds. */
			} else
				renegotiate_interval = DEFAULT_RENEGOTIATE_TIMEOUT * 60; /* Convert to seconds. */
			/* Convert renegotiate_interval to heartbeat units (# of 8 second intervals). */
			renegotiate_interval = DIVIDE_ROUND_UP(renegotiate_interval, HEARTBEAT_INTERVAL_IN_SECS);
			gtmsource_options.renegotiate_interval = renegotiate_interval;
			/* Check if plaintext-fallback mode is specified. Default option is NOPLAINTEXTFALLBACK. */
			if (CLI_PRESENT == (plaintext_fallback = cli_present("PLAINTEXTFALLBACK")))
				repl_tls.plaintext_fallback = (plaintext_fallback != CLI_NEGATED);
			else
				repl_tls.plaintext_fallback = FALSE;
			}
#		endif
	}
	if (gtmsource_options.shut_down)
	{
		if ((timeout_status = cli_present("TIMEOUT")) == CLI_PRESENT)
		{
			if (!cli_get_int("TIMEOUT", &gtmsource_options.shutdown_time))
			{
				util_out_print("Error parsing TIMEOUT qualifier", TRUE);
				return(-1);
			}
			if (DEFAULT_SHUTDOWN_TIMEOUT < gtmsource_options.shutdown_time || 0 > gtmsource_options.shutdown_time)
			{
				gtmsource_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
				util_out_print("shutdown TIMEOUT changed to !UL", TRUE, gtmsource_options.shutdown_time);
			}
		} else if (CLI_NEGATED == timeout_status)
			gtmsource_options.shutdown_time = -1;
		else /* TIMEOUT not specified */
			gtmsource_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
	}
	if (gtmsource_options.statslog)
	{
		statslog_val_len = 4; /* max(strlen("ON"), strlen("OFF")) + 1 */
		if (!cli_get_str("STATSLOG", statslog_val, &statslog_val_len))
		{
			util_out_print("Error parsing STATSLOG qualifier", TRUE);
			return(-1);
		}
		UNIX_ONLY(cli_strupper(statslog_val);)
		if (0 == STRCMP(statslog_val, "ON"))
Пример #7
0
int4 mupip_set_file(int db_fn_len, char *db_fn)
{
	bool			got_standalone;
	boolean_t		bypass_partial_recov, need_standalone = FALSE;
	char			acc_spec[MAX_ACC_METH_LEN], ver_spec[MAX_DB_VER_LEN], exit_stat, *fn;
	unsigned short		acc_spec_len = MAX_ACC_METH_LEN, ver_spec_len = MAX_DB_VER_LEN;
	int			fd, fn_len;
	int4			status;
	int4			status1;
	int			glbl_buff_status, defer_status, rsrvd_bytes_status,
				extn_count_status, lock_space_status, disk_wait_status;
	int4			new_disk_wait, new_cache_size, new_extn_count, new_lock_space, reserved_bytes, defer_time;
	sgmnt_data_ptr_t	csd;
	tp_region		*rptr, single;
	enum db_acc_method	access, access_new;
	enum db_ver		desired_dbver;
	gd_region		*temp_cur_region;
	char			*errptr, *command = "MUPIP SET VERSION";
	int			save_errno;

	error_def(ERR_DBPREMATEOF);
	error_def(ERR_DBRDERR);
	error_def(ERR_DBRDONLY);
	error_def(ERR_INVACCMETHOD);
	error_def(ERR_MUNOACTION);
	error_def(ERR_RBWRNNOTCHG);
	error_def(ERR_WCERRNOTCHG);
	error_def(ERR_WCWRNNOTCHG);
	error_def(ERR_MMNODYNDWNGRD);

	exit_stat = EXIT_NRM;
	defer_status = cli_present("DEFER_TIME");
	if (defer_status)
		need_standalone = TRUE;
	bypass_partial_recov = cli_present("PARTIAL_RECOV_BYPASS") == CLI_PRESENT;
	if (bypass_partial_recov)
		need_standalone = TRUE;
	if (disk_wait_status = cli_present("WAIT_DISK"))
	{
		if (cli_get_int("WAIT_DISK", &new_disk_wait))
		{
			if (new_disk_wait < 0)
			{
				util_out_print("!UL negative, minimum WAIT_DISK allowed is 0.", TRUE, new_disk_wait);
				return (int4)ERR_WCWRNNOTCHG;
			}
			need_standalone = TRUE;
		} else
		{
			util_out_print("Error getting WAIT_DISK qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (glbl_buff_status = cli_present("GLOBAL_BUFFERS"))
	{
		if (cli_get_int("GLOBAL_BUFFERS", &new_cache_size))
		{
			if (new_cache_size > WC_MAX_BUFFS)
			{
				util_out_print("!UL too large, maximum write cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MAX_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_cache_size < WC_MIN_BUFFS)
			{
				util_out_print("!UL too small, minimum cache buffers allowed is !UL", TRUE, new_cache_size,
						WC_MIN_BUFFS);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting GLOBAL BUFFER qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	/* EXTENSION_COUNT does not require standalone access and hence need_standalone will not be set to TRUE for this. */
	if (extn_count_status = cli_present("EXTENSION_COUNT"))
	{
		if (cli_get_int("EXTENSION_COUNT", &new_extn_count))
		{
			if (new_extn_count > MAX_EXTN_COUNT)
			{
				util_out_print("!UL too large, maximum extension count allowed is !UL", TRUE, new_extn_count,
						MAX_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
			if (new_extn_count < MIN_EXTN_COUNT)
			{
				util_out_print("!UL too small, minimum extension count allowed is !UL", TRUE, new_extn_count,
						MIN_EXTN_COUNT);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting EXTENSION COUNT qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
	}
	if (lock_space_status = cli_present("LOCK_SPACE"))
	{
		if (cli_get_int("LOCK_SPACE", &new_lock_space))
		{
			if (new_lock_space > MAX_LOCK_SPACE)
			{
				util_out_print("!UL too large, maximum lock space allowed is !UL", TRUE,
						new_lock_space, MAX_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
			else if (new_lock_space < MIN_LOCK_SPACE)
			{
				util_out_print("!UL too small, minimum lock space allowed is !UL", TRUE,
						new_lock_space, MIN_LOCK_SPACE);
				return (int4)ERR_WCWRNNOTCHG;
			}
		} else
		{
			util_out_print("Error getting LOCK_SPACE qualifier value", TRUE);
			return (int4)ERR_WCWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (rsrvd_bytes_status = cli_present("RESERVED_BYTES"))
	{
		if (!cli_get_int("RESERVED_BYTES", &reserved_bytes))
		{
			util_out_print("Error getting RESERVED BYTES qualifier value", TRUE);
			return (int4)ERR_RBWRNNOTCHG;
		}
		need_standalone = TRUE;
	}
	if (cli_present("ACCESS_METHOD"))
	{
		cli_get_str("ACCESS_METHOD", acc_spec, &acc_spec_len);
		cli_strupper(acc_spec);
		if (0 == memcmp(acc_spec, "MM", acc_spec_len))
			access = dba_mm;
		else  if (0 == memcmp(acc_spec, "BG", acc_spec_len))
			access = dba_bg;
		else
			mupip_exit(ERR_INVACCMETHOD);
		need_standalone = TRUE;
	} else
		access = n_dba;		/* really want to keep current method,
					    which has not yet been read */
	if (cli_present("VERSION"))
	{
		assert(!need_standalone);
		cli_get_str("VERSION", ver_spec, &ver_spec_len);
		cli_strupper(ver_spec);
		if (0 == memcmp(ver_spec, "V4", ver_spec_len))
			desired_dbver = GDSV4;
		else  if (0 == memcmp(ver_spec, "V5", ver_spec_len))
			desired_dbver = GDSV5;
		else
			GTMASSERT;		/* CLI should prevent us ever getting here */
	} else
		desired_dbver = GDSVLAST;	/* really want to keep version, which has not yet been read */
	if (region)
		rptr = grlist;
	else
	{
		rptr = &single;
		memset(&single, 0, sizeof(single));
	}

	csd = (sgmnt_data *)malloc(ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE));
	in_backup = FALSE;		/* Only want yes/no from mupfndfil, not an address */
	for (;  rptr != NULL;  rptr = rptr->fPtr)
	{
		if (region)
		{
			if (dba_usr == rptr->reg->dyn.addr->acc_meth)
			{
				util_out_print("!/Region !AD is not a GDS access type", TRUE, REG_LEN_STR(rptr->reg));
				exit_stat |= EXIT_WRN;
				continue;
			}
			if (!mupfndfil(rptr->reg, NULL))
				continue;
			fn = (char *)rptr->reg->dyn.addr->fname;
			fn_len = rptr->reg->dyn.addr->fname_len;
		} else
		{
			fn = db_fn;
			fn_len = db_fn_len;
		}
		mu_gv_cur_reg_init();
		strcpy((char *)gv_cur_region->dyn.addr->fname, fn);
		gv_cur_region->dyn.addr->fname_len = fn_len;
		if (!need_standalone)
		{
			gvcst_init(gv_cur_region);
			change_reg();	/* sets cs_addrs and cs_data */
			if (gv_cur_region->read_only)
			{
				gtm_putmsg(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region));
				exit_stat |= EXIT_ERR;
				gds_rundown();
				mu_gv_cur_reg_free();
				continue;
			}
			grab_crit(gv_cur_region);
			status = EXIT_NRM;
			access_new = (n_dba == access ? cs_data->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", cs_data->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if (GDSVLAST != desired_dbver)
			{
				if ((dba_mm != access_new) || (GDSV4 != desired_dbver))
					status1 = desired_db_format_set(gv_cur_region, desired_dbver, command);
				else
				{
					status1 = ERR_MMNODYNDWNGRD;
					gtm_putmsg(VARLSTCNT(4) status1, 2, REG_LEN_STR(gv_cur_region));
				}
				if (SS_NORMAL != status1)
				{	/* "desired_db_format_set" would have printed appropriate error messages */
					if (ERR_MUNOACTION != status1)
					{	/* real error occurred while setting the db format. skip to next region */
						status = EXIT_ERR;
					}
				}
			}
			if (EXIT_NRM == status)
			{
				if (extn_count_status)
					cs_data->extension_size = (uint4)new_extn_count;
				wcs_flu(WCSFLU_FLUSH_HDR);
				if (extn_count_status)
					util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, cs_data->extension_size);
				if (GDSVLAST != desired_dbver)
					util_out_print("Database file !AD now has desired DB format !AD", TRUE,
						fn_len, fn, LEN_AND_STR(gtm_dbversion_table[cs_data->desired_db_format]));
			} else
				exit_stat |= status;
			rel_crit(gv_cur_region);
			gds_rundown();
		} else
		{	/* Following part needs standalone access */
			assert(GDSVLAST == desired_dbver);
			got_standalone = mu_rndwn_file(gv_cur_region, TRUE);
			if (FALSE == got_standalone)
				return (int4)ERR_WCERRNOTCHG;
			/* we should open it (for changing) after mu_rndwn_file, since mu_rndwn_file changes the file header too */
			if (-1 == (fd = OPEN(fn, O_RDWR)))
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("open : !AZ", TRUE, errptr);
				exit_stat |= EXIT_ERR;
				db_ipcs_reset(gv_cur_region, FALSE);
				mu_gv_cur_reg_free();
				continue;
			}
			LSEEKREAD(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				PERROR("Error reading header of file");
				errptr = (char *)STRERROR(save_errno);
				util_out_print("read : !AZ", TRUE, errptr);
				util_out_print("Error reading header of file", TRUE);
				util_out_print("Database file !AD not changed:  ", TRUE, fn_len, fn);
				if (-1 != status)
					rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
				else
					rts_error(VARLSTCNT(4) ERR_DBPREMATEOF, 2, fn_len, fn);
			}
			if (rsrvd_bytes_status)
			{
				if (reserved_bytes > MAX_RESERVE_B(csd))
				{
					util_out_print("!UL too large, maximum reserved bytes allowed is !UL for database file !AD",
							TRUE, reserved_bytes, MAX_RESERVE_B(csd), fn_len, fn);
					close(fd);
					db_ipcs_reset(gv_cur_region, FALSE);
					return (int4)ERR_RBWRNNOTCHG;
				}
				csd->reserved_bytes = reserved_bytes;
			}
			access_new = (n_dba == access ? csd->acc_meth : access);
							/* recalculate; n_dba is a proxy for no change */
			change_fhead_timer("FLUSH_TIME", csd->flush_time,
					   (dba_bg == access_new ? TIM_FLU_MOD_BG : TIM_FLU_MOD_MM),
					   FALSE);
			if ((n_dba != access) && (csd->acc_meth != access))	/* n_dba is a proxy for no change */
			{
				if (dba_mm == access)
					csd->defer_time = 1;			/* defer defaults to 1 */
				csd->acc_meth = access;
				if (0 == csd->n_bts)
				{
					csd->n_bts = WC_DEF_BUFFS;
					csd->bt_buckets = getprime(csd->n_bts);
				}
			}
			if (glbl_buff_status)
			{
				csd->n_bts = BT_FACTOR(new_cache_size);
				csd->bt_buckets = getprime(csd->n_bts);
				csd->n_wrt_per_flu = 7;
				csd->flush_trigger = FLUSH_FACTOR(csd->n_bts);
			}
			if (disk_wait_status)
				csd->wait_disk_space = new_disk_wait;
			if (extn_count_status)
				csd->extension_size = (uint4)new_extn_count;
			if (lock_space_status)
				csd->lock_space_size = (uint4)new_lock_space * OS_PAGELET_SIZE;
			if (bypass_partial_recov)
			{
				csd->file_corrupt = FALSE;
				util_out_print("Database file !AD now has partial recovery flag set to  !UL(FALSE) ",
						TRUE, fn_len, fn, csd->file_corrupt);
			}
			if (dba_mm == access_new)
			{
				if (CLI_NEGATED == defer_status)
					csd->defer_time = 0;
				else  if (CLI_PRESENT == defer_status)
				{
					if (!cli_get_num("DEFER_TIME", &defer_time))
					{
						util_out_print("Error getting DEFER_TIME qualifier value", TRUE);
						db_ipcs_reset(gv_cur_region, FALSE);
						return (int4)ERR_RBWRNNOTCHG;
					}
					if (-1 > defer_time)
					{
						util_out_print("DEFER_TIME cannot take negative values less than -1", TRUE);
						util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
						exit_stat |= EXIT_WRN;
						db_ipcs_reset(gv_cur_region, FALSE);
						mu_gv_cur_reg_free();
						continue;
					}
					csd->defer_time = defer_time;
				}
				if (csd->blks_to_upgrd)
				{
					util_out_print("MM access method cannot be set if there are blocks to upgrade",	TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (GDSVCURR != csd->desired_db_format)
				{
					util_out_print("MM access method cannot be set in DB compatibility mode",
						TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				if (JNL_ENABLED(csd) && csd->jnl_before_image)
				{
					util_out_print("MM access method cannot be set with BEFORE image journaling", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
				csd->jnl_before_image = FALSE;
			} else
			{
				if (defer_status)
				{
					util_out_print("DEFER cannot be specified with BG access method.", TRUE);
					util_out_print("Database file !AD not changed", TRUE, fn_len, fn);
					exit_stat |= EXIT_WRN;
					db_ipcs_reset(gv_cur_region, FALSE);
					mu_gv_cur_reg_free();
					continue;
				}
			}
			LSEEKWRITE(fd, 0, csd, sizeof(sgmnt_data), status);
			if (0 != status)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(save_errno);
				util_out_print("write : !AZ", TRUE, errptr);
				util_out_print("Error writing header of file", TRUE);
				util_out_print("Database file !AD not changed: ", TRUE, fn_len, fn);
				rts_error(VARLSTCNT(4) ERR_DBRDERR, 2, fn_len, fn);
			}
			close(fd);
			/* --------------------- report results ------------------------- */
			if (glbl_buff_status)
				util_out_print("Database file !AD now has !UL global buffers",
						TRUE, fn_len, fn, csd->n_bts);
			if (defer_status && (dba_mm == csd->acc_meth))
				util_out_print("Database file !AD now has defer_time set to !SL",
						TRUE, fn_len, fn, csd->defer_time);
			if (rsrvd_bytes_status)
				util_out_print("Database file !AD now has !UL reserved bytes",
						TRUE, fn_len, fn, csd->reserved_bytes);
			if (extn_count_status)
				util_out_print("Database file !AD now has extension count !UL",
						TRUE, fn_len, fn, csd->extension_size);
			if (lock_space_status)
				util_out_print("Database file !AD now has lock space !UL pages",
						TRUE, fn_len, fn, csd->lock_space_size/OS_PAGELET_SIZE);
			if (disk_wait_status)
				util_out_print("Database file !AD now has wait disk set to !UL seconds",
						TRUE, fn_len, fn, csd->wait_disk_space);
			db_ipcs_reset(gv_cur_region, FALSE);
		} /* end of else part if (!need_standalone) */
		mu_gv_cur_reg_free();
	}
	free(csd);
	assert(!(exit_stat & EXIT_INF));
	return (exit_stat & EXIT_ERR ? (int4)ERR_WCERRNOTCHG :
		(exit_stat & EXIT_WRN ? (int4)ERR_WCWRNNOTCHG : SS_NORMAL));
}
Пример #8
0
int gtmsource_get_opt(void)
{
	boolean_t	secondary, dotted_notation;
	int		tries, index = 0;
	unsigned short	secondary_len;
	char		secondary_sys[MAX_SECONDARY_LEN], *c;
	struct hostent	*sec_hostentry;

	boolean_t	log, log_interval_specified;
	unsigned short	log_file_len;

	boolean_t	buffsize_status;

	boolean_t	filter;
	unsigned short	filter_cmd_len;

	int		timeout_status;

	unsigned short	statslog_val_len;
	char		statslog_val[4]; /* "ON" or "OFF" */

	unsigned short	update_val_len;
	char		update_val[SIZEOF("DISABLE")]; /* "ENABLE" or "DISABLE" */

	unsigned short	connect_parms_str_len;
	char		*connect_parms_str, tmp_connect_parms_str[GTMSOURCE_CONN_PARMS_LEN + 1];
	char		*connect_parm_token_str, *connect_parm;
	int		connect_parms_index;
	boolean_t	connect_parms_badval;

	memset((char *)&gtmsource_options, 0, SIZEOF(gtmsource_options));

	gtmsource_options.start = (cli_present("START") == CLI_PRESENT);
	gtmsource_options.shut_down = (cli_present("SHUTDOWN") == CLI_PRESENT);
	gtmsource_options.activate = (cli_present("ACTIVATE") == CLI_PRESENT);
	gtmsource_options.deactivate = (cli_present("DEACTIVATE") == CLI_PRESENT);
	gtmsource_options.checkhealth = (cli_present("CHECKHEALTH") == CLI_PRESENT);
	gtmsource_options.statslog = (cli_present("STATSLOG") == CLI_PRESENT);
	gtmsource_options.showbacklog = (cli_present("SHOWBACKLOG") == CLI_PRESENT);
	gtmsource_options.changelog = (cli_present("CHANGELOG") == CLI_PRESENT);
	gtmsource_options.stopsourcefilter = (cli_present("STOPSOURCEFILTER") == CLI_PRESENT);
	gtmsource_options.update = (cli_present("UPDATE") == CLI_PRESENT);

	if (gtmsource_options.start || gtmsource_options.activate)
	{
		if (secondary = (CLI_PRESENT == cli_present("SECONDARY")))
		{
			secondary_len = MAX_SECONDARY_LEN;
			if (!cli_get_str("SECONDARY", secondary_sys, &secondary_len))
			{
				util_out_print("Error parsing SECONDARY qualifier", TRUE);
				return(-1);
			}
			/* Parse secondary_sys into secondary_host
			 * and secondary_port */
			c = secondary_sys;
			dotted_notation = TRUE;
			while(*c && *c != ':')
			{
				if ('.' != *c && !ISDIGIT(*c))
					dotted_notation = FALSE;
				gtmsource_options.secondary_host[index++] = *c++;
			}
			gtmsource_options.secondary_host[index] = '\0';
			if (':' != *c)
			{
				util_out_print("Secondary port number should be specified", TRUE);
				return(-1);
			}
			errno = 0;
			if (((0 == (gtmsource_options.secondary_port = ATOI(++c))) && (0 != errno))
				|| (0 >= gtmsource_options.secondary_port))
			{
				util_out_print("Error parsing secondary port number !AD", TRUE, LEN_AND_STR(c));
				return(-1);
			}
			/* Validate the specified secondary host name */
			if (dotted_notation)
			{
				if ((in_addr_t)-1 ==
					(gtmsource_options.sec_inet_addr = INET_ADDR(gtmsource_options.secondary_host)))
				{
					util_out_print("Invalid IP address !AD", TRUE,
						LEN_AND_STR(gtmsource_options.secondary_host));
					return(-1);
				}
			} else
			{
				for (tries = 0;
		     	     	     tries < MAX_GETHOST_TRIES &&
		     	     	     !(sec_hostentry = GETHOSTBYNAME(gtmsource_options.secondary_host)) &&
		     	     	     h_errno == TRY_AGAIN;
		     	     	     tries++);
				if (NULL == sec_hostentry)
				{
					util_out_print("Could not find IP address for !AD", TRUE,
						LEN_AND_STR(gtmsource_options.secondary_host));
					return(-1);
				}
				gtmsource_options.sec_inet_addr = ((struct in_addr *)sec_hostentry->h_addr_list[0])->s_addr;
			}
		}
		if (CLI_PRESENT == cli_present("CONNECTPARAMS"))
		{
			connect_parms_str_len = GTMSOURCE_CONN_PARMS_LEN + 1;
			if (!cli_get_str("CONNECTPARAMS", tmp_connect_parms_str, &connect_parms_str_len))
			{
				util_out_print("Error parsing CONNECTPARAMS qualifier", TRUE);
				return(-1);
			}
#ifdef VMS
			/* strip the quotes around the string. (DCL doesn't do it) */
			assert('"' == tmp_connect_parms_str[0]);
			assert('"' == tmp_connect_parms_str[connect_parms_str_len - 1]);
			connect_parms_str = &tmp_connect_parms_str[1];
			tmp_connect_parms_str[connect_parms_str_len - 1] = '\0';
#else
			connect_parms_str = &tmp_connect_parms_str[0];
#endif
			for (connect_parms_index =
					GTMSOURCE_CONN_HARD_TRIES_COUNT,
			     connect_parms_badval = FALSE,
			     connect_parm_token_str = connect_parms_str;
			     !connect_parms_badval &&
			     connect_parms_index < GTMSOURCE_CONN_PARMS_COUNT &&
			     (connect_parm = strtok(connect_parm_token_str,
						    GTMSOURCE_CONN_PARMS_DELIM))
			     		   != NULL;
			     connect_parms_index++,
			     connect_parm_token_str = NULL)

			{
				errno = 0;
				if ((0 == (gtmsource_options.connect_parms[connect_parms_index] = ATOI(connect_parm))
						&& 0 != errno) || 0 >= gtmsource_options.connect_parms[connect_parms_index])
					connect_parms_badval = TRUE;
			}
			if (connect_parms_badval)
			{
				util_out_print("Error parsing or invalid value parameter in CONNECTPARAMS", TRUE);
				return(-1);
			}
			if (GTMSOURCE_CONN_PARMS_COUNT != connect_parms_index)
			{
				util_out_print(
					"All CONNECTPARAMS - HARD TRIES, HARD TRIES PERIOD, "
					"SOFT TRIES PERIOD, "
					"ALERT TIME, HEARTBEAT INTERVAL, "
					"MAX HEARBEAT WAIT should be specified", TRUE);
				return(-1);
			}
		} else
		{
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT] = REPL_CONN_HARD_TRIES_COUNT;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD] = REPL_CONN_HARD_TRIES_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD] = REPL_CONN_SOFT_TRIES_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD] = REPL_CONN_ALERT_ALERT_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD] = REPL_CONN_HEARTBEAT_PERIOD;
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] = REPL_CONN_HEARTBEAT_MAX_WAIT;
		}
		if (gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]<
				gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD])
			gtmsource_options.connect_parms[GTMSOURCE_CONN_ALERT_PERIOD] =
				gtmsource_options.connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD];
		if (gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] <
				gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD])
			gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT] =
				gtmsource_options.connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD];
	}

	if (gtmsource_options.start || gtmsource_options.statslog || gtmsource_options.changelog || gtmsource_options.activate ||
	    gtmsource_options.deactivate)
	{
		log = (cli_present("LOG") == CLI_PRESENT);
		log_interval_specified = (CLI_PRESENT == cli_present("LOG_INTERVAL"));
		if (log)
		{
			log_file_len = MAX_FN_LEN + 1;
			if (!cli_get_str("LOG", gtmsource_options.log_file, &log_file_len))
			{
				util_out_print("Error parsing LOG qualifier", TRUE);
				return(-1);
			}
		} else
			gtmsource_options.log_file[0] = '\0';
		gtmsource_options.src_log_interval = 0;
		if (log_interval_specified)
		{
			if (!cli_get_num("LOG_INTERVAL", (int4 *)&gtmsource_options.src_log_interval))
			{
				util_out_print("Error parsing LOG_INTERVAL qualifier", TRUE);
				return (-1);
			}
		}
		if (gtmsource_options.start && 0 == gtmsource_options.src_log_interval)
			gtmsource_options.src_log_interval = LOGTRNUM_INTERVAL;
		/* For changelog/activate/deactivate, interval == 0 implies don't change log interval already established */
		/* We ignore interval specification for statslog, Vinaya 2005/02/07 */
	}

	if (gtmsource_options.start)
	{
		assert(secondary || CLI_PRESENT == cli_present("PASSIVE"));
		gtmsource_options.mode = ((secondary) ? GTMSOURCE_MODE_ACTIVE : GTMSOURCE_MODE_PASSIVE);
		if (buffsize_status = (CLI_PRESENT == cli_present("BUFFSIZE")))
		{
			if (!cli_get_int("BUFFSIZE", &gtmsource_options.buffsize))
			{
				util_out_print("Error parsing BUFFSIZE qualifier", TRUE);
				return(-1);
			}
			if (MIN_JNLPOOL_SIZE > gtmsource_options.buffsize)
				gtmsource_options.buffsize = MIN_JNLPOOL_SIZE;
		} else
			gtmsource_options.buffsize = DEFAULT_JNLPOOL_SIZE;
		/* Round up buffsize to the nearest (~JNL_WRT_END_MASK + 1) multiple */
		gtmsource_options.buffsize = ((gtmsource_options.buffsize + ~JNL_WRT_END_MASK) & JNL_WRT_END_MASK);
		if (filter = (CLI_PRESENT == cli_present("FILTER")))
		{
			filter_cmd_len = MAX_FILTER_CMD_LEN;
	    		if (!cli_get_str("FILTER", gtmsource_options.filter_cmd, &filter_cmd_len))
			{
				util_out_print("Error parsing FILTER qualifier", TRUE);
				return(-1);
			}
		} else
			gtmsource_options.filter_cmd[0] = '\0';
	}

	if (gtmsource_options.shut_down)
	{
		if ((timeout_status = cli_present("TIMEOUT")) == CLI_PRESENT)
		{
			if (!cli_get_int("TIMEOUT", &gtmsource_options.shutdown_time))
			{
				util_out_print("Error parsing TIMEOUT qualifier", TRUE);
				return(-1);
			}
			if (DEFAULT_SHUTDOWN_TIMEOUT < gtmsource_options.shutdown_time || 0 > gtmsource_options.shutdown_time)
			{
				gtmsource_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
				util_out_print("shutdown TIMEOUT changed to !UL", TRUE, gtmsource_options.shutdown_time);
			}
		} else if (CLI_NEGATED == timeout_status)
			gtmsource_options.shutdown_time = -1;
		else /* TIMEOUT not specified */
			gtmsource_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
	}

	if (gtmsource_options.statslog)
	{
		statslog_val_len = 4; /* max(strlen("ON"), strlen("OFF")) + 1 */
		if (!cli_get_str("STATSLOG", statslog_val, &statslog_val_len))
		{
			util_out_print("Error parsing STATSLOG qualifier", TRUE);
			return(-1);
		}
		UNIX_ONLY(cli_strupper(statslog_val);)
		if (0 == strcmp(statslog_val, "ON"))
Пример #9
0
bool cli_get_parm(char *entry, char val_buf[])
{
	char		*sp;
	int		ind;
	int		match_ind, res;
	char		local_str[MAX_LINE];
	int		eof;
	char		*gets_res;
	int		parm_len;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	ind = 0;
	assert(0 != gpcmd_parm_vals);
	STRNCPY_STR(local_str, entry, SIZEOF(local_str) - 1);
	cli_strupper(local_str);
	match_ind = -1;
	while (0 < strlen(sp = (gpcmd_parm_vals + ind)->name)) /* implicit assignment intended */
	{
		if (0 == (res = STRNCMP_STR(sp, local_str, MAX_OPT_LEN))) /* implicit assignment intended */
		{
			if (-1 != match_ind)
				return (FALSE);
			else
				match_ind = ind;
		} else
		{
			if (0 < res)
				break;
		}
		ind++;
	}
	if (-1 != match_ind)
	{
		if (NULL == TAREF1(parm_ary, match_ind))
		{
			if (!((gpcmd_parm_vals + match_ind)->parm_required)) /* Value not required */
				return FALSE;
			/* If no value and required, prompt for it */
			PRINTF("%s", (gpcmd_parm_vals + match_ind)->prompt);
			fflush(stdout);
			gets_res = cli_fgets(local_str, MAX_LINE, stdin, FALSE);
			if (gets_res)
			{
				parm_len = STRLEN(gets_res);
				/* chop off newline */
				if (parm_len && (local_str[parm_len - 1] == '\n'))
				{
					local_str[parm_len - 1] = '\0';
					--parm_len;
				}
				TAREF1(parm_str_len, match_ind) = parm_len + 1;
				GROW_HEAP_IF_NEEDED(match_ind);
				if (parm_len)
					memcpy(TAREF1(parm_ary, match_ind), &local_str[0], parm_len);
				*(TAREF1(parm_ary, match_ind) + parm_len) = '\0';
			} else
			{	/* No string was returned so create a real ghost to point to.
				   Note that this should be revisited since this is NOT what should
				   be happening. We should be returning FALSE here but need to instead
				   return a null parm since current behaviors have a dependency on it
				   SE 10/2003
				 */
				TAREF1(parm_str_len, match_ind) = 1;
				GROW_HEAP_IF_NEEDED(match_ind);
				*TAREF1(parm_ary, match_ind) = '\0';
			}
		} else if (-1 == *TAREF1(parm_ary, match_ind) && 1 == TAREF1(parm_str_len, match_ind))
			return (FALSE);
		strcpy(val_buf, TAREF1(parm_ary, match_ind));
		if (!cli_look_next_token(&eof) || (0 == cli_gettoken(&eof)))
		{
			TAREF1(parm_str_len, match_ind) = 1;
			GROW_HEAP_IF_NEEDED(match_ind);
			*TAREF1(parm_ary, match_ind) = -1;
		} else
		{
			parm_len = STRLEN(cli_token_buf) + 1;
			if (MAX_LINE < parm_len)
			{
				PRINTF("Parameter string too long\n");
				fflush(stdout);
				return (FALSE);
			}
			TAREF1(parm_str_len, match_ind) = parm_len;
			GROW_HEAP_IF_NEEDED(match_ind);
			memcpy(TAREF1(parm_ary, match_ind), cli_token_buf, parm_len);
		}
	} else
	{
		/* -----------------
		 * check qualifiers
		 * -----------------
		 */
		if (!cli_get_value(local_str, val_buf))
			return (FALSE);
	}
	return (TRUE);
}
Пример #10
0
/*
 * --------------------------------------------------
 *
 * Process the qualifier to see if any extra parameters
 * are possible in the <...>
 * Return:
 *	TRUE	- OK
 *	FALSE	- Error
 * --------------------------------------------------
 */
boolean_t cli_get_sub_quals(CLI_ENTRY *pparm)
{
	CLI_ENTRY 	*pparm_qual, *pparm1;
	char		local_str[MAX_LINE], tmp_str[MAX_LINE], *tmp_str_ptr;
	char 		*ptr_next_val, *ptr_next_comma, *ptr_equal;
	int		len_str, neg_flg, ptr_equal_len;
	boolean_t	val_flg, has_a_qual;

	has_a_qual = FALSE;
	pparm_qual = pparm->qual_vals;
	if (!pparm_qual)
		return TRUE;
	if ((VAL_STR == pparm->val_type) || (VAL_LIST == pparm->val_type))
	{
		strncpy(local_str, pparm->pval_str, SIZEOF(local_str) - 1);
		ptr_next_val = local_str;
		while (NULL != ptr_next_val)
		{
			len_str= STRLEN(ptr_next_val);
			strncpy(tmp_str, ptr_next_val, len_str);
			tmp_str[len_str] = 0;
			tmp_str_ptr = tmp_str;
			ptr_next_comma = strchr(tmp_str_ptr, ',');
			if (NULL == ptr_next_comma)
				ptr_next_comma = tmp_str_ptr + len_str;
			else
				*ptr_next_comma = 0;
			ptr_equal = strchr(tmp_str_ptr, '=');
			if (ptr_equal && (ptr_equal < ptr_next_comma) )
				*ptr_equal = 0;
			else
				ptr_equal = NULL;
			/* Convert just the qualifier to upper case (e.g. in "enable,on,file=x.mjl" --> "ENABLE,ON,FILE=x.mjl")
			 * Do not convert the values of parameters to upper case as that might result in incorrect translation
			 * if UTF8 characters are present in the command line. The logic below anyways needs only the qualifiers
			 * to be translated.
			 */
			cli_strupper(tmp_str);
			/* -------------------------
			 * See if option is negated
			 * -------------------------
			 */
			if (-1 == (neg_flg = cli_check_negated( &tmp_str_ptr, pparm_qual, &pparm1)))
				return FALSE;
			if (1 == neg_flg)
				len_str -=  STRLEN(NO_STRING);

			if ((ptr_equal) && (ptr_equal + 1 < ptr_next_comma))
				val_flg = TRUE;
			else
				val_flg = FALSE;
			/* -------------------------------------------------------------
			 * If value is disallowed for this qualifier, and an assignment
			 * is encountered, report error, values not allowed for
			 * negated qualifiers
			 * -------------------------------------------------------------
			 */
			if (neg_flg || VAL_DISALLOWED == pparm1->required)
			{
				if (val_flg)
				{
					SNPRINTF(cli_err_str, MAX_CLI_ERR_STR,
					  "Assignment is not allowed for this option : %s",
					  pparm1->name);
					cli_lex_in_ptr->tp = 0;
					return FALSE;
				}
			} else
			{
				if ((!val_flg) && VAL_REQ == pparm1->required)
				{
					if (ptr_equal)
						SNPRINTF(cli_err_str, MAX_CLI_ERR_STR,
						  "Unrecognized option : %s, value expected but not found",
						  pparm1->name);
					else
						SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Option : %s needs value", tmp_str_ptr);
					cli_lex_in_ptr->tp = 0;
					return FALSE;
				}
				if (!cli_numeric_check(pparm1, ptr_equal + 1))
				{
					cli_lex_in_ptr->tp = 0;
					return FALSE;
				}
				if (pparm1->present)
				{
					/* The option was specified before, so clean up that one,
					 * the last one overrides
					 */
					if (pparm1->pval_str)
						free(pparm1->pval_str);
				}
				if ((!val_flg) && (VAL_NOT_REQ == pparm1->required) && pparm1->parm_values)
					MALLOC_CPY_STR(pparm1->pval_str, pparm1->parm_values->prompt);
				if (val_flg)
				{
					ptr_equal_len = STRLEN(ptr_equal + 1);
					pparm1->pval_str = malloc(ptr_equal_len + 1);
					strncpy(pparm1->pval_str, ptr_next_val + (ptr_equal - tmp_str_ptr) + 1, ptr_equal_len);
					pparm1->pval_str[ptr_equal_len] = 0;
				}

			}
			if (pparm1->present)
				pparm->negated = 0;
			pparm1->negated = neg_flg;
			pparm1->present = CLI_PRESENT;
			has_a_qual = TRUE;
			if ((tmp_str_ptr + len_str) != ptr_next_comma)
			{
				ptr_next_val = strchr(ptr_next_val, ',')+ 1;
				if (!*ptr_next_val)
				{
					SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Option expected");
					cli_lex_in_ptr->tp = 0;
					return FALSE;

				}
			} else
				ptr_next_val = NULL;
		}
	}
	/* do one last parse on the qualifier table, if there is any other qualifier present,
	 * the DEFA_PRESENT one is not necessary, otherwise leave it as it is.
	 */
	if (has_a_qual)
	{
		pparm1 = pparm_qual;
		while (0 != *pparm1->name)
		{
			if (CLI_DEFAULT == pparm1->present)
				pparm1->present = CLI_ABSENT;
			pparm1++;
		}
	}

	return TRUE;
}
Пример #11
0
/*
 * ---------------------------------------------------------
 * Parse one option.
 * Read tokens from the input.
 * Check if it is a valid qualifier or parameter.
 * If it is a parameter, get it, and save it in the
 * global parameter array.
 * If it is a qualifier, get its value and save it in a value table,
 * corresponding to this option.
 *
 * Arguments:
 *	pcmd_parms	- pointer to command parameter table
 *	eof		- pointer to end of file flag
 *
 * Return:
 *	1 - option parsed OK
 *	-1 - failure to parse option
 *	0 - no more tokens, in which case
 *		the eof flag is set on end of file.
 * ---------------------------------------------------------
 */
int 	parse_arg(CLI_ENTRY *pcmd_parms, int *eof)
{
	CLI_ENTRY 	*pparm;
	char 		*opt_str, *val_str;
	int 		neg_flg;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	/* -----------------------------------------
	 * get qualifier marker, or parameter token
	 * -----------------------------------------
	 */
	if (VAL_LIST == gpcmd_verb->val_type && TREF(parms_cnt) == gpcmd_verb->max_parms)
		return (0);
	if (!cli_look_next_token(eof))
		return (0);
	/* -------------------------------------------------------------------
	 * here cli_token_buf is set by the previous cli_look_next_token(eof)
	 * call itself since it in turn calls cli_gettoken()
	 * -------------------------------------------------------------------
	 */
	if (!cli_is_qualif(cli_token_buf) && !cli_is_assign(cli_token_buf))
	{	/* ----------------------------------------------------
		 * If token is not a qualifier, it must be a parameter
		 *
		 * No need to check for eof on cli_get_string_token(eof) since
		 * already checked that on the previous cli_look_next_token.
		 * now you have to skip initial white spaces before reading
		 * the string since cli_get_string_token considers a space
		 * as a blank token. hence the need for the skip_white_space()
		 * call.
		 * ------------------------------------------------------------
		 */
		skip_white_space();
		cli_get_string_token(eof);
		if (TREF(parms_cnt) >= gpcmd_verb->max_parms)
		{
			SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Too many parameters ");
			return (-1);
		}
		TAREF1(parm_str_len, TREF(parms_cnt)) = strlen(cli_token_buf) + 1;
		GROW_HEAP_IF_NEEDED(TREF(parms_cnt));
		memcpy(TAREF1(parm_ary, TREF(parms_cnt)), cli_token_buf, TAREF1(parm_str_len, TREF(parms_cnt)));
		(TREF(parms_cnt))++;
		return (1);
	}
	/* ---------------------------------------------------------------------
	 * cli_gettoken(eof) need not be checked for return value since earlier
	 * itself we have checked for return value in cli_look_next_token(eof)
	 * ---------------------------------------------------------------------
	 */
	cli_gettoken(eof);
	opt_str = cli_token_buf;
	if (!pcmd_parms)
	{
		SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "No qualifiers allowed for this command");
		return (-1);
	}
	/* ------------------------------------------
	 * Qualifiers must start with qualifier token
	 * ------------------------------------------
	 */
	if (!cli_is_qualif(cli_token_buf))
	{
		SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Qualifier expected instead of : %s ", opt_str);
		return (-1);
	}
	/* -------------------------
	 * Get the qualifier string
	 * -------------------------
	 */
	if (!cli_look_next_token(eof) || 0 == cli_gettoken(eof))
	{
		SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Qualifier string missing %s ", opt_str);
		return (-1);
	}
	/* ---------------------------------------
	 * Fold the qualifier string to upper case
	 * ---------------------------------------
	 */
	cli_strupper(opt_str);
	/* -------------------------
	 * See if option is negated and update
	 * -------------------------
	 */
	if (-1 == (neg_flg = cli_check_negated(&opt_str, pcmd_parms, &pparm)))
		return (-1);
	/* -------------------------------------------------------------
	 * If value is disallowed for this qualifier, and an assignment
	 * token is encounter, report error, values not allowed for
	 * negated qualifiers
	 * -------------------------------------------------------------
	 */
	if (neg_flg || VAL_DISALLOWED == pparm->required)
	{
		if (cli_look_next_token(eof) && cli_is_assign(cli_token_buf))
		{
			SNPRINTF(cli_err_str, MAX_CLI_ERR_STR,
			  "Assignment is not allowed for this option : %s",
			  pparm->name);
			return (-1);
		}
	} else
	{	/* --------------------------------------------------
		 * Get Value either optional, or required.
		 * In either case, there must be an assignment token
		 * --------------------------------------------------
		 */
		if (!cli_look_next_token(eof) || !cli_is_assign(cli_token_buf))
		{
	    		if (VAL_REQ == pparm->required)
			{
				SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Option : %s needs value", pparm->name);
				return (-1);
			} else
			{
				if (pparm->present)
				{
					/* The option was specified before, so clean up that one,
					 * the last one overrides
					 */
					if (pparm->pval_str)
						free(pparm->pval_str);
					if (pparm->qual_vals)
						clear_parm_vals(pparm->qual_vals, FALSE);

				}
				/* -------------------------------
				 * Allocate memory and save value
				 * -------------------------------
				 */
				if (pparm->parm_values)
				{
					MALLOC_CPY_STR(pparm->pval_str, pparm->parm_values->prompt);
					if (!cli_get_sub_quals(pparm))
						return (-1);
				}
			}
		} else
		{
			cli_gettoken(eof);
			/* ---------------------------------
			 * Get the assignment token + value
			 * ---------------------------------
			 */
			if (!cli_is_assign(cli_token_buf))
			{
				SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Assignment missing after option : %s", pparm->name);
				return (-1);
			}
			/* --------------------------------------------------------
			 * get the value token, "=" is NOT a token terminator here
			 * --------------------------------------------------------
			 */
			if (!cli_look_next_string_token(eof) || 0 == cli_get_string_token(eof))
			{
				SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Unrecognized option : %s, value expected but not found",
						pparm->name);
				cli_lex_in_ptr->tp = 0;
				return (-1);
			}
			val_str = cli_token_buf;
			if (!cli_numeric_check(pparm, val_str))
			{
				cli_lex_in_ptr->tp = 0;
				return (-1);
			}
			if (pparm->present)
			{	/* The option was specified before, so clean up that one,
				 * the last one overrides
				 */
				if (pparm->pval_str)
					free(pparm->pval_str);
				if (pparm->qual_vals)
					clear_parm_vals(pparm->qual_vals, FALSE);
			}
			/* -------------------------------
			 * Allocate memory and save value
			 * -------------------------------
			 */
			MALLOC_CPY_STR(pparm->pval_str, cli_token_buf);
			if (!cli_get_sub_quals(pparm))
				return (-1);
		}
	}
	if (pparm->present)
		pparm->negated = 0;
	pparm->negated = neg_flg;
	pparm->present = 1;
	if (NULL != pparm->func)
		func = pparm->func;
	/* ----------------------------------------------------------------------------------------------------------------------
	 * If there is another level, update global pointers
	 * Notice that this global pointer updation should be done only at the end of this routine in order to ensure that the
	 * 	check_disallow() function invoked below sees the currently parsed argument as present (i.e. pparm->present = 1)
	 * ----------------------------------------------------------------------------------------------------------------------
	 */
	if (pparm->parms)
	{	/*-------------------------------------------------------------------------------------------
		 * Check that the disallow conditions for this level are met before switching to next level
		 *-------------------------------------------------------------------------------------------
		 */
		if (FALSE == check_disallow(gpcmd_verb))
			return (-1);
		gpqual_root = pparm;
		clear_parm_vals(pparm->parms, TRUE);
		gpcmd_qual = pparm->parms;
		gpcmd_verb = pparm;	/* this needs to be done in order for check_disallow() to do the proper disallow check.
					 * an example that will not work otherwise is cli_disallow_mupip_replic_receive() */
	}
	return (1);
}
Пример #12
0
int gtmrecv_get_opt(void)
{

    boolean_t	log;
    unsigned short	log_file_len;
    boolean_t	buffsize_status;
    boolean_t	filter;
    unsigned short	filter_cmd_len;
    int		timeout_status;
    boolean_t	listenport_status;
    unsigned short	statslog_val_len;
    char		statslog_val[4]; /* "ON" or "OFF" */
    int		num_actions;


    num_actions = 0;
    num_actions += ((gtmrecv_options.start = (CLI_PRESENT == cli_present("START"))) ? 1 : 0);
    num_actions += ((gtmrecv_options.shut_down = (CLI_PRESENT == cli_present("SHUTDOWN"))) ? 1 : 0);
    num_actions += ((gtmrecv_options.checkhealth = (CLI_PRESENT == cli_present("CHECKHEALTH"))) ? 1 : 0);
    num_actions += ((gtmrecv_options.statslog = (CLI_PRESENT == cli_present("STATSLOG"))) ? 1 : 0);
    num_actions += ((gtmrecv_options.showbacklog = (CLI_PRESENT == cli_present("SHOWBACKLOG"))) ? 1 : 0);
    num_actions += ((gtmrecv_options.changelog = (CLI_PRESENT == cli_present("CHANGELOG"))) ? 1 : 0);

    if (1 < num_actions)
    {
        util_out_print("Invalid mixing of action qualifiers. Only one of START, SHUTDOWN, CHECKHEALTH, STATSLOG, "
                       "SHOWBACKLOG, CHANGELOG should be specified", TRUE);
        return (-1);
    } else if (0 == num_actions)
    {
        util_out_print("No action qualifier specified. One of START, SHUTDOWN, CHECKHEALTH, STATSLOG, SHOWBACKLOG, "
                       "CHANGELOG should be specified", TRUE);
        return (-1);
    }

    gtmrecv_options.updateonly = (CLI_PRESENT == cli_present("UPDATEONLY"));
    gtmrecv_options.updateresync = (CLI_PRESENT == cli_present("UPDATERESYNC"));

    if (gtmrecv_options.start && !gtmrecv_options.updateonly)
    {
        if (!(listenport_status = (CLI_PRESENT == cli_present("LISTENPORT"))))
        {
            util_out_print("LISTENPORT should be specfied with START", TRUE);
            return (-1);
        } else if (!cli_get_num("LISTENPORT", &gtmrecv_options.listen_port))
        {
            util_out_print("Error parsing LISTENPORT qualifier", TRUE);
            return (-1);
        }

        if (buffsize_status = (CLI_PRESENT == cli_present("BUFFSIZE")))
        {
            if (!cli_get_num("BUFFSIZE", &gtmrecv_options.buffsize))
            {
                util_out_print("Error parsing BUFFSIZE qualifier", TRUE);
                return (-1);
            }
            if (MIN_RECVPOOL_SIZE > gtmrecv_options.buffsize)
                gtmrecv_options.buffsize = MIN_RECVPOOL_SIZE;
        } else
            gtmrecv_options.buffsize = DEFAULT_RECVPOOL_SIZE;
        /* Round up or down buffsize */

        if (filter = (CLI_PRESENT == cli_present("FILTER")))
        {
            filter_cmd_len = MAX_FILTER_CMD_LEN;
            if (!cli_get_str("FILTER", gtmrecv_options.filter_cmd, &filter_cmd_len))
            {
                util_out_print("Error parsing FILTER qualifier", TRUE);
                return (-1);
            }
        } else
            gtmrecv_options.filter_cmd[0] = '\0';

        gtmrecv_options.stopsourcefilter = (CLI_PRESENT == cli_present("STOPSOURCEFILTER"));
    }

    if ((gtmrecv_options.start && !gtmrecv_options.updateonly) || gtmrecv_options.statslog || gtmrecv_options.changelog)
    {
        log = (CLI_PRESENT == cli_present("LOG"));
        if ((gtmrecv_options.start && !gtmrecv_options.updateonly || gtmrecv_options.changelog) && !log)
        {
            util_out_print("LOG should be specified with START or CHANGELOG", TRUE);
            return (-1);
        }
        if (log)
        {
            log_file_len = MAX_FN_LEN + 1;
            if (!cli_get_str("LOG", gtmrecv_options.log_file, &log_file_len))
            {
                util_out_print("Error parsing LOG qualifier", TRUE);
                return (-1);
            }
        } else
            gtmrecv_options.log_file[0] = '\0';
    }

    if (!gtmrecv_options.start && gtmrecv_options.updateresync)
    {
        util_out_print("UPDATERESYNC can be used only with START", TRUE);
        gtmrecv_options.updateresync = FALSE;
        return (-1);
    }

    if (gtmrecv_options.shut_down)
    {
        if (CLI_PRESENT == (timeout_status = cli_present("TIMEOUT")))
        {
            if (!cli_get_num("TIMEOUT", &gtmrecv_options.shutdown_time))
            {
                util_out_print("Error parsing TIMEOUT qualifier", TRUE);
                return (-1);
            }
            if (DEFAULT_SHUTDOWN_TIMEOUT < gtmrecv_options.shutdown_time || 0 > gtmrecv_options.shutdown_time)
            {
                gtmrecv_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
                util_out_print("shutdown TIMEOUT changed to !UL", TRUE, gtmrecv_options.shutdown_time);
            }
        } else if (CLI_NEGATED == timeout_status)
            gtmrecv_options.shutdown_time = -1;
        else /* TIMEOUT not specified */
            gtmrecv_options.shutdown_time = DEFAULT_SHUTDOWN_TIMEOUT;
    }

    if (gtmrecv_options.statslog)
    {
        statslog_val_len = 4; /* max(strlen("ON"), strlen("OFF")) + 1 */
        if (!cli_get_str("STATSLOG", statslog_val, &statslog_val_len))
        {
            util_out_print("Error parsing STATSLOG qualifier", TRUE);
            return (-1);
        }
#ifdef UNIX
        cli_strupper(statslog_val);
#endif
        if (0 == strcmp(statslog_val, "ON"))
            gtmrecv_options.statslog = TRUE;
        else if (0 == strcmp(statslog_val, "OFF"))
            gtmrecv_options.statslog = FALSE;
        else
        {
            util_out_print("Invalid value for STATSLOG qualifier, should be either ON or OFF", TRUE);
            return (-1);
        }
    }

    return (0);
}