Article 134680 of comp.os.vms:
Path: nntpd.lkg.dec.com!eps.enet.dec.com!vandenheuvel
From: vandenheuvel@eps.enet.dec.com (Hein RMS van den Heuvel)
Newsgroups: comp.os.vms
Subject: Re: Mailing Word .doc's etc. with VMS ?
Date: 22 NOV 95 18:10:50
Organization: Digital Equipment Corporation
Lines: 225
Message-ID: <490ast$jlm@nntpd.lkg.dec.com>
References: <01HXSLFVZVMQ8WWLZG@kopc.hhs.dk> <48tdo8$s17@gap.cco.caltech.edu>
NNTP-Posting-Host: heer.enet.dec.com


In article <48tdo8$s17@gap.cco.caltech.edu>, mathog@seqaxp.bio.caltech.edu writes...
  :
>This is a little off the subject, but this thread does bring up the need
>for the following command, an alternate form of SET FILE/ATTRIB: 
> 
>  $ set file/fdl=rms.fdl file

Just for grins, I hacked up the DFU freeware sources to do just that
to the extend that FDL quailifiers are avialable and applicable.
It seems to do the trick, but admittedly I only tested a handfull
of FDL combinations.

Here are the CLD file changes.

************
File H1:[VANDENHEUVEL.DFU.SRC]DFU_TABLES.CLD;41
  189   	QUALIFIER	fdl,VALUE(REQUIRED,type=$file)
  190   	QUALIFIER	eblock,nonnegatable,value(type=$number)
******
File H1:[VANDENHEUVEL.DFU.SRC]DFU_TABLES.CLD;40
  189   	QUALIFIER	eblock,nonnegatable,value(type=$number)

That was simple huh? :-)

The edits to DFU_FILEDIR.C were of course a bit more significant,
all the more as I opted to replace "unsigned char attrib[32]" for
the record attributes by a more readable structure fixing a bug.
The remainder of this message contains formatted differences
as the whole source for the module are a bit big.

waddaya think?			+--------------------------------------+
Hein van den Heuvel, Digital.	| All opinions expressed are mine, and |
  "Makers of VMS and other	| may not reflect those of my employer |
   fine Operating Systems."	+--------------------------------------+

