tar: Implement support for extended headers :^)

This commit is contained in:
Tim Schumacher 2022-03-04 20:42:27 +01:00 committed by Andreas Kling
parent f6e86915f5
commit 495a1be925
Notes: sideshowbarker 2024-07-17 23:07:41 +09:00

View file

@ -77,13 +77,57 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
warnln("the provided file is not a well-formatted ustar file");
return 1;
}
HashMap<String, String> global_overrides;
HashMap<String, String> local_overrides;
auto get_override = [&](StringView key) -> Optional<String> {
Optional<String> maybe_local = local_overrides.get(key);
if (maybe_local.has_value())
return maybe_local;
Optional<String> maybe_global = global_overrides.get(key);
if (maybe_global.has_value())
return maybe_global;
return {};
};
for (; !tar_stream.finished(); tar_stream.advance()) {
const Archive::TarFileHeader& header = tar_stream.header();
// Handle meta-entries earlier to avoid consuming the file content stream.
if (header.content_is_like_extended_header()) {
switch (header.type_flag()) {
case Archive::TarFileType::GlobalExtendedHeader: {
TRY(tar_stream.for_each_extended_header([&](StringView key, StringView value) {
if (value.length() == 0)
global_overrides.remove(key);
else
global_overrides.set(key, value);
}));
break;
}
case Archive::TarFileType::ExtendedHeader: {
TRY(tar_stream.for_each_extended_header([&](StringView key, StringView value) {
local_overrides.set(key, value);
}));
break;
}
default:
warnln("Unknown extended header type '{}' of {}", (char)header.type_flag(), header.filename());
VERIFY_NOT_REACHED();
}
continue;
}
LexicalPath path = LexicalPath(header.filename());
if (!header.prefix().is_empty())
path = path.prepend(header.prefix());
String filename = path.string();
String filename = get_override("path"sv).value_or(path.string());
if (list || verbose)
outln("{}", filename);
@ -122,20 +166,15 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
return result_or_error.error();
break;
}
case Archive::TarFileType::GlobalExtendedHeader: {
dbgln("ignoring global extended header: {}", header.filename());
break;
}
case Archive::TarFileType::ExtendedHeader: {
dbgln("ignoring extended header: {}", header.filename());
break;
}
default:
// FIXME: Implement other file types
warnln("file type '{}' of {} is not yet supported", (char)header.type_flag(), header.filename());
VERIFY_NOT_REACHED();
}
}
// Non-global headers should be cleared after every file.
local_overrides.clear();
}
file_stream.close();