Google
 

Trailing-Edge - PDP-10 Archives - RMS-10_T10_704_FT2_880425 - 10,7/rms10/rmssrc/utlmsc.b36
There are 6 other files named utlmsc.b36 in the archive. Click here to see a list.
MODULE UTLMSC	(	 !Module for Miscellaneous routines.
	 IDENT = '01-01'
	 ) =

BEGIN

! COPYRIGHT (C) 1980
! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS 01754
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A SINGLE
! COMPUTER SYSTEM AND MAY BE COPIED ONLY WITH THE INCLUSION OF THE ABOVE
! COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER COPIES THEREOF, MAY NOT
! BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON EXCEPT FOR
! USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE
! TO AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN IN DEC.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
! CORPORATION.
!
! DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
!

!++					
! FACILITIY:	RMS UTILITY (RMSUTL)
!
! ABSTRACT:	This module contains some miscellaneous routines.

!
! ENVIRONMENT:	User mode with  RMS.
!
! AUTHOR: A. Uddin			CREATION DATE: 29 April 80
!
! MODIFIED BY:
!
!--


!
! TABLE OF CONTENTS:
!
!****************** Start RMS-10 V1.1 *********************
!********************* TOPS-10 ONLY ***********************
!
!PRODUCT	MODULE	 SPR
! EDIT	 EDIT	 QAR		DESCRIPTION
!======	======	=====		===========
!
! 100	  1	Dev		Make declarations for TX$APP and TX$TOUT
!				be EXTERNAL ROUTINE so RMS will compile 
!				under BLISS V4 (RMT, 10/22/85).

FORWARD ROUTINE

	RC$REL,		! POSITION TO A RECORD
	GETMEM,
	FREMEM:NOVALUE ;


!
! REQUIRE FILES:
! 

REQUIRE
	'sys:RMSINT' ;

LIBRARY
	'RMSLIB';

BUILTIN MACHSKIP,POINT, REPLACEI, SCANI, COPYII, INCP, COPYNI;

MACRO
ILDB[] = MACHOP (%O'134', %REMAINING) %;


OWN RDDESC : FORMATS[RDSIZE];
OWN ARGLST : FORMATS[5];

LITERAL	KILLFLAG = 1;

EXTERNAL BTY_CLOB,BTY_IDX,BTY_PRIM,BTY_SEC;
EXTERNAL
	BUGERR,			! CHKS FOR RMS BUG ERR & EXITS IF ONE
	FST: POINTER,
	KDB: POINTER,
	NRP$AD,
	PATH: POINTER,		! POINTER TO PATH ARRAY
	RAB: POINTER,
	RST: POINTER,
	KSIZW,KSIZB;			!SEE UTLTOP

!	Error Messages UTL--- Defined in UTLTOP.
!	TXTOUT MACRO AUTO GENS EXTERNAL REF


EXTERNAL ROUTINE

	TX$APP : macrosub,
	TX$TOUT : macrosub,
	INTERR : exitsub;	! Routine to handle errors detected by RMS

GLOBAL ROUTINE FREMEM (START_ADDR, WORDS): NOVALUE =	!<short one-line description>

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine frees memory that was acquired via the
!	GETMEM routine. Both GETMEM and FREMEM interface
!	with RMS's free storage management module (RMSFSM).
!	The parameters to this routine specify the start
!	of a block of memory to be freed and no. of words
!	to be freed. If the no.of words is a multiple of
!	512 words, the block is treated as page(s).

