/* Test file existence, using dircache of possible */ bool file_exists(const char *file) { int fd; #ifdef DEBUG if (!file || !*file) { DEBUGF("%s(%p): Invalid parameter!\n", __func__, file); return false; } #endif #ifdef HAVE_DIRCACHE if (dircache_is_enabled()) return (dircache_get_entry_ptr(file) != NULL); #endif fd = open(file, O_RDONLY); if (fd < 0) return false; close(fd); return true; }
static int open_internal(const char* pathname, int flags, bool use_cache) { DIR_UNCACHED* dir; struct dirent_uncached* entry; int fd; char pathnamecopy[MAX_PATH]; char* name; struct filedesc* file = NULL; int rc; #ifndef HAVE_DIRCACHE (void)use_cache; #endif LDEBUGF("open(\"%s\",%d)\n",pathname,flags); if ( pathname[0] != '/' ) { DEBUGF("'%s' is not an absolute path.\n",pathname); DEBUGF("Only absolute pathnames supported at the moment\n"); errno = EINVAL; return -1; } /* find a free file descriptor */ for ( fd=0; fd<MAX_OPEN_FILES; fd++ ) if ( !openfiles[fd].busy ) break; if ( fd == MAX_OPEN_FILES ) { DEBUGF("Too many files open\n"); errno = EMFILE; return -2; } file = &openfiles[fd]; memset(file, 0, sizeof(struct filedesc)); if (flags & (O_RDWR | O_WRONLY)) { file->write = true; if (flags & O_TRUNC) file->trunc = true; } file->busy = true; #ifdef HAVE_DIRCACHE if (dircache_is_enabled() && !file->write && use_cache) { const struct dircache_entry *ce; # ifdef HAVE_MULTIVOLUME int volume = strip_volume(pathname, pathnamecopy); # endif ce = dircache_get_entry_ptr(pathname); if (!ce) { errno = ENOENT; file->busy = false; return -7; } fat_open(IF_MV2(volume,) ce->startcluster, &(file->fatfile), NULL); file->size = ce->size; file->attr = ce->attribute; file->cacheoffset = -1; file->fileoffset = 0; return fd; } #endif strlcpy(pathnamecopy, pathname, sizeof(pathnamecopy)); /* locate filename */ name=strrchr(pathnamecopy+1,'/'); if ( name ) { *name = 0; dir = opendir_uncached(pathnamecopy); *name = '/'; name++; } else { dir = opendir_uncached("/"); name = pathnamecopy+1; } if (!dir) { DEBUGF("Failed opening dir\n"); errno = EIO; file->busy = false; return -4; } if(name[0] == 0) { DEBUGF("Empty file name\n"); errno = EINVAL; file->busy = false; closedir_uncached(dir); return -5; } /* scan dir for name */ while ((entry = readdir_uncached(dir))) { if ( !strcasecmp(name, entry->d_name) ) { fat_open(IF_MV2(dir->fatdir.file.volume,) entry->startcluster, &(file->fatfile), &(dir->fatdir)); file->size = file->trunc ? 0 : entry->size; file->attr = entry->attribute; break; } }