wxString SfsEntry::resolve(void) const { if (isSymlink()) { char resolved_path[PATH_MAX]; if (realpath(path_.fn_str(), resolved_path) != 0) return wxString::FromAscii(resolved_path); } return (wxEmptyString); }
bool isLink(const bfs::path& path) { if (isSymlink(path)) { return true; } #ifdef MACOSX // aliases appear as regular files if (isRegularFile(path)) { FSRef ref; if (FSPathMakeRef((const UInt8*)path.c_str(), &ref, NULL) == noErr) { Boolean isAlias = false, isFolder = false; if (FSIsAliasFile(&ref, &isAlias, &isFolder) == noErr) { return isAlias; } } } #endif return false; }
/** * Recursively visit all files / directories starting at the given directory. */ FileVisitor::VisitResult File::visitMe(const VisitOptions &options, unsigned maxDepth) const { FileVisitor::VisitResult vr = FileVisitor::VisitResult::CONTINUE; if (isSymlink()) { if (!options.followSymLinks) return vr; // visit the symlink location instead char buf[PATH_MAX]; ssize_t s = readlink(getFullname().c_str(), buf, sizeof(buf)); if (s <= 0) { Log::perror(getFullname()); throw std::runtime_error(std::string("Cannot read a symlink ") + getFullname()); } // terminate string buf[s] = 0; if (buf[0] == PATH_SEP_CHAR) { // absolute link location File linked(buf); return linked.visitMe(options, maxDepth); } else { // relative link location File linked(*this, buf); return linked.visitMe(options, maxDepth); } } if (isDirectory()) { if (maxDepth > 0) { vr = options.visitor.visitDirectory(*this); if (vr == FileVisitor::VisitResult::STOP) return vr; if (vr == FileVisitor::VisitResult::STOP_DIR) { options.visitor.afterVisitDirectory(*this); return FileVisitor::VisitResult::CONTINUE; } // recurse with max depth - 1 vr = recurseInto(options, maxDepth - 1); if (vr == FileVisitor::VisitResult::STOP) return vr; // what to do at end of of directory vr = options.visitor.afterVisitDirectory(*this); } } else { if (options.visitNonRegular || isRegularFile()) vr = options.visitor.visitFile(*this); else vr = FileVisitor::VisitResult::CONTINUE; } if (vr == FileVisitor::VisitResult::STOP) return vr; if (vr == FileVisitor::VisitResult::STOP_DIR) return FileVisitor::VisitResult::CONTINUE; return vr; }
/** Get file attributes. * * Similar to stat(). The 'st_dev' and 'st_blksize' fields are * ignored. The 'st_ino' field is ignored except if the 'use_ino' * mount option is given. * * struct stat { * dev_t st_dev; // ID of device containing file * ino_t st_ino; // inode number * mode_t st_mode; // protection * nlink_t st_nlink; // number of hard links * uid_t st_uid; // user ID of owner * gid_t st_gid; // group ID of owner * dev_t st_rdev; // device ID (if special file) * off_t st_size; // total size, in bytes * blksize_t st_blksize; // blocksize for file system I/O * blkcnt_t st_blocks; // number of 512B blocks allocated * time_t st_atime; // time of last access * time_t st_mtime; // time of last modification * time_t st_ctime; // time of last status change * }; */ static int fuse_getattr(const char *path, struct stat *buf) { #ifndef HIDE_COMPLETED tolog(path); tolog(" - getattr\n"); #endif struct timeval tv; if (gettimeofday(&tv, NULL) == 0) { buf->st_atime = tv.tv_sec; buf->st_mtime = tv.tv_sec; buf->st_ctime = tv.tv_sec; } buf->st_uid = FILE_UID; buf->st_gid = FILE_GID; if (isDirectory(path)) { buf->st_mode = S_IFDIR | S_IRWXU; buf->st_nlink = 2; return 0; } if (isSymlink(path)) { buf->st_mode = S_IFLNK | S_IRWXU; buf->st_nlink = 1; return 0; } if (isOffset(path)) { // Even though it's read-only, the write flag is there in case // a library we use requires write access. It won't be able to write to // the file of course, but it will think it can. buf->st_mode = S_IFREG | S_IRUSR | S_IWUSR; buf->st_nlink = 1; off_t offset = -1; off_t length = -1; sscanf(path + 1, "%llu-%llu", (unsigned long long *) &offset, (unsigned long long *) &length); if ((length == -1) || (length > (mappedFile_size - offset))) { if (mappedFile_size < offset) { length = 0; } else { length = mappedFile_size - offset; } } buf->st_size = length; buf->st_blocks = (buf->st_size + 511) / 512; return 0; } if (isMetaFilename(path)) { // While we are aware of such a beast, these are all zero sized. buf->st_mode = S_IFREG | S_IRUSR | S_IWUSR; buf->st_nlink = 1; buf->st_size = 0; buf->st_blocks = 0; return 0; } // They might be enquiring about the usage file. if (g_strcmp0(path, "/" USAGE_FILE) == 0) { buf->st_mode = S_IFREG | S_IRUSR | S_IWUSR; buf->st_nlink = 1; buf->st_size = strlen(USAGE_FILE_CONTENT); buf->st_blocks = (buf->st_size + 511) / 512; return 0; } return -ENOENT; }