[comp.sys.misc] HELP with C-Power

schaefer@ogcvax.UUCP (04/27/87)

Would someone please tell me what is wrong with this program?  I am trying to
implement a two-diskette copy with one drive, which means switching diskettes.
The first funny thing I found (by #defining DEBUG in the code below) was that
"getchar()" will return a space (0x20) followed by a carriage return (0xd) if
I press RETURN at the prompt.  This I solved by changing from a simple call to
getchar() to the "while" statements in the program as it stands.  Both before
fixing this, and in the version below, weird things happen following the SECOND
while(getchar()) -- the printf() works OK, but the opendir() seems to go out to
lunch (regardless of whether I switch diskettes at the prompt or not).  The
cursor reappears, and the program seems to be reading from the keyboard; if I
hit RETURN often enough, the disk drive light starts flashing, indicating
error.  The first few times this happened, I hit RUN/STOP-RESTORE, exited the
shell with "bye", and ran a 5-line BASIC program to read the error channel.
Every time, the result was the same:  error 70, No Channel.

Any ideas on this?  Is opendir() broken, or perhaps closedir()?  Or is there
an obvious mistake I've made, but am somehow missing?  Code follows.  Some
additional comments have been inserted to help explain what is and isn't
working.

/* Diskette-to-diskette copy */

#include "stdio.h"
#include "dir.h"

#define BSIZ 256

/* File types */
#define CLOSED 0x80
#define DEL    0x00
#define SEQ    0x01
#define PRG    0x02
#define USR    0x03
#define REL    0x04

main (argc,argv)
unsigned argc;
char **argv;
{
   unsigned found, size, max;
   char *fbuf, *fb, file1[16], file2[16], fname[20], c, *typ;
   FILE fp;
   struct direct *dir;

   if (--argc == 0) {
      printf("usage: cp file1 [file2]\n");
      exit();
   }
   strncpy(file1,argv[1],16);
   if (argc == 2)
      strncpy(file2,argv[2],16);
   else
      strcpy(file2,file1);
   printf("Insert source disk --\n");
   printf("Press return to continue\n");
   while ((c = getchar()) != '\n');
#ifdef DEBUG
   printf("getchar=%x\n",(unsigned)c);
#endif
   /* Open the directory and dig out the type of the file, so the user need
      not enter it. */
   opendir(0);
   found = 0;
   /* Search for the file name. */
   while (dir = readdir()) {
      if (strncmp(dir->name,file1,strlen(file1)) == 0) {
         found = 1;
         break;
      }
   }
   closedir();
   if (! found) {
      printf("%s: %s:\n file not found\n",argv[0],file1);
      exit();
   }
   strcpy(fname,file1);
   /* Check to see if properly closed after last write */
   if (! (dir->type & CLOSED)) {
      printf("%s: warning --\n",argv[0]);
      printf(" file %s not properly closed\n",file1);
   }
   /* Mask off closed flag and get appropriate string for type */
   switch (dir->type & ~CLOSED) {
      case DEL :   /* Deleted file */
         printf("%s: %s:\n File no longer exists\n",argv[0],file1);
         exit();
      case SEQ :   /* Sequential */
         typ = ",s";
         break;
      case REL :   /* Relative */
         typ = ",l";
         break;
      case PRG :   /* Program */
         typ = ",p";
         break;
      case USR :   /* User file */
         typ = ",u";
         break;
      default :    /* Flaky directory entry */
         printf("%s: %s: Bad file type %x\n",(unsigned)(dir->type));
         exit();
   }
   /* Append "type suffix" to filename and open the file */
   strcat(fname,typ);
   fp = fopen(fname,"r");
   if (ferror() || !fp) {
      printf("%s: Can't open %s\n",argv[0],file1);
      exit();
   }
   /* Allocate a buffer to read into */
   max = dir->nblocks * BSIZ;
   fbuf = malloc(max);
   if (fbuf <= 0) {
      printf("%s: Can't malloc buffer\n",argv[0]);
      exit();
   }
   fb = fbuf; size = 0;
   printf("Reading ...\n");
   /* Read the file 1 byte at a call to get accurate size */
   while ((size < max) && (fread(fb++,sizeof(char),1,fp) > 0) && !ferror())
      size++;
   if (! feof(fp))
      printf("%s: warning --\n %s not fully copied\n",argv[0],file1);
   printf("Read %d bytes\n",size);
   fclose(fp);
#ifdef DEBUG
   fwrite(fbuf,sizeof(char),size,stdout);   /* This DOES print the file */
#endif
   printf("Insert destination disk --\n");
   printf("Press return to continue\n");
   while ((c = getchar()) != '\n');
#ifdef DEBUG
   printf("getchar=%x\n",(unsigned)c);
   open(8,8,15,"i");   /* This works OK -- initialize diskette */
   close(8);
#endif
   /* Up to here, everything has gone as expected ... */
   /* Open the second disk's directory to check for existence of file2 */
   opendir(0);
   if (ferror()) {
      /* Never get this error message */
      printf("%s: Can't open directory\n",argv[0]);
      exit();
   }
   found = 0;
   /* Search for file2, hoping we won't find it */
   while (dir = readdir()) {
      if (strncmp(dir->name,file2,strlen(file2)) == 0) {
         found = 1;
         break;
      }
   }
   closedir();
   if (found) {
      /* Never get this, either, even when the file DOES exist */
      printf("%s: %s: file exists\n",argv[0],file2);
      exit();
   }
   /* Append "type suffix" to destination file name, and open the file */
   strcpy(fname,file2);
   strcat(fname,typ);
   fp = fopen(fname,"w");
   if (ferror() || !fp) {
      printf("%s: Can't open %s\n",argv[0],file2);
      exit();
   }
   printf("Writing ...\n");   /* Never make it here */
   /* Dump the whole buffer in one write */
   fwrite(fbuf,sizeof(char),size,fp);
   if (ferror())
      printf("%s: warning -- error writing %s\n",argv[0],file2);
   fclose(fp);
   exit();
}
-- 
Bart Schaefer						Dept. of CS&E
CSNET:	schaefer@Oregon-Grad				Oregon Graduate Center
UUCP:	{ihnp4,seismo,sun}!verdix \			19600 NW Von Neumann Dr
 {hplabs,ucbvax,decvax}!tektronix  !ogcvax!schaefer	Beaverton, OR  97006