void open_list_file(void) { char charspace; uint4 status; char *p, list_name[MAX_MIDENT_LEN + STR_LIT_LEN(LISTEXT)], fname[MAX_FBUFF + 1]; mval parms; mval file; mstr fstr; parse_blk pblk; time_t clock; lst_param.list_line = 1; lst_param.page = 0; memset(&pblk, 0, sizeof(pblk)); assert(module_name.len <= MAX_MIDENT_LEN); pblk.def1_size = module_name.len; memcpy(&list_name[0], module_name.addr, pblk.def1_size); MEMCPY_LIT(&list_name[pblk.def1_size], LISTEXT); pblk.def1_size += STR_LIT_LEN(LISTEXT); pblk.def1_buf = list_name; pblk.buffer = &fname[0]; pblk.buff_size = MAX_FBUFF; pblk.fop = F_SYNTAXO; fstr.len = (MV_DEFINED(&cmd_qlf.list_file) ? cmd_qlf.list_file.str.len : 0); fstr.addr = cmd_qlf.list_file.str.addr; if (!(status = parse_file(&fstr, &pblk)) & 1) rts_error(VARLSTCNT(1) status); file.mvtype = parms.mvtype = MV_STR; file.str.len = pblk.b_esl; file.str.addr = &fname[0]; parms.str.len = sizeof(open_params_list); parms.str.addr = (char *)&open_params_list; (*op_open_ptr)(&file, &parms, 30, 0); parms.str.len = 1; charspace = (char)iop_eol; parms.str.addr = &charspace; dev_in_use = io_curr_device; op_use(&file,&parms); clock = time(0); p = GTM_CTIME(&clock); memcpy (print_time_buf, p + 4, sizeof(print_time_buf)); list_head(0); return; }
/* Update header from v4.x to v5.0-000 */ void mu_upgrd_header(v15_sgmnt_data *v15_csd, sgmnt_data *csd) { time_t ctime; seq_num v15_reg_seqno; memset(csd, 0, SIZEOF(sgmnt_data)); MEMCPY_LIT(csd->label, GDS_LABEL); csd->blk_size = v15_csd->blk_size; csd->bplmap = v15_csd->bplmap; csd->start_vbn = v15_csd->start_vbn; csd->acc_meth = v15_csd->acc_meth; csd->max_bts = v15_csd->max_bts; csd->n_bts = v15_csd->n_bts; csd->bt_buckets = v15_csd->bt_buckets; if (v15_csd->reserved_bytes > BLK_HDR_INCREASE) csd->reserved_bytes = v15_csd->reserved_bytes - BLK_HDR_INCREASE; csd->max_rec_size = v15_csd->max_rec_size; csd->max_key_size = v15_csd->max_key_size; csd->lock_space_size = v15_csd->lock_space_size; csd->extension_size = v15_csd->extension_size; csd->def_coll = v15_csd->def_coll; csd->def_coll_ver = v15_csd->def_coll_ver; csd->std_null_coll = v15_csd->std_null_coll; /* New in V5.0-FT01 */ csd->null_subs = v15_csd->null_subs; csd->free_space = v15_csd->free_space; csd->mutex_spin_parms.mutex_hard_spin_count = v15_csd->mutex_spin_parms.mutex_hard_spin_count; csd->mutex_spin_parms.mutex_sleep_spin_count = v15_csd->mutex_spin_parms.mutex_sleep_spin_count; csd->mutex_spin_parms.mutex_spin_sleep_mask = v15_csd->mutex_spin_parms.mutex_spin_sleep_mask; csd->max_update_array_size = v15_csd->max_update_array_size; /* New from V4.0-001G */ csd->max_non_bm_update_array_size = v15_csd->max_non_bm_update_array_size; /* New from V4.0-001G */ csd->file_corrupt = v15_csd->file_corrupt; csd->minor_dbver = GDSMVCURR; /* New in V5.0-000 */ csd->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT; /* New from V5.3-002 */ csd->createinprogress = v15_csd->createinprogress; time(&ctime); assert(SIZEOF(ctime) >= SIZEOF(int4)); csd->creation_time4 = (int4)ctime;/* No need to propagate previous value. Take only lower order 4-bytes of current time */ csd->last_inc_backup = v15_csd->last_inc_backup; csd->last_com_backup = v15_csd->last_com_backup; csd->last_rec_backup = v15_csd->last_rec_backup; csd->reorg_restart_block = v15_csd->reorg_restart_block; /* New from V4.2 */ memcpy(csd->now_running, gtm_release_name, gtm_release_name_len + 1); /* GT.M release name */ VMS_ONLY(csd->owner_node = v15_csd->owner_node;)
void init_callin_functable(void) { unsigned char *env_top, *address_top; uint4 address_len; int save_errno; address_top = GTM64_ONLY(i2ascl)NON_GTM64_ONLY(i2asc)(gtmvectortable_address, (UINTPTR_T)(&callintogtm_vectortable[0])); *address_top = '\0'; address_len = (uint4)(address_top - >mvectortable_address[0]); env_top = >mvectortable_env[0]; MEMCPY_LIT(env_top, GTM_CALLIN_START_ENV); memcpy((env_top + strlen(GTM_CALLIN_START_ENV)), gtmvectortable_address, address_len); *(env_top + strlen(GTM_CALLIN_START_ENV) + address_len) = '\0'; if (PUTENV((char *)gtmvectortable_env)) { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, LEN_AND_LIT("putenv"), CALLFROM, save_errno); } }
void iosocket_flush(io_desc *iod) { #ifdef C9A06001531 /* pending change request C9A06001531 */ d_socket_struct *dsocketptr; socket_struct *socketptr; int on = 1, off = 0; char *errptr; int4 errlen; error_def(ERR_SOCKWRITE); error_def(ERR_TEXT); error_def(ERR_CURRSOCKOFR); assert(gtmsocket == iod->type); dsocketptr = (d_socket_struct *)iod->dev_sp; socketptr = dsocketptr->socket[dsocketptr->current_socket]; if (dsocketptr->current_socket >= dsocketptr->n_socket) { rts_error(VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket); return; } memcpy(dsocketptr->dollar_device, "0", SIZEOF("0")); if( -1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &on, SIZEOF(on)) || (-1 == tcp_routines.aa_setsockopt(socketptr->sd, SOL_SOCKET, TCP_NODELAY, &off, SIZEOF(off)))) { errptr = (char *)STRERROR(errno); errlen = strlen(errptr); iod->dollar.za = 9; MEMCPY_LIT(dsocketptr->dollar_device, "1,"); memcpy(&dsocketptr->dollar_device[SIZEOF("1,") - 1], errptr, errlen + 1); /* we want the null */ if (socketptr->ioerror) rts_error(VARLSTCNT(6) ERR_SOCKWRITE, 0, ERR_TEXT, 2, errlen, errptr); return; } #endif return; }
void gtm_threadgbl_init(void) { void *lcl_gtm_threadgbl; if (SIZEOF(gtm_threadgbl_true_t) != size_gtm_threadgbl_struct) { /* Size mismatch with gtm_threadgbl_deftypes.h - no error handling yet available so do * the best we can. */ FPRINTF(stderr, "GTM-F-GTMASSERT gtm_threadgbl_true_t and gtm_threadgbl_t are different sizes\n"); EXIT(ERR_GTMASSERT); } if (NULL != gtm_threadgbl) { /* has already been initialized - don't re-init */ FPRINTF(stderr, "GTM-F-GTMASSERT gtm_threadgbl is already initialized\n"); EXIT(ERR_GTMASSERT); } gtm_threadgbl = lcl_gtm_threadgbl = malloc(size_gtm_threadgbl_struct); if (NULL == gtm_threadgbl) { /* Storage was not allocated for some reason - no error handling yet still */ perror("GTM-F-MEMORY Unable to allocate startup thread structure"); EXIT(UNIX_ONLY(ERR_MEMORY) VMS_ONLY(ERR_VMSMEMORY)); } memset(gtm_threadgbl, 0, size_gtm_threadgbl_struct); gtm_threadgbl_true = (gtm_threadgbl_true_t *)gtm_threadgbl; /* Add specific initializations if other than 0s here using the TREF() family of macros: */ (TREF(director_ident)).addr = TADR(director_string); TREF(for_stack_ptr) = TADR(for_stack); (TREF(gtmprompt)).addr = TADR(prombuf); (TREF(gtmprompt)).len = SIZEOF(DEFAULT_PROMPT) - 1; TREF(lv_null_subs) = LVNULLSUBS_OK; /* UNIX: set in gtm_env_init_sp(), VMS: set in gtm$startup() - init'd here * in case alternative invocation methods bypass gtm_startup() */ MEMCPY_LIT(TADR(prombuf), DEFAULT_PROMPT); (TREF(replgbl)).jnl_release_timeout = DEFAULT_JNL_RELEASE_TIMEOUT; (TREF(window_ident)).addr = TADR(window_string); ASSERT_SAFE_TO_UPDATE_THREAD_GBLS; TREF(util_outbuff_ptr) = TADR(util_outbuff); /* Point util_outbuff_ptr to the beginning of util_outbuff at first. */ TREF(util_outptr) = TREF(util_outbuff_ptr); (TREF(source_buffer)).addr = (char *)&aligned_source_buffer; (TREF(source_buffer)).len = MAX_SRCLINE; }
void mu_int_err( int err, boolean_t do_path, boolean_t do_range, unsigned char *bot, int has_bot, unsigned char *top, int has_top, unsigned int level) { int i, util_len; unsigned char util_buff[MAX_UTIL_LEN]; unsigned char span_key[MAX_KEY_SZ + 1]; if (!mu_int_errknt) util_out_print("!/Block:Offset Level", TRUE); mu_int_errknt++; mu_int_plen--; util_len=0; MEMCPY_LIT(&util_buff[util_len], NEWLINE); util_len += SIZEOF(NEWLINE) - 1; i2hex_blkfill(mu_int_path[mu_int_plen], &util_buff[util_len], BLOCK_WINDOW); util_len += BLOCK_WINDOW; MEMCPY_LIT(&util_buff[util_len], TEXT1); /* OFFSET_WINDOW + 1 spaces */ util_len += SIZEOF(TEXT3) - 1; /* Using TEXT1 to clear space? */ i2hex_nofill(mu_int_offset[mu_int_plen], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW); util_len += OFFSET_WINDOW + 1; i2hex_blkfill(level, (uchar_ptr_t)&util_buff[util_len], LEVEL_WINDOW); util_len += LEVEL_WINDOW; MEMCPY_LIT(&util_buff[util_len], TEXT2); util_len += SIZEOF(TEXT2) - 1; util_buff[util_len] = 0; if(sndata->sn_type) gtm_putmsg(VARLSTCNT(5) err, 3, LEN_AND_STR((char*)util_buff), (SPAN_NODE == sndata->sn_type) ? (sndata->span_prev_blk + 2) : (sndata->span_blk_cnt)); else gtm_putmsg(VARLSTCNT(4) err, 2, LEN_AND_STR((char*)util_buff)); if (do_path) { if (!master_dir) { util_out_print(" Directory Path: ", FALSE); for (i = 0; trees->path[i + 1]; i++) { util_len = i2hex_nofill(trees->path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT3); util_len += SIZEOF(TEXT3) - 1; util_len += i2hex_nofill(trees->offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT4); util_len += SIZEOF(TEXT4) - 1; util_buff[util_len] = 0; util_out_print((caddr_t)util_buff, FALSE); } util_len = i2hex_nofill(trees->path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT3); util_len += SIZEOF(TEXT3) - 1; util_len += i2hex_nofill(trees->offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW); util_buff[util_len] = 0; util_out_print((caddr_t)util_buff, TRUE); util_out_print(" Path: ", FALSE); } else util_out_print(" Directory Path: ", FALSE); for (i = 0; i < mu_int_plen; i++) { util_len = i2hex_nofill(mu_int_path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT3); util_len += SIZEOF(TEXT3) - 1; util_len += i2hex_nofill(mu_int_offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT4); util_len += SIZEOF(TEXT4) - 1; util_buff[util_len] = 0; util_out_print((caddr_t)util_buff, FALSE); } util_len = i2hex_nofill(mu_int_path[i], (uchar_ptr_t)util_buff, BLOCK_WINDOW); MEMCPY_LIT(&util_buff[util_len], TEXT3); util_len += SIZEOF(TEXT3) - 1; util_len += i2hex_nofill(mu_int_offset[i], (uchar_ptr_t)&util_buff[util_len], OFFSET_WINDOW); util_buff[util_len] = 0; util_out_print((caddr_t)util_buff, TRUE); } if (do_range && mu_int_err_ranges) { util_out_print("Keys from ", FALSE); if (has_bot) { util_out_print("^", FALSE); /* in the case bot is the leftmost key of the gvtree, it needs a second null to be a properly terminated * real key for print_target. since it is a simple set, we unconditionally do it for every key */ bot[has_bot] = 0; print_target(bot); } else { assert(master_dir); /* for a global variable tree, we better have a non-zero begin key */ util_out_print("^%", FALSE); } util_out_print(" to ", FALSE); if (has_top) { util_out_print("^", FALSE); print_target(top); } else util_out_print("the end", FALSE); util_out_print(" are suspect.", TRUE); } if (!level && sndata->sn_type) { if (1 == sndata->sn_type) util_out_print("Spanning Node ^", FALSE); else util_out_print("Spanning Node Chunk ^", FALSE); /* in the case bot is the leftmost key of the gvtree, it needs a second null to be a properly terminated * real key for print_target. since it is a simple set, we unconditionally do it for every key */ sndata->span_node_buf[sndata->key_len] = 0; sndata->span_node_buf[sndata->key_len+1] = 0; print_target(sndata->span_node_buf); util_out_print(" is suspect.", TRUE); } return; }
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; }
bool mubinccpy(backup_reg_list *list) { static readonly mval null_str = {MV_STR, 0, 0 , 0 , 0, 0}; int backup_socket; int4 size, size1, bsize, bm_num, hint, lmsize, save_blks, rsize, match, timeout, outsize; uint4 status, total_blks, bplmap, gds_ratio, blks_per_buff, counter, i, lcnt, read_size; uchar_ptr_t bm_blk_buff, ptr1, ptr1_top, ptr, ptr_top; char_ptr_t outptr, data_ptr; unsigned short rd_iosb[4], port; enum db_acc_method access; blk_hdr *bp, *bptr; struct FAB *fcb, temp_fab, mubincfab; struct RAB temp_rab, mubincrab; inc_header *outbuf; mval val; mstr *file; sgmnt_data_ptr_t header; char *common, addr[SA_MAXLEN + 1]; void (*common_write)(); void (*common_close)(); muinc_blk_hdr_ptr_t sblkh_p; trans_num blk_tn; block_id blk_num_base, blk_num; boolean_t is_bitmap_blk, backup_this_blk; enum db_ver dummy_odbv; int4 blk_bsiz; error_def(ERR_BCKUPBUFLUSH); error_def(ERR_COMMITWAITSTUCK); error_def(ERR_DBCCERR); error_def(ERR_ERRCALL); assert(list->reg == gv_cur_region); assert(incremental); /* Make sure inc_header can be same size on all platforms. Some platforms pad 8 byte aligned structures that end on a 4 byte boundary and some do not. It is critical that this structure is the same size on all platforms as it is sent across TCP connections when doing TCP backup. */ assert(0 == (SIZEOF(inc_header) % 8)); /* ================= Initialization and some checks ======================== */ header = list->backup_hdr; file = &(list->backup_file); if (!mubtomag) mubmaxblk = BACKUP_TEMPFILE_BUFF_SIZE; fcb = ((vms_gds_info *)(gv_cur_region->dyn.addr->file_cntl->file_info))->fab; if (list->tn >= header->trans_hist.curr_tn) { util_out_print("!/TRANSACTION number is greater than or equal to current transaction,", TRUE); util_out_print("No blocks backed up from database !AD", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return TRUE; } /* =========== open backup destination and define common_write ================= */ backup_write_errno = 0; backup_close_errno = 0; switch(list->backup_to) { case backup_to_file: /* open the file and define the common_write function */ mubincfab = cc$rms_fab; mubincfab.fab$b_fac = FAB$M_PUT; mubincfab.fab$l_fop = FAB$M_CBT | FAB$M_MXV | FAB$M_TEF | FAB$M_POS & (~FAB$M_RWC) & (~FAB$M_RWO); mubincfab.fab$l_fna = file->addr; mubincfab.fab$b_fns = file->len; mubincfab.fab$l_alq = cs_addrs->hdr->start_vbn + STARTING_BLOCKS * cs_addrs->hdr->blk_size / DISK_BLOCK_SIZE; mubincfab.fab$w_mrs = mubmaxblk; mubincfab.fab$w_deq = EXTEND_SIZE; switch (status = sys$create(&mubincfab)) { case RMS$_NORMAL: case RMS$_CREATED: case RMS$_SUPERSEDE: case RMS$_FILEPURGED: break; default: gtm_putmsg(status, 0, mubincfab.fab$l_stv); util_out_print("Error: Cannot create backup file !AD.", TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna); return FALSE; } mubincrab = cc$rms_rab; mubincrab.rab$l_fab = &mubincfab; mubincrab.rab$l_rop = RAB$M_WBH; if (RMS$_NORMAL != (status = sys$connect(&mubincrab))) { gtm_putmsg(status, 0, mubincrab.rab$l_stv); util_out_print("Error: Cannot connect to backup file !AD.", TRUE, mubincfab.fab$b_fns, mubincfab.fab$l_fna); mubincfab.fab$l_fop |= FAB$M_DLT; sys$close(&mubincfab); return FALSE; } common = (char *)(&mubincrab); common_write = file_write; common_close = file_close; break; case backup_to_exec: util_out_print("Error: Backup to pipe is yet to be implemented.", TRUE); util_out_print("Error: Your request to backup database !AD to !AD is currently not valid.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); return FALSE; case backup_to_tcp: iotcp_fillroutine(); /* parse it first */ switch (match = SSCANF(file->addr, "%[^:]:%hu", addr, &port)) { case 1 : port = DEFAULT_BKRS_PORT; case 2 : break; default : util_out_print("ERROR: A hostname has to be specified to backup through a TCP connection.", TRUE); return FALSE; } if ((0 == cli_get_int("NETTIMEOUT", &timeout)) || (0 > timeout)) timeout = DEFAULT_BKRS_TIMEOUT; if (0 > (backup_socket = tcp_open(addr, port, timeout, FALSE))) { util_out_print("ERROR: Cannot open tcp connection due to the above error.", TRUE); return FALSE; } common_write = tcp_write; common_close = tcp_close; common = (char *)(&backup_socket); break; default : util_out_print("ERROR: Backup format !UL not supported.", TRUE, list->backup_to); util_out_print("Error: Your request to backup database !AD to !AD is not valid.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); return FALSE; } /* ============================= write inc_header =========================================== */ outptr = malloc(SIZEOF(inc_header)); outbuf = (inc_header *)outptr; MEMCPY_LIT(&outbuf->label[0], INC_HEADER_LABEL); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, &mu_bin_datefmt, &null_str, &null_str, &val); memcpy(&outbuf->date[0], val.str.addr, val.str.len); memcpy(&outbuf->reg[0], gv_cur_region->rname, MAX_RN_LEN); outbuf->start_tn = list->tn; outbuf->end_tn = header->trans_hist.curr_tn; outbuf->db_total_blks = header->trans_hist.total_blks; outbuf->blk_size = header->blk_size; outbuf->blks_to_upgrd = header->blks_to_upgrd; COMMON_WRITE(common, outptr, SIZEOF(inc_header)); free(outptr); if (mu_ctrly_occurred || mu_ctrlc_occurred) { error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return FALSE; } /* ============================ read/write appropriate blocks =============================== */ bsize = header->blk_size; gds_ratio = bsize / DISK_BLOCK_SIZE; blks_per_buff = BACKUP_READ_SIZE / bsize; read_size = blks_per_buff * bsize; outsize = SIZEOF(muinc_blk_hdr) + bsize; outptr = (char_ptr_t)malloc(MAX(outsize, mubmaxblk)); sblkh_p = (muinc_blk_hdr_ptr_t)outptr; data_ptr = (char_ptr_t)(sblkh_p + 1); bp = (blk_hdr_ptr_t)mubbuf; bm_blk_buff = (uchar_ptr_t)malloc(SIZEOF(blk_hdr) + (BLKS_PER_LMAP * BML_BITS_PER_BLK / BITS_PER_UCHAR)); mubincrab.rab$l_rbf = outptr; save_blks = 0; access = header->acc_meth; memset(sblkh_p, 0, SIZEOF(*sblkh_p)); if (access == dba_bg) bp = mubbuf; else { ptr = cs_addrs->db_addrs[0] + (cs_addrs->hdr->start_vbn - 1) * DISK_BLOCK_SIZE; ptr_top = cs_addrs->db_addrs[1] + 1; } sblkh_p->use.bkup.ondsk_blkver = GDSNOVER; for (blk_num_base = 0; blk_num_base < header->trans_hist.total_blks; blk_num_base += blks_per_buff) { if (online && (0 != cs_addrs->shmpool_buffer->failed)) break; if (header->trans_hist.total_blks - blk_num_base < blks_per_buff) { blks_per_buff = header->trans_hist.total_blks - blk_num_base; read_size = blks_per_buff * bsize; } if (access == dba_bg) { if ((SS$_NORMAL != (status = sys$qiow(EFN$C_ENF, fcb->fab$l_stv, IO$_READVBLK, &rd_iosb, 0, 0, bp, read_size, cs_addrs->hdr->start_vbn + (gds_ratio * blk_num_base), 0, 0, 0))) || (SS$_NORMAL != (status = rd_iosb[0]))) { gtm_putmsg(VARLSTCNT(1) status); util_out_print("Error reading data from database !AD.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } else { assert(dba_mm == access); bp = ptr + blk_num_base * bsize; } bptr = (blk_hdr *)bp; /* The blocks we back up will be whatever version they are. There is no implicit conversion in this part of the backup/restore. Since we aren't even looking at the blocks (and indeed some of these blocks could potentially contain unintialized garbage data), we set the block version to GDSNOVER to signal that the block version is unknown. The above applies to "regular" blocks but not to bitmap blocks which we know are initialized. Because we have to read the bitmap blocks, they will be converted as necessary. */ for (i = 0; i < blks_per_buff && ((blk_num_base + i) < header->trans_hist.total_blks); i++, bptr = (blk_hdr *)((char *)bptr + bsize)) { blk_num = blk_num_base + i; if (mu_ctrly_occurred || mu_ctrlc_occurred) { free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); return FALSE; } /* Before we check if this block needs backing up, check if this is a new bitmap block or not. If it is, we can fall through and back it up as normal. But if this is NOT a bitmap block, use the existing bitmap to determine if this block has ever been allocated or not. If not, we don't want to even look at this block. It could be uninitialized which will just make things run slower if we go to read it and back it up. */ if (0 != ((BLKS_PER_LMAP - 1) & blk_num)) { /* Not a local bitmap block */ if (!gvcst_blk_ever_allocated(bm_blk_buff + SIZEOF(blk_hdr), ((blk_num * BML_BITS_PER_BLK) % (BLKS_PER_LMAP * BML_BITS_PER_BLK)))) continue; /* Bypass never-set blocks to avoid conversion problems */ is_bitmap_blk = FALSE; if (SIZEOF(v15_blk_hdr) <= (blk_bsiz = ((v15_blk_hdr_ptr_t)bptr)->bsiz)) { /* We have either a V4 block or uninitialized garbage */ if (blk_bsiz > bsize) /* This is not a valid V4 block so ignore it */ continue; blk_tn = ((v15_blk_hdr_ptr_t)bptr)->tn; } else { /* Assume V5 block */ if ((blk_bsiz = bptr->bsiz) > bsize) /* Not a valid V5 block either */ continue; blk_tn = bptr->tn; } } else { /* This is a bitmap block so save it into our bitmap block buffer. It is used as the basis of whether or not we have to process a given block or not. We process allocated and recycled blocks leaving free (never used) blocks alone as they have no data worth saving. But after saving it, upgrade it to the current format if necessary. */ is_bitmap_blk = TRUE; memcpy(bm_blk_buff, bptr, BM_SIZE(header->bplmap)); if (SIZEOF(v15_blk_hdr) <= ((v15_blk_hdr_ptr_t)bm_blk_buff)->bsiz) { /* This is a V4 format block -- needs upgrading */ status = gds_blk_upgrade(bm_blk_buff, bm_blk_buff, bsize, &dummy_odbv); if (SS_NORMAL != status) { free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); util_out_print("Error: Block 0x!XL is too large for automatic upgrade", TRUE, sblkh_p->blkid); return FALSE; } } assert(BM_SIZE(header->bplmap) == ((blk_hdr_ptr_t)bm_blk_buff)->bsiz); assert(LCL_MAP_LEVL == ((blk_hdr_ptr_t)bm_blk_buff)->levl); assert(gvcst_blk_is_allocated(bm_blk_buff + SIZEOF(blk_hdr), ((blk_num * BML_BITS_PER_BLK) % (BLKS_PER_LMAP * BML_BITS_PER_BLK)))); blk_bsiz = BM_SIZE(header->bplmap); blk_tn = ((blk_hdr_ptr_t)bm_blk_buff)->tn; } /* The conditions for backing up a block or ignoring it (in order of evaluation): 1) If blk is larger than size of db at time backup was initiated, we ignore the block. 2) Always backup blocks 0, 1, and 2 as these are the only blocks that can contain data and still have a transaction number of 0. 3) For bitmap blocks, if blks_to_upgrd != 0 and the TN is 0 and the block number >= last_blk_at_last_bkup, then backup the block. This way we get the correct version of the bitmap block in the restore (otherwise have no clue what version to create them in as bitmaps are created with a TN of 0 when before image journaling is enabled). 4) If the block TN is below our TN threshold, ignore the block. 5) Else if none of the above conditions, backup the block. */ if (online && (header->trans_hist.curr_tn <= blk_tn)) backup_this_blk = FALSE; else if (3 > blk_num || (is_bitmap_blk && 0 != header->blks_to_upgrd && (trans_num)0 == blk_tn && blk_num >= list->last_blk_at_last_bkup)) backup_this_blk = TRUE; else if ((blk_tn < list->tn)) backup_this_blk = FALSE; else backup_this_blk = TRUE; if (!backup_this_blk) { if (online) cs_addrs->nl->nbb = blk_num; continue; /* not applicable */ } sblkh_p->blkid = blk_num; memcpy(data_ptr, bptr, blk_bsiz); sblkh_p->valid_data = TRUE; /* Validation marker */ COMMON_WRITE(common, outptr, outsize); if (online) { if (0 != cs_addrs->shmpool_buffer->failed) break; cs_addrs->nl->nbb = blk_num; } save_blks++; } } /* ============================= write saved information for online backup ========================== */ if (online && (0 == cs_addrs->shmpool_buffer->failed)) { /* -------- make sure everyone involved finishes -------- */ cs_addrs->nl->nbb = BACKUP_NOT_IN_PROGRESS; /* By getting crit here, we ensure that there is no process still in transaction logic that sees (nbb != BACKUP_NOT_IN_PRORESS). After rel_crit(), any process that enters transaction logic will see (nbb == BACKUP_NOT_IN_PRORESS) because we just set it to that value. At this point, backup buffer is complete and there will not be any more new entries in the backup buffer until the next backup. */ grab_crit(gv_cur_region); assert(cs_data == cs_addrs->hdr); if (dba_bg == cs_data->acc_meth) { /* Now that we have crit, wait for any pending phase2 updates to finish. Since phase2 updates happen * outside of crit, we dont want them to keep writing to the backup temporary file even after the * backup is complete and the temporary file has been deleted. */ if (cs_addrs->nl->wcs_phase2_commit_pidcnt && !wcs_phase2_commit_wait(cs_addrs, NULL)) { gtm_putmsg(VARLSTCNT(7) ERR_COMMITWAITSTUCK, 5, process_id, 1, cs_addrs->nl->wcs_phase2_commit_pidcnt, DB_LEN_STR(gv_cur_region)); rel_crit(gv_cur_region); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } if (debug_mupip) { util_out_print("MUPIP INFO: Current Transaction # at end of backup is 0x!16@XQ", TRUE, &cs_data->trans_hist.curr_tn); } rel_crit(gv_cur_region); counter = 0; while (0 != cs_addrs->shmpool_buffer->backup_cnt) { if (0 != cs_addrs->shmpool_buffer->failed) { util_out_print("Process !UL encountered the following error.", TRUE, cs_addrs->shmpool_buffer->failed); if (0 != cs_addrs->shmpool_buffer->backup_errno) gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } backup_buffer_flush(gv_cur_region); if (++counter > MAX_BACKUP_FLUSH_TRY) { gtm_putmsg(VARLSTCNT(1) ERR_BCKUPBUFLUSH); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } if (counter & 0xF) wcs_sleep(counter); else { /* Force shmpool recovery to see if it can find the lost blocks */ if (!shmpool_lock_hdr(gv_cur_region)) { gtm_putmsg(VARLSTCNT(9) ERR_DBCCERR, 2, REG_LEN_STR(gv_cur_region), ERR_ERRCALL, 3, CALLFROM); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); assert(FALSE); return FALSE;; } shmpool_abandoned_blk_chk(gv_cur_region, TRUE); shmpool_unlock_hdr(gv_cur_region); } } /* -------- Open the temporary file -------- */ temp_fab = cc$rms_fab; temp_fab.fab$b_fac = FAB$M_GET; temp_fab.fab$l_fna = list->backup_tempfile; temp_fab.fab$b_fns = strlen(list->backup_tempfile); temp_rab = cc$rms_rab; temp_rab.rab$l_fab = &temp_fab; for (lcnt = 1; MAX_OPEN_RETRY >= lcnt; lcnt++) { if (RMS$_FLK != (status = sys$open(&temp_fab, NULL, NULL))) break; wcs_sleep(lcnt); } if (RMS$_NORMAL != status) { gtm_putmsg(status, 0, temp_fab.fab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } if (RMS$_NORMAL != (status = sys$connect(&temp_rab))) { gtm_putmsg(status, 0, temp_rab.rab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } /* -------- read and write every record in the temporary file -------- */ while (1) { temp_rab.rab$w_usz = outsize; temp_rab.rab$l_ubf = outptr; status = sys$get(&temp_rab); if (RMS$_NORMAL != status) { if (RMS$_EOF == status) status = RMS$_NORMAL; break; } assert(outsize == temp_rab.rab$w_rsz); /* Still validly sized blk? */ assert((outsize - SIZEOF(shmpool_blk_hdr)) >= ((blk_hdr_ptr_t)(outptr + SIZEOF(shmpool_blk_hdr)))->bsiz); COMMON_WRITE(common, outptr, temp_rab.rab$w_rsz); } if (RMS$_NORMAL != status) { gtm_putmsg(status, 0, temp_rab.rab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } /* ---------------- Close the temporary file ----------------------- */ if (RMS$_NORMAL != (status = sys$close(&temp_fab))) { gtm_putmsg(status, 0, temp_fab.fab$l_stv); util_out_print("WARNING: DB file !AD backup aborted.", TRUE, fcb->fab$b_fns, fcb->fab$l_fna); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } } /* ============================= write end_msg and fileheader ======================================= */ if ((!online) || (0 == cs_addrs->shmpool_buffer->failed)) { MEMCPY_LIT(outptr, END_MSG); /* Although the write only need be of length SIZEOF(END_MSG) - 1 for file IO, if the write is going to TCP we have to write all these records with common length so just write the "regular" sized buffer. The extra garbage left over from the last write will be ignored as we key only on the this end text. */ COMMON_WRITE(common, outptr, outsize); ptr1 = header; size1 = ROUND_UP(SIZEOF(sgmnt_data), DISK_BLOCK_SIZE); ptr1_top = ptr1 + size1; for (;ptr1 < ptr1_top ; ptr1 += size1) { if ((size1 = ptr1_top - ptr1) > mubmaxblk) size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE; COMMON_WRITE(common, ptr1, size1); } MEMCPY_LIT(outptr, HDR_MSG); COMMON_WRITE(common, outptr, SIZEOF(HDR_MSG)); ptr1 = MM_ADDR(header); size1 = ROUND_UP(MASTER_MAP_SIZE(header), DISK_BLOCK_SIZE); ptr1_top = ptr1 + size1; for (;ptr1 < ptr1_top ; ptr1 += size1) { if ((size1 = ptr1_top - ptr1) > mubmaxblk) size1 = (mubmaxblk / DISK_BLOCK_SIZE) * DISK_BLOCK_SIZE; COMMON_WRITE(common, ptr1, size1); } MEMCPY_LIT(outptr, MAP_MSG); COMMON_WRITE(common, outptr, SIZEOF(MAP_MSG)); } /* ================== close backup destination, output and return ================================== */ if (online && (0 != cs_addrs->shmpool_buffer->failed)) { util_out_print("Process !UL encountered the following error.", TRUE, cs_addrs->shmpool_buffer->failed); if (0 != cs_addrs->shmpool_buffer->backup_errno) gtm_putmsg(VARLSTCNT(1) cs_addrs->shmpool_buffer->backup_errno); free(outptr); free(bm_blk_buff); error_mupip = TRUE; COMMON_CLOSE(common); return FALSE; } COMMON_CLOSE(common); free(outptr); free(bm_blk_buff); util_out_print("DB file !AD incrementally backed up in !AD", TRUE, fcb->fab$b_fns, fcb->fab$l_fna, file->len, file->addr); util_out_print("!UL blocks saved.", TRUE, save_blks); util_out_print("Transactions from 0x!16@XQ to 0x!16@XQ are backed up.", TRUE, &cs_addrs->shmpool_buffer->inc_backup_tn, &header->trans_hist.curr_tn); cs_addrs->hdr->last_inc_backup = header->trans_hist.curr_tn; if (record) cs_addrs->hdr->last_rec_backup = header->trans_hist.curr_tn; file_backed_up = TRUE; return TRUE; }
xc_status_t gc_init_interface(int prompt_passwd) { /* zOS is special when it comes to dynamic linking. * (1). Building DLL with UNRESOLVED symbols * ========================================= * Unlike other Unix platforms, on zOS DLL cannot be built having unresolved symbols and expecting them to get resolved * by the loader. * In this particular scenario we have symbols gtm_malloc, gtm_is_file_identical, gtm_free, gtm_filename_to_id and * gtm_xcfileid_free that are part of mupip executable. * As an workaround we are using function pointers to call into the interface functions so that we don't have an link-time * errors. * At runtime we do an dlopen with NULL which returns handle to global space and dlsym sets the function pointers to point * to the correct functions at runtime. * * (2). DLSYM on symbols that are already resolved from another DLL * ================================================================ * When mumps calls into libgtmcrypt it has above mentioned symbols already resolved from libgtmshr.dll. * On zOS, when we try to DLSYM using the handle returned by DLOPEN(NULL,..), DLSYM crashes while trying to find symbols * that are already loaded from another DLL(libgtmshr.dll). * As an work around we dlopen libgtmshr.dll when called from MUMPS. */ # ifdef __MVS__ void *handle = NULL; const char *gtm_dist, *dlerr_ptr; char gtmshr_file[GTM_PATH_MAX]; int dir_len; if (!(gtm_dist = getenv(GTM_DIST))) UPDATE_ERROR_STRING(ENV_UNDEF_ERROR, GTM_DIST); dir_len = STRLEN(gtm_dist); memcpy(>mshr_file[0], gtm_dist, dir_len); gtmshr_file[dir_len] = DIR_SEPARATOR; MEMCPY_LIT(>mshr_file[dir_len + 1], GTMSHR_IMAGENAME); gtmshr_file[dir_len + STR_LIT_LEN(GTMSHR_IMAGENAME) + 1] = '\0'; /* prompt_passwd = TRUE implies plugin is invoked from MUMPS. We need to dlopen libgtmshr when invoked from MUMPS. * Please refer comment (2) above. */ handle = dlopen(prompt_passwd ? gtmshr_file : NULL, GC_FLAGS); if (NULL == handle) { if (NULL == (dlerr_ptr = dlerror())) { UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. Unknown system error"); } else UPDATE_ERROR_STRING("Unable to resolve GT.M interface functions. %s", dlerr_ptr); return GC_FAILURE; } DLSYM_ERR_AND_EXIT(gtm_is_file_identical_fptr_t, gtm_is_file_identical_fptr, GTM_IS_FILE_IDENTICAL_FUNC); DLSYM_ERR_AND_EXIT(gtm_malloc_fptr_t, gtm_malloc_fptr, GTM_MALLOC_FUNC); DLSYM_ERR_AND_EXIT(gtm_free_fptr_t, gtm_free_fptr, GTM_FREE_FUNC); DLSYM_ERR_AND_EXIT(gtm_filename_to_id_fptr_t, gtm_filename_to_id_fptr, GTM_FILENAME_TO_ID_FUNC); DLSYM_ERR_AND_EXIT(gtm_ci_fptr_t, gtm_ci_fptr, GTM_CI_FUNC); DLSYM_ERR_AND_EXIT(gtm_zstatus_fptr_t, gtm_zstatus_fptr, GTM_ZSTATUS_FUNC); DLSYM_ERR_AND_EXIT(gtm_xcfileid_free_fptr_t, gtm_xcfileid_free_fptr, GTM_XCFILEID_FREE_FUNC); # else gtm_is_file_identical_fptr = >m_is_file_identical; gtm_malloc_fptr = >m_malloc; gtm_free_fptr = >m_free; gtm_filename_to_id_fptr = >m_filename_to_id; gtm_ci_fptr = >m_ci; gtm_zstatus_fptr = >m_zstatus; gtm_xcfileid_free_fptr = >m_xcfileid_free; # endif return GC_SUCCESS; }
void lvzwr_out(lv_val *lvp) { char buff; uchar_ptr_t lastc; int n, nsubs, sbs_depth; lv_val *dst_lv, *res_lv, *lvpc; mstr one; mval *subscp, *val, outindx; ht_ent_addr *tabent_addr; ht_ent_mname *tabent_mname; boolean_t htent_added, dump_container; zwr_alias_var *newzav, *zav; mident_fixed zwrt_varname; lvzwrite_datablk *newzwrb; gparam_list param_list; /* for op_putindx call through callg */ gvnh_reg_t *gvnh_reg; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; val = &lvp->v; assert(lvzwrite_block); if (!merge_args) { /* The cases that exist here are: * 1) This is a container variable. If the lv_val it refers to has been printed, show that association. * Else, "create" a $ZWRTACxxx var/index that will define the value. Then before returning, cause * that container var to be dumped with the appropriate $ZWRTACxxx index as the var name. * 2) This is an alias base variable. If first time seen, we print normally but record it and put a * ";#" tag on the end to signify it is an alias var (doesn't affect value). If we look it up and it * is not the first time this lv_val has been printed, then we instead print the statement needed to * alias it to the first seen var. * 3) This is just a normal var needing to be printed normally. */ htent_added = FALSE; one.addr = &buff; one.len = 1; lvzwrite_block->zav_added = FALSE; if (lvp->v.mvtype & MV_ALIASCONT) { /* Case 1 -- have an alias container */ assert(curr_symval->alias_activity); assert(!LV_IS_BASE_VAR(lvp)); /* verify is subscripted var */ lvpc = (lv_val *)lvp->v.str.addr; assert(lvpc); assert(LV_IS_BASE_VAR(lvpc)); /* Verify base var lv_val */ if (tabent_addr = (ht_ent_addr *)lookup_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc)) { /* The value was found, we have a reference we can print now */ assert(HTENT_VALID_ADDR(tabent_addr, zwr_alias_var, zav)); *one.addr = '*'; zshow_output(zwr_output, &one); lvzwr_out_targkey(&one); *one.addr = '='; zshow_output(zwr_output, &one); zav = (zwr_alias_var *)tabent_addr->value; assert(0 < zav->zwr_var.len); zwr_output->flush = TRUE; zshow_output(zwr_output, (const mstr *)&zav->zwr_var); return; } /* This lv_val isn't known to us yet. Scan the hash curr_symval hash table to see if it is known as a * base variable as we could have a "forward reference" here. */ tabent_mname = als_lookup_base_lvval(lvpc); /* note even though both paths below add a zav, not bothering to set zav_added because that flag is * really only (currently) cared about in reference to processing a basevar so we wouldn't * be in this code path anyway. Comment here to record potential usage if that changes. */ if (tabent_mname) { /* Found a base var it can reference -- create a zwrhtab entry for it */ assert(tabent_mname->key.var_name.len); newzav = als_getzavslot(); newzav->zwr_var = tabent_mname->key.var_name; htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc, newzav, &tabent_addr); assert(htent_added); dump_container = FALSE; } else { /* Unable to find lv_val .. must be "orphaned" so we generate a new $ZWRTAC var for it. The first * check however is if this is the first $ZWRTAC var being generated for this $ZWR. If yes, generate * a $ZWRTAC="" line to preceed it. This will be a flag to load to clear out all existing $ZWRTAC * temp vars so there is no pollution between loads of ZWRitten data. */ if (0 == zwrtacindx++) { /* Put out "dummy" statement that will clear all the $ZWRTAC vars for a clean slate */ zwr_output->flush = TRUE; zshow_output(zwr_output, &dzwrtac_clean); } MEMCPY_LIT(zwrt_varname.c, DOLLAR_ZWRTAC); lastc = i2asc((uchar_ptr_t)zwrt_varname.c + STR_LIT_LEN(DOLLAR_ZWRTAC), zwrtacindx); newzav = als_getzavslot(); newzav->zwr_var.addr = zwrt_varname.c; newzav->zwr_var.len = INTCAST(((char *)lastc - &zwrt_varname.c[0])); s2pool(&newzav->zwr_var); htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvpc, newzav, &tabent_addr); assert(htent_added); dump_container = TRUE; } /* Note value_printed flag in newzav not set since we are NOT dumping the value at this point * but only the association. Since the flag is not set, we *will* dump it when we get to that * actual variable. */ *one.addr = '*'; zshow_output(zwr_output, &one); lvzwr_out_targkey(&one); *one.addr = '='; zshow_output(zwr_output, &one); zwr_output->flush = TRUE; zshow_output(zwr_output, (const mstr *)&newzav->zwr_var); if (dump_container) { /* We want to dump the entire container variable but the name doesn't match the var we are * currently dumping so push a new lvzwrite_block onto the stack, fill it in for the current var * and call lvzwr_var() to handle it. When done, dismantle the temp lvzwrite_block. */ newzwrb = (lvzwrite_datablk *)malloc(SIZEOF(lvzwrite_datablk)); memset(newzwrb, 0, SIZEOF(lvzwrite_datablk)); newzwrb->sub = (zwr_sub_lst *)malloc(SIZEOF(zwr_sub_lst) * MAX_LVSUBSCRIPTS); newzwrb->curr_name = &newzav->zwr_var; newzwrb->prev = lvzwrite_block; lvzwrite_block = newzwrb; lvzwr_var(lvpc, 0); assert(newzav->value_printed); assert(newzwrb == lvzwrite_block); free(newzwrb->sub); lvzwrite_block = newzwrb->prev; free(newzwrb); } return; } else if (LV_IS_BASE_VAR(lvp) && IS_ALIASLV(lvp)) { /* Case 2 -- alias base variable (only base vars have reference counts). Note this can occur with * TP save/restore vars since we increment both trefcnt and crefcnt for these hidden copied references. * Because of that, we can't assert alias_activity but otherwise it shouldn't affect processing. */ if (!(htent_added = add_hashtab_addr(&zwrhtab->h_zwrtab, (char **)&lvp, NULL, &tabent_addr))) { /* Entry already existed -- need to output association rather than values */ assert(tabent_addr); zav = (zwr_alias_var *)tabent_addr->value; assert(zav); if (zav->value_printed) { /* Value has already been output -- print association this time */ *one.addr = '*'; /* Flag as creating an alias */ zshow_output(zwr_output, &one); /* Now for (new) variable name */ zshow_output(zwr_output, lvzwrite_block->curr_name); *one.addr = '='; zshow_output(zwr_output, &one); /* .. and the var name aliasing to (the first seen with this lv_val) */ assert(zav->zwr_var.len); zwr_output->flush = TRUE; zshow_output(zwr_output, &zav->zwr_var); return; } /* Else the value for this entry has not yet been printed so let us fall into case 3 * and get that done. Also set the flag so we mark it as an alias. Note this can happen if * a container value for a name is encountered before the base var it points to. We will * properly resolve the entry but its value won't have been printed until we actually encounter * it in the tree. */ htent_added = TRUE; /* to force the ;# tag at end of value printing */ zav->value_printed = TRUE; /* value will be output shortly below */ } else { /* Entry was added so is first appearance -- give it a value to hold onto and print it */ newzav = als_getzavslot(); newzav->zwr_var = *lvzwrite_block->curr_name; newzav->value_printed = TRUE; /* or rather it will be shortly.. */ tabent_addr->value = (void *)newzav; lvzwrite_block->zav_added = TRUE; /* Note fall into case 3 to print var and value if exists */ } } /* Case 3 - everything else */ if (!MV_DEFINED(val)) return; MV_FORCE_STR(val); lvzwr_out_targkey(&one); *one.addr = '='; zshow_output(zwr_output, &one); mval_write(zwr_output, val, !htent_added); if (htent_added) { /* output the ";#" tag to indicate this is an alias output */ zwr_output->flush = TRUE; zshow_output(zwr_output, &semi_star); } } else { /* MERGE assignment from local variable */ nsubs = lvzwrite_block->curr_subsc; if (MARG1_IS_GBL(merge_args)) { /* Target is a global var : i.e. MERGE ^gvn1=lcl1. * In this case, mglvnp->gblp[IND1]->gvkey_nsubs would have been initialized in op_merge.c already. * Use that to check if the target node in ^gvn1 exceeds max # of subscripts. */ if (MAX_GVSUBSCRIPTS <= (mglvnp->gblp[IND1]->gvkey_nsubs + nsubs)) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS); memcpy(gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->base, mglvnp->gblp[IND1]->s_gv_currkey->end + 1); gv_currkey->end = mglvnp->gblp[IND1]->s_gv_currkey->end; for (n = 0; n < nsubs; n++) { subscp = ((zwr_sub_lst *)lvzwrite_block->sub)->subsc_list[n].actual; MV_FORCE_STR(subscp); mval2subsc(subscp, gv_currkey, gv_cur_region->std_null_coll); if (!subscp->str.len && (ALWAYS != gv_cur_region->null_subs)) sgnl_gvnulsubsc(); } MV_FORCE_STR(val); gvnh_reg = TREF(gd_targ_gvnh_reg); /* set by op_gvname/op_gvextnam/op_gvnaked done before op_merge */ /* If gvnh_reg corresponds to a spanning global, then determine * gv_cur_region/gv_target/gd_targ_* variables based on updated gv_currkey. */ GV_BIND_SUBSNAME_FROM_GVNH_REG_IF_GVSPAN(gvnh_reg, (TREF(gd_targ_addr)), gv_currkey); /* For spanning globals, "gv_cur_region" points to the target region for ^gvn1 only now. * So do the GVSUBOFLOW check (both for spanning and non-spanning globals) now. */ if (gv_currkey->end >= gv_cur_region->max_key_size) ISSUE_GVSUBOFLOW_ERROR(gv_currkey, KEY_COMPLETE_TRUE); op_gvput(val); } else { /* Target is a local var : pre-process target in case it is a container */ assert(MARG1_IS_LCL(merge_args)); dst_lv = mglvnp->lclp[IND1]; if (!LV_IS_BASE_VAR(dst_lv)) { LV_SBS_DEPTH(dst_lv, FALSE, sbs_depth); if (MAX_LVSUBSCRIPTS < (sbs_depth + nsubs)) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_MERGEINCOMPL, 0, ERR_MAXNRSUBSCRIPTS); } param_list.arg[0] = dst_lv; /* this is already protected from stp_gcol by op_merge so no need to * push this into the stack for stp_gcol protection. */ for (n = 0 ; n < nsubs; n++) { /* Note: no need to do push these mvals on the stack before calling op_putindx * as lvzwrite_block->sub is already protected by stp_gcol_src.h. */ param_list.arg[n+1] = ((zwr_sub_lst *)lvzwrite_block->sub)->subsc_list[n].actual; } param_list.n = n + 1; dst_lv = (lv_val *)callg((callgfnptr)op_putindx, ¶m_list); MV_FORCE_STR(val); assert(!(MV_ALIASCONT & dst_lv->v.mvtype)); /* op_putindx would have already done DECR_AC_REF for us */ dst_lv->v = *val; dst_lv->v.mvtype &= ~MV_ALIASCONT; /* Make sure alias container property does not pass */ } } }
sm_uc_ptr_t dump_record(sm_uc_ptr_t rp, block_id blk, sm_uc_ptr_t bp, sm_uc_ptr_t b_top) { sm_uc_ptr_t r_top, key_top, cptr0, cptr1, cptr_top, cptr_base = NULL, cptr_next = NULL; char key_buf[MAX_KEY_SZ + 1], *temp_ptr, *temp_key, util_buff[MAX_UTIL_LEN]; char *prefix_str, *space_str, *dot_str, *format_str; unsigned char cc; short int size; int4 util_len, head; uint4 ch; int buf_len, field_width,fastate, chwidth = 0; ssize_t chlen; block_id blk_id; boolean_t rechdr_displayed = FALSE; sgmnt_addrs *csa; if (rp >= b_top) return NULL; head = cli_present("HEADER"); GET_SHORT(size, &((rec_hdr_ptr_t)rp)->rsiz); cc = ((rec_hdr_ptr_t)rp)->cmpc; if ((CLI_NEGATED != head) && !patch_is_fdmp) { MEMCPY_LIT(util_buff, "Rec:"); util_len = SIZEOF("Rec:") - 1; util_len += i2hex_nofill(patch_rec_counter, (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Blk "); util_len += SIZEOF(" Blk ") - 1; util_len += i2hex_nofill(blk, (uchar_ptr_t)&util_buff[util_len], 8); MEMCPY_LIT(&util_buff[util_len], " Off "); util_len += SIZEOF(" Off ") - 1; util_len += i2hex_nofill((int)(rp - bp), (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Size "); util_len += SIZEOF(" Size ") - 1; util_len += i2hex_nofill(size, (uchar_ptr_t)&util_buff[util_len], 4); MEMCPY_LIT(&util_buff[util_len], " Cmpc "); util_len += SIZEOF(" Cmpc ") - 1; util_len += i2hex_nofill(cc, (uchar_ptr_t)&util_buff[util_len], 2); MEMCPY_LIT(&util_buff[util_len], " "); util_len += SIZEOF(" ") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); } r_top = rp + size; if (r_top > b_top) r_top = b_top; else if (r_top < rp + SIZEOF(rec_hdr)) r_top = rp + SIZEOF(rec_hdr); if (cc > patch_comp_count) cc = patch_comp_count; if (((blk_hdr_ptr_t)bp)->levl) key_top = r_top - SIZEOF(block_id); else { for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top;) if (!*key_top++ && !*key_top++) break; } size = key_top - rp - SIZEOF(rec_hdr); if (size > SIZEOF(patch_comp_key) - 2 - cc) size = SIZEOF(patch_comp_key) - 2 - cc; if (size < 0) size = 0; memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size); patch_comp_count = cc + size; patch_comp_key[patch_comp_count] = patch_comp_key[patch_comp_count + 1] = 0; if (patch_is_fdmp) { if (dse_fdmp(key_top, (int)(r_top - key_top))) patch_fdmp_recs++; } else { if (r_top - SIZEOF(block_id) >= key_top) { GET_LONG(blk_id, key_top); if ((((blk_hdr_ptr_t)bp)->levl) || (blk_id <= cs_addrs->ti->total_blks)) { MEMCPY_LIT(util_buff, "Ptr "); util_len = SIZEOF("Ptr ") - 1; util_len += i2hex_nofill(blk_id, (uchar_ptr_t)&util_buff[util_len], SIZEOF(blk_id) * 2); MEMCPY_LIT(&util_buff[util_len], " "); util_len += SIZEOF(" ") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); } } util_out_print("Key ", FALSE); if (r_top == b_top && ((blk_hdr_ptr_t)bp)->levl && !((rec_hdr_ptr_t)rp)->cmpc && r_top - rp == SIZEOF(rec_hdr) + SIZEOF(block_id)) util_out_print("*", FALSE); else if (patch_comp_key[0]) { util_out_print("^", FALSE); csa = cs_addrs; RETRIEVE_ROOT_VAL(patch_comp_key, key_buf, temp_ptr, temp_key, buf_len); INIT_ROOT_GVT(key_buf, buf_len, curr_gbl_root); } print_target((uchar_ptr_t)patch_comp_key); util_out_print(0, TRUE); if (CLI_PRESENT != head) { prefix_str = " |"; if (wide_out) { format_str = " !AD"; dot_str = " ."; space_str = " "; field_width = 4; } else { format_str = " !AD"; dot_str = " ."; space_str = " "; field_width = 3; } fastate = 0; for (cptr0 = rp; cptr0 < r_top; cptr0 += NUM_BYTES_PER_LINE) { if (util_interrupt) { /* return, rather than signal ERR_CTRLC so that the calling routine can deal with that signal and do the appropriate cleanup */ return NULL; } util_len = 8; i2hex_blkfill((int)(cptr0 - bp), (uchar_ptr_t)util_buff, 8); MEMCPY_LIT(&util_buff[util_len], " : |"); util_len += SIZEOF(" : |") - 1; util_buff[util_len] = 0; util_out_print(util_buff, FALSE); /* Dump hexadecimal byte values */ for (cptr1 = cptr0; cptr1 < (cptr0 + NUM_BYTES_PER_LINE); cptr1++) { if (cptr1 < r_top) { i2hex_blkfill(*(sm_uc_ptr_t)cptr1, (uchar_ptr_t)util_buff, field_width); util_buff[field_width] = 0; util_out_print(util_buff, FALSE); } else util_out_print(space_str, FALSE); } util_out_print("|", TRUE); util_out_print(prefix_str, FALSE); /* Display character/wide-character glyphs */ for (cptr1 = cptr0, cptr_top = cptr0 + NUM_BYTES_PER_LINE; cptr1 < cptr_top; cptr1++) { if (!rechdr_displayed && (cptr1 == (rp + SIZEOF(rec_hdr)))) rechdr_displayed = TRUE; assert(rechdr_displayed || (cptr1 < (rp + SIZEOF(rec_hdr)))); assert(!rechdr_displayed || (cptr1 >= (rp + SIZEOF(rec_hdr)))); switch (fastate) { case 0: /* prints single-byte characters or intepret multi-byte characters */ if (cptr1 >= r_top) util_out_print(space_str, FALSE); else if (!gtm_utf8_mode || IS_ASCII(*cptr1) || !rechdr_displayed) { /* single-byte characters */ if (PRINTABLE(*(sm_uc_ptr_t)cptr1)) util_out_print(format_str, FALSE, 1, cptr1); else util_out_print(dot_str, FALSE); } #ifdef UNICODE_SUPPORTED else { /* multi-byte characters */ cptr_next = UTF8_MBTOWC(cptr1, r_top, ch); chlen = cptr_next - cptr1; if (WEOF == ch || !U_ISPRINT(ch)) { /* illegal or non-printable characters */ cptr1--; fastate = 1; } else { /* multi-byte printable characters */ cptr_base = cptr1; chwidth = UTF8_WCWIDTH(ch); assert(chwidth >= 0 && chwidth <= 2); cptr1--; fastate = 2; } } #endif break; case 1: /* illegal or non-printable characters */ util_out_print(dot_str, FALSE); if (--chlen <= 0) fastate = 0; break; case 2: /* printable multi-byte characters */ if (chlen-- > 1) /* fill leading bytes with spaces */ util_out_print(space_str, FALSE); else { util_out_print("!AD", FALSE, field_width - chwidth, space_str); if (0 < chwidth) util_out_print("!AD", FALSE, cptr_next - cptr_base, cptr_base); fastate = 0; } break; } } util_out_print("|", TRUE); } } if (CLI_NEGATED != head) util_out_print(0, TRUE); } return (r_top == b_top) ? NULL : r_top; }
void zshow_stack(zshow_out *output) { boolean_t line_reset; unsigned char *addr; unsigned short nocount_frames[MAX_INDR_PER_COUNTED], *nfp; stack_frame *fp; mstr v; unsigned char buff[MAX_ENTRYREF_LEN + SIZEOF(INDR_OVERFLOW)]; v.addr = (char *)&buff[0]; flush_pio(); nfp = &nocount_frames[0]; line_reset = FALSE; for (fp = frame_pointer; ; fp = fp->old_frame_pointer) { if (NULL == fp->old_frame_pointer) { /* This frame is a base frame - endpoint or jump it? */ # ifdef GTM_TRIGGER if (fp->type & SFT_TRIGR) /* Have a trigger baseframe, pick up stack continuation frame_pointer stored by base_frame() */ fp = *(stack_frame **)(fp + 1); else # endif break; /* Endpoint.. */ } if (!(fp->type & SFT_COUNT) || (fp->type & SFT_ZINTR)) { if (nfp < &nocount_frames[MAX_INDR_PER_COUNTED]) /* If room in array, save indirect frame type */ *nfp++ = fp->type; else nocount_frames[MAX_INDR_PER_COUNTED - 1] = 0xffff; /* Indicate array overflow */ if (fp->type & SFT_ZTRAP || fp->type & SFT_DEV_ACT || HAS_TRANS_CODE_ERR(fp)) line_reset = TRUE; } else { if (HAS_TRANS_CODE_ERR(fp)) { *nfp++ = (fp->flags & SFF_ZTRAP_ERR) ? SFT_ZTRAP : SFT_DEV_ACT; line_reset = TRUE; } if (line_reset && ADDR_IN_CODE(fp->mpc, fp->rvector)) { addr = fp->mpc + 1; line_reset = FALSE; } else addr = fp->mpc; v.len = INTCAST(symb_line(addr, &buff[0], 0, fp->rvector) - &buff[0]); if (v.len == 0) { MEMCPY_LIT(&buff[0], UNK_LOC_MESS); v.len = SIZEOF(UNK_LOC_MESS) - 1; } if (nfp != &nocount_frames[0]) { for (--nfp; nfp >= &nocount_frames[0]; nfp--) { switch(*nfp) { case SFT_ZBRK_ACT: MEMCPY_LIT(&buff[v.len], ZBRK_FRAME); v.len += SIZEOF(ZBRK_FRAME) - 1; break; case SFT_DEV_ACT: MEMCPY_LIT(&buff[v.len], DEVERR_FRAME); v.len += SIZEOF(DEVERR_FRAME) - 1; break; case SFT_ZTRAP: MEMCPY_LIT(&buff[v.len], ZTRAP_FRAME); v.len += SIZEOF(ZTRAP_FRAME) - 1; break; case SFT_DM: MEMCPY_LIT(&buff[v.len], DIR_MODE_MESS); v.len += SIZEOF(DIR_MODE_MESS) - 1; break; case (SFT_COUNT | SFT_ZINTR): MEMCPY_LIT(&buff[v.len], ZINTR_FRAME); v.len += SIZEOF(DIR_MODE_MESS) - 1; break; case 0xffff: MEMCPY_LIT(&buff[v.len], INDR_OVERFLOW); v.len += SIZEOF(INDR_OVERFLOW) - 1; break; default: break; } output->flush = TRUE; zshow_output(output, &v); v.len = 0; } nfp = &nocount_frames[0]; } else { output->flush = TRUE; zshow_output(output, &v); } } } return; }
int gtm_trigger_complink(gv_trigger_t *trigdsc, boolean_t dolink) { char rtnname[GTM_PATH_MAX + 1], rtnname_template[GTM_PATH_MAX + 1]; char objname[GTM_PATH_MAX + 1]; char zcomp_parms[(GTM_PATH_MAX * 2) + SIZEOF(mident_fixed) + SIZEOF(OBJECT_PARM) + SIZEOF(NAMEOFRTN_PARM)]; mstr save_zsource; int rtnfd, rc, lenrtnname, lenobjname, len, alphnum_len, retry, save_errno; char *mident_suffix_p1, *mident_suffix_p2, *mident_suffix_top, *namesub1, *namesub2, *zcomp_parms_ptr; mval zlfile, zcompprm; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; DBGTRIGR_ONLY(memcpy(rtnname, trigdsc->rtn_desc.rt_name.addr, trigdsc->rtn_desc.rt_name.len)); DBGTRIGR_ONLY(rtnname[trigdsc->rtn_desc.rt_name.len] = 0); DBGTRIGR((stderr, "gtm_trigger_complink: (Re)compiling trigger %s\n", rtnname)); ESTABLISH_RET(gtm_trigger_complink_ch, ((0 == error_condition) ? TREF(dollar_zcstatus) : error_condition )); /* Verify there are 2 available chars for uniqueness */ assert((MAX_MIDENT_LEN - TRIGGER_NAME_RESERVED_SPACE) >= (trigdsc->rtn_desc.rt_name.len)); assert(NULL == trigdsc->rtn_desc.rt_adr); gtm_trigger_comp_prev_run_time = run_time; run_time = TRUE; /* Required by compiler */ /* Verify the routine name set by MUPIP TRIGGER and read by gvtr_db_read_hasht() is not in use */ if (NULL != find_rtn_hdr(&trigdsc->rtn_desc.rt_name)) { /* Ooops .. need name to be more unique.. */ /* Though variable definitions are conventionally done at the function entry, the reason alphanumeric_table * definition is done here is to minimize the time taken to initialize the below table in the most common case * (i.e. no trigger name collisions). */ char alphanumeric_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0'}; alphnum_len = STR_LIT_LEN(alphanumeric_table); namesub1 = trigdsc->rtn_desc.rt_name.addr + trigdsc->rtn_desc.rt_name.len++; /* If WBTEST_HELPOUT_TRIGNAMEUNIQ is defined, set alphnum_len to 1. This way, we make the maximum * possible combinations for the uniqe trigger names to be 3 which is significantly lesser than * the actual number of combinations (62x62 = 3844). For eg., if ^a is a global having triggers defined * in 4 global directories, then the possible unique trigger names are a#1# ; a#1#A ; a#1#AA. */ GTM_WHITE_BOX_TEST(WBTEST_HELPOUT_TRIGNAMEUNIQ, alphnum_len, 1); mident_suffix_top = (char *)alphanumeric_table + alphnum_len; /* Phase 1. See if any single character can add uniqueness */ for (mident_suffix_p1 = (char *)alphanumeric_table; mident_suffix_p1 < mident_suffix_top; mident_suffix_p1++) { *namesub1 = *mident_suffix_p1; if (NULL == find_rtn_hdr(&trigdsc->rtn_desc.rt_name)) break; } if (mident_suffix_p1 == mident_suffix_top) { /* Phase 2. Phase 1 could not find uniqueness .. Find it with 2 char variations */ namesub2 = trigdsc->rtn_desc.rt_name.addr + trigdsc->rtn_desc.rt_name.len++; for (mident_suffix_p1 = (char *)alphanumeric_table; mident_suffix_p1 < mident_suffix_top; mident_suffix_p1++) { /* First char loop */ for (mident_suffix_p2 = (char *)alphanumeric_table; mident_suffix_p2 < mident_suffix_top; mident_suffix_p2++) { /* 2nd char loop */ *namesub1 = *mident_suffix_p1; *namesub2 = *mident_suffix_p2; if (NULL == find_rtn_hdr(&trigdsc->rtn_desc.rt_name)) { mident_suffix_p1 = mident_suffix_top + 1; /* Break out of both loops */ break; } } } if (mident_suffix_p1 == mident_suffix_top) { /* Phase 3: Punt */ assert(WBTEST_HELPOUT_TRIGNAMEUNIQ == gtm_white_box_test_case_number); rts_error(VARLSTCNT(5) ERR_TRIGNAMEUNIQ, 3, trigdsc->rtn_desc.rt_name.len - 2, trigdsc->rtn_desc.rt_name.addr, alphnum_len * alphnum_len); } } } /* Write trigger execute string out to temporary file and compile it */ assert(MAX_XECUTE_LEN >= trigdsc->xecute_str.str.len); rc = SNPRINTF(rtnname_template, GTM_PATH_MAX, "%s/trgtmpXXXXXX", DEFAULT_GTM_TMP); assert(0 < rc); /* Note rc is return code aka length - we expect a non-zero length */ assert(GTM_PATH_MAX >= rc); /* The mkstemp() routine is known to bogus-fail for no apparent reason at all especially on AIX 6.1. In the event * this shortcoming plagues other platforms as well, we add a low-cost retry wrapper. */ retry = MAX_MKSTEMP_RETRIES; do { strcpy(rtnname, rtnname_template); rtnfd = mkstemp(rtnname); } while ((-1 == rtnfd) && (EEXIST == errno) && (0 < --retry)); if (-1 == rtnfd) { save_errno = errno; assert(FALSE); rts_error(VARLSTCNT(12) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("mkstemp()"), CALLFROM, ERR_TEXT, 2, RTS_ERROR_TEXT(rtnname), save_errno); } assert(0 < rtnfd); /* Verify file descriptor */ rc = 0; # ifdef GEN_TRIGCOMPFAIL_ERROR { /* Used ONLY to generate an error in a trigger compile by adding some junk in a previous line */ DOWRITERC(rtnfd, ERROR_CAUSING_JUNK, strlen(ERROR_CAUSING_JUNK), rc); /* BYPASSOK */ if (0 != rc) { UNLINK(rtnname); rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc); } } # endif DOWRITERC(rtnfd, trigdsc->xecute_str.str.addr, trigdsc->xecute_str.str.len, rc); if (0 != rc) { UNLINK(rtnname); rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc); } if (NULL == memchr(trigdsc->xecute_str.str.addr, '\n', trigdsc->xecute_str.str.len)) { DOWRITERC(rtnfd, NEWLINE, strlen(NEWLINE), rc); /* BYPASSOK */ if (0 != rc) { UNLINK(rtnname); rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("write()"), CALLFROM, rc); } } CLOSEFILE(rtnfd, rc); if (0 != rc) { UNLINK(rtnname); rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("close()"), CALLFROM, rc); } assert(MAX_MIDENT_LEN > trigdsc->rtn_desc.rt_name.len); zcomp_parms_ptr = zcomp_parms; lenrtnname = STRLEN(rtnname); MEMCPY_LIT(zcomp_parms_ptr, NAMEOFRTN_PARM); zcomp_parms_ptr += STRLEN(NAMEOFRTN_PARM); memcpy(zcomp_parms_ptr, trigdsc->rtn_desc.rt_name.addr, trigdsc->rtn_desc.rt_name.len); zcomp_parms_ptr += trigdsc->rtn_desc.rt_name.len; MEMCPY_LIT(zcomp_parms_ptr, OBJECT_PARM); zcomp_parms_ptr += STRLEN(OBJECT_PARM); strcpy(objname, rtnname); /* Make copy of rtnname to become object name */ strcat(objname, OBJECT_FTYPE); /* Turn into object file reference */ lenobjname = lenrtnname + STRLEN(OBJECT_FTYPE); memcpy(zcomp_parms_ptr, objname, lenobjname); zcomp_parms_ptr += lenobjname; *zcomp_parms_ptr++ = ' '; memcpy(zcomp_parms_ptr, rtnname, lenrtnname); zcomp_parms_ptr += lenrtnname; *zcomp_parms_ptr = '\0'; /* Null tail */ len = INTCAST(zcomp_parms_ptr - zcomp_parms); assert((SIZEOF(zcomp_parms) - 1) > len); /* Verify no overflow */ zcompprm.mvtype = MV_STR; zcompprm.str.addr = zcomp_parms; zcompprm.str.len = len; /* Backup dollar_zsource so trigger doesn't show */ PUSH_MV_STENT(MVST_MSAV); mv_chain->mv_st_cont.mvs_msav.v = dollar_zsource; mv_chain->mv_st_cont.mvs_msav.addr = &dollar_zsource; TREF(trigger_compile) = TRUE; /* Set flag so compiler knows this is a special trigger compile */ op_zcompile(&zcompprm, FALSE); /* Compile but don't require a .m file extension */ TREF(trigger_compile) = FALSE; /* compile_source_file() establishes handler so always returns */ if (0 != TREF(dollar_zcstatus)) { /* Someone err'd.. */ run_time = gtm_trigger_comp_prev_run_time; REVERT; UNLINK(objname); /* Remove files before return error */ UNLINK(rtnname); return ERR_TRIGCOMPFAIL; } if (dolink) { /* Link is optional as MUPIP TRIGGER doesn't need link */ zlfile.mvtype = MV_STR; zlfile.str.addr = objname; zlfile.str.len = lenobjname; /* Specifying literal_null for a second arg (as opposed to NULL or 0) allows us to specify * linking the object file (no compilation or looking for source). The 2nd arg is parms for * recompilation and is non-null in an explicit zlink which we need to emulate. */ # ifdef GEN_TRIGLINKFAIL_ERROR UNLINK(objname); /* delete object before it can be used */ # endif op_zlink(&zlfile, (mval *)&literal_null); /* need cast due to "extern const" attributes */ /* No return here if link fails for some reason */ trigdsc->rtn_desc.rt_adr = find_rtn_hdr(&trigdsc->rtn_desc.rt_name); if (NULL == trigdsc->rtn_desc.rt_adr) GTMASSERT; /* Can't find routine we just put there? Catastrophic if happens */ /* Replace the randomly generated source name with the constant "GTM Trigger" */ trigdsc->rtn_desc.rt_adr->src_full_name.addr = GTM_TRIGGER_SOURCE_NAME; trigdsc->rtn_desc.rt_adr->src_full_name.len = STRLEN(GTM_TRIGGER_SOURCE_NAME); trigdsc->rtn_desc.rt_adr->trigr_handle = trigdsc; /* Back pointer to trig def */ } if (MVST_MSAV == mv_chain->mv_st_type && &dollar_zsource == mv_chain->mv_st_cont.mvs_msav.addr) { /* Top mv_stent is one we pushed on there - restore dollar_zsource and get rid of it */ dollar_zsource = mv_chain->mv_st_cont.mvs_msav.v; POP_MV_STENT(); } else assert(FALSE); /* This mv_stent should be the one we just pushed */ /* Remove temporary files created */ UNLINK(objname); /* Delete the object file first since rtnname is the unique key */ UNLINK(rtnname); /* Delete the source file */ run_time = gtm_trigger_comp_prev_run_time; REVERT; return 0; }
void open_list_file(void) { char charspace; uint4 status; unsigned char list_name[MAX_MIDENT_LEN + STR_LIT_LEN(LISTEXT)], fname[255]; struct FAB fab; struct NAM nam; #ifdef __ALPHA # pragma member_alignment save # pragma nomember_alignment #endif static readonly struct{ unsigned char newversion; unsigned char wrap; unsigned char width; int4 v_width; unsigned char eol; }open_params_list = { (unsigned char)iop_newversion, (unsigned char)iop_wrap, (unsigned char)iop_recordsize, (int4)132, (unsigned char)iop_eol }; #ifdef __ALPHA # pragma member_alignment restore #endif mval params; mval file; struct dsc$descriptor_s print_time_d = { SIZEOF(print_time_buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, print_time_buf }; lst_param.list_line = 1; lst_param.page = 0; fab = cc$rms_fab; nam = cc$rms_nam; fab.fab$l_dna = &list_name[0]; assert(module_name.len <= MAX_MIDENT_LEN); fab.fab$b_dns = module_name.len; memcpy(&list_name[0], module_name.addr, fab.fab$b_dns); MEMCPY_LIT(&list_name[fab.fab$b_dns], LISTEXT); fab.fab$b_dns += STR_LIT_LEN(LISTEXT); if (MV_DEFINED(&cmd_qlf.list_file)) { fab.fab$b_fns = cmd_qlf.list_file.str.len; fab.fab$l_fna = cmd_qlf.list_file.str.addr; } nam.nam$l_esa = &fname[0]; nam.nam$b_ess = SIZEOF(fname); nam.nam$b_nop = (NAM$M_SYNCHK); fab.fab$l_nam = &nam; fab.fab$l_fop = FAB$M_NAM; if ((status = sys$parse(&fab,0,0)) != RMS$_NORMAL) { rts_error(VARLSTCNT(1) status); } file.mvtype = params.mvtype = MV_STR; file.str.len = nam.nam$b_esl; file.str.addr = &fname[0]; params.str.len = SIZEOF(open_params_list); params.str.addr = &open_params_list; (*op_open_ptr)(&file, ¶ms, 30, 0); params.str.len = 1; charspace = (char) iop_eol; params.str.addr = &charspace; dev_in_use = io_curr_device; op_use(&file,¶ms); lib$date_time(&print_time_d); list_head(0); return; }
STATICFNDEF boolean_t process_delim(char *delim_str, uint4 *delim_len) { int char_count; mstr dst; int dst_len; char *dst_ptr; char dst_string[MAX_DELIM_LEN + 1]; uint4 len; char *ptr; char *ptr1; int q_len; char src_string[MAX_DELIM_LEN + 1]; mstr src; char *src_ptr; if (MAX_DELIM_LEN < *delim_len) { util_out_print_gtmio("Delimiter too long", FLUSH); return FALSE; } ptr = delim_str; len = *delim_len; src_ptr = src_string; dst_len = 0; /* If ", scan to end quote * If $, look for char --> c or zchar --> zch * If _, leave it */ while (0 < len) { switch (*ptr) { case '"': PROCESS_STRING(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN); break; case '$': UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN); if (0 == len) { util_out_print_gtmio("Invalid entry in delimiter", FLUSH); return FALSE; } if ((3 < len) && ('C' == lower_to_upper_table[*ptr]) && ('H' == lower_to_upper_table[*(ptr + 1)]) && ('A' == lower_to_upper_table[*(ptr + 2)]) && ('R' == lower_to_upper_table[*(ptr + 3)])) { if (MAX_DELIM_LEN < ++dst_len) { util_out_print_gtmio("Trigger definition too long", FLUSH); return FALSE; } *src_ptr++ = 'C'; ptr += 4; len -= 4; } else if ((4 < len) && ('Z' == lower_to_upper_table[*ptr]) && ('C' == lower_to_upper_table[*(ptr + 1)]) && ('H' == lower_to_upper_table[*(ptr + 2)]) && ('A' == lower_to_upper_table[*(ptr + 3)]) && ('R' == lower_to_upper_table[*(ptr + 4)])) { if (MAX_DELIM_LEN < (dst_len + 3)) { util_out_print_gtmio("Trigger definition too long", FLUSH); return FALSE; } MEMCPY_LIT(src_ptr, "ZCH"); src_ptr += 3; dst_len += 3; ptr += 5; len -= 5; } else { UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN); } break; default: UPDATE_DST(ptr, len, FALSE, src_ptr, dst_len, MAX_DELIM_LEN); break; } } *src_ptr = '\0'; src.addr = src_string; src.len = (mstr_len_t)(src_ptr - src_string); dst.addr = dst_string; dst.len = 0; if (!zwr2format(&src, &dst)) { util_out_print_gtmio("Invalid delimiter", FLUSH); return FALSE; } if (MAX_DELIM_LEN < dst.len) { util_out_print_gtmio("Delimiter too long", FLUSH); return FALSE; } memcpy(delim_str, dst_string, dst.len); *delim_len = dst.len; return TRUE; }
void mucregini(int4 blk_init_size) { int4 status; int4 i; th_index_ptr_t th; collseq *csp; uint4 ustatus; mstr jnlfile, jnldef, tmpjnlfile; time_t ctime; MEMCPY_LIT(cs_data->label, GDS_LABEL); cs_data->desired_db_format = GDSVCURR; cs_data->fully_upgraded = TRUE; cs_data->db_got_to_v5_once = TRUE; /* no V4 format blocks that are non-upgradeable */ cs_data->minor_dbver = GDSMVCURR; cs_data->certified_for_upgrade_to = GDSVCURR; cs_data->creation_db_ver = GDSVCURR; cs_data->creation_mdb_ver = GDSMVCURR; cs_data->master_map_len = MASTER_MAP_SIZE_DFLT; cs_data->bplmap = BLKS_PER_LMAP; assert(BLK_SIZE <= MAX_DB_BLK_SIZE); cs_data->blk_size = BLK_SIZE; i = cs_data->trans_hist.total_blks; cs_data->trans_hist.free_blocks = i - DIVIDE_ROUND_UP(i, BLKS_PER_LMAP) - 2; cs_data->max_rec_size = gv_cur_region->max_rec_size; cs_data->max_key_size = gv_cur_region->max_key_size; cs_data->null_subs = gv_cur_region->null_subs; cs_data->std_null_coll = gv_cur_region->std_null_coll; #ifdef UNIX cs_data->freeze_on_fail = gv_cur_region->freeze_on_fail; cs_data->mumps_can_bypass = gv_cur_region->mumps_can_bypass; #endif cs_data->reserved_bytes = gv_cur_region->dyn.addr->reserved_bytes; cs_data->clustered = FALSE; cs_data->file_corrupt = 0; if (gv_cur_region->dyn.addr->lock_space) cs_data->lock_space_size = gv_cur_region->dyn.addr->lock_space * OS_PAGELET_SIZE; else cs_data->lock_space_size = DEF_LOCK_SIZE; cs_data->staleness[0] = -300000000; /* staleness timer = 30 seconds */ cs_data->staleness[1] = -1; cs_data->ccp_quantum_interval[0] = -20000000; /* 2 sec */ cs_data->ccp_quantum_interval[1] = -1; cs_data->ccp_response_interval[0] = -600000000; /* 1 min */ cs_data->ccp_response_interval[1] = -1; cs_data->ccp_tick_interval[0] = -1000000; /* 1/10 sec */ cs_data->ccp_tick_interval[1] = -1; cs_data->last_com_backup = 1; cs_data->last_inc_backup = 1; cs_data->last_rec_backup = 1; cs_data->defer_time = gv_cur_region->dyn.addr->defer_time; cs_data->jnl_alq = gv_cur_region->jnl_alq; if (cs_data->jnl_state && !cs_data->jnl_alq) cs_data->jnl_alq = JNL_ALLOC_DEF; cs_data->jnl_deq = gv_cur_region->jnl_deq; cs_data->jnl_before_image = gv_cur_region->jnl_before_image; cs_data->jnl_state = gv_cur_region->jnl_state; cs_data->epoch_interval = JNL_ALLOWED(cs_data) ? DEFAULT_EPOCH_INTERVAL : 0; cs_data->alignsize = JNL_ALLOWED(cs_data) ? (DISK_BLOCK_SIZE * JNL_DEF_ALIGNSIZE) : 0; ROUND_UP_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, gv_cur_region->jnl_buffer_size, cs_data); #ifdef UNIX if (JNL_ALLOWED(cs_data)) { if (cs_data->jnl_alq + cs_data->jnl_deq > gv_cur_region->jnl_autoswitchlimit) { cs_data->autoswitchlimit = gv_cur_region->jnl_autoswitchlimit; cs_data->jnl_alq = cs_data->autoswitchlimit; } else cs_data->autoswitchlimit = ALIGNED_ROUND_DOWN(gv_cur_region->jnl_autoswitchlimit, cs_data->jnl_alq, cs_data->jnl_deq); } else cs_data->autoswitchlimit = 0; assert(!(MAX_IO_BLOCK_SIZE % DISK_BLOCK_SIZE)); if (cs_data->jnl_alq + cs_data->jnl_deq > cs_data->autoswitchlimit) cs_data->jnl_alq = cs_data->autoswitchlimit; #else cs_data->autoswitchlimit = JNL_ALLOWED(cs_data) ? ALIGNED_ROUND_DOWN(JNL_ALLOC_MAX, cs_data->jnl_alq, cs_data->jnl_deq) : 0; #endif if (!cs_data->jnl_buffer_size) ROUND_UP_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, JNL_BUFFER_DEF, cs_data); if (JNL_ALLOWED(cs_data)) if (cs_data->jnl_buffer_size < JNL_BUFF_PORT_MIN(cs_data)) { ROUND_UP_MIN_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, cs_data); } else if (cs_data->jnl_buffer_size > JNL_BUFFER_MAX) { ROUND_DOWN_MAX_JNL_BUFF_SIZE(cs_data->jnl_buffer_size, cs_data); } cs_data->def_coll = gv_cur_region->def_coll; if (cs_data->def_coll) { if (csp = ready_collseq((int)(cs_data->def_coll))) { cs_data->def_coll_ver = (csp->version)(cs_data->def_coll); if (!do_verify(csp, cs_data->def_coll, cs_data->def_coll_ver)) { gtm_putmsg(VARLSTCNT(4) ERR_COLLTYPVERSION, 2, cs_data->def_coll, cs_data->def_coll_ver); mupip_exit(ERR_MUNOACTION); } } else { gtm_putmsg(VARLSTCNT(3) ERR_COLLATIONUNDEF, 1, cs_data->def_coll); mupip_exit(ERR_MUNOACTION); } } /* mupip_set_journal() relies on cs_data->jnl_file_len being 0 if cs_data->jnl_state is jnl_notallowed. * Note that even though gv_cur_region->jnl_state is jnl_notallowed, gv_cur_region->jnl_file_len can be non-zero */ cs_data->jnl_file_len = JNL_ALLOWED(cs_data) ? gv_cur_region->jnl_file_len : 0; cs_data->reg_seqno = 1; VMS_ONLY( cs_data->resync_seqno = 1; cs_data->old_resync_seqno = 1; cs_data->resync_tn = 1; )
void gtm_getmsg (int4 msgnum, mstr *msgbuf) { short int m_len, faclen, taglen, j, sever; char *cp; const char *top, *msgp, *fac; char outbuf[32]; char_ptr_t tag; const err_msg *msg; const err_ctl *ctl; ctl = err_check(msgnum); if (ctl != 0) { assert((msgnum & FACMASK(ctl->facnum)) && (MSGMASK(msgnum, ctl->facnum) <= ctl->msg_cnt)); j = MSGMASK(msgnum, ctl->facnum); msg = ctl->fst_msg + j - 1; msgp = msg->msg; tag = (char_ptr_t)msg->tag; fac = ctl->facname; sever = SEVMASK(msgnum); } else { sever = ERROR; tag = (char_ptr_t)outbuf; if ((MAX_SYSERR > msgnum) && (msgnum > 0)) { assert(NULL != STRERROR(1)); /* OSF/1 check; can happen with 64-bit pointers and bad declaration */ cp = (char *)tag; MEMCPY_LIT(cp, ERR_TAG); cp += strlen(ERR_TAG); cp = (char *)i2asc((uchar_ptr_t)cp, msgnum); *cp = '\0'; msgp = STRERROR(msgnum); } else { tag = "UNKNOWN"; msgp = "Unknown system error !SL"; } fac = "SYSTEM"; } m_len = strlen(msgp); if (!dec_nofac) { m_len += (faclen = strlen(fac)); m_len += 4; /* %-<sev>- */ m_len += (taglen = strlen((const char *)tag)); m_len += 2; /* , */ } m_len = m_len > msgbuf->len - 1 ? msgbuf->len - 1 : m_len; cp = msgbuf->addr; top = cp + m_len; if (!dec_nofac) { if (cp < top) *cp++ = '%'; j = faclen > top-cp ? top-cp : faclen; if (j) { memcpy(cp, fac, j); cp += j; } if (cp < top) *cp++ = '-'; if (cp < top) { switch(sever) { case SUCCESS: *cp++ = 'S'; break; case INFO: *cp++ = 'I'; break; case WARNING: *cp++ = 'W'; break; case ERROR: *cp++ = 'E'; break; case SEVERE: *cp++ = 'F'; break; default: *cp++ = 'U'; break; } } if (cp < top) *cp++ = '-'; j = taglen > top-cp ? top-cp : taglen; if (j) { memcpy(cp, tag, j); cp += j; } if (cp < top) *cp++ = ','; if (cp < top) *cp++ = ' '; } memcpy(cp, msgp, top - cp); cp += top - cp; msgbuf->len = m_len; *cp++ = 0; }
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; }
gtcm_server() { static readonly int4 reptim[2] = {-100000, -1}; /* 10ms */ static readonly int4 wait[2] = {-1000000, -1}; /* 100ms */ void gtcm_ch(), gtcm_exi_handler(), gtcm_init_ast(), gtcm_int_unpack(), gtcm_mbxread_ast(), gtcm_neterr(), gtcm_read_ast(), gtcm_remove_from_action_queue(), gtcm_shutdown_ast(), gtcm_write_ast(), la_freedb(); bool gtcm_link_accept(); bool alid; char buff[512]; char *h = NULL; char *la_getdb(); char nbuff[256]; char *pak = NULL; char reply; unsigned short outlen; int4 closewait[2] = {0, -1}; int4 inid = 0, mdl = 0, nid = 0, days = 0; int4 lic_status; int4 lic_x; int4 lm_mdl_nid(); uint4 status; int i, receive(), value; mstr name1, name2; struct NTD *cmu_ntdroot(); connection_struct *prev_curr_entry; struct dsc$descriptor_s dprd; struct dsc$descriptor_s dver; $DESCRIPTOR(node_name, nbuff); $DESCRIPTOR(proc_name, "GTCM_SERVER"); $DESCRIPTOR(timout, buff); DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; assert(0 == EMPTY_QUEUE); /* check so dont need gdsfhead everywhere */ common_startup_init(GTCM_GNP_SERVER_IMAGE); /* Side-effect: Sets skip_dbtriggers to TRUE for non-trigger platforms */ gtm_env_init(); /* read in all environment variables */ name1.addr = "GTCMSVRNAM"; name1.len = SIZEOF("GTCMSVRNAM") - 1; status = trans_log_name(&name1, &name2, nbuff); if (SS$_NORMAL == status) { proc_name.dsc$a_pointer = nbuff; proc_name.dsc$w_length = node_name.dsc$w_length = name2.len; } else if (SS$_NOLOGNAM == status) { MEMCPY_LIT(nbuff, "GTCMSVR"); node_name.dsc$w_length = SIZEOF("GTCMSVR") - 1; } else rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); sys$setprn(&proc_name); status = lib$get_foreign(&timout, 0, &outlen, 0); if ((status & 1) && (6 > outlen)) { for (i = 0; i < outlen; i++) { value = value * 10; if (buff[i] <= '9' && buff[i] >= '0') value += buff[i] - 48; else break; } if (outlen && (i == outlen)) { cm_timeout = TRUE; closewait[0] = value * -10000000; } } dprd.dsc$w_length = cm_prd_len; dprd.dsc$b_dtype = DSC$K_DTYPE_T; dprd.dsc$b_class = DSC$K_CLASS_S; dprd.dsc$a_pointer= cm_prd_name; dver.dsc$w_length = cm_ver_len; dver.dsc$b_dtype = DSC$K_DTYPE_T; dver.dsc$b_class = DSC$K_CLASS_S; dver.dsc$a_pointer= cm_ver_name; ast_init(); licensed = TRUE; lkid = 2; # ifdef NOLICENSE lid = 1; # else /* this code used to be scattered to discourage reverse engineering, but since it now disabled, that seems pointless */ lic_status = ((NULL == (h = la_getdb(LMDB))) ? LP_NOCNFDB : SS$_NORMAL); lic_status = ((1 == (lic_status & 1)) ? lm_mdl_nid(&mdl, &nid, &inid) : lic_status); lic_status = ((1 == (lic_status & 1)) ? lp_licensed(h, &dprd, &dver, mdl, nid, &lid, &lic_x, &days, pak) : lic_status); if (LP_NOCNFDB != lic_status) la_freedb(h); if (1 == (lic_status & 1)) { licensed = TRUE; if (days < 14) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WILLEXPIRE); } else { licensed = FALSE; sys$exit(lic_status); } # endif gtcm_ast_avail = astq_dyn_avail - GTCM_AST_OVRHD; stp_init(STP_INITSIZE); rts_stringpool = stringpool; cache_init(); procnum = 0; get_proc_info(0, TADR(login_time), &image_count); memset(proc_to_clb, 0, SIZEOF(proc_to_clb)); status = cmi_init(&node_name, 0, 0, gtcm_init_ast, gtcm_link_accept); if (!(status & 1)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ((status ^ 3) | 4)); sys$exit(status); } ntd_root = cmu_ntdroot(); ntd_root->mbx_ast = gtcm_mbxread_ast; ntd_root->err = gtcm_neterr; gtcm_connection = FALSE; lib$establish(gtcm_ch); gtcm_exi_blk.exit_hand = >cm_exi_handler; gtcm_exi_blk.arg_cnt = 1; gtcm_exi_blk.cond_val = >cm_exi_condition; sys$dclexh(>cm_exi_blk); INVOKE_INIT_SECSHR_ADDRS; initialize_pattern_table(); assert(run_time); /* Should have been set by common_startup_init */ while (!cm_shutdown) { if (blkdlist) gtcml_chkreg(); assert(!lib$ast_in_prog()); status = sys$dclast(>cm_remove_from_action_queue, 0, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) CMERR_CMSYSSRV, 0, status, 0); if (INTERLOCK_FAIL == curr_entry) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) CMERR_CMINTQUE); if (EMPTY_QUEUE != curr_entry) { switch (*curr_entry->clb_ptr->mbf) { case CMMS_L_LKCANALL: reply = gtcmtr_lkcanall(); break; case CMMS_L_LKCANCEL: reply = gtcmtr_lkcancel(); break; case CMMS_L_LKREQIMMED: reply = gtcmtr_lkreqimmed(); break; case CMMS_L_LKREQNODE: reply = gtcmtr_lkreqnode(); break; case CMMS_L_LKREQUEST: reply = gtcmtr_lkrequest(); break; case CMMS_L_LKRESUME: reply = gtcmtr_lkresume(); break; case CMMS_L_LKACQUIRE: reply = gtcmtr_lkacquire(); break; case CMMS_L_LKSUSPEND: reply = gtcmtr_lksuspend(); break; case CMMS_L_LKDELETE: reply = gtcmtr_lkdelete(); break; case CMMS_Q_DATA: reply = gtcmtr_data(); break; case CMMS_Q_GET: reply = gtcmtr_get(); break; case CMMS_Q_KILL: reply = gtcmtr_kill(); break; case CMMS_Q_ORDER: reply = gtcmtr_order(); break; case CMMS_Q_PREV: reply = gtcmtr_zprevious(); break; case CMMS_Q_PUT: reply = gtcmtr_put(); break; case CMMS_Q_QUERY: reply = gtcmtr_query(); break; case CMMS_Q_ZWITHDRAW: reply = gtcmtr_zwithdraw(); break; case CMMS_S_INITPROC: reply = gtcmtr_initproc(); break; case CMMS_S_INITREG: reply = gtcmtr_initreg(); break; case CMMS_S_TERMINATE: reply = gtcmtr_terminate(TRUE); break; case CMMS_E_TERMINATE: reply = gtcmtr_terminate(FALSE); break; case CMMS_U_LKEDELETE: reply = gtcmtr_lke_clearrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_U_LKESHOW: reply = gtcmtr_lke_showrep(curr_entry->clb_ptr, curr_entry->clb_ptr->mbf); break; case CMMS_B_BUFRESIZE: reply = CM_WRITE; value = *(unsigned short *)(curr_entry->clb_ptr->mbf + 1); if (value > curr_entry->clb_ptr->mbl) { free(curr_entry->clb_ptr->mbf); curr_entry->clb_ptr->mbf = malloc(value); } *curr_entry->clb_ptr->mbf = CMMS_C_BUFRESIZE; curr_entry->clb_ptr->mbl = value; curr_entry->clb_ptr->cbl = 1; break; case CMMS_B_BUFFLUSH: reply = gtcmtr_bufflush(); break; case CMMS_Q_INCREMENT: reply = gtcmtr_increment(); break; default: reply = FALSE; if (SS$_NORMAL == status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(3) ERR_BADGTMNETMSG, 1, (int)*curr_entry->clb_ptr->mbf); break; } if (curr_entry) /* curr_entry can be NULL if went through gtcmtr_terminate */ { status = sys$gettim(&curr_entry->lastact[0]); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); /* curr_entry is used by gtcm_mbxread_ast to determine if it needs to defer the interrupt message */ prev_curr_entry = curr_entry; if (CM_WRITE == reply) { /* if ast == gtcm_write_ast, let it worry */ curr_entry->clb_ptr->ast = gtcm_write_ast; curr_entry = EMPTY_QUEUE; cmi_write(prev_curr_entry->clb_ptr); } else { curr_entry = EMPTY_QUEUE; if (1 == (prev_curr_entry->int_cancel.laflag & 1)) { /* valid interrupt cancel msg, handle in gtcm_mbxread_ast */ status = sys$dclast(gtcm_int_unpack, prev_curr_entry, 0); if (SS$_NORMAL != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); } else if (CM_READ == reply) { prev_curr_entry->clb_ptr->ast = gtcm_read_ast; cmi_read(prev_curr_entry->clb_ptr); } } } } else if (1 < astq_dyn_avail) { # ifdef GTCM_REPTIM /* if reptim is not needed - and smw doesn't know why it would be - remove this */ status = sys$schdwk(0, 0, &wait[0], &reptim[0]); # else status = sys$schdwk(0, 0, &wait[0], 0); # endif sys$hiber(); sys$canwak(0, 0); } if (cm_timeout && (0 == gtcm_users)) sys$setimr(efn_ignore, closewait, gtcm_shutdown_ast, &cm_shutdown, 0); } }
/* Update header from v4.x to v5.0-000 */ void mu_upgrd_header(v15_sgmnt_data *v15_csd, sgmnt_data *csd) { time_t ctime; seq_num v15_reg_seqno; error_def(ERR_MUINFOUINT8); memset(csd, 0, SIZEOF(sgmnt_data)); MEMCPY_LIT(csd->label, GDS_LABEL); csd->blk_size = v15_csd->blk_size; csd->bplmap = v15_csd->bplmap; csd->start_vbn = v15_csd->start_vbn; csd->acc_meth = v15_csd->acc_meth; csd->max_bts = v15_csd->max_bts; csd->n_bts = v15_csd->n_bts; csd->bt_buckets = v15_csd->bt_buckets; if (v15_csd->reserved_bytes > BLK_HDR_INCREASE) csd->reserved_bytes = v15_csd->reserved_bytes - BLK_HDR_INCREASE; csd->max_rec_size = v15_csd->max_rec_size; csd->max_key_size = v15_csd->max_key_size; csd->lock_space_size = v15_csd->lock_space_size; csd->extension_size = v15_csd->extension_size; csd->def_coll = v15_csd->def_coll; csd->def_coll_ver = v15_csd->def_coll_ver; csd->std_null_coll = v15_csd->std_null_coll; /* New in V5.0-FT01 */ csd->null_subs = v15_csd->null_subs; csd->free_space = v15_csd->free_space; csd->mutex_spin_parms.mutex_hard_spin_count = v15_csd->mutex_spin_parms.mutex_hard_spin_count; csd->mutex_spin_parms.mutex_sleep_spin_count = v15_csd->mutex_spin_parms.mutex_sleep_spin_count; csd->mutex_spin_parms.mutex_spin_sleep_mask = v15_csd->mutex_spin_parms.mutex_spin_sleep_mask; csd->max_update_array_size = v15_csd->max_update_array_size; /* New from V4.0-001G */ csd->max_non_bm_update_array_size = v15_csd->max_non_bm_update_array_size; /* New from V4.0-001G */ csd->file_corrupt = v15_csd->file_corrupt; csd->minor_dbver = GDSMVCURR; /* New in V5.0-000 */ csd->wcs_phase2_commit_wait_spincnt = WCS_PHASE2_COMMIT_DEFAULT_SPINCNT; /* New from V5.3-002 */ csd->createinprogress = v15_csd->createinprogress; time(&ctime); assert(SIZEOF(ctime) >= SIZEOF(int4)); csd->creation_time4 = (int4)ctime;/* No need to propagate previous value. Take only lower order 4-bytes of current time */ csd->last_inc_backup = v15_csd->last_inc_backup; csd->last_com_backup = v15_csd->last_com_backup; csd->last_rec_backup = v15_csd->last_rec_backup; csd->reorg_restart_block = v15_csd->reorg_restart_block; /* New from V4.2 */ memcpy(csd->now_running, gtm_release_name, gtm_release_name_len + 1); /* GT.M release name */ csd->owner_node = v15_csd->owner_node; csd->image_count = v15_csd->image_count; csd->kill_in_prog = 0; csd->abandoned_kills = v15_csd->kill_in_prog; /* assert to 0 ??? */ csd->blks_to_upgrd = v15_csd->trans_hist.total_blks - v15_csd->trans_hist.free_blocks; /* New in V5.0-000 */ assert(csd->blks_to_upgrd); csd->tn_upgrd_blks_0 = 0; /* New in V5.0-000 */ csd->fully_upgraded = FALSE; /* New in V5.0-000 */ csd->desired_db_format = GDSVCURR; /* New in V5.0-000 */ csd->desired_db_format_tn = v15_csd->trans_hist.curr_tn - 1; /* New in V5.0-000 */ csd->reorg_db_fmt_start_tn = 0; /* New in V5.0-000 */ csd->certified_for_upgrade_to = v15_csd->certified_for_upgrade_to; /* New in V5.0-000 */ csd->master_map_len = MASTER_MAP_SIZE_V4; /* New in V5.0-000 */ csd->reorg_upgrd_dwngrd_restart_block = 0; /* New in V5.0-000 */ csd->creation_db_ver = v15_csd->creation_db_ver; /* Retain creation major/minor version */ csd->creation_mdb_ver = v15_csd->creation_mdb_ver; csd->trans_hist.early_tn = v15_csd->trans_hist.early_tn; csd->trans_hist.curr_tn = v15_csd->trans_hist.curr_tn; /* INCREMENT_CURR_TN comment added to note curr_tn set is done */ csd->max_tn = MAX_TN_V5; /* New in V5.0-000 */ SET_TN_WARN(csd, csd->max_tn_warn); /* New in V5.0-000 */ csd->trans_hist.last_mm_sync = v15_csd->trans_hist.last_mm_sync; csd->trans_hist.mm_tn = v15_csd->trans_hist.mm_tn; csd->trans_hist.lock_sequence = v15_csd->trans_hist.lock_sequence; csd->trans_hist.total_blks = v15_csd->trans_hist.total_blks; csd->trans_hist.free_blocks = v15_csd->trans_hist.free_blocks; csd->flush_time[0] = v15_csd->flush_time[0]; csd->flush_time[1] = v15_csd->flush_time[1]; csd->flush_trigger = v15_csd->flush_trigger; csd->n_wrt_per_flu = v15_csd->n_wrt_per_flu; csd->wait_disk_space = v15_csd->wait_disk_space; csd->defer_time = v15_csd->defer_time; #ifdef UNIX csd->semid = INVALID_SEMID; csd->shmid = INVALID_SHMID; csd->gt_sem_ctime.ctime = 0; csd->gt_shm_ctime.ctime = 0; #endif /* Note none of the counter fields are being carried over. An upgrade or downgrade will implicitly set them to zero by not initializing them. */ csd->staleness[0] = v15_csd->staleness[0]; csd->staleness[1] = v15_csd->staleness[1]; csd->ccp_tick_interval[0] = v15_csd->ccp_tick_interval[0]; csd->ccp_tick_interval[1] = v15_csd->ccp_tick_interval[1]; csd->ccp_quantum_interval[0] = v15_csd->ccp_quantum_interval[0]; csd->ccp_quantum_interval[1] = v15_csd->ccp_quantum_interval[1]; csd->ccp_response_interval[0] = v15_csd->ccp_response_interval[0]; csd->ccp_response_interval[1] = v15_csd->ccp_response_interval[1]; csd->ccp_jnl_before = v15_csd->ccp_jnl_before; csd->clustered = v15_csd->clustered; csd->unbacked_cache = v15_csd->unbacked_cache; csd->rc_srv_cnt = v15_csd->rc_srv_cnt; csd->dsid = v15_csd->dsid; csd->rc_node = v15_csd->rc_node; v15_reg_seqno = csd->reg_seqno = v15_csd->reg_seqno; csd->repl_state = v15_csd->repl_state; VMS_ONLY( csd->resync_seqno = v15_csd->resync_seqno; csd->resync_tn = v15_csd->resync_tn; csd->old_resync_seqno = v15_csd->old_resync_seqno; /* resync_seqno should never be greater the region's reg_seqno. Ensure that this is indeed the case. In PRO, * fix the fields to be at most the value of the region's reg_seqno if they are found to be greater than * reg_seqno */ assert((csd->resync_seqno <= v15_reg_seqno) && (csd->old_resync_seqno <= v15_reg_seqno)); if (csd->resync_seqno > v15_reg_seqno) csd->resync_seqno = v15_reg_seqno; if (csd->old_resync_seqno > v15_reg_seqno) csd->old_resync_seqno = v15_reg_seqno; assert(0 != csd->reg_seqno || (0 == csd->resync_seqno && 0 == csd->resync_tn && repl_closed == csd->repl_state)); assert(0 != csd->resync_seqno || (0 == csd->reg_seqno && 0 == csd->resync_tn && repl_closed == csd->repl_state)); assert(0 != csd->resync_tn || (0 == csd->reg_seqno && 0 == csd->resync_seqno && repl_closed == csd->repl_state)); if (0 == csd->reg_seqno || 0 == csd->resync_seqno || 0 == csd->resync_tn) { /* This can happen for pre-replication versions */ csd->reg_seqno = 1; csd->resync_seqno = 1; csd->resync_tn = 1; csd->old_resync_seqno = 1; csd->repl_state = repl_closed; } )
STATICFNDEF boolean_t process_dollar_char(char **src_ptr, int *src_len, boolean_t have_star, char **d_ptr, int *dst_len) { int char_count; char *char_ptr; int len; char *dst_ptr; char dst_string[MAX_DCHAR_LEN]; int lcl_dst_len; mstr m_dst; mstr m_src; char *ptr; int q_len; char *tmp_dst_ptr; tmp_dst_ptr = dst_ptr = *d_ptr; ptr = *src_ptr; len = *src_len; lcl_dst_len = *dst_len; assert('$' == *ptr); UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN); if (0 == len) return FALSE; switch (*ptr) { case 'c': case 'C': UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN); if ((0 < len) && ('(' == *ptr)) break; else if ((3 < len) && ('H' == lower_to_upper_table[*ptr]) && ('A' == lower_to_upper_table[*(ptr + 1)]) && ('R' == lower_to_upper_table[*(ptr + 2)]) && ('(' == *(ptr + 3))) { ptr += 3; len -= 3; break; } else return FALSE; break; case 'z': case 'Z': UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN); if ((2 < len) && ('C' == lower_to_upper_table[*ptr]) && ('H' == lower_to_upper_table[*(ptr + 1)]) && ('(' == *(ptr + 2))) { ptr += 2; len -= 2; } else if ((4 < len) && ('C' == lower_to_upper_table[*ptr]) && ('H' == lower_to_upper_table[*(ptr + 1)]) && ('A' == lower_to_upper_table[*(ptr + 2)]) && ('R' == lower_to_upper_table[*(ptr + 3)]) && ('(' == *(ptr + 4))) { ptr += 4; len -= 4; } else return FALSE; if (MAX_GVSUBS_LEN < lcl_dst_len + 2) { util_out_print_gtmio("Subscript too long", FLUSH); return FALSE; } MEMCPY_LIT(dst_ptr, "CH"); dst_ptr += 2; lcl_dst_len += 2; break; default: return FALSE; } assert('(' == *ptr); UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN); while ((0 < len) && (')' != *ptr)) { UPDATE_DST(ptr, len, have_star, dst_ptr, lcl_dst_len, MAX_GVSUBS_LEN); } q_len = 0; if (!have_star) { if (MAX_GVSUBS_LEN < ++lcl_dst_len) { util_out_print_gtmio("$[Z]CHAR expression too long", FLUSH); return FALSE; } *dst_ptr++ = *ptr++; *dst_ptr = '\0'; m_src.addr = tmp_dst_ptr; m_src.len = (mstr_len_t)(dst_ptr - tmp_dst_ptr); m_dst.addr = dst_string; m_dst.len = 0; if (!zwr2format(&m_src, &m_dst)) return FALSE; lcl_dst_len = *dst_len; /* Reset length because we're creating the final version now */ if (MAX_GVSUBS_LEN < ++lcl_dst_len) { util_out_print_gtmio("Subscript too long", FLUSH); return FALSE; } *tmp_dst_ptr++ = '"'; char_ptr = m_dst.addr; if (MAX_GVSUBS_LEN < (lcl_dst_len + m_dst.len)) { util_out_print_gtmio("Subscript too long", FLUSH); return FALSE; } for (char_count = 0; m_dst.len > char_count; char_count++) { if ('"' == *char_ptr) { if (MAX_GVSUBS_LEN < ++lcl_dst_len) { util_out_print_gtmio("Subscript too long", FLUSH); return FALSE; } *tmp_dst_ptr++ = '"'; q_len++; } *tmp_dst_ptr++ = *char_ptr++; lcl_dst_len++; } if (MAX_GVSUBS_LEN < ++lcl_dst_len) { util_out_print_gtmio("Subscript too long", FLUSH); return FALSE; } *tmp_dst_ptr++ = '"'; dst_ptr = tmp_dst_ptr; } else ptr++; assert(!have_star || ((dst_ptr == *d_ptr) && (lcl_dst_len == *dst_len))); *src_ptr = ptr; *src_len = len + 2 + q_len; /* Allow for the open and close quotes and any internal quotes */ *d_ptr = dst_ptr; *dst_len = lcl_dst_len; return TRUE; }
int4 mur_cre_file_extfmt(jnl_ctl_list *jctl, int recstat) { fi_type *file_info; char *ptr, rename_fn[MAX_FN_LEN]; int rename_fn_len, base_len, fn_exten_size, extrlen, tmplen; uint4 status; mval op_val, op_pars; boolean_t is_stdout; /* Output will go STDOUT? */ static readonly char *fn_exten[] = {EXT_MJF, EXT_BROKEN, EXT_LOST}; static readonly char *ext_file_type[] = {STR_JNLEXTR, STR_BRKNEXTR, STR_LOSTEXTR}; static readonly unsigned char open_params_list[]= { (unsigned char)iop_m, (unsigned char)iop_newversion, (unsigned char)iop_noreadonly, (unsigned char)iop_nowrap, (unsigned char)iop_stream, (unsigned char)iop_eol }; assert(GOOD_TN == recstat || BROKEN_TN == recstat || LOST_TN == recstat); assert(0 == GOOD_TN); assert(1 == BROKEN_TN); assert(2 == LOST_TN); assert(GOOD_TN != recstat || mur_options.extr[GOOD_TN]); /* Argument journal -extract=-stdout ? */ is_stdout = mur_options.extr_fn[recstat] && (0 == STRNCASECMP(mur_options.extr_fn[recstat], JNL_STDO_EXTR, SIZEOF(JNL_STDO_EXTR))); /* If we need to write to stdout, we can bypass file renaming stuff */ if(!is_stdout) { ptr = (char *)&jctl->jnl_fn[jctl->jnl_fn_len]; while (DOT != *ptr) /* we know journal file name alway has a DOT */ ptr--; base_len = (int)(ptr - (char *)&jctl->jnl_fn[0]); file_info = (void *)malloc(SIZEOF(fi_type)); if (0 == mur_options.extr_fn_len[recstat]) { mur_options.extr_fn[recstat] = malloc(MAX_FN_LEN); mur_options.extr_fn_len[recstat] = base_len; memcpy(mur_options.extr_fn[recstat], jctl->jnl_fn, base_len); fn_exten_size = STRLEN(fn_exten[recstat]); memcpy(mur_options.extr_fn[recstat] + base_len, fn_exten[recstat], fn_exten_size); mur_options.extr_fn_len[recstat] += fn_exten_size; } file_info->fn_len = mur_options.extr_fn_len[recstat]; file_info->fn = mur_options.extr_fn[recstat]; murgbl.file_info[recstat] = file_info; if (RENAME_FAILED == rename_file_if_exists(file_info->fn, file_info->fn_len, rename_fn, &rename_fn_len, &status)) return status; op_pars.mvtype = MV_STR; op_pars.str.len = SIZEOF(open_params_list); op_pars.str.addr = (char *)open_params_list; op_val.mvtype = MV_STR; op_val.str.len = file_info->fn_len; op_val.str.addr = (char *)file_info->fn; if ((status = (*op_open_ptr)(&op_val, &op_pars, 0, NULL)) == 0) { gtm_putmsg(VARLSTCNT(5) ERR_FILENOTCREATE, 2, file_info->fn_len, file_info->fn, errno); return ERR_FILENOTCREATE; } } /* Write file version info for the file created here. See C9B08-001729 */ if (!mur_options.detail) { MEMCPY_LIT(murgbl.extr_buff, JNL_EXTR_LABEL); extrlen = STR_LIT_LEN(JNL_EXTR_LABEL); } else { MEMCPY_LIT(murgbl.extr_buff, JNL_DET_EXTR_LABEL); extrlen = STR_LIT_LEN(JNL_DET_EXTR_LABEL); } if (LOST_TN == recstat) { if (mur_options.update) { if (mur_options.rollback) ptr = " ROLLBACK"; else ptr = " RECOVER"; } else ptr = " EXTRACT"; tmplen = STRLEN(ptr); memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen); extrlen += tmplen; if (mur_options.rollback) { if (mur_options.fetchresync_port && murgbl.was_rootprimary) ptr = " PRIMARY "; else ptr = " SECONDARY "; tmplen = STRLEN(ptr); memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen); extrlen += tmplen; assert(NULL != jnlpool.repl_inst_filehdr); ptr = (char *)&jnlpool.repl_inst_filehdr->inst_info.this_instname[0]; tmplen = STRLEN(ptr); memcpy(&murgbl.extr_buff[extrlen], ptr, tmplen); extrlen += tmplen; } } if (gtm_utf8_mode) { murgbl.extr_buff[extrlen++] = ' '; MEMCPY_LIT(&murgbl.extr_buff[extrlen], UTF8_NAME); extrlen += STR_LIT_LEN(UTF8_NAME); } murgbl.extr_buff[extrlen++] = '\\'; jnlext_write((is_stdout ? NULL : file_info), murgbl.extr_buff, extrlen); if (!is_stdout) /* We wrote to stdout so it doesn't make a sense to print a message about file creation. */ gtm_putmsg(VARLSTCNT(6) ERR_FILECREATE, 4, LEN_AND_STR(ext_file_type[recstat]), file_info->fn_len, file_info->fn); return SS_NORMAL; }
/* Downgrade header from v5.0-000 to v4.x */ void mu_dwngrd_header(sgmnt_data *csd, v15_sgmnt_data *v15_csd) { time_t temp_time; error_def(ERR_MUINFOUINT8); memset(v15_csd, 0, SIZEOF(v15_sgmnt_data)); MEMCPY_LIT(v15_csd->label, GDS_LABEL_GENERIC); MEMCPY_LIT((v15_csd->label + SIZEOF(GDS_LABEL_GENERIC) - 1), GDS_V40); v15_csd->blk_size = csd->blk_size; v15_csd->bplmap = csd->bplmap; v15_csd->start_vbn = csd->start_vbn; v15_csd->acc_meth = csd->acc_meth; v15_csd->max_bts = csd->max_bts; v15_csd->n_bts = csd->n_bts; v15_csd->bt_buckets = csd->bt_buckets; v15_csd->reserved_bytes = csd->reserved_bytes + BLK_HDR_INCREASE; v15_csd->max_rec_size = csd->max_rec_size; v15_csd->max_key_size = csd->max_key_size; v15_csd->lock_space_size = csd->lock_space_size; v15_csd->extension_size = csd->extension_size; v15_csd->def_coll = csd->def_coll; v15_csd->def_coll_ver = csd->def_coll_ver; v15_csd->std_null_coll = csd->std_null_coll; v15_csd->null_subs = csd->null_subs; v15_csd->free_space = csd->free_space; v15_csd->mutex_spin_parms.mutex_hard_spin_count = csd->mutex_spin_parms.mutex_hard_spin_count; v15_csd->mutex_spin_parms.mutex_sleep_spin_count = csd->mutex_spin_parms.mutex_sleep_spin_count; v15_csd->mutex_spin_parms.mutex_spin_sleep_mask = csd->mutex_spin_parms.mutex_spin_sleep_mask; v15_csd->max_update_array_size = csd->max_update_array_size; /* This is filler for some early V4 versions */ v15_csd->max_non_bm_update_array_size = csd->max_non_bm_update_array_size;/* This is filler for some early V4 versions */ v15_csd->file_corrupt = csd->file_corrupt; v15_csd->createinprogress = csd->createinprogress; time(&temp_time); /* No need to propagate previous value */ v15_csd->creation.date_time = (v15_time_t)temp_time; v15_csd->last_inc_backup = (v15_trans_num)csd->last_inc_backup; v15_csd->last_com_backup = (v15_trans_num)csd->last_com_backup; v15_csd->last_rec_backup = (v15_trans_num)csd->last_rec_backup; v15_csd->reorg_restart_block = csd->reorg_restart_block; memcpy(v15_csd->now_running, gtm_release_name, gtm_release_name_len + 1); /* GT.M release name */ v15_csd->owner_node = csd->owner_node; v15_csd->image_count = csd->image_count; v15_csd->kill_in_prog = (csd->kill_in_prog + csd->abandoned_kills); v15_csd->trans_hist.curr_tn = (v15_trans_num) csd->trans_hist.curr_tn; v15_csd->trans_hist.early_tn = (v15_trans_num) csd->trans_hist.early_tn; v15_csd->trans_hist.last_mm_sync = (v15_trans_num) csd->trans_hist.last_mm_sync; v15_csd->trans_hist.header_open_tn = (v15_trans_num) csd->trans_hist.curr_tn; v15_csd->trans_hist.mm_tn = (v15_trans_num) csd->trans_hist.mm_tn; v15_csd->trans_hist.lock_sequence = csd->trans_hist.lock_sequence; v15_csd->trans_hist.total_blks = csd->trans_hist.total_blks; v15_csd->trans_hist.free_blocks = csd->trans_hist.free_blocks; v15_csd->flush_time[0] = csd->flush_time[0]; v15_csd->flush_time[1] = csd->flush_time[1]; v15_csd->flush_trigger = csd->flush_trigger; v15_csd->n_wrt_per_flu = csd->n_wrt_per_flu; v15_csd->wait_disk_space = csd->wait_disk_space; v15_csd->defer_time = csd->defer_time; #ifdef UNIX v15_csd->semid = INVALID_SEMID; v15_csd->shmid = INVALID_SHMID; v15_csd->gt_sem_ctime.ctime = 0; v15_csd->gt_shm_ctime.ctime = 0; #endif /* Note none of the counter fields are being carried over. An upgrade or downgrade will implicitly set them to zero by not initializing them. */ v15_csd->staleness[0] = csd->staleness[0]; v15_csd->staleness[1] = csd->staleness[1]; v15_csd->ccp_tick_interval[0] = csd->ccp_tick_interval[0]; v15_csd->ccp_tick_interval[1] = csd->ccp_tick_interval[1]; v15_csd->ccp_quantum_interval[0] = csd->ccp_quantum_interval[0]; v15_csd->ccp_quantum_interval[1] = csd->ccp_quantum_interval[1]; v15_csd->ccp_response_interval[0] = csd->ccp_response_interval[0]; v15_csd->ccp_response_interval[1] = csd->ccp_response_interval[1]; v15_csd->ccp_jnl_before = csd->ccp_jnl_before; v15_csd->clustered = csd->clustered; v15_csd->unbacked_cache = csd->unbacked_cache; v15_csd->rc_srv_cnt = csd->rc_srv_cnt; v15_csd->dsid = csd->dsid; v15_csd->rc_node = csd->rc_node; v15_csd->reg_seqno = csd->reg_seqno; VMS_ONLY( v15_csd->resync_seqno = csd->resync_seqno; v15_csd->old_resync_seqno = csd->old_resync_seqno; v15_csd->resync_tn = csd->resync_tn; )
void mu_extract(void) { int stat_res, truncate_res; int reg_max_rec, reg_max_key, reg_max_blk, reg_std_null_coll; int iter, format, local_errno, int_nlen; boolean_t freeze = FALSE, logqualifier, success; char format_buffer[FORMAT_STR_MAX_SIZE], ch_set_name[MAX_CHSET_NAME], cli_buff[MAX_LINE], label_buff[LABEL_STR_MAX_SIZE], gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */ glist gl_head, *gl_ptr; gd_region *reg, *region_top; mu_extr_stats global_total, grand_total; uint4 item_code, devbufsiz, maxfield; unsigned short label_len, n_len, ch_set_len, buflen; unsigned char *outbuf, *outptr, *chptr, *leadptr; struct stat statbuf; mval val, curr_gbl_name, op_val, op_pars; mstr chset_mstr; gtm_chset_t saved_out_set; static unsigned char ochset_set = FALSE; static readonly unsigned char open_params_list[] = { (unsigned char)iop_noreadonly, (unsigned char)iop_nowrap, (unsigned char)iop_stream, (unsigned char)iop_eol }; static readonly unsigned char no_param = (unsigned char)iop_eol; coll_hdr extr_collhdr; error_def(ERR_NOSELECT); error_def(ERR_GTMASSERT); error_def(ERR_EXTRACTCTRLY); error_def(ERR_EXTRACTFILERR); error_def(ERR_MUPCLIERR); error_def(ERR_MUNOACTION); error_def(ERR_MUNOFINISH); error_def(ERR_RECORDSTAT); error_def(ERR_NULLCOLLDIFF); /* Initialize all local character arrays to zero before using */ memset(cli_buff, 0, sizeof(cli_buff)); memset(outfilename, 0, sizeof(outfilename)); memset(label_buff, 0, sizeof(label_buff)); memset(format_buffer, 0, sizeof(format_buffer)); active_device = io_curr_device.out; mu_outofband_setup(); if (CLI_PRESENT == cli_present("OCHSET")) { ch_set_len = sizeof(ch_set_name); if (cli_get_str("OCHSET", ch_set_name, &ch_set_len)) { if (0 == ch_set_len) mupip_exit(ERR_MUNOACTION); /* need to change to OPCHSET error when added */ ch_set_name[ch_set_len] = '\0'; #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != active_device->output_conv_cd) ICONV_CLOSE_CD(active_device->output_conv_cd); if (DEFAULT_CODE_SET != active_device->out_code_set) ICONV_OPEN_CD(active_device->output_conv_cd, INSIDE_CH_SET, ch_set_name); #else chset_mstr.addr = ch_set_name; chset_mstr.len = ch_set_len; SET_ENCODING(active_device->ochset, &chset_mstr); get_chset_desc(&chset_names[active_device->ochset]); #endif ochset_set = TRUE; } } logqualifier = (CLI_NEGATED != cli_present("LOG")); if (CLI_PRESENT == cli_present("FREEZE")) freeze = TRUE; n_len = sizeof(format_buffer); if (FALSE == cli_get_str("FORMAT", format_buffer, &n_len)) { n_len = sizeof("ZWR") - 1; memcpy(format_buffer, "ZWR", n_len); } int_nlen = n_len; lower_to_upper((uchar_ptr_t)format_buffer, (uchar_ptr_t)format_buffer, int_nlen); if (0 == memcmp(format_buffer, "ZWR", n_len)) format = MU_FMT_ZWR; else if (0 == memcmp(format_buffer, "GO", n_len)) { if (gtm_utf8_mode) { util_out_print("Extract error: GO format is not supported in UTF-8 mode. Use ZWR format.", TRUE); mupip_exit(ERR_MUPCLIERR); } format = MU_FMT_GO; } else if (0 == memcmp(format_buffer, "BINARY", n_len)) format = MU_FMT_BINARY; else { util_out_print("Extract error: bad format type", TRUE); mupip_exit(ERR_MUPCLIERR); } n_len = sizeof(cli_buff); if (FALSE == cli_get_str((char *)select_text, cli_buff, &n_len)) { n_len = 1; cli_buff[0] = '*'; } /* gv_select will select globals */ gv_select(cli_buff, n_len, freeze, (char *)select_text, &gl_head, ®_max_rec, ®_max_key, ®_max_blk); if (!gl_head.next) { rts_error(VARLSTCNT(1) ERR_NOSELECT); mupip_exit(ERR_NOSELECT); } /* For binary format, check whether all regions have same null collation order */ if (MU_FMT_BINARY == format) { for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions, reg_std_null_coll = -1; reg < region_top ; reg++) { if (reg->open) { if (reg_std_null_coll != reg->std_null_coll) { if (reg_std_null_coll == -1) reg_std_null_coll = reg->std_null_coll; else { rts_error(VARLSTCNT(1) ERR_NULLCOLLDIFF); mupip_exit(ERR_NULLCOLLDIFF); } } } } assert(-1 != reg_std_null_coll); } grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0; global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0; n_len = sizeof(outfilename); if (FALSE == cli_get_str("FILE", outfilename, &n_len)) { rts_error(VARLSTCNT(1) ERR_MUPCLIERR); mupip_exit(ERR_MUPCLIERR); } if (-1 == Stat((char *)outfilename, &statbuf)) { if (ENOENT != errno) { local_errno = errno; perror("Error opening output file"); mupip_exit(local_errno); } } else { util_out_print("Error opening output file: !AD -- File exists", TRUE, n_len, outfilename); mupip_exit(ERR_MUNOACTION); } op_pars.mvtype = MV_STR; op_pars.str.len = sizeof(open_params_list); op_pars.str.addr = (char *)open_params_list; op_val.mvtype = MV_STR; op_val.str.len = filename_len = n_len; op_val.str.addr = (char *)outfilename; (*op_open_ptr)(&op_val, &op_pars, 0, 0); ESTABLISH(mu_extract_handler); op_use(&op_val, &op_pars); if (MU_FMT_BINARY == format) { /* binary header label format: * fixed length text, fixed length date & time, * fixed length max blk size, fixed length max rec size, fixed length max key size, fixed length std_null_coll * 32-byte padded user-supplied string */ outbuf = (unsigned char *)malloc(sizeof(BIN_HEADER_LABEL) + sizeof(BIN_HEADER_DATEFMT) - 1 + 4 * BIN_HEADER_NUMSZ + BIN_HEADER_LABELSZ); outptr = outbuf; MEMCPY_LIT(outptr, BIN_HEADER_LABEL); outptr += STR_LIT_LEN(BIN_HEADER_LABEL); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, (mval *)&mu_bin_datefmt, &null_str, &null_str, &val); memcpy(outptr, val.str.addr, val.str.len); outptr += val.str.len; WRITE_NUMERIC(reg_max_blk); WRITE_NUMERIC(reg_max_rec); WRITE_NUMERIC(reg_max_key); WRITE_NUMERIC(reg_std_null_coll); if (gtm_utf8_mode) { MEMCPY_LIT(outptr, UTF8_NAME); label_len = STR_LIT_LEN(UTF8_NAME); outptr[label_len++] = ' '; } else label_len = 0; buflen = sizeof(label_buff); if (FALSE == cli_get_str("LABEL", label_buff, &buflen)) { MEMCPY_LIT(&outptr[label_len], EXTR_DEFAULT_LABEL); buflen = STR_LIT_LEN(EXTR_DEFAULT_LABEL); } else memcpy(&outptr[label_len], label_buff, buflen); label_len += buflen; if (label_len > BIN_HEADER_LABELSZ) { /* Label size exceeds the space, so truncate the label and back off to the valid beginning (i.e. to the leading byte) of the last character that can entirely fit in the space */ label_len = BIN_HEADER_LABELSZ; chptr = &outptr[BIN_HEADER_LABELSZ]; UTF8_LEADING_BYTE(chptr, outptr, leadptr); assert(chptr - leadptr < 4); if (leadptr < chptr) label_len -= (chptr - leadptr); } outptr += label_len; for (iter = label_len; iter < BIN_HEADER_LABELSZ; iter++) *outptr++ = ' '; label_len = outptr - outbuf; if (!ochset_set) { #ifdef KEEP_zOS_EBCDIC /* extract ascii header for binary by default */ /* Do we need to restore it somewhere? */ saved_out_set = (io_curr_device.out)->out_code_set; (io_curr_device.out)->out_code_set = DEFAULT_CODE_SET; #else saved_out_set = (io_curr_device.out)->ochset; (io_curr_device.out)->ochset = CHSET_M; #endif } op_val.str.addr = (char *)(&label_len); op_val.str.len = sizeof(label_len); op_write(&op_val); op_val.str.addr = (char *)outbuf; op_val.str.len = label_len; op_write(&op_val); } else { assert((MU_FMT_GO == format) || (MU_FMT_ZWR == format)); label_len = sizeof(label_buff); if (FALSE == cli_get_str("LABEL", label_buff, &label_len)) { MEMCPY_LIT(label_buff, EXTR_DEFAULT_LABEL); label_len = STR_LIT_LEN(EXTR_DEFAULT_LABEL); } if (gtm_utf8_mode) { label_buff[label_len++] = ' '; MEMCPY_LIT(&label_buff[label_len], UTF8_NAME); label_len += STR_LIT_LEN(UTF8_NAME); } label_buff[label_len++] = '\n'; op_val.mvtype = MV_STR; op_val.str.len = label_len; op_val.str.addr = label_buff; op_write(&op_val); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, &datefmt, &null_str, &null_str, &val); op_val = val; op_val.mvtype = MV_STR; op_write(&op_val); if (MU_FMT_ZWR == format) { op_val.str.addr = " ZWR"; op_val.str.len = sizeof(" ZWR") - 1; op_write(&op_val); } op_wteol(1); } REVERT; ESTABLISH(mu_extract_handler1); success = TRUE; for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next) { if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { gbl_name_buff[0]='^'; memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len); gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff, global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen); mu_ctrlc_occurred = FALSE; } gv_bind_name(gd_header, &gl_ptr->name.str); if (MU_FMT_BINARY == format) { label_len = sizeof(extr_collhdr); op_val.mvtype = MV_STR; op_val.str.addr = (char *)(&label_len); op_val.str.len = sizeof(label_len); op_write(&op_val); extr_collhdr.act = gv_target->act; extr_collhdr.nct = gv_target->nct; extr_collhdr.ver = gv_target->ver; op_val.str.addr = (char *)(&extr_collhdr); op_val.str.len = sizeof(extr_collhdr); op_write(&op_val); } /* Note: Do not change the order of the expression below. * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all. * We want mu_extr_gblout() to be called irrespective of the value of success */ success = mu_extr_gblout(&gl_ptr->name, &global_total, format) && success; if (logqualifier) { gbl_name_buff[0]='^'; memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len); gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff, global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen); mu_ctrlc_occurred = FALSE; } grand_total.recknt += global_total.recknt; if (grand_total.reclen < global_total.reclen) grand_total.reclen = global_total.reclen; if (grand_total.keylen < global_total.keylen) grand_total.keylen = global_total.keylen; if (grand_total.datalen < global_total.datalen) grand_total.datalen = global_total.datalen; } op_val.mvtype = op_pars.mvtype = MV_STR; op_val.str.addr = (char *)outfilename;; op_val.str.len = filename_len; op_pars.str.len = sizeof(no_param); op_pars.str.addr = (char *)&no_param; op_close(&op_val, &op_pars); REVERT; if (mu_ctrly_occurred) { gtm_putmsg(VARLSTCNT(1) ERR_EXTRACTCTRLY); mupip_exit(ERR_MUNOFINISH); } gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT(gt_lit), grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen); if (MU_FMT_BINARY == format) { /* truncate the last newline charactor flushed by op_close */ STAT_FILE((char *)outfilename, &statbuf, stat_res); if (-1 == stat_res) rts_error(VARLSTCNT(1) errno); TRUNCATE_FILE((const char *)outfilename, statbuf.st_size - 1, truncate_res); if (-1 == truncate_res) rts_error(VARLSTCNT(1) errno); } mupip_exit(success ? SS_NORMAL : ERR_MUNOFINISH); }
char *jnl2ext(char *jnl_buff, char *ext_buff) { char *curr, *val_ptr, *ptr, rectype, key_buff[sizeof(gv_key) + MAX_KEY_SZ + 7]; jnl_record *rec; gv_key *key; jnl_string *keystr; int val_extr_len, val_len, rec_len; rec = (jnl_record *)jnl_buff; rectype = rec->prefix.jrec_type; rec_len = rec->prefix.forwptr; if (rec_len != REC_LEN_FROM_SUFFIX(jnl_buff, rec_len)) { assert(FALSE); return ext_buff; } if (!IS_REPLICATED(rectype)) { assert(FALSE); return ext_buff; } curr = ext_buff; if (IS_TUPD(rectype)) { if (FALSE == first_tstart) { GET_SHORTP(curr, &muext_code[MUEXT_TSTART][0]); curr += 2; DELIMIT_CURR; MEMCPY_LIT(curr, ZERO_TIME_DELIM); curr += STR_LIT_LEN(ZERO_TIME_DELIM); curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_kill.prefix.tn); DELIMIT_CURR; MEMCPY_LIT(curr, PIDS_DELIM); curr += STR_LIT_LEN(PIDS_DELIM); curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_kill.token_seq.jnl_seqno); *curr++ = '\n'; *curr = '\0'; first_tstart = TRUE; } num_tstarts++; } else if (JRT_TCOM == rectype) { num_tcommits++; if (num_tcommits == num_tstarts) { num_tcommits = num_tstarts = 0; first_tstart = FALSE; GET_SHORTP(curr, &muext_code[MUEXT_TCOMMIT][0]); curr += 2; DELIMIT_CURR; MEMCPY_LIT(curr, ZERO_TIME_DELIM); curr += STR_LIT_LEN(ZERO_TIME_DELIM); curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_tcom.prefix.tn); DELIMIT_CURR; MEMCPY_LIT(curr, PIDS_DELIM); curr += STR_LIT_LEN(PIDS_DELIM); curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_tcom.token_seq.jnl_seqno); DELIMIT_CURR; curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_tcom.participants); *curr++ = '\n'; *curr = '\0'; return curr; } return ext_buff; } if (IS_SET(rectype)) GET_SHORTP(curr, &muext_code[MUEXT_SET][0]); else if (IS_KILL(rectype)) GET_SHORTP(curr, &muext_code[MUEXT_KILL][0]); else if (IS_ZKILL(rectype)) GET_SHORTP(curr, &muext_code[MUEXT_ZKILL][0]); else /* if (JRT_NULL == rectype) */ { assert(JRT_NULL == rectype); GET_SHORTP(curr, &muext_code[MUEXT_NULL][0]); } curr += 2; DELIMIT_CURR; MEMCPY_LIT(curr, ZERO_TIME_DELIM); curr += STR_LIT_LEN(ZERO_TIME_DELIM); curr = (char *)i2asc((uchar_ptr_t)curr, rec->jrec_kill.prefix.tn); DELIMIT_CURR; MEMCPY_LIT(curr, PIDS_DELIM); curr += STR_LIT_LEN(PIDS_DELIM); curr = (char *)i2ascl((uchar_ptr_t)curr, rec->jrec_kill.token_seq.jnl_seqno); if (rectype == JRT_NULL) { *curr++ = '\n'; *curr='\0'; return curr; } assert(IS_SET_KILL_ZKILL(rectype)); DELIMIT_CURR; keystr = (jnl_string *)&rec->jrec_kill.mumps_node; ptr = (char *)ROUND_UP((uint4)key_buff, 8); key = (gv_key *)ptr; key->top = MAX_KEY_SZ; key->end = keystr->length; if (key->end > key->top) { assert(FALSE); return ext_buff; } memcpy(key->base, &keystr->text[0], keystr->length); key->base[key->end] = 0; curr = (char *)format_targ_key((uchar_ptr_t)curr, MAX_ZWR_KEY_SZ, key, TRUE); if (IS_SET(rectype)) { *curr++ = '='; val_ptr = &keystr->text[keystr->length]; GET_MSTR_LEN(val_len, val_ptr); val_ptr += sizeof(mstr_len_t); format2zwr((sm_uc_ptr_t)val_ptr, val_len, (uchar_ptr_t)curr, &val_extr_len); curr += val_extr_len; } *curr++ = '\n'; *curr='\0'; return curr; }
void dse_maps(void) { block_id blk, bml_blk; blk_segment *bs1, *bs_ptr; int4 blk_seg_cnt, blk_size; /* needed for BLK_INIT, BLK_SEG and BLK_FINI macros */ sm_uc_ptr_t bp; char util_buff[MAX_UTIL_LEN]; int4 bml_size, bml_list_size, blk_index, bml_index; int4 total_blks, blks_in_bitmap; int4 bplmap, dummy_int; unsigned char *bml_list; cache_rec_ptr_t cr, dummy_cr; bt_rec_ptr_t btr; int util_len; uchar_ptr_t blk_ptr; boolean_t was_crit; uint4 jnl_status; srch_blk_status blkhist; jnl_private_control *jpc; jnl_buffer_ptr_t jbp; sgmnt_addrs *csa; sgmnt_data_ptr_t csd; if (CLI_PRESENT == cli_present("BUSY") || CLI_PRESENT == cli_present("FREE") || CLI_PRESENT == cli_present("MASTER") || CLI_PRESENT == cli_present("RESTORE_ALL")) { if (gv_cur_region->read_only) rts_error(VARLSTCNT(4) ERR_DBRDONLY, 2, DB_LEN_STR(gv_cur_region)); } CHECK_AND_RESET_UPDATE_ARRAY; /* reset update_array_ptr to update_array */ csa = cs_addrs; assert(&FILE_INFO(gv_cur_region)->s_addrs == csa); was_crit = csa->now_crit; if (csa->critical) crash_count = csa->critical->crashcnt; csd = csa->hdr; bplmap = csd->bplmap; if (CLI_PRESENT == cli_present("BLOCK")) { if (!cli_get_hex("BLOCK", (uint4 *)&blk)) return; if (blk < 0 || blk >= csa->ti->total_blks) { util_out_print("Error: invalid block number.", TRUE); return; } patch_curr_blk = blk; } else blk = patch_curr_blk; if (CLI_PRESENT == cli_present("FREE")) { if (0 == bplmap) { util_out_print("Cannot perform map updates: bplmap field of file header is zero.", TRUE); return; } if (blk / bplmap * bplmap == blk) { util_out_print("Cannot perform action on a map block.", TRUE); return; } bml_blk = blk / bplmap * bplmap; bm_setmap(bml_blk, blk, FALSE); return; } if (CLI_PRESENT == cli_present("BUSY")) { if (0 == bplmap) { util_out_print("Cannot perform map updates: bplmap field of file header is zero.", TRUE); return; } if (blk / bplmap * bplmap == blk) { util_out_print("Cannot perform action on a map block.", TRUE); return; } bml_blk = blk / bplmap * bplmap; bm_setmap(bml_blk, blk, TRUE); return; } blk_size = csd->blk_size; if (CLI_PRESENT == cli_present("MASTER")) { if (0 == bplmap) { util_out_print("Cannot perform maps updates: bplmap field of file header is zero.", TRUE); return; } if (!was_crit) grab_crit(gv_cur_region); bml_blk = blk / bplmap * bplmap; if (dba_mm == csd->acc_meth) bp = MM_BASE_ADDR(csa) + (off_t)bml_blk * blk_size; else { assert(dba_bg == csd->acc_meth); if (!(bp = t_qread(bml_blk, &dummy_int, &dummy_cr))) rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); } if ((csa->ti->total_blks / bplmap) * bplmap == bml_blk) total_blks = (csa->ti->total_blks - bml_blk); else total_blks = bplmap; if (NO_FREE_SPACE == bml_find_free(0, bp + SIZEOF(blk_hdr), total_blks)) bit_clear(bml_blk / bplmap, csa->bmm); else bit_set(bml_blk / bplmap, csa->bmm); if (bml_blk > csa->nl->highest_lbm_blk_changed) csa->nl->highest_lbm_blk_changed = bml_blk; if (!was_crit) rel_crit(gv_cur_region); return; } if (CLI_PRESENT == cli_present("RESTORE_ALL")) { if (0 == bplmap) { util_out_print("Cannot perform maps updates: bplmap field of file header is zero.", TRUE); return; } total_blks = csa->ti->total_blks; assert(ROUND_DOWN2(blk_size, 2 * SIZEOF(int4)) == blk_size); bml_size = BM_SIZE(bplmap); bml_list_size = (total_blks + bplmap - 1) / bplmap * bml_size; bml_list = (unsigned char *)malloc(bml_list_size); for (blk_index = 0, bml_index = 0; blk_index < total_blks; blk_index += bplmap, bml_index++) bml_newmap((blk_hdr_ptr_t)(bml_list + bml_index * bml_size), bml_size, csa->ti->curr_tn); if (!was_crit) { grab_crit(gv_cur_region); csa->hold_onto_crit = TRUE; /* need to do this AFTER grab_crit */ } blk = get_dir_root(); assert(blk < bplmap); csa->ti->free_blocks = total_blks - DIVIDE_ROUND_UP(total_blks, bplmap); bml_busy(blk, bml_list + SIZEOF(blk_hdr)); csa->ti->free_blocks = csa->ti->free_blocks - 1; dse_m_rest(blk, bml_list, bml_size, &csa->ti->free_blocks, TRUE); for (blk_index = 0, bml_index = 0; blk_index < total_blks; blk_index += bplmap, bml_index++) { t_begin_crit(ERR_DSEFAIL); CHECK_TN(csa, csd, csd->trans_hist.curr_tn); /* can issue rts_error TNTOOLARGE */ CWS_RESET; CHECK_AND_RESET_UPDATE_ARRAY; /* reset update_array_ptr to update_array */ assert(csa->ti->early_tn == csa->ti->curr_tn); blk_ptr = bml_list + bml_index * bml_size; blkhist.blk_num = blk_index; if (!(blkhist.buffaddr = t_qread(blkhist.blk_num, &blkhist.cycle, &blkhist.cr))) rts_error(VARLSTCNT(1) ERR_DSEBLKRDFAIL); BLK_INIT(bs_ptr, bs1); BLK_SEG(bs_ptr, blk_ptr + SIZEOF(blk_hdr), bml_size - SIZEOF(blk_hdr)); BLK_FINI(bs_ptr, bs1); t_write(&blkhist, (unsigned char *)bs1, 0, 0, LCL_MAP_LEVL, TRUE, FALSE, GDS_WRITE_KILLTN); BUILD_AIMG_IF_JNL_ENABLED(csd, csa->ti->curr_tn); t_end(&dummy_hist, NULL, csa->ti->curr_tn); } /* Fill in master map */ for (blk_index = 0, bml_index = 0; blk_index < total_blks; blk_index += bplmap, bml_index++) { blks_in_bitmap = (blk_index + bplmap <= total_blks) ? bplmap : total_blks - blk_index; assert(1 < blks_in_bitmap); /* the last valid block in the database should never be a bitmap block */ if (NO_FREE_SPACE != bml_find_free(0, (bml_list + bml_index * bml_size) + SIZEOF(blk_hdr), blks_in_bitmap)) bit_set(blk_index / bplmap, csa->bmm); else bit_clear(blk_index / bplmap, csa->bmm); if (blk_index > csa->nl->highest_lbm_blk_changed) csa->nl->highest_lbm_blk_changed = blk_index; } if (!was_crit) { csa->hold_onto_crit = FALSE; /* need to do this before the rel_crit */ rel_crit(gv_cur_region); } if (unhandled_stale_timer_pop) process_deferred_stale(); free(bml_list); csd->kill_in_prog = csd->abandoned_kills = 0; return; } MEMCPY_LIT(util_buff, "!/Block "); util_len = SIZEOF("!/Block ") - 1; util_len += i2hex_nofill(blk, (uchar_ptr_t)&util_buff[util_len], 8); memcpy(&util_buff[util_len], " is marked !AD in its local bit map.!/", SIZEOF(" is marked !AD in its local bit map.!/") - 1); util_len += SIZEOF(" is marked !AD in its local bit map.!/") - 1; util_buff[util_len] = 0; if (!was_crit) grab_crit(gv_cur_region); util_out_print(util_buff, TRUE, 4, dse_is_blk_free(blk, &dummy_int, &dummy_cr) ? "free" : "busy"); if (!was_crit) rel_crit(gv_cur_region); return; }