From: przemek@rrdstrad.nist.gov (Przemek Klosowski)
Newsgroups: comp.os.vms,comp.sys.dec
Subject: Re: Changing record length of fixed record files (SUMMARY)
Date: 29 Sep 92 19:00:52 GMT
Followup-To: comp.os.vms
Organization: U. of Maryland/NIST
In-reply-to: przemek@rrdstrad.nist.gov's message of 22 Sep 92 20:06:09 GMT


Hello!

I asked how to conveniently change a record size of a binary VMS file
(the files contain 320-byte long records of VAX floating numbers, and
they were edited on a UNIX system and copied back with wrong record
size (512)). The editing process is asynchronous, and it is not
practical to initiate the copy from the VMS side---if it weren't so,
the task would have been easy, as there is a VMS utility that allows
one to copy data over the network and set the RMS structure of a resulting
file (EXCHANGE/NETWORK file/FDL=fdldescription).

Several people wrote me in response to my query (my thanks go to all
of them, listed later in this message). Some recommended creating a
template file with correct record lenght and using COPY/OVERLAY.
However, this works only when both original and new file have record
lengths that are a multiply of 512 bytes, which is not the case here.

Another idea was to use the PD FILE utility; it did not work for me,
because my version of FILE was compiled using GCC, and could only get
its parameters via a CLD mechanism; however, I had to call it as a
foreign command using lib$spawn().

Yet another idea that occurred to me was to use the EXCHANGE/NETWORK
utility for a _local_ file:
	lib$spawn(EXCHANGE/NETWORK OLDFILE NEWFILE/FDL=FIXED320) This
requires a use of an extra file (FIXED320.FDL) containing the PDL
description of a desired file format. Carl J Lydick
<carl@SOL1.GPS.CALTECH.EDU> suggested a way of sending this
descripiton directly to EXCHANGE via a mailbox; this, however, is
beyond the scope of this article.

Finally, dano@petrucio.ae.utexas.edu (Dano Carroll) sent me a Fortran
program that I enclose in part at the end that contains code to directly
manipulate the record length using the sys$modify call.


I thank those kind folks for their help and advice:

       pack@acd.ucar.edu  
     bengtl@maths.lth.se  
   murphy@decuac.DEC.COM  
     hudson@ug.cs.dal.ca  
 blue!garry@uunet.UU.NET  
          KARSTEN@tfl.dk  
 blair@snogum.enet.dec.com
   carl@SOL1.GPS.CALTECH  
dano@petrucio.ae.utexas.edu 


        Przemek Klosowski                               _----___
   ------------------------------------------------  ##=\ ^^ ^^ ^=====O-
        417 Muddy Branch Rd #203                         \ ^^  /
        Gaithersburg MD 20878                             |_^_|
        (301) 977 0046                                     VvV
     _______________________________________________________________
    |  przemek@ndcvx.cc.nd.edu     |      przemek@rrdstrad.nist.gov |
    |  Physics Department         and     NIST, Reactor Bldg #235   |
    |  U. of Maryland              |      Gaithersburg MD 20899     |
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



      OPTIONS /EXTEND_SOURCE
      call fixupfile('qbuffer.buf')
      end

Code obtained from: dano@petrucio.ae.utexas.edu (Dano Carroll); 
Changes the record length of a file via RMS calls. High wizardry.

      OPTIONS /EXTEND_SOURCE
      subroutine fixupfile(filename)
      character*(*) filename
      integer*4 lib$spawn, status, reclen 
 
      INCLUDE '($SYSSRVNAM)'
      INCLUDE '($FABDEF)/LIST'
      INCLUDE '($NAMDEF)/LIST'
      INCLUDE '($RMEDEF)/LIST'
      INCLUDE '($RMSDEF)/LIST'
      RECORD /FABDEF/ MYFAB
      RECORD /NAMDEF/ MYNAM
      byte  RESNAME(NAM$C_MAXRSS), EXPNAME(NAM$C_MAXRSS)   
C
C	Set file attribute block values
C
      MYFAB.FAB$B_BID = FAB$C_BID
      MYFAB.FAB$B_BLN = FAB$C_BLN
      MYFAB.FAB$L_FNA = %LOC(FILENAME)

      MYFAB.FAB$B_FNS = LENGTH(FILENAME)

      MYFAB.FAB$B_FAC = FAB$M_PUT
      MYFAB.FAB$L_FOP = IOR(FAB$M_ESC,MYFAB.FAB$L_FOP)
      MYFAB.FAB$L_FOP = IOR(FAB$M_NAM,MYFAB.FAB$L_FOP)
      MYFAB.FAB$L_CTX = IOR(RME$C_SETRFM,MYFAB.FAB$L_CTX)
      MYFAB.FAB$W_IFI = 0
      MYFAB.FAB$L_NAM = %LOC(MYNAM)
      MYNAM.NAM$B_BID = NAM$C_BID
      MYNAM.NAM$B_BLN = NAM$C_BLN
      MYNAM.NAM$L_RSA = %LOC(RESNAME)
      MYNAM.NAM$B_RSS = NAM$C_MAXRSS
      MYNAM.NAM$L_ESA = %LOC(EXPNAME)
      MYNAM.NAM$B_ESS = NAM$C_MAXRSS
C
C	Parse the file specification
C
      STATUS = SYS$PARSE(MYFAB)
      IF ( .NOT. STATUS ) CALL LIB$SIGNAL(%VAL(STATUS))
C
C	Search for the file
C
      STATUS = SYS$SEARCH(MYFAB)
      IF ( .NOT. STATUS ) CALL LIB$SIGNAL(%VAL(STATUS))
C
C	  Open the file
C
      STATUS = SYS$OPEN(MYFAB)
      IF ( .NOT. STATUS ) CALL LIB$SIGNAL(%VAL(STATUS))
      if (MYFAB.FAB$W_MRS .eq. 512) then
c         presumably file was copied over; convert record length
c         to Beat's 80*4 = 320
C	  It will be in bytes (not longwords), unlike in other places
C
         MYFAB.FAB$W_MRS = 320
         STATUS = SYS$MODIFY(MYFAB)
         IF ( .NOT. STATUS ) CALL LIB$SIGNAL(%VAL(STATUS))
      else 
         if (MYFAB.FAB$W_MRS .ne. 320) then
            type *,'-W- File QBUFFER.BUF has weird record length'
         endif
      endif
C     
C     Close the file
C     
      STATUS = SYS$CLOSE(MYFAB)
      IF ( .NOT. STATUS ) CALL LIB$SIGNAL(%VAL(STATUS))

      end

--
			przemek klosowski (przemek@rrdstrad.nist.gov)
			Reactor Division (bldg. 235), E111
			National Institute of Standards and Technology
			Gaithersburg, MD 20899,      USA

			(301) 975 6249