diff --git a/cruft/util b/cruft/util index 174bd62..1ca4762 160000 --- a/cruft/util +++ b/cruft/util @@ -1 +1 @@ -Subproject commit 174bd62a293d3e15dc4fdc3112dea21443fc1d90 +Subproject commit 1ca47626aa5c033d9a40d7040657ba4ecc045155 diff --git a/tools/stat.cpp b/tools/stat.cpp index 0733543..2446b3c 100644 --- a/tools/stat.cpp +++ b/tools/stat.cpp @@ -12,12 +12,7 @@ #include -constexpr unsigned type_index (mode_t val) -{ - return (val & S_IFMT) >> cruft::ctz (unsigned {S_IFMT}); -} - - +/////////////////////////////////////////////////////////////////////////////// struct type_printer { type_printer (struct stat const &_data) : data (_data) @@ -26,6 +21,8 @@ struct type_printer { struct stat const &data; }; + +//----------------------------------------------------------------------------- std::ostream& operator<< (std::ostream &os, type_printer const &val) { os << "[ "; @@ -50,6 +47,7 @@ std::ostream& operator<< (std::ostream &os, type_printer const &val) } +/////////////////////////////////////////////////////////////////////////////// struct mode_printer { mode_printer (struct stat const &_data) : data (_data) @@ -59,6 +57,7 @@ struct mode_printer { }; +//----------------------------------------------------------------------------- std::ostream& operator<< (std::ostream &os, mode_printer const &val) { return S_ISREG (val.data.st_mode) ? os << "REGULAR" @@ -72,6 +71,7 @@ std::ostream& operator<< (std::ostream &os, mode_printer const &val) } +//----------------------------------------------------------------------------- std::ostream& operator<< (std::ostream &os, struct stat const &val) { return os << "{ dev: " << val.st_dev @@ -86,6 +86,61 @@ std::ostream& operator<< (std::ostream &os, struct stat const &val) } +/////////////////////////////////////////////////////////////////////////////// +static void do_stat (char const *path) +{ + struct stat buffer; + cruft::posix::error::try_call (stat, path, &buffer); + std::cout << buffer; +} + + +//----------------------------------------------------------------------------- +void do_xattr (char const *path) +{ + std::cout << ", xattr: "; + + { + std::cout << "{ "; + + std::string attr_list (1024, '\0'); + { + auto res = listxattr (path, attr_list.data (), attr_list.size ()); + if (res < 0) + cruft::posix::error::throw_code (); + attr_list.resize (res); + } + + std::string keybuffer (64, '\0'); + std::string val (128, '\0'); + cruft::view attr_view { attr_list.data (), attr_list.size () }; + for (auto const &key: cruft::tokeniser (attr_view, '\0')) { + keybuffer.resize (0); + std::copy (std::begin (key), std::end (key), std::back_inserter (keybuffer)); + + while (true) { + auto const res = getxattr (path, keybuffer.c_str (), val.data (), val.size ()); + if (res == E2BIG) { + val.resize (val.size () * 2); + continue; + } + + if (res < 0) + cruft::posix::error::throw_code (); + + val.resize (res); + break; + } + + std::cout << keybuffer << ": " << val << ", "; + } + + std::cout << "}"; + } +} + + +/////////////////////////////////////////////////////////////////////////////// int main (int argc, char **argv) { if (argc < 2) { @@ -97,52 +152,8 @@ int main (int argc, char **argv) std::cout << "{ stat: "; char const *path = argv[i]; - - { - struct stat buffer; - cruft::posix::error::try_call (stat, path, &buffer); - std::cout << buffer; - } - - std::cout << ", xattr: "; - - { - std::cout << "{ "; - - std::string attr_list (1024, '\0'); - { - auto res = listxattr (path, attr_list.data (), attr_list.size ()); - if (res < 0) - cruft::posix::error::throw_code (); - attr_list.resize (res); - } - - std::string keybuffer (64, '\0'); - std::string val (128, '\0'); - cruft::view attr_view { attr_list.data (), attr_list.size () }; - for (auto const &key: cruft::tokeniser (attr_view, '\0')) { - keybuffer.resize (0); - std::copy (std::begin (key), std::end (key), std::back_inserter (keybuffer)); - - while (true) { - auto const res = getxattr (path, keybuffer.c_str (), val.data (), val.size ()); - if (res == E2BIG) { - val.resize (val.size () * 2); - continue; - } - - if (res < 0) - cruft::posix::error::throw_code (); - - val.resize (res); - break; - } - - std::cout << keybuffer << ": " << val << ", "; - } - - std::cout << "}"; - } + do_stat (path); + do_xattr (path); std::cout << '\n'; }