dav/tar.c

Sat, 28 Oct 2017 15:25:17 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 28 Oct 2017 15:25:17 +0200
changeset 334
5f80c5d0e87f
child 336
6331271116d0
permissions
-rw-r--r--

adds tar import/export

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) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
38 case TAR_OK: return "ok";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
39 case TAR_PATH_TOO_LONG: return "path too long";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
40 case TAR_FILE_TOO_LARGE: return "file too large";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
41 case TAR_CONTENT_TOO_LARGE: return "tar content too large";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
42 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
43 case TAR_CONTENT_BROKEN: return "tar content broken";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
44 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 return "error";
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 }
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 TarOutputStream* tar_open(FILE *f) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 TarOutputStream *tar = malloc(sizeof(TarOutputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50 tar->file= f;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 tar->cur_filesize = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 tar->cur_written = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 tar->error = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 return tar;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 }
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 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
59 // split path in prefix and name and check length
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 char *p = util_parent_path(path);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 char *n = util_resource_name(path);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 if(!p || !n) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 }
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 sstr_t prefix = sstr(p);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 sstr_t name = sstr(n);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69 if(prefix.ptr[prefix.length-1] == '/') {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 prefix.length--;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 }
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 if(prefix.length > 154) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 tar->error = TAR_PATH_TOO_LONG;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 if(name.length > 99) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 tar->error = TAR_PATH_TOO_LONG;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 }
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 // check file length
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 if(size >= 077777777777 ) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 tar->error = TAR_FILE_TOO_LARGE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 }
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 // set header fields
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 TarHeader h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 memset(&h, 0, sizeof(TarHeader));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 // name
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 memcpy(h.name, name.ptr, name.length);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 // mode
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 snprintf(h.mode, 8, "%0.7o", mode);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 h.mode[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 // uid/gid
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 memset(h.uid, '0', 16);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 h.uid[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 h.gid[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 // size
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 snprintf(h.size, 12, "%0.11lo", size);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 h.size[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 // mtime
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 uint64_t t = (uint64_t)mtime;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 snprintf(h.mtime, 12, "%0.11lo", mtime);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 h.mtime[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 // chksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 memset(h.chksum, ' ', 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 // typeflag
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 h.typeflag = type;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 // linkname - zeros
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 // magic
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 snprintf(h.magic, 6, "ustar");
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 // version
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 h.version[0] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 h.version[1] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 // uname/gname - zero
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 // devmajor/devminor
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 snprintf(h.devmajor, 16, "%0.15o", 0);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 h.devmajor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 h.devminor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 // prefix
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 memcpy(h.prefix, prefix.ptr, prefix.length);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 // compute checksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 uint8_t *header = (uint8_t*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 uint32_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 for(int i=0;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 chksum += header[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 snprintf(h.chksum, 8, "%0.7o", chksum);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 fwrite(&h, 1, 512, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 }
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 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
141 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
142 }
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 int tar_begin_file(
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 TarOutputStream *tar,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 char *path,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 uint32_t mode,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 uint64_t size,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 time_t mtime)
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 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
152 return -1;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 tar->cur_filesize = size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 tar->cur_written = 0;
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 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159 }
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 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
162 size_t w = fwrite(ptr, s, n, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 stream->cur_written += w;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 if(stream->cur_written > stream->cur_filesize) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 stream->error = TAR_CONTENT_TOO_LARGE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 return w;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 }
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 int tar_end_file(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 size_t pad = 512 - tar->cur_written % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 fwrite(buf, 1, pad, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 tar->cur_filesize = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 tar->cur_written = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 }
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 int tar_close(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 fwrite(buf, 1, 512, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 }
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 TarInputStream* tar_inputstream_open(FILE *f) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 TarInputStream *tar = malloc(sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 memset(tar, 0, sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 tar->file = f;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 return tar;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 }
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 TarEntry* tar_read_entry(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 if(tar->cur_read < tar->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 tar->error = TAR_UNFINISHED_FILE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 }
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 TarHeader h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 memset(&h, 0, sizeof(TarHeader));
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 if(fread(&h, 1, 512, tar->file) != 512) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 tar->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208 }
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 // some checks
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 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
212
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 char *buf = (char*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 uint64_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 int chksumfield = 8 * 32;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 for(int i=0;i<148;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 chksum += buf[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 chksum += chksumfield;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 for(int i=156;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 chksum += buf[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 }
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 if(chksum != chksumfield) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 long long int cks = strtoll(h.chksum, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 if(cks != chksum) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 }
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 if(memcmp(h.magic, "ustar\0", 6)) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 return NULL;
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.version, "00", 2)) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236 }
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 // check if name and prefix are null terminated
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 int nameterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240 int prefixterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 for(int i=0;i<100;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 if(h.name[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 nameterm = 1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 break;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 }
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 for(int i=0;i<155;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 if(h.prefix[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 prefixterm = 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 if(!nameterm || !prefixterm) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 }
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 // get size
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 if(h.size[11] != ' ') {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261 long long int size = strtoll(h.size, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 if(size < 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 }
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 if(h.name[0] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 }
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 // get path
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271 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
272
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 free(tar->cur_entry.path);
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277 tar->cur_entry.path = path;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 tar->cur_entry.size = (uint64_t)size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 tar->cur_entry.type = h.typeflag;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 tar->cur_read = 0;
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 tar->error = TAR_OK;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283 return &tar->cur_entry;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 }
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 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
287 size_t bufsize = s*n;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 size_t available = stream->cur_entry.size - stream->cur_read;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 size_t nb = available > bufsize ? bufsize : available;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 if(nb == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 size_t r = fread(ptr, 1, nb, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 if(r != nb) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 stream->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 }
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 stream->cur_read += r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 if(stream->cur_read >= stream->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 // read padding
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 size_t pad = 512 - stream->cur_read % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 if(fread(buf, 1, pad, stream->file) != pad) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 stream->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 }
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 return r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 }
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 int tar_inputstream_close(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 free(tar->cur_entry.path);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 free(tar);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 }

mercurial