From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 13-MAY-1994 10:08:19.64
To:	EVERHART
CC:	
Subj:	Re: bound volume sets

From: vandenheuvel@eps.enet.dec.com (Hein RMS van den Heuvel)
X-Newsgroups: comp.os.vms
Subject: Re: bound volume sets
Date: 8 MAY 94 00:39:31
Organization: Digital Equipment Corporation
Lines: 117
Message-Id: <2qhr7h$568@jac.zko.dec.com>
Nntp-Posting-Host: EPSYS
To: Info-VAX@CRVAX.SRI.COM
X-Gateway-Source-Info: USENET


In article <01HC0JQ82F2E8Y51TC@SC.Siliconix.Com>, Norm Donovan X5678 <Norm.Donovan@Siliconix.Com> writes...
:
>To get arround this, and since VMS lacks a CRE/DIR/SIZE= command, we had
>to:
> 
> 1.  Create the .DIR
> 2.  Fill it with long named files.
> 3.  Delete all of the files.

Agreed, there is room for improvement here. The proposed workaround will 
work, but can become extremly painfull for directories say > 2K blocs.
Here is how I tackled it when faced with the need of pre-allocating
a very large directory. First I tried a similar scheme as above, but
using $set file/entr=very_long_name.and_then_some x.y to avoid having
to manipulate actual files. That still was not good enough. Took out 
the big hammer...	
	Create a .dir, any .dir.
	Set file /nodir that dir.
	Copy/cont/all=nnnn that.dir target.dir
	Run program (hack!) to re-mark as directory.
I'll include the source for this utterly unsupported, but functinal hack.
If I was to need this at a regular basis then I would
	- Submit an SPR (or QAR) to articulate my needs.
	- Roll my own routine, using LIB$CREATE_DIR to create template or
	  Use FDL$CREATE with the 'right' FDL string (or file) to create 
	  a file that has the desired attributes and then mark it.


Hope this helps,               +--------------------------------------+
                               | All opinions expressed are mine, and |
Hein van den Heuvel            | may not reflect those of my employer |
vandenheuvel@eps.enet.dec.com  +--------------------------------------+

#include atrdef
#include fibdef
#include fCHdef
#include iodef
#include rms
#include stdio
#include stdlib
#include string

main(argc,argv)
int argc;
char *argv[];
    {
    char usage[] = "Usage: $ SET_DIR filename\n";
    char *ebkptr, *ffbptr;
    int status, channel;
    int file_ebk, spec_ebk, file_nbytes, spec_nbytes;
    int spec_block, spec_byte;
    short file_ffb, spec_ffb;
    struct FAB fab;
    struct NAM nam;
    struct { short status; char not_used[6]; } iosb;
    struct { short count; short not_used; long address; } fibdes;
    struct fibdef fib;
    struct atrdef atr[2];
    int uchar;

    if (argc != 2) printf("%s",&usage), exit(1);

/*  Use RMS to open the file so that we get a channel number, which is
    required by the QIO */

    fab = cc$rms_fab;
    fab.fab$l_fna = argv[1];
    fab.fab$b_fns = strlen(fab.fab$l_fna);
    fab.fab$b_fac = FAB$M_GET | FAB$M_PUT;
    fab.fab$l_fop = FAB$M_UFO;
    fab.fab$b_org = FAB$C_SEQ;	/* ebk and ffb are only valid for seq files */
    fab.fab$l_nam = &nam;

    nam = cc$rms_nam;

    if (((status=sys$open(&fab)) & 1) != 1) lib$stop(status);
    channel = fab.fab$l_stv;   /* got the channel number and FID */

/*  Set up the structures required for the ACP interface */

    fibdes.count = sizeof(fib);
    fibdes.address = &fib;

    fib.fib$r_acctl_overlay.fib$l_acctl  = ( FIB$M_WRITE );
    fib.fib$r_fid_overlay.fib$r_fid_fields.fib$w_fid_num =
	nam.nam$w_fid[0];
    fib.fib$r_fid_overlay.fib$r_fid_fields.fib$w_fid_seq =
	nam.nam$w_fid[1];
    fib.fib$r_fid_overlay.fib$r_fid_fields.fib$r_fid_rvn_overlay.fib$w_fid_rvn =
	nam.nam$w_fid[2];

    atr[0].atr$w_type  = ATR$C_UCHAR;
    atr[0].atr$w_size  = ATR$S_UCHAR;
    atr[0].atr$l_addr  = &uchar;
    atr[1].atr$w_type  = 0;
    atr[1].atr$w_size  = 0;

/*  Get the file's current uchar */

    status = SYS$QIOW(0,channel,IO$_ACCESS,&iosb,0,0,&fibdes,0,0,0,&atr,0);
    if ((status & 1) != 1) lib$stop(status);
    if ((iosb.status & 1) != 1) lib$stop(iosb.status);

/*  Set the new uchar */

    uchar |= FCH$M_DIRECTORY;

    status = SYS$QIOW(0,channel,IO$_MODIFY,&iosb,0,0,&fibdes,0,0,0,&atr,0);
    if ((status & 1) != 1) lib$stop(status);
    if ((iosb.status & 1) != 1) lib$stop(iosb.status);

/*  Release the file */

    status = SYS$QIOW(0,channel,IO$_DEACCESS,&iosb,0,0,&fibdes,0,0,0,0,0);

    }

