void iomt_use(io_desc *iod, mval *pp) { unsigned char ch, len; int lab_type; int4 length, width; int4 skips; d_mt_struct *mt_ptr, *out_ptr; io_desc *d_in, *d_out; mident tab; int p_offset; error_def(ERR_MTINVLAB); error_def(ERR_DEVPARMNEG); error_def(ERR_UNIMPLOP); p_offset = 0; d_in = iod->pair.in; d_out = iod->pair.out; mt_ptr = (d_mt_struct *)iod->dev_sp; out_ptr = (d_mt_struct *)d_out->dev_sp; while (*(pp->str.addr + p_offset) != iop_eol) { switch (ch = *(pp->str.addr + p_offset++)) { case iop_ebcdic: mt_ptr->ebcdic = TRUE; break; case iop_noebcdic: mt_ptr->ebcdic = FALSE; break; case iop_newversion: mt_ptr->newversion = TRUE; break; case iop_label: memset(tab.c, 0, sizeof(mident)); len = *(pp->str.addr + p_offset); memcpy(tab.c, (pp->str.addr + p_offset + 1), (len < sizeof(mident) ? len : sizeof(mident))); if ((lab_type = namelook(mtlab_index, mtlab_names, tab.c)) < 0) rts_error(VARLSTCNT(1) ERR_MTINVLAB); mt_ptr->labeled = mtlab_type[lab_type]; break; case iop_nolabel: mt_ptr->labeled = FALSE; break; case iop_rdcheckdata: mt_ptr->read_mask |= IO_M_DATACHECK; break; case iop_nordcheckdata: mt_ptr->read_mask &= (~(IO_M_DATACHECK)); break; case iop_wtcheckdata: mt_ptr->write_mask |= IO_M_DATACHECK; break; case iop_nowtcheckdata: mt_ptr->write_mask &= (~(IO_M_DATACHECK)); break; case iop_inhretry: mt_ptr->write_mask |= IO_M_INHRETRY; mt_ptr->read_mask |= IO_M_INHRETRY; break; case iop_retry: mt_ptr->write_mask &= ~IO_M_INHRETRY; mt_ptr->read_mask &= ~IO_M_INHRETRY; break; case iop_inhextgap: mt_ptr->write_mask |= IO_M_INHEXTGAP; break; case iop_extgap: mt_ptr->write_mask &= ~IO_M_INHEXTGAP; 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_width: GET_LONG(width, (pp->str.addr + p_offset)); if (width < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); if (width == 0) { iod->wrap = FALSE; iod->width = mt_ptr->record_sz; } else if (width <= mt_ptr->record_sz) { iomt_flush(iod); iod->width = width; iod->wrap = TRUE; } break; case iop_wrap: out_ptr->wrap = TRUE; break; case iop_nowrap: out_ptr->wrap = FALSE; break; case iop_skipfile: GET_LONG(skips, (pp->str.addr + p_offset)); iomt_skipfile(iod, skips); break; case iop_unload: assert(FALSE); break; case iop_rewind: iomt_rewind(iod); break; case iop_erasetape: iomt_erase(iod); break; case iop_space: GET_LONG(skips, (pp->str.addr + p_offset)); iomt_skiprecord(iod, skips); break; case iop_writeof: iomt_eof(iod); break; case iop_writetm: iomt_tm(iod); break; case iop_writelb: memset(&tab, 0, sizeof(mident)); len = *(pp->str.addr + p_offset); memcpy(&tab.c[0], pp->str.addr + p_offset + 1, (len < sizeof(mident) ? len : sizeof(mident))); if ((lab_type = namelook(mtwtlab_index, mtwtlab_names, tab.c)) < 0) rts_error(VARLSTCNT(1) ERR_MTINVLAB); iomt_wtansilab(iod, mtwtlab_type[lab_type]); break; case iop_next: rts_error(VARLSTCNT(1) ERR_UNIMPLOP); break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_ipchset: { if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; } case iop_opchset: { if ( (iconv_t) 0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; } default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } }
void iosocket_use(io_desc *iod, mval *pp) { unsigned char ch, len; int handled_len, handlea_len, handles_len; int4 length, width, new_len; d_socket_struct *dsocketptr; socket_struct *socketptr, newsocket; char handlea[MAX_HANDLE_LEN], handles[MAX_HANDLE_LEN], handled[MAX_HANDLE_LEN]; char addr[SA_MAXLITLEN], *errptr, sockaddr[SA_MAXLITLEN], temp_addr[SA_MAXLITLEN], ioerror; unsigned char delimiter_buffer[MAX_N_DELIMITER * (MAX_DELIM_LEN + 1)]; unsigned char zff_buffer[MAX_ZFF_LEN]; boolean_t attach_specified = FALSE, detach_specified = FALSE, connect_specified = FALSE, ioerror_specified = FALSE, listen_specified = FALSE, socket_specified = FALSE, delay_specified = FALSE, nodelay_specified = FALSE, bfsize_specified = FALSE, ibfsize_specified = FALSE, moreread_specified = FALSE, create_new_socket; int4 index, n_specified, zff_len, delimiter_len, moreread_timeout; int fil_type, nodelay, p_offset = 0; uint4 bfsize = DEFAULT_SOCKET_BUFFER_SIZE, ibfsize; char *tab; int save_errno; size_t d_socket_struct_len; mstr lcl_zff; assert(iod->state == dev_open); assert(iod->type == gtmsocket); dsocketptr = (d_socket_struct *)(iod->dev_sp); /* ---------------------------------- parse the command line ------------------------------------ */ n_specified = 0; zff_len = -1; /* indicates neither ZFF nor ZNOFF specified */ delimiter_len = -1; /* indicates neither DELIM nor NODELIM specified */ /* A read or wait was interrupted for this device. Allow only parmless use in $zinterrupt code for and interrupted device. */ if (iop_eol != *(pp->str.addr + p_offset)) { /* Parameters were specified */ if (dsocketptr->mupintr) { /* And if we are in $zinterrupt code this is not allowed */ if (dollar_zininterrupt) rts_error(VARLSTCNT(1) ERR_ZINTRECURSEIO); /* We are not in $zinterrupt code and this device was not resumed properly so clear its restartability. */ io_find_mvstent(iod, TRUE); dsocketptr->mupintr = FALSE; } } else if (dsocketptr->mupintr && !dollar_zininterrupt) { /* The interrupted read was not properly resumed so clear it now */ dsocketptr->mupintr = FALSE; dsocketptr->sock_save_state.who_saved = sockwhich_invalid; io_find_mvstent(iod, TRUE); } while (iop_eol != (ch = *(pp->str.addr + p_offset++))) { assert((params)ch < (params)n_iops); switch (ch) { case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_filter: len = *(pp->str.addr + p_offset); tab = pp->str.addr + p_offset + 1; if ((fil_type = namelook(filter_index, filter_names, tab, len)) < 0) { rts_error(VARLSTCNT(1) ERR_TTINVFILTER); return; } switch (fil_type) { case 0: iod->write_filter |= CHAR_FILTER; break; case 1: iod->write_filter |= ESC1; break; case 2: iod->write_filter &= ~CHAR_FILTER; break; case 3: iod->write_filter &= ~ESC1; break; } break; case iop_nofilter: iod->write_filter = 0; break; case iop_attach: n_specified++; attach_specified = TRUE; handlea_len = (int)(*(pp->str.addr + p_offset)); memcpy(handlea, (char *)(pp->str.addr + p_offset + 1), handlea_len); break; case iop_detach: n_specified++; detach_specified = TRUE; handled_len = (int)(*(pp->str.addr + p_offset)); memcpy(handled, (char *)(pp->str.addr + p_offset + 1), handled_len); break; case iop_connect: n_specified++; connect_specified = TRUE; len = *(pp->str.addr + p_offset); if (len < SA_MAXLITLEN) { memcpy(sockaddr, (char *)(pp->str.addr + p_offset + 1), len); sockaddr[len] = '\0'; } else rts_error(VARLSTCNT(6) ERR_ADDRTOOLONG, 4, len, pp->str.addr + p_offset + 1, len, SA_MAXLITLEN); break; case iop_delimiter: n_specified++; 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_nodelimiter: delimiter_len = 0; break; case iop_zdelay: delay_specified = TRUE; break; case iop_znodelay: nodelay_specified = TRUE; break; case iop_zbfsize: bfsize_specified = TRUE; GET_ULONG(bfsize, pp->str.addr + p_offset); if ((0 == bfsize) || (MAX_SOCKET_BUFFER_SIZE < bfsize)) rts_error(VARLSTCNT(3) ERR_ILLESOCKBFSIZE, 1, bfsize); break; case iop_zibfsize: ibfsize_specified = TRUE; GET_ULONG(ibfsize, pp->str.addr + p_offset); if ((0 == ibfsize) || (MAX_INTERNAL_SOCBUF_SIZE < ibfsize)) rts_error(VARLSTCNT(3) ERR_ILLESOCKBFSIZE, 1, ibfsize); break; case iop_ioerror: n_specified++; ioerror_specified = TRUE; ioerror = *(char *)(pp->str.addr + p_offset + 1); break; case iop_zlisten: n_specified++; listen_specified = TRUE; len = *(pp->str.addr + p_offset); if (len < SA_MAXLITLEN) { memcpy(sockaddr, (char *)(pp->str.addr + p_offset + 1), len); sockaddr[len] = '\0'; } else rts_error(VARLSTCNT(6) ERR_ADDRTOOLONG, 4, len, pp->str.addr + p_offset + 1, len, SA_MAXLITLEN); break; case iop_socket: n_specified++; socket_specified = TRUE; handles_len = (int)(*(pp->str.addr + p_offset)); memcpy(handles, (char *)(pp->str.addr + p_offset + 1), handles_len); break; case iop_ipchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ((iconv_t)0 != iod->input_conv_cd) ICONV_CLOSE_CD(iod->input_conv_cd); SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); #endif break; case iop_opchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ((iconv_t)0 != iod->output_conv_cd) ICONV_CLOSE_CD(iod->output_conv_cd); SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); #endif break; case iop_zff: if (MAX_ZFF_LEN >= (zff_len = (int4)(unsigned char)*(pp->str.addr + p_offset))) memcpy(zff_buffer, (char *)(pp->str.addr + p_offset + 1), zff_len); else rts_error(VARLSTCNT(4) ERR_ZFF2MANY, 2, zff_len, MAX_ZFF_LEN); break; case iop_znoff: zff_len = 0; 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_width: /* SOCKET WIDTH is handled the same way as TERMINAL WIDTH */ GET_LONG(width, pp->str.addr + p_offset); if (width < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); if (0 == width) { iod->width = TCPDEF_WIDTH; iod->wrap = FALSE; } else { iod->width = width; iod->wrap = TRUE; } break; case iop_wrap: iod->wrap = TRUE; break; case iop_nowrap: iod->wrap = FALSE; break; case iop_morereadtime: /* Time in milliseconds socket read will wait for more data before returning */ GET_LONG(moreread_timeout, pp->str.addr + p_offset); if (-1 == moreread_timeout) moreread_timeout = DEFAULT_MOREREAD_TIMEOUT; else if (-1 > moreread_timeout) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); else if (MAX_MOREREAD_TIMEOUT < moreread_timeout) rts_error(VARLSTCNT(3) ERR_MRTMAXEXCEEDED, 1, MAX_MOREREAD_TIMEOUT); moreread_specified = TRUE; break; default: /* ignore deviceparm */ break; } p_offset += ((io_params_size[ch] == IOP_VAR_SIZE) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } /* ------ return immediately if no flag, worth a check because it is mostly true ------------ */ if (1 == p_offset) return; /* ------------------------------ compatibility verification -------------------------------- */ if ((socket_specified) && ((n_specified > 2) || ((2 == n_specified) && (0 >= delimiter_len)))) { rts_error(VARLSTCNT(8) ERR_ACOMPTBINC, 6, LEN_AND_LIT("SOCKET"), LEN_AND_LIT("DELIMITER"), LEN_AND_LIT("USE")); return; } if (connect_specified && listen_specified) { rts_error(VARLSTCNT(8) ERR_ABNCOMPTINC, 6, LEN_AND_LIT("CONNECT"), LEN_AND_LIT("ZLISTEN"), LEN_AND_LIT("USE")); return; } if (delay_specified && nodelay_specified) { rts_error(VARLSTCNT(8) ERR_ABNCOMPTINC, 6, LEN_AND_LIT("DELAY"), LEN_AND_LIT("NODELAY"), LEN_AND_LIT("OPEN")); return; } /* ------------------ make a local copy of device structure to play with -------------------- */ d_socket_struct_len = SIZEOF(d_socket_struct) + (SIZEOF(socket_struct) * (gtm_max_sockets - 1)); memcpy(newdsocket, dsocketptr, d_socket_struct_len); /* --------------- handle the two special cases attach/detach first ------------------------- */ if (detach_specified) { if (1 < n_specified) { rts_error(VARLSTCNT(6) ERR_ANCOMPTINC, 4, LEN_AND_LIT("DETACH"), LEN_AND_LIT("USE")); return; } if (NULL == socket_pool) iosocket_poolinit(); iosocket_switch(handled, handled_len, newdsocket, socket_pool); memcpy(dsocketptr, newdsocket, d_socket_struct_len); if (0 > dsocketptr->current_socket) { io_curr_device.in = io_std_device.in; io_curr_device.out = io_std_device.out; } return; /* detach can only be specified by itself */ } if (attach_specified) { /* NOTE: A socket could be moved from one device to another using DETACH/ATTACH. A socket does not carry I[O]CHSET with * it while being moved. Such a socket will use the I[O]CHSET of the device it is ATTACHed to. If there is input still * buffered, this may cause unintentional consequences in the application if I[O]CHSET changes. GT.M does not detect * (or report) a change in I[O]CHSET due to DETACH/ATTACH. */ if (1 < n_specified) { rts_error(VARLSTCNT(6) ERR_ANCOMPTINC, 4, LEN_AND_LIT("ATTACH"), LEN_AND_LIT("USE")); return; } if (NULL == socket_pool) { rts_error(VARLSTCNT(4) ERR_SOCKNOTFND, 2, handlea_len, handlea); return; } iosocket_switch(handlea, handlea_len, socket_pool, newdsocket); memcpy(dsocketptr, newdsocket, d_socket_struct_len); return; /* attach can only be specified by itself */ } /* ------------ create/identify the socket to work on and make a local copy ----------------- */ if (create_new_socket = (listen_specified || connect_specified)) /* real "=" */ { /* allocate the structure for a new socket */ if (NULL == (socketptr = iosocket_create(sockaddr, bfsize, -1))) return; /* give the new socket a handle */ iosocket_handle(handles, &handles_len, TRUE, dsocketptr); socketptr->handle_len = handles_len; memcpy(socketptr->handle, handles, handles_len); socketptr->dev = newdsocket; /* use newdsocket temporarily for the sake of bind/connect */ } else { if (socket_specified) { /* use the socket flag to identify which socket to apply changes */ if (0 > (index = iosocket_handle(handles, &handles_len, FALSE, newdsocket))) { rts_error(VARLSTCNT(4) ERR_SOCKNOTFND, 2, handles_len, handles); return; } newdsocket->current_socket = index; socketptr = newdsocket->socket[index]; } else { socketptr = newdsocket->socket[newdsocket->current_socket]; if (newdsocket->n_socket <= newdsocket->current_socket) { assert(FALSE); rts_error(VARLSTCNT(4) ERR_CURRSOCKOFR, 2, newdsocket->current_socket, newdsocket->n_socket); return; } } } newsocket = *socketptr; /* ---------------------- apply changes to the local copy of the socket --------------------- */ if (0 <= delimiter_len) { iosocket_delimiter(delimiter_buffer, delimiter_len, &newsocket, (0 == delimiter_len)); /* The delimiter has changed. The iosocket_readfl/write routine won't notice so we have to do the UTF16xx conversion since we changed it. */ DBGSOCK2((stdout, "socuse: Delimiter(s) replaced - num delims: %d delimiter_len: %d ichset: %d ochset: %d\n", newsocket.n_delimiter, delimiter_len, iod->ichset, iod->ochset)); if (0 < delimiter_len) { if (!newsocket.first_read && (CHSET_UTF16BE == iod->ichset || CHSET_UTF16LE == iod->ichset)) { /* We have been reading with this socket so convert this new delimiter set */ DBGSOCK2((stdout, "socuse: Converting new delimiters for input\n")); iosocket_delim_conv(&newsocket, iod->ichset); } if (!newsocket.first_write && (CHSET_UTF16BE == iod->ochset || CHSET_UTF16LE == iod->ochset)) { /* We have been writing with this socket so convert the new default output delimiter */ DBGSOCK2((stdout, "socuse: Converting new delimiters for output\n")); if (newsocket.first_read || (CHSET_UTF16BE != iod->ichset && CHSET_UTF16LE != iod->ichset)) { /* Need to do conversion as iosocket_delim_conv above didn't do it for us */ DBGSOCK2((stdout, "socuse: running convert for write since input didn't do it\n")); new_len = gtm_conv(chset_desc[CHSET_UTF8], chset_desc[iod->ochset], &newsocket.delimiter[0], NULL, NULL); if (MAX_DELIM_LEN < new_len) { rts_error(VARLSTCNT(1) ERR_DELIMSIZNA); return; } } else { DBGSOCK2((stdout, "socuse: using previous length from read conversion\n")); new_len = newsocket.idelimiter[0].len; } newsocket.odelimiter0.len = new_len; UNICODE_ONLY(newsocket.odelimiter0.char_len = newsocket.delimiter[0].char_len); newsocket.odelimiter0.addr = malloc(new_len); memcpy(newsocket.odelimiter0.addr, (newsocket.first_read ? (char *)stringpool.free : newsocket.idelimiter[0].addr), new_len); } } } if (iod->wrap && 0 != newsocket.n_delimiter && iod->width < newsocket.delimiter[0].len) rts_error(VARLSTCNT(4) ERR_DELIMWIDTH, 2, iod->width, newsocket.delimiter[0].len); if (0 <= zff_len && /* ZFF or ZNOFF specified */ 0 < (newsocket.zff.len = zff_len)) /* assign the new ZFF len, might be 0 from ZNOFF, or ZFF="" */ { /* ZFF="non-zero-len-string" specified */ if (CHSET_UTF16BE == iod->ochset || CHSET_UTF16LE == iod->ochset) /* need conversion of ZFF */ { DBGSOCK2((stdout, "socuse: Converting zff\n")); lcl_zff.addr = (char *)zff_buffer; lcl_zff.len = zff_len; new_len = gtm_conv(chset_desc[CHSET_UTF8], chset_desc[iod->ochset], &lcl_zff, NULL, NULL); if (MAX_ZFF_LEN < new_len) rts_error(VARLSTCNT(4) ERR_ZFF2MANY, 2, new_len, MAX_ZFF_LEN); if (NULL == newsocket.zff.addr) /* we rely on newsocket.zff.addr being set to 0 in iosocket_create() */ newsocket.zff.addr = (char *)malloc(MAX_ZFF_LEN); newsocket.zff.len = new_len; UNICODE_ONLY(newsocket.zff.char_len = 0); /* don't care */ memcpy(newsocket.zff.addr, stringpool.free, new_len); } else { /* Store parm without conversion */ if (gtm_utf8_mode) /* Check if ZFF has any invalid UTF-8 character */ { /* Note: the ZFF string originates from the source program, so is in UTF-8 mode or M mode regardless of OCHSET of this device. ZFF is output on WRITE # command, and MUST contain valid UTF-8 sequence. This validation is handled by gtm_conv in the path above. */ utf8_len_strict(zff_buffer, zff_len); } if (NULL == newsocket.zff.addr) /* we rely on newsocket.zff.addr being set to 0 in iosocket_create() */ newsocket.zff.addr = (char *)malloc(MAX_ZFF_LEN); memcpy(newsocket.zff.addr, zff_buffer, zff_len); } } if (ioerror_specified) newsocket.ioerror = ('T' == ioerror || 't' == ioerror); if (nodelay_specified || delay_specified) newsocket.nodelay = nodelay_specified; /* defaults to DELAY */ if (ibfsize_specified) newsocket.bufsiz = ibfsize; if (moreread_specified) { newsocket.moreread_timeout = moreread_timeout; newsocket.def_moreread_timeout = TRUE; /* need to know this was user-defined in iosocket_readfl.c */ } if (!create_new_socket) { /* these changes apply to only pre-existing sockets */ if (bfsize_specified) newsocket.buffer_size = bfsize; #ifdef TCP_NODELAY nodelay = newsocket.nodelay ? 1 : 0; if ((socketptr->nodelay != newsocket.nodelay) && (-1 == tcp_routines.aa_setsockopt(newsocket.sd, IPPROTO_TCP, TCP_NODELAY, &nodelay, SIZEOF(nodelay)))) { save_errno = errno; errptr = (char *)STRERROR(save_errno); rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("TCP_NODELAY"), save_errno, LEN_AND_STR(errptr)); return; } #endif if ((socketptr->bufsiz != newsocket.bufsiz) && (-1 == tcp_routines.aa_setsockopt(newsocket.sd, SOL_SOCKET, SO_RCVBUF, &newsocket.bufsiz, SIZEOF(newsocket.bufsiz)))) { save_errno = errno; errptr = (char *)STRERROR(save_errno); rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("SO_RCVBUF"), save_errno, LEN_AND_STR(errptr)); return; } if (socketptr->buffer_size != newsocket.buffer_size) { if (socketptr->buffered_length > bfsize) rts_error(VARLSTCNT(4) ERR_SOCKBFNOTEMPTY, 2, bfsize, socketptr->buffered_length); newsocket.buffer = (char *)malloc(bfsize); if (0 < socketptr->buffered_length) { memcpy(newsocket.buffer, socketptr->buffer + socketptr->buffered_offset, socketptr->buffered_length); newsocket.buffered_offset = 0; } } } /* -------------------------------------- action -------------------------------------------- */ if ((listen_specified && (!iosocket_bind(&newsocket, NO_M_TIMEOUT, ibfsize_specified))) || (connect_specified && (!iosocket_connect(&newsocket, 0, ibfsize_specified)))) { /* error message should be printed from bind/connect */ if (socketptr->sd > 0) (void)tcp_routines.aa_close(socketptr->sd); iosocket_delimiter((unsigned char *)NULL, 0, &newsocket, TRUE); if (NULL != socketptr->zff.addr) free(socketptr->zff.addr); if (NULL != socketptr->buffer) free(socketptr->buffer); free(socketptr); return; } /* ------------------------------------ commit changes -------------------------------------- */ if (create_new_socket) { if (gtm_max_sockets <= newdsocket->n_socket) { rts_error(VARLSTCNT(3) ERR_SOCKMAX, 1, gtm_max_sockets); return; } /* a new socket is created. so add to the list */ newsocket.dev = dsocketptr; newdsocket->socket[newdsocket->n_socket++] = socketptr; newdsocket->current_socket = newdsocket->n_socket - 1; } else if (socketptr->buffer_size != newsocket.buffer_size) free(socketptr->buffer); *socketptr = newsocket; memcpy(dsocketptr, newdsocket, d_socket_struct_len); return; }
static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspace) { int4 status; int4 size; mstr tn; /* translated name */ mstr chset_mstr; int oflag; unsigned char ch; int file_des; struct stat outbuf; char *buf, namebuf[LOGNAME_LEN + 1]; d_mt_struct *mt_ptr; int umask_orig, umask_creat; int char_or_block_special; int fstat_res; int save_errno; int p_offset; boolean_t ichset_specified, ochset_specified; error_def(ERR_SYSCALL); mt_ptr = NULL; char_or_block_special = FALSE; file_des = -2; oflag = 0; tn.len = tl->len; if (tn.len > LOGNAME_LEN) tn.len = LOGNAME_LEN; tn.addr = tl->dollar_io; memcpy(namebuf, tn.addr, tn.len); namebuf[tn.len] = '\0'; buf = namebuf; 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; tl->iod->type = n_io_dev_types; p_offset = 0; while(iop_eol != *(pp->str.addr + p_offset)) { ch = *(pp->str.addr + p_offset++); if (iop_sequential == ch) tl->iod->type = rm; if (IOP_VAR_SIZE == io_params_size[ch]) p_offset += *(pp->str.addr + p_offset) + 1; else p_offset += io_params_size[ch]; } } if ((n_io_dev_types == tl->iod->type) && mspace && mspace->str.len) tl->iod->type = us; if (n_io_dev_types == tl->iod->type) { if (0 == memvcmp(tn.addr, tn.len, sys_input.addr, sys_input.len)) { file_des = 0; FSTAT_FILE(file_des, &outbuf, fstat_res); if (-1 == fstat_res) { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } else { if (0 == memvcmp(tn.addr, tn.len, sys_output.addr, sys_output.len)) { file_des = 1; FSTAT_FILE(file_des, &outbuf, fstat_res); if (-1 == fstat_res) { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } else if (0 == memvcmp(tn.addr, tn.len, "/dev/null", 9)) tl->iod->type = nl; else if ((-1 == Stat(buf, &outbuf)) && (n_io_dev_types == tl->iod->type)) { if (ENOENT == errno) tl->iod->type = rm; else { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } } } if (n_io_dev_types == tl->iod->type) { switch(outbuf.st_mode & S_IFMT) { case S_IFCHR: case S_IFBLK: char_or_block_special = TRUE; break; case S_IFIFO: tl->iod->type = ff; break; case S_IFREG: case S_IFDIR: tl->iod->type = rm; break; case S_IFSOCK: case 0: tl->iod->type = ff; break; default: break; } } naml->iod = tl->iod; } active_device = naml->iod; if ((-2 == file_des) && (dev_open != naml->iod->state) && (us != naml->iod->type) && (tcp != naml->iod->type)) { oflag |= (O_RDWR | O_CREAT | O_NOCTTY); size = 0; p_offset = 0; ichset_specified = ochset_specified = FALSE; while(iop_eol != *(pp->str.addr + p_offset)) { assert((params) *(pp->str.addr + p_offset) < (params)n_iops); switch ((ch = *(pp->str.addr + p_offset++))) { case iop_allocation: if (rm == naml->iod->type) { GET_LONG(size, pp->str.addr + p_offset); size *= 512; } break; case iop_append: if (rm == naml->iod->type) oflag |= O_APPEND; break; case iop_contiguous: break; case iop_newversion: if ((dev_open != naml->iod->state) && (rm == naml->iod->type)) oflag |= O_TRUNC; break; case iop_readonly: oflag &= ~(O_RDWR | O_CREAT | O_WRONLY); oflag |= O_RDONLY; break; case iop_writeonly: oflag &= ~(O_RDWR | O_RDONLY); oflag |= O_WRONLY | O_CREAT; break; case iop_ipchset: #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != naml->iod->input_conv_cd ) { ICONV_CLOSE_CD(naml->iod->input_conv_cd); } SET_CODE_SET(naml->iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != naml->iod->in_code_set) ICONV_OPEN_CD(naml->iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; #endif if (gtm_utf8_mode) { chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(naml->iod->ichset, &chset_mstr); ichset_specified = TRUE; } break; case iop_opchset: #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != naml->iod->output_conv_cd) { ICONV_CLOSE_CD(naml->iod->output_conv_cd); } SET_CODE_SET(naml->iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != naml->iod->out_code_set) ICONV_OPEN_CD(naml->iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; #endif if (gtm_utf8_mode) { chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(naml->iod->ochset, &chset_mstr); ochset_specified = TRUE; } break; case iop_m: case iop_utf8: case iop_utf16: case iop_utf16be: case iop_utf16le: if (gtm_utf8_mode) { naml->iod->ichset = naml->iod->ochset = (iop_m == ch) ? CHSET_M : (iop_utf8 == ch) ? CHSET_UTF8 : (iop_utf16 == ch) ? CHSET_UTF16 : (iop_utf16be == ch) ? CHSET_UTF16BE : CHSET_UTF16LE; ichset_specified = ochset_specified = TRUE; } break; default: break; } if (IOP_VAR_SIZE == io_params_size[ch]) p_offset += *(pp->str.addr + p_offset) + 1; else p_offset += io_params_size[ch]; } if (!ichset_specified) naml->iod->ichset = (gtm_utf8_mode) ? CHSET_UTF8 : CHSET_M; if (!ochset_specified) naml->iod->ochset = (gtm_utf8_mode) ? CHSET_UTF8 : CHSET_M; if (CHSET_M != naml->iod->ichset && CHSET_UTF16 != naml->iod->ichset) get_chset_desc(&chset_names[naml->iod->ichset]); if (CHSET_M != naml->iod->ochset && CHSET_UTF16 != naml->iod->ochset) get_chset_desc(&chset_names[naml->iod->ochset]); /* RW permissions for owner and others as determined by umask. */ umask_orig = umask(000); /* determine umask (destructive) */ (void)umask(umask_orig); /* reset umask */ umask_creat = 0666 & ~umask_orig; /* * the check for EINTR below is valid and should not be converte d to an EINTR * wrapper macro, due to the other errno values being checked. */ while ((-1 == (file_des = OPEN4(buf, oflag, umask_creat, size)))) { if ( EINTR == errno || ETXTBSY == errno || ENFILE == errno || EBUSY == errno || ((mb == naml->iod->type) && (ENXIO == errno))) continue; else break; } if (-1 == file_des) return FALSE; } assert (tcp != naml->iod->type); #ifdef KEEP_zOS_EBCDIC SET_CODE_SET(naml->iod->in_code_set, OUTSIDE_CH_SET); if (DEFAULT_CODE_SET != naml->iod->in_code_set) ICONV_OPEN_CD(naml->iod->input_conv_cd, OUTSIDE_CH_SET, INSIDE_CH_SET); SET_CODE_SET(naml->iod->out_code_set, OUTSIDE_CH_SET); if (DEFAULT_CODE_SET != naml->iod->out_code_set) ICONV_OPEN_CD(naml->iod->output_conv_cd, INSIDE_CH_SET, OUTSIDE_CH_SET); #endif /* smw 99/12/18 not possible to be -1 here */ if (-1 == file_des) { rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("open()"), CALLFROM, save_errno); } if (n_io_dev_types == naml->iod->type) { if (isatty(file_des)) naml->iod->type = tt; else if (char_or_block_special && file_des > 2) /* assume mag tape */ naml->iod->type = mt; else naml->iod->type = rm; } assert(naml->iod->type < n_io_dev_types); naml->iod->disp_ptr = &io_dev_dispatch_mupip[naml->iod->type]; 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 = 0; /* MUPIP should not use 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; } status = (naml->iod->disp_ptr->open)(naml, pp, file_des, mspace, NO_M_TIMEOUT); if (TRUE == status) naml->iod->state = dev_open; else if (dev_open == naml->iod->state) naml->iod->state = dev_closed; if (1 == file_des) naml->iod->dollar.zeof = TRUE; active_device = 0; if (run_time) return (status); return TRUE; }
void dse_open (void) { unsigned short cli_len; int4 save_errno; mval val; mval pars; int cnt; static readonly unsigned char open_params_list[2] = { (unsigned char)iop_newversion, (unsigned char)iop_eol }; if (cli_present("FILE") == CLI_PRESENT) { if (CLOSED_FMT != dse_dmp_format) { util_out_print("Error: output file already open.",TRUE); util_out_print("Current output file: !AD", TRUE, strlen(patch_ofile), &patch_ofile[0]); return; } cli_len = sizeof(patch_ofile); if (!cli_get_str("FILE", patch_ofile, &cli_len)) return; if (0 == cli_len) { util_out_print("Error: must specify a file name.",TRUE); return; } patch_ofile[cli_len] = 0; patch_len = cli_len; pars.mvtype = MV_STR; pars.str.len = sizeof(open_params_list); pars.str.addr = (char *)open_params_list; val.mvtype = MV_STR; val.str.len = patch_len; val.str.addr = (char *)patch_ofile; (*op_open_ptr)(&val, &pars, 0, NULL); op_use(&val, &pars); if (CLI_PRESENT == cli_present("OCHSET")) { if (cli_get_str("OCHSET", ch_set_name, &cli_len)) { if (0 == cli_len) { util_out_print("Error: must specify a charactor set name.",TRUE); return; } ch_set_name[cli_len] = 0; ch_set_len = cli_len; if ( (iconv_t)0 != dse_over_cvtcd ) { ICONV_CLOSE_CD(dse_over_cvtcd); } ICONV_OPEN_CD(dse_over_cvtcd, INSIDE_CH_SET, ch_set_name); } } else if ( (iconv_t) 0 == dse_over_cvtcd ) ICONV_OPEN_CD(dse_over_cvtcd, INSIDE_CH_SET, OUTSIDE_CH_SET); dse_dmp_format = OPEN_FMT; } else { if (CLOSED_FMT != dse_dmp_format) util_out_print("Current output file: !AD", TRUE, strlen(patch_ofile), &patch_ofile[0]); else util_out_print("No current output file.",TRUE); } return; }
void iott_use(io_desc *iod, mval *pp) { boolean_t flush_input; char dc1, *ttab; d_tt_struct *temp_ptr, *tt_ptr; int p_offset, fil_type, save_errno, status; int4 length, width; io_desc *d_in, *d_out; io_termmask mask_term; struct sigaction act; struct termios t; uint4 mask_in; unsigned char ch, len; boolean_t ch_set; p_offset = 0; assert(iod->state == dev_open); ESTABLISH_GTMIO_CH(&iod->pair, ch_set); iott_flush(iod); tt_ptr = (d_tt_struct *)iod->dev_sp; if (*(pp->str.addr + p_offset) != iop_eol) { if (tt_ptr->mupintr) if (dollar_zininterrupt) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_ZINTRECURSEIO); else { /* The interrupted read was not properly resumed so clear it now */ tt_ptr->mupintr = FALSE; tt_ptr->tt_state_save.who_saved = ttwhichinvalid; io_find_mvstent(iod, TRUE); } status = tcgetattr(tt_ptr->fildes, &t); if (0 != status) { save_errno = errno; ISSUE_NOPRINCIO_IF_NEEDED_TT(io_curr_device.out); rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TCGETATTR, 1, tt_ptr->fildes, save_errno); } flush_input = FALSE; d_in = iod->pair.in; d_out = iod->pair.out; temp_ptr = (d_tt_struct *)d_in->dev_sp; mask_in = temp_ptr->term_ctrl; mask_term = temp_ptr->mask_term; while (*(pp->str.addr + p_offset) != iop_eol) { switch (ch = *(pp->str.addr + p_offset++)) { case iop_canonical: tt_ptr->canonical = TRUE; t.c_lflag |= ICANON; break; case iop_nocanonical: tt_ptr->canonical = FALSE; t.c_lflag &= ~(ICANON); break; case iop_empterm: tt_ptr->ext_cap |= TT_EMPTERM; break; case iop_noempterm: tt_ptr->ext_cap &= ~TT_EMPTERM; break; case iop_cenable: if (!ctrlc_on) { /* if it's already cenable, no need to change */ temp_ptr = (d_tt_struct *)io_std_device.in->dev_sp; if (tt_ptr->fildes == temp_ptr->fildes) { /* if this is $PRINCIPAL make sure the ctrlc_handler is enabled */ sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = ctrlc_handler_ptr; sigaction(SIGINT, &act, 0); ctrlc_on = TRUE; } } break; case iop_nocenable: if (ctrlc_on) { /* if it's already nocenable, no need to change */ temp_ptr = (d_tt_struct *)io_std_device.in->dev_sp; if (tt_ptr->fildes == temp_ptr->fildes) { /* if this is $PRINCIPAL may disable the ctrlc_handler */ if (0 == (CTRLC_MSK & tt_ptr->enbld_outofbands.mask)) { /* but only if ctrap=$c(3) is not active */ sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = SIG_IGN; sigaction(SIGINT, &act, 0); } ctrlc_on = FALSE; } } break; case iop_clearscreen: if (NULL != CLR_EOS) gtm_tputs(CLR_EOS, 1, outc); break; case iop_convert: mask_in |= TRM_CONVERT; break; case iop_noconvert: mask_in &= ~TRM_CONVERT; break; case iop_ctrap: GET_LONG(tt_ptr->enbld_outofbands.mask, pp->str.addr + p_offset); if (!ctrlc_on) { /* if cenable, ctrlc_handler active anyway, otherwise, depends on ctrap=$c(3) */ sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = (CTRLC_MSK & tt_ptr->enbld_outofbands.mask) ? ctrlc_handler_ptr : SIG_IGN; sigaction(SIGINT, &act, 0); } break; case iop_downscroll: if (d_out->dollar.y > 0) { d_out->dollar.y--; if (NULL != CURSOR_ADDRESS) gtm_tputs(gtm_tparm(CURSOR_ADDRESS, d_out->dollar.y, d_out->dollar.x), 1, outc); } break; case iop_echo: mask_in &= (~TRM_NOECHO); break; case iop_noecho: mask_in |= TRM_NOECHO; break; case iop_editing: if (io_curr_device.in == io_std_device.in) { /* $PRINCIPAL only */ tt_ptr->ext_cap |= TT_EDITING; if (!tt_ptr->recall_buff.addr) { assert(tt_ptr->in_buf_sz); tt_ptr->recall_buff.addr = malloc(tt_ptr->in_buf_sz); tt_ptr->recall_size = tt_ptr->in_buf_sz; tt_ptr->recall_buff.len = 0; /* nothing in buffer */ } } break; case iop_noediting: if (io_curr_device.in == io_std_device.in) tt_ptr->ext_cap &= ~TT_EDITING; /* $PRINCIPAL only */ break; case iop_escape: mask_in |= TRM_ESCAPE; break; case iop_noescape: mask_in &= (~TRM_ESCAPE); default: break; case iop_eraseline: if (NULL != CLR_EOL) gtm_tputs(CLR_EOL, 1, outc); break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_filter: len = *(pp->str.addr + p_offset); ttab = pp->str.addr + p_offset + 1; if ((fil_type = namelook(filter_index, filter_names, ttab, len)) < 0) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_TTINVFILTER); return; } switch (fil_type) { case 0: iod->write_filter |= CHAR_FILTER; break; case 1: iod->write_filter |= ESC1; break; case 2: iod->write_filter &= ~CHAR_FILTER; break; case 3: iod->write_filter &= ~ESC1; break; } break; case iop_nofilter: iod->write_filter = 0; break; case iop_flush: flush_input = TRUE; break; case iop_hostsync: t.c_iflag |= IXOFF; break; case iop_nohostsync: t.c_iflag &= ~IXOFF; break; case iop_insert: if (io_curr_device.in == io_std_device.in) tt_ptr->ext_cap &= ~TT_NOINSERT; /* $PRINCIPAL only */ break; case iop_noinsert: if (io_curr_device.in == io_std_device.in) tt_ptr->ext_cap |= TT_NOINSERT; /* $PRINCIPAL only */ break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (0 > length) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DEVPARMNEG); d_out->length = length; break; case iop_pasthru: mask_in |= TRM_PASTHRU; break; case iop_nopasthru: mask_in &= (~TRM_PASTHRU); break; case iop_readsync: mask_in |= TRM_READSYNC; break; case iop_noreadsync: dc1 = (char)17; temp_ptr = (d_tt_struct *)io_std_device.in->dev_sp; DOWRITERC(temp_ptr->fildes, &dc1, 1, status); if (0 != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) status); mask_in &= (~TRM_READSYNC); break; case iop_terminator: memcpy(&mask_term.mask[0], (pp->str.addr + p_offset), SIZEOF(io_termmask)); temp_ptr = (d_tt_struct *)d_in->dev_sp; if (mask_term.mask[0] == NUL && mask_term.mask[1] == NUL && mask_term.mask[2] == NUL && mask_term.mask[3] == NUL && mask_term.mask[4] == NUL && mask_term.mask[5] == NUL && mask_term.mask[6] == NUL && mask_term.mask[7] == NUL) { temp_ptr->default_mask_term = TRUE; if (CHSET_UTF8 == d_in->ichset) { mask_term.mask[0] = TERM_MSK_UTF8_0; mask_term.mask[4] = TERM_MSK_UTF8_4; } else mask_term.mask[0] = TERM_MSK; } else temp_ptr->default_mask_term = FALSE; break; case iop_noterminator: temp_ptr = (d_tt_struct *)d_in->dev_sp; temp_ptr->default_mask_term = FALSE; memset(&mask_term.mask[0], 0, SIZEOF(io_termmask)); break; case iop_ttsync: t.c_iflag |= IXON; break; case iop_nottsync: t.c_iflag &= ~IXON; break; case iop_typeahead: mask_in &= (~TRM_NOTYPEAHD); break; case iop_notypeahead: mask_in |= TRM_NOTYPEAHD; break; case iop_upscroll: d_out->dollar.y++; if (d_out->length) d_out->dollar.y %= d_out->length; if (NULL != CURSOR_ADDRESS) gtm_tputs(gtm_tparm(CURSOR_ADDRESS, d_out->dollar.y, d_out->dollar.x), 1, outc); break; case iop_width: GET_LONG(width, pp->str.addr + p_offset); if (0 > width) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_DEVPARMNEG); /* Do not allow a WIDTH of 1 if UTF mode (ICHSET or OCHSET is not M) */ if ((1 == width) && ((CHSET_M != d_in->ochset) || (CHSET_M != d_in->ichset))) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_WIDTHTOOSMALL); if (0 == width) { d_out->wrap = FALSE; d_out->width = TTDEF_PG_WIDTH; } else { d_out->width = width; d_out->wrap = TRUE; } break; case iop_wrap: d_out->wrap = TRUE; break; case iop_nowrap: d_out->wrap = FALSE; break; case iop_x: GET_LONG(d_out->dollar.x, pp->str.addr + p_offset); if (0 > (int4)d_out->dollar.x) d_out->dollar.x = 0; if (d_out->dollar.x > d_out->width && d_out->wrap) { d_out->dollar.y += (d_out->dollar.x / d_out->width); if (d_out->length) d_out->dollar.y %= d_out->length; d_out->dollar.x %= d_out->width; } if (NULL != CURSOR_ADDRESS) gtm_tputs(gtm_tparm(CURSOR_ADDRESS, d_out->dollar.y, d_out->dollar.x), 1, outc); break; case iop_y: GET_LONG(d_out->dollar.y, pp->str.addr + p_offset); if (0 > (int4)d_out->dollar.y) d_out->dollar.y = 0; if (d_out->length) d_out->dollar.y %= d_out->length; if (NULL != CURSOR_ADDRESS) gtm_tputs(gtm_tparm(CURSOR_ADDRESS, d_out->dollar.y, d_out->dollar.x), 1, outc); break; case iop_ipchset: { # ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); # endif break; } case iop_opchset: { # ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != iod->output_conv_cd) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); # endif break; } } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } temp_ptr = (d_tt_struct *)d_in->dev_sp; Tcsetattr(tt_ptr->fildes, TCSANOW, &t, status, save_errno); if (0 != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_TCSETATTR, 1, tt_ptr->fildes, save_errno); temp_ptr->term_ctrl = mask_in; memcpy(&temp_ptr->mask_term, &mask_term, SIZEOF(io_termmask)); if (flush_input) { TCFLUSH(tt_ptr->fildes, TCIFLUSH, status); if (0 != status) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, LIT_AND_LEN("tcflush input"), CALLFROM, errno); } } else if (tt_ptr->mupintr && !dollar_zininterrupt) { /* The interrupted read was not properly resumed so clear it now */ tt_ptr->mupintr = FALSE; tt_ptr->tt_state_save.who_saved = ttwhichinvalid; io_find_mvstent(iod, TRUE); /* clear mv stack entry */ } REVERT_GTMIO_CH(&iod->pair, ch_set); return; }
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 iorm_use(io_desc *iod, mval *pp) { boolean_t fstat_done; unsigned char c; short mode, mode1; int4 length, width; long size; int fstat_res, save_errno; d_rm_struct *rm_ptr; struct stat statbuf; int p_offset; error_def(ERR_DEVPARMNEG); error_def(ERR_RMWIDTHPOS); error_def(ERR_RMWIDTHTOOBIG); error_def(ERR_SYSCALL); p_offset = 0; rm_ptr = (d_rm_struct *)iod->dev_sp; fstat_done = FALSE; while (*(pp->str.addr + p_offset) != iop_eol) { assert((params) *(pp->str.addr + p_offset) < (params)n_iops); switch (c = *(pp->str.addr + p_offset++)) { case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_fixed: if (iod->state != dev_open) rm_ptr->fixed = TRUE; break; case iop_nofixed: if (iod->state != dev_open) rm_ptr->fixed = FALSE; 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_w_protection: FSTAT_CHECK; mode &= ~(0x07); mode |= *(pp->str.addr + p_offset); break; case iop_g_protection: FSTAT_CHECK; mode &= ~(0x07 << 3); mode |= *(pp->str.addr + p_offset) << 3; break; case iop_s_protection: case iop_o_protection: FSTAT_CHECK; mode &= ~(0x07 << 6); mode |= *(pp->str.addr + p_offset) << 6; break; case iop_readonly: rm_ptr->noread = TRUE; break; case iop_noreadonly: rm_ptr->noread = FALSE; break; case iop_recordsize: GET_LONG(width, (pp->str.addr + p_offset)); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); else if (MAX_STRLEN < width) rts_error(VARLSTCNT(1) ERR_RMWIDTHTOOBIG); iod->width = width; break; case iop_rewind: if (iod->state == dev_open && !rm_ptr->fifo) { iorm_flush(iod); if (lseek(rm_ptr->fildes, (off_t)0, SEEK_SET) == -1) rts_error(VARLSTCNT(1) errno); if (fseek(rm_ptr->filstr, (long)0, SEEK_SET) == -1) /* Rewind the input stream */ rts_error(VARLSTCNT(1) errno); iod->dollar.zeof = FALSE; iod->dollar.y = 0; iod->dollar.x = 0; rm_ptr->lastop = RM_NOOP; } break; case iop_stream: rm_ptr->stream = TRUE; break; case iop_truncate: if (!rm_ptr->fifo) { /* Warning! ftell() returns a long and fseek only accepts a long * as its second argument. this may cause problems for files longer * the 2Gb. */ if ((size = ftell(rm_ptr->filstr)) != -1) { int ftruncate_res; if (lseek(rm_ptr->fildes, (off_t)size, SEEK_SET) == -1) rts_error(VARLSTCNT(1) errno); FTRUNCATE(rm_ptr->fildes, (off_t)size, ftruncate_res); if (fseek(rm_ptr->filstr, size, SEEK_SET) == -1) rts_error(VARLSTCNT(1) errno); iod->dollar.zeof = TRUE; } } break; case iop_uic: { unsigned char *ch, ct, *end; int chown_res; uic_struct uic; ch = (unsigned char *)pp->str.addr + p_offset; ct = *ch++; end = ch + ct; uic.grp = uic.mem = 0; while ((*ch != ',') && (ch < end)) uic.mem = (10 * uic.mem) + (*ch++ - '0'); if (*ch == ',') { while (++ch < end) uic.grp = (10 * uic.grp) + (*ch - '0'); } CHG_OWNER(iod->trans_name->dollar_io, uic.mem, uic.grp, chown_res); if (-1 == chown_res) rts_error(VARLSTCNT(1) errno); break; } case iop_width: assert(iod->state == dev_open); GET_LONG(width, (pp->str.addr + p_offset)); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); else if (MAX_STRLEN < width) rts_error(VARLSTCNT(1) ERR_RMWIDTHTOOBIG); iod->width = width; iod->wrap = TRUE; break; case iop_wrap: iod->wrap = TRUE; break; case iop_nowrap: iod->wrap = FALSE; break; case iop_ipchset: { if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; } case iop_opchset: { if ( (iconv_t) 0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); 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 (fstat_done && mode != mode1) { /* if the mode has been changed by the qualifiers, reset it */ if (-1 == CHMOD(iod->trans_name->dollar_io, mode)) rts_error(VARLSTCNT(1) errno); } return; }
void ionl_use(io_desc *iod, mval *pp) { unsigned char ch, len; int fil_type; int4 width, length; io_desc *d_in, *d_out; mident tab; int p_offset; error_def(ERR_TTINVFILTER); error_def(ERR_DEVPARMNEG); p_offset = 0; d_in = iod->pair.in; d_out = iod->pair.out; assert(iod->state == dev_open); while (*(pp->str.addr + p_offset) != iop_eol) { switch (ch = *(pp->str.addr + p_offset++)) { case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_filter: memset(&tab, 0, sizeof(mident)); len = *(pp->str.addr + p_offset); memcpy(&tab.c[0], pp->str.addr + p_offset + 1, (len < sizeof(mident) ? len : sizeof(mident))); if ((fil_type = namelook(filter_index, filter_names, tab.c)) < 0) { rts_error(VARLSTCNT(1) ERR_TTINVFILTER); return; } switch (fil_type) { case 0: iod->write_filter |= CHAR_FILTER; break; case 1: iod->write_filter |= ESC1; break; case 2: iod->write_filter &= ~CHAR_FILTER; break; case 3: iod->write_filter &= ~ESC1; break; } break; case iop_nofilter: iod->write_filter = 0; break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (length < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); d_out->length = length; break; case iop_width: GET_LONG(width, pp->str.addr + p_offset); if (width < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); if (width == 0) { d_out->wrap = FALSE; d_out->width = TTDEF_PG_WIDTH; } else { d_out->width = width; d_out->wrap = TRUE; } break; case iop_wrap: d_out->wrap = TRUE; break; case iop_nowrap: d_out->wrap = FALSE; break; case iop_x: { int4 col; GET_LONG(col, pp->str.addr + p_offset); d_out->dollar.x = col; if ((d_out->dollar.x) < 0) d_out->dollar.x = 0; if (d_out->dollar.x > d_out->width && d_out->wrap) d_out->dollar.x %= d_out->width; break; } case iop_y: { int4 row; GET_LONG(row, (pp->str.addr + p_offset)); d_out->dollar.y = row; if ((d_out->dollar.y) < 0) d_out->dollar.y = 0; if (d_out->length) d_out->dollar.y %= d_out->length; break; } case iop_ipchset: { if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; } case iop_opchset: { if ( (iconv_t) 0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; } } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } return; }
void iotcp_use(io_desc *iod, mval *pp) { unsigned char c; int4 length, width; d_tcp_struct *tcpptr, newtcp; int p_offset; error_def(ERR_DEVPARMNEG); error_def(ERR_RMWIDTHPOS); #ifdef DEBUG_TCP PRINTF("%s >>>\n", __FILE__); #endif p_offset = 0; tcpptr = (d_tcp_struct *)iod->dev_sp; /* copy existing parameters */ memcpy(&newtcp, tcpptr, sizeof(d_tcp_struct)); while (*(pp->str.addr + p_offset) != iop_eol) { assert((params) *(pp->str.addr + p_offset) < (params) n_iops); switch (c = *(pp->str.addr + p_offset++)) { case iop_width: GET_LONG(width, pp->str.addr + p_offset); if (width == 0) newtcp.width = TCPDEF_WIDTH; else if (width > 0) newtcp.width = width; else rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (length == 0) newtcp.length = TCPDEF_LENGTH; else if (length > 0) newtcp.length = length; else rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); break; case iop_urgent: newtcp.urgent = TRUE; break; case iop_nourgent: newtcp.urgent = FALSE; break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_ipchset: { if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; } case iop_opchset: { if ( (iconv_t)0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; } default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]); } /* commit changes */ memcpy(tcpptr, &newtcp, sizeof(d_tcp_struct)); #ifdef DEBUG_TCP PRINTF("%s <<<\n", __FILE__); #endif return; }
void iosocket_close(io_desc *iod, mval *pp) { boolean_t socket_specified = FALSE; unsigned char ch; int handle_len; d_socket_struct *dsocketptr; socket_struct *socketptr; char sock_handle[MAX_HANDLE_LEN]; int4 ii, jj, start, end, index; int p_offset = 0; boolean_t socket_destroy = FALSE; assert(iod->type == gtmsocket); dsocketptr = (d_socket_struct *)iod->dev_sp; while (iop_eol != (ch = *(pp->str.addr + p_offset++))) { switch (ch) { case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_socket: handle_len = (short)(*(pp->str.addr + p_offset)); assert(handle_len > 0); memcpy(sock_handle, (char *)(pp->str.addr + p_offset + 1), handle_len); socket_specified = TRUE; break; case iop_ipchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); #endif break; case iop_opchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ( (iconv_t)0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); #endif break; case iop_destroy: socket_destroy = TRUE; break; case iop_nodestroy: socket_destroy = FALSE; break; default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } if (socket_specified) { if (0 > (index = iosocket_handle(sock_handle, &handle_len, FALSE, dsocketptr))) { rts_error_csa(CSA_ARG(NULL) VARLSTCNT(4) ERR_SOCKNOTFND, 2, handle_len, sock_handle); return; } start = end = index; } else { start = dsocketptr->n_socket - 1; end = 0; } for (ii = start; ii >= end; ii--) { socketptr = dsocketptr->socket[ii]; tcp_routines.aa_close(socketptr->sd); SOCKET_FREE(socketptr); if (dsocketptr->current_socket >= ii) dsocketptr->current_socket--; for (jj = ii + 1; jj <= dsocketptr->n_socket - 1; jj++) dsocketptr->socket[jj - 1] = dsocketptr->socket[jj]; dsocketptr->n_socket--; } if (!socket_specified) { iod->state = dev_closed; if (socket_destroy) { active_device = 0; iosocket_destroy(iod); } } }
void iomb_use(io_desc *iod, mval *pp) { char *path; uint4 status; d_mb_struct *mb_ptr; params ch; int p_offset; p_offset = 0; iomb_flush(iod); mb_ptr = (d_mb_struct *)iod->dev_sp; while ( (ch = *(pp->str.addr + p_offset++)) != iop_eol) { switch (ch) { case iop_delete: if (mb_ptr->prmflg && mb_ptr->del_on_close) { close(mb_ptr->channel); path = iod->trans_name->dollar_io; if ((status = UNLINK(path)) == -1) rts_error(VARLSTCNT(1) errno); } break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_wait: mb_ptr->write_mask = 1; break; case iop_nowait: mb_ptr->write_mask = 0; break; case iop_ipchset: { if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; } case iop_opchset: { if ( (iconv_t) 0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; } default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[*(pp->str.addr + p_offset)]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[*(pp->str.addr + p_offset)]); } }