Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

write_raw support from Marek Kubica

Merged branch 'feature/write-format-raw' of https://github.com/Leonidas-from-XIV/libarchive
  • Loading branch information...
commit e5d1fbb2e24ad7ce3b94740c99c053c9ce24bffd 1 parent 014de9c
Tim Kientzle kientzle authored
3  Makefile.am
@@ -199,6 +199,7 @@ libarchive_la_SOURCES= \
199 199 libarchive/archive_write_set_format_iso9660.c \
200 200 libarchive/archive_write_set_format_mtree.c \
201 201 libarchive/archive_write_set_format_pax.c \
  202 + libarchive/archive_write_set_format_raw.c \
202 203 libarchive/archive_write_set_format_shar.c \
203 204 libarchive/archive_write_set_format_ustar.c \
204 205 libarchive/archive_write_set_format_v7tar.c \
@@ -486,6 +487,8 @@ libarchive_test_SOURCES= \
486 487 libarchive/test/test_write_format_mtree_no_separator.c \
487 488 libarchive/test/test_write_format_mtree_quoted_filename.c\
488 489 libarchive/test/test_write_format_pax.c \
  490 + libarchive/test/test_write_format_raw.c \
  491 + libarchive/test/test_write_format_raw_b64.c \
489 492 libarchive/test/test_write_format_shar_empty.c \
490 493 libarchive/test/test_write_format_tar.c \
491 494 libarchive/test/test_write_format_tar_empty.c \
1  libarchive/CMakeLists.txt
@@ -125,6 +125,7 @@ SET(libarchive_SOURCES
125 125 archive_write_set_format_iso9660.c
126 126 archive_write_set_format_mtree.c
127 127 archive_write_set_format_pax.c
  128 + archive_write_set_format_raw.c
128 129 archive_write_set_format_shar.c
129 130 archive_write_set_format_ustar.c
130 131 archive_write_set_format_v7tar.c
1  libarchive/archive.h
@@ -670,6 +670,7 @@ __LA_DECL int archive_write_set_format_mtree_classic(struct archive *);
670 670 /* TODO: int archive_write_set_format_old_tar(struct archive *); */
671 671 __LA_DECL int archive_write_set_format_pax(struct archive *);
672 672 __LA_DECL int archive_write_set_format_pax_restricted(struct archive *);
  673 +__LA_DECL int archive_write_set_format_raw(struct archive *);
673 674 __LA_DECL int archive_write_set_format_shar(struct archive *);
674 675 __LA_DECL int archive_write_set_format_shar_dump(struct archive *);
675 676 __LA_DECL int archive_write_set_format_ustar(struct archive *);
5 libarchive/archive_write_format.3
@@ -24,13 +24,14 @@
24 24 .\"
25 25 .\" $FreeBSD$
26 26 .\"
27   -.Dd February 2, 2012
  27 +.Dd February 14, 2013
28 28 .Dt ARCHIVE_WRITE_FORMAT 3
29 29 .Os
30 30 .Sh NAME
31 31 .Nm archive_write_set_format_cpio ,
32 32 .Nm archive_write_set_format_pax ,
33 33 .Nm archive_write_set_format_pax_restricted ,
  34 +.Nm archive_write_set_format_raw ,
34 35 .Nm archive_write_set_format_shar ,
35 36 .Nm archive_write_set_format_shar_dump ,
36 37 .Nm archive_write_set_format_ustar
@@ -46,6 +47,8 @@ Streaming Archive Library (libarchive, -larchive)
46 47 .Ft int
47 48 .Fn archive_write_set_format_pax_restricted "struct archive *"
48 49 .Ft int
  50 +.Fn archive_write_set_format_raw "struct archive *"
  51 +.Ft int
49 52 .Fn archive_write_set_format_shar "struct archive *"
50 53 .Ft int
51 54 .Fn archive_write_set_format_shar_dump "struct archive *"
3  libarchive/archive_write_set_format.c
@@ -47,6 +47,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
47 47 { ARCHIVE_FORMAT_CPIO_SVR4_NOCRC, archive_write_set_format_cpio_newc },
48 48 { ARCHIVE_FORMAT_ISO9660, archive_write_set_format_iso9660 },
49 49 { ARCHIVE_FORMAT_MTREE, archive_write_set_format_mtree },
  50 + { ARCHIVE_FORMAT_RAW, archive_write_set_format_raw },
50 51 { ARCHIVE_FORMAT_SHAR, archive_write_set_format_shar },
51 52 { ARCHIVE_FORMAT_SHAR_BASE, archive_write_set_format_shar },
52 53 { ARCHIVE_FORMAT_SHAR_DUMP, archive_write_set_format_shar_dump },
@@ -57,7 +58,7 @@ struct { int code; int (*setter)(struct archive *); } codes[] =
57 58 archive_write_set_format_pax_restricted },
58 59 { ARCHIVE_FORMAT_TAR_USTAR, archive_write_set_format_ustar },
59 60 { ARCHIVE_FORMAT_XAR, archive_write_set_format_xar },
60   - { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
  61 + { ARCHIVE_FORMAT_ZIP, archive_write_set_format_zip },
61 62 { 0, NULL }
62 63 };
63 64
1  libarchive/archive_write_set_format_by_name.c
@@ -63,6 +63,7 @@ struct { const char *name; int (*setter)(struct archive *); } names[] =
63 63 { "pax", archive_write_set_format_pax },
64 64 { "paxr", archive_write_set_format_pax_restricted },
65 65 { "posix", archive_write_set_format_pax },
  66 + { "raw", archive_write_set_format_raw },
