STATICFNDEF boolean_t process_options(char *option_str, uint4 option_len, boolean_t *isolation, boolean_t *noisolation, boolean_t *consistency, boolean_t *noconsistency) { char local_options[MAX_OPTIONS_LEN]; char *ptr, *strtokptr; if (MAX_OPTIONS_LEN < option_len) { util_out_print_gtmio("Too many options", FLUSH); return FALSE; } memcpy(local_options, option_str, option_len); *isolation = *noisolation = *consistency = *noconsistency = FALSE; ptr = local_options; for ( ; 0 < option_len; ptr++, option_len--) *ptr = TOUPPER(*ptr); ptr = STRTOK_R(local_options, ",", &strtokptr); do { switch (*ptr) { case 'C': if (1 == STRLEN(ptr)) *consistency = TRUE; else { assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_CONSISTENCY)); *consistency = TRUE; } break; case 'I': if (1 == STRLEN(ptr)) *isolation = TRUE; else { assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_ISOLATION)); *isolation = TRUE; } break; case 'N': assert('O' == *(ptr + 1)); if ('C' == *(ptr + 2)) { assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_NOCONSISTENCY)); *noconsistency = TRUE; } else { assert('I' == *(ptr + 2)); assert(0 == MEMCMP_LIT(ptr, HASHT_OPT_NOISOLATION)); *noisolation = TRUE; } break; default: assert(FALSE); /* Parsing should have found invalid command */ break; } } while (ptr = STRTOK_R(NULL, ",", &strtokptr)); return !((*isolation && *noisolation) || (*consistency && *noconsistency)); }
void compile_source_file(unsigned short flen, char *faddr) { plength plen; mval fstr, ret; int i; unsigned char *p; error_def (ERR_FILEPARSE); error_def (ERR_FILENOTFND); error_def (ERR_ERRORSUMMARY); if (MAX_FBUFF < flen) { dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, flen, faddr); dollar_zcstatus = ERR_ERRORSUMMARY; } else { fstr.mvtype = MV_STR; fstr.str.addr = faddr; fstr.str.len = flen; ESTABLISH(source_ch); tt_so_do_once = FALSE; for (i = 0 ; ; i++) { plen.p.pint = op_fnzsearch(&fstr, 0, &ret); if (!ret.str.len) { if (!i) { dec_err(VARLSTCNT(4) ERR_FILENOTFND, 2, fstr.str.len, fstr.str.addr); dollar_zcstatus = ERR_ERRORSUMMARY; } break; } assert(ret.mvtype == MV_STR); assert(ret.str.len <= MAX_FBUFF); source_name_len = ret.str.len; memcpy(source_file_name, ret.str.addr, source_name_len); source_file_name[source_name_len] = 0; p = &source_file_name[plen.p.pblk.b_dir]; if ((plen.p.pblk.b_dir >= sizeof("/dev/") - 1) && !MEMCMP_LIT(source_file_name, "/dev/")) tt_so_do_once = TRUE; else if (plen.p.pblk.b_ext != 2 || ('M' != p[plen.p.pblk.b_name + 1] && 'm' != p[plen.p.pblk.b_name + 1])) { dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, source_name_len, source_file_name); dollar_zcstatus = ERR_ERRORSUMMARY; continue; } if (compiler_startup()) dollar_zcstatus = ERR_ERRORSUMMARY; if (tt_so_do_once) break; } REVERT; } }
/*--------------------------- * 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; }
void op_gvincr(mval *increment, mval *result) { unsigned char buff[MAX_ZWR_KEY_SZ], *end; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* If specified var name is global ^%Y*, the name is illegal to use in a SET or KILL command, only GETs are allowed */ if ((RESERVED_NAMESPACE_LEN <= gv_currkey->end) && (0 == MEMCMP_LIT(gv_currkey->base, RESERVED_NAMESPACE))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_PCTYRESERVED); if (gv_cur_region->read_only) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region)); if ((TREF(gv_last_subsc_null) || TREF(gv_some_subsc_null)) && (ALWAYS != gv_cur_region->null_subs)) sgnl_gvnulsubsc(); assert(gv_currkey->end + 1 <= gv_cur_region->max_key_size); MV_FORCE_NUM(increment); switch (gv_cur_region->dyn.addr->acc_meth) { case dba_bg: case dba_mm: gvcst_incr(increment, result); break; case dba_cm: gvcmx_increment(increment, result); break; case dba_usr: /* $INCR not supported for DDP/USR access method */ if (0 == (end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE))) end = &buff[MAX_ZWR_KEY_SZ - 1]; rts_error_csa(CSA_ARG(NULL) VARLSTCNT(10) ERR_UNIMPLOP, 0, ERR_TEXT, 2, LEN_AND_LIT("GTCM DDP server does not support $INCREMENT"), ERR_GVIS, 2, end - buff, buff, ERR_TEXT, 2, REG_LEN_STR(gv_cur_region)); break; default: assertpro(FALSE); } assert(MV_DEFINED(result)); }
void mu_signal_process(char *command, int signal) { unsigned short slen; int len, toprocess_id, save_errno; char buff[256]; error_def(ERR_MUPCLIERR); error_def(ERR_MUPIPSIG); slen = sizeof(buff); if (!cli_get_str("ID", buff, &slen)) mupip_exit(ERR_MUPCLIERR); len = slen; toprocess_id = asc2i((uchar_ptr_t)buff, len); if (toprocess_id < 0) { util_out_print("Error converting !AD to a number", FLUSH, len, buff); mupip_exit(ERR_MUPCLIERR); } else { if (-1 == kill(toprocess_id, signal)) { save_errno = errno; util_out_print("Error issuing !AD to process !UL: !AZ", FLUSH, LEN_AND_STR(command), toprocess_id, STRERROR(errno)); } else { util_out_print("!AD issued to process !UL", FLUSH, LEN_AND_STR(command), toprocess_id); if (!MEMCMP_LIT(command, STOP_STR)) { send_msg(VARLSTCNT(9) ERR_MUPIPSIG, 7, LEN_AND_STR(command), signal, process_id, process_id, toprocess_id, toprocess_id); } } } return; }
/* Note: Need condition handler to clean-up allocated structures and close intput file in the event of an error */ struct extcall_package_list *exttab_parse(mval *package) { int parameter_alloc_values[MAX_ACTUALS], parameter_count, ret_pre_alloc_val, i, fclose_res; int len, keywordlen; boolean_t is_input[MAX_ACTUALS], is_output[MAX_ACTUALS], got_status; mstr callnam, rtnnam, clnuprtn; mstr val, trans; void_ptr_t pakhandle; enum gtm_types ret_tok, parameter_types[MAX_ACTUALS], pr; char str_buffer[MAX_TABLINE_LEN], *tbp, *end; char str_temp_buffer[MAX_TABLINE_LEN]; FILE *ext_table_file_handle; struct extcall_package_list *pak; struct extcall_entry_list *entry_ptr; /* First, construct package name environment variable */ memcpy(str_buffer, PACKAGE_ENV_PREFIX, SIZEOF(PACKAGE_ENV_PREFIX)); tbp = &str_buffer[SIZEOF(PACKAGE_ENV_PREFIX) - 1]; if (package->str.len) { /* guaranteed by compiler */ assert(package->str.len < MAX_NAME_LENGTH - SIZEOF(PACKAGE_ENV_PREFIX) - 1); *tbp++ = '_'; memcpy(tbp, package->str.addr, package->str.len); tbp += package->str.len; } *tbp = 0; /* Now we have the environment name, lookup file name */ ext_table_file_name = GETENV(str_buffer); if (NULL == ext_table_file_name) { /* Environment variable for the package not found */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTENV, 2, LEN_AND_STR(str_buffer)); } ext_table_file_handle = Fopen(ext_table_file_name, "r"); if (NULL == ext_table_file_handle) { /* Package's external call table could not be found */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTOPN, 2, LEN_AND_STR(ext_table_file_name)); } ext_source_line_num = 0; /* Pick-up name of shareable library */ tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) { /* External call table is a null file */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCCTNULLF, 2, package->str.len, package->str.addr); } STRNCPY_STR(str_temp_buffer, str_buffer, MAX_TABLINE_LEN); val.addr = str_temp_buffer; val.len = STRLEN(str_temp_buffer); /* Need to copy the str_buffer into another temp variable since * TRANS_LOG_NAME requires input and output buffers to be different. * If there is an env variable present in the pathname, TRANS_LOG_NAME * expands it and return SS_NORMAL. Else it returns SS_NOLOGNAM. * Instead of checking 2 return values, better to check against SS_LOG2LONG * which occurs if the pathname is too long after any kind of expansion. */ if (SS_LOG2LONG == TRANS_LOG_NAME(&val, &trans, str_buffer, SIZEOF(str_buffer), dont_sendmsg_on_log2long)) { /* Env variable expansion in the pathname caused buffer overflow */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_LOGTOOLONG, 3, val.len, val.addr, SIZEOF(str_buffer) - 1); } pakhandle = fgn_getpak(str_buffer, INFO); if (NULL == pakhandle) { /* Unable to obtain handle to the shared library */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_ZCUNAVAIL, 2, package->str.len, package->str.addr); } pak = get_memory(SIZEOF(*pak)); pak->first_entry = 0; put_mstr(&package->str, &pak->package_name); pak->package_handle = pakhandle; pak->package_clnup_rtn = NULL; len = STRLEN("GTMSHLIBEXIT"); /* At this point, we have a valid package, pointed to by pak */ # ifdef DEBUG_EXTCALL FPRINTF(stderr, "GT.M external call opened package name: %s\n", pak->package_name.addr); # endif for (;;) { star_found = FALSE; tbp = read_table(LIT_AND_LEN(str_buffer), ext_table_file_handle); if (NULL == tbp) break; tbp = exttab_scan_space(str_buffer); /* Empty line? */ if (!*tbp) continue; /* No, must be entryref or keyword */ end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); keywordlen = end - tbp; end = exttab_scan_space(end); if ('=' == *end) { /* Keyword before '=' has a string of size == STRLEN("GTMSHLIBEXIT") */ if (keywordlen == len) { if (0 == MEMCMP_LIT(tbp, "GTMSHLIBEXIT")) { /* Skip past the '=' char */ tbp = exttab_scan_space(end + 1); if (*tbp) { /* We have a cleanup routine name */ clnuprtn.addr = tbp; clnuprtn.len = scan_ident(tbp) - tbp; clnuprtn.addr[clnuprtn.len] = 0; pak->package_clnup_rtn = (clnupfptr)fgn_getrtn(pak->package_handle, &clnuprtn, ERROR); } else ext_stx_error(ERR_ZCCLNUPRTNMISNG, ext_table_file_name); continue; } } ext_stx_error(ERR_ZCINVALIDKEYWORD, ext_table_file_name); continue; } if ('^' == *end) { end++; end = scan_ident(end); if (!end) ext_stx_error(ERR_ZCENTNAME, ext_table_file_name); } rtnnam.addr = tbp; rtnnam.len = INTCAST(end - tbp); tbp = exttab_scan_space(end); if (':' != *tbp++) ext_stx_error(ERR_ZCCOLON, ext_table_file_name); /* Get return type */ ret_tok = scan_keyword(&tbp); /* Check for legal return type */ switch (ret_tok) { case gtm_status: case gtm_void: case gtm_int: case gtm_uint: case gtm_long: case gtm_ulong: case gtm_char_star: case gtm_float_star: case gtm_string_star: case gtm_int_star: case gtm_uint_star: case gtm_long_star: case gtm_ulong_star: case gtm_double_star: case gtm_char_starstar: case gtm_pointertofunc: case gtm_pointertofunc_star: case gtm_jboolean: case gtm_jint: case gtm_jlong: case gtm_jfloat: case gtm_jdouble: case gtm_jstring: case gtm_jbyte_array: case gtm_jbig_decimal: break; default: ext_stx_error(ERR_ZCRTNTYP, ext_table_file_name); } got_status = (ret_tok == gtm_status); /* Get call name */ if ('[' == *tbp) { if (star_found) ret_pre_alloc_val = scan_array_bound(&tbp,ret_tok); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for the * extra terminating NULL. Negative values would have been caught by scan_array_bound() above. */ if (ret_pre_alloc_val > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else ret_pre_alloc_val = -1; /* Fix C9E12-002681 */ if ('%' == *tbp) *tbp = '_'; end = scan_ident(tbp); if (!end) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); callnam.addr = tbp; callnam.len = INTCAST(end - tbp); tbp = exttab_scan_space(end); tbp = exttab_scan_space(tbp); for (parameter_count = 0;(MAX_ACTUALS > parameter_count) && (')' != *tbp); parameter_count++) { star_found = FALSE; /* Must have comma if this is not the first parameter, otherwise '(' */ if (((0 == parameter_count)?'(':',') != *tbp++) ext_stx_error(ERR_ZCRPARMNAME, ext_table_file_name); tbp = exttab_scan_space(tbp); /* Special case: () is ok */ if ((0 == parameter_count) && (*tbp == ')')) break; /* Looking for an I, an O or an IO */ is_input[parameter_count] = is_output[parameter_count] = FALSE; if ('I' == *tbp) { is_input[parameter_count] = TRUE; tbp++; } if ('O' == *tbp) { is_output[parameter_count] = TRUE; tbp++; } if (((FALSE == is_input[parameter_count]) && (FALSE == is_output[parameter_count])) ||(':' != *tbp++)) ext_stx_error(ERR_ZCRCALLNAME, ext_table_file_name); /* Scanned colon--now get type */ pr = scan_keyword(&tbp); if (gtm_notfound == pr) ext_stx_error(ERR_ZCUNTYPE, ext_table_file_name); if (gtm_status == pr) { /* Only one type "status" allowed per call */ if (got_status) ext_stx_error(ERR_ZCMLTSTATUS, ext_table_file_name); else got_status = TRUE; } parameter_types[parameter_count] = pr; if ('[' == *tbp) { if (star_found && !is_input[parameter_count]) parameter_alloc_values[parameter_count] = scan_array_bound(&tbp, pr); else ext_stx_error(ERR_ZCPREALLVALPAR, ext_table_file_name); /* We should allow the pre-allocated value upto to the maximum string size (MAX_STRLEN) plus 1 for * the extra terminating NULL. Negative values would have been caught by scan_array_bound() above. */ if (parameter_alloc_values[parameter_count] > MAX_STRLEN + 1) ext_stx_error(ERR_ZCPREALLVALINV, ext_table_file_name); } else parameter_alloc_values[parameter_count] = -1; tbp = exttab_scan_space(tbp); } entry_ptr = get_memory(SIZEOF(*entry_ptr)); entry_ptr->next_entry = pak->first_entry; pak->first_entry = entry_ptr; entry_ptr->return_type = ret_tok; entry_ptr->ret_pre_alloc_val = ret_pre_alloc_val; entry_ptr->argcnt = parameter_count; entry_ptr->input_mask = array_to_mask(is_input, parameter_count); entry_ptr->output_mask = array_to_mask(is_output, parameter_count); entry_ptr->parms = get_memory(parameter_count * SIZEOF(entry_ptr->parms[0])); entry_ptr->param_pre_alloc_size = get_memory(parameter_count * SIZEOF(intszofptr_t)); entry_ptr->parmblk_size = (SIZEOF(void *) * parameter_count) + SIZEOF(intszofptr_t); for (i = 0 ; i < parameter_count; i++) { entry_ptr->parms[i] = parameter_types[i]; assert(gtm_void != parameter_types[i]); entry_ptr->parmblk_size += parm_space_needed[parameter_types[i]]; entry_ptr->param_pre_alloc_size[i] = parameter_alloc_values[i]; } put_mstr(&rtnnam, &entry_ptr->entry_name); put_mstr(&callnam, &entry_ptr->call_name); /* The reason for passing INFO severity is that PROFILE has several routines listed in * the external call table that are not in the shared library. PROFILE folks would * rather see info/warning messages for such routines at shared library open time, * than error out. These unimplemented routines, they say were not being called from * the application and wouldn't cause any application failures. If we fail to open * the shared libary, or we fail to locate a routine that is called from the * application, we issue rts_error message (in extab_parse.c). */ entry_ptr->fcn = fgn_getrtn(pak->package_handle, &entry_ptr->call_name, INFO); # ifdef DEBUG_EXTCALL FPRINTF(stderr, " package entry point: %s, address: %x\n", entry_ptr->entry_name.addr, entry_ptr->fcn); # endif } FCLOSE(ext_table_file_handle, fclose_res); return pak; }
void compile_source_file(unsigned short flen, char *faddr, boolean_t MFtIsReqd) { plength plen; mval fstr, ret; int i, rc; unsigned char *p; boolean_t wildcarded, dm_action; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (MAX_FBUFF < flen) { dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, flen, faddr); TREF(dollar_zcstatus) = ERR_ERRORSUMMARY; } else { object_file_des = FD_INVALID; fstr.mvtype = MV_STR; fstr.str.addr = faddr; fstr.str.len = flen; ESTABLISH(source_ch); tt_so_do_once = FALSE; zsrch_clr(STRM_COMP_SRC); /* Clear any existing search cache */ for (i = 0; ; i++) { plen.p.pint = op_fnzsearch(&fstr, STRM_COMP_SRC, 0, &ret); if (!ret.str.len) { if (!i) { dec_err(VARLSTCNT(4) ERR_FILENOTFND, 2, fstr.str.len, fstr.str.addr); TREF(dollar_zcstatus) = ERR_ERRORSUMMARY; } break; } assert(ret.mvtype == MV_STR); assert(ret.str.len <= MAX_FBUFF); source_name_len = ret.str.len; memcpy(source_file_name, ret.str.addr, source_name_len); source_file_name[source_name_len] = 0; p = &source_file_name[plen.p.pblk.b_dir]; if ((plen.p.pblk.b_dir >= SIZEOF("/dev/") - 1) && !MEMCMP_LIT(source_file_name, "/dev/")) tt_so_do_once = TRUE; else if (MFtIsReqd && (plen.p.pblk.b_ext != 2 || ('M' != p[plen.p.pblk.b_name + 1] && 'm' != p[plen.p.pblk.b_name + 1]))) { /* M filetype is required but not present */ dec_err(VARLSTCNT(4) ERR_FILEPARSE, 2, source_name_len, source_file_name); TREF(dollar_zcstatus) = ERR_ERRORSUMMARY; continue; } if (compiler_startup()) TREF(dollar_zcstatus) = ERR_ERRORSUMMARY; if (FD_INVALID != object_file_des) { CLOSEFILE_RESET(object_file_des, rc); /* resets "object_file_des" to FD_INVALID */ if (-1 == rc) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_OBJFILERR, 2, object_name_len, object_file_name, errno); } if (tt_so_do_once) break; } REVERT; } }
void op_zedit(mval *v, mval *p) { char *edt; char es[MAX_FBUFF + 1], typ, *ptr; short path_len, tslash; int objcnt; int waitid; unsigned int childid, status; #ifdef _BSD union wait wait_status; #endif bool has_ext, exp_dir; parse_blk pblk; mstr src; zro_ent *sp, *srcdir; struct sigaction act, intr; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (!editor.len) { edt = GETENV("EDITOR"); if (!edt) edt = "editor"; rts_error(VARLSTCNT(4) ERR_FILENOTFND, 2, LEN_AND_STR(edt)); } MV_FORCE_STR(v); MV_FORCE_STR(p); src.len = v->str.len; src.addr = v->str.addr; if (0 == src.len) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr); memset(&pblk, 0, SIZEOF(pblk)); pblk.buffer = es; pblk.buff_size = MAX_FBUFF; status = parse_file(&src, &pblk); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZEDFILSPEC, 2, src.len, src.addr, status); has_ext = 0 != (pblk.fnb & F_HAS_EXT); exp_dir = 0 != (pblk.fnb & F_HAS_DIR); if (!(pblk.fnb & F_HAS_NAME)) { assert(!has_ext); rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, pblk.b_esl, pblk.buffer); } if (!exp_dir) { memmove(&es[0], pblk.l_name, pblk.b_name + pblk.b_ext); path_len = pblk.b_name + pblk.b_ext; ptr = es; } else { path_len = pblk.b_esl; ptr = pblk.l_name; } typ = 0; if (!has_ext) { if ('.' != *ptr) { typ = STR_LIT_LEN(DOTM); if (path_len + typ > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es); memcpy(&es[path_len], DOTM, STR_LIT_LEN(DOTM)); path_len += typ; } } else { if ((STR_LIT_LEN(DOTOBJ) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTOBJ)) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, path_len, es); else if ((STR_LIT_LEN(DOTM) == pblk.b_ext) && !MEMCMP_LIT(ptr + pblk.b_name, DOTM)) typ = STR_LIT_LEN(DOTM); } dollar_zsource.str.addr = es; dollar_zsource.str.len = path_len - typ; s2pool(&dollar_zsource.str); es[path_len] = 0; if (!exp_dir) { src.addr = es; src.len = path_len; srcdir = (zro_ent *)0; zro_search(0, 0, &src, &srcdir, TRUE); if (NULL == srcdir) { /* find the first source directory */ objcnt = (TREF(zro_root))->count; for (sp = TREF(zro_root) + 1; (NULL == srcdir) && (0 < objcnt--); ++sp) { if (ZRO_TYPE_OBJECT == sp->type) { sp++; assert(ZRO_TYPE_COUNT == sp->type); if (0 != sp->count) srcdir = sp + 1; } else { /* shared library entries (ZRO_TYPE_OBJLIB) do not have source directories */ assert(ZRO_TYPE_OBJLIB == sp->type); } } } if (srcdir && srcdir->str.len) { assert(ZRO_TYPE_SOURCE == srcdir->type); tslash = ('/' == srcdir->str.addr[srcdir->str.len - 1]) ? 0 : 1; if (path_len + srcdir->str.len + tslash >= SIZEOF(es)) rts_error(VARLSTCNT(4) ERR_ZEDFILSPEC, 2, src.len, src.addr); memmove(&es[ srcdir->str.len + tslash], &es[0], path_len); if (tslash) es[ srcdir->str.len ] = '/'; memcpy(&es[0], srcdir->str.addr, srcdir->str.len); path_len += srcdir->str.len + tslash; es[ path_len ] = 0; } } flush_pio(); if (tt == io_std_device.in->type) resetterm(io_std_device.in); /* ignore interrupts */ sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = SIG_IGN; sigaction(SIGINT, &act, &intr); childid = fork(); /* BYPASSOK: we exec immediately, no FORK_CLEAN needed */ if (childid) { waitid = (int)childid; for (;;) { #ifdef _BSD WAIT(&wait_status, waitid); #else WAIT((int *)&status, waitid); #endif if (waitid == (int)childid) break; if (-1 == waitid) break; } if (-1 != waitid) dollar_zeditor = 0; else dollar_zeditor = errno; /* restore interrupt handler */ sigaction(SIGINT, &intr, 0); if (tt == io_std_device.in->type) setterm(io_std_device.in); } else { EXECL(editor.addr, editor.addr, es, 0); exit(-1); } }
void repl_inst_dump_jnlpoolctl(jnlpool_ctl_ptr_t jnlpool_ctl) { char *string; util_out_print("", TRUE); PRINT_DASHES; util_out_print(JNLPOOLCTL_TITLE_STRING, TRUE); PRINT_DASHES; PRINT_OFFSET_HEADER; assert(0 == offsetof(jnlpool_ctl_struct, jnlpool_id)); /* The following offsetof calculations depend on this */ PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, label[0]), SIZEOF(jnlpool_ctl->jnlpool_id.label)); util_out_print( PREFIX_JNLPOOLCTL "Label !11AD", TRUE, GDS_LABEL_SZ - 1, jnlpool_ctl->jnlpool_id.label); PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, pool_type), SIZEOF(jnlpool_ctl->jnlpool_id.pool_type)); string = (JNLPOOL_SEGMENT == jnlpool_ctl->jnlpool_id.pool_type) ? "JNLPOOL" : ((RECVPOOL_SEGMENT == jnlpool_ctl->jnlpool_id.pool_type) ? "RECVPOOL" : "UNKNOWN"); if (MEMCMP_LIT(string, "UNKNOWN")) util_out_print( PREFIX_JNLPOOLCTL "Type !R22AZ", TRUE, string); else { util_out_print( PREFIX_JNLPOOLCTL "Type !R22AZ [0x!XL]", TRUE, string, jnlpool_ctl->jnlpool_id.pool_type); } PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, now_running[0]), SIZEOF(jnlpool_ctl->jnlpool_id.now_running)); util_out_print( PREFIX_JNLPOOLCTL "GT.M Version !R30AZ", TRUE, jnlpool_ctl->jnlpool_id.now_running); PRINT_OFFSET_PREFIX(offsetof(replpool_identifier, instfilename[0]), SIZEOF(jnlpool_ctl->jnlpool_id.instfilename)); if (22 >= strlen(jnlpool_ctl->jnlpool_id.instfilename)) { util_out_print( PREFIX_JNLPOOLCTL "Instance file name !R22AZ", TRUE, jnlpool_ctl->jnlpool_id.instfilename); } else util_out_print( PREFIX_JNLPOOLCTL "Instance file name !AZ", TRUE, jnlpool_ctl->jnlpool_id.instfilename); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, start_jnl_seqno), SIZEOF(jnlpool_ctl->start_jnl_seqno)); util_out_print( PREFIX_JNLPOOLCTL "Start Journal Seqno !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->start_jnl_seqno, &jnlpool_ctl->start_jnl_seqno); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnl_seqno), SIZEOF(jnlpool_ctl->jnl_seqno)); util_out_print( PREFIX_JNLPOOLCTL "Journal Seqno !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->jnl_seqno, &jnlpool_ctl->jnl_seqno); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, last_triple_seqno), SIZEOF(jnlpool_ctl->last_triple_seqno)); util_out_print( PREFIX_JNLPOOLCTL "Last Triple Seqno !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->last_triple_seqno, &jnlpool_ctl->last_triple_seqno); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnldata_base_off), SIZEOF(jnlpool_ctl->jnldata_base_off)); util_out_print( PREFIX_JNLPOOLCTL "Journal Data Base Offset !10UL [0x!XL]", TRUE, jnlpool_ctl->jnldata_base_off, jnlpool_ctl->jnldata_base_off); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, jnlpool_size), SIZEOF(jnlpool_ctl->jnlpool_size)); util_out_print( PREFIX_JNLPOOLCTL "Journal Pool Size (in bytes) !10UL [0x!XL]", TRUE, jnlpool_ctl->jnlpool_size, jnlpool_ctl->jnlpool_size); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, early_write_addr), SIZEOF(jnlpool_ctl->early_write_addr)); util_out_print( PREFIX_JNLPOOLCTL "Early Write Offset !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->early_write_addr, &jnlpool_ctl->early_write_addr); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, write_addr), SIZEOF(jnlpool_ctl->write_addr)); util_out_print( PREFIX_JNLPOOLCTL "Absolute Write Offset !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->write_addr, &jnlpool_ctl->write_addr); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, write), SIZEOF(jnlpool_ctl->write)); util_out_print( PREFIX_JNLPOOLCTL "Relative Write Offset !10UL [0x!XL]", TRUE, jnlpool_ctl->write, jnlpool_ctl->write); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, upd_disabled), SIZEOF(jnlpool_ctl->upd_disabled)); PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Updates Disabled !R22AZ", jnlpool_ctl->upd_disabled, -1); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, primary_is_dualsite), SIZEOF(jnlpool_ctl->primary_is_dualsite)); PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Primary is Dual Site !R22AZ", jnlpool_ctl->primary_is_dualsite, -1); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, secondary_is_dualsite), SIZEOF(jnlpool_ctl->secondary_is_dualsite)); PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Secondary is Dual Site !R22AZ", jnlpool_ctl->secondary_is_dualsite, -1); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, lastwrite_len), SIZEOF(jnlpool_ctl->lastwrite_len)); util_out_print( PREFIX_JNLPOOLCTL "Last Write Length (in bytes) !10UL [0x!XL]", TRUE, jnlpool_ctl->lastwrite_len, jnlpool_ctl->lastwrite_len); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, send_losttn_complete), SIZEOF(jnlpool_ctl->send_losttn_complete)); PRINT_BOOLEAN(PREFIX_JNLPOOLCTL "Send LostTN Complete !R22AZ", jnlpool_ctl->send_losttn_complete, -1); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, primary_instname[0]), SIZEOF(jnlpool_ctl->primary_instname)); util_out_print( PREFIX_JNLPOOLCTL "Primary Instance Name !R20AZ", TRUE, jnlpool_ctl->primary_instname); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, max_zqgblmod_seqno), SIZEOF(jnlpool_ctl->max_zqgblmod_seqno)); util_out_print( PREFIX_JNLPOOLCTL "Zqgblmod Seqno !20@UQ [0x!16@XQ]", TRUE, &jnlpool_ctl->max_zqgblmod_seqno, &jnlpool_ctl->max_zqgblmod_seqno); PRINT_OFFSET_PREFIX(offsetof(jnlpool_ctl_struct, this_proto_ver), SIZEOF(jnlpool_ctl->this_proto_ver)); util_out_print( PREFIX_JNLPOOLCTL "Source Server Protocol Version !3UL [0x!2XB]", TRUE, jnlpool_ctl->this_proto_ver, jnlpool_ctl->this_proto_ver); }
socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified) { socket_struct *socketptr; socket_struct *prev_socketptr; socket_struct *socklist_head; boolean_t passive = FALSE; unsigned short port; int ii, save_errno, tmplen, errlen, sockaddrlen; char temp_addr[SA_MAXLITLEN], protocolstr[6], *adptr; const char *errptr; struct addrinfo *ai_ptr; struct addrinfo hints, *addr_info_ptr = NULL; #ifndef VMS struct sockaddr_un *sa_un_ptr, sa_un_trans; mval localpath; mstr transpath; int trans_status; #endif enum socket_protocol protocol; int af; int sd; int errcode; char host_buffer[NI_MAXHOST]; char port_buffer[NI_MAXSERV]; int port_buffer_len; int colon_cnt, protooffset; char *last_2colon = NULL; int addrlen; GTM_SOCKLEN_TYPE tmp_addrlen; if (0 > file_des) { /* no socket descriptor yet */ memset(&hints, 0, SIZEOF(hints)); protooffset = colon_cnt = 0; sockaddrlen = STRLEN(sockaddr); for (ii = sockaddrlen - 1; 0 <= ii; ii--) { if (SEPARATOR == sockaddr[ii]) { colon_cnt++; if (1 == colon_cnt) protooffset = ii + 1; else { last_2colon = &sockaddr[ii]; break; } } } if (0 == colon_cnt) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC); return NULL; } tmplen = sockaddrlen - protooffset; if (SIZEOF(protocolstr) <= tmplen) { /* last piece just too big to be valid */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]); return NULL; } lower_to_upper((uchar_ptr_t)protocolstr, (uchar_ptr_t)&sockaddr[protooffset], tmplen); if (((SIZEOF("TCP") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "TCP"))) protocol = socket_tcpip; # ifndef VMS else if (((SIZEOF("LOCAL") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "LOCAL"))) protocol = socket_local; # endif else { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]); return NULL; } if (socket_tcpip == protocol) { if (1 == colon_cnt) { /* for listening socket or broadcasting socket */ if (!listen_specified || (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, protocolstr) < 2)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC); return NULL; } passive = TRUE; /* We always first try using IPv6 address, if supported */ af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET); if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP))) { /* Try creating IPv4 socket */ af = AF_INET; if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP))) { save_errno = errno; errptr = (char *)STRERROR(save_errno); errlen = STRLEN(errptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr); return NULL; } } SERVER_HINTS(hints, af); port_buffer_len = 0; I2A(port_buffer, port_buffer_len, port); port_buffer[port_buffer_len]='\0'; if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr))) { close(sd); RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return NULL; } SOCKET_ALLOC(socketptr); socketptr->local.port = port; socketptr->temp_sd = sd; socketptr->sd = FD_INVALID; ai_ptr = &(socketptr->local.ai); memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo)); SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr); ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr); ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen; ai_ptr->ai_next = NULL; freeaddrinfo(addr_info_ptr); } else { /* connection socket */ assert(2 == colon_cnt); if (listen_specified || (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, protocolstr) < 2)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC); return NULL; } /* for connection socket */ SPRINTF(port_buffer, "%hu", port); addrlen = last_2colon - sockaddr; if ('[' == sockaddr[0]) { if (NULL == memchr(sockaddr, ']', addrlen)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC); return NULL; } addrlen -= 2; memcpy(temp_addr, &sockaddr[1], addrlen); } else memcpy(temp_addr, sockaddr, addrlen); temp_addr[addrlen] = 0; CLIENT_HINTS(hints); if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr))) { RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return NULL; } /* we will test all address families in iosocket_connect() */ SOCKET_ALLOC(socketptr); socketptr->remote.ai_head = addr_info_ptr; socketptr->remote.port = port; socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */ } # ifndef VMS } else if (socket_local == protocol) { /* should we get_full_path first */ /* check protooffset < sizeof sun_path */ /* protooffset is after colon */ SOCKET_ALLOC(socketptr); socketptr->protocol = socket_local; sa_un_ptr = malloc(SIZEOF(struct sockaddr_un)); sa_un_ptr->sun_family = AF_UNIX; MV_INIT_STRING(&localpath, protooffset - 1, sockaddr); trans_status = TRANS_LOG_NAME(&localpath.str, &transpath, sa_un_trans.sun_path, (int)SIZEOF(sa_un_trans.sun_path), dont_sendmsg_on_log2long); if (SS_LOG2LONG == trans_status) { /* if LOG2LONG, returned len not valid so report untranslated length */ SOCKET_FREE(socketptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ADDRTOOLONG, 4, localpath.str.len, localpath.str.addr, localpath.str.len, SIZEOF(sa_un_trans.sun_path)); return NULL; } memcpy(sa_un_ptr->sun_path, transpath.addr, transpath.len); sa_un_ptr->sun_path[transpath.len] = '\0'; if (listen_specified) { passive = TRUE; socketptr->local.sa = (struct sockaddr *)sa_un_ptr; socketptr->local.ai.ai_family = AF_UNIX; socketptr->local.ai.ai_socktype = SOCK_STREAM; socketptr->local.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset; if (-1 == (sd = socket(AF_UNIX, SOCK_STREAM, 0))) { save_errno = errno; SOCKET_FREE(socketptr); errptr = (char *)STRERROR(save_errno); errlen = STRLEN(errptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr); return NULL; } socketptr->temp_sd = sd; socketptr->sd = FD_INVALID; } else { socketptr->remote.sa = (struct sockaddr *)sa_un_ptr; /* setup remote fields */ socketptr->remote.ai.ai_family = AF_UNIX; socketptr->remote.ai.ai_socktype = SOCK_STREAM; socketptr->remote.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset; socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */ } # endif } else
/* given the bounds of a particular subscript (assumed correct), we convert the subscript into * a form that mimics the GDS representation of that subscript */ boolean_t convert_key_to_db(mval *gvn, int start, int stop, gv_key *gvkey, unsigned char **key) { mval tmpval, *mvptr, dollarcharmval; int isrc; char strbuff[MAX_KEY_SZ + 1], *str, *str_top; char fnname[MAX_LEN_FOR_CHAR_FUNC], *c; boolean_t is_zchar; int4 num; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (ISDIGIT_ASCII(gvn->str.addr[start]) || '-' == gvn->str.addr[start] || '+' == gvn->str.addr[start] || '.' == gvn->str.addr[start]) { /* convert a number */ tmpval.str.addr = &gvn->str.addr[start]; tmpval.str.len = stop - start; tmpval.mvtype = MV_STR; mvptr = &tmpval; MV_FORCE_NUM(mvptr); if (MVTYPE_IS_NUM_APPROX(tmpval.mvtype)) return FALSE; mval2subsc(&tmpval, gvkey, gv_cur_region->std_null_coll); } else { /* It's a string. We need to accept strings, $CHAR args, and $ZCHAR args. */ str = &strbuff[0]; str_top = &strbuff[0] + MAX_KEY_SZ + 1; /* MV_NUM_APPROX needed by mval2subsc to skip val_iscan call */ tmpval.mvtype = (MV_STR | MV_NUM_APPROX); for (isrc = start; isrc < stop; ) { if ('_' == gvn->str.addr[isrc]) { /* We can skip this case, since we're already "appending" * the strings on the lhs to the string on the rhs. */ isrc++; } else if ('$' == gvn->str.addr[isrc]) { /* We determine if what comes after is a Char or a ZCHar, * and copy over accordingly */ c = &fnname[0]; isrc++; /* skip the '$' */ while ('(' != gvn->str.addr[isrc]) *c++ = TOUPPER(gvn->str.addr[isrc++]); *c = '\0'; assert(strlen(c) <= MAX_LEN_FOR_CHAR_FUNC - 1); if (!MEMCMP_LIT(fnname, "ZCHAR") || !MEMCMP_LIT(fnname, "ZCH")) is_zchar = TRUE; else if (!MEMCMP_LIT(fnname, "CHAR") || !MEMCMP_LIT(fnname, "C")) is_zchar = FALSE; else assert(FALSE); /* Parse the arguments */ isrc++; /* skip the '(' */ while (TRUE) { /* Inside the argument list for $[Z]CHAR */ /* STRTOUL will stop at the ',' or ')' */ num = (int4)STRTOUL(&gvn->str.addr[isrc], NULL, 10); # ifdef UNICODE_SUPPORTED if (!is_zchar && is_gtm_chset_utf8) op_fnchar(2, &dollarcharmval, num); else # endif op_fnzchar(2, &dollarcharmval, num); assert(MV_IS_STRING(&dollarcharmval)); if (dollarcharmval.str.len) { if (str + dollarcharmval.str.len > str_top) /* String overflows capacity. */ return FALSE; memcpy(str, dollarcharmval.str.addr, dollarcharmval.str.len); str += dollarcharmval.str.len; } /* move on to the next argument */ while (',' != gvn->str.addr[isrc] && ')' != gvn->str.addr[isrc]) isrc++; if (',' == gvn->str.addr[isrc]) isrc++; else { assert(')' == gvn->str.addr[isrc]); isrc++; /* skip ')' */ break; } } } else if ('"' == gvn->str.addr[isrc]) { /* Assume valid string. */ isrc++; while (isrc < stop && !('"' == gvn->str.addr[isrc] && '"' != gvn->str.addr[isrc+1])) { if (str == str_top) /* String overflows capacity. */ return FALSE; if ('"' == gvn->str.addr[isrc] && '"' == gvn->str.addr[isrc+1]) { *str++ = '"'; isrc += 2; } else *str++ = gvn->str.addr[isrc++]; } isrc++; /* skip over '"' */ } else assert(FALSE); } tmpval.str.addr = strbuff; tmpval.str.len = str - strbuff; DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = TRUE;) mval2subsc(&tmpval, gvkey, gv_cur_region->std_null_coll); DEBUG_ONLY(TREF(skip_mv_num_approx_assert) = FALSE;) }
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; }
uint4 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog) { sm_uc_ptr_t old_base[2], mmap_retaddr; boolean_t was_crit, is_mm; char buff[DISK_BLOCK_SIZE]; int result, save_errno, status; uint4 new_bit_maps, bplmap, map, new_blocks, new_total, max_tot_blks, old_total; uint4 jnl_status; gtm_uint64_t avail_blocks, mmap_sz; off_t new_eof; trans_num curr_tn; unix_db_info *udi; inctn_opcode_t save_inctn_opcode; int4 prev_extend_blks_to_upgrd; jnl_private_control *jpc; jnl_buffer_ptr_t jbp; cache_rec_ptr_t cr; DCL_THREADGBL_ACCESS; assert(!IS_DSE_IMAGE); assert((cs_addrs->nl == NULL) || (process_id != cs_addrs->nl->trunc_pid)); /* mu_truncate shouldn't extend file... */ assert(!process_exiting); DEBUG_ONLY(old_base[0] = old_base[1] = NULL); assert(!gv_cur_region->read_only); udi = FILE_INFO(gv_cur_region); is_mm = (dba_mm == cs_addrs->hdr->acc_meth); # if !defined(MM_FILE_EXT_OK) if (!udi->grabbed_access_sem && is_mm) return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not allowed ? */ # endif /* Both blocks and total blocks are unsigned ints so make sure we aren't asking for huge numbers that will overflow and end up doing silly things. */ assert((blocks <= (MAXTOTALBLKS(cs_data) - cs_data->trans_hist.total_blks)) || WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR)); # if defined(__sun) || defined(__hpux) cs_data->defer_allocate = TRUE; # endif if (!blocks && (cs_data->defer_allocate || (TRANS_IN_PROG_TRUE == trans_in_prog))) return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not enabled ? */ bplmap = cs_data->bplmap; /* New total of non-bitmap blocks will be number of current, non-bitmap blocks, plus new blocks desired * There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this * manner as every non-bitmap block must have an associated bitmap) * Current number of bitmaps is (total number of current blocks + bplmap - 1) / bplmap. * Subtract current number of bitmaps from number needed for expanded database to get number of new bitmaps needed. */ new_bit_maps = DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap) + blocks, bplmap - 1) - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap); new_blocks = blocks + new_bit_maps; assert((0 < (int)new_blocks) || (!cs_data->defer_allocate && (0 == new_blocks))); if (new_blocks + cs_data->trans_hist.total_blks > MAXTOTALBLKS(cs_data)) { assert(WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR)); send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_TOTALBLKMAX); return (uint4)(NO_FREE_SPACE); } if (0 != (save_errno = disk_block_available(udi->fd, &avail_blocks, FALSE))) { send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno); rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno); } else { if (!(gtmDebugLevel & GDL_IgnoreAvailSpace)) { /* Bypass this space check if debug flag above is on. Allows us to create a large sparce DB * in space it could never fit it if wasn't sparse. Needed for some tests. */ avail_blocks = avail_blocks / (cs_data->blk_size / DISK_BLOCK_SIZE); if ((blocks * EXTEND_WARNING_FACTOR) > avail_blocks) { if (blocks > (uint4)avail_blocks) { SETUP_THREADGBL_ACCESS; if (!INST_FREEZE_ON_NOSPC_ENABLED(cs_addrs)) return (uint4)(NO_FREE_SPACE); else send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_NOSPACEEXT), 4, DB_LEN_STR(gv_cur_region), new_blocks, (uint4)avail_blocks); } else send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, DB_LEN_STR(gv_cur_region), (uint4)(avail_blocks - ((new_blocks <= avail_blocks) ? new_blocks : 0))); } } } # ifdef DEBUG if (WBTEST_ENABLED(WBTEST_MM_CONCURRENT_FILE_EXTEND) && dollar_tlevel && !MEMCMP_LIT(gv_cur_region->rname, "DEFAULT")) { SYSTEM("$gtm_dist/mumps -run $gtm_wbox_mrtn"); assert(1 == cs_addrs->nl->wbox_test_seq_num); /* should have been set by mubfilcpy */ cs_addrs->nl->wbox_test_seq_num = 2; /* signal mupip backup to stop sleeping in mubfilcpy */ } # endif /* From here on, we need to use GDSFILEXT_CLNUP before returning to the caller */ was_crit = cs_addrs->now_crit; assert(!cs_addrs->hold_onto_crit || was_crit); /* If we are coming from mupip_extend (which gets crit itself) we better have waited for any unfreezes to occur. * If we are coming from online rollback (when that feature is available), we will come in holding crit and in * the final retry. In that case too, we expect to have waited for unfreezes to occur in the caller itself. * Therefore if we are coming in holding crit from MUPIP, we expect the db to be unfrozen so no need to wait for * freeze. * If we are coming from GT.M and final retry (in which case we come in holding crit) we expect to have waited * for any unfreezes (by invoking tp_crit_all_regions) to occur (TP or non-TP) before coming into this * function. However, there is one exception. In the final retry, if tp_crit_all_regions notices that * at least one of the participating regions did ONLY READs, it will not wait for any freeze on THAT region * to complete before grabbing crit. Later, in the final retry, if THAT region did an update which caused * op_tcommit to invoke bm_getfree->gdsfilext, then we would have come here with a frozen region on which * we hold crit. */ assert(!was_crit || !cs_data->freeze || (dollar_tlevel && (CDB_STAGNATE <= t_tries))); /* * If we are in the final retry and already hold crit, it is possible that csa->nl->wc_blocked is also set to TRUE * (by a concurrent process in phase2 which encountered an error in the midst of commit and secshr_db_clnup * finished the job for it). In this case we do NOT want to invoke wcs_recover as that will update the "bt" * transaction numbers without correspondingly updating the history transaction numbers (effectively causing * a cdb_sc_blkmod type of restart). Therefore do NOT call grab_crit (which unconditionally invokes wcs_recover) * if we already hold crit. */ if (!was_crit) { for ( ; ; ) { grab_crit(gv_cur_region); if (!cs_data->freeze && !IS_REPL_INST_FROZEN) break; rel_crit(gv_cur_region); while (cs_data->freeze || IS_REPL_INST_FROZEN) hiber_start(1000); } } else if (cs_data->freeze && dollar_tlevel) { /* We don't want to continue with file extension as explained above. Hence return with an error code which * op_tcommit will recognize (as a cdb_sc_needcrit/cdb_sc_instancefreeze type of restart) and restart accordingly. */ assert(CDB_STAGNATE <= t_tries); GDSFILEXT_CLNUP; return (uint4)FINAL_RETRY_FREEZE_PROG; } if (IS_REPL_INST_FROZEN && trans_in_prog) { assert(CDB_STAGNATE <= t_tries); GDSFILEXT_CLNUP; return (uint4)FINAL_RETRY_INST_FREEZE; } assert(cs_addrs->ti->total_blks == cs_data->trans_hist.total_blks); old_total = cs_data->trans_hist.total_blks; if (old_total != filesize) { /* Somebody else has already extended it, since we are in crit, this is trust-worthy. However, in case of MM, * we still need to remap the database */ assert((old_total > filesize) GTM_TRUNCATE_ONLY( || !is_mm)); /* For BG, someone else could have truncated or extended - we have no idea */ GDSFILEXT_CLNUP; return (SS_NORMAL); }
void repl_inst_dump_gtmsourcelocal(gtmsource_local_ptr_t gtmsourcelocal_ptr) { int idx; char *string; boolean_t first_time = TRUE; for (idx = 0; idx < NUM_GTMSRC_LCL; idx++, gtmsourcelocal_ptr++) { if (('\0' == gtmsourcelocal_ptr->secondary_instname[0]) && (0 == gtmsourcelocal_ptr->read_jnl_seqno) && (0 == gtmsourcelocal_ptr->connect_jnl_seqno)) continue; if (first_time) { util_out_print("", TRUE); first_time = FALSE; PRINT_DASHES; util_out_print(SOURCELOCAL_TITLE_STRING, TRUE); PRINT_DASHES; } else PRINT_DASHES; PRINT_OFFSET_HEADER; PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_instname[0]), SIZEOF(gtmsourcelocal_ptr->secondary_instname)); util_out_print( PREFIX_SOURCELOCAL "Secondary Instance Name !R16AZ", TRUE, idx, (char *)gtmsourcelocal_ptr->secondary_instname); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsource_pid), SIZEOF(gtmsourcelocal_ptr->gtmsource_pid)); util_out_print( PREFIX_SOURCELOCAL "Source Server Pid !10UL", TRUE, idx, gtmsourcelocal_ptr->gtmsource_pid); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, mode), SIZEOF(gtmsourcelocal_ptr->mode)); string = (GTMSOURCE_MODE_PASSIVE == gtmsourcelocal_ptr->mode) ? "PASSIVE" : ((GTMSOURCE_MODE_ACTIVE == gtmsourcelocal_ptr->mode) ? "ACTIVE" : "UNKNOWN"); if (MEMCMP_LIT(string, "UNKNOWN")) util_out_print( PREFIX_SOURCELOCAL "Source Server Mode !R22AZ", TRUE, idx, string); else { util_out_print( PREFIX_SOURCELOCAL "Source Server Mode !R22AZ [0x!XL]", TRUE, idx, string, gtmsourcelocal_ptr->mode); } PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsource_state), SIZEOF(gtmsourcelocal_ptr->gtmsource_state)); string = ((0 <= gtmsourcelocal_ptr->gtmsource_state) && (GTMSOURCE_NUM_STATES > gtmsourcelocal_ptr->gtmsource_state)) ? (char *)state_array[gtmsourcelocal_ptr->gtmsource_state] : "UNKNOWN"; if (MEMCMP_LIT(string, "UNKNOWN")) util_out_print( PREFIX_SOURCELOCAL "Processing State !R22AZ", TRUE, idx, string); else { util_out_print( PREFIX_SOURCELOCAL "Processing State !R22AZ [0x!XL]", TRUE, idx, string, gtmsourcelocal_ptr->gtmsource_state); } PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, gtmsrc_lcl_array_index), SIZEOF(gtmsourcelocal_ptr->gtmsrc_lcl_array_index)); util_out_print( PREFIX_SOURCELOCAL "Slot Index !15UL", TRUE, idx, gtmsourcelocal_ptr->gtmsrc_lcl_array_index); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, repl_zlib_cmp_level), SIZEOF(gtmsourcelocal_ptr->repl_zlib_cmp_level)); util_out_print( PREFIX_SOURCELOCAL "Journal record Compression Level !15UL", TRUE, idx, gtmsourcelocal_ptr->repl_zlib_cmp_level); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, remote_proto_ver), SIZEOF(gtmsourcelocal_ptr->remote_proto_ver)); util_out_print( PREFIX_SOURCELOCAL "Receiver Server Protocol Version !3UL [0x!2XB]", TRUE, idx, gtmsourcelocal_ptr->remote_proto_ver, gtmsourcelocal_ptr->remote_proto_ver); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_state), SIZEOF(gtmsourcelocal_ptr->read_state)); string = (READ_POOL == gtmsourcelocal_ptr->read_state) ? "POOL" : ((READ_FILE == gtmsourcelocal_ptr->read_state) ? "FILE" : "UNKNOWN"); if (MEMCMP_LIT(string, "UNKNOWN")) util_out_print( PREFIX_SOURCELOCAL "Currently Reading from !R21AZ", TRUE, idx, string); else { util_out_print( PREFIX_SOURCELOCAL "Currently Reading from !R21AZ [0x!XL]", TRUE, idx, string, gtmsourcelocal_ptr->read_state); } PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read), SIZEOF(gtmsourcelocal_ptr->read)); util_out_print( PREFIX_SOURCELOCAL "Relative Read Offset !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->read, gtmsourcelocal_ptr->read); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_addr), SIZEOF(gtmsourcelocal_ptr->read_addr)); util_out_print( PREFIX_SOURCELOCAL "Absolute Read Offset !20@UQ [0x!16@XQ]", TRUE, idx, >msourcelocal_ptr->read_addr, >msourcelocal_ptr->read_addr); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, read_jnl_seqno), SIZEOF(gtmsourcelocal_ptr->read_jnl_seqno)); util_out_print( PREFIX_SOURCELOCAL "Resync Sequence Number !20@UQ [0x!16@XQ]", TRUE, idx, >msourcelocal_ptr->read_jnl_seqno, >msourcelocal_ptr->read_jnl_seqno); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_jnl_seqno), SIZEOF(gtmsourcelocal_ptr->connect_jnl_seqno)); util_out_print( PREFIX_SOURCELOCAL "Connect Sequence Number !20@UQ [0x!16@XQ]", TRUE, idx, >msourcelocal_ptr->connect_jnl_seqno, >msourcelocal_ptr->connect_jnl_seqno); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, num_triples), SIZEOF(gtmsourcelocal_ptr->num_triples)); util_out_print( PREFIX_SOURCELOCAL "Number of Triples !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->num_triples, gtmsourcelocal_ptr->num_triples); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, next_triple_num), SIZEOF(gtmsourcelocal_ptr->next_triple_num)); util_out_print( PREFIX_SOURCELOCAL "Next Triple Number !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->next_triple_num, gtmsourcelocal_ptr->next_triple_num); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, next_triple_seqno), SIZEOF(gtmsourcelocal_ptr->next_triple_seqno)); util_out_print( PREFIX_SOURCELOCAL "Next Triple Seqno !20@UQ [0x!16@XQ]", TRUE, idx, >msourcelocal_ptr->next_triple_seqno, >msourcelocal_ptr->next_triple_seqno); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, last_flush_resync_seqno), SIZEOF(gtmsourcelocal_ptr->last_flush_resync_seqno)); util_out_print( PREFIX_SOURCELOCAL "Last Flush Resync Seqno !20@UQ [0x!16@XQ]", TRUE, idx, >msourcelocal_ptr->last_flush_resync_seqno, >msourcelocal_ptr->last_flush_resync_seqno); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, send_new_triple), SIZEOF(gtmsourcelocal_ptr->send_new_triple)); PRINT_BOOLEAN( PREFIX_SOURCELOCAL "Send New Triple !R8AZ", gtmsourcelocal_ptr->send_new_triple, idx); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, send_losttn_complete), SIZEOF(gtmsourcelocal_ptr->send_losttn_complete)); PRINT_BOOLEAN( PREFIX_SOURCELOCAL "Send LostTN Complete !R8AZ", gtmsourcelocal_ptr->send_losttn_complete, idx); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_host[0]), SIZEOF(gtmsourcelocal_ptr->secondary_host)); if (20 >= strlen(gtmsourcelocal_ptr->secondary_host)) { util_out_print( PREFIX_SOURCELOCAL "Secondary HOSTNAME !R20AZ", TRUE, idx, gtmsourcelocal_ptr->secondary_host); } else { util_out_print( PREFIX_SOURCELOCAL "Secondary HOSTNAME !AZ", TRUE, idx, gtmsourcelocal_ptr->secondary_host); } PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_inet_addr), SIZEOF(gtmsourcelocal_ptr->secondary_inet_addr)); util_out_print( PREFIX_SOURCELOCAL "Secondary INET Address !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->secondary_inet_addr, gtmsourcelocal_ptr->secondary_inet_addr); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, secondary_port), SIZEOF(gtmsourcelocal_ptr->secondary_port)); util_out_print( PREFIX_SOURCELOCAL "Secondary Port !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->secondary_port, gtmsourcelocal_ptr->secondary_port); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, log_interval), SIZEOF(gtmsourcelocal_ptr->log_interval)); util_out_print( PREFIX_SOURCELOCAL "Log Interval !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->log_interval, gtmsourcelocal_ptr->log_interval); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, log_file[0]), SIZEOF(gtmsourcelocal_ptr->log_file)); if (20 >= strlen(gtmsourcelocal_ptr->log_file)) util_out_print( PREFIX_SOURCELOCAL "Log File !R20AZ", TRUE, idx, gtmsourcelocal_ptr->log_file); else util_out_print( PREFIX_SOURCELOCAL "Log File !AZ", TRUE, idx, gtmsourcelocal_ptr->log_file); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, changelog), SIZEOF(gtmsourcelocal_ptr->changelog)); util_out_print( PREFIX_SOURCELOCAL "Changelog !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->changelog, gtmsourcelocal_ptr->changelog); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, statslog), SIZEOF(gtmsourcelocal_ptr->statslog)); util_out_print( PREFIX_SOURCELOCAL "Statslog !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->statslog, gtmsourcelocal_ptr->statslog); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, statslog_file[0]), SIZEOF(gtmsourcelocal_ptr->statslog_file)); if (20 >= strlen(gtmsourcelocal_ptr->log_file)) { util_out_print( PREFIX_SOURCELOCAL "Statslog File !R20AZ", TRUE, idx, gtmsourcelocal_ptr->statslog_file); } else { util_out_print( PREFIX_SOURCELOCAL "Statslog File !AZ", TRUE, idx, gtmsourcelocal_ptr->statslog_file); } PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Hard Tries Count !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_COUNT]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Hard Tries Period !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HARD_TRIES_PERIOD]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Soft Tries Period !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_SOFT_TRIES_PERIOD]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Alert Period !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_ALERT_PERIOD]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Heartbeat Period !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_PERIOD]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT]), SIZEOF(gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT])); util_out_print( PREFIX_SOURCELOCAL "Connect Parms Heartbeat Max Wait !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT], gtmsourcelocal_ptr->connect_parms[GTMSOURCE_CONN_HEARTBEAT_MAX_WAIT]); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, shutdown), SIZEOF(gtmsourcelocal_ptr->shutdown)); util_out_print( PREFIX_SOURCELOCAL "Shutdown State !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->shutdown, gtmsourcelocal_ptr->shutdown); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, shutdown_time), SIZEOF(gtmsourcelocal_ptr->shutdown_time)); util_out_print( PREFIX_SOURCELOCAL "Shutdown Time in seconds !10UL [0x!XL]", TRUE, idx, gtmsourcelocal_ptr->shutdown_time, gtmsourcelocal_ptr->shutdown_time); PRINT_OFFSET_PREFIX(offsetof(gtmsource_local_struct, filter_cmd[0]), SIZEOF(gtmsourcelocal_ptr->filter_cmd)); if (20 >= strlen(gtmsourcelocal_ptr->filter_cmd)) { util_out_print( PREFIX_SOURCELOCAL "Filter Command !R20AZ", TRUE, idx, gtmsourcelocal_ptr->filter_cmd); } else { util_out_print( PREFIX_SOURCELOCAL "Filter Command !AZ", TRUE, idx, gtmsourcelocal_ptr->filter_cmd); } PRINT_DASHES; } }
void go_load(uint4 begin, uint4 end) { char *ptr; int len, fmt, keylength, keystate; uint4 iter, max_data_len, max_subsc_len, key_count, max_rec_size; mstr src, des; unsigned char *rec_buff, ch; boolean_t utf8_extract, format_error = FALSE, hasht_ignored = FALSE, hasht_gbl = FALSE; char *val_off; int val_len, val_off1, val_len1; boolean_t is_setextract; gvinit(); max_rec_size = DEFAULT_MAX_REC_SIZE; rec_buff = (unsigned char *)malloc(max_rec_size); fmt = MU_FMT_ZWR; /* by default, the extract format is ZWR (not GO) */ len = file_input_get(&ptr); if (mupip_error_occurred) { free(rec_buff); return; } if (len >= 0) { util_out_print("!AD", TRUE, len, ptr); utf8_extract = ((len >= STR_LIT_LEN(UTF8_NAME)) && (0 == MEMCMP_LIT(ptr + len - STR_LIT_LEN("UTF-8"), "UTF-8"))) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else gtm_putmsg(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_error_occurred = TRUE; free(rec_buff); return; } } else mupip_exit(ERR_LOADFILERR); len = file_input_get(&ptr); if (mupip_error_occurred) { free(rec_buff); return; } if (len >= 0) { util_out_print("!AD", TRUE, len, ptr); fmt = (0 == memcmp(ptr + len - STR_LIT_LEN("ZWR"), "ZWR", STR_LIT_LEN("ZWR"))) ? MU_FMT_ZWR : MU_FMT_GO; } else mupip_exit(ERR_LOADFILERR); if (begin < 3) begin = 3; for (iter = 3; iter < begin; iter++) { len = file_input_get(&ptr); if (len < 0) /* The IO device has signalled an end of file */ { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); mupip_error_occurred = TRUE; } if (mupip_error_occurred) { util_out_print("Error reading record number: !UL\n", TRUE, iter); free(rec_buff); return; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; key_count = 0; for (iter = begin - 1; ; ) { if (++iter > end) break; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? iter : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } if (0 > (len = file_input_get(&ptr))) break; if (mupip_error_occurred) { mu_gvis(); break; } if ('\n' == *ptr) { if ('\n' == *(ptr+1)) break; ptr++; } if (0 == len) continue; if (MU_FMT_GO != fmt) { /* Determine if the ZWR has $extract format */ if ('$' == *ptr) { keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, &val_off1, &val_len1); ptr = ptr + 4; /* Skip first 4 character '$','z','e','(' */ is_setextract = TRUE; } else { /* Determine the ZWR key length. -1 (SIZEOF(=)) is needed since ZWR allows '^x(1,2)='*/ keylength = zwrkeyvallen(ptr, len, &val_off, &val_len, NULL, NULL); is_setextract = FALSE; } ISSUE_TRIGDATAIGNORE_IF_NEEDED(keylength, ptr, hasht_gbl); if (hasht_gbl) { hasht_gbl = FALSE; continue; } go_call_db(GO_PUT_SUB, ptr, keylength, 0, 0); if (mupip_error_occurred) { mu_gvis(); util_out_print("Error loading record number: !UL\n", TRUE, iter); mupip_error_occurred = FALSE; continue; } assert(keylength < len - 1); if (max_subsc_len < (gv_currkey->end + 1)) max_subsc_len = gv_currkey->end + 1; src.len = val_len; src.addr = val_off; des.len = 0; if (src.len > max_rec_size) { max_rec_size = src.len; free(rec_buff); rec_buff = (unsigned char *)malloc(max_rec_size); } des.addr = (char *)rec_buff; if (FALSE == zwr2format(&src, &des)) { util_out_print("Format error in record number !8UL: !/!AD", TRUE, iter, src.len, src.addr); format_error = TRUE; continue; } if (max_data_len < des.len) max_data_len = des.len; (is_setextract) ? go_call_db(GO_SET_EXTRACT, des.addr, des.len, val_off1, val_len1) : go_call_db(GO_PUT_DATA, (char *)rec_buff, des.len, 0, 0); if (mupip_error_occurred) { mu_gvis(); util_out_print("Error loading record number: !UL\n", TRUE, iter); mupip_error_occurred = FALSE; continue; } key_count++; } else { ISSUE_TRIGDATAIGNORE_IF_NEEDED(len, ptr, hasht_gbl); if (hasht_gbl) { if (0 > (len = file_input_get(&ptr))) break; iter++; hasht_gbl = FALSE; continue; } go_call_db(GO_PUT_SUB, ptr, len, 0, 0); if (mupip_error_occurred) { mu_gvis(); util_out_print("Error loading record number: !UL\n", TRUE, iter); mupip_error_occurred = FALSE; continue; } if (max_subsc_len < (gv_currkey->end + 1)) max_subsc_len = gv_currkey->end + 1; if (++iter > end) { iter--; /* Decrement as didn't load key */ break; } if ((len = file_input_get(&ptr)) < 0) break; if (mupip_error_occurred) { mu_gvis(); util_out_print("Error loading record number: !UL\n", TRUE, iter); break; } stringpool.free = stringpool.base; if (max_data_len < len) max_data_len = len; go_call_db(GO_PUT_DATA, ptr, len, 0, 0); if (mupip_error_occurred) { mu_gvis(); util_out_print("Error loading record number: !UL\n", TRUE, iter); mupip_error_occurred = FALSE; continue; } key_count++; } } free(rec_buff); file_input_close(); if (mu_ctrly_occurred) { gtm_putmsg(VARLSTCNT(1) ERR_LOADCTRLY); mupip_exit(ERR_MUNOFINISH); } util_out_print("LOAD TOTAL!_!_Key Cnt: !UL Max Subsc Len: !UL Max Data Len: !UL",TRUE,key_count,max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL\n", TRUE, key_count ? (iter - 1) : 0); if (format_error) mupip_exit(ERR_LOADFILERR); }
void bin_load(uint4 begin, uint4 end) { unsigned char *ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop, *ptr_base; unsigned char hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1], sn_key_str[MAX_KEY_SZ + 1], *sn_key_str_end; unsigned char *end_buff; unsigned short rec_len, next_cmpc, numsubs; int len; int current, last, length, max_blk_siz, max_key, status; int tmp_cmpc, sn_chunk_number, expected_sn_chunk_number = 0, sn_hold_buff_pos, sn_hold_buff_size; uint4 iter, max_data_len, max_subsc_len, key_count, gblsize; ssize_t rec_count, global_key_count, subsc_len,extr_std_null_coll, last_sn_error_offset=0, file_offset_base=0, file_offset=0; boolean_t need_xlation, new_gvn, utf8_extract; boolean_t is_hidden_subscript, ok_to_put = TRUE, putting_a_sn = FALSE, sn_incmp_gbl_already_killed = FALSE; rec_hdr *rp, *next_rp; mval v, tmp_mval; mstr mstr_src, mstr_dest; collseq *extr_collseq, *db_collseq, *save_gv_target_collseq; coll_hdr extr_collhdr, db_collhdr; gv_key *tmp_gvkey = NULL; /* null-initialize at start, will be malloced later */ gv_key *sn_gvkey = NULL; /* null-initialize at start, will be malloced later */ gv_key *sn_savekey = NULL; /* null-initialize at start, will be malloced later */ char std_null_coll[BIN_HEADER_NUMSZ + 1], *sn_hold_buff = NULL, *sn_hold_buff_temp = NULL; # ifdef GTM_CRYPT gtmcrypt_key_t *encr_key_handles; char *inbuf; int4 index; int req_dec_blk_size, init_status, crypt_status; muext_hash_hdr_ptr_t hash_array = NULL; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(4 == SIZEOF(coll_hdr)); gvinit(); v.mvtype = MV_STR; len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); hdr_lvl = EXTR_HEADER_LEVEL(ptr); if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (V5_BIN_HEADER_SZ == len)) || (('6' == hdr_lvl) && (BIN_HEADER_SZ == len)) || (('7' == hdr_lvl) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len)))) { rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* expecting the level in a single character */ assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3)); if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION_ENCR) < hdr_lvl) { /* ignore the level check */ rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* check if extract was generated in UTF-8 mode */ utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_exit(ERR_LDBINFMT); } if ('4' >= hdr_lvl) { /* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte) * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above. */ for (c = ptr, ctop = c + len; c < ctop; c++) { if ('\0' == *c) *c = ' '; } } util_out_print("Label = !AD\n", TRUE, len, ptr); new_gvn = FALSE; if (hdr_lvl > '3') { if (hdr_lvl > '5') { memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ); std_null_coll[BIN_HEADER_NUMSZ] = '\0'; } else { memcpy(std_null_coll, ptr + V5_BIN_HEADER_NULLCOLLOFFSET, V5_BIN_HEADER_NUMSZ); std_null_coll[V5_BIN_HEADER_NUMSZ] = '\0'; } extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10); if (0 != extr_std_null_coll && 1!= extr_std_null_coll) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } } else extr_std_null_coll = 0; # ifdef GTM_CRYPT if ('7' <= hdr_lvl) { int i, num_indexes; len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); hash_array = (muext_hash_hdr *)malloc(len); /* store hashes of all the files used during extract into muext_hash_hdr structure */ memcpy((char *)hash_array, ptr, len); num_indexes = len / GTMCRYPT_HASH_LEN; encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes); INIT_PROC_ENCRYPTION(crypt_status); GC_BIN_LOAD_ERR(crypt_status); for (index = 0; index < num_indexes; index++) { if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN)) continue; GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status); GC_BIN_LOAD_ERR(crypt_status); } } # endif if ('2' < hdr_lvl) { len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); if (SIZEOF(coll_hdr) != len) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } extr_collhdr = *((coll_hdr *)(ptr)); new_gvn = TRUE; } else gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0'); if (begin < 2) begin = 2; for (iter = 2; iter < begin; iter++) { if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base))) { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); util_out_print("Error reading record number: !UL\n", TRUE, iter); mupip_error_occurred = TRUE; return; } else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); iter--; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; global_key_count = key_count = 0; rec_count = begin - 1; extr_collseq = db_collseq = NULL; need_xlation = FALSE; assert(NULL == tmp_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* tmp_gvkey will point to malloced memory after this */ assert(NULL == sn_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(sn_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* sn_gvkey will point to malloced memory after this */ assert(NULL == sn_savekey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(sn_savekey, DBKEYSIZE(MAX_KEY_SZ)); /* sn_gvkey will point to malloced memory after this */ for (; !mupip_DB_full ;) { if (++rec_count > end) break; next_cmpc = 0; mupip_error_occurred = FALSE; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base)) || mupip_error_occurred) break; else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); new_gvn = TRUE; /* next record will contain a new gvn */ rec_count--; /* Decrement as this record does not count as a record for loading purposes */ continue; } rp = (rec_hdr*)(ptr); # ifdef GTM_CRYPT if ('7' <= hdr_lvl) { /* Getting index value from the extracted file. It indicates which database file this record belongs to */ GET_LONG(index, ptr); if (-1 != index) /* Indicates that the record is encrypted. */ { req_dec_blk_size = len - SIZEOF(int4); inbuf = (char *)(ptr + SIZEOF(int4)); GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status); GC_BIN_LOAD_ERR(crypt_status); } rp = (rec_hdr*)(ptr + SIZEOF(int4)); } # endif btop = ptr + len; cp1 = (unsigned char*)(rp + 1); v.str.addr = (char*)cp1; while (*cp1++) ; v.str.len =INTCAST((char*)cp1 - v.str.addr - 1); if (('2' >= hdr_lvl) || new_gvn) { if ((HASHT_GBLNAME_LEN == v.str.len) && (0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN))) continue; bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str); max_key = gv_cur_region->max_key_size; db_collhdr.act = gv_target->act; db_collhdr.ver = gv_target->ver; db_collhdr.nct = gv_target->nct; } GET_USHORT(rec_len, &rp->rsiz); if (EVAL_CMPC(rp) != 0 || v.str.len > rec_len || mupip_error_occurred) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; continue; } if (new_gvn) { global_key_count = 1; if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver || db_collhdr.nct != extr_collhdr.nct || gv_cur_region->std_null_coll != extr_std_null_coll)) { if (extr_collhdr.act) { if (extr_collseq = ready_collseq((int)extr_collhdr.act)) { if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act, extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } if (db_collhdr.act) { if (db_collseq = ready_collseq((int)db_collhdr.act)) { if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } need_xlation = TRUE; } else need_xlation = FALSE; } new_gvn = FALSE; for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len)) { GET_USHORT(rec_len, &rp->rsiz); if (rec_len + (unsigned char *)rp > btop) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; break; } cp1 = (unsigned char*)(rp + 1); cp2 = gv_currkey->base + EVAL_CMPC(rp); current = 1; for (;;) { last = current; current = *cp2++ = *cp1++; if (0 == last && 0 == current) break; if (cp1 > (unsigned char *)rp + rec_len || cp2 > (unsigned char *)gv_currkey + gv_currkey->top) { gv_currkey->end = cp2 - gv_currkey->base - 1; gv_currkey->base[gv_currkey->end] = 0; gv_currkey->base[gv_currkey->end - 1] = 0; bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; break; } } if (mupip_error_occurred) break; gv_currkey->end = cp2 - gv_currkey->base - 1; if (need_xlation) { assert(hdr_lvl >= '3'); assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll); /* gv_currkey would have been modified/translated in the earlier put */ memcpy(gv_currkey->base, cmpc_str, next_cmpc); next_rp = (rec_hdr *)((unsigned char*)rp + rec_len); if ((unsigned char*)next_rp < btop) { next_cmpc = EVAL_CMPC(next_rp); assert(next_cmpc <= gv_currkey->end); memcpy(cmpc_str, gv_currkey->base, next_cmpc); } else next_cmpc = 0; /* length of the key might change (due to nct variation), * so get a copy of the original key from the extract */ memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1); gvkey_char_ptr = dup_key_str; while (*gvkey_char_ptr++) ; gv_currkey->prev = 0; gv_currkey->end = gvkey_char_ptr - dup_key_str; assert(gv_keysize <= tmp_gvkey->top); while (*gvkey_char_ptr) { /* get next subscript (in GT.M internal subsc format) */ subsc_len = 0; tmp_ptr = src_buff; while (*gvkey_char_ptr) *tmp_ptr++ = *gvkey_char_ptr++; subsc_len = tmp_ptr - src_buff; src_buff[subsc_len] = '\0'; if (extr_collseq) { /* undo the extract time collation */ TREF(transform) = TRUE; save_gv_target_collseq = gv_target->collseq; gv_target->collseq = extr_collseq; } else TREF(transform) = FALSE; /* convert the subscript to string format */ end_buff = gvsub2str(src_buff, dest_buff, FALSE); /* transform the string to the current subsc format */ TREF(transform) = TRUE; tmp_mval.mvtype = MV_STR; tmp_mval.str.addr = (char *)dest_buff; tmp_mval.str.len = INTCAST(end_buff - dest_buff); tmp_gvkey->prev = 0; tmp_gvkey->end = 0; if (extr_collseq) gv_target->collseq = save_gv_target_collseq; mval2subsc(&tmp_mval, tmp_gvkey); /* we now have the correctly transformed subscript */ tmp_key_ptr = gv_currkey->base + gv_currkey->end; memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1); gv_currkey->prev = gv_currkey->end; gv_currkey->end += tmp_gvkey->end; gvkey_char_ptr++; } if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev) { if (extr_std_null_coll == 0) { GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end); } else { STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end); } } } if (gv_currkey->end >= max_key) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; continue; } /* * Spanning node-related variables and their usage: * * expected_sn_chunk_number: 0 - looking for spanning nodes (regular nodes are OK, too) * !0 - number of the next chunk needed (implies we are building * a spanning node's value) * * While building a spanning node's value: * numsubs: the number of chunks needed to build the spanning node's value * gblsize: the expected size of the completed value * sn_chunk_number: The chunk number of the chunk from the current record from the extract * * Managing the value * sn_hold_buff: buffer used to accumulate the spanning node's value * sn_hold_buff_size: Allocated size of buffer * sn_hold_buff_pos: amount of the buffer used; where to place the next chunk * sn_hold_buff_temp: used when we have to increase the size of the buffer * * Controlling the placing of the key,value in the database: * ok_to_put: means we are ready to place the key,value in the database, i.e., we have the full value * (either of the spanning node or a regular node). * putting_a_sn: we are placing a spanning node in the database, i.e, use the key from sn_gvkey and * the value from sn_hold_buff. */ CHECK_HIDDEN_SUBSCRIPT(gv_currkey,is_hidden_subscript); if (!is_hidden_subscript && (max_subsc_len < (gv_currkey->end + 1))) max_subsc_len = gv_currkey->end + 1; v.str.addr = (char*)cp1; v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp)); if (expected_sn_chunk_number && !is_hidden_subscript) { /* we were expecting a chunk of an spanning node and we did not get one */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected chunk number : !UL but found a non-spanning node", TRUE, expected_sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; sn_hold_buff_pos = 0; expected_sn_chunk_number = 0; ok_to_put = TRUE; putting_a_sn = FALSE; numsubs = 0; } if (is_hidden_subscript) { /* it's a chunk and we were expecting one */ sn_chunk_number = SPAN_GVSUBS2INT((span_subs *) &(gv_currkey->base[gv_currkey->end - 4])); if (!expected_sn_chunk_number && is_hidden_subscript && sn_chunk_number) { /* we not expecting a payload chunk (as opposed to a control record) but we got one */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Not expecting a spanning node chunk but found chunk : !UL", TRUE, sn_chunk_number + 1); if (v.str.len) DISPLAY_VALUE("!_!_Errant Chunk :"); continue; } if (0 == sn_chunk_number) { /* first spanning node chunk, get ctrl info */ if (0 != expected_sn_chunk_number) { DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", TRUE, expected_sn_chunk_number + 1, sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; } /* start building a new spanning node */ sn_gvkey->end = gv_currkey->end - (SPAN_SUBS_LEN + 1); memcpy(sn_gvkey->base, gv_currkey->base, sn_gvkey->end); sn_gvkey->base[sn_gvkey->end] = 0; sn_gvkey->prev = gv_currkey->prev; sn_gvkey->top = gv_currkey->top; GET_NSBCTRL(v.str.addr, numsubs, gblsize); /* look for first payload chunk */ expected_sn_chunk_number = 1; sn_hold_buff_pos = 0; ok_to_put = FALSE; sn_incmp_gbl_already_killed = FALSE; } else { /* we only need to compare the key before the hidden subscripts */ if ((expected_sn_chunk_number == sn_chunk_number) && (sn_gvkey->end == gv_currkey->end - (SPAN_SUBS_LEN + 1)) && !memcmp(sn_gvkey->base,gv_currkey->base, sn_gvkey->end) && ((sn_hold_buff_pos + v.str.len) <= gblsize)) { if (NULL == sn_hold_buff) { sn_hold_buff_size = DEFAULT_SN_HOLD_BUFF_SIZE; sn_hold_buff = (char *)malloc(DEFAULT_SN_HOLD_BUFF_SIZE); } if ((sn_hold_buff_pos + v.str.len) > sn_hold_buff_size) { sn_hold_buff_size = sn_hold_buff_size * 2; sn_hold_buff_temp = (char *)malloc(sn_hold_buff_size); memcpy(sn_hold_buff_temp, sn_hold_buff, sn_hold_buff_pos); free (sn_hold_buff); sn_hold_buff = sn_hold_buff_temp; } memcpy(sn_hold_buff + sn_hold_buff_pos, v.str.addr, v.str.len); sn_hold_buff_pos += v.str.len; if (expected_sn_chunk_number == numsubs) { if (sn_hold_buff_pos != gblsize) { /* we don't have the expected size even though */ /* we have all the expected chunks. */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected size : !UL actual size : !UL", TRUE, gblsize, sn_hold_buff_pos); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; expected_sn_chunk_number = 0; ok_to_put = FALSE; sn_hold_buff_pos = 0; } else { expected_sn_chunk_number = 0; ok_to_put = TRUE; putting_a_sn = TRUE; } }else expected_sn_chunk_number++; }else { DISPLAY_INCMP_SN_MSG; if ((sn_hold_buff_pos + v.str.len) <= gblsize) util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", /*BYPASSOK*/ TRUE, expected_sn_chunk_number + 1, sn_chunk_number + 1); else util_out_print("!_!_Global value too large: expected size : !UL actual size : !UL chunk number : !UL", TRUE, /*BYPASSOK*/ gblsize, sn_hold_buff_pos + v.str.len, sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; if (v.str.len) DISPLAY_VALUE("!_!_Errant Chunk :"); KILL_INCMP_SN_IF_NEEDED; sn_hold_buff_pos = 0; expected_sn_chunk_number = 0; } } } else ok_to_put = TRUE; if (ok_to_put) { if (putting_a_sn) { gv_currkey->base[gv_currkey->end - (SPAN_SUBS_LEN + 1)] = 0; gv_currkey->end -= (SPAN_SUBS_LEN + 1); v.str.addr = sn_hold_buff; v.str.len = sn_hold_buff_pos; } if (max_data_len < v.str.len) max_data_len = v.str.len; bin_call_db(BIN_PUT, (INTPTR_T)&v, 0); if (mupip_error_occurred) { if (!mupip_DB_full) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); file_offset = file_offset_base + ((unsigned char *)rp - ptr_base); util_out_print("!_!_at File offset : [0x!XL]", TRUE, file_offset); DISPLAY_CURRKEY; DISPLAY_VALUE("!_!_Value :"); } break; } if (putting_a_sn) putting_a_sn = FALSE; else { key_count++; global_key_count++; } } } } GTMCRYPT_ONLY( if (NULL != hash_array) free(hash_array); )
uint4 gdsfilext(uint4 blocks, uint4 filesize, boolean_t trans_in_prog) { sm_uc_ptr_t old_base[2], mmap_retaddr; boolean_t was_crit, is_mm; int result, save_errno, status; DEBUG_ONLY(int first_save_errno); uint4 new_bit_maps, bplmap, map, new_blocks, new_total, max_tot_blks, old_total; uint4 jnl_status; gtm_uint64_t avail_blocks, mmap_sz; off_t new_eof, new_size; trans_num curr_tn; unix_db_info *udi; inctn_opcode_t save_inctn_opcode; int4 prev_extend_blks_to_upgrd; jnl_private_control *jpc; jnl_buffer_ptr_t jbp; cache_rec_ptr_t cr; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(!IS_DSE_IMAGE); assert((cs_addrs->nl == NULL) || (process_id != cs_addrs->nl->trunc_pid)); /* mu_truncate shouldn't extend file... */ assert(!process_exiting); DEBUG_ONLY(old_base[0] = old_base[1] = NULL); assert(!gv_cur_region->read_only); udi = FILE_INFO(gv_cur_region); is_mm = (dba_mm == cs_addrs->hdr->acc_meth); # if !defined(MM_FILE_EXT_OK) if (!udi->grabbed_access_sem && is_mm) return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not allowed ? */ # endif /* Both blocks and total blocks are unsigned ints so make sure we aren't asking for huge numbers that will overflow and end up doing silly things. */ assert((blocks <= (MAXTOTALBLKS(cs_data) - cs_data->trans_hist.total_blks)) || WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR)); # if defined(__sun) || defined(__hpux) cs_data->defer_allocate = TRUE; # endif if (!blocks && (cs_data->defer_allocate || (TRANS_IN_PROG_TRUE == trans_in_prog))) return (uint4)(NO_FREE_SPACE); /* should this be changed to show extension not enabled ? */ bplmap = cs_data->bplmap; /* New total of non-bitmap blocks will be number of current, non-bitmap blocks, plus new blocks desired * There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this * manner as every non-bitmap block must have an associated bitmap) * Current number of bitmaps is (total number of current blocks + bplmap - 1) / bplmap. * Subtract current number of bitmaps from number needed for expanded database to get number of new bitmaps needed. */ new_bit_maps = DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap) + blocks, bplmap - 1) - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, bplmap); new_blocks = blocks + new_bit_maps; assert((0 < (int)new_blocks) || (!cs_data->defer_allocate && (0 == new_blocks))); if (new_blocks + cs_data->trans_hist.total_blks > MAXTOTALBLKS(cs_data)) { assert(WBTEST_ENABLED(WBTEST_FILE_EXTEND_ERROR)); send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_TOTALBLKMAX); return (uint4)(NO_FREE_SPACE); } if (0 != (save_errno = disk_block_available(udi->fd, &avail_blocks, FALSE))) { send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno); rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno); } else { if (!(gtmDebugLevel & GDL_IgnoreAvailSpace)) { /* Bypass this space check if debug flag above is on. Allows us to create a large sparce DB * in space it could never fit it if wasn't sparse. Needed for some tests. */ avail_blocks = avail_blocks / (cs_data->blk_size / DISK_BLOCK_SIZE); if ((blocks * EXTEND_WARNING_FACTOR) > avail_blocks) { if (blocks > (uint4)avail_blocks) { if (!INST_FREEZE_ON_NOSPC_ENABLED(cs_addrs)) return (uint4)(NO_FREE_SPACE); else send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) MAKE_MSG_WARNING(ERR_NOSPACEEXT), 4, DB_LEN_STR(gv_cur_region), new_blocks, (uint4)avail_blocks); } else send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DSKSPACEFLOW, 3, DB_LEN_STR(gv_cur_region), (uint4)(avail_blocks - ((new_blocks <= avail_blocks) ? new_blocks : 0))); } } } # ifdef DEBUG if (WBTEST_ENABLED(WBTEST_MM_CONCURRENT_FILE_EXTEND) && dollar_tlevel && !MEMCMP_LIT(gv_cur_region->rname, "DEFAULT")) { SYSTEM("$gtm_dist/mumps -run $gtm_wbox_mrtn"); assert(1 == cs_addrs->nl->wbox_test_seq_num); /* should have been set by mubfilcpy */ cs_addrs->nl->wbox_test_seq_num = 2; /* signal mupip backup to stop sleeping in mubfilcpy */ } # endif /* From here on, we need to use GDSFILEXT_CLNUP before returning to the caller */ was_crit = cs_addrs->now_crit; assert(!cs_addrs->hold_onto_crit || was_crit); /* If we are coming from mupip_extend (which gets crit itself) we better have waited for any unfreezes to occur. * If we are coming from online rollback (when that feature is available), we will come in holding crit and in * the final retry. In that case too, we expect to have waited for unfreezes to occur in the caller itself. * Therefore if we are coming in holding crit from MUPIP, we expect the db to be unfrozen so no need to wait for * freeze. * If we are coming from GT.M and final retry (in which case we come in holding crit) we expect to have waited * for any unfreezes (by invoking tp_crit_all_regions) to occur (TP or non-TP) before coming into this * function. However, there is one exception. In the final retry, if tp_crit_all_regions notices that * at least one of the participating regions did ONLY READs, it will not wait for any freeze on THAT region * to complete before grabbing crit. Later, in the final retry, if THAT region did an update which caused * op_tcommit to invoke bm_getfree->gdsfilext, then we would have come here with a frozen region on which * we hold crit. */ assert(!was_crit || !FROZEN_HARD(cs_data) || (dollar_tlevel && (CDB_STAGNATE <= t_tries))); /* * If we are in the final retry and already hold crit, it is possible that csa->nl->wc_blocked is also set to TRUE * (by a concurrent process in phase2 which encountered an error in the midst of commit and secshr_db_clnup * finished the job for it). In this case we do NOT want to invoke wcs_recover as that will update the "bt" * transaction numbers without correspondingly updating the history transaction numbers (effectively causing * a cdb_sc_blkmod type of restart). Therefore do NOT call grab_crit (which unconditionally invokes wcs_recover) * if we already hold crit. */ if (!was_crit) { for ( ; ; ) { grab_crit(gv_cur_region); if (FROZEN_CHILLED(cs_data)) DO_CHILLED_AUTORELEASE(cs_addrs, cs_data); if (!FROZEN(cs_data) && !IS_REPL_INST_FROZEN) break; rel_crit(gv_cur_region); while (FROZEN(cs_data) || IS_REPL_INST_FROZEN) { hiber_start(1000); if (FROZEN_CHILLED(cs_data) && CHILLED_AUTORELEASE(cs_data)) break; } } } else if (FROZEN_HARD(cs_data) && dollar_tlevel) { /* We don't want to continue with file extension as explained above. Hence return with an error code which * op_tcommit will recognize (as a cdb_sc_needcrit/cdb_sc_instancefreeze type of restart) and restart accordingly. */ assert(CDB_STAGNATE <= t_tries); GDSFILEXT_CLNUP; return (uint4)FINAL_RETRY_FREEZE_PROG; } else WAIT_FOR_REGION_TO_UNCHILL(cs_addrs, cs_data); if (IS_REPL_INST_FROZEN && trans_in_prog) { assert(CDB_STAGNATE <= t_tries); GDSFILEXT_CLNUP; return (uint4)FINAL_RETRY_INST_FREEZE; } assert(cs_addrs->ti->total_blks == cs_data->trans_hist.total_blks); old_total = cs_data->trans_hist.total_blks; if (old_total != filesize) { /* Somebody else has already extended it, since we are in crit, this is trust-worthy. However, in case of MM, * we still need to remap the database */ assert((old_total > filesize) || !is_mm); /* For BG, someone else could have truncated or extended - we have no idea */ GDSFILEXT_CLNUP; return (SS_NORMAL); } if (trans_in_prog && SUSPICIOUS_EXTEND) { if (!was_crit) { GDSFILEXT_CLNUP; return (uint4)(EXTEND_SUSPECT); } /* If free_blocks counter is not ok, then correct it. Do the check again. If still fails, then it means we held * crit through bm_getfree into gdsfilext and still didn't get it right. */ assertpro(!is_free_blks_ctr_ok() && !SUSPICIOUS_EXTEND); } if (JNL_ENABLED(cs_data)) { if (!jgbl.dont_reset_gbl_jrec_time) SET_GBL_JREC_TIME; /* needed before jnl_ensure_open as that can write jnl records */ jpc = cs_addrs->jnl; jbp = jpc->jnl_buff; /* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order * of jnl records. This needs to be done BEFORE the jnl_ensure_open as that could write * journal records (if it decides to switch to a new journal file). */ ADJUST_GBL_JREC_TIME(jgbl, jbp); jnl_status = jnl_ensure_open(gv_cur_region, cs_addrs); if (jnl_status) { GDSFILEXT_CLNUP; send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(cs_data), DB_LEN_STR(gv_cur_region)); return (uint4)(NO_FREE_SPACE); /* should have better return status */ } } if (is_mm) { cs_addrs->nl->mm_extender_pid = process_id; status = wcs_wtstart(gv_cur_region, 0, NULL, NULL); cs_addrs->nl->mm_extender_pid = 0; assertpro(SS_NORMAL == status); old_base[0] = cs_addrs->db_addrs[0]; old_base[1] = cs_addrs->db_addrs[1]; cs_addrs->db_addrs[0] = NULL; /* don't rely on it until the mmap below */ # ifdef _AIX status = shmdt(old_base[0] - BLK_ZERO_OFF(cs_data->start_vbn)); # else status = munmap((caddr_t)old_base[0], (size_t)(old_base[1] - old_base[0])); # endif if (0 != status) { save_errno = errno; GDSFILEXT_CLNUP; send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(12) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), ERR_SYSCALL, 5, LEN_AND_STR(MEM_UNMAP_SYSCALL), CALLFROM, save_errno); return (uint4)(NO_FREE_SPACE); } } else { /* Due to concurrency issues, it is possible some process had issued a disk read of the GDS block# corresponding * to "old_total" right after a truncate wrote a GDS-block of zeros on disk (to signal end of the db file). * If so, the global buffer containing this block needs to be invalidated now as part of the extend. If not, it is * possible the EOF block on disk is now going to be overwritten by a properly initialized bitmap block (as part * of the gdsfilext below) while the global buffer continues to have an incorrect copy of that bitmap block and * this in turn would cause XXXX failures due to a bad bitmap block in shared memory. (GTM-7519) */ cr = db_csh_get((block_id)old_total); if ((NULL != cr) && ((cache_rec_ptr_t)CR_NOTVALID != cr)) { assert((0 == cr->dirty) && (0 == cr->bt_index) && !cr->stopped); cr->cycle++; cr->blk = CR_BLKEMPTY; } } CHECK_TN(cs_addrs, cs_data, cs_data->trans_hist.curr_tn); /* can issue rts_error TNTOOLARGE */ new_total = old_total + new_blocks; new_eof = BLK_ZERO_OFF(cs_data->start_vbn) + ((off_t)new_total * cs_data->blk_size); # if !defined(__sun) && !defined(__hpux) if (!cs_data->defer_allocate) { new_size = new_eof + cs_data->blk_size; save_errno = posix_fallocate(udi->fd, 0, new_size); DEBUG_ONLY(first_save_errno = save_errno); if ((ENOSPC == save_errno) && IS_GTM_IMAGE) save_errno = extend_wait_for_fallocate(udi, new_size); if (0 != save_errno) { GDSFILEXT_CLNUP; assert(ENOSPC == save_errno); if (ENOSPC != save_errno) send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_PREALLOCATEFAIL, 2, DB_LEN_STR(gv_cur_region), save_errno); return (uint4)(NO_FREE_SPACE); } } # endif save_errno = db_write_eof_block(udi, udi->fd, cs_data->blk_size, new_eof, &(TREF(dio_buff))); if ((ENOSPC == save_errno) && IS_GTM_IMAGE) save_errno = extend_wait_for_write(udi, cs_data->blk_size, new_eof); if (0 != save_errno) { GDSFILEXT_CLNUP; if (ENOSPC != save_errno) send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(5) ERR_DBFILERR, 2, DB_LEN_STR(gv_cur_region), save_errno); return (uint4)(NO_FREE_SPACE); } if (WBTEST_ENABLED(WBTEST_FILE_EXTEND_INTERRUPT_1)) { LONG_SLEEP(600); assert(FALSE); } /* Ensure the EOF and metadata get to disk BEFORE any bitmap writes. Otherwise, the file size could no longer reflect * a proper extent and subsequent invocations of gdsfilext could corrupt the database. */ if (!IS_STATSDB_CSA(cs_addrs)) { GTM_DB_FSYNC(cs_addrs, udi->fd, status); assert(0 == status); if (0 != status) { GDSFILEXT_CLNUP; send_msg_csa(CSA_ARG(cs_addrs) VARLSTCNT(8) ERR_DBFILERR, 5, RTS_ERROR_LITERAL("fsync1()"), CALLFROM, status); return (uint4)(NO_FREE_SPACE); } } if (WBTEST_ENABLED(WBTEST_FILE_EXTEND_INTERRUPT_2)) { LONG_SLEEP(600); assert(FALSE); /* Should be killed before that */ } DEBUG_ONLY(prev_extend_blks_to_upgrd = cs_data->blks_to_upgrd;)
void op_zlink(mval *v, mval *quals) { struct FAB srcfab; struct NAM srcnam, objnam; struct XABDAT srcxab, objxab; boolean_t compile, expdir, libr, obj_found, src_found; short flen; unsigned short type; unsigned char srccom[MAX_FN_LEN], srcnamebuf[MAX_FN_LEN], objnamebuf[MAX_FN_LEN], objnamelen, srcnamelen,ver[6]; unsigned char objcom[MAX_FN_LEN], list_file[MAX_FN_LEN], ceprep_file[MAX_FN_LEN], *fname; zro_ent *srcdir, *objdir; mstr srcstr, objstr, version; mval qualifier; unsigned status, srcfnb; uint4 lcnt, librindx, qlf; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; MV_FORCE_STR(v); if (MAX_FN_LEN < v->str.len) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, MIN(UCHAR_MAX, v->str.len), v->str.addr, ERR_FILENAMETOOLONG); version.len = 0; srcdir = objdir = 0; version.addr = ver; libr = FALSE; obj_fab = cc$rms_fab; if (quals) { MV_FORCE_STR(quals); srcfab = cc$rms_fab; srcfab.fab$l_fna = v->str.addr; srcfab.fab$b_fns = v->str.len; srcfab.fab$l_nam = &srcnam; srcnam = cc$rms_nam; srcnam.nam$l_esa = srcnamebuf; srcnam.nam$b_ess = SIZEOF(srcnamebuf); srcnam.nam$b_nop = NAM$M_SYNCHK; status = sys$parse(&srcfab); if (!(status & 1)) rts_error(VARLSTCNT(9) ERR_ZLINKFILE, 2, v->str.len, v->str.addr, ERR_FILEPARSE, 2, v->str.len, v->str.addr, status); if (srcnam.nam$l_fnb & NAM$M_WILDCARD) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr, ERR_WILDCARD, 2, v->str.len, v->str.addr); srcfnb = srcnam.nam$l_fnb; expdir = (srcfnb & (NAM$M_NODE | NAM$M_EXP_DEV | NAM$M_EXP_DIR)); if (srcfnb & NAM$M_EXP_VER) { memcpy(version.addr, srcnam.nam$l_ver, srcnam.nam$b_ver); version.len = srcnam.nam$b_ver; } if (expdir) { if (version.len) flen = srcnam.nam$b_esl - srcnam.nam$b_type - version.len; else flen = srcnam.nam$b_esl - srcnam.nam$b_type - 1; /* semicolon is put in by default */ fname = srcnam.nam$l_esa; } else { flen = srcnam.nam$b_name; fname = srcnam.nam$l_name; } ENSURE_STP_FREE_SPACE(flen); memcpy(stringpool.free, fname, flen); dollar_zsource.str.addr = stringpool.free; dollar_zsource.str.len = flen; stringpool.free += flen; if (srcfnb & NAM$M_EXP_TYPE) { if ((SIZEOF(DOTOBJ) - 1 == srcnam.nam$b_type) && !MEMCMP_LIT(srcnam.nam$l_type, DOTOBJ)) { type = OBJ; objstr.addr = srcnam.nam$l_esa; objstr.len = srcnam.nam$b_esl; } else { type = SRC; memcpy(srcnamebuf, dollar_zsource.str.addr, flen); memcpy(&srcnamebuf[flen], srcnam.nam$l_type, srcnam.nam$b_type); memcpy(&srcnamebuf[flen + srcnam.nam$b_type], version.addr, version.len); srcnamelen = flen + srcnam.nam$b_type + version.len; srcnamebuf[srcnamelen] = 0; srcstr.addr = srcnamebuf; srcstr.len = srcnamelen; memcpy(objnamebuf, dollar_zsource.str.addr, flen); memcpy(&objnamebuf[flen], DOTOBJ, SIZEOF(DOTOBJ)); objnamelen = flen + SIZEOF(DOTOBJ) - 1; objstr.addr = objnamebuf; objstr.len = objnamelen; } } else { type = NOTYPE; memcpy(srcnamebuf, dollar_zsource.str.addr, flen); memcpy(&srcnamebuf[flen], DOTM, SIZEOF(DOTM)); srcnamelen = flen + SIZEOF(DOTM) - 1; memcpy(objnamebuf, dollar_zsource.str.addr, flen); MEMCPY_LIT(&objnamebuf[flen], DOTOBJ); memcpy(&objnamebuf[flen + SIZEOF(DOTOBJ) - 1], version.addr, version.len); objnamelen = flen + SIZEOF(DOTOBJ) + version.len - 1; objnamebuf[objnamelen] = 0; srcstr.addr = srcnamebuf; srcstr.len = srcnamelen; objstr.addr = objnamebuf; objstr.len = objnamelen; } if (!expdir) { if (OBJ == type) { zro_search(&objstr, &objdir, 0, 0); if (!objdir) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr); } else if (SRC == type) { zro_search(&objstr, &objdir, &srcstr, &srcdir); if (!srcdir) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_FILENOTFND, 2, srcnamelen, srcnamebuf); } else { zro_search(&objstr, &objdir, &srcstr, &srcdir); if (!objdir && !srcdir) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_FILENOTFND, 2, dollar_zsource.str.len, dollar_zsource.str.addr); } } } else { expdir = FALSE; type = NOTYPE; flen = v->str.len; memcpy(srcnamebuf, v->str.addr, flen); MEMCPY_LIT(&srcnamebuf[flen], DOTM); srcnamelen = flen + SIZEOF(DOTM) - 1; if ('%' == srcnamebuf[0]) srcnamebuf[0] = '_'; memcpy(objnamebuf, srcnamebuf, flen); MEMCPY_LIT(&objnamebuf[flen], DOTOBJ); objnamelen = flen + SIZEOF(DOTOBJ) - 1; srcstr.addr = srcnamebuf; srcstr.len = srcnamelen; objstr.addr = objnamebuf; objstr.len = objnamelen; zro_search(&objstr, &objdir, &srcstr, &srcdir); if (!objdir && !srcdir) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, v->str.len, v->str.addr, ERR_FILENOTFND, 2, v->str.len, v->str.addr); qualifier.mvtype = MV_STR; qualifier.str = TREF(dollar_zcompile); quals = &qualifier; } if (OBJ == type) { obj_fab.fab$b_fac = FAB$M_GET; obj_fab.fab$b_shr = FAB$M_SHRGET; if (NULL != objdir) { if (ZRO_TYPE_OBJLIB == objdir->type) libr = TRUE; else { srcfab.fab$l_dna = objdir->str.addr; srcfab.fab$b_dns = objdir->str.len; } } for (lcnt = 0; lcnt < MAX_FILE_OPEN_TRIES; lcnt++) { status = (FALSE == libr) ? sys$open(&srcfab): zl_olb(&objdir->str, &objstr, &librindx); if (RMS$_FLK != status) break; hiber_start(WAIT_FOR_FILE_TIME); } if (FALSE == (status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status); if (FALSE == ((FALSE == libr) ? incr_link(&srcfab, libr) : incr_link(&librindx, libr))) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, ERR_VERSION); status = (FALSE == libr) ? sys$close(&srcfab) : lbr$close(&librindx); if (FALSE == (status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, dollar_zsource.str.len, dollar_zsource.str.addr, status); } else /* either NO type or SOURCE type */ { src_found = obj_found = compile = FALSE; srcfab = obj_fab = cc$rms_fab; obj_fab.fab$l_xab = &objxab; srcxab = objxab = cc$rms_xabdat; obj_fab.fab$l_nam = &objnam; srcnam = objnam = cc$rms_nam; obj_fab.fab$l_fna = objnamebuf; obj_fab.fab$b_fns = objnamelen; obj_fab.fab$b_fac = FAB$M_GET; obj_fab.fab$b_shr = FAB$M_SHRGET; objnam.nam$l_esa = objcom; objnam.nam$b_ess = SIZEOF(objcom); srcfab.fab$l_nam = &srcnam; srcfab.fab$l_xab = &srcxab; srcfab.fab$l_fna = srcnamebuf; srcfab.fab$b_fns = srcnamelen; srcfab.fab$b_fac = FAB$M_GET; srcfab.fab$b_shr = FAB$M_SHRGET; srcnam.nam$l_esa = srccom; srcnam.nam$b_ess = SIZEOF(srccom); cmd_qlf.object_file.str.addr = objcom; cmd_qlf.object_file.str.len = 255; cmd_qlf.list_file.str.addr = list_file; cmd_qlf.list_file.str.len = 255; cmd_qlf.ceprep_file.str.addr = ceprep_file; cmd_qlf.ceprep_file.str.len = 255; if (srcdir && srcdir->str.len) { srcfab.fab$l_dna = srcdir->str.addr; srcfab.fab$b_dns = srcdir->str.len; } if (objdir && objdir->str.len) { if (ZRO_TYPE_OBJLIB == objdir->type) libr = TRUE; else { obj_fab.fab$l_dna = objdir->str.addr; obj_fab.fab$b_dns = objdir->str.len; } } if (SRC != type) { if (!expdir && !objdir) obj_found = FALSE; else if (!libr) { for (lcnt = 0; lcnt < MAX_FILE_OPEN_TRIES; lcnt++) { status = sys$open(&obj_fab); if (RMS$_FLK != status) break; hiber_start(WAIT_FOR_FILE_TIME); } if (!(status & 1)) { if (RMS$_FNF == status) obj_found = FALSE; else rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status); } else obj_found = TRUE; } else { status = zl_olb(&objdir->str, &objstr, &librindx); if (status) obj_found = TRUE; } } else compile = TRUE; if (!expdir && !srcdir) src_found = FALSE; else { for (lcnt = 0; lcnt < MAX_FILE_OPEN_TRIES; lcnt++) { status = sys$open(&srcfab); if (RMS$_FLK != status) break; hiber_start(WAIT_FOR_FILE_TIME); } if (!(status & 1)) { if ((RMS$_FNF == status) && (SRC != type)) src_found = FALSE; else rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status); } else { src_found = TRUE; if (SRC == type) { status = sys$close(&srcfab); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status); } } } if (SRC != type) { if (src_found) { if (obj_found) { if (QUADCMP(&srcxab.xab$q_rdt, &objxab.xab$q_rdt)) { status = sys$close(&obj_fab); obj_fab = cc$rms_fab; if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, status); compile = TRUE; } } else compile = TRUE; status = sys$close(&srcfab); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, status); } else if (!obj_found) rts_error(VARLSTCNT(8) ERR_ZLINKFILE, 2, objnamelen, objnamebuf, ERR_FILENOTFND, 2, objnamelen, objnamebuf); } if (compile) { zl_cmd_qlf(&quals->str, &cmd_qlf); if (!MV_DEFINED(&cmd_qlf.object_file)) { objnam.nam$b_nop = NAM$M_SYNCHK; status = sys$parse(&obj_fab); if (!(status & 1)) rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna); cmd_qlf.object_file.mvtype = MV_STR; cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver; } qlf = cmd_qlf.qlf; if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type)) { cmd_qlf.qlf = glb_cmd_qlf.qlf; rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT); } zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa); if ((SRC == type) && !(qlf & CQ_OBJECT)) return; } status = libr ? incr_link(&librindx, libr) : incr_link(&obj_fab, libr); if (!status) /* due only to version mismatch, so recompile */ { if (!libr) { status = sys$close(&obj_fab); obj_fab = cc$rms_fab; } else status = lbr$close(&librindx); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status); if (compile) GTMASSERT; if (!src_found) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_VERSION); zl_cmd_qlf(&quals->str, &cmd_qlf); if (!MV_DEFINED(&cmd_qlf.object_file)) { objnam.nam$b_nop = NAM$M_SYNCHK; status = sys$parse(&obj_fab); if (!(status & 1)) rts_error(VARLSTCNT(4) ERR_FILEPARSE, 2, obj_fab.fab$b_fns, obj_fab.fab$l_fna); cmd_qlf.object_file.mvtype = MV_STR; cmd_qlf.object_file.str.len = objnam.nam$b_esl - objnam.nam$b_ver; } if (!(cmd_qlf.qlf & CQ_OBJECT) && (SRC != type)) { cmd_qlf.qlf = glb_cmd_qlf.qlf; rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, srcnamelen, srcnamebuf, ERR_ZLNOOBJECT); } zlcompile(srcnam.nam$b_esl, srcnam.nam$l_esa); if (!incr_link(&obj_fab, libr)) GTMASSERT; } if (!libr) { status = sys$close(&obj_fab); obj_fab = cc$rms_fab; } else status = lbr$close(&librindx); if (!(status & 1)) rts_error(VARLSTCNT(5) ERR_ZLINKFILE, 2, objstr.len, objstr.addr, status); } return; }
void bin_load(uint4 begin, uint4 end) { unsigned char *ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop; unsigned char hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1]; unsigned char *end_buff; unsigned short rec_len, next_cmpc; int len; int current, last, length, max_blk_siz, max_key, status; uint4 iter, max_data_len, max_subsc_len, key_count; ssize_t rec_count, global_key_count, subsc_len,extr_std_null_coll; boolean_t need_xlation, new_gvn, utf8_extract; rec_hdr *rp, *next_rp; mval v, tmp_mval; mstr mstr_src, mstr_dest; collseq *extr_collseq, *db_collseq, *save_gv_target_collseq; coll_hdr extr_collhdr, db_collhdr; gv_key *tmp_gvkey = NULL; /* null-initialize at start, will be malloced later */ char std_null_coll[BIN_HEADER_NUMSZ + 1]; # ifdef GTM_CRYPT gtmcrypt_key_t *encr_key_handles; char *inbuf; int4 index; int req_dec_blk_size, init_status, crypt_status; muext_hash_hdr_ptr_t hash_array = NULL; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(4 == SIZEOF(coll_hdr)); gvinit(); v.mvtype = MV_STR; len = file_input_bin_get((char **)&ptr); hdr_lvl = EXTR_HEADER_LEVEL(ptr); if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len)))) { rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* expecting the level in a single character */ assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3)); if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION) < hdr_lvl) { /* ignore the level check */ rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* check if extract was generated in UTF-8 mode */ utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_exit(ERR_LDBINFMT); } if ('4' >= hdr_lvl) { /* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte) * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above. */ for (c = ptr, ctop = c + len; c < ctop; c++) { if ('\0' == *c) *c = ' '; } } util_out_print("Label = !AD\n", TRUE, len, ptr); new_gvn = FALSE; if (hdr_lvl > '3') { memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ); std_null_coll[BIN_HEADER_NUMSZ] = '\0'; extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10); if (0 != extr_std_null_coll && 1!= extr_std_null_coll) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } } else extr_std_null_coll = 0; # ifdef GTM_CRYPT if ('5' <= hdr_lvl) { int i, num_indexes; len = file_input_bin_get((char **)&ptr); hash_array = (muext_hash_hdr *)malloc(len); /* store hashes of all the files used during extract into muext_hash_hdr structure */ memcpy((char *)hash_array, ptr, len); num_indexes = len / GTMCRYPT_HASH_LEN; encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes); INIT_PROC_ENCRYPTION(crypt_status); GC_BIN_LOAD_ERR(crypt_status); for (index = 0; index < num_indexes; index++) { if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN)) continue; GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status); GC_BIN_LOAD_ERR(crypt_status); } } # endif if ('2' < hdr_lvl) { len = file_input_bin_get((char **)&ptr); if (SIZEOF(coll_hdr) != len) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } extr_collhdr = *((coll_hdr *)(ptr)); new_gvn = TRUE; } else gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0'); if (begin < 2) begin = 2; for (iter = 2; iter < begin; iter++) { if (!(len = file_input_bin_get((char **)&ptr))) { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); util_out_print("Error reading record number: !UL\n", TRUE, iter); mupip_error_occurred = TRUE; return; } else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); iter--; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; global_key_count = key_count = 0; rec_count = begin - 1; extr_collseq = db_collseq = NULL; need_xlation = FALSE; assert(NULL == tmp_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* tmp_gvkey will point to malloced memory after this */ for (; !mupip_DB_full ;) { if (++rec_count > end) break; next_cmpc = 0; mupip_error_occurred = FALSE; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } /* reset the stringpool for every record in order to avoid garbage collection */ stringpool.free = stringpool.base; if (!(len = file_input_bin_get((char **)&ptr)) || mupip_error_occurred) break; else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); new_gvn = TRUE; /* next record will contain a new gvn */ rec_count--; /* Decrement as this record does not count as a record for loading purposes */ continue; } rp = (rec_hdr*)(ptr); # ifdef GTM_CRYPT if ('5' <= hdr_lvl) { /* Getting index value from the extracted file. It indicates which database file this record belongs to */ GET_LONG(index, ptr); if (-1 != index) /* Indicates that the record is encrypted. */ { req_dec_blk_size = len - SIZEOF(int4); inbuf = (char *)(ptr + SIZEOF(int4)); GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status); GC_BIN_LOAD_ERR(crypt_status); } rp = (rec_hdr*)(ptr + SIZEOF(int4)); } # endif btop = ptr + len; cp1 = (unsigned char*)(rp + 1); v.str.addr = (char*)cp1; while (*cp1++) ; v.str.len =INTCAST((char*)cp1 - v.str.addr - 1); if (('2' >= hdr_lvl) || new_gvn) { if ((HASHT_GBLNAME_LEN == v.str.len) && (0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN))) continue; bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str); max_key = gv_cur_region->max_key_size; db_collhdr.act = gv_target->act; db_collhdr.ver = gv_target->ver; db_collhdr.nct = gv_target->nct; } GET_USHORT(rec_len, &rp->rsiz); if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (new_gvn) { global_key_count = 1; if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver || db_collhdr.nct != extr_collhdr.nct || gv_cur_region->std_null_coll != extr_std_null_coll)) { if (extr_collhdr.act) { if (extr_collseq = ready_collseq((int)extr_collhdr.act)) { if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act, extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } if (db_collhdr.act) { if (db_collseq = ready_collseq((int)db_collhdr.act)) { if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } need_xlation = TRUE; } else need_xlation = FALSE; } new_gvn = FALSE; for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len)) { GET_USHORT(rec_len, &rp->rsiz); if (rec_len + (unsigned char *)rp > btop) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } cp1 = (unsigned char*)(rp + 1); cp2 = gv_currkey->base + rp->cmpc; current = 1; for (;;) { last = current; current = *cp2++ = *cp1++; if (0 == last && 0 == current) break; if (cp1 > (unsigned char *)rp + rec_len || cp2 > (unsigned char *)gv_currkey + gv_currkey->top) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } } if (mupip_error_occurred) break; gv_currkey->end = cp2 - gv_currkey->base - 1; if (need_xlation) { assert(hdr_lvl >= '3'); assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll); /* gv_currkey would have been modified/translated in the earlier put */ memcpy(gv_currkey->base, cmpc_str, next_cmpc); next_rp = (rec_hdr *)((unsigned char*)rp + rec_len); if ((unsigned char*)next_rp < btop) { next_cmpc = next_rp->cmpc; assert(next_cmpc <= gv_currkey->end); memcpy(cmpc_str, gv_currkey->base, next_cmpc); } else next_cmpc = 0; /* length of the key might change (due to nct variation), * so get a copy of the original key from the extract */ memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1); gvkey_char_ptr = dup_key_str; while (*gvkey_char_ptr++) ; gv_currkey->prev = 0; gv_currkey->end = gvkey_char_ptr - dup_key_str; assert(gv_keysize <= tmp_gvkey->top); while (*gvkey_char_ptr) { /* get next subscript (in GT.M internal subsc format) */ subsc_len = 0; tmp_ptr = src_buff; while (*gvkey_char_ptr) *tmp_ptr++ = *gvkey_char_ptr++; subsc_len = tmp_ptr - src_buff; src_buff[subsc_len] = '\0'; if (extr_collseq) { /* undo the extract time collation */ TREF(transform) = TRUE; save_gv_target_collseq = gv_target->collseq; gv_target->collseq = extr_collseq; } else TREF(transform) = FALSE; /* convert the subscript to string format */ end_buff = gvsub2str(src_buff, dest_buff, FALSE); /* transform the string to the current subsc format */ TREF(transform) = TRUE; tmp_mval.mvtype = MV_STR; tmp_mval.str.addr = (char *)dest_buff; tmp_mval.str.len = INTCAST(end_buff - dest_buff); tmp_gvkey->prev = 0; tmp_gvkey->end = 0; if (extr_collseq) gv_target->collseq = save_gv_target_collseq; mval2subsc(&tmp_mval, tmp_gvkey); /* we now have the correctly transformed subscript */ tmp_key_ptr = gv_currkey->base + gv_currkey->end; memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1); gv_currkey->prev = gv_currkey->end; gv_currkey->end += tmp_gvkey->end; gvkey_char_ptr++; } if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev) { if (extr_std_null_coll == 0) { GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end); } else { STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end); } } } if (gv_currkey->end >= max_key) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (max_subsc_len < (gv_currkey->end + 1)) max_subsc_len = gv_currkey->end + 1; v.str.addr = (char*)cp1; v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp)); if (max_data_len < v.str.len) max_data_len = v.str.len; bin_call_db(BIN_PUT, (INTPTR_T)&v, 0); if (mupip_error_occurred) { if (!mupip_DB_full) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); util_out_print(0, TRUE); } break; } key_count++; global_key_count++; } } GTMCRYPT_ONLY( if (NULL != hash_array) free(hash_array); )
void bin_load(uint4 begin, uint4 end) { unsigned char *ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr; unsigned char hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1]; unsigned char *end_buff; unsigned short len, rec_len, next_cmpc; int current, last, length, max_blk_siz, max_key, status; uint4 iter, max_data_len, max_subsc_len, key_count; ssize_t rec_count, global_key_count, subsc_len,extr_std_null_coll; boolean_t need_xlation, new_gvn, utf8_extract; rec_hdr *rp, *next_rp; mval v, tmp_mval; mstr mstr_src, mstr_dest; collseq *extr_collseq, *db_collseq, *save_gv_target_collseq; coll_hdr extr_collhdr, db_collhdr; gv_key *tmp_gvkey; char std_null_coll[BIN_HEADER_NUMSZ + 1]; error_def(ERR_GVIS); error_def(ERR_TEXT); error_def(ERR_LDBINFMT); error_def(ERR_LOADCTRLY); error_def(ERR_LOADEOF); error_def(ERR_MUNOFINISH); error_def(ERR_COLLTYPVERSION); error_def(ERR_COLLATIONUNDEF); error_def(ERR_OLDBINEXTRACT); error_def(ERR_LOADINVCHSET); tmp_gvkey = (gv_key *)malloc(sizeof(gv_key) + MAX_KEY_SZ - 1); assert(4 == sizeof(coll_hdr)); gvinit(); v.mvtype = MV_STR; len = mu_bin_get((char **)&ptr); hdr_lvl = EXTR_HEADER_LEVEL(ptr); if (!((hdr_lvl == '4' && len == BIN_HEADER_SZ) || (hdr_lvl < '4' && len == V3_BIN_HEADER_SZ))) { rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* assert the assumption that the level can be represented in a single character */ assert(' ' == *(ptr + sizeof(BIN_HEADER_LABEL) - 3)); if (0 != memcmp(ptr, BIN_HEADER_LABEL, sizeof(BIN_HEADER_LABEL) - 2) || hdr_lvl < '2' || *(BIN_HEADER_VERSION) < hdr_lvl) { /* ignore the level check */ rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* check if extract was generated in UTF-8 mode */ utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_exit(ERR_LDBINFMT); } util_out_print("Label = !AD\n", TRUE, len, ptr); new_gvn = FALSE; if (hdr_lvl > '3') { memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ); std_null_coll[BIN_HEADER_NUMSZ] = '\0'; extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10); if (0 != extr_std_null_coll && 1!= extr_std_null_coll) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } } else extr_std_null_coll = 0; if (hdr_lvl > '2') { len = mu_bin_get((char **)&ptr); if (sizeof(coll_hdr) != len) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } extr_collhdr = *((coll_hdr *)(ptr)); new_gvn = TRUE; } else gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0'); if (begin < 2) begin = 2; for (iter = 2; iter < begin; iter++) { if (!(len = mu_bin_get((char **)&ptr))) { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); util_out_print("Error reading record number: !UL\n", TRUE, iter); mupip_error_occurred = TRUE; return; } else if (len == sizeof(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); iter--; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; key_count = 0; rec_count = begin - 1; extr_collseq = db_collseq = NULL; need_xlation = FALSE; for (; !mupip_DB_full ;) { if (++rec_count > end) break; next_cmpc = 0; mupip_error_occurred = FALSE; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } /* reset the stringpool for every record in order to avoid garbage collection */ stringpool.free = stringpool.base; if (!(len = mu_bin_get((char **)&ptr)) || mupip_error_occurred) break; else if (len == sizeof(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); new_gvn = TRUE; /* next record will contain a new gvn */ rec_count--; /* Decrement as this record does not count as a record for loading purposes */ continue; } global_key_count = 1; rp = (rec_hdr*)ptr; btop = ptr + len; cp1 = (unsigned char*)(rp + 1); v.str.addr = (char*)cp1; while (*cp1++) ; v.str.len =INTCAST((char*)cp1 - v.str.addr - 1); if (hdr_lvl <= '2' || new_gvn) { bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str); max_key = gv_cur_region->max_key_size; db_collhdr.act = gv_target->act; db_collhdr.ver = gv_target->ver; db_collhdr.nct = gv_target->nct; } GET_SHORT(rec_len, &rp->rsiz); if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred) { bin_call_db(ERR_COR, rec_count, global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (new_gvn) { if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver || db_collhdr.nct != extr_collhdr.nct || gv_cur_region->std_null_coll != extr_std_null_coll)) { if (extr_collhdr.act) { if (extr_collseq = ready_collseq((int)extr_collhdr.act)) { if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act, extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } if (db_collhdr.act) { if (db_collseq = ready_collseq((int)db_collhdr.act)) { if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } need_xlation = TRUE; } else need_xlation = FALSE; } new_gvn = FALSE; for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len)) { GET_SHORT(rec_len, &rp->rsiz); if (rec_len + (unsigned char *)rp > btop) { bin_call_db(ERR_COR, rec_count, global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } cp1 = (unsigned char*)(rp + 1); cp2 = gv_currkey->base + rp->cmpc; current = 1; for (;;) { last = current; current = *cp2++ = *cp1++; if (0 == last && 0 == current) break; if (cp1 > (unsigned char *) rp + rec_len || cp2 > (unsigned char *) gv_currkey + gv_currkey->top) { bin_call_db(ERR_COR, rec_count, global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } } if (mupip_error_occurred) break; gv_currkey->end = cp2 - gv_currkey->base - 1; if (need_xlation) { assert(hdr_lvl >= '3'); assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll); /* gv_currkey would have been modified/translated in the earlier put */ memcpy(gv_currkey->base, cmpc_str, next_cmpc); next_rp = (rec_hdr *)((unsigned char*)rp + rec_len); if ((unsigned char*)next_rp < btop) { next_cmpc = next_rp->cmpc; assert(next_cmpc <= gv_currkey->end); memcpy(cmpc_str, gv_currkey->base, next_cmpc); } else next_cmpc = 0; /* length of the key might change (due to nct variation), * so get a copy of the original key from the extract */ memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1); gvkey_char_ptr = dup_key_str; while (*gvkey_char_ptr++) ; gv_currkey->prev = 0; gv_currkey->end = gvkey_char_ptr - dup_key_str; tmp_gvkey->top = gv_keysize; while (*gvkey_char_ptr) { /* get next subscript (in GT.M internal subsc format) */ subsc_len = 0; tmp_ptr = src_buff; while (*gvkey_char_ptr) *tmp_ptr++ = *gvkey_char_ptr++; subsc_len = tmp_ptr - src_buff; src_buff[subsc_len] = '\0'; if (extr_collseq) { /* undo the extract time collation */ transform = TRUE; save_gv_target_collseq = gv_target->collseq; gv_target->collseq = extr_collseq; } else transform = FALSE; /* convert the subscript to string format */ end_buff = gvsub2str(src_buff, dest_buff, FALSE); /* transform the string to the current subsc format */ transform = TRUE; tmp_mval.mvtype = MV_STR; tmp_mval.str.addr = (char *)dest_buff; tmp_mval.str.len = INTCAST(end_buff - dest_buff); tmp_gvkey->prev = 0; tmp_gvkey->end = 0; if (extr_collseq) gv_target->collseq = save_gv_target_collseq; mval2subsc(&tmp_mval, tmp_gvkey); /* we now have the correctly transformed subscript */ tmp_key_ptr = gv_currkey->base + gv_currkey->end; memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1); gv_currkey->prev = gv_currkey->end; gv_currkey->end += tmp_gvkey->end; gvkey_char_ptr++; } if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev) { if (extr_std_null_coll == 0) { GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end); } else { STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end); } } } if (gv_currkey->end >= max_key) { bin_call_db(ERR_COR, rec_count, global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (max_subsc_len < (gv_currkey->end + 1)) max_subsc_len = gv_currkey->end + 1; v.str.addr = (char*)cp1; v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp) ); if (max_data_len < v.str.len) max_data_len = v.str.len; bin_call_db(BIN_PUT, (INTPTR_T)&v, 0); if (mupip_error_occurred) { if (!mupip_DB_full) { bin_call_db(ERR_COR, rec_count, global_key_count); util_out_print(0, TRUE); } break; } key_count++; global_key_count++; } } free(tmp_gvkey); mu_load_close(); util_out_print("LOAD TOTAL!_!_Key Cnt: !UL Max Subsc Len: !UL Max Data Len: !UL", TRUE, key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL\n", TRUE, key_count ? (rec_count - 1) : 0); if (mu_ctrly_occurred) { gtm_putmsg(VARLSTCNT(1) ERR_LOADCTRLY); mupip_exit(ERR_MUNOFINISH); } }