;******************************************************************************* ; TRIUMF - Vancouver, British Columbia, Canada ;******************************************************************************* ; Filespec: 41::$disk1:sys$manager:save_recall_buffer.mar ; ;******************************************************************************* ; Please note: This program takes routes into certain areas of the CLI ; storage area by using hardwired displacements that may vary with ; the version of VMS. The present version of save_recall_buffer ; works with VMS version 4.2 - 4.4 but has not been tested with higher ; versions. To minimize the chance of problems, the displacements ; should be checked in each new version of VMS to make sure that there ; are no changes. ; ; PPD$L_PRC = ^X08 ; Displ into ppd for cli ptr ; PRC_G_COMMANDS = ^X133 ; Displ into cliarea for rec ptr ; PRC_L_RECALLPTR = ^X12F ; Displ to current command ptr ; ; Description: This is a macro assembler program that may run on ; any VAX running VMS version 4.x. This program reads the cli's ; recall command buffer and stores it in a disk file. The disk file ; is located in sys$login and is called recall_buffer.dat. Before a new ; file is created, the last copy of recall_buffer.dat is deleted. ; If the system does not have delete and write access to the user's ; sys$login directory then the program will fail. ; ; At the end of a terminal session this program can be run to save ; the cli environment. The next time that the user logs-in a program ; called restore_recall_buffer can be run to setup the last cli ; commands used. ; ; The command buffer is 1025. bytes long. The organization ( not that it ; matters here) is as a circular buffer therefore the first and last bytes ; will probably be string bytes from the middle of a command string. ; ; . ; . ; . ; null byte of string n ; length byte of string n ; string byte of string n ; string byte of string n ; . ; . ; string byte of string n ; length byte of string n ; null byte of string n + 1 ; length byte of string n + 1 ; string byte of string n + 1 ; string byte of string n + 1 ; . ; . ; string byte of string n + 1 ; length byte of string n + 1 ; null byte of string n + 2 ; length byte of string n + 2 ; string byte of string n + 2 ; . ; . ;******************************************************************************* ; Assemble, link, and run instructions ; ; macro save_recall_buffer.mar ; link save_recall_buffer,sys$library:sys.stb/select ; run save_recall_buffer ; ;******************************************************************************* ; History of Revisions ; ; Rev Date Name Comments ; --- ---- ---- -------- ; ; 1.0 86/9/12 Mike Mouat -initial development ; 1.1 86/9/17 Mike Mouat -set sys$login:recall_buffer.dat ; file prot=s:rwed,o:rwed,g:,w: ; ;******************************************************************************* .TITLE SAVE_RECALL_BUFFER .LIBRARY /SYS$LIBRARY:LIB.MLB/ ; The recall command buffer is located in the CLI private area (work ; area). There is a pointer to the CLI private area in the process ; permanent data (ppd) area. The system has a global symbol definition ; of the start of the ppd so its best to begin there and then get ; pointers to the recall buffer. .PSECT DATA,WRT,NOEXE OUTFAB: $FAB FNM = ,- ; Primary output filename FOP = CTG,- ; Make contiguous file FAC = ,- ; Open for PUT operations SHR = ,- ; Exclusive file access MRS = REC_SIZE,- ; Maximum record size RAT = CR,- ; Implied carriage control XAB = DEF_XAB ; Address of start of XAB chain OUTRAB: $RAB FAB = OUTFAB,- ; Pointer to FAB ROP = WBH,- ; Write behind option RBF = REC_BUF ; Output gets data from here REC_SIZE = 1029 ; Maximum record size PPD$L_PRC = ^X08 ; Displ into ppd for cli ptr PRC_G_COMMANDS = ^X133 ; Displ into cliarea for rec ptr PRC_L_RECALLPTR = ^X12F ; Displ to current command ptr DEF_XAB: $XABPRO PRO = ; File prot=s:rwed,o:rwed,g:,w: REC_BUF: .BLKB REC_SIZE-4 ; Record buffer RECALL_PTR: .LONG 0 ; Save current command pointer ; Note: REC_BUFF and RECALL_PTR ;... are stored as one record ;******************************************************************************* .PSECT CODE,NOWRT,EXE .ENTRY SAVERB,^M ; Save reg's 2-7,10,11 ; Delete the last copy of sys$login:recall_buffer.dat so that there is ; no build up of unwanted files. Then create, open and connect to a ; new version of sys$login:recall_buffer.dat. $ERASE FAB=OUTFAB ; Delete last copy of data file MOVL #4,OUTFAB+FAB$L_ALQ ; Allocate 4 blocks for output $CREATE FAB=OUTFAB ; Create and open output file BLBC R0,EXIT3 ; Quit on error $CONNECT RAB=OUTRAB ; Connect to output BLBS R0,WRITE ; Branch to read loop BRB EXIT4 ; Trap connect-error EXIT3: MOVAL OUTFAB,R6 ; Keep fab address BRB F_ERR ; Signal record error EXIT4: MOVAL OUTRAB,R6 ; If error retain rab address BRB R_ERR ; Signal record error ; The recall command buffer will be saved byte for byte as it exists ( and ; when restored it will be restored byte for byte) . There is a pointer in ; the cli private storage area that points to the start of the buffer, get it. ; There is also a pointer that keeps track of the current command, this pointer ; must also be retrieved and saved. WRITE: MOVAB G^CTL$AG_CLIDATA,R10 ; Get address of ppd MOVL PPD$L_PRC(R10),R11 ; Get addr of cli privatestorage MOVL PRC_L_RECALLPTR(R11),RECALL_PTR ; Get current command pointer MOVAB PRC_G_COMMANDS(R11), R7 ; Get start addr of recall buf MOVC3 #1025,(R7),REC_BUF ; Move buffer to temp storage MOVW #1029,OUTRAB+RAB$W_RSZ ; Size of output record $PUT RAB=OUTRAB ; Write the record BLBC R0,EXIT4 ; Quit on error BRB DONE ; Finished, so cleanup and stop F_ERR: PUSHL FAB$L_STV(R6) ; Push stv and sts of fab PUSHL FAB$L_STS(R6) ; on the stack CALLS #2,G^LIB$SIGNAL ; Signal error BRB EXIT ; R_ERR: PUSHL RAB$L_STV(R6) ; Push stv and sts of rab PUSHL RAB$L_STS(R6) ; on the stack CALLS #2,G^LIB$SIGNAL ; Signal error DONE: $CLOSE FAB=OUTFAB ; Close output file EXIT: RET ; Return with status in r0 .END SAVERB