66 67 { "rpax", archive_write_set_format_pax_restricted },
67 68 { "shar", archive_write_set_format_shar },
68 69 { "shardump", archive_write_set_format_shar_dump },
125 libarchive/archive_write_set_format_raw.c
... ... @@ -0,0 +1,125 @@
  1 +/*-
  2 + * Copyright (c) 2013 Marek Kubica
  3 + * All rights reserved.
  4 + *
  5 + * Redistribution and use in source and binary forms, with or without
  6 + * modification, are permitted provided that the following conditions
  7 + * are met:
  8 + * 1. Redistributions of source code must retain the above copyright
  9 + * notice, this list of conditions and the following disclaimer.
  10 + * 2. Redistributions in binary form must reproduce the above copyright
  11 + * notice, this list of conditions and the following disclaimer in the
  12 + * documentation and/or other materials provided with the distribution.
  13 + *
  14 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17 + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24 + */
  25 +
  26 +#include "archive_platform.h"
  27 +
  28 +#ifdef HAVE_ERRNO_H
  29 +#include <errno.h>
  30 +#endif
  31 +
  32 +#include "archive_entry.h"
  33 +#include "archive_write_private.h"
  34 +
  35 +static ssize_t archive_write_raw_data(struct archive_write *,
  36 + const void *buff, size_t s);
  37 +static int archive_write_raw_free(struct archive_write *);
  38 +static int archive_write_raw_header(struct archive_write *,
  39 + struct archive_entry *);
  40 +
  41 +struct raw {
  42 + int entries_written;
  43 +};
  44 +
  45 +/*
  46 + * Set output format to 'raw' format.
  47 + */
  48 +int
  49 +archive_write_set_format_raw(struct archive *_a)
  50 +{
  51 + struct archive_write *a = (struct archive_write *)_a;
  52 + struct raw *raw;
  53 +
  54 + archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
  55 + ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
  56 +
  57 + /* If someone else was already registered, unregister them. */
  58 + if (a->format_free != NULL)
  59 + (a->format_free)(a);
  60 +
  61 + raw = (struct raw *)calloc(1, sizeof(*raw));
  62 + if (raw == NULL) {
  63 + archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
  64 + return (ARCHIVE_FATAL);
  65 + }
  66 + raw->entries_written = 0;
  67 + a->format_data = raw;
  68 + a->format_name = "raw";
  69 + /* no options exist for this format */
  70 + a->format_options = NULL;
  71 + a->format_write_header = archive_write_raw_header;
  72 + a->format_write_data = archive_write_raw_data;
  73 + a->format_finish_entry = NULL;
  74 + /* nothing needs to be done on closing */
  75 + a->format_close = NULL;
  76 + a->format_free = archive_write_raw_free;
  77 + a->archive.archive_format = ARCHIVE_FORMAT_RAW;
  78 + a->archive.archive_format_name = "RAW";
  79 + return (ARCHIVE_OK);
  80 +}
  81 +
  82 +static int
  83 +archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
  84 +{
  85 + struct raw *raw = (struct raw *)a->format_data;
  86 +
  87 + if (archive_entry_filetype(entry) != AE_IFREG) {
  88 + archive_set_error(&a->archive, ERANGE,
  89 + "Raw format only supports filetype AE_IFREG");
  90 + return (ARCHIVE_FATAL);
  91 + }
  92 +
  93 +
  94 + if (raw->entries_written > 0) {
  95 + archive_set_error(&a->archive, ERANGE,
  96 + "Raw format only supports one entry per archive");
  97 + return (ARCHIVE_FATAL);
  98 + }
  99 + raw->entries_written++;
  100 +
  101 + return (ARCHIVE_OK);
  102 +}
  103 +
  104 +static ssize_t
  105 +archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
  106 +{
  107 + int ret;
  108 +
  109 + ret = __archive_write_output(a, buff, s);
  110 + if (ret >= 0)
  111 + return (s);
  112 + else
  113 + return (ret);
  114 +}
  115 +
  116 +static int
  117 +archive_write_raw_free(struct archive_write *a)
  118 +{
  119 + struct raw *raw;
  120 +
  121 + raw = (struct raw *)a->format_data;
  122 + free(raw);
  123 + a->format_data = NULL;
  124 + return (ARCHIVE_OK);
  125 +}
