rpm: use "create+rename" method of replacing existing files
No binary (build failed)
—
(log yok)
| @@ -106,15 +106,28 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |
| switch (file_header->mode & S_IFMT) { | |
| case S_IFREG: { | |
| /* Regular file */ | |
| + | char *dst_name; |
| int flags = O_WRONLY | O_CREAT | O_EXCL; | |
| if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) | |
| flags = O_WRONLY | O_CREAT | O_TRUNC; | |
| - | dst_fd = xopen3(file_header->name, |
| + | dst_name = file_header->name; |
| + | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
| + | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) |
| + | /* rpm-style temp file name */ |
| + | dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); |
| + | #endif |
| + | dst_fd = xopen3(dst_name, |
| flags, | |
| file_header->mode | |
| ); | |
| bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); | |
| close(dst_fd); | |
| + | #ifdef ARCHIVE_REPLACE_VIA_RENAME |
| + | if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { |
| + | xrename(dst_name, file_header->name); |
| + | free(dst_name); |
| + | } |
| + | #endif |
| break; | |
| } | |
| case S_IFDIR: | |
| @@ -242,8 +242,8 @@ static void extract_cpio(int fd, const char *source_rpm) | |
| /* compat: overwrite existing files. | |
| * try "rpm -i foo.src.rpm" few times in a row - | |
| * standard rpm will not complain. | |
| - | * (TODO? real rpm creates "file;1234" and then renames it) */ |
| - | | ARCHIVE_UNLINK_OLD; |
| + | */ |
| + | | ARCHIVE_REPLACE_VIA_RENAME; |
| archive_handle->src_fd = fd; | |
| /*archive_handle->offset = 0; - init_handle() did it */ | |
| @@ -122,6 +122,9 @@ typedef struct archive_handle_t { | |
| #define ARCHIVE_NUMERIC_OWNER (1 << 7) | |
| #define ARCHIVE_O_TRUNC (1 << 8) | |
| #define ARCHIVE_REMEMBER_NAMES (1 << 9) | |
| + | #if ENABLE_RPM |
| + | #define ARCHIVE_REPLACE_VIA_RENAME (1 << 10) |
| + | #endif |
| /* POSIX tar Header Block, from POSIX 1003.1-1990 */ | |