/* * -------------------------------------------- * Copy next token to the token buffer. * Do not advance the token pointer. * * Return: * Token Length * * Side effects: * set eof to <> 0 for EOF condition. * ------------------------------------------------------- */ int cli_look_next_token(int *eof) { int tok_len; char *old_tp; assert(cli_lex_in_ptr); if (((char *) NULL == cli_lex_in_ptr->tp) || (!strlen(cli_lex_in_ptr->tp))) return(0); old_tp = cli_lex_in_ptr->tp; tok_len = cli_gettoken(eof); cli_lex_in_ptr->tp = old_tp; return(tok_len); }
int gtm_main (int argc, char **argv, char **envp) #ifdef __osf__ # pragma pointer_size (restore) #endif { char *ptr, *eq, **p; int eof, parse_ret; int gtmcrypt_errno; # ifdef GTM_SOCKET_SSL_SUPPORT int status; char tlsid_env_name[MAX_TLSID_LEN * 2]; # endif DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; gtmenvp = envp; gtm_dist_ok_to_use = TRUE; common_startup_init(GTM_IMAGE); GTMTRIG_DBG_ONLY(ch_at_trigger_init = &mdb_condition_handler); err_init(stop_image_conditional_core); UNICODE_ONLY(gtm_strToTitle_ptr = >m_strToTitle); GTM_ICU_INIT_IF_NEEDED; /* Note: should be invoked after err_init (since it may error out) and before CLI parsing */ cli_lex_setup(argc, argv); /* put the arguments into buffer, then clean up the token buffer * cli_gettoken() copies all arguments except the first one argv[0] * into the buffer (cli_lex_in_ptr->in_str). * i.e. command line: "/usr/library/V990/mumps -run somefile" * the buffer cli_lex_in_ptr->in_str == "-run somefile" */ if (1 < argc) cli_gettoken(&eof); /* cli_gettoken() extracts the first token into cli_token_buf (in tok_extract()) * which should be done in parse_cmd(), So, reset the token buffer here to make * parse_cmd() starts from the first token */ cli_token_buf[0] = '\0'; /* insert the "MUMPS " in the parsing buffer the buffer is now: * cli_lex_in_ptr->in_str == "MUMPS -run somefile" * we didnot change argv[0] */ ptr = cli_lex_in_ptr->in_str; memmove(strlen("MUMPS ") + ptr, ptr, strlen(ptr) + 1); /* BYPASSOK */ MEMCPY_LIT(ptr, "MUMPS "); /* reset the argument buffer pointer, it's changed in cli_gettoken() call above * do NOT reset to 0(NULL) to avoid fetching cmd line args into buffer again * cli_lex_in_ptr->tp is the pointer to indicate current position in the buffer * cli_lex_in_ptr->in_str */ cli_lex_in_ptr->tp = cli_lex_in_ptr->in_str; parse_ret = parse_cmd(); if (parse_ret && (EOF != parse_ret)) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) parse_ret, 2, LEN_AND_STR(cli_err_str)); if (cli_present("DIRECT_MODE")) invocation_mode = MUMPS_DIRECT; else if (cli_present("RUN")) invocation_mode = MUMPS_RUN; gtm_chk_dist(argv[0]); /* this should be after cli_lex_setup() due to S390 A/E conversion in cli_lex_setup */ init_gtm(); # ifdef GTM_TLS if (MUMPS_COMPILE != invocation_mode) { if ((NULL != (ptr = (char *)getenv(GTM_PASSWD_ENV))) && (0 == strlen(ptr))) { INIT_PROC_ENCRYPTION(NULL, gtmcrypt_errno); if (0 != gtmcrypt_errno) { CLEAR_CRYPTERR_MASK(gtmcrypt_errno); assert(!IS_REPEAT_MSG_MASK(gtmcrypt_errno)); assert((ERR_CRYPTDLNOOPEN == gtmcrypt_errno) || (ERR_CRYPTINIT == gtmcrypt_errno)); if (ERR_CRYPTDLNOOPEN == gtmcrypt_errno) gtmcrypt_errno = ERR_CRYPTDLNOOPEN2; else if (ERR_CRYPTINIT == gtmcrypt_errno) gtmcrypt_errno = ERR_CRYPTINIT2; gtmcrypt_errno = SET_CRYPTERR_MASK(gtmcrypt_errno); GTMCRYPT_REPORT_ERROR(gtmcrypt_errno, rts_error, SIZEOF(GTMCRYPT_ERRLIT) - 1, GTMCRYPT_ERRLIT); /* BYPASSOK */ } } # ifdef GTM_SOCKET_SSL_SUPPORT /* The below logic is for prefetching the password for TLS identifiers that may have been set in the environment. * But, since SSL support for Socket devices is not yet implemented, this logic need not be enabled as of this * writing. When SSL support for socket devices is implemented, the surrounding #ifdef can be removed. */ if (NULL != getenv("gtmcrypt_config")) { /* Environment is configured for SSL/TLS (and/or encryption). Check if any environment variable of the form * `gtmtls_passwd_*' is set to NULL string. If so, nudge the SSL/TLS library to read password(s) from the * user. */ for (p = envp; *p; p++) { ptr = *p; if (0 == MEMCMP_LIT(ptr, GTMTLS_PASSWD_ENV_PREFIX)) { /* At least one environment variable of $gtmtls_passwd_* is found. */ eq = strchr(ptr, '='); if (0 != strlen(eq + 1)) break; /* Set to non-empty string. No need to initialize the library now. */ /* Set to empty string. */ if (NULL == tls_ctx) { if (SS_NORMAL != (status = gtm_tls_loadlibrary())) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0, ERR_TEXT, 2, LEN_AND_STR(dl_err)); } if (NULL == (tls_ctx = gtm_tls_init(GTM_TLS_API_VERSION, GTMTLS_OP_INTERACTIVE_MODE))) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0, ERR_TEXT, 2, LEN_AND_STR(gtm_tls_get_error())); } } assert(NULL != tls_ctx); assert((MAX_TLSID_LEN * 2) > (int)(eq - ptr)); memcpy(tlsid_env_name, ptr, (int)(eq - ptr)); tlsid_env_name[(int)(eq - ptr)] = '\0'; gtm_tls_prefetch_passwd(tls_ctx, tlsid_env_name); } } } # endif } # endif dm_start(); return 0; }
/* * ----------------------------------------------------------- * 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) { func = 0; eof = 0; } else return (0); /* ------------------------- * If gettoken returned EOF * ------------------------- */ if (eof) return (EOF); else return (ERR_CLIERR); }
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); }
/* * --------------------------------------------------------- * 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); }