[comp.sys.cbm] Can REL files be copied?

mrios@ihlpb.ATT.COM (Rios) (04/10/89)

(That's easy.  Feed KERMIT 2.2 to the line eater to DISTRACT it.)

My friend and I run a BBS (the Meltdown, (312)665-9732).  That is to say, we
run it when it isn't crashing left and right.  One of the problems that we
have is making a backup of the system.  We'd like to be able to back up
specific files, most notable the file containing users' information.  This
file, much to our dismay, is a REL file (along with a few others we'd like
to copy).

Is there a way to copy REL files from one drive to another for archival and
backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.

-- 
	Michael Rios		attih!ihlpb!mrios	AT&T Secret Police

20231192189121297114420851912920825201522219494725185114479132125914208523125

fred@cbmvax.UUCP (Fred Bowen) (04/11/89)

In article <10180@ihlpb.ATT.COM> mrios@ihlpb.ATT.COM (Rios) writes:
>Is there a way to copy REL files from one drive to another for archival and
>backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.

Sure- there are two copy programs on 1571 and 1581 test/demo diskettes which
are capable of doing this:  Butterfield's UNICOPY and Commodore's FILECOPY.
Why aren't you using the 1581 with the BBS?  It's faster, has greater capacity
(size, number of files, and maximum size of REL files), and it costs less.
--
-- 
Fred Bowen			uucp:	{uunet|rutgers|pyramid}!cbmvax!fred
				arpa:	cbmvax!fred@uunet.uu.net
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380

jgreco@csd4.milw.wisc.edu (Joe Greco) (04/11/89)

In comp.sys.cbm article <10180@ihlpb.ATT.COM>, mrios@ihlpb.ATT.COM (Rios) wrote:
](That's easy.  Feed KERMIT 2.2 to the line eater to DISTRACT it.)

What?

]My friend and I run a BBS (the Meltdown, (312)665-9732).  That is to say, we
]run it when it isn't crashing left and right.  One of the problems that we
]have is making a backup of the system.  We'd like to be able to back up
]specific files, most notable the file containing users' information.  This
]file, much to our dismay, is a REL file (along with a few others we'd like
]to copy).

Ah, yes.  UNI-COPY pads REL records with carriage returns; this is a
real pain for programs that NEED the end-of-record pointers intact.
The Transactor (I believe) published a really NICE REL file copy
program several issues back.

]Is there a way to copy REL files from one drive to another for archival and
]backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.

A custom program usually works best, though.

]-- 
]	Michael Rios		attih!ihlpb!mrios	AT&T Secret Police
]
]20231192189121297114420851912920825201522219494725185114479132125914208523125


--
jgreco@csd4.milw.wisc.edu		Joe Greco at FidoNet 1:154/200
USnail: 9905 W Montana Ave			     PunterNet Node 30 or 31
	West Allis, WI  53227-3329	"These aren't anybody's opinions."
