[comp.os.vms] INDEX, Part 1 of 5

JOE@FHCRCVAX.BITNET (Joe Meadows) (09/11/87)

Hi,
A few weeks ago I promised to post a utility I was working on, which
I call INDEX. INDEX allows you to search through INDEXF.SYS based on
just about any thing stored in there. For those who are wondering,
INDEXF.SYS is where all the file headers are stored. I've put the help
file at the beginning of this series of "shar" files. You can cut and
execute each of the five parts by themselves, they are each approx. 30K
bytes. I will be sending them one part per day for the next five days.

  Cheers,
  Joe Meadows Jr.               bitnet - JOE@FHCRCVAX
  VAX/VMS System Manager / guru in training
  Fred Hutchinson Cancer Research Center
  1124 Columbia St.             arpa   - JOE%FHCRCVAX.BITNET@WISCVM.WISC.EDU
  Seattle Wa. 98104             voice  - (206) 467-4970

$ create/log INDEX.HLP
$DECK
! Last modified Sep. 11th, 1987 (minor changes)
1 INDEX
  INDEX [device-name]

    INDEX is a utility to allow you to display information about
  a file, based on information stored in the files header. INDEX
  operates in one of two modes, it either displays information
  read directly out of the index file, or it asks the disk ACP
  to return header information to it. The first mode of operation
  is used for general searches, and does not necessarily return
  the most current up to date information, as there may be many
  headers cached in memory, and thus out of synch with the index file.
  The second mode of operation is used when you specify a /FILE_ID
  or /FULLNAME qualifier, giving it an explicit list of files to
  work with. In this case it asks the disk ACP for the headers, thus
  getting the most current, up to date information available, if
  possible. Note that in either case, the index file is opened for
  read acces, thus to use this utility, you must have read access to
  the file [000000]INDEXF.SYS, and if using /FILE_ID or /FULLNAME
  you must also have read access to the requested files.

    INDEX takes one paramater, the name of the device whose index
  file is to be searched. If device-name is not specified it defaults
  to SYS$DISK (your current default disk). It correctly handles
  rooted device names, and can handle multi-volume disk sets.

  You may limit what files will be displayed by using the appropriate
  qualifiers. Most of the qualifiers that affect what files will be
  displayed allow a minimum and maximum value, if you do not specify
  a maximum value, then it is assumed you want all things greater than
  the minimum. If you want a specific value, than you must enter it as
  both the minimum and maximum value, i.e.
    $ INDEX/ALLOCATED=(1497,1497)
  would display all files with exactly 1497 blocks allocated.

2 Examples
  The following examples are meant to demonstrate some of the uses
  of INDEX.

3 ACL
  Suppose you are going delete a user, and you want to be sure that
  no one has a file that specifically refers to that user, you could
  specify:
    $ INDEX/DISPLAY=ACL/ACE=([USER1],[USER2],PROJECT$P001)
  This would display all files (and their access control lists) which
  had any ACLs that refered to the uic identifiers [USER1], [USER2],
  or the 'project' identifier PROJECT$P001
3 Activity
  Suppose you wanted to get an idea of disk usage, you could generate
  a report showing all the files created in a specified time period:
    $ INDEX/DISPLAY=(CREATION,ALLOCATED,USED)-
    $_ /CREATION=(YESTERDAY,TODAY)
  would display all files created today

  or all the files modified in a specifid time period:
    $ INDEX/DISPLAY=(CREATION,REVISION,ALLOCATED,USED)-
    $_ /REVISION=(YESTERDAY,TODAY)
  would display all files revised today
3 Big_Directories
  Suppose you want to find all the directory files that are bigger
  than 50 blocks, you could use:
    $ INDEX/DISPLAY=(USED,ALLOCATED) -
    $_ /CHARACTERISTICS=DIRECTORY/ALLOCATED=50/MATCH=AND
  Notice the use of the /MATCH qualifier. Normally this defaults
  to OR, so that if any one of the conditions are met then the file
  will be displayed.
3 FID
  If you know a file id, you can display the info on that file via:
    $ INDEX/DISPLAY=ALL/FILE_ID=(1,4)
  This would display INDEXF.SYS [fid = (1,1,0)] and
  000000.DIR (4,4,0). Note that only the first number of the
  File ID should be specified.
