[mod.computers.vax] [oops!] more about directory files

GKN@SDSC.BITNET (Gerard K. Newman) (06/14/86)

[That last one got away from me a little too soon.  Let's try again.]

        From: Ed <Flint.Wbst@Xerox.COM>
        Subject: how to distinguish/create directory files with RMS ??
        Date: 10 Jun 86 14:43:09 EDT (Tuesday)

        I assume that I am missing something very basic, but after pouring
        through RMS manuals, I still don't have an answer.

        Can I determine that a file is a directory file or not simply by looking
        at some field in the fab/rab/xab/nam structures ?? Conversely, can I
        create a directory file simply by setting a bit in the same field (as
        opposed to using LIB$CREATE_DIR) ??

You're not missing anything;  the "I am a directory" bit isn't available in
any of the standard RMS data structures.  I found this out rather rudely
here recently when someone (not me) did a Set File/NoDirectory on our main
software directory, and then discovered that there is no Set File/Directory
command.

What you have to do is to issue a read attributes QIO against the file.  Take
the FID from the NAM block, stick it in a short-form FIB, and request the
ATR$C_UCHAR attributes in the attribute control list.  Bit FCH$M_DIRECTORY
indicates if the file is a directory or not.

Here is a simple program which will open a file and say "It is" or "It isn't"
a directory.  Define the logical name IN_FILE to point to the file you're
interested in (it's a quick-and-very-dirty program, but it works).

gkn

---------------------------------------
Arpa:   GKN%SDSC.BITNET@WISCVM.WISC.EDU
USPS:   Gerard K. Newman
        San Diego Supercomputer Center
        P.O. Box 85608
        San Diego, CA  92138
AT&T:   (619) 455-5076

------------------------------------cut here------------------------------------
        .Title  DirTest - See if a file is a directory
        .Ident  /01.000/
        .Default Displacement,Word

        .Library "SYS$LIBRARY:LIB.MLB"  ;Get $FCHDEF from here

        .NoCross

        $IODEF                          ;Define I/O function codes
        $RMSDEF                         ;Define RMS status codes
        $SSDEF                          ;Define system service codes
        $FIBDEF                         ;Define File Information Block offsets
        $FCHDEF                         ;Define file characteristics bits
        $ATRDEF                         ;Define file attributes

        .Cross

        .Psect  DATA    NOEXE,RD,WRT,PIC,NOSHR,PAGE

; FAB to open the file

FAB:            $FAB    FNM=<IN_FILE:>,- ;FAB for the input file
                        FOP=<UFO>,-     ;Just open the file for me.
                NAM=NAM                 ;Need a name block
NAM:            $NAM                    ;Here it is

; FIB descriptor and FIB

FIB_DESC:       .Long   FIB_END-FIB     ;Length of the FIB
                .Address FIB            ;Address of the FIB

FIB:            .Long   0               ;FIB$L_ACCTL and FIB$B_WSIZE
FID:            .Blkw   3               ;FIB$W_FID:  File ID
DID:            .Blkw   3               ;FIB$W_DID:  Directory ID
                .Blkl                   ;FIB$L_WCC:  Wildcard context
                .Word   FIB$M_FINDFID   ;FIB$W_NMCTL:  File name control bits
FIB_END:                                ;Mark the end of the FIB

; Attribute descriptor list

ATTR_LIST:      .Word   ATR$S_UCHAR,ATR$C_UCHAR ;4 byte file characteristics
                .Address UCHAR          ;Put 'em here
                .Long   0               ;That's all

UCHAR:          .Blkl                   ;Will receive the file attributes
IOSB:           .Blkq                   ;I/O status for IO$_ACCESS

IS:             .Ascid  "File is a directory file"
ISNT:           .Ascid  "File is not a directory file"

        .Psect  CODE    EXE,RD,NOWRT,PIC,SHR,PAGE

        .Entry  START,0

        $OPEN   FAB=FAB                 ;Open the file
        BLBC    R0,20$                  ;Oh well.

; Copy the FID and DID into the FIB (how's that for alphabet soup?)

        MOVL    NAM+NAM$W_FID,FID       ;Copy the
        MOVW    NAM+NAM$W_FID+4,FID+4   ; FID
        MOVL    NAM+NAM$W_DID,DID       ;Copy the
        MOVW    NAM+NAM$W_DID+4,DID+4   ; DID
        MOVAL   ATTR_LIST,R1            ;Address the attribute control list
        $QIOW_S CHAN=FAB+FAB$L_STV,-    ;Do some I/O on this channel
                FUNC=#IO$_ACCESS,-      ;Access the file
                IOSB=IOSB,-             ;I/O status here
                P1=FIB_DESC,-           ;Here's the FIB
                P5=R1                   ;Return these attributes
        MOVZWL  IOSB,R0                 ;Get the status from the XQP
        BLBC    R0,20$                  ;Eeek!
        MOVAQ   ISNT,R0                 ;Presume it's not a directory
        BBC     #FCH$V_DIRECTORY,UCHAR,10$ ;Branch if we were correct
        MOVAQ   IS,R0                   ;Else it is.

10$:    PUSHL   R0                      ;Stack the message descriptor address
        CALLS   #1,G^LIB$PUT_OUTPUT     ;Display a message

20$:    RET                             ;Back to DCL (cleanup done by rundown)


        .End    START