From a3d3cddeb38fd64d39d59e32be4b838d03cf353c Mon Sep 17 00:00:00 2001 From: apio Date: Sun, 6 Nov 2022 11:51:03 +0100 Subject: [PATCH] Add functions to search for specific files or file types --- README.md | 18 +++++++++++++++++- minitar.h | 2 ++ src/tar.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 464405e..0e1a2f5 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,29 @@ This function returns NULL on end-of-file (when all entries have been read). ### minitar_free_entry `void minitar_free_entry(struct minitar_entry* entry)` -Frees the heap-allocated `struct minitar_entry` and the file contents stored inside it. The pointer passed to `minitar_free_entry()` should be the return value of a previous call to `minitar_read_entry()`. +Frees the heap-allocated `struct minitar_entry` and the file contents stored inside it. The pointer passed to `minitar_free_entry()` should be the return value of a previous call to `minitar_read_entry()`, `minitar_find_by_name()` or `minitar_find_any_of()`. ### minitar_rewind `void minitar_rewind(struct minitar* mp)` Rewinds the `struct minitar` back to the beginning of the archive file, which means that the next call to `minitar_read_entry()` will return the first entry instead of the entry after the last read entry. +### minitar_find_by_name +`struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name)` + +Returns the first entry with a matching name, or NULL if none are found. The return value is a `struct minitar_entry`, which is heap-allocated and should be freed after use with `minitar_free_entry()`. This structure is already documented in the entry documenting `minitar_read_entry()`. + +This function starts searching from the current archive position, which means that to find a matching entry in the entire archive `minitar_rewind()` should be called on it first. + +The state of `mp` after `minitar_find_by_name()` returns is unspecified, but a successive call to `minitar_find_by_name()` will return the next matching entry, if there is one. (Calling `minitar_find_by_name()` in a loop until it returns NULL will return all matching entries.) + +In order to petform other minitar operations on the archive, `minitar_rewind()` should probably be called first, to get a known state. + +### minitar_find_any_of +`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. + ### minitar_close `int minitar_close(struct minitar* mp)` diff --git a/minitar.h b/minitar.h index e8ad393..dcaf38b 100644 --- a/minitar.h +++ b/minitar.h @@ -43,6 +43,8 @@ struct minitar* minitar_open(const char* pathname); struct minitar_entry* minitar_read_entry(struct minitar* mp); void minitar_free_entry(struct minitar_entry* entry); void minitar_rewind(struct minitar* mp); +struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name); +struct minitar_entry* minitar_find_any_of(struct minitar* mp, enum minitar_file_type type); int minitar_close(struct minitar* mp); #endif \ No newline at end of file diff --git a/src/tar.c b/src/tar.c index b7cb056..8e71332 100644 --- a/src/tar.c +++ b/src/tar.c @@ -2,6 +2,7 @@ #include "tar.h" #include "minitar.h" #include +#include int minitar_read_header(struct minitar* mp, struct tar_header* hdr); int minitar_validate_header(struct tar_header* hdr); @@ -72,4 +73,32 @@ void minitar_free_entry(struct minitar_entry* entry) { free(entry->ptr); free(entry); +} + +struct minitar_entry* minitar_find_by_name(struct minitar* mp, const char* name) +{ + struct minitar_entry* entry; + do { + entry = minitar_read_entry(mp); + if (entry) + { + if (!strcmp(entry->metadata.name, name)) 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* entry; + do { + entry = minitar_read_entry(mp); + if (entry) + { + if (entry->metadata.type == type) return entry; + minitar_free_entry(entry); + } + } while (entry); + return NULL; } \ No newline at end of file