From 3d5828fb6da7376eb220817376f22fac4da2815a Mon Sep 17 00:00:00 2001 From: Glenn L McGrath Date: Thu, 14 Aug 2003 02:55:15 +0000 Subject: [PATCH] Change hardlink handling for tar to work the same way as cpio --- archival/libunarchive/data_extract_all.c | 82 ++++++++++++------------ archival/libunarchive/get_header_tar.c | 8 ++- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/archival/libunarchive/data_extract_all.c b/archival/libunarchive/data_extract_all.c index bd264dd74..c6ace2c33 100644 --- a/archival/libunarchive/data_extract_all.c +++ b/archival/libunarchive/data_extract_all.c @@ -39,54 +39,52 @@ extern void data_extract_all(archive_handle_t *archive_handle) free(name); } - /* Create the filesystem entry */ - switch(file_header->mode & S_IFMT) { - case S_IFREG: { -#ifdef CONFIG_CPIO - if (file_header->link_name && file_header->size == 0) { - /* hard link */ - res = link(file_header->link_name, file_header->name); - if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { - bb_perror_msg("Couldnt create hard link"); - } - } else -#endif - { + /* Handle hard links seperately */ + if (!S_ISLNK(file_header->mode) && (file_header->link_name) && (file_header->size == 0)) { + /* hard link */ + res = link(file_header->link_name, file_header->name); + if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { + bb_perror_msg("Couldnt create hard link"); + } + } else { + /* Create the filesystem entry */ + switch(file_header->mode & S_IFMT) { + case S_IFREG: { /* Regular file */ unlink(file_header->name); dst_fd = bb_xopen(file_header->name, O_WRONLY | O_CREAT | O_EXCL); archive_copy_file(archive_handle, dst_fd); close(dst_fd); - } - break; + break; + } + case S_IFDIR: + unlink(file_header->name); + res = mkdir(file_header->name, file_header->mode); + if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { + bb_perror_msg("extract_archive: %s", file_header->name); + } + break; + case S_IFLNK: + /* Symlink */ + unlink(file_header->name); + res = symlink(file_header->link_name, file_header->name); + if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { + bb_perror_msg("Cannot create symlink from %s to '%s'", file_header->name, file_header->link_name); + } + break; + case S_IFSOCK: + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + unlink(file_header->name); + res = mknod(file_header->name, file_header->mode, file_header->device); + if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { + bb_perror_msg("Cannot create node %s", file_header->name); + } + break; + default: + bb_error_msg_and_die("Unrecognised file type"); } - case S_IFDIR: - unlink(file_header->name); - res = mkdir(file_header->name, file_header->mode); - if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { - bb_perror_msg("extract_archive: %s", file_header->name); - } - break; - case S_IFLNK: - /* Symlink */ - unlink(file_header->name); - res = symlink(file_header->link_name, file_header->name); - if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { - bb_perror_msg("Cannot create symlink from %s to '%s'", file_header->name, file_header->link_name); - } - break; - case S_IFSOCK: - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - unlink(file_header->name); - res = mknod(file_header->name, file_header->mode, file_header->device); - if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { - bb_perror_msg("Cannot create node %s", file_header->name); - } - break; - default: - bb_error_msg_and_die("Unrecognised file type"); } chmod(file_header->name, file_header->mode); diff --git a/archival/libunarchive/get_header_tar.c b/archival/libunarchive/get_header_tar.c index 33cb75dfd..3bbe15d36 100644 --- a/archival/libunarchive/get_header_tar.c +++ b/archival/libunarchive/get_header_tar.c @@ -128,8 +128,12 @@ extern char get_header_tar(archive_handle_t *archive_handle) case '0': file_header->mode |= S_IFREG; break; +#if 0 + /* hard links are detected as entries with 0 size, a link name, + * and not being a symlink, hence we have nothing to do here */ case '1': - bb_error_msg("WARNING: Converting hard link to symlink"); + break; +#endif case '2': file_header->mode |= S_IFLNK; break; @@ -173,6 +177,7 @@ extern char get_header_tar(archive_handle_t *archive_handle) # endif } #endif + if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { archive_handle->action_header(archive_handle->file_header); archive_handle->flags |= ARCHIVE_EXTRACT_QUIET; @@ -185,4 +190,3 @@ extern char get_header_tar(archive_handle_t *archive_handle) return(EXIT_SUCCESS); } -