Article 149058 of comp.os.vms:
In article <4p9dv7$23j@rigel.rz.uni-ulm.de>,\
 franke@spica.rz.uni-ulm.de (Kurt Franke) writes...
[...]
>|>      The way to do what you want is use $QIOW to talk the disk XQP.  You
>|> can assign a channel once [per disk, that is] and then make an IO$_ACCESS
>|> query for each file to obtain its attributes.  It's more complicated than
>|> dealing with RMS, but the alternative is to actually open each file....
> 
> And now the unavoidable followup question.
> 
> Is there some example code doing this with $QIOW anywhere on the net ?

     This is a routine I wrote that got added into lynx 2.5; it's
intended to change a file's attributes to be defined as fixed-length
512 byte records with the contiguous-best-try flag set.  The is-a-
directory flag happens to be contained is the same longword as the
latter.  You wouldn't need element 0 of the attribute request list,
nor the associated `struct fabdef' code, and for your IO$_DEACCESS
call you'd omit the attribute request list altogether since you're
not changing the file.  You'll also need different values in the FAB
part of if stick with the RMS shortcut instead of switching to plain
SYS$ASSIGN.  (You'd want GET instead of PUT access, and to allow full
sharing, and you'd also want to set the no-record bit in the FIB prior
to IO$_ACCESS.)

     This routine isn't intended to process multiple files, so it
doesn't cache and reuse the channel to the disk.  If you're going to
be processing lots of files (which was more or less implied by your
original code fragment), you'll want to avoid extra $ASSIGN + $DASSGN
overhead.  But you won't be able to use RMS user-file-open ($OPEN)
in that case, so you'll need to set up the 48-bit file ID value in
the FIB block yourself.  You can get that straight from the NAM block
that you've already got.

		Pat Rankin, rankin@eql.caltech.edu
-----
#include <string.h>
#include <fab.h>
#include <rmsdef.h>             /* RMS status codes */
#include <iodef.h>              /* I/O function codes */
#include <fibdef.h>             /* file information block defs */
#include <atrdef.h>             /* attribute request codes */
#include <fchdef.h>             /* file characteristics */
#if 0
#include <fatdef.h>             /* file attribute defs */
#else
/* VMS I/O User's Reference Manual: Part I (V5.x doc set) */
struct fatdef {
    unsigned char       fat$b_rtype,    fat$b_rattrib;
    unsigned short      fat$w_rsize;
    unsigned long       fat$l_hiblk,    fat$l_efblk;
    unsigned short      fat$w_ffbyte;
    unsigned char       fat$b_bktsize,  fat$b_vfcsize;
    unsigned short      fat$w_maxrec,   fat$w_defext,   fat$w_gbc;
    unsigned    : 16, : 32, : 16;   /* 6 bytes reserved, 2 bytes not used */
    unsigned short      fat$w_versions;
};
#endif

/* arbitrary descriptor without type and class info */
typedef struct dsc { unsigned short len, mbz; void *adr; } Desc;

extern unsigned long    sys$open(),  sys$qiow(),  sys$dassgn();

#define syswork(sts)    ((sts) & 1)
#define sysfail(sts)    (!syswork(sts))


/*
 *      Force a file to be marked as having fixed-length,
 *      512 byte records without implied carriage control.
 */
unsigned long  vms_file_fixup ( char *filename )
{
    struct FAB      fab;                /* RMS file access block */
    struct fibdef   fib;                /* XQP file information block */
    struct fatdef   recattr;            /* XQP file "record" attributes */
    struct atrdef   attr_rqst_list[3];  /* XQP attribute request itemlist */

    Desc            fib_dsc;
    unsigned short  channel,  iosb[4];
    unsigned long   fchars,  sts,  tmp;

    /* initialize file access block */
    fab = cc$rms_fab;
    fab.fab$l_fna = filename;
    fab.fab$b_fns = (unsigned char) strlen(filename);
    fab.fab$l_fop = FAB$M_UFO;  /* user file open; no further RMS processing */
    fab.fab$b_fac = FAB$M_PUT;  /* need write access */
    fab.fab$b_shr = FAB$M_NIL;  /* exclusive access */

    sts = sys$open(&fab);       /* channel in stv; $dassgn to close */
    if (sts == RMS$_FLK) {
	/* For MultiNet, at least, if the file was just written by a remote
	   NFS client, the local NFS server might still have it open, and the
	   failed access attempt will provoke it to be closed, so try again. */
	sts = sys$open(&fab);
    }
    if (sysfail(sts)) return sts;

    /* RMS supplies a user-mode channel (see FAB$L_FOP FAB$V_UFO doc) */
    channel = (unsigned short) fab.fab$l_stv;

    /* set up ACP interface strutures */
    /* file information block, passed by descriptor; it's okay to start with
       an empty FIB after RMS has accessed the file for us */
    fib_dsc.len = sizeof fib;
    fib_dsc.mbz = 0;
    fib_dsc.adr = &fib;
    memset((void *)&fib, 0, sizeof fib);
    /* attribute request list */
    attr_rqst_list[0].atr$w_size = sizeof recattr;
    attr_rqst_list[0].atr$w_type = ATR$C_RECATTR;
    *(void **)&attr_rqst_list[0].atr$l_addr = (void *)&recattr;
    attr_rqst_list[1].atr$w_size = sizeof fchars;
    attr_rqst_list[1].atr$w_type = ATR$C_UCHAR;
    *(void **)&attr_rqst_list[1].atr$l_addr = (void *)&fchars;
    attr_rqst_list[2].atr$w_size = attr_rqst_list[2].atr$w_type = 0;
    attr_rqst_list[2].atr$l_addr = 0;
    /* file "record" attributes */
    memset((void *)&recattr, 0, sizeof recattr);
    fchars = 0;         /* file characteristics */

    /* get current attributes */
    sts = sys$qiow(0, channel, IO$_ACCESS, iosb, (void(*)())0, 0,
		   &fib_dsc, 0, 0, 0, attr_rqst_list, 0);
    if (syswork(sts))  sts = iosb[0];

    /* set desired attributes */
    if (syswork(sts)) {
	recattr.fat$b_rtype = FAB$C_SEQ | FAB$C_FIX;    /* org=seq, rfm=fix */
	recattr.fat$w_rsize = recattr.fat$w_maxrec = 512;   /* lrl=mrs=512 */
	recattr.fat$b_rattrib = 0;                      /* rat=none */
	fchars |= FCH$M_CONTIGB;                /* contiguous-best-try */
	sts = sys$qiow(0, channel, IO$_DEACCESS, iosb, (void(*)())0, 0,
		       &fib_dsc, 0, 0, 0, attr_rqst_list, 0);
	if (syswork(sts))  sts = iosb[0];
    }

    /* all done */
    tmp = sys$dassgn(channel);
    if (syswork(sts))  sts = tmp;
    return sts;
}


