peter@sugar.uu.net (Peter da Silva) (11/26/88)
The following code does truly horrible things when I run it in a subdirectory
of RAD: (and maybe elsewhere, but I've only found a problem in RAD:s). The
somewhat odd sequence of file opening and closing is to minimise the disk
swaps in a one-drive system... for a file small enough to fit in the buffer
only one disk swap is needed, for example.
Anyway, there may be nothing wrong with this code, in which case I may have
found a bug in RAD:.
It will do things like creating a loop in the directory, the original file
will vanish, and the copy will not show up.
If I run it often enough it blows away RAD:, but VD0: is copacetic.
------- snip snip -------
#include <exec/memory.h>
#include <libraries/dos.h>
void *AllocMem();
#include <stdio.h>
#define COPYBUF 32768
FILE *debug = 0;
/* Quick kludge main() to kick the code off */
main(ac, av)
int ac;
char **av;
{
if(av[1][0] == '-' && av[1][1] == 'd') {
debug = stderr;
av++;
ac--;
}
if(ac < 3) {
TellUser("Not enough arguments", 0, 0);
exit(20);
}
CopyNamed(av[1], av[2]);
}
/* Copy a single named file. */
CopyNamed(from, to)
char *from, *to;
{
long Inlock;
struct FileInfoBlock *fib;
long Infile, Outfile;
char *buffer;
long bufsiz;
long nwrite, nread;
int ioerr;
/* Get file info block, for file protection and comment */
if(!(Inlock = Lock(from, MODE_OLDFILE))) {
TellUser("Can't Lock", from, IoErr());
return 0;
}
if(!(fib = AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC))) {
OutOfMemory(from);
UnLock(Inlock);
return 0;
}
if(!Examine(Inlock, fib)) {
TellUser("Can't Examine", from, IoErr());
FreeMem(fib, sizeof(struct FileInfoBlock));
UnLock(Inlock);
return 0;
}
UnLock(Inlock);
/* Allocate a moderately large buffer. */
for(bufsiz = COPYBUF; bufsiz >= 512; bufsiz /= 2)
if(buffer = AllocMem(bufsiz, MEMF_PUBLIC))
break;
if(bufsiz < 512) {
OutOfMemory(from);
FreeMem(fib, sizeof(struct FileInfoBlock));
return 0;
}
if(debug)
fprintf(debug, "About to open '%s' for reading.\n", from);
/* Open input file, read blocks from it, and close it as soon
as a partial read is made... this will keep us from having
to go back to the original disk if there's no more data */
if(!(Infile = Open(from, MODE_OLDFILE))) {
TellUser("Can't Open", from, IoErr());
FreeMem(buffer, bufsiz);
FreeMem(fib, sizeof(struct FileInfoBlock));
return 0;
}
if(debug)
fprintf(debug, "About to enter main loop, copying '%s' to '%s'\n",
from, to);
nread = Read(Infile, buffer, bufsiz);
if(nread < 0) ioerr = IoErr();
if(nread >= 0) {
if(nread < bufsiz) {
Close(Infile);
Infile = 0;
}
if(debug)
fprintf(debug, "About to open '%s' for writing.\n", to);
/* Held off opening output file until I'm about to write to it.
this, again, will reduce disk swaps */
if(!(Outfile = Open(to, MODE_NEWFILE))) {
TellUser("Can't Create", to, IoErr());
FreeMem(buffer, bufsiz);
if(Infile) Close(Infile);
FreeMem(fib, sizeof(struct FileInfoBlock));
return 0;
}
do {
if(Infile && nread < bufsiz) {
Close(Infile);
Infile = 0;
}
nwrite = Write(Outfile, buffer, nread);
fprintf(debug, "read %d wrote %d\n", nread, nwrite);
if(nwrite < nread) ioerr = IoErr();
} while(
Infile &&
nwrite == nread &&
(nread = Read(Infile, buffer, bufsiz)) > 0 );
if(nread < 0)
ioerr = IoErr();
if(debug)
fprintf(debug, "Finished, about to close files.\n");
Close(Outfile);
}
/* This will only happen on a write error */
if(Infile) Close(Infile);
FreeMem(buffer, bufsiz);
if(nread < 0) {
TellUser("Read error", from, ioerr);
FreeMem(fib, sizeof(struct FileInfoBlock));
return 0;
}
if(nwrite < nread) {
TellUser("Write error", from, ioerr);
FreeMem(fib, sizeof(struct FileInfoBlock));
return 0;
}
SetComment(to, fib->fib_Comment);
SetProtection(to, fib->fib_Protection);
FreeMem(fib, sizeof(struct FileInfoBlock));
if(debug)
fprintf(debug, "Copy successful, returning.\n");
return 1;
}
TellUser(msg, file, ioerr)
char *msg, *file;
int ioerr;
{
fprintf(stderr, "CopyTest");
if(file) fprintf(stderr, ": %s", file);
fprintf(stderr, ": %s", msg);
if(ioerr) fprintf(stderr, " -- Error %d", ioerr);
fprintf(stderr, ".\n");
}
OutOfMemory(file)
char *file;
{
TellUser("Out of Memory", file, 0);
}
--
Peter da Silva `-_-' peter@sugar.uu.net
Have you hugged U your wolf today?
Disclaimer: My typos are my own damn busines#!rne