Ejemplo n.º 1
0
int op_readfl(mval *v, int4 length, int4 timeout)
{
	int4	stat;		/* status */
	size_t	cnt, insize, outsize;
	char	*start_ptr, *save_ptr;
	unsigned char	*temp_ch;
	error_def(ERR_TEXT);
	error_def(ERR_RDFLTOOSHORT);
	error_def(ERR_RDFLTOOLONG);

	if (timeout < 0)
		timeout = 0;
	if (length <= 0)
		rts_error(VARLSTCNT(1) ERR_RDFLTOOSHORT);
	if (length > MAX_STRLEN)
		rts_error(VARLSTCNT(1) ERR_RDFLTOOLONG);
	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
	if (stringpool.free + length + ESC_LEN > stringpool.top)
		stp_gcol(length + ESC_LEN);
	v->mvtype = MV_STR;
	v->str.addr = (char *)stringpool.free;
	v->str.len = 0;
	active_device = io_curr_device.in;
	stat = (io_curr_device.in->disp_ptr->readfl)(v, length, timeout);
	stringpool.free += v->str.len;
	assert((int4)v->str.len <= length);
	assert(stringpool.free <= stringpool.top);

	if (DEFAULT_CODE_SET != active_device->in_code_set)
	{
		cnt = insize = outsize = v->str.len;
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.free <= stringpool.top);
		if (cnt > stringpool.top - stringpool.free)
			stp_gcol(cnt);
		temp_ch = stringpool.free;
		save_ptr = v->str.addr;
		start_ptr = (char *)temp_ch;
		stringpool.free += cnt;
		assert(stringpool.free >= stringpool.base);
		assert(stringpool.free <= stringpool.top);

		ICONVERT(active_device->input_conv_cd, (unsigned char **)&(v->str.addr), &insize, &temp_ch, &outsize);

		v->str.addr = start_ptr;
	}

	active_device = 0;
	if (NO_M_TIMEOUT != timeout)
		return (stat);
	return FALSE;
}
Ejemplo n.º 2
0
int iomb_read(mval *v,int4 t)
{
	io_desc 	*io_ptr;
	d_mb_struct	*mb_ptr;
	int 		status;


	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
	io_ptr = io_curr_device.in;
	mb_ptr = (d_mb_struct *) io_ptr->dev_sp;
	if (stringpool.free + mb_ptr->maxmsg > stringpool.top)
		stp_gcol (mb_ptr->maxmsg);
	v->str.addr = (char *)stringpool.free;
	status = TRUE;
	assert (io_ptr->state == dev_open);
	if (mb_ptr->in_top == mb_ptr->in_pos)
		status = iomb_dataread(t);

	memcpy(v->str.addr,mb_ptr->in_pos,(v->str.len = INTCAST(mb_ptr->in_top - mb_ptr->in_pos)));
	mb_ptr->in_pos = mb_ptr->in_top = mb_ptr->inbuf;
	io_ptr->dollar.x = 0;
	io_ptr->dollar.y++;
	return status;
}
Ejemplo n.º 3
0
Archivo: gtm_conv.c Proyecto: 5HT/mumps
int gtm_conv(UConverter* from, UConverter* to, mstr *src, char* dstbuff, int* bufflen)
{
	char		*dstptr, *dstbase, *srcptr;
	const char	*ichset;
	int		dstlen, src_charlen, srclen;
	UErrorCode	status, status1;

	if (0 == src->len)
		return 0;
	if (NULL == dstbuff)
	{
		/* Compute the stringpool buffer space needed for conversion given that source
		 * is encoded in the ichset representation.  The ICU functions ucnv_getMinCharSize()
		 * and ucnv_getMaxCharSize() are used to compute the minimum and maximum number of
		 * bytes required per UChar if converted from/to ichset/ochset respectively */
		src_charlen = (src->len / ucnv_getMinCharSize(from)) + 1; /* number of UChar's from ichset */
		dstlen = UCNV_GET_MAX_BYTES_FOR_STRING(src_charlen, ucnv_getMaxCharSize(to));
		dstlen = (dstlen > MAX_STRLEN) ? MAX_STRLEN : dstlen;
		if (stringpool.free + dstlen > stringpool.top)
			stp_gcol(dstlen);
		dstbase = (char *)stringpool.free;
	} else
	{
		dstbase = dstbuff;
		dstlen = *bufflen;
	}
	srcptr = src->addr;
	srclen = (int)src->len;
	dstptr = dstbase;
	status = U_ZERO_ERROR; /* initialization to "success" is required by ICU */
	ucnv_convertEx(to, from, &dstptr, dstptr + dstlen, (const char**)&srcptr, srcptr + srclen,
		NULL, NULL, NULL, NULL, TRUE, TRUE, &status);
	if (U_FAILURE(status))
	{
		if (U_BUFFER_OVERFLOW_ERROR == status)
		{	/* translation requires more space than the maximum allowed GT.M string size */
			if (NULL == dstbuff)
				rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
			else
			{
				/* Insufficient buffer passed. Return the required buffer length */
				src_charlen = (srclen / ucnv_getMinCharSize(from)) + 1;
				*bufflen = UCNV_GET_MAX_BYTES_FOR_STRING(src_charlen, ucnv_getMaxCharSize(to));
				return -1;
			}
		}
		status1 = U_ZERO_ERROR;
		ichset = ucnv_getName(from, &status1);
		assert(U_SUCCESS(status1));
		UTF8_BADCHAR(1,(unsigned char *) (srcptr - 1), NULL,STRLEN(ichset), ichset);
	}
	return (int) (dstptr - dstbase);
}
Ejemplo n.º 4
0
void op_fnzbitxor(mval *dst, mval *bitstr1, mval *bitstr2)
{
	int 		n, str_len1, str_len2, new_str_len;
	unsigned char	*byte_1, *byte_n;
	unsigned char	*byte1_1, *byte1_n, byte1_len;
	unsigned char	*byte2_1, *byte2_n, byte2_len;

	error_def(ERR_INVBITSTR);

	MV_FORCE_STR(bitstr1);
	MV_FORCE_STR(bitstr2);

	if (!bitstr1->str.len || !bitstr2->str.len)
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);

	byte1_len = *(unsigned char *)bitstr1->str.addr;
	str_len1 = (bitstr1->str.len - 1) * 8;
	if (7 < byte1_len)
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);

	byte2_len = *(unsigned char *)bitstr2->str.addr;
	str_len2 = (bitstr2->str.len -1) * 8;
	if (7 < byte2_len)
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);

	if (str_len1 - byte1_len > str_len2 - byte2_len)
		new_str_len = str_len2 - byte2_len;
	else
		new_str_len = str_len1 - byte1_len;

	n = (new_str_len + 7)/8 ;

	if (stringpool.top - stringpool.free < n + 1)
		stp_gcol(n + 1);
	byte_1 = (unsigned char *)stringpool.free;
	*byte_1 = n * 8 - new_str_len;
	byte1_1 = (unsigned char *)bitstr1->str.addr;
	byte2_1 = (unsigned char *)bitstr2->str.addr;

	for(byte_n = byte_1 + 1, byte1_n = byte1_1 + 1, byte2_n = byte2_1 + 1 ;
		 byte_n <= (byte_1 + n); byte_n++, byte1_n++, byte2_n++)
	{
		*byte_n = *byte1_n ^ *byte2_n;
	}

	*--byte_n &= mask[*byte_1];
	dst->mvtype = MV_STR;
	dst->str.addr = (char *)stringpool.free;
	dst->str.len = n + 1;
	stringpool.free += n + 1;
}
Ejemplo n.º 5
0
void get_command_line(mval *result, boolean_t zcmd_line)
{
	int		first_item, len, word_cnt;
	unsigned char	*cp;
	void		stp_gcol();

	result->mvtype = MV_STR;
	len = -1;							/* to compensate for no space at the end */
	if (cmd_cnt > 1)
	{
		first_item = 1;
		if (zcmd_line)
		{	/* $ZCMDLINE returns the processed command line. Remove "-direct" and/or "-run <runarg>" from cmd line */
			cp = (unsigned char *)cmd_arg[1];
			if ('-' == *cp++)
			{
				first_item++;
				if ('r' == TOLOWER(*cp))
					first_item++;
			}
		}
		for (word_cnt = first_item; word_cnt < cmd_cnt; word_cnt++)
			len += strlen(cmd_arg[word_cnt]) + 1;		/* include space between arguments */
	}
	if (0 >= len)
	{
		result->str.len = 0;
		return;
	}
	if (stringpool.free + len > stringpool.top)
		stp_gcol(len);
	cp = stringpool.free;
	stringpool.free += len;
	result->str.addr = (char *)cp;
	result->str.len = len;
	for (word_cnt = first_item; ; *cp++ = ' ')
	{
		len = strlen(cmd_arg[word_cnt]);
		memcpy(cp, cmd_arg[word_cnt], len);
		if (++word_cnt == cmd_cnt)
			break;
		cp += len;
	}
	assert(cp + len == stringpool.free);
	return;
}
Ejemplo n.º 6
0
int comp_fini(bool status, mstr *obj, opctype retcode, oprtype *retopr, int src_len)
{

	triple *ref;
	error_def(ERR_INDEXTRACHARS);

	if (status  &&  source_column != src_len + 2  &&  source_buffer[source_column] != '\0')
	{
		status = FALSE;
		stx_error(ERR_INDEXTRACHARS);
	}
	if (status)
	{
		cg_phase = CGP_RESOLVE;
		assert(for_stack_ptr == for_stack);
		if (*for_stack_ptr)
			tnxtarg(*for_stack_ptr);
		ref = newtriple(retcode);
		if (retopr)
			ref->operand[0] = *retopr;
		start_fetches(OC_NOOP);
		resolve_ref(0);	/* cannot fail because there are no MLAB_REF's in indirect code */
		alloc_reg();
		stp_gcol(0);
		assert(indr_stringpool.base == stringpool.base);
		indr_stringpool = stringpool;
		stringpool = rts_stringpool;
		compile_time = FALSE;
 		ind_code(obj);
		indr_stringpool.free = indr_stringpool.base;
	}
	else
	{
		assert(indr_stringpool.base == stringpool.base);
		indr_stringpool = stringpool;
		stringpool = rts_stringpool;
		indr_stringpool.free = indr_stringpool.base;
		compile_time = FALSE;
		cg_phase = CGP_NOSTATE;
	}
	transform = TRUE;
	mcfree();
	return status;

}
Ejemplo n.º 7
0
oprtype make_gvsubsc(mval *v)
{
	mval w;
	gv_key *gp;
	if (stringpool.top - stringpool.free < MAX_SRCLINE + sizeof(gv_key))
	{	stp_gcol(MAX_SRCLINE + sizeof(gv_key));
	}
	if ((int) stringpool.free & 1)
		stringpool.free++;	/* word align key for structure refs */
	gp = (gv_key *) stringpool.free;
	gp->top = MAX_SRCLINE;
	gp->end = gp->prev = 0;
	mval2subsc(v,gp);
	w.mvtype = MV_STR | MV_SUBLIT;
	w.str.addr = (char *) gp->base;
	w.str.len = gp->end + 1;
	stringpool.free = &gp->base[gp->end + 1];
	assert(stringpool.free <= stringpool.top);
	return put_lit(&w);
}
Ejemplo n.º 8
0
void get_reference(mval *var)
{
	char	*end, *start;
	char	extnamdelim[] = "^|\"\"|";
	char	*extnamsrc, *extnamtop;
	int	maxlen;

	/* you need to return a double-quote for every single-quote. assume worst case. */
	maxlen = MAX_ZWR_KEY_SZ + (!extnam_str.len ? 0 : ((extnam_str.len * 2) + sizeof(extnamdelim)));
	if (stringpool.free + maxlen > stringpool.top)
		stp_gcol(maxlen);
	var->mvtype = MV_STR;
	start = var->str.addr = (char *)stringpool.free;
	var->str.len = 0;
	if (gv_currkey && gv_currkey->end)
	{
		if (extnam_str.len)
		{
			*start++ = extnamdelim[0];
			*start++ = extnamdelim[1];
			*start++ = extnamdelim[2];
			extnamsrc = &extnam_str.addr[0];
			extnamtop = extnamsrc + extnam_str.len;
			for ( ; extnamsrc < extnamtop; )
			{
				*start++ = *extnamsrc;
				if ('"' == *extnamsrc++)	/* caution : pointer increment side-effect */
					*start++ = '"';
			}
			*start++ = extnamdelim[3];
		}
		end = (char *)format_targ_key((unsigned char *)start, MAX_ZWR_KEY_SZ, gv_currkey, TRUE);
		if (extnam_str.len)
			/* Note: the next vertical bar overwrites the caret that
			 * was part of he original name of the global variable
			 */
			*start = extnamdelim[4];
		var->str.len = end - var->str.addr;
		stringpool.free += var->str.len;
	}
}
Ejemplo n.º 9
0
void s2pool_align(mstr *string)
{
	int length, align_padlen;

	if ((length = string->len) == 0)
		return;
	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
	if (mstr_native_align)
		align_padlen = PADLEN(stringpool.free, NATIVE_WSIZE);
	else
		align_padlen = 0;
	if (length + align_padlen > stringpool.top - stringpool.free)
		stp_gcol(length + align_padlen);
	stringpool.free += align_padlen;
	memcpy(stringpool.free, string->addr, length);
	string->addr = (char *)stringpool.free;
	stringpool.free += length;
	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
}
Ejemplo n.º 10
0
void op_fnzbitnot(mval *dst,mval *bitstr)
{
	int str_len;
	unsigned char *byte_1, *byte_n, *dist_byte, byte_len;
	int n;
	error_def(ERR_INVBITSTR);

	MV_FORCE_STR(bitstr);

	if (!bitstr->str.len)
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);

	byte_len = *(unsigned char *)bitstr->str.addr;
	str_len = (bitstr->str.len -1) * 8;
	if ((byte_len < 0) || (byte_len > 7))
	{
		rts_error(VARLSTCNT(1) ERR_INVBITSTR);
	}

	if (stringpool.top - stringpool.free < bitstr->str.len)
		stp_gcol(bitstr->str.len);
	byte_1 = (unsigned char *)bitstr->str.addr;
	dist_byte = (unsigned char *)stringpool.free;
	*dist_byte = *byte_1;
	dist_byte++;

	n = bitstr->str.len;
	for (byte_n = byte_1 + 1; byte_n <= (byte_1 + n); byte_n++, dist_byte++)
	{
		*dist_byte = ~(*byte_n);
	}

	dst->mvtype = MV_STR;
	dst->str.addr = (char *)stringpool.free;
	dst->str.len = bitstr->str.len;
	stringpool.free += bitstr->str.len;
}
Ejemplo n.º 11
0
int f_char(oprtype *a, opctype op)
{
	triple *root, *last, *curr;
	oprtype argv[CHARMAXARGS], *argp;
	mval v;
	bool all_lits;
	char *c;
	int argc, i;
	error_def(ERR_FCHARMAXARGS);

	all_lits = TRUE;
	argp = &argv[0];
	argc = 0;
	for (;;)
	{
		if (!intexpr(argp))
			return FALSE;
		assert(argp->oprclass == TRIP_REF);
		if (argp->oprval.tref->opcode != OC_ILIT)
			all_lits = FALSE;
		argc++;
		argp++;
		if (window_token != TK_COMMA)
			break;
		advancewindow();
		if (argc >= CHARMAXARGS)
		{	stx_error(ERR_FCHARMAXARGS);
			return FALSE;
		}
	}
	if (all_lits)
	{
		if (stringpool.top - stringpool.free < argc)
			stp_gcol(argc);
		v.mvtype = MV_STR;
		v.str.addr = c = (char *) stringpool.free;
		argp = &argv[0];
		for (; argc > 0 ;argc--, argp++)
		{
			i = argp->oprval.tref->operand[0].oprval.ilit;
			if ((i >= 0) && (i < 256))	/* only true for single byte character set */
				*c++ = i;
		}
		v.str.len = c - v.str.addr;
		stringpool.free =(unsigned char *)  c;
		s2n(&v);
		*a = put_lit(&v);
		return TRUE;
	}
	root = maketriple(op);
	root->operand[0] = put_ilit(argc + 2);
	curr = newtriple(OC_PARAMETER);
	curr->operand[0] = put_ilit(0);
	root->operand[1] = put_tref(curr);
	last = curr;
	argp = &argv[0];
	for (; argc > 0 ;argc--, argp++)
	{
		curr = newtriple(OC_PARAMETER);
		curr->operand[0] = *argp;
		last->operand[1] = put_tref(curr);
		last = curr;
	}
	ins_triple(root);
	*a = put_tref(root);
	return TRUE;
}
Ejemplo n.º 12
0
void op_fnj3(mval *src,int width,int fract,mval *dst)
{
	int4 n, n1, m;
	int w, digs, digs_used;
	int sign;
	static readonly int4 fives_table[9] =
	{ 500000000, 50000000, 5000000, 500000, 50000, 5000, 500, 50, 5};
	unsigned char *cp;
	error_def(ERR_JUSTFRACT);
	error_def(ERR_MAXSTRLEN);

	if (width < 0)
		width = 0;
	else	if (width > MAX_STRLEN)
			rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
	if (fract < 0)
		rts_error(VARLSTCNT(1) ERR_JUSTFRACT);
	w = width + MAX_NUM_SIZE + 2 + fract;
	/* the literal two above accounts for the possibility
	of inserting a zero and/or a minus with a width of zero */
	if  (w > MAX_STRLEN)
		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
	MV_FORCE_NUM(src);
	/* need to guarantee that the n2s call will not cause string pool overflow */
	if (stringpool.top - stringpool.free < w)
		stp_gcol(w);
	sign = 0;
	cp = stringpool.free;
	if (src->mvtype & MV_INT)
	{
		n = src->m[1];
                if (n < 0)
                {
			sign = 1;
			n = -n;
		}
		/* Round if necessary */
		if (fract < 3)
			n += fives_table[fract + 6];
		/* Compute digs, the number of non-zero leading digits */
		if (n < 1000)
		{
			digs = 0;
			/* if we have something like $j(-.01,0,1), the answer should be 0.0, not -0.0
			   so lets check for that here */
			if (sign && fract < 4 && n / ten_pwr[3 - fract] == 0)
			{
				sign = 0;
				n = 0;
			} else
				n *= 1000000;
		} else if (n >= 1000000000)
		{
			digs = 7;
		} else
		{
			for (digs = 6; n < 100000000 ; n *= 10 , digs--)
				;
		}
		/* Do we need leading spaces? */
		w = width - sign - (fract != 0) - fract - digs;
		if (digs == 0)
			w--;
		if (w > 0)
		{
			memset(cp, ' ', w);
			cp += w;
		}
		if (sign)
			*cp++ = '-';
		if (digs == 0)
			*cp++ = '0';
		else
		{
			/* It is possible that when rounding, that
			   we overflowed by one digit.  In this case,
			   the left-most digit must be a "1".
			   Take care of this case first.
			*/
			if (digs == 7)
			{
				*cp++ = '1';
				n -= 1000000000;
				digs = 6;
			}
			for ( ; digs > 0 ; digs--)
			{
				n1 = n / 100000000;
				*cp++ = n1 + '0';
				n = (n - n1 * 100000000) * 10;
			}
		}
		if (fract)
		{
			*cp++ = '.';
			for (digs = fract ; digs > 0 && n != 0; digs--)
			{
				n1 = n / 100000000;
				*cp++ = n1 + '0';
				n = (n - n1 * 100000000) * 10;
			}
			if (digs)
			{
				memset(cp, '0', digs);
				cp += digs;
			}
		}
	} else
	{
		digs = src->e - MV_XBIAS;
		m = src->m[0];
		n = src->m[1];
		sign = src->sgn;
		w = digs + fract;
		if (w < 18 && w >= 0)
		{
			if (w < 9)
			{
				n += fives_table[w];
				if (n >= MANT_HI)
				{
					n1 = n / 10;
					m = m / 10 + ((n - n1 * 10) * MANT_LO);
					n = n1;
					digs++;
				}
			}
			else
			{
				m += fives_table[w - 9];
				if (m >= MANT_HI)
				{
					m -= MANT_HI;
					n++;
					if (n >= MANT_HI)
					{
						n1 = n / 10;
						m = m / 10 + ((n - n1 * 10) * MANT_LO);
						n = n1;
						digs++;
					}
				}
			}
		}
		/* if we have something like $j(-.0001,0,1), the answer should be 0.0, not -0.0 */
		if (digs <= - fract)
		{
			sign = 0;
			n = m = 0;
		}
		w = width - fract - (fract != 0) - sign - (digs < 1 ? 1 : digs);
		if (w > 0)
		{
			memset(cp, ' ', w);
			cp += w;
		}
		if (sign)
			*cp++ = '-';
		digs_used = 0;
		if (digs < 1)
			*cp++ = '0';
		else
		{
			for ( ; digs > 0 && (n != 0 || m != 0); digs--)
			{
				n1 = n / 100000000;
				*cp++ = n1 + '0';
				digs_used++;
				if (digs_used == 9)
				{
					n = m;
					m = 0;
				} else
					n = (n - n1 * 100000000) * 10;
			}
			if (digs > 0)
			{
				memset(cp, '0', digs);
				cp += digs;
			}
		}
		if (fract)
		{
			*cp++ = '.';
			if (digs < 0)
			{
				digs = - digs;
				if (digs > fract)
					digs = fract;
				memset(cp, '0', digs);
				cp += digs;
				fract -= digs;
			}
			for (digs = fract ; digs > 0 && (n != 0 || m != 0); digs--)
			{
				n1 = n / 100000000;
				*cp++ = n1 + '0';
				digs_used++;
				if (digs_used == 9)
				{
					n = m;
					m = 0;
				} else
					n = (n - n1 * 100000000) * 10;
			}
			if (digs)
			{
				memset(cp, '0', digs);
				cp += digs;
			}
		}
	}
	dst->mvtype = MV_STR;
	dst->str.addr = (char *) stringpool.free;
	dst->str.len = (char *) cp - dst->str.addr;
	stringpool.free = cp;
	return;
}
Ejemplo n.º 13
0
short	iott_readfl (mval *v, int4 length, int4 timeout)	/* timeout in seconds */
{
	boolean_t	ret, nonzerotimeout, timed;
	uint4		mask;
	unsigned char	inchar, *temp;
#ifdef __MVS__
	unsigned char	asc_inchar;
#endif
	int		dx, msk_in, msk_num, outlen, rdlen, save_errno, selstat, status, width;
	int4		msec_timeout;			/* timeout in milliseconds */
	io_desc		*io_ptr;
	d_tt_struct	*tt_ptr;
	io_terminator	outofbands;
	io_termmask	mask_term;
	unsigned char	*zb_ptr, *zb_top;
	ABS_TIME	cur_time, end_time;
	fd_set		input_fd;
	struct timeval	input_timeval;
	struct timeval	save_input_timeval;

	error_def(ERR_CTRAP);
	error_def(ERR_IOEOF);
	error_def(ERR_NOPRINCIO);

	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
	io_ptr = io_curr_device.in;
	tt_ptr = (d_tt_struct *)(io_ptr->dev_sp);
	assert(dev_open == io_ptr->state);
	iott_flush(io_curr_device.out);
	width = io_ptr->width;
	if (stringpool.free + length > stringpool.top)
		stp_gcol (length);
	outlen = 0;
	/* ---------------------------------------------------------
	 * zb_ptr is be used to fill-in the value of $zb as we go
	 * If we drop-out with error or otherwise permaturely,
	 * consider $zb to be null.
	 * ---------------------------------------------------------
	 */
	zb_ptr = io_ptr->dollar.zb;
	zb_top = zb_ptr + sizeof(io_ptr->dollar.zb) - 1;
	*zb_ptr = 0;
	io_ptr->esc_state = START;
	io_ptr->dollar.za = 0;
	io_ptr->dollar.zeof = FALSE;
	v->str.len = 0;
	dx = (int)io_ptr->dollar.x;
	ret = TRUE;
	temp = stringpool.free;
	mask = tt_ptr->term_ctrl;
	mask_term = tt_ptr->mask_term;
	if (mask & TRM_NOTYPEAHD)
		TCFLUSH(tt_ptr->fildes, TCIFLUSH, status);
	if (mask & TRM_READSYNC)
	{
		DOWRITERC(tt_ptr->fildes, &dc1, 1, status);
		if (0 != status)
		{
			io_ptr->dollar.za = 9;
			rts_error(VARLSTCNT(1) status);
		}
	}
	nonzerotimeout = FALSE;
	if (NO_M_TIMEOUT == timeout)
	{
		timed = FALSE;
		input_timeval.tv_sec = 100;
		msec_timeout = NO_M_TIMEOUT;
	} else
	{
		timed = TRUE;
		input_timeval.tv_sec = timeout;
		msec_timeout = timeout2msec(timeout);
		if (!msec_timeout)
			iott_mterm(io_ptr);
		else
		{
			nonzerotimeout = TRUE;
   			sys_get_curr_time(&cur_time);
			add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
		}
	}
	input_timeval.tv_usec = 0;
	do
	{
		if (outofband)
		{
			outlen = 0;
			if (!msec_timeout)
				iott_rterm(io_ptr);
			outofband_action(FALSE);
			break;
		}
		errno = 0;
		FD_ZERO(&input_fd);
		FD_SET(tt_ptr->fildes, &input_fd);
		assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd));
		/* the checks for EINTR below are valid and should not be converted to EINTR
		 * wrapper macros, since the select/read is not retried on EINTR.
		 */
		save_input_timeval = input_timeval;	/* take a copy and pass it because select() below might change it */
		selstat = select(tt_ptr->fildes + 1, (void *)&input_fd, (void *)NULL, (void *)NULL, &save_input_timeval);
		if (selstat < 0)
		{
			if (EINTR != errno)
				goto term_error;
		} else if (0 == selstat)
		{
			if (timed)
			{
				ret = FALSE;
				break;
			}
			continue;	/* select() timeout; keep going */
		} else if (0 < (rdlen = read(tt_ptr->fildes, &inchar, 1)))	/* This read is protected */
		{
			assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd));
			/* --------------------------------------------------
			 * set prin_in_dev_failure to FALSE to indicate that
			 * input device is working now.
			 * --------------------------------------------------
			 */
			prin_in_dev_failure = FALSE;
			if (tt_ptr->canonical)
			{
				if (0 == inchar)
				{
					/* --------------------------------------
					 * This means that the device has hungup
					 * --------------------------------------
					 */
					io_ptr->dollar.zeof = TRUE;
					io_ptr->dollar.x = 0;
					io_ptr->dollar.za = 9;
					io_ptr->dollar.y++;
					if (io_ptr->error_handler.len > 0)
						rts_error(VARLSTCNT(1) ERR_IOEOF);
					break;
				} else
					io_ptr->dollar.zeof = FALSE;
			}
			if (mask & TRM_CONVERT)
				NATIVE_CVT2UPPER(inchar, inchar);
                        GETASCII(asc_inchar,inchar);
			if ((dx >= width) && io_ptr->wrap && !(mask & TRM_NOECHO))
			{
				DOWRITE(tt_ptr->fildes, NATIVE_TTEOL, strlen(NATIVE_TTEOL));
				dx = 0;
			}
			if ((' ' > INPUT_CHAR) && (tt_ptr->enbld_outofbands.mask & (1 << INPUT_CHAR)))
			{
				outlen = 0;
				io_ptr->dollar.za = 9;
				std_dev_outbndset(INPUT_CHAR);	/* it needs ASCII?	*/
				outofband = 0;
				if (!msec_timeout)
					iott_rterm(io_ptr);
				rts_error(VARLSTCNT(3) ERR_CTRAP, 1, ctrap_action_is);
				break;
			}
			if ((0 != (mask & TRM_ESCAPE))
			     && ((NATIVE_ESC == inchar) || (START != io_ptr->esc_state)))
			{
				if (zb_ptr >= zb_top)
				{	/* $zb overflow */
					io_ptr->dollar.za = 2;
					break;
				}
				*zb_ptr++ = inchar;
				iott_escape(zb_ptr - 1, zb_ptr, io_ptr);
				*(zb_ptr - 1) = INPUT_CHAR;     /* need to store ASCII value    */
				if (FINI == io_ptr->esc_state)
					break;
				if (BADESC == io_ptr->esc_state)
				{	/* Escape sequence failed parse */
					io_ptr->dollar.za = 2;
					break;
				}
				/* --------------------------------------------------------------------
				 * In escape sequence...do not process further, but get next character
				 * --------------------------------------------------------------------
				 */
			} else
			{	/* SIMPLIFY THIS! */
				msk_num = (uint4)INPUT_CHAR / NUM_BITS_IN_INT4;
				msk_in = (1 << ((uint4)INPUT_CHAR % NUM_BITS_IN_INT4));
				if (msk_in & mask_term.mask[msk_num])
				{
					*zb_ptr++ = INPUT_CHAR;
					break;
				}
				if (((int)inchar == tt_ptr->ttio_struct->c_cc[VERASE]) && !(mask & TRM_PASTHRU))
				{
					if ((0< outlen) && (0 < dx))
					{
						outlen--;
						dx--;
						*temp--;
						if (!(mask & TRM_NOECHO))
						{
							DOWRITERC(tt_ptr->fildes, eraser, sizeof(eraser), status);
							if (0 != status)
								goto term_error;
						}
					}
				} else
				{
					if (!(mask & TRM_NOECHO))
					{
						DOWRITERC(tt_ptr->fildes, &inchar, 1, status);
						if (0 != status)
							goto term_error;
					}
					*temp++ = inchar;
					outlen++;
					dx++;
				}
			}
		} else if (0 == rdlen)
		{
			if (0 < selstat)
			{	/* this should be the only possibility */
				io_ptr->dollar.zeof = TRUE;
				io_ptr->dollar.x = 0;
				io_ptr->dollar.za = 0;
				io_ptr->dollar.y++;
				if (io_curr_device.in == io_std_device.in)
				{
					if (!prin_in_dev_failure)
						prin_in_dev_failure = TRUE;
					else
					{
                                        	send_msg(VARLSTCNT(1) ERR_NOPRINCIO);
                                        	stop_image_no_core();
					}
                                }
				if (io_ptr->dollar.zeof)
				{
					io_ptr->dollar.za = 9;
					rts_error(VARLSTCNT(1) ERR_IOEOF);
				} else
				{
					io_ptr->dollar.zeof = TRUE;
					io_ptr->dollar.za = 0;
					if (0 < io_ptr->error_handler.len)
						rts_error(VARLSTCNT(1) ERR_IOEOF);
				}
				break;
			}
			if (0 == errno)
			{	/* eof */
				io_ptr->dollar.zeof = TRUE;
				io_ptr->dollar.x = 0;
				io_ptr->dollar.za = 0;
				io_ptr->dollar.y++;
				if (0 < io_ptr->error_handler.len)
					rts_error(VARLSTCNT(1) ERR_IOEOF);
				break;
			}
		} else if (EINTR != errno)	/* rdlen < 0 */
			goto term_error;
		if (nonzerotimeout)
		{
			sys_get_curr_time(&cur_time);
			cur_time = sub_abs_time(&end_time, &cur_time);
			if (0 > cur_time.at_sec)
			{
				ret = FALSE;
				break;
			}
			input_timeval.tv_sec = cur_time.at_sec;
			input_timeval.tv_usec = cur_time.at_usec;
		}
	} while (outlen < length);
	*zb_ptr++ = 0;
	if (!msec_timeout)
	{
		iott_rterm(io_ptr);
		if (0 == outlen)
			ret = FALSE;
	}
	if (mask & TRM_READSYNC)
	{
		DOWRITERC(tt_ptr->fildes, &dc3, 1, status);
		if (0 != status)
		{
			io_ptr->dollar.za = 9;
			rts_error(VARLSTCNT(1) status);
		}
	}
	if (outofband)
	{
		v->str.len = 0;
		io_ptr->dollar.za = 9;
		return(FALSE);
	}
	v->str.len = outlen;
	v->str.addr = (char *)stringpool.free;
	if (!(mask & TRM_NOECHO))
	{
		if ((io_ptr->dollar.x += v->str.len) >= io_ptr->width && io_ptr->wrap)
		{
			io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width);
			if (io_ptr->length)
				io_ptr->dollar.y %= io_ptr->length;
			io_ptr->dollar.x %= io_ptr->width;
			if (0 == io_ptr->dollar.x)
				DOWRITE(tt_ptr->fildes, NATIVE_TTEOL, strlen(NATIVE_TTEOL));
		}
	}
	return ((short)ret);

