Do not issue errors on existing files when given the -k option
* Makefile.am (dist-hook): Fix rule. * src/extract.c (maybe_recoverable): Return three-state value. (extract_dir): Skip extraction if maybe_recoverable indicates so. (extract_file): Likewise.
This commit is contained in:
@@ -23,7 +23,7 @@ EXTRA_DIST = ChangeLog.1 Make.rules
|
|||||||
SUBDIRS = doc gnu lib rmt src scripts po tests
|
SUBDIRS = doc gnu lib rmt src scripts po tests
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
$(MAKE) changelog_dir=$(distdir) make-ChangeLog
|
$(MAKE) changelog_dir=$(distdir) ChangeLog
|
||||||
-rm -f $(distdir).cpio
|
-rm -f $(distdir).cpio
|
||||||
find $(distdir) | cpio -Hcrc -o | \
|
find $(distdir) | cpio -Hcrc -o | \
|
||||||
GZIP=$(GZIP_ENV) gzip -c > $(distdir).cpio.gz
|
GZIP=$(GZIP_ENV) gzip -c > $(distdir).cpio.gz
|
||||||
|
|||||||
@@ -486,17 +486,24 @@ file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define RECOVER_NO 0
|
||||||
|
#define RECOVER_OK 1
|
||||||
|
#define RECOVER_SKIP 2
|
||||||
|
|
||||||
/* Attempt repairing what went wrong with the extraction. Delete an
|
/* Attempt repairing what went wrong with the extraction. Delete an
|
||||||
already existing file or create missing intermediate directories.
|
already existing file or create missing intermediate directories.
|
||||||
Return nonzero if we somewhat increased our chances at a successful
|
Return RECOVER_OK if we somewhat increased our chances at a successful
|
||||||
extraction. errno is properly restored on zero return. */
|
extraction, RECOVER_NO if there are no chances, and RECOVER_SKIP if the
|
||||||
|
caller should skip extraction of that member. The value of errno is
|
||||||
|
properly restored on returning RECOVER_NO. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
maybe_recoverable (char *file_name, int *interdir_made)
|
maybe_recoverable (char *file_name, int *interdir_made)
|
||||||
{
|
{
|
||||||
int e = errno;
|
int e = errno;
|
||||||
|
|
||||||
if (*interdir_made)
|
if (*interdir_made)
|
||||||
return 0;
|
return RECOVER_NO;
|
||||||
|
|
||||||
switch (errno)
|
switch (errno)
|
||||||
{
|
{
|
||||||
@@ -506,13 +513,13 @@ maybe_recoverable (char *file_name, int *interdir_made)
|
|||||||
switch (old_files_option)
|
switch (old_files_option)
|
||||||
{
|
{
|
||||||
case KEEP_OLD_FILES:
|
case KEEP_OLD_FILES:
|
||||||
return 0;
|
return RECOVER_SKIP;
|
||||||
|
|
||||||
case KEEP_NEWER_FILES:
|
case KEEP_NEWER_FILES:
|
||||||
if (file_newer_p (file_name, ¤t_stat_info))
|
if (file_newer_p (file_name, ¤t_stat_info))
|
||||||
{
|
{
|
||||||
errno = e;
|
errno = e;
|
||||||
return 0;
|
return RECOVER_NO;
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
|
||||||
@@ -522,7 +529,7 @@ maybe_recoverable (char *file_name, int *interdir_made)
|
|||||||
{
|
{
|
||||||
int r = remove_any_file (file_name, ORDINARY_REMOVE_OPTION);
|
int r = remove_any_file (file_name, ORDINARY_REMOVE_OPTION);
|
||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
return r;
|
return r > 0 ? RECOVER_OK : RECOVER_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
case UNLINK_FIRST_OLD_FILES:
|
case UNLINK_FIRST_OLD_FILES:
|
||||||
@@ -534,15 +541,15 @@ maybe_recoverable (char *file_name, int *interdir_made)
|
|||||||
if (! make_directories (file_name))
|
if (! make_directories (file_name))
|
||||||
{
|
{
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
return 0;
|
return RECOVER_NO;
|
||||||
}
|
}
|
||||||
*interdir_made = 1;
|
*interdir_made = 1;
|
||||||
return 1;
|
return RECOVER_OK;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* Just say we can't do anything about it... */
|
/* Just say we can't do anything about it... */
|
||||||
|
|
||||||
return 0;
|
return RECOVER_NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -666,13 +673,21 @@ extract_dir (char *file_name, int typeflag)
|
|||||||
errno = EEXIST;
|
errno = EEXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maybe_recoverable (file_name, &interdir_made))
|
switch (maybe_recoverable (file_name, &interdir_made))
|
||||||
continue;
|
|
||||||
|
|
||||||
if (errno != EEXIST)
|
|
||||||
{
|
{
|
||||||
mkdir_error (file_name);
|
case RECOVER_OK:
|
||||||
return 1;
|
continue;
|
||||||
|
|
||||||
|
case RECOVER_SKIP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RECOVER_NO:
|
||||||
|
if (errno != EEXIST)
|
||||||
|
{
|
||||||
|
mkdir_error (file_name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -760,13 +775,18 @@ extract_file (char *file_name, int typeflag)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int recover = RECOVER_NO;
|
||||||
do
|
do
|
||||||
fd = open_output_file (file_name, typeflag, mode ^ invert_permissions);
|
fd = open_output_file (file_name, typeflag, mode ^ invert_permissions);
|
||||||
while (fd < 0 && maybe_recoverable (file_name, &interdir_made));
|
while (fd < 0
|
||||||
|
&& (recover = maybe_recoverable (file_name, &interdir_made))
|
||||||
|
== RECOVER_OK);
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
skip_member ();
|
skip_member ();
|
||||||
|
if (recover == RECOVER_SKIP)
|
||||||
|
return 0;
|
||||||
open_error (file_name);
|
open_error (file_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user