!
! FORMAL PARAMETERS:
!
!	START_ADDR: 
!	WORDS:
!

	BEGIN
	LOCAL
		TEMP1,
		TEMP2,
		FUNC;

		IF (TEMP2 = .WORDS ^ W2P)  GTR ZERO
		THEN
			BEGIN
			TEMP1 = .START_ADDR ^ W2P;	! CONVERT ADDR TO PAGE NO
			TEMP2 = .TEMP2 +  (IF .WORDS MOD 512 GTR ZERO
						THEN
							1
						ELSE
							0);
			FUNC = U$PPAGE;		! FREE PAGE 
			END

		ELSE

			BEGIN
			TEMP1 = START_ADDR;	! FREEING BLOCK OF MEMORY
			TEMP2 = .WORDS;
			FUNC = U$PMEM;		! FREE BLOCK OF MEMORY
			END;

		BLD_ARG_LST (ARGLST,.FUNC,.TEMP1,.TEMP2,KILLFLAG);
		$UTLINT (ARGLST,INTERR);
		RETURN;
	END;				! end of routine FREMEM



GLOBAL ROUTINE GETMEM ( SIZE_OF_ALLOC ) =

!++
! FUNCTIONAL DESCRIPTION:
!
!	This routine is called to allocate a block of memory from
!	the RMS's free storage manager. If the block of memory exceeds
!	512 words, the request is treated as a multiple of pages and
!	GPAGE function in RMS is called. Else the GMEM function is
!	called.
!
! FORMAL PARAMETERS:
!
!	SIZE_OF_ALLOC
!
! IMPLICIT INPUTS:
!
!	NONE
!
! IMPLICIT OUTPUTS:
!
!	None
!
! COMPLETION CODES:
!
!	Returns the address of allocated block of memory.
!	On an RMS error, control is transferred to INTERR.
!
! SIDE EFFECTS:
!
!	None
!--


	BEGIN
	LOCAL
		FUNC,
		TEMP1;

	IF (TEMP1 = .SIZE_OF_ALLOC ^ W2P) GTR ZERO
	THEN
		BEGIN
		FUNC = U$GPAGE;		! GET PAGE FUNCTION
		TEMP1 = .TEMP1 + (IF .SIZE_OF_ALLOC MOD 512 GTR ZERO
				  THEN
				 	1
				  ELSE
					0);
		END
	ELSE
		BEGIN
		FUNC = U$GMEM;		! GET BLOCK OF MEM
		TEMP1 = .SIZE_OF_ALLOC;	!NO OF WORDS TO ALLOC
		END;


	BLD_ARG_LST (ARGLST,.FUNC,.TEMP1);
	$UTLINT (ARGLST, INTERR);
	RETURN .ARGLST [ 0,WRD ];	! RETURN POINTER TO MEM ALLOCATED
	END;		! end of GETMEM routine


GLOBAL ROUTINE RC$FIND =

! RC$FIND - FINDS A RECORD USING "RAB"
! RETURNS:
!	-1 IF ERR MSG OUTPUT, 0 IF RNF, OR PHYSICAL RFA OF RECORD FND
! NOTES:
!	RB$NRP MUST BE SET SO THAT THE PHYSICAL RFA IS RETURNED
!	PHYSICAL RFA MEANS THE UDR RATHER THAN ITS RRV FOR PRIM KEY
!	AND THE SIDR RATHER THAN THE UDR FOR SEC KEY

BEGIN

EXTERNAL SCANNING;			!FLAG TO DET IF SCANNING CMD

	IF .SCANNING AND (CHKFLAG ($FIELD(ROP,.RAB),RB$KGT) EQL 0)
					!LOW LIM OF SCAN WANTS DEL ENTS INCL
	THEN BEGIN			!SCANNING
		LOCAL BKDESC : FORMATS[BDSIZE];
		LOCAL PT1 : POINTER;
		LOCAL NRP1;
		RDDESC[RDUSERSIZE] = .$FIELD(KSZ,.RAB);
		RDDESC[RDUSERPTR] = .$FIELD(KBF,.RAB);
		RDDESC[RDFLAGS] = RDFLGHORIZOK;	!FIND GE KEY
		BLD_ARG_LST (ARGLST,U$FNDDATA,RDDESC,BKDESC);
		$UTLINT (ARGLST, INTERR);	!FIND HI KEY REC (EVEN IF DEL)
		PT1 = .RDDESC [RDRECPTR];	!GET PTR TO ACTU REC
		NRP1 = MAKERFA (.BKDESC [BKDBKTNO], .PT1 [DRRECORDID]);
		$CALL (BD$PUT, BKDESC, 0);	!DONT NEED DATA ITSELF
		IF CHKFLAG (RDDESC[RDSTATUS], RDFLGPST)
		THEN RETURN 0			!KEY TOO HI, NO SUCH REC
		ELSE RETURN .NRP1;		!RET ENTRY FND
	END;