2  libarchive/test/CMakeLists.txt
@@ -201,6 +201,8 @@ IF(ENABLE_TEST)
201 201 test_write_format_mtree_no_separator.c
202 202 test_write_format_mtree_quoted_filename.c
203 203 test_write_format_pax.c
  204 + test_write_format_raw.c
  205 + test_write_format_raw_b64.c
204 206 test_write_format_shar_empty.c
205 207 test_write_format_tar.c
206 208 test_write_format_tar_empty.c
123 libarchive/test/test_write_format_raw.c
... ... @@ -0,0 +1,123 @@
  1 +/*-
  2 + * Copyright (c) 2013 Marek Kubica
  3 + * All rights reserved.
  4 + *
  5 + * Redistribution and use in source and binary forms, with or without
  6 + * modification, are permitted provided that the following conditions
  7 + * are met:
  8 + * 1. Redistributions of source code must retain the above copyright
  9 + * notice, this list of conditions and the following disclaimer.
  10 + * 2. Redistributions in binary form must reproduce the above copyright
  11 + * notice, this list of conditions and the following disclaimer in the
  12 + * documentation and/or other materials provided with the distribution.
  13 + *
  14 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17 + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24 + */
  25 +#include "test.h"
  26 +
  27 +static void
  28 +test_format(int (*set_format)(struct archive *))
  29 +{
  30 + char filedata[64];
  31 + struct archive_entry *ae;
  32 + struct archive *a;
  33 + size_t used;
  34 + size_t buffsize = 1000000;
  35 + char *buff;
  36 + const char *err;
  37 +
  38 + buff = malloc(buffsize);
  39 +
  40 + /* Create a new archive in memory. */
  41 + assert((a = archive_write_new()) != NULL);
  42 + assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
  43 + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
  44 + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));
  45 +
  46 + /*
  47 + * Write a file to it.
  48 + */
  49 + assert((ae = archive_entry_new()) != NULL);
  50 + archive_entry_set_pathname(ae, "test");
  51 + archive_entry_set_filetype(ae, AE_IFREG);
  52 + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
  53 + archive_entry_free(ae);
  54 + assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9));
  55 + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
  56 + assertEqualInt(ARCHIVE_OK, archive_write_free(a));
  57 +
  58 + /*
  59 + * Read from it.
  60 + */
  61 + assert((a = archive_read_new()) != NULL);
  62 + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
  63 + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a));
  64 + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
  65 +
  66 + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
  67 + assertEqualIntA(a, 9, archive_read_data(a, filedata, 10));
  68 + assertEqualMem(filedata, "12345678", 9);
  69 + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
  70 + assertEqualInt(ARCHIVE_OK, archive_read_free(a));
  71 +
  72 + /* Create a new archive */
  73 + assert((a = archive_write_new()) != NULL);
  74 + assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
  75 + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
  76 + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));
  77 +
  78 + /* write first file: that should succeed */
  79 + assert((ae = archive_entry_new()) != NULL);
  80 + archive_entry_set_pathname(ae, "test");
  81 + archive_entry_set_filetype(ae, AE_IFREG);
  82 + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
  83 + archive_entry_free(ae);
  84 + assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9));
  85 +
  86 + /* write second file: this should fail */
  87 + assert((ae = archive_entry_new()) != NULL);
  88 + archive_entry_set_pathname(ae, "test2");
  89 + archive_entry_set_filetype(ae, AE_IFREG);
  90 + assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae));
  91 + err = archive_error_string(a);
  92 + assertEqualMem(err, "Raw format only supports one entry per archive", 47);
  93 + archive_entry_free(ae);
  94 +
  95 + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
  96 + assertEqualInt(ARCHIVE_OK, archive_write_free(a));
  97 +
  98 + /* Create a new archive */
  99 + assert((a = archive_write_new()) != NULL);
  100 + assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
  101 + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
  102 + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));
  103 +
  104 + /* write a directory: this should fail */
  105 + assert((ae = archive_entry_new()) != NULL);
  106 + archive_entry_copy_pathname(ae, "dir");
  107 + archive_entry_set_filetype(ae, AE_IFDIR);
  108 + archive_entry_set_size(ae, 512);
  109 + assertEqualIntA(a, ARCHIVE_FATAL, archive_write_header(a, ae));
  110 + err = archive_error_string(a);
  111 + assertEqualMem(err, "Raw format only supports filetype AE_IFREG", 43);
  112 + archive_entry_free(ae);
  113 +
  114 + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
  115 + assertEqualInt(ARCHIVE_OK, archive_write_free(a));
  116 +
  117 + free(buff);
  118 +}
  119 +
  120 +DEFINE_TEST(test_write_format_raw)
  121 +{
  122 + test_format(archive_write_set_format_raw);
  123 +}
