X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=c01c88d12b58d10749d4a0a6b848c7d7a6c0765c;hb=48ce2946d97a7eea01cdde404042ad7b7c3c3151;hp=c89ebd01e74c4a1acb7abffd0b6fabc3f0e83892;hpb=5249a993776ba32c851cf6eb3734958512d55d11;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index c89ebd0..c01c88d 100644 --- a/src/extract.c +++ b/src/extract.c @@ -30,11 +30,6 @@ static bool we_are_root; /* true if our effective uid == 0 */ static mode_t newdir_umask; /* umask when creating new directories */ static mode_t current_umask; /* current umask (which is set to 0 if -p) */ -static bool directories_first; /* Directory members precede non-directory - ones in the archive. This is detected for - incremental archives only. This variable - helps correctly restore directory - timestamps */ /* Status of the permissions of a file that we are extracting. */ enum permstatus @@ -120,19 +115,6 @@ extr_init (void) same_permissions_option += we_are_root; same_owner_option += we_are_root; - /* Save 'root device' to avoid purging mount points. - FIXME: Should the same be done after handling -C option ? */ - if (one_file_system_option) - { - struct stat st; - char *dir = xgetcwd (); - - if (deref_stat (true, dir, &st)) - stat_diag (dir); - else - root_device = st.st_dev; - } - /* Option -p clears the kernel umask, so it does not affect proper restoration of file permissions. New intermediate directories will comply with umask at start of program. */ @@ -331,13 +313,13 @@ set_stat (char const *file_name, NOTICE: this works only if the archive has usual member order, i.e. directory, then the files in that directory. Incremental archive have somewhat reversed order: first go subdirectories, then all other - members. To help cope with this case the variable directories_first - is set by prepare_to_extract. + members. To help cope with this case the variable + delay_directory_restore_option is set by prepare_to_extract. If an archive was explicitely created so that its member order is reversed, some directory timestamps can be restored incorrectly, e.g.: - tar --no-recursion -cf archive dir dir/subdir dir/subdir/file + tar --no-recursion -cf archive dir dir/file1 foo dir/file2 */ static void delay_set_stat (char const *file_name, struct tar_stat_info const *st, @@ -626,6 +608,19 @@ extract_dir (char *file_name, int typeflag) mode_t mode; int interdir_made = 0; + /* Save 'root device' to avoid purging mount points. */ + if (one_file_system_option && root_device == 0) + { + struct stat st; + char *dir = xgetcwd (); + + if (deref_stat (true, dir, &st)) + stat_diag (dir); + else + root_device = st.st_dev; + free (dir); + } + if (incremental_option) /* Read the entry and delete files that aren't listed in the archive. */ purge_directory (file_name); @@ -1107,8 +1102,8 @@ prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun) case DIRTYPE: case GNUTYPE_DUMPDIR: *fun = extract_dir; - if (current_stat_info.dumpdir) - directories_first = true; + if (current_stat_info.is_dumpdir) + delay_directory_restore_option = true; break; case GNUTYPE_VOLHDR: @@ -1213,7 +1208,7 @@ extract_archive (void) /* Restore stats for all non-ancestor directories, unless it is an incremental archive. (see NOTICE in the comment to delay_set_stat above) */ - if (!directories_first) + if (!delay_directory_restore_option) apply_nonancestor_delayed_set_stat (file_name, 0); /* Take a safety backup of a previously existing file. */