From 7e42b10078230e8813c11fda6edbd3612696a304 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 25 Feb 2023 20:28:23 +0100 Subject: [PATCH] fix: Make the untar example create parent directories if they don't exist (like mkdir -p) This lets it deal with tar archives that are packaged like this: usr/include/hello.h usr/include/bye.h usr/lib/libexample.a Instead of requiring directory entries: usr/ usr/include/ usr/include/hello.h (etc) This helps since some tar archives (our own example tool, pack, for example, does this) are packaged without directory entries. --- examples/untar.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/examples/untar.c b/examples/untar.c index c9e5706..4d793db 100644 --- a/examples/untar.c +++ b/examples/untar.c @@ -9,6 +9,7 @@ #define _XOPEN_SOURCE 700 #include #include +#include #include #include #include @@ -17,8 +18,37 @@ #include #include +static int create_parent_recursively(const char* path) +{ + char* path_copy = strdup(path); + if (!path_copy) return -1; + + char* parent = dirname(path_copy); + +create: + if (mkdir(parent, 0755) < 0) + { + if (errno == ENOENT) + { + create_parent_recursively(parent); + goto create; + } + + if (errno == EEXIST) goto success; + + free(path_copy); + return -1; + } + +success: + free(path_copy); + return 0; +} + static int untar_file(const struct minitar_entry* entry, const void* buf) { + if (create_parent_recursively(entry->metadata.path) < 0) return 1; + int fd = open(entry->metadata.path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644); if (fd < 0) return 1;