X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fnames.c;h=eee6bde928d99c99a1766f9315b3ac3cfda58e24;hb=4ac671c49ba5df93c2f386bc8d7dbe50f4671a57;hp=2fc751d81fac59c0faab9515850f7e83891c9c76;hpb=de328a580ab6f5ff4a3237ce21f1ef0b7dd12984;p=chaz%2Ftar diff --git a/src/names.c b/src/names.c index 2fc751d..eee6bde 100644 --- a/src/names.c +++ b/src/names.c @@ -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; @@ -673,9 +669,9 @@ label_notfound (void) /* Sort *singly* linked LIST of names, of given LENGTH, using COMPARE to order names. Return the sorted list. Note that after calling - this function, the `prev' links in list elements are messed up. + this function, the 'prev' links in list elements are messed up. - Apart from the type `struct name' and the definition of SUCCESSOR, + Apart from the type 'struct name' and the definition of SUCCESSOR, this is a generic list-sorting function, but it's too painful to make it both generic and portable in C. */ @@ -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); @@ -886,7 +894,7 @@ name_compare (void const *entry1, void const *entry2) } -/* Rebase `name' member of CHILD and all its siblings to +/* Rebase 'name' member of CHILD and all its siblings to the new PARENT. */ static void rebase_child_list (struct name *child, struct name *parent) @@ -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); + } } } @@ -1087,7 +1100,7 @@ name_scan (const char *file_name) struct name *gnu_list_name; struct name const * -name_from_list () +name_from_list (void) { if (!gnu_list_name) gnu_list_name = namelist; @@ -1134,28 +1147,6 @@ excluded_name (char const *name) { return excluded_file_name (excluded, name + FILE_SYSTEM_PREFIX_LEN (name)); } - -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); -} - /* Return the size of the prefix of FILE_NAME that is removed after