void mupip_cvtgbl(void) { unsigned short fn_len, len; char fn[256]; unsigned char buff[7]; uint4 begin, end; int i, format; uint4 cli_status; gtm_int64_t begin_i8, end_i8; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* If an online rollback occurs when we are loading up the database with new globals and takes us back to a prior logical * state, then we should not continue with the load. The reason being that the application might rely on certain globals to * be present before loading others and that property could be voilated if online rollback takes the database back to a * completely different logical state. Set the variable issue_DBROLLEDBACK_anyways that forces the restart logic to issue * an rts_error the first time it detects an online rollback (that takes the database to a prior logical state). */ TREF(issue_DBROLLEDBACK_anyways) = TRUE; is_replicator = TRUE; skip_dbtriggers = TRUE; fn_len = SIZEOF(fn); if (cli_present("STDIN")) { /* User wants to load from standard input */ assert(SIZEOF(fn) > sys_input.len); memcpy(fn, sys_input.addr, sys_input.len); fn_len = sys_input.len; assert(-1 != fcntl(fileno(stdin), F_GETFD)); /* Check if both file name and -STDIN specified. */ if (cli_get_str("FILE", fn, &fn_len)) mupip_exit(ERR_MUPCLIERR); } else if (!cli_get_str("FILE", fn, &fn_len)) /* User wants to read from a file. */ mupip_exit(ERR_MUPCLIERR); /* Neither -STDIN nor file name specified. */ if (mupip_error_occurred) exit(-1); file_input_init(fn, fn_len); mu_outofband_setup(); if ((cli_status = cli_present("BEGIN")) == CLI_PRESENT) { if (!cli_get_int64("BEGIN", &begin_i8)) mupip_exit(ERR_MUPCLIERR); if (1 > begin_i8) mupip_exit(ERR_LOADBGSZ); else if (MAXUINT4 < begin_i8) mupip_exit(ERR_LOADBGSZ2); begin = (uint4) begin_i8; } else { begin = 1; begin_i8 = 1; } if ((cli_status = cli_present("END")) == CLI_PRESENT) { if (!cli_get_int64("END", &end_i8)) mupip_exit(ERR_MUPCLIERR); if (1 > end_i8) mupip_exit(ERR_LOADEDSZ); else if (MAXUINT4 < end_i8) mupip_exit(ERR_LOADEDSZ2); if (end_i8 < begin_i8) mupip_exit(ERR_LOADEDBG); end = (uint4) end_i8; } else end = MAXUINT4; if ((cli_status = cli_present("FILL_FACTOR")) == CLI_PRESENT) { assert(SIZEOF(gv_fillfactor) == SIZEOF(int4)); if (!cli_get_int("FILL_FACTOR", (int4 *)&gv_fillfactor)) gv_fillfactor = MAX_FILLFACTOR; if (gv_fillfactor < MIN_FILLFACTOR) gv_fillfactor = MIN_FILLFACTOR; else if (gv_fillfactor > MAX_FILLFACTOR) gv_fillfactor = MAX_FILLFACTOR; } else gv_fillfactor = MAX_FILLFACTOR; if (cli_present("FORMAT") == CLI_PRESENT) { len = SIZEOF("FORMAT"); if (!cli_get_str("FORMAT", (char *)buff, &len)) go_load(begin, end); else { lower_to_upper(buff, buff, len); if (!memcmp(buff, "ZWR", len)) go_load(begin, end); else if (!memcmp(buff, "BINARY", len)) bin_load(begin, end); else if (!memcmp(buff, "GO", len)) go_load(begin, end); else if (!memcmp(buff, "GOQ", len)) goq_load(); else { util_out_print("Illegal format for load",TRUE); mupip_exit(ERR_MUPCLIERR); } } } else go_load(begin, end); if (mupip_error_occurred) { util_out_print("Error occurred during loading",TRUE); exit(-1); } else mupip_exit(SS_NORMAL); }
int4* find_line_addr (rhdtyp *routine, mstr *label, int4 offset, mident **lent_name) { lab_tabent *base, *top, *ptr; rhdtyp *real_routine; mident_fixed target_label; mident lname; lnr_tabent *line_table, *first_line; int stat, n; error_def(ERR_LABELONLY); if (!routine) return NULL; real_routine = CURRENT_RHEAD_ADR(routine); first_line = LNRTAB_ADR(real_routine); if (!label->len || !*label->addr) { /* No label specified. Return the first line */ base = LABTAB_ADR(real_routine); assert(0 == base->lab_name.len); if (lent_name) *lent_name = &base->lab_name; line_table = first_line; } else { lname.len = (label->len <= MAX_MIDENT_LEN) ? label->len : MAX_MIDENT_LEN; if (cmd_qlf.qlf & CQ_LOWER_LABELS) lname.addr = label->addr; else { lower_to_upper((uchar_ptr_t)&target_label.c[0], (uchar_ptr_t)label->addr, lname.len); lname.addr = &target_label.c[0]; } ptr = base = LABTAB_ADR(real_routine); top = base + real_routine->labtab_len; for ( ; ; ) { n = (int)(top - base) / 2; ptr = base + n; MIDENT_CMP(&lname, &ptr->lab_name, stat); if (0 == stat) { if (lent_name) *lent_name = &ptr->lab_name; line_table = LABENT_LNR_ENTRY(real_routine, ptr); break; } else if (stat > 0) base = ptr; else top = ptr; if (n < 1) return NULL; } } line_table += offset; if (line_table < first_line || line_table >= first_line + real_routine->lnrtab_len) return NULL; return line_table; }
void op_fnzparse (mval *file, mval *field, mval *def1, mval *def2, mval *type, mval *ret) { char field_type; uint4 status; char field_buf[DIR_LEN], type_buf[SYN_LEN], result[MAX_FBUFF + 1]; parse_blk pblk; error_def(ERR_ZPARSETYPE); error_def(ERR_ZPARSFLDBAD); error_def(ERR_INVSTRLEN); MV_FORCE_STR(field); MV_FORCE_STR(def1); MV_FORCE_STR(def2); MV_FORCE_STR(file); MV_FORCE_STR(type); if (def1->str.len > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, def1->str.len, MAX_FBUFF); if (def2->str.len > MAX_FBUFF) rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, def2->str.len, MAX_FBUFF); if (field->str.len == 0) { field_type = ZP_FULL; } else { field_type = 0; if (field->str.len <= DIR_LEN) { lower_to_upper((uchar_ptr_t)&field_buf[0], (uchar_ptr_t)field->str.addr, field->str.len); switch( field_buf[0] ) { case 'D': if (field->str.len <= DEV_LEN && memcmp(&field_buf[0], "DEVICE", field->str.len) == 0) field_type = ZP_DEVICE; else if (field->str.len <= DIR_LEN && memcmp(&field_buf[0], "DIRECTORY", field->str.len) == 0) field_type = ZP_DIRECTORY; break; case 'N': if (field->str.len <= ZP_LEN) { if (memcmp(&field_buf[0], "NAME", field->str.len) == 0) field_type = ZP_NAME; else if (memcmp(&field_buf[0], "NODE", field->str.len) == 0) field_type = ZP_NODE; } break; case 'T': if (field->str.len <= ZP_LEN && memcmp(&field_buf[0], "TYPE", field->str.len) == 0) field_type = ZP_TYPE; break; case 'V': if (field->str.len <= VER_LEN && memcmp(&field_buf[0], "VERSION", field->str.len) == 0) field_type = ZP_VERSION; break; default: break; } } if (field_type == 0) rts_error(VARLSTCNT(4) ERR_ZPARSFLDBAD, 2, field->str.len, field->str.addr); } memset(&pblk, 0, sizeof(pblk)); if (type->str.len != 0) { if (type->str.len <= SYN_LEN) lower_to_upper((uchar_ptr_t)&type_buf[0], (uchar_ptr_t)type->str.addr, type->str.len); if (type->str.len <= SYN_LEN && memcmp(&type_buf[0], "SYNTAX_ONLY", type->str.len) == 0) pblk.fop |= F_SYNTAXO; else if (type->str.len <= NCON_LEN && memcmp(&type_buf[0], "NO_CONCEAL", type->str.len) == 0) { /* no meaning on unix */ } else rts_error(VARLSTCNT(4) ERR_ZPARSETYPE, 2, type->str.len, type->str.addr); } pblk.buffer = result; pblk.buff_size = MAX_FBUFF; pblk.def1_size = def1->str.len; pblk.def1_buf = def1->str.addr; pblk.def2_size = def2->str.len; pblk.def2_buf = def2->str.addr; if ((parse_file(&file->str, &pblk) & 1) == 0) { ret->mvtype = MV_STR; ret->str.len = 0; return; } ret->mvtype = MV_STR; switch( field_type ) { case ZP_DIRECTORY: ret->str.addr = pblk.l_dir; ret->str.len = pblk.b_dir; break; case ZP_NAME: ret->str.addr = pblk.l_name; ret->str.len = pblk.b_name; break; case ZP_TYPE: ret->str.addr = pblk.l_ext; ret->str.len = pblk.b_ext; break; default: ret->str.addr = pblk.buffer; ret->str.len = pblk.b_esl; break; } s2pool(&ret->str); return; }
void op_fngetjpi(mint jpid, mval *kwd, mval *ret) { error_def (ERR_BADJPIPARAM); struct tms proc_times; int4 info ; int keywd_indx; char upcase[MAX_KEY_LEN]; assert (stringpool.free >= stringpool.base); assert (stringpool.top >= stringpool.free); if (stringpool.top - stringpool.free < MAX_STR) stp_gcol(MAX_STR); MV_FORCE_STR(kwd); if (kwd->str.len == 0) rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, 4, "Null"); if (MAX_KEY < kwd->str.len) rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); lower_to_upper((uchar_ptr_t)upcase, (uchar_ptr_t)kwd->str.addr, (int)kwd->str.len); keywd_indx = kw_cputim ; /* future enhancement: * (i) since keywords are sorted, we can exit the while loop if 0 < memcmp. * (ii) also, the current comparison relies on kwd->str.len which means a C would imply CPUTIM instead of CSTIME * or CUTIME this ambiguity should probably be removed by asking for an exact match of the full keyword */ while ((0 != memcmp(upcase, key[keywd_indx], kwd->str.len)) && keywd_indx < MAX_KEY) keywd_indx++; if( keywd_indx == MAX_KEY ) { rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); } if ((kw_isprocalive != keywd_indx) && ((unsigned int)-1 == times(&proc_times))) { rts_error(VARLSTCNT(1) errno); /* need a more specific GTM error message in addition to errno */ return; } switch (keywd_indx) { case kw_cputim: info = proc_times.tms_utime + proc_times.tms_stime + proc_times.tms_cutime + proc_times.tms_cstime; break; case kw_cstime: info = proc_times.tms_cstime; break; case kw_cutime: info = proc_times.tms_cutime; break; case kw_isprocalive: info = (0 != jpid) ? is_proc_alive(jpid, 0) : 1; break; case kw_stime: info = proc_times.tms_stime; break; case kw_utime: info = proc_times.tms_utime; break; case kw_end: default: rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); return; } if (kw_isprocalive != keywd_indx) info = (int4)((info * 100) / sysconf(_SC_CLK_TCK)); /* Convert to standard 100 ticks per second */ i2mval(ret, info); }
socket_struct *iosocket_create(char *sockaddr, uint4 bfsize, int file_des, boolean_t listen_specified) { socket_struct *socketptr; socket_struct *prev_socketptr; socket_struct *socklist_head; boolean_t passive = FALSE; unsigned short port; int ii, save_errno, tmplen, errlen, sockaddrlen; char temp_addr[SA_MAXLITLEN], protocolstr[6], *adptr; const char *errptr; struct addrinfo *ai_ptr; struct addrinfo hints, *addr_info_ptr = NULL; #ifndef VMS struct sockaddr_un *sa_un_ptr, sa_un_trans; mval localpath; mstr transpath; int trans_status; #endif enum socket_protocol protocol; int af; int sd; int errcode; char host_buffer[NI_MAXHOST]; char port_buffer[NI_MAXSERV]; int port_buffer_len; int colon_cnt, protooffset; char *last_2colon = NULL; int addrlen; GTM_SOCKLEN_TYPE tmp_addrlen; if (0 > file_des) { /* no socket descriptor yet */ memset(&hints, 0, SIZEOF(hints)); protooffset = colon_cnt = 0; sockaddrlen = STRLEN(sockaddr); for (ii = sockaddrlen - 1; 0 <= ii; ii--) { if (SEPARATOR == sockaddr[ii]) { colon_cnt++; if (1 == colon_cnt) protooffset = ii + 1; else { last_2colon = &sockaddr[ii]; break; } } } if (0 == colon_cnt) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC); return NULL; } tmplen = sockaddrlen - protooffset; if (SIZEOF(protocolstr) <= tmplen) { /* last piece just too big to be valid */ rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]); return NULL; } lower_to_upper((uchar_ptr_t)protocolstr, (uchar_ptr_t)&sockaddr[protooffset], tmplen); if (((SIZEOF("TCP") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "TCP"))) protocol = socket_tcpip; # ifndef VMS else if (((SIZEOF("LOCAL") - 1) == tmplen) && (0 == MEMCMP_LIT(protocolstr, "LOCAL"))) protocol = socket_local; # endif else { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_PROTNOTSUP, 2, tmplen , &sockaddr[protooffset]); return NULL; } if (socket_tcpip == protocol) { if (1 == colon_cnt) { /* for listening socket or broadcasting socket */ if (!listen_specified || (SSCANF(sockaddr, PORT_PROTO_FORMAT, &port, protocolstr) < 2)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVPORTSPEC); return NULL; } passive = TRUE; /* We always first try using IPv6 address, if supported */ af = ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET); if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP))) { /* Try creating IPv4 socket */ af = AF_INET; if (-1 == (sd = socket(af, SOCK_STREAM, IPPROTO_TCP))) { save_errno = errno; errptr = (char *)STRERROR(save_errno); errlen = STRLEN(errptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr); return NULL; } } SERVER_HINTS(hints, af); port_buffer_len = 0; I2A(port_buffer, port_buffer_len, port); port_buffer[port_buffer_len]='\0'; if (0 != (errcode = getaddrinfo(NULL, port_buffer, &hints, &addr_info_ptr))) { close(sd); RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return NULL; } SOCKET_ALLOC(socketptr); socketptr->local.port = port; socketptr->temp_sd = sd; socketptr->sd = FD_INVALID; ai_ptr = &(socketptr->local.ai); memcpy(ai_ptr, addr_info_ptr, SIZEOF(struct addrinfo)); SOCKET_AI_TO_LOCAL_ADDR(socketptr, addr_info_ptr); ai_ptr->ai_addr = SOCKET_LOCAL_ADDR(socketptr); ai_ptr->ai_addrlen = addr_info_ptr->ai_addrlen; ai_ptr->ai_next = NULL; freeaddrinfo(addr_info_ptr); } else { /* connection socket */ assert(2 == colon_cnt); if (listen_specified || (SSCANF(last_2colon + 1, PORT_PROTO_FORMAT, &port, protocolstr) < 2)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC); return NULL; } /* for connection socket */ SPRINTF(port_buffer, "%hu", port); addrlen = last_2colon - sockaddr; if ('[' == sockaddr[0]) { if (NULL == memchr(sockaddr, ']', addrlen)) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_INVADDRSPEC); return NULL; } addrlen -= 2; memcpy(temp_addr, &sockaddr[1], addrlen); } else memcpy(temp_addr, sockaddr, addrlen); temp_addr[addrlen] = 0; CLIENT_HINTS(hints); if (0 != (errcode = getaddrinfo(temp_addr, port_buffer, &hints, &addr_info_ptr))) { RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return NULL; } /* we will test all address families in iosocket_connect() */ SOCKET_ALLOC(socketptr); socketptr->remote.ai_head = addr_info_ptr; socketptr->remote.port = port; socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */ } # ifndef VMS } else if (socket_local == protocol) { /* should we get_full_path first */ /* check protooffset < sizeof sun_path */ /* protooffset is after colon */ SOCKET_ALLOC(socketptr); socketptr->protocol = socket_local; sa_un_ptr = malloc(SIZEOF(struct sockaddr_un)); sa_un_ptr->sun_family = AF_UNIX; MV_INIT_STRING(&localpath, protooffset - 1, sockaddr); trans_status = TRANS_LOG_NAME(&localpath.str, &transpath, sa_un_trans.sun_path, (int)SIZEOF(sa_un_trans.sun_path), dont_sendmsg_on_log2long); if (SS_LOG2LONG == trans_status) { /* if LOG2LONG, returned len not valid so report untranslated length */ SOCKET_FREE(socketptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ADDRTOOLONG, 4, localpath.str.len, localpath.str.addr, localpath.str.len, SIZEOF(sa_un_trans.sun_path)); return NULL; } memcpy(sa_un_ptr->sun_path, transpath.addr, transpath.len); sa_un_ptr->sun_path[transpath.len] = '\0'; if (listen_specified) { passive = TRUE; socketptr->local.sa = (struct sockaddr *)sa_un_ptr; socketptr->local.ai.ai_family = AF_UNIX; socketptr->local.ai.ai_socktype = SOCK_STREAM; socketptr->local.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset; if (-1 == (sd = socket(AF_UNIX, SOCK_STREAM, 0))) { save_errno = errno; SOCKET_FREE(socketptr); errptr = (char *)STRERROR(save_errno); errlen = STRLEN(errptr); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(5) ERR_SOCKINIT, 3, save_errno, errlen, errptr); return NULL; } socketptr->temp_sd = sd; socketptr->sd = FD_INVALID; } else { socketptr->remote.sa = (struct sockaddr *)sa_un_ptr; /* setup remote fields */ socketptr->remote.ai.ai_family = AF_UNIX; socketptr->remote.ai.ai_socktype = SOCK_STREAM; socketptr->remote.ai.ai_addrlen = (size_t)((struct sockaddr_un *)0)->sun_path + protooffset; socketptr->sd = socketptr->temp_sd = FD_INVALID; /* don't mess with 0 */ } # endif } else
bool mubgetfil(backup_reg_list *list, char *name, unsigned short len) { struct stat stat_buf; int stat_res; char temp; char tcp[5]; if (0 == len) return FALSE; if (list != mu_repl_inst_reg_list) { /* Do the following checks only if this region does NOT correspond to the replication instance region. */ if ('|' == *name) { len -= 1; list->backup_to = backup_to_exec; list->backup_file.len = len; list->backup_file.addr = (char *)malloc(len + 1); memcpy(list->backup_file.addr, name + 1, len); return TRUE; } if (len > 5) { lower_to_upper((uchar_ptr_t)tcp, (uchar_ptr_t)name, 5); if (0 == memcmp(tcp, "TCP:/", 5)) { list->backup_to = backup_to_tcp; len -= 5; name += 5; while ('/' == *name) { len--; name++; } list->backup_file.len = len; list->backup_file.addr = (char *)malloc(len + 1); memcpy(list->backup_file.addr, name, len); *(list->backup_file.addr + len) = 0; return TRUE; } } } temp = name[len]; name[len] = 0; STAT_FILE(name, &stat_buf, stat_res); if (-1 == stat_res) { if (errno != ENOENT) { util_out_print("Error accessing backup output file or directory: !AD", TRUE, len, name); mupip_exit(errno); } else { /* new file */ list->backup_file.len = len; list->backup_file.addr = (char *)malloc(len + 1); memcpy(list->backup_file.addr, name, len); *(list->backup_file.addr + len) = 0; } } else if (S_ISDIR(stat_buf.st_mode)) { if (!is_directory) { is_directory = TRUE; directory.len = len; directory.addr = (char *)malloc(len + 1); memcpy(directory.addr, name, len); *(directory.addr + len) = 0; } mubexpfilnam(name, len, list); } else { /* the file already exists */ util_out_print("File !AD already exists.", TRUE, len, name); error_mupip = TRUE; return FALSE; } name[len] = temp; return TRUE; }
void op_fnztrnlnm(mval *name,mval *table,int4 ind,mval *mode,mval *case_blind,mval *item,mval *ret) { struct dsc$descriptor lname, ltable; uint4 attribute, status, retlen, mask, full_mask; char acmode; short int *item_code, pass, index; bool full; char buff[256], result[MAX_RESULT_SIZE]; char i, slot, last_slot; char def_table[] = "LNM$DCL_LOGICAL"; struct { item_list_3 item[3]; int4 terminator; } item_list; error_def(ERR_BADTRNPARAM); if(!name->str.len || MAX_LOGNAM_LENGTH < name->str.len || MAX_LOGNAM_LENGTH < table->str.len) rts_error(VARLSTCNT(1) SS$_IVLOGNAM); memset(&item_list,0,SIZEOF(item_list)); item_list.item[0].item_code = 0; item_list.item[0].buffer_address = result; item_list.item[0].buffer_length = MAX_RESULT_SIZE; item_list.item[0].return_length_address = &retlen; item_code = &item_list.item[0].item_code; lname.dsc$w_length = name->str.len; lname.dsc$a_pointer = name->str.addr; lname.dsc$b_dtype = DSC$K_DTYPE_T; lname.dsc$b_class = DSC$K_CLASS_S; if (table->str.len) { ltable.dsc$w_length = table->str.len; ltable.dsc$a_pointer = table->str.addr; }else { ltable.dsc$a_pointer = def_table; ltable.dsc$w_length = strlen(def_table); } ltable.dsc$b_dtype = DSC$K_DTYPE_T; ltable.dsc$b_class = DSC$K_CLASS_S; if(ind) { item_list.item[0].item_code = LNM$_INDEX; item_list.item[0].buffer_address = &ind; item_list.item[1].item_code = 0; item_list.item[1].buffer_address = result; item_list.item[1].buffer_length = MAX_RESULT_SIZE; item_list.item[1].return_length_address = &retlen; item_code = &item_list.item[1].item_code; } attribute = LNM$M_CASE_BLIND; if (case_blind->str.len) { if (case_blind->str.len > 14) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, case_blind->str.len), case_blind->str.addr); lower_to_upper(buff,case_blind->str.addr,case_blind->str.len); if (case_blind->str.len == 14 && !memcmp(buff,"CASE_SENSITIVE",14)) attribute = 0; else if (case_blind->str.len != 10 || memcmp(buff,"CASE_BLIND",10)) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,case_blind->str.len,case_blind->str.addr); } acmode = NOVALUE; if (mode->str.len) { if (mode->str.len > 14) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, mode->str.len), mode->str.addr); lower_to_upper(buff,mode->str.addr,mode->str.len); switch (buff[0]) { case 'U': if ( mode->str.len = 4 && !memcmp(buff, "USER", 4)) acmode = PSL$C_USER; case 'S': if ( mode->str.len = 10 && !memcmp(buff, "SUPERVISOR", 10)) acmode = PSL$C_SUPER; case 'K': if ( mode->str.len = 6 && !memcmp(buff, "KERNEL", 6)) acmode = PSL$C_KERNEL; case 'E': if ( mode->str.len = 9 && !memcmp(buff, "EXECUTIVE", 9)) acmode = PSL$C_EXEC; } if (acmode == NOVALUE) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,mode->str.len,mode->str.addr); } full = FALSE; *item_code = NOVALUE; if (item->str.len) { if (item->str.len > 12) rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, MIN(SHRT_MAX, item->str.len), item->str.addr); lower_to_upper(buff,item->str.addr,item->str.len); if ((i = buff[0] - 'A') < MIN_INDEX || i > MAX_INDEX) { rts_error(VARLSTCNT(4) ERR_BADTRNPARAM, 2, item->str.len, item->str.addr); } if ( trnlnm_index[i].len) { slot = trnlnm_index[i].index; last_slot = trnlnm_index[i].len; for (; slot < last_slot; slot++) { if (item->str.len == trnlnm_table[slot].len && !memcmp(trnlnm_table[slot].name, buff, item->str.len)) { if (trnlnm_table[slot].item_code == FULL_VALUE) { if (ind) index = 2; else index = 1; *item_code = LNM$_STRING; item_list.item[index].buffer_address = &full_mask; item_list.item[index].buffer_length = SIZEOF(full_mask); item_list.item[index].item_code = LNM$_ATTRIBUTES; item_code = &item_list.item[index].item_code; full = TRUE; }else { *item_code = trnlnm_table[slot].item_code; } break; } } } if (*item_code == NOVALUE) { rts_error(VARLSTCNT(4) ERR_BADTRNPARAM,2,item->str.len,item->str.addr); } }else { *item_code = LNM$_STRING; } for ( pass = 0 ; ; pass++ ) { retlen = 0; status = sys$trnlnm(&attribute, <able, &lname, acmode == NOVALUE ? 0 : &acmode, &item_list); if (status & 1) { if (*item_code == LNM$_STRING || *item_code == LNM$_TABLE) { ret->mvtype = MV_STR; ENSURE_STP_FREE_SPACE(retlen); ret->str.addr = stringpool.free; ret->str.len = retlen; memcpy(ret->str.addr, result, retlen); stringpool.free += retlen; return; }else if (*item_code == LNM$_LENGTH || *item_code == LNM$_MAX_INDEX) { MV_FORCE_MVAL(ret,*(int4 *)result) ; n2s(ret); return; }else if (*item_code == LNM$_ACMODE) { ret->mvtype = MV_STR; switch(*result) { case PSL$C_USER: ENSURE_STP_FREE_SPACE(4); ret->str.addr = stringpool.free; ret->str.len = 4; memcpy(ret->str.addr, "USER", 4); stringpool.free += 4; return; case PSL$C_SUPER: ENSURE_STP_FREE_SPACE(5); ret->str.addr = stringpool.free; ret->str.len = 5; memcpy(ret->str.addr, "SUPER", 5); stringpool.free += 5; return; case PSL$C_EXEC: ENSURE_STP_FREE_SPACE(9); ret->str.addr = stringpool.free; ret->str.len = 9; memcpy(ret->str.addr, "EXECUTIVE", 9); stringpool.free += 9; return; case PSL$C_KERNEL: ENSURE_STP_FREE_SPACE(6); ret->str.addr = stringpool.free; ret->str.len = 6; memcpy(ret->str.addr, "KERNEL", 6); stringpool.free += 6; return; default: GTMASSERT; } }else { assert(*item_code == LNM$_ATTRIBUTES); if (full) { if (!retlen) /* If the logical name exists, but has no entry for the specified index, */ { /* then the return status will be normal as the TERMINAL attribute will */ /* be filled in, but there will be no equivalence name, thus retlen == 0 */ ret->mvtype = MV_STR; if (!pass) { ret->str.len = 0; return; } ENSURE_STP_FREE_SPACE(lname.dsc$w_length); ret->str.addr = stringpool.free; ret->str.len = lname.dsc$w_length; memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length); stringpool.free += lname.dsc$w_length; return; } if(full_mask & LNM$M_TERMINAL) { ret->mvtype = MV_STR; ENSURE_STP_FREE_SPACE(retlen); ret->str.addr = stringpool.free; ret->str.len = retlen; memcpy(ret->str.addr, result, retlen); stringpool.free += retlen; return; } memcpy(buff,result,retlen); lname.dsc$w_length = retlen; lname.dsc$a_pointer = buff; }else { mask = attr_tab[slot]; if (mask == NOVALUE) GTMASSERT; MV_FORCE_MVAL(ret,( *((int4*)result) & mask ? 1 : 0 )) ; n2s(ret); return; } } }else if (status == SS$_NOLOGNAM) { ret->mvtype = MV_STR; if (full && pass > 0) { ENSURE_STP_FREE_SPACE(lname.dsc$w_length); ret->str.addr = stringpool.free; ret->str.len = lname.dsc$w_length; memcpy(ret->str.addr, lname.dsc$a_pointer, lname.dsc$w_length); stringpool.free += lname.dsc$w_length; }else { ret->str.len = 0; } return; }else { rts_error(VARLSTCNT(1) status); } } MV_FORCE_MVAL(ret, 0) ; return; }
void op_fngetdvi(mval *device, mval *keyword, mval *ret) { itmlist_struct item_list; short out_len, iosb[4]; uint4 status; char index, slot, last_slot; int4 item_code, out_value; unsigned char buff[MAX_KEY_LENGTH], *upper_case; bool want_secondary; $DESCRIPTOR(device_name,""); error_def(ERR_DVIKEYBAD); error_def(ERR_INVSTRLEN); MV_FORCE_STR(device); MV_FORCE_STR(keyword); if (MAX_DEV_LENGTH < device->str.len) rts_error(VARLSTCNT(1) SS$_IVLOGNAM); if (keyword->str.len > MAX_KEY_LENGTH) rts_error(VARLSTCNT(4) ERR_INVSTRLEN, 2, keyword->str.len, MAX_KEY_LENGTH); if (!keyword->str.len) { rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, 4, "NULL"); } lower_to_upper(&buff[0], keyword->str.addr, keyword->str.len); upper_case = buff; if ( device->str.len == 0 || (device->str.len == 1 && *device->str.addr == '0')) { device_name.dsc$a_pointer = "SYS$INPUT"; device_name.dsc$w_length = SIZEOF("SYS$INPUT")-1; } else { device_name.dsc$a_pointer = device->str.addr; device_name.dsc$w_length = device->str.len; } item_list.bufflen = VAL_LENGTH; item_list.itmcode = SPL_CODE; item_list.buffaddr = &out_value; item_list.retlen = &out_len; item_list.end = NULL; status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 ); if (status != SS$_NORMAL && status != SS$_NONLOCAL) { rts_error(VARLSTCNT(1) status ) ; } sys$synch(efn_immed_wait, &iosb[0]); if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL) { rts_error(VARLSTCNT(1) iosb[0] ); } if (out_value != NULL) { want_secondary = TRUE; } else { want_secondary = FALSE; } if ((index = *upper_case - 'A') < MIN_INDEX || index > MAX_INDEX) { rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr); } item_code = 0; if ( dvi_index[ index ].len) { slot = dvi_index[ index ].index; last_slot = dvi_index[ index ].len; for ( ; slot < last_slot ; slot++ ) { if (keyword->str.len == dvi_table[ slot ].len && !memcmp(dvi_table[ slot ].name, upper_case, keyword->str.len)) { item_code = dvi_table[ slot ].item_code; break; } } } if (!item_code) { rts_error(VARLSTCNT(6) ERR_DVIKEYBAD, 4, device->str.len, device->str.addr, keyword->str.len, keyword->str.addr); } switch( item_code ) { /* **** the following item codes require a string be returned **** */ case DVI$_ALLDEVNAM: case DVI$_DEVLOCKNAM: case DVI$_DEVNAM: case DVI$_FULLDEVNAM: case DVI$_LOGVOLNAM: case DVI$_NEXTDEVNAM: case DVI$_ROOTDEVNAM: case DVI$_TT_ACCPORNAM: case DVI$_TT_PHYDEVNAM: case DVI$_VOLNAM: if (want_secondary) { if (!((item_code == DVI$_DEVNAM) && (keyword->str.len == 9))) { item_code |= DVI$C_SECONDARY; } } assert(stringpool.free >= stringpool.base); assert(stringpool.top >= stringpool.free); ENSURE_STP_FREE_SPACE(MAX_DVI_STRLEN); item_list.bufflen = MAX_DVI_STRLEN; item_list.itmcode = item_code; item_list.buffaddr = stringpool.free; item_list.retlen = &out_len; item_list.end = NULL; status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 ); if (status != SS$_NORMAL && status != SS$_NONLOCAL) { rts_error(VARLSTCNT(1) status ); } sys$synch(efn_immed_wait, &iosb[0]); if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL) { rts_error(VARLSTCNT(1) iosb[0] ) ; } ret->str.addr = stringpool.free; ret->str.len = out_len; ret->mvtype = MV_STR; stringpool.free += out_len; assert(stringpool.free >= stringpool.base); assert(stringpool.top >= stringpool.free); return; default: if (want_secondary) item_code |= DVI$C_SECONDARY; item_list.itmcode = item_code; item_list.bufflen = VAL_LENGTH; item_list.buffaddr = &out_value; item_list.retlen = &out_len; item_list.end = NULL; status = sys$getdvi( efn_immed_wait, 0, &device_name, &item_list, &iosb[0], 0, 0, 0 ); if (status != SS$_NORMAL && status != SS$_NONLOCAL) rts_error(VARLSTCNT(1) status ); sys$synch(efn_immed_wait, &iosb[0]); if (iosb[0] != SS$_NORMAL && iosb[0] != SS$_NONLOCAL) rts_error(VARLSTCNT(1) iosb[0] ); if (want_secondary) item_code = item_code - 1; switch(item_code) { case DVI$_LOCKID: case DVI$_ACPPID: case DVI$_OWNUIC: if (out_value) { assert(stringpool.free >= stringpool.base); assert(stringpool.top >= stringpool.free); ENSURE_STP_FREE_SPACE(HEX_LEN); i2hex(out_value, stringpool.free, HEX_LEN); ret->str.addr = stringpool.free; ret->str.len = HEX_LEN; stringpool.free += HEX_LEN; assert(stringpool.free >= stringpool.base); assert(stringpool.top >= stringpool.free); } else { ret->str.addr = ""; ret->str.len = 0; } ret->mvtype = MV_STR; break; case DVI$_ACPTYPE: switch(out_value) { case 0: ret->str.addr = "ILLEGAL"; ret->str.len = 7; break; case 1: ret->str.addr = "F11V1"; ret->str.len = 5; break; case 2: ret->str.addr = "F11V2"; ret->str.len = 5; break; case 3: ret->str.addr = "MTA"; ret->str.len = 3; break; case 4: ret->str.addr = "NET"; ret->str.len = 3; break; case 5: ret->str.addr = "REM"; ret->str.len = 3; } ret->mvtype = MV_STR; break; default: i2mval(ret,out_value) ; } return; } }
bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mval *mspace) { char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ char dev_type[MAX_DEV_TYPE_LEN]; int n; mstr tn; /* translated name */ uint4 stat; /* status */ int p_offset; unsigned char ch; ABS_TIME cur_time, end_time; bool out_of_time = FALSE; if (0 == naml->iod) { if (0 == tl->iod) { tl->iod = (io_desc *)malloc(SIZEOF(io_desc)); memset((char*)tl->iod, 0, SIZEOF(io_desc)); tl->iod->pair.in = tl->iod; tl->iod->pair.out = tl->iod; tl->iod->trans_name = tl; p_offset = 0; while (iop_eol != *(pp->str.addr + p_offset)) { if ((iop_tmpmbx == (ch = *(pp->str.addr + p_offset++))) || (iop_prmmbx == ch)) tl->iod->type = mb; else if (iop_nl == ch) tl->iod->type = nl; p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } if (!tl->iod->type && mspace && mspace->str.len) { lower_to_upper(dev_type, mspace->str.addr, mspace->str.len); if (((SIZEOF("SOCKET") - 1) == mspace->str.len) && (0 == memcmp(dev_type, LIT_AND_LEN("SOCKET")))) tl->iod->type = gtmsocket; else tl->iod->type = us; } if (!tl->iod->type) { tn.len = tl->len; tn.addr = &tl->dollar_io; tl->iod->type = io_type(&tn); } } naml->iod = tl->iod; } tl->iod->disp_ptr = &io_dev_dispatch[tl->iod->type]; assert(0 != naml->iod); active_device = naml->iod; if (dev_never_opened == naml->iod->state) { naml->iod->wrap = DEFAULT_IOD_WRAP; naml->iod->width = DEFAULT_IOD_WIDTH; naml->iod->length = DEFAULT_IOD_LENGTH; naml->iod->write_filter = write_filter; } if (dev_open != naml->iod->state) { naml->iod->dollar.x = 0; naml->iod->dollar.y = 0; naml->iod->dollar.za = 0; naml->iod->dollar.zb[0] = 0; naml->iod->dollar.zeof = FALSE; } if (0 == timeout) stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout); /* ZY: add a parameter timeout */ else if (NO_M_TIMEOUT == timeout) { while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout))) /* ZY: add timeout */ { hiber_start(1000); /* 1 second */ if (outofband) outofband_action(FALSE); } } else { sys_get_curr_time(&cur_time); add_int_to_abs_time(&cur_time, timeout * 1000, &end_time); while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout)) /* ZY: add timeout */ && (!out_of_time)) { hiber_start(1000); /* 1 second */ if (outofband) outofband_action(FALSE); sys_get_curr_time(&cur_time); if (abs_time_comp(&end_time, &cur_time) <= 0) out_of_time = TRUE; } } if (TRUE == stat) { naml->iod->state = dev_open; if (27 == naml->iod->trans_name->dollar_io[0]) { tn.addr = &naml->iod->trans_name->dollar_io[4]; n = naml->iod->trans_name->len - 4; if (n < 0) n = 0; tn.len = n; naml->iod->trans_name = get_log_name(&tn, INSERT); naml->iod->trans_name->iod = naml->iod; } } else { if (dev_open == naml->iod->state && (gtmsocket != naml->iod->type)) naml->iod->state = dev_closed; else if ((gtmsocket == naml->iod->type) && naml->iod->newly_created) { assert(naml->iod->state != dev_open); iosocket_destroy(naml->iod); } } active_device = 0; if ((NO_M_TIMEOUT != timeout) && IS_MCODE_RUNNING) return (stat); return FALSE; }
short iosocket_open(io_log_name *dev, mval *pp, int file_des, mval *mspace, int4 timepar) { char addr[SA_MAXLITLEN], *errptr, sockaddr[SA_MAXLITLEN], temp_addr[SA_MAXLITLEN], dev_type[MAX_DEV_TYPE_LEN]; unsigned char ch, *c, *next, *top; int handle_len, moreread_timeout, len; unsigned short port; int4 errlen, msec_timeout, real_errno, p_offset = 0, zff_len, delimiter_len; int d_socket_struct_len; ABS_TIME cur_time, end_time; io_desc *ioptr; struct sockaddr_in peer; /* socket address + port */ fd_set tcp_fd; uint4 bfsize = DEFAULT_SOCKET_BUFFER_SIZE, ibfsize; d_socket_struct *dsocketptr; socket_struct *socketptr; mv_stent *mv_zintdev; boolean_t zint_conn_restart = FALSE; socket_interrupt *sockintr; mstr chset_mstr; boolean_t attach_specified = FALSE, listen_specified = FALSE, connect_specified = FALSE, ioerror_specified = FALSE, delay_specified = FALSE, nodelay_specified = FALSE, ibfsize_specified = FALSE, moreread_specified = FALSE, is_principal = FALSE, /* called from inetd */ ichset_specified, ochset_specified; unsigned char delimiter_buffer[MAX_N_DELIMITER * (MAX_DELIM_LEN + 1)], zff_buffer[MAX_ZFF_LEN]; char ioerror, ip[3], tcp[4], sock_handle[MAX_HANDLE_LEN], delimiter[MAX_DELIM_LEN + 1]; error_def(ERR_DELIMSIZNA); error_def(ERR_ADDRTOOLONG); error_def(ERR_SOCKETEXIST); error_def(ERR_ABNCOMPTINC); error_def(ERR_DEVPARINAP); error_def(ERR_DEVPARMNEG); error_def(ERR_ILLESOCKBFSIZE); error_def(ERR_ZFF2MANY); error_def(ERR_DELIMWIDTH); error_def(ERR_SOCKMAX); error_def(ERR_ZINTRECURSEIO); error_def(ERR_MRTMAXEXCEEDED); ioptr = dev->iod; assert((params) *(pp->str.addr + p_offset) < (unsigned char)n_iops); assert(ioptr != 0); assert(ioptr->state >= 0 && ioptr->state < n_io_dev_states); assert(ioptr->type == gtmsocket); if ((ioptr->state == dev_closed) && mspace && mspace->str.len && mspace->str.addr) { lower_to_upper((uchar_ptr_t)dev_type, (uchar_ptr_t)mspace->str.addr, mspace->str.len); if (STR_LIT_LEN("SOCKET") != mspace->str.len || 0 != memcmp(dev_type, "SOCKET", STR_LIT_LEN("SOCKET"))) { if (ioptr->dev_sp) free(ioptr->dev_sp); ioptr->state = dev_never_opened; } } d_socket_struct_len = SIZEOF(d_socket_struct) + (SIZEOF(socket_struct) * (gtm_max_sockets - 1)); if (ioptr->state == dev_never_opened) { dsocketptr = ioptr->dev_sp = (void *)malloc(d_socket_struct_len); memset(dsocketptr, 0, d_socket_struct_len); dsocketptr->iod = ioptr; } else dsocketptr = (d_socket_struct *)ioptr->dev_sp; if (ioptr->state == dev_never_opened) { ioptr->state = dev_closed; ioptr->width = TCPDEF_WIDTH; ioptr->length = TCPDEF_LENGTH; ioptr->wrap = TRUE; if (-1 == iotcp_fillroutine()) assert(FALSE); if (!io_std_device.in) /* called from io_init */ is_principal = TRUE; } if (dsocketptr->mupintr) { /* check if connect was interrupted */ sockintr = &dsocketptr->sock_save_state; if (sockwhich_invalid == sockintr->who_saved) GTMASSERT; /* Interrupt should never have an invalid save state */ if (dollar_zininterrupt) { dsocketptr->mupintr = FALSE; sockintr->who_saved = sockwhich_invalid; rts_error(VARLSTCNT(1) ERR_ZINTRECURSEIO); } if (sockwhich_connect != sockintr->who_saved) GTMASSERT; /* ZINTRECURSEIO should have caught */ mv_zintdev = io_find_mvstent(dsocketptr->iod, FALSE); if (mv_zintdev && mv_zintdev->mv_st_cont.mvs_zintdev.buffer_valid) { /* mupintr will be reset and mvstent popped in iosocket_connect */ connect_specified = TRUE; ibfsize_specified = sockintr->ibfsize_specified; assert(newdsocket); assert(newdsocket == sockintr->newdsocket); memcpy(newdsocket, (d_socket_struct *)mv_zintdev->mv_st_cont.mvs_zintdev.curr_sp_buffer.addr, d_socket_struct_len); socketptr = newdsocket->socket[newdsocket->current_socket]; assert(socketptr == (socket_struct *)mv_zintdev->mv_st_cont.mvs_zintdev.socketptr); zint_conn_restart = TRUE; /* skip what we already did, state == dev_closed */ } } else { ioptr->dollar.zeof = FALSE; if (NULL == newdsocket) newdsocket = (d_socket_struct *)malloc(d_socket_struct_len); memcpy(newdsocket, dsocketptr, d_socket_struct_len); memcpy(newdsocket->dollar_device, "0", SIZEOF("0")); zff_len = -1; /* indicates neither ZFF nor ZNOFF specified */ delimiter_len = -1; /* indicates neither DELIM nor NODELIM specified */ ichset_specified = ochset_specified = FALSE; while (iop_eol != (ch = *(pp->str.addr + p_offset++))) { switch(ch) { case iop_delimiter: delimiter_len = (int4)(unsigned char)*(pp->str.addr + p_offset); if (((MAX_DELIM_LEN + 1) * MAX_N_DELIMITER) >= delimiter_len) memcpy(delimiter_buffer, (pp->str.addr + p_offset + 1), delimiter_len); else rts_error(VARLSTCNT(1) ERR_DELIMSIZNA); break; case iop_ipchset: UNICODE_ONLY( if (gtm_utf8_mode) { /* Only change ipchset if in UTF8 mode */ chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(ioptr->ichset, &chset_mstr); ichset_specified = TRUE; } ); break; case iop_opchset: UNICODE_ONLY( if (gtm_utf8_mode) { /* Only change ipchset if in UTF8 mode */ chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(ioptr->ochset, &chset_mstr); ochset_specified = TRUE; } ); break; case iop_chset: UNICODE_ONLY( if (gtm_utf8_mode) { /* Only change ipchset/opchset if in UTF8 mode */ chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(ioptr->ichset, &chset_mstr); ioptr->ochset = ioptr->ichset; ichset_specified = ochset_specified = TRUE; } ); break; /* Note the following 4 cases (iop_m/utf16/utf16be/utf16le) have no corresponding device parameter but are included here because they can be easily used in internal processing. */ case iop_m: UNICODE_ONLY( ioptr->ichset = ioptr->ochset = CHSET_M; ichset_specified = ochset_specified = TRUE; );
void mu_extract(void) { int stat_res, truncate_res; int reg_max_rec, reg_max_key, reg_max_blk, reg_std_null_coll; int iter, format, local_errno, int_nlen; boolean_t freeze = FALSE, logqualifier, success; char format_buffer[FORMAT_STR_MAX_SIZE], ch_set_name[MAX_CHSET_NAME], cli_buff[MAX_LINE], label_buff[LABEL_STR_MAX_SIZE], gbl_name_buff[MAX_MIDENT_LEN + 2]; /* 2 for null and '^' */ glist gl_head, *gl_ptr; gd_region *reg, *region_top; mu_extr_stats global_total, grand_total; uint4 item_code, devbufsiz, maxfield; unsigned short label_len, n_len, ch_set_len, buflen; unsigned char *outbuf, *outptr, *chptr, *leadptr; struct stat statbuf; mval val, curr_gbl_name, op_val, op_pars; mstr chset_mstr; gtm_chset_t saved_out_set; static unsigned char ochset_set = FALSE; static readonly unsigned char open_params_list[] = { (unsigned char)iop_noreadonly, (unsigned char)iop_nowrap, (unsigned char)iop_stream, (unsigned char)iop_eol }; static readonly unsigned char no_param = (unsigned char)iop_eol; coll_hdr extr_collhdr; error_def(ERR_NOSELECT); error_def(ERR_GTMASSERT); error_def(ERR_EXTRACTCTRLY); error_def(ERR_EXTRACTFILERR); error_def(ERR_MUPCLIERR); error_def(ERR_MUNOACTION); error_def(ERR_MUNOFINISH); error_def(ERR_RECORDSTAT); error_def(ERR_NULLCOLLDIFF); /* Initialize all local character arrays to zero before using */ memset(cli_buff, 0, sizeof(cli_buff)); memset(outfilename, 0, sizeof(outfilename)); memset(label_buff, 0, sizeof(label_buff)); memset(format_buffer, 0, sizeof(format_buffer)); active_device = io_curr_device.out; mu_outofband_setup(); if (CLI_PRESENT == cli_present("OCHSET")) { ch_set_len = sizeof(ch_set_name); if (cli_get_str("OCHSET", ch_set_name, &ch_set_len)) { if (0 == ch_set_len) mupip_exit(ERR_MUNOACTION); /* need to change to OPCHSET error when added */ ch_set_name[ch_set_len] = '\0'; #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != active_device->output_conv_cd) ICONV_CLOSE_CD(active_device->output_conv_cd); if (DEFAULT_CODE_SET != active_device->out_code_set) ICONV_OPEN_CD(active_device->output_conv_cd, INSIDE_CH_SET, ch_set_name); #else chset_mstr.addr = ch_set_name; chset_mstr.len = ch_set_len; SET_ENCODING(active_device->ochset, &chset_mstr); get_chset_desc(&chset_names[active_device->ochset]); #endif ochset_set = TRUE; } } logqualifier = (CLI_NEGATED != cli_present("LOG")); if (CLI_PRESENT == cli_present("FREEZE")) freeze = TRUE; n_len = sizeof(format_buffer); if (FALSE == cli_get_str("FORMAT", format_buffer, &n_len)) { n_len = sizeof("ZWR") - 1; memcpy(format_buffer, "ZWR", n_len); } int_nlen = n_len; lower_to_upper((uchar_ptr_t)format_buffer, (uchar_ptr_t)format_buffer, int_nlen); if (0 == memcmp(format_buffer, "ZWR", n_len)) format = MU_FMT_ZWR; else if (0 == memcmp(format_buffer, "GO", n_len)) { if (gtm_utf8_mode) { util_out_print("Extract error: GO format is not supported in UTF-8 mode. Use ZWR format.", TRUE); mupip_exit(ERR_MUPCLIERR); } format = MU_FMT_GO; } else if (0 == memcmp(format_buffer, "BINARY", n_len)) format = MU_FMT_BINARY; else { util_out_print("Extract error: bad format type", TRUE); mupip_exit(ERR_MUPCLIERR); } n_len = sizeof(cli_buff); if (FALSE == cli_get_str((char *)select_text, cli_buff, &n_len)) { n_len = 1; cli_buff[0] = '*'; } /* gv_select will select globals */ gv_select(cli_buff, n_len, freeze, (char *)select_text, &gl_head, ®_max_rec, ®_max_key, ®_max_blk); if (!gl_head.next) { rts_error(VARLSTCNT(1) ERR_NOSELECT); mupip_exit(ERR_NOSELECT); } /* For binary format, check whether all regions have same null collation order */ if (MU_FMT_BINARY == format) { for (reg = gd_header->regions, region_top = gd_header->regions + gd_header->n_regions, reg_std_null_coll = -1; reg < region_top ; reg++) { if (reg->open) { if (reg_std_null_coll != reg->std_null_coll) { if (reg_std_null_coll == -1) reg_std_null_coll = reg->std_null_coll; else { rts_error(VARLSTCNT(1) ERR_NULLCOLLDIFF); mupip_exit(ERR_NULLCOLLDIFF); } } } } assert(-1 != reg_std_null_coll); } grand_total.recknt = grand_total.reclen = grand_total.keylen = grand_total.datalen = 0; global_total.recknt = global_total.reclen = global_total.keylen = global_total.datalen = 0; n_len = sizeof(outfilename); if (FALSE == cli_get_str("FILE", outfilename, &n_len)) { rts_error(VARLSTCNT(1) ERR_MUPCLIERR); mupip_exit(ERR_MUPCLIERR); } if (-1 == Stat((char *)outfilename, &statbuf)) { if (ENOENT != errno) { local_errno = errno; perror("Error opening output file"); mupip_exit(local_errno); } } else { util_out_print("Error opening output file: !AD -- File exists", TRUE, n_len, outfilename); mupip_exit(ERR_MUNOACTION); } op_pars.mvtype = MV_STR; op_pars.str.len = sizeof(open_params_list); op_pars.str.addr = (char *)open_params_list; op_val.mvtype = MV_STR; op_val.str.len = filename_len = n_len; op_val.str.addr = (char *)outfilename; (*op_open_ptr)(&op_val, &op_pars, 0, 0); ESTABLISH(mu_extract_handler); op_use(&op_val, &op_pars); if (MU_FMT_BINARY == format) { /* binary header label format: * fixed length text, fixed length date & time, * fixed length max blk size, fixed length max rec size, fixed length max key size, fixed length std_null_coll * 32-byte padded user-supplied string */ outbuf = (unsigned char *)malloc(sizeof(BIN_HEADER_LABEL) + sizeof(BIN_HEADER_DATEFMT) - 1 + 4 * BIN_HEADER_NUMSZ + BIN_HEADER_LABELSZ); outptr = outbuf; MEMCPY_LIT(outptr, BIN_HEADER_LABEL); outptr += STR_LIT_LEN(BIN_HEADER_LABEL); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, (mval *)&mu_bin_datefmt, &null_str, &null_str, &val); memcpy(outptr, val.str.addr, val.str.len); outptr += val.str.len; WRITE_NUMERIC(reg_max_blk); WRITE_NUMERIC(reg_max_rec); WRITE_NUMERIC(reg_max_key); WRITE_NUMERIC(reg_std_null_coll); if (gtm_utf8_mode) { MEMCPY_LIT(outptr, UTF8_NAME); label_len = STR_LIT_LEN(UTF8_NAME); outptr[label_len++] = ' '; } else label_len = 0; buflen = sizeof(label_buff); if (FALSE == cli_get_str("LABEL", label_buff, &buflen)) { MEMCPY_LIT(&outptr[label_len], EXTR_DEFAULT_LABEL); buflen = STR_LIT_LEN(EXTR_DEFAULT_LABEL); } else memcpy(&outptr[label_len], label_buff, buflen); label_len += buflen; if (label_len > BIN_HEADER_LABELSZ) { /* Label size exceeds the space, so truncate the label and back off to the valid beginning (i.e. to the leading byte) of the last character that can entirely fit in the space */ label_len = BIN_HEADER_LABELSZ; chptr = &outptr[BIN_HEADER_LABELSZ]; UTF8_LEADING_BYTE(chptr, outptr, leadptr); assert(chptr - leadptr < 4); if (leadptr < chptr) label_len -= (chptr - leadptr); } outptr += label_len; for (iter = label_len; iter < BIN_HEADER_LABELSZ; iter++) *outptr++ = ' '; label_len = outptr - outbuf; if (!ochset_set) { #ifdef KEEP_zOS_EBCDIC /* extract ascii header for binary by default */ /* Do we need to restore it somewhere? */ saved_out_set = (io_curr_device.out)->out_code_set; (io_curr_device.out)->out_code_set = DEFAULT_CODE_SET; #else saved_out_set = (io_curr_device.out)->ochset; (io_curr_device.out)->ochset = CHSET_M; #endif } op_val.str.addr = (char *)(&label_len); op_val.str.len = sizeof(label_len); op_write(&op_val); op_val.str.addr = (char *)outbuf; op_val.str.len = label_len; op_write(&op_val); } else { assert((MU_FMT_GO == format) || (MU_FMT_ZWR == format)); label_len = sizeof(label_buff); if (FALSE == cli_get_str("LABEL", label_buff, &label_len)) { MEMCPY_LIT(label_buff, EXTR_DEFAULT_LABEL); label_len = STR_LIT_LEN(EXTR_DEFAULT_LABEL); } if (gtm_utf8_mode) { label_buff[label_len++] = ' '; MEMCPY_LIT(&label_buff[label_len], UTF8_NAME); label_len += STR_LIT_LEN(UTF8_NAME); } label_buff[label_len++] = '\n'; op_val.mvtype = MV_STR; op_val.str.len = label_len; op_val.str.addr = label_buff; op_write(&op_val); stringpool.free = stringpool.base; op_horolog(&val); stringpool.free = stringpool.base; op_fnzdate(&val, &datefmt, &null_str, &null_str, &val); op_val = val; op_val.mvtype = MV_STR; op_write(&op_val); if (MU_FMT_ZWR == format) { op_val.str.addr = " ZWR"; op_val.str.len = sizeof(" ZWR") - 1; op_write(&op_val); } op_wteol(1); } REVERT; ESTABLISH(mu_extract_handler1); success = TRUE; for (gl_ptr = gl_head.next; gl_ptr; gl_ptr = gl_ptr->next) { if (mu_ctrly_occurred) break; if (mu_ctrlc_occurred) { gbl_name_buff[0]='^'; memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len); gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff, global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen); mu_ctrlc_occurred = FALSE; } gv_bind_name(gd_header, &gl_ptr->name.str); if (MU_FMT_BINARY == format) { label_len = sizeof(extr_collhdr); op_val.mvtype = MV_STR; op_val.str.addr = (char *)(&label_len); op_val.str.len = sizeof(label_len); op_write(&op_val); extr_collhdr.act = gv_target->act; extr_collhdr.nct = gv_target->nct; extr_collhdr.ver = gv_target->ver; op_val.str.addr = (char *)(&extr_collhdr); op_val.str.len = sizeof(extr_collhdr); op_write(&op_val); } /* Note: Do not change the order of the expression below. * Otherwise if success is FALSE, mu_extr_gblout() will not be called at all. * We want mu_extr_gblout() to be called irrespective of the value of success */ success = mu_extr_gblout(&gl_ptr->name, &global_total, format) && success; if (logqualifier) { gbl_name_buff[0]='^'; memcpy(&gbl_name_buff[1], gl_ptr->name.str.addr, gl_ptr->name.str.len); gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, gl_ptr->name.str.len + 1, gbl_name_buff, global_total.recknt, global_total.keylen, global_total.datalen, global_total.reclen); mu_ctrlc_occurred = FALSE; } grand_total.recknt += global_total.recknt; if (grand_total.reclen < global_total.reclen) grand_total.reclen = global_total.reclen; if (grand_total.keylen < global_total.keylen) grand_total.keylen = global_total.keylen; if (grand_total.datalen < global_total.datalen) grand_total.datalen = global_total.datalen; } op_val.mvtype = op_pars.mvtype = MV_STR; op_val.str.addr = (char *)outfilename;; op_val.str.len = filename_len; op_pars.str.len = sizeof(no_param); op_pars.str.addr = (char *)&no_param; op_close(&op_val, &op_pars); REVERT; if (mu_ctrly_occurred) { gtm_putmsg(VARLSTCNT(1) ERR_EXTRACTCTRLY); mupip_exit(ERR_MUNOFINISH); } gtm_putmsg(VARLSTCNT(8) ERR_RECORDSTAT, 6, LEN_AND_LIT(gt_lit), grand_total.recknt, grand_total.keylen, grand_total.datalen, grand_total.reclen); if (MU_FMT_BINARY == format) { /* truncate the last newline charactor flushed by op_close */ STAT_FILE((char *)outfilename, &statbuf, stat_res); if (-1 == stat_res) rts_error(VARLSTCNT(1) errno); TRUNCATE_FILE((const char *)outfilename, statbuf.st_size - 1, truncate_res); if (-1 == truncate_res) rts_error(VARLSTCNT(1) errno); } mupip_exit(success ? SS_NORMAL : ERR_MUNOFINISH); }
void mupip_cvtgbl(void) { char fn[MAX_FN_LEN + 1], *line1_ptr, *line3_ptr; gtm_int64_t begin_i8, end_i8; int dos, i, file_format, line1_len, line3_len, utf8; uint4 begin, cli_status, end, max_rec_size; unsigned char buff[MAX_ONERROR_VALUE_LEN]; unsigned short fn_len, len; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; assert(MAX_ONERROR_VALUE_LEN > MAX_FORMAT_VALUE_LEN); /* so the buff[] definition above is good for FORMAT and ONERROR */ /* If an online rollback occurs when we are loading up the database with new globals and takes us back to a prior logical * state, then we should not continue with the load. The reason being that the application might rely on certain globals to * be present before loading others and that property could be violated if online rollback takes the database back to a * completely different logical state. Set the variable issue_DBROLLEDBACK_anyways that forces the restart logic to issue * an rts_error the first time it detects an online rollback (that takes the database to a prior logical state). */ TREF(issue_DBROLLEDBACK_anyways) = TRUE; is_replicator = TRUE; skip_dbtriggers = TRUE; fn_len = SIZEOF(fn); if (cli_present("STDIN")) { /* User wants to load from standard input */ assert(SIZEOF(fn) > sys_input.len); memcpy(fn, sys_input.addr, sys_input.len); fn_len = sys_input.len; assert(-1 != fcntl(fileno(stdin), F_GETFD)); /* Check if both file name and -STDIN specified. */ if (cli_get_str("FILE", fn, &fn_len)) mupip_exit(ERR_MUPCLIERR); } else if (!cli_get_str("FILE", fn, &fn_len)) /* User wants to read from a file. */ mupip_exit(ERR_MUPCLIERR); /* Neither -STDIN nor file name specified. */ file_input_init(fn, fn_len, IOP_EOL); if (mupip_error_occurred) EXIT(-1); mu_outofband_setup(); if ((cli_status = cli_present("BEGIN")) == CLI_PRESENT) { if (!cli_get_int64("BEGIN", &begin_i8)) mupip_exit(ERR_MUPCLIERR); if (1 > begin_i8) mupip_exit(ERR_LOADBGSZ); else if (MAXUINT4 < begin_i8) mupip_exit(ERR_LOADBGSZ2); begin = (uint4) begin_i8; } else { begin = 1; begin_i8 = 1; } if ((cli_status = cli_present("END")) == CLI_PRESENT) { if (!cli_get_int64("END", &end_i8)) mupip_exit(ERR_MUPCLIERR); if (1 > end_i8) mupip_exit(ERR_LOADEDSZ); else if (MAXUINT4 < end_i8) mupip_exit(ERR_LOADEDSZ2); if (end_i8 < begin_i8) mupip_exit(ERR_LOADEDBG); end = (uint4) end_i8; } else end = MAXUINT4; if ((cli_status = cli_present("FILL_FACTOR")) == CLI_PRESENT) { assert(SIZEOF(gv_fillfactor) == SIZEOF(int4)); if (!cli_get_int("FILL_FACTOR", (int4 *)&gv_fillfactor)) gv_fillfactor = MAX_FILLFACTOR; if (gv_fillfactor < MIN_FILLFACTOR) gv_fillfactor = MIN_FILLFACTOR; else if (gv_fillfactor > MAX_FILLFACTOR) gv_fillfactor = MAX_FILLFACTOR; } else gv_fillfactor = MAX_FILLFACTOR; if (cli_present("ONERROR") == CLI_PRESENT) { len = SIZEOF(buff); if (!cli_get_str("ONERROR", (char *)buff, &len)) { assert(FALSE); onerror = ONERROR_PROCEED; } else { lower_to_upper(buff, buff, len); if (!memcmp(buff, "STOP", len)) onerror = ONERROR_STOP; else if (!memcmp(buff, "PROCEED", len)) onerror = ONERROR_PROCEED; else if (!memcmp(buff, "INTERACTIVE", len)) { if (isatty(0)) /*if stdin is a terminal*/ onerror = ONERROR_INTERACTIVE; else onerror = ONERROR_STOP; } else { util_out_print("Illegal ONERROR parameter for load",TRUE); mupip_exit(ERR_MUPCLIERR); } } } else onerror = ONERROR_PROCEED; /* Default: Proceed on error */ file_format = get_load_format(&line1_ptr, &line3_ptr, &line1_len, &line3_len, &max_rec_size, &utf8, &dos); /* from header */ if (MU_FMT_GOQ == file_format) mupip_exit(ERR_LDBINFMT); if (BADZCHSET == utf8) mupip_exit(ERR_MUNOFINISH); if (cli_present("FORMAT") == CLI_PRESENT) { /* If the command speficies a format see if it matches the label */ len = SIZEOF(buff); if (!cli_get_str("FORMAT", (char *)buff, &len)) go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, file_format, utf8, dos); else { lower_to_upper(buff, buff, len); if (!memcmp(buff, "ZWR", len)) { /* If the label did not determine a format let them specify ZWR and they can sort out the result */ if ((MU_FMT_ZWR == file_format) || (MU_FMT_UNRECOG == file_format)) go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, MU_FMT_ZWR, utf8, dos); else mupip_exit(ERR_LDBINFMT); } else if (!memcmp(buff, "BINARY", len)) { if (MU_FMT_BINARY == file_format) bin_load(begin, end, line1_ptr, line1_len); else mupip_exit(ERR_LDBINFMT); } else if (!memcmp(buff, "GO", len)) { /* If the label did not determine a format let them specify GO and they can sort out the result */ if ((MU_FMT_GO == file_format) || (MU_FMT_UNRECOG == file_format)) go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, MU_FMT_GO, utf8, dos); else mupip_exit(ERR_LDBINFMT); } else if (!memcmp(buff, "GOQ", len)) { /* get_load_format doesn't recognize GOQ labels' */ if (MU_FMT_UNRECOG == file_format) goq_load(); else mupip_exit(ERR_LDBINFMT); } else { util_out_print("Illegal file format for load",TRUE); mupip_exit(ERR_MUPCLIERR); } } } else { if (MU_FMT_BINARY == file_format) bin_load(begin, end, line1_ptr, line1_len); else if ((MU_FMT_ZWR == file_format) || (MU_FMT_GO == file_format)) go_load(begin, end, (unsigned char *)line1_ptr, line3_ptr, line3_len, max_rec_size, file_format, utf8, dos); else { assert(MU_FMT_UNRECOG == file_format); mupip_exit(ERR_LDBINFMT); } } mupip_exit(mupip_error_occurred ? ERR_MUNOFINISH : SS_NORMAL); }
void mupip_backup(void) { bool journal; char *tempdirname, *tempfilename, *ptr; uint4 level, blk, status, ret; unsigned short s_len, length, ntries; int4 size, gds_ratio, buff_size, i, crit_counter; uint4 ustatus; size_t backup_buf_size; trans_num tn; backup_buff_ptr_t bptr; static boolean_t once = TRUE; backup_reg_list *rptr, *clnup_ptr; boolean_t inc_since_inc , inc_since_rec, result, newjnlfiles, gotit, newjnlfiles_specified, keep_prev_link, bkdbjnl_disable_specified, bkdbjnl_off_specified; unsigned char since_buff[50]; jnl_create_info jnl_info; file_control *fc; char tempdir_trans_buffer[MAX_TRANS_NAME_LEN], tempnam_prefix[MAX_FN_LEN], tempdir_full_buffer[MAX_FN_LEN + 1], jnl_file_name[JNL_NAME_SIZE]; char *jnl_str_ptr, rep_str[256], jnl_str[256], entry[256], full_jnl_fn[JNL_NAME_SIZE], prev_jnl_fn[JNL_NAME_SIZE]; int ccnt, index, comparison, num, jnl_fstat; mstr tempdir_log, tempdir_trans, *file, tempdir_full, filestr; uint4 jnl_status, temp_file_name_len, tempdir_trans_len, trans_log_name_status; #if defined(VMS) struct FAB temp_fab; struct NAM temp_nam; struct XABPRO temp_xabpro; short iosb[4]; char def_jnl_fn[MAX_FN_LEN]; GDS_INFO *gds_info; char exp_file_name[MAX_FN_LEN]; uint4 exp_file_name_len; #elif defined(UNIX) struct stat stat_buf; int fstat_res; int sync_io_status; boolean_t sync_io, sync_io_specified; #else # error UNSUPPORTED PLATFORM #endif boolean_t jnl_options[jnl_end_of_list] = {FALSE, FALSE, FALSE}, save_no_prev_link; error_def(ERR_BACKUPCTRL); error_def(ERR_MUPCLIERR); error_def(ERR_FREEZECTRL); error_def(ERR_DBRDONLY); error_def(ERR_DBFILERR); error_def(ERR_MUNOACTION); error_def(ERR_MUNOFINISH); error_def(ERR_BACKUP2MANYKILL); error_def(ERR_MUSELFBKUP); error_def(ERR_JNLNOCREATE); error_def(ERR_JNLCREATE); error_def(ERR_PREVJNLLINKCUT); error_def(ERR_JNLSTATE); error_def(ERR_FILEEXISTS); error_def(ERR_JNLDISABLE); error_def(ERR_FILEPARSE); error_def(ERR_JNLFNF); error_def(ERR_NOTRNDMACC); /* ==================================== STEP 1. Initialization ======================================= */ ret = SS_NORMAL; jnl_str_ptr = &jnl_str[0]; halt_ptr = grlist = NULL; in_backup = TRUE; inc_since_inc = inc_since_rec = file_backed_up = error_mupip = FALSE; debug_mupip = (CLI_PRESENT == cli_present("DBG")); mu_outofband_setup(); jnl_status = 0; if (once) { gvinit(); once = FALSE; } /* ============================ STEP 2. Parse and construct grlist ================================== */ if (incremental = (CLI_PRESENT == cli_present("INCREMENTAL") || CLI_PRESENT == cli_present("BYTESTREAM"))) { int4 temp_tn; if (0 == cli_get_hex("TRANSACTION", &temp_tn)) { temp_tn = 0; s_len = sizeof(since_buff); if (cli_get_str("SINCE", (char *)since_buff, &s_len)) { lower_to_upper(since_buff, since_buff, s_len); if ((0 == memcmp(since_buff, "INCREMENTAL", s_len)) || (0 == memcmp(since_buff, "BYTESTREAM", s_len))) inc_since_inc = TRUE; else if (0 == memcmp(since_buff, "RECORD", s_len)) inc_since_rec = TRUE; } } else if (temp_tn < 1) { util_out_print("The minimum allowable transaction number is one.", TRUE); mupip_exit(ERR_MUNOACTION); } tn = (trans_num)temp_tn; } online = (TRUE != cli_negated("ONLINE")); record = (CLI_PRESENT == cli_present("RECORD")); newjnlfiles_specified = FALSE; newjnlfiles = TRUE; /* by default */ keep_prev_link = TRUE; if (CLI_PRESENT == cli_present("NEWJNLFILES")) { newjnlfiles_specified = newjnlfiles = TRUE; if (CLI_NEGATED == cli_present("NEWJNLFILES.PREVLINK")) keep_prev_link = FALSE; UNIX_ONLY( sync_io_status = cli_present("NEWJNLFILES.SYNC_IO"); sync_io_specified = TRUE; if (CLI_PRESENT == sync_io_status) sync_io = TRUE; else if (CLI_NEGATED == sync_io_status) sync_io = FALSE; else sync_io_specified = FALSE; ) } else if (CLI_NEGATED == cli_present("NEWJNLFILES"))
void str_to_upper(char* str) { for(char* pc=str;*pc!=0;++pc) { *pc = lower_to_upper(*pc); } }
void iosocket_tls(mval *optionmval, int4 timeoutarg, mval *tlsid, mval *password, mval *extraarg) { /* note extraarg is not currently used */ int4 length, flags, timeout, msec_timeout, status, status2, len, errlen, devlen, tls_errno, save_errno; io_desc *iod; d_socket_struct *dsocketptr; socket_struct *socketptr; char optionstr[MAX_TLSOPTION], idstr[MAX_TLSID_LEN], passwordstr[GTM_PASSPHRASE_MAX_ASCII + 1]; const char *errp; tls_option option; gtm_tls_socket_t *tlssocket; ABS_TIME cur_time, end_time; # ifdef USE_POLL struct pollfd fds; # else fd_set fds, *readfds, *writefds; struct timeval timeout_spec, *timeout_ptr; # endif iod = io_curr_device.out; assert(gtmsocket == iod->type); dsocketptr = (d_socket_struct *)iod->dev_sp; if (0 >= dsocketptr->n_socket) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_NOSOCKETINDEV); return; } if (dsocketptr->n_socket <= dsocketptr->current_socket) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_CURRSOCKOFR, 2, dsocketptr->current_socket, dsocketptr->n_socket); return; } if (dsocketptr->mupintr) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO); socketptr = dsocketptr->socket[dsocketptr->current_socket]; ENSURE_DATA_SOCKET(socketptr); if (socket_tcpip != socketptr->protocol) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, RTS_ERROR_MVAL(optionmval), LEN_AND_LIT("but socket is not TCP")); return; } if (socket_connected != socketptr->state) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("/TLS"), LEN_AND_LIT("but socket not connected")); return; } if (NULL != tlsid) { length = tlsid->str.len; if (MAX_TLSID_LEN < (length + 1)) /* for null */ { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("TLSID"), LEN_AND_LIT("too long")); return; } STRNCPY_STR(idstr, tlsid->str.addr, length); idstr[length] = '\0'; } else idstr[0] = '\0'; if (NULL != password) { length = password->str.len; if (GTM_PASSPHRASE_MAX_ASCII < length) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_LIT("passphrase"), LEN_AND_LIT("too long")); return; } STRNCPY_STR(passwordstr, password->str.addr, length); passwordstr[length] = '\0'; } else passwordstr[0] = '\0'; length = MIN(MAX_TLSOPTION, optionmval->str.len); lower_to_upper((uchar_ptr_t)optionstr, (uchar_ptr_t)optionmval->str.addr, length); if (0 == memcmp(optionstr, "CLIENT", length)) option = tlsopt_client; else if (0 == memcmp(optionstr, "SERVER", length)) option = tlsopt_server; else if (0 == memcmp(optionstr, "RENEGOTIATE", length)) option = tlsopt_renegotiate; else option = tlsopt_invalid; memcpy(iod->dollar.device, "0", SIZEOF("0")); if (NO_M_TIMEOUT != timeoutarg) { msec_timeout = timeout2msec(timeoutarg); sys_get_curr_time(&cur_time); add_int_to_abs_time(&cur_time, msec_timeout, &end_time); } else msec_timeout = -1; if ((tlsopt_client == option) || (tlsopt_server == option)) { /* most of the setup is common */ if (socketptr->tlsenabled) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSPARAM, 4, LEN_AND_STR(optionstr), LEN_AND_LIT("but TLS already enabled")); return; } assertpro((0 >= socketptr->buffered_length) && (0 >= socketptr->obuffer_length)); if (NULL == tls_ctx) { /* first use of TLS */ if (-1 == gtm_tls_loadlibrary()) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSDLLNOOPEN, 0, ERR_TEXT, 2, LEN_AND_STR(dl_err)); return; } if (NULL == (tls_ctx = (gtm_tls_init(GTM_TLS_API_VERSION, GTMTLS_OP_INTERACTIVE_MODE)))) { errp = gtm_tls_get_error(); len = SIZEOF(ONE_COMMA) - 1; memcpy(iod->dollar.device, ONE_COMMA, len); errlen = STRLEN(errp); devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen); memcpy(&iod->dollar.device[len], errp, devlen + 1); if (devlen < errlen) iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0'; if (socketptr->ioerror) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSINIT, 0, ERR_TEXT, 2, errlen, errp); if (NO_M_TIMEOUT != timeoutarg) dollar_truth = FALSE; return; } } socketptr->tlsenabled = TRUE; flags = GTMTLS_OP_SOCKET_DEV | ((tlsopt_client == option) ? GTMTLS_OP_CLIENT_MODE : 0); socketptr->tlssocket = gtm_tls_socket(tls_ctx, NULL, socketptr->sd, idstr, flags); if (NULL == socketptr->tlssocket) { socketptr->tlsenabled = FALSE; errp = gtm_tls_get_error(); len = SIZEOF(ONE_COMMA) - 1; memcpy(iod->dollar.device, ONE_COMMA, len); errlen = STRLEN(errp); devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen); memcpy(&iod->dollar.device[len], errp, devlen + 1); if (devlen < errlen) iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0'; if (socketptr->ioerror) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSCONVSOCK, 0, ERR_TEXT, 2, errlen, errp); if (NO_M_TIMEOUT != timeoutarg) dollar_truth = FALSE; return; } status = 0; # ifndef USE_POLL if (NO_M_TIMEOUT == timeoutarg) timeout_ptr = NULL; else { timeout_spec.tv_sec = msec_timeout / 1000; timeout_spec.tv_usec = (msec_timeout % 1000) * 1000; /* remainder in millsecs to microsecs */ timeout_ptr = &timeout_spec; } # endif do { status2 = 0; if (0 != status) { # ifdef USE_POLL fds.fd = socketptr->sd; fds.events = (GTMTLS_WANT_READ == status) ? POLLIN : POLLOUT; # else readfds = writefds = NULL; assertpro(FD_SETSIZE > socketptr->sd); FD_ZERO(&fds); FD_SET(socketptr->sd, &fds); writefds = (GTMTLS_WANT_WRITE == status) ? &fds : NULL; readfds = (GTMTLS_WANT_READ == status) ? &fds : NULL; # endif POLL_ONLY(if (-1 == (status2 = poll(&fds, 1, msec_timeout)))) SELECT_ONLY(if (-1 == (status2 = select(socketptr->sd + 1, readfds, writefds, NULL, timeout_ptr)))) { save_errno = errno; if (EAGAIN == save_errno) { rel_quant(); /* allow resources to become available */ status2 = 0; /* treat as timeout */ } else if (EINTR == save_errno) status2 = 0; } } else status2 = 1; /* do accept/connect first time */ if (0 < status2) { if (tlsopt_server == option) status = gtm_tls_accept((gtm_tls_socket_t *)socketptr->tlssocket); else status = gtm_tls_connect((gtm_tls_socket_t *)socketptr->tlssocket); } if ((0 > status2) || ((status != 0) && ((GTMTLS_WANT_READ != status) && (GTMTLS_WANT_WRITE != status)))) { if (0 != status) { tls_errno = gtm_tls_errno(); if (0 > tls_errno) errp = gtm_tls_get_error(); else errp = STRERROR(tls_errno); } else errp = STRERROR(save_errno); socketptr->tlsenabled = FALSE; len = SIZEOF(ONE_COMMA) - 1; memcpy(iod->dollar.device, ONE_COMMA, len); errlen = STRLEN(errp); devlen = MIN((SIZEOF(iod->dollar.device) - len - 1), errlen); memcpy(&iod->dollar.device[len], errp, devlen + 1); if (devlen < errlen) iod->dollar.device[SIZEOF(iod->dollar.device) - 1] = '\0'; if (socketptr->ioerror) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_TLSHANDSHAKE, 0, ERR_TEXT, 2, errlen, errp); return; } if ((0 != status) && (0 <= status2)) /* not accepted/connected and not error */ { /* check for timeout if not error or want read or write */ if ((0 != timeoutarg) && (NO_M_TIMEOUT != timeoutarg)) { sys_get_curr_time(&cur_time); cur_time = sub_abs_time(&end_time, &cur_time); if (0 >= cur_time.at_sec) { /* no more time */ gtm_tls_session_close((gtm_tls_socket_t **)&socketptr->tlssocket); socketptr->tlsenabled = FALSE; dollar_truth = FALSE; return; } else { /* adjust msec_timeout for poll/select */ # ifdef USE_POLL msec_timeout = (cur_time.at_sec * 1000) + (cur_time.at_usec / 1000); # else timeout_spec.tv_sec = cur_time.at_sec; timeout_spec.tv_usec = (gtm_tv_usec_t)cur_time.at_usec; # endif } } else if (0 == timeoutarg) { /* only one chance */ gtm_tls_session_close((gtm_tls_socket_t **)&socketptr->tlssocket); socketptr->tlsenabled = FALSE; dollar_truth = FALSE; return; } continue; } } while ((GTMTLS_WANT_READ == status) || (GTMTLS_WANT_WRITE == status)); /* turn on output buffering */ if (0 == socketptr->obuffer_size) socketptr->obuffer_size = socketptr->buffer_size; socketptr->obuffer_length = socketptr->obuffer_offset = 0; socketptr->obuffer_wait_time = DEFAULT_WRITE_WAIT; socketptr->obuffer_flush_time = DEFAULT_WRITE_WAIT * 2; /* until add device parameter */ socketptr->obuffer = malloc(socketptr->obuffer_size); } else if (tlsopt_renegotiate == option)
int f_text(oprtype *a, opctype op) { int implicit_offset = 0; triple *r, *label; error_def(ERR_TEXTARG); error_def(ERR_RTNNAME); r = maketriple(op); switch (window_token) { case TK_CIRCUMFLEX: implicit_offset = 1; /* CAUTION - fall-through */ case TK_PLUS: r->operand[0] = put_str(zero_mstr.addr, 0); /* Null label - top of routine */ break; case TK_INTLIT: int_label(); /* CAUTION - fall through */ case TK_IDENT: if (!(cmd_qlf.qlf & CQ_LOWER_LABELS)) lower_to_upper((uchar_ptr_t)window_ident.addr, (uchar_ptr_t)window_ident.addr, window_ident.len); r->operand[0] = put_str(window_ident.addr, window_ident.len); advancewindow(); break; case TK_ATSIGN: if (!indirection(&(r->operand[0]))) return FALSE; r->opcode = OC_INDTEXT; break; default: stx_error(ERR_TEXTARG); return FALSE; } assert(TK_PLUS == window_token || TK_CIRCUMFLEX == window_token || TK_RPAREN == window_token || TK_EOL == window_token); if (OC_INDTEXT != r->opcode || TK_PLUS == window_token || TK_CIRCUMFLEX == window_token) { /* Need another parm chained in to deal with offset and routine name except for the case where an * indirect specifies the entire argument. */ label = newtriple(OC_PARAMETER); r->operand[1] = put_tref(label); } if (TK_PLUS != window_token) { if (OC_INDTEXT != r->opcode || TK_CIRCUMFLEX == window_token) /* Set default offset (0 or 1 as computed above) when offset not specified */ label->operand[0] = put_ilit(implicit_offset); else { /* Fill in indirect text for case where indirect specifies entire operand */ r->opcode = OC_INDFUN; r->operand[1] = put_ilit((mint)indir_fntext); } } else { /* Process offset */ advancewindow(); if (!intexpr(&(label->operand[0]))) return FALSE; } if (TK_CIRCUMFLEX != window_token) { /* No routine specified - default to current routine */ if (OC_INDFUN != r->opcode) { if (!run_time) label->operand[1] = put_str(routine_name.addr, routine_name.len); else label->operand[1] = put_tref(newtriple(OC_CURRTN)); } } else { /* Routine has been specified - pull it */ advancewindow(); switch(window_token) { case TK_IDENT: # ifdef GTM_TRIGGER if (TK_HASH == director_token) /* Coagulate tokens as necessary (and available) to allow '#' in the routine name */ advwindw_hash_in_mname_allowed(); # endif label->operand[1] = put_str(window_ident.addr, window_ident.len); advancewindow(); break; case TK_ATSIGN: if (!indirection(&label->operand[1])) return FALSE; r->opcode = OC_INDTEXT; break; default: stx_error(ERR_RTNNAME); return FALSE; } } ins_triple(r); *a = put_tref(r); return TRUE; }
int f_text(oprtype *a, opctype op) { char *c; int implicit_offset = 0, len; triple *label, *r; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; r = maketriple(op); switch (TREF(window_token)) { case TK_CIRCUMFLEX: implicit_offset = 1; /* CAUTION - fall-through */ case TK_PLUS: r->operand[0] = put_str(zero_mstr.addr, 0); /* Null label - top of routine */ break; case TK_INTLIT: int_label(); /* CAUTION - fall through */ case TK_IDENT: if (!(cmd_qlf.qlf & CQ_LOWER_LABELS)) lower_to_upper((uchar_ptr_t)(TREF(window_ident)).addr, (uchar_ptr_t)(TREF(window_ident)).addr, (TREF(window_ident)).len); r->operand[0] = put_str((TREF(window_ident)).addr, (TREF(window_ident)).len); advancewindow(); break; case TK_ATSIGN: if (!indirection(&(r->operand[0]))) return FALSE; r->opcode = OC_INDTEXT; break; default: stx_error(ERR_TEXTARG); return FALSE; } /* The assert below can be useful when working on $TEXT parsing issues but causes problems in debug builds with * bad syntax asserts. Hence it is normally commented out. Uncomment to re-enable for $TEXT parsing issues. */ /* assert((TK_PLUS == TREF(window_token)) || (TK_CIRCUMFLEX == TREF(window_token)) || (TK_RPAREN == TREF(window_token)) * || (TK_EOL == TREF(window_token))); */ if ((OC_INDTEXT != r->opcode) || (TK_PLUS == TREF(window_token)) || (TK_CIRCUMFLEX == TREF(window_token))) { /* Need another parm chained in to deal with offset and routine name except for the case where an * indirect specifies the entire argument. */ label = newtriple(OC_PARAMETER); r->operand[1] = put_tref(label); } if (TK_PLUS != TREF(window_token)) { if ((OC_INDTEXT != r->opcode) || (TK_CIRCUMFLEX == TREF(window_token))) /* Set default offset (0 or 1 as computed above) when offset not specified */ label->operand[0] = put_ilit(implicit_offset); else { /* Fill in indirect text for case where indirect specifies entire operand */ r->opcode = OC_INDFUN; r->operand[1] = put_ilit((mint)indir_fntext); } } else { /* Process offset */ advancewindow(); if (EXPR_FAIL == expr(&(label->operand[0]), MUMPS_INT)) return FALSE; } if (TK_CIRCUMFLEX != TREF(window_token)) { /* No routine specified - default to current routine */ if (OC_INDFUN != r->opcode) label->operand[1] = PUT_CURRENT_RTN; /* tell op_fntext to pick up current routine version */ } else { /* Routine has been specified - pull it */ advancewindow(); switch (TREF(window_token)) { case TK_IDENT: # ifdef GTM_TRIGGER if (TK_HASH == TREF(director_token)) /* Coagulate tokens as necessary (and available) to allow '#' in the routine name */ advwindw_hash_in_mname_allowed(); # endif if (TK_DOLLAR == TREF(director_token)) /* the item has a $ in it */ { /* violate information hiding to special case illegal names GT.M can return from $STACK() et al */ c = TREF(lexical_ptr) - STR_LIT_LEN("GTM$"); advancewindow(); /* parse to $ */ if (0 == memcmp(c, "GTM$", STR_LIT_LEN("GTM$"))) { /* parse past GTM$DMOD or GTM$CI to prevent RPARENMISSING error */ advancewindow(); /* parse to end of ident */ len = TREF(lexical_ptr) - c - (TK_EOL == TREF(director_token) ? 0 : 1); for (implicit_offset = 0; ARRAYSIZE(suppressed_values) > implicit_offset; implicit_offset++) { /* reuse of implicit_offset */ if ((STRLEN(suppressed_values[implicit_offset]) == len) && (0 == memcmp(c, suppressed_values[implicit_offset], len))) { label->operand[1] = put_str(suppressed_values[implicit_offset], len); break; } } if (ARRAYSIZE(suppressed_values) == implicit_offset) (TREF(last_source_column))--; /* if no match (error) adjust for extra parse */ } else implicit_offset = ARRAYSIZE(suppressed_values); if (ARRAYSIZE(suppressed_values) == implicit_offset) { /* give the error that would arise had we just ignored the $ */ stx_error(ERR_RPARENMISSING); return FALSE; } } else label->operand[1] = put_str((TREF(window_ident)).addr, (TREF(window_ident)).len); advancewindow(); break; case TK_ATSIGN: if (!indirection(&label->operand[1])) return FALSE; r->opcode = OC_INDTEXT; break; default: stx_error(ERR_RTNNAME); return FALSE; } } ins_triple(r); *a = put_tref(r); return TRUE; }