From: goathunter@wkuvx1.bitnet
Newsgroups: comp.os.vms
Subject: Re: Saving the recall buffer
Date: 18 Aug 92 07:08:26 CDT
Distribution: world
Organization: Western Kentucky University, Bowling Green, KY

In article <920817140148.20409853@FRED.ALHRG.WPAFB.AF.MIL>, SYSTEMM@FRED.ALHRG.WPAFB.AF.MIL (System Manager Wuest) writes:
> 
>    I know this is not a FAQ because I've been watching INFO-VAX for at least
>    a year and it has never come up.  I'm sure it is not an original idea. ;-)
> 
>    Has anyone developed the code to save the RECALL buffer from one session 
>    to another?  I won't belabor how useful this might be...
> 
One of my earliest _VAX Professional_ articles presented just such a
program.  CMD will SAVE, RESTORE, FLUSH (it was written before
RECALL/ERASE existed), and LIST the command recall buffer.

I've included it below.  It must be installed with CMEXEC privilege to
be used by users without that priv.  (The recall buffer is protected
from user write.)

	$ MACRO CMD
	$ LINK/NOTRACE CMD
	$ INSTALL ADD dev:[dir]CMD.EXE
	$ cmd :== $dev:[dir]cmd.exe

Valid qualifiers are /LIST, /FLUSH, /SAVE, /RESTORE, /BOTH (save,flush).

Hunter
------
Hunter Goatley, VMS Systems Programmer, Western Kentucky University
goathunter@WKUVX1.BITNET, 502-745-5251

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-011  26-Jun-1992
$!   On 18-AUG-1992 07:04:06.32   By user GOATHUNTER (@WKUVX1.BITNET)
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. CMD.MAR;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ x = P1 - f$parse(P1,,,"version")
$ y = f$search(x)
$ if y .eqs. "" then $ goto file_absent
$ x = f$integer(f$parse(P1,,,"version")-";")
$ y = f$integer(f$parse(y,,,"version")-";")
$ if x .gt. y then $ goto file_absent
$ if f$mode() .eqs. "INTERACTIVE" then $ goto file_interactive
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists. Skipped."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists. Skipped."
$file_delete:
$ delete 'f'*
$ exit
$file_interactive:
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists."
$ read/error=file_delete/end=file_delete-
  /prompt="Create new version [y/n]: " -
  sys$command x
