ifupdown: save some 100+ bytes of code in addstr()
[oweals/busybox.git] / archival / tar.c
index 91232bcf38889cc01d025fc824ef9f2a51d57405..db812e0f4ff14f5d7ac3ee3ff193ed4da162400b 100644 (file)
  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  */
 
-#include <fcntl.h>
-#include <getopt.h>
-#include <search.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fnmatch.h>
-#include <string.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <sys/sysmacros.h>     /* major() and minor() */
-#include "unarchive.h"
 #include "busybox.h"
+#include "unarchive.h"
+#include <fnmatch.h>
+#include <getopt.h>
 
 #ifdef CONFIG_FEATURE_TAR_CREATE
 
@@ -192,26 +181,6 @@ static int putOctal(char *cp, int len, long value)
        return TRUE;
 }
 
-/* Pad file to TAR_BLOCK_SIZE with zeros */
-static void block_write_zeroes(int fd, size_t size)
-{
-       char zerobuf[TAR_BLOCK_SIZE];
-       memset(zerobuf, 0, size);
-       /* No point in trying to continue on error */
-       if (full_write(fd, zerobuf, size) < 0)
-               bb_perror_msg_and_die("write");
-}
-
-static size_t pad_block_write(int fd, size_t size)
-{
-       size_t rem = (TAR_BLOCK_SIZE - size) & (TAR_BLOCK_SIZE-1);
-       if (rem) {
-               block_write_zeroes(fd, rem);
-               size += rem;
-       }
-       return size;
-}
-
 /* Write out a tar header for the specified file/directory/whatever */
 static int writeTarHeader(struct TarBallInfo *tbInfo,
                const char *header_name, const char *fileName, struct stat *statbuf)
@@ -221,7 +190,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
        const unsigned char *cp = (const unsigned char *) &header;
        ssize_t size = sizeof(struct TarHeader);
 
-       memset(&header, 0, size);
+       bzero(&header, size);
 
        safe_strncpy(header.name, header_name, sizeof(header.name));
 
@@ -288,14 +257,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
        putOctal(header.chksum, 7, chksum);
 
        /* Now write the header out to disk */
-       size = full_write(tbInfo->tarFd, (char *) &header,
-                                       sizeof(struct TarHeader));
-       if (size < 0) {
-               bb_error_msg(bb_msg_io_error, fileName);
-               return FALSE;
-       }
-       /* Pad the header up to the tar block size */
-       size = pad_block_write(tbInfo->tarFd, size);
+       xwrite(tbInfo->tarFd, &header, sizeof(struct TarHeader));
 
        /* Now do the verbose thing (or not) */
 
@@ -339,7 +301,7 @@ static int exclude_file(const llist_t *excluded_files, const char *file)
 # endif
 
 static int writeFileToTarball(const char *fileName, struct stat *statbuf,
-                                                         void *userData)
+                       void *userData, int depth)
 {
        struct TarBallInfo *tbInfo = (struct TarBallInfo *) userData;
        const char *header_name;
@@ -414,14 +376,16 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf,
 
        /* If it was a regular file, write out the body */
        if (inputFileFd >= 0) {
-               ssize_t readSize = 0;
+               off_t readSize = 0;
 
                /* write the file to the archive */
                readSize = bb_copyfd_eof(inputFileFd, tbInfo->tarFd);
                close(inputFileFd);
 
                /* Pad the file up to the tar block size */
-               readSize = pad_block_write(tbInfo->tarFd, readSize);
+               readSize = (TAR_BLOCK_SIZE - readSize) & (TAR_BLOCK_SIZE-1);
+               bzero(bb_common_bufsiz1, readSize);
+               xwrite(tbInfo->tarFd, bb_common_bufsiz1, readSize);
        }
 
        return TRUE;
@@ -493,7 +457,7 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
 
                                if (n == 0 && vfork_exec_errno != 0) {
                                        errno = vfork_exec_errno;
-                                       bb_perror_msg_and_die("Could not exec %s", zip_exec);
+                                       bb_perror_msg_and_die("cannot exec %s", zip_exec);
                                } else if ((n < 0) && (errno == EAGAIN || errno == EINTR))
                                        continue;       /* try it again */
                                break;
@@ -509,15 +473,15 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
        /* Read the directory/files and iterate over them one at a time */
        while (include) {
                if (!recursive_action(include->data, TRUE, dereferenceFlag,
-                               FALSE, writeFileToTarball, writeFileToTarball, &tbInfo))
+                               FALSE, writeFileToTarball, writeFileToTarball, &tbInfo, 0))
                {
                        errorFlag = TRUE;
                }
                include = include->link;
        }
        /* Write two empty blocks to the end of the archive */
