diff options
Diffstat (limited to 'lib/microtar/src/microtar-stdio.c')
-rw-r--r-- | lib/microtar/src/microtar-stdio.c | 113 |
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" | 28 | static 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 | ||
13 | static 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 | ||
18 | static int file_read(mtar_t *tar, void *data, unsigned size) { | 37 | static 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 | ||
23 | static 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 | ||
28 | static int file_close(mtar_t *tar) { | 46 | static 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 | ||
52 | static int file_close(void* stream) | ||
53 | { | ||
54 | int err = fclose((FILE*)stream); | ||
55 | return (err == 0 ? MTAR_ESUCCESS : MTAR_EFAILURE); | ||
56 | } | ||
33 | 57 | ||
34 | int mtar_open(mtar_t *tar, const char *filename, const char *mode) { | 58 | static 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 */ | 65 | int 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 | } |