]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
tar: use option_flags bitfield for boolean options
authorMartin Matuska <martin@matuska.org>
Wed, 22 Feb 2017 20:39:48 +0000 (21:39 +0100)
committerMartin Matuska <martin@matuska.org>
Wed, 22 Feb 2017 23:28:20 +0000 (00:28 +0100)
tar/bsdtar.c
tar/bsdtar.h
tar/read.c
tar/util.c
tar/write.c

index 93bf60a94da84e4aecad2ce6a033aad042ae5d5b..8c7ffe806768875de9eb7d77f710e576e16ba29b 100644 (file)
@@ -137,7 +137,6 @@ main(int argc, char **argv)
        char                     compression, compression2;
        const char              *compression_name, *compression2_name;
        const char              *compress_program;
-       char                     option_a, option_o;
        char                     possible_help_request;
        char                     buff[16];
 
@@ -150,7 +149,7 @@ main(int argc, char **argv)
        bsdtar->fd = -1; /* Mark as "unused" */
        bsdtar->gid = -1;
        bsdtar->uid = -1;
-       option_a = option_o = 0;
+       bsdtar->flags = 0;
        compression = compression2 = '\0';
        compression_name = compression2_name = NULL;
        compress_program = NULL;
@@ -252,7 +251,7 @@ main(int argc, char **argv)
        while ((opt = bsdtar_getopt(bsdtar)) != -1) {
                switch (opt) {
                case 'a': /* GNU tar */
-                       option_a = 1; /* Record it and resolve it later. */
+                       bsdtar->flags |= OPTFLAG_AUTO_COMPRESS;
                        break;
                case 'B': /* GNU tar */
                        /* libarchive doesn't need this; just ignore it. */
@@ -285,10 +284,10 @@ main(int argc, char **argv)
                        set_mode(bsdtar, opt);
                        break;
                case OPTION_CHECK_LINKS: /* GNU tar */
-                       bsdtar->option_warn_links = 1;
+                       bsdtar->flags |= OPTFLAG_WARN_LINKS;
                        break;
                case OPTION_CHROOT: /* NetBSD */
-                       bsdtar->option_chroot = 1;
+                       bsdtar->flags |= OPTFLAG_CHROOT;
                        break;
                case OPTION_CLEAR_NOCHANGE_FFLAGS:
                        bsdtar->extract_flags |=
@@ -344,7 +343,7 @@ main(int argc, char **argv)
                            ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED;
                        break;
                case OPTION_IGNORE_ZEROS:
-                       bsdtar->option_ignore_zeros = 1;
+                       bsdtar->flags |= OPTFLAG_IGNORE_ZEROS;
                        break;
                case 'I': /* GNU tar */
                        /*
@@ -398,7 +397,7 @@ main(int argc, char **argv)
                        break;
                case 'l': /* SUSv2 and GNU tar beginning with 1.16 */
                        /* GNU tar 1.13  used -l for --one-file-system */
-                       bsdtar->option_warn_links = 1;
+                       bsdtar->flags |= OPTFLAG_WARN_LINKS;
                        break;
                case OPTION_LRZIP:
                case OPTION_LZ4:
@@ -422,7 +421,7 @@ main(int argc, char **argv)
                        bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME;
                        break;
                case 'n': /* GNU tar */
-                       bsdtar->option_no_subdirs = 1;
+                       bsdtar->flags |= OPTFLAG_NO_SUBDIRS;
                        break;
                /*
                 * Selecting files by time:
@@ -479,20 +478,21 @@ main(int argc, char **argv)
                case OPTION_NO_XATTR: /* Issue #131 */
                        bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR;
                        bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_XATTR;
+                       bsdtar->flags |= OPTFLAG_NO_XATTR;
                        break;
                case OPTION_NULL: /* GNU tar */
-                       bsdtar->option_null++;
+                       bsdtar->flags |= OPTFLAG_NULL;
                        break;
                case OPTION_NUMERIC_OWNER: /* GNU tar */
                        bsdtar->uname = "";
                        bsdtar->gname = "";
-                       bsdtar->option_numeric_owner++;
+                       bsdtar->flags |= OPTFLAG_NUMERIC_OWNER;
                        break;
                case 'O': /* GNU tar */
-                       bsdtar->option_stdout = 1;
+                       bsdtar->flags |= OPTFLAG_STDOUT;
                        break;
                case 'o': /* SUSv2 and GNU conflict here, but not fatally */
-                       option_o = 1; /* Record it and resolve it later. */
+                       bsdtar->flags |= OPTFLAG_O;
                        break;
                /*
                 * Selecting files by time:
@@ -548,7 +548,7 @@ main(int argc, char **argv)
 #endif
                case 'P': /* GNU tar */
                        bsdtar->extract_flags &= ~SECURITY;
-                       bsdtar->option_absolute_paths = 1;
+                       bsdtar->flags |= OPTFLAG_ABSOLUTE_PATHS;
                        break;
                case 'p': /* GNU tar, star */
                        bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM;
@@ -564,7 +564,7 @@ main(int argc, char **argv)
                        cset_set_format(bsdtar->cset, "pax");
                        break;
                case 'q': /* FreeBSD GNU tar --fast-read, NetBSD -q */
-                       bsdtar->option_fast_read = 1;
+                       bsdtar->flags |= OPTFLAG_FAST_READ;
                        break;
                case 'r': /* SUSv2 */
                        set_mode(bsdtar, opt);
@@ -601,11 +601,11 @@ main(int argc, char **argv)
                        bsdtar->verbose++;
                        break;
                case OPTION_TOTALS: /* GNU tar */
-                       bsdtar->option_totals++;
+                       bsdtar->flags |= OPTFLAG_TOTALS;
                        break;
                case 'U': /* GNU tar */
                        bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK;
-                       bsdtar->option_unlink_first = 1;
+                       bsdtar->flags |= OPTFLAG_UNLINK_FIRST;
                        break;
                case 'u': /* SUSv2 */
                        set_mode(bsdtar, opt);
@@ -643,7 +643,7 @@ main(int argc, char **argv)
                        break;
 #endif
                case 'w': /* SUSv2 */
-                       bsdtar->option_interactive = 1;
+                       bsdtar->flags |= OPTFLAG_INTERACTIVE;
                        break;
                case 'X': /* GNU tar */
                        if (archive_match_exclude_pattern_from_file(
@@ -703,11 +703,11 @@ main(int argc, char **argv)
                    "Must specify one of -c, -r, -t, -u, -x");
 
        /* Check boolean options only permitted in certain modes. */
-       if (option_a)
+       if (bsdtar->flags & OPTFLAG_AUTO_COMPRESS)
                only_mode(bsdtar, "-a", "c");
        if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
                only_mode(bsdtar, "--one-file-system", "cru");
-       if (bsdtar->option_fast_read)
+       if (bsdtar->flags & OPTFLAG_FAST_READ)
                only_mode(bsdtar, "--fast-read", "xt");
        if (bsdtar->extract_flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED)
                only_mode(bsdtar, "--hfsCompression", "x");
@@ -715,9 +715,9 @@ main(int argc, char **argv)
                only_mode(bsdtar, "--nopreserveHFSCompression", "x");
        if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP)
                only_mode(bsdtar, "--nodump", "cru");
-       if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_XATTR)
+       if (bsdtar->flags & OPTFLAG_NO_XATTR)
                only_mode(bsdtar, "--no-xattr", "crux");
-       if (option_o > 0) {
+       if (bsdtar->flags & OPTFLAG_O) {
                switch (bsdtar->mode) {
                case 'c':
                        /*
@@ -730,7 +730,7 @@ main(int argc, char **argv)
                        break;
                case 'x':
                        /* POSIX-compatible behavior. */
-                       bsdtar->option_no_owner = 1;
+                       bsdtar->flags |= OPTFLAG_NO_OWNER;
                        bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
                        break;
                default:
@@ -738,16 +738,17 @@ main(int argc, char **argv)
                        break;
                }
        }
-       if (bsdtar->option_no_subdirs)
+       if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
                only_mode(bsdtar, "-n", "cru");
-       if (bsdtar->option_stdout)
+       if (bsdtar->flags & OPTFLAG_STDOUT)
                only_mode(bsdtar, "-O", "xt");
-       if (bsdtar->option_unlink_first)
+       if (bsdtar->flags & OPTFLAG_UNLINK_FIRST)
                only_mode(bsdtar, "-U", "x");
-       if (bsdtar->option_warn_links)
+       if (bsdtar->flags & OPTFLAG_WARN_LINKS)
                only_mode(bsdtar, "--check-links", "cr");
 
-       if (option_a && cset_auto_compress(bsdtar->cset, bsdtar->filename)) {
+       if ((bsdtar->flags & OPTFLAG_AUTO_COMPRESS) &&
+           cset_auto_compress(bsdtar->cset, bsdtar->filename)) {
                /* Ignore specified compressions if auto-compress works. */
                compression = '\0';
                compression2 = '\0';
index 4b84ba18ab467046b74f20d0d6a3138fdee18a21..89cf2f9a966678460f18ad484e84c40292efbf3e 100644 (file)
@@ -50,6 +50,7 @@ struct bsdtar {
        int               bytes_per_block; /* -b block_size */
        int               bytes_in_last_block; /* See -b handling. */
        int               verbose;   /* -v */
+       int               flags; /* Bitfield of boolean options */
        int               extract_flags; /* Flags for extract operation */
        int               readdisk_flags; /* Flags for read disk operation */
        int               strip_components; /* Remove this many leading dirs */
@@ -60,20 +61,7 @@ struct bsdtar {
        const char       *passphrase; /* --passphrase */
        char              mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */
        char              symlink_mode; /* H or L, per BSD conventions */
-       char              option_absolute_paths; /* -P */
-       char              option_chroot; /* --chroot */
-       char              option_fast_read; /* --fast-read */
        const char       *option_options; /* --options */
-       char              option_ignore_zeros; /* --ignore-zeros */
-       char              option_interactive; /* -w */
-       char              option_no_owner; /* -o */
-       char              option_no_subdirs; /* -n */
-       char              option_numeric_owner; /* --numeric-owner */
-       char              option_null; /* --null */
-       char              option_stdout; /* -O */
-       char              option_totals; /* --totals */
-       char              option_unlink_first; /* -U */
-       char              option_warn_links; /* --check-links */
        char              day_first; /* show day before month in -tv output */
        struct creation_set *cset;
 
@@ -114,6 +102,24 @@ struct bsdtar {
        char                    *ppbuff;        /* for util.c */
 };
 
+/* Options for flags bitfield */
+#define        OPTFLAG_AUTO_COMPRESS   (0x00000001)    /* -a */
+#define        OPTFLAG_ABSOLUTE_PATHS  (0x00000002)    /* -P */
+#define        OPTFLAG_CHROOT          (0x00000004)    /* --chroot */
+#define        OPTFLAG_FAST_READ       (0x00000008)    /* --fast-read */
+#define        OPTFLAG_IGNORE_ZEROS    (0x00000010)    /* --ignore-zeros */
+#define        OPTFLAG_INTERACTIVE     (0x00000020)    /* -w */
+#define        OPTFLAG_NO_OWNER        (0x00000040)    /* -o */
+#define        OPTFLAG_NO_SUBDIRS      (0x00000080)    /* -n */
+#define        OPTFLAG_NULL            (0x00000100)    /* --null */
+#define        OPTFLAG_NUMERIC_OWNER   (0x00000200)    /* --numeric-owner */
+#define        OPTFLAG_O               (0x00000400)    /* -o */
+#define        OPTFLAG_STDOUT          (0x00000800)    /* -O */
+#define        OPTFLAG_TOTALS          (0x00001000)    /* --totals */
+#define        OPTFLAG_UNLINK_FIRST    (0x00002000)    /* -U */
+#define        OPTFLAG_WARN_LINKS      (0x00004000)    /* --check-links */
+#define        OPTFLAG_NO_XATTR        (0x00008000)    /* --no-xattr */
+
 /* Fake short equivalents for long options that otherwise lack them. */
 enum {
        OPTION_B64ENCODE = 1,
index 3c6cb0c13c39c82b58e5a8bc16e5873d786c2f53..658c810f9c59b0e7e07a73639629b6edfe1410e1 100644 (file)
@@ -105,7 +105,7 @@ tar_mode_x(struct bsdtar *bsdtar)
        writer = archive_write_disk_new();
        if (writer == NULL)
                lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
-       if (!bsdtar->option_numeric_owner)
+       if ((bsdtar->flags & OPTFLAG_NUMERIC_OWNER) == 0)
                archive_write_disk_set_standard_lookup(writer);
        archive_write_disk_set_options(writer, bsdtar->extract_flags);
 
@@ -177,7 +177,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
        if (bsdtar->names_from_file != NULL)
                if (archive_match_include_pattern_from_file(
                    bsdtar->matching, bsdtar->names_from_file,
-                   bsdtar->option_null) != ARCHIVE_OK)
+                   (bsdtar->flags & OPTFLAG_NULL)) != ARCHIVE_OK)
                        lafe_errc(1, 0, "Error inclusion pattern: %s",
                            archive_error_string(bsdtar->matching));
 
@@ -208,7 +208,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
        }
        if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
                lafe_errc(1, 0, "%s", archive_error_string(a));
-       if (bsdtar->option_ignore_zeros)
+       if (bsdtar->flags & OPTFLAG_IGNORE_ZEROS)
                if (archive_read_set_options(a,
                    "read_concatenated_archives") != ARCHIVE_OK)
                        lafe_errc(1, 0, "%s", archive_error_string(a));
@@ -234,7 +234,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
                    &progress_data);
        }
 
-       if (mode == 'x' && bsdtar->option_chroot) {
+       if (mode == 'x' && (bsdtar->flags & OPTFLAG_CHROOT)) {
 #if HAVE_CHROOT
                if (chroot(".") != 0)
                        lafe_errc(1, errno, "Can't chroot to \".\"");
@@ -245,7 +245,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
        }
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
-       if (mode == 'x' && bsdtar->option_stdout) {
+       if (mode == 'x' && (bsdtar->flags & OPTFLAG_STDOUT)) {
                _setmode(1, _O_BINARY);
        }
 #endif
@@ -253,7 +253,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
        for (;;) {
                /* Support --fast-read option */
                const char *p;
-               if (bsdtar->option_fast_read &&
+               if ((bsdtar->flags & OPTFLAG_FAST_READ) &&
                    archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
                        break;
 
@@ -307,7 +307,8 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
                if (mode == 't') {
                        /* Perversely, gtar uses -O to mean "send to stderr"
                         * when used with -t. */
-                       out = bsdtar->option_stdout ? stderr : stdout;
+                       out = (bsdtar->flags & OPTFLAG_STDOUT) ?
+                           stderr : stdout;
 
                        /*
                         * TODO: Provide some reasonable way to
@@ -345,7 +346,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
                        if (edit_pathname(bsdtar, entry))
                                continue; /* Excluded by a rewrite failure. */
 
-                       if (bsdtar->option_interactive &&
+                       if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
                            !yes("extract '%s'", archive_entry_pathname(entry)))
                                continue;
 
@@ -364,7 +365,7 @@ read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
 
                        /* TODO siginfo_printinfo(bsdtar, 0); */
 
-                       if (bsdtar->option_stdout)
+                       if (bsdtar->flags & OPTFLAG_STDOUT)
                                r = archive_read_data_into_fd(a, 1);
                        else
                                r = archive_read_extract2(a, entry, writer);
index 8f65b1762740e4eb23a6470714e8ca1fc2830c84..662db5baa79664d54f4ef27faa57334ad7d73430 100644 (file)
@@ -534,7 +534,7 @@ edit_pathname(struct bsdtar *bsdtar, struct archive_entry *entry)
                }
        }
 
-       if (!bsdtar->option_absolute_paths) {
+       if ((bsdtar->flags & OPTFLAG_ABSOLUTE_PATHS) == 0) {
                /* By default, don't write or restore absolute pathnames. */
                name = strip_absolute_path(bsdtar, name);
                if (*name == '\0')
index 532abb23883e05e6253356f94fe9efa0d189b98a..9c2456625271c6019268b8fd2c6bd44390a25c60 100644 (file)
@@ -583,7 +583,7 @@ cleanup:
        archive_read_free(bsdtar->diskreader);
        bsdtar->diskreader = NULL;
 
-       if (bsdtar->option_totals) {
+       if (bsdtar->flags & OPTFLAG_TOTALS) {
                fprintf(stderr, "Total bytes written: %s\n",
                    tar_i64toa(archive_filter_bytes(a, -1)));
        }
@@ -606,7 +606,8 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
 
        bsdtar->next_line_is_dir = 0;
 
-       lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null);
+       lr = lafe_line_reader(bsdtar->names_from_file,
+           (bsdtar->flags & OPTFLAG_NULL));
        while ((line = lafe_line_reader_next(lr)) != NULL) {
                if (bsdtar->next_line_is_dir) {
                        if (*line != '\0')
@@ -617,7 +618,8 @@ archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
                                bsdtar->return_value = 1;
                        }
                        bsdtar->next_line_is_dir = 0;
-               } else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
+               } else if (((bsdtar->flags & OPTFLAG_NULL) == 0) &&
+                   strcmp(line, "-C") == 0)
                        bsdtar->next_line_is_dir = 1;
                else {
                        if (*line != '/')
@@ -690,7 +692,7 @@ append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
        while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
                if (archive_match_excluded(bsdtar->matching, in_entry))
                        continue;
-               if (bsdtar->option_interactive &&
+               if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
                    !yes("copy '%s'", archive_entry_pathname(in_entry)))
                        continue;
                if (bsdtar->verbose > 1) {
@@ -809,11 +811,11 @@ excluded_callback(struct archive *a, void *_data, struct archive_entry *entry)
 {
        struct bsdtar *bsdtar = (struct bsdtar *)_data;
 
-       if (bsdtar->option_no_subdirs)
+       if (bsdtar->flags & OPTFLAG_NO_SUBDIRS)
                return;
        if (!archive_read_disk_can_descend(a))
                return;
-       if (bsdtar->option_interactive &&
+       if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
            !yes("add '%s'", archive_entry_pathname(entry)))
                return;
        archive_read_disk_descend(a);
@@ -844,12 +846,13 @@ metadata_filter(struct archive *a, void *_data, struct archive_entry *entry)
         * check would veto this file, we shouldn't bother
         * the user with it.
         */
-       if (bsdtar->option_interactive &&
+       if ((bsdtar->flags & OPTFLAG_INTERACTIVE) &&
            !yes("add '%s'", archive_entry_pathname(entry)))
                return (0);
 
        /* Note: if user vetoes, we won't descend. */
-       if (!bsdtar->option_no_subdirs && archive_read_disk_can_descend(a))
+       if (((bsdtar->flags & OPTFLAG_NO_SUBDIRS) == 0) &&
+           archive_read_disk_can_descend(a))
                archive_read_disk_descend(a);
 
        return (1);