dav/tar.c

Sun, 12 May 2019 13:49:36 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 12 May 2019 13:49:36 +0200
changeset 599
508cbc4d30ea
parent 499
efd8f489d415
child 747
efbd59642577
permissions
-rw-r--r--

fix res_link initialization

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 }

mercurial