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