Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/amachronic/microtar.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/microtar.c')
-rw-r--r--src/microtar.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/microtar.c b/src/microtar.c
index 5ae7eeb..d304e6d 100644
--- a/src/microtar.c
+++ b/src/microtar.c
@@ -244,9 +244,14 @@ static int ensure_header(mtar_t* tar)
return MTAR_ESUCCESS;
}
+static unsigned data_beg_pos(const mtar_t* tar)
+{
+ return tar->header_pos + HEADER_LEN;
+}
+
static unsigned data_end_pos(const mtar_t* tar)
{
- return tar->header_pos + HEADER_LEN + tar->header.size;
+ return data_beg_pos(tar) + tar->header.size;
}
const char* mtar_strerror(int err)
@@ -373,6 +378,45 @@ int mtar_read_data(mtar_t* tar, void* ptr, unsigned size)
return (int)size;
}
+int mtar_seek_data(mtar_t* tar, int offset, int whence)
+{
+ if(!(tar->state & S_HEADER_VALID))
+ return MTAR_EAPI;
+
+ unsigned data_beg = data_beg_pos(tar);
+ unsigned data_end = data_end_pos(tar);
+ unsigned newpos;
+
+ switch(whence) {
+ case SEEK_SET:
+ if(offset < 0)
+ return MTAR_ESEEKRANGE;
+
+ newpos = data_beg + offset;
+ break;
+
+ case SEEK_CUR:
+ if((offset > 0 && (unsigned) offset > data_end - tar->pos) ||
+ (offset < 0 && (unsigned)-offset > tar->pos - data_beg))
+ return MTAR_ESEEKRANGE;
+
+ newpos = tar->pos + offset;
+ break;
+
+ case SEEK_END:
+ if(offset > 0)
+ return MTAR_ESEEKRANGE;
+
+ newpos = data_end + offset;
+ break;
+
+ default:
+ return MTAR_EAPI;
+ }
+
+ return tseek(tar, newpos);
+}
+
int mtar_eof_data(mtar_t* tar)
{
/* API usage error, but just claim EOF. */