;	$FIELD(ROP,.RAB) = .$FIELD(ROP,.RAB) OR RB$NRP;
	$FIND (.RAB);			!TRY TO LOCATE THE RECORD
	IF .$FIELD(STS,.RAB) EQL ER$RNF	!REASONABLY FAIL?
		OR
	 .$FIELD(STS,.RAB) EQL ER$EOF	!REASONABLY FAIL?
	THEN RETURN 0;			!YES

	IF $CALL(M$ERMS,.RAB,UPLIT (%ASCIZ'?UTLURR unable to setup record range')) EQL 1
	THEN	IF .SCANNING			!IS IT SCANNING CMD?
		THEN RETURN .RST[RSTNRP]	!YES, RET RFA OF SEQ ELEM IN IDX
		ELSE RETURN .RST[RSTDATARFA]	!NO, PHYS UDR ADDR
	ELSE	RETURN -1;			!OOPS
END;

GLOBAL ROUTINE RC$GET =

! RC$GET - READS RECORD USING "RAB"
! RETURNS:
!	-1 IF ERR MSG OUTPUT, 0 IF RNF, OR PHYS RFA OF RECORD THAT WAS GOTTEN
! NOTES:
!	KLUDGE AROUND FACT THAT 1ST GET AFTER FIND ZEROES RSTNRP

BEGIN
	LOCAL T1;

	T1 = .RST[RSTNRP];		!SAVE NRP
	$GET (.RAB);			!TRY TO LOCATE THE RECORD
	IF .RST[RSTNRP] EQL 0 THEN RST[RSTNRP] = .T1;
					!RESTORE IT IF GET ZAPPED IT
	IF .$FIELD(STS,.RAB) EQL ER$RNF	!REASONABLY FAIL?
		OR
	 .$FIELD(STS,.RAB) EQL ER$EOF	!REASONABLY FAIL?
	THEN RETURN 0;			!YES
	IF $CALL(M$ERMS,.RAB, UPLIT (%ASCIZ'?UTLUGR unable to get record')) EQL 1
	THEN RETURN .RST[RSTDATARFA]	!TELL CALLER WHAT FOUND
	ELSE RETURN -1;			!OOPS
END;

GLOBAL ROUTINE RC$RFA (ENTRFA) =

! RC$RFA - FIND DATA-LEVEL ENTRY BY RFA VALUE
! ARGUMENTS:
!	ENTRFA = RFA OF REC TO FIND
! RETURNS:
!	0 IF REC NOT FND
!	1 IF FND

BEGIN
	LOCAL	BKDESC: FORMATS[BDSIZE];

	RDDESC[RDRECPTR] = 0;		!INSURE DONT IMPROP START IN MID
	RDDESC[RDRFA] = .ENTRFA;	!MAKE ARG PASSABLE
	BLD_ARG_LST (ARGLST,U$FBYRFA,RDDESC,BKDESC,0);
	$UTLINT (ARGLST,BUGERR);	!READ IN THIS RECORD
	IF .$FIELD(STS,ARGLST) EQL ER$RFA
	THEN RETURN 0;			!NO REC TO GET KEY FROM
	IF .ARGLST EQL 0		!ANY OTHER FAILURE?
	THEN RETURN $CALL (M$ERMS, ARGLST, UPLIT (%ASCIZ '?UTLUIO unable to do I/O'));
	$CALL (BD$PUT, BKDESC, 0);	!GIVE IT BACK
	RETURN 1;			!RET FND ENTRY
