]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Parse a command line instead of using
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 11 Oct 2012 02:13:20 +0000 (11:13 +0900)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Thu, 11 Oct 2012 05:28:58 +0000 (14:28 +0900)
   archive_write_add_filter_programl,
   archive_write_add_filter_programv,
   archive_read_support_filter_programl,
   archive_read_support_filter_programv,
   archive_read_support_filter_programl_signature and
   archive_read_support_filter_programv_signature.
And so remove those functions, which I recently added.

24 files changed:
Makefile.am
libarchive/CMakeLists.txt
libarchive/archive.h
libarchive/archive_cmdline.c [new file with mode: 0644]
libarchive/archive_cmdline_private.h [new file with mode: 0644]
libarchive/archive_read_private.h
libarchive/archive_read_support_filter_bzip2.c
libarchive/archive_read_support_filter_grzip.c
libarchive/archive_read_support_filter_gzip.c
libarchive/archive_read_support_filter_lrzip.c
libarchive/archive_read_support_filter_lzop.c
libarchive/archive_read_support_filter_program.c
libarchive/archive_read_support_filter_xz.c
libarchive/archive_write_add_filter_grzip.c
libarchive/archive_write_add_filter_lrzip.c
libarchive/archive_write_add_filter_lzop.c
libarchive/archive_write_add_filter_program.c
libarchive/archive_write_private.h
libarchive/filter_fork.h
libarchive/filter_fork_posix.c
libarchive/filter_fork_windows.c
libarchive/test/test_read_filter_program.c
libarchive/test/test_read_filter_program_signature.c
libarchive/test/test_write_filter_program.c

index 5052643b67f86fbeb0d7fab8878571b026528d1f..74770b845447d0143beb23a0d3925f7859a2eeb1 100644 (file)
@@ -90,6 +90,8 @@ libarchive_la_SOURCES=                                                \
        libarchive/archive_acl.c                                \
        libarchive/archive_acl_private.h                        \
        libarchive/archive_check_magic.c                        \
+       libarchive/archive_cmdline.c                            \
+       libarchive/archive_cmdline_private.h                    \
        libarchive/archive_crc32.h                              \
        libarchive/archive_crypto.c                             \
        libarchive/archive_crypto_private.h                     \