-       block_write_zeroes(tbInfo.tarFd, TAR_BLOCK_SIZE);
-       block_write_zeroes(tbInfo.tarFd, TAR_BLOCK_SIZE);
+       bzero(bb_common_bufsiz1, 2*TAR_BLOCK_SIZE);
+       xwrite(tbInfo.tarFd, bb_common_bufsiz1, 2*TAR_BLOCK_SIZE);
 
        /* To be pedantically correct, we would check if the tarball
         * is smaller than 20 tar blocks, and pad it if it was smaller,
@@ -532,10 +496,10 @@ static int writeTarFile(const int tar_fd, const int verboseFlag,
                freeHardLinkInfo(&tbInfo.hlInfoHead);
 
        if (errorFlag)
-               bb_error_msg("Error exit delayed from previous errors");
+               bb_error_msg("error exit delayed from previous errors");
 
        if (gzipPid && waitpid(gzipPid, NULL, 0)==-1)
-               bb_error_msg("Couldnt wait");
+               bb_error_msg("cannot wait");
 
        return !errorFlag;
 }
@@ -559,7 +523,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
                tmp = cur;
                cur = cur->link;
                free(tmp);
-               while ((line = bb_get_chomped_line_from_file(src_stream)) != NULL) {
+               while ((line = xmalloc_getline(src_stream)) != NULL) {
                        char *filename_ptr = last_char_is(line, '/');
                        if (filename_ptr > line)
                                *filename_ptr = '\0';
@@ -576,8 +540,8 @@ static llist_t *append_file_list_to_list(llist_t *list)
 #ifdef CONFIG_FEATURE_TAR_COMPRESS
 static char get_header_tar_Z(archive_handle_t *archive_handle)
 {
-       /* Cant lseek over pipe's */
-       archive_handle->seek = seek_by_char;
+       /* Can't lseek over pipes */
+       archive_handle->seek = seek_by_read;
 
        /* do the decompression, and cleanup */
        if (xread_char(archive_handle->src_fd) != 0x1f ||
@@ -592,7 +556,7 @@ static char get_header_tar_Z(archive_handle_t *archive_handle)
                /* nothing */;
 
        /* Can only do one file at a time */
-       return(EXIT_FAILURE);
+       return EXIT_FAILURE;
 }
 #else
 #define get_header_tar_Z       0
@@ -724,7 +688,7 @@ int tar_main(int argc, char **argv)
        archive_handle_t *tar_handle;
        char *base_dir = NULL;
        const char *tar_filename = "-";
-       unsigned long opt;
+       unsigned opt;
        llist_t *excludes = NULL;
 
        /* Initialise default values */
@@ -732,12 +696,12 @@ int tar_main(int argc, char **argv)
        tar_handle->flags = ARCHIVE_CREATE_LEADING_DIRS | ARCHIVE_PRESERVE_DATE | ARCHIVE_EXTRACT_UNCONDITIONAL;
 
        /* Prepend '-' to the first argument if required */
-       bb_opt_complementally = ENABLE_FEATURE_TAR_CREATE ?
+       opt_complementary = ENABLE_FEATURE_TAR_CREATE ?
                "--:X::T::\n::c:t:x:?:c--tx:t--cx:x--ct" :
                "--:X::T::\n::t:x:?:t--x:x--t";
        if (ENABLE_FEATURE_TAR_LONG_OPTIONS)
-               bb_applet_long_options = tar_long_options;
-       opt = bb_getopt_ulflags(argc, argv, tar_options,
+               applet_long_options = tar_long_options;
+       opt = getopt32(argc, argv, tar_options,
                                &base_dir,      /* Change to dir <optarg> */
                                &tar_filename /* archive filename */
 #ifdef CONFIG_FEATURE_TAR_FROM
@@ -751,7 +715,7 @@ int tar_main(int argc, char **argv)
                if ((tar_handle->action_header == header_list) ||
                        (tar_handle->action_header == header_verbose_list))
                {
-                               tar_handle->action_header = header_verbose_list;
+                       tar_handle->action_header = header_verbose_list;
                } else tar_handle->action_header = header_list;
        }
        if((opt & CTX_EXTRACT) && tar_handle->action_data != data_extract_to_stdout)
@@ -841,7 +805,7 @@ int tar_main(int argc, char **argv)
 
                if ((tar_filename[0] == '-') && (tar_filename[1] == '\0')) {
                        tar_handle->src_fd = fileno(tar_stream);
-                       tar_handle->seek = seek_by_char;
+                       tar_handle->seek = seek_by_read;
                } else {
                        tar_handle->src_fd = xopen3(tar_filename, flags, 0666);
                }