dav/tar.c

Mon, 30 Oct 2017 16:29:07 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Mon, 30 Oct 2017 16:29:07 +0100
changeset 336
6331271116d0
parent 334
5f80c5d0e87f
child 344
72791e299d64
permissions
-rw-r--r--

some small fixes in tar.c

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 *
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2017 Olaf Wintermann. All rights reserved.
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 snprintf(h.mode, 8, "%0.7o", mode);
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 memset(h.uid, '0', 16);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 h.uid[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 h.gid[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 // size
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 snprintf(h.size, 12, "%0.11lo", size);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 h.size[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 // mtime
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 uint64_t t = (uint64_t)mtime;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 snprintf(h.mtime, 12, "%0.11lo", mtime);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 h.mtime[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 // chksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 memset(h.chksum, ' ', 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 // typeflag
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 h.typeflag = type;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 // linkname - zeros
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 // magic
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 snprintf(h.magic, 6, "ustar");
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 // version
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 h.version[0] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 h.version[1] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 // uname/gname - zero
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 // devmajor/devminor
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 snprintf(h.devmajor, 16, "%0.15o", 0);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 h.devmajor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 h.devminor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 // prefix
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 memcpy(h.prefix, prefix.ptr, prefix.length);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 // compute checksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 uint8_t *header = (uint8_t*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 uint32_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 for(int i=0;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 chksum += header[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 snprintf(h.chksum, 8, "%0.7o", chksum);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 fwrite(&h, 1, 512, tar->file);
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 return 0;
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
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 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
142 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
143 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 int tar_begin_file(
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 TarOutputStream *tar,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 char *path,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 uint32_t mode,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 uint64_t size,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 time_t mtime)
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 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
153 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 tar->cur_filesize = size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 tar->cur_written = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 return 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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162 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
163 size_t w = fwrite(ptr, s, n, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 stream->cur_written += w;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 if(stream->cur_written > stream->cur_filesize) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 stream->error = TAR_CONTENT_TOO_LARGE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 return w;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 int tar_end_file(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 size_t pad = 512 - tar->cur_written % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 fwrite(buf, 1, pad, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 tar->cur_filesize = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 tar->cur_written = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 int tar_close(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 fwrite(buf, 1, 512, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 TarInputStream* tar_inputstream_open(FILE *f) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 TarInputStream *tar = malloc(sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 memset(tar, 0, sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 tar->file = f;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 return tar;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 TarEntry* tar_read_entry(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 if(tar->cur_read < tar->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 tar->error = TAR_UNFINISHED_FILE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 TarHeader h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 memset(&h, 0, sizeof(TarHeader));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 if(fread(&h, 1, 512, tar->file) != 512) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 tar->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 // some checks
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 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
213
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 char *buf = (char*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 uint64_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 int chksumfield = 8 * 32;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 for(int i=0;i<148;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 chksum += buf[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 chksum += chksumfield;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 for(int i=156;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 chksum += buf[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 if(chksum != chksumfield) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 long long int cks = strtoll(h.chksum, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 if(cks != chksum) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 }
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 if(memcmp(h.magic, "ustar\0", 6)) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 if(memcmp(h.version, "00", 2)) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 // check if name and prefix are null terminated
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 int nameterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 int prefixterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 for(int i=0;i<100;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 if(h.name[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 nameterm = 1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 break;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 for(int i=0;i<155;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 if(h.prefix[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 prefixterm = 1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 break;
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 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 if(!nameterm || !prefixterm) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 }
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 // get size
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 if(h.size[11] != ' ') {
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 long long int size = strtoll(h.size, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 if(size < 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 }
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 if(h.name[0] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 }
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 // get path
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272 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
273
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275 free(tar->cur_entry.path);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 tar->cur_entry.path = path;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 tar->cur_entry.size = (uint64_t)size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 tar->cur_entry.type = h.typeflag;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 tar->cur_read = 0;
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->error = TAR_OK;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 return &tar->cur_entry;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 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
288 size_t bufsize = s*n;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 size_t available = stream->cur_entry.size - stream->cur_read;
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 size_t nb = available > bufsize ? bufsize : available;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 if(nb == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 size_t r = fread(ptr, 1, nb, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 if(r != nb) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 stream->error = TAR_ERROR;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 stream->cur_read += r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 if(stream->cur_read >= stream->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 // read padding
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 size_t pad = 512 - stream->cur_read % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 if(fread(buf, 1, pad, stream->file) != pad) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 stream->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 return r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 }
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 int tar_inputstream_close(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 free(tar->cur_entry.path);
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 free(tar);
336
6331271116d0 some small fixes in tar.c
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 334
diff changeset
320 return 0;
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 }

mercurial