Voice:	414/321-6184			Data: 414/321-9287 (Happy Hacker's BBS)

dwtamkin@chinet.chi.il.us (David W. Tamkin) (04/11/89)

Michael Rios wrote in <10180@ihlpb.ATT.COM> in comp.sys.cbm:

| Is there a way to copy REL files from one drive to another for archival and
| backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.

Most copy utilities will not touch relative files.  I've seen a couple that
will, and somewhere I have one for the 64 and any drive.  Obviously, disk
backup programs, which don't care how any sector relates to any other, would
do the job but can't copy from a 1571 to a 1581 properly.

One difficulty in copying relative files is that EOI (st=64) is sent at the
end of every record.  The only way to know when to stop reading is an error
50 (record not present) from the source disk.  The other is that BASIC's
INPUT#, GET#, and PRINT# commands respectively untalk, untalk, and unlisten
the addressed device when they are done, and unlistening or untalking a disk
drive with an open relative file bumps the record pointer to the start of
the next higher record.

One possible algorithm is this: read the block count and record length of the
source file from its directory entry on the source disk.  Allow for side
sectors and take an estimate of how many records there are (empty as well as
used).  Try to position to that record in the source file, and if you get an
error 50, try one record lower; if you get an ok from the drive, try one
record higher.  Keep going until you've had at least one 50 and one ok so
that you have the proper count of records in the source file.

Now, knowing the number of the highest record and the record length, open
the target file, position to the highest record you're going to make, and
write a CHR$(255); [with the semicolon from BASIC to suppress the CR or just
without a CR from ML].  Then from record 1 on up to the highest one, read in
a record and write it; read a record and write it, etc.  Be careful to
repeat position commands wherever advisable and to allow for the bumping to
the start of the next record after INPUT#, GET#, and PRINT#.  If you are
doing this in BASIC, avoid INPUT# unless you are positive of exactly how many
commas, colons, and carriage returns are inside each record, counting both
data characters and field separators.  GET# is safe but hard to use because
you need a different variable name for each character in the record and have
to run a long variable list in the GET# command.  If you know the exact
number of fields in every record and the fields are separated with commas,
colons, or CR's (and never have any of those characters inside the fields),
then you can use INPUT# with a variable list, one variable per field.  If
you are brave enough, you could even use the bumping of the record pointer
as a way to get into position for the next record.

You cannot use a loop to do the right number of GET#'s or INPUT#'s per
record, because with each run through the loop, the disk drive will get
untalked and move the record pointer to the start of the next record.  For
writing the target file, there is a similar problem: you have to assemble the
whole record into a single string before doing the PRINT# or concatenate its
parts with semicolons and use a single PRINT# command per record.  It's
probably best of all to use ML and to be careful of unlistening or untalking
at risky times: at least in ML you can control it.

But yes, relative files can be copied.  The c: DOS command in dual drives
(both from Commodore and from MSD) did it flawlessly.  Now if only someone
will produce a peripheral where drive 0 is a 1571 and drive 1 is a 1581,
we'll all be thrilled.

David W. Tamkin    POB 567542    Norridge IL  60656-7542 |   CIS: 73720,1570
dwtamkin@chinet.chi.il.us                   5 Nisan 5749 | GEnie: D.W.TAMKIN
Agreement with me cannot logically be imputed to anyone else who uses Chinet.

po87553@tut.fi (Ojala Pasi Juhani) (04/11/89)

>Is there a way to copy REL files from one drive to another for archival and
>backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.

 I have used 'Uni-copy', which can be found on that demo disk that
came with 1581. It can copy REL-files also, anyhow, it is a bit slow,
and can't use just one drive.
 
 Another way is to backup the whole disk, and then delete the other
files if necassary..

-- 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Pasi Ojala     +  Pasbox , Finland (31)-710024    21-06   +
+ po87553@tut.fi +           V.21/22 8n1    Petnet node 2   +
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

izot@f171.n221.z1.FIDONET.ORG (Geoffrey Welsh) (04/11/89)

 > From: dwtamkin@chinet.chi.il.us (David W. Tamkin)
 > Message-ID: <8190@chinet.chi.il.us>
 
 > One difficulty in copying relative files is that EOI (st=64) is sent at the
 > end of every record.  The only way to know when to stop reading is an error
 > 50 (record not present) from the source disk.  The other is that BASIC's
 > INPUT#, GET#, and PRINT# commands respectively untalk, untalk, and unlisten
 > the addressed device when they are done, and unlistening or untalking a
 > disk
 > drive with an open relative file bumps the record pointer to the start of
 > the next higher record.
 
   Sorry to say this, but that serves you right for doing this in BASIC. File
copying accross devices is slow enough without introducing the fun of a BASIC 
interpreter. And, as you say, the BASIC commands do things you don't want them 
to. That's always the risk when using a high-level language.
 
 > One possible algorithm is this: read the block count and record length of
 > the
 > source file from its directory entry on the source disk.  Allow for side
 > sectors and take an estimate of how many records there are (empty as well
 > as
 > used).  Try to position to that record in the source file, and if you get
 > an
 > error 50, try one record lower; if you get an ok from the drive, try one
 > record higher.  Keep going until you've had at least one 50 and one ok so
 > that you have the proper count of records in the source file.
 
   Sounds like a good technique to me. Using a record buffer (only need one 
page, since records won't exceed 255 bytes in length), an ML program could 
copy the files quickly & easily:
 
Open the files;
 
LDX INCHAN              ; secondary address used for input file
JSR CHKIN
LDY #0
while not EOI {
  JSR $FFE4
  STA BUFFER,Y
  INY
  }
STY RECLEN
JSR CLRCHN              ; untalk
LDX OUTCHA              ; secondary adderss used for output file
JSR CHKOUT
LDY #0
WRLOOP LDA BUFFER,Y
JSR $FFD2
CPY RECLEN
BNE WRLOOP
JSR CLRCHN              ; unlisten
 
Repeat that for as many records as you need;
Close the files.
 
   In this way, commas, quotes, CRs, etc. all get copied into the new REL file 
record. No intermediate untalks to foul up record pointers.
 
 > But yes, relative files can be copied.  The c: DOS command in dual drives
 > (both from Commodore and from MSD) did it flawlessly.
 
   I have dumps of those ROMs in my Toronto office; perhaps it would be worth 
seeing how they did it (it may not always be the best way, but it works well 
(therefore always a good candidate for "best" anyways).
 


--  
 Geoffrey Welsh - via FidoNet node 1:221/162
     UUCP: ...!watmath!isishq!171!izot
 Internet: izot@f171.n221.z1.FIDONET.ORG

TRM900@PSUVM.BITNET (Tony R. Marasco) (04/11/89)

In the note,"Can REL files be copied?", mrios@ihlpb.ATT.COM (Rios) says:
>
>
>Is there a way to copy REL files from one drive to another for archival and
>backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.
>

  I have such a program.  If anyone needs it, just ask.
-------
+-------------------------------------------------------------------------+
| Tony Marasco                 |  UUCP: psuvax1!psuvm!trm900              |
| Penn State University        |  BITNET: trm900@psuvm.BITNET             |
| Schuylkill Haven Highway     |                   - or -                 |
| Schuylkill Haven, PA 17976   |  trm900%psuvm.psu.edu@CUNYVM.CUNY.EDU    |
| "Questions are a burden for others.  Answers are a prison for oneself." |
|       -- The Prisoner                                                   |
+-------------------------------------------------------------------------+

) (04/12/89)

In article <10180@ihlpb.ATT.COM> mrios@ihlpb.ATT.COM (Rios) writes:

>
>Is there a way to copy REL files from one drive to another for archival and
>backup purposes?  Ideally, copying from a 1571 to a 1581 would be good.
>

Yes there is... I think that the 1581 Demo-Disc has a copy program for
copying Rel-files from 1571 to 1581 and back...

But I'm not sure...

					Greetings Kianusch

 ------------------------------------------------------------------------------ 

        Remember I.C.S.L. ... It's going to be famous in the future...

dattier@jolnet.ORPK.IL.US (David W. Tamkin) (04/13/89)

Geoffrey Welsh wrote in <2030.2442CAD5@isishq.FIDONET.ORG> in comp.sys.cbm:

| > From: dwtamkin@chinet.chi.il.us (David W. Tamkin)
| > Message-ID: <8190@chinet.chi.il.us>
|  
| > One difficulty in copying relative files is that EOI (st=64) is sent at the
| > end of every record.  The only way to know when to stop reading is an error
| > 50 (record not present) from the source disk.  The other is that BASIC's
| > INPUT#, GET#, and PRINT# commands respectively untalk, untalk, and unlisten
| > the addressed device when they are done, and unlistening or untalking a
| > disk drive with an open relative file bumps the record pointer to the
| > start of the next higher record.
|  
|    Sorry to say this, but that serves you right for doing this in BASIC. File
| copying accross devices is slow enough without introducing the fun of a BASIC 
| interpreter. And, as you say, the BASIC commands do things you don't want
| them to. That's always the risk when using a high-level language.

Well, for those of you who saw this out of context, the bumping of the
record pointer plus the slowness were two reasons I recommended against
using BASIC.  Welsh *did* understand that, but those of you who didn't see
my article or who rely on smileys might need one after the "serves you
right" observation.

There might be other high-level languages that hold your hand without
cutting off your circulation; when it comes to relative files, Commodore
BASIC is not among them.  (In BASIC 3.5 and higher, when you have fixed-
length fields, the RECORD# command can undo the damage; however, the copy
program would need to figure out the lengths of the fields [by measuring the
strings so far from that record?], and that gets to be a major pain.  A copy
program should just grab a whole record without giving a hell what its
contents mean to any application programs, as Welsh's example shows.)

David W. Tamkin   POB 567542   Norridge IL  60656-7542  |       8 Nisan 5749
dattier@jolnet.orpk.il.us    Jolnet Public Access Unix  |  GEnie: D.W.TAMKIN
...!killer!jolnet!dattier        Orland Park, Illinois  |    CIS: 73720,1570
Anyone on Jolnet who agrees with me is welcome to speak up on his or her own.

jgreco@csd4.milw.wisc.edu (Joe Greco) (04/14/89)

In comp.sys.cbm article <2030.2442CAD5@isishq.FIDONET.ORG>, izot@f171.n221.z1.FIDONET.ORG (Geoffrey Welsh) wrote:
]
] > From: dwtamkin@chinet.chi.il.us (David W. Tamkin)
] > Message-ID: <8190@chinet.chi.il.us>
] 
] > One difficulty in copying relative files is that EOI (st=64) is sent at the
] > end of every record.  The only way to know when to stop reading is an error
] > 50 (record not present) from the source disk.  The other is that BASIC's
] > INPUT#, GET#, and PRINT# commands respectively untalk, untalk, and unlisten
] > the addressed device when they are done, and unlistening or untalking a
] > disk
] > drive with an open relative file bumps the record pointer to the start of
] > the next higher record.
] 
]   Sorry to say this, but that serves you right for doing this in BASIC. File
]copying accross devices is slow enough without introducing the fun of a BASIC 
]interpreter. And, as you say, the BASIC commands do things you don't want them 
]to. That's always the risk when using a high-level language.
] 
....
]   Sounds like a good technique to me. Using a record buffer (only need one 
]page, since records won't exceed 255 bytes in length), an ML program could 
]copy the files quickly & easily:
...
]   In this way, commas, quotes, CRs, etc. all get copied into the new REL file 
]record. No intermediate untalks to foul up record pointers.