$ if .not. x then $ e "-W-SKIPPED, File ''P1' skipped."
$ if .not. x then $ goto file_delete
$ P1 = P1 - f$parse(P1,,,"version")
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X;========================================================================
X;=`09`09`09`09`09`09`09`09`09=
X;=`09Programmer:`09Hunter Goatley`09`09`09`09`09=
X;=`09`09`09goathunter@WKUVX1.BITNET`09`09`09=
X;=`09Program:`09CMD.MAR`09`09`09`09`09`09=
X;=`09Purpose:`09Save, restore, flush, & list DCL command buffer`09=
X;=`09Language:`09VAX-11 MACRO32  assembly language`09`09=
X;=`09System:`09`09VAX/VMS v4.x`09`09`09`09`09=
X;=`09Date:`09`09October 8, 1986`09`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;========================================================================
X;=`09`09`09`09`09`09`09`09`09=
X;=`09Copyright `A9 1989 by Hunter Goatley`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09This program may be distributed freely for non-profit use`09=
X;=`09as long as this notice remains intact.`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;========================================================================
X;=`09`09`09`09`09`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09This  program  allows  the user to flush the command buffer,`09=
X;=`09list all of the commands in  the buffer,  write the contents`09=
X;=`09of the buffer to a file, and restore the buffer from a file.`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09To use this program, set up a foreign symbol, such as:`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09`09`09$ CMD :== $dev:`5Bdir`5DCMD.EXE`09`09`09=
X;=`09`09`09$ CMD/qualifier`09`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09To build:`09`09`09`09`09`09`09=
X;=`09`09`09$ MACRO CMD`09`09`09`09`09=
X;=`09`09`09$ LINK CMD/NOTRACEBACK`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09To install:`09`09`09`09`09`09`09=
X;=`09`09`09$ INSTALL ADD CMD.EXE/PRIV=CMEXEC`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09The valid qualifiers are:`09`09`09`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;=`09/LIST`09-  List all commands in the DCL command buffer`09`09=
X;=`09/SAVE`09-  Save the commands in SYS$LOGIN:SAVE_CMDS.TXT`09`09=
X;=`09/RESTORE-  Restore commands previously SAVEd`09`09`09=
X;=`09/FLUSH`09-  Flush the command buffer`09`09`09`09=
X;=`09/BOTH`09-  SAVE, then FLUSH the DCL command buffer`09`09=
X;=`09`09`09`09`09`09`09`09`09=
X;========================================================================
X;
X`09.LINK`09"SYS$SYSTEM:SYS.STB"/selective_search
X`09.LINK`09"SYS$SYSTEM:DCLDEF.STB"/selective_search
X
X;
X;  This macro compares the current address (in R10) with the beginning addre
Vss
X;  of the data area -- if they are equal, set the current address = to the e
Vnd
X;  of the data block (wrap).
X;
X`09.MACRO`09CHECK`09?HERE
X`09CMPL`09R11,R10`09`09`09; Have we gone past the beginning?
X`09BNEQ`09HERE`09`09`09; No -- skip next instruction
X`09MOVAB`09PRC_G_COMMANDS(R3),R10
X`09ADDL2`09#PRC_S_COMMANDS+1,R10
X;`09MOVL`09#CMD_BUF_END,R10`09; Make R10 point to one byte past the
X`09`09`09`09`09; ... end of the data area.  With next
X`09`09`09`09`09; ... autodecrement, it will point to
X`09`09`09`09`09; ... the last byte of the table.
X HERE:`09.ENDM`09CHECK
X`09`09`09`09`09;
X;
X;  This macro compares the first four bytes of FOR_BUFF with a valid qualifi
Ver.
X;  If there is a match, the appropriate routine is called and control branch
Ves
X;  to return to VMS.
X;
X`09.MACRO`09PRESENT`09QUAL,ROUTIN1,ROUTIN2=0,?LABEL
X`09CMPL`09#`5EA\QUAL\,FOR_BUFF`09; Was /QUAL given?
X`09BNEQU`09LABEL`09`09`09; No - try next
X`09CALLS`09#0,ROUTIN1`09`09; Call the proper routine
X`09.IF`09DIF`090,ROUTIN2`09; Was a second routine given?
X`09BLBC`09R0,BYE`09`09`09; Error?
X`09CALLS`09#0,ROUTIN2`09`09; No - call the second routine
X`09.ENDC`09`09`09`09; ...
X`09BRW`09BYE`09`09`09; Return to VMS (only one qualifier
XLABEL:`09.ENDM`09PRESENT`09`09`09; ...  at a time!!!
X
X`09.PSECT`09DCL_CMDS_DATA,NOEXE,WRT,LONG
X`09`09`09`09`09;
X`09$SSDEF`09`09`09`09; Include status symbols
X`09$RMSDEF`09`09`09`09; Include RMS symbols
X`09$FABDEF`09`09`09`09; Include $FAB symbols
X`09$RABDEF`09`09`09`09; Include $RAB symbols
X`09$PRVDEF`09`09`09`09; Include privilege symbols
X;
X;=======================================================================
X;
XCMDFAB: $FAB`09FNM=<SYS$LOGIN:SAVE_CMDS.TXT>, -`09; File name
X`09`09FAC=<GET,PUT>, -`09`09; File ACcess (R/W only)
X`09`09MRS=1420, -`09`09`09; Maximum Record Size
X`09`09RAT=CR, -`09`09`09; Record ATtributes
X`09`09ORG=SEQ`09`09`09`09; File Organization (sequential)
X;
X;***  Record Access Block for SAVE_CMDS.TXT
X;
XCMDRAB:
X`09$RAB    FAB=CMDFAB, -`09`09; Record Access Block
X`09`09RBF=CMDREC, -`09`09; If writing, write from CMDREC
X`09`09UBF=CMDREC`09`09; Address of SAVE_CMDS record buffer
X
X;
X;
XCMDREC:`09.BLKB`091032`09`09`09; Buffer for DCL commands
X;
X;=======================================================================
X;
XMAXCMDLEN = 256`09`09`09`09; Maximum length of a DCL command
X`09`09`09`09`09;
XCMDBUFFER_D:`09`09`09`09; Descriptor for the command buffer
X`09.WORD`09MAXCMDLEN`09`09; ...
X`09.BYTE`09DSC$K_DTYPE_T`09`09; ...
X`09.BYTE`09DSC$K_CLASS_S`09`09; ...
X`09.ADDRESS .+4`09`09`09; ...
XCMDBUFFER:`09`09`09`09; The command buffer
X`09.BYTE`09`5EA/ /`5BMAXCMDLEN`5D`09; ...
X`09`09`09`09`09;
XFAOCTR:`09.ASCID`09/!3UL !AS/
XFAOUT:`09.WORD`09256`09`09`09`09; ...
X`09.BYTE`09DSC$K_DTYPE_T`09`09`09; ...
X`09.BYTE`09DSC$K_CLASS_S`09`09`09; ...
X`09.ADDRESS .+4`09`09`09`09; ...
X`09.BLKB`09256
X
XFOR_BUFF_D:`09`09`09`09; Descriptor for the command line
X`09.WORD`09MAXCMDLEN`09`09; ...  returned by LIB$GET_FOREIGN
X`09.BYTE`09DSC$K_DTYPE_T`09`09; ...
X`09.BYTE`09DSC$K_CLASS_S`09`09; ...
X`09.ADDRESS .+4`09`09`09; ...
XFOR_BUFF:`09`09`09`09; BUffer holding the command line
X`09.BLKB`09MAXCMDLEN`09`09; ...
XFOR_LEN:.LONG`090`09`09`09; Length of command line returned
XUSAGE_D:`09`09`09`09; Usage message
X`09.ASCID`09-
X \Must give valid qualifier: /LIST, /FLUSH, /SAVE, /RESTORE, /BOTH (save,flu
Vsh)\
XCMEXEC:`09.QUAD`09PRV$M_CMEXEC`09`09; Privilege needed to flush & restore
XCMKRNL:`09.QUAD`09PRV$M_CMKRNL`09`09; Alternative privilege needed
X;
X;===========================================================================
V====
X;
X`09.PSECT`09DCL_CMDS,EXE,NOWRT
X`09.ENTRY`09DCL_CMDS,`5EM<>
X
X`09MOVW`09#PRC_S_COMMANDS+4,-`09; Store the size of the command buffer
X`09`09CMDRAB+RAB$W_RSZ`09; ... in the RAB
X`09MOVW`09#PRC_S_COMMANDS+4,-`09; Store the size of the command buffer
X`09`09CMDRAB+RAB$W_USZ`09; ... in the RAB
X
X; A simple command line parser follows.  The code simply checks for a "/"
X; followed by at least 3 characters of the command qualifier.  Not very
X; forgiving, but easy to code.
X;
X`09PUSHAW`09FOR_LEN`09`09`09; Get any commands on command line
X`09PUSHL`09#0`09`09`09; Don't want to prompt for anything
X`09PUSHAQ`09FOR_BUFF_D`09`09; Buffer for command line
X`09CALLS`09#3,G`5ELIB$GET_FOREIGN`09; Get the command line
X`09TSTW`09FOR_LEN`09`09`09; Was anything given?
X`09BNEQ`0910$`09`09`09; Yes  - see what was
X`09PUSHAQ`09USAGE_D`09`09`09; No - print usage message
X`09CALLS`09#1,G`5ELIB$PUT_OUTPUT`09; ...
X`09BRW`09BYE`09`09`09; ...
X`09`09`09`09`09;
X10$:`09PRESENT`09</RES>,RESTORE_CMDS`09`09; Was /RESTORE given?
X`09PRESENT`09</LIS>,LIST_CMDS`09`09; Was /LIST?
X`09PRESENT`09</FLU>,FLUSH_CMDS`09`09; Was /FLUSH?
X`09PRESENT`09</SAV>,SAVE_CMDS`09`09; Was /SAVE?
X`09PRESENT`09</BOT>,SAVE_CMDS,FLUSH_CMDS`09; Was /BOTH (save and flush)?
X
X`09PUSHAQ`09USAGE_D`09`09`09; If here, a valid qualifier was not
X`09CALLS`09#1,G`5ELIB$PUT_OUTPUT`09; ...  given - print USAGE message
X BYE:`09$EXIT_S`09CODE=R0`09`09`09; Exit to VMS
X`09`09`09`09`09;
X;===========================================================================
V====
X;   Subroutine SAVE_CMDS - Save the DCL commands in SYS$LOGIN:SAVE_CMDS.TXT
X;
X`09.ENTRY`09SAVE_CMDS,`5EM<>
X`09`09`09`09`09`09;
X`09$CREATE`09FAB=CMDFAB`09`09`09; Create the output file
X`09BLBC`09R0,100$`09`09`09`09; Error?
X    `09$CONNECT RAB=CMDRAB`09`09`09; Connect the RAB
X`09BLBC`09R0,100$`09`09`09`09; Error?
X`09MOVAB`09G`5ECTL$AG_CLIDATA,R3`09`09; Get address of CLI data
X`09MOVL`09PPD$L_PRC(R3),R3`09`09; Get address of PRC region
X`09MOVC3`09#PRC_S_COMMANDS+4, -`09`09; Get the DCL previous command
X`09`09PRC_L_RECALLPTR(R3),CMDREC`09; ... buffer (not protected
X`09`09`09`09`09`09; ... against user-mode reads)
X`09$PUT`09RAB=CMDRAB`09`09`09; Write the buffer to the file
X`09BLBC`09R0,100$`09`09`09`09; Error?
X`09$CLOSE`09FAB=CMDFAB`09`09`09; Close the file
X 100$:`09RET`09`09`09`09`09; Return to caller
X`09`09`09`09`09`09;
X;===========================================================================
V====
X;   Subroutine RESTORE_CMDS - Restore DCL commands in SYS$LOGIN:SAVE_CMDS.TX
VT
X;   Calls EXEC_RESTORE from EXECUTIVE mode
X;
X`09.ENTRY`09RESTORE_CMDS,`5EM<>
X`09`09`09`09`09`09;
X`09CALLS`09#0,GETPRV`09`09`09; Turn on the CMEXEC to do this
X`09BLBC`09R0,10$`09`09`09`09; If error (No priv), return
X`09$OPEN`09FAB=CMDFAB`09`09`09; Open SAVE_CMDS.TXT for reading
X`09BLBC`09R0,10$`09`09`09`09; Error?
X`09$CONNECT RAB=CMDRAB`09`09`09; Connect the RAB
X`09BLBC`09R0,10$`09`09`09`09; Error?
X`09$GET`09RAB=CMDRAB`09`09`09; Read the only record in the
X`09`09`09`09`09`09; ... file (the command buffer)
X`09BLBC`09R0,10$`09`09`09`09; Error?
X`09$CMEXEC_S -`09`09`09`09; Go move the command buffer
X`09`09ROUTIN=EXEC_RESTORE`09`09; ... to process space
X`09$CLOSE`09FAB=CMDFAB`09`09`09; Close the file
X 10$:`09RET`09`09`09`09`09; Return to caller
X;
X;===========================================================================
V====
X;****`09This executive mode routine moves the previous commands from CMDREC
X;****`09to the CLI data area.
X;
X`09.ENTRY`09EXEC_RESTORE,`5EM<>
X`09`09   `09`09`09`09;
X`09MOVAL`09HANDLER,(FP)`09`09`09; Unnecessary handler, but...
X`09MOVAB`09G`5ECTL$AG_CLIDATA,R3`09`09; Get address of CLI data
X`09MOVL`09PPD$L_PRC(R3),R3`09`09; Get address of PRC region
X`09MOVC3`09#PRC_S_COMMANDS+4,CMDREC, -`09; Move the prev command block
X`09`09PRC_L_RECALLPTR(R3)`09`09; ...  to the CLI data area
X`09MOVZBL`09#SS$_NORMAL,R0`09`09`09; Set up a success return
X`09RET`09`09`09`09`09; Return to caller
X`09`09`09`09`09`09;
X`09.ENTRY`09HANDLER,`5EM<>`09`09`09; Exit handler in case of
X`09$EXIT_S`09`09`09`09`09; ... $ACCVIO (Kill process)
X`09`09`09`09`09`09;
X;===========================================================================
V====
X;   Subroutine LIST_CMDS - List all commands stored in DCL RECALL buffer
X;
X`09.ENTRY`09LIST_CMDS,`5EM<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
X`09MOVAB`09G`5ECTL$AG_CLIDATA,R3`09`09; Get address of CLI data
X`09MOVL`09PPD$L_PRC(R3),R3`09`09; Get address of PRC region
X`09MOVL`09PRC_L_RECALLPTR(R3),R10`09; Get addr of end of most recent cmd
X`09MOVL`09R10,R9`09`09`09; Make a copy of it
X`09MOVAB`09PRC_G_COMMANDS(R3),R11`09; Get the beginning of the data block
X`09CLRL`09R6`09`09`09; Clear command counter
X 10$:`09MOVAB`09CMDBUFFER,R8`09`09; Get the buffer address
X`09`09   `09`09`09; Clear the buffer
X`09MOVZBL`09-(R10),R7`09`09; Get the length of the first command
X`09BNEQ`0920$
X`09BRW`0940$`09`09`09; 2 null bytes in a row? End
X 20$:`09MOVW`09R7,CMDBUFFER_D`09`09; Move the length to the descriptor
X`09CHECK`09`09`09`09; Check to see if this command wraps
X`09`09`09`09`09; ...  to the end of the data area
X`09ADDL2`09R7,R8`09`09`09; Make R8 point to end of buffer
X 30$:`09MOVB`09-(R10),-(R8)`09`09; Move the first byte
X`09CHECK`09`09`09`09; Check our addresses
X`09SOBGTR`09R7,30$`09`09`09; Loop until command is moved
X`09INCL`09R6`09`09`09; Bump the command counter
X`09$FAO_S`09CTRSTR=FAOCTR, -`09; Format for output
X`09`09OUTBUF=FAOUT, -`09`09; ...
X`09`09OUTLEN=FAOUT, -`09`09; ...
X`09`09P1=R6, -`09`09; ...
X`09`09P2=#CMDBUFFER_D`09`09; ...
X`09PUSHAQ`09FAOUT`09`09`09; Write it to the terminal
X`09CALLS`09#1,G`5ELIB$PUT_OUTPUT`09; ....
X`09MOVW`09#256,FAOUT`09`09; Reset FAO output descriptor
X`09DECL`09R10`09`09`09; Should now point to prefix count
X`09CHECK`09`09`09`09; Check our addresses
X`09DECL`09R10`09`09`09; Should now point to 0 byte
X`09CHECK`09`09`09`09; Check our addresses
X`09CMPL`09R10,R9`09`09`09; If current addr = starting addr
X`09BEQL`0940$`09`09`09; ...  end of data
X`09BRW`0910$`09`09`09; Loop until all commands printed
X 40$:`09MOVL`09#SS$_NORMAL,R0`09`09; Set return code
X`09RET`09`09`09`09; Return to caller
X`09`09`09`09`09;
X;===========================================================================
V====
X;   Subroutine FLUSH_CMDS - Flush the DCL command RECALL buffer
X;
X`09.ENTRY`09FLUSH_CMDS,`5EM<>
X`09CALLS`09#0,GETPRV`09`09; Turn on the CMEXEC to do this
X`09BLBC`09R0,10$`09`09`09; If error (No priv), return
X`09$CMEXEC_S -`09`09`09; Flush the DCL command buffer
X`09`09ROUTIN=EXEC_FLUSH`09; ...  (zero it out)
X 10$:`09RET`09`09`09`09; Return to caller
X;
X;  Zero out the DCL command recall buffer
X;
X`09.ENTRY`09EXEC_FLUSH,`5EM<R2,R3,R4,R5>
X`09MOVAB`09G`5ECTL$AG_CLIDATA,R3`09`09; Get address of CLI data
X`09MOVL`09PPD$L_PRC(R3),R3`09`09; Get address of PRC region
X`09MOVAB`09PRC_G_COMMANDS(R3),-`09`09; Reset last command pointer
X`09`09PRC_L_RECALLPTR(R3)`09`09; ...
X`09MOVC5`09#0,#0,#0,#PRC_S_COMMANDS,-`09; Zero out the DCL command
X`09`09PRC_G_COMMANDS(R3)`09`09; ...  recall buffer
X`09MOVL`09#SS$_NORMAL,R0`09`09`09; Set return status
X`09RET`09`09`09`09`09; Return to caller
X`09`09`09`09`09`09;
X;===========================================================================
V====
X;   Subroutine GETPRV - Turn on either CMEXEC or CMKRNL to do FLUSH and REST
VORE
X;
X`09.ENTRY`09GETPRV,`5EM<>
X`09$SETPRV_S -`09`09`09; Turn on CMEXEC privilege
X`09`09ENBFLG=#1, -`09`09; ...
X`09`09PRVADR=CMEXEC`09`09; ...
X`09CMPL`09#SS$_NORMAL,R0`09`09; Was CMEXEC turned on?
X`09BEQLU`0910$`09`09`09; Yes - return
X`09$SETPRV_S -`09`09`09; If not, try to turn on CMKRNL
X`09`09ENBFLG=#1, -`09`09; ...
X`09`09PRVADR=CMKRNL`09`09; ...
X`09CMPL`09#SS$_NORMAL,R0`09`09; Was CMEXEC turned on?
X`09BEQLU`0910$`09`09`09; Yes - return
X`09MOVL`09#SS$_NOCMEXEC,R0`09; If not, tell that CMEXEC is needed
X 10$:`09RET`09`09`09`09; Return to caller
X
X`09.END`09DCL_CMDS
$ CALL UNPACK CMD.MAR;1 756169595
$ v=f$verify(v)
$ EXIT