/* Student No.: 111550046 Student Name: 周哲煒 Email: chou.cs11@nycu.edu.tw SE tag: xnxcxtxuxoxsx Statement: I am fully aware that this program is not supposed to be posted to a public server, such as a public GitHub repository or a public web page. */ #define FUSE_USE_VERSION 30 #include #include #include #include #include #include #include #include #include #include #include // Tar entry structure struct TarEntry { std::string name; mode_t mode; size_t size; size_t offset; size_t mtime; // Modification time size_t uid; // User ID size_t gid; // Group ID std::string linkname; // For symbolic links }; std::map tar_entries; const char *tar_file = "test.tar"; // Hardcoded filename //tohex std::string tooct(int n){ std::string oct; while(n!=0){ oct = std::to_string(n%8) + oct; n = n/8; } return oct; } // Helper: Parse the tar file and populate tar_entries void parse_tar_file() { FILE *file = fopen(tar_file, "rb"); if (!file) { perror("Failed to open tar file"); exit(EXIT_FAILURE); } char header[512]; size_t offset = 0; while (fread(header, 512, 1, file)) { if (header[0] == '\0') break; // End of tar file // Get metadata from header TarEntry entry; entry.name = std::string(header, 100).c_str(); // Null-terminated entry.mode = strtol(std::string(header + 100, 8).c_str(), nullptr, 8); entry.uid = strtol(std::string(header + 108, 8).c_str(), nullptr, 8); entry.gid = strtol(std::string(header + 116, 8).c_str(), nullptr, 8); entry.size = strtol(std::string(header + 124, 12).c_str(), nullptr, 8); entry.mtime = strtol(std::string(header + 136, 12).c_str(), nullptr, 8); entry.offset = offset + 512; entry.linkname = std::string(header + 157, 100).c_str(); /** / // Check if it's a directory (name ends with '/') if (entry.name.back() == '/') { std::cout<st_mode = S_IFDIR | 0444; // Read-only directory st->st_uid = getuid(); st->st_gid = getgid(); st->st_mtime = 0; st->st_size = 0; } else if (tar_entries.count(path)) { // File or directory in tar const TarEntry &entry = tar_entries[path]; // std::cout<< "go through: "<st_mode = S_IFDIR | entry.mode; // Directory st->st_uid = entry.uid; st->st_gid = entry.gid; st->st_mtime = entry.mtime; st->st_size = 0; // std::cout << "Directory|" << entry.name << "|"<st_mode) << "|" << st->st_nlink << "|" << st->st_size << "\n"; } else if(!entry.linkname.empty()) { // std::cout<< entry.linkname<<"\n"; st->st_mode = S_IFLNK | entry.mode; // Symbolic link st->st_uid = entry.uid; st->st_gid = entry.gid; st->st_mtime = entry.mtime; st->st_size = entry.size; // std::cout << "Symbolic Link|" << entry.name << "|"<st_mode) << "|" << st->st_nlink << "|" << st->st_size << "\n"; } else { st->st_mode = S_IFREG| entry.mode; st ->st_uid = entry.uid; st ->st_gid = entry.gid; st->st_mtime = entry.mtime; st->st_size = entry.size; // std::cout << "File|" << entry.name << "|"<st_mode) << "|" << st->st_nlink << "|" << st->st_size << "\n"; } } else { // std::cout<<"Not found\n"; return -ENOENT; // Not found } return 0; } // FUSE: readdir // List directory contents, called when listing files in a directory int my_readdir(const char *path, void *buffer, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { // std::cout<<"my_readdir\t"<< "path: "<