X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=c3a99e084d3d143f1b8d4612d00d33008a72ef54;hb=f6edb92580aa886a2a0189463c19189a050dc62d;hp=63f3525915022558319eacbe006df92107ba09be;hpb=01c4475b17bf80cc04e6927b809190f2956e2f89;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index 63f3525..c3a99e0 100644 --- a/src/extract.c +++ b/src/extract.c @@ -1,7 +1,7 @@ /* Extract files from a tar archive. Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000, - 2001, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2001, 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc. Written by John Gilmore, on 1985-11-19. @@ -146,7 +146,7 @@ set_mode (char const *file_name, { mode_t mode; bool failed; - + if (0 < same_permissions_option && permstatus != INTERDIR_PERMSTATUS) { @@ -207,8 +207,9 @@ static void check_time (char const *file_name, struct timespec t) { if (t.tv_sec <= 0) - WARN ((0, 0, _("%s: implausibly old time stamp %s"), - file_name, tartime (t, true))); + WARNOPT (WARN_TIMESTAMP, + (0, 0, _("%s: implausibly old time stamp %s"), + file_name, tartime (t, true))); else if (timespec_cmp (volume_start_time, t) < 0) { struct timespec now; @@ -224,8 +225,9 @@ check_time (char const *file_name, struct timespec t) diff.tv_nsec += BILLION; diff.tv_sec--; } - WARN ((0, 0, _("%s: time stamp %s is %s s in the future"), - file_name, tartime (t, true), code_timespec (diff, buf))); + WARNOPT (WARN_TIMESTAMP, + (0, 0, _("%s: time stamp %s is %s s in the future"), + file_name, tartime (t, true), code_timespec (diff, buf))); } } } @@ -682,6 +684,7 @@ extract_dir (char *file_name, int typeflag) } if (S_ISDIR (st.st_mode)) { + status = 0; mode = st.st_mode; break; } @@ -752,7 +755,8 @@ open_output_file (char *file_name, int typeflag, mode_t mode) if (!conttype_diagnosed) { conttype_diagnosed = 1; - WARN ((0, 0, _("Extracting contiguous files as regular files"))); + WARNOPT (WARN_CONTIGUOUS_CAST, + (0, 0, _("Extracting contiguous files as regular files"))); } } fd = open (file_name, openflag, mode); @@ -884,12 +888,22 @@ create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made) struct stat st; while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0) - if (! maybe_recoverable (file_name, interdir_made)) - break; + { + switch (maybe_recoverable (file_name, interdir_made)) + { + case RECOVER_OK: + continue; - if (fd < 0) - open_error (file_name); - else if (fstat (fd, &st) != 0) + case RECOVER_SKIP: + return 0; + + case RECOVER_NO: + open_error (file_name); + return -1; + } + } + + if (fstat (fd, &st) != 0) { stat_error (file_name); close (fd); @@ -952,9 +966,10 @@ extract_link (char *file_name, int typeflag) { int interdir_made = 0; char const *link_name; + int rc; link_name = current_stat_info.link_name; - + if (! absolute_names_option && contains_dot_dot (link_name)) return create_placeholder_file (file_name, false, &interdir_made); @@ -992,8 +1007,10 @@ extract_link (char *file_name, int typeflag) errno = e; } - while (maybe_recoverable (file_name, &interdir_made)); + while ((rc = maybe_recoverable (file_name, &interdir_made)) == RECOVER_OK); + if (rc == RECOVER_SKIP) + return 0; if (!(incremental_option && errno == EEXIST)) { link_error (link_name, file_name); @@ -1006,7 +1023,6 @@ static int extract_symlink (char *file_name, int typeflag) { #ifdef HAVE_SYMLINK - int status; int interdir_made = 0; if (! absolute_names_option @@ -1014,15 +1030,22 @@ extract_symlink (char *file_name, int typeflag) || contains_dot_dot (current_stat_info.link_name))) return create_placeholder_file (file_name, true, &interdir_made); - while ((status = symlink (current_stat_info.link_name, file_name))) - if (!maybe_recoverable (file_name, &interdir_made)) - break; + while (symlink (current_stat_info.link_name, file_name)) + switch (maybe_recoverable (file_name, &interdir_made)) + { + case RECOVER_OK: + continue; - if (status == 0) - set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE); - else - symlink_error (current_stat_info.link_name, file_name); - return status; + case RECOVER_SKIP: + return 0; + + case RECOVER_NO: + symlink_error (current_stat_info.link_name, file_name); + return -1; + } + + set_stat (file_name, ¤t_stat_info, NULL, 0, 0, SYMTYPE); + return 0; #else static int warned_once; @@ -1030,7 +1053,9 @@ extract_symlink (char *file_name, int typeflag) if (!warned_once) { warned_once = 1; - WARN ((0, 0, _("Attempting extraction of symbolic links as hard links"))); + WARNOPT (WARN_SYMBOLIC_CAST, + (0, 0, + _("Attempting extraction of symbolic links as hard links"))); } return extract_link (file_name, typeflag); #endif @@ -1040,23 +1065,29 @@ extract_symlink (char *file_name, int typeflag) static int extract_node (char *file_name, int typeflag) { - int status; int interdir_made = 0; mode_t mode = current_stat_info.stat.st_mode & ~ current_umask; mode_t invert_permissions = 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; - do - status = mknod (file_name, mode ^ invert_permissions, - current_stat_info.stat.st_rdev); - while (status && maybe_recoverable (file_name, &interdir_made)); + while (mknod (file_name, mode ^ invert_permissions, + current_stat_info.stat.st_rdev)) + switch (maybe_recoverable (file_name, &interdir_made)) + { + case RECOVER_OK: + continue; - if (status != 0) - mknod_error (file_name); - else - set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, - ARCHIVED_PERMSTATUS, typeflag); - return status; + case RECOVER_SKIP: + return 0; + + case RECOVER_NO: + mknod_error (file_name); + return -1; + } + + set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, + ARCHIVED_PERMSTATUS, typeflag); + return 0; } #endif @@ -1071,23 +1102,28 @@ extract_fifo (char *file_name, int typeflag) 0 < same_owner_option ? mode & (S_IRWXG | S_IRWXO) : 0; while ((status = mkfifo (file_name, mode)) != 0) - if (!maybe_recoverable (file_name, &interdir_made)) - break; + switch (maybe_recoverable (file_name, &interdir_made)) + { + case RECOVER_OK: + continue; - if (status == 0) - set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, - ARCHIVED_PERMSTATUS, typeflag); - else - mkfifo_error (file_name); - return status; + case RECOVER_SKIP: + return 0; + + case RECOVER_NO: + mkfifo_error (file_name); + return -1; + } + + set_stat (file_name, ¤t_stat_info, NULL, invert_permissions, + ARCHIVED_PERMSTATUS, typeflag); + return 0; } #endif static int extract_volhdr (char *file_name, int typeflag) { - if (verbose_option) - fprintf (stdlis, _("Reading %s\n"), quote (current_stat_info.file_name)); skip_member (); return 0; } @@ -1188,9 +1224,10 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun) break; default: - WARN ((0, 0, - _("%s: Unknown file type `%c', extracted as normal file"), - quotearg_colon (file_name), typeflag)); + WARNOPT (WARN_UNKNOWN_CAST, + (0, 0, + _("%s: Unknown file type `%c', extracted as normal file"), + quotearg_colon (file_name), typeflag)); *fun = extract_file; } @@ -1214,8 +1251,9 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun) case KEEP_NEWER_FILES: if (file_newer_p (file_name, ¤t_stat_info)) { - WARN ((0, 0, _("Current %s is newer or same age"), - quote (file_name))); + WARNOPT (WARN_IGNORE_NEWER, + (0, 0, _("Current %s is newer or same age"), + quote (file_name))); return 0; } break; @@ -1234,6 +1272,8 @@ extract_archive (void) char typeflag; tar_extractor_t fun; + fatal_exit_hook = extract_finish; + /* Try to disable the ability to unlink a directory. */ priv_set_remove_linkdir (); @@ -1249,7 +1289,7 @@ extract_archive (void) /* Print the block from current_header and current_stat. */ if (verbose_option) - print_header (¤t_stat_info, -1); + print_header (¤t_stat_info, current_header, -1); /* Restore stats for all non-ancestor directories, unless it is an incremental archive. @@ -1398,18 +1438,3 @@ rename_directory (char *src, char *dst) } return true; } - -void -fatal_exit (void) -{ - extract_finish (); - error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now")); - abort (); -} - -void -xalloc_die (void) -{ - error (0, 0, "%s", _("memory exhausted")); - fatal_exit (); -}