[comp.os.vms] KERMITing TAR files

carl@CITHEX.CALTECH.EDU.UUCP (04/18/87)

The following is the source for MODRFM.  It's sort of squashed looking because
it fits on a single screen this way.  The program calls RMS directly, using
the undocumented routine SYS$MODIFY as well as SYS$OPEN and SYS$CLOSE, which
ARE documented.  The structure member .fab$l_ctx is documented to have no
effect on RMS processing, but is there to allow the user to store information
about what he's doing to the file.  Perusing the system FORTRAN text library
(which holds all the FORTRAN include files) I once discovered that if the
.fab$l_ctx member holds the value RME$C_SETRFM and the .fab$l_fop member
holds the FAB$M_ESC (escape from normal RMS processing limitations), the
program becomes magic and can lie to RMS and be believed.  As set up now,
the program sets the record format to fixed and the blocksize to whatever you
specify on the command line.  Link the object module produced by compiling the
file as follows:
	$ CC MODRFM
	$ link modrfm,sys$input:/opt
	sys$share:vaxcrtl/share
To convert a TAR file to KERMIT-compatible format, use the commands:
	$ modrfm 512 filename
(assuming you've defined modrfm as a foreign command). Then
	$ Create/fdl=sys$input: newfilename
	record
		format	fixed
		size	512
		carr	none
	$ copy/overlay filename newfilename
Ignore the warning about incompatible attributes; if the attributes were
compatible, we wouldn't be doing this, would we?
Then kermit the file, using file type binary.
/******************************************************************************/
#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));
  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;    myfab.fab$b_rfm = FAB$C_FIX;
    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));
} }