NEW_DFU_FILEDIR.C
{ struct FAB fab, *fdlfab;
  struct RAB *fdlrab;
  struct NAM nam;
  struct XAB *xab;
  static struct fibdef fib;
OLD_DFU_FILEDIR.C
{ struct FAB fab;
  struct NAM nam;
  static struct fibdef fib;

NEW_DFU_FILEDIR.C
    fname[255], lname[255], dummy[80], ans[4];
  unsigned int func, x, bad, dir, lock, log, cont, rvcount,
OLD_DFU_FILEDIR.C
   71       fname[255], dummy[80], ans[4];
   72     unsigned int func, x, bad, dir, lock, log, cont, rvcount,

NEW_DFU_FILEDIR.C
  static struct {
    unsigned char  rtype, rattrib;
    unsigned short rsize;
    unsigned int   hiblk, efblk;
    unsigned short ffbyte;
    unsigned char  bktsize, vfcsize;
    unsigned short maxrec, defext, gbc, fill[4], versions; } attrib;

  Boolean matfile, matbadacl, matdir, matupdate, matlock, matcont, matbakdate,
OLD_DFU_FILEDIR.C
   76     static unsigned char attrib[32];
   77     Boolean matfile, matbadacl, matdir, matupdate, matlock, matcont, matbakdate,

NEW_DFU_FILEDIR.C
    matebyte, mateblock, matconfirm, matfdl, matlike;
  static struct { unsigned short atr_size, atr_type;
OLD_DFU_FILEDIR.C
   82       matebyte, mateblock, matconfirm;
   83     static struct { unsigned short atr_size, atr_type;

NEW_DFU_FILEDIR.C
  $DESCRIPTOR(lname_descr , lname);
  $DESCRIPTOR(dummy_descr , dummy);
OLD_DFU_FILEDIR.C
   94     $DESCRIPTOR(dummy_descr , dummy);

NEW_DFU_FILEDIR.C
/* CHeck for FDL file */
  status = parse_item("fdl", &lname_descr, 0 , &matfdl, 0);
  if (matfdl) {
    status = fdl$parse ( &lname_descr, &fdlfab, &fdlrab,&1); /* signal */
    if (!(status&1)) return status;
    }

/* Get all the over-riding attributes */
  status = parse_item("confirm", &dummy_descr, 0 , &matconfirm, 2);
OLD_DFU_FILEDIR.C
  111   /* Get all the attributes */
  112     status = parse_item("confirm", &dummy_descr, 0 , &matconfirm, 2);

NEW_DFU_FILEDIR.C
      if (ans[0] == 'y') {

/* Now modify all the fdl specified attributes.
** There is a choice between blindly taking any field found in FAB or XAB
** and just setting those field with none-zero values. The information 
** whether a certain field was specified in the FDL or defaulted is not
** accessible outside FDL itself. Current choice is to blindly apply FAB
** but selectivly apply date's
** note: fab$v_ctg and fab$l_alq are NOT copied
*/

  if (matfdl) {
	    
    struct { int lo, hi; } *mydate;

/* FAB fields */

    uchar = uchar | FH2$M_CONTIGB; /* Only bother to set the bit if set */
    attrib.bktsize = fdlfab->fab$b_bks;
    attrib.defext  = fdlfab->fab$w_deq;
    attrib.bktsize = fdlfab->fab$w_gbc;
    attrib.rtype = fdlfab->fab$b_rfm + (16 * fdlfab->fab$b_org);
    attrib.rattrib = fdlfab->fab$b_rat;
    attrib.vfcsize = fdlfab->fab$b_fsz;
    xab = (void *) fdlfab->fab$l_xab;
    while (xab != NULL) {
	switch (xab->xab$b_cod)
	{
	    /* one could also count XAB$C_KEYs in this loop */	    

/* XABDAT fields */
	    case XAB$C_DAT:
		{
		struct XABDAT *x;
		x = (void *) xab;
	        if (x->xab$w_rvn) ascdates.date[0] = x->xab$w_rvn;
		mydate = &x->xab$q_bdt;
		if (mydate->hi) memcpy(&bakdate, mydate, 8);
		mydate = &x->xab$q_rdt;
		if (mydate->hi) memcpy(&revdate, mydate, 8);
		mydate = &x->xab$q_edt;
		if (mydate->hi) memcpy(&expdate, mydate, 8);
		mydate = &x->xab$q_cdt;
		if (mydate->hi) memcpy(&credate, mydate, 8);
		break;
		}
	    case XAB$C_RDT:
		{
		struct XABRDT *x;
		x = (void *) xab;
	        if (x->xab$w_rvn) ascdates.date[0] = x->xab$w_rvn;
		mydate = &x->xab$q_rdt;
		if (mydate->hi) memcpy(&revdate, mydate, 8);
		break;
		}
	}   /* switch */
	xab = xab->xab$l_nxt;
      }	    /* while xab's */
  }	    /* matfdl */

/* Now modify all the explicitly specified  attributes */

        rtype = attrib.rtype % 16;
        fileorg = attrib.rtype - rtype;
        fileorg = fileorg / 16 ;
OLD_DFU_FILEDIR.C
  236   /* Now modify all the required attributes */
  237         if (ans[0] == 'y')
  238         { rtype = attrib[0] % 16;
  239           fileorg = attrib[0] - rtype;
  240           fileorg = fileorg / 16 ;

NEW_DFU_FILEDIR.C
        if (matebyte) attrib.ffbyte = ebyte;
        if (mateblock)
        { if (!matebyte) attrib.ffbyte = 0; /* Clear eof if not specified */
          hiblk = attrib.hiblk; /* Save highest block */
          if (eblock == 0) 
OLD_DFU_FILEDIR.C
  257           if (matebyte) memcpy(&attrib[12], &ebyte, 2);
  258           if (mateblock)
  259           { if (!matebyte) 
  260             { attrib[12] = 0; /* Clear eof byte if it was not specified */
  261               attrib[13] = 0;
  262             }
  263             memcpy(&hiblk, &attrib[4], 4); /* Save highest block */
  264             if (eblock == 0) 

NEW_DFU_FILEDIR.C
          attrib.efblk = hiblk;
        }
        if (matrvcount) ascdates.date[0] = rvcount;
        if (matrecsize) attrib.rsize = recsize;
        if (matbucksize) attrib.bktsize = (unsigned char) bucksize;
        if (matvfcsize) attrib.vfcsize = (unsigned char) vfcsize;
        if (matmaxrec) attrib.maxrec = maxrec;
        if (matnone) attrib.rattrib = 0;
        if (matfortran) attrib.rattrib = FAT$M_FORTRANCC;
        if (matimplied) attrib.rattrib = FAT$M_IMPLIEDCC;
        if (matprint) attrib.rattrib = FAT$M_PRINTCC;
        if (matnospan) attrib.rattrib = attrib.rattrib | FAT$M_NOSPAN;
        if (matfixed) rtype = FAT$C_FIXED;
OLD_DFU_FILEDIR.C
  269             memcpy(&attrib[8], &hiblk, 4);
  270           }
  271           if (matrvcount) ascdates.date[0] = rvcount;
  272           if (matrecsize) memcpy(&attrib[2],&recsize,2);
  273           if (matbucksize) attrib[14] = (unsigned char) bucksize;
  274           if (matvfcsize) attrib[15] = (unsigned char) vfcsize;
  275           if (matmaxrec) attrib[16] = (unsigned char) maxrec;
  276           if (matnone) attrib[1] = 0;
  277           if (matfortran) attrib[1] = FAT$M_FORTRANCC;
  278           if (matimplied) attrib[1] = FAT$M_IMPLIEDCC;
  279           if (matprint) attrib[1] = FAT$M_PRINTCC;
  280           if (matnospan) attrib[1] = attrib[1] | FAT$M_NOSPAN;
  281           if (matfixed) rtype = FAT$C_FIXED;

NEW_DFU_FILEDIR.C
        attrib.rtype = (unsigned char) (fileorg * 16) + 
         (unsigned char) rtype;
OLD_DFU_FILEDIR.C
  292           attrib[0] = (unsigned char) (fileorg * 16) + 
  293            (unsigned char) rtype;

NEW_DFU_FILEDIR.C
  if (matfdl) status = fdl$release ( &fdlfab, &fdlrab );
  return(1);
OLD_DFU_FILEDIR.C
  324     return(1);


