예제 #1
0
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]);
	}
}
예제 #2
0
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;
}
예제 #3
0
파일: mu_op_open.c 프로젝트: 5HT/mumps
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;
}
예제 #4
0
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;

}
예제 #5
0
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;
}
예제 #6
0
파일: mu_extract.c 프로젝트: 5HT/mumps
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, &reg_max_rec, &reg_max_key, &reg_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);
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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);
        }
    }
}
예제 #11
0
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)]);
	}
}