term_error:
	save_errno = errno;
	io_ptr->dollar.za = 9;
	if (!msec_timeout)
		iott_rterm(io_ptr);
	rts_error(VARLSTCNT(1) save_errno);
	return FALSE;
}
Ejemplo n.º 14
0
void op_fngetjpi(mint jpid, mval *kwd, mval *ret)
{
	error_def	(ERR_BADJPIPARAM);
	struct tms	proc_times;
	int4		info ;
	int		keywd_indx;
	char		upcase[MAX_KEY_LEN];

	assert (stringpool.free >= stringpool.base);
	assert (stringpool.top >= stringpool.free);
	if (stringpool.top - stringpool.free < MAX_STR)
		stp_gcol(MAX_STR);

	MV_FORCE_STR(kwd);
	if (kwd->str.len == 0)
		rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, 4, "Null");

	if (MAX_KEY < kwd->str.len)
		rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);

	lower_to_upper((uchar_ptr_t)upcase, (uchar_ptr_t)kwd->str.addr, (int)kwd->str.len);

	keywd_indx = kw_cputim ;
	/* future enhancement:
	 * 	(i) since keywords are sorted, we can exit the while loop if 0 < memcmp.
	 * 	(ii) also, the current comparison relies on kwd->str.len which means a C would imply CPUTIM instead of CSTIME
	 * 		or CUTIME this ambiguity should probably be removed by asking for an exact match of the full keyword
	 */
	while ((0 != memcmp(upcase, key[keywd_indx], kwd->str.len)) && keywd_indx < MAX_KEY)
		keywd_indx++;

	if( keywd_indx == MAX_KEY )
        {
                 rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);
        }

	if ((kw_isprocalive != keywd_indx) && ((unsigned int)-1 == times(&proc_times)))
	{
		rts_error(VARLSTCNT(1) errno);	/* need a more specific GTM error message in addition to errno */
		return;
	}
	switch (keywd_indx)
	{
		case kw_cputim:
			info = proc_times.tms_utime + proc_times.tms_stime + proc_times.tms_cutime + proc_times.tms_cstime;
			break;
		case kw_cstime:
			info = proc_times.tms_cstime;
			break;
		case kw_cutime:
			info = proc_times.tms_cutime;
			break;
		case kw_isprocalive:
			info = (0 != jpid) ? is_proc_alive(jpid, 0) : 1;
			break;
		case kw_stime:
			info = proc_times.tms_stime;
			break;
		case kw_utime:
			info = proc_times.tms_utime;
			break;
		case kw_end:
		default:
			rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr);
			return;
	}
	if (kw_isprocalive != keywd_indx)
		info = (int4)((info * 100) / sysconf(_SC_CLK_TCK));	/* Convert to standard 100 ticks per second */
	i2mval(ret, info);
}
Ejemplo n.º 15
0
int compile_pattern(oprtype *opr, bool is_indirect)
{
	ptstr		retstr;
	mval		retmval;
	mstr		instr;
	int		status;
	triple		*oldchain, tmpchain, *ref, *triptr;

	if (is_indirect)
	{
		if (shift_gvrefs)
		{
			dqinit(&tmpchain, exorder);
			oldchain = setcurtchain(&tmpchain);
			if (!indirection(opr))
			{
				setcurtchain(oldchain);
				return FALSE;
			}
			ref = newtriple(OC_INDPAT);
			newtriple(OC_GVSAVTARG);
			setcurtchain(oldchain);
			dqadd(expr_start, &tmpchain, exorder);
			expr_start = tmpchain.exorder.bl;
			triptr = newtriple(OC_GVRECTARG);
			triptr->operand[0] = put_tref(expr_start);
		} else
		{
			if (!indirection(opr))
				return FALSE;
			ref = newtriple(OC_INDPAT);
		}
		ref->operand[0] = *opr;
		*opr = put_tref(ref);
		return TRUE;
	} else
	{
		instr.addr = (char *)&source_buffer[source_column - 1];
		instr.len = strlen(instr.addr);
		status = patstr(&instr, &retstr, NULL);
		last_source_column = (short int)(instr.addr - (char *)source_buffer);
		assert(last_source_column);
		if (status)
		{	/* status == syntax error when non-zero */
			stx_error(status);
			return FALSE;
		}
		retmval.mvtype = MV_STR;
		retmval.str.len = retstr.len * sizeof(uint4);
		retmval.str.addr = stringpool.free;
		if (stringpool.top - stringpool.free < retmval.str.len)
			stp_gcol(retmval.str.len);
		memcpy(stringpool.free, &retstr.buff[0], retmval.str.len);
		stringpool.free += retmval.str.len;
		*opr = put_lit(&retmval);
		lexical_ptr = (char *)&source_buffer[last_source_column - 1];
		advancewindow();
		advancewindow();
		return TRUE;
	}
}
Ejemplo n.º 16
0
short iomt_read (mval *v, int4 t)
{
	error_def (ERR_MTRDTHENWRT);
	io_desc        *dv;
	d_mt_struct    *mt_ptr;

#ifdef DP
	FPRINTF(stderr, ">> iomt_read\n");
#endif

	assert (stringpool.free >= stringpool.base);
	assert (stringpool.free <= stringpool.top);
	dv = io_curr_device.in;
	mt_ptr = (d_mt_struct *) dv->dev_sp;
	if (stringpool.free + mt_ptr->record_sz > stringpool.top)
		stp_gcol (mt_ptr->record_sz);
	v->str.addr = (char *) stringpool.free;

#ifdef UNIX
	if (mt_ptr->mode != MT_M_READ)
	{
		uint4   status;

		status = iomt_reopen (dv, MT_M_READ, FALSE);
		if (status != SS_NORMAL)
		{
			return (status);
		}
	}
#endif
	switch (mt_ptr->last_op)
	{
	case mt_rewind:
		if (mt_ptr->labeled == MTLAB_DOS11)
			iomt_rddoslab (dv);
		else if (mt_ptr->labeled == MTLAB_ANSI)
			iomt_rdansistart (dv);
		/* CAUTION: FALL THROUGH  */
	case mt_null:
		if (iomt_readblk (dv))
		{
			if (mt_ptr->stream)
				iomt_rdstream (mt_ptr->record_sz, v->str.addr, dv);
			else
				iomt_getrec (dv);
		}
		break;
	case mt_read:
		if (mt_ptr->stream)
			iomt_rdstream (mt_ptr->record_sz, v->str.addr, dv);
		else
			iomt_getrec (dv);
		break;
	default:
		rts_error (VARLSTCNT (1) ERR_MTRDTHENWRT);
	}
	if (io_curr_device.in->dollar.zeof)
	{
		v->str.len = 0;
		return TRUE;
	}
	if (!mt_ptr->stream)
		memcpy (v->str.addr, mt_ptr->rec.addr, mt_ptr->rec.len);
	v->str.len = mt_ptr->rec.len;
	io_curr_device.in->dollar.x = 0;
	io_curr_device.in->dollar.y++;
	mt_ptr->last_op = (mt_ptr->buffptr >= mt_ptr->bufftop)
		? mt_null : mt_read;

#ifdef DP
	FPRINTF(stderr, "<< iomt_read\n");
#endif

	return TRUE;
}
Ejemplo n.º 17
0
int	iotcp_readfl(mval *v, int4 width, int4 timeout)
/* 0 == width is a flag that the caller is read and the length is not actually fixed */
/* timeout in seconds */
{
	/* VMS uses the UCX interface; should support others that emulate it */
	boolean_t	ret, timed, vari;
	int		flags, len, real_errno, save_errno;
	int		i;
	io_desc		*io_ptr;
	d_tcp_struct	*tcpptr;
	int4		status;
	int4		msec_timeout;	/* timeout in milliseconds */
	TID		timer_id;
	ABS_TIME	cur_time, end_time, time_for_read, lcl_time_for_read, zero;
	fd_set		tcp_fd;
	char		*errptr;
	int4		errlen;

	error_def(ERR_IOEOF);
	error_def(ERR_TEXT);
	error_def(ERR_GETSOCKOPTERR);
	error_def(ERR_SETSOCKOPTERR);

#ifdef DEBUG_TCP
	PRINTF("%s >>>\n", __FILE__);
#endif
	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);
	if (0 == width)
	{	/* op_readfl won't do this; must be a call from iotcp_read */
		vari = TRUE;
		width = MAX_READLEN;
	} else
	{
		vari = FALSE;
		width = (width < MAX_READLEN) ? width : MAX_READLEN;
	}
	if (stringpool.free + width > stringpool.top)
		stp_gcol(width);
	io_ptr = io_curr_device.in;
	assert(dev_open == io_ptr->state);
	tcpptr = (d_tcp_struct *)(io_ptr->dev_sp);
	if (io_ptr->dollar.x && (TCP_WRITE == tcpptr->lastop))
	{	/* switching from write to read */
#ifdef C9A06001531
		/* pending change request C9A06-001531 */
		if (!io_ptr->dollar.za)
			iotcp_wteol(1, io_ptr);
#endif
		io_ptr->dollar.x = 0;
	}
	tcpptr->lastop = TCP_READ;
	ret = TRUE;
	timer_id = (TID)iotcp_readfl;
	out_of_time = FALSE;
	time_for_read.at_sec = ((0 == timeout) ? 0 : 1);
	time_for_read.at_usec = 0;
	if (NO_M_TIMEOUT == timeout)
	{
		timed = FALSE;
		msec_timeout = NO_M_TIMEOUT;
	} else
	{
		timed = TRUE;
		msec_timeout = timeout2msec(timeout);
		if (msec_timeout > 0)
		{	/* there is time to wait */
#ifdef UNIX
			/* set blocking I/O */
			FCNTL2(tcpptr->socket, F_GETFL, flags);
			if (flags < 0)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(errno);
				rts_error(VARLSTCNT(7) ERR_GETSOCKOPTERR, 5, LEN_AND_LIT("F_GETFL FOR NON BLOCKING I/O"),
						save_errno, LEN_AND_STR(errptr));
			}
			FCNTL3(tcpptr->socket, F_SETFL, flags & (~(O_NDELAY | O_NONBLOCK)), fcntl_res);
			if (fcntl_res < 0)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(errno);
				rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("F_SETFL FOR NON BLOCKING I/O"),
						save_errno, LEN_AND_STR(errptr));
			}