77 libarchive/test/test_write_format_raw_b64.c
... ... @@ -0,0 +1,77 @@
  1 +/*-
  2 + * Copyright (c) 2013 Marek Kubica
  3 + * All rights reserved.
  4 + *
  5 + * Redistribution and use in source and binary forms, with or without
  6 + * modification, are permitted provided that the following conditions
  7 + * are met:
  8 + * 1. Redistributions of source code must retain the above copyright
  9 + * notice, this list of conditions and the following disclaimer.
  10 + * 2. Redistributions in binary form must reproduce the above copyright
  11 + * notice, this list of conditions and the following disclaimer in the
  12 + * documentation and/or other materials provided with the distribution.
  13 + *
  14 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
  15 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17 + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
  18 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24 + */
  25 +#include "test.h"
  26 +
  27 +static void
  28 +test_format(int (*set_format)(struct archive *))
  29 +{
  30 + char filedata[64];
  31 + struct archive_entry *ae;
  32 + struct archive *a;
  33 + size_t used;
  34 + size_t buffsize = 1000000;
  35 + char *buff;
  36 +
  37 + buff = malloc(buffsize);
  38 +
  39 + /* Create a new archive in memory. */
  40 + assert((a = archive_write_new()) != NULL);
  41 + assertEqualIntA(a, ARCHIVE_OK, (*set_format)(a));
  42 + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_b64encode(a));
  43 + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used));
  44 +
  45 + /*
  46 + * Write a file to it.
  47 + */
  48 + assert((ae = archive_entry_new()) != NULL);
  49 + archive_entry_set_pathname(ae, "test");
  50 + archive_entry_set_filetype(ae, AE_IFREG);
  51 + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
  52 + archive_entry_free(ae);
  53 + assertEqualIntA(a, 9, archive_write_data(a, "12345678", 9));
  54 + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
  55 + assertEqualInt(ARCHIVE_OK, archive_write_free(a));
  56 +
  57 + /*
  58 + * Read from it.
  59 + */
  60 + assert((a = archive_read_new()) != NULL);
  61 + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a));
  62 + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_none(a));
  63 + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
  64 +
  65 + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
  66 + assertEqualIntA(a, 37, archive_read_data(a, filedata, 64));
  67 + assertEqualMem(filedata, "begin-base64 644 -\nMTIzNDU2NzgA\n====\n", 37);
  68 + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
  69 + assertEqualInt(ARCHIVE_OK, archive_read_free(a));
  70 +
  71 + free(buff);
  72 +}
  73 +
  74 +DEFINE_TEST(test_write_format_raw_b64)
  75 +{
  76 + test_format(archive_write_set_format_raw);
  77 +}

0 comments on commit e5d1fbb

Please sign in to comment.
Something went wrong with that request. Please try again.