.TITLE SRDOPR-OPEN & READ .IDENT -6.62- ; Nov-87 .ENABL LC ;+ ; ;**SRD--SORT DIRECTORY ; ;THIS MODULE OPENS THE UFD AND READS IT INTO MEMORY ;- ; ; MODIFICATIONS: ; ; CEF001 -- 1-June-83 ; ADD .PSECTS ; ; ; VERSION 6.4 - 07-Nov-83 (;BT003) ; ; Bob Turkelson ; SRD Working Group ; ; Correct calculation of number of memory blocks to extend ; task so that upper bits are cleared if sign bit propagation ; has occurred. (Previously had memory protection violation ; for a sufficiently large directory since task would shrink.) ; Added the /FO:[g,m] switch to select files by file owner, with ; /FO defaulting to files owned by the directory being listed; ; may be negated to select files with different file owners. ; Form a UIC string when the directory is opened in SRDOPR for ; use in UIC headings and diagnostic messages. ; ; ; VERSION 6.5 - 16-Jan-85 (;WG001) ; ; SRD Working Group ; ; Add support for named directories. ; ; Version 6.62 - 28-Nov-1987 (;bfb001) ; ; Barton F. Bruce / Cambridge Computer Associates, Inc. ; ; redefine F$$DVN and N$$DIR to indicate that support is ; desired subject to FEAT$ saying it is present in the SYSTEM. ; New bits are in FEATSW. ;; ; ;= ; ;SYSTEM MACRO CALLS ; .PSECT SRDATA,D,RW,LCL,CON,REL ;CEF001 .MCALL OFNB$,QIOW$S .GLOBL SRDOPR BUFSZ: .WORD 0 ; Real Size of Buffer .IF DF R$$11M&D$$CAL ; .MCALL EXTK$S ; .ENDC ;R$$11M&D$$CAL .PSECT SRDCOD,I,RO,LCL,CON,REL ;CEF001 SRDOPR: CLR LENNTV ; Zero length of name-type-version ;BT003 TST F.BDB+UFDFDB ; DIRECTORY ALREADY OPEN (FROM LAST PIECE)?? BNE 10$ ; YES MOVB #FO.RD!FA.SHR,F.FACC+UFDFDB ;ASSUME ONLY READ ACCESS BIT #WBSW,SWMS2$ ;DOES HE WANT IT WRITTEN BACK? BEQ 5$ ;BR IF NO MOVB #FO.MFY,F.FACC+UFDFDB ;REQUEST ACCESS OF FILE FOR MODIFY 5$: OFNB$ #UFDFDB ;OPEN THE DIRECTORY BCC 7$ ;THIS SHOULD WORK! CMPB #IE.PRI,F.ERR+UFDFDB ; PRIV ERROR ??? BEQ 6$ FERR DOERR ; NO--SOME OTHER ERROR 6$: FERR DPRIV ; YES ; 7$: MOV UFDFDB+F.FNB+N.FID,SAVDID ; Save Directory ID MOV UFDFDB+F.FNB+N.FID+2,SAVDID+2 ; MOV UFDFDB+F.FNB+N.FID+4,SAVDID+4 ; MOV #UFDFDB+F.FNAM,R3 ; Point to first half of directory name ;BT003 bit #featnd,featsw ; If named directories supported ;bfb001 beq 71$ ; br no ;bfb001 MOVB #200,GRPBIN ; Named directories are assumed to ;WG001 MOVB #200,GRPMEM ; have UIC [200,200] ;WG001 br 72$ ;bfb001 71$: MOV (R3)+,R1 ; Get first half of directory name (group) ;BT003 MOV #GRPASC,R0 ; Point to area for ASCII string for group ;BT003 CALL $C5TA ; Convert group from RAD50 to ASCII ;BT003 INC R0 ; Jump over byte between group, member strings ;BT003 MOV (R3),R1 ; Get last half of directory name (member) ;BT003 CALL $C5TA ; Convert member from RAD50 to ASCII ;BT003 MOV #GRPASC,R0 ; Point to ASCII string for group ;BT003 CALL $COTB ; Convert group to binary ;BT003 MOVB R1,GRPBIN ; Store group number (binary) ;BT003 CALL $COTB ; Convert member to binary ;BT003 MOVB R1,MEMBIN ; Store member number (binary) ;BT003 72$: BIT #FOSW,SWMS3$ ; File owner checking specified? ;BT003 BEQ 701$ ; EQ - no ;BT003 MOVB FOGBF$,FOGRP$ ; Get first value from /FO switch ;BT003 MOVB FOMBF$,FOMEM$ ; Get second value from /FO switch ;BT003 TSTB FOGRP$ ; Wild card group specified? ;BT003 BNE 701$ ; NE - no ;BT003 TSTB FOMEM$ ; Wild card member specified? ;BT003 BNE 701$ ; NE - no ;BT003 MOVB GRPBIN,FOGRP$ ; Both wild cards means use directory group ;BT003 MOVB MEMBIN,FOMEM$ ; and member in /FO and /-FO selection ;BT003 701$: MOV #UICHD,R0 ; Point to UIC string for heading ;BT003 MOVB #'[,(R0)+ ; Move in UIC delimiter ;BT003 bit #featnd,featsw ; If named directories supported ;bfb001 beq 73$ ; br no ;bfb001 MOV UFDFDB+F.FNAM,R1 ; Get first part of directory name ;WG001 CALL $C5TA ; Convert first three characters to ASCII ;WG001 MOV UFDFDB+F.FNAM+2,R1 ; Get next part of directory name ;WG001 CALL $C5TA ; Convert next three characters to ASCII ;WG001 MOV UFDFDB+F.FNAM+4,R1 ; Get last part of directory name ;WG001 CALL $C5TA ; Convert last three characters to ASCII ;WG001 703$: CMPB -(R0),#<' > ; Trim trailing blanks ;WG001 BEQ 703$ ;WG001 INC R0 ; Point to next character position in string ;WG001 br 74$ ;bfb001 73$: MOVB GRPBIN,R1 ; Get directory group (binary) ;BT003 CLR R2 ; Set leading zero suppression flag ;BT003 CALL $CBTMG ; Convert byte to ASCII ;BT003 MOVB #',,(R0)+ ; Move in separator ;BT003 MOVB MEMBIN,R1 ; Get directory member (binary) ;BT003 CLR R2 ; Set leading zero suppression flag ;BT003 CALL $CBTMG ; Convert byte to ASCII ;BT003 74$: MOVB #'],(R0)+ ; Terminate UIC ;BT003 CLRB (R0) ; Indicate end of string ;BT003 10$: MOV DIRBF$,F.BKDS+2+UFDFDB ;POINT AT START OF BUFFER CLR @DIRBF$ MOV F.EFBK+2+UFDFDB,R1 ; IS BUFFER LARGE ENOUGH ? SUB F.BKVB+2+UFDFDB,R1 INC R1 BEQ 15$ TST F.FFBY+UFDFDB BNE 15$ DEC R1 15$: CMP R1,#127. ; Will it overflow on the calculation? BLOS 16$ ; If LOS no - carry on MOVB #127.,R1 ; Yes - use a smaller value ; (we'll get the rest later) ; 16$: SWAB R1 ASL R1 ; R1 = DIRECTORY SIZE IN BYTES MOV R1,R3 ; SAVE THAT FOR IO OPERATION BNE 18$ ; NE - non-zero length directory ;BT003 JMP 99$ ; Skip over zero length directory ;BT003 18$: ;BT003 MOV R3,BUFSZ ; Save real buffer size CMP R3,MINSZ$ ; Less than minimum size? BHIS 17$ ; If HIS no - carry on MOV MINSZ$,R3 ; Yes - use minimum ; 17$: ; Initialize buffer pointer and block number MOV DIRBF$,R4 ; SAVE BEGINNING OF BUFFER. MOV UFDFDB+F.BKVB+2,R5 ; REMEMBER CURRENT BLOCK NUMBER. BNE 20$ ; If NE OK - carry on INC R5 ; Else set to 1 ; 20$: .IF DF R$$11M&D$$CAL ; IF ON RSX11M AND DYNAMIC ... CLR DIRIC$ ; ... THEN CLEAR EXTENSION INCREMENT. .ENDC ;R$$11M&D$$CAL 30$: MOV DIRBE$,R0 ; GET TOP OF EXISTING BUFFER SUB R4,R0 ; FIND SIZE OF EXISTING BUFFER .IF DF R$$11M&D$$CAL ; IF RSX11M AND DYNAMIC ALLOCATION... BIC #^O77,R0 ; REDUCE BUFFER TO 64 BYTES. .ENDC ;R$$11M&D$$CAL ; MOV R3,R1 ; GET REMAINING BYTES TO READ IN. SUB R0,R1 ; GET NEEDED - BUFFERSIZE .IF DF R$$11M&D$$CAL ; If on RSX-11M and dynamic checkpoint alloc ;BT003 BEQ 40$ ; BR IF NO ADJUSTMENT NEEDED. MOV R0,R2 ; Save size of existing buffer ;BT003 MOV R1,R0 ; GET ACTUAL NUMBER OF BYTES TO ADJUST. .REPT 6 ; ASR R0 ; CONVERT TO 64 BYTE BLOCK .ENDR ;6 ; Here we need to clear the upper bits of R0 (the number of 64-byte blocks to ;BT003 ; extend or shrink the task) if the task is being extended by more than ;BT003 ; 100000 octal bytes since the shift-right instructions propagate the sign ;BT003 ; bit (otherwise the task would shrink rather than expand). However, we can ;BT003 ; not clear these bits if the task really should shrink. ;BT003 ; If the existing buffer size is >= 100000 octal bytes, or if the number of ;BT003 ; bytes to read is less than 100000, we won't be expanding by 100000 bytes ;BT003 ; or more, so there is no need to clear the upper bits. ;BT003 ; If the buffer size is less than 100000 and the number of bytes to read is ;BT003 ; at least 100000, the task will definitely expand rather than shrink, so ;BT003 ; it does not hurt to clear the upper bits (and is necessary if the extension ;BT003 ; is at least 100000). ;BT003 TST R2 ; Is existing buffer size >= 100000 octal bytes?;BT003 BLT 33$ ; LT - yes, no need to clear upper bits ;BT003 TST R3 ; Is number of bytes to read < 100000 octal? ;BT003 BGE 33$ ; GE - yes, no need to clear upper bits ;BT003 BIC #176000,R0 ; Clear upper bits in case sign bit propagated ;BT003 33$: ;BT003 .IF NDF D$$CAL ; IF NO DYNAMIC ALLOCATION... BMI 40$ ; THEN DON'T TRY TO DECREASE. .ENDC ;D$$CAL EXTK$S R0 ; ASK FOR MORE OR LESS SPACE BCS 35$ ; SKIP ON ERROR IN EXTEND. ADD R1,DIRBE$ ; INCREMENT BUFFER POINTER. .IF DF D$$CAL ; IF DYNAMIC ALLOCATION ... ADD R0,DIRIC$ ; ACCUM AMOUNT GOTTEN. .ENDC ;D$$CAL ; BR 40$ ; AND READ IN THE DIRECTORY. 35$: EXTK$S #10 ; EXTEND BY 1000 (8) BCS 40$ ; SKIP IF NO MORE SPACE. .IF DF D$$CAL ; ADD #10,DIRIC$ ; ACCOUNT FOR SPACE. .ENDC ;D$$CAL ; ADD #1000,DIRBE$ ; AND ADD INTO THE END OF BUFFER. BR 35$ ; AND TRY FOR MORE SPACE. .ENDC ;R$$11M&D$$CAL ;BT003 ; Loop, reading in as much of the file ; as possible, compressing the buffer, ; then re-reading again. If we're unable to ; fit all the directory file into the buffer, ; then we'll quit with a fatal DIRB error. ; R0 - Used to calculate how many blocks read ; R1 - Points to the end of the buffer (For SRDCOM) ; R2 - Number of bytes to read ; R3 - Total size of directory in bytes ; R4 - Points to buffer to read into. ; R5 - Contains starting block number of read. 40$: MOV DIRBE$,R2 ; Get pointer to buffer end ; Check to see if buffer is large enough to ; read entire directory file into memory. SUB R4,R2 ; COMPUTE SIZE OF BUFFER. BLOS 41$ ; LOS - error, die BIC #777,R2 ; Block align CMP R2,#1000 ; Is there at least a block ? BHIS 42$ ; HIS - yes 41$: BR 80$ ; Use what we've got 42$: MOV BUFSZ,R3 ; Restore real size required CMP R2,R3 ; Is there enough space ? BLO 47$ ; LO - then enough space ; Buffer is large enough. Zero R3 so as to indicate ; that another read is not required. 45$: MOV R3,R2 ; Set length of read CLR R3 ; Show no more to read BR 48$ ; Set up the read to fill the buffer, then compress, ; and try again. 47$: SUB R2,R3 ; Adjust what's left ; Now read the directory buffer into memory. 48$: QIOW$S #IO.RVB,#UFDLUN,#DSKEFN,,#IOSB$,, MOVB IOSB$,UFDFDB+F.ERR ; IO WORK? BPL 50$ ; BR IF YES CMPB #IE.EOF,F.ERR+UFDFDB ;END-OF FILE??? BEQ 60$ ;CONTINUE IF YES! FERR REDE ;READ ERROR OF INPUT FILE ; Adjust pointers and set up to compress the ; dictionary. ; 50$: MOV R2,R0 ; GET AMOUNT JUST READ INTO R0 CLRB R0 ; CLEAN OUT LOW ORDER SWAB R0 ; ASR R0 ; COMPUTE NUMBER OF BLOCKS READ ADD R0,R5 ; ADJUST BLOCK POINTER. MOV R5,UFDFDB+F.BKVB+2 ; Store it MOV R3,-(SP) ; SAVE R3 MOV R5,-(SP) ; Save R5 ; Now compress the directory buffer MOV IOSB$+2,R1 ; GET END OF BUFFER ... ADD R4,R1 ; INTO R1. MOV R4,R2 ; GET BEGINNING INTO R2 CALL SRDCOM ; COMPRESS THE BUFFER. MOV R1,R4 ; RECOVER LAST ADDRESS IN BUFFER MOV (SP)+,R5 ; Recover Block Number MOV (SP)+,R3 ; RECOVER NUMBER OF BYTES TO BE READ BNE 30$ ; LOOP UNTIL WHOLE DIRECTORY READ ; OR UNTIL RUN OUT OF MEMORY. 60$: MOVB #IE.EOF,F.ERR+UFDFDB 80$: MOV R4,F.BKDS+2+UFDFDB ; SAVE END OF DIRECTORY. RETURN ; RETURN TO MAIN 99$: JMP LSTNX$ ; PROCEED TO NEXT DIRECTORY .END