bool gtcmtr_query(void) { unsigned char *ptr, *gv_key_top_ptr, regnum; unsigned short top, old_top; unsigned short key_len, tmp_len, tot_val_len; cm_region_list *reg_ref; mval val; boolean_t found, was_null; uint4 msg_len; ptr = curr_entry->clb_ptr->mbf; assert(CMMS_Q_QUERY == *ptr); ptr++; GET_USHORT(tmp_len, ptr); ptr += SIZEOF(short); regnum = *ptr++; reg_ref = gtcm_find_region(curr_entry, regnum); tmp_len--; /* subtract size of regnum */ assert(0 == offsetof(gv_key, top)); GET_USHORT(old_top, ptr); /* old_top = ((gv_key *)ptr)->top; */ CM_GET_GVCURRKEY(ptr, tmp_len); assert(1 == gv_currkey->base[gv_currkey->end - 2]); assert(0 != gv_currkey->prev || KEY_DELIMITER == gv_currkey->base[gv_currkey->end - 3]); gtcm_bind_name(reg_ref->reghead, FALSE); /* gtcm_bind_name sets gv_target; do not use gv_target before gtcm_bind_name */ if (gv_target->nct || gv_target->collseq) { /* undo client appended 01 00 00 before user provided collation routine gets control */ if (0 == gv_currkey->prev || 1 != gv_currkey->base[gv_currkey->prev] || 0 != gv_currkey->base[gv_currkey->prev + 1]) { /* name level $Q, or last subscript of incoming key not null */ DEBUG_ONLY(was_null = FALSE;) gv_currkey->end -= 2; gv_currkey->base[gv_currkey->end] = KEY_DELIMITER; } else
long SDMCode::Unmarshal(const char* buf) { int cur; cur = UnmarshalHeader(buf); if (cur == SDM_INVALID_MESSAGE) { return SDM_INVALID_MESSAGE; } if(total_length>msg_length) { return SDM_INVALID_MESSAGE; } seq_num = GET_USHORT(&buf[cur]); cur += sizeof(seq_num); num_segments = GET_USHORT(&buf[cur]); cur += sizeof(num_segments); // // Get the filename size_t uiCurLength = strlen(buf + cur); strncpy(filename, buf + cur, sizeof(filename)); if (uiCurLength > sizeof(filename) - 1) filename[sizeof(filename) - 1] = '\0'; cur += (int)uiCurLength + 1; memcpy(&code, &buf[cur], msg_length - (strlen(filename)+1) - 8); cur += msg_length - (unsigned int)(strlen(filename)+1) - 8; code_length = msg_length - (unsigned int)(strlen(filename)+1) - 8; c_sum = GET_INT(&buf[cur]); cur += sizeof(c_sum); #ifdef BUILD_WITH_MESSAGE_LOGGING Logger.MessageReceived(*this); #endif return cur; }
// process incoming squadmate messaging info void multi_msg_process_squadmsg_packet(unsigned char *data, header *hinfo) { int command; ushort net_sig; short source_id; int source_index; char s_val; int offset = HEADER_LENGTH; // get all packet data GET_INT(command); GET_SHORT(source_id); GET_USHORT(net_sig); GET_DATA(s_val); PACKET_SET_SIZE(); // determine who the order is from source_index = find_player_id(source_id); if(source_index == -1){ nprintf(("Network","Received squadmsg order packet from unknown player!!\n")); return; } // display the squadmessage somehow multi_msg_show_squadmsg(&Net_players[source_index],command,net_sig,(int)s_val); }
bool gtcmtr_data(void) { cm_region_list *reg_ref; unsigned char *ptr,regnum; unsigned short top,len; mval v; int x; ptr = curr_entry->clb_ptr->mbf; assert(*ptr == CMMS_Q_DATA); ptr++; GET_USHORT(len, ptr); ptr += sizeof(unsigned short); regnum = *ptr++; reg_ref = gtcm_find_region(curr_entry, regnum); len--; /* subtract size of regnum */ CM_GET_GVCURRKEY(ptr, len); gtcm_bind_name(reg_ref->reghead, TRUE); x = 0; if (gv_target->root) x = gvcst_data(); v = *fndata_table[x / 10][x & 1]; ptr = curr_entry->clb_ptr->mbf; *ptr++ = CMMS_R_DATA; len = sizeof(unsigned char); PUT_USHORT(ptr, len); ptr += sizeof(unsigned short); *ptr++ = MV_FORCE_INTD(&v); curr_entry->clb_ptr->cbl = ptr - curr_entry->clb_ptr->mbf; return TRUE; }
long SDMmessage::UnmarshalHeader(const char* buf) { if(buf == NULL || buf[0] != MsgName) { return SDM_INVALID_MESSAGE; } sec = GET_LONG(&buf[1]); subsec = GET_LONG(&buf[5]); msg_length = GET_USHORT(&buf[9]); return HEADER_SIZE; }
/* compute post_incr_mval from the current value of gv_currkey that was just now searched down the tree */ enum cdb_sc gvincr_compute_post_incr(srch_blk_status *bh) { int4 cur_blk_size; sm_uc_ptr_t buffaddr; rec_hdr_ptr_t rp; unsigned short rec_size; int4 target_key_size, data_len; uint4 gvincr_malloc_len; mval pre_incr_mval; int tmp_cmpc; buffaddr = bh->buffaddr; cur_blk_size = ((blk_hdr_ptr_t)buffaddr)->bsiz; rp = (rec_hdr_ptr_t)(buffaddr + bh->curr_rec.offset); GET_USHORT(rec_size, &rp->rsiz); target_key_size = bh->curr_rec.match; assert(target_key_size == gv_currkey->end + 1); data_len = rec_size + EVAL_CMPC(rp) - SIZEOF(rec_hdr) - target_key_size; if ((0 > data_len) || (((sm_uc_ptr_t)rp + rec_size) > ((sm_uc_ptr_t)buffaddr + cur_blk_size))) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } if (data_len > gvincr_pre_incr_bufflen) { if (NULL != gvincr_pre_incr_buff) free(gvincr_pre_incr_buff); gvincr_malloc_len = (data_len > GVINCR_PRE_INCR_MIN_BUFFLEN) ? data_len : GVINCR_PRE_INCR_MIN_BUFFLEN; gvincr_pre_incr_buff = (char *)malloc(gvincr_malloc_len); gvincr_pre_incr_bufflen = gvincr_malloc_len; } /* malloced buffer is used for pre_incr_mval instead of stringpool because this is memory that is * inherently used only by $INCREMENT and is needed only during the lifetime of the increment. * keeping it in the stringpool causes it to stay until the next garbage collection which adds * to unnecessary overheads. */ pre_incr_mval.mvtype = MV_STR; pre_incr_mval.str.addr = (char *)gvincr_pre_incr_buff; pre_incr_mval.str.len = data_len; memcpy(pre_incr_mval.str.addr, (sm_uc_ptr_t)rp + rec_size - data_len, data_len); op_add(&pre_incr_mval, &increment_delta_mval, post_incr_mval); assert(MV_IS_NUMERIC(post_incr_mval)); /* "post_incr_mval" is of numeric type, convert it to a string type so it can be used by the caller to set "value" */ MV_FORCE_STR(post_incr_mval); /* will use stringpool to store string representation */ /* "post_incr_mval" is a copy of the mval pointer passed to "op_gvincr" and hence is on the M-stack * and therefore is known to the garbage collector (stp_gcol). hence it is ok for it to use the stringpool */ return cdb_sc_normal; }
int file_input_bin_get(char **in_ptr, ssize_t *file_offset, char **buff_base) { char *ptr; int rd_cnt, rd_len, s1; unsigned short s1s; ESTABLISH_RET(mupip_load_ch, 0); if (SIZEOF(short) > (buff1_end - buff1_ptr)) { if (0 >= (rd_len = file_input_bin_read())) /* NOTE assignment */ { if (buff1_end != buff1_ptr) rts_error(VARLSTCNT(1) ERR_PREMATEOF); else if (-1 == rd_len) rts_error(VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr); else { REVERT; return 0; } } buff1_end += rd_len; } GET_USHORT(s1s, buff1_ptr); buff1_ptr += SIZEOF(short); s1 = s1s; assert(0 < s1); assert(BUFF_SIZE >= s1); if ((buff1_end - buff1_ptr) < s1) { /* not enough data in buffer, read additional bytes */ rd_len = file_input_bin_read(); if ((rd_len + buff1_end - buff1_ptr) < s1) { if (-1 == rd_len) rts_error(VARLSTCNT(4) ERR_LOADFILERR, 2, load_fn_len, load_fn_ptr); rts_error(VARLSTCNT(1) ERR_PREMATEOF); } buff1_end += rd_len; } *in_ptr = buff1_ptr; buff1_ptr += s1; *file_offset = buff1_ptr_file_offset; *buff_base = buff1; REVERT; return s1; }
/* * Performs a random traversal for the sampling methods */ enum cdb_sc rand_traverse(double *r) { sm_uc_ptr_t pVal, pTop, pRec, pBlkBase; register gv_namehead *pTarg; register srch_blk_status *pCurr; register srch_hist *pTargHist; block_id nBlkId; block_id valBlk[MAX_RECS_PER_BLK]; /* valBlk[j] := value in j-th record of current block */ unsigned char nLevl; cache_rec_ptr_t cr; int cycle; trans_num tn; sm_uc_ptr_t buffaddr; unsigned short nRecLen; uint4 tmp; boolean_t is_mm; int4 random; int4 rCnt; /* number of entries in valBlk */ DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; is_mm = (dba_mm == cs_data->acc_meth); pTarg = gv_target; pTargHist = &gv_target->hist; /* The following largely mimics gvcst_search/gvcst_search_blk */ nBlkId = pTarg->root; tn = cs_addrs->ti->curr_tn; if (NULL == (pBlkBase = t_qread(nBlkId, (sm_int_ptr_t)&cycle, &cr))) return (enum cdb_sc)rdfail_detail; nLevl = ((blk_hdr_ptr_t)pBlkBase)->levl; if (MAX_BT_DEPTH < (int)nLevl) { assert(CDB_STAGNATE > t_tries); return cdb_sc_maxlvl; } if (0 == (int)nLevl) { assert(CDB_STAGNATE > t_tries); return cdb_sc_badlvl; } pTargHist->depth = (int)nLevl; pCurr = &pTargHist->h[nLevl]; (pCurr + 1)->blk_num = 0; pCurr->tn = tn; pCurr->cycle = cycle; pCurr->cr = cr; for (;;) { assert(pCurr->level == nLevl); pCurr->cse = NULL; pCurr->blk_num = nBlkId; pCurr->buffaddr = pBlkBase; for ( rCnt = 0, pRec = pBlkBase + SIZEOF(blk_hdr), pTop = pBlkBase + ((blk_hdr_ptr_t)pBlkBase)->bsiz; pRec != pTop && rCnt < MAX_RECS_PER_BLK; rCnt++, pRec += nRecLen ) { /* enumerate records in block */ GET_USHORT(nRecLen, &((rec_hdr_ptr_t)pRec)->rsiz); pVal = pRec + nRecLen - SIZEOF(block_id); if (nRecLen == 0) { assert(CDB_STAGNATE > t_tries); return cdb_sc_badoffset; } if (pRec + nRecLen > pTop) { assert(CDB_STAGNATE > t_tries); return cdb_sc_blklenerr; } GET_LONG(tmp, pVal); valBlk[rCnt] = tmp; } r[nLevl] = rCnt; /* randomly select next block */ random = (int4)(rCnt * drand48()); random = random & 0x7fffffff; /* to make sure that the sign bit(msb) is off */ nBlkId = valBlk[random]; if (is_mm && (nBlkId > cs_addrs->total_blks)) { if (cs_addrs->total_blks < cs_addrs->ti->total_blks) return cdb_sc_helpedout; else return cdb_sc_blknumerr; } --pCurr; --nLevl; if (nLevl < 1) break; pCurr->tn = cs_addrs->ti->curr_tn; if (NULL == (pBlkBase = t_qread(nBlkId, (sm_int_ptr_t)&pCurr->cycle, &pCurr->cr))) return (enum cdb_sc)rdfail_detail; if (((blk_hdr_ptr_t)pBlkBase)->levl != nLevl) { assert(CDB_STAGNATE > t_tries); return cdb_sc_badlvl; } } return cdb_sc_normal; }
bool gtcmtr_increment(void) { cm_region_list *reg_ref; mval incr_delta, post_incr; unsigned char buff[MAX_ZWR_KEY_SZ], *end; unsigned char *ptr, regnum; short n; unsigned short top, len, temp_short; static readonly gds_file_id file; error_def(ERR_KEY2BIG); error_def(ERR_GVIS); error_def(ERR_DBPRIVERR); ptr = curr_entry->clb_ptr->mbf; assert(*ptr == CMMS_Q_INCREMENT); ptr++; GET_USHORT(len, ptr); ptr += SIZEOF(unsigned short); regnum = *ptr++; reg_ref = gtcm_find_region(curr_entry,regnum); len--; /* subtract size of regnum */ CM_GET_GVCURRKEY(ptr, len); gtcm_bind_name(reg_ref->reghead, TRUE); if (gv_cur_region->read_only) rts_error(VARLSTCNT(4) ERR_DBPRIVERR, 2, DB_LEN_STR(gv_cur_region)); if (JNL_ALLOWED(cs_addrs)) { /* we need to copy client's specific prc_vec into the global variable in order that the gvcst* routines * do the right job. actually we need to do this only if JNL_ENABLED(cs_addrs), but since it is not * easy to re-execute the following two assignments in case gvcst_incr's call to t_end encounters a * cdb_sc_jnlstatemod retry code, we choose the easier approach of executing the following segment * if JNL_ALLOWED(cs_addrs) is TRUE instead of checking for JNL_ENABLED(cs_addrs) to be TRUE. * this approach has the overhead that we will be doing the following assignments even though JNL_ENABLED * might not be TRUE but since the following two are just pointer copies, it is not considered a big overhead. * this approach ensures that the jnl_put_jrt_pini gets the appropriate prc_vec for writing into the * journal record in case JNL_ENABLED turns out to be TRUE in t_end time. * note that the value of JNL_ALLOWED(cs_addrs) cannot be changed on the fly without obtaining standalone access * and hence the correctness of prc_vec (whenever it turns out necessary) is guaranteed. */ originator_prc_vec = curr_entry->pvec; cs_addrs->jnl->pini_addr = reg_ref->pini_addr; } GET_USHORT(len, ptr); ptr += SIZEOF(unsigned short); incr_delta.mvtype = MV_STR; incr_delta.str.len = len; incr_delta.str.addr = (char *)ptr; if ((n = gv_currkey->end + 1) > gv_cur_region->max_key_size) { if ((end = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gv_currkey, TRUE)) == 0) end = &buff[MAX_ZWR_KEY_SZ - 1]; rts_error(VARLSTCNT(11) ERR_KEY2BIG, 4, n, (int4)gv_cur_region->max_key_size, REG_LEN_STR(gv_cur_region), 0, ERR_GVIS, 2, end - buff, buff); } MV_FORCE_NUMD(&incr_delta); gvcst_incr(&incr_delta, &post_incr); if (JNL_ALLOWED(cs_addrs)) reg_ref->pini_addr = cs_addrs->jnl->pini_addr; /* In case journal switch occurred */ ptr = curr_entry->clb_ptr->mbf; if (MV_DEFINED(&post_incr)) { temp_short = (unsigned short)post_incr.str.len; assert((int4)temp_short == post_incr.str.len); /* ushort <- int4 assignment lossy? */ if (curr_entry->clb_ptr->mbl < 1 + /* msg header */ SIZEOF(temp_short) + /* size of length of $INCR return value */ temp_short) /* length of $INCR return value */ { /* resize buffer */ cmi_realloc_mbf(curr_entry->clb_ptr, 1 + SIZEOF(temp_short) + temp_short); ptr = curr_entry->clb_ptr->mbf; } *ptr++ = CMMS_R_INCREMENT; PUT_USHORT(ptr, temp_short); ptr += SIZEOF(unsigned short); memcpy(ptr, post_incr.str.addr, temp_short); ptr += temp_short; } else
bool gvcst_get(mval *v) { srch_blk_status *s; enum cdb_sc status; int key_size, data_len; unsigned short rsiz; rec_hdr_ptr_t rp; T_BEGIN_READ_NONTP_OR_TP(ERR_GVGETFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL))) { if ((key_size = gv_currkey->end + 1) == gv_target->hist.h[0].curr_rec.match) { rp = (rec_hdr_ptr_t)(gv_target->hist.h[0].buffaddr + gv_target->hist.h[0].curr_rec.offset); GET_USHORT(rsiz, &rp->rsiz); data_len = rsiz + rp->cmpc - sizeof(rec_hdr) - key_size; if (data_len < 0 || (sm_uc_ptr_t)rp + rsiz > gv_target->hist.h[0].buffaddr + ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->bsiz) { assert(CDB_STAGNATE > t_tries); status = cdb_sc_rmisalign1; } else { if (stringpool.top - stringpool.free < data_len) stp_gcol(data_len); assert(stringpool.top - stringpool.free >= data_len); memcpy(stringpool.free, (sm_uc_ptr_t)rp + rsiz - data_len, data_len); if (0 == dollar_tlevel) { if (0 == t_end(&gv_target->hist, NULL)) continue; } else { status = tp_hist(NULL); if (cdb_sc_normal != status) { t_retry(status); continue; } } v->mvtype = MV_STR; v->str.addr = (char *)stringpool.free; v->str.len = data_len; stringpool.free += data_len; if (cs_addrs->read_write) cs_addrs->hdr->n_gets++; return TRUE; } } else { if (0 == dollar_tlevel) { if (0 == t_end(&gv_target->hist, NULL)) continue; } else { status = tp_hist(NULL); if (cdb_sc_normal != status) { t_retry(status); continue; } } cs_addrs->hdr->n_gets++; return FALSE; } } t_retry(status); } }
int4 v12_jnl_record_length(jnl_record *rec, int4 top) /* top is maximum length of record (e.g.: end of buffer) */ { enum jnl_record_type rectype; int4 n; uint4 data_len; unsigned short m; unsigned char lcl_jrec_type; mstr_len_t mstr_len; if ((rectype = REF_CHAR(&rec->jrec_type)) <= JRT_BAD || rectype >= JRT_RECTYPES) { return -1; } n = JREC_PREFIX_SIZE + v12_jnl_fixed_size[rectype]; switch (rectype) { case JRT_PINI: case JRT_PFIN: case JRT_TCOM: case JRT_ZTCOM: case JRT_EPOCH: case JRT_EOF: case JRT_NULL: case JRT_INCTN: n += JREC_SUFFIX_SIZE; break; case JRT_ALIGN: if (n > top) break; GET_USHORT(m, &rec->val.jrec_align.align_str.align_string.length); n += m + JREC_SUFFIX_SIZE; break; case JRT_KILL: case JRT_ZKILL: n += sizeof(unsigned short); if (n > top) break; GET_USHORT(m, &rec->val.jrec_kill.mumps_node.length); n += m + JREC_SUFFIX_SIZE; break; case JRT_FKILL: case JRT_GKILL: case JRT_TKILL: case JRT_UKILL: case JRT_FZKILL: case JRT_GZKILL: case JRT_TZKILL: case JRT_UZKILL: n += sizeof(unsigned short); if (n > top) break; GET_USHORT(m, &rec->val.jrec_fkill.mumps_node.length); n += m + JREC_SUFFIX_SIZE; break; case JRT_SET: n += sizeof(unsigned short); if (n > top) break; GET_USHORT(m, &rec->val.jrec_set.mumps_node.length); n += m; if (n + sizeof(mstr_len_t) > top) { n += sizeof(mstr_len_t); break; } GET_MSTR_LEN(mstr_len, (char *)rec + n); n += mstr_len + sizeof(mstr_len_t) + JREC_SUFFIX_SIZE; break; case JRT_FSET: case JRT_GSET: case JRT_TSET: case JRT_USET: n += sizeof(unsigned short); if (n > top) break; GET_USHORT(m, &rec->val.jrec_fset.mumps_node.length); n += m; if (n + sizeof(mstr_len_t) > top) { n += sizeof(mstr_len_t); break; } GET_MSTR_LEN(mstr_len, (char *)rec + n); n += mstr_len + sizeof(mstr_len_t) + JREC_SUFFIX_SIZE; break; case JRT_PBLK: if (n > top) break; GET_USHORT(m, &rec->val.jrec_pblk.bsiz); n += m + JREC_SUFFIX_SIZE; break; case JRT_AIMG: if (n > top) break; GET_USHORT(m, &rec->val.jrec_aimg.bsiz); n += m + JREC_SUFFIX_SIZE; break; default: assert(FALSE); return -1; } n = ROUND_UP(n, JNL_REC_START_BNDRY); return n; }
boolean_t gvcst_order2(void) { blk_hdr_ptr_t bp; boolean_t found, two_histories; enum cdb_sc status; rec_hdr_ptr_t rp; unsigned short rec_size; srch_blk_status *bh; srch_hist *rt_history; sm_uc_ptr_t c1, c2, ctop, alt_top; int tmp_cmpc; T_BEGIN_READ_NONTP_OR_TP(ERR_GVORDERFAIL); for (;;) { assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ two_histories = FALSE; #if defined(DEBUG) && defined(UNIX) if (gtm_white_box_test_case_enabled && (WBTEST_ANTIFREEZE_GVORDERFAIL == gtm_white_box_test_case_number)) { status = cdb_sc_blknumerr; t_retry(status); continue; } #endif if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL))) { found = TRUE; bh = gv_target->hist.h; rp = (rec_hdr_ptr_t)(bh->buffaddr + bh->curr_rec.offset); bp = (blk_hdr_ptr_t)bh->buffaddr; if ((rec_hdr_ptr_t)CST_TOB(bp) <= rp) { two_histories = TRUE; rt_history = gv_target->alt_hist; status = gvcst_rtsib(rt_history, 0); if (cdb_sc_normal == status) { bh = rt_history->h; if (cdb_sc_normal != (status = gvcst_search_blk(gv_currkey, bh))) { t_retry(status); continue; } rp = (rec_hdr_ptr_t)(bh->buffaddr + bh->curr_rec.offset); bp = (blk_hdr_ptr_t)bh->buffaddr; } else { if (cdb_sc_endtree == status) { found = FALSE; two_histories = FALSE; /* second history not valid */ } else { t_retry(status); continue; } } } if (found) { assert(gv_altkey->top == gv_currkey->top); assert(gv_altkey->top == gv_keysize); assert(gv_altkey->end < gv_altkey->top); /* store new subscipt */ c1 = gv_altkey->base; alt_top = gv_altkey->base + gv_altkey->top - 1; /* Make alt_top one less than gv_altkey->top to allow double-null at end of a key-name */ /* 4/17/96 * HP compiler bug work-around. The original statement was * c2 = (unsigned char *)CST_BOK(rp) + bh->curr_rec.match - rp->cmpc; * * ...but this was sometimes compiled incorrectly (the lower 4 bits * of rp->cmpc, sign extended, were subtracted from bh->curr_rec.match). * I separated out the subtraction of rp->cmpc. * * -VTF. */ c2 = (sm_uc_ptr_t)CST_BOK(rp) + bh->curr_rec.match; memcpy(c1, gv_currkey->base, bh->curr_rec.match); c1 += bh->curr_rec.match; c2 -= EVAL_CMPC(rp); GET_USHORT(rec_size, &rp->rsiz); ctop = (sm_uc_ptr_t)rp + rec_size; for (;;) { if (c2 >= ctop || c1 >= alt_top) { assert(CDB_STAGNATE > t_tries); status = cdb_sc_rmisalign; goto restart; /* goto needed because of nested FOR loop */ } if (0 == (*c1++ = *c2++)) { *c1 = 0; break; } } gv_altkey->end = c1 - gv_altkey->base; assert(gv_altkey->end < gv_altkey->top); } if (!dollar_tlevel) { if ((trans_num)0 == t_end(&gv_target->hist, two_histories ? rt_history : NULL, TN_NOT_SPECIFIED)) continue; } else { status = tp_hist(two_histories ? rt_history : NULL); if (cdb_sc_normal != status) { t_retry(status); continue; } } assert(cs_data == cs_addrs->hdr); INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_order, 1); return (found && (bh->curr_rec.match >= gv_currkey->prev)); } restart: t_retry(status); } }
/* This function is the equivalent of invoking gvcst_data & gvcst_get at the same time. * One crucial difference is that this function does NOT handle restarts by automatically invoking t_retry. * Instead, it returns the restart code to the caller so that it can handle the restart accordingly. * This is important in the case of triggers because we do NOT want to call t_retry in case of a implicit tstart * wrapped gvcst_put or gvcst_kill trigger-invoking update transaction. Additionally, this function assumes * that it is called always inside of TP (i.e. dollar_tlevel is non-zero). */ enum cdb_sc gvcst_dataget(mint *dollar_data, mval *val) { blk_hdr_ptr_t bp; boolean_t do_rtsib; enum cdb_sc status; mint dlr_data; rec_hdr_ptr_t rp; unsigned short match, rsiz; srch_blk_status *bh; srch_hist *rt_history; sm_uc_ptr_t b_top; int key_size, data_len; uint4 save_t_err; error_def(ERR_GVDATAGETFAIL); error_def(ERR_GVKILLFAIL); /* The following code is lifted from gvcst_data. Any changes here might need to be reflected there as well */ assert(dollar_tlevel); assert((CDB_STAGNATE > t_tries) || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ save_t_err = t_err; assert(ERR_GVKILLFAIL == save_t_err); /* this function should currently be called only from gvcst_kill */ t_err = ERR_GVDATAGETFAIL; /* switch t_err to reflect dataget sub-operation (under the KILL operation) */ /* In case of a failure return, it is ok to return with t_err set to ERR_GVDATAGETFAIL as that gives a better * picture of exactly where in the transaction the failure occurred. */ rt_history = gv_target->alt_hist; rt_history->h[0].blk_num = 0; if (cdb_sc_normal != (status = gvcst_search(gv_currkey, NULL))) return status; bh = gv_target->hist.h; bp = (blk_hdr_ptr_t)bh->buffaddr; rp = (rec_hdr_ptr_t)(bh->buffaddr + bh->curr_rec.offset); b_top = bh->buffaddr + bp->bsiz; match = bh->curr_rec.match; key_size = gv_currkey->end + 1; do_rtsib = FALSE; /* Even if key does not exist, return null string in "val". Caller can use dollar_data to distinguish * whether the key is undefined or defined and set to the null string. */ val->mvtype = MV_STR; val->str.len = 0; if (key_size == match) { dlr_data = 1; /* the following code is lifted from gvcst_get. any changes here might need to be reflected there as well */ GET_USHORT(rsiz, &rp->rsiz); data_len = rsiz + rp->cmpc - SIZEOF(rec_hdr) - key_size; if ((0 > data_len) || ((sm_uc_ptr_t)rp + rsiz > b_top)) { assert(CDB_STAGNATE > t_tries); status = cdb_sc_rmisalign1; return status; } else { ENSURE_STP_FREE_SPACE(data_len); memcpy(stringpool.free, (sm_uc_ptr_t)rp + rsiz - data_len, data_len); val->str.addr = (char *)stringpool.free; val->str.len = data_len; stringpool.free += data_len; } /* --------------------- end code lifted from gvcst_get ---------------------------- */ rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)rp + rsiz); if ((sm_uc_ptr_t)rp > b_top) { status = cdb_sc_rmisalign; return status; } else if ((sm_uc_ptr_t)rp == b_top) do_rtsib = TRUE; else if (rp->cmpc >= gv_currkey->end) dlr_data += 10; } else if (match >= gv_currkey->end) dlr_data = 10; else { dlr_data = 0; if (rp == (rec_hdr_ptr_t)b_top) do_rtsib = TRUE; } if (do_rtsib && (cdb_sc_endtree != (status = gvcst_rtsib(rt_history, 0)))) { if ((cdb_sc_normal != status) || (cdb_sc_normal != (status = gvcst_search_blk(gv_currkey, rt_history->h)))) return status; if (rt_history->h[0].curr_rec.match >= gv_currkey->end) { assert(1 >= dlr_data); dlr_data += 10; } } status = tp_hist(0 == rt_history->h[0].blk_num ? NULL : rt_history); if (cdb_sc_normal != status) return status; *dollar_data = dlr_data; t_err = save_t_err; /* restore t_err to what it was at function entry */ return status; }
enum cdb_sc gvcst_search_blk (gv_key *pKey, srch_blk_status *pStat) { /* register variables named in perceived order of declining impact */ register int nFlg, nTargLen, nMatchCnt, nTmp; sm_uc_ptr_t pBlkBase, pRecBase, pTop, pRec, pPrevRec; unsigned char *pCurrTarg, *pTargKeyBase; unsigned short nRecLen; /* the following load code (and code in a few other places) is coded in a "assember" style * in an attempt to encourage the compiler to get it efficient; * if instance, memory and non-memory instructions are interlaced to encourge pipelining. * of course a great compiler doesn't need help, but this is portable code and ... */ pBlkBase = pStat->buffaddr; pRecBase = pBlkBase; pTop = pBlkBase + ((blk_hdr_ptr_t)pBlkBase)->bsiz; nRecLen = sizeof(blk_hdr); pCurrTarg = pKey->base; nMatchCnt = 0; nTargLen = (int)pKey->end; pTargKeyBase = pCurrTarg; nTargLen++; /* for the terminating NUL on the key */ for (;;) { pRec = pRecBase + nRecLen; if (pRec >= pTop) { /* Terminated at end of block */ if (pRec > pTop) /* If record goes off the end, then block must be bad */ { INVOKE_GVCST_SEARCH_FAIL_IF_NEEDED(pStat); assert(CDB_STAGNATE > t_tries); return cdb_sc_blklenerr; } nTargLen = 0; if (((blk_hdr_ptr_t)pBlkBase)->levl == 0) { /* data block */ pPrevRec = pRecBase; pRecBase = pRec; } else nMatchCnt = 0; /* star key */ break; } GET_USHORT(nRecLen, &((rec_hdr_ptr_t)pRec)->rsiz); if (nRecLen == 0) /* If record length is 0, then block must be bad */ { INVOKE_GVCST_SEARCH_FAIL_IF_NEEDED(pStat); assert(CDB_STAGNATE > t_tries); return cdb_sc_badoffset; } pPrevRec = pRecBase; pRecBase = pRec; /* If current compression count > last match, then this record also matches on 'last match' characters; keep looping */ if ((nTmp = ((rec_hdr_ptr_t)pRec)->cmpc) > nMatchCnt) continue; if (nTmp < nMatchCnt) { /* Terminate on compression count < previous match, this key is after the target */ if (nRecLen == BSTAR_REC_SIZE && ((blk_hdr_ptr_t)pBlkBase)->levl != 0) /* Star key has size of sizeof(rec_hdr) + sizeof(block_id), make match = 0 */ nTargLen = 0; else /* Data block, make match = current compression count */ nTargLen = nTmp; break; } /* Compression count == match count; Compare current target with current record */ pRec += sizeof(rec_hdr); do { if ((nFlg = *pCurrTarg - *pRec++) != 0) break; pCurrTarg++; } while ( --nTargLen); if (nFlg > 0) nMatchCnt = pCurrTarg - pTargKeyBase; else { /* Key is after target*/ if (nRecLen == BSTAR_REC_SIZE && (((blk_hdr_ptr_t)pBlkBase)->levl != 0)) /* Star key has size of sizeof(rec_hdr) + sizeof(block_id), make match = 0 */ nTargLen = 0; else nTargLen = pCurrTarg - pTargKeyBase; break; } } pStat->prev_rec.offset = (short)(pPrevRec - pBlkBase); pStat->prev_rec.match = (short)nMatchCnt; pStat->curr_rec.offset = (short)(pRecBase - pBlkBase); pStat->curr_rec.match = (short)nTargLen; return cdb_sc_normal; }
/* search_tail is the "start anywhere" version of search_blk getting started is a bit awkward, so excuse the gotos */ enum cdb_sc gvcst_search_tail (gv_key *pKey, srch_blk_status *pStat, gv_key *pOldKey) { /* register variables named in perceived order of declining impact */ register int nFlg, nTargLen, nMatchCnt, nTmp; sm_uc_ptr_t pBlkBase, pRecBase, pRec, pTop, pPrevRec; unsigned char *pCurrTarg, *pTargKeyBase, *pOldKeyBase, *pCurrTargPos; unsigned short nRecLen; /* see comment in gvcst_search_blk above on coding style */ if (pStat->prev_rec.offset == 0) return gvcst_search_blk(pKey, pStat); /* nice clean start at the begining of a block */ pBlkBase = pStat->buffaddr; pRecBase = pBlkBase + pStat->curr_rec.offset; pRec = pRecBase; pTop = pBlkBase + ((blk_hdr_ptr_t)pBlkBase)->bsiz; nMatchCnt = pStat->prev_rec.match; pCurrTarg = pKey->base; pTargKeyBase = pCurrTarg; pOldKeyBase = pOldKey->base; pPrevRec = pBlkBase + pStat->prev_rec.offset; nTargLen = pKey->end; nTargLen++; /* for the NUL that terminates the key */ if (pRec >= pTop) { /* Terminated at end of block */ /* eob_tail: */ if (pRec > pTop) { INVOKE_GVCST_SEARCH_FAIL_IF_NEEDED(pStat); assert(CDB_STAGNATE > t_tries); return cdb_sc_blklenerr; } if ((nTargLen = nMatchCnt) != 0) { do { if (*pCurrTarg++ != *pOldKeyBase++) break; } while (--nTargLen); } if (((blk_hdr_ptr_t)pBlkBase)->levl != 0) nMatchCnt = 0; /* star key */ else nMatchCnt -= nTargLen; nTargLen = 0; } else { GET_USHORT(nRecLen, &((rec_hdr_ptr_t)pRec)->rsiz); if ((nFlg = nTmp = ((rec_hdr_ptr_t)pRec)->cmpc) != 0) { do { if ((nFlg = *pCurrTarg - *pOldKeyBase++) != 0) break; pCurrTarg++; } while (--nTmp); if (nFlg > 0) { nMatchCnt = pCurrTarg - pTargKeyBase; nTargLen -= nMatchCnt; } if (nFlg < 0) { nTargLen += pTargKeyBase - pCurrTarg; goto match_term; } } if (nFlg == 0) { nTmp = nMatchCnt; nMatchCnt = pCurrTarg - pTargKeyBase; nTargLen -= nMatchCnt; nTmp -= nMatchCnt; if (nTmp > 0) { pCurrTargPos = pCurrTarg; do { if (*pCurrTargPos++ != *pOldKeyBase++) break; nMatchCnt++; } while (--nTmp); } goto alt_loop_entry; } for (;;) { pRec = pRecBase + nRecLen; if (pRec >= pTop) { /* Terminated at end of block */ if (pRec > pTop) /* If record goes off the end, then block must be bad */ { INVOKE_GVCST_SEARCH_FAIL_IF_NEEDED(pStat); assert(CDB_STAGNATE > t_tries); return cdb_sc_blklenerr; } nTargLen = 0; if (((blk_hdr_ptr_t)pBlkBase)->levl == 0) { /* data block */ pPrevRec = pRecBase; pRecBase = pRec; } else nMatchCnt = 0; /* star key */ break; } GET_USHORT(nRecLen, &((rec_hdr_ptr_t)pRec)->rsiz); if (nRecLen == 0) /* If record length is 0, then block must be bad */ { INVOKE_GVCST_SEARCH_FAIL_IF_NEEDED(pStat); assert(CDB_STAGNATE > t_tries); return cdb_sc_badoffset; } pPrevRec = pRecBase; pRecBase = pRec; /* If current compression count > last match, then this record also matches on 'last match' characters; keep looping */ if ((nTmp = ((rec_hdr_ptr_t)pRec)->cmpc) > nMatchCnt) continue; if (nTmp < nMatchCnt) /* cc_term: */ { /* Terminated on compression count < previous match, this key is after the target */ if (nRecLen == BSTAR_REC_SIZE && ((blk_hdr_ptr_t)pBlkBase)->levl != 0) /* Star key has size of sizeof(rec_hdr) + sizeof(block_id), make match = 0 */ nTargLen = 0; else /* Data block, make match = current compression count */ nTargLen = nTmp; break; } alt_loop_entry: /* Compression count == match count; Compare current target with current record */ pRec += sizeof(rec_hdr); do { if ((nFlg = *pCurrTarg - *pRec++) != 0) break; pCurrTarg++; } while (--nTargLen); if (nFlg > 0) nMatchCnt = pCurrTarg - pTargKeyBase; else match_term: { /* Key is after target*/ if (nRecLen == BSTAR_REC_SIZE && (((blk_hdr_ptr_t)pBlkBase)->levl != 0)) /* Star key has size of sizeof(rec_hdr) + sizeof(block_id), make match = 0 */ nTargLen = 0; else nTargLen = pCurrTarg - pTargKeyBase; break; } } } /* clean_up: */ pStat->prev_rec.offset = (short)(pPrevRec - pBlkBase); pStat->prev_rec.match = (short)nMatchCnt; pStat->curr_rec.offset = (short)(pRecBase - pBlkBase); pStat->curr_rec.match = (short)nTargLen; return cdb_sc_normal; }
bool gtcmtr_bufflush(void) { cm_region_list *reg_ref; mval v; short n; unsigned short num_trans, data_len; unsigned char buff[MAX_ZWR_KEY_SZ], *end; unsigned char *ptr, regnum, len, cc, prv; static readonly gds_file_id file; error_def(ERR_KEY2BIG); error_def(ERR_REC2BIG); error_def(ERR_GVIS); ptr = curr_entry->clb_ptr->mbf; assert(*ptr == CMMS_B_BUFFLUSH); ptr++; v.mvtype = MV_STR; GET_USHORT(num_trans, ptr); ptr += sizeof (short); for (; num_trans-- > 0;) { regnum = *ptr++; reg_ref = gtcm_find_region(curr_entry, regnum); len = *ptr++; cc = *ptr++; prv = *ptr++; assert (len + cc - 1 < gv_currkey->top); memcpy(&gv_currkey->base[cc], ptr, len); ptr += len; gv_currkey->end = len + cc - 1; gv_currkey->prev = prv; assert(prv < gv_currkey->end); if ((n = gv_currkey->end + 1) > gv_cur_region->max_key_size) { if ((end = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gv_currkey, TRUE)) == 0) end = &buff[MAX_ZWR_KEY_SZ - 1]; rts_error(VARLSTCNT(11) ERR_KEY2BIG, 4, n, (int4)gv_cur_region->max_key_size, REG_LEN_STR(gv_cur_region), 0, ERR_GVIS, 2, end - buff, buff); } gtcm_bind_name(reg_ref->reghead, TRUE); if (JNL_ENABLED(cs_addrs->hdr)) { cs_addrs->jnl->pini_addr = reg_ref->pini_addr; originator_prc_vec = curr_entry->pvec; } GET_USHORT(data_len, ptr); ptr += sizeof(short); v.str.len = data_len; v.str.addr = (char *)ptr; if (n + v.str.len + sizeof(rec_hdr) > gv_cur_region->max_rec_size) { if ((end = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gv_currkey, TRUE)) == 0) end = &buff[MAX_ZWR_KEY_SZ - 1]; rts_error(VARLSTCNT(11) ERR_REC2BIG, 4, n + v.str.len + sizeof(rec_hdr), (int4)gv_cur_region->max_rec_size, REG_LEN_STR(gv_cur_region), 0, ERR_GVIS, 2, end - buff, buff); } gvcst_put(&v); if (JNL_ENABLED(cs_addrs->hdr)) reg_ref->pini_addr = cs_addrs->jnl->pini_addr; /* In case journal switch occurred */ ptr += data_len; } ptr = curr_entry->clb_ptr->mbf; *ptr++ = CMMS_C_BUFFLUSH; curr_entry->clb_ptr->cbl = S_HDRSIZE; return TRUE; }
// process an incoming respawn info packet void multi_respawn_process_packet(ubyte *data, header *hinfo) { ubyte code,cur_link_status; char cur_primary_bank,cur_secondary_bank; ushort net_sig,ship_ets; short player_id; int player_index; vector v; char parse_name[1024] = ""; int offset = HEADER_LENGTH; // determine who send the packet player_index = find_player_id(hinfo->id); if(player_index == -1){ nprintf(("Network","Couldn't find player for processing respawn packet!\n")); } // get the opcode GET_DATA(code); // do something based upon the opcode switch((int)code){ case AI_RESPAWN_NOTICE: p_object *pobjp; GET_USHORT( net_sig ); pobjp = mission_parse_get_arrival_ship( net_sig ); Assert( pobjp != NULL ); multi_respawn_ai( pobjp ); break; case RESPAWN_BROADCAST: // get the respawn data GET_USHORT(net_sig); get_vector_data( data, &offset, v ); GET_SHORT(player_id); GET_DATA(cur_primary_bank); GET_DATA(cur_secondary_bank); GET_DATA(cur_link_status); GET_USHORT(ship_ets); GET_STRING(parse_name); player_index = find_player_id(player_id); if(player_index == -1){ nprintf(("Network","Couldn't find player to respawn!\n")); break; } // create the ship and assign its position, net_signature, and class // respawn the player multi_respawn_player(&Net_players[player_index], cur_primary_bank, cur_secondary_bank, cur_link_status, ship_ets, net_sig, parse_name, &v); // if this is for me, I should jump back into gameplay if(&Net_players[player_index] == Net_player){ extern int Player_multi_died_check; Player_multi_died_check = -1; gameseq_post_event(GS_EVENT_ENTER_GAME); } break; case RESPAWN_REQUEST: // determine whether he wants to respawn as an observer or not GET_DATA(code); nprintf(("Network","Received respawn request\n")); if(player_index == -1){ nprintf(("Network","Received respawn request from unknown player!\n")); break; } // make sure he's not making an invalid request if((code == 0) && !(Net_players[player_index].flags & NETINFO_FLAG_RESPAWNING)){ nprintf(("Network","Received respawn request from player who shouldn't be respawning!\n")); Int3(); break; } else if((code == 1) && !(Net_players[player_index].flags & NETINFO_FLAG_LIMBO)){ nprintf(("Network","Received respawn observer request from a player who shouldn't be respawning as an observer!\n")); Int3(); break; } // otherwise perform the operation // respawn the guy as an observer if(code){ multi_respawn_make_observer(&Net_players[player_index]); } // respawn him as normal else { // create his new ship, and change him from respawning to respawned Assert(Net_players[player_index].p_info.p_objp != NULL); if(Net_players[player_index].p_info.p_objp != NULL){ multi_respawn_player(&Net_players[player_index], Net_players[player_index].s_info.cur_primary_bank, Net_players[player_index].s_info.cur_secondary_bank,Net_players[player_index].s_info.cur_link_status, Net_players[player_index].s_info.ship_ets, 0, Net_players[player_index].p_info.p_objp->name); } } break; } PACKET_SET_SIZE(); }
int jnl_v11tov15(uchar_ptr_t jnl_buff, uint4 *jnl_len, uchar_ptr_t conv_buff, uint4 *conv_len, uint4 conv_bufsiz) { /* Convert a transaction from jnl version 11 (V4.2-002) to 15 (V.4.4-002) */ unsigned char *jb, *cb, *cstart, *jstart, rectype; int status, reclen; unsigned short key_len; unsigned int long_data_len, jlen, total_data, nzeros, conv_reclen, clen_without_sfx, total_key; jrec_prefix prefix; jrec_suffix suffix; seq_num jsno; jb = jnl_buff; cb = conv_buff; status = SS_NORMAL; jlen = *jnl_len; while (0 < jlen) { if (0 < (reclen = v11_jnl_record_length((jnl_record *)jb, jlen))) { if (reclen <= jlen) { rectype = REF_CHAR(jb + V11_JREC_TYPE_OFFSET); total_key = total_data = 0; assert(IS_REPLICATED(rectype)); if (IS_ZTP(rectype)) GTMASSERT; /* ZTP not supported */ if (IS_SET_KILL_ZKILL(rectype)) { GET_USHORT(key_len, jb + V11_JREC_PREFIX_SIZE + v11_jnl_fixed_size[rectype]); total_key = key_len + sizeof(unsigned short); if (IS_SET(rectype)) { GET_MSTR_LEN(long_data_len, jb + V11_JREC_PREFIX_SIZE + v11_jnl_fixed_size[rectype] + total_key); total_data = long_data_len + sizeof(mstr_len_t); } conv_reclen = JREC_PREFIX_SIZE + FIXED_UPD_RECLEN + total_key + total_data + JREC_SUFFIX_SIZE; conv_reclen = ROUND_UP2(conv_reclen, JNL_REC_START_BNDRY); } else if (IS_COM(rectype)) conv_reclen = JREC_PREFIX_SIZE + TCOM_RECLEN + JREC_SUFFIX_SIZE; clen_without_sfx = conv_reclen - JREC_SUFFIX_SIZE; if (cb - conv_buff + conv_reclen > conv_bufsiz) { repl_errno = EREPL_INTLFILTER_NOSPC; status = -1; break; } cstart = cb; jstart = jb; prefix.jrec_type = rectype; suffix.backptr = prefix.forwptr = conv_reclen; prefix.pini_addr = 0; prefix.time = 0; prefix.tn = 0; suffix.suffix_code = JNL_REC_SUFFIX_CODE; memcpy(cb, (unsigned char*)&prefix, JREC_PREFIX_SIZE); cb += JREC_PREFIX_SIZE; memcpy(cb, jb + V11_JREC_PREFIX_SIZE + V11_JNL_SEQNO_OFFSET, sizeof(seq_num)); cb += sizeof(seq_num); if (IS_SET_KILL_ZKILL(rectype)) { PUT_JNL_STR_LEN(cb, key_len); jb += (V11_JREC_PREFIX_SIZE + V11_MUMPS_NODE_OFFSET + sizeof(unsigned short)); if (IS_FENCED(rectype)) jb += TP_TOKEN_TID_SIZE; cb += sizeof(jnl_str_len_t); memcpy(cb, jb, key_len); cb += key_len; jb += key_len; if (IS_SET(rectype)) { PUT_MSTR_LEN(cb, long_data_len); cb += sizeof(mstr_len_t); jb += sizeof(mstr_len_t); memcpy(cb, jb, long_data_len); cb += long_data_len; } } else if (IS_COM(rectype)) { assert(JRT_TCOM == rectype); memset(cb, 0, TID_STR_SIZE); cb += TID_STR_SIZE; memcpy(cb, jb + V11_JREC_PREFIX_SIZE + V11_TCOM_PARTICIPANTS_OFFSET, sizeof(uint4)); cb += sizeof(uint4); } else assert(FALSE); nzeros = (cstart + clen_without_sfx - cb); if (nzeros > 0) { memset(cb, 0, nzeros); cb += nzeros; } jb = jstart + reclen; memcpy(cb, (unsigned char*)&suffix, JREC_SUFFIX_SIZE); cb += JREC_SUFFIX_SIZE; assert(cb == cstart + conv_reclen); jlen -= reclen; continue; } repl_errno = EREPL_INTLFILTER_INCMPLREC; status = -1; break; } repl_errno = EREPL_INTLFILTER_BADREC; status = -1; break; } assert(0 == jlen || -1 == status); *jnl_len = jb - jnl_buff; *conv_len = cb - conv_buff; return(status); }
static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size, LPCSTR lpszGrpFile, BOOL bModifiedFileName) { HLOCAL hGroup; INT i, seqnum; LPCSTR extension; LPCSTR lpszName; INT x, y, width, height, iconx, icony, nCmdShow; INT number_of_programs; BOOL bOverwriteFileOk; if (buffer[0] != 'P' || buffer[1] != 'M') return(0); if (buffer[2] == 'C' && buffer[3] == 'C') /* original with checksum */ bOverwriteFileOk = FALSE; else if (buffer[2] == 'X' && buffer[3] == 'X') /* modified without checksum */ bOverwriteFileOk = TRUE; else return(0); /* checksum = GET_USHORT(buffer, 4) (ignored) */ extension = buffer + GET_USHORT(buffer, 6); if (extension == buffer + size) extension = 0; else if (extension + 6 > buffer + size) return(0); nCmdShow = GET_USHORT(buffer, 8); x = GET_SHORT(buffer, 10); y = GET_SHORT(buffer, 12); width = GET_USHORT(buffer, 14); height = GET_USHORT(buffer, 16); iconx = GET_SHORT(buffer, 18); icony = GET_SHORT(buffer, 20); lpszName = buffer + GET_USHORT(buffer, 22); if (lpszName >= buffer + size) return(0); /* unknown bytes 24 - 31 ignored */ /* Unknown bytes should be: wLogPixelsX = GET_SHORT(buffer, 24); wLogPixelsY = GET_SHORT(buffer, 26); byBitsPerPixel = byte at 28; byPlanes = byte at 29; wReserved = GET_SHORT(buffer, 30); */ hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y, width, height, iconx, icony, bModifiedFileName, bOverwriteFileOk, TRUE); if (!hGroup) return(0); number_of_programs = GET_USHORT(buffer, 32); if (2 * number_of_programs + 34 > size) return(0); for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++) { LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i); if (program_ptr + 24 > buffer + size) return(0); if (!GET_USHORT(buffer, 34 + 2*i)) continue; if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum, extension, hGroup, lpszGrpFile)) { GROUP_DeleteGroup(hGroup); return(0); } } /* FIXME shouldn't be necessary */ GROUP_ShowGroupWindow(hGroup); return hGroup; }
mint gvcst_data(void) { blk_hdr_ptr_t bp; boolean_t do_rtsib; enum cdb_sc status; mint val; rec_hdr_ptr_t rp; unsigned short match, rsiz; srch_blk_status *bh; srch_hist *rt_history; sm_uc_ptr_t b_top; assert((gv_target->root < cs_addrs->ti->total_blks) || dollar_tlevel); T_BEGIN_READ_NONTP_OR_TP(ERR_GVDATAFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { /* The following code is duplicated in gvcst_dataget. Any changes here might need to be reflected there as well */ rt_history = gv_target->alt_hist; rt_history->h[0].blk_num = 0; if (cdb_sc_normal != (status = gvcst_search(gv_currkey, NULL))) { t_retry(status); continue; } bh = gv_target->hist.h; bp = (blk_hdr_ptr_t)bh->buffaddr; rp = (rec_hdr_ptr_t)(bh->buffaddr + bh->curr_rec.offset); b_top = bh->buffaddr + bp->bsiz; match = bh->curr_rec.match; do_rtsib = FALSE; if (gv_currkey->end + 1 == match) { val = 1; GET_USHORT(rsiz, &rp->rsiz); rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)rp + rsiz); if ((sm_uc_ptr_t)rp > b_top) { t_retry(cdb_sc_rmisalign); continue; } else if ((sm_uc_ptr_t)rp == b_top) do_rtsib = TRUE; else if (rp->cmpc >= gv_currkey->end) val += 10; } else if (match >= gv_currkey->end) val = 10; else { val = 0; if (rp == (rec_hdr_ptr_t)b_top) do_rtsib = TRUE; } if (do_rtsib && (cdb_sc_endtree != (status = gvcst_rtsib(rt_history, 0)))) { if ((cdb_sc_normal != status) || (cdb_sc_normal != (status = gvcst_search_blk(gv_currkey, rt_history->h)))) { t_retry(status); continue; } if (rt_history->h[0].curr_rec.match >= gv_currkey->end) { assert(1 >= val); val += 10; } } if (!dollar_tlevel) { if ((trans_num)0 == t_end(&gv_target->hist, 0 == rt_history->h[0].blk_num ? NULL : rt_history, TN_NOT_SPECIFIED)) continue; } else { status = tp_hist(0 == rt_history->h[0].blk_num ? NULL : rt_history); if (cdb_sc_normal != status) { t_retry(status); continue; } } INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_data, 1); return val; } }
static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size, LPCSTR program_ptr, INT seqnum, LPCSTR extension, HLOCAL hGroup, LPCSTR lpszGrpFile) { INT icontype; HICON hIcon; LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir; LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr; INT x, y, nIconIndex, iconANDsize, iconXORsize; INT nHotKey, nCmdShow; UINT width, height, planes, bpp; x = GET_SHORT(program_ptr, 0); y = GET_SHORT(program_ptr, 2); nIconIndex = GET_USHORT(program_ptr, 4); /* FIXME is this correct ?? */ icontype = GET_USHORT(program_ptr, 6); switch (icontype) { default: MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile, IDS_WARNING, MB_OK); case 0x048c: iconXORsize = GET_USHORT(program_ptr, 8); iconANDsize = GET_USHORT(program_ptr, 10) / 8; iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12); iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14); iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16); width = GET_USHORT(iconinfo_ptr, 4); height = GET_USHORT(iconinfo_ptr, 6); planes = GET_USHORT(iconinfo_ptr, 10); bpp = GET_USHORT(iconinfo_ptr, 11); break; case 0x000c: iconANDsize = GET_USHORT(program_ptr, 8); iconXORsize = GET_USHORT(program_ptr, 10); iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12); iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14); iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16); width = GET_USHORT(iconinfo_ptr, 4); height = GET_USHORT(iconinfo_ptr, 6); planes = GET_USHORT(iconinfo_ptr, 10); bpp = GET_USHORT(iconinfo_ptr, 11); } if (iconANDbits_ptr + iconANDsize > buffer + size || iconXORbits_ptr + iconXORsize > buffer + size) return(0); hIcon = CreateIcon( Globals.hInstance, width, height, planes, bpp, iconANDbits_ptr, iconXORbits_ptr ); lpszName = buffer + GET_USHORT(program_ptr, 18); lpszCmdLine = buffer + GET_USHORT(program_ptr, 20); lpszIconFile = buffer + GET_USHORT(program_ptr, 22); if (iconinfo_ptr + 6 > buffer + size || lpszName > buffer + size || lpszCmdLine > buffer + size || lpszIconFile > buffer + size) return(0); /* Scan Extensions */ lpszWorkDir = ""; nHotKey = 0; nCmdShow = SW_SHOWNORMAL; if (extension) { LPCSTR ptr = extension; while (ptr + 6 <= buffer + size) { UINT type = GET_USHORT(ptr, 0); UINT number = GET_USHORT(ptr, 2); UINT skip = GET_USHORT(ptr, 4); if (number == seqnum) { switch (type) { case 0x8000: if (ptr + 10 > buffer + size) return(0); if (ptr[6] != 'P' || ptr[7] != 'M' || ptr[8] != 'C' || ptr[9] != 'C') return(0); break; case 0x8101: lpszWorkDir = ptr + 6; break; case 0x8102: if (ptr + 8 > buffer + size) return(0); nHotKey = GET_USHORT(ptr, 6); break; case 0x8103: if (ptr + 8 > buffer + size) return(0); nCmdShow = GET_USHORT(ptr, 6); break; default: MAIN_MessageBoxIDS_s(IDS_UNKNOWN_FEATURE_s, lpszGrpFile, IDS_WARNING, MB_OK); } } if (!skip) break; ptr += skip; } } return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y, lpszCmdLine, lpszIconFile, nIconIndex, lpszWorkDir, nHotKey, nCmdShow)); }
void gvcst_root_search(void) { srch_blk_status *h0; uchar_ptr_t c, c1; sm_uc_ptr_t rp; unsigned short rlen, hdr_len; uchar_ptr_t subrec_ptr; enum cdb_sc status; boolean_t gbl_target_was_set; gv_namehead *save_targ; mname_entry *gvent; int altkeylen; assert((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth)); assert(gv_altkey->top == gv_currkey->top); assert(gv_altkey->top == gv_keysize); assert(gv_currkey->end < gv_currkey->top); for (c = gv_altkey->base, c1 = gv_currkey->base; *c1;) *c++ = *c1++; *c++ = 0; *c = 0; gv_altkey->end = c - gv_altkey->base; assert(gv_altkey->end < gv_altkey->top); assert(gv_target != cs_addrs->dir_tree); save_targ = gv_target; /* Check if "gv_target->gvname" matches "gv_altkey->base". If not, there is a name mismatch (out-of-design situation). * This check is temporary until we catch the situation that caused D9H02-002641 */ /* --- Check BEGIN --- */ gvent = &save_targ->gvname; altkeylen = gv_altkey->end - 1; if (!altkeylen || (altkeylen != gvent->var_name.len) || memcmp(gv_altkey->base, gvent->var_name.addr, gvent->var_name.len)) GTMASSERT; /* --- Check END --- */ if (INVALID_GV_TARGET != reset_gv_target) gbl_target_was_set = TRUE; else { gbl_target_was_set = FALSE; reset_gv_target = save_targ; } gv_target = cs_addrs->dir_tree; if (is_standalone) /* *&& (0 != gv_target->clue.end) && (FALSE == is_valid_hist(&gv_target->hist))) */ gv_target->clue.end = 0; T_BEGIN_READ_NONTP_OR_TP(ERR_GVGETFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { hdr_len = rlen = 0; gv_target = cs_addrs->dir_tree; if (dollar_trestart) gv_target->clue.end = 0; if (cdb_sc_normal == (status = gvcst_search(gv_altkey, 0))) { if (gv_altkey->end + 1 == gv_target->hist.h[0].curr_rec.match) { h0 = gv_target->hist.h; rp = (h0->buffaddr + h0->curr_rec.offset); hdr_len = sizeof(rec_hdr) + gv_altkey->end + 1 - ((rec_hdr_ptr_t)rp)->cmpc; GET_USHORT(rlen, rp); if (FALSE == (CHKRECLEN(rp, h0->buffaddr, rlen)) || (rlen < hdr_len + sizeof(block_id))) { gv_target->clue.end = 0; RESET_GV_TARGET_LCL(save_targ); t_retry(cdb_sc_rmisalign); continue; } GET_LONG(save_targ->root, (rp + hdr_len)); if (rlen > hdr_len + sizeof(block_id)) { assert(NULL != global_collation_mstr.addr || 0 == global_collation_mstr.len); if (global_collation_mstr.len < rlen - (hdr_len + sizeof(block_id))) { if (NULL != global_collation_mstr.addr) free(global_collation_mstr.addr); global_collation_mstr.len = rlen - (hdr_len + SIZEOF(block_id)); global_collation_mstr.addr = (char *)malloc(global_collation_mstr.len); } /* the memcpy needs to be done here instead of out of for loop for * concurrency consideration. We don't use s2pool because the pointer rp is 64 bits */ memcpy(global_collation_mstr.addr, rp + hdr_len + sizeof(block_id), rlen - (hdr_len + sizeof(block_id))); } if (0 != dollar_tlevel) { status = tp_hist(NULL); if (cdb_sc_normal != status) { gv_target->clue.end = 0; RESET_GV_TARGET_LCL(save_targ); gv_target->root = 0; t_retry(status); continue; } break; } } if (0 == dollar_tlevel) { if ((trans_num)0 != t_end(&gv_target->hist, 0)) break; } else { status = tp_hist(NULL); if (cdb_sc_normal == status) break; gv_target->clue.end = 0; RESET_GV_TARGET_LCL(save_targ); gv_target->root = 0; t_retry(status); continue; } save_targ->root = 0; } else { gv_target->clue.end = 0; RESET_GV_TARGET_LCL(save_targ); t_retry(status); continue; } } RESET_GV_TARGET_LCL_AND_CLR_GBL(save_targ); if (rlen > hdr_len + sizeof(block_id)) { assert(NULL != global_collation_mstr.addr); subrec_ptr = get_spec((uchar_ptr_t)global_collation_mstr.addr, (int)(rlen - (hdr_len + sizeof(block_id))), COLL_SPEC); if (subrec_ptr) { gv_target->nct = *(subrec_ptr + COLL_NCT_OFFSET); gv_target->act = *(subrec_ptr + COLL_ACT_OFFSET); gv_target->ver = *(subrec_ptr + COLL_VER_OFFSET); } else { gv_target->nct = 0; gv_target->act = 0; gv_target->ver = 0; } } else { gv_target->nct = 0; gv_target->act = cs_addrs->hdr->def_coll; gv_target->ver = cs_addrs->hdr->def_coll_ver; } if (gv_target->act) act_in_gvt(); assert(gv_target->act || NULL == gv_target->collseq); return; }
enum cdb_sc gvcst_kill_blk(srch_blk_status *blkhist, char level, gv_key *search_key, srch_rec_status low, srch_rec_status high, boolean_t right_extra, cw_set_element **cseptr) { typedef sm_uc_ptr_t bytptr; unsigned short temp_ushort; int4 temp_long; int tmp_cmpc; int blk_size, blk_seg_cnt, lmatch, rmatch, targ_len, prev_len, targ_base, next_rec_shrink, temp_int, blkseglen; bool kill_root, first_copy; blk_hdr_ptr_t old_blk_hdr; rec_hdr_ptr_t left_ptr; /*pointer to record before first record to delete*/ rec_hdr_ptr_t del_ptr; /*pointer to first record to delete*/ rec_hdr_ptr_t right_ptr; /*pointer to record after last record to delete*/ rec_hdr_ptr_t right_prev_ptr; rec_hdr_ptr_t rp, rp1; /*scratch record pointer*/ rec_hdr_ptr_t first_in_blk, top_of_block, new_rec_hdr, star_rec_hdr; blk_segment *bs1, *bs_ptr; block_index new_block_index; unsigned char *skb; static readonly block_id zeroes = 0; cw_set_element *cse, *old_cse; bytptr curr, prev, right_bytptr; off_chain chain1, curr_chain, prev_chain; block_id blk; sm_uc_ptr_t buffer; srch_blk_status *t1; *cseptr = NULL; if (low.offset == high.offset) return cdb_sc_normal; blk = blkhist->blk_num; if (dollar_tlevel) { PUT_LONG(&chain1, blk); if ((1 == chain1.flag) && ((int)chain1.cw_index >= sgm_info_ptr->cw_set_depth)) { assert(sgm_info_ptr->tp_csa == cs_addrs); assert(FALSE == cs_addrs->now_crit); return cdb_sc_blknumerr; } } buffer = blkhist->buffaddr; old_blk_hdr = (blk_hdr_ptr_t)buffer; kill_root = FALSE; blk_size = cs_data->blk_size; first_in_blk = (rec_hdr_ptr_t)((bytptr)old_blk_hdr + SIZEOF(blk_hdr)); top_of_block = (rec_hdr_ptr_t)((bytptr)old_blk_hdr + old_blk_hdr->bsiz); left_ptr = (rec_hdr_ptr_t)((bytptr)old_blk_hdr + low.offset); right_ptr = (rec_hdr_ptr_t)((bytptr)old_blk_hdr + high.offset); if (right_extra && right_ptr < top_of_block) { right_prev_ptr = right_ptr; GET_USHORT(temp_ushort, &right_ptr->rsiz); right_ptr = (rec_hdr_ptr_t)((bytptr)right_ptr + temp_ushort); } if ((bytptr)left_ptr < (bytptr)old_blk_hdr || (bytptr)right_ptr > (bytptr)top_of_block || (bytptr)left_ptr >= (bytptr)right_ptr) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } if ((bytptr)left_ptr == (bytptr)old_blk_hdr) { if ((bytptr)right_ptr == (bytptr)top_of_block) { if ((bytptr)first_in_blk == (bytptr)top_of_block) { if (0 != level) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } return cdb_sc_normal; } if (!gv_target->hist.h[level + 1].blk_num) kill_root = TRUE; else { /* We are about to free up the contents of this entire block. If this block corresponded to * a global that has NOISOLATION turned on and has a non-zero recompute list (i.e. some SETs * already happened in this same TP transaction), make sure we disable the NOISOLATION * optimization in this case as that is applicable only if one or more SETs happened in this * data block and NOT if a KILL happens. Usually this is done by a t_write(GDS_WRITE_KILLTN) * call but since in this case the entire block is being freed, "t_write" wont be invoked * so we need to explicitly set GDS_WRITE_KILLTN like t_write would have (GTM-8269). * Note: blkhist->first_tp_srch_status is not reliable outside of TP. Thankfully the recompute * list is also maintained only in case of TP so a check of dollar_tlevel is enough to * dereference both "first_tp_srch_status" and "recompute_list_head". */ if (dollar_tlevel) { t1 = blkhist->first_tp_srch_status ? blkhist->first_tp_srch_status : blkhist; cse = t1->cse; if ((NULL != cse) && cse->recompute_list_head) cse->write_type |= GDS_WRITE_KILLTN; } return cdb_sc_delete_parent; } } del_ptr = first_in_blk; } else { GET_USHORT(temp_ushort, &left_ptr->rsiz); del_ptr = (rec_hdr_ptr_t)((bytptr)left_ptr + temp_ushort); if ((bytptr)del_ptr <= (bytptr)(left_ptr + 1) || (bytptr)del_ptr > (bytptr)right_ptr) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } } if ((bytptr)del_ptr == (bytptr)right_ptr) return cdb_sc_normal; lmatch = low.match; rmatch = high.match; if (level) { for (rp = del_ptr ; rp < right_ptr ; rp = rp1) { GET_USHORT(temp_ushort, &rp->rsiz); rp1 = (rec_hdr_ptr_t)((bytptr)rp + temp_ushort); if (((bytptr)rp1 < (bytptr)(rp + 1) + SIZEOF(block_id)) || ((bytptr)rp1 < buffer) || ((bytptr)rp1 > (buffer + blk_size))) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } GET_LONG(temp_long, ((bytptr)rp1 - SIZEOF(block_id))); if (dollar_tlevel) { chain1 = *(off_chain *)&temp_long; if ((1 == chain1.flag) && ((int)chain1.cw_index >= sgm_info_ptr->cw_set_depth)) { assert(sgm_info_ptr->tp_csa == cs_addrs); assert(FALSE == cs_addrs->now_crit); return cdb_sc_blknumerr; } } gvcst_delete_blk(temp_long, level - 1, FALSE); } } if (kill_root) { /* create an empty data block */ BLK_INIT(bs_ptr, bs1); if (!BLK_FINI(bs_ptr, bs1)) { assert(CDB_STAGNATE > t_tries); return cdb_sc_mkblk; } new_block_index = t_create(blk, (uchar_ptr_t)bs1, 0, 0, 0); /* create index block */ BLK_ADDR(new_rec_hdr, SIZEOF(rec_hdr), rec_hdr); new_rec_hdr->rsiz = SIZEOF(rec_hdr) + SIZEOF(block_id); SET_CMPC(new_rec_hdr, 0); BLK_INIT(bs_ptr, bs1); BLK_SEG(bs_ptr, (bytptr)new_rec_hdr, SIZEOF(rec_hdr)); BLK_SEG(bs_ptr, (bytptr)&zeroes, SIZEOF(block_id)); if (!BLK_FINI(bs_ptr, bs1)) { assert(CDB_STAGNATE > t_tries); return cdb_sc_mkblk; } cse = t_write(blkhist, (unsigned char *)bs1, SIZEOF(blk_hdr) + SIZEOF(rec_hdr), new_block_index, 1, TRUE, FALSE, GDS_WRITE_KILLTN); assert(!dollar_tlevel || !cse->high_tlevel); *cseptr = cse; if (NULL != cse) cse->first_off = 0; return cdb_sc_normal; } next_rec_shrink = (int)(old_blk_hdr->bsiz + ((bytptr)del_ptr - (bytptr)right_ptr)); if (SIZEOF(blk_hdr) >= next_rec_shrink) { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } if ((bytptr)right_ptr == (bytptr)top_of_block) { if (level) { GET_USHORT(temp_ushort, &left_ptr->rsiz); next_rec_shrink += SIZEOF(rec_hdr) + SIZEOF(block_id) - temp_ushort; } } else { targ_base = (rmatch < lmatch) ? rmatch : lmatch; prev_len = 0; if (right_extra) { EVAL_CMPC2(right_prev_ptr, tmp_cmpc); targ_len = tmp_cmpc - targ_base; if (targ_len < 0) targ_len = 0; temp_int = tmp_cmpc - EVAL_CMPC(right_ptr); if (0 >= temp_int) prev_len = - temp_int; else { if (temp_int < targ_len) targ_len -= temp_int; else targ_len = 0; } } else { targ_len = EVAL_CMPC(right_ptr) - targ_base; if (targ_len < 0) targ_len = 0; } next_rec_shrink += targ_len + prev_len; } BLK_INIT(bs_ptr, bs1); first_copy = TRUE; blkseglen = (int)((bytptr)del_ptr - (bytptr)first_in_blk); if (0 < blkseglen) { if (((bytptr)right_ptr != (bytptr)top_of_block) || (0 == level)) { BLK_SEG(bs_ptr, (bytptr)first_in_blk, blkseglen); first_copy = FALSE; } else { blkseglen = (int)((bytptr)left_ptr - (bytptr)first_in_blk); if (0 < blkseglen) { BLK_SEG(bs_ptr, (bytptr)first_in_blk, blkseglen); first_copy = FALSE; } BLK_ADDR(star_rec_hdr, SIZEOF(rec_hdr), rec_hdr); SET_CMPC(star_rec_hdr, 0); star_rec_hdr->rsiz = (unsigned short)(SIZEOF(rec_hdr) + SIZEOF(block_id)); BLK_SEG(bs_ptr, (bytptr)star_rec_hdr, SIZEOF(rec_hdr)); GET_USHORT(temp_ushort, &left_ptr->rsiz); BLK_SEG(bs_ptr, ((bytptr)left_ptr + temp_ushort - SIZEOF(block_id)), SIZEOF(block_id)); } } blkseglen = (int)((bytptr)top_of_block - (bytptr)right_ptr); assert(0 <= blkseglen); if (0 != blkseglen) { next_rec_shrink = targ_len + prev_len; if (0 >= next_rec_shrink) { BLK_SEG(bs_ptr, (bytptr)right_ptr, blkseglen); } else { BLK_ADDR(new_rec_hdr, SIZEOF(rec_hdr), rec_hdr); SET_CMPC(new_rec_hdr, EVAL_CMPC(right_ptr) - next_rec_shrink); GET_USHORT(temp_ushort, &right_ptr->rsiz); new_rec_hdr->rsiz = temp_ushort + next_rec_shrink; BLK_SEG(bs_ptr, (bytptr)new_rec_hdr, SIZEOF(rec_hdr)); if (targ_len) { BLK_ADDR(skb, targ_len, unsigned char); memcpy(skb, &search_key->base[targ_base], targ_len); BLK_SEG(bs_ptr, skb, targ_len); } if (prev_len) BLK_SEG(bs_ptr, (bytptr)(right_prev_ptr + 1) , prev_len); right_bytptr = (bytptr)(right_ptr + 1); blkseglen = (int)((bytptr)top_of_block - right_bytptr); if (0 < blkseglen) { BLK_SEG(bs_ptr, right_bytptr, blkseglen); } else { assert(CDB_STAGNATE > t_tries); return cdb_sc_rmisalign; } } } if (!BLK_FINI(bs_ptr, bs1)) { assert(CDB_STAGNATE > t_tries); return cdb_sc_mkblk; } cse = t_write(blkhist, (unsigned char *)bs1, 0, 0, level, first_copy, TRUE, GDS_WRITE_KILLTN); assert(!dollar_tlevel || !cse->high_tlevel); *cseptr = cse; if (horiz_growth) { old_cse = cse->low_tlevel; assert(old_cse && old_cse->done); assert(2 == (SIZEOF(old_cse->undo_offset) / SIZEOF(old_cse->undo_offset[0]))); assert(2 == (SIZEOF(old_cse->undo_next_off) / SIZEOF(old_cse->undo_next_off[0]))); assert(!old_cse->undo_next_off[0] && !old_cse->undo_offset[0]); assert(!old_cse->undo_next_off[1] && !old_cse->undo_offset[1]); } if ((NULL != cse) && (0 != cse->first_off)) { /* fix up chains in the block to account for deleted records */ prev = NULL; curr = buffer + cse->first_off; GET_LONGP(&curr_chain, curr); while (curr < (bytptr)del_ptr) { /* follow chain to first deleted record */ if (0 == curr_chain.next_off) break; if (right_ptr == top_of_block && (bytptr)del_ptr - curr == SIZEOF(off_chain)) break; /* special case described below: stop just before the first deleted record */ prev = curr; curr += curr_chain.next_off; GET_LONGP(&curr_chain, curr); } if (right_ptr == top_of_block && (bytptr)del_ptr - curr == SIZEOF(off_chain)) { /* if the right side of the block is gone and our last chain is in the last record, * terminate the chain and adjust the previous entry to point at the new *-key * NOTE: this assumes there's NEVER a TP delete of records in the GVT */ assert(0 != level); /* store next_off in old_cse before actually changing it in the buffer(for rolling back) */ if (horiz_growth) { old_cse->undo_next_off[0] = curr_chain.next_off; old_cse->undo_offset[0] = (block_offset)(curr - buffer); assert(old_cse->undo_offset[0]); } curr_chain.next_off = 0; GET_LONGP(curr, &curr_chain); if (NULL != prev) { /* adjust previous chain next_off to reflect the fact that the record it refers to is now a *-key */ GET_LONGP(&prev_chain, prev); /* store next_off in old_cse before actually changing it in the buffer(for rolling back) */ if (horiz_growth) { old_cse->undo_next_off[1] = prev_chain.next_off; old_cse->undo_offset[1] = (block_offset)(prev - buffer); assert(old_cse->undo_offset[1]); } prev_chain.next_off = (unsigned int)((bytptr)left_ptr - prev + (unsigned int)(SIZEOF(rec_hdr))); GET_LONGP(prev, &prev_chain); } else /* it's the first (and only) one */ cse->first_off = (block_offset)((bytptr)left_ptr - buffer + SIZEOF(rec_hdr)); } else if (curr >= (bytptr)del_ptr) { /* may be more records on the right that aren't deleted */ while (curr < (bytptr)right_ptr) { /* follow chain past last deleted record */ if (0 == curr_chain.next_off) break; curr += curr_chain.next_off; GET_LONGP(&curr_chain, curr); } /* prev : ptr to chain record immediately preceding the deleted area, * or 0 if none. * * curr : ptr to chain record immediately following the deleted area, * or to last chain record. */ if (curr < (bytptr)right_ptr) { /* the former end of the chain is going, going, gone */ if (NULL != prev) { /* terminate the chain before the delete */ GET_LONGP(&prev_chain, prev); /* store next_off in old_cse before actually changing it in the buffer(for rolling back) */ if (horiz_growth) { old_cse->undo_next_off[0] = prev_chain.next_off; old_cse->undo_offset[0] = (block_offset)(prev - buffer); assert(old_cse->undo_offset[0]); } prev_chain.next_off = 0; GET_LONGP(prev, &prev_chain); } else cse->first_off = 0; /* the whole chain is gone */ } else { /* stitch up the left and right to account for the hole in the middle */ /* next_rec_shrink is the change in record size due to the new compression count */ if (NULL != prev) { GET_LONGP(&prev_chain, prev); /* ??? new compression may be less (ie +) so why are negative shrinks ignored? */ /* store next_off in old_cse before actually changing it in the buffer(for rolling back) */ if (horiz_growth) { old_cse->undo_next_off[0] = prev_chain.next_off; old_cse->undo_offset[0] = (block_offset)(prev - buffer); assert(old_cse->undo_offset[0]); } prev_chain.next_off = (unsigned int)(curr - prev - ((bytptr)right_ptr - (bytptr)del_ptr) + (next_rec_shrink > 0 ? next_rec_shrink : 0)); GET_LONGP(prev, &prev_chain); } else /* curr remains first: adjust the head */ cse->first_off = (block_offset)(curr - buffer - ((bytptr)right_ptr - (bytptr)del_ptr) + (next_rec_shrink > 0 ? next_rec_shrink : 0)); } } } horiz_growth = FALSE; return cdb_sc_normal; }
void iorm_use(io_desc *iod, mval *pp) { unsigned char c; int4 width, length, blocksize; int4 status; d_rm_struct *rm_ptr; struct RAB *r; struct FAB *f; int p_offset; boolean_t shared_seen = FALSE; error_def(ERR_DEVPARMNEG); error_def(ERR_RMWIDTHPOS); error_def(ERR_RMWIDTHTOOBIG); error_def(ERR_RMNOBIGRECORD); error_def(ERR_RMBIGSHARE); error_def(ERR_MTBLKTOOBIG); error_def(ERR_MTBLKTOOSM); p_offset = 0; rm_ptr = (d_rm_struct *)iod->dev_sp; r = &rm_ptr->r; f = &rm_ptr->f; assert(r->rab$l_fab == f); while (*(pp->str.addr + p_offset) != iop_eol) { assert(*(pp->str.addr + p_offset) < n_iops); switch ((c = *(pp->str.addr + p_offset++))) { case iop_allocation: if (iod->state != dev_open) f->fab$l_alq = *(int4*)(pp->str.addr + p_offset); break; case iop_append: if (iod->state != dev_open) r->rab$l_rop |= RAB$M_EOF; break; case iop_blocksize: if (iod->state != dev_open) { GET_LONG(blocksize, pp->str.addr + p_offset); if (MAX_RMS_ANSI_BLOCK < blocksize) rts_error(VARLSTCNT(1) ERR_MTBLKTOOBIG); else if (MIN_RMS_ANSI_BLOCK > blocksize) rts_error(VARLSTCNT(3) ERR_MTBLKTOOSM, 1, MIN_RMS_ANSI_BLOCK); else f->fab$w_bls = (unsigned short)blocksize; } break; case iop_contiguous: if (iod->state != dev_open) { f->fab$l_fop &= ~FAB$M_CBT; f->fab$l_fop |= FAB$M_CTG; } break; case iop_delete: f->fab$l_fop |= FAB$M_DLT; break; case iop_extension: GET_USHORT(f->fab$w_deq, pp->str.addr + p_offset); break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = pp->str.addr + p_offset + 1; s2pool(&iod->error_handler); break; case iop_fixed: if (iod->state != dev_open) rm_ptr->f.fab$b_rfm = rm_ptr->b_rfm = FAB$C_FIX; break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (length < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); iod->length = length; break; case iop_newversion: if (iod->state != dev_open) { f->fab$l_fop |= FAB$M_MXV; f->fab$l_fop &= ~(FAB$M_CIF | FAB$M_SUP); } break; case iop_nosequential: break; case iop_s_protection: rm_ptr->promask &= ~(0x0F << XAB$V_SYS); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_SYS); break; case iop_w_protection: rm_ptr->promask &= ~(0x0F << XAB$V_WLD); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_WLD); break; case iop_g_protection: rm_ptr->promask &= ~(0x0F << XAB$V_GRP); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_GRP); break; case iop_o_protection: rm_ptr->promask &= ~(0x0F << XAB$V_OWN); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_OWN); break; case iop_readonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET; break; case iop_noreadonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_TRN; break; case iop_recordsize: if (iod->state != dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); iod->width = width; if (MAX_RMS_RECORDSIZE >= width) r->rab$w_usz = f->fab$w_mrs = (unsigned short)width; else if (MAX_STRLEN < width) rts_error(VARLSTCNT(1) ERR_RMWIDTHTOOBIG); else if (!rm_ptr->largerecord) rts_error(VARLSTCNT(1) ERR_RMNOBIGRECORD); rm_ptr->l_usz = rm_ptr->l_mrs = width; } break; case iop_shared: if (iod->state != dev_open) shared_seen = TRUE; break; case iop_spool: f->fab$l_fop |= FAB$M_SPL; break; case iop_submit: f->fab$l_fop |= FAB$M_SCF; break; case iop_rfa: break; case iop_space: if (iod->state == dev_open && f->fab$l_dev & DEV$M_SQD) { GET_LONG(r->rab$l_bkt, pp->str.addr + p_offset); if ((status = sys$space(r, 0, 0)) != RMS$_NORMAL) rts_error(VARLSTCNT(1) status); r->rab$l_bkt = 0; } break; case iop_uic: { unsigned char *ch, ct, *end; uic_struct uic; struct XABPRO *xabpro; ch = pp->str.addr + p_offset; ct = *ch++; end = ch + ct; uic.grp = uic.mem = 0; xabpro = malloc(SIZEOF(struct XABPRO)); *xabpro = cc$rms_xabpro; /* g,m are octal - no matter currently since iorm_open overwrites fab xab */ while (*ch != ',' && ch < end) uic.grp = (10 * uic.grp) + (*ch++ - '0'); if (*ch == ',') { while (++ch < end) uic.mem = (10 * uic.mem) + (*ch - '0'); } xabpro->xab$l_uic = *((int4 *)&uic); f->fab$l_xab = xabpro; break; } case iop_width: if (iod->state == dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); else if (width <= rm_ptr->l_mrs) { iorm_flush(iod); rm_ptr->l_usz = iod->width = width; if (!rm_ptr->largerecord) r->rab$w_usz = (short)width; iod->wrap = TRUE; } } break; case iop_wrap: iod->wrap = TRUE; break; case iop_nowrap: iod->wrap = FALSE; break; case iop_convert: r->rab$l_rop |= RAB$M_CVT; break; case iop_rewind: if (iod->state == dev_open && rm_ptr->f.fab$l_dev & DEV$M_FOD) { if (iod->dollar.zeof && rm_ptr->outbuf_pos > rm_ptr->outbuf) iorm_wteol(1, iod); sys$rewind(r); iod->dollar.zeof = FALSE; iod->dollar.y = 0; iod->dollar.x = 0; rm_ptr->outbuf_pos = rm_ptr->outbuf; rm_ptr->r.rab$l_ctx = FAB$M_GET; } break; case iop_truncate: r->rab$l_rop |= RAB$M_TPT; break; case iop_notruncate: r->rab$l_rop &= ~RAB$M_TPT; break; case iop_bigrecord: if (iod->state != dev_open) rm_ptr->largerecord = TRUE; break; case iop_nobigrecord: if (iod->state != dev_open) { if (MAX_RMS_RECORDSIZE < rm_ptr->l_mrs) rts_error(ERR_RMNOBIGRECORD); rm_ptr->largerecord = FALSE; } break; case iop_rfm: break; default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]); } if (shared_seen) { f->fab$b_shr = FAB$M_SHRGET; if (rm_ptr->largerecord) { if (f->fab$b_fac & FAB$M_PUT) { rts_error(VARLSTCNT(1) ERR_RMBIGSHARE); } } else if ((f->fab$b_fac & FAB$M_PUT) == FALSE) f->fab$b_shr |= FAB$M_SHRPUT; } }/* eor */
mint gvcst_data(void) { blk_hdr_ptr_t bp; enum cdb_sc status; mint val; rec_hdr_ptr_t rp; unsigned short rec_size; srch_blk_status *bh; srch_hist *rt_history; sm_uc_ptr_t b_top; assert((gv_target->root < cs_addrs->ti->total_blks) || (0 < dollar_tlevel)); T_BEGIN_READ_NONTP_OR_TP(ERR_GVDATAFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { rt_history = gv_target->alt_hist; rt_history->h[0].blk_num = 0; if ((status = gvcst_search(gv_currkey, NULL)) != cdb_sc_normal) { t_retry(status); continue; } bh = gv_target->hist.h; bp = (blk_hdr_ptr_t)bh->buffaddr; rp = (rec_hdr_ptr_t)(bh->buffaddr + bh->curr_rec.offset); b_top = bh->buffaddr + bp->bsiz; val = 0; if (gv_currkey->end + 1 == bh->curr_rec.match) val = 1; else if (bh->curr_rec.match >= gv_currkey->end) val = 10; if (1 == val || rp == (rec_hdr_ptr_t)b_top) { GET_USHORT(rec_size, &rp->rsiz); if (rp == (rec_hdr_ptr_t)b_top || (sm_uc_ptr_t)rp + rec_size == b_top) { if (cdb_sc_endtree != (status = gvcst_rtsib(rt_history, 0))) { if ((cdb_sc_normal != status) || (cdb_sc_normal != (status = gvcst_search_blk(gv_currkey, rt_history->h)))) { t_retry(status); continue; } if (rt_history->h[0].curr_rec.match >= gv_currkey->end) val += 10; } } else { if ((sm_uc_ptr_t)rp + rec_size > b_top) { t_retry(cdb_sc_rmisalign); continue; } rp = (rec_hdr_ptr_t)((sm_uc_ptr_t)rp + rec_size); if (rp->cmpc >= gv_currkey->end) val += 10; } } if (0 == dollar_tlevel) { if ((trans_num)0 == t_end(&gv_target->hist, 0 == rt_history->h[0].blk_num ? NULL : rt_history)) continue; } else { status = tp_hist(0 == rt_history->h[0].blk_num ? NULL : rt_history); if (cdb_sc_normal != status) { t_retry(status); continue; } } INCR_GVSTATS_COUNTER(cs_addrs, cs_addrs->nl, n_data, 1); return val; } }
boolean_t gvcst_gblmod(mval *v) { boolean_t gblmod, is_dummy; enum cdb_sc status; int key_size, key_size2, data_len; srch_hist *alt_history; blk_hdr_ptr_t bp; rec_hdr_ptr_t rp; unsigned short match, match2, rsiz, offset_to_value, oldend; srch_blk_status *bh; sm_uc_ptr_t b_top; trans_num tn_to_compare; T_BEGIN_READ_NONTP_OR_TP(ERR_GBLMODFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { gblmod = TRUE; if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL))) { alt_history = gv_target->alt_hist; alt_history->h[0].blk_num = 0; VMS_ONLY( if (cs_addrs->hdr->resync_tn >= ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->tn) gblmod = FALSE; ) # ifdef UNIX tn_to_compare = ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->tn; bh = gv_target->hist.h; bp = (blk_hdr_ptr_t) bh->buffaddr; rp = (rec_hdr_ptr_t) (bh->buffaddr + bh->curr_rec.offset); b_top = bh->buffaddr + bp->bsiz; GET_USHORT(rsiz, &rp->rsiz); key_size = gv_currkey->end + 1; data_len = rsiz + EVAL_CMPC(rp) - SIZEOF(rec_hdr) - key_size; match = bh->curr_rec.match; if (key_size == match) { if ((0 > data_len) || ((sm_uc_ptr_t)rp + rsiz > b_top)) { status = cdb_sc_rmisalign1; t_retry(status); continue; } offset_to_value = SIZEOF(rec_hdr) + key_size - EVAL_CMPC(rp); /* If it could be a spanning node, i.e., has special value, then try to get tn from the * block that contains the first special subscript. Since dummy nodes always have the * same value, the tn number is not updated It s enough to do only the first piece * since all pieces of a spanning node are killed before an update is applied. */ if (IS_SN_DUMMY(data_len, (sm_uc_ptr_t)rp + offset_to_value)) { oldend = gv_currkey->end; APPEND_HIDDEN_SUB(gv_currkey); if (cdb_sc_normal == (status = gvcst_search(gv_currkey, alt_history))) { key_size2 = gv_currkey->end + 1; match = alt_history->h[0].curr_rec.match; if (key_size2 == match) tn_to_compare = ((blk_hdr_ptr_t)alt_history->h[0].buffaddr)->tn; } else { gv_currkey->end = oldend; gv_currkey->base[gv_currkey->end - 1] = KEY_DELIMITER; gv_currkey->base[gv_currkey->end] = KEY_DELIMITER; t_retry(status); continue; } gv_currkey->end = oldend; gv_currkey->base[gv_currkey->end - 1] = KEY_DELIMITER; gv_currkey->base[gv_currkey->end] = KEY_DELIMITER; } } if (cs_addrs->hdr->zqgblmod_tn > tn_to_compare) gblmod = FALSE; # endif if (!dollar_tlevel) { if ((trans_num)0 == t_end(&gv_target->hist, 0 == alt_history->h[0].blk_num ? NULL : alt_history, TN_NOT_SPECIFIED)) continue; } else { status = tp_hist(0 == alt_history->h[0].blk_num ? NULL : alt_history); if (cdb_sc_normal != status) { t_retry(status); continue; } } return gblmod; }
void bin_load(uint4 begin, uint4 end) { unsigned char *ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop, *ptr_base; unsigned char hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1], sn_key_str[MAX_KEY_SZ + 1], *sn_key_str_end; unsigned char *end_buff; unsigned short rec_len, next_cmpc, numsubs; int len; int current, last, length, max_blk_siz, max_key, status; int tmp_cmpc, sn_chunk_number, expected_sn_chunk_number = 0, sn_hold_buff_pos, sn_hold_buff_size; uint4 iter, max_data_len, max_subsc_len, key_count, gblsize; ssize_t rec_count, global_key_count, subsc_len,extr_std_null_coll, last_sn_error_offset=0, file_offset_base=0, file_offset=0; boolean_t need_xlation, new_gvn, utf8_extract; boolean_t is_hidden_subscript, ok_to_put = TRUE, putting_a_sn = FALSE, sn_incmp_gbl_already_killed = FALSE; rec_hdr *rp, *next_rp; mval v, tmp_mval; mstr mstr_src, mstr_dest; collseq *extr_collseq, *db_collseq, *save_gv_target_collseq; coll_hdr extr_collhdr, db_collhdr; gv_key *tmp_gvkey = NULL; /* null-initialize at start, will be malloced later */ gv_key *sn_gvkey = NULL; /* null-initialize at start, will be malloced later */ gv_key *sn_savekey = NULL; /* null-initialize at start, will be malloced later */ char std_null_coll[BIN_HEADER_NUMSZ + 1], *sn_hold_buff = NULL, *sn_hold_buff_temp = NULL; # ifdef GTM_CRYPT gtmcrypt_key_t *encr_key_handles; char *inbuf; int4 index; int req_dec_blk_size, init_status, crypt_status; muext_hash_hdr_ptr_t hash_array = NULL; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(4 == SIZEOF(coll_hdr)); gvinit(); v.mvtype = MV_STR; len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); hdr_lvl = EXTR_HEADER_LEVEL(ptr); if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (V5_BIN_HEADER_SZ == len)) || (('6' == hdr_lvl) && (BIN_HEADER_SZ == len)) || (('7' == hdr_lvl) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len)))) { rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* expecting the level in a single character */ assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3)); if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION_ENCR) < hdr_lvl) { /* ignore the level check */ rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* check if extract was generated in UTF-8 mode */ utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_exit(ERR_LDBINFMT); } if ('4' >= hdr_lvl) { /* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte) * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above. */ for (c = ptr, ctop = c + len; c < ctop; c++) { if ('\0' == *c) *c = ' '; } } util_out_print("Label = !AD\n", TRUE, len, ptr); new_gvn = FALSE; if (hdr_lvl > '3') { if (hdr_lvl > '5') { memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ); std_null_coll[BIN_HEADER_NUMSZ] = '\0'; } else { memcpy(std_null_coll, ptr + V5_BIN_HEADER_NULLCOLLOFFSET, V5_BIN_HEADER_NUMSZ); std_null_coll[V5_BIN_HEADER_NUMSZ] = '\0'; } extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10); if (0 != extr_std_null_coll && 1!= extr_std_null_coll) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } } else extr_std_null_coll = 0; # ifdef GTM_CRYPT if ('7' <= hdr_lvl) { int i, num_indexes; len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); hash_array = (muext_hash_hdr *)malloc(len); /* store hashes of all the files used during extract into muext_hash_hdr structure */ memcpy((char *)hash_array, ptr, len); num_indexes = len / GTMCRYPT_HASH_LEN; encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes); INIT_PROC_ENCRYPTION(crypt_status); GC_BIN_LOAD_ERR(crypt_status); for (index = 0; index < num_indexes; index++) { if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN)) continue; GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status); GC_BIN_LOAD_ERR(crypt_status); } } # endif if ('2' < hdr_lvl) { len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base); if (SIZEOF(coll_hdr) != len) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } extr_collhdr = *((coll_hdr *)(ptr)); new_gvn = TRUE; } else gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0'); if (begin < 2) begin = 2; for (iter = 2; iter < begin; iter++) { if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base))) { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); util_out_print("Error reading record number: !UL\n", TRUE, iter); mupip_error_occurred = TRUE; return; } else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); iter--; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; global_key_count = key_count = 0; rec_count = begin - 1; extr_collseq = db_collseq = NULL; need_xlation = FALSE; assert(NULL == tmp_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* tmp_gvkey will point to malloced memory after this */ assert(NULL == sn_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(sn_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* sn_gvkey will point to malloced memory after this */ assert(NULL == sn_savekey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(sn_savekey, DBKEYSIZE(MAX_KEY_SZ)); /* sn_gvkey will point to malloced memory after this */ for (; !mupip_DB_full ;) { if (++rec_count > end) break; next_cmpc = 0; mupip_error_occurred = FALSE; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } if (!(len = file_input_bin_get((char **)&ptr, &file_offset_base, (char **)&ptr_base)) || mupip_error_occurred) break; else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); new_gvn = TRUE; /* next record will contain a new gvn */ rec_count--; /* Decrement as this record does not count as a record for loading purposes */ continue; } rp = (rec_hdr*)(ptr); # ifdef GTM_CRYPT if ('7' <= hdr_lvl) { /* Getting index value from the extracted file. It indicates which database file this record belongs to */ GET_LONG(index, ptr); if (-1 != index) /* Indicates that the record is encrypted. */ { req_dec_blk_size = len - SIZEOF(int4); inbuf = (char *)(ptr + SIZEOF(int4)); GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status); GC_BIN_LOAD_ERR(crypt_status); } rp = (rec_hdr*)(ptr + SIZEOF(int4)); } # endif btop = ptr + len; cp1 = (unsigned char*)(rp + 1); v.str.addr = (char*)cp1; while (*cp1++) ; v.str.len =INTCAST((char*)cp1 - v.str.addr - 1); if (('2' >= hdr_lvl) || new_gvn) { if ((HASHT_GBLNAME_LEN == v.str.len) && (0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN))) continue; bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str); max_key = gv_cur_region->max_key_size; db_collhdr.act = gv_target->act; db_collhdr.ver = gv_target->ver; db_collhdr.nct = gv_target->nct; } GET_USHORT(rec_len, &rp->rsiz); if (EVAL_CMPC(rp) != 0 || v.str.len > rec_len || mupip_error_occurred) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; continue; } if (new_gvn) { global_key_count = 1; if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver || db_collhdr.nct != extr_collhdr.nct || gv_cur_region->std_null_coll != extr_std_null_coll)) { if (extr_collhdr.act) { if (extr_collseq = ready_collseq((int)extr_collhdr.act)) { if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act, extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } if (db_collhdr.act) { if (db_collseq = ready_collseq((int)db_collhdr.act)) { if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } need_xlation = TRUE; } else need_xlation = FALSE; } new_gvn = FALSE; for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len)) { GET_USHORT(rec_len, &rp->rsiz); if (rec_len + (unsigned char *)rp > btop) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; break; } cp1 = (unsigned char*)(rp + 1); cp2 = gv_currkey->base + EVAL_CMPC(rp); current = 1; for (;;) { last = current; current = *cp2++ = *cp1++; if (0 == last && 0 == current) break; if (cp1 > (unsigned char *)rp + rec_len || cp2 > (unsigned char *)gv_currkey + gv_currkey->top) { gv_currkey->end = cp2 - gv_currkey->base - 1; gv_currkey->base[gv_currkey->end] = 0; gv_currkey->base[gv_currkey->end - 1] = 0; bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; break; } } if (mupip_error_occurred) break; gv_currkey->end = cp2 - gv_currkey->base - 1; if (need_xlation) { assert(hdr_lvl >= '3'); assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll); /* gv_currkey would have been modified/translated in the earlier put */ memcpy(gv_currkey->base, cmpc_str, next_cmpc); next_rp = (rec_hdr *)((unsigned char*)rp + rec_len); if ((unsigned char*)next_rp < btop) { next_cmpc = EVAL_CMPC(next_rp); assert(next_cmpc <= gv_currkey->end); memcpy(cmpc_str, gv_currkey->base, next_cmpc); } else next_cmpc = 0; /* length of the key might change (due to nct variation), * so get a copy of the original key from the extract */ memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1); gvkey_char_ptr = dup_key_str; while (*gvkey_char_ptr++) ; gv_currkey->prev = 0; gv_currkey->end = gvkey_char_ptr - dup_key_str; assert(gv_keysize <= tmp_gvkey->top); while (*gvkey_char_ptr) { /* get next subscript (in GT.M internal subsc format) */ subsc_len = 0; tmp_ptr = src_buff; while (*gvkey_char_ptr) *tmp_ptr++ = *gvkey_char_ptr++; subsc_len = tmp_ptr - src_buff; src_buff[subsc_len] = '\0'; if (extr_collseq) { /* undo the extract time collation */ TREF(transform) = TRUE; save_gv_target_collseq = gv_target->collseq; gv_target->collseq = extr_collseq; } else TREF(transform) = FALSE; /* convert the subscript to string format */ end_buff = gvsub2str(src_buff, dest_buff, FALSE); /* transform the string to the current subsc format */ TREF(transform) = TRUE; tmp_mval.mvtype = MV_STR; tmp_mval.str.addr = (char *)dest_buff; tmp_mval.str.len = INTCAST(end_buff - dest_buff); tmp_gvkey->prev = 0; tmp_gvkey->end = 0; if (extr_collseq) gv_target->collseq = save_gv_target_collseq; mval2subsc(&tmp_mval, tmp_gvkey); /* we now have the correctly transformed subscript */ tmp_key_ptr = gv_currkey->base + gv_currkey->end; memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1); gv_currkey->prev = gv_currkey->end; gv_currkey->end += tmp_gvkey->end; gvkey_char_ptr++; } if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev) { if (extr_std_null_coll == 0) { GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end); } else { STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end); } } } if (gv_currkey->end >= max_key) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); DISPLAY_FILE_OFFSET_OF_RECORD_AND_REST_OF_BLOCK; continue; } /* * Spanning node-related variables and their usage: * * expected_sn_chunk_number: 0 - looking for spanning nodes (regular nodes are OK, too) * !0 - number of the next chunk needed (implies we are building * a spanning node's value) * * While building a spanning node's value: * numsubs: the number of chunks needed to build the spanning node's value * gblsize: the expected size of the completed value * sn_chunk_number: The chunk number of the chunk from the current record from the extract * * Managing the value * sn_hold_buff: buffer used to accumulate the spanning node's value * sn_hold_buff_size: Allocated size of buffer * sn_hold_buff_pos: amount of the buffer used; where to place the next chunk * sn_hold_buff_temp: used when we have to increase the size of the buffer * * Controlling the placing of the key,value in the database: * ok_to_put: means we are ready to place the key,value in the database, i.e., we have the full value * (either of the spanning node or a regular node). * putting_a_sn: we are placing a spanning node in the database, i.e, use the key from sn_gvkey and * the value from sn_hold_buff. */ CHECK_HIDDEN_SUBSCRIPT(gv_currkey,is_hidden_subscript); if (!is_hidden_subscript && (max_subsc_len < (gv_currkey->end + 1))) max_subsc_len = gv_currkey->end + 1; v.str.addr = (char*)cp1; v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp)); if (expected_sn_chunk_number && !is_hidden_subscript) { /* we were expecting a chunk of an spanning node and we did not get one */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected chunk number : !UL but found a non-spanning node", TRUE, expected_sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; sn_hold_buff_pos = 0; expected_sn_chunk_number = 0; ok_to_put = TRUE; putting_a_sn = FALSE; numsubs = 0; } if (is_hidden_subscript) { /* it's a chunk and we were expecting one */ sn_chunk_number = SPAN_GVSUBS2INT((span_subs *) &(gv_currkey->base[gv_currkey->end - 4])); if (!expected_sn_chunk_number && is_hidden_subscript && sn_chunk_number) { /* we not expecting a payload chunk (as opposed to a control record) but we got one */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Not expecting a spanning node chunk but found chunk : !UL", TRUE, sn_chunk_number + 1); if (v.str.len) DISPLAY_VALUE("!_!_Errant Chunk :"); continue; } if (0 == sn_chunk_number) { /* first spanning node chunk, get ctrl info */ if (0 != expected_sn_chunk_number) { DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", TRUE, expected_sn_chunk_number + 1, sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; } /* start building a new spanning node */ sn_gvkey->end = gv_currkey->end - (SPAN_SUBS_LEN + 1); memcpy(sn_gvkey->base, gv_currkey->base, sn_gvkey->end); sn_gvkey->base[sn_gvkey->end] = 0; sn_gvkey->prev = gv_currkey->prev; sn_gvkey->top = gv_currkey->top; GET_NSBCTRL(v.str.addr, numsubs, gblsize); /* look for first payload chunk */ expected_sn_chunk_number = 1; sn_hold_buff_pos = 0; ok_to_put = FALSE; sn_incmp_gbl_already_killed = FALSE; } else { /* we only need to compare the key before the hidden subscripts */ if ((expected_sn_chunk_number == sn_chunk_number) && (sn_gvkey->end == gv_currkey->end - (SPAN_SUBS_LEN + 1)) && !memcmp(sn_gvkey->base,gv_currkey->base, sn_gvkey->end) && ((sn_hold_buff_pos + v.str.len) <= gblsize)) { if (NULL == sn_hold_buff) { sn_hold_buff_size = DEFAULT_SN_HOLD_BUFF_SIZE; sn_hold_buff = (char *)malloc(DEFAULT_SN_HOLD_BUFF_SIZE); } if ((sn_hold_buff_pos + v.str.len) > sn_hold_buff_size) { sn_hold_buff_size = sn_hold_buff_size * 2; sn_hold_buff_temp = (char *)malloc(sn_hold_buff_size); memcpy(sn_hold_buff_temp, sn_hold_buff, sn_hold_buff_pos); free (sn_hold_buff); sn_hold_buff = sn_hold_buff_temp; } memcpy(sn_hold_buff + sn_hold_buff_pos, v.str.addr, v.str.len); sn_hold_buff_pos += v.str.len; if (expected_sn_chunk_number == numsubs) { if (sn_hold_buff_pos != gblsize) { /* we don't have the expected size even though */ /* we have all the expected chunks. */ DISPLAY_INCMP_SN_MSG; util_out_print("!_!_Expected size : !UL actual size : !UL", TRUE, gblsize, sn_hold_buff_pos); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; KILL_INCMP_SN_IF_NEEDED; expected_sn_chunk_number = 0; ok_to_put = FALSE; sn_hold_buff_pos = 0; } else { expected_sn_chunk_number = 0; ok_to_put = TRUE; putting_a_sn = TRUE; } }else expected_sn_chunk_number++; }else { DISPLAY_INCMP_SN_MSG; if ((sn_hold_buff_pos + v.str.len) <= gblsize) util_out_print("!_!_Expected chunk number : !UL but found chunk number : !UL", /*BYPASSOK*/ TRUE, expected_sn_chunk_number + 1, sn_chunk_number + 1); else util_out_print("!_!_Global value too large: expected size : !UL actual size : !UL chunk number : !UL", TRUE, /*BYPASSOK*/ gblsize, sn_hold_buff_pos + v.str.len, sn_chunk_number + 1); if (sn_hold_buff_pos) DISPLAY_PARTIAL_SN_HOLD_BUFF; if (v.str.len) DISPLAY_VALUE("!_!_Errant Chunk :"); KILL_INCMP_SN_IF_NEEDED; sn_hold_buff_pos = 0; expected_sn_chunk_number = 0; } } } else ok_to_put = TRUE; if (ok_to_put) { if (putting_a_sn) { gv_currkey->base[gv_currkey->end - (SPAN_SUBS_LEN + 1)] = 0; gv_currkey->end -= (SPAN_SUBS_LEN + 1); v.str.addr = sn_hold_buff; v.str.len = sn_hold_buff_pos; } if (max_data_len < v.str.len) max_data_len = v.str.len; bin_call_db(BIN_PUT, (INTPTR_T)&v, 0); if (mupip_error_occurred) { if (!mupip_DB_full) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); file_offset = file_offset_base + ((unsigned char *)rp - ptr_base); util_out_print("!_!_at File offset : [0x!XL]", TRUE, file_offset); DISPLAY_CURRKEY; DISPLAY_VALUE("!_!_Value :"); } break; } if (putting_a_sn) putting_a_sn = FALSE; else { key_count++; global_key_count++; } } } } GTMCRYPT_ONLY( if (NULL != hash_array) free(hash_array); )
cm_region_head *gtcmd_ini_reg(connection_struct *cnx) { cm_region_head *ptr,*last; struct stat stat_buf; unsigned char *fname, buff[256]; unsigned short len; uint4 status, retlen; unsigned char node[MAX_HOST_NAME_LEN]; sgmnt_addrs *csa; error_def (ERR_DBOPNERR); ptr = 0; fname = cnx->clb_ptr->mbf; fname++; GET_USHORT(len, fname); /* len = *((unsigned short *)fname); */ fname += sizeof(unsigned short); buff[len] = 0; memcpy(buff, fname, len); STAT_FILE((char *)buff, &stat_buf, status); if (-1 == status) rts_error(VARLSTCNT(5) ERR_DBOPNERR, 2, len, fname, errno); last = reglist; for (ptr = reglist ; ptr ; ptr = ptr->next) { if (is_gdid_stat_identical(&FILE_INFO(ptr->reg)->fileid, &stat_buf)) break; last = ptr; } if (!ptr) { /* open region */ ptr = (cm_region_head*)malloc(sizeof(*ptr)); ptr->next = NULL; ptr->last = NULL; ptr->head.fl = ptr->head.bl = 0; SET_LATCH_GLOBAL(&ptr->head.latch, LOCK_AVAILABLE); if (!last) reglist = ptr; else { last->next = ptr; ptr->last = last; } mu_gv_cur_reg_init(); ptr->reg = gv_cur_region; ptr->refcnt = 0; ptr->wakeup = 0; ptr->reg->open = FALSE; csa = &FILE_INFO(ptr->reg)->s_addrs; csa->now_crit = FALSE; csa->nl = (node_local_ptr_t)malloc(sizeof(node_local)); assert(MAX_FN_LEN > len); memcpy(ptr->reg->dyn.addr->fname, fname, len); ptr->reg->dyn.addr->fname_len = len; set_gdid_from_stat(&FILE_INFO(ptr->reg)->fileid, &stat_buf); ptr->reg_hash = (htab_desc *)malloc(sizeof(htab_desc)); if (-1 != gethostname((char *)node, sizeof(node))) { retlen = strlen((char *)node); retlen = MIN(retlen, MAX_RN_LEN - 1); memcpy(ptr->reg->rname, node, retlen); } else retlen = 0; ptr->reg->rname[retlen] = ':'; ptr->reg->rname_len = retlen + 1; gtcmd_cst_init(ptr); } else if (!ptr->reg->open) { gv_cur_region = ptr->reg; ptr->wakeup = 0; /* Because going to reinit ctl->wakeups when open region */ gtcmd_cst_init(ptr); } else gv_cur_region = ptr->reg; return ptr; }
void bin_load(uint4 begin, uint4 end) { unsigned char *ptr, *cp1, *cp2, *btop, *gvkey_char_ptr, *tmp_ptr, *tmp_key_ptr, *c, *ctop; unsigned char hdr_lvl, src_buff[MAX_KEY_SZ + 1], dest_buff[MAX_ZWR_KEY_SZ], cmpc_str[MAX_KEY_SZ + 1], dup_key_str[MAX_KEY_SZ + 1]; unsigned char *end_buff; unsigned short rec_len, next_cmpc; int len; int current, last, length, max_blk_siz, max_key, status; uint4 iter, max_data_len, max_subsc_len, key_count; ssize_t rec_count, global_key_count, subsc_len,extr_std_null_coll; boolean_t need_xlation, new_gvn, utf8_extract; rec_hdr *rp, *next_rp; mval v, tmp_mval; mstr mstr_src, mstr_dest; collseq *extr_collseq, *db_collseq, *save_gv_target_collseq; coll_hdr extr_collhdr, db_collhdr; gv_key *tmp_gvkey = NULL; /* null-initialize at start, will be malloced later */ char std_null_coll[BIN_HEADER_NUMSZ + 1]; # ifdef GTM_CRYPT gtmcrypt_key_t *encr_key_handles; char *inbuf; int4 index; int req_dec_blk_size, init_status, crypt_status; muext_hash_hdr_ptr_t hash_array = NULL; # endif DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(4 == SIZEOF(coll_hdr)); gvinit(); v.mvtype = MV_STR; len = file_input_bin_get((char **)&ptr); hdr_lvl = EXTR_HEADER_LEVEL(ptr); if (!(((('4' == hdr_lvl) || ('5' == hdr_lvl)) && (BIN_HEADER_SZ == len)) || (('4' > hdr_lvl) && (V3_BIN_HEADER_SZ == len)))) { rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* expecting the level in a single character */ assert(' ' == *(ptr + SIZEOF(BIN_HEADER_LABEL) - 3)); if (0 != memcmp(ptr, BIN_HEADER_LABEL, SIZEOF(BIN_HEADER_LABEL) - 2) || ('2' > hdr_lvl) || *(BIN_HEADER_VERSION) < hdr_lvl) { /* ignore the level check */ rts_error(VARLSTCNT(1) ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } /* check if extract was generated in UTF-8 mode */ utf8_extract = (0 == MEMCMP_LIT(&ptr[len - BIN_HEADER_LABELSZ], UTF8_NAME)) ? TRUE : FALSE; if ((utf8_extract && !gtm_utf8_mode) || (!utf8_extract && gtm_utf8_mode)) { /* extract CHSET doesn't match $ZCHSET */ if (utf8_extract) rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("UTF-8")); else rts_error(VARLSTCNT(4) ERR_LOADINVCHSET, 2, LEN_AND_LIT("M")); mupip_exit(ERR_LDBINFMT); } if ('4' >= hdr_lvl) { /* Binary extracts in V50000-to-V52000 (label=4) and pre-V50000 (label=3) could have a '\0' byte (NULL byte) * in the middle of the string. Replace it with ' ' (space) like it would be in V52000 binary extracts and above. */ for (c = ptr, ctop = c + len; c < ctop; c++) { if ('\0' == *c) *c = ' '; } } util_out_print("Label = !AD\n", TRUE, len, ptr); new_gvn = FALSE; if (hdr_lvl > '3') { memcpy(std_null_coll, ptr + BIN_HEADER_NULLCOLLOFFSET, BIN_HEADER_NUMSZ); std_null_coll[BIN_HEADER_NUMSZ] = '\0'; extr_std_null_coll = STRTOUL(std_null_coll, NULL, 10); if (0 != extr_std_null_coll && 1!= extr_std_null_coll) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupted null collation field in header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } } else extr_std_null_coll = 0; # ifdef GTM_CRYPT if ('5' <= hdr_lvl) { int i, num_indexes; len = file_input_bin_get((char **)&ptr); hash_array = (muext_hash_hdr *)malloc(len); /* store hashes of all the files used during extract into muext_hash_hdr structure */ memcpy((char *)hash_array, ptr, len); num_indexes = len / GTMCRYPT_HASH_LEN; encr_key_handles = (gtmcrypt_key_t *)malloc(SIZEOF(gtmcrypt_key_t) * num_indexes); INIT_PROC_ENCRYPTION(crypt_status); GC_BIN_LOAD_ERR(crypt_status); for (index = 0; index < num_indexes; index++) { if (0 == memcmp(hash_array[index].gtmcrypt_hash, EMPTY_GTMCRYPT_HASH, GTMCRYPT_HASH_LEN)) continue; GTMCRYPT_GETKEY(hash_array[index].gtmcrypt_hash, encr_key_handles[index], crypt_status); GC_BIN_LOAD_ERR(crypt_status); } } # endif if ('2' < hdr_lvl) { len = file_input_bin_get((char **)&ptr); if (SIZEOF(coll_hdr) != len) { rts_error(VARLSTCNT(5) ERR_TEXT, 2, RTS_ERROR_TEXT("Corrupt collation header"), ERR_LDBINFMT); mupip_exit(ERR_LDBINFMT); } extr_collhdr = *((coll_hdr *)(ptr)); new_gvn = TRUE; } else gtm_putmsg(VARLSTCNT(3) ERR_OLDBINEXTRACT, 1, hdr_lvl - '0'); if (begin < 2) begin = 2; for (iter = 2; iter < begin; iter++) { if (!(len = file_input_bin_get((char **)&ptr))) { gtm_putmsg(VARLSTCNT(3) ERR_LOADEOF, 1, begin); util_out_print("Error reading record number: !UL\n", TRUE, iter); mupip_error_occurred = TRUE; return; } else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); iter--; } } assert(iter == begin); util_out_print("Beginning LOAD at record number: !UL\n", TRUE, begin); max_data_len = 0; max_subsc_len = 0; global_key_count = key_count = 0; rec_count = begin - 1; extr_collseq = db_collseq = NULL; need_xlation = FALSE; assert(NULL == tmp_gvkey); /* GVKEY_INIT macro relies on this */ GVKEY_INIT(tmp_gvkey, DBKEYSIZE(MAX_KEY_SZ)); /* tmp_gvkey will point to malloced memory after this */ for (; !mupip_DB_full ;) { if (++rec_count > end) break; next_cmpc = 0; mupip_error_occurred = FALSE; if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { util_out_print("!AD:!_ Key cnt: !UL max subsc len: !UL max data len: !UL", TRUE, LEN_AND_LIT(gt_lit), key_count, max_subsc_len, max_data_len); util_out_print("Last LOAD record number: !UL", TRUE, key_count ? (rec_count - 1) : 0); mu_gvis(); util_out_print(0, TRUE); mu_ctrlc_occurred = FALSE; } /* reset the stringpool for every record in order to avoid garbage collection */ stringpool.free = stringpool.base; if (!(len = file_input_bin_get((char **)&ptr)) || mupip_error_occurred) break; else if (len == SIZEOF(coll_hdr)) { extr_collhdr = *((coll_hdr *)(ptr)); assert(hdr_lvl > '2'); new_gvn = TRUE; /* next record will contain a new gvn */ rec_count--; /* Decrement as this record does not count as a record for loading purposes */ continue; } rp = (rec_hdr*)(ptr); # ifdef GTM_CRYPT if ('5' <= hdr_lvl) { /* Getting index value from the extracted file. It indicates which database file this record belongs to */ GET_LONG(index, ptr); if (-1 != index) /* Indicates that the record is encrypted. */ { req_dec_blk_size = len - SIZEOF(int4); inbuf = (char *)(ptr + SIZEOF(int4)); GTMCRYPT_DECODE_FAST(encr_key_handles[index], inbuf, req_dec_blk_size, NULL, crypt_status); GC_BIN_LOAD_ERR(crypt_status); } rp = (rec_hdr*)(ptr + SIZEOF(int4)); } # endif btop = ptr + len; cp1 = (unsigned char*)(rp + 1); v.str.addr = (char*)cp1; while (*cp1++) ; v.str.len =INTCAST((char*)cp1 - v.str.addr - 1); if (('2' >= hdr_lvl) || new_gvn) { if ((HASHT_GBLNAME_LEN == v.str.len) && (0 == memcmp(v.str.addr, HASHT_GBLNAME, HASHT_GBLNAME_LEN))) continue; bin_call_db(BIN_BIND, (INTPTR_T)gd_header, (INTPTR_T)&v.str); max_key = gv_cur_region->max_key_size; db_collhdr.act = gv_target->act; db_collhdr.ver = gv_target->ver; db_collhdr.nct = gv_target->nct; } GET_USHORT(rec_len, &rp->rsiz); if (rp->cmpc != 0 || v.str.len > rec_len || mupip_error_occurred) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (new_gvn) { global_key_count = 1; if ((db_collhdr.act != extr_collhdr.act || db_collhdr.ver != extr_collhdr.ver || db_collhdr.nct != extr_collhdr.nct || gv_cur_region->std_null_coll != extr_std_null_coll)) { if (extr_collhdr.act) { if (extr_collseq = ready_collseq((int)extr_collhdr.act)) { if (!do_verify(extr_collseq, extr_collhdr.act, extr_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, extr_collhdr.act, extr_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, extr_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } if (db_collhdr.act) { if (db_collseq = ready_collseq((int)db_collhdr.act)) { if (!do_verify(db_collseq, db_collhdr.act, db_collhdr.ver)) { gtm_putmsg(VARLSTCNT(8) ERR_COLLTYPVERSION, 2, db_collhdr.act, db_collhdr.ver, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLTYPVERSION); } } else { gtm_putmsg(VARLSTCNT(7) ERR_COLLATIONUNDEF, 1, db_collhdr.act, ERR_GVIS, 2, gv_altkey->end - 1, gv_altkey->base); mupip_exit(ERR_COLLATIONUNDEF); } } need_xlation = TRUE; } else need_xlation = FALSE; } new_gvn = FALSE; for (; rp < (rec_hdr*)btop; rp = (rec_hdr*)((unsigned char *)rp + rec_len)) { GET_USHORT(rec_len, &rp->rsiz); if (rec_len + (unsigned char *)rp > btop) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } cp1 = (unsigned char*)(rp + 1); cp2 = gv_currkey->base + rp->cmpc; current = 1; for (;;) { last = current; current = *cp2++ = *cp1++; if (0 == last && 0 == current) break; if (cp1 > (unsigned char *)rp + rec_len || cp2 > (unsigned char *)gv_currkey + gv_currkey->top) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); break; } } if (mupip_error_occurred) break; gv_currkey->end = cp2 - gv_currkey->base - 1; if (need_xlation) { assert(hdr_lvl >= '3'); assert(extr_collhdr.act || db_collhdr.act || extr_collhdr.nct || db_collhdr.nct || extr_std_null_coll != gv_cur_region->std_null_coll); /* gv_currkey would have been modified/translated in the earlier put */ memcpy(gv_currkey->base, cmpc_str, next_cmpc); next_rp = (rec_hdr *)((unsigned char*)rp + rec_len); if ((unsigned char*)next_rp < btop) { next_cmpc = next_rp->cmpc; assert(next_cmpc <= gv_currkey->end); memcpy(cmpc_str, gv_currkey->base, next_cmpc); } else next_cmpc = 0; /* length of the key might change (due to nct variation), * so get a copy of the original key from the extract */ memcpy(dup_key_str, gv_currkey->base, gv_currkey->end + 1); gvkey_char_ptr = dup_key_str; while (*gvkey_char_ptr++) ; gv_currkey->prev = 0; gv_currkey->end = gvkey_char_ptr - dup_key_str; assert(gv_keysize <= tmp_gvkey->top); while (*gvkey_char_ptr) { /* get next subscript (in GT.M internal subsc format) */ subsc_len = 0; tmp_ptr = src_buff; while (*gvkey_char_ptr) *tmp_ptr++ = *gvkey_char_ptr++; subsc_len = tmp_ptr - src_buff; src_buff[subsc_len] = '\0'; if (extr_collseq) { /* undo the extract time collation */ TREF(transform) = TRUE; save_gv_target_collseq = gv_target->collseq; gv_target->collseq = extr_collseq; } else TREF(transform) = FALSE; /* convert the subscript to string format */ end_buff = gvsub2str(src_buff, dest_buff, FALSE); /* transform the string to the current subsc format */ TREF(transform) = TRUE; tmp_mval.mvtype = MV_STR; tmp_mval.str.addr = (char *)dest_buff; tmp_mval.str.len = INTCAST(end_buff - dest_buff); tmp_gvkey->prev = 0; tmp_gvkey->end = 0; if (extr_collseq) gv_target->collseq = save_gv_target_collseq; mval2subsc(&tmp_mval, tmp_gvkey); /* we now have the correctly transformed subscript */ tmp_key_ptr = gv_currkey->base + gv_currkey->end; memcpy(tmp_key_ptr, tmp_gvkey->base, tmp_gvkey->end + 1); gv_currkey->prev = gv_currkey->end; gv_currkey->end += tmp_gvkey->end; gvkey_char_ptr++; } if ( gv_cur_region->std_null_coll != extr_std_null_coll && gv_currkey->prev) { if (extr_std_null_coll == 0) { GTM2STDNULLCOLL(gv_currkey->base, gv_currkey->end); } else { STD2GTMNULLCOLL(gv_currkey->base, gv_currkey->end); } } } if (gv_currkey->end >= max_key) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); mu_gvis(); util_out_print(0, TRUE); continue; } if (max_subsc_len < (gv_currkey->end + 1)) max_subsc_len = gv_currkey->end + 1; v.str.addr = (char*)cp1; v.str.len =INTCAST(rec_len - (cp1 - (unsigned char *)rp)); if (max_data_len < v.str.len) max_data_len = v.str.len; bin_call_db(BIN_PUT, (INTPTR_T)&v, 0); if (mupip_error_occurred) { if (!mupip_DB_full) { bin_call_db(ERR_COR, (INTPTR_T)rec_count, (INTPTR_T)global_key_count); util_out_print(0, TRUE); } break; } key_count++; global_key_count++; } } GTMCRYPT_ONLY( if (NULL != hash_array) free(hash_array); )
int jnl_v11tov12(uchar_ptr_t jnl_buff, uint4 *jnl_len, uchar_ptr_t conv_buff, uint4 *conv_len, uint4 conv_bufsiz) { /* Convert a transaction from jnl version 11 (V4.2-FT10/V4.2-002) to 12 post V4.2-002 */ /* Differences between ver 11, and 12 : * 11 12 *------------------------------------------------------------------------------------------------------------ * {tcom,ztcom}.participants NA Shifted by 8 bytes due to * addition of orig_tc_short_time * {tcom,ztcom}.ts_short_time same as above * An addtional field orig_ts_short_time is added. */ unsigned char *jb, *cb, *cstart, *jstart, rectype; int status, reclen; unsigned short key_len; unsigned int long_data_len, data_len, jlen, total_data, nzeros, conv_reclen, clen_without_sfx, total_key; boolean_t is_set, is_com; jb = jnl_buff; cb = conv_buff; status = SS_NORMAL; jlen = *jnl_len; while (0 < jlen) { if (0 < (reclen = v11_jnl_record_length((jnl_record *)jb, jlen))) { if (reclen <= jlen) { rectype = REF_CHAR(jb + V11_JREC_TYPE_OFFSET); is_set = is_com = FALSE; total_key = total_data = 0; if ((is_set = (JRT_SET == rectype || JRT_TSET == rectype || JRT_USET == rectype || JRT_FSET == rectype || JRT_GSET == rectype)) || (JRT_KILL == rectype || JRT_TKILL == rectype || JRT_UKILL == rectype || JRT_FKILL == rectype || JRT_GKILL == rectype) || (JRT_ZKILL == rectype || JRT_FZKILL == rectype || JRT_GZKILL == rectype || JRT_TZKILL == rectype || JRT_UZKILL == rectype)) { GET_USHORT(key_len, jb + V11_JREC_PREFIX_SIZE + v11_jnl_fixed_size[rectype]); total_key = key_len + sizeof(unsigned short); if (is_set) { GET_MSTR_LEN(long_data_len, jb + V11_JREC_PREFIX_SIZE + v11_jnl_fixed_size[rectype] + total_key); total_data = long_data_len + sizeof(mstr_len_t); } } if (JRT_TCOM == rectype || JRT_ZTCOM == rectype) is_com = TRUE; assert(V11_JNL_REC_START_BNDRY == V12_JNL_REC_START_BNDRY); assert(V11_JREC_PREFIX_SIZE == V12_JREC_PREFIX_SIZE); clen_without_sfx = ROUND_UP(V11_JREC_PREFIX_SIZE + v12_jnl_fixed_size[rectype] + total_key + total_data, V12_JNL_REC_START_BNDRY); conv_reclen = clen_without_sfx + V12_JREC_SUFFIX_SIZE; if (cb - conv_buff + conv_reclen > conv_bufsiz) { repl_errno = EREPL_INTLFILTER_NOSPC; status = -1; break; } cstart = cb; jstart = jb; memcpy(cb, jb, V12_JREC_PREFIX_SIZE + V12_MUMPS_NODE_OFFSET); /* copy pini_addr and short_time */ cb += (V12_JREC_PREFIX_SIZE + V12_MUMPS_NODE_OFFSET); *(uint4 *)(cstart + V12_JREC_PREFIX_SIZE + V11_MUMPS_NODE_OFFSET) = 0;/* don't care */ jb += (V11_JREC_PREFIX_SIZE + V11_MUMPS_NODE_OFFSET); if ((JRT_TSET == rectype || JRT_USET == rectype || JRT_FSET == rectype || JRT_GSET == rectype) || (JRT_TKILL == rectype || JRT_UKILL == rectype || JRT_FKILL == rectype || JRT_GKILL == rectype) || (JRT_FZKILL == rectype || JRT_GZKILL == rectype || JRT_TZKILL == rectype || JRT_UZKILL == rectype)) { memcpy(cb, jb, TP_TOKEN_TID_SIZE); cb += TP_TOKEN_TID_SIZE; jb += TP_TOKEN_TID_SIZE; } memcpy(cb, jb, total_key); cb += total_key; jb += total_key; if (is_set) { /* copy all the data after short time till the mumps_node */ data_len = long_data_len; PUT_MSTR_LEN(cb, data_len); cb += sizeof(mstr_len_t); jb += sizeof(mstr_len_t); memcpy(cb, jb, data_len); cb += data_len; jb += data_len; } else if (is_com) { memcpy(cb, jb, TOKEN_PARTICIPANTS_TS_SHORT_TIME_SIZE); cb += TOKEN_PARTICIPANTS_TS_SHORT_TIME_SIZE; jb += TOKEN_PARTICIPANTS_TS_SHORT_TIME_SIZE; } nzeros = (cstart + clen_without_sfx - cb); if (nzeros > 0) { memset(cb, 0, nzeros); cb += nzeros; } jb = jstart + reclen; assert(V11_JREC_SUFFIX_SIZE == V12_JREC_SUFFIX_SIZE); memcpy(cb, jb - V11_JREC_SUFFIX_SIZE, V11_JREC_SUFFIX_SIZE); cb += V11_JREC_SUFFIX_SIZE; assert(cb == cstart + conv_reclen); jlen -= reclen; continue; } repl_errno = EREPL_INTLFILTER_INCMPLREC; status = -1; break; } repl_errno = EREPL_INTLFILTER_BADREC; status = -1; break; } assert(0 == jlen || -1 == status); *jnl_len = jb - jnl_buff; *conv_len = cb - conv_buff; return(status); }