/* Open the source file for reading, closing any previously open file. If dir_list is not NULL, calls path_search() to search the file in dir_list */ bool SrcFile_open( SrcFile *self, const char *filename, UT_array *dir_list ) { /* close last file */ if (self->file != NULL) { xfclose(self->file); self->file = NULL; } /* search path, add to strpool */ const char *filename_path = path_search(filename, dir_list); /* check for recursive includes, return if found */ if (!check_recursive_include(self, filename_path)) return false; self->filename = filename_path; self->line_filename = filename_path; /* open new file in binary mode, for cross-platform newline processing */ self->file = fopen( self->filename, "rb" ); if (!self->file) error_read_file(self->filename); /* init current line */ Str_clear( self->line ); self->line_nr = 0; self->line_inc = 1; self->is_c_source = false; if (self->file) return true; else return false; /* error opening file */ }
/*----------------------------------------------------------------------------- * file error handling *----------------------------------------------------------------------------*/ static void file_error( char *filename, Bool writing ) { init_module(); if ( writing ) error_write_file( filename ); else error_read_file( filename ); }
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; }