50 lines
1.8 KiB
C++
50 lines
1.8 KiB
C++
// vfs_cat -- print one file from a layered VFS to stdout (for byte-equality
|
|
// checks against `unzip -p`, and as a tiny inspection tool).
|
|
//
|
|
// vfs_cat [--registration] (--zip ARCHIVE | --native DIR)... REL
|
|
// vfs_cat --list (--zip ARCHIVE | --native DIR)... [PREFIX]
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
#include "mars/vfs/vfs.h"
|
|
|
|
using namespace mars::vfs;
|
|
|
|
int main(int argc, char** argv) {
|
|
Order order = Order::NativeFirst;
|
|
bool list = false;
|
|
std::string rel;
|
|
std::vector<std::pair<bool, std::string>> mounts; // (is_zip, path)
|
|
for (int i = 1; i < argc; ++i) {
|
|
std::string a = argv[i];
|
|
if (a == "--registration") order = Order::Registration;
|
|
else if (a == "--list") list = true;
|
|
else if ((a == "--zip" || a == "--native") && i + 1 < argc) mounts.emplace_back(a == "--zip", argv[++i]);
|
|
else rel = a;
|
|
}
|
|
if (mounts.empty() || (!list && rel.empty())) {
|
|
std::fprintf(stderr, "usage: vfs_cat [--registration] (--zip A | --native D)... REL\n"
|
|
" vfs_cat --list (--zip A | --native D)... [PREFIX]\n");
|
|
return 2;
|
|
}
|
|
Vfs v(order);
|
|
for (const auto& [is_zip, path] : mounts) {
|
|
auto r = is_zip ? v.mount_zip(path) : v.mount_native(path);
|
|
if (!r) {
|
|
std::fprintf(stderr, "mount %s: %s\n", path.c_str(), r.error().message.c_str());
|
|
return 1;
|
|
}
|
|
}
|
|
if (list) {
|
|
for (const auto& e : v.list(rel)) std::printf("%10llu m%d %s\n", static_cast<unsigned long long>(e.size), e.mount, e.name.c_str());
|
|
return 0;
|
|
}
|
|
auto bytes = v.read(rel);
|
|
if (!bytes) {
|
|
std::fprintf(stderr, "%s: %s\n", rel.c_str(), bytes.error().message.c_str());
|
|
return 1;
|
|
}
|
|
std::fwrite(bytes->data(), 1, bytes->size(), stdout);
|
|
return 0;
|
|
}
|