summaryrefslogtreecommitdiff
path: root/lib/microtar/src/microtar-stdio.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/microtar/src/microtar-stdio.c')
-rw-r--r--lib/microtar/src/microtar-stdio.c113
1 files changed, 68 insertions, 45 deletions
diff --git a/lib/microtar/src/microtar-stdio.c b/lib/microtar/src/microtar-stdio.c
index 215000aa98..2697d005cd 100644
--- a/lib/microtar/src/microtar-stdio.c
+++ b/lib/microtar/src/microtar-stdio.c
@@ -1,65 +1,88 @@
1/** 1/*
2 * Copyright (c) 2017 rxi 2 * Copyright (c) 2017 rxi
3 * Copyright (c) 2021 Aidan MacDonald
3 * 4 *
4 * This library is free software; you can redistribute it and/or modify it 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * under the terms of the MIT license. See `microtar.c` for details. 6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
6 */ 22 */
7 23
24#include "microtar-stdio.h"
8#include <stdio.h> 25#include <stdio.h>
9#include <string.h> 26#include <string.h>
10 27
11#include "microtar.h" 28static int file_read(void* stream, void* data, unsigned size)
29{
30 unsigned res = fread(data, 1, size, (FILE*)stream);
31 if(res != size && ferror((FILE*)stream))
32 return MTAR_EREADFAIL;
12 33
13static int file_write(mtar_t *tar, const void *data, unsigned size) { 34 return res;
14 unsigned res = fwrite(data, 1, size, tar->stream);
15 return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
16} 35}
17 36
18static int file_read(mtar_t *tar, void *data, unsigned size) { 37static int file_write(void* stream, const void* data, unsigned size)
19 unsigned res = fread(data, 1, size, tar->stream); 38{
20 return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL; 39 unsigned res = fwrite(data, 1, size, (FILE*)stream);
21} 40 if(res != size && ferror((FILE*)stream))
41 return MTAR_EWRITEFAIL;
22 42
23static int file_seek(mtar_t *tar, unsigned offset) { 43 return res;
24 int res = fseek(tar->stream, offset, SEEK_SET);
25 return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
26} 44}
27 45
28static int file_close(mtar_t *tar) { 46static int file_seek(void* stream, unsigned offset)
29 fclose(tar->stream); 47{
30 return MTAR_ESUCCESS; 48 int res = fseek((FILE*)stream, offset, SEEK_SET);
49 return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
31} 50}
32 51
52static int file_close(void* stream)
53{
54 int err = fclose((FILE*)stream);
55 return (err == 0 ? MTAR_ESUCCESS : MTAR_EFAILURE);
56}
33 57
34int mtar_open(mtar_t *tar, const char *filename, const char *mode) { 58static const mtar_ops_t file_ops = {
35 int err; 59 .read = file_read,
36 mtar_header_t h; 60 .write = file_write,
37 61 .seek = file_seek,
38 /* Init tar struct and functions */ 62 .close = file_close,
39 memset(tar, 0, sizeof(*tar)); 63};
40 tar->write = file_write;
41 tar->read = file_read;
42 tar->seek = file_seek;
43 tar->close = file_close;
44 64
45 /* Assure mode is always binary */ 65int mtar_open(mtar_t* tar, const char* filename, const char* mode)
46 if ( strchr(mode, 'r') ) mode = "rb"; 66{
47 if ( strchr(mode, 'w') ) mode = "wb"; 67 /* Determine access mode */
48 if ( strchr(mode, 'a') ) mode = "ab"; 68 int access;
49 /* Open file */ 69 char* read = strchr(mode, 'r');
50 tar->stream = fopen(filename, mode); 70 char* write = strchr(mode, 'w');
51 if (!tar->stream) { 71 if(read) {
52 return MTAR_EOPENFAIL; 72 if(write)
53 } 73 return MTAR_EAPI;
54 /* Read first header to check it is valid if mode is `r` */ 74 access = MTAR_READ;
55 if (*mode == 'r') { 75 } else if(write) {
56 err = mtar_read_header(tar, &h); 76 access = MTAR_WRITE;
57 if (err != MTAR_ESUCCESS) { 77 } else {
58 mtar_close(tar); 78 return MTAR_EAPI;
59 return err;
60 } 79 }
61 }
62 80
63 /* Return ok */ 81 /* Open file */
64 return MTAR_ESUCCESS; 82 FILE* file = fopen(filename, mode);
83 if(!file)
84 return MTAR_EOPENFAIL;
85
86 mtar_init(tar, access, &file_ops, file);
87 return MTAR_ESUCCESS;
65} 88}