Wed, 13 Mar 2019 15:05:40 +0100
extends sync db
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1 | /* |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3 | * |
364
3769ba002fd1
updates copyright date
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
351
diff
changeset
|
4 | * Copyright 2018 Olaf Wintermann. All rights reserved. |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5 | * |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6 | * Redistribution and use in source and binary forms, with or without |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7 | * modification, are permitted provided that the following conditions are met: |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8 | * |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9 | * 1. Redistributions of source code must retain the above copyright |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10 | * notice, this list of conditions and the following disclaimer. |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11 | * |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13 | * notice, this list of conditions and the following disclaimer in the |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14 | * documentation and/or other materials provided with the distribution. |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15 | * |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26 | * POSSIBILITY OF SUCH DAMAGE. |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27 | */ |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
29 | #include "tar.h" |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
30 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
31 | #include <string.h> |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
32 | #include <ucx/string.h> |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
33 | #include <libidav/utils.h> |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
34 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
35 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
36 | const char* tar_error2str(TarError error) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
37 | switch(error) { |
336
6331271116d0
some small fixes in tar.c
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
334
diff
changeset
|
38 | default: break; |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
39 | case TAR_OK: return "ok"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
40 | case TAR_PATH_TOO_LONG: return "path too long"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
41 | case TAR_FILE_TOO_LARGE: return "file too large"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
42 | case TAR_CONTENT_TOO_LARGE: return "tar content too large"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
43 | case TAR_UNFINISHED_FILE: return "can't read a tar header at this position"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
44 | case TAR_CONTENT_BROKEN: return "tar content broken"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
45 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
46 | return "error"; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
47 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49 | TarOutputStream* tar_open(FILE *f) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50 | TarOutputStream *tar = malloc(sizeof(TarOutputStream)); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51 | tar->file= f; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
52 | tar->cur_filesize = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
53 | tar->cur_written = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
54 | tar->error = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
55 | return tar; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
56 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
57 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
58 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
59 | static int add_header(TarOutputStream *tar, char *path, uint32_t mode, uint64_t size, time_t mtime, int type) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
60 | // split path in prefix and name and check length |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
61 | char *p = util_parent_path(path); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
62 | char *n = util_resource_name(path); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
63 | if(!p || !n) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
64 | return -1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
65 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
66 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
67 | sstr_t prefix = sstr(p); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
68 | sstr_t name = sstr(n); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
69 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
70 | if(prefix.ptr[prefix.length-1] == '/') { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
71 | prefix.length--; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
72 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
73 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
74 | if(prefix.length > 154) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
75 | tar->error = TAR_PATH_TOO_LONG; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
76 | return -1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
77 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
78 | if(name.length > 99) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
79 | tar->error = TAR_PATH_TOO_LONG; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
80 | return -1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
81 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
82 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
83 | // check file length |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
84 | if(size >= 077777777777 ) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
85 | tar->error = TAR_FILE_TOO_LARGE; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
86 | return -1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
87 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
88 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
89 | // set header fields |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
90 | TarHeader h; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
91 | memset(&h, 0, sizeof(TarHeader)); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
92 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
93 | // name |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
94 | memcpy(h.name, name.ptr, name.length); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
95 | // mode |
344
72791e299d64
removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
336
diff
changeset
|
96 | snprintf(h.mode, 8, "%07o", mode); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
97 | h.mode[7] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
98 | // uid/gid |
385
85d5049f694b
fixes out of bounds write in tar.c
Mike Becker <universe@uap-core.de>
parents:
364
diff
changeset
|
99 | memset(h.uid, '0', 8); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
100 | h.uid[7] = ' '; |
385
85d5049f694b
fixes out of bounds write in tar.c
Mike Becker <universe@uap-core.de>
parents:
364
diff
changeset
|
101 | memset(h.gid, '0', 8); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
102 | h.gid[7] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
103 | // size |
344
72791e299d64
removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
336
diff
changeset
|
104 | snprintf(h.size, 12, "%011lo", size); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
105 | h.size[11] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
106 | // mtime |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
107 | uint64_t t = (uint64_t)mtime; |
344
72791e299d64
removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
336
diff
changeset
|
108 | snprintf(h.mtime, 12, "%011lo", mtime); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
109 | h.mtime[11] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
110 | // chksum |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
111 | memset(h.chksum, ' ', 8); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
112 | // typeflag |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
113 | h.typeflag = type; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
114 | // linkname - zeros |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
115 | // magic |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
116 | snprintf(h.magic, 6, "ustar"); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
117 | // version |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
118 | h.version[0] = '0'; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
119 | h.version[1] = '0'; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
120 | // uname/gname - zero |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
121 | // devmajor/devminor |
351
11789a88d0b0
fixes some warnings
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
344
diff
changeset
|
122 | char *devbuf = (char*)h.devmajor; |
11789a88d0b0
fixes some warnings
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
344
diff
changeset
|
123 | snprintf(devbuf, 16, "%015o", 0); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
124 | h.devmajor[7] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
125 | h.devminor[7] = ' '; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
126 | // prefix |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
127 | memcpy(h.prefix, prefix.ptr, prefix.length); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
128 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
129 | // compute checksum |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
130 | uint8_t *header = (uint8_t*)&h; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
131 | uint32_t chksum = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
132 | for(int i=0;i<512;i++) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
133 | chksum += header[i]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
134 | } |
344
72791e299d64
removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
336
diff
changeset
|
135 | snprintf(h.chksum, 8, "%07o", chksum); |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
136 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
137 | fwrite(&h, 1, 512, tar->file); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
138 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
139 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
140 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
141 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
142 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
143 | int tar_add_dir(TarOutputStream *tar, char *path, uint32_t mode, time_t mtime) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
144 | return add_header(tar, path, mode, 0, mtime, TAR_TYPE_DIRECTORY); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
145 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
146 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
147 | int tar_begin_file( |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
148 | TarOutputStream *tar, |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
149 | char *path, |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
150 | uint32_t mode, |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
151 | uint64_t size, |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
152 | time_t mtime) |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
153 | { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
154 | if(add_header(tar, path, mode, size, mtime, TAR_TYPE_FILE)) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
155 | return -1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
156 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
157 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
158 | tar->cur_filesize = size; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
159 | tar->cur_written = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
160 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
161 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
162 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
163 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
164 | size_t tar_fwrite(const void *ptr, size_t s, size_t n, TarOutputStream *stream) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
165 | size_t w = fwrite(ptr, s, n, stream->file); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
166 | stream->cur_written += w; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
167 | if(stream->cur_written > stream->cur_filesize) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
168 | stream->error = TAR_CONTENT_TOO_LARGE; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
169 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
170 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
171 | return w; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
172 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
173 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
174 | int tar_end_file(TarOutputStream *tar) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
175 | size_t pad = 512 - tar->cur_written % 512; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
176 | char buf[512]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
177 | memset(buf, 0, 512); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
178 | fwrite(buf, 1, pad, tar->file); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
179 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
180 | tar->cur_filesize = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
181 | tar->cur_written = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
182 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
183 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
184 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
185 | int tar_close(TarOutputStream *tar) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
186 | char buf[512]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
187 | memset(buf, 0, 512); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
188 | fwrite(buf, 1, 512, tar->file); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
189 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
190 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
191 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
192 | TarInputStream* tar_inputstream_open(FILE *f) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
193 | TarInputStream *tar = malloc(sizeof(TarInputStream)); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
194 | memset(tar, 0, sizeof(TarInputStream)); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
195 | tar->file = f; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
196 | return tar; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
197 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
198 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
199 | TarEntry* tar_read_entry(TarInputStream *tar) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
200 | if(tar->cur_read < tar->cur_entry.size) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
201 | tar->error = TAR_UNFINISHED_FILE; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
202 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
203 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
204 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
205 | TarHeader h; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
206 | memset(&h, 0, sizeof(TarHeader)); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
207 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
208 | if(fread(&h, 1, 512, tar->file) != 512) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
209 | tar->error = TAR_ERROR; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
210 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
211 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
212 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
213 | // some checks |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
214 | tar->error = TAR_CONTENT_BROKEN; // set error for all following returns |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
215 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
216 | char *buf = (char*)&h; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
217 | uint64_t chksum = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
218 | int chksumfield = 8 * 32; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
219 | for(int i=0;i<148;i++) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
220 | chksum += buf[i]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
221 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
222 | chksum += chksumfield; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
223 | for(int i=156;i<512;i++) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
224 | chksum += buf[i]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
225 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
226 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
227 | if(chksum != chksumfield) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
228 | long long int cks = strtoll(h.chksum, NULL, 8); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
229 | if(cks != chksum) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
230 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
231 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
232 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
233 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
234 | if(memcmp(h.magic, "ustar\0", 6)) { |
499
efd8f489d415
fix: don't detect end of tar file as broken content
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
478
diff
changeset
|
235 | if(!memcmp(h.magic, "\0\0\0\0", 4)) { |
efd8f489d415
fix: don't detect end of tar file as broken content
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
478
diff
changeset
|
236 | tar->error = TAR_OK; |
efd8f489d415
fix: don't detect end of tar file as broken content
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
478
diff
changeset
|
237 | } |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
238 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
239 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
240 | if(memcmp(h.version, "00", 2)) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
241 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
242 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
243 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
244 | // check if name and prefix are null terminated |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
245 | int nameterm = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
246 | int prefixterm = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
247 | for(int i=0;i<100;i++) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
248 | if(h.name[i] == 0) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
249 | nameterm = 1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
250 | break; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
251 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
252 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
253 | for(int i=0;i<155;i++) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
254 | if(h.prefix[i] == 0) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
255 | prefixterm = 1; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
256 | break; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
257 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
258 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
259 | if(!nameterm || !prefixterm) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
260 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
261 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
262 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
263 | // get size |
406
36333e8a9411
fixes compatiblity with GNU tar's version of ustar
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
385
diff
changeset
|
264 | if(!(h.size[11] == ' ' || h.size[11] == 0)) { |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
265 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
266 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
267 | long long int size = strtoll(h.size, NULL, 8); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
268 | if(size < 0) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
269 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
270 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
271 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
272 | if(h.name[0] == 0) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
273 | return NULL; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
274 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
275 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
276 | // get path |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
277 | char *path = h.prefix[0] != 0 ? util_concat_path(h.prefix, h.name) : strdup(h.name); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
278 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
279 | if(tar->cur_entry.path) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
280 | free(tar->cur_entry.path); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
281 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
282 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
283 | tar->cur_entry.path = path; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
284 | tar->cur_entry.size = (uint64_t)size; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
285 | tar->cur_entry.type = h.typeflag; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
286 | tar->cur_read = 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
287 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
288 | tar->error = TAR_OK; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
289 | return &tar->cur_entry; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
290 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
291 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
292 | size_t tar_fread(void *ptr, size_t s, size_t n, TarInputStream *stream) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
293 | size_t bufsize = s*n; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
294 | size_t available = stream->cur_entry.size - stream->cur_read; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
295 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
296 | size_t nb = available > bufsize ? bufsize : available; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
297 | if(nb == 0) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
298 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
299 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
300 | size_t r = fread(ptr, 1, nb, stream->file); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
301 | if(r != nb) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
302 | stream->error = TAR_ERROR; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
303 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
304 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
305 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
306 | stream->cur_read += r; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
307 | if(stream->cur_read >= stream->cur_entry.size) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
308 | // read padding |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
309 | size_t pad = 512 - stream->cur_read % 512; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
310 | char buf[512]; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
311 | if(fread(buf, 1, pad, stream->file) != pad) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
312 | stream->error = TAR_ERROR; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
313 | return 0; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
314 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
315 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
316 | |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
317 | return r; |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
318 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
319 | |
478
baa63fef5c5c
fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
406
diff
changeset
|
320 | int tar_seek(TarInputStream *stream, long offset, int whence) { |
baa63fef5c5c
fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
406
diff
changeset
|
321 | return fseek(stream->file, offset, whence); |
baa63fef5c5c
fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
406
diff
changeset
|
322 | } |
baa63fef5c5c
fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
406
diff
changeset
|
323 | |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
324 | int tar_inputstream_close(TarInputStream *tar) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
325 | if(tar->cur_entry.path) { |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
326 | free(tar->cur_entry.path); |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
327 | } |
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
328 | free(tar); |
336
6331271116d0
some small fixes in tar.c
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
334
diff
changeset
|
329 | return 0; |
334
5f80c5d0e87f
adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
330 | } |