2012-02-05 11:35:58 -05:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
2012-03-24 14:06:46 -04:00
|
|
|
* Copyright 2001, 2012 Fidelity Information Services, Inc *
|
2012-02-05 11:35:58 -05:00
|
|
|
* *
|
|
|
|
* This source code contains the intellectual property *
|
|
|
|
* of its copyright holder(s), and is made available *
|
|
|
|
* under a license. If you do not know the terms of *
|
|
|
|
* the license, please stop and do not read further. *
|
|
|
|
* *
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
#if defined(__MVS__) && !defined(_ISOC99_SOURCE)
|
|
|
|
#define _ISOC99_SOURCE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mdef.h"
|
|
|
|
|
|
|
|
#include "gtm_stdio.h"
|
|
|
|
#include "gtm_string.h"
|
|
|
|
#include "cli.h"
|
|
|
|
#include "cli_parse.h"
|
|
|
|
#include "error.h"
|
|
|
|
#include "cli_disallow.h"
|
|
|
|
|
|
|
|
#define NO_STRING "NO"
|
|
|
|
|
|
|
|
/* Dynamically allocates (that is, grows) enough space for the current array
|
|
|
|
* of parameter strings during the lifetime of the process. Since the number
|
|
|
|
* of array elements is limited, it is better to allocate memory as needed
|
|
|
|
* rather than constantly free and reallocate. */
|
|
|
|
#define GROW_HEAP_IF_NEEDED(PARM_ARY_INDEX) \
|
|
|
|
{ \
|
|
|
|
if (TAREF1(parm_str_len, PARM_ARY_INDEX) > TAREF1(parm_ary_len, PARM_ARY_INDEX)) \
|
|
|
|
{ \
|
|
|
|
if (TAREF1(parm_ary, PARM_ARY_INDEX)) \
|
|
|
|
free(TAREF1(parm_ary, PARM_ARY_INDEX)); \
|
|
|
|
\
|
|
|
|
TAREF1(parm_ary, PARM_ARY_INDEX) = (char *)malloc(TAREF1(parm_str_len, PARM_ARY_INDEX)); \
|
|
|
|
\
|
|
|
|
TAREF1(parm_ary_len, PARM_ARY_INDEX) = TAREF1(parm_str_len, PARM_ARY_INDEX); \
|
|
|
|
} \
|
|
|
|
}
|
|
|
|
|
|
|
|
#if MAX_OPT_LEN > MAX_LINE
|
|
|
|
# error MAX_OPT_LEN is greater than MAX_LINE. Fix STRNCMP_STR and STRNCPY_STR usages below.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GBLDEF void (*func)(void); /* Function to be dispatched
|
|
|
|
to for this command */
|
|
|
|
|
|
|
|
GBLREF char cli_err_str[]; /* Parse Error message buffer */
|
|
|
|
static CLI_ENTRY *gpqual_root; /* pointer to root of
|
|
|
|
subordinate qualifier table */
|
|
|
|
static CLI_ENTRY *gpcmd_qual; /* pointer command qualifier table */
|
|
|
|
static CLI_ENTRY *gpcmd_verb; /* pointer to verb table */
|
|
|
|
static CLI_PARM *gpcmd_parm_vals; /* pointer to parameters for command */
|
|
|
|
|
|
|
|
GBLREF char cli_token_buf[];
|
|
|
|
GBLREF CLI_ENTRY *cmd_ary;
|
|
|
|
|
|
|
|
GBLREF IN_PARMS *cli_lex_in_ptr;
|
|
|
|
|
|
|
|
error_def(ERR_CLIERR);
|
|
|
|
error_def(ERR_MUNOACTION);
|
|
|
|
error_def(ERR_MUPCLIERR);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* -----------------------------------------------
|
|
|
|
* Clear all parameter values and flags of command
|
|
|
|
* parameter table for a given command.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* cmd_parms - address of parameter array
|
|
|
|
* follow - whether to clear extra value tables or not
|
|
|
|
* TRUE - follow down
|
|
|
|
* FALSE - do not follow down
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* none
|
|
|
|
* -----------------------------------------------
|
|
|
|
*/
|
|
|
|
void clear_parm_vals(CLI_ENTRY *cmd_parms, boolean_t follow) /* pointer to option's parameter table */
|
|
|
|
{
|
|
|
|
CLI_ENTRY *root_param;
|
|
|
|
int need_copy;
|
|
|
|
|
|
|
|
need_copy = (gpcmd_qual != cmd_parms);
|
|
|
|
while (strlen(cmd_parms->name) > 0)
|
|
|
|
{
|
|
|
|
if (cmd_parms->pval_str)
|
|
|
|
free(cmd_parms->pval_str);
|
|
|
|
/* if root table exists, copy over any qualifier values to the new parameter table */
|
|
|
|
if ((FALSE != follow) && need_copy &&
|
|
|
|
(root_param = find_cmd_param(cmd_parms->name, gpcmd_qual, FALSE)))
|
|
|
|
{
|
|
|
|
cmd_parms->pval_str = root_param->pval_str;
|
|
|
|
cmd_parms->negated = root_param->negated;
|
|
|
|
cmd_parms->present = root_param->present;
|
|
|
|
root_param->pval_str = 0;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
cmd_parms->negated = 0;
|
|
|
|
cmd_parms->present = 0;
|
|
|
|
cmd_parms->pval_str = 0;
|
|
|
|
/* dfault_str also implements default values.
|
|
|
|
0: it is not present by default,
|
|
|
|
DEFA_PRESENT: it is present by default, no value,
|
|
|
|
str pointer: it is present by default, with the value pointed to
|
|
|
|
*/
|
|
|
|
if (cmd_parms->dfault_str)
|
|
|
|
{
|
|
|
|
cmd_parms->present = CLI_DEFAULT;
|
|
|
|
if (CLI_PRESENT != (INTPTR_T)cmd_parms->dfault_str)
|
|
|
|
cmd_parms->pval_str = cmd_parms->dfault_str;
|
|
|
|
}
|
|
|
|
if ((FALSE != follow) && cmd_parms->qual_vals)
|
|
|
|
clear_parm_vals(cmd_parms->qual_vals, FALSE);
|
|
|
|
}
|
|
|
|
cmd_parms++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* -----------------------------------------------
|
|
|
|
* Find command in command table
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* str - command string
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* if found, index into command table array,
|
|
|
|
* else -1
|
|
|
|
* -----------------------------------------------
|
|
|
|
*/
|
|
|
|
int find_verb(char *str)
|
|
|
|
{
|
|
|
|
return (find_entry(str, cmd_ary));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* Find command parameter in command parameter table
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* str - parameter string
|
|
|
|
* pparm - pointer to parameter table for this command
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* if found, pointer to parameter structure
|
|
|
|
* else 0
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
*/
|
|
|
|
CLI_ENTRY *find_cmd_param(char *str, CLI_ENTRY *pparm, int follow)
|
|
|
|
{
|
|
|
|
CLI_ENTRY *pparm_tmp;
|
|
|
|
int ind, ind_match;
|
|
|
|
char *sp;
|
|
|
|
|
|
|
|
ind_match = -1;
|
|
|
|
if (NULL == pparm)
|
|
|
|
return NULL;
|
|
|
|
if (0 <= (ind = find_entry(str, pparm)))
|
|
|
|
return pparm + ind;
|
|
|
|
|
|
|
|
if (FALSE == follow)
|
|
|
|
return NULL;
|
|
|
|
/* if to follow, go through the qual_vals, and check those tables */
|
|
|
|
for(ind =0; 0 < strlen((pparm + ind)->name); ind++)
|
|
|
|
{
|
|
|
|
pparm_tmp = (pparm + ind)->qual_vals;
|
|
|
|
if (pparm_tmp)
|
|
|
|
ind_match = find_entry(str, pparm_tmp);
|
|
|
|
if (-1 != ind_match)
|
|
|
|
return pparm_tmp + ind_match;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ---------------------------------------------------------
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* -----------------------------------------------------
|
|
|
|
* Check if the value is numeric if it is supposed to be
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* TRUE - It is numeric or val_type is not
|
|
|
|
* numeric anyway
|
|
|
|
* FALSE - Is not numeric
|
|
|
|
* -----------------------------------------------------
|
|
|
|
*/
|
|
|
|
boolean_t cli_numeric_check(CLI_ENTRY *pparm, char *val_str)
|
|
|
|
{
|
|
|
|
boolean_t retval = TRUE;
|
|
|
|
|
|
|
|
if (VAL_NUM == pparm->val_type)
|
|
|
|
{
|
|
|
|
if (pparm->hex_num)
|
|
|
|
{
|
|
|
|
if (!cli_is_hex(val_str))
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR,
|
|
|
|
"Unrecognized value: %s, HEX number expected",
|
|
|
|
val_str);
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
|
|
|
} else if (!cli_is_dcm(val_str))
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR,
|
|
|
|
"Unrecognized value: %s, Decimal number expected",
|
|
|
|
val_str);
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (retval);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------
|
|
|
|
* Check if option is negated
|
|
|
|
*---------------------------
|
|
|
|
*/
|
|
|
|
int cli_check_negated(char **opt_str_ptr, CLI_ENTRY *pcmd_parm_ptr, CLI_ENTRY **pparm_ptr)
|
|
|
|
{
|
|
|
|
int neg_flg;
|
|
|
|
CLI_ENTRY *pcmd_parms;
|
|
|
|
char *opt_str_tmp;
|
|
|
|
|
|
|
|
pcmd_parms = pcmd_parm_ptr;
|
|
|
|
opt_str_tmp = *opt_str_ptr;
|
|
|
|
if (0 == MEMCMP_LIT(*opt_str_ptr, NO_STRING))
|
|
|
|
{
|
|
|
|
*opt_str_ptr += SIZEOF(NO_STRING) - 1;
|
|
|
|
neg_flg = 1;
|
|
|
|
} else
|
|
|
|
neg_flg = 0;
|
|
|
|
/* --------------------------------------------
|
|
|
|
* search qualifier table for qualifier string
|
|
|
|
* --------------------------------------------
|
|
|
|
*/
|
|
|
|
if (0 == (*pparm_ptr = find_cmd_param(*opt_str_ptr, pcmd_parms, FALSE)))
|
|
|
|
{
|
|
|
|
/* Check that the qualifier does not have the NO prefix */
|
|
|
|
if (0 == (*pparm_ptr = find_cmd_param(opt_str_tmp, pcmd_parms, FALSE)))
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Unrecognized option : %s", *opt_str_ptr);
|
|
|
|
cli_lex_in_ptr->tp = 0;
|
|
|
|
return (-1);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
/* It was a valid qualifier with the prefix NO */
|
|
|
|
*opt_str_ptr = opt_str_tmp;
|
|
|
|
neg_flg = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* ----------------------------------------------------
|
|
|
|
* if option is negated and it is not negatable, error
|
|
|
|
* ----------------------------------------------------
|
|
|
|
*/
|
|
|
|
if (!(*pparm_ptr)->negatable && neg_flg)
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Option %s may not be negated", *opt_str_ptr);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
return neg_flg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* --------------------------------------------------
|
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* -----------------------------------------------------------
|
|
|
|
* Parse one command.
|
|
|
|
* Get tokens from the input stream.
|
|
|
|
* See if the first token is a command name, as it should be,
|
|
|
|
* and if it is, check if optional arguments that follow,
|
|
|
|
* are legal, and if they are, get their values and
|
|
|
|
* save them in a value table, corresponding to this
|
|
|
|
* option.
|
|
|
|
* If any of these conditions are not met, parse error occures.
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* 0 - command parsed OK
|
|
|
|
* EOF - end of file
|
|
|
|
* <> - failure to parse command
|
|
|
|
* -----------------------------------------------------------
|
|
|
|
*/
|
|
|
|
int parse_cmd(void)
|
|
|
|
{
|
|
|
|
int res, cmd_ind;
|
|
|
|
char *cmd_str;
|
|
|
|
int opt_cnt;
|
|
|
|
int eof, cmd_err;
|
|
|
|
DCL_THREADGBL_ACCESS;
|
|
|
|
|
|
|
|
SETUP_THREADGBL_ACCESS;
|
|
|
|
opt_cnt = 0;
|
|
|
|
gpqual_root = NULL;
|
|
|
|
func = 0;
|
|
|
|
cmd_err = 0;
|
|
|
|
TREF(parms_cnt) = 0; /* Parameters count */
|
|
|
|
*cli_err_str = 0;
|
|
|
|
|
|
|
|
cmd_str = cli_token_buf;
|
|
|
|
/* ------------------------
|
|
|
|
* If no more tokens exist
|
|
|
|
* ------------------------
|
|
|
|
*/
|
|
|
|
if (0 == cli_gettoken(&eof))
|
|
|
|
{
|
|
|
|
if (eof)
|
|
|
|
return (EOF);
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
/* ------------------------------
|
|
|
|
* Find command in command table
|
|
|
|
* ------------------------------
|
|
|
|
*/
|
|
|
|
if (-1 != (cmd_ind = find_verb(cmd_str)))
|
|
|
|
{
|
|
|
|
gpcmd_qual = cmd_ary[cmd_ind].parms;
|
|
|
|
gpcmd_parm_vals = cmd_ary[cmd_ind].parm_values;
|
|
|
|
gpcmd_verb = &cmd_ary[cmd_ind];
|
|
|
|
if (gpcmd_qual)
|
|
|
|
clear_parm_vals(gpcmd_qual, TRUE);
|
|
|
|
func = cmd_ary[cmd_ind].func;
|
|
|
|
/* ----------------------
|
|
|
|
* Parse command options
|
|
|
|
* ----------------------
|
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
|
|
|
res = parse_arg(gpcmd_qual, &eof);
|
|
|
|
if (1 == res)
|
|
|
|
{
|
|
|
|
opt_cnt++;
|
|
|
|
}
|
|
|
|
} while (1 == res);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Unrecognized command: %s", cmd_str);
|
|
|
|
cli_lex_in_ptr->tp = 0;
|
|
|
|
res = -1;
|
|
|
|
}
|
|
|
|
if ((1 > opt_cnt) && (-1 != res) && (VAL_REQ == cmd_ary[cmd_ind].required))
|
|
|
|
{
|
|
|
|
SNPRINTF(cli_err_str, MAX_CLI_ERR_STR, "Command argument expected, but not found");
|
|
|
|
res = -1;
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------
|
|
|
|
* Check that the disallow conditions are met (to allow)
|
|
|
|
*------------------------------------------------------
|
|
|
|
*/
|
|
|
|
if ((-1 != res) && (FALSE == check_disallow(gpcmd_verb)))
|
|
|
|
res = -1;
|
|
|
|
/* -------------------------------------
|
|
|
|
* If parse error, display error string
|
|
|
|
* -------------------------------------
|
|
|
|
*/
|
|
|
|
if (-1 == res)
|
2012-03-24 14:06:46 -04:00
|
|
|
{
|
2012-02-05 11:35:58 -05:00
|
|
|
func = 0;
|
2012-03-24 14:06:46 -04:00
|
|
|
eof = 0;
|
|
|
|
}
|
2012-02-05 11:35:58 -05:00
|
|
|
else
|
|
|
|
return (0);
|
|
|
|
/* -------------------------
|
|
|
|
* If gettoken returned EOF
|
|
|
|
* -------------------------
|
|
|
|
*/
|
|
|
|
if (eof)
|
|
|
|
return (EOF);
|
|
|
|
else
|
|
|
|
return (ERR_CLIERR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------------------------------------------------
|
|
|
|
* See if command parameter is present on the command line,
|
|
|
|
* and if it is, return the pointer to its table entry.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* parm_str - parameter string to search for
|
|
|
|
*
|
|
|
|
* Return:
|
|
|
|
* 0 - not present
|
|
|
|
* pointer to parameter entry
|
|
|
|
* ------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
CLI_ENTRY *get_parm_entry(char *parm_str)
|
|
|
|
{
|
|
|
|
CLI_ENTRY *pparm;
|
|
|
|
bool root_match;
|
|
|
|
char local_str[MAX_LINE], *tmp_ptr;
|
|
|
|
|
|
|
|
STRNCPY_STR(local_str, parm_str, SIZEOF(local_str) - 1);
|
|
|
|
root_match = (gpqual_root && !STRNCMP_STR(gpqual_root->name, local_str, MAX_OPT_LEN));
|
|
|
|
|
|
|
|
/* ---------------------------------------
|
|
|
|
* search qualifier table for this option
|
|
|
|
* ---------------------------------------
|
|
|
|
*/
|
|
|
|
if (!gpcmd_qual)
|
|
|
|
return (NULL);
|
|
|
|
if (NULL == strchr(local_str,'.'))
|
|
|
|
pparm = find_cmd_param(local_str, gpcmd_qual, TRUE);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tmp_ptr= strchr(local_str,'.');
|
|
|
|
/* there should be at least 1 character after the . */
|
|
|
|
assert (tmp_ptr + 1 < local_str + strlen(local_str));
|
|
|
|
*tmp_ptr = 0;
|
|
|
|
pparm = find_cmd_param(local_str, gpcmd_qual, FALSE);
|
|
|
|
if (pparm)
|
|
|
|
pparm = find_cmd_param(tmp_ptr+1, pparm->qual_vals, FALSE);
|
|
|
|
|
|
|
|
}
|
|
|
|
if (root_match && !pparm)
|
|
|
|
return (gpqual_root);
|
|
|
|
else if (pparm)
|
|
|
|
return (pparm);
|
|
|
|
else
|
|
|
|
return (NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ------------------------------------------------------------
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ------------------------------------------------------------
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* --------------------------------------------------
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
2012-03-24 14:06:46 -04:00
|
|
|
{
|
2012-02-05 11:35:58 -05:00
|
|
|
if (NULL == TAREF1(parm_ary, match_ind))
|
|
|
|
{
|
2012-03-24 14:06:46 -04:00
|
|
|
if (!((gpcmd_parm_vals + match_ind)->parm_required)) /* Value not required */
|
|
|
|
return FALSE;
|
|
|
|
/* If no value and required, prompt for it */
|
2012-02-05 11:35:58 -05:00
|
|
|
PRINTF("%s", (gpcmd_parm_vals + match_ind)->prompt);
|
2012-03-24 14:06:46 -04:00
|
|
|
fflush(stdout);
|
2012-02-05 11:35:58 -05:00
|
|
|
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");
|
2012-03-24 14:06:46 -04:00
|
|
|
fflush(stdout);
|
2012-02-05 11:35:58 -05:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GTM_TRIGGER
|
|
|
|
int parse_triggerfile_cmd(void)
|
|
|
|
{
|
|
|
|
int res, cmd_ind;
|
|
|
|
int opt_cnt;
|
|
|
|
int eof;
|
|
|
|
char cmd[] = "TRIGGER";
|
|
|
|
char *ptr;
|
|
|
|
DCL_THREADGBL_ACCESS;
|
|
|
|
|
|
|
|
SETUP_THREADGBL_ACCESS;
|
|
|
|
opt_cnt = 0;
|
|
|
|
gpqual_root = 0;
|
|
|
|
func = 0;
|
|
|
|
TREF(parms_cnt) = 0; /* Parameters count */
|
|
|
|
*cli_err_str = 0;
|
|
|
|
cmd_ind = find_verb(cmd);
|
|
|
|
assert(-1 != cmd_ind);
|
|
|
|
gpcmd_qual = cmd_ary[cmd_ind].qual_vals;
|
|
|
|
gpcmd_parm_vals = NULL;
|
|
|
|
gpcmd_verb = cmd_ary[cmd_ind].qual_vals;
|
|
|
|
if (gpcmd_qual)
|
|
|
|
clear_parm_vals(gpcmd_qual, TRUE);
|
|
|
|
func = cmd_ary[cmd_ind].func;
|
|
|
|
/* ----------------------
|
|
|
|
* Parse command options
|
|
|
|
* ----------------------
|
|
|
|
*/
|
|
|
|
do
|
|
|
|
{
|
|
|
|
res = parse_arg(gpcmd_qual, &eof);
|
|
|
|
} while (1 == res);
|
|
|
|
/* -------------------------------------
|
|
|
|
* If parse error, display error string
|
|
|
|
* -------------------------------------
|
|
|
|
*/
|
|
|
|
if (-1 == res)
|
|
|
|
func = 0;
|
|
|
|
else
|
|
|
|
return (0);
|
|
|
|
/* -------------------------
|
|
|
|
* If gettoken returned EOF
|
|
|
|
* -------------------------
|
|
|
|
*/
|
|
|
|
if (eof)
|
|
|
|
return (EOF);
|
|
|
|
else
|
|
|
|
return (ERR_MUNOACTION);
|
|
|
|
}
|
|
|
|
#endif
|