END;					!RC$RFA

GLOBAL ROUTINE RC$REL (RSTBLOCK, RECNUM) =

! FUNCTIONAL DESCRIPTION:
!	This routine is called to position an imaginary
!	record pointer to a record identified by a signed
!	number. The number defines the new record position
!	relative to the RFA passed.
!	For ex., if the argument ,i.e., relative record number, 
!	is +1 the record pointer is positioned to the next record.
!	If it -1, the record pointer is positioned to the previous
!	record etc. .
!
! FORMAL PARAMETERS:
!	RSTBLOCK.	RST DATA CORRES TO RELATIVE 0
!	RECNUM.		RELATIVE RECORD NUMBER
!
! COMPLETION CODES:
!	-1 = FAILURE WITH MSG
!	 0 = FAILURE.
!	m,,n = RFA OF RECORD FOUND
!

BEGIN

!	V1 RESTRICTON: RECNO MUST BE GE 0 

	LABEL	CONSIS;
	LOCAL	P1 : POINTER;
	LOCAL	TEMPBD : POINTER;
	LOCAL	T1;

	$CALL (M$RSTCOP, .RSTBLOCK, .RST);	!RESTORE RST INFO
	$CALL (BD$PUT, RST[RSTCBKD1], 0);	!CLEAR AWAY WHATS THERE
	RDDESC[RDRFA] = .RST[RSTDATARFA];	!PHYS LOC RECORD
	BLD_ARG_LST (ARGLST,U$FBYRRV,RDDESC,RST[RSTCBKD1]);
	$UTLINT (ARGLST,BUGERR);		!HAVE RMS SET CURR KEY
	IF .$FIELD(STS,ARGLST) EQL ER$RFA	!NO LONGER THERE?
	THEN BEGIN				!YES
		TXTOUT (UTLRNX);		!CANT REPOS BECAUS REC EXPUNGED
		RETURN -1;			!TELL CALLER
	END;
	IF .ARGLST EQL 0			!ANY OTHER FAILURE?
	THEN RETURN $CALL (M$ERMS, ARGLST, UPLIT (%ASCIZ '?UTLUIO unable to do I/O'));
	RST[RSTPAGPTR] = .RDDESC[RDRECPTR];	!PUT CURR REC'S LOC INTO RST
	P1 = .RDDESC[RDRECPTR];			!CHK DELETED FLAG
	RST[RSTLASTOPER] = C$FIND;		!WANT $GET TO GET SAVED REC

	$FIELD(RAC,.RAB) = RB$SEQ;		!SET ACC MODE
	IF .RECNUM GTR ZERO
	THEN	DECR J FROM .RECNUM TO 1	!LOCATE RELATIVE TO CURR
		DO	BEGIN
			$FIND (.RAB);
			IF .$FIELD(STS,.RAB) EQL ER$RNF	!REASONABLY FAIL?
				OR
			 .$FIELD(STS,.RAB) EQL ER$EOF	!REASONABLY FAIL?
			THEN RETURN 0;			!YES
			IF $CALL(M$ERMS,.RAB, UPLIT (%ASCIZ'?UTLUGR unable to get record')) LEQ 0
			THEN RETURN -1;			!OOPS
		END
	ELSE	CONSIS: BEGIN			!VERIF THAT CURR REC STILL THERE
		IF DELETEFLAG(P1) NEQ 0		!IS IT LOGICALLY DELETED?
		THEN BEGIN
			TXTOUT (UTLPNO);	!YES, REC DEL, SO POS NOT OCC
			RETURN -1;
		END;
		IF .KDB[KDBREF] EQL 0		!SIDR ARRAY CHK NECES?
		THEN LEAVE CONSIS;		!NO, PRIM KEY
		RDDESC[RDRECPTR] = 0;		!INSURE DONT IMPROP START IN MID
		RDDESC[RDRFA] = .RST[RSTNRP];	!PHYS LOC RECORD
		BLD_ARG_LST (ARGLST,U$FBYRFA,RDDESC,TEMPBD,0);
		$UTLINT (ARGLST,INTERR);	!HAVE RMS SET CURR KEY
		P1 = .RDDESC[RDRECPTR];		!GET PTR TO REC
		T1 = .KSIZW + .KDB[KDBHSZ] + .RST[RSTSIDRELEMENT] - 1;
						!PTR TO APPROP ELEM IN SIDR ARR
		T1 = .P1[.T1,WRD];		!GET VAL OF WD SO CAN PUTBKT
		$CALL (BD$PUT, TEMPBD, 0);	!GIVE IT BACK
		IF .T1 NEQ 0 THEN LEAVE CONSIS;	!IS ARRAY ELEM OCC?
		TXTOUT (UTLPNO);		!POS NOT OCC (EG. AFTER $UPDATE)
		RETURN -1;			!TELL CALLER ERR MSG PUT OUT
	END;					!END CONSIS
	RETURN .RST [RSTDATARFA];
