tar: implement --no-recursion
authorNatanael Copa <natanael.copa@gmail.com>
Tue, 24 Apr 2012 15:06:19 +0000 (17:06 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 18 May 2012 14:34:30 +0000 (16:34 +0200)
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>
archival/tar.c

index cf972c24c6a3c38dae08fd614a9782718631fdf5..a64d6510fb133c74d8c2d1501ff83320219eeceb 100644 (file)
@@ -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);
        }