X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=src%2Fincremen.c;h=9e0bb547b2d127c63bb5b28c1fe07702b17220fe;hb=d21d48dfba7ba5c0d136e2114291b45e09cf9b41;hp=48de66805defe2be728eb72e36e5d318dbbea4db;hpb=08a8d2dec63967653c7f54a1b4b7cb49c3c12679;p=chaz%2Ftar diff --git a/src/incremen.c b/src/incremen.c index 48de668..9e0bb54 100644 --- a/src/incremen.c +++ b/src/incremen.c @@ -150,6 +150,7 @@ procdir (char *name_buffer, struct stat *stat_data, { struct directory *directory; bool nfs = NFS_FILE_STAT (*stat_data); + struct name *np; if ((directory = find_directory (name_buffer)) != NULL) { @@ -202,8 +203,12 @@ procdir (char *name_buffer, struct stat *stat_data, ? ALL_CHILDREN : CHANGED_CHILDREN; } - - if (one_file_system_option && device != stat_data->st_dev) + + /* If the directory is on another device and --one-file-system was given, + omit it... */ + if (one_file_system_option && device != stat_data->st_dev + /* ... except if it was explicitely given in the command line */ + && !((np = name_scan (name_buffer, true)) && np->explicit)) directory->children = NO_CHILDREN; else if (children == ALL_CHILDREN) directory->children = ALL_CHILDREN; @@ -454,7 +459,7 @@ read_directory_file (void) incremental_version = 0; if (incremental_version > TAR_INCREMENTAL_VERSION) - ERROR((1, 0, _("Unsupported incremental format version: %s"), + ERROR((1, 0, _("Unsupported incremental format version: %d"), incremental_version)); t = u = (errno = 0, strtoumax (buf, &ebuf, 10)); @@ -631,8 +636,8 @@ write_directory_file (void) /* Restoration of incremental dumps. */ -void -get_gnu_dumpdir () +static void +get_gnu_dumpdir (struct tar_stat_info *stat_info) { size_t size; size_t copied; @@ -640,23 +645,17 @@ get_gnu_dumpdir () char *to; char *archive_dir; - size = current_stat_info.stat.st_size; - if (size != current_stat_info.stat.st_size) - xalloc_die (); + size = stat_info->stat.st_size; archive_dir = xmalloc (size); to = archive_dir; set_next_block_after (current_header); - if (multi_volume_option) - { - assign_string (&save_name, current_stat_info.orig_file_name); - save_totsize = current_stat_info.stat.st_size; - } + mv_begin (stat_info); + for (; size > 0; size -= copied) { - if (multi_volume_option) - save_sizeleft = size; + mv_size_left (size); data_block = find_next_block (); if (!data_block) ERROR ((1, 0, _("Unexpected EOF in archive"))); @@ -668,14 +667,24 @@ get_gnu_dumpdir () set_next_block_after ((union block *) (data_block->buffer + copied - 1)); } - if (multi_volume_option) - assign_string (&save_name, 0); + + mv_end (); - current_stat_info.stat.st_size = 0; /* For skip_member() and friends - to work correctly */ - current_stat_info.dumpdir = archive_dir; + stat_info->dumpdir = archive_dir; + stat_info->skipped = true; /* For skip_member() and friends + to work correctly */ } +/* Return T if STAT_INFO represents a dumpdir archive member. + Note: can invalidate current_header. It happens if flush_archive() + gets called within get_gnu_dumpdir() */ +bool +is_dumpdir (struct tar_stat_info *stat_info) +{ + if (stat_info->is_dumpdir && !stat_info->dumpdir) + get_gnu_dumpdir (stat_info); + return stat_info->is_dumpdir; +} /* Examine the directories under directory_name and delete any files that were not there at the time of the back-up. */ @@ -685,6 +694,12 @@ purge_directory (char const *directory_name) char *current_dir; char *cur, *arc; + if (!is_dumpdir (¤t_stat_info)) + { + skip_member (); + return; + } + current_dir = savedir (directory_name); if (!current_dir)