]> Dogcows Code - chaz/tar/blobdiff - src/names.c
* src/names.c: tar: fix bug with --one-file-system --listed-incremental
[chaz/tar] / src / names.c
index 2fc751d81fac59c0faab9515850f7e83891c9c76..ba4d509e47ead3bfd99846250f05c623878a11c8 100644 (file)
@@ -47,8 +47,6 @@ static char *cached_no_such_gname;
 static uid_t cached_no_such_uid;
 static gid_t cached_no_such_gid;
 
-static void register_individual_file (char const *name);
-
 /* Given UID, find the corresponding UNAME.  */
 void
 uid_to_uname (uid_t uid, char **uname)
@@ -360,8 +358,6 @@ name_next_elt (int change_dirs)
        {
          if (unquote_option)
            unquote_string (name_buffer);
-         if (incremental_option)
-           register_individual_file (name_buffer);
          entry.type = ep->type;
          entry.v.name = name_buffer;
          return &entry;
@@ -818,6 +814,7 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
            {
              struct name *np;
              struct tar_stat_info subdir;
+             int subfd;
 
              if (allocated_length <= name_length + string_length)
                {
@@ -841,21 +838,32 @@ add_hierarchy_to_namelist (struct tar_stat_info *st, struct name *name)
 
              tar_stat_init (&subdir);
              subdir.parent = st;
-             subdir.fd = openat (st->fd, string + 1,
-                                 open_read_flags | O_DIRECTORY);
-             if (subdir.fd < 0)
-               open_diag (namebuf);
-             else if (fstat (subdir.fd, &subdir.stat) != 0)
-               stat_diag (namebuf);
-             else if (! (O_DIRECTORY || S_ISDIR (subdir.stat.st_mode)))
+             if (st->fd < 0)
                {
-                 errno = ENOTDIR;
-                 open_diag (namebuf);
+                 subfd = -1;
+                 errno = - st->fd;
                }
+             else
+               subfd = subfile_open (st, string + 1,
+                                     open_read_flags | O_DIRECTORY);
+             if (subfd < 0)
+               open_diag (namebuf);
              else
                {
-                 subdir.orig_file_name = xstrdup (namebuf);
-                 add_hierarchy_to_namelist (&subdir, np);
+                 subdir.fd = subfd;
+                 if (fstat (subfd, &subdir.stat) != 0)
+                   stat_diag (namebuf);
+                 else if (! (O_DIRECTORY || S_ISDIR (subdir.stat.st_mode)))
+                   {
+                     errno = ENOTDIR;
+                     open_diag (namebuf);
+                   }
+                 else
+                   {
+                     subdir.orig_file_name = xstrdup (namebuf);
+                     add_hierarchy_to_namelist (&subdir, np);
+                     restore_parent_fd (&subdir);
+                   }
                }
 
              tar_stat_destroy (&subdir);
@@ -969,23 +977,28 @@ collect_and_sort_names (void)
 
       tar_stat_init (&st);
 
-      if (deref_stat (dereference_option, name->name, &st.stat) != 0)
+      if (deref_stat (name->name, &st.stat) != 0)
        {
          stat_diag (name->name);
          continue;
        }
       if (S_ISDIR (st.stat.st_mode))
        {
-         st.fd = open (name->name, open_read_flags | O_DIRECTORY);
-         if (st.fd < 0)
+         int dir_fd = openat (chdir_fd, name->name,
+                              open_read_flags | O_DIRECTORY);
+         if (dir_fd < 0)
            open_diag (name->name);
-         else if (fstat (st.fd, &st.stat) != 0)
-           stat_diag (name->name);
-         else if (O_DIRECTORY || S_ISDIR (st.stat.st_mode))
+         else
            {
-             st.orig_file_name = xstrdup (name->name);
-             name->found_count++;
-             add_hierarchy_to_namelist (&st, name);
+             st.fd = dir_fd;
+             if (fstat (dir_fd, &st.stat) != 0)
+               stat_diag (name->name);
+             else if (O_DIRECTORY || S_ISDIR (st.stat.st_mode))
+               {
+                 st.orig_file_name = xstrdup (name->name);
+                 name->found_count++;
+                 add_hierarchy_to_namelist (&st, name);
+               }
            }
        }
 
@@ -1134,28 +1147,6 @@ excluded_name (char const *name)
 {
   return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name));
 }
-\f
-static Hash_table *individual_file_table;
-
-static void
-register_individual_file (char const *name)
-{
-  struct stat st;
-
-  if (deref_stat (dereference_option, name, &st) != 0)
-    return; /* Will be complained about later */
-  if (S_ISDIR (st.st_mode))
-    return;
-
-  hash_string_insert (&individual_file_table, name);
-}
-
-bool
-is_individual_file (char const *name)
-{
-  return hash_string_lookup (individual_file_table, name);
-}
-
 \f
 
 /* Return the size of the prefix of FILE_NAME that is removed after
This page took 0.022558 seconds and 4 git commands to generate.