index 4bdb648e19dd12fabf201ee4c42637969583796d..2d9809b23998ebd4e0cebffc53154eca6c270b45 100644 (file)
@@ -15,6 +15,9 @@ SET(include_HEADERS
 SET(libarchive_SOURCES
   archive_acl.c
   archive_check_magic.c
+  archive_cmdline.c
+  archive_cmdline_private.h
+  archive_crc32.h
   archive_crypto.c
   archive_crypto_private.h
   archive_endian.h
index dd3e1906a00d08a8535f7c7899201d676b5a15be..d73e62519d89bae75f96490c9b3cffa47af35d08 100644 (file)
@@ -348,23 +348,9 @@ __LA_DECL int archive_read_support_filter_lzop(struct archive *);
 __LA_DECL int archive_read_support_filter_none(struct archive *);
 __LA_DECL int archive_read_support_filter_program(struct archive *,
                     const char *command);
-__LA_DECL int archive_read_support_filter_programl(struct archive *,
-                    const char *command, const char *arg,
-                    .../* (char *)0 */);
-__LA_DECL int archive_read_support_filter_programv(struct archive *,
-                    const char *command, char * const argv[]);
 __LA_DECL int archive_read_support_filter_program_signature
                (struct archive *, const char * /* cmd */,
                                    const void * /* match */, size_t);
-__LA_DECL int archive_read_support_filter_programl_signature
-               (struct archive *, const char * /* cmd */,
-                const char * /* arg */,
-                .../* , (char *)0, const void *, size_t */);
-__LA_DECL int archive_read_support_filter_programv_signature
-               (struct archive *, const char * /* cmd */,
-                char * const [] /* argv */,
-                const void * /* match */, size_t);
-
 __LA_DECL int archive_read_support_filter_rpm(struct archive *);
 __LA_DECL int archive_read_support_filter_uu(struct archive *);
 __LA_DECL int archive_read_support_filter_xz(struct archive *);
@@ -644,10 +630,6 @@ __LA_DECL int archive_write_add_filter_lzop(struct archive *);
 __LA_DECL int archive_write_add_filter_none(struct archive *);
 __LA_DECL int archive_write_add_filter_program(struct archive *,
                     const char *cmd);
-__LA_DECL int archive_write_add_filter_programl(struct archive *,
-                    const char *cmd, const char *arg, .../*, (char *)0 */);
-__LA_DECL int archive_write_add_filter_programv(struct archive *,
-                    const char *cmd, char * const argv[]);
 __LA_DECL int archive_write_add_filter_uuencode(struct archive *);
 __LA_DECL int archive_write_add_filter_xz(struct archive *);
 
diff --git a/libarchive/archive_cmdline.c b/libarchive/archive_cmdline.c
new file mode 100644 (file)
index 0000000..5129ab3
--- /dev/null
@@ -0,0 +1,222 @@
+/*-
+ * Copyright (c) 2012 Michihiro NAKAJIMA 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+
+__FBSDID("$FreeBSD$");
+
+#ifdef HAVE_STRING_H
+#  include <string.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+#endif
+
+#include "archive.h"
+#include "archive_cmdline_private.h"
+#include "archive_string.h"
+
+static int cmdline_set_path(struct archive_cmdline *, const char *);
+static int cmdline_add_arg(struct archive_cmdline *, const char *);
+
+static ssize_t
+extract_quotation(struct archive_string *as, const char *p)
+{
+       const char *s;
+
+       for (s = p + 1; *s; s++) {
+               if (*s == '\\') {
+                       if (s[1] != '\0')
+                               archive_strappend_char(as, s[0]);
+               } else if (*s == '"')
+                       break;
+               else
+                       archive_strappend_char(as, s[0]);
+       }
+       if (*s != '"')
+               return (ARCHIVE_FAILED);/* Invalid sequence. */
+       return ((ssize_t)(s + 1 - p));
+}
+
+static ssize_t
+get_argument(struct archive_string *as, const char *p)
+{
+       const char *s = p;
+
+       archive_string_empty(as);
+
+       /* Skip beginning space characters. */
+       while (*s != '\0' && *s == ' ')
+               s++;
+       /* Copy non-space characters. */
+       while (*s != '\0' && *s != ' ') {
+               if (*s == '\\') {
+                       if (s[1] != '\0') {
+                               archive_strappend_char(as, s[1]);
+                               s += 2;
+                       } else {
+                               s++;/* Ignore this character.*/
+                               break;
+                       }
+               } else if (*s == '"') {
+                       ssize_t q = extract_quotation(as, s);
+                       if (q < 0)
+                               return (ARCHIVE_FAILED);/* Invalid sequence. */
+                       s += q;
+               } else {
+                       archive_strappend_char(as, s[0]);
+                       s++;
+               }
+       }
+       return ((ssize_t)(s - p));
+}
+
+/*
+ * Set up command line arguments.
+ * Returns ARChIVE_OK if everything okey.
+ * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
+ * empty command line.
+ * Returns ARChIVE_FATAL if no memory.
+ */
+int
+__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
+{
+       struct archive_string as;
+       const char *p;
+       ssize_t al;
+       int r;
+
+       archive_string_init(&as);
+
+       /* Get first argument as a command path. */
+       al = get_argument(&as, cmd);
+       if (al < 0) {
+               r = ARCHIVE_FAILED;/* Invalid sequence. */
+               goto exit_function;
+       }
+       if (archive_strlen(&as) == 0) {
+               r = ARCHIVE_FAILED;/* An empty command path. */
+               goto exit_function;
+       }
+       r = cmdline_set_path(data, as.s);
+       if (r != ARCHIVE_OK)
+               goto exit_function;
+       p = strrchr(as.s, '/');
+       if (p == NULL)
+               p = as.s;
+       else
+               p++;
+       r = cmdline_add_arg(data, p);
+       if (r != ARCHIVE_OK)
+               goto exit_function;
+       cmd += al;
+
+       for (;;) {
+               al = get_argument(&as, cmd);
+               if (al < 0) {
+                       r = ARCHIVE_FAILED;/* Invalid sequence. */
+                       goto exit_function;
+               }
+               if (al == 0)
+                       break;
+               cmd += al;
+               if (archive_strlen(&as) == 0 && *cmd == '\0')
+                       break;
+               r = cmdline_add_arg(data, as.s);
+               if (r != ARCHIVE_OK)
+                       goto exit_function;
+       }
+       r = ARCHIVE_OK;
+exit_function:
+       archive_string_free(&as);
+       return (r);
+}
+
+/*
+ * Set the program path.
+ */
+static int
+cmdline_set_path(struct archive_cmdline *data, const char *path)
+{
+       char *newptr;
+
+       newptr = realloc(data->path, strlen(path) + 1);
+       if (newptr == NULL)
+               return (ARCHIVE_FATAL);
+       data->path = newptr;
+       strcpy(data->path, path);
+       return (ARCHIVE_OK);
+}
+
+/*
+ * Add a argument for the program.
+ */
+static int
+cmdline_add_arg(struct archive_cmdline *data, const char *arg)
+{
+       char **newargv;
+
+       if (data->path == NULL)
+               return (ARCHIVE_FAILED);
+
+       newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
+       if (newargv == NULL)
+               return (ARCHIVE_FATAL);
+       data->argv = newargv;
+       data->argv[data->argc] = strdup(arg);
+       if (data->argv[data->argc] == NULL)
+               return (ARCHIVE_FATAL);
+       /* Set the terminator of argv. */
+       data->argv[++data->argc] = NULL;
+       return (ARCHIVE_OK);
+}
+
+struct archive_cmdline *
+__archive_cmdline_allocate(void)
+{
+       return (struct archive_cmdline *)
+               calloc(1, sizeof(struct archive_cmdline *));
+}
+
+/*
+ * Release the resources.
+ */
+int
+__archive_cmdline_free(struct archive_cmdline *data)
+{
+
+       if (data) {
+               free(data->path);
+               if (data->argv != NULL) {
+                       int i;
+                       for (i = 0; data->argv[i] != NULL; i++)
+                               free(data->argv[i]);
+                       free(data->argv);
+               }
+               free(data);
+       }
+       return (ARCHIVE_OK);
+}
+
diff --git a/libarchive/archive_cmdline_private.h b/libarchive/archive_cmdline_private.h
new file mode 100644 (file)
index 0000000..85fba1e
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+#ifndef ARCHIVE_CMDLINE_PRIVATE_H
+#define ARCHIVE_CMDLINE_PRIVATE_H
+
+struct archive_cmdline {
+        char            *path;
+        char            **argv;
+        int              argc;
+};
+
+struct archive_cmdline *__archive_cmdline_allocate(void);
+int __archive_cmdline_parse(struct archive_cmdline *, const char *);
+int __archive_cmdline_free(struct archive_cmdline *);
+
+#endif
index 2dc9645ca0a101e80258e9bcbbab0ec1ffd37ad6..de3f3cdb566a9a8821c557e68426792cdffa6e93 100644 (file)
@@ -225,8 +225,5 @@ int64_t     __archive_read_seek(struct archive_read*, int64_t, int);
 int64_t        __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
 int64_t        __archive_read_consume(struct archive_read *, int64_t);
 int64_t        __archive_read_filter_consume(struct archive_read_filter *, int64_t);
-int __archive_read_programl(struct archive_read_filter *, const char *,
-    const char *, .../*, (char *)0 */);
-int __archive_read_programv(struct archive_read_filter *, const char *,
-    char * const argv[]);
+int __archive_read_program(struct archive_read_filter *, const char *);
 #endif
index 4d07e81d0d01419d407e25f567f69869de384f69..0050fab0f126c6637ddc2de01198d8e033a7c73c 100644 (file)
@@ -170,8 +170,8 @@ bzip2_reader_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "bunzip2", "bunzip2", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "bunzip2");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_BZIP2;
index 7a132ab2d072366a215d892efbf8fd69aa0f3afe..61403f6dcb0e25f9c4a30baf97552ecdcc75edd5 100644 (file)
@@ -109,8 +109,8 @@ grzip_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "grzip", "grzip", "-d", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "grzip -d");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_GRZIP;
index fb3d1f4ae9e86051465b6bf3c64df7e518724e82..50a6a6bf5a7430a28a417f61086156f71251c80b 100644 (file)
@@ -231,8 +231,8 @@ gzip_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "gzip", "gzip", "-d", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "gzip -d");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_GZIP;
index 2cfd76e8882863ccad2991df9b67a93a9121ee87..62d3f9b6aa551c54c42a56d32f1f89688e411143 100644 (file)
@@ -119,8 +119,8 @@ lrzip_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "lrzip", "lrzip", "-q", "-d", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "lrzip -d -q");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_LRZIP;
index 4c8e0e0d2676dd6fceb1d8f27bc81ca2cf195c72..cfaa30879c253409df8a70b7d2db09ce770c6146 100644 (file)
@@ -109,8 +109,8 @@ lzop_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "lzop", "lzop", "-d", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "lzop -d");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_LZOP;
index f2b0e0df94dc2726891983f8d286d62daa7cab44..850ab45459e8588a22a1850341f0a89cfee2910c 100644 (file)
@@ -82,72 +82,6 @@ archive_read_support_filter_program(struct archive *a, const char *cmd)
        return (archive_read_support_filter_program_signature(a, cmd, NULL, 0));
 }
 
