Esempio n. 1
0
void op_svput(int varnum, mval *v)
{
	int	i, ok, state;
	char	*vptr;
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	switch (varnum)
	{
		case SV_X:
			MV_FORCE_NUM(v);
			io_curr_device.out->dollar.x = (short)MV_FORCE_INT(v);
			if ((short)(io_curr_device.out->dollar.x) < 0)
				io_curr_device.out->dollar.x = 0;
			break;
		case SV_Y:
			MV_FORCE_NUM(v);
			io_curr_device.out->dollar.y = (short)MV_FORCE_INT(v);
			if ((short)(io_curr_device.out->dollar.y) < 0)
				io_curr_device.out->dollar.y = 0;
			break;
		case SV_ZCOMPILE:
			MV_FORCE_STR(v);
			if ((TREF(dollar_zcompile)).addr)
				free ((TREF(dollar_zcompile)).addr);
			(TREF(dollar_zcompile)).addr = (char *)malloc(v->str.len);
			memcpy((TREF(dollar_zcompile)).addr, v->str.addr, v->str.len);
			(TREF(dollar_zcompile)).len = v->str.len;
			break;
		case SV_ZSTEP:
			MV_FORCE_STR(v);
			op_commarg(v,indir_linetail);
			op_unwind();
			dollar_zstep = *v;
			break;
		case SV_ZGBLDIR:
			MV_FORCE_STR(v);
			if ((dollar_zgbldir.str.len != v->str.len)
			    || memcmp(dollar_zgbldir.str.addr, v->str.addr, dollar_zgbldir.str.len))
			{
				if (0 == v->str.len)
				{
					/* set $zgbldir="" */
					dpzgbini();
					gd_header = NULL;
				} else
				{
					gd_header = zgbldir(v);
					/* update the gd_map */
					SET_GD_MAP;
					dollar_zgbldir.str.len = v->str.len;
					dollar_zgbldir.str.addr = v->str.addr;
					s2pool(&dollar_zgbldir.str);
				}
				if (NULL != gv_currkey)
				{
					gv_currkey->base[0] = '\0';
					gv_currkey->prev = gv_currkey->end = 0;
				} else if (NULL != gd_header)
					gvinit();
				if (NULL != gv_target)
					gv_target->clue.end = 0;
			}
			break;
		case SV_ZMAXTPTIME:
			dollar_zmaxtptime = mval2i(v);
			break;
		case SV_ZROUTINES:
			MV_FORCE_STR(v);
			/* The string(v) should be parsed and loaded before setting $zroutines
			 * to retain the old value in case errors occur while loading */
			zro_load(&v->str);
			if ((TREF(dollar_zroutines)).addr)
				free ((TREF(dollar_zroutines)).addr);
			(TREF(dollar_zroutines)).addr = (char *)malloc(v->str.len);
			memcpy((TREF(dollar_zroutines)).addr, v->str.addr, v->str.len);
			(TREF(dollar_zroutines)).len = v->str.len;
			break;
		case SV_ZSOURCE:
			MV_FORCE_STR(v);
			dollar_zsource.mvtype = MV_STR;
			dollar_zsource.str = v->str;
			break;
		case SV_ZTRAP:
#			ifdef GTM_TRIGGER
			if (0 < gtm_trigger_depth)
				rts_error(VARLSTCNT(1) ERR_NOZTRAPINTRIG);
#			endif
			MV_FORCE_STR(v);
			if (ztrap_new)
				op_newintrinsic(SV_ZTRAP);
			dollar_ztrap.mvtype = MV_STR;
			dollar_ztrap.str = v->str;
			/* Setting either $ZTRAP or $ETRAP to empty causes any current error trapping to be canceled */
			if (!v->str.len)
			{
				dollar_etrap.mvtype = MV_STR;
				dollar_etrap.str = v->str;
				ztrap_explicit_null = TRUE;
			} else /* Ensure that $ETRAP and $ZTRAP are not both active at the same time */
			{
				ztrap_explicit_null = FALSE;
				if (dollar_etrap.str.len > 0)
					gtm_newintrinsic(&dollar_etrap);
			}
			if (ztrap_form & ZTRAP_POP)
				ztrap_save_ctxt();
			if (tp_timeout_deferred && !dollar_zininterrupt)
				/* A tp timeout was deferred. Now that $ETRAP is no longer in effect and no job interrupt is in
				 * effect, the timeout need no longer be deferred and can be recognized.
				 */
				tptimeout_set(0);
			break;
		case SV_ZSTATUS:
			MV_FORCE_STR(v);
			dollar_zstatus.mvtype = MV_STR;
			dollar_zstatus.str = v->str;
			break;
		case SV_PROMPT:
			MV_FORCE_STR(v);
			MV_FORCE_LEN_STRICT(v); /* Ensure that direct mode prompt will not have BADCHARs,
						 * otherwise the BADCHAR error may fill up the filesystem
						 */
			if (v->str.len <= SIZEOF_prombuf)
				(TREF(gtmprompt)).len = v->str.len;
			else if (!gtm_utf8_mode)
				(TREF(gtmprompt)).len = SIZEOF_prombuf;
#			ifdef UNICODE_SUPPORTED
			else
			{
				UTF8_LEADING_BYTE(v->str.addr + SIZEOF_prombuf, v->str.addr, vptr);
				(TREF(gtmprompt)).len = INTCAST(vptr - v->str.addr);
			}
#			endif
			memcpy((TREF(gtmprompt)).addr, v->str.addr, (TREF(gtmprompt)).len);
			break;
		case SV_ECODE:
			MV_FORCE_STR(v);
			if (v->str.len)
			{
				/* Format must be like ,Mnnn,Mnnn,Zxxx,Uxxx,
				 * Mnnn are ANSI standard error codes
				 * Zxxx are implementation-specific codes
				 * Uxxx are end-user defined codes
				 * Note that there must be commas at the start and at the end
				 */
				for (state = 2, i = 0; (i < v->str.len) && (state <= 2); i++)
				{
					switch(state)
					{
						case 2: state = (v->str.addr[i] == ',') ? 1 : 101;
							break;
						case 1: state = ((v->str.addr[i] == 'M') ||
								 (v->str.addr[i] == 'U') ||
								 (v->str.addr[i] == 'Z')) ? 0 : 101;
							break;
						case 0: state = (v->str.addr[i] == ',') ? 1 : 0;
							break;
					}
				}
				/* The above check would pass strings like ","
				 * so double-check that there are at least three characters
				 * (starting comma, ending comma, and something in between)
				 */
				if ((state != 1) || (v->str.len < 3))
				{
					/* error, ecode = M101 */
					rts_error(VARLSTCNT(4) ERR_INVECODEVAL, 2, v->str.len, v->str.addr);
				}
			}
			if (v->str.len > 0)
			{
				ecode_add(&v->str);
				rts_error(VARLSTCNT(2) ERR_SETECODE, 0);
			} else
			{
				NULLIFY_DOLLAR_ECODE;	/* reset $ECODE related variables to correspond to $ECODE = NULL state */
				NULLIFY_ERROR_FRAME;	/* we are no more in error-handling mode */
				if (tp_timeout_deferred && !dollar_zininterrupt)
					/* A tp timeout was deferred. Now that we are clear of error handling and no job interrupt
					 * is in process, allow the timeout to be recognized.
					 */
					tptimeout_set(0);
			}
			break;
		case SV_ETRAP:
			MV_FORCE_STR(v);
			dollar_etrap.mvtype = MV_STR;
			dollar_etrap.str = v->str;
			/* Setting either $ZTRAP or $ETRAP to empty causes any current error trapping to be canceled */
			if (!v->str.len)
			{
				dollar_ztrap.mvtype = MV_STR;
				dollar_ztrap.str = v->str;
			} else if (dollar_ztrap.str.len > 0)
			{	/* Ensure that $ETRAP and $ZTRAP are not both active at the same time */
				assert(FALSE == ztrap_explicit_null);
				gtm_newintrinsic(&dollar_ztrap);
			}
			ztrap_explicit_null = FALSE;
			break;
		case SV_ZERROR:
			MV_FORCE_STR(v);
			dollar_zerror.mvtype = MV_STR;
			dollar_zerror.str = v->str;
			break;
		case SV_ZYERROR:
			MV_FORCE_STR(v);
			dollar_zyerror.mvtype = MV_STR;
			dollar_zyerror.str = v->str;
			break;
		case SV_SYSTEM:
			assert(FALSE);
			rts_error(VARLSTCNT(4) ERR_SYSTEMVALUE, 2, v->str.len, v->str.addr);
			break;
		case SV_ZDIR:
			setzdir(v, NULL); 	/* change directory to v */
			getzdir(); 		/* update dollar_zdir with current working directory */
			break;
		case SV_ZINTERRUPT:
			MV_FORCE_STR(v);
			dollar_zinterrupt.mvtype = MV_STR;
			dollar_zinterrupt.str = v->str;
			break;
		case SV_ZDATE_FORM:
			MV_FORCE_NUM(v);
			TREF(zdate_form) = (short)MV_FORCE_INT(v);
			break;
		case SV_ZTEXIT:
			MV_FORCE_STR(v);
			dollar_ztexit.mvtype = MV_STR;
			dollar_ztexit.str = v->str;
			/* Coercing $ZTEXIT to boolean at SET command is more efficient than coercing before each
			 * rethrow at TR/TRO. Since we want to maintain dollar_ztexit as a string, coercion should
			 * not be performed on dollar_ztext, but on a temporary (i.e. parameter v)
			 */
			dollar_ztexit_bool = MV_FORCE_BOOL(v);
			break;
		case SV_ZQUIT:
			dollar_zquit_anyway = MV_FORCE_BOOL(v);
			break;
		case SV_ZTVALUE:
#			ifdef GTM_TRIGGER
			assert(!dollar_tlevel || (tstart_trigger_depth <= gtm_trigger_depth));
			if (!dollar_tlevel || (tstart_trigger_depth == gtm_trigger_depth))
				rts_error(VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
			if (dollar_ztriggerop != &gvtr_cmd_mval[GVTR_CMDTYPE_SET])
				rts_error(VARLSTCNT(4) ERR_SETINSETTRIGONLY, 2, RTS_ERROR_TEXT("$ZTVALUE"));
			assert(0 < gtm_trigger_depth);
			memcpy(dollar_ztvalue, v, SIZEOF(mval));
			dollar_ztvalue->mvtype &= ~MV_ALIASCONT;	/* Make sure to shut off alias container flag on copy */
			assert(NULL != ztvalue_changed_ptr);
			*ztvalue_changed_ptr = TRUE;
			break;
#			else
			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTWORMHOLE:
#			ifdef GTM_TRIGGER
			MV_FORCE_STR(v);
			/* See jnl.h for why MAX_ZTWORMHOLE_SIZE should be less than minimum alignsize */
			assert(MAX_ZTWORMHOLE_SIZE < (JNL_MIN_ALIGNSIZE * DISK_BLOCK_SIZE));
			if (MAX_ZTWORMHOLE_SIZE < v->str.len)
				rts_error(VARLSTCNT(4) ERR_ZTWORMHOLE2BIG, 2, v->str.len, MAX_ZTWORMHOLE_SIZE);
			dollar_ztwormhole.mvtype = MV_STR;
			dollar_ztwormhole.str = v->str;
			break;
#			else
			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTSLATE:
#			ifdef GTM_TRIGGER
			assert(!dollar_tlevel || (tstart_trigger_depth <= gtm_trigger_depth));
			if (!dollar_tlevel || (tstart_trigger_depth == gtm_trigger_depth))
				rts_error(VARLSTCNT(4) ERR_SETINTRIGONLY, 2, RTS_ERROR_TEXT("$ZTSLATE"));
			assert(0 < gtm_trigger_depth);
			MV_FORCE_DEFINED(v);
			memcpy((char *)&dollar_ztslate, v, SIZEOF(mval));
			dollar_ztslate.mvtype &= ~MV_ALIASCONT;	/* Make sure to shut off alias container flag on copy */
			break;
#			else
			rts_error(VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		default:
			GTMASSERT;
	}
	return;
}
Esempio n. 2
0
void op_svput(int varnum, mval *v)
{
    int		i, ok, state;
    error_def(ERR_UNIMPLOP);
    error_def(ERR_TEXT);
    error_def(ERR_INVECODEVAL);
    error_def(ERR_SETECODE);
    error_def(ERR_SYSTEMVALUE);

    switch (varnum)
    {
    case SV_X:
        MV_FORCE_NUM(v);
        io_curr_device.out->dollar.x = (short)MV_FORCE_INT(v);
        if ((short)(io_curr_device.out->dollar.x) < 0)
            io_curr_device.out->dollar.x = 0;
        break;
    case SV_Y:
        MV_FORCE_NUM(v);
        io_curr_device.out->dollar.y = (short)MV_FORCE_INT(v);
        if ((short)(io_curr_device.out->dollar.y) < 0)
            io_curr_device.out->dollar.y = 0;
        break;
    case SV_ZCOMPILE:
        MV_FORCE_STR(v);
        if (dollar_zcompile.addr)
            free (dollar_zcompile.addr);
        dollar_zcompile.addr = (char *)malloc(v->str.len);
        memcpy (dollar_zcompile.addr, v->str.addr, v->str.len);
        dollar_zcompile.len = v->str.len;
        break;
    case SV_ZSTEP:
        MV_FORCE_STR(v);
        op_commarg(v,indir_linetail);
        op_unwind();
        dollar_zstep = *v;
        break;
    case SV_ZGBLDIR:
        MV_FORCE_STR(v);
        if (!(dollar_zgbldir.str.len == v->str.len &&
                !memcmp(dollar_zgbldir.str.addr, v->str.addr,
                        dollar_zgbldir.str.len)))
        {
            if(v->str.len == 0)
            {
                /* set $zgbldir="" */
                dpzgbini();
                gd_header = NULL;
            } else
            {
                gd_header = zgbldir(v);
                dollar_zgbldir.str.len = v->str.len;
                dollar_zgbldir.str.addr = v->str.addr;
                s2pool(&dollar_zgbldir.str);
            }
            if (gv_currkey)
                gv_currkey->base[0] = 0;
            if (gv_target)
                gv_target->clue.end = 0;
        }
        break;
    case SV_ZMAXTPTIME:
        dollar_zmaxtptime = mval2i(v);
        break;
    case SV_ZROUTINES:
        MV_FORCE_STR(v);
        /* The string(v) should be parsed and loaded before setting $zroutines
         * to retain the old value in case errors occur while loading */
        zro_load(&v->str);
        if (dollar_zroutines.addr)
            free (dollar_zroutines.addr);
        dollar_zroutines.addr = (char *)malloc(v->str.len);
        memcpy (dollar_zroutines.addr, v->str.addr, v->str.len);
        dollar_zroutines.len = v->str.len;
        break;
    case SV_ZSOURCE:
        MV_FORCE_STR(v);
        dollar_zsource = v->str;
        break;
    case SV_ZTRAP:
        MV_FORCE_STR(v);
        if (ztrap_new)
            op_newintrinsic(SV_ZTRAP);
        dollar_ztrap.mvtype = MV_STR;
        dollar_ztrap.str = v->str;
        /* Setting either $ZTRAP or $ETRAP to empty causes any current error trapping to be canceled */
        if (!v->str.len)
        {
            dollar_etrap.mvtype = MV_STR;
            dollar_etrap.str = v->str;
            ztrap_explicit_null = TRUE;
        } else /* Ensure that $ETRAP and $ZTRAP are not both active at the same time */
        {
            ztrap_explicit_null = FALSE;
            if (dollar_etrap.str.len > 0)
                gtm_newintrinsic(&dollar_etrap);
        }
        if (ztrap_form & ZTRAP_POP)
            ztrap_save_ctxt();
        break;
    case SV_ZSTATUS:
        MV_FORCE_STR(v);
        dollar_zstatus.mvtype = MV_STR;
        dollar_zstatus.str = v->str;
        break;
    case SV_PROMPT:
        MV_FORCE_STR(v);
        gtmprompt.len = v->str.len < sizeof(prombuf) ? v->str.len : sizeof(prombuf);
        memcpy(gtmprompt.addr,v->str.addr,gtmprompt.len);
        break;
    case SV_ECODE:
        MV_FORCE_STR(v);
        if (v->str.len)
        {
            /* Format must be like ,Mnnn,Mnnn,Zxxx,Uxxx,
             * Mnnn are ANSI standard error codes
             * Zxxx are implementation-specific codes
             * Uxxx are end-user defined codes
             * Note that there must be commas at the start and at the end
             */
            for (state = 2, i = 0; (i < v->str.len) && (state <= 2); i++)
            {
                switch(state)
                {
                case 2:
                    state = (v->str.addr[i] == ',') ? 1 : 101;
                    break;
                case 1:
                    state = ((v->str.addr[i] == 'M') ||
                             (v->str.addr[i] == 'U') ||
                             (v->str.addr[i] == 'Z')) ? 0 : 101;
                    break;
                case 0:
                    state = (v->str.addr[i] == ',') ? 1 : 0;
                    break;
                }
            }
            /* The above check would pass strings like ","
             * so double-check that there are at least three characters
             * (starting comma, ending comma, and something in between)
             */
            if ((state != 1) || (v->str.len < 3))
            {
                /* error, ecode = M101 */
                rts_error(VARLSTCNT(4) ERR_INVECODEVAL, 2, v->str.len, v->str.addr);
            }
        }
        if (v->str.len > 0)
        {
            ecode_add(&v->str);
            rts_error(VARLSTCNT(2) ERR_SETECODE, 0);
        } else
        {
            NULLIFY_DOLLAR_ECODE;	/* reset $ECODE related variables to correspond to $ECODE = NULL state */
            NULLIFY_ERROR_FRAME;	/* we are no more in error-handling mode */
        }
        break;
    case SV_ETRAP:
        MV_FORCE_STR(v);
        dollar_etrap.mvtype = MV_STR;
        dollar_etrap.str = v->str;
        /* Setting either $ZTRAP or $ETRAP to empty causes any current error trapping to be canceled */
        if (!v->str.len)
        {
            dollar_ztrap.mvtype = MV_STR;
            dollar_ztrap.str = v->str;
        } else if (dollar_ztrap.str.len > 0)
        {   /* Ensure that $ETRAP and $ZTRAP are not both active at the same time */
            assert(FALSE == ztrap_explicit_null);
            gtm_newintrinsic(&dollar_ztrap);
        }
        ztrap_explicit_null = FALSE;
        break;
    case SV_ZERROR:
        MV_FORCE_STR(v);
        dollar_zerror.mvtype = MV_STR;
        dollar_zerror.str = v->str;
        break;
    case SV_ZYERROR:
        MV_FORCE_STR(v);
        dollar_zyerror.mvtype = MV_STR;
        dollar_zyerror.str = v->str;
        break;
    case SV_SYSTEM:
        ok = 1;
        if (!(v->mvtype & MV_STR))
            ok = 0;
        if (ok && v->str.addr[0] != '4')
            ok = 0;
        if (ok && v->str.addr[1] != '7')
            ok = 0;
        if ((' ' != v->str.addr[2]) && !ispunct(v->str.addr[2]))
            ok = 0;
        if (ok)
            dollar_system.str = v->str;
        else
            rts_error(VARLSTCNT(4) ERR_SYSTEMVALUE, 2, v->str.len, v->str.addr);
        break;
    case SV_ZDIR:
        setzdir(v, NULL); /* change directory to v */
        getzdir(); /* update dollar_zdir with current working directory */
        break;
    case SV_ZINTERRUPT:
        MV_FORCE_STR(v);
        dollar_zinterrupt.mvtype = MV_STR;
        dollar_zinterrupt.str = v->str;
        break;
    case SV_ZDATE_FORM:
        MV_FORCE_NUM(v);
        zdate_form = (short)MV_FORCE_INT(v);
        break;
    case SV_ZTEXIT:
        MV_FORCE_STR(v);
        dollar_ztexit.mvtype = MV_STR;
        dollar_ztexit.str = v->str;
        /* Coercing $ZTEXIT to boolean at SET command is more efficient than coercing before each
         * rethrow at TR/TRO. Since we want to maintain dollar_ztexit as a string, coercion should
         * not be performed on dollar_ztext, but on a temporary (i.e. parameter v) */
        dollar_ztexit_bool = MV_FORCE_BOOL(v);
        break;
    default:
        GTMASSERT;
    }
    return;
}
Esempio n. 3
0
void op_svget(int varnum, mval *v)
{
	io_log_name	*tl;
	int 		count;
	gtm_uint64_t	ucount;
	char		*c1, *c2;
	mval		*mvp;
#	ifdef UNIX
	d_rm_struct	*d_rm;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
#	if defined(UNIX) && defined(DEBUG)
	if (gtm_white_box_test_case_enabled && (WBTEST_HUGE_ALLOC == gtm_white_box_test_case_number))
	{
		if (1 == gtm_white_box_test_case_count)
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xffff;
		else if (2 == gtm_white_box_test_case_count)
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff;
		else if (3 == gtm_white_box_test_case_count)
		{
#			ifdef GTM64
			if (8 == SIZEOF(size_t))
				totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta
					= totalUsed = totalUsedGta = 0xfffffffffffffff;
			else
#			endif
				totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed = totalUsedGta = 0xfffffff;
		} else
			totalAlloc = totalAllocGta = totalRmalloc = totalRallocGta = totalUsed
				= totalUsedGta = GTM64_ONLY(SIZEOF(size_t)) NON_GTM64_ONLY(SIZEOF(size_t) > 4 ? 4 : SIZEOF(size_t));
	}
#	endif
	switch (varnum)
	{
		case SV_HOROLOG:
			op_horolog(v);
			break;
		case SV_ZGBLDIR:
			v->mvtype = MV_STR;
			v->str = dollar_zgbldir.str;
			break;
		case SV_PRINCIPAL:
			tl = dollar_principal ? dollar_principal : io_root_log_name->iod->trans_name;
			v->str.addr = tl->dollar_io;
			v->str.len = tl->len;
			/*** The following should be in the I/O code ***/
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			v->mvtype = MV_STR;
			break;
		case SV_ZIO:
			v->mvtype = MV_STR;
			/* NOTE:	This is **NOT** equivalent to :
			 *		io_curr_log_name->dollar_io
			 */
			v->str.addr = io_curr_device.in->trans_name->dollar_io;
			v->str.len = io_curr_device.in->trans_name->len;
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			break;
		case SV_JOB:
			*v = dollar_job;
			break;
		case SV_REFERENCE:
			get_reference(v);
			break;
		case SV_SYSTEM:
			*v = dollar_system;
			break;
		case SV_STORAGE:
			/* double2mval(v, getstorage()); Causes issues with unaligned stack on x86_64 - remove until fixed */
			i2mval(v, getstorage());
			break;
		case SV_TLEVEL:
			count = (int)dollar_tlevel;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_TRESTART:
			MV_FORCE_MVAL(v, (int)((MAX_VISIBLE_TRESTART < dollar_trestart) ? MAX_VISIBLE_TRESTART : dollar_trestart));
			break;
		case SV_X:
			count = (int)io_curr_device.out->dollar.x;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_Y:
			count = (int)io_curr_device.out->dollar.y;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZA:
			count = (int)io_curr_device.in->dollar.za;
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZB:
			c1 = (char *)io_curr_device.in->dollar.zb;
			c2 = c1 + SIZEOF(io_curr_device.in->dollar.zb);
			ENSURE_STP_FREE_SPACE(SIZEOF(io_curr_device.in->dollar.zb));
			v->mvtype = MV_STR;
			v->str.addr = (char *)stringpool.free;
			while (c1 < c2 && *c1)
				*stringpool.free++ = *c1++;
			v->str.len = INTCAST((char *)stringpool.free - v->str.addr);
			break;
		case SV_ZC:	/****THESE ARE DUMMY VALUES ONLY!!!!!!!!!!!!!!!!!****/
			MV_FORCE_MVAL(v, 0);
			break;
		case SV_ZCMDLINE:
			get_command_line(v, TRUE);	/* TRUE to indicate we want $ZCMDLINE
							   (i.e. processed not actual command line) */
			break;
		case SV_ZEOF:
#			ifdef UNIX
			if (rm == io_curr_device.in->type)
			{
				d_rm = (d_rm_struct *)io_curr_device.in->dev_sp;
				if (RM_READ != d_rm->lastop)
				{
					*v = literal_zero;
					break;
				}
			}
#			endif
			*v = io_curr_device.in->dollar.zeof ? literal_one : literal_zero;
			break;
		case SV_ZQUIT:
			*v = dollar_zquit_anyway ? literal_one : literal_zero;
			break;
		case SV_IO:
			v->str.addr = io_curr_device.in->name->dollar_io;
			v->str.len = io_curr_device.in->name->len;
			/*** The following should be in the I/O code ***/
			if (ESC == *v->str.addr)
			{
				if (5 > v->str.len)
					v->str.len = 0;
				else
				{
					v->str.addr += ESC_OFFSET;
					v->str.len -= ESC_OFFSET;
				}
			}
			s2pool(&(v->str));
			v->mvtype = MV_STR;
			break;
		case SV_PROMPT:
			v->mvtype = MV_STR;
			v->str.addr = (TREF(gtmprompt)).addr;
			v->str.len = (TREF(gtmprompt)).len;
			s2pool(&v->str);
			break;
		case SV_ZCOMPILE:
			v->mvtype = MV_STR;
			v->str = TREF(dollar_zcompile);
			s2pool(&(v->str));
			break;
		case SV_ZDIR:
			setzdir(NULL, v);
			if (v->str.len != dollar_zdir.str.len || 0 != memcmp(v->str.addr, dollar_zdir.str.addr, v->str.len))
				gtm_putmsg_csa(CSA_ARG(NULL) VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4, v->str.len, v->str.addr,
					   dollar_zdir.str.len, dollar_zdir.str.addr);
			SKIP_DEVICE_IF_NOT_NEEDED(v);
			s2pool(&(v->str));
			break;
		case SV_ZSTEP:
			*v = dollar_zstep;
			break;
		case SV_ZMODE:
			*v = TREF(dollar_zmode);
			break;
		case SV_ZMAXTPTIME:
			i2mval(v, TREF(dollar_zmaxtptime));
			break;
		case SV_ZPOS:
			getzposition(v);
			break;
		case SV_ZPROC:
			getzprocess();
			*v = dollar_zproc;
			break;
		case SV_ZLEVEL:
			count = dollar_zlevel();
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZROUTINES:
			if (!TREF(zro_root))
				zro_init();
			v->mvtype = MV_STR;
			v->str = TREF(dollar_zroutines);
			s2pool(&(v->str));
			break;
		case SV_ZSOURCE:
			v->mvtype = MV_STR;
			v->str = dollar_zsource.str;
			break;
		case SV_ZSTATUS:
			*v = dollar_zstatus;
			s2pool(&(v->str));
			break;
		case SV_ZTRAP:
			v->mvtype = MV_STR;
			v->str = dollar_ztrap.str;
			assert(!v->str.len || !ztrap_explicit_null);
			s2pool(&(v->str));
			break;
		case SV_DEVICE:
			get_dlr_device(v);
			break;
		case SV_KEY:
			get_dlr_key(v);
			break;
		case SV_ZVERSION:
			v->mvtype = MV_STR;
			v->str.addr = (char *)gtm_release_name;
			v->str.len = gtm_release_name_len;
			break;
		case SV_ZSYSTEM:
			MV_FORCE_MVAL(v, dollar_zsystem);
			break;
		case SV_ZCSTATUS:
			/* Maintain the external $ZCSTATUS == 1 for SUCCESS on UNIX while internal good is 0 */
			MV_FORCE_MVAL(v, UNIX_ONLY((0 == TREF(dollar_zcstatus)) ? 1 : ) TREF(dollar_zcstatus));
			break;
		case SV_ZEDITOR:
			MV_FORCE_MVAL(v, dollar_zeditor);
			break;
		case SV_QUIT:
			MV_FORCE_MVAL(v, dollar_quit());
			break;
		case SV_ECODE:
			ecode_get(-1, v);
			break;
		case SV_ESTACK:
			count = (dollar_zlevel() - 1) - dollar_estack_delta.m[0];
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ETRAP:
			v->mvtype = MV_STR;
			v->str = dollar_etrap.str;
			assert(!v->str.len || !ztrap_explicit_null);
			s2pool(&(v->str));
			break;
		case SV_STACK:
			count = (dollar_zlevel() - 1);
			MV_FORCE_MVAL(v, count);
			break;
		case SV_ZERROR:
			v->mvtype = MV_STR;
			v->str = dollar_zerror.str;
			s2pool(&(v->str));
			break;
		case SV_ZYERROR:
			v->mvtype = MV_STR;
			v->str = dollar_zyerror.str;
			s2pool(&(v->str));
			break;
		case SV_ZINTERRUPT:
			v->mvtype = MV_STR;
			v->str = dollar_zinterrupt.str;
			s2pool(&(v->str));
			break;
		case SV_ZININTERRUPT:
			MV_FORCE_MVAL(v, dollar_zininterrupt);
			break;
		case SV_ZJOB:
			MV_FORCE_UMVAL(v, dollar_zjob);
			break;
		case SV_ZDATE_FORM:
			MV_FORCE_MVAL(v, TREF(zdate_form));
			break;
		case SV_ZTEXIT:
			*v = dollar_ztexit;
			break;
		case SV_ZALLOCSTOR:
			ucount = (gtm_uint64_t)totalAlloc + (gtm_uint64_t)totalAllocGta;
			ui82mval(v, ucount);
			break;
		case SV_ZREALSTOR:
			ucount = (gtm_uint64_t)totalRmalloc + (gtm_uint64_t)totalRallocGta;
			ui82mval(v, ucount);
			break;
		case SV_ZUSEDSTOR:
			ucount = (gtm_uint64_t)totalUsed + (gtm_uint64_t)totalUsedGta;
			ui82mval(v, ucount);
			break;
		case SV_ZCHSET:
			v->mvtype = MV_STR;
			v->str = dollar_zchset;
			break;
		case SV_ZPATNUMERIC:
			v->mvtype = MV_STR;
			v->str = dollar_zpatnumeric;
			break;
		case SV_ZTNAME:
		case SV_ZTCODE:		/* deprecated */
#			ifdef GTM_TRIGGER
			if (NULL == dollar_ztname)
				memcpy(v, &literal_null, SIZEOF(mval));
			else
			{
				v->mvtype = MV_STR;
				v->str.addr = dollar_ztname->addr;
				v->str.len = dollar_ztname->len;
			}
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTDATA:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but it might be numeric and need conversion to a string */
			assert(!dollar_ztdata || MV_DEFINED(dollar_ztdata));
			if (NULL != dollar_ztdata)
				MV_FORCE_STR(dollar_ztdata);
			memcpy(v, (NULL != dollar_ztdata) ? dollar_ztdata : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTDELIM:
#			ifdef GTM_TRIGGER
			assert(!dollar_ztdelim || MV_DEFINED(dollar_ztdelim));
			if (NULL == dollar_ztdelim || !(MV_STR & dollar_ztdelim->mvtype) || (0 == dollar_ztdelim->str.len))
				memcpy(v, &literal_null, SIZEOF(mval));
			else
				memcpy(v, dollar_ztdelim, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTOLDVAL:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but it might be numeric and need conversion to a string */
			assert(!dollar_ztoldval || MV_DEFINED(dollar_ztoldval));
			if (NULL != dollar_ztoldval)
				MV_FORCE_STR(dollar_ztoldval);
			memcpy(v, (NULL != dollar_ztoldval) ? dollar_ztoldval : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTRIGGEROP:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but assert it's a string */
			assert(!dollar_ztriggerop || (MV_STR & dollar_ztriggerop->mvtype));
			memcpy(v, (NULL != dollar_ztriggerop) ? dollar_ztriggerop : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTUPDATE:
#			ifdef GTM_TRIGGER
			/* Value comes from GT.M, but if there were no delims involved, the value will be undefined, and
			 * we return a "literal_null".
			 */
			memcpy(v, ((NULL != dollar_ztupdate && (MV_STR & dollar_ztupdate->mvtype)) ? dollar_ztupdate
				   : &literal_null), SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTVALUE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			assert(!dollar_ztvalue || MV_DEFINED(dollar_ztvalue));
			if (NULL != dollar_ztvalue)
				MV_FORCE_STR(dollar_ztvalue);
			memcpy(v, (NULL != dollar_ztvalue) ? dollar_ztvalue : &literal_null, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTWORMHOLE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			mvp = &dollar_ztwormhole;
			if (MV_DEFINED(mvp))
			{
				MV_FORCE_STR(mvp);
				memcpy(v, mvp, SIZEOF(mval));
			} else
				memcpy(v, &literal_null, SIZEOF(mval));
			ztwormhole_used = TRUE;
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTSLATE:
#			ifdef GTM_TRIGGER
			/* Value comes from user-land so make sure things are proper */
			assert(MV_DEFINED((&dollar_ztslate)));
			mvp = &dollar_ztslate;
			MV_FORCE_STR(mvp);
			memcpy(v, mvp, SIZEOF(mval));
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZTLEVEL:
#			ifdef GTM_TRIGGER
			MV_FORCE_MVAL(v, gtm_trigger_depth);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZONLNRLBK:
#			ifdef UNIX
			count = TREF(dollar_zonlnrlbk);
			MV_FORCE_MVAL(v, count);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZCLOSE:
#			ifdef UNIX
			count = TREF(dollar_zclose);
			MV_FORCE_MVAL(v, count);
			break;
#			else
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_UNIMPLOP);
#			endif
		case SV_ZKEY:
			get_dlr_zkey(v);
			break;
		default:
			assertpro(FALSE);
	}
}
Esempio n. 4
0
int4 parse_file(mstr *file, parse_blk *pblk)
{
	struct stat		statbuf;
	struct addrinfo		*ai_ptr, *localhost_ai_ptr, *temp_ai_ptr, hints;
	mstr			trans, tmp;
	int			status, diff, local_node_len, query_node_len, node_name_len;
	parse_blk		def;
	char			local_node_name[MAX_HOST_NAME_LEN + 1], query_node_name[MAX_HOST_NAME_LEN + 1];
	char			*base, *ptr, *top, *del, *node, *name, *ext, ch;
	char			**hostaddrlist;
	char			def_string[MAX_FBUFF + 1];
	boolean_t		hasnode, hasdir, hasname, hasext, wilddir, wildname;
	enum parse_state	state;
	struct sockaddr_storage	query_sas;
	struct sockaddr		localhost_sa, *localhost_sa_ptr;
	mval			def_trans;
	int			errcode;

	pblk->fnb = 0;
	ai_ptr = localhost_ai_ptr = temp_ai_ptr = NULL;
	assert(((unsigned int)pblk->buff_size + 1) <= (MAX_FBUFF + 1));
	/* All callers of parse_blk set buff_size to 1 less than the allocated buffer. This is because buff_size is a char
	 * type (for historical reasons) and so cannot go more than 255 whereas we support a max of 255 characters. So we
	 * allocate buffers that contain one more byte (for the terminating '\0') but dont set that in buff_size. Use
	 * that extra byte for the trans_log_name call.
	 */
	status = TRANS_LOG_NAME(file, &trans, pblk->buffer, pblk->buff_size + 1, dont_sendmsg_on_log2long);
	if (SS_LOG2LONG == status)
		return ERR_PARBUFSM;
	assert(trans.addr == pblk->buffer);
	memset(&def, 0, SIZEOF(def));	/* Initial the defaults to zero */
	if (pblk->def1_size > 0)
	{	/* Parse default filespec if supplied */
		def.fop = F_SYNTAXO;
		def.buffer = def_string;
		def.buff_size = MAX_FBUFF;
		def.def1_size = pblk->def2_size;
		def.def1_buf = pblk->def2_buf;
		tmp.len = pblk->def1_size;
		tmp.addr = pblk->def1_buf;
		if ((status = parse_file(&tmp, &def)) != ERR_PARNORMAL)
			return status;
		assert(!def.b_node);
		if (def.b_dir)	def.fnb |= F_HAS_DIR;
		if (def.b_name)	def.fnb |= F_HAS_NAME;
		if (def.b_ext)	def.fnb |= F_HAS_EXT;
	}
	wildname = wilddir = hasnode = hasdir = hasname = hasext = FALSE;
	node = base = ptr = trans.addr;
	top = ptr + trans.len;
	if ((0 == trans.len) || ('/' != *ptr))
	{	/* No file given, no full path given, or a nodename was specified */
		setzdir(NULL, &def_trans); /* Default current directory if none given */
		assert((0 == dollar_zdir.str.len) /* dollar_zdir not initialized yet, possible thru main() -> gtm_chk_dist() */
			|| ((def_trans.str.len == dollar_zdir.str.len) /* Check if cwd and cached value are the same */
				&& (0 == memcmp(def_trans.str.addr, dollar_zdir.str.addr, def_trans.str.len))));
		if (pblk->fop & F_PARNODE)
		{	/* What we have could be a nodename */
			assert(pblk->fop & F_SYNTAXO);
			while (node < top)
			{
				ch = *node++;
				if (':' == ch)		/* We have nodeness */
					break;
				if ('/' == ch)
				{	/* Not a node - bypass node checking */
					node = top;
					break;
				}
			}
			if (node < top)
			{
				hasnode = TRUE;
				ptr = base = node;				/* Update pointers past node name */
				/* See if the desired (query) node is the local node */
				node_name_len = (int)(node - trans.addr);	/* Scanned node including ':' */
				query_node_len = node_name_len - 1;		/* Pure name length, no ':' on end */
				assert(MAX_HOST_NAME_LEN >= query_node_len);
				assert(0 < query_node_len);
				assert(':' == *(trans.addr + query_node_len));
				memcpy(query_node_name, trans.addr, query_node_len);
				query_node_name[query_node_len] = 0;
				localhost_sa_ptr = NULL;	/* Null value needed if not find query node (remote default) */
				CLIENT_HINTS(hints);
				if (0 != (errcode = getaddrinfo(query_node_name, NULL, &hints, &ai_ptr)))	/* Assignment! */
					ai_ptr = NULL;		/* Skip additional lookups */
				else
					memcpy((sockaddr_ptr)&query_sas, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
				CLIENT_HINTS(hints);
				if (0 == (errcode = getaddrinfo(LOCALHOSTNAME, NULL, &hints, &localhost_ai_ptr))
					&& (0 == memcmp(localhost_ai_ptr->ai_addr, (sockaddr_ptr)&query_sas,
						localhost_ai_ptr->ai_addrlen)))
				{
					localhost_sa_ptr = localhost_ai_ptr->ai_addr;
				}
				FREEADDRINFO(localhost_ai_ptr);
				if (ai_ptr && !localhost_sa_ptr)
				{	/* Have not yet established this is not a local node -- check further */
					GETHOSTNAME(local_node_name, MAX_HOST_NAME_LEN, status);
					if (-1 == status)
						rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5,
								LEN_AND_LIT("gethostname"), CALLFROM, errno);
					CLIENT_HINTS(hints);
					if (0 != (errcode = getaddrinfo(local_node_name, NULL, &hints, &localhost_ai_ptr)))
						localhost_ai_ptr = NULL;	/* Empty address list */
					for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
					     temp_ai_ptr = temp_ai_ptr->ai_next)
					{
						if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
								 temp_ai_ptr->ai_addrlen))
						{
							localhost_sa_ptr = temp_ai_ptr->ai_addr;
							break;		/* Tiz truly a local node */
						}
					}
					FREEADDRINFO(localhost_ai_ptr);
				}
				if (ai_ptr && !localhost_sa_ptr)
				{
					CLIENT_HINTS(hints);
					if (0 != (errcode = getaddrinfo(LOCALHOSTNAME6, NULL, &hints, &localhost_ai_ptr)))
						localhost_ai_ptr = NULL;	/* Empty address list */
					for (temp_ai_ptr = localhost_ai_ptr; temp_ai_ptr!= NULL;
					     temp_ai_ptr = temp_ai_ptr->ai_next)
					{
						if (0 == memcmp((sockaddr_ptr)&query_sas, temp_ai_ptr->ai_addr,
								 temp_ai_ptr->ai_addrlen))
						{
							localhost_sa_ptr = temp_ai_ptr->ai_addr;
							break;		/* Tiz truly a local node */
						}
					}
					FREEADDRINFO(localhost_ai_ptr);
				}
				if (!localhost_sa_ptr)		/* Not local (or an unknown) host given */
				{	/* Remote node specified -- don't apply any defaults */
					FREEADDRINFO(ai_ptr);
					pblk->l_node = trans.addr;
					pblk->b_node = node_name_len;
					pblk->l_dir = base;
					pblk->b_dir = top - base;
					pblk->l_name = pblk->l_ext = base + pblk->b_dir;
					pblk->b_esl = pblk->b_node + pblk->b_dir;
					pblk->b_name = pblk->b_ext = 0;
					pblk->fnb |= (hasnode << V_HAS_NODE);
					return ERR_PARNORMAL;
				}
				FREEADDRINFO(ai_ptr);
				/* Remove local node name from filename buffer */
				assert(0 < trans.len - node_name_len);
				memmove(trans.addr, node, trans.len - node_name_len);
				ptr = base = node -= node_name_len;
				top -= node_name_len;
				trans.len -= node_name_len;
				if ('/' == *base)	/* No default directory if full path given */
					def_trans.str.len = 0;
			} else
			{	/* Supplied text was not a node -- reset pointer back to beginning for rescan */
				node = trans.addr;
			}
		}
		/* If parse buffer is not large enough, return error */
		if (def_trans.str.len + trans.len > pblk->buff_size)
			return ERR_PARBUFSM;
		/* Construct full filename to parse prefixing given filename with default path prefix */
		if (0 < def_trans.str.len)
		{
			memmove(ptr + def_trans.str.len, ptr, trans.len);
			memcpy(ptr, def_trans.str.addr, def_trans.str.len);
			assert('/' == ptr[def_trans.str.len - 1]);
			ptr += def_trans.str.len;
			top += def_trans.str.len;
		}
	}
	name = ptr;
	state = NOSTATE;
	for (; ptr < top;)
	{
		ch = *ptr;
		if ('.' == ch)
		{	/* Could be /./ or /../ or name.name */
			ptr++;
			state = (DOT1 == state) ? ((DOT2 == state) ? NAME : DOT2) : DOT1;
		} else if (ch == '/')
		{	/* We must still be doing the path */
			ptr++;
			hasdir = TRUE;
			hasname = FALSE;
			hasext = FALSE;
			wilddir |= wildname;
			wildname = FALSE;
			if ((DOT1 != state) && (DOT2 != state) && (SLASH != state))
			{	/* No dots seen recently so scan as if this is start of filename */
				state = SLASH;
				name = ptr;
				continue;
			}
			if (DOT1 == state)
			{	/* Just remove "./" chars from path */
				del = ptr - 2;
			} else if (DOT2 == state)
			{	/* Have xx/../ construct. Remove /../ and previous level directory from path */
				del = ptr - 4;		/* /../ characters being removed */
				assert ('/' == *del);
				if (del > base)
				{
					del--;
					while ('/' != *del)
						del--;
				}
				assert((del >= base) && ('/' == *del));
				del++;
			} else if (SLASH == state)
			{	/* Remove duplicate slash from path */
				del = ptr - 1;
				while ((ptr < top) && ('/' == *ptr))
					ptr++;
			}
			memmove(del, ptr, top - ptr);
			diff = (int)(ptr - del);
			ptr -= diff;
			top -= diff;
			state = SLASH;
			name = ptr;
		} else
		{	/* Hopeful of filename */
			hasname = TRUE;
			while (ptr < top)	/* Do small scan looking for filename end */
			{
				ch = *ptr;
				if ('/' == ch)
					break;	/* Ooops, still doing path */
				if ('.' == ch)
				{/* Filename has an extension */
					hasext = TRUE;
					ext = ptr;
				} else if (('?' == ch) || ('*' == ch))
					wildname = TRUE;
				ptr++;
			}
			state = NAME;
		}
	}
	/* Handle scan end with non-normal state */
	if ((SLASH == state) || (DOT1 == state) || (DOT2 == state))
	{
		assert(!hasname && !hasext);
		hasdir = TRUE;
		if (state == DOT1)
		{	/* Ignore ./ */
			top--;
			ptr--;
		}
		if (DOT2 == state)
		{	/* Ignore ../ plus last directory level specified */
			del = ptr - 3;		/* on the end */
			assert ('/' == *del);
			if (del > base)
			{
				del--;
				while ('/' != *del)
					del--;
			}
			assert((del >= base) && ('/' == *del));
			del++;
			ptr = top = del;
			name = ptr;
		}
	}
	if (!hasname)
	{
		assert(!hasext);
		name = ptr;
		if (def.fnb & F_HAS_NAME)
		{	/* Use default filename if we didn't find one */
			diff = (int)(name - node);
			if (def.b_name + diff > pblk->buff_size)
				return ERR_PARBUFSM;
			memcpy(name, def.l_name, def.b_name);
			ptr += def.b_name;
		}
		ext = ptr;
	}
	if (!hasext)
	{
		ext = ptr;
		if (def.fnb & F_HAS_EXT)
		{	/* Use default file extension if we didn't find one */
			diff = (int)((ext - node));
			if (def.b_ext + diff > pblk->buff_size)
				return ERR_PARBUFSM;
			memcpy(ext, def.l_ext, def.b_ext);
			ptr += def.b_ext;
		}
	}
	pblk->b_name = ext - name;
	pblk->b_ext = ptr - ext;
	if (!hasdir && (def.fnb & F_HAS_DIR))
	{
		diff = (int)(name - base);
		diff = def.b_dir - diff;
		if (def.b_dir + pblk->b_name + pblk->b_ext > pblk->buff_size)
			return ERR_PARBUFSM;
		if (diff > 0)
			memmove(name + diff, name, pblk->b_name + pblk->b_ext);
		else if (diff < 0)
			memcpy(name + diff, name, pblk->b_name + pblk->b_ext);
		memcpy(base, def.l_dir, def.b_dir);
		ptr += diff;
		name += diff;
	}
	pblk->b_dir = name - base;
	pblk->b_esl = ptr - base;
	pblk->l_dir = base;
	pblk->l_name = base + pblk->b_dir;
	pblk->l_ext = pblk->l_name + pblk->b_name;
	pblk->fnb |= (hasdir << V_HAS_DIR);
	pblk->fnb |= (hasname << V_HAS_NAME);
	pblk->fnb |= (hasext << V_HAS_EXT);
	pblk->fnb |= (wildname << V_WILD_NAME);
	pblk->fnb |= (wilddir << V_WILD_DIR);
	if (!(pblk->fop & F_SYNTAXO)  &&  !wilddir)
	{
		assert('/' == pblk->l_dir[pblk->b_dir - 1]);
		if (pblk->b_dir > 1)
		{
			pblk->l_dir[pblk->b_dir - 1] = 0;
			STAT_FILE(pblk->l_dir, &statbuf, status);
			pblk->l_dir[pblk->b_dir - 1] = '/';
			if ((-1 == status) || !(statbuf.st_mode & S_IFDIR))
				return ERR_FILENOTFND;
		}
	}
	return ERR_PARNORMAL;
}
Esempio n. 5
0
void zshow_svn(zshow_out *output)
{
	mstr		x;
	mval		var, zdir;
	io_log_name	*tl;
       	stack_frame	*fp;
	int 		count, save_dollar_zlevel;
	char		*c1, *c2;
	char		zdir_error[3 * GTM_MAX_DIR_LEN + 128]; /* PATH_MAX + "->" + GTM-W-ZDIROUTOFSYNC, <text of ZDIROUTOFSYNC> */

	error_def(ERR_ZDIROUTOFSYNC);

	/* SV_DEVICE */
		get_dlr_device(&var);
		ZS_VAR_EQU(&x, device_text);
		mval_write(output, &var, TRUE);
	/* SV_ECODE */
		ecode_get(-1, &var);
		ZS_VAR_EQU(&x, ecode_text);
		mval_write(output, &var, TRUE);
	/* SV_ESTACK */
		save_dollar_zlevel = dollar_zlevel();
		count = (save_dollar_zlevel - 1) - dollar_estack_delta.m[0];
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, estack_text);
		mval_write(output, &var, TRUE);
	/* SV_ETRAP */
		var.mvtype = MV_STR;
		var.str = dollar_etrap.str;
		ZS_VAR_EQU(&x, etrap_text);
		mval_write(output, &var, TRUE);
	/* SV_HOROLOG */
		op_horolog(&var);
		ZS_VAR_EQU(&x, horolog_text);
		mval_write(output, &var, TRUE);
	/* SV_IO */
		var.str.addr = io_curr_device.in->name->dollar_io;
		var.str.len = io_curr_device.in->name->len;
		/*** The following should be in the I/O code ***/
		if (ESC == *var.str.addr)
		{
			if (5 > var.str.len)
				var.str.len = 0;
			else
			{
				var.str.addr += ESC_OFFSET;
				var.str.len -= ESC_OFFSET;
			}
		}
		var.mvtype = MV_STR;
		ZS_VAR_EQU(&x, io_text);
		mval_write(output, &var, TRUE);
	/* SV_JOB */
		ZS_VAR_EQU(&x, job_text);
		mval_write(output, &dollar_job, TRUE);
	/* SV_KEY */
		get_dlr_key(&var);
		ZS_VAR_EQU(&x, key_text);
		mval_write(output, &var, TRUE);
	/* SV_PRINCIPAL */
		if (dollar_principal)
			tl = dollar_principal;
		else
			tl = io_root_log_name->iod->trans_name;
		var.str.addr = tl->dollar_io;
		var.str.len = tl->len;
		/*** The following should be in the I/O code ***/
		if (ESC == *var.str.addr)
		{
			if (5 > var.str.len)
				var.str.len = 0;
			else
			{
				var.str.addr += ESC_OFFSET;
				var.str.len -= ESC_OFFSET;
			}
		}
		var.mvtype = MV_STR;
		ZS_VAR_EQU(&x, principal_text);
		mval_write(output, &var, TRUE);
	/* SV_QUIT */
		count = ((NULL == get_ret_targ()) ? 0 : 1);
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, quit_text);
		mval_write(output, &var, TRUE);
	/* SV_REFERENCE */
		get_reference(&var);
		ZS_VAR_EQU(&x, reference_text);
		mval_write(output, &var, TRUE);
	/* SV_STACK */
		count = (save_dollar_zlevel - 1);
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, stack_text);
		mval_write(output, &var, TRUE);
	/* SV_STORAGE */
		i2mval(&var, getstorage());
		ZS_VAR_EQU(&x, storage_text);
		mval_write(output, &var, TRUE);
	/* SV_SYSTEM */
		var.mvtype = MV_STR;
		var.str = dollar_system.str;
		ZS_VAR_EQU(&x, system_text);
		mval_write(output, &var, TRUE);
	/* SV_TEST */
		i2mval(&var, (int)op_dt_get());
		ZS_VAR_EQU(&x, test_text);
		mval_write(output, &var, TRUE);
	/* SV_TLEVEL */
		count = (int)dollar_tlevel;
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, tlevel_text);
		mval_write(output, &var, TRUE);
	/* SV_TRESTART */
		MV_FORCE_MVAL(&var, (int)((MAX_VISIBLE_TRESTART < dollar_trestart) ? MAX_VISIBLE_TRESTART : dollar_trestart));
		ZS_VAR_EQU(&x, trestart_text);
		mval_write(output, &var, TRUE);
	/* SV_X */
		count = (int)io_curr_device.out->dollar.x;
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, x_text);
		mval_write(output, &var, TRUE);
	/* SV_Y */
		count = (int)io_curr_device.out->dollar.y;
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, y_text);
		mval_write(output, &var, TRUE);
	/* SV_ZA */
		count = (int)io_curr_device.in->dollar.za;
		MV_FORCE_MVAL(&var, count);
		ZS_VAR_EQU(&x, za_text);
		mval_write(output, &var, TRUE);
	/* SV_ZB */
		c1 = (char *)io_curr_device.in->dollar.zb;
		c2 = c1 + sizeof(io_curr_device.in->dollar.zb);
		var.mvtype = MV_STR;
		var.str.addr = (char *)io_curr_device.in->dollar.zb;
		while (c1 < c2 && *c1)
			c1++;
		var.str.len = (char *)c1 - var.str.addr;
		ZS_VAR_EQU(&x, zb_text);
		mval_write(output, &var, TRUE);
	/* SV_ZCMDLINE */
		get_command_line(&var, TRUE);	/* TRUE to indicate we want $ZCMDLINE (i.e. processed not actual command line) */
		ZS_VAR_EQU(&x, zcmdline_text);
		mval_write(output, &var, TRUE);
	/* SV_ZCOMPILE */
		var.mvtype = MV_STR;
		var.str = dollar_zcompile;
		ZS_VAR_EQU(&x, zcompile_text);
		mval_write(output, &var, TRUE);
	/* SV_ZCSTATUS */
		MV_FORCE_MVAL(&var, dollar_zcstatus);
		ZS_VAR_EQU(&x, zcstatus_text);
		mval_write(output, &var, TRUE);
	/* SV_ZDATEFORM */
		MV_FORCE_MVAL(&var, zdate_form);
		ZS_VAR_EQU(&x, zdate_form_text);
		mval_write(output, &var, TRUE);
	/* SV_ZDIR */
		ZS_VAR_EQU(&x, zdirectory_text);
		setzdir(NULL, &zdir);
		if (zdir.str.len != dollar_zdir.str.len || 0 != memcmp(zdir.str.addr, dollar_zdir.str.addr, zdir.str.len))
		{
			memcpy(zdir_error, zdir.str.addr, zdir.str.len);
			memcpy(&zdir_error[zdir.str.len], arrow_text, STR_LIT_LEN(arrow_text));
			sgtm_putmsg(&zdir_error[zdir.str.len + STR_LIT_LEN(arrow_text)], VARLSTCNT(6) ERR_ZDIROUTOFSYNC, 4,
					zdir.str.len, zdir.str.addr, dollar_zdir.str.len, dollar_zdir.str.addr);
			zdir.str.addr = zdir_error;
			zdir.str.len = strlen(zdir_error) - 1; /* eliminate trailing '\n' */
		}
		SKIP_DEVICE_IF_NOT_NEEDED(&zdir);
		mval_write(output, &zdir, TRUE);
	/* SV_ZEDITOR */
		MV_FORCE_MVAL(&var, dollar_zeditor);
		ZS_VAR_EQU(&x, zeditor_text);
		mval_write(output, &var, TRUE);
	/* SV_ZEOF */
		ZS_VAR_EQU(&x, zeof_text);
		mval_write(output, io_curr_device.in->dollar.zeof ? (mval *)&literal_one : (mval *)&literal_zero, TRUE);
	/* SV_ZERROR */
		var.mvtype = MV_STR;
		var.str = dollar_zerror.str;
		ZS_VAR_EQU(&x, zerror_text);
		mval_write(output, &var, TRUE);
	/* SV_ZGBLDIR */
		ZS_VAR_EQU(&x, zgbldir_text);
		mval_write(output, &dollar_zgbldir, TRUE);
	/* SV_ZININTERRUPT */
		MV_FORCE_MVAL(&var, dollar_zininterrupt);
		ZS_VAR_EQU(&x, zininterrupt_text);
		mval_write(output, &var, TRUE);
	/* SV_ZINTERRUPT */
		var.mvtype = MV_STR;
		var.str = dollar_zinterrupt.str;
		ZS_VAR_EQU(&x, zinterrupt_text);
		mval_write(output, &var, TRUE);
	/* SV_ZIO */
		var.mvtype = MV_STR;
		/* NOTE:	This is **NOT** equivalent to :
		 *		io_curr_log_name->dollar_io
		 */
		var.str.addr = io_curr_device.in->trans_name->dollar_io;
		var.str.len = io_curr_device.in->trans_name->len;
		if (*var.str.addr == ESC)
		{
			if (5 > var.str.len)
				var.str.len = 0;
			else
			{
				var.str.addr += ESC_OFFSET;
				var.str.len -= ESC_OFFSET;
			}
		}
		ZS_VAR_EQU(&x, zio_text);
		mval_write(output, &var, TRUE);
	/* SV_ZJOB */
		MV_FORCE_ULONG_MVAL(&var, dollar_zjob);
		ZS_VAR_EQU(&x, zjob_text);
		mval_write(output, &var, TRUE);
	/* SV_ZLEVEL */
		MV_FORCE_MVAL(&var, save_dollar_zlevel);
		ZS_VAR_EQU(&x, zlevel_text);
		mval_write(output, &var, TRUE);
	/* SV_ZMAXTPTIME */
		MV_FORCE_MVAL(&var, dollar_zmaxtptime);
		ZS_VAR_EQU(&x, zmaxtptime_text);
		mval_write(output, &var, TRUE);
	/* SV_ZMODE */
		ZS_VAR_EQU(&x, zmode_text);
		mval_write(output, &dollar_zmode, TRUE);
	/* SV_ZPOS */
		getzposition(&var);
		ZS_VAR_EQU(&x, zpos_text);
		mval_write(output, &var, TRUE);
	/* SV_ZPROC */
		ZS_VAR_EQU(&x, zproc_text);
		mval_write(output, &dollar_zproc, TRUE);
	/* SV_PROMPT */
		var.mvtype = MV_STR;
		var.str.addr = gtmprompt.addr;
		var.str.len = gtmprompt.len;
		ZS_VAR_EQU(&x, zprompt_text);
		mval_write(output, &var, TRUE);
	/* SV_ZROUTINES */
		if (!zro_root)
			zro_init();
		var.mvtype = MV_STR;
		var.str = dollar_zroutines;
		ZS_VAR_EQU(&x, zroutines_text);
		mval_write(output, &var, TRUE);
	/* SV_ZSOURCE */
		var.mvtype = MV_STR;
		var.str = dollar_zsource;
		ZS_VAR_EQU(&x, zsource_text);
		mval_write(output, &var, TRUE);
	/* SV_ZSTATUS */
		ZS_VAR_EQU(&x, zstatus_text);
		mval_write(output, &dollar_zstatus, TRUE);
	/* SV_ZSTEP   */
		ZS_VAR_EQU(&x, zstep_text);
		mval_write(output, &dollar_zstep, TRUE);
	/* SV_ZSYSTEM */
		MV_FORCE_MVAL(&var, dollar_zsystem);
		ZS_VAR_EQU(&x, zsystem_text);
		mval_write(output, &var, TRUE);
	/* SV_ZTEXIT */
		var.mvtype = MV_STR;
		var.str = dollar_ztexit.str;
		ZS_VAR_EQU(&x, ztexit_text);
		mval_write(output, &var, TRUE);
	/* SV_ZTRAP */
		var.mvtype = MV_STR;
		var.str = dollar_ztrap.str;
		ZS_VAR_EQU(&x, ztrap_text);
		mval_write(output, &var, TRUE);
	/* SV_ZVERSION */
		var.mvtype = MV_STR;
		var.str.addr = (char *)&gtm_release_name[0];
		var.str.len = gtm_release_name_len;
		ZS_VAR_EQU(&x, zversion_text);
		mval_write(output, &var, TRUE);
	/* SV_ZYERROR */
		var.mvtype = MV_STR;
		var.str = dollar_zyerror.str;
		ZS_VAR_EQU(&x, zyerror_text);
		mval_write(output, &var, TRUE);
}