0009-pax-Fix-GNU-long-name-handling-with-short-read.patch (4518B)
- From f88fb1145beac6cce7012b506579d23e0b9826a2 Mon Sep 17 00:00:00 2001
- From: Michael Forney <mforney@mforney.org>
- Date: Sat, 3 Dec 2016 20:49:24 -0800
- Subject: [PATCH] pax: Fix GNU long name handling with short read
- ---
- bin/pax/ar_subs.c | 66 +++++++++++++++++++++++++++++++++------------
- bin/pax/buf_subs.c | 4 +--
- bin/pax/file_subs.c | 25 +----------------
- 3 files changed, 51 insertions(+), 44 deletions(-)
- diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
- index f018108af59..4c49efa1362 100644
- --- a/bin/pax/ar_subs.c
- +++ b/bin/pax/ar_subs.c
- @@ -37,6 +37,7 @@
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- +#include <err.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <signal.h>
- @@ -51,6 +52,7 @@
- static void wr_archive(ARCHD *, int is_app);
- static int get_arc(void);
- static int next_head(ARCHD *);
- +static int rd_gnu_string(ARCHD *);
- extern sigset_t s_mask;
- /*
- @@ -93,16 +95,8 @@ list(void)
- * step through the archive until the format says it is done
- */
- while (next_head(arcn) == 0) {
- - if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
- - /*
- - * we need to read, to get the real filename
- - */
- - off_t cnt;
- - if (!rd_wrfile(arcn, arcn->type == PAX_GLF
- - ? -1 : -2, &cnt))
- - (void)rd_skip(cnt + arcn->pad);
- + if (rd_gnu_string(arcn))
- continue;
- - }
- /*
- * check for pattern, and user specified options match.
- @@ -245,15 +239,8 @@ extract(void)
- * says it is done
- */
- while (next_head(arcn) == 0) {
- - if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
- - /*
- - * we need to read, to get the real filename
- - */
- - if (!rd_wrfile(arcn, arcn->type == PAX_GLF
- - ? -1 : -2, &cnt))
- - (void)rd_skip(cnt + arcn->pad);
- + if (rd_gnu_string(arcn))
- continue;
- - }
- /*
- * check for pattern, and user specified options match. When
- @@ -1282,3 +1269,48 @@ get_arc(void)
- paxwarn(1, "Sorry, unable to determine archive format.");
- return(-1);
- }
- +
- +/*
- + * rd_gnu_string()
- + * Read the file contents into an allocated string if it is a GNU tar
- + * long link/file.
- + * Return:
- + * 1 if gnu string read, 0 otherwise
- + */
- +
- +static int
- +rd_gnu_string(ARCHD *arcn)
- +{
- + char **strp;
- +
- + switch (arcn->type) {
- + case PAX_GLF:
- + strp = &gnu_name_string;
- + break;
- + case PAX_GLL:
- + strp = &gnu_link_string;
- + break;
- + default:
- + strp = NULL;
- + break;
- + }
- + if (!strp)
- + return 0;
- + /*
- + * we need to read, to get the real filename
- + */
- + if (*strp)
- + err(1, "WARNING! Major Internal Error! GNU hack Failing!");
- + *strp = malloc(arcn->sb.st_size + 1);
- + if (*strp == NULL) {
- + paxwarn(1, "Out of memory");
- + (void)rd_skip(arcn->skip + arcn->pad);
- + } else if (rd_wrbuf(*strp, arcn->sb.st_size) < arcn->sb.st_size) {
- + free(*strp);
- + *strp = NULL;
- + } else {
- + (*strp)[arcn->sb.st_size] = '\0';
- + (void)rd_skip(arcn->pad);
- + }
- + return 1;
- +}
- diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
- index 25dfed5b69b..e3e22a09cc6 100644
- --- a/bin/pax/buf_subs.c
- +++ b/bin/pax/buf_subs.c
- @@ -676,9 +676,7 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left)
- * pass the blocksize of the file being written to the write routine,
- * if the size is zero, use the default MINFBSZ
- */
- - if (ofd < 0)
- - sz = PAXPATHLEN + 1; /* GNU tar long link/file */
- - else if (fstat(ofd, &sb) == 0) {
- + if (fstat(ofd, &sb) == 0) {
- if (sb.st_blksize > 0)
- sz = (int)sb.st_blksize;
- } else
- diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
- index 9f482480a3b..ae0caf29f6c 100644
- --- a/bin/pax/file_subs.c
- +++ b/bin/pax/file_subs.c
- @@ -924,7 +924,6 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
- char *end;
- int wcnt;
- char *st = str;
- - char **strp;
- /*
- * while we have data to process
- @@ -983,29 +982,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
- /*
- * have non-zero data in this file system block, have to write
- */
- - switch (fd) {
- - case -1:
- - strp = &gnu_name_string;
- - break;
- - case -2:
- - strp = &gnu_link_string;
- - break;
- - default:
- - strp = NULL;
- - break;
- - }
- - if (strp) {
- - if (*strp)
- - err(1, "WARNING! Major Internal Error! GNU hack Failing!");
- - *strp = malloc(wcnt + 1);
- - if (*strp == NULL) {
- - paxwarn(1, "Out of memory");
- - return(-1);
- - }
- - memcpy(*strp, st, wcnt);
- - (*strp)[wcnt] = '\0';
- - break;
- - } else if (write(fd, st, wcnt) != wcnt) {
- + if (write(fd, st, wcnt) != wcnt) {
- syswarn(1, errno, "Failed write to file %s", name);
- return(-1);
- }
- --
- 2.49.0