Skip to content

Commit

Permalink
busybox: make tar cJf work for real
Browse files Browse the repository at this point in the history
the previous patch only added the flag, but its usage leads to
uncompressed tarballs, which disguise themselves as compressed.
  • Loading branch information
rofl0r committed Sep 20, 2013
1 parent bab02b5 commit a3d89d2
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 0 deletions.
106 changes: 106 additions & 0 deletions KEEP/busybox-tar-norecurse.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
commit 5a94115b99030c87baff2195c2d2a8165e8373ad
Author: Natanael Copa <natanael.copa@gmail.com>
Date: Tue Apr 24 17:06:19 2012 +0200

tar: implement --no-recursion

function old new delta
tar_longopts 259 274 +15
.rodata 5757 5772 +15
tar_main 1038 1052 +14
writeTarFile 362 353 -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 44/-9) Total: 35 bytes
text data bss dec hex filename
81457 1706 8344 91507 16573 busybox_old
81477 1706 8344 91527 16587 busybox_unstripped

Signed-off-by: Natanael Copa <natanael.copa@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>

diff --git a/archival/tar.c b/archival/tar.c
index cf972c2..a64d651 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -60,8 +60,8 @@

#if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2
/* Do not pass gzip flag to writeTarFile() */
-#define writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude, gzip) \
- writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude)
+#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \
+ writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude)
#endif


@@ -598,7 +598,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)

/* gcc 4.2.1 inlines it, making code bigger */
static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
- int dereferenceFlag, const llist_t *include,
+ int recurseFlags, const llist_t *include,
const llist_t *exclude, int gzip)
{
int errorFlag = FALSE;
@@ -621,8 +621,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,

/* Read the directory/files and iterate over them one at a time */
while (include) {
- if (!recursive_action(include->data, ACTION_RECURSE |
- (dereferenceFlag ? ACTION_FOLLOWLINKS : 0),
+ if (!recursive_action(include->data, recurseFlags,
writeFileToTarball, writeFileToTarball, &tbInfo, 0)
) {
errorFlag = TRUE;
@@ -662,7 +661,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
}
#else
int writeTarFile(int tar_fd, int verboseFlag,
- int dereferenceFlag, const llist_t *include,
+ int recurseFlags, const llist_t *include,
const llist_t *exclude, int gzip);
#endif /* FEATURE_TAR_CREATE */

@@ -749,6 +748,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
// o no-same-owner
// p same-permissions
// k keep-old
+// no-recursion
// numeric-owner
// no-same-permissions
// overwrite
@@ -768,6 +768,7 @@ enum {
IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit
IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
#if ENABLE_FEATURE_TAR_LONG_OPTIONS
+ OPTBIT_NORECURSION,
IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,)
OPTBIT_NUMERIC_OWNER,
OPTBIT_NOPRESERVE_PERM,
@@ -791,6 +792,7 @@ enum {
OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
+ OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion
OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
@@ -835,6 +837,7 @@ static const char tar_longopts[] ALIGN1 =
# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME
"touch\0" No_argument "m"
# endif
+ "no-recursion\0" No_argument "\xfa"
# if ENABLE_FEATURE_TAR_TO_COMMAND
"to-command\0" Required_argument "\xfb"
# endif
@@ -1050,7 +1053,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
zipMode = 2;
#endif
/* NB: writeTarFile() closes tar_handle->src_fd */
- return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE,
+ return writeTarFile(tar_handle->src_fd, verboseFlag,
+ (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0)
+ | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE),
tar_handle->accept,
tar_handle->reject, zipMode);
}
128 changes: 128 additions & 0 deletions KEEP/busybox-tar-xz2.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
diff --git a/archival/tar.c b/archival/tar.c
index 3cd033b..7e5cf2d 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -58,13 +58,6 @@
#define block_buf bb_common_bufsiz1


-#if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2
-/* Do not pass gzip flag to writeTarFile() */
-#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \
- writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude)
-#endif
-
-
#if ENABLE_FEATURE_TAR_CREATE

/*
@@ -519,21 +512,29 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb
return TRUE;
}

-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
-# if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2)
-# define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd)
-# endif
+enum compressor_type {
+ ct_none = 0,
+ ct_gzip = 1,
+ ct_bzip2 = 2,
+ ct_xz = 3,
+};
+
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
/* Don't inline: vfork scares gcc and pessimizes code */
-static void NOINLINE vfork_compressor(int tar_fd, int gzip)
+static void NOINLINE vfork_compressor(int tar_fd, enum compressor_type ct)
{
pid_t gzipPid;
-# if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2
- const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2";
-# elif ENABLE_FEATURE_SEAMLESS_GZ
- const char *zip_exec = "gzip";
-# else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */
- const char *zip_exec = "bzip2";
-# endif
+ static const char compressor[][6] = {
+ [ct_gzip - 1] = "gzip",
+#if ENABLE_FEATURE_SEAMLESS_BZ2
+ [ct_bzip2 - 1] = "bzip2",
+#endif
+#if ENABLE_FEATURE_SEAMLESS_XZ
+ [ct_xz - 1] = "xz",
+#endif
+ };
+ const char *zip_exec = compressor[ct-1];
+
// On Linux, vfork never unpauses parent early, although standard
// allows for that. Do we want to waste bytes checking for it?
# define WAIT_FOR_CHILD 0
@@ -593,13 +594,13 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip)
bb_perror_msg_and_die("can't execute '%s'", zip_exec);
}
}
-#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */
+#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ */


/* gcc 4.2.1 inlines it, making code bigger */
static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
int recurseFlags, const llist_t *include,
- const llist_t *exclude, int gzip)
+ const llist_t *exclude, enum compressor_type ct)
{
int errorFlag = FALSE;
struct TarBallInfo tbInfo;
@@ -612,9 +613,9 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
* can avoid including the tarball into itself.... */
xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file");

-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- if (gzip)
- vfork_compressor(tbInfo.tarFd, gzip);
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
+ if (ct != ct_none)
+ vfork_compressor(tbInfo.tarFd, ct);
#endif

tbInfo.excludeList = exclude;
@@ -647,8 +648,8 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
if (errorFlag)
bb_error_msg("error exit delayed from previous errors");

-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- if (gzip) {
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
+ if (ct != ct_none) {
int status;
if (safe_waitpid(-1, &status, 0) == -1)
bb_perror_msg("waitpid");
@@ -662,7 +663,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag,
#else
int writeTarFile(int tar_fd, int verboseFlag,
int recurseFlags, const llist_t *include,
- const llist_t *exclude, int gzip);
+ const llist_t *exclude, enum compressor_type ct);
#endif /* FEATURE_TAR_CREATE */

#if ENABLE_FEATURE_TAR_FROM
@@ -1053,12 +1054,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv)

/* Create an archive */
if (opt & OPT_CREATE) {
-#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2
- int zipMode = 0;
+ enum compressor_type zipMode = ct_none;
+#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 || ENABLE_FEATURE_SEAMLESS_XZ
if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP))
- zipMode = 1;
+ zipMode = ct_gzip;
if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2))
- zipMode = 2;
+ zipMode = ct_bzip2;
+ if (ENABLE_FEATURE_SEAMLESS_XZ && (opt & OPT_XZ))
+ zipMode = ct_xz;
#endif
/* NB: writeTarFile() closes tar_handle->src_fd */
return writeTarFile(tar_handle->src_fd, verboseFlag,
2 changes: 2 additions & 0 deletions pkg/busybox
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ dopatch "$K"/busybox-man.patch || exit 1
dopatch "$K"/busybox-sed.patch || exit 1
dopatch "$K"/busybox-awk-emptyfun.patch || exit 1
dopatch "$K"/busybox-awk-int-overflow.patch || exit 1
dopatch "$K"/busybox-tar-norecurse.patch || exit 1
dopatch "$K"/busybox-tar-xz.patch || exit 1
dopatch "$K"/busybox-tar-xz2.patch || exit 1


#__inline seems to get activated when -std=gnu99 is used, causing havoc
Expand Down

0 comments on commit a3d89d2

Please sign in to comment.