Also note that one of the better ways of finding the max record length
is to open the physical directory file and LOOK.  That has the
disadvantage of not working with RAMDOS and some less than compatible
disk drives.

Maintaining the end of record pointer is IMPORTANT....  UNI-COPY (aka
COPY-ALL) does not do this, at least in my experience.

Ironically, I believe UNI-COPY uses the method of finding the max
record length that I described.

] > But yes, relative files can be copied.  The c: DOS command in dual drives
] > (both from Commodore and from MSD) did it flawlessly.
] 
]   I have dumps of those ROMs in my Toronto office; perhaps it would be worth 
]seeing how they did it (it may not always be the best way, but it works well 
](therefore always a good candidate for "best" anyways).

Commodore probably just uses a buffer-duplicate routine.  Since the
REL file is very similar to a SEQ file, all that really has to be done
differently is the rebuilding of the Side Sector Tables (and Super SS
tables, on some drives).  Can't say for sure that this IS how it is
done, but I can't imagine many other ways.
--
jgreco@csd4.milw.wisc.edu		Joe Greco at FidoNet 1:154/200
USnail: 9905 W Montana Ave			     PunterNet Node 30 or 31
	West Allis, WI  53227-3329	"These aren't anybody's opinions."
Voice:	414/321-6184			Data: 414/321-9287 (Happy Hacker's BBS)

jgreco@csd4.milw.wisc.edu (Joe Greco) (04/14/89)

In comp.sys.cbm article <6570@cbmvax.UUCP>, fred@cbmvax.UUCP (Fred Bowen) wrote:
>Sure- there are two copy programs on 1571 and 1581 test/demo diskettes which
>are capable of doing this:  Butterfield's UNICOPY and Commodore's FILECOPY.
>Why aren't you using the 1581 with the BBS?  It's faster, has greater capacity
>(size, number of files, and maximum size of REL files), and it costs less.

Butterfield's UNI-COPY (read COPY-ALL, to avoid confusion with his
UNI-COPY single drive program of long ago) corrupts the end of record
pointers.  I've never seen this "FILECOPY" program, it certainly was
NOT on my 1571 test/demo disk (and I haven't seen it on any 1581 disks.)

1581's are fair for BBS use.  I still prefer IEEE drives... ;-)  Three
8050's and a 2040 are still faster.
--
jgreco@csd4.milw.wisc.edu		Joe Greco at FidoNet 1:154/200
USnail: 9905 W Montana Ave			     PunterNet Node 30 or 31
	West Allis, WI  53227-3329	"These aren't anybody's opinions."
Voice:	414/321-6184			Data: 414/321-9287 (Happy Hacker's BBS)

izot@f171.n221.z1.FIDONET.ORG (Geoffrey Welsh) (04/15/89)

 > From: jgreco@csd4.milw.wisc.edu (Joe Greco)
 > Message-ID: <2023@csd4.milw.wisc.edu>
 
 > Also note that one of the better ways of finding the max record length
 > is to open the physical directory file and LOOK.  That has the
 > disadvantage of not working with RAMDOS and some less than compatible
 > disk drives.
 
   The method discussed finds the number of records in the file, not the 
number of bytes per record (which I think we'd all agree should be fetched 
from the directory file).
 


--  
 Geoffrey Welsh - via FidoNet node 1:221/162
     UUCP: ...!watmath!isishq!171!izot
 Internet: izot@f171.n221.z1.FIDONET.ORG

jgreco@csd4.milw.wisc.edu (Joe Greco) (04/21/89)

In comp.sys.cbm article <2063.244810B4@isishq.FIDONET.ORG>, izot@f171.n221.z1.FIDONET.ORG (Geoffrey Welsh) wrote:
]
] > From: jgreco@csd4.milw.wisc.edu (Joe Greco)
] > Message-ID: <2023@csd4.milw.wisc.edu>
] 
] > Also note that one of the better ways of finding the max record length
] > is to open the physical directory file and LOOK.  That has the
] > disadvantage of not working with RAMDOS and some less than compatible
] > disk drives.
] 
]   The method discussed finds the number of records in the file, not the 
]number of bytes per record (which I think we'd all agree should be fetched 
]from the directory file).

