.TITLE BROOM -- Disk Blanking Program. .IDENT /V01.0/ .NLIST ME,BEX,CND .ENABL LC .SBTTL Documentation Notes. ; Module Name: BROOM.MAC ; ; Programmer: Eric A. Johnson ; ; Date: 25-Jun-80 ; ; Version: 1.0 ; ; Residence: DB0:[377,23] ; ; For: System Security ; ; Core Requirements: 7K ; ; Machine/System: PDP11/70/IAS V03.0 ; ; Type/Language: MACRO-11 ; ; Indirect Command File: DB0:[377,23]BROOM.CMD ; ; Abstract: This program allocates a file on each mounted disk ; the size of which is equal to the number of free blocks ; on the volume, then writes a blank buffer to each block. ; This effectively erases the free space on the disk so that ; deleted files are truely deleted. BROOM allows two types ; of commands as follows: ; ; BRM> /AL ; ; instructs the program to clean every eligible Files-11 ; volume that is mounted for the user, including all system ; devices. The second form is; ; ; BRM> dev:,dev:,... ; ; where dev is a mounted Files-11 device only. It is strongly ; recommended that BROOM is only used on queisent devices as ; the program allocates every available block on the device ; to the temporary file. .SBTTL Local Macro Definitions. .MCALL QIOW$,DIR$,EXST$S,FDAT$R,OPNT$D,CLOSE$,NBOF$L,WAIT$ .MCALL FSRSZ$,FDBDF$,FDRC$A,FDBK$A,FDOP$A,NMBLK$,WRITE$ .MCALL GCMLB$,GCML$ .MCALL CSI$,CSI$SW,CSI$SV,CSI$ND,CSI$1,CSI$2 .MACRO PUSH,LIST .IRP .I., .IF IDN,<.I.>,<*> CLR -(SP) .IFF MOV .I.,-(SP) .ENDC .ENDR .ENDM .MACRO POP,LIST .IRP .I., .IF IDN,<.I.>,<*> TST (SP)+ .IFF MOV (SP)+,.I. .ENDC .ENDR .ENDM .MACRO PRINT,.BUFF.,.LEN.,.CCW. MOV .BUFF.,-(SP) MOV .LEN.,-(SP) .IF B .CCW. CLR -(SP) .IFF MOV .CCW.,-(SP) .ENDC CALL $OUT .ENDM .SBTTL Working storage and Symbol defs. LUN = 1 ; LUN for LG messeges. FILUN = 2 ; LUN for file. EX.ENA = 256. ; Value for FCS extend routine. $WRT: QIOW$ IO.WLB,LUN,1,100,,,<0,0,0> IOSTAT: .BLKW 2 ; I/O STATUS BLOCK FRBK: .BLKW 2 ; Free blocks on device OUTBUF: .BLKB 80. ; Messege output buffer. PATBUF: .BLKB 512. ; File output buffer. .SBTTL Get command line block CMDBLK: GCMLB$ 0,BRM,,LUN,,80. ;Define working storage for GCML. .SBTTL CSI block and table definitions. CSI$ .EVEN CSIBLK: .BLKB C.SIZE ;CSI working storage. CSIMSK: .WORD ;Word for switch settings. CSCH.A=1 ;/AL switch CSITBL: CSI$SW AL,CSCH.A,CSIMSK,SET ;Clean all F-11 devices. CSI$ND .SBTTL Messeges. FREMSG: .ASCIZ "BROOM -- Device %2A%O has %T blocks free." NSDMSG: .ASCIZ "BROOM -- %VA is not a mounted Files-11 device." OPNMSG: .ASCIZ "BROOM -- Error opening file on %2A%O:" FCSMSG: .ASCIZ "BROOM -- FCS Error %D." WRTMSG: .ASCIZ "BROOM -- Error encountered during WRITE$." WTEMSG: .ASCIZ "BROOM -- Error encountered on write completion." ERCMSG: .ASCII "BROOM -- Error processing command line." ERCMSL=.-ERCMSG .SBTTL FDB for cleanup file. .EVEN FSRSZ$ 1 ; Allocate FSR buffer. AJAX: FDBDF$ ; Allocate 1 FDB. FDRC$A FD.RWM ; Block I/O. FDBK$A PATBUF,512.,,,IOSTAT ; Init block access. FDOP$A FILUN,,FILNAM,FO.WRT!FA.TMP ; Define file open section. FILNAM: NMBLK$ CLEANER,TMP,,SY,0 ; Default Nameblock. .EVEN NBOF$L ; Define nameblock offsets. ; Define Volume control block offsets. V.TRCT = 0 ; Count of users on volume V.IFWI = 2 ; Index file window address V.STD = 4 ; V.FCB = 6 ; V.IBLB = 12 ; Start LBN of Index File Bitmap(high) V.IBSZ = 13 ; Number of blocks in bitmap V.FMAX = 16 ; Maximum number of files on volume V.WISZ = 20 ; Window size V.SBCL = 21 ; Storage bitmap cluster size V.SBSZ = 22 ; Number of blocks in storage bitmap V.SBLB = 24 ; Start LBN of Storage File Bitmap V.FIEX = 25 ; Default file extension increment V.FPRO = 30 ; Default file protection V.FRBK = 34 ; Free blocks on device V.LRUC = 35 ; Count of entries in directory LRU V.LABL = 40 ; Volume label V.STAT = 54 ; VC.IFW=1 ; VC.BMW=2 ; V.FFNU = 55 ; V.LGTH = 56 ; V.LENG = 12. ; Volume Label length. .sbttl Start of code, get command line. BROOM:: GCML$ #CMDBLK ;Get the command line. BCS CMDERR ;Go look at the error. CLR CSIMSK ;Clear the switch word CSI$1 #CSIBLK,CMDBLK+G.CMLD+2,CMDBLK+G.CMLD ;Init CSI block. BCS CMDERR ;Branch if error. TST CSIBLK+C.CMLD ;Anything to look at? BEQ BROOM ;Nope - try again. MOV #CSITBL,CSIBLK+C.SWAD ;Put address of switch table into blk. PRSDEV: CSI$2 #CSIBLK,OUTPUT ;Decode next command. BCS CMDERR ;Branch if error. CLR CSIBLK+C.SWAD ;Allow switches in first spec only. BITB #,CSIBLK+C.STAT ;Test for name or directory. BNE CMDERR ;Error if specified. BITB #CS.DVF,CSIBLK+C.STAT ;Was a device specified? BNE 10$ ;Branch if it was. BITB #CS.MOR,CSIBLK+C.STAT ;If no device, then /AL is the only... BNE CMDERR ; ...thing we can except in cmd. JMP PUDSCN ;If no more command, then /AL is OK. 10$: BIT #CSCH.A,CSIMSK ;If so, the /AL switch is not allowed. BNE CMDERR ;If it was, refuse to cooperate. JMP PUDSCN ;Else go find the PUD entry for dev. CMDERR: CMPB #GE.EOF,CMDBLK+G.ERR ;End of file from GCML? BEQ EXOUT ;Leave quietly if so. PRINT #ERCMSG,#ERCMSL,#40 ;Else error in command. BR BROOM ;Go try it again. ; All roads lead here. EXTERR: EXST$S #EX$ERR ;Exit with error status. EXOUT: EXST$S #EX$SUC ;Exit gracefully. .sbttl Start of the PUD scan. ; Scan the Physical Unit Directory looking for disk-like devices ; and clean them up when we find them. PUDSCN: MOV .PUDBA,R4 ;R4->Start of PUD. TOP: CMP .PUDEA,R4 ;Are we done yet? BNE CHKDEV ;No -- go check it out. ; When we reach the end of the PUD we'll drop through to here. BIT #CSCH.A,CSIMSK ;Was /AL switch specified? BNE EXOUT ;If so then we're all done. MOV #OUTBUF,R0 ;R0->Messege output buffer. MOV #NSDMSG,R1 ;R1->Format string. MOV #,R2 ;R2->Parameter block. CALL $EDMSG ;Make it beautiful. PRINT #OUTBUF,R1,#40 ;Couldn't find the device. JMP BROOM ;Go get next command line. ; Check this device. CHKDEV: ; First check for redirection. CMP U.RP(R4),R4 ;Redirected to self? BEQ CHKC1 ;Yup -- Real device. JMP NXTDEV ;Nope -- We don't want it. ; Now check Characteristics word #1. CHKC1: BIT #UC.DIR,U.C1(R4) ;Directory device? BEQ 10$ ;Nope -- Skip it. BIT #UC.SDI,U.C1(R4) ;Single directory device? BNE 10$ ;Yup -- Can't use it. BIT #UC.SQD,U.C1(R4) ;Sequential device? BNE 10$ ;Yup -- Useless to us here. BIT #UC.MNT,U.C1(R4) ;Mountable? BEQ 10$ ;Nope -- Leave it alone. BIT #UC.F11,U.C1(R4) ;Files-11 device? BNE CHKUF ;Yup -- C1 is ok, let's continue. 10$: JMP NXTDEV ;Can't use device, go try another. ; Check Flags byte. CHKUF: BITB #UF.OFL,U.FB(R4) ;Is controller off-line? BEQ CHKCH ;No -- continue. JMP NXTDEV ;Oh well, try another. ; Check Volume Characteristics byte. CHKCH: BITB #CH.LAB!CH.FOR,U.CH(R4) ;Is volume a labeled tape or foreign? BNE 10$ ;Neither condition is acceptable. BITB #CH.UNL!CH.OFF,U.CH(R4) ;Is dismount pending or vol off-line? BEQ CHKVCB ;Nope -- continue. 10$: JMP NXTDEV ;Go get a fresh daisy. ; Check for valid Volume Control Block. CHKVCB: MOV U.VA(R4),R5 ;R5->Volume Control Block. BNE CHKONE ;Not zero, we have a good one, horray! JMP NXTDEV ;Actually, we should warn them. ; Check to see if we desire to clean this device. CHKONE: BIT #CSCH.A,CSIMSK ;Are we doing all devices? BNE OKDEV ;Yup - Get to work. MOV CSIBLK+C.DEVD+2,R0 ;R0->Device string. CMPB U.DN(R4),(R0)+ ;Compare the device name. BNE 10$ ;Branch if not the same. CMPB U.DN+1(R4),(R0)+ ;Compare second character. BNE 10$ ;Branch if not the same. CALL $COTB ;Convert unit no. to binary. CMPB U.UN(R4),R1 ;Is it the right unit? BEQ OKDEV ;Yup - go do the dirty work. 10$: JMP NXTDEV ;Wrong unit, go look for another. .sbttl Clean Device. ; We have a device to clean-up now, so let's get to work. OKDEV: ; Print out a list of the devices that we will clean. MOVB V.FRBK(R5),FRBK ;Get total... MOV V.FRBK+2(R5),FRBK+2 ; ...free blocks. MOV #FRBK,-(SP) ;Push the address of double word. CLR -(SP) ;Prep the stack. MOVB U.UN(R4),(SP) ;Add the unit number. MOV R4,-(SP) ;And the device name. ADD #U.DN,(SP) ;Make sure we are there. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #FREMSG,R1 ;R1->Format String. MOV SP,R2 ;R2->Argument block. CALL $EDMSG ;Make it pretty. ADD #6,SP ;Clean the stack. PRINT #OUTBUF,R1,#40 ;Output the messege. ; Set up the FDB with the device name. 10$: MOV U.DN(R4),FILNAM+N.DVNM ;Set up the name blk with device. MOV U.UN(R4),FILNAM+N.UNIT ;Also the unit number. ; Define file attributes and attempt to open him. FDAT$R #AJAX,#R.FIX,#FD.BLK ;Fill in the FDB. OPNT$D #AJAX ;Open the big guy marked for delete. BCS OPNERR ;Go complain if problem. ; Now extend the file to include all free blocks on device. MOV FRBK+2,R1 ;R1 contains the 2 low order bytes. CLR R2 ;Clear R2 for extend operation. MOVB FRBK,R2 ;Set up high byte of file size. SUB #1,R1 ;Always leave a free block. SBC R2 ;Subtract a carry bit from hi byte. SWAB R2 ;It must be in high byte of R2 BIT #EX.ENA,R2 ;This is the type we want. CALL .EXTND ;Gobble it up. ; This is the beginning of the write loop. WRITLP: WRITE$ #AJAX,,,,#5 ;Attempt to write a block. BCS WRTERR ;Complain if problem. WAIT$ #AJAX,#5 ;Wait for I/O completion. BCC WRITLP ;If I/O was successful, go do another. ; Wait error response. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #WTEMSG,R1 ;R1->Format String. CALL $EDMSG ;Make it pretty. PRINT #OUTBUF,R1,#40 ;Output the messege. BR PUTFCS ;Go tell'em what kind it was. ; Write error response. WRTERR: CMPB #IE.DFU,AJAX+F.ERR ;End of file encountered? BEQ CLSOUT ;Yup -- That's what we're looking for. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #WRTMSG,R1 ;R1->Format String. CALL $EDMSG ;Make it pretty. PRINT #OUTBUF,R1,#40 ;Output the messege. ; Common code to write FCS error messege. PUTFCS: MOV #-1,-(SP) ;Ready the stack. MOVB AJAX+F.ERR,(SP) ;Push the FCS error. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #FCSMSG,R1 ;R1->Format String. MOV SP,R2 ;R2->Argument block. CALL $EDMSG ;Make it pretty. TST (SP)+ ;Clean the stack. PRINT #OUTBUF,R1,#40 ;Output the messege. ; Close the file cause we're done with him. He'll go away on his own. CLSOUT: CLOSE$ #AJAX ;Now close him. BIT #CSCH.A,CSIMSK ;Are we cleaning all devices? BNE NXTDEV ;Yup -- go look for another one. BITB #CS.MOR,CSIBLK+C.STAT ;Is there anymore in the cmd line? BEQ 10$ ;No, branch aid... JMP PRSDEV ;Else look at the command string. 10$: JMP BROOM ;Go get another command. ; We come here to complain if we couldn't open the file. OPNERR: CLR -(SP) ;Clear a word of the arg block. MOVB U.UN(R4),(SP) ;Push the unit number. MOV R4,-(SP) ;And the device name. ADD #U.DN,(SP) ;Make sure we are there. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #OPNMSG,R1 ;R1->Format String. MOV SP,R2 ;R2->Argument block. CALL $EDMSG ;Make it pretty. ADD #4,SP ;Clean the stack. PRINT #OUTBUF,R1,#40 ;Output the messege. MOV #-1,-(SP) ;Push the base on the stack. MOVB AJAX+F.ERR,(SP) ;Add the FCS error. MOV #OUTBUF,R0 ;R0->Output buffer. MOV #FCSMSG,R1 ;R1->Format String. MOV SP,R2 ;R2->Argument block. CALL $EDMSG ;Make it pretty. TST (SP)+ ;Clean the stack. PRINT #OUTBUF,R1,#40 ;Output the messege. JMP EXTERR ;Die a bad death. .sbttl Advance to next PUD entry. NXTDEV: ADD #U.SZ,R4 ;Point to next PUD entry. JMP TOP ;And start again. .sbttl $OUT -- Output line to TO: ; This subroutine will output a string to the terminal ; that is currently assigned to TO: $OUT: MOV 4(SP),$WRT+Q.IOPL+2 ; Set buffer length BEQ 10$ ; EQ - then skip I/O MOV 2(SP),$WRT+Q.IOPL+4 ; Set CCW word MOV 6(SP),$WRT+Q.IOPL ; Set buffer address DIR$ #$WRT ; Perform I/O 10$: MOV (SP),6(SP) ; Restore return address ADD #6,SP ; Clean up stack RETURN ; Return to whom called us .END BROOM