[PATCH] cpio: implement output prefix for passthrough mode (-p)
Shubham Chakraborty via busybox <[email protected]>
| Newsgroups | gmane.linux.busybox |
|---|---|
| Message-ID | <[email protected]> |
GNU cpio -vp DIR outputs "DIR/NAME" instead of just "NAME". This patch implements this behavior by adding a cpio__prefix field to archive_handle_t and updating header_list/header_verbose_list to use it. To achieve this, the action_header callback signature was changed from (const file_header_t*) to (archive_handle_t*) to allow access to the prefix and other handle-specific data. Also removes a related TODO in archival/libarchive/header_list.c. Signed-off-by: Shubham Chakraborty <[email protected]> --- archival/ar.c | 3 ++- archival/cpio.c | 12 +++++++++++- archival/libarchive/get_header_ar.c | 2 +- archival/libarchive/get_header_cpio.c | 2 +- archival/libarchive/get_header_tar.c | 2 +- archival/libarchive/header_list.c | 9 ++++++--- archival/libarchive/header_skip.c | 2 +- archival/libarchive/header_verbose_list.c | 19 ++++++++++++------- include/bb_archive.h | 9 +++++---- 9 files changed, 40 insertions(+), 20 deletions(-) diff --git a/archival/ar.c b/archival/ar.c index 320cbae72..d3d6c3c06 100644 --- a/archival/ar.c +++ b/archival/ar.c @@ -194,8 +194,9 @@ static int write_ar_archive(archive_handle_t *handle) } #endif /* FEATURE_AR_CREATE */ -static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header) +static void FAST_FUNC header_verbose_list_ar(archive_handle_t *archive_handle) { + const file_header_t *file_header = archive_handle->file_header; char mode[12]; char *mtime; diff --git a/archival/cpio.c b/archival/cpio.c index b033b3733..dfeb12c8a 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -511,7 +511,8 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) goto dump; } /* parent */ - xchdir(*argv++); + archive_handle->cpio__prefix = *argv++; + xchdir(archive_handle->cpio__prefix); close(pp.wr); xmove_fd(pp.rd, STDIN_FILENO); //opt &= ~OPT_PASSTHROUGH; @@ -557,6 +558,15 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) archive_handle->action_header = header_list; } } + if (archive_handle->cpio__prefix && (opt & OPT_VERBOSE)) { + if (archive_handle->action_header == header_list) + archive_handle->action_header = header_list; /* already set? */ + else + archive_handle->action_header = header_verbose_list; + } else if (archive_handle->cpio__prefix) { + archive_handle->action_header = header_list; + } + if (opt & OPT_CREATE_LEADING_DIR) { archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS; } diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c index 6bd897392..8106ccb4d 100644 --- a/archival/libarchive/get_header_ar.c +++ b/archival/libarchive/get_header_ar.c @@ -124,7 +124,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) typed->name[strcspn(typed->name, " /")] = '\0'; if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { - archive_handle->action_header(typed); + archive_handle->action_header(archive_handle); #if ENABLE_DPKG || ENABLE_DPKG_DEB if (archive_handle->dpkg__sub_archive) { struct archive_handle_t *sa = archive_handle->dpkg__sub_archive; diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 9ad0557c2..63a0b6d8a 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c @@ -125,7 +125,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) //cpio: etc/hosts not created: newer or same age file exists //etc/hosts <-- should NOT show it //2 blocks <-- should say "0 blocks" - archive_handle->action_header(file_header); + archive_handle->action_header(archive_handle); } else { data_skip(archive_handle); } diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 606d8067f..470a962b1 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -469,7 +469,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) cp = last_char_is(file_header->name, '/'); if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { - archive_handle->action_header(/*archive_handle->*/ file_header); + archive_handle->action_header(archive_handle); /* Note that we kill the '/' only after action_header() */ /* (like GNU tar 1.15.1: verbose mode outputs "dir/dir/") */ if (cp) diff --git a/archival/libarchive/header_list.c b/archival/libarchive/header_list.c index 9490b3635..8eb64f65c 100644 --- a/archival/libarchive/header_list.c +++ b/archival/libarchive/header_list.c @@ -5,8 +5,11 @@ #include "libbb.h" #include "bb_archive.h" -void FAST_FUNC header_list(const file_header_t *file_header) +void FAST_FUNC header_list(archive_handle_t *archive_handle) { -//TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */ - puts(printable_string(file_header->name)); +#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM + if (archive_handle->cpio__prefix) + printf("%s/", archive_handle->cpio__prefix); +#endif + puts(printable_string(archive_handle->file_header->name)); } diff --git a/archival/libarchive/header_skip.c b/archival/libarchive/header_skip.c index f5987bfe2..e7691534e 100644 --- a/archival/libarchive/header_skip.c +++ b/archival/libarchive/header_skip.c @@ -5,6 +5,6 @@ #include "libbb.h" #include "bb_archive.h" -void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM) +void FAST_FUNC header_skip(archive_handle_t *archive_handle UNUSED_PARAM) { } diff --git a/archival/libarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c index e7a09430d..63acd0f1f 100644 --- a/archival/libarchive/header_verbose_list.c +++ b/archival/libarchive/header_verbose_list.c @@ -5,8 +5,9 @@ #include "libbb.h" #include "bb_archive.h" -void FAST_FUNC header_verbose_list(const file_header_t *file_header) +void FAST_FUNC header_verbose_list(archive_handle_t *archive_handle) { + const file_header_t *file_header = archive_handle->file_header; struct tm tm_time; struct tm *ptm = &tm_time; //localtime(&file_header->mtime); char modestr[12]; @@ -29,7 +30,7 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) /*sprintf(gid, "%u", (unsigned)file_header->gid);*/ group = utoa(file_header->gid); } - printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", + printf("%s %s/%s %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ", bb_mode_string(modestr, file_header->mode), user, group, @@ -39,14 +40,13 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) ptm->tm_mday, ptm->tm_hour, ptm->tm_min, - ptm->tm_sec, - file_header->name); + ptm->tm_sec); #else /* !FEATURE_TAR_UNAME_GNAME */ localtime_r(&file_header->mtime, ptm); - printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u %s", + printf("%s %u/%u %9"OFF_FMT"u %4u-%02u-%02u %02u:%02u:%02u ", bb_mode_string(modestr, file_header->mode), (unsigned)file_header->uid, (unsigned)file_header->gid, @@ -56,11 +56,16 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header) ptm->tm_mday, ptm->tm_hour, ptm->tm_min, - ptm->tm_sec, - printable_string(file_header->name)); + ptm->tm_sec); #endif /* FEATURE_TAR_UNAME_GNAME */ +#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM + if (archive_handle->cpio__prefix) + printf("%s/", archive_handle->cpio__prefix); +#endif + printf("%s", printable_string(file_header->name)); + /* NB: GNU tar shows "->" for symlinks and "link to" for hardlinks */ if (file_header->link_target) { printf(" -> %s", printable_string(file_header->link_target)); diff --git a/include/bb_archive.h b/include/bb_archive.h index 1dc77f31d..d6a7162d6 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -68,7 +68,7 @@ typedef struct archive_handle_t { llist_t *link_placeholders; /* Process the header component, e.g. tar -t */ - void FAST_FUNC (*action_header)(const file_header_t *); + void FAST_FUNC (*action_header)(struct archive_handle_t *); /* Process the data component, e.g. extract to filesystem */ void FAST_FUNC (*action_data)(struct archive_handle_t *); @@ -101,6 +101,7 @@ typedef struct archive_handle_t { #endif #if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM uoff_t cpio__blocks; + char *cpio__prefix; struct bb_uidgid_t cpio__owner; struct hardlinks_t *cpio__hardlinks_to_create; struct hardlinks_t *cpio__created_hardlinks; @@ -187,9 +188,9 @@ void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC; void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC; void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC; -void header_skip(const file_header_t *file_header) FAST_FUNC; -void header_list(const file_header_t *file_header) FAST_FUNC; -void header_verbose_list(const file_header_t *file_header) FAST_FUNC; +void header_skip(archive_handle_t *archive_handle) FAST_FUNC; +void header_list(archive_handle_t *archive_handle) FAST_FUNC; +void header_verbose_list(archive_handle_t *archive_handle) FAST_FUNC; char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC; char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC; -- 2.53.0