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