-static void
-free_argv(char **argv)
-{
-       int i;
-
-       if (argv) {
-               for (i = 0; argv[i] != NULL; i++)
-                       free(argv[i]);
-               free(argv);
-       }
-}
-
-int
-archive_read_support_filter_programl(struct archive *a, const char *cmd,
-    const char *arg, ...)
-{
-       va_list ap;
-       char **argv;
-       int i, r;
-
-       i = 2;
-       if (arg != NULL) {
-               va_start(ap, arg);
-               while (va_arg(ap, char *) != NULL)
-                       i++;
-               va_end(ap);
-       }
-       argv = calloc(i, sizeof(char *));
-       if (argv == NULL)
-               goto memerr;
-       argv[0] = strdup((arg)?arg:cmd);
-       if (argv[0] == NULL)
-               goto memerr;
-       i = 1;
-       va_start(ap, arg);
-       if (arg) {
-               char *val;
-               while ((val = va_arg(ap, char *)) != NULL) {
-                       argv[i] = strdup(val);
-                       if (argv[i] == NULL) {
-                               va_end(ap);
-                               goto memerr;
-                       }
-                       i++;
-               }
-       }
-       va_end(ap);
-       argv[i] = NULL;
-       r = archive_read_support_filter_programv_signature(a, cmd, argv,
-               NULL, 0);
-       free_argv(argv);
-       return (r);
-memerr:
-       free_argv(argv);
-       archive_set_error(a, ENOMEM, "Can't allocate memory");
-       return (ARCHIVE_FATAL);
-}
-
-int
-archive_read_support_filter_programv(struct archive *a, const char *cmd,
-    char * const argv[])
-{
-       return (archive_read_support_filter_programv_signature(a, cmd, argv,
-               NULL, 0));
-}
-
 /*
  * The bidder object stores the command and the signature to watch for.
  * The 'inhibit' entry here is used to ensure that unchecked filters never
@@ -155,7 +89,6 @@ archive_read_support_filter_programv(struct archive *a, const char *cmd,
  */
 struct program_bidder {
        char *cmd;
-       char **argv;
        void *signature;
        size_t signature_len;
        int inhibit;
@@ -234,124 +167,6 @@ archive_read_support_filter_program_signature(struct archive *_a,
        state->cmd = strdup(cmd);
        if (state->cmd == NULL)
                goto memerr;
-       state->argv = calloc(2, sizeof(char *));
-       if (state->argv == NULL)
-               goto memerr;
-       state->argv[0] = strdup(cmd);
-       if (state->argv[0] == NULL)
-               goto memerr;
-       state->argv[1] = NULL;
-
-       return set_bidder_signature(bidder, state, signature, signature_len);
-memerr:
-       free_state(state);
-       archive_set_error(_a, ENOMEM, "Can't allocate memory");
-       return (ARCHIVE_FATAL);
-}
-
-int
-archive_read_support_filter_programl_signature(struct archive *_a,
-    const char *cmd, const char *arg, .../* , signature, signature_len */)
-{
-       struct archive_read *a = (struct archive_read *)_a;
-       struct archive_read_filter_bidder *bidder;
-       struct program_bidder *state;
-       const void *signature;
-       size_t signature_len;
-       va_list ap;
-       int i;
-
-       /*
-        * Get a bidder object from the read core.
-        */
-       if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
-               return (ARCHIVE_FATAL);
-
-       /*
-        * Allocate our private state.
-        */
-       state = (struct program_bidder *)calloc(1, sizeof (*state));
-       if (state == NULL)
-               goto memerr;
-       state->cmd = strdup(cmd);
-       if (state->cmd == NULL)
-               goto memerr;
-
-       i = 2;
-       if (arg != NULL) {
-               va_start(ap, arg);
-               while (va_arg(ap, char *) != NULL)
-                       i++;
-               va_end(ap);
-       }
-       state->argv = calloc(i, sizeof(char *));
-       if (state->argv == NULL)
-               goto memerr;
-       state->argv[0] = strdup((arg)?arg:cmd);
-       if (state->argv[0] == NULL)
-               goto memerr;
-       i = 1;
-       va_start(ap, arg);
-       if (arg) {
-               char *val;
-               while ((val = va_arg(ap, char *)) != NULL) {
-                       state->argv[i] = strdup(val);
-                       if (state->argv[i] == NULL) {
-                               va_end(ap);
-                               goto memerr;
-                       }
-                       i++;
-               }
-       }
-       signature = va_arg(ap, const void *);
-       signature_len = va_arg(ap, size_t);
-       va_end(ap);
-       state->argv[i] = NULL;
-
-       return set_bidder_signature(bidder, state, signature, signature_len);
-memerr:
-       free_state(state);
-       archive_set_error(_a, ENOMEM, "Can't allocate memory");
-       return (ARCHIVE_FATAL);
-}
-
-int
-archive_read_support_filter_programv_signature(struct archive *_a,
-    const char *cmd, char * const argv[], const void *signature,
-    size_t signature_len)
-{
-       struct archive_read *a = (struct archive_read *)_a;
-       struct archive_read_filter_bidder *bidder;
-       struct program_bidder *state;
-       int i;
-
-       /*
-        * Get a bidder object from the read core.
-        */
-       if (__archive_read_get_bidder(a, &bidder) != ARCHIVE_OK)
-               return (ARCHIVE_FATAL);
-
-       /*
-        * Allocate our private state.
-        */
-       state = (struct program_bidder *)calloc(1, sizeof (*state));
-       if (state == NULL)
-               goto memerr;
-       state->cmd = strdup(cmd);
-       if (state->cmd == NULL)
-               goto memerr;
-
-       for (i = 0; argv[i] != NULL; i++)
-               ;
-       state->argv = calloc(i + 1, sizeof(char *));
-       if (state->argv == NULL)
-               goto memerr;
-       for (i = 0; argv[i] != NULL; i++) {
-               state->argv[i] = strdup(argv[i]);
-               if (state->argv[i] == NULL)
-                       goto memerr;
-       }
-       state->argv[i] = NULL;
 
        return set_bidder_signature(bidder, state, signature, signature_len);
 memerr:
@@ -375,7 +190,6 @@ free_state(struct program_bidder *state)
 
        if (state) {
                free(state->cmd);
-               free_argv(state->argv);
                free(state->signature);
                free(state);
        }
@@ -579,71 +393,16 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
 }
 
 int
-__archive_read_programl(struct archive_read_filter *self, const char *cmd,
-    const char *arg, ...)
-{
-       va_list ap;
-       char **argv;
-       char *val;
-       int i, r;
-
-       i = 2;
-       if (arg != NULL) {
-               va_start(ap, arg);
-               while (va_arg(ap, char *) != NULL)
-                       i++;
-               va_end(ap);
-       }
-       argv = malloc(i * sizeof(char *));
-       if (argv == NULL)
-               goto memerr;
-
-       if (arg != NULL) {
-               argv[0] = strdup(arg);
-               if (argv[0] == NULL)
-                       goto memerr;
-               i = 1;
-               va_start(ap, arg);
-               while ((val = va_arg(ap, char *)) != NULL) {
-                       argv[i] = strdup(val);
-                       if (argv[i] == NULL)
-                               goto memerr;
-                       i++;
-               }
-               va_end(ap);
-               argv[i] = NULL;
-       } else {
-               argv[0] = strdup(cmd);
-               if (argv[0] == NULL)
-                       goto memerr;
-               argv[1] = NULL;
-       }
-
-       r = __archive_read_programv(self, cmd, argv);
-       free_argv(argv);
-       return (r);
-memerr:
-       free_argv(argv);
-       archive_set_error(&self->archive->archive, ENOMEM,
-           "Can't allocate input data");
-       return (ARCHIVE_FATAL);
-}
-
-int
-__archive_read_programv(struct archive_read_filter *self, const char *cmd,
-    char * const argv[])
+__archive_read_program(struct archive_read_filter *self, const char *cmd)
 {
        struct program_filter   *state;
        static const size_t out_buf_len = 65536;
        char *out_buf;
        const char *prefix = "Program: ";
        pid_t child;
-       int i;
        size_t l;
 
        l = strlen(prefix) + strlen(cmd) + 1;
-       for (i = 0; argv[i] != NULL; i++)
-               l += strlen(argv[i]) + 1;
        state = (struct program_filter *)calloc(1, sizeof(*state));
        out_buf = (char *)malloc(out_buf_len);
        if (state == NULL || out_buf == NULL ||
@@ -659,10 +418,6 @@ __archive_read_programv(struct archive_read_filter *self, const char *cmd,
        }
        archive_strcpy(&state->description, prefix);
        archive_strcat(&state->description, cmd);
-       for (i = 0; argv[i] != NULL; i++) {
-               archive_strappend_char(&state->description, ' ');
-               archive_strcat(&state->description, argv[i]);
-       }
 
        self->code = ARCHIVE_FILTER_PROGRAM;
        self->name = state->description.s;
@@ -670,7 +425,7 @@ __archive_read_programv(struct archive_read_filter *self, const char *cmd,
        state->out_buf = out_buf;
        state->out_buf_len = out_buf_len;
 
-       child = __archive_create_child(cmd, argv, &state->child_stdin,
+       child = __archive_create_child(cmd, &state->child_stdin,
            &state->child_stdout);
        if (child == -1) {
                free(state->out_buf);
@@ -710,8 +465,7 @@ program_bidder_init(struct archive_read_filter *self)
        struct program_bidder   *bidder_state;
 
        bidder_state = (struct program_bidder *)self->bidder->data;
-       return (__archive_read_programv(self, bidder_state->cmd,
-                   bidder_state->argv));
+       return (__archive_read_program(self, bidder_state->cmd));
 }
 
 static ssize_t
index e94c29e3f366402873836033f409e37cbc556366..ea47fe43a278ccc27bdb4c68dbb536919c508713 100644 (file)
@@ -941,8 +941,8 @@ lzma_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "unlzma", "unlzma", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "unlzma");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_LZMA;
@@ -958,8 +958,8 @@ xz_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "unxz", "unxz", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "unxz");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_XZ;
@@ -972,8 +972,8 @@ lzip_bidder_init(struct archive_read_filter *self)
 {
        int r;
 
-       r = __archive_read_programl(self, "unlzip", "unlzip", NULL);
-       /* Note: We set the format here even if __archive_read_programl()
+       r = __archive_read_program(self, "unlzip");
+       /* Note: We set the format here even if __archive_read_program()
         * above fails.  We do, after all, know what the format is
         * even if we weren't able to read it. */
        self->code = ARCHIVE_FILTER_LZIP;
index b5255903a9beed4b48b685f1d8c0681ebee37f80..dc58ed05f1dd19406cb1a35a0ca6de94395d0336 100644 (file)
@@ -104,16 +104,11 @@ archive_write_grzip_open(struct archive_write_filter *f)
        int r;
 
        r = __archive_write_program_set_cmd(data->pdata, "grzip");
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = __archive_write_program_add_arg(data->pdata, "grzip");
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = __archive_write_program_open(f, data->pdata);
-       return (r);
-memerr:
-       archive_set_error(f->archive, ENOMEM, "Can't allocate memory");
-       return (ARCHIVE_FATAL);
+       if (r != ARCHIVE_OK) {
+               archive_set_error(f->archive, ENOMEM, "Can't allocate memory");
+               return (ARCHIVE_FATAL);
+       }
+       return __archive_write_program_open(f, data->pdata);
 }
 
 static int
index 1ffb78bf3c14a18f037e5737240dcb6398f62927..578ca84ef065530bed8d8a1f666321eefacd5619 100644 (file)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #include "archive.h"
+#include "archive_string.h"
 #include "archive_write_private.h"
 
 struct write_lrzip {
@@ -126,60 +127,44 @@ static int
 archive_write_lrzip_open(struct archive_write_filter *f)
 {
        struct write_lrzip *data = (struct write_lrzip *)f->data;
+       struct archive_string as;
        int r;
 
-       r = __archive_write_program_set_cmd(data->pdata, "lrzip");
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = __archive_write_program_add_arg(data->pdata, "lrzip");
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = __archive_write_program_add_arg(data->pdata, "-q");
-       if (r != ARCHIVE_OK)
-               goto memerr;
+       archive_string_init(&as);
+       archive_strcpy(&as, "lrzip -q");
 
        /* Specify compression type. */
        switch (data->compression) {
        case lzma:/* default compression */
                break;
        case bzip2:
-               r = __archive_write_program_add_arg(data->pdata, "-b");
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strcat(&as, " -b");
                break;
        case gzip:
-               r = __archive_write_program_add_arg(data->pdata, "-g");
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strcat(&as, " -g");
                break;
        case lzo:
-               r = __archive_write_program_add_arg(data->pdata, "-l");
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strcat(&as, " -l");
                break;
        case zpaq:
-               r = __archive_write_program_add_arg(data->pdata, "-z");
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strcat(&as, " -z");
                break;
        }
 
        /* Specify compression level. */
        if (data->compression_level > 0) {
-               char level[2];
-               r = __archive_write_program_add_arg(data->pdata, "-L");
-               if (r != ARCHIVE_OK)
-                       goto memerr;
-               level[0] = '0' + data->compression_level;
-               level[1] = '\0';
-               r = __archive_write_program_add_arg(data->pdata, level);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strcat(&as, " -L ");
+               archive_strappend_char(&as, '0' + data->compression_level);
        }
+       r = __archive_write_program_set_cmd(data->pdata, as.s);
+       if (r != ARCHIVE_OK)
+               goto memerr;
+       archive_string_free(&as);
 
        r = __archive_write_program_open(f, data->pdata);
        return (r);
 memerr:
+       archive_string_free(&as);
        archive_set_error(f->archive, ENOMEM, "Can't allocate memory");
        return (ARCHIVE_FATAL);
 }
index 06af6d71aca342448ba11655c8a921a8443a2365..7106c7095ed3ea9a23cff647cd1655dd9b2c05d5 100644 (file)
@@ -33,8 +33,12 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
 
 #include "archive.h"
+#include "archive_string.h"
 #include "archive_write_private.h"
 
 struct write_lzop {
@@ -108,27 +112,25 @@ static int
 archive_write_lzop_open(struct archive_write_filter *f)
 {
        struct write_lzop *data = (struct write_lzop *)f->data;
+       struct archive_string as;
        int r;
 
-       r = __archive_write_program_set_cmd(data->pdata, "lzop");
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = __archive_write_program_add_arg(data->pdata, "lzop");
-       if (r != ARCHIVE_OK)
-               goto memerr;
+       archive_string_init(&as);
+       archive_strcpy(&as, "lzop");
        /* Specify compression level. */
        if (data->compression_level > 0) {
-               char level[3];
-               level[0] = '-';
-               level[1] = '0' + data->compression_level;
-               level[2] = '\0';
-               r = __archive_write_program_add_arg(data->pdata, level);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
+               archive_strappend_char(&as, '-');
+               archive_strappend_char(&as, '0' + data->compression_level);
        }
+       r = __archive_write_program_set_cmd(data->pdata, as.s);
+       if (r != ARCHIVE_OK)
+               goto memerr;
+       archive_string_free(&as);
+
        r = __archive_write_program_open(f, data->pdata);
        return (r);
 memerr:
+       archive_string_free(&as);
        archive_set_error(f->archive, ENOMEM, "Can't allocate memory");
        return (ARCHIVE_FATAL);
 }
index d80442eff23a09a1d589ee560e68cd44557992e1..16dcc54be69822db48fa4c29777512ee809ba67c 100644 (file)
@@ -60,8 +60,6 @@ archive_write_set_compression_program(struct archive *a, const char *cmd)
 
 struct archive_write_program_data {
        char            *cmd;
-       char            **argv;
-       int              argc;
 #if defined(_WIN32) && !defined(__CYGWIN__)
        HANDLE           child;
 #else
@@ -84,8 +82,6 @@ static int archive_compressor_program_write(struct archive_write_filter *,
 static int archive_compressor_program_close(struct archive_write_filter *);
 static int archive_compressor_program_free(struct archive_write_filter *);
 
-static int init_filter_program(struct archive *,
-           struct archive_write_program_data *data);
 /*
  * Add a filter to this write handle that passes all data through an
  * external program.
@@ -93,7 +89,10 @@ static int init_filter_program(struct archive *,
 int
 archive_write_add_filter_program(struct archive *_a, const char *cmd)
 {
+       struct archive_write_filter *f = __archive_write_allocate_filter(_a);
        struct archive_write_program_data *pdata;
+       struct private_data *data;
+       static const char *prefix = "Program: ";
        int r;
 
        archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
@@ -105,129 +104,18 @@ archive_write_add_filter_program(struct archive *_a, const char *cmd)
        r = __archive_write_program_set_cmd(pdata, cmd);
        if (r != ARCHIVE_OK)
                goto memerr;
-       r = __archive_write_program_add_arg(pdata, cmd);
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       r = init_filter_program(_a, pdata);
-       if (r == ARCHIVE_OK)
-               return (r);
-memerr:
-       __archive_write_program_free(pdata);
-       archive_set_error(_a, ENOMEM,
-           "Can't allocate memory for filter program");
-       return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_add_filter_programl(struct archive *_a, const char *cmd,
-    const char *arg, ...)
-{
-       struct archive_write_program_data *pdata;
-       va_list ap;
-       char *val;
-       int r;
-
-       archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
-           ARCHIVE_STATE_NEW, "archive_write_add_filter_programl");
-
-       pdata = __archive_write_program_allocate();
-       if (pdata == NULL)
-               goto memerr;
-       r = __archive_write_program_set_cmd(pdata, cmd);
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       if (arg != NULL) {
-               r = __archive_write_program_add_arg(pdata, arg);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
-               va_start(ap, arg);
-               while ((val = va_arg(ap, char *)) != NULL) {
-                       r = __archive_write_program_add_arg(pdata, val);
-                       if (r != ARCHIVE_OK)
-                               goto memerr;
-               }
-               va_end(ap);
-       } else {
-               r = __archive_write_program_add_arg(pdata, cmd);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
-       }
-       r = init_filter_program(_a, pdata);
-       if (r == ARCHIVE_OK)
-               return (r);
-memerr:
-       __archive_write_program_free(pdata);
-       archive_set_error(_a, ENOMEM,
-           "Can't allocate memory for filter program");
-       return (ARCHIVE_FATAL);
-}
-
-int
-archive_write_add_filter_programv(struct archive *_a, const char *cmd,
-    char * const argv[])
-{
-       struct archive_write_program_data *pdata;
-       int i, r;
-
-       archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
-           ARCHIVE_STATE_NEW, "archive_write_add_filter_programv");
-
-       pdata = __archive_write_program_allocate();
-       if (pdata == NULL)
-               goto memerr;
-       r = __archive_write_program_set_cmd(pdata, cmd);
-       if (r != ARCHIVE_OK)
-               goto memerr;
-       for (i = 0; argv[i] != NULL; i++) {
-               r = __archive_write_program_add_arg(pdata, argv[i]);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
-       }
-       if (i == 0) {
-               r = __archive_write_program_add_arg(pdata, cmd);
-               if (r != ARCHIVE_OK)
-                       goto memerr;
-       }
-       r = init_filter_program(_a, pdata);
-       if (r == ARCHIVE_OK)
-               return (r);
-memerr:
-       __archive_write_program_free(pdata);
-       archive_set_error(_a, ENOMEM,
-           "Can't allocate memory for filter program");
-       return (ARCHIVE_FATAL);
-}
-
-/*
- * Setup callback.
- */
-static int
-init_filter_program(struct archive *_a,
-    struct archive_write_program_data *pdata)
-{
-
-       struct archive_write_filter *f = __archive_write_allocate_filter(_a);
-       struct private_data *data;
-       static const char *prefix = "Program: ";
-       int i;
-       size_t l;
 
        data = calloc(1, sizeof(*data));
        if (data == NULL)
                goto memerr;
-       l = strlen(prefix) + strlen(pdata->cmd) + 1;
-       for (i = 0; pdata->argv[i] != NULL; i++)
-               l += strlen(pdata->argv[i]) + 1;
 
        /* Make up a description string. */
-       if (archive_string_ensure(&data->description, l) == NULL)
+       if (archive_string_ensure(&data->description,
+           strlen(prefix) + strlen(cmd) + 1) == NULL)
                goto memerr;
        archive_strcpy(&data->description, prefix);
-       archive_strcat(&data->description, pdata->cmd);
-       for (i = 0; pdata->argv[i] != NULL; i++) {
-               archive_strappend_char(&data->description, ' ');
-               archive_strcat(&data->description, pdata->argv[i]);
-       }
+       archive_strcat(&data->description, cmd);
+
        data->pdata = pdata;
        f->name = data->description.s;
        f->code = ARCHIVE_FILTER_PROGRAM;
@@ -238,7 +126,7 @@ init_filter_program(struct archive *_a,
        f->free = archive_compressor_program_free;
        return (ARCHIVE_OK);
 memerr:
-       archive_compressor_program_free(f);
+       __archive_write_program_free(pdata);
        archive_set_error(_a, ENOMEM,
            "Can't allocate memory for filter program");
        return (ARCHIVE_FATAL);
@@ -308,13 +196,6 @@ __archive_write_program_free(struct archive_write_program_data *data)
                if (data->child)
                        CloseHandle(data->child);
 #endif
-               free(data->cmd);
-               if (data->argv != NULL) {
-                       int i;
-                       for (i = 0; data->argv[i] != NULL; i++)
-                               free(data->argv[i]);
-                       free(data->argv);
-               }
                free(data->child_buf);
                free(data);
        }
@@ -322,49 +203,22 @@ __archive_write_program_free(struct archive_write_program_data *data)
 }
 
 /*
- * Set the program path.
+ * Set up command line arguments.
+ * Returns ARChIVE_OK if everything okey.
+ * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
+ * empty command line.
+ * Returns ARChIVE_FATAL if no memory.
  */
 int
 __archive_write_program_set_cmd(struct archive_write_program_data *data,
     const char *cmd)
 {
-       char *newptr;
-
-       newptr = realloc(data->cmd, strlen(cmd) + 1);
-       if (newptr == NULL)
-               return (ARCHIVE_FATAL);
-       data->cmd = newptr;
-       strcpy(data->cmd, cmd);
-       return (ARCHIVE_OK);
-}
-
-/*
- * Add a argument for the program.
- */
-int
-__archive_write_program_add_arg(struct archive_write_program_data *data,
-    const char *arg)
-{
-       char **newargv;
-       int i;
 
+       free(data->cmd);
+       data->cmd = strdup(cmd);
        if (data->cmd == NULL)
                return (ARCHIVE_FATAL);
-
-       newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
-       if (newargv == NULL)
-               return (ARCHIVE_FATAL);
-       if (newargv != data->argv && data->argv != NULL) {
-               for (i = 0; i <= data->argc; i++)
-                       newargv[i] = data->argv[i];
-       }
-       data->argv = newargv;
-       data->argv[data->argc] = strdup(arg);
-       if (data->argv[data->argc] == NULL)
-               return (ARCHIVE_FATAL);
-       /* Set the terminator of argv. */
-       data->argv[++data->argc] = NULL;
-       return (ARCHIVE_OK);
+       return ARCHIVE_OK;
 }
 
 int
@@ -390,7 +244,7 @@ __archive_write_program_open(struct archive_write_filter *f,
                }
        }
 
-       child = __archive_create_child(data->cmd, data->argv,
+       child = __archive_create_child(data->cmd,
                 &data->child_stdin, &data->child_stdout);
        if (child == -1) {
                archive_set_error(f->archive, EINVAL,
index 2f31428d4e0d1df53bb2864f98fab085934ec80a..c394bcfa53be06d3229b03633bdd59c6c98b221a 100644 (file)
@@ -140,10 +140,8 @@ int        __archive_write_program_open(struct archive_write_filter *,
            struct archive_write_program_data *);
 int    __archive_write_program_close(struct archive_write_filter *,
            struct archive_write_program_data *);
-int    __archive_write_program_write(struct archive_write_filter *,
-           struct archive_write_program_data *, const void *, size_t);
 int    __archive_write_program_set_cmd(struct archive_write_program_data *,
            const char *);
-int    __archive_write_program_add_arg(struct archive_write_program_data *,
-           const char *);
+int    __archive_write_program_write(struct archive_write_filter *,
+           struct archive_write_program_data *, const void *, size_t);
 #endif
index 1652c85d08a16d6099043b4595e7648db9de7f81..a28272bee33b62d9c8d1fafa8d427689fa21552a 100644 (file)
@@ -33,8 +33,7 @@
 #define FILTER_FORK_H
 
 pid_t
-__archive_create_child(const char *path, char * const argv[], int *child_stdin,
-       int *child_stdout);
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout);
 
 void
 __archive_check_child(int in, int out);
index bfaa5adce0ba5c8abb6fe6cb89549e692d457f48..02dbd4bb436288550524a8f24322b1511ae82a75 100644 (file)
@@ -67,11 +67,13 @@ __FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00
 #  include <unistd.h>
 #endif
 
+#include "archive.h"
+#include "archive_cmdline_private.h"
+
 #include "filter_fork.h"
 
 pid_t
-__archive_create_child(const char *path, char * const argv[], int *child_stdin,
-    int *child_stdout)
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
 {
        pid_t child;
        int stdin_pipe[2], stdout_pipe[2], tmp;
@@ -79,6 +81,13 @@ __archive_create_child(const char *path, char * const argv[], int *child_stdin,
        posix_spawn_file_actions_t actions;
        int r;
 #endif
+       struct archive_cmdline *cmdline;
+
+       cmdline = __archive_cmdline_allocate();
+       if (cmdline == NULL)
+               goto state_allocated;
+       if (__archive_cmdline_parse(cmdline, cmd) != ARCHIVE_OK)
+               goto state_allocated;
 
        if (pipe(stdin_pipe) == -1)
                goto state_allocated;
@@ -128,7 +137,8 @@ __archive_create_child(const char *path, char * const argv[], int *child_stdin,
                if (r != 0)
                        goto actions_inited;
        }
-       r = posix_spawnp(&child, path, &actions, NULL, argv, NULL);
+       r = posix_spawnp(&child, cmdline->path, &actions, NULL,
+               cmdline->argv, NULL);
        if (r != 0)
                goto actions_inited;
        posix_spawn_file_actions_destroy(&actions);
@@ -153,7 +163,7 @@ __archive_create_child(const char *path, char * const argv[], int *child_stdin,
                        _exit(254);
                if (stdout_pipe[1] != 1 /* stdout */)
                        close(stdout_pipe[1]);
-               execvp(path, argv);
+               execvp(cmdline->path, cmdline->argv);
                _exit(254);
        }
 #endif /* HAVE_POSIX_SPAWNP */
@@ -165,6 +175,7 @@ __archive_create_child(const char *path, char * const argv[], int *child_stdin,
        fcntl(*child_stdin, F_SETFL, O_NONBLOCK);
        *child_stdout = stdout_pipe[0];
        fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
+       __archive_cmdline_free(cmdline);
 
        return child;
 
@@ -180,6 +191,7 @@ stdin_opened:
        close(stdin_pipe[0]);
        close(stdin_pipe[1]);
 state_allocated:
+       __archive_cmdline_free(cmdline);
        return -1;
 }
 
index 9c458d66dfb3d4e964e75ec0348a5afe24894096..43fce771983fc03b6471508708f89aa9fff00c04 100644 (file)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009-2012 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  */
 
 #include "archive_platform.h"
-#include "archive_string.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
+#include "archive_cmdline_private.h"
+#include "archive_string.h"
 
 #include "filter_fork.h"
 
 pid_t
-__archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
-    int *child_stdout)
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
 {
        HANDLE childStdout[2], childStdin[2],childStderr;
        SECURITY_ATTRIBUTES secAtts;
@@ -40,6 +40,7 @@ __archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
        PROCESS_INFORMATION childInfo;
        struct archive_string cmdline;
        struct archive_string fullpath;
+       struct archive_cmdline *acmd;
        char *arg0, *ext;
        int i, l;
        DWORD fl, fl_old;
@@ -50,26 +51,33 @@ __archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
        archive_string_init(&cmdline);
        archive_string_init(&fullpath);
 
+       acmd = __archive_cmdline_allocate();
+       if (acmd == NULL)
+               goto fail;
+       if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK)
+               goto fail;
+
        /*
-        * Search the full path of 'cmd'.
-        * NOTE: This does not need if we give CreateProcessA 'cmd' as a part
-        * of the cmdline and give CreateProcessA NULL as first parameter,
-        * but I do not like that way.
+        * Search the full path of 'path'.
+        * NOTE: This does not need if we give CreateProcessA 'path' as
+        * a part of the cmdline and give CreateProcessA NULL as first
+        * parameter, but I do not like that way.
         */
-       ext = strrchr(cmd, '.');
+       ext = strrchr(acmd->path, '.');
        if (ext == NULL || strlen(ext) > 4)
-               /* 'cmd' does not have a proper extension, so we have to
+               /* 'path' does not have a proper extension, so we have to
                 * give SearchPath() ".exe" as the extension. */
                ext = ".exe";
        else
-               ext = NULL;/* 'cmd' has an extension. */
+               ext = NULL;/* 'path' has an extension. */
 
        fl = MAX_PATH;
        do {
                if (archive_string_ensure(&fullpath, fl) == NULL)
                        goto fail;
                fl_old = fl;
-               fl = SearchPathA(NULL, cmd, ext, fl, fullpath.s, &arg0);
+               fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s,
+                       &arg0);
        } while (fl != 0 && fl > fl_old);
        if (fl == 0)
                goto fail;
@@ -77,22 +85,22 @@ __archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
        /*
         * Make a command line.
         */
-       for (l = 0, i = 0;  argv[i] != NULL; i++) {
+       for (l = 0, i = 0;  acmd->argv[i] != NULL; i++) {
                if (i == 0)
                        continue;
-               l += strlen(argv[i]) + 1;
+               l += strlen(acmd->argv[i]) + 1;
        }
        if (archive_string_ensure(&cmdline, l + 1) == NULL)
                goto fail;
-       for (i = 0;  argv[i] != NULL; i++) {
+       for (i = 0;  acmd->argv[i] != NULL; i++) {
                if (i == 0) {
                        const char *p, *sp;
 
-                       if ((p = strchr(argv[i], '/')) != NULL ||
-                           (p = strchr(argv[i], '\\')) != NULL)
+                       if ((p = strchr(acmd->argv[i], '/')) != NULL ||
+                           (p = strchr(acmd->argv[i], '\\')) != NULL)
                                p++;
                        else
-                               p = argv[i];
+                               p = acmd->argv[i];
                        if ((sp = strchr(p, ' ')) != NULL)
                                archive_strappend_char(&cmdline, '"');
                        archive_strcat(&cmdline, p);
@@ -100,7 +108,7 @@ __archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
                                archive_strappend_char(&cmdline, '"');
                } else {
                        archive_strappend_char(&cmdline, ' ');
-                       archive_strcat(&cmdline, argv[i]);
+                       archive_strcat(&cmdline, acmd->argv[i]);
                }
        }
        if (i <= 1) {
@@ -151,6 +159,7 @@ __archive_create_child(const char *cmd, char * const argv[], int *child_stdin,
 
        archive_string_free(&cmdline);
        archive_string_free(&fullpath);
+       __archive_cmdline_free(acmd);
        return (childInfo.dwProcessId);
 
 fail:
@@ -166,6 +175,7 @@ fail:
                CloseHandle(childStderr);
        archive_string_free(&cmdline);
        archive_string_free(&fullpath);
+       __archive_cmdline_free(acmd);
        return (-1);
 }
 
index 15f45a94d4d727206c2bed1e8c360a108028189a..a27589a146c985a7a73686eb2f2d2eb653920bc4 100644 (file)
@@ -61,101 +61,6 @@ DEFINE_TEST(test_read_filter_program)
        /*
         * If we have "gzip -d", try using that.
         */
-       if (!canGunzip()) {
-               skipping("Can't run gunzip program on this platform");
-               return;
-       }
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_program(a, "gunzip"));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_next_header(a, &ae));
-       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_PROGRAM);
-       assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-
-DEFINE_TEST(test_read_filter_programl)
-{
-       int r;
-       struct archive_entry *ae;
-       struct archive *a;
-
-       /*
-        * First, test handling when a non-existent compression
-        * program is requested.
-        */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_program(a, "nonexistent");
-       if (r == ARCHIVE_FATAL) {
-               skipping("archive_read_support_filter_program() "
-                   "unsupported on this platform");
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, r);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       if (!canGzip()) {
-               skipping("Can't run gzip program on this platform");
-               return;
-       }
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programl(a, "gzip", "gzip",
-               "-d", NULL));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_next_header(a, &ae));
-       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_PROGRAM);
-       assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-DEFINE_TEST(test_read_filter_programv)
-{
-       int r;
-       struct archive_entry *ae;
-       struct archive *a;
-       char * const argv[] = {"gzip", "-d", NULL};
-
-       /*
-        * First, test handling when a non-existent compression
-        * program is requested.
-        */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_program(a, "nonexistent");
-       if (r == ARCHIVE_FATAL) {
-               skipping("archive_read_support_filter_program() "
-                   "unsupported on this platform");
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, r);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
        if (!canGzip()) {
                skipping("Can't run gzip program on this platform");
                return;
@@ -164,7 +69,7 @@ DEFINE_TEST(test_read_filter_programv)
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_filter_none(a));
        assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programv(a, "gzip", argv));
+           archive_read_support_filter_program(a, "gzip -d"));
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_format_all(a));
        assertEqualIntA(a, ARCHIVE_OK,
index 0fbedc3a7416cce98307b69007dfc20eb746da0a..110addb87fe968274d9292a19d0fb313ae2c727d 100644 (file)
@@ -64,134 +64,6 @@ DEFINE_TEST(test_read_filter_program_signature)
        /*
         * If we have "gzip -d", try using that.
         */
-       if (!canGunzip()) {
-               skipping("Can't run gunzip program on this platform");
-               return;
-       }
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_program_signature(a, "gunzip",
-               signature, signature_len));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_next_header(a, &ae));
-       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_PROGRAM);
-       assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       /*
-        * Test bad signature.
-        */
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_program_signature(a, "gunzip",
-               badsignature, signature_len));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-
-DEFINE_TEST(test_read_filter_programl_signature)
-{
-       int r;
-       struct archive_entry *ae;
-       struct archive *a;
-
-       /*
-        * First, test handling when a non-existent compression
-        * program is requested.
-        */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_program(a, "nonexistent");
-       if (r == ARCHIVE_FATAL) {
-               skipping("archive_read_support_filter_program() "
-                   "unsupported on this platform");
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, r);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       if (!canGzip()) {
-               skipping("Can't run gzip program on this platform");
-               return;
-       }
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programl_signature(a, "gzip", "gzip",
-               "-d", NULL, signature, signature_len));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_next_header(a, &ae));
-       assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_PROGRAM);
-       assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       /*
-        * Test bad signature.
-        */
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_none(a));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programl_signature(a, "gzip", "gzip",
-               "-d", NULL, badsignature, signature_len));
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-DEFINE_TEST(test_read_filter_programv_signature)
-{
-       int r;
-       struct archive_entry *ae;
-       struct archive *a;
-       char * const argv[] = {"gzip", "-d", NULL};
-
-       /*
-        * First, test handling when a non-existent compression
-        * program is requested.
-        */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_program(a, "nonexistent");
-       if (r == ARCHIVE_FATAL) {
-               skipping("archive_read_support_filter_program() "
-                   "unsupported on this platform");
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, r);
-       assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_FATAL,
-           archive_read_open_memory(a, archive, sizeof(archive)));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
        if (!canGzip()) {
                skipping("Can't run gzip program on this platform");
                return;
@@ -200,7 +72,7 @@ DEFINE_TEST(test_read_filter_programv_signature)
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_filter_none(a));
        assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programv_signature(a, "gzip", argv,
+           archive_read_support_filter_program_signature(a, "gzip -d",
                signature, signature_len));
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_format_all(a));
@@ -220,7 +92,7 @@ DEFINE_TEST(test_read_filter_programv_signature)
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_filter_none(a));
        assertEqualIntA(a, ARCHIVE_OK,
-           archive_read_support_filter_programv_signature(a, "gzip", argv,
+           archive_read_support_filter_program_signature(a, "gunzip",
                badsignature, signature_len));
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_support_format_all(a));
index ad6261e8957bbaef1993ec8bebe742aa036b0023..c156b6d55d1e201872f0377e9eb1589bbe091fcd 100644 (file)
@@ -55,196 +55,7 @@ DEFINE_TEST(test_write_filter_program)
        /* Write it through an external "gzip" program. */
        assert((a = archive_write_new()) != NULL);
        assertA(0 == archive_write_set_format_ustar(a));
