From a365d052b01a5df1ffe716ee8af3e71ee15836fa Mon Sep 17 00:00:00 2001 From: zhangruifang2020 Date: Mon, 17 Jul 2023 11:39:03 +0800 Subject: [PATCH] revert Fix 45b0ee2b407913c533f7ded8d6f8cbeec16ff6ca --- src/copyin.c | 173 +++++++-------------------------------------------- 1 file changed, 22 insertions(+), 151 deletions(-) diff --git a/src/copyin.c b/src/copyin.c index f2babb7..2316feb 100644 --- a/src/copyin.c +++ b/src/copyin.c @@ -30,7 +30,6 @@ #ifndef FNM_PATHNAME # include #endif -#include #ifndef HAVE_LCHOWN # define lchown(f,u,g) 0 @@ -622,136 +621,6 @@ copyin_device (struct cpio_file_stat* file_hdr) file_hdr->c_mtime); } -struct delayed_link - { - /* The device and inode number of the placeholder. */ - dev_t dev; - ino_t ino; - - /* The desired link metadata. */ - mode_t mode; - uid_t uid; - gid_t gid; - time_t mtime; - - /* Link source and target names. */ - char *source; - char target[1]; - }; - -static Hash_table *delayed_link_table; - -static size_t -dl_hash (void const *entry, size_t table_size) -{ - struct delayed_link const *dl = entry; - uintmax_t n = dl->dev; - int nshift = (sizeof (n) - sizeof (dl->dev)) * CHAR_BIT; - if (0 < nshift) - n <<= nshift; - n ^= dl->ino; - return n % table_size; -} - -static bool -dl_compare (void const *a, void const *b) -{ - struct delayed_link const *da = a, *db = b; - return (da->dev == db->dev) & (da->ino == db->ino); -} - -static int -symlink_placeholder (char *oldpath, char *newpath, struct cpio_file_stat *file_stat) -{ - int fd = open (newpath, O_WRONLY | O_CREAT | O_EXCL, 0); - struct stat st; - struct delayed_link *p; - size_t newlen = strlen (newpath); - - if (fd < 0) - { - open_error (newpath); - return -1; - } - - if (fstat (fd, &st) != 0) - { - stat_error (newpath); - close (fd); - return -1; - } - - close (fd); - - p = xmalloc (sizeof (*p) + strlen (oldpath) + newlen + 1); - p->dev = st.st_dev; - p->ino = st.st_ino; - - p->mode = file_stat->c_mode; - p->uid = file_stat->c_uid; - p->gid = file_stat->c_gid; - p->mtime = file_stat->c_mtime; - - strcpy (p->target, newpath); - p->source = p->target + newlen + 1; - strcpy (p->source, oldpath); - - if (!((delayed_link_table - || (delayed_link_table = hash_initialize (0, 0, dl_hash, - dl_compare, free))) - && hash_insert (delayed_link_table, p))) - xalloc_die (); - - return 0; -} - -static void -replace_symlink_placeholders (void) -{ - struct delayed_link *dl; - - if (!delayed_link_table) - return; - for (dl = hash_get_first (delayed_link_table); - dl; - dl = hash_get_next (delayed_link_table, dl)) - { - struct stat st; - - /* Make sure the placeholder file is still there. If not, - don't create a link, as the placeholder was probably - removed by a later extraction. */ - if (lstat (dl->target, &st) == 0 - && st.st_dev == dl->dev - && st.st_ino == dl->ino) - { - if (unlink (dl->target)) - unlink_error (dl->target); - else - { - int res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode); - if (res < 0 && create_dir_flag) - { - create_all_directories (dl->target); - res = UMASKED_SYMLINK (dl->source, dl->target, dl->mode); - } - if (res < 0) - symlink_error (dl->source, dl->target); - else if (!no_chown_flag) - { - uid_t uid = set_owner_flag ? set_owner : dl->uid; - gid_t gid = set_group_flag ? set_group : dl->gid; - if (lchown (dl->target, uid, gid) < 0 && errno != EPERM) - chown_error_details (dl->target, uid, gid); - } - } - } - } - - hash_free (delayed_link_table); - delayed_link_table = NULL; -} - static void copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) { @@ -777,26 +646,29 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des) link_name = xstrdup (file_hdr->c_tar_linkname); } - if (no_abs_paths_flag) - symlink_placeholder (link_name, file_hdr->c_name, file_hdr); - else + cpio_safer_name_suffix (link_name, true, !no_abs_paths_flag, false); + + res = UMASKED_SYMLINK (link_name, file_hdr->c_name, + file_hdr->c_mode); + if (res < 0 && create_dir_flag) { - res = UMASKED_SYMLINK (link_name, file_hdr->c_name, - file_hdr->c_mode); - if (res < 0 && create_dir_flag) - { - create_all_directories (file_hdr->c_name); - res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); - } - if (res < 0) - symlink_error (link_name, file_hdr->c_name); - else if (!no_chown_flag) - { - uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; - gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; - if (lchown (file_hdr->c_name, uid, gid) < 0 && errno != EPERM) - chown_error_details (file_hdr->c_name, uid, gid); - } + create_all_directories (file_hdr->c_name); + res = UMASKED_SYMLINK (link_name, file_hdr->c_name, file_hdr->c_mode); + } + if (res < 0) + { + error (0, errno, _("%s: Cannot symlink to %s"), + quotearg_colon (link_name), quote_n (1, file_hdr->c_name)); + free (link_name); + return; + } + if (!no_chown_flag) + { + uid_t uid = set_owner_flag ? set_owner : file_hdr->c_uid; + gid_t gid = set_group_flag ? set_group : file_hdr->c_gid; + if ((lchown (file_hdr->c_name, uid, gid) < 0) + && errno != EPERM) + chown_error_details (file_hdr->c_name, uid, gid); } free (link_name); } @@ -1577,7 +1449,6 @@ process_copy_in (void) if (dot_flag) fputc ('\n', stderr); - replace_symlink_placeholders (); apply_delayed_set_stat (); cpio_file_stat_free (&file_hdr); -- 2.27.0