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.
This commit is contained in:
apio 2023-02-25 20:28:23 +01:00
parent cb432fd306
commit 7e42b10078
Signed by: apio
GPG Key ID: B8A7D06E42258954

View File

@ -9,6 +9,7 @@
#define _XOPEN_SOURCE 700 #define _XOPEN_SOURCE 700
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <libgen.h>
#include <minitar.h> #include <minitar.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -17,8 +18,37 @@
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
#include <unistd.h> #include <unistd.h>
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) 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); int fd = open(entry->metadata.path, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0644);
if (fd < 0) return 1; if (fd < 0) return 1;