diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-11-05 03:12:14 +0300 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-11-05 03:24:35 +0300 |
commit | 385a359280639742f5c6354b9fbbb42d7b0bc19a (patch) | |
tree | d949372b38f36d22acab53beb5849cf5dfa8bd46 | |
parent | ae05eb8fe08b54451e0badb809b11a527f15b28c (diff) |
Keep track of access mode to enforce API usage
-rw-r--r-- | src/microtar-stdio.c | 17 | ||||
-rw-r--r-- | src/microtar.c | 26 | ||||
-rw-r--r-- | src/microtar.h | 8 |
3 files changed, 46 insertions, 5 deletions
diff --git a/src/microtar-stdio.c b/src/microtar-stdio.c index e95b030..b022bf8 100644 --- a/src/microtar-stdio.c +++ b/src/microtar-stdio.c @@ -23,6 +23,7 @@ #include "microtar.h" #include <stdio.h> +#include <string.h> static int file_read(void* stream, void* data, unsigned size) { @@ -57,10 +58,24 @@ static const mtar_ops_t file_ops = { int mtar_open(mtar_t* tar, const char* filename, const char* mode) { + /* Determine access mode */ + int access; + char* read = strchr(mode, 'r'); + char* write = strchr(mode, 'w'); + if(read) { + if(write) + return MTAR_EAPI; + access = MTAR_READ; + } else if(write) { + access = MTAR_WRITE; + } else { + return MTAR_EAPI; + } + /* Open file */ FILE* file = fopen(filename, mode); if(!file) return MTAR_EOPENFAIL; - return mtar_init(tar, &file_ops, file); + return mtar_init(tar, access, &file_ops, file); } diff --git a/src/microtar.c b/src/microtar.c index e45f7bf..030bae9 100644 --- a/src/microtar.c +++ b/src/microtar.c @@ -291,9 +291,10 @@ const char* mtar_strerror(int err) } } -int mtar_init(mtar_t* tar, const mtar_ops_t* ops, void* stream) +int mtar_init(mtar_t* tar, int access, const mtar_ops_t* ops, void* stream) { memset(tar, 0, sizeof(mtar_t)); + tar->access = access; tar->ops = ops; tar->stream = stream; return 0; @@ -301,7 +302,7 @@ int mtar_init(mtar_t* tar, const mtar_ops_t* ops, void* stream) int mtar_close(mtar_t* tar) { - int err1 = mtar_finalize(tar); + int err1 = tar->access == MTAR_WRITE ? mtar_finalize(tar) : MTAR_ESUCCESS; int err2 = tar->ops->close(tar->stream); tar->ops = NULL; @@ -328,6 +329,9 @@ const mtar_header_t* mtar_get_header(const mtar_t* tar) int mtar_rewind(mtar_t* tar) { + if(tar->access != MTAR_READ) + return MTAR_EAPI; + int err = tseek(tar, 0); tar->state = 0; return err; @@ -335,6 +339,9 @@ int mtar_rewind(mtar_t* tar) int mtar_next(mtar_t* tar) { + if(tar->access != MTAR_READ) + return MTAR_EAPI; + if(tar->state & S_HEADER_VALID) { tar->state &= ~S_HEADER_VALID; @@ -349,6 +356,9 @@ int mtar_next(mtar_t* tar) int mtar_foreach(mtar_t* tar, mtar_foreach_cb cb, void* arg) { + if(tar->access != MTAR_READ) + return MTAR_EAPI; + int err = mtar_rewind(tar); if(err) return err; @@ -383,6 +393,8 @@ int mtar_find(mtar_t* tar, const char* name) int mtar_read_data(mtar_t* tar, void* ptr, unsigned size) { + if(tar->access != MTAR_READ) + return MTAR_EAPI; if(!(tar->state & S_HEADER_VALID)) return MTAR_EAPI; @@ -405,6 +417,8 @@ int mtar_read_data(mtar_t* tar, void* ptr, unsigned size) int mtar_seek_data(mtar_t* tar, int offset, int whence) { + if(tar->access != MTAR_READ) + return MTAR_EAPI; if(!(tar->state & S_HEADER_VALID)) return MTAR_EAPI; @@ -444,7 +458,9 @@ int mtar_seek_data(mtar_t* tar, int offset, int whence) int mtar_eof_data(mtar_t* tar) { - /* API usage error, but just claim EOF. */ + /* API usage errors, but just claim EOF. */ + if(tar->access != MTAR_READ) + return 1; if(!(tar->state & S_HEADER_VALID)) return 1; @@ -453,6 +469,8 @@ int mtar_eof_data(mtar_t* tar) int mtar_write_header(mtar_t* tar, const mtar_header_t* h) { + if(tar->access != MTAR_WRITE) + return MTAR_EAPI; if(tar->state & S_WROTE_FINALIZE) return MTAR_EAPI; @@ -538,6 +556,8 @@ int mtar_write_data(mtar_t* tar, const void* ptr, unsigned size) int mtar_finalize(mtar_t* tar) { + if(tar->access != MTAR_WRITE) + return MTAR_EAPI; if(tar->state & S_WROTE_FINALIZE) return MTAR_ESUCCESS; diff --git a/src/microtar.h b/src/microtar.h index d2e472b..d42bda6 100644 --- a/src/microtar.h +++ b/src/microtar.h @@ -58,6 +58,11 @@ enum { MTAR_TFIFO = '6', }; +enum { + MTAR_READ, + MTAR_WRITE, +}; + typedef struct mtar_header mtar_header_t; typedef struct mtar mtar_t; typedef struct mtar_ops mtar_ops_t; @@ -86,6 +91,7 @@ struct mtar { char buffer[512]; /* IO buffer, put first to allow library users to * control its alignment */ int state; /* Used to simplify the API and verify API usage */ + int access; /* Access mode */ unsigned pos; /* Current position in file */ unsigned header_pos; /* Position of the current header */ mtar_header_t header; /* Most recently parsed header */ @@ -97,7 +103,7 @@ const char* mtar_strerror(int err); int mtar_open(mtar_t* tar, const char* filename, const char* mode); -int mtar_init(mtar_t* tar, const mtar_ops_t* ops, void* stream); +int mtar_init(mtar_t* tar, int access, const mtar_ops_t* ops, void* stream); int mtar_close(mtar_t* tar); int mtar_is_open(mtar_t* tar); |