END;	%(OF RC$REL)%

GLOBAL ROUTINE M$ERMS(CURRAB,TITASZ) =

! M$ERMS - OUTPUT APPROPRIATE MESSAGE AFTER RMS FAILURE
! ARGUMENTS:
!	CURRAB = PTR TO ARGBLK USED IN LAST RMS CALL
!	TITASZ = PTR TO ASCIZ STRING TO USE IN BEGINNING OF MSG
! RETURNS:
!	-1 IF MESSAGE PUT OUT
!	1 IF SU$--- WAS ERROR CODE
! NOTES:
!	EXITS TO CMD LEVEL IF CODE IS ER$BUG

BEGIN
	EXTERNAL RMEVEC : VECTOR;		!SYMBOLIC RMS ERRS
	LOCAL 	CAUSE,STS,STV;
	MACRO $CAUSE (ERR$, MSG$) =	!SET PTR TO MSG FOR USER-CAUSED RMS ERR
		IF .STS EQL ERR$ THEN CAUSE = UPLIT (%ASCIZ MSG$)
	%;

	STS = .$FIELD(STS,.CURRAB);	!GET RMS OPERATION STATUS
	STV = .$FIELD(STV,.CURRAB);	!GET 2NDARY STATUS, IN CASE NEEDED
	IF .STS LSS ER$BAS THEN RETURN 1;	!NO PROBLEM
	IF .STS EQL ER$BUG THEN $EXIT(INTERR);
					!JUST GIVE UP ON RMS INT ERR
	CAUSE = 0;			!INDIC NO CAUSE IDENT YET
	$CAUSE (ER$CHG, 'key not declared changable');
	$CAUSE (ER$DEL, 'record deleted');
	$CAUSE (ER$DME, 'no more room in memory');
	$CAUSE (ER$DUP, 'duplicates not allowed');
	$CAUSE (ER$FEX, 'file already exists');
	$CAUSE (ER$FNF, 'file not found');
	$CAUSE (ER$FLK, 'the access mode of another program conflicts');
	$CAUSE (ER$FSI, 'file spec improperly formatted');
	$CAUSE (ER$KSZ, 'invalid key size specified');
	$CAUSE (ER$PRV, 'of inadequate file access privileges');
	$CAUSE (ER$RTB, 'record buffer too small');
	$CAUSE (ER$SIZ, 'key longer than 255 characters');

	IF .CAUSE NEQ 0			!USER-CAUSED ERR?
	THEN TXTOUT (UTLXRF, .TITASZ, .CAUSE)
	ELSE TXTOUT (UTLURF, .TITASZ, RMEVEC[.STS-ER$BAS], .STV);
	RETURN -1;			!GIVE ERR MSG FAILURE RET
END;					!END M$ERMS

