boolean_t mur_report_error(jnl_ctl_list *jctl, enum mur_error code) { error_def(ERR_BOVTMGTEOVTM); error_def(ERR_DUPTOKEN); error_def(ERR_JNLBADRECFMT); error_def(ERR_PREVJNLNOEOF); error_def(ERR_UNKNOWNRECTYPE); switch (code) { default: assert(FALSE); break; case MUR_DUPTOKEN: assert(FALSE); gtm_putmsg(VARLSTCNT(7) ERR_DUPTOKEN, 5, &((struct_jrec_tcom *)jctl->reg_ctl->mur_desc->jnlrec)->token_seq.token, jctl->jnl_fn_len, jctl->jnl_fn, DB_LEN_STR(jctl->reg_ctl->gd)); break; case MUR_PREVJNLNOEOF: gtm_putmsg(VARLSTCNT(4) ERR_PREVJNLNOEOF, 2, jctl->jnl_fn_len, jctl->jnl_fn); break; case MUR_JNLBADRECFMT: gtm_putmsg(VARLSTCNT(5) ERR_JNLBADRECFMT, 3, jctl->jnl_fn_len, jctl->jnl_fn, jctl->rec_offset); break; case MUR_BOVTMGTEOVTM: gtm_putmsg(VARLSTCNT(6) ERR_BOVTMGTEOVTM, 4, jctl->jnl_fn_len, jctl->jnl_fn, &jctl->jfh->bov_timestamp, &jctl->jfh->eov_timestamp); break; } return MUR_WITHIN_ERROR_LIMIT(murgbl.err_cnt, mur_options.error_limit); /* side-effect : increments murgbl.err_cnt */ }
boolean_t mur_report_error(enum mur_error code) { error_def(ERR_UNKNOWNRECTYPE); error_def(ERR_DUPTOKEN); error_def(ERR_PREVJNLNOEOF); error_def(ERR_JNLBADRECFMT); switch (code) { default: assert(FALSE); break; case MUR_DUPTOKEN: assert(FALSE); gtm_putmsg(VARLSTCNT(7) ERR_DUPTOKEN, 5, &((struct_jrec_tcom *)mur_rab.jnlrec)->token_seq.token, mur_jctl->jnl_fn_len, mur_jctl->jnl_fn, DB_LEN_STR(mur_ctl[mur_regno].gd)); break; case MUR_PREVJNLNOEOF: gtm_putmsg(VARLSTCNT(4) ERR_PREVJNLNOEOF, 2, mur_jctl->jnl_fn_len, mur_jctl->jnl_fn); break; case MUR_JNLBADRECFMT: gtm_putmsg(VARLSTCNT(5) ERR_JNLBADRECFMT, 3, mur_jctl->jnl_fn_len, mur_jctl->jnl_fn, mur_jctl->rec_offset); break; case MUR_BOVTMGTEOVTM: break; } return MUR_WITHIN_ERROR_LIMIT(murgbl.err_cnt, mur_options.error_limit); /* side-effect : increments murgbl.err_cnt */ }
int mu_rndwn_sem_all(void) { int save_errno, exit_status = SS_NORMAL, semid; char entry[MAX_ENTRY_LEN]; FILE *pf; char fname[MAX_FN_LEN + 1], *fgets_res; boolean_t rem_sem; shm_parms *parm_buff; if (NULL == (pf = POPEN(IPCS_SEM_CMD_STR ,"r"))) { save_errno = errno; gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno); return ERR_MUNOTALLSEC; } while (NULL != (FGETS(entry, SIZEOF(entry), pf, fgets_res)) && entry[0] != '\n') { if (-1 != (semid = parse_sem_id(entry))) { if (is_orphaned_gtm_semaphore(semid)) { if (-1 != semctl(semid, 0, IPC_RMID)) { gtm_putmsg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid); send_msg(VARLSTCNT(3) ERR_SEMREMOVED, 1, semid); } } } } pclose(pf); return exit_status; }
void cre_jnl_file_intrpt_rename(int fn_len, sm_uc_ptr_t fn) { mstr filestr; int status1, status2, ext_new_jnl_fn_len; uint4 status, ustatus; unsigned char ext_new_jnl_fn[MAX_FN_LEN]; error_def(ERR_FILEPARSE); error_def(ERR_RENAMEFAIL); error_def(ERR_FILEDELFAIL); error_def(ERR_FILEDEL); error_def(ERR_FILERENAME); filestr.addr = (char *)fn; filestr.len = fn_len; prepare_unique_name((char *)fn, fn_len, "", EXT_NEW, (char *)ext_new_jnl_fn, &ext_new_jnl_fn_len, &ustatus); assert(SS_NORMAL == ustatus); status1 = gtm_file_stat(&filestr, NULL, NULL, FALSE, &ustatus); if (FILE_STAT_ERROR == status1) { if (run_time) send_msg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus); else gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus); return; } filestr.addr = (char *)ext_new_jnl_fn; filestr.len = ext_new_jnl_fn_len; status2 = gtm_file_stat(&filestr, NULL, NULL, FALSE, &ustatus); if (FILE_STAT_ERROR == status2) { if (run_time) send_msg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus); else gtm_putmsg(VARLSTCNT(5) ERR_FILEPARSE, 2, filestr.len, filestr.addr, ustatus); return; } if (FILE_NOT_FOUND == status1) { if (FILE_PRESENT == status2) { status = gtm_rename(filestr.addr, filestr.len, (char *)fn, fn_len, &ustatus); if (SYSCALL_ERROR(status)) { if (run_time) { VMS_ONLY(send_msg(VARLSTCNT(8) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr, fn_len, fn, status, ustatus);) UNIX_ONLY(send_msg(VARLSTCNT(7) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr, fn_len, fn, status);) } else { VMS_ONLY(gtm_putmsg(VARLSTCNT(8) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr, fn_len, fn, status, ustatus);) UNIX_ONLY(gtm_putmsg(VARLSTCNT(7) ERR_RENAMEFAIL, 4, filestr.len, filestr.addr, fn_len, fn, status);) }
/* * Description: * Grab ftok semaphore on replication instance file * Release all replication semaphores for the instance (both jnlpool and recvpool) * Release ftok semaphore * Parameters: * Return Value: TRUE, if succsessful * FALSE, if fails. */ boolean_t mu_replpool_remove_sem(boolean_t immediate) { char *instname; gd_region *replreg; unix_db_info *udi; unsigned int full_len; int save_errno; error_def(ERR_REPLFTOKSEM); error_def(ERR_REPLACCSEM); /* * JNL POOL SEMAPHORES */ replreg = jnlpool.jnlpool_dummy_reg; assert(replreg); instname = (char *)replreg->dyn.addr->fname; full_len = replreg->dyn.addr->fname_len; if (0 == full_len) return TRUE; if (!ftok_sem_get(replreg, TRUE, REPLPOOL_ID, immediate)) rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname); if (0 != remove_sem_set(SOURCE)) { save_errno = REPL_SEM_ERRNO; if (!ftok_sem_release(replreg, TRUE, TRUE)) gtm_putmsg(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname); udi = FILE_INFO(replreg); rts_error(VARLSTCNT(6) ERR_REPLACCSEM, 3, udi->semid, full_len, instname, save_errno); } repl_inst_jnlpool_reset(); /* * RECV POOL SEMAPHORES */ replreg = recvpool.recvpool_dummy_reg; assert(replreg); if (0 != remove_sem_set(RECV)) { save_errno = REPL_SEM_ERRNO; if (!ftok_sem_release(replreg, TRUE, TRUE)) gtm_putmsg(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname); udi = FILE_INFO(replreg); rts_error(VARLSTCNT(6) ERR_REPLACCSEM, 3, udi->semid, full_len, instname, save_errno); } repl_inst_recvpool_reset(); if (!ftok_sem_release(replreg, TRUE, immediate)) rts_error(VARLSTCNT(4) ERR_REPLFTOKSEM, 2, full_len, instname); return TRUE; }
static void tcp_write(char *temp, char *buf, int nbytes) { int socket, nwritten, iostatus, send_retry; socket = *(int *)(temp); nwritten = 0; send_retry = MAX_TCP_SEND_RETRY; do { if (-1 != (iostatus = tcp_routines.aa_send(socket, buf + nwritten, nbytes - nwritten, 0))) { nwritten += iostatus; if (nwritten == nbytes) break; } else if (EINTR != errno) break; } while (0 < send_retry--); if ((nwritten != nbytes) && (-1 == iostatus)) { gtm_putmsg(VARLSTCNT(1) errno); tcp_routines.aa_close(socket); backup_write_errno = errno; } return; }
/* input parameter "command_name" is a string that is either "MUPIP REORG UPGRADE/DOWNGRADE" or "MUPIP SET VERSION" */ int4 desired_db_format_set(gd_region *reg, enum db_ver new_db_format, char *command_name) { boolean_t was_crit; char *db_fmt_str; char *wcblocked_ptr; int4 status; uint4 jnl_status; inctn_opcode_t save_inctn_opcode; sgmnt_addrs *csa; sgmnt_data_ptr_t csd; trans_num curr_tn; jnl_private_control *jpc; jnl_buffer_ptr_t jbp; assert(reg->open); csa = &FILE_INFO(reg)->s_addrs; csd = csa->hdr; GTMCRYPT_ONLY( /* We don't allow databases to be encrypted if the version is V4 */ if (csd->is_encrypted && (GDSV4 == new_db_format)) { gtm_putmsg(VARLSTCNT(4) ERR_CRYPTNOV4, 2, DB_LEN_STR(reg)); return ERR_CRYPTNOV4; } )
STATICFNDEF void mu_rndwn_all_helper(shm_parms *parm_buff, char *fname, int *exit_status, int *tmp_exit_status) { replpool_identifier replpool_id; boolean_t ret_status, jnlpool_sem_created; unsigned char ipcs_buff[MAX_IPCS_ID_BUF], *ipcs_ptr; ESTABLISH(mu_rndwn_all_helper_ch); if (validate_db_shm_entry(parm_buff, fname, tmp_exit_status)) { if (SS_NORMAL == *tmp_exit_status) { /* shm still exists */ mu_gv_cur_reg_init(); gv_cur_region->dyn.addr->fname_len = strlen(fname); STRNCPY_STR(gv_cur_region->dyn.addr->fname, fname, gv_cur_region->dyn.addr->fname_len); if (mu_rndwn_file(gv_cur_region, FALSE)) gtm_putmsg(VARLSTCNT(4) ERR_MUFILRNDWNSUC, 2, DB_LEN_STR(gv_cur_region)); else *exit_status = ERR_MUNOTALLSEC; mu_gv_cur_reg_free(); } else { /* shm has been cleaned up by "validate_db_shm_entry" so no need of any more cleanup here */ assert(ERR_SHMREMOVED == *tmp_exit_status); *tmp_exit_status = SS_NORMAL; /* reset tmp_exit_status for below logic to treat this as normal */ } } else if ((SS_NORMAL == *tmp_exit_status) && validate_replpool_shm_entry(parm_buff, (replpool_id_ptr_t)&replpool_id, tmp_exit_status)) { if (SS_NORMAL == *tmp_exit_status) { assert(JNLPOOL_SEGMENT == replpool_id.pool_type || RECVPOOL_SEGMENT == replpool_id.pool_type); ret_status = mu_rndwn_repl_instance(&replpool_id, TRUE, FALSE, &jnlpool_sem_created); ipcs_ptr = i2asc((uchar_ptr_t)ipcs_buff, parm_buff->shmid); *ipcs_ptr = '\0'; gtm_putmsg(VARLSTCNT(6) (JNLPOOL_SEGMENT == replpool_id.pool_type) ? (ret_status ? ERR_MUJPOOLRNDWNSUC : ERR_MUJPOOLRNDWNFL) : (ret_status ? ERR_MURPOOLRNDWNSUC : ERR_MURPOOLRNDWNFL), 4, LEN_AND_STR(ipcs_buff), LEN_AND_STR(replpool_id.instfilename)); if (!ret_status) *exit_status = ERR_MUNOTALLSEC; } else { /* shm has been cleaned up by "validate_replpool_shm_entry" so no need of any more cleanup here */ assert(ERR_SHMREMOVED == *tmp_exit_status); *tmp_exit_status = SS_NORMAL; /* reset tmp_exit_status for below logic to treat this as normal */ } } REVERT; }
uint4 mupip_set_journal_newstate(set_jnl_options *jnl_options, jnl_create_info *jnl_info, mu_set_rlist *rptr) { enum jnl_state_codes jnl_curr_state; enum repl_state_codes repl_curr_state; boolean_t current_image; enum db_acc_method acc_meth; error_def(ERR_REPLNOBEFORE); error_def(ERR_REPLJNLCNFLCT); error_def(ERR_JNLDISABLE); error_def(ERR_MMBEFOREJNL); error_def(ERR_MMNOBFORRPL); jnl_curr_state = (enum jnl_state_codes)rptr->sd->jnl_state; repl_curr_state = (enum repl_state_codes)rptr->sd->repl_state; acc_meth = rptr->sd->acc_meth; current_image = rptr->sd->jnl_before_image; if (CLI_ABSENT == jnl_options->cli_journal) rptr->jnl_new_state = jnl_curr_state; else if ((CLI_NEGATED == jnl_options->cli_journal) || (CLI_NEGATED == jnl_options->cli_enable)) rptr->jnl_new_state = jnl_notallowed; /* DISABLE specified */ else if ((jnl_notallowed != jnl_curr_state) || (CLI_PRESENT == jnl_options->cli_enable)) { /* journaling is already ENABLED or ENABLE is explicitly specified */ if (CLI_NEGATED == jnl_options->cli_on) /* OFF specified */ rptr->jnl_new_state = jnl_closed; else if (repl_curr_state == repl_was_open && CLI_PRESENT != jnl_options->cli_replic_on) { /* Journaling was turned OFF by jnl_file_lost(). Do not allow turning journaling ON without also turning replication ON */ gtm_putmsg(VARLSTCNT(10) ERR_REPLJNLCNFLCT, 8, LEN_AND_STR(jnl_state_lit[jnl_open]), DB_LEN_STR(gv_cur_region), LEN_AND_STR(repl_state_lit[repl_closed]), LEN_AND_STR(jnl_state_lit[jnl_open])); return EXIT_WRN; } else /* ON explicitly specified or present by default */ rptr->jnl_new_state = jnl_open; } else /* jnl_notallowed == jnl_curr_state && CLI_ABSENT == jnl_options->cli_enable */ { if (CLI_PRESENT != jnl_options->cli_replic_on) { gtm_putmsg(VARLSTCNT(4) ERR_JNLDISABLE, 2, DB_LEN_STR(gv_cur_region)); return EXIT_WRN; } else rptr->jnl_new_state = jnl_open; /* turn journaling on for REPLICATION=ON */ } VMS_ONLY(rptr->before_images = (jnl_options->image_type_specified ? jnl_info->before_images : current_image);)
boolean_t mur_fopen_sp(jnl_ctl_list *jctl) { struct stat stat_buf; int status, perms; error_def(ERR_JNLFILEOPNERR); error_def(ERR_SYSCALL); perms = O_RDONLY; jctl->read_only = TRUE; /* Both for recover and rollback open in read/write mode. We do not need to write in journal file * for mupip journal extract/show/verify or recover -forward. So open it as read-only */ if (mur_options.update && !mur_options.forward) { perms = O_RDWR; jctl->read_only = FALSE; } jctl->channel = OPEN((char *)jctl->jnl_fn, perms); if (-1 != jctl->channel) { FSTAT_FILE(jctl->channel, &stat_buf, status); if (-1 != status) { jctl->os_filesize = (off_jnl_t)stat_buf.st_size; return TRUE; } jctl->status = errno; CLOSEFILE(jctl->channel, status); } else jctl->status = errno; if (ENOENT == jctl->status) /* File Not Found is a common error, so no need for SYSCALL */ gtm_putmsg(VARLSTCNT(5) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, jctl->status); else gtm_putmsg(VARLSTCNT(12) ERR_JNLFILEOPNERR, 2, jctl->jnl_fn_len, jctl->jnl_fn, ERR_SYSCALL, 5, LEN_AND_STR((-1 == jctl->channel) ? "open" : "fstat"), CALLFROM, jctl->status); jctl->channel = NOJNL; return FALSE; }
static bool lke_process(int argc) { bool flag = FALSE; int res; static int save_stderr = SYS_STDERR; ESTABLISH_RET(util_ch, TRUE); if (util_interrupt) rts_error(VARLSTCNT(1) ERR_CTRLC); if (SYS_STDERR != save_stderr) /* necesary in case of rts_error */ close_fileio(&save_stderr); assert(SYS_STDERR == save_stderr); func = 0; util_interrupt = 0; if (argc < 2) display_prompt(); if ( EOF == (res = parse_cmd())) { if (util_interrupt) { rts_error(VARLSTCNT(1) ERR_CTRLC); REVERT; return TRUE; } else { REVERT; return FALSE; } } else if (res) { if (1 < argc) { REVERT; rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); } else gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); } if (func) { flag = open_fileio(&save_stderr); /* save_stderr = SYS_STDERR if -output option not present */ func(); if (flag) close_fileio(&save_stderr); assert(SYS_STDERR == save_stderr); } REVERT; return(1 >= argc); }
void turn_tracing_on(mval *gvn) { struct tms *curr; trace_entry tmp_trc_tbl_entry; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; if (is_tracing_on) { gtm_putmsg(VARLSTCNT(1) ERR_TRACINGON); return; } if (0 == gvn->str.len || '^' != gvn->str.addr[0]) rts_error(VARLSTCNT(4) ERR_NOTGBL, 2, gvn->str.len, gvn->str.addr); if (!TREF(mprof_ptr)) { TREF(mprof_ptr) = (mprof_wrapper *)malloc(SIZEOF(mprof_wrapper)); memset(TREF(mprof_ptr), 0, SIZEOF(mprof_wrapper)); } parse_gvn(gvn); (TREF(mprof_ptr))->gbl_to_fill = *gvn; (TREF(mprof_ptr))->gbl_to_fill.str.addr = (char *)malloc(gvn->str.len); /* len was already set up */ memcpy((TREF(mprof_ptr))->gbl_to_fill.str.addr, gvn->str.addr, gvn->str.len); if (!(TREF(mprof_ptr))->pcavailbase) { (TREF(mprof_ptr))->pcavailbase = (char **)malloc(PROFCALLOC_DSBLKSIZE); *(TREF(mprof_ptr))->pcavailbase = 0; } (TREF(mprof_ptr))->pcavailptr = (TREF(mprof_ptr))->pcavailbase; (TREF(mprof_ptr))->pcavail = PROFCALLOC_DSBLKSIZE - SIZEOF(char *); memset((TREF(mprof_ptr))->pcavailptr + 1, 0, (TREF(mprof_ptr))->pcavail); curr = &((TREF(mprof_ptr))->tprev); TIMES(curr); mprof_stack_init(); TREF(prof_fp) = mprof_stack_push(); get_entryref_information(FALSE, NULL); tmp_trc_tbl_entry.rout_name = NULL; tmp_trc_tbl_entry.label_name = NULL; (TREF(mprof_ptr))->curr_tblnd = (TREF(mprof_ptr))->head_tblnd = NULL; (TREF(prof_fp))->start.tms_stime = (*curr).tms_stime; (TREF(prof_fp))->start.tms_utime = (*curr).tms_utime; (TREF(prof_fp))->carryover.tms_stime = 0; (TREF(prof_fp))->carryover.tms_utime = 0; (TREF(prof_fp))->dummy_stack_count = 0; (TREF(prof_fp))->rout_name = (TREF(prof_fp))->label_name = NULL; POPULATE_PROFILING_TABLE(); is_tracing_on = TRUE; return; }
/* -------------------------------------------------------------------------------- This function renames a file, if exists. Otherwise do nothing. --------------------------------------------------------------------------------- */ int rename_file_if_exists(char *org_fn, int org_fn_len, char *rename_fn, int *rename_fn_len, uint4 *ustatus) { mstr orgfile; int status; error_def(ERR_FILERENAME); error_def(ERR_RENAMEFAIL); memcpy(rename_fn, org_fn, org_fn_len + 1); /* Ensure it to be NULL terminated */ *rename_fn_len = org_fn_len; orgfile.addr = org_fn; orgfile.len = org_fn_len; if (FILE_NOT_FOUND == (status = gtm_file_stat(&orgfile, NULL, NULL, FALSE, ustatus))) return RENAME_NOT_REQD; else if (FILE_STAT_ERROR == status) return RENAME_FAILED; /* File is present in the system */ assert(0 < MAX_FN_LEN - org_fn_len - 1); if (SS_NORMAL != (status = prepare_unique_name(org_fn, org_fn_len, "", "", rename_fn, rename_fn_len, ustatus))) return RENAME_FAILED; assert(0 == rename_fn[*rename_fn_len]); if (SS_NORMAL != (status= gtm_rename(org_fn, org_fn_len, rename_fn, *rename_fn_len, ustatus))) { if (run_time) send_msg(VARLSTCNT(9) ERR_RENAMEFAIL, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn, status, 0, *ustatus); else gtm_putmsg(VARLSTCNT1(8) ERR_RENAMEFAIL, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn, status, PUT_SYS_ERRNO(*ustatus)); return RENAME_FAILED; } if (run_time) send_msg(VARLSTCNT (6) ERR_FILERENAME, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn); else gtm_putmsg(VARLSTCNT (6) ERR_FILERENAME, 4, org_fn_len, org_fn, *rename_fn_len, rename_fn); return RENAME_SUCCESS; }
/* the logic here can be reused in iotcp_readfl.c and iosocket_readfl.c */ static void tcp_read(BFILE *bf, char *buf, int nbytes) { int needed, status; char *curr; fd_set fs; ABS_TIME save_nap, nap; needed = nbytes; curr = buf; nap.at_sec = 1; nap.at_usec = 0; while (1) { FD_ZERO(&fs); FD_SET(bf->fd, &fs); assert(0 != FD_ISSET(bf->fd, &fs)); /* Note: the check for EINTR from the select below should remain, as aa_select is a * function, and not all callers of aa_select behave the same when EINTR is returned. */ save_nap = nap; status = tcp_routines.aa_select(bf->fd + 1, (void *)(&fs), (void *)0, (void *)0, &nap); nap = save_nap; if (status > 0) { status = tcp_routines.aa_recv(bf->fd, curr, needed, 0); if ((0 == status) || (needed == status)) /* lost connection or all set */ { break; } else if (status > 0) { needed -= status; curr += status; } } if ((status < 0) && (errno != EINTR)) { gtm_putmsg(VARLSTCNT(1) errno); close(bf->fd); restore_read_errno = errno; break; } } return; }
int main (int argc, char **argv) { int res; DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; set_blocksig(); gtm_imagetype_init(MUPIP_IMAGE); invocation_mode = MUMPS_UTILTRIGR; gtm_wcswidth_fnptr = gtm_wcswidth; gtm_env_init(); /* read in all environment variables */ err_init(util_base_ch); 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 */ sig_init(generic_signal_handler, NULL, suspsigs_handler, continue_handler); /* Note: no ^C handler is defined (yet) */ atexit(mupip_exit_handler); licensed = TRUE; in_backup = FALSE; op_open_ptr = mu_op_open; mu_get_term_characterstics(); cli_lex_setup(argc,argv); if (argc < 2) /* Interactive mode */ display_prompt(); /* this call should be after cli_lex_setup() due to S390 A/E conversion */ gtm_chk_dist(argv[0]); INIT_GBL_ROOT(); /* Needed for GVT initialization */ init_gtm(); while (TRUE) { func = 0; if ((res = parse_cmd()) == EOF) break; else if (res) { if (1 < argc) rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); else gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); } if (func) func(); if (argc > 1) /* Non-interactive mode, exit after command */ break; display_prompt(); } mupip_exit(SS_NORMAL); }
void gtmsource_seqno_init(void) { /* Find the start_jnl_seqno */ gd_region *reg, *region_top; seq_num local_read_jsn, local_jsn; sgmnt_addrs *csa; sgmnt_data_ptr_t csd; sm_uc_ptr_t gld_fn; /* Unix and VMS have different field names for now, but will both be soon changed to instname instead of gtmgbldir */ gld_fn = (sm_uc_ptr_t)jnlpool.jnlpool_ctl->jnlpool_id.gtmgbldir; QWASSIGN(jnlpool.jnlpool_ctl->start_jnl_seqno, seq_num_zero); QWASSIGN(local_read_jsn, seq_num_zero); QWASSIGN(local_jsn, seq_num_zero); region_top = gd_header->regions + gd_header->n_regions; for (reg = gd_header->regions; reg < region_top; reg++) { assert(reg->open); csa = &FILE_INFO(reg)->s_addrs; csd = csa->hdr; if (REPL_ALLOWED(csd)) { if (QWLT(local_read_jsn, csd->resync_seqno)) QWASSIGN(local_read_jsn, csd->resync_seqno); if (QWLT(local_jsn, csd->reg_seqno)) QWASSIGN(local_jsn, csd->reg_seqno); /* Copy gtmgbldir into the database shared memory. * Used later to avoid updates from a different gtmgbldir to this database. */ assert(SIZEOF(csa->nl->replinstfilename) == SIZEOF(jnlpool.jnlpool_ctl->jnlpool_id.gtmgbldir)); memcpy(csa->nl->replinstfilename, gld_fn, SIZEOF(csa->nl->replinstfilename)); } } if (QWEQ(local_jsn, seq_num_zero)) { /* No replicated region, or databases created with older version of GTM */ gtm_putmsg(VARLSTCNT(5) ERR_NOREPLCTDREG, 3, LEN_AND_LIT("global directory"), gld_fn); /* Error, has to shutdown all regions 'cos mupip needs exclusive access to turn replication on */ gtmsource_autoshutdown(); } QWASSIGN(jnlpool.jnlpool_ctl->start_jnl_seqno, local_jsn); QWASSIGN(jnlpool.jnlpool_ctl->jnl_seqno, local_jsn); QWASSIGN(jnlpool.gtmsource_local->read_jnl_seqno, local_read_jsn); }
/* Enables tracing and ensures that all critical structures are initialized */ void turn_tracing_on(mval *gvn, boolean_t from_env, boolean_t save_gbl) { ext_tms curr; trace_entry tmp_trc_tbl_entry; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; mdb_ch_set = !from_env; /* if tracing is on explicitly, or if it is implicit with saving */ if (save_gbl || !from_env) { if (is_tracing_on) { gtm_putmsg(VARLSTCNT(1) ERR_TRACINGON); return; } if ((0 == gvn->str.len) || ('^' != gvn->str.addr[0])) MPROF_RTS_ERROR((VARLSTCNT(4) ERR_NOTGBL, 2, gvn->str.len, gvn->str.addr)); } /* the following should only be a one-time operation */ if (!TREF(mprof_ptr)) { TREF(mprof_ptr) = (mprof_wrapper *)malloc(SIZEOF(mprof_wrapper)); memset(TREF(mprof_ptr), 0, SIZEOF(mprof_wrapper)); } /* only need to have the gvn if we are going to save the data */ if (save_gbl && (0 < gvn->str.len)) { parse_gvn(gvn); (TREF(mprof_ptr))->gbl_to_fill = *gvn; (TREF(mprof_ptr))->gbl_to_fill.str.addr = (char *)malloc(gvn->str.len); /* len was already set up */ memcpy((TREF(mprof_ptr))->gbl_to_fill.str.addr, gvn->str.addr, gvn->str.len); } /* preallocate some space */ if (!(TREF(mprof_ptr))->pcavailbase) { (TREF(mprof_ptr))->pcavailbase = (char **)malloc(PROFCALLOC_DSBLKSIZE); *(TREF(mprof_ptr))->pcavailbase = 0; } (TREF(mprof_ptr))->pcavailptr = (TREF(mprof_ptr))->pcavailbase; (TREF(mprof_ptr))->pcavail = PROFCALLOC_DSBLKSIZE - OFFSET_LEN; memset((TREF(mprof_ptr))->pcavailptr + 1, 0, (TREF(mprof_ptr))->pcavail); curr = (TREF(mprof_ptr))->tprev; TIMES(&curr); UNIX_ONLY(child_times_usec();)
uint4 set_jnl_file_close(set_jnl_file_close_opcode_t set_jnl_file_close_opcode) { uint4 jnl_status = 0; cs_addrs = &FILE_INFO(gv_cur_region)->s_addrs; jnl_status = jnl_ensure_open(); if (0 == jnl_status) { if (0 == cs_addrs->jnl->pini_addr) jnl_put_jrt_pini(cs_addrs); wcs_flu(WCSFLU_FLUSH_HDR | WCSFLU_WRITE_EPOCH); jnl_put_jrt_pfin(cs_addrs); jnl_file_close(gv_cur_region, TRUE, TRUE); } else gtm_putmsg(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(cs_addrs->hdr), DB_LEN_STR(gv_cur_region)); return jnl_status; }
static void file_close(char *temp) { uint4 status; struct RAB *rab; void gtm_putmsg(); rab = (struct RAB *)(temp); if (error_mupip) rab->rab$l_fab->fab$l_fop |= FAB$M_DLT; status = sys$close(rab->rab$l_fab); if (status != RMS$_NORMAL) { backup_close_errno = status; gtm_putmsg(status); util_out_print("FATAL ERROR: System Service failure.",TRUE); } return; }
int mu_rndwn_all(void) { int save_errno, fname_len, exit_status = SS_NORMAL, shmid, tmp_exit_status; char entry[MAX_ENTRY_LEN]; FILE *pf; char *fname, *fgets_res; shm_parms *parm_buff; if (NULL == (pf = POPEN(IPCS_CMD_STR ,"r"))) { save_errno = errno; gtm_putmsg(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("POPEN()"), CALLFROM, save_errno); return ERR_MUNOTALLSEC; } fname = (char *)malloc(MAX_FN_LEN + 1); while (NULL != (FGETS(entry, SIZEOF(entry), pf, fgets_res)) && entry[0] != '\n') { tmp_exit_status = SS_NORMAL; parm_buff = get_shm_parm(entry); if (NULL == parm_buff) { exit_status = ERR_MUNOTALLSEC; continue; } mu_rndwn_all_helper(parm_buff, fname, &exit_status, &tmp_exit_status); if ((SS_NORMAL == exit_status) && (SS_NORMAL != tmp_exit_status)) exit_status = tmp_exit_status; if (mu_rndwn_all_helper_error) { /* Encountered a runtime error while processing this ipc. Make sure we return with * MUNOTALLSEC and reset this static variable before starting processing on next ipc. */ mu_rndwn_all_helper_error = FALSE; if (SS_NORMAL == exit_status) exit_status = ERR_MUNOTALLSEC; } if (NULL != parm_buff) free(parm_buff); } pclose(pf); free(fname); return exit_status; }
static void file_write(char *temp, char *buf, int nbytes) { uint4 status; struct RAB *rab; void gtm_putmsg(); assert(nbytes > 4); rab = (struct RAB *)(temp); rab->rab$w_rsz = nbytes; rab->rab$l_rbf = buf; if (RMS$_NORMAL != (status = sys$put(rab))) { backup_write_errno = status; gtm_putmsg(status, 0, rab->rab$l_stv); (rab->rab$l_fab)->fab$l_fop |= FAB$M_DLT; sys$close(rab->rab$l_fab); } return; }
void mupip_exit(int4 stat) { int4 tmp_severity; if (stat != SS_NORMAL) { if (error_condition != stat) /* If message not already put out.. */ { gtm_putmsg(VARLSTCNT(1) stat); tmp_severity = SEVMASK(stat); } else tmp_severity = severity; /* Make sure give an rc when we exit */ if (SUCCESS != tmp_severity && INFO != tmp_severity) stat = (((stat & UNIX_EXIT_STATUS_MASK) != 0) ? stat : -1); else stat = 0; } mupip_exit_status_displayed = TRUE; exit(stat); }
static void exec_read(BFILE *bf, char *buf, int nbytes) { int needed, got; int4 status; char *curr; pid_t waitpid_res; assert(nbytes > 0); needed = nbytes; curr = buf; #ifdef DEBUG_ONLINE PRINTF("file descriptor is %d and bytes needed is %d\n", bf->fd, needed); #endif while(0 != (got = read(bf->fd, curr, needed))) { if (got == needed) break; else if (got > 0) { needed -= got; curr += got; } /* the check for EINTR below is valid and should not be converted to an EINTR * wrapper macro, for an immediate retry is not attempted. Instead, wcs_sleep * is called. */ else if ((EINTR != errno) && (EAGAIN != errno)) { gtm_putmsg(VARLSTCNT(1) errno); if ((pipe_child > 0) && (FALSE != is_proc_alive(pipe_child, 0))) WAITPID(pipe_child, (int *)&status, 0, waitpid_res); close(bf->fd); restore_read_errno = errno; break; } wcs_sleep(100); } return; }
static bool dse_process(int argc) { int res; ESTABLISH_RET(util_ch, TRUE); func = 0; util_interrupt = 0; if (EOF == (res = parse_cmd())) { if (util_interrupt) { rts_error(VARLSTCNT(1) ERR_CTRLC); REVERT; return TRUE; } else { REVERT; return FALSE; } } else if (res) { if (1 < argc) { /* Here we need to REVERT since otherwise we stay in dse in a loop * The design of dse needs to be changed to act like VMS (which is: * if there is an error in the dse command (dse dumpoa), go to command * prompt, but UNIX exits */ REVERT; rts_error(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); } else gtm_putmsg(VARLSTCNT(4) res, 2, LEN_AND_STR(cli_err_str)); } if (func) func(); REVERT; return(1 >= argc); }
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); )
int gtmrecv_start_helpers(int n_readers, int n_writers) { /* Set flag in recvpool telling the receiver server to start n_readers and n_writers helper processes. * Wait for receiver server to complete the process - completed successfully, or terminated with error */ upd_helper_ctl_ptr_t upd_helper_ctl; upd_helper_entry_ptr_t helper, helper_top; char err_str[BUFSIZ]; int avail_slots, started_readers, started_writers; error_def(ERR_REPLERR); error_def(ERR_REPLINFO); error_def(ERR_REPLWARN); assert(0 != n_readers || 0 != n_writers); upd_helper_ctl = recvpool.upd_helper_ctl; /* let's clean up dead helpers first so we get an accurate count of available slots */ upd_helper_ctl->reap_helpers = HELPER_REAP_NOWAIT; while (HELPER_REAP_NONE != upd_helper_ctl->reap_helpers && SRV_ALIVE == is_recv_srv_alive()) SHORT_SLEEP(GTMRECV_WAIT_FOR_UPD_SHUTDOWN); upd_helper_ctl->reap_helpers = HELPER_REAP_NONE; /* just in case recvr died */ /* count available slots so receiver doesn't have to */ for (avail_slots = 0, helper = upd_helper_ctl->helper_list, helper_top = helper + MAX_UPD_HELPERS; helper < helper_top; helper++) { if (0 == helper->helper_pid) { avail_slots++; helper->helper_pid_prev = 0; /* force out abnormally terminated helpers as well */ helper->helper_shutdown = NO_SHUTDOWN; /* clean state */ } } if (avail_slots < n_readers + n_writers) { SNPRINTF(err_str, SIZEOF(err_str), "%d helpers will exceed the maximum allowed (%d), limit the helpers to %d\n", n_readers + n_writers, MAX_UPD_HELPERS, avail_slots); gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2, LEN_AND_STR(err_str)); return ABNORMAL_SHUTDOWN; } upd_helper_ctl->start_n_readers = n_readers; upd_helper_ctl->start_n_writers = n_writers; SHM_WRITE_MEMORY_BARRIER; upd_helper_ctl->start_helpers = TRUE; /* hey receiver, let's go, start 'em up */ while (upd_helper_ctl->start_helpers && SRV_ALIVE == is_recv_srv_alive()) SHORT_SLEEP(GTMRECV_WAIT_FOR_SRV_START); if (!upd_helper_ctl->start_helpers) { started_readers = upd_helper_ctl->start_n_readers; started_writers = upd_helper_ctl->start_n_writers; SNPRINTF(err_str, SIZEOF(err_str), "%s %d out of %d readers and %d out of %d writers started", ((started_readers + started_writers) == (n_readers + n_writers)) ? "All" : "Only", started_readers, n_readers, started_writers, n_writers); if ((started_readers + started_writers) == (n_readers + n_writers)) { gtm_putmsg(VARLSTCNT(4) ERR_REPLINFO, 2, LEN_AND_STR(err_str)); return NORMAL_SHUTDOWN; } gtm_putmsg(VARLSTCNT(4) ERR_REPLWARN, 2, LEN_AND_STR(err_str)); return ABNORMAL_SHUTDOWN; } gtm_putmsg(VARLSTCNT(4) ERR_REPLERR, 2, LEN_AND_LIT("Receiver server is not alive to start helpers. Start receiver server first")); return ABNORMAL_SHUTDOWN; }
void deferred_signal_handler(void) { void (*signal_routine)(); DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* To avoid nested calls to this routine, we set forced_exit to FALSE at the very beginning */ forced_exit = FALSE; if (exit_handler_active) { assert(FALSE); /* at this point in time (June 2003) there is no way we know of to get here, hence the assert */ return; /* since anyway we are exiting currently, resume exit handling instead of reissuing another one */ } /* For signals that get a delayed response so we can get out of crit, we also delay the messages. * This routine will output those delayed messages from the appropriate structures to both the * user and the system console. */ /* note can't use switch here because ERR_xxx are not defined as constants */ if (ERR_KILLBYSIG == forced_exit_err) { send_msg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal); gtm_putmsg(VARLSTCNT(6) ERR_KILLBYSIG, 4, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal); } else if (ERR_KILLBYSIGUINFO == forced_exit_err) { send_msg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.send_pid, signal_info.send_uid); gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGUINFO, 6, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.send_pid, signal_info.send_uid); } else if (ERR_KILLBYSIGSINFO1 == forced_exit_err) { send_msg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.int_iadr, signal_info.bad_vadr); gtm_putmsg(VARLSTCNT(8) ERR_KILLBYSIGSINFO1, 6, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.int_iadr, signal_info.bad_vadr); } else if (ERR_KILLBYSIGSINFO2 == forced_exit_err) { send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.int_iadr); gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO2, 5, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.int_iadr); } else if (ERR_KILLBYSIGSINFO3 == forced_exit_err) { send_msg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.bad_vadr); gtm_putmsg(VARLSTCNT(7) ERR_KILLBYSIGSINFO3, 5, GTMIMAGENAMETXT(image_type), process_id, signal_info.signal, signal_info.bad_vadr); } else if (ERR_FORCEDHALT != forced_exit_err || !gtm_quiet_halt) { /* No HALT messages if quiet halt is requested */ send_msg(VARLSTCNT(1) forced_exit_err); gtm_putmsg(VARLSTCNT(1) forced_exit_err); } assert(OK_TO_INTERRUPT); /* Signal intent to exit BEFORE driving condition handlers. This avoids checks that will otherwise fail (for example * if mdb_condition_handler/preemptive_ch gets called below, that could invoke the RESET_GV_TARGET macro which in turn * would assert that gv_target->gd_csa is equal to cs_addrs. This could not be true in case we were in mainline code * that was interrupted by the flush timer for a different region which in turn was interrupted by an external signal * that would drive us to exit. Setting the "process_exiting" variable causes those csa checks to pass. */ SET_PROCESS_EXITING_TRUE; # ifdef DEBUG if (gtm_white_box_test_case_enabled && (WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number) && (2 == gtm_white_box_test_case_count)) { DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); DBGFPF((stderr, "DEFERRED_SIGNAL_HANDLER: will sleep for 20 seconds\n")); LONG_SLEEP(20); DBGFPF((stderr, "DEFERRED_SIGNAL_HANDLER: done sleeping\n")); ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS); } # endif /* If any special routines are registered to be driven on a signal, drive them now */ if ((0 != exi_condition) && (NULL != call_on_signal)) { signal_routine = call_on_signal; call_on_signal = NULL; /* So we don't recursively call ourselves */ (*signal_routine)(); } /* Note, we do not drive create_fatal_error zshow_dmp() in this routine since any deferrable signals are * by definition not fatal. */ exit(-exi_condition); }
void gtm_startup(struct startup_vector *svec) /* Note: various references to data copied from *svec could profitably be referenced directly */ { unsigned char *mstack_ptr; void gtm_ret_code(); static readonly unsigned char init_break[1] = {'B'}; int4 lct; int i; static char other_mode_buf[] = "OTHER"; mstr log_name; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(INVALID_IMAGE != image_type); assert(svec->argcnt == SIZEOF(*svec)); IA64_ONLY(init_xfer_table()); get_page_size(); cache_table_relobjs = &cache_table_rebuild; ht_rhash_ch = &hashtab_rehash_ch; jbxm_dump_ch = &jobexam_dump_ch; heartbeat_timer_ptr = &heartbeat_timer; stpgc_ch = &stp_gcol_ch; rtn_fst_table = rtn_names = (rtn_tabent *)svec->rtn_start; rtn_names_end = rtn_names_top = (rtn_tabent *)svec->rtn_end; if (svec->user_stack_size < 4096) svec->user_stack_size = 4096; if (svec->user_stack_size > 8388608) svec->user_stack_size = 8388608; mstack_ptr = (unsigned char *)malloc(svec->user_stack_size); msp = stackbase = mstack_ptr + svec->user_stack_size - mvs_size[MVST_STORIG]; /* mark the stack base so that if error occur during call-in gtm_init(), the unwind * logic in gtmci_ch() will get rid of the stack completely */ fgncal_stack = stackbase; mv_chain = (mv_stent *)msp; mv_chain->mv_st_type = MVST_STORIG; /* Initialize first (anchor) mv_stent so doesn't do anything */ mv_chain->mv_st_next = 0; mv_chain->mv_st_cont.mvs_storig = 0; stacktop = mstack_ptr + 2 * mvs_size[MVST_NTAB]; stackwarn = stacktop + (16 * 1024); break_message_mask = svec->break_message_mask; if (svec->user_strpl_size < STP_INITSIZE) svec->user_strpl_size = STP_INITSIZE; else if (svec->user_strpl_size > STP_MAXINITSIZE) svec->user_strpl_size = STP_MAXINITSIZE; stp_init(svec->user_strpl_size); if (svec->user_indrcache_size > MAX_INDIRECTION_NESTING || svec->user_indrcache_size < MIN_INDIRECTION_NESTING) svec->user_indrcache_size = MIN_INDIRECTION_NESTING; TREF(ind_result_array) = (mval **)malloc(SIZEOF(mval *) * svec->user_indrcache_size); TREF(ind_source_array) = (mval **)malloc(SIZEOF(mval *) * svec->user_indrcache_size); TREF(ind_result_sp) = TREF(ind_result_array); TREF(ind_result_top) = TREF(ind_result_sp) + svec->user_indrcache_size; TREF(ind_source_sp) = TREF(ind_source_array); TREF(ind_source_top) = TREF(ind_source_sp) + svec->user_indrcache_size; rts_stringpool = stringpool; TREF(compile_time) = FALSE; /* assert that is_replicator and run_time is properly set by gtm_imagetype_init invoked at process entry */ # ifdef DEBUG switch (image_type) { case GTM_IMAGE: case GTM_SVC_DAL_IMAGE: assert(is_replicator && run_time); break; case MUPIP_IMAGE: assert(!is_replicator && !run_time); break; default: assert(FALSE); } # endif gtm_utf8_init(); /* Initialize the runtime for Unicode */ /* Initialize alignment requirement for the runtime stringpool */ log_name.addr = DISABLE_ALIGN_STRINGS; log_name.len = STR_LIT_LEN(DISABLE_ALIGN_STRINGS); /* mstr_native_align = logical_truth_value(&log_name, FALSE, NULL) ? FALSE : TRUE; */ mstr_native_align = FALSE; /* TODO: remove this line and uncomment the above line */ getjobname(); INVOKE_INIT_SECSHR_ADDRS; getzprocess(); getzmode(); geteditor(); zcall_init(); cmd_qlf.qlf = glb_cmd_qlf.qlf; cache_init(); # ifdef __sun if (NULL != GETENV(PACKAGE_ENV_TYPE)) /* chose xcall (default) or rpc zcall */ xfer_table[xf_fnfgncal] = (xfer_entry_t)op_fnfgncal_rpc; /* using RPC */ # endif msp -= SIZEOF(stack_frame); frame_pointer = (stack_frame *)msp; memset(frame_pointer,0, SIZEOF(stack_frame)); frame_pointer->temps_ptr = (unsigned char *)frame_pointer; frame_pointer->ctxt = GTM_CONTEXT(gtm_ret_code); frame_pointer->mpc = CODE_ADDRESS(gtm_ret_code); frame_pointer->type = SFT_COUNT; frame_pointer->rvector = (rhdtyp*)malloc(SIZEOF(rhdtyp)); memset(frame_pointer->rvector, 0, SIZEOF(rhdtyp)); symbinit(); /* Variables for supporting $ZSEARCH sorting and wildcard expansion */ TREF(zsearch_var) = lv_getslot(curr_symval); TREF(zsearch_dir1) = lv_getslot(curr_symval); TREF(zsearch_dir2) = lv_getslot(curr_symval); LVVAL_INIT((TREF(zsearch_var)), curr_symval); LVVAL_INIT((TREF(zsearch_dir1)), curr_symval); LVVAL_INIT((TREF(zsearch_dir2)), curr_symval); /* Initialize global pointer to control-C handler. Also used in iott_use */ ctrlc_handler_ptr = &ctrlc_handler; io_init(IS_MUPIP_IMAGE); /* starts with nocenable for GT.M runtime, enabled for MUPIP */ if (!IS_MUPIP_IMAGE) { sig_init(generic_signal_handler, ctrlc_handler_ptr, suspsigs_handler, continue_handler); atexit(gtm_exit_handler); cenable(); /* cenable unless the environment indicates otherwise - 2 steps because this can report errors */ } jobinterrupt_init(); getzdir(); dpzgbini(); zco_init(); /* a base addr of 0 indicates a gtm_init call from an rpc server */ if ((GTM_IMAGE == image_type) && (NULL != svec->base_addr)) jobchild_init(); else { /* Trigger enabled utilities will enable through here */ (TREF(dollar_zmode)).mvtype = MV_STR; (TREF(dollar_zmode)).str.addr = other_mode_buf; (TREF(dollar_zmode)).str.len = SIZEOF(other_mode_buf) -1; } svec->frm_ptr = (unsigned char *)frame_pointer; dollar_ztrap.mvtype = MV_STR; dollar_ztrap.str.len = SIZEOF(init_break); dollar_ztrap.str.addr = (char *)init_break; dollar_zstatus.mvtype = MV_STR; dollar_zstatus.str.len = 0; dollar_zstatus.str.addr = NULL; ecode_init(); zyerror_init(); ztrap_form_init(); ztrap_new_init(); zdate_form_init(svec); dollar_system_init(svec); init_callin_functable(); gtm_env_xlate_init(); SET_LATCH_GLOBAL(&defer_latch, LOCK_AVAILABLE); curr_pattern = pattern_list = &mumps_pattern; pattern_typemask = mumps_pattern.typemask; initialize_pattern_table(); ce_init(); /* initialize compiler escape processing */ /* Initialize local collating sequence */ TREF(transform) = TRUE; lct = find_local_colltype(); if (lct != 0) { TREF(local_collseq) = ready_collseq(lct); if (!TREF(local_collseq)) { exi_condition = -ERR_COLLATIONUNDEF; gtm_putmsg(VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, lct); exit(exi_condition); } } else TREF(local_collseq) = 0; prealloc_gt_timers(); gt_timers_add_safe_hndlrs(); for (i = 0; FNPC_MAX > i; i++) { /* Initialize cache structure for $Piece function */ (TREF(fnpca)).fnpcs[i].pcoffmax = &(TREF(fnpca)).fnpcs[i].pstart[FNPC_ELEM_MAX]; (TREF(fnpca)).fnpcs[i].indx = i; } (TREF(fnpca)).fnpcsteal = (TREF(fnpca)).fnpcs; /* Starting place to look for cache reuse */ (TREF(fnpca)).fnpcmax = &(TREF(fnpca)).fnpcs[FNPC_MAX - 1]; /* The last element */ /* Initialize zwrite subsystem. Better to do it now when we have storage to allocate than * if we fail and storage allocation may not be possible. To that end, pretend we have * seen alias acitivity so those structures are initialized as well. */ assert(FALSE == curr_symval->alias_activity); curr_symval->alias_activity = TRUE; lvzwr_init((enum zwr_init_types)0, (mval *)NULL); curr_symval->alias_activity = FALSE; if ((NULL != (TREF(mprof_env_gbl_name)).str.addr)) turn_tracing_on(TADR(mprof_env_gbl_name), TRUE, (TREF(mprof_env_gbl_name)).str.len > 0); return; }
void gv_select(char *cli_buff, int n_len, boolean_t freeze, char opname[], glist *gl_head, int *reg_max_rec, int *reg_max_key, int *reg_max_blk) { bool stashed = FALSE; int num_quote, len, gmap_size, new_gmap_size, estimated_entries, count, rslt; char *ptr, *ptr1, *c; mstr gmap[512], *gmap_ptr, *gmap_ptr_base, gmap_beg, gmap_end; mval val, curr_gbl_name; glist *gl_tail, *gl_ptr; #ifdef GTM64 hash_table_int8 ext_hash; ht_ent_int8 *tabent; #else hash_table_int4 ext_hash; ht_ent_int4 *tabent; #endif /* GTM64 */ error_def(ERR_FREEZE); error_def(ERR_DBRDONLY); error_def(ERR_SELECTSYNTAX); error_def(ERR_MUNOFINISH); error_def(ERR_MUNOACTION); error_def(ERR_FREEZECTRL); memset(gmap, 0, SIZEOF(gmap)); gmap_size = SIZEOF(gmap) / SIZEOF(gmap[0]); gmap_ptr_base = &gmap[0]; /* "estimated_entries" is a conservative estimate of the # of entries that could be used up in the gmap array */ estimated_entries = 1; /* take into account the NULL gmap entry at the end of the array */ for (ptr = cli_buff; *ptr; ptr = ptr1) { for (ptr1 = ptr; ; ptr1++) { if (',' == *ptr1) { len = (int)(ptr1 - ptr); ptr1++; break; } else if (!*ptr1) { len = (int)(ptr1 - ptr); break; } } gmap_beg.addr = ptr; c = gmap_beg.addr + len - 1; num_quote = 0; while ('"' == *c) { len--; c--; num_quote++; } if (0 >= len) { gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname)); mupip_exit(ERR_MUNOACTION); } c = gmap_beg.addr; while (0 < num_quote) { if ('"' == *c) { c++; len--; } else { gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname)); mupip_exit(ERR_MUNOACTION); } num_quote--; } gmap_beg.addr = c; if ('^' == *c) { gmap_beg.addr++; len--; } gmap_beg.len = len; c = mu_extr_ident(&gmap_beg); len -= INTCAST(c - gmap_beg.addr); assert(len >= 0); if (0 == len) gmap_end = gmap_beg; else if (gmap_beg.len == 1 && '*' == *c) { gmap_beg.addr = (char*)&percent_lit; gmap_beg.len = SIZEOF(percent_lit); gmap_end.addr = (char*)&tilde_lit; gmap_end.len = SIZEOF(tilde_lit); } else if (1 == len && '*' == *c) { gmap_end = gmap_beg; gmap_beg.len--; *c = '~'; } else if (':' != *c) { gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname)); mupip_exit(ERR_MUNOACTION); } else { gmap_beg.len = INTCAST(c - gmap_beg.addr); c++; gmap_end.addr = c; gmap_end.len = len - 1; if ('^' == *c) { gmap_end.addr++; gmap_end.len--; } c = mu_extr_ident(&gmap_end); MSTR_CMP(gmap_beg, gmap_end, rslt); if (((c - gmap_end.addr) != gmap_end.len) || (0 < rslt)) { gtm_putmsg(VARLSTCNT(4) ERR_SELECTSYNTAX, 2, LEN_AND_STR(opname)); mupip_exit(ERR_MUNOACTION); } } /* "estimated_entries" is the maximum number of entries that could be used up in the gmap array including the * next global_map call. The actual number of used entries could be much lower than this. * But since determining the actual number would mean scanning the gmap array for the first NULL pointer (a * performance overhead), we do an approximate check instead. */ estimated_entries += MAX_GMAP_ENTRIES_PER_ITER; if (estimated_entries >= gmap_size) { /* Current gmap array does not have enough space. Double size before calling global_map */ new_gmap_size = gmap_size * 2; /* double size of gmap array */ gmap_ptr = (mstr *)malloc(SIZEOF(mstr) * new_gmap_size); memcpy(gmap_ptr, gmap_ptr_base, SIZEOF(mstr) * gmap_size); if (gmap_ptr_base != &gmap[0]) free(gmap_ptr_base); gmap_size = new_gmap_size; gmap_ptr_base = gmap_ptr; } global_map(gmap_ptr_base, &gmap_beg, &gmap_end); DEBUG_ONLY( count = 1; for (gmap_ptr = gmap_ptr_base; gmap_ptr->addr; gmap_ptr++) count++; assert(count < gmap_size); ) } if (freeze) { GTM64_ONLY(init_hashtab_int8(&ext_hash, 0, HASHTAB_COMPACT, HASHTAB_SPARE_TABLE);) NON_GTM64_ONLY(init_hashtab_int4(&ext_hash, 0, HASHTAB_COMPACT, HASHTAB_SPARE_TABLE);) }
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); }