diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-20 15:58:42 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-02-20 15:58:42 +0100 |
commit | 2aec773688fd64857e9446838187170760acddd4 (patch) | |
tree | 4528074a1856b5656b5db6d140026a486c44714d | |
parent | 10f5f9b10d5bb18aa612e8f340d8454421015b00 (diff) | |
download | busybox-w32-2aec773688fd64857e9446838187170760acddd4.tar.gz busybox-w32-2aec773688fd64857e9446838187170760acddd4.tar.bz2 busybox-w32-2aec773688fd64857e9446838187170760acddd4.zip |
rpm: use "create+rename" method of replacing existing files
Users were reporting getting errors like
"ls: error while loading shared libraries: libc.so.6: ELF load command past end of file"
while rpm was unpacking glibc tarball.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/data_extract_all.c | 15 | ||||
-rw-r--r-- | archival/rpm.c | 4 | ||||
-rw-r--r-- | include/bb_archive.h | 3 |
3 files changed, 19 insertions, 3 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 3f67b835f..45776dcbe 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -106,15 +106,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
106 | switch (file_header->mode & S_IFMT) { | 106 | switch (file_header->mode & S_IFMT) { |
107 | case S_IFREG: { | 107 | case S_IFREG: { |
108 | /* Regular file */ | 108 | /* Regular file */ |
109 | char *dst_name; | ||
109 | int flags = O_WRONLY | O_CREAT | O_EXCL; | 110 | int flags = O_WRONLY | O_CREAT | O_EXCL; |
110 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | 111 | if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) |
111 | flags = O_WRONLY | O_CREAT | O_TRUNC; | 112 | flags = O_WRONLY | O_CREAT | O_TRUNC; |
112 | dst_fd = xopen3(file_header->name, | 113 | dst_name = file_header->name; |
114 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | ||
115 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) | ||
116 | /* rpm-style temp file name */ | ||
117 | dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); | ||
118 | #endif | ||
119 | dst_fd = xopen3(dst_name, | ||
113 | flags, | 120 | flags, |
114 | file_header->mode | 121 | file_header->mode |
115 | ); | 122 | ); |
116 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); | 123 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); |
117 | close(dst_fd); | 124 | close(dst_fd); |
125 | #ifdef ARCHIVE_REPLACE_VIA_RENAME | ||
126 | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { | ||
127 | xrename(dst_name, file_header->name); | ||
128 | free(dst_name); | ||
129 | } | ||
130 | #endif | ||
118 | break; | 131 | break; |
119 | } | 132 | } |
120 | case S_IFDIR: | 133 | case S_IFDIR: |
diff --git a/archival/rpm.c b/archival/rpm.c index 793701652..6b227d537 100644 --- a/archival/rpm.c +++ b/archival/rpm.c | |||
@@ -242,8 +242,8 @@ static void extract_cpio(int fd, const char *source_rpm) | |||
242 | /* compat: overwrite existing files. | 242 | /* compat: overwrite existing files. |
243 | * try "rpm -i foo.src.rpm" few times in a row - | 243 | * try "rpm -i foo.src.rpm" few times in a row - |
244 | * standard rpm will not complain. | 244 | * standard rpm will not complain. |
245 | * (TODO? real rpm creates "file;1234" and then renames it) */ | 245 | */ |
246 | | ARCHIVE_UNLINK_OLD; | 246 | | ARCHIVE_REPLACE_VIA_RENAME; |
247 | archive_handle->src_fd = fd; | 247 | archive_handle->src_fd = fd; |
248 | /*archive_handle->offset = 0; - init_handle() did it */ | 248 | /*archive_handle->offset = 0; - init_handle() did it */ |
249 | 249 | ||
diff --git a/include/bb_archive.h b/include/bb_archive.h index a7a2a1135..b82cfd83c 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -122,6 +122,9 @@ typedef struct archive_handle_t { | |||
122 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) | 122 | #define ARCHIVE_NUMERIC_OWNER (1 << 7) |
123 | #define ARCHIVE_O_TRUNC (1 << 8) | 123 | #define ARCHIVE_O_TRUNC (1 << 8) |
124 | #define ARCHIVE_REMEMBER_NAMES (1 << 9) | 124 | #define ARCHIVE_REMEMBER_NAMES (1 << 9) |
125 | #if ENABLE_RPM | ||
126 | #define ARCHIVE_REPLACE_VIA_RENAME (1 << 10) | ||
127 | #endif | ||
125 | 128 | ||
126 | 129 | ||
127 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | 130 | /* POSIX tar Header Block, from POSIX 1003.1-1990 */ |