From:	HENRY::IN%"carl%CITHEX.CALTECH.EDU%SRI-KL.ARPA%relay.cs.net@rca.com" 28-NOV-1986 08:45
To:	info-vax@CitHex.Caltech.Edu
Subj:	Re: copying VMS BACKUP save sets using FTP from Unix system

From:	ST%"gmt@arizona.edu" 25-Nov-86 22:28:10 MST
To:	ST%"INFO-VAX"
Subj:	copying VMS BACKUP save sets using FTP from Unix system
Message-Id: <8611260528.AA29122@megaron.arizona.edu>
Topic: infovax, Entry # 4073
In-Reply-To: <8611260520.AA25875@arizona.arizona.edu>

  >  I'm trying to prepare a VMS software package, in the form of a BACKUP save
  >  set, for distribution via anonymous FTP.  The distributing machine will be
  >  a Vax running 4.3 BSD Unix.  The save set copies to the Unix machine with
  >  no problems. When I go to the VMS machine and copy the data back using
  >  binary FTP, the data itself comes across fine but the block size gets set
  >  to 512 instead of the correct (in this case) 8192.  To be precise,
  >  DIR/FULL shows Record format:  Fixed length 512 byte records and
  >  everything else is correct. 

Below is the source (in both FORTRAN and C) for a proram to modify the record
format of a file.  It sets the record format of the selected files to FIXED,
with your choice of recordlength.  The FORTRAN program prompts for the record
length then for each file until it reaches an EOF on the input stream. 
The C program as the syntax "MCR MODRFM recordsize file1 [file2 [file3 ...]]"
They use an undocumented RMS routine (SYS$MODIFY) and a misdocumented FAB
field (FAB$L_CTX).
! Fortran program to change a file's record format record length field:
      INCLUDE '($FABDEF)'
      INCLUDE '($RMEDEF)'
      RECORD /FABDEF/ MYFAB
      INTEGER*4 LENGTH, STATUS, SYS$OPEN, SYS$CLOSE, SYS$MODIFY, BLKSIZ
      BYTE FILENAME(80)
      MYFAB.FAB$B_BID = FAB$C_BID
      MYFAB.FAB$B_BLN = FAB$C_BLN
      MYFAB.FAB$L_FNA = %LOC(FILENAME)
      MYFAB.FAB$B_FAC = FAB$M_PUT
      MYFAB.FAB$L_FOP = IOR(FAB$M_ESC,MYFAB.FAB$L_FOP)
      MYFAB.FAB$L_CTX = IOR(RME$C_SETRFM,MYFAB.FAB$L_CTX)
      MYFAB.FAB$W_IFI = 0
1     TYPE 5, 'Blocksize: '
5     FORMAT(1X,A,$)
      ACCEPT *, BLKSIZ
      IF(BLKSIZ .LT. 1 .OR.BLKSIZ .GT. 32767) THEN
        TYPE *,' Blocksize must be between 1 and 32767 inclusive.'
        GOTO 1
      ENDIF
10    TYPE 5, 'Filename: '
      READ(5,20,END=999) LENGTH, (FILENAME(I), I = 1, LENGTH)
20    FORMAT(Q, 80A1)
      MYFAB.FAB$B_FNS = LENGTH
      STATUS = SYS$OPEN(MYFAB, %VAL(0),%VAL(0))
      IF (IAND(STATUS, 7) .NE. 1) TYPE *, ' OPEN ERROR. STATUS = ', status
      MYFAB.FAB$W_MRS = BLKSIZ
      STATUS = SYS$MODIFY(MYFAB, %VAL(0), %VAL(0))
      IF (IAND(STATUS, 7) .NE. 1) TYPE *, ' MODIFY ERROR. STATUS = ', status
      STATUS = SYS$CLOSE(MYFAB, %VAL(0), %VAL(0))
      IF (IAND(STATUS, 7) .NE. 1) TYPE *, ' CLOSE ERROR. STATUS = ', status
      GOTO 10
999   END
/* C program to change a file's record format record length field: */
#include <fab.h>
#define RME$C_SETRFM	0X00000001
main(nargs, args)	int nargs;	char **args;
{ struct FAB myfab = cc$rms_fab;
  long blksiz, atol(), status;
  if (--nargs < 2 || sscanf(*++args, "%d%c", &blksiz, &status) != 1)
    exit((puts("USAGE: MODRFM blocksize file [file...]"),1));
  if (blksiz < 1 || blksiz > 32767)
    exit((puts("blocksize must be between 1 and 32767 inclusive."),1));
  myfab.fab$b_fac = FAB$M_PUT;
  myfab.fab$l_fop |= FAB$M_ESC;
  myfab.fab$l_ctx |= RME$C_SETRFM;
  myfab.fab$w_ifi = 0;
  while (--nargs > 0) {
    myfab.fab$l_fna = *++args;
    myfab.fab$b_fns = strlen(*args);
    if (((status = SYS$OPEN(&myfab, 0, 0)) & 7) != 1)
      exit((printf("Couldn't open %s\n", *args), status));
    myfab.fab$w_mrs = blksiz;
    if (((status = SYS$MODIFY(&myfab, 0, 0)) & 7) != 1)
      exit((printf("Couldn't modify %s\n", *args), status));
    if (((status = SYS$CLOSE(&myfab, 0, 0)) & 7) != 1)
      exit((printf("Couldn't close %s\n", *args), status));
} }

