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);
 	}