GLOBAL ROUTINE M$KDB(KEYREF) = 

! M$KDB - SETUP KDB, RABKRF, KSIZB/W GIVEN KEY OF REF
! ARGUMENTS:
!	KEYREF = KEY OF REF
! RETURNS:
!	1 & FLDS SET UP  OR  0, INDICATING KREF OUT OF RANGE

BEGIN
	BLD_ARG_LST (ARGLST,U$GETKDB,.KEYREF);
	$UTLINT (ARGLST,BUGERR);		!HAVE RMS SET CURR KEY
	IF .ARGLST EQL 0 THEN RETURN 0;		!RMS DIDNT RECOG THE KRF
	KDB = .ARGLST;				!PERMANIZE IN RMSUTL ENVIR
	KSIZW = .KDB[KDBKSZW];			!MAKE KEY SIZ WDS AVAIL
	KSIZB = .KDB[KDBKSZ];			!DITTO BYTES
	$FIELD(KRF,.RAB) = .KEYREF;		!SET IN ARGBLK TOO
	RETURN 1;
END;						!M$KDB

GLOBAL ROUTINE M$KLOC(KBFADR,ENTADR,BKTYPE) =

! M$KLOC - LOCATE (AND COPY AND COMBINE IF NECESSARY) ENTRY'S KEY-VALUE
! ARGUMENTS:
!	KBFADR = ADDR OF KEY BUFFER
!	ENTADR = ADDRESS OF ENTRY
!	BKTYPE = TYPE OF BKT KEY IS BEING PICKED UP FROM
! RETURNS:
!	ADDRESS WHERE KEY-VALUE (NOW) IS OR -1 IF INTERNAL ERROR

BEGIN
	LOCAL	PRIKDB:	POINTER;

	IF .BKTYPE EQL BTY_SEC
	THEN RETURN .ENTADR + SIDRHDRSIZE;		!SET KEY LOC IN SDIR

	IF .BKTYPE EQL BTY_PRIM			!LOCATING KEY VAL IN UDR?
	THEN BEGIN				!YES
		PRIKDB = .FST [FSTKDB];		!ADDR OF PRI KDB
		BLD_ARG_LST(ARGLST,U$MOVEKEY, .ENTADR+.PRIKDB[KDBHSZ], .KBFADR);
		$UTLINT (ARGLST,INTERR);	!COPY THE KEY VALUE
		RETURN .KBFADR;
	END;

	IF .BKTYPE EQL BTY_IDX			!LOCATING KEY VAL IN IDX ENT?
	THEN RETURN .ENTADR+IRHDRSIZE;		!RET ADDR ACTU IN ENTRY

	TXTOUT (UTLIUE);			!BAD BKTYPE ARG
	RETURN -1;
END;						!M$KLOC

GLOBAL ROUTINE M$KUDR(KBFADR,ENTADR) =

! M$KUDR - COPY REC'S KEY TO BUF AT KBFADR
! ARGUMENTS:
!	KBFADR = ADDR OF KEY BUFFER
!	ENTADR = ADDRESS OF UDR, RFA OF UDR, OR 0 (USE RSTPAGPTR)
! RETURNS:
!	NORMALLY 1 IF KEY-VALUE FND, -1 IF SCREWUP
!	KEY IN BUFFER & KSZ AND KBF SETUP IF T1 GE 1
!	IF ENTADR=RFA, ADDIT RULES:
!	0 IF NO REC FOR GIVEN RFA, 1 IF RFA OF DELETED REC, PHYS RFA IF REC OK

