]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/tar/read.c
MFC r299529,r299540,r299576,r299896:
[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->option_numeric_owner)
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->option_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                 char *p;
192                 /* Set default read options. */
193                 p = (char *)malloc(sizeof(IGNORE_WRONG_MODULE_NAME)
194                     + strlen(reader_options) + 1);
195                 if (p == 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                 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);
204                 free(p);
205                 if (r == ARCHIVE_FATAL)
206                         lafe_errc(1, 0, "%s", archive_error_string(a));
207                 else
208                         archive_clear_error(a);
209         }
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);
218         else
219                 r = archive_read_set_passphrase_callback(a, bsdtar,
220                         &passphrase_callback);
221         if (r != ARCHIVE_OK)
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));
227
228         do_chdir(bsdtar);
229
230         if (mode == 'x') {
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,
235                     &progress_data);
236         }
237
238         if (mode == 'x' && bsdtar->option_chroot) {
239 #if HAVE_CHROOT
240                 if (chroot(".") != 0)
241                         lafe_errc(1, errno, "Can't chroot to \".\"");
242 #else
243                 lafe_errc(1, 0,
244                     "chroot isn't supported on this platform");
245 #endif
246         }
247
248 #if defined(_WIN32) && !defined(__CYGWIN__)
249         if (mode == 'x' && bsdtar->option_stdout) {
250                 _setmode(1, _O_BINARY);
251         }
252 #endif
253
254         for (;;) {
255                 /* Support --fast-read option */
256                 const char *p;
257                 if (bsdtar->option_fast_read &&
258                     archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
259                         break;
260
261                 r = archive_read_next_header(a, &entry);
262                 progress_data.entry = entry;
263                 if (r == ARCHIVE_EOF)
264                         break;
265                 if (r < ARCHIVE_OK)
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...");
272                         continue;
273                 }
274                 if (r == ARCHIVE_FATAL)
275                         break;
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;
280                         continue;
281                 }
282
283                 if (bsdtar->uid >= 0) {
284                         archive_entry_set_uid(entry, bsdtar->uid);
285                         archive_entry_set_uname(entry, NULL);
286                 }
287                 if (bsdtar->gid >= 0) {
288                         archive_entry_set_gid(entry, bsdtar->gid);
289                         archive_entry_set_gname(entry, NULL);
290                 }
291                 if (bsdtar->uname)
292                         archive_entry_set_uname(entry, bsdtar->uname);
293                 if (bsdtar->gname)
294                         archive_entry_set_gname(entry, bsdtar->gname);
295
296                 /*
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.)
304                  */
305                 if (archive_match_excluded(bsdtar->matching, entry))
306                         continue; /* Excluded by a pattern test. */
307
308                 if (mode == 't') {
309                         /* Perversely, gtar uses -O to mean "send to stderr"
310                          * when used with -t. */
311                         out = bsdtar->option_stdout ? 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->option_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->option_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 }