Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!bbn!oberon!cit-vax!ucla-cs!zen!ucbvax!CITHEX.CALTECH.EDU!carl From: carl@CITHEX.CALTECH.EDU (Carl J Lydick) Newsgroups: comp.os.vms Subject: Re: converting fixed record files Message-ID: <871108162607.0if@CitHex.Caltech.Edu> Date: Sun, 8-Nov-87 19:44:07 EST Article-I.D.: CitHex.871108162607.0if Posted: Sun Nov 8 19:44:07 1987 Date-Received: Thu, 12-Nov-87 05:42:31 EST Sender: daemon@ucbvax.BERKELEY.EDU Organization: The ARPA Internet Lines: 82 > Using the standard utilities under VMS it is impossible, as far as > I know, to convert a fixed record file to a file with shorter records, > without loosing the remainder, what I want is simple to redefine the > fixed record size of a file. > I know that it is possible to write a program to read and write in > the desired format, but is there a more sophisticated way to do this, > or did I not read the manuals well? The answer, to the best of my knowledge, is not in the manuals. There is a hint as to how to do it in the module $RMEDEF in SYS$LIBRARY:FORSYSDEF.TLB. The following programs (one in FORTRAN, one in C) do this (note that the checks on the value of the blocksize variable are VERY important: if you set the blocksize to an illegal value, RMS will no longer be willing to access the file; at that point, the only way to fix things is to edit the disk's index file): ! Fortran program to change a file's 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 TYPE 5, 'Blocksize: ' 5 FORMAT(1X,A,$) ACCEPT *, BLKSIZ IF (BLKSIZ .LT. 1 .OR. BLKSIZ .GT. 32767) THEN TYPE *, ' BLKSIZ must be in the range [1,32767]' GOTO 999 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 length field: */ #include #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) { puts("USAGE: MODRFM blocksize file [file...]"); exit(1); } if (blksiz < 1 || blksiz > 32767) { { puts("blocksize must be in the range [1,32767]"); exit(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)); } }