diff --git a/archival/dpkg.c b/archival/dpkg.c index bf9e9992c..dae8a9747 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -1665,20 +1665,25 @@ static void unpack_package(deb_file_t *deb_file) archive_handle = init_archive_deb_ar(deb_file->filename); init_archive_deb_data(archive_handle); archive_handle->dpkg__sub_archive->accept = conffile_list; + /* Why ARCHIVE_REMEMBER_NAMES? + * We want names collected in ->passed list even if conffile_list + * is NULL (otherwise get_header_tar may optimize name saving out): + */ + archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_REMEMBER_NAMES | ARCHIVE_UNLINK_OLD; archive_handle->dpkg__sub_archive->filter = filter_rename_config; archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix; archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */ - archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD; unpack_ar_archive(archive_handle); /* Create the list file */ list_filename = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "list"); out_stream = xfopen_for_write(list_filename); + archive_handle->dpkg__sub_archive->passed = llist_rev(archive_handle->dpkg__sub_archive->passed); while (archive_handle->dpkg__sub_archive->passed) { + char *filename = llist_pop(&archive_handle->dpkg__sub_archive->passed); /* the leading . has been stripped by data_extract_all_prefix already */ - fputs(archive_handle->dpkg__sub_archive->passed->data, out_stream); - fputc('\n', out_stream); - archive_handle->dpkg__sub_archive->passed = archive_handle->dpkg__sub_archive->passed->link; + fprintf(out_stream, "%s\n", filename); + free(filename); } fclose(out_stream); diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index b168653d8..bc09756ba 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -452,9 +452,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) if (cp) *cp = '\0'; archive_handle->action_data(archive_handle); - if (archive_handle->accept || archive_handle->reject) + if (archive_handle->accept || archive_handle->reject + || (archive_handle->ah_flags & ARCHIVE_REMEMBER_NAMES) + ) { llist_add_to(&archive_handle->passed, file_header->name); - else /* Caller isn't interested in list of unpacked files */ + } else /* Caller isn't interested in list of unpacked files */ free(file_header->name); } else { data_skip(archive_handle); diff --git a/include/bb_archive.h b/include/bb_archive.h index 2043d8570..7bb5615da 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -121,6 +121,7 @@ typedef struct archive_handle_t { #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) #define ARCHIVE_NUMERIC_OWNER (1 << 7) #define ARCHIVE_O_TRUNC (1 << 8) +#define ARCHIVE_REMEMBER_NAMES (1 << 9) /* POSIX tar Header Block, from POSIX 1003.1-1990 */