#endif
			sys_get_curr_time(&cur_time);
			add_int_to_abs_time(&cur_time, msec_timeout, &end_time);
			start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL);
		} else
			out_of_time = TRUE;
	}
	for (i = 0, status = 0; status >= 0; )
	{
		FD_ZERO(&tcp_fd);
		FD_SET(tcpptr->socket, &tcp_fd);
		assert(0 != FD_ISSET(tcpptr->socket, &tcp_fd));
		assert(((1 == time_for_read.at_sec) || (0 == time_for_read.at_sec)) && (0 == time_for_read.at_usec));
		/*
		 * the check for EINTR below is valid and should not be converted to an EINTR
		 * wrapper macro, since it might be a timeout.
		 */
		lcl_time_for_read = time_for_read;
		status = tcp_routines.aa_select(tcpptr->socket + 1, (void *)(&tcp_fd), (void *)0, (void *)0,
							&lcl_time_for_read);
		if (status > 0)
		{
			status = tcp_routines.aa_recv(tcpptr->socket, (char *)(stringpool.free +  i), width - i, 0);
			if ((0 == status) || ((-1 == status) && (ECONNRESET == errno || EPIPE == errno || EINVAL == errno)))
			{ /* lost connection. */
				if (0 == status)
					errno = ECONNRESET;
				real_errno = errno;
				status = -2;
				break;
			}

		}
		if (status < 0)
		{
			if (EINTR == errno && FALSE == out_of_time)
			{	/* interrupted by a signal which is not OUR timer, continue looping */
				status = 0;
			} else
				real_errno = errno;
		} else
			real_errno = 0;
		if (outofband)
			break;
		if (timed)
		{
			if (msec_timeout > 0)
			{
				sys_get_curr_time(&cur_time);
				cur_time = sub_abs_time(&end_time, &cur_time);
				if (cur_time.at_sec <= 0)
				{
					out_of_time = TRUE;
					cancel_timer(timer_id);
					if (status > 0)
						i += status;
					break;
				}
			} else
			{
				if (status > 0)
					i += status;
				break;
			}
		}
		if (0 > status)
			break;
		i += status;
		if ((vari && (0 != i)) || (i >= width))
			break;
	}
	if (EINTR == real_errno)
		status = 0;	/* don't treat a <CTRL-C> or timeout as an error */
	if (timed)
	{
		if (0 == msec_timeout)
		{
			if (0 == status)
				ret = FALSE;
		} else
		{
#ifdef UNIX
			real_errno = errno;
			FCNTL3(tcpptr->socket, F_SETFL, flags, fcntl_res);
			if (fcntl_res < 0)
			{
				save_errno = errno;
				errptr = (char *)STRERROR(errno);
				rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("F_SETFL FOR RESTORING SOCKET OPTIONS"),
					  	save_errno, LEN_AND_STR(errptr));
			}
			errno = real_errno;
#endif
			if (out_of_time && (i < width))
				ret = FALSE;
			else
				cancel_timer(timer_id);
		}
	}
	if (i > 0)
	{	/* there's somthing to return */
		v->str.len = i;
		v->str.addr = (char *)stringpool.free;
		if (((io_ptr->dollar.x += i) >= io_ptr->width) && (TRUE == io_ptr->wrap))
		{
			io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width);
			if (0 != io_ptr->length)
				io_ptr->dollar.y %= io_ptr->length;
			io_ptr->dollar.x %= io_ptr->width;
		}
	} else
		v->str.len = 0;
