X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fextract.c;h=9b6b7f97487e39d6a297e99c797f9ae37e882cc3;hb=a09e840507c16357ec11b17a02e103c3a26adebc;hp=faee4eb889ec15c3deaa66d463f6bbe7fad7e773;hpb=beca89bccb6b806e3528d4d0aa01cb5f2831c954;p=chaz%2Ftar diff --git a/src/extract.c b/src/extract.c index faee4eb..9b6b7f9 100644 --- a/src/extract.c +++ b/src/extract.c @@ -297,7 +297,7 @@ set_mode (char const *file_name, static void check_time (char const *file_name, struct timespec t) { - if (t.tv_sec <= 0) + if (t.tv_sec < 0) WARNOPT (WARN_TIMESTAMP, (0, 0, _("%s: implausibly old time stamp %s"), file_name, tartime (t, true))); @@ -855,7 +855,21 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links) } - +static bool +is_directory_link (const char *file_name) +{ + struct stat st; + int e = errno; + int res; + + res = (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0 && + S_ISLNK (st.st_mode) && + fstatat (chdir_fd, file_name, &st, 0) == 0 && + S_ISDIR (st.st_mode)); + errno = e; + return res; +} + /* Extractor functions for various member types */ static int @@ -911,10 +925,15 @@ extract_dir (char *file_name, int typeflag) if (errno == EEXIST && (interdir_made + || keep_directory_symlink_option || old_files_option == DEFAULT_OLD_FILES || old_files_option == OVERWRITE_OLD_FILES)) { struct stat st; + + if (keep_directory_symlink_option && is_directory_link (file_name)) + return 0; + if (deref_stat (file_name, &st) == 0) { current_mode = st.st_mode; @@ -1341,7 +1360,7 @@ extract_symlink (char *file_name, int typeflag) if (!warned_once) { warned_once = 1; - WARNOPT (WARN_SYMBOLIC_CAST, + WARNOPT (WARN_SYMLINK_CAST, (0, 0, _("Attempting extraction of symbolic links as hard links"))); }