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:
authorAidan MacDonald <amachronic@protonmail.com>2021-11-05 03:12:14 +0300
committerAidan MacDonald <amachronic@protonmail.com>2021-11-05 03:24:35 +0300
commit385a359280639742f5c6354b9fbbb42d7b0bc19a (patch)
treed949372b38f36d22acab53beb5849cf5dfa8bd46
parentae05eb8fe08b54451e0badb809b11a527f15b28c (diff)
Keep track of access mode to enforce API usage
-rw-r--r--src/microtar-stdio.c17
-rw-r--r--src/microtar.c26
-rw-r--r--src/microtar.h8
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);