int Fcopy(FILE * const fdst, FILE * const fsrc) { byte *buf; size_t len, i; int err; DBG_ENTER("Fcopy", Suppl_supplio) assert(fsrc); assert(fdst); chkHeap if(Fmaxbuf(&buf, &len)) DBG_RETURN_I( 3) /* out of memory */ chkHeap while((err = Fcopybuf(fdst, fsrc, buf, len, &i)) == 0); chkHeap free(buf); /* err == 0 --> impossible err == 1 --> read error, this is OK, if read had hit EOF */ chkHeap DBG_RETURN_BI(err < 2? Feof(fsrc) == 0: err) }
int copy(char *dst, char *pattern, struct CopySource *src , int openMode) { char mode[3], *p; struct ffblk ff; struct CopySource *h; char *rDest, *rSrc; FILE *fin, *fout; int rc, asc; char *buf; size_t len; assert(dst); assert(pattern); assert(src); if(FINDFIRST(pattern, &ff, FA_RDONLY | FA_ARCH) != 0) { error_sfile_not_found(pattern); return 0; } mode[2] = '\0'; do { if((rDest = fillFnam(dst, ff.ff_name)) == 0) return 0; h = src; do { /* to prevent to open a source file for writing, e.g. for COPY *.c *.? */ if((rSrc = fillFnam(h->fnam, ff.ff_name)) == 0) { free(rDest); return 0; } rc = samefile(rDest, rSrc); free(rSrc); if(rc < 0) { error_out_of_memory(); free(rDest); return 0; } else if(rc) { error_selfcopy(rDest); free(rDest); return 0; } } while((h = h->app) != 0); if(interactive_command /* Suppress prompt if in batch file */ && openMode != 'a' && !optY && (fout = fopen(rDest, "rb")) != 0) { int destIsDevice = isadev(fileno(fout)); fclose(fout); if(!destIsDevice) { /* Devices do always exist */ switch(userprompt(PROMPT_OVERWRITE_FILE, rDest)) { default: /* Error */ case 4: /* Quit */ free(rDest); return 0; case 3: /* All */ optY = 1; case 1: /* Yes */ break; case 2: /* No */ free(rDest); continue; } } } if(cbreak) { free(rDest); return 0; } mode[0] = openMode; mode[1] = 'b'; if((fout = fdevopen(rDest, mode)) == 0) { error_open_file(rDest); free(rDest); return 0; } mode[0] = 'r'; h = src; do { if((rSrc = fillFnam(h->fnam, ff.ff_name)) == 0) { fclose(fout); free(rDest); return 0; } mode[1] = (asc = h->flags & ASCII) != 0? 't': 'b'; reOpenIn: if((fin = fdevopen(rSrc, mode)) == 0) { error_open_file(rSrc); fclose(fout); free(rSrc); free(rDest); return 0; } if(isadev(fileno(fin)) && mode[1] != 't' && (h->flags & BINARY) == 0) { /* character devices are opened in textmode by default */ fclose(fin); mode[1] = 't'; goto reOpenIn; } dispCopy(rSrc, rDest, openMode == 'a' || h != src); if(cbreak) { fclose(fin); fclose(fout); free(rSrc); free(rDest); return 0; } /* Now copy the file */ rc = 1; if(mode[1] != 't') { /* binary file */ if(Fcopy(fout, fin) != 0) { if(ferror(fin)) { error_read_file(rSrc); } else if(ferror(fout)) { error_write_file(rDest); } else error_copy(); rc = 0; } } else { /* text file, manually transform '\n' */ if(Fmaxbuf((byte**)&buf, &len) == 0) { if(len > INT_MAX) len = INT_MAX; while(fgets(buf, len, fin)) { p = strchr(buf, '\0'); if(*--p == '\n') { *p = '\0'; fputs(buf, fout); putc('\r', fout); putc('\n', fout); } else fputs(buf, fout); } free(buf); } else { error_out_of_memory(); rc = 0; } } if(rc) if(ferror(fin)) { error_read_file(rSrc); rc = 0; } else if(ferror(fout)) { error_write_file(rDest); rc = 0; } if(cbreak) rc = 0; fclose(fin); free(rSrc); if(!rc) { fclose(fout); free(rDest); return 0; } } while((h = h->app) != 0); if(asc) { /* append the ^Z as we copied in ASCII mode */ putc(0x1a, fout); } rc = ferror(fout); fclose(fout); if(rc) { error_write_file(rDest); free(rDest); return 0; } free(rDest); } while(FINDNEXT(&ff) == 0); return 1; }