diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-11-04 22:34:01 +0300 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-11-05 03:24:35 +0300 |
commit | a848bc3f3caac2cc56e5d9c7436e9950f87d6e93 (patch) | |
tree | 7b071a7ac7dc2ddafa36720d791e3c777a4fd844 | |
parent | 064171c0762f2cd8dbae4865d3e472e634f35bd2 (diff) |
Add mtar_foreach()
This is a very convienient way of iterating over a tar archive.
It can be used for search operations or data extraction and
mtar_find() has been re-implemented using it.
-rw-r--r-- | src/microtar.c | 27 | ||||
-rw-r--r-- | src/microtar.h | 4 |
2 files changed, 25 insertions, 6 deletions
diff --git a/src/microtar.c b/src/microtar.c index 37d3f5d..97f53fb 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -315,20 +315,35 @@ int mtar_next(mtar_t* tar) return ensure_header(tar); } -int mtar_find(mtar_t* tar, const char* name) +int mtar_foreach(mtar_t* tar, mtar_foreach_cb cb, void* arg) { - /* seek to the beginning */ int err = mtar_rewind(tar); if(err) return err; - /* iterate over all records */ while((err = mtar_next(tar)) == MTAR_ESUCCESS) - if(!strcmp(tar->header.name, name)) - return MTAR_ESUCCESS; + if((err = cb(tar, &tar->header, arg)) != 0) + return err; - /* hit the end of archive -> file not found */ if(err == MTAR_ENULLRECORD) + err = MTAR_ESUCCESS; + + return err; +} + +static int find_foreach_cb(mtar_t* tar, const mtar_header_t* h, void* arg) +{ + (void)tar; + const char* name = (const char*)arg; + return strcmp(name, h->name) ? 0 : 1; +} + +int mtar_find(mtar_t* tar, const char* name) +{ + int err = mtar_foreach(tar, find_foreach_cb, (void*)name); + if(err == 1) + err = MTAR_ESUCCESS; + else if(err == MTAR_ESUCCESS) err = MTAR_ENOTFOUND; return err; diff --git a/src/microtar.h b/src/microtar.h index c01f11d..a6d058b 100644 --- a/src/microtar.h +++ b/src/microtar.h @@ -43,6 +43,7 @@ enum { MTAR_ENOTFOUND = -8, MTAR_EOVERFLOW = -9, MTAR_EAPI = -10, + MTAR_ELAST = MTAR_EAPI, }; enum { @@ -59,6 +60,8 @@ typedef struct mtar_header mtar_header_t; typedef struct mtar mtar_t; typedef struct mtar_ops mtar_ops_t; +typedef int(*mtar_foreach_cb)(mtar_t*, const mtar_header_t*, void*); + struct mtar_header { unsigned mode; unsigned owner; @@ -100,6 +103,7 @@ const mtar_header_t* mtar_get_header(const mtar_t* tar); int mtar_rewind(mtar_t* tar); int mtar_next(mtar_t* tar); +int mtar_foreach(mtar_t* tar, mtar_foreach_cb cb, void* arg); int mtar_find(mtar_t* tar, const char* name); int mtar_read_data(mtar_t* tar, void* ptr, unsigned size); |