3 Fragmentation
  Suppose you want to know how badly fragmented the system is:
    $ INDEX/DISPLAY=(EXTENTS,HEADERS)/HEADERS=1
  would display all the files with more than one extention header,
  of course, you needn't wait till your system gets that fragmented,
  you may have a different idea of what is too fragmented:
    $ INDEX/DISPLAY=(EXTENTS,HEADERS)/EXTENTS=20
  would display all the files broken into 20 or more peices.
3 LBN
  Suppose you have a block go bad, you know the LBN, and you want to
  know the file which contains it:
    $ INDEX/LBN=19500
  would display the file containing that LBN.

  Another way (is this cheating?) would be to search for any
  file marked corrupt:
    $ INDEX/CHARACTERISTICS=FILE_CORRUPT

  Perhaps you want to see what LBNs are in a specific file,
   $ INDEX/DISPLAY=LBN/FULLNAME=EXAMPLE.TXT
3 WASTE
  If you want to know how many blocks are being wasted (the difference
  between used and allocated), you could display it via
    $ INDEX/DISPLAY=WASTED/FULLNAME=EXAMPLE.TXT
  Or find all files wasting space...
    $ INDEX/DISPLAY=WASTED/WASTED=100

2 Input_Qualifiers
  Besides searching through the index file directly, you can select what
  files will be used (and still subject to the "selection qualifiers"),
  via /FILE_ID and /FULLNAME .

  You may search through all the index files in a multiple volume
  set by specifying /VOLUME. This is especially usefull in doing
  searches based on LBN, ACE, and ACL, as one or more of a files
  extension headers may reside on a separate disk, and extension
  headers which are on their own would otherwise be ignored.
