dav/tar.c

Sat, 20 Apr 2024 13:01:58 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 20 Apr 2024 13:01:58 +0200
changeset 815
1f40ca07ae1b
parent 785
645f7e802873
permissions
-rw-r--r--

add more xattr malloc checks

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>
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
32 #include <cx/string.h>
334
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);
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
62 const char *n = util_resource_name(path);
334
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
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
67 cxstring prefix = cx_str(p);
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
68 cxstring name = cx_str(n);
334
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;
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
76 free(p);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 if(name.length > 99) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 tar->error = TAR_PATH_TOO_LONG;
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
81 free(p);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 // check file length
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 if(size >= 077777777777 ) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 tar->error = TAR_FILE_TOO_LARGE;
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
88 free(p);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 return -1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 }
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 // set header fields
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 TarHeader h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 memset(&h, 0, sizeof(TarHeader));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 // name
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 memcpy(h.name, name.ptr, name.length);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 // mode
344
72791e299d64 removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 336
diff changeset
99 snprintf(h.mode, 8, "%07o", mode);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 h.mode[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 // uid/gid
385
85d5049f694b fixes out of bounds write in tar.c
Mike Becker <universe@uap-core.de>
parents: 364
diff changeset
102 memset(h.uid, '0', 8);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 h.uid[7] = ' ';
385
85d5049f694b fixes out of bounds write in tar.c
Mike Becker <universe@uap-core.de>
parents: 364
diff changeset
104 memset(h.gid, '0', 8);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 h.gid[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 // size
785
645f7e802873 fix build on macOS
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 747
diff changeset
107 snprintf(h.size, 12, "%011lo", (unsigned long)size);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 h.size[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 // mtime
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 uint64_t t = (uint64_t)mtime;
344
72791e299d64 removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 336
diff changeset
111 snprintf(h.mtime, 12, "%011lo", mtime);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 h.mtime[11] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 // chksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 memset(h.chksum, ' ', 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 // typeflag
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 h.typeflag = type;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 // linkname - zeros
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 // magic
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 snprintf(h.magic, 6, "ustar");
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 // version
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 h.version[0] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 h.version[1] = '0';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 // uname/gname - zero
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 // devmajor/devminor
351
11789a88d0b0 fixes some warnings
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 344
diff changeset
125 char *devbuf = (char*)h.devmajor;
11789a88d0b0 fixes some warnings
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 344
diff changeset
126 snprintf(devbuf, 16, "%015o", 0);
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 h.devmajor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 h.devminor[7] = ' ';
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 // prefix
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 memcpy(h.prefix, prefix.ptr, prefix.length);
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 // compute checksum
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 uint8_t *header = (uint8_t*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 uint32_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 for(int i=0;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 chksum += header[i];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 }
344
72791e299d64 removes openssl dependencies for base64
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 336
diff changeset
138 snprintf(h.chksum, 8, "%07o", chksum);
334
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 fwrite(&h, 1, 512, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141
747
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
142 free(p);
efbd59642577 ucx 3 update, basic dav commands work, most stuff is still broken
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 499
diff changeset
143
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144 return 0;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 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
149 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
150 }
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 int tar_begin_file(
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 TarOutputStream *tar,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 char *path,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 uint32_t mode,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 uint64_t size,
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 time_t mtime)
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 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
160 return -1;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 tar->cur_filesize = size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 tar->cur_written = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 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
170 size_t w = fwrite(ptr, s, n, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 stream->cur_written += w;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 if(stream->cur_written > stream->cur_filesize) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 stream->error = TAR_CONTENT_TOO_LARGE;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 return w;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 int tar_end_file(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 size_t pad = 512 - tar->cur_written % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 fwrite(buf, 1, pad, tar->file);
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 tar->cur_filesize = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 tar->cur_written = 0;
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 int tar_close(TarOutputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 memset(buf, 0, 512);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 fwrite(buf, 1, 512, tar->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 return 0;
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 TarInputStream* tar_inputstream_open(FILE *f) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 TarInputStream *tar = malloc(sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 memset(tar, 0, sizeof(TarInputStream));
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 tar->file = f;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201 return tar;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 TarEntry* tar_read_entry(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 if(tar->cur_read < tar->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 tar->error = TAR_UNFINISHED_FILE;
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 TarHeader h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 memset(&h, 0, sizeof(TarHeader));
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 if(fread(&h, 1, 512, tar->file) != 512) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 tar->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 // some checks
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 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
220
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 char *buf = (char*)&h;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 uint64_t chksum = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 int chksumfield = 8 * 32;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 for(int i=0;i<148;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 chksum += buf[i];
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 chksum += chksumfield;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 for(int i=156;i<512;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 chksum += buf[i];
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(chksum != chksumfield) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 long long int cks = strtoll(h.chksum, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 if(cks != chksum) {
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 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
240 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
241 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
242 }
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 if(memcmp(h.version, "00", 2)) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 return NULL;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 // check if name and prefix are null terminated
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 int nameterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 int prefixterm = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 for(int i=0;i<100;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 if(h.name[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 nameterm = 1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 break;
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 for(int i=0;i<155;i++) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 if(h.prefix[i] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 prefixterm = 1;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261 break;
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 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 if(!nameterm || !prefixterm) {
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 // get size
406
36333e8a9411 fixes compatiblity with GNU tar's version of ustar
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 385
diff changeset
269 if(!(h.size[11] == ' ' || h.size[11] == 0)) {
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 return NULL;
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 long long int size = strtoll(h.size, NULL, 8);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 if(size < 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 return NULL;
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 if(h.name[0] == 0) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 return NULL;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 // get path
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 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
283
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285 free(tar->cur_entry.path);
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 tar->cur_entry.path = path;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 tar->cur_entry.size = (uint64_t)size;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 tar->cur_entry.type = h.typeflag;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 tar->cur_read = 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 tar->error = TAR_OK;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 return &tar->cur_entry;
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
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 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
298 size_t bufsize = s*n;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 size_t available = stream->cur_entry.size - stream->cur_read;
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 size_t nb = available > bufsize ? bufsize : available;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 if(nb == 0) {
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 size_t r = fread(ptr, 1, nb, stream->file);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 if(r != nb) {
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 stream->cur_read += r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 if(stream->cur_read >= stream->cur_entry.size) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 // read padding
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314 size_t pad = 512 - stream->cur_read % 512;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 char buf[512];
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316 if(fread(buf, 1, pad, stream->file) != pad) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 stream->error = TAR_ERROR;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 return 0;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
322 return r;
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324
478
baa63fef5c5c fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 406
diff changeset
325 int tar_seek(TarInputStream *stream, long offset, int whence) {
baa63fef5c5c fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 406
diff changeset
326 return fseek(stream->file, offset, whence);
baa63fef5c5c fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 406
diff changeset
327 }
baa63fef5c5c fixes redirects
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 406
diff changeset
328
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 int tar_inputstream_close(TarInputStream *tar) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 if(tar->cur_entry.path) {
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 free(tar->cur_entry.path);
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 }
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 free(tar);
336
6331271116d0 some small fixes in tar.c
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 334
diff changeset
334 return 0;
334
5f80c5d0e87f adds tar import/export
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 }

mercurial