dav/tar.c

Sun, 17 Dec 2023 14:25:34 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 17 Dec 2023 14:25:34 +0100
changeset 797
edbb20b1438d
parent 785
645f7e802873
permissions
-rw-r--r--

[Makefile] fix missing rules preventing dry-runs

We have to support dry-runs, because many IDEs are using
dry-runs to collect build information.

Some rules have dependencies that expect certain files or
directories to be just present. We added respective build
rules which invoke the test program. This way, the behavior
when running make normally is exactly the same, but dry-runs
are also not failing now.

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