Full path is now metadata->path and basename metadata->name

Shouldn't have rushed to 1.0.0 so quickly. Oh well, I guess I can allow 1.1.0...
This commit is contained in:
apio 2022-11-23 18:32:10 +01:00
parent b7c27a25a6
commit fd85cf1c6a
5 changed files with 46 additions and 13 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.8..3.22) cmake_minimum_required(VERSION 3.8..3.22)
project(minitar LANGUAGES C VERSION 1.0.0) project(minitar LANGUAGES C VERSION 1.1.0)
set(SOURCES set(SOURCES
src/tar.c src/tar.c

View File

@ -25,7 +25,7 @@ int main(int argc, char** argv)
do { do {
entry = minitar_read_entry(mp); entry = minitar_read_entry(mp);
if(entry) { if(entry) {
printf("%s\n", entry->metadata.name); printf("%s\n", entry->metadata.path);
minitar_free_entry(entry); minitar_free_entry(entry);
} }
} while(entry); } while(entry);
@ -75,10 +75,16 @@ The state of `mp` after `minitar_find_by_name()` returns is unspecified, but a s
In order to perform other minitar operations on the archive, `minitar_rewind()` should probably be called first, to get a known state. In order to perform other minitar operations on the archive, `minitar_rewind()` should probably be called first, to get a known state.
### minitar_find_by_path
`struct minitar_entry* minitar_find_by_path(struct minitar* mp, const char* path)`
Same as `minitar_find_by_name()`, but matches the full path inside the archive instead of the file name.
### minitar_find_any_of ### minitar_find_any_of
`struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type)` `struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type)`
Does the same thing as `minitar_find_by_name()`, but matches the file type instead of the name. As with `minitar_find_by_name()`, this function starts searching from the current archive position and calling it in a loop until it returns NULL will return all matching entries. Same as `minitar_find_by_name()`, but matches the file type instead of the name. As with `minitar_find_by_name()`, this function starts searching from the current archive position and calling it in a loop until it returns NULL will return all matching entries.
### minitar_read_contents ### minitar_read_contents
`size_t minitar_read_contents(struct minitar* mp, struct minitar_entry* entry, char* buf, size_t max)` `size_t minitar_read_contents(struct minitar* mp, struct minitar_entry* entry, char* buf, size_t max)`
@ -122,7 +128,9 @@ Other file types supported in tar archives, such as FIFOs or symlinks, are not s
This structure represents an entry's metadata, with the following fields: This structure represents an entry's metadata, with the following fields:
`name`: A string representing the full path of the entry within the archive. (`char[]`) `path`: A string representing the full path of the entry within the archive. (`char[]`)
`name`: A string representing the base name of the entry (the last component of its path). (`char[]`)
`mode`: An integer representing the permissions of the entry. (`mode_t`) `mode`: An integer representing the permissions of the entry. (`mode_t`)

View File

@ -22,7 +22,8 @@ enum minitar_file_type
struct minitar_entry_metadata struct minitar_entry_metadata
{ {
char name[257]; char path[257];
char name[128];
mode_t mode; mode_t mode;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
@ -49,6 +50,7 @@ extern "C"
void minitar_free_entry(struct minitar_entry* entry); void minitar_free_entry(struct minitar_entry* entry);
void minitar_rewind(struct minitar* mp); void minitar_rewind(struct minitar* mp);
struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name); struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name);
struct minitar_entry* minitar_find_by_path(struct minitar* mp, const char* path);
struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type); struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type);
int minitar_close(struct minitar* mp); int minitar_close(struct minitar* mp);
size_t minitar_read_contents(struct minitar* mp, struct minitar_entry* entry, char* buf, size_t max); size_t minitar_read_contents(struct minitar* mp, struct minitar_entry* entry, char* buf, size_t max);

View File

@ -92,6 +92,20 @@ struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name)
return NULL; return NULL;
} }
struct minitar_entry* minitar_find_by_path(struct minitar* mp, const char* path)
{
struct minitar_entry* entry;
do {
entry = minitar_read_entry(mp);
if (entry)
{
if (!strcmp(entry->metadata.path, path)) return entry;
minitar_free_entry(entry);
}
} while (entry);
return NULL;
}
struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type) struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type)
{ {
struct minitar_entry* entry; struct minitar_entry* entry;

View File

@ -3,6 +3,7 @@
#define _IN_MINITAR #define _IN_MINITAR
#include "minitar.h" #include "minitar.h"
#include "tar.h" #include "tar.h"
#include <libgen.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdnoreturn.h> #include <stdnoreturn.h>
@ -58,30 +59,38 @@ void minitar_parse_metadata_from_tar_header(const struct tar_header* hdr, struct
{ {
if (!strlen(hdr->prefix)) if (!strlen(hdr->prefix))
{ {
minitar_strlcpy(metadata->name, hdr->name, 100); size_t size = minitar_strlcpy(metadata->path, hdr->name, 100);
metadata->name[100] = '\0'; if (size >= 100) metadata->path[100] = '\0';
else
metadata->path[size] = '\0';
} }
else else
{ {
minitar_strlcpy(metadata->name, hdr->prefix, 155); minitar_strlcpy(metadata->path, hdr->prefix, 155);
minitar_append_char(metadata->name, '/'); minitar_append_char(metadata->path, '/');
strncat(metadata->name, hdr->name, 100); strncat(metadata->path, hdr->name, 100);
metadata->name[256] = '\0'; metadata->path[256] = '\0';
} }
char* mut_path = strdup(metadata->path);
if (!mut_path) minitar_panic("Failed to allocate memory");
char* bname = basename(mut_path);
minitar_strlcpy(metadata->name, bname, sizeof(metadata->name));
free(mut_path);
metadata->mode = (mode_t)strtoul(hdr->mode, NULL, 8); metadata->mode = (mode_t)strtoul(hdr->mode, NULL, 8);
metadata->uid = (uid_t)strtoul(hdr->uid, NULL, 8); metadata->uid = (uid_t)strtoul(hdr->uid, NULL, 8);
metadata->gid = (gid_t)strtoul(hdr->gid, NULL, 8); metadata->gid = (gid_t)strtoul(hdr->gid, NULL, 8);
char* sizeptr = strndup( char* sizeptr = strndup(
hdr->size, 12); // The hdr->size field is not null-terminated, yet strndup returns a null-terminated string. hdr->size, 12); // The hdr->size field is not null-terminated, yet strndup returns a null-terminated string.
if (!sizeptr) minitar_panic("Failed to allocate memory to duplicate a tar header's size field"); if (!sizeptr) minitar_panic("Failed to allocate memory");
metadata->size = (size_t)strtoull(sizeptr, NULL, 8); metadata->size = (size_t)strtoull(sizeptr, NULL, 8);
free(sizeptr); free(sizeptr);
char* timeptr = strndup( char* timeptr = strndup(
hdr->mtime, 12); // The hdr->mtime field is not null-terminated, yet strndup returns a null-terminated string. hdr->mtime, 12); // The hdr->mtime field is not null-terminated, yet strndup returns a null-terminated string.
if (!timeptr) minitar_panic("Failed to allocate memory to duplicate a tar header's mtime field"); if (!timeptr) minitar_panic("Failed to allocate memory");
metadata->mtime = (time_t)strtoull(timeptr, NULL, 8); metadata->mtime = (time_t)strtoull(timeptr, NULL, 8);
free(timeptr); free(timeptr);