I must have lost the line of thought  :-)  ...  I think you are wrong,
fetching the number of bytes per record should not necessarily be
fetched from the directory file!

One innovative technique I saw used once involved reading a single
record (preserving the length) of the source file, writing over it
'till error occured, then rewriting the correct data.  It was a little
more complex, and had the disadvantage of not working so well with
write protected disks.  ;-)

Anyone have a FOOLPROOF method?
--
jgreco@csd4.milw.wisc.edu		Joe Greco at FidoNet 1:154/200
USnail: 9905 W Montana Ave			     PunterNet Node 30 or 31
	West Allis, WI  53227-3329	"These aren't anybody's opinions."
Voice:	414/321-6184			Data: 414/321-9287 (Happy Hacker's BBS)

fred@cbmvax.UUCP (Fred Bowen) (04/21/89)

In article <2156@csd4.milw.wisc.edu> Joe Greco writes:
>In article <2063.244810B4@isishq.FIDONET.ORG> Geoffrey Welsh wrote:
>] > Also note that one of the better ways of finding the max record length
>] > is to open the physical directory file and LOOK.  That has the
>] > disadvantage of not working with RAMDOS and some less than compatible
>] > disk drives.
>]
>]The method discussed finds the number of records in the file, not the 
>]number of bytes per record (which I think we'd all agree should be fetched 
>]from the directory file).
>
>fetching the number of bytes per record should not necessarily be
>fetched from the directory file!  Anyone have a FOOLPROOF method?

