]> Dogcows Code - chaz/tar/blobdiff - src/extract.c
Update copyright years.
[chaz/tar] / src / extract.c
index faee4eb889ec15c3deaa66d463f6bbe7fad7e773..2cc1f7b383a121fb5a6d864e96bf54f8af4a9d95 100644 (file)
@@ -1,7 +1,7 @@
 /* Extract files from a tar archive.
 
-   Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2013
-   Free Software Foundation, Inc.
+   Copyright 1988, 1992-1994, 1996-2001, 2003-2007, 2010, 2012-2014 Free
+   Software Foundation, Inc.
 
    This file is part of GNU tar.
 
@@ -191,6 +191,19 @@ extr_init (void)
       umask (newdir_umask);    /* restore the kernel umask */
       current_umask = newdir_umask;
     }
+
+  /* If the user wants to guarantee that everything is under one directory,
+     determine its name now and let it be created later.  */
+  if (one_top_level_option && !one_top_level_dir)
+    {
+      char *base = base_name (archive_name_array[0]);
+
+      one_top_level_dir = strip_compression_suffix (base);
+      free (base);
+      
+      if (!one_top_level_dir)
+       USAGE_ERROR ((0, 0, _("Cannot deduce top-level directory name; please set it explicitly with --one-top-level=DIR")));
+    }
 }
 
 /* Use fchmod if possible, fchmodat otherwise.  */
@@ -297,7 +310,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 +868,21 @@ apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
 }
 
 \f
-
+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;
+}
+\f
 /* Extractor functions for various member types */
 
 static int
@@ -911,10 +938,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 +1373,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")));
     }
This page took 0.022926 seconds and 4 git commands to generate.