]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/tar/read.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / libarchive / tar / read.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
24  */
25
26 #include "bsdtar_platform.h"
27 __FBSDID("$FreeBSD$");
28
29 #ifdef HAVE_SYS_TYPES_H
30 #include <sys/types.h>
31 #endif
32 #ifdef HAVE_SYS_PARAM_H
33 #include <sys/param.h>
34 #endif
35 #ifdef HAVE_SYS_STAT_H
36 #include <sys/stat.h>
37 #endif
38
39 #ifdef HAVE_ERRNO_H
40 #include <errno.h>
41 #endif
42
43 #ifdef HAVE_FCNTL_H
44 #include <fcntl.h>
45 #endif
46
47 #ifdef HAVE_GRP_H
48 #include <grp.h>
49 #endif
50
51 #ifdef HAVE_IO_H
52 #include <io.h>
53 #endif
54
55 #ifdef HAVE_LIMITS_H
56 #include <limits.h>
57 #endif
58 #ifdef HAVE_PWD_H
59 #include <pwd.h>
60 #endif
61 #ifdef HAVE_STDINT_H
62 #include <stdint.h>
63 #endif
64 #include <stdio.h>
65 #ifdef HAVE_STDLIB_H
66 #include <stdlib.h>
67 #endif
68 #ifdef HAVE_STRING_H
69 #include <string.h>
70 #endif
71 #ifdef HAVE_TIME_H
72 #include <time.h>
73 #endif
74 #ifdef HAVE_UNISTD_H
75 #include <unistd.h>
76 #endif
77
78 #include "bsdtar.h"
79 #include "err.h"
80
81 struct progress_data {
82         struct bsdtar *bsdtar;
83         struct archive *archive;
84         struct archive_entry *entry;
85 };
86
87 static void     read_archive(struct bsdtar *bsdtar, char mode, struct archive *);
88 static int unmatched_inclusions_warn(struct archive *matching, const char *);
89
90
91 void
92 tar_mode_t(struct bsdtar *bsdtar)
93 {
94         read_archive(bsdtar, 't', NULL);
95         if (unmatched_inclusions_warn(bsdtar->matching,
96             "Not found in archive") != 0)
97                 bsdtar->return_value = 1;
98 }
99
100 void
101 tar_mode_x(struct bsdtar *bsdtar)
102 {
103         struct archive *writer;
104
105         writer = archive_write_disk_new();
106         if (writer == NULL)
107                 lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
108         if ((bsdtar->flags & OPTFLAG_NUMERIC_OWNER) == 0)
109                 archive_write_disk_set_standard_lookup(writer);
110         archive_write_disk_set_options(writer, bsdtar->extract_flags);
111
112         read_archive(bsdtar, 'x', writer);
113
114         if (unmatched_inclusions_warn(bsdtar->matching,
115             "Not found in archive") != 0)
116                 bsdtar->return_value = 1;
117         archive_write_free(writer);
118 }
119
120 static void
121 progress_func(void *cookie)
122 {
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;
128         int compression;
129
130         if (!need_report())
131                 return;
132
133         if (bsdtar->verbose)
134                 fprintf(stderr, "\n");
135         if (a != NULL) {
136                 comp = archive_filter_bytes(a, -1);
137                 uncomp = archive_filter_bytes(a, 0);
138                 if (comp > uncomp)
139                         compression = 0;
140                 else
141                         compression = (int)((uncomp - comp) * 100 / uncomp);
142                 fprintf(stderr,
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));
147         }
148         if (entry != NULL) {
149                 safe_fprintf(stderr, "Current: %s",
150                     archive_entry_pathname(entry));
151                 fprintf(stderr, " (%s bytes)\n",
152                     tar_i64toa(archive_entry_size(entry)));
153         }
154 }
155
156 /*
157  * Handle 'x' and 't' modes.
158  */
159 static void
160 read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
161 {
162         struct progress_data    progress_data;
163         FILE                     *out;
164         struct archive           *a;
165         struct archive_entry     *entry;
166         const char               *reader_options;
167         int                       r;
168
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));
174                 bsdtar->argv++;
175         }
176
177         if (bsdtar->names_from_file != NULL)
178                 if (archive_match_include_pattern_from_file(
179                     bsdtar->matching, bsdtar->names_from_file,
180                     (bsdtar->flags & OPTFLAG_NULL)) != ARCHIVE_OK)
181                         lafe_errc(1, 0, "Error inclusion pattern: %s",
182                             archive_error_string(bsdtar->matching));
183
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);
188
189         reader_options = getenv(ENV_READER_OPTIONS);
190         if (reader_options != NULL) {
191                 size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1;
192                 size_t opt_len = strlen(reader_options) + 1;
193                 char *p;
194                 /* Set default read options. */
195                 if ((p = malloc(module_len + opt_len)) == NULL)
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                 memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len);
201                 memcpy(p + module_len, reader_options, opt_len);
202                 r = archive_read_set_options(a, p);
203                 free(p);
204                 if (r == ARCHIVE_FATAL)
205                         lafe_errc(1, 0, "%s", archive_error_string(a));
206                 else
207                         archive_clear_error(a);
208         }
209         if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
210                 lafe_errc(1, 0, "%s", archive_error_string(a));
211         if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS)
212                 if (archive_read_set_options(a,
213                     "read_concatenated_archives") != ARCHIVE_OK)
214                         lafe_errc(1, 0, "%s", archive_error_string(a));
215         if (bsdtar->passphrase != NULL)
216                 r = archive_read_add_passphrase(a, bsdtar->passphrase);
217         else
218                 r = archive_read_set_passphrase_callback(a, bsdtar,
219                         &passphrase_callback);
220         if (r != ARCHIVE_OK)
221                 lafe_errc(1, 0, "%s", archive_error_string(a));
222         if (archive_read_open_filename(a, bsdtar->filename,
223                                         bsdtar->bytes_per_block))
224                 lafe_errc(1, 0, "Error opening archive: %s",
225                     archive_error_string(a));
226
227         do_chdir(bsdtar);
228
229         if (mode == 'x') {
230                 /* Set an extract callback so that we can handle SIGINFO. */
231                 progress_data.bsdtar = bsdtar;
232                 progress_data.archive = a;
233                 archive_read_extract_set_progress_callback(a, progress_func,
234                     &progress_data);
235         }
236
237         if (mode == 'x' && (bsdtar->flags & OPTFLAG_CHROOT)) {
238 #if HAVE_CHROOT
239                 if (chroot(".") != 0)
240                         lafe_errc(1, errno, "Can't chroot to \".\"");
241 #else
242                 lafe_errc(1, 0,
243                     "chroot isn't supported on this platform");
244 #endif
245         }
246
247 #if defined(_WIN32) && !defined(__CYGWIN__)
248         if (mode == 'x' && (bsdtar->flags & OPTFLAG_STDOUT)) {
249                 _setmode(1, _O_BINARY);
250         }
251 #endif
252
253         for (;;) {
254                 /* Support --fast-read option */
255                 const char *p;
256                 if ((bsdtar->flags & OPTFLAG_FAST_READ) &&
257                     archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
258                         break;
259
260                 r = archive_read_next_header(a, &entry);
261                 progress_data.entry = entry;
262                 if (r == ARCHIVE_EOF)
263                         break;
264                 if (r < ARCHIVE_OK)
265                         lafe_warnc(0, "%s", archive_error_string(a));
266                 if (r <= ARCHIVE_WARN)
267                         bsdtar->return_value = 1;
268                 if (r == ARCHIVE_RETRY) {
269                         /* Retryable error: try again */
270                         lafe_warnc(0, "Retrying...");
271                         continue;
272                 }
273                 if (r == ARCHIVE_FATAL)
274                         break;
275                 p = archive_entry_pathname(entry);
276                 if (p == NULL || p[0] == '\0') {
277                         lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping.");
278                         bsdtar->return_value = 1;
279                         continue;
280                 }
281
282                 if (bsdtar->uid >= 0) {
283                         archive_entry_set_uid(entry, bsdtar->uid);
284                         archive_entry_set_uname(entry, NULL);
285                 }
286                 if (bsdtar->gid >= 0) {
287                         archive_entry_set_gid(entry, bsdtar->gid);
288                         archive_entry_set_gname(entry, NULL);
289                 }
290                 if (bsdtar->uname)
291                         archive_entry_set_uname(entry, bsdtar->uname);
292                 if (bsdtar->gname)
293                         archive_entry_set_gname(entry, bsdtar->gname);
294
295                 /*
296                  * Note that pattern exclusions are checked before
297                  * pathname rewrites are handled.  This gives more
298                  * control over exclusions, since rewrites always lose
299                  * information.  (For example, consider a rewrite
300                  * s/foo[0-9]/foo/.  If we check exclusions after the
301                  * rewrite, there would be no way to exclude foo1/bar
302                  * while allowing foo2/bar.)
303                  */
304                 if (archive_match_excluded(bsdtar->matching, entry))
305                         continue; /* Excluded by a pattern test. */
306
307                 if (mode == 't') {
308                         /* Perversely, gtar uses -O to mean "send to stderr"
309                          * when used with -t. */
310                         out = (bsdtar->flags & OPTFLAG_STDOUT) ?
311                             stderr : stdout;
312
313                         /*
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.
318                          */
319                         if (bsdtar->verbose < 2)
320                                 safe_fprintf(out, "%s",
321                                     archive_entry_pathname(entry));
322                         else
323                                 list_item_verbose(bsdtar, out, entry);
324                         fflush(out);
325                         r = archive_read_data_skip(a);
326                         if (r == ARCHIVE_WARN) {
327                                 fprintf(out, "\n");
328                                 lafe_warnc(0, "%s",
329                                     archive_error_string(a));
330                         }
331                         if (r == ARCHIVE_RETRY) {
332                                 fprintf(out, "\n");
333                                 lafe_warnc(0, "%s",
334                                     archive_error_string(a));
335                         }
336                         if (r == ARCHIVE_FATAL) {
337                                 fprintf(out, "\n");
338                                 lafe_warnc(0, "%s",
339                                     archive_error_string(a));
340                                 bsdtar->return_value = 1;
341                                 break;
342                         }
343                         fprintf(out, "\n");
344                 } else {
345                         /* Note: some rewrite failures prevent extraction. */
346                         if (edit_pathname(bsdtar, entry))
347                                 continue; /* Excluded by a rewrite failure. */
348
349                         if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
350                             !yes("extract '%s'", archive_entry_pathname(entry)))
351                                 continue;
352
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);
357                                 fflush(stderr);
358                         } else if (bsdtar->verbose > 0) {
359                                 /* Format follows SUSv2, including the
360                                  * deferred '\n'. */
361                                 safe_fprintf(stderr, "x %s",
362                                     archive_entry_pathname(entry));
363                                 fflush(stderr);
364                         }
365
366                         /* TODO siginfo_printinfo(bsdtar, 0); */
367
368                         if (bsdtar->flags & OPTFLAG_STDOUT)
369                                 r = archive_read_data_into_fd(a, 1);
370                         else
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;
381                         }
382                         if (bsdtar->verbose)
383                                 fprintf(stderr, "\n");
384                         if (r == ARCHIVE_FATAL)
385                                 break;
386                 }
387         }
388
389
390         r = archive_read_close(a);
391         if (r != ARCHIVE_OK)
392                 lafe_warnc(0, "%s", archive_error_string(a));
393         if (r <= ARCHIVE_WARN)
394                 bsdtar->return_value = 1;
395
396         if (bsdtar->verbose > 2)
397                 fprintf(stdout, "Archive Format: %s,  Compression: %s\n",
398                     archive_format_name(a), archive_filter_name(a, 0));
399
400         archive_read_free(a);
401 }
402
403
404 static int
405 unmatched_inclusions_warn(struct archive *matching, const char *msg)
406 {
407         const char *p;
408         int r;
409
410         if (matching == NULL)
411                 return (0);
412
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");
418
419         return (archive_match_path_unmatched_inclusions(matching));
420 }