The best way is, to me anyway, the most obvious and straightforward- find the
end of the record by moving the record/byte pointer through the record until
the DOS returns an error.  This is how FILECOPY works.

The code from FILECOPY (f$ and n$(i) are the filename, sc and dc are the
source and destination channels, and sysba is some simple ML which reads/writes
blocks to minimize talker/attention turn around time):

5000 rem  copy rel file
5010 print "scanning ";f$
5020 open8,su,8,n$(i): u=sc: gosub 8000: if s then return
5030 l=0: for rn=7 to 0 step-1: rg=2^rn:	rem binary scan for reclen
5040 : r=1:l=l+rg:gosub 6000: if s then l=l-rg
5050 : next
5060 r=0: for rn=15 to 0step-1: rg=2^rn:	rem binary scan for numrec
5070 : r=r+rg: gosub 6000: if s then r=r-rg
5080 : next
5100 print "creating ";f$
5110 open9,du,9,n$(i)+",l,"+chr$(l)
5120 :  u=dc: gosub 8000: if s then return
5130 a$="p"+chr$(96+8)+chr$(1)+chr$(0)+chr$(1):   print#14,a$: print#14,a$
5140 :  u=sc: gosub 8000: if s then return
5150 a$="p"+chr$(96+9)+chr$(rl)+chr$(rh)+chr$(1): print#15,a$: print#15,a$
5160 :  print#9,chr$(255);:				rem write end record
5170 a$="p"+chr$(96+9)+chr$(1)+chr$(0)+chr$(1):   print#15,a$: print#15,a$
5180 :  u=dc: gosub 8000: if s then return
5200 print "copying ";f$
5210 for rn=1 to r: sysba: next
5220 close8: close9: u=dc: gosub 8000
5230 return
5240 :
6000 rh=int(r/256):rl=r-rh*256 :rem  send src p cmd.  r=rec#, l=offset
6010 a$="p"+chr$(96+8)+chr$(rl)+chr$(rh)+chr$(l): print#14,a$: print#14,a$
6020 : u=sc:			rem get disk stat & return
6030 :
8000 input#u,a$,b$,c$,d$: s=val(a$): s$=a$+e$+b$+e$+c$+e$+d$ :return
--
-- 
Fred Bowen			uucp:	{uunet|rutgers|pyramid}!cbmvax!fred
				arpa:	cbmvax!fred@uunet.uu.net
				tele:	215 431-9100

Commodore Electronics, Ltd.,  1200 Wilson Drive,  West Chester,  PA,  19380