#ifdef DEBUG_TCP
	PRINTF("%s <<<\n", __FILE__);
#endif
	len = sizeof("1,") - 1;
	if (status >= 0)
	{	/* no real problems */
		io_ptr->dollar.za = 0;
/*	the handling of urgent data doesn't work and never has, the design should be changed to use a /URGENT controlnmemonic
 *	because there is really only one character available at a time
		zero.at_sec = zero.at_usec = 0;
		FD_ZERO(&tcp_fd);
		FD_SET(tcpptr->socket, &tcp_fd);
		if (tcp_routines.aa_select(tcpptr->socket + 1, (void *)(tcpptr->urgent ? &tcp_fd : 0), (void *)0,
								(void *)(tcpptr->urgent ? 0 : &tcp_fd), &zero) > 0)
		{
			memcpy(tcpptr->dollar_device, "1,", len);
			if (tcpptr->urgent)
			{
				memcpy(&tcpptr->dollar_device[len], "No ",sizeof("No "));
				len += sizeof("No ") - 1;
			}
			memcpy(&tcpptr->dollar_device[len], "Urgent Data", sizeof("Urgent Data"));
		} else
*/
			memcpy(tcpptr->dollar_device, "0", sizeof("0"));
	} else
	{	/* there's a significant problem */
		if (0 == i)
			io_ptr->dollar.x = 0;
		io_ptr->dollar.za = 9;
		memcpy(tcpptr->dollar_device, "1,", len);
		errptr = (char *)STRERROR(errno);
		errlen = STRLEN(errptr);
		memcpy(&tcpptr->dollar_device[len], errptr, errlen);
		if (io_ptr->dollar.zeof || -1 == status || 0 < io_ptr->error_handler.len)
		{
			io_ptr->dollar.zeof = TRUE;
			rts_error(VARLSTCNT(6) ERR_IOEOF, 0, ERR_TEXT, 2, errlen, errptr);
		} else
			io_ptr->dollar.zeof = TRUE;
	}
	return (ret);
}
Ejemplo n.º 18
0
void op_gvquery (mval *v)
{
	int4			size;
	unsigned char		buff[MAX_ZWR_KEY_SZ], *end, *glob_begin;
 	bool			found;
	enum db_acc_method 	acc_meth;
	unsigned char		*extnamsrc, *extnamdst, *extnamtop;
	int			maxlen;
	char			extnamdelim[] = "^|\"\"|";
	mval			val;

	/* We want to turn QUERY into QUERYGET for all types of access methods so that we can cache the value of the key returned
	 * by $QUERY. The value is very likely to be used shortly after $QUERY - Vinaya, Aug 13, 2001 */
	acc_meth = gv_cur_region->dyn.addr->acc_meth;
	if (gv_curr_subsc_null)
	{
		if (0 == gv_cur_region->std_null_coll)
			gv_currkey->base[gv_currkey->prev] = 01;
		else
		{
			gv_currkey->base[gv_currkey->end++]= 1;
			gv_currkey->base[gv_currkey->end++] = 0;
			gv_currkey->base[gv_currkey->end] = 0;
		}
	} else
	{ /* Note, gv_currkey->prev isn't changed here. We rely on this in gtcmtr_query to distinguish different forms of the key */
		gv_currkey->base[gv_currkey->end++]= 1;
		gv_currkey->base[gv_currkey->end++] = 0;
		gv_currkey->base[gv_currkey->end] = 0;
	}
	switch (acc_meth)
	{
		case dba_bg:
		case dba_mm:
			found = ((0 != gv_target->root) ? gvcst_query() : FALSE); /* global does not exist if root is 0 */
			break;
		case dba_cm:
			found = gvcmx_query(&val); /* val ignored currently - Vinaya Aug 13, 2001*/
			break;
		case dba_usr:
			found = gvusr_query(v); /* $Q result in v for dba_usr, for others, in gv_altkey */
			break;
		default:
			assert(FALSE); /* why didn't we cover all access methods? */
			found = FALSE;
			break;
	}
	v->mvtype = MV_STR;
	if (found)
	{
		if (acc_meth != dba_usr)
		{
			if ((end = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gv_altkey, TRUE)) == 0)
				end = &buff[MAX_ZWR_KEY_SZ - 1];
			size = (int)(end - &buff[0] - 1); /* exclude ^ */
			glob_begin = &buff[1]; /* skip ^ */
		} else
		{
			size = v->str.len - 1; /* exclude ^ */
			glob_begin = (unsigned char *)v->str.addr + 1; /* skip ^ */
		}
		/* Need to return a double-quote for every single-quote; assume worst case. */
		/* Account for ^ in both cases - extnam and no extnam */
		maxlen = size + ((0 == extnam_str.len) ? 1 : ((extnam_str.len * 2) + (int)(STR_LIT_LEN(extnamdelim))));
		if ((stringpool.top - stringpool.free) < maxlen)
		{
			v->str.len = 0; /* so stp_gcol ignores otherwise incompletely setup mval */
			stp_gcol(maxlen);
		}
		extnamdst = stringpool.free;
		*extnamdst++ = extnamdelim[0];
		if (extnam_str.len > 0)
		{
			*extnamdst++ = extnamdelim[1];
			*extnamdst++ = extnamdelim[2];
			for (extnamsrc = (unsigned char *)extnam_str.addr, extnamtop = extnamsrc + extnam_str.len;
					extnamsrc < extnamtop; )
			{
				*extnamdst++ = *extnamsrc;
				if ('"' == *extnamsrc++)	/* caution : pointer increment side-effect */
					*extnamdst++ = '"';
			}
			*extnamdst++ = extnamdelim[3];
			*extnamdst++ = extnamdelim[4];
			extnam_str.len = 0;
		}
		memcpy(extnamdst, glob_begin, size);
		v->str.len = INTCAST(extnamdst - stringpool.free + size);
		v->str.addr = (char *)stringpool.free;
		stringpool.free += v->str.len;
		assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base);
		assert (v->str.addr + v->str.len <= (char *)stringpool.top &&
			v->str.addr + v->str.len >= (char *)stringpool.base);
	} else /* !found */
		v->str.len = 0;
	return;
}
Ejemplo n.º 19
0
void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret)
/* label contains label to be located or null string */
/* int_exp contains label offset or line number to reference */
/* ret is used to return the correct string to caller */
{
	char		*cp, *ctop;
	int		i, lbl, letter;
	mval		*temp_rtn, temp_mval;
	mstr		*sld;
	uint4		stat;
	rhdtyp		*rtn_vector;

	error_def(ERR_TXTNEGLIN);
	error_def(ERR_TXTSRCMAT);
	error_def(ERR_ZLINKFILE);
	error_def(ERR_ZLMODULE);

	MV_FORCE_STR(label);
	MV_FORCE_STR(rtn);
	temp_rtn = &temp_mval;
	*temp_rtn = *rtn;	/* make a copy of the routine in case the caller used the same mval for rtn and ret */
	ret->str.len = 0;	/* make ret an emptystring in case the return is by way of the condition handler */
	ret->mvtype = MV_STR;
	sld = (mstr *)NULL;
	ESTABLISH(fntext_ch);	/* to swallow errors and permit an emptystring result */
	if ((int_exp == 0) && ((label->str.len == 0) || (*label->str.addr == 0)))
		stat = ZEROLINE;
	else
		stat = get_src_line(temp_rtn, label, int_exp, &sld);
	if ((FALSE == (stat & CHECKSUMFAIL)) && (FALSE == (stat & NEGATIVELINE)))
	{
		if (stat & ZEROLINE)
		{
			if (NULL == (rtn_vector = find_rtn_hdr(&temp_rtn->str)))
			{	/* not here, so try to bring it in */
				op_zlink(temp_rtn, 0);
				rtn_vector = find_rtn_hdr(&temp_rtn->str);
			}
			if (NULL != rtn_vector)
			{
				ret->str.addr = cp = (char *)&rtn_vector->routine_name;
				for (ctop = cp + sizeof(mident);  *cp && cp < ctop;  cp++)
					;
				ret->str.len = cp - ret->str.addr;
			}
		} else  if (NULL != sld)
			ret->str = *sld;
	}
	REVERT;
	/* If non-empty, copy result to stringpool and
	 * convert any tabs in linestart to spaces
	 */
	if (ret->str.len)
	{
		if (stringpool.free + ret->str.len > stringpool.top)
				stp_gcol(ret->str.len);
		cp = stringpool.free;
		for (i = 0, lbl = 1; i < ret->str.len; i++)
		{
			letter = ret->str.addr[i];
			if (lbl)
			{
				if ((' ' == letter) || ('\t' == letter))
				{
					letter = ' ';
					lbl = 0;
				}
				*cp++ = letter;
			} else
			{
				if ((' ' != letter) && ('\t' != letter))
				{
					memcpy(cp, &ret->str.addr[i], ret->str.len - i);
					break;
				} else
					*cp++ = ' ';
			}
		}
		ret->str.addr=stringpool.free;
		stringpool.free += ret->str.len;
	}
	return;
}
Ejemplo n.º 20
0
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v)
{
	unsigned char	*ptr;
	short		len, temp_short;
	int4		status, max_reply_len;
	struct CLB	*lnk;
	unsigned char	buff[MAX_ZWR_KEY_SZ], *end;

	error_def(ERR_BADSRVRNETMSG);
	error_def(ERR_UNIMPLOP);
	error_def(ERR_TEXT);
	error_def(ERR_GVIS);

	lnk = gv_cur_region->dyn.addr->cm_blk;
	if (!((link_info *)lnk->usr)->server_supports_long_names && (PRE_V5_MAX_MIDENT_LEN < strlen((char *)gv_currkey->base)))
	{
		end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE);
		rts_error(VARLSTCNT(14) ERR_UNIMPLOP, 0,
					ERR_TEXT, 2,
					LEN_AND_LIT("GT.CM server does not support global names longer than 8 characters"),
					ERR_GVIS, 2, end - buff, buff,
					ERR_TEXT, 2, DB_LEN_STR(gv_cur_region));
	}
	lnk->ast = 0;	/* all database queries are sync */
	lnk->cbl = 1 + /* HDR */
		   gv_currkey->end + /* key */
		   sizeof(unsigned short) + /* gv_key.top */
		   sizeof(unsigned short) + /* gv_key.end */
		   sizeof(unsigned short) + /* gv_key.prev */
		   sizeof(unsigned char) + /* gv_key.base */
		   sizeof(unsigned char) + /* regnum */
		   sizeof(unsigned short); /* size for variable len SUBSC */
	/* the current GT.CM maximum message buffer length is bounded by the size of a short which is 64K. but the
	 * calculation below of lnk->cbl and max_reply_len takes into account the fact that the value that is sent in as
	 * input or read in from the server side can be at most MAX_DBSTRLEN in size. therefore, there is a dependency
	 * that MAX_DBSTRLEN always be less than the GT.CM maximum message buffer length. to ensure this is always the
	 * case, the following assert is added so that whenever MAX_DBSTRLEN is increased, we will fail this assert
	 * and reexamine the code below.
	 */
	assert(sizeof(lnk->cbl) == 2);	/* assert it is a short. when it becomes a uint4 the assert can be removed
					 * if the macro CM_MAX_BUF_LEN (used below) is changed appropriately */
	assert(MAX_DBSTRLEN == (32 * 1024 - 1));
	if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code)
	{
		if (CMMS_Q_INCREMENT == query_code)
		{ /* 1-byte boolean value of "undef_inhibit" passed to the server for $INCREMENT
		   although, effective V5.0-000, undef_inhibit is no longer relevant as $INCREMENT()
		   implicitly does a $GET() on the global. We keep this byte to ensure compatibility
		   with V5.0-FT01 */
			lnk->cbl++;
		}
		assert((uint4)lnk->cbl + sizeof(unsigned short) + (uint4)MAX_DBSTRLEN <= (uint4)CM_MAX_BUF_LEN);
		lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */
	}
	if ((CMMS_Q_GET == query_code)
			|| (CMMS_Q_INCREMENT == query_code)
			|| (CMMS_Q_QUERY == query_code) && ((link_info *)lnk->usr)->query_is_queryget)
		max_reply_len = lnk->mbl + SIZEOF(unsigned short) + MAX_DBSTRLEN; /* can't predict the length of data value */
	else
		max_reply_len = lnk->mbl;
	assert(max_reply_len <= (int4)CM_MAX_BUF_LEN);
	if (stringpool.top < stringpool.free + max_reply_len)
		stp_gcol(max_reply_len);
	lnk->mbf = stringpool.free;
	ptr = lnk->mbf;
	*ptr++ = query_code;
	/* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */
	temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1;
	CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	*ptr++ = gv_cur_region->cmx_regnum;
	CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	memcpy(ptr, gv_currkey->base, gv_currkey->end + 1);
	if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code)
	{
		ptr += gv_currkey->end + 1;
		temp_short = (short)v->str.len;
		assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */
		CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		memcpy(ptr,v->str.addr, v->str.len);
		if (CMMS_Q_INCREMENT == query_code)
		{ /* UNDEF flag is no longer relevant, but set the flag to ensure compatibility with V5.0-FT01 */
			assert(sizeof(undef_inhibit) == 1);
			ptr[v->str.len] = (unsigned char)undef_inhibit;
		}
	}
	status = cmi_write(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	status = cmi_read(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	ptr = lnk->mbf;
	if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code)
	{
		if (reply_code != *ptr)
		{
			if (*ptr != CMMS_E_ERROR)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk,FALSE);
		}
		return;
	}
	if (reply_code != *ptr)
	{
		if ((CMMS_R_UNDEF != *ptr) || ((CMMS_Q_GET != query_code) && (CMMS_Q_INCREMENT != query_code)))
		{
			if (CMMS_E_ERROR != *ptr)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk, FALSE);
		}
		if (CMMS_Q_INCREMENT == query_code)
			v->mvtype = 0;	/* set the result to be undefined */
		return;
	}
	ptr++;
	if (CMMS_R_DATA == reply_code)
	{
		CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		if (1 != temp_short)
			rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
		ptr += sizeof(short);
		status = *ptr;	/* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */
		MV_FORCE_MVAL(v, status);
		return;
	}
	if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER)
	{
		CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		if (1 == len)
		{
			MV_FORCE_MVAL(v, 0);
		} else
		{
			if (*ptr++ != gv_cur_region->cmx_regnum)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			/* memcpy(gv_altkey, ptr, len - 1); */
			CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) -
						     sizeof(unsigned short));
			ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short));
			MV_FORCE_MVAL(v, 1);
		}
		if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget)
		{
			if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget)
				v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */
			return;
		}
	}
	assert(CMMS_R_GET == reply_code
		|| CMMS_R_INCREMENT == reply_code
		|| CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len);
	CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(unsigned short);
	assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */
	v->mvtype = MV_STR;
	v->str.len = len;
	v->str.addr = (char *)stringpool.free;	/* we don't need the reply msg anymore, can overwrite reply */
	memcpy(v->str.addr, ptr, len);		/* so that we don't leave a gaping hole in the stringpool */
	stringpool.free += len;
	return;
}
Ejemplo n.º 21
0
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v)
{
	unsigned char	*ptr;
	short		len, temp_short;
	int4		status, max_reply_len;
	struct CLB	*lnk;
	error_def(ERR_BADSRVRNETMSG);

	lnk = gv_cur_region->dyn.addr->cm_blk;
	lnk->ast = 0;	/* all database queries are sync */
	lnk->cbl = 1 + /* HDR */
		   gv_currkey->end + /* key */
		   sizeof(unsigned short) + /* gv_key.top */
		   sizeof(unsigned short) + /* gv_key.end */
		   sizeof(unsigned short) + /* gv_key.prev */
		   sizeof(unsigned char) + /* gv_key.base */
		   sizeof(unsigned char) + /* regnum */
		   sizeof(unsigned short); /* size for variable len SUBSC */
	if (CMMS_Q_PUT == query_code)
		lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */
	if (CMMS_Q_GET == query_code || CMMS_Q_QUERY == query_code && ((link_info *)lnk->usr)->query_is_queryget)
		max_reply_len = lnk->mbl + sizeof(unsigned short) + MAX_STRLEN; /* can't predict the length of data value */
	else
		max_reply_len = lnk->mbl;
	if (stringpool.top < stringpool.free + max_reply_len)
		stp_gcol(max_reply_len);
	lnk->mbf = stringpool.free;
	ptr = lnk->mbf;
	*ptr++ = query_code;
	/* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */
	temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1;
	CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	*ptr++ = gv_cur_region->cmx_regnum;
	CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(short);
	memcpy(ptr, gv_currkey->base, gv_currkey->end + 1);
	if (query_code == CMMS_Q_PUT)
	{
		ptr += gv_currkey->end + 1;
		temp_short = (short)v->str.len;
		assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */
		CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		memcpy(ptr,v->str.addr, v->str.len);
	}
	status = cmi_write(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code)
	{
		status = cmi_read(lnk);
		if (CMI_ERROR(status))
		{
			((link_info *)(lnk->usr))->neterr = TRUE;
			gvcmz_error(query_code, status);
			return;
		}
		ptr = lnk->mbf;
		if (reply_code != *ptr)
		{
			if (*ptr != CMMS_E_ERROR)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk,FALSE);
		}
		return;
	}
	status = cmi_read(lnk);
	if (CMI_ERROR(status))
	{
		((link_info *)(lnk->usr))->neterr = TRUE;
		gvcmz_error(query_code, status);
		return;
	}
	ptr = lnk->mbf;
	if (reply_code != *ptr)
	{
		if (CMMS_R_UNDEF != *ptr || CMMS_Q_GET != query_code)
		{
			if (CMMS_E_ERROR != *ptr)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			gvcmz_errmsg(lnk, FALSE);
		}
		return;
	}
	ptr++;
	if (CMMS_R_DATA == reply_code)
	{
		CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		if (1 != temp_short)
			rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
		ptr += sizeof(short);
		status = *ptr;	/* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */
		MV_FORCE_MVAL(v, status);
		return;
	}
	if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER)
	{
		CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
		ptr += sizeof(short);
		if (1 == len)
		{
			MV_FORCE_MVAL(v, 0);
		} else
		{
			if (*ptr++ != gv_cur_region->cmx_regnum)
				rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG);
			/* memcpy(gv_altkey, ptr, len - 1); */
			CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
			ptr += sizeof(unsigned short);
			memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) -
						     sizeof(unsigned short));
			ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short));
			MV_FORCE_MVAL(v, 1);
		}
		if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget)
		{
			if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget)
				v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */
			return;
		}
	}
	assert(CMMS_R_GET == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len);
	CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder);
	ptr += sizeof(unsigned short);
	assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */
	v->mvtype = MV_STR;
	v->str.len = len;
	v->str.addr = (char *)stringpool.free;	/* we don't need the reply msg anymore, can overwrite reply */
	memcpy(v->str.addr, ptr, len);		/* so that we don't leave a gaping hole in the stringpool */
	stringpool.free += len;
	return;
}
Ejemplo n.º 22
0
bool	gvcst_get(mval *v)
{
	srch_blk_status	*s;
	enum cdb_sc	status;
	int		key_size, data_len;
	unsigned short	rsiz;
	rec_hdr_ptr_t	rp;

	T_BEGIN_READ_NONTP_OR_TP(ERR_GVGETFAIL);
	assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit);	/* we better hold crit in the final retry (TP & non-TP) */
	for (;;)
	{
		if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL)))
		{
			if ((key_size = gv_currkey->end + 1) == gv_target->hist.h[0].curr_rec.match)
			{
				rp = (rec_hdr_ptr_t)(gv_target->hist.h[0].buffaddr + gv_target->hist.h[0].curr_rec.offset);
				GET_USHORT(rsiz, &rp->rsiz);
				data_len = rsiz + rp->cmpc - sizeof(rec_hdr) - key_size;
				if (data_len < 0  || (sm_uc_ptr_t)rp + rsiz >
					gv_target->hist.h[0].buffaddr + ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->bsiz)
				{
					assert(CDB_STAGNATE > t_tries);
					status = cdb_sc_rmisalign1;
				} else
				{
					if (stringpool.top - stringpool.free < data_len)
						stp_gcol(data_len);
					assert(stringpool.top - stringpool.free >= data_len);
					memcpy(stringpool.free, (sm_uc_ptr_t)rp + rsiz - data_len, data_len);
					if (0 == dollar_tlevel)
					{
						if (0 == t_end(&gv_target->hist, NULL))
							continue;
					} else
					{
						status = tp_hist(NULL);
						if (cdb_sc_normal != status)
						{
							t_retry(status);
							continue;
						}
					}
					v->mvtype = MV_STR;
					v->str.addr = (char *)stringpool.free;
					v->str.len = data_len;
					stringpool.free += data_len;
					if (cs_addrs->read_write)
						cs_addrs->hdr->n_gets++;
					return TRUE;
				}
			} else
			{
				if (0 == dollar_tlevel)
				{
					if (0 == t_end(&gv_target->hist, NULL))
						continue;
				} else
				{
					status = tp_hist(NULL);
					if (cdb_sc_normal != status)
					{
						t_retry(status);
						continue;
					}
				}

				cs_addrs->hdr->n_gets++;
				return FALSE;
			}
		}
		t_retry(status);
	}
}
Ejemplo n.º 23
0
/*
 * ----------------------------------------------------------
 * Fast path setpiece when delimiter is one (lit) char replacing
 * a single piece (last is same as first).
 *
 * Arguments:
 *	src	- source mval
 *	delim	- delimiter char
 *	expr	- expression string mval
 *	ind	- index in source mval to be set
 *	dst	- destination mval where the result is saved.
 *
 * Return:
 *	none
 * ----------------------------------------------------------
 */