BEGIN
	LOCAL	BKDESC: FORMATS[BDSIZE];
	MAP	ENTADR: POINTER;

	RDDESC[RDRFA] = 1;			!PRESUME NORM CASE & SUCC
	IF .ENTADR EQL 0			!USING DEFAULT ENTRY ADDR?
	THEN ENTADR = .RST[RSTPAGPTR];		!YES
	IF .ENTADR<LH> NEQ 0			!IS ARG RFA?
	THEN BEGIN				!YES
		RDDESC[RDRFA] = .ENTADR;	!MAKE ARG PASSABLE
		BLD_ARG_LST (ARGLST,U$FBYRRV,RDDESC,BKDESC);
		$UTLINT (ARGLST,BUGERR);	!READ IN THIS RECORD, IF ENTADR=RRV, RDRFA RESET TO PHYS RFA
		IF .$FIELD(STS,ARGLST) EQL ER$RFA
		THEN RETURN 0;			!NO REC TO GET KEY FROM
		IF .ARGLST EQL 0		!ANY OTHER FAILURE?
		THEN RETURN $CALL (M$ERMS, ARGLST, UPLIT (%ASCIZ '?UTLUIO unable to do I/O'));
		ENTADR = .RDDESC[RDRECPTR];	!GET ADDR OF REC
		IF DELETEFLAG(ENTADR) NEQ 0	!REC DELETED?
		THEN RDDESC[RDRFA] = 1;		!INDIC KEY SET UP, BUT REC DEL
		$CALL (BD$PUT,BKDESC,0);	!DONT NEED BKT
	END;

	IF RRVFLAG(ENTADR) NEQ 0		!SHOULDNT HAPPEN
	THEN BEGIN				!OOPS, SOMEHOW PTING AT RRV
		TXTOUT (UTLIUE);		!GIVE MSG
		RETURN -1;
	END;

	$FIELD(KBF,.RAB) = $CALL (M$KLOC, .KBFADR, .ENTADR, BTY_PRIM);
						!LOC KEY &SET BUF ADDR IN RAB
	$FIELD(KSZ,.RAB) = .KDB[KDBKSZ];	!DITTO KSZ
	RETURN .RDDESC[RDRFA];
END;

GLOBAL ROUTINE M$USET : NOVALUE =

! M$USET - SET CURR ENV FOR $UTLINT

BEGIN
	BLD_ARG_LST(ARGLST,U$SETENVIR,.RAB);
	$UTLINT(ARGLST,INTERR);			!SET RABUTL IN RMSUIN
	NRP$AD = RST[RSTNRP];			!SAVE PTR TO RSTNRP

	BLD_ARG_LST (ARGLST, U$PATH,0);
	$UTLINT (ARGLST,INTERR);		! NO ERRORS EXPECTED
	PATH = .ARGLST [0,WRD];		!ADDR OF PATH ARRAY

	RETURN;
END;

GLOBAL ROUTINE M$RSTCOP(RSTCUR, RSTSAV) : NOVALUE =

! M$RSTCOP - COPIES NRP RELATED DATA BETWEEN RST COPIES
! ARGUMENTS:
!	RSTCUR = POINTER TO RST TO COPY
!	RSTSAV = POINTER TO SAVE BLK
! NOTES:
!	USED BY RC$REL TO ESTAB CURR REC.
!	ADDIT, LASTOPER ALWAYS SET TO FIND AND PAGPTR 0-ED

BEGIN
	MAP	RSTCUR : POINTER;
	MAP	RSTSAV : POINTER;

	RSTSAV[RSTFLAGS] = .RSTCUR[RSTFLAGS];
	RSTSAV[RSTDATARFA] = .RSTCUR[RSTDATARFA];
	RSTSAV[RSTNRP] = .RSTCUR[RSTNRP];
	RSTSAV[RSTRPREF] = .RSTCUR[RSTRPREF];
	RSTSAV[RSTNRPREF] = .RSTCUR[RSTNRPREF];
	RSTSAV[RSTNRPRRV] = .RSTCUR[RSTNRPRRV];
	RSTSAV[RSTSIDRELEMENT] = .RSTCUR[RSTSIDRELEMENT];
	RSTSAV[RSTRPSIDR] = .RSTCUR[RSTRPSIDR];
	RETURN;
END;					!END M$RSTCOP
END
ELUDOM