-       r = archive_write_add_filter_program(a, "gzip");
-       if (r == ARCHIVE_FATAL) {
-               skipping("Write compression via external "
-                   "program unsupported on this platform");
-               archive_write_free(a);
-               return;
-       }
-       assertA(0 == archive_write_set_bytes_per_block(a, blocksize));
-       assertA(0 == archive_write_set_bytes_in_last_block(a, blocksize));
-       assertA(blocksize == archive_write_get_bytes_in_last_block(a));
-       assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
-       assertA(blocksize == archive_write_get_bytes_in_last_block(a));
-
-       /*
-        * Write a file to it.
-        */
-       assert((ae = archive_entry_new()) != NULL);
-       archive_entry_set_mtime(ae, 1, 10);
-       archive_entry_copy_pathname(ae, "file");
-       archive_entry_set_mode(ae, S_IFREG | 0755);
-       archive_entry_set_size(ae, 8);
-
-       assertA(0 == archive_write_header(a, ae));
-       archive_entry_free(ae);
-       assertA(8 == archive_write_data(a, "12345678", 9));
-
-       /* Close out the archive. */
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-
-       /*
-        * Now, read the data back through the built-in gzip support.
-        */
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
-       r = archive_read_support_filter_gzip(a);
-       /* The compression_gzip() handler will fall back to gunzip
-        * automatically, but if we know gunzip isn't available, then
-        * skip the rest. */
-       if (r != ARCHIVE_OK && !canGzip()) {
-               skipping("No libz and no gunzip program, "
-                   "unable to verify gzip compression");
-               assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
-
-       if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))) {
-               archive_read_free(a);
-               return;
-       }
-
-       assertEqualInt(1, archive_entry_mtime(ae));
-       assertEqualInt(0, archive_entry_atime(ae));
-       assertEqualInt(0, archive_entry_ctime(ae));
-       assertEqualString("file", archive_entry_pathname(ae));
-       assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
-       assertEqualInt(8, archive_entry_size(ae));
-       assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
-       assertEqualMem(buff2, "12345678", 8);
-
-       /* Verify the end of the archive. */
-       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-DEFINE_TEST(test_write_filter_programl)
-{
-       struct archive_entry *ae;
-       struct archive *a;
-       size_t used;
-       int blocksize = 1024;
-       int r;
-
-       if (!canGzip()) {
-               skipping("Cannot run 'gzip'");
-               return;
-       }
-       /* NOTE: Setting blocksize=1024 will cause gunzip failure because
-        * it add extra bytes that gunzip ignores with its warning and
-        * exit code 1. So we should set blocksize=1 in order not to
-        * yield the extra bytes when using gunzip. */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_gzip(a);
-       if (r != ARCHIVE_OK && canGzip())
-               blocksize = 1;
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       /* Create a new archive in memory. */
-       /* Write it through an external "gzip" program. */
-       assert((a = archive_write_new()) != NULL);
-       assertA(0 == archive_write_set_format_ustar(a));
-       r = archive_write_add_filter_programl(a, "gzip", "gzip", NULL);
-       if (r == ARCHIVE_FATAL) {
-               skipping("Write compression via external "
-                   "program unsupported on this platform");
-               archive_write_free(a);
-               return;
-       }
-       assertA(0 == archive_write_set_bytes_per_block(a, blocksize));
-       assertA(0 == archive_write_set_bytes_in_last_block(a, blocksize));
-       assertA(blocksize == archive_write_get_bytes_in_last_block(a));
-       assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
-       assertA(blocksize == archive_write_get_bytes_in_last_block(a));
-
-       /*
-        * Write a file to it.
-        */
-       assert((ae = archive_entry_new()) != NULL);
-       archive_entry_set_mtime(ae, 1, 10);
-       archive_entry_copy_pathname(ae, "file");
-       archive_entry_set_mode(ae, S_IFREG | 0755);
-       archive_entry_set_size(ae, 8);
-
-       assertA(0 == archive_write_header(a, ae));
-       archive_entry_free(ae);
-       assertA(8 == archive_write_data(a, "12345678", 9));
-
-       /* Close out the archive. */
-       assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_write_free(a));
-
-       /*
-        * Now, read the data back through the built-in gzip support.
-        */
-       assert((a = archive_read_new()) != NULL);
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
-       r = archive_read_support_filter_gzip(a);
-       /* The compression_gzip() handler will fall back to gunzip
-        * automatically, but if we know gunzip isn't available, then
-        * skip the rest. */
-       if (r != ARCHIVE_OK && !canGzip()) {
-               skipping("No libz and no gunzip program, "
-                   "unable to verify gzip compression");
-               assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-               return;
-       }
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
-
-       if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))) {
-               archive_read_free(a);
-               return;
-       }
-
-       assertEqualInt(1, archive_entry_mtime(ae));
-       assertEqualInt(0, archive_entry_atime(ae));
-       assertEqualInt(0, archive_entry_ctime(ae));
-       assertEqualString("file", archive_entry_pathname(ae));
-       assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
-       assertEqualInt(8, archive_entry_size(ae));
-       assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
-       assertEqualMem(buff2, "12345678", 8);
-
-       /* Verify the end of the archive. */
-       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
-       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-}
-
-DEFINE_TEST(test_write_filter_programv)
-{
-       struct archive_entry *ae;
-       struct archive *a;
-       size_t used;
-       int blocksize = 1024;
-       int r;
-       char * const argv[] = {"gzip", NULL};
-
-       if (!canGzip()) {
-               skipping("Cannot run 'gzip'");
-               return;
-       }
-       /* NOTE: Setting blocksize=1024 will cause gunzip failure because
-        * it add extra bytes that gunzip ignores with its warning and
-        * exit code 1. So we should set blocksize=1 in order not to
-        * yield the extra bytes when using gunzip. */
-       assert((a = archive_read_new()) != NULL);
-       r = archive_read_support_filter_gzip(a);
-       if (r != ARCHIVE_OK && canGzip())
-               blocksize = 1;
-       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-
-       /* Create a new archive in memory. */
-       /* Write it through an external "gzip" program. */
-       assert((a = archive_write_new()) != NULL);
-       assertA(0 == archive_write_set_format_ustar(a));
-       r = archive_write_add_filter_programv(a, "gzip", argv);
+       r = archive_write_add_filter_program(a, "gzip -6");
        if (r == ARCHIVE_FATAL) {
                skipping("Write compression via external "
                    "program unsupported on this platform");