void op_setp1(mval *src, int delim, mval *expr, int ind, mval *dst)
{
    int		len, pfx_str_len, sfx_start_offset, sfx_str_len, rep_str_len, str_len, delim_cnt, pfx_scan_offset;
    int		cpy_cache_lines;
    unsigned char	ldelim, lc, *start_sfx, *str_addr, *end_pfx, *end_src, *start_pfx;
    boolean_t	do_scan;
    mval		dummymval;	/* It's value is not used but is part of the call to op_fnp1() */
    fnpc		*cfnpc, *pfnpc;

    error_def(ERR_MAXSTRLEN);

    ldelim = delim;		/* Local copy (in unsigned char format) */
    do_scan = FALSE;
    cpy_cache_lines = -1;

    MV_FORCE_STR(expr);	/* Expression to put into piece place */
    if (MV_DEFINED(src))
    {
        /* We have 3 possible scenarios:

           1) If length of src is too small to cause cacheing by op_fnp1, then just do
           the work ourselves with no cacheing.
           2) If the requested piece is larger than can be cached by op_fnp1, call fnp1
           for the maximum piece possible, use the cache info to "prime the pump" and
           then process the rest of the string ourselves.
           3) If the requested piece can be obtained from the cache, call op_fnp1 to validate
           and rebuild the cache if necessary and then retrieve the necessary info from
           the fnpc cache.
        */
        MV_FORCE_STR(src);	/* Make sure is string prior to length check */
        if (FNPC_STRLEN_MIN < src->str.len && FNPC_ELEM_MAX >= ind)
        {   /* 3) Best of all possible cases. The op_fnp1 can do most of our work for us
               and we can preload the cache on the new string to help its subsequent
               uses along as well.
            */
            SETWON;
            op_fnp1(src, delim, ind, &dummymval, FALSE);
            SETWOFF;
            cfnpc = &fnpca.fnpcs[src->fnpc_indx - 1];
            assert(cfnpc->last_str.addr == src->str.addr);
            assert(cfnpc->last_str.len == src->str.len);
            assert(cfnpc->delim == delim);
            assert(0 < cfnpc->npcs);
            /* Three more scenarios: #1 piece all in cache, #2 piece would be in cache but ran
               out of text or #3 piece is beyond what can be cached
            */
            if (cfnpc->npcs >= ind)
            {   /* #1 The piece we want is totally within the cache which is good news */
                pfx_str_len = cfnpc->pstart[ind - 1];
                delim_cnt = 0;
                sfx_start_offset = cfnpc->pstart[ind] - 1;			/* Include delimiter */
                rep_str_len = cfnpc->pstart[ind] - cfnpc->pstart[ind - 1] - 1;	/* Replace string length */
                sfx_str_len = src->str.len - pfx_str_len - rep_str_len;
                cpy_cache_lines = ind - 1;
            } else
            {   /* #2 The string was too short so the cache does not contain our string. This means
                   that the prefix becomes any text that IS in the cache and we set the delim_cnt
                   to be the number of missing pieces so the delimiters can be put in as part of the
                   prefix when we build the new string.
                */
                pfx_str_len = cfnpc->pstart[cfnpc->npcs] - 1;
                delim_cnt = ind - cfnpc->npcs;
                sfx_start_offset = 0;
                sfx_str_len = 0;
                cpy_cache_lines = cfnpc->npcs;
            }
        } else if (FNPC_STRLEN_MIN < src->str.len)
        {   /* 2) We have a element that would not be able to be in the fnpc cache. Go ahead
               and call op_fnp1 to get cache info up to the maximum and then we will continue
               the scan on our own.
            */
            SETWON;
            op_fnp1(src, delim, FNPC_ELEM_MAX, &dummymval, FALSE);
            SETWOFF;
            cfnpc = &fnpca.fnpcs[src->fnpc_indx - 1];
            assert(cfnpc->last_str.addr == src->str.addr);
            assert(cfnpc->last_str.len == src->str.len);
            assert(cfnpc->delim == delim);
            assert(0 < cfnpc->npcs);
            if (FNPC_ELEM_MAX > cfnpc->npcs)
            {   /* We ran out of text so the scan is complete. This is basically the same
                   as case #2 above.
                */
                pfx_str_len = cfnpc->pstart[cfnpc->npcs] - 1;
                delim_cnt = ind - cfnpc->npcs;
                sfx_start_offset = 0;
                sfx_str_len = 0;
                cpy_cache_lines = cfnpc->npcs;
            } else
            {   /* We have a case where the piece we want cannot be kept in cache. In the special
                   case where there is no more text to handle, we don't need to scan further. Otherwise
                   we prime the pump and continue the scan where the cache left off.
                */
                if ((pfx_scan_offset = cfnpc->pstart[FNPC_ELEM_MAX]) < src->str.len)
                {   /* Normal case where we prime the pump */
                    do_scan = TRUE;
                } else
                {   /* Special case -- no more text to scan */
                    pfx_str_len = cfnpc->pstart[FNPC_ELEM_MAX] - 1;
                    sfx_start_offset = 0;
                    sfx_str_len = 0;
                }
                delim_cnt = ind - FNPC_ELEM_MAX;
                cpy_cache_lines = FNPC_ELEM_MAX;
            }

        } else
        {   /* 1) We have a short string where no cacheing happens. Do the scanning work ourselves */
            MV_FORCE_STR(src);
            do_scan = TRUE;
            pfx_scan_offset = 0;
            delim_cnt = ind;
        }
    } else
    {   /* Source is not defined -- treat as a null string */
        pfx_str_len = sfx_str_len = sfx_start_offset = 0;
        delim_cnt = ind - 1;
    }

    /* If we have been forced to do our own scan, do that here. Note the variable pfx_scan_offset has been
       set to where the scan should begin in the src string and delim_cnt has been set to how many delimiters
       still need to be processed.
    */
    if (do_scan)
    {   /* Scan the line isolating prefix piece, and end of the
           piece being replaced
        */
        COUNT_EVENT(cs_small);
        end_pfx = start_sfx = (unsigned char *)src->str.addr + pfx_scan_offset;
        end_src = (unsigned char *)src->str.addr + src->str.len;

        /* The compiler would unroll this loop this way anyway but we want to
           adjust the start_sfx pointer after the loop but only if we have gone
           into it at least once.
        */
        if (0 < delim_cnt && start_sfx < end_src)
        {
            do
            {
                end_pfx = start_sfx;
                while (start_sfx < end_src && (lc = *start_sfx) != ldelim) start_sfx++;
                start_sfx++;
                delim_cnt--;
            } while (0 < delim_cnt && start_sfx < end_src);

            /* We have to backup up the suffix start pointer except under the condition
               that the last character in the buffer is the last delimiter we were looking
               for.
            */
            if (0 == delim_cnt || start_sfx < end_src || lc != ldelim)
                --start_sfx;				/* Back up suffix to include delimiter char */

            /* If we scanned to the end (no text left) and still have delimiters to
               find, the entire src text should be part of the prefix */
            if (start_sfx >= end_src && 0 < delim_cnt)
            {
                end_pfx = start_sfx;
                if (lc == ldelim)			/* if last char was delim, reduce delim cnt */
                    --delim_cnt;
            }

        } else
        {
            /* If not doing any token finding, then this count becomes the number
               of tokens to output. Adjust accordingly.
            */
            if (0 > --delim_cnt)
                delim_cnt = 0;
        }
        INCR_COUNT(cs_small_pcs, ind - delim_cnt);

        /* Now having the following situation:
           end_pfx	-> end of the prefix piece including delimiter
           start_sfx	-> start of suffix piece (with delimiter) or = end_pfx/src->str.addr if none
        */
        pfx_str_len = end_pfx - (unsigned char *)src->str.addr;
        if (0 > pfx_str_len)
            pfx_str_len = 0;
        sfx_start_offset = start_sfx - (unsigned char *)src->str.addr;
        sfx_str_len = src->str.len - sfx_start_offset;
        if (0 > sfx_str_len)
            sfx_str_len = 0;
    }

    /* Calculate total string len. delim_cnt has needed padding delimiters for null fields */
    str_len = expr->str.len + pfx_str_len + delim_cnt + sfx_str_len;
    if (str_len > MAX_STRLEN)
        rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
    if (str_len > (stringpool.top - stringpool.free))
        stp_gcol(str_len);
    str_addr = stringpool.free;
    start_pfx = (unsigned char *)src->str.addr;

    /* copy prefix */
    if (0 < pfx_str_len)
    {
        memcpy(str_addr, src->str.addr, pfx_str_len);
        str_addr += pfx_str_len;
    }

    /* copy delimiters */
    while (delim_cnt-- > 0)
        *str_addr++ = ldelim;

    /* copy expression */
    if (0 < expr->str.len)
    {
        memcpy(str_addr, expr->str.addr, expr->str.len);
        str_addr += expr->str.len;
    }

    /* copy suffix */
    if (0 < sfx_str_len)
    {
        memcpy(str_addr, start_pfx + sfx_start_offset, sfx_str_len);
        str_addr += sfx_str_len;
    }

    assert(str_addr - stringpool.free == str_len);
    dst->mvtype = MV_STR;
    dst->str.len = str_addr - stringpool.free;
    dst->str.addr = (char *)stringpool.free;
    stringpool.free = str_addr;

    /* If available, update the cache information for this newly created mval to hopefully
       give it a head start on its next usage. Note that we can only copy over the cache info
       for the prefix. We cannot include information for the 'expression' except where it starts
       because the expression could itself contain delimiters that would be found on a rescan.
    */
    if (0 < cpy_cache_lines)
    {
        pfnpc = cfnpc;				/* pointer for src mval's cache */
        do
        {
            cfnpc = fnpca.fnpcsteal;	/* Next cache element to steal */
            if (fnpca.fnpcmax < cfnpc)
                cfnpc = &fnpca.fnpcs[0];
            fnpca.fnpcsteal = cfnpc + 1;	/* -> next element to steal */
        } while (cfnpc == pfnpc);		/* Make sure we don't step on ourselves */

        cfnpc->last_str = dst->str;		/* Save validation info */
        cfnpc->delim = delim;
        cfnpc->npcs = cpy_cache_lines;
        dst->fnpc_indx = cfnpc->indx + 1;	/* Save where we are putting this element
							   (1 based index in mval so 0 isn't so common) */
        memcpy(&cfnpc->pstart[0], &pfnpc->pstart[0], (cfnpc->npcs + 1) * sizeof(unsigned int));
    } else
    {   /* No cache available -- just reset index pointer to get fastest cache validation failure */
        dst->fnpc_indx = -1;
    }
}
Ejemplo n.º 24
0
unsigned char *n2s(mval *mv_ptr)
{
	unsigned char	*start, *cp, *cp1;
	int4		exp, n0, m1, m0, tmp;
	unsigned char	lcl_buf[MAX_DIGITS_IN_INT];

	if (!MV_DEFINED(mv_ptr))
	{
		underr(mv_ptr);
		return NULL;
	}
	start = stringpool.free;
	if (start + MAX_NUM_SIZE > stringpool.top)
	{
		stp_gcol(MAX_NUM_SIZE);
		start = stringpool.free;
	}
	cp = start;
	m1 = mv_ptr->m[1];
	if (m1 == 0)	/* SHOULD THIS BE UNDER THE MV_INT TEST? */
		*cp++ = '0';
	else  if (mv_ptr->mvtype & MV_INT)
	{
		if (m1 < 0)
		{
			*cp++ = '-';
			m1 = -m1;
		}
		cp1 = lcl_buf + sizeof(lcl_buf);
		/* m0 is the integer part */
		m0 = m1 / MV_BIAS;
		/* m1 will become the fractional part */
		m1 = m1 - (m0 * MV_BIAS);
		if (m1 > 0)
		{
			for (n0 = 0;  n0 < MV_BIAS_PWR;  n0++)
			{
				tmp = m1;
				m1 /= 10;
				tmp -= (m1 * 10);
				if (tmp)
					break;
			}
			*--cp1 = tmp + '0';
			for (n0++;  n0 < MV_BIAS_PWR;  n0++)
			{
				tmp = m1;
				m1 /= 10;
				*--cp1 = tmp - (m1 * 10) + '0';
			}
			*--cp1 = '.';
		}
		while (m0 > 0)
		{
			tmp = m0;
			m0 /= 10;
			*--cp1 = tmp - (m0 * 10) + '0';
		}
		n0 = &lcl_buf[sizeof(lcl_buf)] - cp1;
		memcpy(cp, cp1, n0);
		cp += n0;
	} else
	{
		exp = (int4)mv_ptr->e - MV_XBIAS;
		if (mv_ptr->sgn)
			*cp++ = '-';
		m0 = mv_ptr->m[0];
		if (exp < 0)
		{
			*cp++ = '.';
			for (n0 = exp;  n0 < 0;  n0++)
				*cp++ = '0';
		}
		for (;  m1;  m1 = m0, m0 = 0)
		{
			for (n0 = 0;  n0 < PACKED_DIGITS;  n0++)
			{
				if (exp-- == 0)
				{
					if (m0 == 0 && m1 == 0)
						break;
					*cp++ = '.';
				} else  if (exp < 0 && m0 == 0 && m1 == 0)
					break;
				tmp = m1 / MANT_LO;
				m1 = (m1 - tmp * MANT_LO) * 10;
				*cp++ = tmp + '0';
			}
		}
		while (exp-- > 0)
			*cp++ = '0';
	}
	mv_ptr->mvtype |= MV_STR;
	mv_ptr->mvtype &= ~MV_NUM_APPROX;
	mv_ptr->str.addr = (char *)start;
	mv_ptr->str.len = cp - start;
	stringpool.free = cp;
	return cp;
}
Ejemplo n.º 25
0
void op_gvnext(mval *v)
{
	register char		*c;
	bool			found;
 	int4			n;
	enum db_acc_method 	acc_meth;

	acc_meth = gv_cur_region->dyn.addr->acc_meth;
	/* if the lowest subscript is -1, then make it null */
	if ( 	(gv_currkey->end == gv_currkey->prev + 4) &&
		*(&gv_currkey->base[0] + gv_currkey->prev) == 0x40 &&
		*(&gv_currkey->base[0] + gv_currkey->prev + 1) == 0xEE &&
		*(&gv_currkey->base[0] + gv_currkey->prev + 2) == 0xFF)

	{	*(&gv_currkey->base[0] + gv_currkey->prev) = 01;
		*(char *)(&gv_currkey->base[0] + gv_currkey->prev + 1) = 0;
		*(char *)(&gv_currkey->base[0] + gv_currkey->prev + 2) = 0;
		gv_currkey->end -= 2;
	}
	else
	{	if (gv_curr_subsc_null)
		{	*(&gv_currkey->base[0] + gv_currkey->prev) = 01;
		}
		else
		{	*(&gv_currkey->base[0] + gv_currkey->end - 1) = 1;
			*(&gv_currkey->base[0] + gv_currkey->end + 1) = 0;
			gv_currkey->end++;
		}
	}
	if (acc_meth == dba_bg || acc_meth == dba_mm)
	{
		if (gv_target->root)
		{	found = gvcst_order();
		}else
			found = FALSE;		/* global does not exist */
	}else if (acc_meth == dba_cm)
	{	found = gvcmx_order();
	}else
	{	found = gvusr_order();
	}

	v->mvtype = MV_STR;
	if (!found)
	{
		if (stringpool.top - stringpool.free < 2)
			stp_gcol(2);
		c = v->str.addr = (char *) stringpool.free;
		*c++ = '-';
		*c = '1';
	 	v->str.len = 2;
 		stringpool.free += 2;
	}
	else
	{
		gv_altkey->prev = gv_currkey->prev;

 		if (stringpool.top - stringpool.free < MAX_SUBSC_LEN)
		{	if (*(&gv_altkey->base[0] + gv_altkey->prev) != 0xFF)
			{	n = MAX_NUM_SLEN;
			}
			else
			{ 	n = gv_altkey->top - gv_altkey->prev;
				assert (n > 0);
			}
			if (stringpool.top - stringpool.free < n)
			{	stp_gcol (n);
			}
		}
		v->str.addr = (char *) stringpool.free;
		c = (char *)(&gv_altkey->base[0] + gv_altkey->prev);
		stringpool.free = gvsub2str ((uchar_ptr_t)c,stringpool.free, FALSE);
		v->str.len = stringpool.free - (unsigned char *) v->str.addr;
		assert (v->str.addr < (char *) stringpool.top && v->str.addr >= (char *) stringpool.base);
		assert (v->str.addr + v->str.len <= (char *) stringpool.top &&
			v->str.addr + v->str.len >= (char *) stringpool.base);
	}
	return;
}
Ejemplo n.º 26
0
int
omi_prc_def(omi_conn *cptr, char *xend, char *buff, char *bend)
{
    GBLREF bool	 undef_inhibit;

    char	*bptr;
    omi_li	 len;
    int		 rv;
    mval	 vo, vd, vg;

    bptr = buff;

/*  Global Ref */
    OMI_LI_READ(&len, cptr->xptr);
/*  Set up a condition handler */
    ESTABLISH_RET(omi_dbms_ch,0);
    rv = omi_gvextnam(cptr, len.value, cptr->xptr);
/*  If true, there was an error finding the global reference in the DBMS */
    if (rv < 0)
    {
	REVERT;
	return rv;
    }
    cptr->xptr += len.value;

/*  Bounds checking */
    if (cptr->xptr > xend)
    {
	REVERT;
	return -OMI_ER_PR_INVMSGFMT;
    }

/*  We want to make sure there is plenty of space in the string pool
 *  for all three operations ($ORDER, $GET, $DATA) */
    if (cptr->exts & OMI_XTF_NEWOP)
	stp_gcol(0);

/*  $DATA */
    op_gvdata(&vd);
    if (!(vd.mvtype & MV_INT))
    {
	REVERT;
	return -OMI_ER_DB_UNRECOVER;
    }

    if (cptr->exts & OMI_XTF_NEWOP)
    {
/*	$GET */
	undef_inhibit = TRUE;
	rv = op_gvget(&vg);
/*	$ORDER */
	op_gvorder(&vo);
	OMI_SI_WRIT(vo.str.len, bptr);
	if (vo.str.len)
	{
	    memcpy(bptr, vo.str.addr, vo.str.len);
	    bptr += vo.str.len;
	}
    }

/*  $DATA (buffer write) */
    OMI_SI_WRIT(vd.m[1] / MV_BIAS, bptr);

    if (cptr->exts & OMI_XTF_NEWOP)
    {
/*	$GET (buffer write) */
	OMI_SI_WRIT((rv ? 1 : 0), bptr);
	if (!rv || !vg.str.len)
	    OMI_LI_WRIT(0, bptr);
	else
	{
	    OMI_LI_WRIT(vg.str.len, bptr);
	    memcpy(bptr, vg.str.addr, vg.str.len);
	    bptr += vg.str.len;
	}
    }

    REVERT;

    return (int)(bptr - buff);

}
Ejemplo n.º 27
0
void dir_srch (parse_blk *pfil)
{
	struct stat	statbuf;
	int		stat_res;
	lv_val		*dir1, *dir2, *tmp;
	mstr		tn;
	short		p2_len;
	char		filb[MAX_FBUFF + 1], patb[sizeof(ptstr)], *c, *lastd, *top, *p2, *c1, ch;
	mval		pat_mval, sub, compare;
	bool		wildname, seen_wd;
	struct dirent 	*dent;
	DIR		*dp;
	plength		*plen;
	int		closedir_res;

	op_kill(zsrch_dir1);
	op_kill(zsrch_dir2);

	if (!pfil->b_name)
		return;		/* nothing to search for */

	ESTABLISH(dir_ch);
	pat_mval.mvtype = MV_STR;
	pat_mval.str.addr = patb;	/* patb should be sizeof(ptstr.buff) but instead is sizeof(ptstr) since the C compiler
					 * complains about the former and the latter is just 4 bytes more */
	pat_mval.str.len = 0;
	sub.mvtype = MV_STR;
	sub.str.len = 0;
	compare.mvtype = MV_STR;
	compare.str.len = 0;
	wildname = (pfil->fnb & F_WILD_NAME) != 0;
	dir1 = zsrch_dir1;
	dir2 = zsrch_dir2;

	if (pfil->fnb & F_WILD_DIR)
	{
		seen_wd = FALSE;
		for (c = pfil->l_dir, lastd = c, top = c + pfil->b_dir; c < top;)
		{
			ch = *c++;
			if (ch == '/')	/* note the start of each directory segment */
			{
				if (seen_wd)
					break;
				lastd = c;
			}
			if (ch == '?' || ch == '*')
				seen_wd = TRUE;
		}
		assert(c <= top);
		sub.str.addr = pfil->l_dir;
		sub.str.len = lastd - sub.str.addr;
		tmp = op_putindx(VARLSTCNT(2) dir1, &sub);
		tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
		for(;;)
		{
			tn.addr = lastd;	/* wildcard segment */
			tn.len = c - lastd - 1;
			lastd = c;
			genpat(&tn, &pat_mval);
			seen_wd = FALSE;
			p2 = c - 1;
			for (; c < top;)
			{
				ch = *c++;
				if (ch == '/')	/* note the start of each directory segment */
				{
					if (seen_wd)
						break;
					lastd = c;
				}
				if (ch == '?' || ch == '*')
					seen_wd = TRUE;
			}
			p2_len = lastd - p2;	/* length of non-wild segment after wild section */
			for (;;)
			{
				pop_top(dir1, &sub);	/* get next item off the top */
				if (!sub.str.len)
					break;

				memcpy(filb, sub.str.addr, sub.str.len);
				filb[sub.str.len] = 0;
				sub.str.addr = filb;
				dp = OPENDIR(filb);
				if (!dp)
					continue;
				while(READDIR(dp, dent))
				{
					compare.str.addr = &dent->d_name[0];
					compare.str.len = strlen(&dent->d_name[0]);
					assert(compare.str.len);
					if (   dent->d_name[0] == '.'
					    && (compare.str.len == 1  ||  (compare.str.len == 2  &&  dent->d_name[1] == '.'))   )
					{
						continue;	/* don't want to read . and .. */
					}

					if (compare.str.len + sub.str.len + p2_len > MAX_FBUFF)
						continue;

					if (do_pattern(&compare, &pat_mval))
					{	/* got a hit */
						if (stringpool.free + compare.str.len + sub.str.len + p2_len + 1 > stringpool.top)
							stp_gcol(compare.str.len + sub.str.len + p2_len + 1);

						/* concatenate directory and name */
						c1 = (char *)stringpool.free;
						tn = sub.str;
						s2pool(&tn);
						tn = compare.str;
						s2pool(&tn);
						tn.addr = p2;
						tn.len = p2_len;
						s2pool(&tn);
						*stringpool.free++ = 0;
						compare.str.addr = c1;
						compare.str.len += sub.str.len + p2_len;
						STAT_FILE(compare.str.addr, &statbuf, stat_res);
						if (-1 == stat_res)
							continue;
						if (!(statbuf.st_mode & S_IFDIR))
							continue;
						/* put in results tree */
						tmp = op_putindx(VARLSTCNT(2) dir2, &compare);
						tmp->v.mvtype = MV_STR;
						tmp->v.str.len = 0;
					}
				}
				CLOSEDIR(dp, closedir_res);
			}
			tmp = dir1; dir1 = dir2; dir2 = tmp;
			if (c >= top)
				break;
		}
	} else
	{
		sub.str.addr = pfil->l_dir;
		sub.str.len = pfil->b_dir;
		tmp = op_putindx(VARLSTCNT(2) dir1, &sub);
		tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
	}

	if (wildname)
	{
		tn.addr = pfil->l_name;
		tn.len = pfil->b_name + pfil->b_ext;
		genpat(&tn, &pat_mval);
	}

	for (;;)
	{
		pop_top(dir1, &sub);	/* get next item off the top */
		if (!sub.str.len)
			break;

		if (wildname)
		{
			memcpy(filb, sub.str.addr, sub.str.len);
			filb[sub.str.len] = 0;
			sub.str.addr = filb;
			dp = OPENDIR(filb);
			if (!dp)
				continue;
			while(READDIR(dp, dent))
			{
				compare.str.addr = &dent->d_name[0];
				compare.str.len = strlen(&dent->d_name[0]);
				if (   dent->d_name[0] == '.'
				    && (compare.str.len == 1  ||  (compare.str.len == 2  &&  dent->d_name[1] == '.')))
				{
					continue;	/* don't want to read . and .. */
				}
				if (compare.str.len + sub.str.len > MAX_FBUFF)
					continue;

				if (do_pattern(&compare, &pat_mval))
				{	/* got a hit */
					if (stringpool.free + compare.str.len + sub.str.len > stringpool.top)
						stp_gcol(compare.str.len + sub.str.len);

					/* concatenate directory and name */
					c = (char *)stringpool.free;
					tn = sub.str;
					s2pool(&tn);
					tn = compare.str;
					s2pool(&tn);
					compare.str.addr = c;
					compare.str.len += sub.str.len;

					/* put in results tree */
					tmp = op_putindx(VARLSTCNT(2) ind_var, &compare);
					tmp->v.mvtype = MV_STR;
					tmp->v.str.len = 0;
					plen = (plength *)&tmp->v.m[1];
					plen->p.pblk.b_esl = compare.str.len;
					plen->p.pblk.b_dir = sub.str.len;
					for (c = &compare.str.addr[sub.str.len], c1 = top = &compare.str.addr[compare.str.len];
					     c < top;
					    )
					{
						if (*c++ != '.')
							break;
					}
					for (; c < top;)
					{
						if (*c++ == '.')
							c1 = c - 1;
					}
					plen->p.pblk.b_ext = top - c1;
					plen->p.pblk.b_name = plen->p.pblk.b_esl - plen->p.pblk.b_dir - plen->p.pblk.b_ext;
				}
			}
			CLOSEDIR(dp, closedir_res);
		} else
		{
			assert(pfil->fnb & F_WILD_DIR);
			compare.str.addr = pfil->l_name;
			compare.str.len = pfil->b_name + pfil->b_ext;

			if (compare.str.len + sub.str.len > MAX_FBUFF)
				continue;

			memcpy(filb, sub.str.addr, sub.str.len);
			filb[sub.str.len] = 0;
			sub.str.addr = filb;

			if (stringpool.free + compare.str.len + sub.str.len > stringpool.top)
				stp_gcol(compare.str.len + sub.str.len);

			/* concatenate directory and name */
			c1 = (char *)stringpool.free;
			tn = sub.str;
			s2pool(&tn);
			tn = compare.str;
			s2pool(&tn);
			compare.str.addr = c1;
			compare.str.len += sub.str.len;

			/* put in results tree */
			tmp = op_putindx(VARLSTCNT(2) ind_var, &compare);
			tmp->v.mvtype = MV_STR; tmp->v.str.len = 0;
			plen = (plength *)&tmp->v.m[1];
			plen->p.pblk.b_esl = compare.str.len;
			plen->p.pblk.b_dir = sub.str.len;
			plen->p.pblk.b_name = pfil->b_name;
			plen->p.pblk.b_ext = pfil->b_ext;
		}
	}
	op_kill(zsrch_dir1);
	op_kill(zsrch_dir2);
	REVERT;
}
Ejemplo n.º 28
0
short	iorm_read (mval *v, int4 timeout) /* timeout in seconds */
{
	boolean_t	ret, timed;
	int4		msec_timeout;	/* timeout in milliseconds */
	uint4		width;
	char		inchar, *temp;
	int		flags;
	int		fcntl_res;
	int4		i;
	io_desc		*io_ptr;
	d_rm_struct	*rm_ptr;
	int4		status;
	TID		timer_id;

	error_def(ERR_IOEOF);

	assert(stringpool.free >= stringpool.base);
	assert(stringpool.free <= stringpool.top);

	io_ptr = io_curr_device.in;
	assert (io_ptr->state == dev_open);
	rm_ptr = (d_rm_struct*) (io_ptr->dev_sp);
	if (io_ptr->dollar.x  &&  rm_ptr->lastop == RM_WRITE)
	{
		if (!io_ptr->dollar.za)
			iorm_wteol(1, io_ptr);
		io_ptr->dollar.x = 0;
	}

	rm_ptr->lastop = RM_READ;
	timer_id = (TID) iorm_read;
	width = io_ptr->width;
	if (stringpool.free + width > stringpool.top)
		stp_gcol (width);
	i = 0;
	ret = TRUE;
	temp = (char*) stringpool.free;
	out_of_time = FALSE;
	if (timeout == NO_M_TIMEOUT)
	{
		timed = FALSE;
		msec_timeout = NO_M_TIMEOUT;
	}
	else
	{
		timed = TRUE;
		msec_timeout = timeout2msec(timeout);
		if (msec_timeout > 0)
		{
			start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL);
		}
		else
		{
			out_of_time = TRUE;
			FCNTL2(rm_ptr->fildes, F_GETFL, flags);
                        FCNTL3(rm_ptr->fildes, F_SETFL, (flags | O_NDELAY), fcntl_res);
		}
	}
	errno = 0;
	if (rm_ptr->fixed)
	{
		/*
		 * the check for EINTR below is valid and should not be converted to an EINTR
		 * wrapper macro, since it might be a timeout.
		 */
		DOREADRLTO(rm_ptr->fildes, temp, width, out_of_time, status);
		if (0 > status)
		{
			i = 0;
			if (errno == EINTR  &&  out_of_time)
				status = -2;
		}
		else
			i = status;
	}
	else
	{
		do
		{
			if ((status = getc (rm_ptr->filstr)) != EOF)
			{
				inchar = (unsigned char) status;
				if (inchar == NATIVE_NL)
					break;
				*temp++ = inchar;
				i++;
			}
			else
			{
				inchar = 0;
				if (errno == 0)
					status = 0;
				else if (errno == EINTR)
				{
					if (out_of_time)
						status = -2;
				        else
						continue;	/* Ignore interruption if wasn't our timeout */
				}
				break;
			}
		} while (i < width);
	}
	if (status == EOF  &&  errno != EINTR)
	{
		io_ptr->dollar.za = 9;
		v->str.len = 0;
		if ((timed) && (!out_of_time))
			cancel_timer(timer_id);
		rts_error(VARLSTCNT(1) errno);
	}

	if (timed)
	{
		if (msec_timeout == 0)
		{
			FCNTL3(rm_ptr->fildes, F_SETFL, flags, fcntl_res);
			if (rm_ptr->fifo && status == 0)
				ret = FALSE;
		}
		else
		{
			if (out_of_time)
				ret = FALSE;
			else
				cancel_timer(timer_id);
		}
	}

	if (status == 0  &&  i == 0  &&  !rm_ptr->fifo)
	{
		v->str.len = 0;
		if (io_ptr->dollar.zeof == TRUE)
		{
			io_ptr->dollar.za = 9;
			rts_error(VARLSTCNT(1) ERR_IOEOF);
		}
		io_ptr->dollar.zeof = TRUE;
		io_ptr->dollar.x = 0;
		io_ptr->dollar.za = 0;
		io_ptr->dollar.y++;
		if (io_ptr->error_handler.len > 0)
		{	rts_error(VARLSTCNT(1) ERR_IOEOF);
		}
	}
	else
	{
		v->str.len = i;
		v->str.addr = (char *) stringpool.free;
		if (!rm_ptr->fixed && inchar == NATIVE_NL)
		{
		    	io_ptr->dollar.x = 0;
			io_ptr->dollar.y++;
		}
		else
			if ((io_ptr->dollar.x += i) >= io_ptr->width && io_ptr->wrap)
			{
				io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width);
				if(io_ptr->length)
					io_ptr->dollar.y %= io_ptr->length;
				io_ptr->dollar.x %= io_ptr->width;
			}
	}
	io_ptr->dollar.za = 0;
	return((short) ret);
}