![]() |
![]() HP OpenVMS Systemsask the wizard |
![]() |
The Question is: How can I determine, from a program, whether or not a specific filename is a directory file? I do not want to rely on the .DIR extension, because ordinary files can be created with .DIR, and directories can be renamed to something other than *.DIR;1 (alt hough they aren't very useful if you rename them that way, they still keep their "directory file" status). I also do not want to spawn off a "DIR/FULL" command and parse the output. Thanks!! The Answer is : Options include the following... struct stat st; if ( !stat(filename,&st) && S_ISDIR(st.st_mode) ) { /* this is a directory */ } Alternatively, check the directory bit via the I/O ACPCONTROL (XQP) interface. This interface is documented in the OpenVMS I/O User's Reference Manual, available via: http://www.openvms.digital.com:8000/ A (very primitive) Macro32 tool that sets the directory bit on a file (using the XQP interface) is included below. .title SETDIRBIT fixes the DIRECTORY bit ; ; this program is used to turn on the "DIRECTORY" bit in the ; file header. The file (more correctly, the directory) to be ; reset is specified by FID (file identification) and device. ; (The FID can be retrieved from a DIRECTORY/FULL command.) ; ; a) Put the FID into the "fid" buffer, below. ; ; b) The device the FID is from must also be plugged into ; the "dev" descriptor, below. ; ; The UCHAR field is protected -- see the I/O User's Reference ; Manual, Part I, ACP/QIO Interface. (SYSTEM or OWNER access ; to the file (the directory) is required.) ; ; 11-Apr-1988 Hoffman ; This was written up... No claims to style or content: ; intended simply to solve a one-shot problem. MINIMAL ; error checking and user-hostile! ; .library 'Sys$Library:LIB.Mlb' $atrdef ; File attribute definitions $fchdef ; File characteristics $fibdef ; File Information Block $iodef ; I/O definitions $ssdef ; System Service Definitions .psect data,wrt,noexe,long,noshr,usr fid: ; A file id (FID) looks like this: [NUM,SEQ,RVN] .word 652 ; file NUM .word 9 ; file SEQ .word 0 ; file RVN .word 0 ; (so we can use a MOVQ) ; dev: ; And the name of the disk the file id is from... .ascid /HSC000$DUA2:/ ; iosb: .blkw 4 ; garden variety IOSB ; fchan: .blkw 1 ; channel to the disk ; FIBSIZE=22 ; use the short FIB fibbuf: .blkb FIBSIZE ; here's the FIB itself fib: .long FIBSIZE ; here's the FIB descriptor .address fibbuf ; uchar: .blkb ATR$S_UCHAR ; the FAT characteristics buffer fat: ; The File Attributes itemlist follows: .word ATR$S_UCHAR ; length of the buffer .word ATR$C_UCHAR ; address of the buffer .address uchar ; where the UCHAR field is... .blkq 0 ; zero marks the end... ; .psect code,nowrt,exe,long,shr,usr .entry SETDIRBIT, ^M<R2> ; ; Get a channel to the device ; $ASSIGN_S - devnam=dev,- chan=fchan blbs r0,10$ ret ; 10$: ; ; Move the two important "bits" of trivia out to the FIB. ; moval fibbuf,R0 movq fid,FIB$W_FID(R0) movl #FIB$M_WRITE,FIB$L_ACCTL(R0) ; ; Access the file (directory) ; $QIOW_S - chan=fchan,- func=#<IO$_ACCESS!IO$M_ACCESS>,- iosb=IOSB,- p1=fib,- p5=#fat blbc r0,19$ blbs iosb,20$ 19$: ret ; 20$: ; ; Force the DIRECTORY bit on! ; bisl2 #FCH$M_DIRECTORY,uchar ; ; Write the modified characteristics out... ; $QIOW_S - chan=fchan,- func=#<IO$_MODIFY>,- iosb=IOSB,- p1=fib,- p5=#fat blbc r0,29$ blbs iosb,30$ 29$: ret ; 30$: ; ; And deaccess the file (directory) ; $QIOW_S - chan=fchan,- func=#<IO$_DEACCESS>,- iosb=IOSB blbc r0,39$ blbs iosb,40$ 39$: ret ; 40$: ; ; Deassign the channel to the disk ; $DASSGN_S - chan=fchan movzwl #SS$_NORMAL,R0 ; ; And bail out... ; ret .END SETDIRBIT Or you can check the bit using the following C example of an RMS call: #include <rms.h> #include <stdio.h> #include <string.h> typedef struct { short len, cod; void *address; int *retlen; } item; /* ** Author: Hein van den Heuvel ** Compaq Computer Corporation */ main (int argc, char *argv[]) { int stat, records, directory, SYS$OPEN(); char *is_not; struct FAB fab; struct XABITM itm; item uchar_items[] = { sizeof (int), XAB$_UCHAR_DIRECTORY, &directory, 0, 0, 0, 0, 0 } ; fab = cc$rms_fab; fab.fab$l_xab = (void *) &itm; fab.fab$b_shr = FAB$M_SHRUPD; fab.fab$b_fac = FAB$M_GET; fab.fab$l_fna = argv[1]; fab.fab$b_fns = strlen ( argv[1] ); itm.xab$b_bln = XAB$C_ITMLEN; /* no template available ?! */ itm.xab$b_cod = XAB$C_ITM; itm.xab$l_itemlist = (char *) &uchar_items; itm.xab$b_mode = XAB$K_SENSEMODE; itm.xab$l_nxt = 0; stat = SYS$OPEN ( &fab ); if (!(stat&1)) return stat; is_not = directory? "IS" : "is NOT"; printf ("File %s %s a directory\n", argv[1], is_not); return 1; }
|