Sat, 22 Jun 2019 16:36:52 +0200
move some properties to new namespace
for properties encryption we need to decide which props must be encrypted and the plan is, to decide by namespace
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 | } |