2 * Copyright (c) 2003-2007 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #include "bsdtar_platform.h"
27 __FBSDID("$FreeBSD: src/usr.bin/tar/read.c,v 1.40 2008/08/21 06:41:14 kientzle Exp $");
29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
32 #ifdef HAVE_SYS_PARAM_H
33 #include <sys/param.h>
35 #ifdef HAVE_SYS_STAT_H
81 struct progress_data
{
82 struct bsdtar
*bsdtar
;
83 struct archive
*archive
;
84 struct archive_entry
*entry
;
87 static void read_archive(struct bsdtar
*bsdtar
, char mode
, struct archive
*);
88 static int unmatched_inclusions_warn(struct archive
*matching
, const char *);
92 tar_mode_t(struct bsdtar
*bsdtar
)
94 read_archive(bsdtar
, 't', NULL
);
95 if (unmatched_inclusions_warn(bsdtar
->matching
,
96 "Not found in archive") != 0)
97 bsdtar
->return_value
= 1;
101 tar_mode_x(struct bsdtar
*bsdtar
)
103 struct archive
*writer
;
105 writer
= archive_write_disk_new();
107 lafe_errc(1, ENOMEM
, "Cannot allocate disk writer object");
108 if (!bsdtar
->option_numeric_owner
)
109 archive_write_disk_set_standard_lookup(writer
);
110 archive_write_disk_set_options(writer
, bsdtar
->extract_flags
);
112 read_archive(bsdtar
, 'x', writer
);
114 if (unmatched_inclusions_warn(bsdtar
->matching
,
115 "Not found in archive") != 0)
116 bsdtar
->return_value
= 1;
117 archive_write_free(writer
);
121 progress_func(void *cookie
)
123 struct progress_data
*progress_data
= (struct progress_data
*)cookie
;
124 struct bsdtar
*bsdtar
= progress_data
->bsdtar
;
125 struct archive
*a
= progress_data
->archive
;
126 struct archive_entry
*entry
= progress_data
->entry
;
127 uint64_t comp
, uncomp
;
134 fprintf(stderr
, "\n");
136 comp
= archive_filter_bytes(a
, -1);
137 uncomp
= archive_filter_bytes(a
, 0);
141 compression
= (int)((uncomp
- comp
) * 100 / uncomp
);
143 "In: %s bytes, compression %d%%;",
144 tar_i64toa(comp
), compression
);
145 fprintf(stderr
, " Out: %d files, %s bytes\n",
146 archive_file_count(a
), tar_i64toa(uncomp
));
149 safe_fprintf(stderr
, "Current: %s",
150 archive_entry_pathname(entry
));
151 fprintf(stderr
, " (%s bytes)\n",
152 tar_i64toa(archive_entry_size(entry
)));
157 * Handle 'x' and 't' modes.
160 read_archive(struct bsdtar
*bsdtar
, char mode
, struct archive
*writer
)
162 struct progress_data progress_data
;
165 struct archive_entry
*entry
;
166 const char *reader_options
;
169 while (*bsdtar
->argv
) {
170 if (archive_match_include_pattern(bsdtar
->matching
,
171 *bsdtar
->argv
) != ARCHIVE_OK
)
172 lafe_errc(1, 0, "Error inclusion pattern: %s",
173 archive_error_string(bsdtar
->matching
));
177 if (bsdtar
->names_from_file
!= NULL
)
178 if (archive_match_include_pattern_from_file(
179 bsdtar
->matching
, bsdtar
->names_from_file
,
180 bsdtar
->option_null
) != ARCHIVE_OK
)
181 lafe_errc(1, 0, "Error inclusion pattern: %s",
182 archive_error_string(bsdtar
->matching
));
184 a
= archive_read_new();
185 if (cset_read_support_filter_program(bsdtar
->cset
, a
) == 0)
186 archive_read_support_filter_all(a
);
187 archive_read_support_format_all(a
);
189 reader_options
= getenv(ENV_READER_OPTIONS
);
190 if (reader_options
!= NULL
) {
192 /* Set default read options. */
193 p
= (char *)malloc(sizeof(IGNORE_WRONG_MODULE_NAME
)
194 + strlen(reader_options
) + 1);
196 lafe_errc(1, errno
, "Out of memory");
197 /* Prepend magic code to ignore options for
198 * a format or modules which are not added to
199 * the archive read object. */
200 strncpy(p
, IGNORE_WRONG_MODULE_NAME
,
201 sizeof(IGNORE_WRONG_MODULE_NAME
) -1);
202 strcpy(p
+ sizeof(IGNORE_WRONG_MODULE_NAME
) -1, reader_options
);
203 r
= archive_read_set_options(a
, p
);
205 if (r
== ARCHIVE_FATAL
)
206 lafe_errc(1, 0, "%s", archive_error_string(a
));
208 archive_clear_error(a
);
210 if (ARCHIVE_OK
!= archive_read_set_options(a
, bsdtar
->option_options
))
211 lafe_errc(1, 0, "%s", archive_error_string(a
));
212 if (bsdtar
->option_ignore_zeros
)
213 if (archive_read_set_options(a
,
214 "read_concatenated_archives") != ARCHIVE_OK
)
215 lafe_errc(1, 0, "%s", archive_error_string(a
));
216 if (bsdtar
->passphrase
!= NULL
)
217 r
= archive_read_add_passphrase(a
, bsdtar
->passphrase
);
219 r
= archive_read_set_passphrase_callback(a
, bsdtar
,
220 &passphrase_callback
);
222 lafe_errc(1, 0, "%s", archive_error_string(a
));
223 if (archive_read_open_filename(a
, bsdtar
->filename
,
224 bsdtar
->bytes_per_block
))
225 lafe_errc(1, 0, "Error opening archive: %s",
226 archive_error_string(a
));
231 /* Set an extract callback so that we can handle SIGINFO. */
232 progress_data
.bsdtar
= bsdtar
;
233 progress_data
.archive
= a
;
234 archive_read_extract_set_progress_callback(a
, progress_func
,
238 if (mode
== 'x' && bsdtar
->option_chroot
) {
240 if (chroot(".") != 0)
241 lafe_errc(1, errno
, "Can't chroot to \".\"");
244 "chroot isn't supported on this platform");
248 #if defined(_WIN32) && !defined(__CYGWIN__)
249 if (mode
== 'x' && bsdtar
->option_stdout
) {
250 _setmode(1, _O_BINARY
);
255 /* Support --fast-read option */
257 if (bsdtar
->option_fast_read
&&
258 archive_match_path_unmatched_inclusions(bsdtar
->matching
) == 0)
261 r
= archive_read_next_header(a
, &entry
);
262 progress_data
.entry
= entry
;
263 if (r
== ARCHIVE_EOF
)
266 lafe_warnc(0, "%s", archive_error_string(a
));
267 if (r
<= ARCHIVE_WARN
)
268 bsdtar
->return_value
= 1;
269 if (r
== ARCHIVE_RETRY
) {
270 /* Retryable error: try again */
271 lafe_warnc(0, "Retrying...");
274 if (r
== ARCHIVE_FATAL
)
276 p
= archive_entry_pathname(entry
);
277 if (p
== NULL
|| p
[0] == '\0') {
278 lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping.");
279 bsdtar
->return_value
= 1;
283 if (bsdtar
->uid
>= 0) {
284 archive_entry_set_uid(entry
, bsdtar
->uid
);
285 archive_entry_set_uname(entry
, NULL
);
287 if (bsdtar
->gid
>= 0) {
288 archive_entry_set_gid(entry
, bsdtar
->gid
);
289 archive_entry_set_gname(entry
, NULL
);
292 archive_entry_set_uname(entry
, bsdtar
->uname
);
294 archive_entry_set_gname(entry
, bsdtar
->gname
);
297 * Note that pattern exclusions are checked before
298 * pathname rewrites are handled. This gives more
299 * control over exclusions, since rewrites always lose
300 * information. (For example, consider a rewrite
301 * s/foo[0-9]/foo/. If we check exclusions after the
302 * rewrite, there would be no way to exclude foo1/bar
303 * while allowing foo2/bar.)
305 if (archive_match_excluded(bsdtar
->matching
, entry
))
306 continue; /* Excluded by a pattern test. */
309 /* Perversely, gtar uses -O to mean "send to stderr"
310 * when used with -t. */
311 out
= bsdtar
->option_stdout
? stderr
: stdout
;
314 * TODO: Provide some reasonable way to
315 * preview rewrites. gtar always displays
316 * the unedited path in -t output, which means
317 * you cannot easily preview rewrites.
319 if (bsdtar
->verbose
< 2)
320 safe_fprintf(out
, "%s",
321 archive_entry_pathname(entry
));
323 list_item_verbose(bsdtar
, out
, entry
);
325 r
= archive_read_data_skip(a
);
326 if (r
== ARCHIVE_WARN
) {
329 archive_error_string(a
));
331 if (r
== ARCHIVE_RETRY
) {
334 archive_error_string(a
));
336 if (r
== ARCHIVE_FATAL
) {
339 archive_error_string(a
));
340 bsdtar
->return_value
= 1;
345 /* Note: some rewrite failures prevent extraction. */
346 if (edit_pathname(bsdtar
, entry
))
347 continue; /* Excluded by a rewrite failure. */
349 if (bsdtar
->option_interactive
&&
350 !yes("extract '%s'", archive_entry_pathname(entry
)))
353 if (bsdtar
->verbose
> 1) {
354 /* GNU tar uses -tv format with -xvv */
355 safe_fprintf(stderr
, "x ");
356 list_item_verbose(bsdtar
, stderr
, entry
);
358 } else if (bsdtar
->verbose
> 0) {
359 /* Format follows SUSv2, including the
361 safe_fprintf(stderr
, "x %s",
362 archive_entry_pathname(entry
));
366 /* TODO siginfo_printinfo(bsdtar, 0); */
368 if (bsdtar
->option_stdout
)
369 r
= archive_read_data_into_fd(a
, 1);
371 r
= archive_read_extract2(a
, entry
, writer
);
372 if (r
!= ARCHIVE_OK
) {
373 if (!bsdtar
->verbose
)
374 safe_fprintf(stderr
, "%s",
375 archive_entry_pathname(entry
));
376 safe_fprintf(stderr
, ": %s",
377 archive_error_string(a
));
378 if (!bsdtar
->verbose
)
379 fprintf(stderr
, "\n");
380 bsdtar
->return_value
= 1;
383 fprintf(stderr
, "\n");
384 if (r
== ARCHIVE_FATAL
)
390 r
= archive_read_close(a
);
392 lafe_warnc(0, "%s", archive_error_string(a
));
393 if (r
<= ARCHIVE_WARN
)
394 bsdtar
->return_value
= 1;
396 if (bsdtar
->verbose
> 2)
397 fprintf(stdout
, "Archive Format: %s, Compression: %s\n",
398 archive_format_name(a
), archive_filter_name(a
, 0));
400 archive_read_free(a
);
405 unmatched_inclusions_warn(struct archive
*matching
, const char *msg
)
410 if (matching
== NULL
)
413 while ((r
= archive_match_path_unmatched_inclusions_next(
414 matching
, &p
)) == ARCHIVE_OK
)
415 lafe_warnc(0, "%s: %s", p
, msg
);
416 if (r
== ARCHIVE_FATAL
)
417 lafe_errc(1, errno
, "Out of memory");
419 return (archive_match_path_unmatched_inclusions(matching
));