From: martin@RADIOGAGA.HARZ.DE
Sent: Thursday, September 23, 1999 12:16 AM
To: Info-VAX@Mvb.Saic.Com
Subject: Re: Copying Data Files

Kevin Handy (kth@srv.net) wrote:
: Does anyone have a function (preferably C or Basic) to copy
: one file to another when passed the two file names.
: Will be used on a wide variety of file types (indexed, sequentai,
: etc.)
:
: Something equivenent to 'copy xxx.xxx yyy.yyy', except
: as a function without spawning a DCL process.

From: carl@SOL1.GPS.CALTECH.EDU (Carl J Lydick)
Newsgroups: comp.os.vms
Subject: Re: Copying _any_ file within a program
Date: 21 May 1995 19:27:39 GMT
Organization: HST Wide Field/Planetary Camera
Message-ID: <3po47b$le8@gap.cco.caltech.edu>

mrl@winternet.com (Mark Ludwig) writes:
=I need to copy files from within a program.  For performance and
=environmental reasons, I'd like to avoid spawning a COPY command.  Our
=first attempt used CONV$PASS_FILES, but this doesn't work for binary
=files which have no recognizeable end-of-line.
...
=The Digital phone rep. suggested the best way to copy a file of
=arbitrary data would be to use block-level I/O operations.  From years
=past doing such things I recall there being a fair number of
=subtleties in setting up the RMS control blocks.  Rather than spend a
=bunch of time on that, I'm hoping someone can point me to some
=freely-available source which does a block copy using $READ/$WRITE.

Actually, setting up the FABs and RABs isn't all that difficult.
The following routine does what I think you want.

#include descrip
#include rms

notlib_copy(struct dsc$descriptor *inp_file, struct dsc$descriptor *out_file)
{	struct FAB inp_fab, out_fab;
	struct RAB inp_rab, out_rab;
	char buffer[32256];
	long stat;

	inp_fab = cc$rms_fab;
	inp_fab.fab$b_fac = FAB$M_BIO | FAB$M_GET;
	inp_fab.fab$l_fna = inp_file->dsc$a_pointer;
	inp_fab.fab$b_fns = inp_file->dsc$w_length;
	inp_fab.fab$l_fop = FAB$M_SQO;
	inp_fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_UPI;
	if(((stat = SYS$OPEN(&inp_fab)) & 7) != 1)
		return stat;
	inp_rab = cc$rms_rab;
	inp_rab.rab$l_fab = &inp_fab;
	inp_rab.rab$l_rop = RAB$M_BIO;
	if(((stat = SYS$CONNECT(&inp_rab)) & 7) != 1)
	{	SYS$CLOSE(&inp_fab);
		return stat;
	}
	out_fab = inp_fab;
	out_fab.fab$b_fac = FAB$M_BIO | FAB$M_PUT;
	out_fab.fab$l_fna = out_file->dsc$a_pointer;
	out_fab.fab$b_fns = out_file->dsc$w_length;
	out_fab.fab$w_ifi = 0;
	out_fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_UPI;
	if(((stat = SYS$CREATE(&out_fab)) & 7) != 1)
	{	SYS$CLOSE(&inp_fab);
		return stat;
	}
	out_rab = inp_rab;
	out_rab.rab$l_fab = &out_fab;
	out_rab.rab$w_isi = 0;
	if(((stat = SYS$CONNECT(&out_rab)) & 7) != 1)
	{	SYS$CLOSE(&inp_fab);
		SYS$CLOSE(&out_fab);
		return stat;
	}
	inp_rab.rab$l_ubf = buffer;
	inp_rab.rab$w_usz = 32256;
	out_rab.rab$l_rbf = buffer;
	while(1)
	{	if((((stat = SYS$READ(&inp_rab)) & 7) != 1) && stat != RMS$_EOF)
		{	SYS$CLOSE(&inp_fab);
			SYS$CLOSE(&out_fab);
			return stat;
		}
		else if(stat == RMS$_EOF)
		{	SYS$CLOSE(&inp_fab);
			SYS$CLOSE(&out_fab);
			return RMS$_NORMAL;
		}
		else
		{	out_rab.rab$w_rsz = inp_rab.rab$w_rsz;
			if(((stat = SYS$WRITE(&out_rab)) & 7) != 1)
			{	SYS$CLOSE(&inp_fab);
				SYS$CLOSE(&out_fab);
				return stat;
			}
		}
	}
}
--
                        | Martin Vorlaender | VMS & WNT programmer
 VMS is today what      | work: mv@pdv-systeme.de
 Microsoft wants        |       http://www.pdv-systeme.de/users/martinv/
 Windows NT 8.0 to be!  | home: martin@radiogaga.harz.de
