aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-02-20 15:58:42 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2013-02-20 15:58:42 +0100
commit2aec773688fd64857e9446838187170760acddd4 (patch)
tree4528074a1856b5656b5db6d140026a486c44714d
parent10f5f9b10d5bb18aa612e8f340d8454421015b00 (diff)
downloadbusybox-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.c15
-rw-r--r--archival/rpm.c4
-rw-r--r--include/bb_archive.h3
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 */