diff --git a/include/dwarfs/file_stat.h b/include/dwarfs/file_stat.h index 9dc2b6e9..d57dddf4 100644 --- a/include/dwarfs/file_stat.h +++ b/include/dwarfs/file_stat.h @@ -66,6 +66,9 @@ struct file_stat { return t == posix_file_type::block || t == posix_file_type::character; } + static std::string perm_string(mode_type mode); + static std::string mode_string(mode_type mode); + dev_type dev; ino_type ino; nlink_type nlink; diff --git a/src/dwarfs/file_stat.cpp b/src/dwarfs/file_stat.cpp index 82c52c7a..bc562d7c 100644 --- a/src/dwarfs/file_stat.cpp +++ b/src/dwarfs/file_stat.cpp @@ -61,6 +61,40 @@ uint64_t time_from_filetime(FILETIME const& ft) { #endif +char get_filetype_label(file_stat::mode_type mode) { + switch (posix_file_type::from_mode(mode)) { + case posix_file_type::regular: + return '-'; + case posix_file_type::directory: + return 'd'; + case posix_file_type::symlink: + return 'l'; + case posix_file_type::block: + return 'b'; + case posix_file_type::character: + return 'c'; + case posix_file_type::fifo: + return 'p'; + case posix_file_type::socket: + return 's'; + default: + DWARFS_THROW(runtime_error, + fmt::format("unknown file type: {:#06x}", mode)); + } +} + +void perms_to_stream(std::ostream& os, file_stat::mode_type mode) { + os << (mode & file_stat::mode_type(fs::perms::owner_read) ? 'r' : '-'); + os << (mode & file_stat::mode_type(fs::perms::owner_write) ? 'w' : '-'); + os << (mode & file_stat::mode_type(fs::perms::owner_exec) ? 'x' : '-'); + os << (mode & file_stat::mode_type(fs::perms::group_read) ? 'r' : '-'); + os << (mode & file_stat::mode_type(fs::perms::group_write) ? 'w' : '-'); + os << (mode & file_stat::mode_type(fs::perms::group_exec) ? 'x' : '-'); + os << (mode & file_stat::mode_type(fs::perms::others_read) ? 'r' : '-'); + os << (mode & file_stat::mode_type(fs::perms::others_write) ? 'w' : '-'); + os << (mode & file_stat::mode_type(fs::perms::others_exec) ? 'x' : '-'); +} + } // namespace #ifdef _WIN32 @@ -174,4 +208,22 @@ file_stat make_file_stat(fs::path const& path) { #endif +std::string file_stat::mode_string(mode_type mode) { + std::ostringstream oss; + + oss << (mode & mode_type(fs::perms::set_uid) ? 'U' : '-'); + oss << (mode & mode_type(fs::perms::set_gid) ? 'G' : '-'); + oss << (mode & mode_type(fs::perms::sticky_bit) ? 'S' : '-'); + oss << get_filetype_label(mode); + perms_to_stream(oss, mode); + + return oss.str(); +} + +std::string file_stat::perm_string(mode_type mode) { + std::ostringstream oss; + perms_to_stream(oss, mode); + return oss.str(); +} + } // namespace dwarfs diff --git a/src/dwarfs/metadata_v2.cpp b/src/dwarfs/metadata_v2.cpp index 8128f0e7..b4f98f28 100644 --- a/src/dwarfs/metadata_v2.cpp +++ b/src/dwarfs/metadata_v2.cpp @@ -583,28 +583,6 @@ class metadata_ final : public metadata_v2::impl { } } - static char get_filetype_label(uint16_t mode) { - switch (posix_file_type::from_mode(mode)) { - case posix_file_type::regular: - return '-'; - case posix_file_type::directory: - return 'd'; - case posix_file_type::symlink: - return 'l'; - case posix_file_type::block: - return 'b'; - case posix_file_type::character: - return 'c'; - case posix_file_type::fifo: - return 'p'; - case posix_file_type::socket: - return 's'; - default: - DWARFS_THROW(runtime_error, - fmt::format("unknown file type: {:#06x}", mode)); - } - } - size_t find_inode_offset(inode_rank rank) const { if (meta_.dir_entries()) { auto range = boost::irange(size_t(0), meta_.inodes().size()); @@ -651,8 +629,6 @@ class metadata_ final : public metadata_v2::impl { std::optional find(directory_view dir, std::string_view name) const; - std::string modestring(uint16_t mode) const; - uint32_t chunk_table_lookup(uint32_t ino) const { return chunk_table_.empty() ? meta_.chunk_table()[ino] : chunk_table_[ino]; } @@ -940,7 +916,7 @@ void metadata_::dump( auto mode = iv.mode(); auto inode = iv.inode_num(); - os << indent << " " << modestring(mode); + os << indent << " " << file_stat::mode_string(mode); if (inode > 0) { os << " " << entry.name(); @@ -1267,7 +1243,7 @@ folly::dynamic metadata_::as_dynamic(dir_entry_view entry) const { auto inode = iv.inode_num(); obj["mode"] = mode; - obj["modestring"] = modestring(mode); + obj["modestring"] = file_stat::mode_string(mode); obj["inode"] = inode; if (inode > 0) { @@ -1370,27 +1346,6 @@ std::string metadata_::serialize_as_json(bool simple) const { return json; } -template -std::string metadata_::modestring(uint16_t mode) const { - std::ostringstream oss; - - oss << (mode & uint16_t(fs::perms::set_uid) ? 'U' : '-'); - oss << (mode & uint16_t(fs::perms::set_gid) ? 'G' : '-'); - oss << (mode & uint16_t(fs::perms::sticky_bit) ? 'S' : '-'); - oss << get_filetype_label(mode); - oss << (mode & uint16_t(fs::perms::owner_read) ? 'r' : '-'); - oss << (mode & uint16_t(fs::perms::owner_write) ? 'w' : '-'); - oss << (mode & uint16_t(fs::perms::owner_exec) ? 'x' : '-'); - oss << (mode & uint16_t(fs::perms::group_read) ? 'r' : '-'); - oss << (mode & uint16_t(fs::perms::group_write) ? 'w' : '-'); - oss << (mode & uint16_t(fs::perms::group_exec) ? 'x' : '-'); - oss << (mode & uint16_t(fs::perms::others_read) ? 'r' : '-'); - oss << (mode & uint16_t(fs::perms::others_write) ? 'w' : '-'); - oss << (mode & uint16_t(fs::perms::others_exec) ? 'x' : '-'); - - return oss.str(); -} - template template void metadata_::walk(uint32_t self_index, uint32_t parent_index, @@ -1758,7 +1713,7 @@ folly::dynamic metadata_::get_inode_info(inode_view iv) const { } obj["mode"] = iv.mode(); - obj["modestring"] = modestring(iv.mode()); + obj["modestring"] = file_stat::mode_string(iv.mode()); obj["uid"] = iv.getuid(); obj["gid"] = iv.getgid();