/FILE_ID
  /FILE_ID=(list-of-file-id's)

  This allows you to display selected files without the overhead
  of searching through the entire index file. This limits the
  search to only the selected files, as indicated by their file-id.
  This searches through the index file to complete the file-id,
  then if the file-id is valid, it asks the disk acp for the header
  to this file, forcing the information to be as accurate as possible.
  If the file id is no longer valid, it will display the file header
  as stored in the index file, with an asterisk in front of the
  file id (if it is being displayed). Note that if the file id is
  valid that you will need read access to the file requested, as
  well as read access to the index file.
/FULLNAME
  /FULLNAME=(list-of-full-file-specs)

  This allows you to display selected files without the overhead
  of searching through the entire index file. This limits the
  search to only the selected files.

  This requires read access to the requested files, but does not
  access the index file.
/VOLUME
  /VOLUME

  This forces INDEX to search through all the index files in a
  multi-volume disk set. This is especially usefull in doing searches
  based on LBN, ACE, and ACL, as one or more of a files extension
  headers may reside on a separate disk, and extension headers which
  are on their own would otherwise be ignored.

  For example, suppose that DUA1 and DUA2 are set up as a multiple
  volume set called MULTI$DISK. If the file TEST.DAT were created
  on DUA1, but half of TEST.DAT was placed on DUA2, from logical
  block number 100 through 500, then the command:
    INDEX/LBN=250/DISPLAY=LBN DUA2:
  would not return any info on TEST.DAT, since the first file segment
  was located on DUA1. However, the command:
    INDEX/LBN=250/DISPLAY=LBN/VOLUME MULTI$DISK  ! (or "DUA1", or "DUA2")
  would report that DUA1:TEST.DAT contained the LBN 250.
  It may also report some other files as containing LBN 250, since
  each disk is being searched, hence you would want to display
  the LBN information, to be able to determine which file was the
  one you were really concerned about.
2 Output_qualifiers
  You may redirect output to a file, via /OUTPUT, and you may choose
  what is to be displayed via /DISPLAY.  By default the full file name
  is always displayed. The only way to disable this (should you so desire)
  is to select NOFULLNAME as a display option.
/OUTPUT
  /OUTPUT[=filename]
    Controls where output will go to. If qualifier isn't present
    then all output will be to screen.

    If qualifier is present but a filename is not specified, it will
    default to INDEXF.LIS.
/DISPLAY
  /DISPLAY=(list-of-display-keywords)
  Controls what will be displayed from the file header.

  All off the DISPLAY keywords are negatable, so that you could say:
  /DISPLAY=(ALL, NOLBN) to get a listing including all the header
  information except for the list of logical block numbers. By default
  FULLNAME is always displayed. If you really don't want to see it
  you must specify NOFULLNAME.

   ALL
     Display everything about the file (except negated items)
   ACL
   ACCESS_MODE
   ACTIVE_RECOVERY_UNITS
   ALLOCATED
   ATTRIBUTES
   BACKUP_DATE
   BUCKET_SIZE
   CHARACTERISTICS
   CREATION_DATE
   DEFAULT_EXTEND_QUANTITY
   DIRECTORY_FILE_ID
   EXPIRATION_DATE
   EXTENTS
   FILE_ID
   FULLNAME (The name as returned by the disk ACP, if possible, otherwise
             it will return the name in the file header preceded with [?],
             and on the next line it will display the name of the file that
             this files backlink points to, if possible)
   GLOBAL_BUFFER_COUNT
   HEADERS
   HIGHWATER_MARK
   JOURNAL
   LBN
   MAXIMUM_RECORD_SIZE
   NAME (this is the name as it exists in the file header, this name may
         be different than the name returned by FULLNAME due to multiple
         links to the same file, esp. when selecting based on /FULLNAME)
   NUMBER_OF_REVISIONS
   ORGANIZATION
   OWNER_UIC
   PROTECTION
   RECORD_SIZE
   REVISION_DATE
   TYPE
   USED (displays blocks used, and first free byte)
   VERSION_LIMIT
   VFC_SIZE
   WASTED_BLOCKS
2 Selection_qualifiers
/MATCH
  /MATCH=(match-option)

  Match-option can be AND or OR, and signifies wether a file will be
  displayed only if all criterion pass (AND) or if any one criteria
  passes (OR). OR matching is used by default.

  example:
  $ INDEX/CHAR=DIR/OWNER=[USER]/MATCH=AND
  Display all directories owner by [USER].

  $ INDEX/WASTED=50/ALLOC=100000/MATCH=OR
  Is equivalent to:
  $ INDEX/WASTED=50/ALLOC=100000
  Which displays all files wasting 50 blocks or more, or which have
  100,000 (or more) blocks allocated.

/ACE
  /ACE=(list-of-identifiers-or-uics)

  Allows you to select files which have an identifier ace containing
  one (or more) of the specified ids.

  example:
  $ INDEX/DISPLAY=ACL/ACE=([PROJECTS,P001],[SYSTEM],BATCH)
  Would display all files that referenced any of those identifiers in their
  ACL.
/ACL
  /ACL

  Allows you to display all files that have an ACL of any kind.
/ATTRIBUTES
  /ATTRIBUTES=(list-of-attributes-keywords)

   Allows you to specify what record attributes a file must have or
   not have, to be displayed.

   FORTRANCC   Fortran carriage control
   IMPLIEDCC   Implied carriage control
   PRINTCC     Print carriage control
   SPAN        Records can span blocks

  example:
  $ INDEX/DISP=ATTRIBUTES/ATTRIB=(FORTRAN,PRINT)
  Display all files that have either fortran or print carriage control.

/CHARACTERISTICS
 /CHARACTERISTICS=(list-of-characteristics-keywords)

   Allows you to specify what file characteristics a file must have
   or not have, to be displayed.

   ACL_CORRUPT          File contains corrupt ACL
   BACKUP               File can be backed up
   BEST_TRY_CONTIGUOUS  Keep file as contiguous as possible
   CHARGE               File space is charged to owner
   CONTIGUOUS           File is contiguous
   DIRECTORY            File is a directory
   ERASE_ON_DELETE      File is to be erased when deleted
   FILE_CORRUPT         File contains suspected bad blocks
   LOCKED               File is deaccess locked
   MARKED_FOR_DELETE    File is marked for delete
   SPOOL                File is a spool file
   READ_VERIFY          Verify all read operations
   WRITE_BACK           File may be write-back cached
   WRITE_VERIFY         Verify all write operations

  example:
  $ INDEX/DISP=(CHAR,FILE_ID)/CHAR=SPOOL
  Display all spool files..

  $ INDEX/DISPL=CHAR/CHAR=(READ_VERIFY,WRITE_VERIFY, -
  $_ NOFILE_CORRUPT,NOACL_CORRUPT,NOMARKED_FOR_DELETE)
  This displays all file that are set to either read or write verify,
  but aren't corrupt in any way, nor deleted.
/JOURNAL
  /JOURNAL=(list-of-journal-keywords)

   Allows you to specify what journal attributes a file must have or
   not have, to be displayed.

   JOURNAL    This is a journal file
   AIJNL      Enable after image journal
   ATJNL      Enable audit trail journal
   BIJNL      Enable before image journal
   RUJNL      Enable recovery unit journal
   NEVER_RU   File is never accessible in recovery unit
   ONLY_RU    File is accessible only in recovery unit
/ORGANIZATION
  /ORGANIZATION=(list-of-organization-keywords)

   Allows you to specify what file organization a file must have or
   not have, to be displayed.

   SEQUENTIAL
   RELATIVE
   INDEXED
   DIRECT

  example:
  $ INDEX/ORG=INDEX
  Display all indexed files.

  $ INDEX/ORG=NOSEQUENTIAL
  Display all non-sequential files.

  $ INDEX/ORG=(INDEX,RELATIVE)
  Display all files that are either indexed, or relative.
/TYPE
  /TYPE=(list-of-type-keywords)

   Allows you to specify what record type a file must have or
   not have, to be displayed.

   UNDEFINED Record type is undefined
   FIXED     Records have a fixed length
   VARIABLE  Record have variable length - stored in the file
             as a 2 byte integer storing the record length, followed
             by the record, possibly null padded to make next record
             start on a word boundary.
   VFC       Variable with fixed control
   STREAM    Stream format (unix-ish, records? what records?)
   LFSTREAM  Stream format, records are separated by line feed
   CRSTREAM  Stream format, records are separated by carriage return

  example:
  INDEX/DISPL=TYPE/TYPE=(STREAM,LFSTREAM,CRSTREAM)
  Display files having a stream format of some type.
  Note that this is in effect an OR search, a file must have,
  or not have, only one of the types specified.
/ACCESS_MODE
  /ACCESS_MODE=(list-off-access_mode-keywords)

   Allows you to specify what access mode a file must have or not have,
   to be displayed. Note that I am not sure if VMS even uses this... As
   a wild guess I would imagine that if it does use it, it would only be
   for open files, and the header would be cached in memory, not in the
   index file, so it probably could never be accessed except when an
   ACP QIO function is performed to get the absolute most current/correct
   header, as is done when /FILE_ID or /FULLNAME is specified.

   USER
   SUPERVISOR
   EXECUTIVE
   KERNEL
/CREATION_DATE
  /CREATION_DATE=(min,max)

  Display files created between the 'min' and 'max' dates.

  example:
  $ INDEX/DISPL=CREAT/CREAT=(YESTERDAY,TODAY)
  Display all files created today.
/REVISION_DATE
  /REVISION_DATE=(min,max)

  Display files created between the 'min' and 'max' dates.

  example:
  $ INDEX/DISPL=(CREATION,REVISION)/REVISION=(YESTERDAY,TODAY)
/EXPIRATION_DATE
  /EXPIRATION_DATE=(min,max)

  Display files expiring between the 'min' and 'max' dates.

  example:
  $ INDEX/DISPL=(CREATION,EXPIRATION)/EXPIRATION=(YESTERDAY,TODAY)
/BACKUP_DATE
  /BACKUP_DATE=(min,max)

  Display files backed up between the 'min' and 'max' dates.

  example:
  $ INDEX/DISPL=(CREATION,BACKUP)/BACKUP=(YESTERDAY,TODAY)
/ACTIVE_RECOVERY_UNITS
  /ACTIVE_RECOVERY_UNITS=(min,max)

  1 = by RMS
  2 = by DBMS
  3 = by Rdb/VMS
  4 = by Checkpoint/Restart
  > 4 = by other reverable facility
/ALLOCATED
  /ALLOCATED=(min,max)
/BUCKET_SIZE
  /BUCKET_SIZE=(min,max)
/DEFAULT_EXTEND_QUANTITY
  /DEFAULT_EXTEND_QUANTITY=(min,max)
/DIRECTORY_FILE_ID
  /DIRECTORY_FILE_ID=(list-of-directory-file-id's)

  You can use this to find all files that are (should be?) in a specified
  directory, so long as you know the file-id of the directory.
/EXTENTS
  /EXTENTS=(min,max)
/FIRST_FREE_BYTE
  /FIRST_FREE_BYTE=(min,max)
/GLOBAL_BUFFER_COUNT
  /GLOBAL_BUFFER_COUNT=(min,max)
/HEADERS
  /HEADERS=(min,max)
/HIGHWATER_MARK
  /HIGHWATER_MARK=(min,max)
/LBN
  /LBN=(list-of-LBNs)
/MAXIMUM_RECORD_SIZE
  /MAXIMUM_RECORD_SIZE=(min,max)

  Maximum allowable record length. 0 means there is no maximum.
/RECORD_SIZE
  /RECORD_SIZE=(min,max)

  Longest record length.
/NAME
  /NAME=filename

  This allows you to search based on the name stored in the header.
  Note that this is slower than using /FULLNAME but is usefull if
  you know the name of a file but not its location.
/NUMBER_OF_REVISIONS
  /NUMBER_OF_REVISIONS=(min,max)
/OWNER_UIC
  /OWNER_UIC=(list-of-UICs)
  This accepts any valid UIC. Valid UIC formats include
   [octal-number,octal-number]
   <octal-number,octal-number>
   [identifier,identifier]
   <identifier,identifier>
   [identifier]
   <identifier>
   %xHexadecimal-number
/PROTECTION
  /PROTECTION=(SET=(protection),CLEAR=(protection))

  This allows you to search for all files that have specified protection
  bits SET and or CLEAR, for example, to find all files that are world
  writeable, but not world readable, you could specify :
    /PROTECTION=(SET=(WORLD=W), CLEAR=(WORLD=R))
  or just all files that are set to WORLD:RWED, use
    /PROTECTION=(SET=W:RWED)
  or all files that are set to owner not readable, use
    /PROTECTION=(CLEAR=O:R)
/USED
  /USED=(min,max)
/VERSION_LIMIT
  /VERSION_LIMIT=(min,max)

  Note that this is the directory version limit, i.e. this is set by
  the command SET DIRECTORY/VERSION=n
/VFC_SIZE
  /VFC_SIZE=(min,max)
/WASTED_BLOCKS
  /WASTED_BLOCKS=(min,max)
/PLACEMENT
  /PLACEMENT=(list-of-placement-keywords)

  EXACT                   Exact placement specified
  ON_CYLINDER             On cylinder allocation desired
  RELATIVE_VOLUME_NUMBER  Place on specified RVN
  LBN_SPECIFIED           Use LBN of next map pointer
$EOD
$ create/log ACEDEF.H
$DECK
/* This header file was created by Joe Meadows, and is not copyrighted
   in any way. No guarantee is made as to the accuracy of the contents
   of this header file. This header file was last modified on Sep. 8th,
   1987. */
#define ACE$C_KEYID     1
#define ACE$C_RMSJNL_BI 2
#define ACE$C_RMSJNL_AI 3
#define ACE$C_RMSJNL_AT 4
#define ACE$C_AUDIT     5
#define ACE$C_ALARM     6
#define ACE$C_INFO      7
#define ACE$C_RMSJNL_RU_DEFAULT 8
#define ACE$C_DIRDEF    9
#define ACE$C_RMSJNL_RU 10
#define ACE$C_RESERVED  255
#define ACE$C_CUST      1
#define ACE$C_CSS       2
#define ACE$C_VMS       3
#define ACE$M_SUCCESS   1
#define ACE$M_FAILURE   2
#define ACE$M_DEFAULT   256
#define ACE$M_PROTECTED 512
#define ACE$M_HIDDEN    1024
#define ACE$M_NOPROPAGATE       2048
#define ACE$M_READ      1
#define ACE$M_WRITE     2
#define ACE$M_EXECUTE   4
#define ACE$M_DELETE    8
#define ACE$M_CONTROL   16
#define ACE$K_LENGTH    8
#define ACE$C_LENGTH    8
#define ACE$S_RMSJNL_RU_DEFAULT 17
#define ACE$M_JOURNAL_DISABLED  1
#define ACE$M_BACKUP_DONE       2
#define ACE$S_RMSJNL_RU 38
#define ACE$S_RMSJNL    50
#define ACE$S_ACEDEF    50
#define ACE$S_INFO_TYPE 4
#define ACE$S_RESERVED  4

#define ACE$S_AUDITNAME 16
#define ACE$S_VOLNAM    12
#define ACE$S_FID       6
#define ACE$S_CDATE     8
#define ACE$S_MODIFICATION_TIME 8
#define DATE {unsigned : 32; unsigned : 32;}

struct acedef {
  unsigned char ace$b_size;
  unsigned char ace$b_type;

  variant_union {
    unsigned short int ace$w_flags;
    variant_struct {
      unsigned : 8;
      unsigned ace$v_default : 1;
      unsigned ace$v_protected : 1;
      unsigned ace$v_hidden : 1;
      unsigned ace$v_nopropagate : 1;
    } ace$dummy_common_flags;           /* common to all ace's */
    variant_struct {
      unsigned ace$v_success : 1;
      unsigned ace$v_failure : 1;
    } ace$dummy_alarm_flags;            /* for alarm ace */
    unsigned ace$v_info_type : 4;       /* for application ace */
    unsigned ace$v_reserved : 4;        /* for identifier ace */
  } ace$dummy_flags_union;

  variant_union {

    /* alarm and identifier ace */
    variant_struct {
      variant_union {
        unsigned long int ace$l_access;
        variant_struct {
          unsigned ace$v_read : 1;
          unsigned ace$v_write : 1;
          unsigned ace$v_execute : 1;
          unsigned ace$v_delete : 1;
          unsigned ace$v_control : 1;
        } ace$dummy_access_bits;
      } ace$dummy_access_union;
      variant_union {
        unsigned long int ace$l_key;
        char ace$t_auditname[ACE$S_AUDITNAME];
      } ace$dummy_alarm_id_union;
    } ace$dummy_alarm_id_ace;

    /* application ace */
    variant_struct {
      unsigned long int ace$l_info_flags;
      char ace$t_info_start;
    } ace$dummy_application_ace;

    /* default protection ace */
    variant_struct {
      unsigned long int ace$l_spare1;
      unsigned long int ace$l_sys_prot;
      unsigned long int ace$l_own_prot;
      unsigned long int ace$l_grp_prot;
      unsigned long int ace$l_wor_prot;
    } ace$dummy_protectionc_ace;

    variant_struct {
      char ace$t_volnam[ACE$S_VOLNAM];
      unsigned char ace$b_volnam_len;
      unsigned char ace$b_rjrver;
      variant_union {
        unsigned char ace$r_fid_overlay[ACE$S_FID];
        unsigned short int ace$w_fid[ACE$S_FID/2];
        variant_struct {
          unsigned short int ace$w_fid_num;
          unsigned short int ace$w_fid_seq;
          variant_union {
            unsigned char ace$r_fid_rvn_overlay[2];
            unsigned short int ace$w_fid_rvn;
            variant_struct {
              unsigned char ace$b_fid_rvn;
              unsigned char ace$b_fid_nmx;
            } ace$r_fid_rvn_fields;
          } ace$dummy_fid_rvn_fields;
        } ace$r_fid_fields;
      } ace$dummy_fid_fields;
      variant_union {
        unsigned short int ace$w_rmsjnl_flags;
        variant_struct {
          unsigned ace$v_journal_disabled : 1;
          unsigned ace$v_backup_done : 1;
        } ace$dummy_rmsjnl_flags_bits;
      } ace$dummy_rmsjnl_flags_union;
      unsigned long int ace$l_jnlidx;
      struct DATE ace$q_cdate;
      unsigned long int ace$l_backup_seqno;
      struct DATE ace$q_modification_time;
    } ace$dummy_undocumented_ace;
  } ace$dummy_ace_fields;
};
$EOD
$ create/log ATRDEF.H
$DECK
/* This header file was created by Joe Meadows, and is not copyrighted
   in any way. No guarantee is made as to the accuracy of the contents
   of this header file. This header file was last modified on Sep. 8th,
   1987. */
#define ATR$C_UCHAR 3
#define ATR$S_UCHAR 4
#define ATR$C_RECATTR 4
#define ATR$S_RECATTR 32
#define ATR$C_FILNAM 5
#define ATR$S_FILNAM 6
#define ATR$C_FILTYP 6
#define ATR$S_FILTYP 2
#define ATR$C_FILVER 7
#define ATR$S_FILVER 2
#define ATR$C_EXPDAT 8
#define ATR$S_EXPDAT 7
#define ATR$C_STATBLK 9
#define ATR$S_STATBLK 32
#define ATR$C_HEADER 10
#define ATR$S_HEADER 512
#define ATR$C_BLOCKSIZE 11
#define ATR$S_BLOCKSIZE 2
#define ATR$C_USERLABEL 12
#define ATR$S_USERLABEL 80
#define ATR$C_ASCDATES 13
#define ATR$S_ASCDATES 35
#define ATR$C_ALCONTROL 14
#define ATR$S_ALCONTROL 14
#define ATR$C_ENDLBLAST 15
#define ATR$S_ENDLBLAST 4
#define ATR$C_ASCNAME 16
#define ATR$S_ASCNAME 86
#define ATR$C_CREDATE 17
#define ATR$S_CREDATE 8
#define ATR$C_REVDATE 18
#define ATR$S_REVDATE 8
#define ATR$C_EXPDATE 19
#define ATR$S_EXPDATE 8
#define ATR$C_BAKDATE 20
#define ATR$S_BAKDATE 8
#define ATR$C_UIC 21
#define ATR$S_UIC 4
#define ATR$C_FPRO 22
#define ATR$S_FPRO 2
#define ATR$C_RPRO 23
#define ATR$S_RPRO 2
#define ATR$C_ACLEVEL 24
#define ATR$S_ACLEVEL 1
#define ATR$C_SEMASK 25
#define ATR$S_SEMASK 8
#define ATR$C_UIC_RO 26
#define ATR$S_UIC_RO 4
#define ATR$C_DIRSEQ 27
#define ATR$S_DIRSEQ 2
#define ATR$C_BACKLINK 28
#define ATR$S_BACKLINK 6
#define ATR$C_JOURNAL 29
#define ATR$S_JOURNAL 1
#define ATR$C_HDR1_ACC 30
#define ATR$S_HDR1_ACC 1
#define ATR$C_ADDACLENT 31
#define ATR$S_ADDACLENT 255
#define ATR$C_DELACLENT 32
#define ATR$S_DELACLENT 255
#define ATR$C_MODACLENT 33
#define ATR$S_MODACLENT 255
#define ATR$C_FNDACLENT 34
#define ATR$S_FNDACLENT 255
#define ATR$C_FNDACLTYP 35
#define ATR$S_FNDACLTYP 255
#define ATR$C_FNDACETYP 35
#define ATR$S_FNDACETYP 255
#define ATR$C_DELETEACL 36
#define ATR$S_DELETEACL 255
#define ATR$C_READACL 37
#define ATR$S_READACL 512
#define ATR$C_ACLLENGTH 38
#define ATR$S_ACLLENGTH 4
#define ATR$C_READACE 39
#define ATR$S_READACE 255
#define ATR$C_RESERVED 40
#define ATR$S_RESERVED 380
#define ATR$C_HIGHWATER 41
#define ATR$S_HIGHWATER 4
#define ATR$C_DUMMY_0 42
#define ATR$S_DUMMY_0 4
#define ATR$C_PRIVS_USED 43
#define ATR$S_PRIVS_USED 4
#define ATR$C_MATCHING_ACE 44
#define ATR$S_MATCHING_ACE 255
#define ATR$C_ACCESS_MODE 45
#define ATR$S_ACCESS_MODE 1
#define ATR$C_FILE_SPEC 46
#define ATR$S_FILE_SPEC 512
#define ATR$C_CLASS_MASK 47
#define ATR$S_CLASS_MASK 20
#define ATR$C_BUFFER_OFFSET 48
#define ATR$S_BUFFER_OFFSET 2
#define ATR$C_RU_ACTIVE 49
#define ATR$S_RU_ACTIVE 1
#define ATR$C_MAX_CODE 49
#define ATR$C_MAX_PLUS1 50

#define ATR$S_ATRDEF 8
struct ATRDEF
{
  unsigned short int atr$w_size;
  unsigned short int atr$w_type;
  char *atr$l_addr;
};
$EOD
$ create/log C.OPT
$DECK
sys$share:vaxcrtl.exe/share
$EOD
$ create/log CLD.H
$DECK
/* This header file was created by Joe Meadows, and is not copyrighted
   in any way. No guarantee is made as to the accuracy of the contents
   of this header file. This header file was last modified on Sep. 8th,
   1987. */
/* this file will contain the text names for the CLD qualifiers etc. */
/* this include file contains the strings that describe the command line */
char *t_rtype = "Type";
char *ta_rtype[] = {
  "Undefined",
  "Fixed",
  "Variable",
  "VFC",
  "Stream",
  "LFStream",
  "CRStream"
};
char *t_fileorg = "Organization";
char *ta_fileorg[] = {
  "Sequential",
  "Relative",
  "Indexed",
  "Direct"
};
char *t_attr = "Attributes";
  char *t_fortrancc = "FortranCC";
  char *t_impliedcc = "ImpliedCC";
  char *t_printcc = "PrintCC";
  char *t_nospan = "Span";
char *t_char = "Characteristics";
  char *t_badacl = "ACL_Corrupt";
  char *t_nobackup = "Backup";
  char *t_contigb = "Best_Try_Contiguous";
  char *t_nocharge = "Charge";
  char *t_contig = "Contiguous";
  char *t_directory = "Directory";
  char *t_erase = "Erase_On_Delete";
  char *t_badblock = "File_Corrupt";
  char *t_locked = "Locked";
  char *t_markdel = "Marked_For_Delete";
  char *t_spool = "Spool";
  char *t_readcheck = "Read_Verify";
  char *t_writeback = "Write_Back";
  char *t_writcheck = "Write_Verify";
char *t_journal = "Journal";
  char *t_journal_file = "Journal";
  char *t_aijnl = "AIJnl";
  char *t_atjnl = "ATJnl";
  char *t_bijnl = "BIJnl";
  char *t_rujnl = "RUJnl";
  char *t_never_ru = "Never_RU";
  char *t_only_ru = "Only_RU";
char *t_access = "Access_Mode";
char *ta_access[] = {
  "USER",
  "SUPERVISOR",
  "EXECUTIVE",
  "KERNEL"
};

char *t_placement = "Placement";
  char *t_place_exact = "Exact";
  char *t_place_oncyl = "On_Cylinder";
  char *t_place_rvn = "Relative_Volume_Number";
  char *t_place_lbn = "LBN_Specified";

char *t_prot = "Protection";
char *t_protset = "Protection.set";
char *t_protclr = "Protection.clear";
char *ta_prot[] = {"SYSTEM", "OWNER", "GROUP", "WORLD"};
char *t_fileprot[] = {
  "RWED", "WED", "RED", "ED", "RWD", "WD", "RD",
  "D", "RWE", "WE", "RE", "E", "RW", "W", "R", ""
};
char *t_credate = "Creation_Date";
char *t_revdate = "Revision_Date";
char *t_expdate = "Expiration_Date";
char *t_bakdate = "Backup_Date";
char *t_revisions = "Number_Of_Revisions";
char *t_vfcsize = "VFC_Size";
char *t_rsize = "Record_Size";
char *t_maxrec = "Maximum_Record_Size";
char *t_efblk = "Used";
char *t_ffbyte = "First_Free_Byte";
char *t_hiblk = "Allocated";
char *t_defext = "Default_Extend_Quantity";
char *t_bktsize = "Bucket_Size";
char *t_gbc = "Global_Buffer_Count";
char *t_versions = "Version_Limit";
char *t_extents = "Extents";
char *t_header = "Headers";
char *t_lbn = "LBN";
char *t_owner = "Owner_UIC";
char *t_fid = "File_ID";
char *t_backlink = "Directory_File_ID";
char *t_highwater = "Highwater_Mark";
char *t_ru_active = "Active_Recovery_Units";
char *t_wasted = "Wasted_Blocks";
char *t_filename = "Name";
char *t_fullname = "Fullname";

char *t_display = "Display";
char *t_aclexists = "ACL";
char *t_aclcontains = "ACE";
$EOD
$ create/log CLI.C
$DECK
/* Modification History
   --------------------
   Sep. 8, 1987 JEM - Conversion from BETA to Release

*/
#include climsgdef
#include descrip

int cli_get_value(s1,s2)
  char *s1;
  struct dsc$descriptor *s2;
{
  static struct dsc$descriptor s1_desc={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};

  s1_desc.dsc$w_length = strlen(s1);
  s1_desc.dsc$a_pointer = s1;

  return(cli$get_value(&s1_desc,s2));
}

int cli_present(s1)
  char *s1;
{
  static struct dsc$descriptor s1_desc={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};

  s1_desc.dsc$w_length = strlen(s1);
  s1_desc.dsc$a_pointer = s1;

  return(cli$present(&s1_desc));
}

unsigned int change(orig,s1,s2)
  unsigned int orig;
  char *s1,*s2;
{
  static struct dsc$descriptor s3_desc={0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0};
  long int status;
  unsigned int i;

  append_with_point(s1,s2,&s3_desc);

  status = cli$present(&s3_desc);
  i=orig;
  if (status & 1)
    i=1;
  if (status == CLI$_NEGATED)
    i=0;
  return(i);
}

int append_with_point(s1,s2,out)
  char *s1,*s2;
  struct dsc$descriptor *out;
{
  static struct dsc$descriptor s1_desc={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  static struct dsc$descriptor s2_desc={0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
  static char point = '.';
  static struct dsc$descriptor pt_desc={1,DSC$K_DTYPE_T,DSC$K_CLASS_S,&point};

  s1_desc.dsc$w_length = strlen(s1);
  s1_desc.dsc$a_pointer = s1;
  s2_desc.dsc$w_length = strlen(s2);
  s2_desc.dsc$a_pointer = s2;

  /* new = s1 + "." + s2 */
  str$copy_dx(out,&s1_desc);
  str$append(out,&pt_desc);
  str$append(out,&s2_desc);

  return;
}
$EOD