From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 26-JUN-1992 22:26:16.17
To:	INFO-VAX@SRI.COM
CC:	
Subj:	Re: SYSUAF.DAT Compression

"Phantom Tryke, VAXing in Beertown" asked about compressing SYSUAF.DAT
(as well as other questions), and at least one person showed sample
code using CONVERT to rebuild the file.

First, it is important to note that doing this to SYSUAF should be done on a
fairly idle system, and to be safe it should be followed by a reboot.  This is
because some products (ARSAP comes to mind, unfortunately) like to open SYSUAF
and leave it open all the time.  If you rebuild SYSUAF, you now have two
copies, one that new OPENs will use, and one that old OPENs are using, and the
old versions might get updated, but those updates will be lost.
What I usually do is to edit SYSTARTUP_V5.COM to begin with $EXIT, shutdown,
reboot, rebuild the files, remove the $EXIT, and reboot again.  A
conversational minimal boot would do the same thing and is about as much
hassle if not more.

Second, "fixing" an indexed file like SYSUAF should be done along with
RIGHTSLIST, VMSMAIL_PROFILE, and maybe even VMS$PASSWORD_HISTORY.
How often you need to do this depends on usage; after a "large" number of
additions/deletions is a good vague description.

Below is a fairly comprehensive procedure I've evolved over a couple of
years to rebuild most indexed files.  Let me know if anybody finds
problems with it.

Oh, Phantom, you ought to put your e-mail address at the end of your
mail.  Not everybody's system will retain your original From: address;
ours just shows INFO-VAX@UBVM.cc.buffalo.edu"



$!  FIXI.COM
$!
$!  Fix an indexed file -- re-do the index structure, possibly
$!  shortening it or lengthening it depending on conditions.
$!
$!  Modified 3/13/92 to fix two problems --
$!    1.  Previously, it only handled .DAT files.  Make it smart enough to
$!        handle anything except .FDL files, whether or not P1 includes a
$!        file type (default to .DAT).
$!    2.  Ensure the target file ends up in the same directory as the source.
$!        We used to have a problem if the caller did a SET DEF SYS$SYSTEM then
$!        ran FIXI against SYSUAF, for example, because the new version ended
$!        up in the system-specific directory rather than the common directory
$!        which is where the original was.  I consider this a bug in CONVERT
$!        (after all, EDT gets it right!) but *you* try to convince DEC!
$!  Modified 4/27/92.  Added /NOSORT to the CONVERT command, which may
$!        speed it up a bit.  This is safe since the original file is in
$!        primary key order already and we aren't making any changes.
$!  Modified 5/22/92.  Do the convert into a temporary file then
$!        rename it to the final name.  This prevents us from leaving a
$!        trashed-up file if, for example, the system crashes in the middle
$!        of the CONVERT (it did happen!).  This adds one complication in that
$!        any ACL on the original file gets lost, so we also have to do a
$!        SET ACL/LIKE= to fix that up.  Protections get carried because they
$!        are put in the FDL, but the ACL does not (is this an oversight in
$!        FDL management by DEC?).
$!
$!
$!  First, quit if no parameter was given.
$!
$ IF P1.EQS.""
$    THEN WRITE SYS$OUTPUT "Fix what?"
$         EXIT
$    ENDIF
$!
$!  Insert the default type of .DAT if it was not given.
$!  Detect directory-does-not-exist and syntax errors.
$!  This also upper-cases alphabetics, and changes the possible use of
$!  "file.type.version" to use a semicolon instead, which is important
$!  later.  It does not, however, change <dir> to [dir] though this is
$!  not important (I did want to mention it in case it becomes important).
$!
$ F1=F$PARSE("''P1'",".DAT")
$ IF F1.EQS.""
$    THEN WRITE SYS$OUTPUT "Illegal file spec or directory does not exist"
$         EXIT
$    ENDIF
$!
$!  See if the file exists, and what its full spec is.
$!
$ F1=F$SEARCH("''F1'")
$ IF F1.EQS.""
$    THEN WRITE SYS$OUTPUT "That file does not exist"
$         EXIT
$    ENDIF
$!
$!  The input file specification may contain a semicolon or even an
$!  explicit version number.  For the output file spec, need to strip
$!  off the semicolon and any version number that might be there.
$!  But, leave any version number on the input, in case the caller is
$!  wanting to rebuild an older file than the highest version (in either
$!  case the rebuilt version becomes the new highest version number).
$!  Note that in the event the caller specified the version number in the
$!  alternate form of "file.type.version" using another period instead of
$!  a semicolon, F$PARSE (above) has kindly changed it to semicolon style.
$!
$ F2=F$ELEMENT(0,";",F1)
$ IF F2.EQS.";"
$    THEN WRITE SYS$OUTPUT "Eh?  Version number error!"
$         EXIT
$    ENDIF
$!
$!  Now, we want to use the same file name and directory to hold the two
$!  FDL files we create, so we need to get yet another version of the file
$!  specification but without the "type" field.  This is not easy in DCL,
$!  which gives you F$PARSE to get individual fields, but not "everything
$!  except" a particular field.  So, a tricky method is used --
$!
$ TYPE=F$PARSE("''F2'",,,"TYPE")
$ IF TYPE.EQS.".FDL"
$    THEN WRITE SYS$OUTPUT "Cannot fix an FDL file!"
$         EXIT
$    ENDIF
$ F3=F$EXTRACT(0,F$LENGTH(F2)-F$LENGTH(TYPE),F2)+".FDL"
$!
$!  We also need a temporary file name, such as file.TMP, except that if
$!  the input file happens to be a .TMP file, we use .TEMP instead.
$!
$ IF TYPE.NES.".TMP"
$    THEN F4=F$EXTRACT(0,F$LENGTH(F2)-F$LENGTH(TYPE),F2)+".TMP"
$    ELSE F4=F$EXTRACT(0,F$LENGTH(F2)-F$LENGTH(TYPE),F2)+".TEMP"
$    ENDIF
$!
$!  Finally, what it is all about.  Rebuild the file.
$!
$ ANALYZE/RMS/FDL/OUTPUT='F3 'F1
$ EDIT/FDL/NOINTER/ANALYSIS='F3 'F3
$ CONVERT/NOSORT/FDL='F3 'F1 'F4
$ SET ACL/LIKE=(OBJECT_NAME='F1) 'F4
$ RENAME 'F4 'F2
$!
$!  These PURGEs are optional and may in fact vary depending on need.
$!  Thus, they probably shouldn't even be here.
$!
$ PURGE/KEEP=2 'F3
$ PURGE/KEEP=4 'F2


