svn commit: r189438 - head/lib/libarchive
Tim Kientzle
kientzle at FreeBSD.org
Thu Mar 5 21:58:58 PST 2009
Author: kientzle
Date: Fri Mar 6 05:58:56 2009
New Revision: 189438
URL: http://svn.freebsd.org/changeset/base/189438
Log:
Merge r491,493,500,507,510,530,543 from libarchive.googlecode.com:
This implements the new generic options framework that provides a way
to override format- and compression-specific parameters.
Modified:
head/lib/libarchive/archive.h
head/lib/libarchive/archive_private.h
head/lib/libarchive/archive_read.c
head/lib/libarchive/archive_read_private.h
head/lib/libarchive/archive_read_support_compression_bzip2.c
head/lib/libarchive/archive_read_support_compression_compress.c
head/lib/libarchive/archive_read_support_compression_gzip.c
head/lib/libarchive/archive_read_support_compression_program.c
head/lib/libarchive/archive_read_support_format_ar.c
head/lib/libarchive/archive_read_support_format_cpio.c
head/lib/libarchive/archive_read_support_format_empty.c
head/lib/libarchive/archive_read_support_format_iso9660.c
head/lib/libarchive/archive_read_support_format_mtree.c
head/lib/libarchive/archive_read_support_format_tar.c
head/lib/libarchive/archive_read_support_format_zip.c
head/lib/libarchive/archive_util.c
head/lib/libarchive/archive_write.c
head/lib/libarchive/archive_write_private.h
head/lib/libarchive/archive_write_set_compression_gzip.c
head/lib/libarchive/archive_write_set_format_ar.c
head/lib/libarchive/archive_write_set_format_cpio.c
head/lib/libarchive/archive_write_set_format_cpio_newc.c
head/lib/libarchive/archive_write_set_format_mtree.c
head/lib/libarchive/archive_write_set_format_pax.c
head/lib/libarchive/archive_write_set_format_shar.c
head/lib/libarchive/archive_write_set_format_ustar.c
Modified: head/lib/libarchive/archive.h
==============================================================================
--- head/lib/libarchive/archive.h Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive.h Fri Mar 6 05:58:56 2009 (r189438)
@@ -384,6 +384,19 @@ __LA_DECL int archive_read_data_into_b
void *buffer, __LA_SSIZE_T len);
__LA_DECL int archive_read_data_into_fd(struct archive *, int fd);
+/*
+ * Set read options.
+ */
+/* Apply option string to the format only. */
+__LA_DECL int archive_read_set_format_options(struct archive *_a,
+ const char *s);
+/* Apply option string to the filter only. */
+__LA_DECL int archive_read_set_filter_options(struct archive *_a,
+ const char *s);
+/* Apply option string to both the format and the filter. */
+__LA_DECL int archive_read_set_options(struct archive *_a,
+ const char *s);
+
/*-
* Convenience function to recreate the current entry (whose header
* has just been read) on disk.
@@ -552,6 +565,20 @@ __LA_DECL void archive_write_finish(st
__LA_DECL int archive_write_finish(struct archive *);
#endif
+/*
+ * Set write options.
+ */
+/* Apply option string to the format only. */
+__LA_DECL int archive_write_set_format_options(struct archive *_a,
+ const char *s);
+/* Apply option string to the compressor only. */
+__LA_DECL int archive_write_set_compressor_options(struct archive *_a,
+ const char *s);
+/* Apply option string to both the format and the compressor. */
+__LA_DECL int archive_write_set_options(struct archive *_a,
+ const char *s);
+
+
/*-
* To create objects on disk:
* 1) Ask archive_write_disk_new for a new archive_write_disk object.
Modified: head/lib/libarchive/archive_private.h
==============================================================================
--- head/lib/libarchive/archive_private.h Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_private.h Fri Mar 6 05:58:56 2009 (r189438)
@@ -102,6 +102,9 @@ void __archive_check_magic(struct archiv
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
+int __archive_parse_options(const char *p, const char *fn,
+ int keysize, char *key, int valsize, char *val);
+
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
#endif
Modified: head/lib/libarchive/archive_read.c
==============================================================================
--- head/lib/libarchive/archive_read.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -108,6 +108,95 @@ archive_read_extract_set_skip_file(struc
a->skip_file_ino = i;
}
+/*
+ * Set read options for the format.
+ */
+int
+archive_read_set_format_options(struct archive *_a, const char *s)
+{
+ struct archive_read *a;
+ char key[64], val[64];
+ int len, r;
+
+ a = (struct archive_read *)_a;
+ if (a->format == NULL || a->format->options == NULL ||
+ a->format->name == NULL)
+ /* This format does not support option. */
+ return (ARCHIVE_OK);
+
+ while ((len = __archive_parse_options(s, a->format->name,
+ sizeof(key), key, sizeof(val), val)) > 0) {
+ if (val[0] == '\0')
+ r = a->format->options(a, key, NULL);
+ else
+ r = a->format->options(a, key, val);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ s += len;
+ }
+ if (len < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Illegal format options.");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Set read options for the filter.
+ */
+int
+archive_read_set_filter_options(struct archive *_a, const char *s)
+{
+ struct archive_read *a;
+ struct archive_read_filter *filter;
+ struct archive_read_filter_bidder *bidder;
+ char key[64], val[64];
+ int len, r;
+
+ a = (struct archive_read *)_a;
+ filter = a->filter;
+ len = 0;
+ for (filter = a->filter; filter != NULL; filter = filter->upstream) {
+ bidder = filter->bidder;
+ if (bidder->options == NULL)
+ /* This bidder does not support option */
+ continue;
+ while ((len = __archive_parse_options(s, filter->name,
+ sizeof(key), key, sizeof(val), val)) > 0) {
+ if (val[0] == '\0')
+ r = bidder->options(bidder, key, NULL);
+ else
+ r = bidder->options(bidder, key, val);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ s += len;
+ }
+ }
+ if (len < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Illegal format options.");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Set read options for the format and the filter.
+ */
+int
+archive_read_set_options(struct archive *_a, const char *s)
+{
+ int r;
+
+ r = archive_read_set_format_options(_a, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = archive_read_set_filter_options(_a, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ return (ARCHIVE_OK);
+}
/*
* Open the archive
@@ -658,7 +747,9 @@ _archive_read_finish(struct archive *_a)
int
__archive_read_register_format(struct archive_read *a,
void *format_data,
+ const char *name,
int (*bid)(struct archive_read *),
+ int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
int (*read_data)(struct archive_read *, const void **, size_t *, off_t *),
int (*read_data_skip)(struct archive_read *),
@@ -677,11 +768,13 @@ __archive_read_register_format(struct ar
return (ARCHIVE_WARN); /* We've already installed */
if (a->formats[i].bid == NULL) {
a->formats[i].bid = bid;
+ a->formats[i].options = options;
a->formats[i].read_header = read_header;
a->formats[i].read_data = read_data;
a->formats[i].read_data_skip = read_data_skip;
a->formats[i].cleanup = cleanup;
a->formats[i].data = format_data;
+ a->formats[i].name = name;
return (ARCHIVE_OK);
}
}
Modified: head/lib/libarchive/archive_read_private.h
==============================================================================
--- head/lib/libarchive/archive_read_private.h Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_private.h Fri Mar 6 05:58:56 2009 (r189438)
@@ -54,6 +54,9 @@ struct archive_read_filter_bidder {
struct archive_read_filter *);
/* Initialize a newly-created filter. */
int (*init)(struct archive_read_filter *);
+ /* Set an option for the filter bidder. */
+ int (*options)(struct archive_read_filter_bidder *,
+ const char *key, const char *value);
/* Release the bidder's configuration data. */
int (*free)(struct archive_read_filter_bidder *);
};
@@ -149,7 +152,10 @@ struct archive_read {
struct archive_format_descriptor {
void *data;
+ const char *name;
int (*bid)(struct archive_read *);
+ int (*options)(struct archive_read *, const char *key,
+ const char *value);
int (*read_header)(struct archive_read *, struct archive_entry *);
int (*read_data)(struct archive_read *, const void **, size_t *, off_t *);
int (*read_data_skip)(struct archive_read *);
@@ -166,7 +172,9 @@ struct archive_read {
int __archive_read_register_format(struct archive_read *a,
void *format_data,
+ const char *name,
int (*bid)(struct archive_read *),
+ int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
int (*read_data)(struct archive_read *, const void **, size_t *, off_t *),
int (*read_data_skip)(struct archive_read *),
Modified: head/lib/libarchive/archive_read_support_compression_bzip2.c
==============================================================================
--- head/lib/libarchive/archive_read_support_compression_bzip2.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_compression_bzip2.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -84,6 +84,7 @@ archive_read_support_compression_bzip2(s
reader->data = NULL;
reader->bid = bzip2_reader_bid;
reader->init = bzip2_reader_init;
+ reader->options = NULL;
reader->free = bzip2_reader_free;
return (ARCHIVE_OK);
}
Modified: head/lib/libarchive/archive_read_support_compression_compress.c
==============================================================================
--- head/lib/libarchive/archive_read_support_compression_compress.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_compression_compress.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -152,6 +152,7 @@ archive_read_support_compression_compres
bidder->data = NULL;
bidder->bid = compress_bidder_bid;
bidder->init = compress_bidder_init;
+ bidder->options = NULL;
bidder->free = compress_bidder_free;
return (ARCHIVE_OK);
}
Modified: head/lib/libarchive/archive_read_support_compression_gzip.c
==============================================================================
--- head/lib/libarchive/archive_read_support_compression_gzip.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_compression_gzip.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -90,7 +90,8 @@ archive_read_support_compression_gzip(st
bidder->data = NULL;
bidder->bid = gzip_bidder_bid;
bidder->init = gzip_bidder_init;
- bidder->free = NULL; /* No data, so no cleanup necessary. */
+ bidder->options = NULL;
+ bidder->free = NULL;
return (ARCHIVE_OK);
}
Modified: head/lib/libarchive/archive_read_support_compression_program.c
==============================================================================
--- head/lib/libarchive/archive_read_support_compression_program.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_compression_program.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -122,6 +122,7 @@ archive_read_support_compression_program
bidder->data = state;
bidder->bid = program_bidder_bid;
bidder->init = program_bidder_init;
+ bidder->options = NULL;
bidder->free = program_bidder_free;
return (ARCHIVE_OK);
}
Modified: head/lib/libarchive/archive_read_support_format_ar.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_ar.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_ar.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -105,7 +105,9 @@ archive_read_support_format_ar(struct ar
r = __archive_read_register_format(a,
ar,
+ "ar",
archive_read_format_ar_bid,
+ NULL,
archive_read_format_ar_read_header,
archive_read_format_ar_read_data,
archive_read_format_ar_skip,
Modified: head/lib/libarchive/archive_read_support_format_cpio.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_cpio.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_cpio.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -150,7 +150,9 @@ archive_read_support_format_cpio(struct
r = __archive_read_register_format(a,
cpio,
+ "cpio",
archive_read_format_cpio_bid,
+ NULL,
archive_read_format_cpio_read_header,
archive_read_format_cpio_read_data,
NULL,
Modified: head/lib/libarchive/archive_read_support_format_empty.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_empty.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_empty.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -44,7 +44,9 @@ archive_read_support_format_empty(struct
r = __archive_read_register_format(a,
NULL,
+ NULL,
archive_read_format_empty_bid,
+ NULL,
archive_read_format_empty_read_header,
archive_read_format_empty_read_data,
NULL,
Modified: head/lib/libarchive/archive_read_support_format_iso9660.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_iso9660.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_iso9660.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -279,7 +279,9 @@ archive_read_support_format_iso9660(stru
r = __archive_read_register_format(a,
iso9660,
+ "iso9660",
archive_read_format_iso9660_bid,
+ NULL,
archive_read_format_iso9660_read_header,
archive_read_format_iso9660_read_data,
archive_read_format_iso9660_read_data_skip,
Modified: head/lib/libarchive/archive_read_support_format_mtree.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_mtree.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_mtree.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -148,8 +148,8 @@ archive_read_support_format_mtree(struct
memset(mtree, 0, sizeof(*mtree));
mtree->fd = -1;
- r = __archive_read_register_format(a, mtree,
- mtree_bid, read_header, read_data, skip, cleanup);
+ r = __archive_read_register_format(a, mtree, "mtree",
+ mtree_bid, NULL, read_header, read_data, skip, cleanup);
if (r != ARCHIVE_OK)
free(mtree);
Modified: head/lib/libarchive/archive_read_support_format_tar.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_tar.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_tar.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -253,8 +253,9 @@ archive_read_support_format_tar(struct a
}
memset(tar, 0, sizeof(*tar));
- r = __archive_read_register_format(a, tar,
+ r = __archive_read_register_format(a, tar, "tar",
archive_read_format_tar_bid,
+ NULL,
archive_read_format_tar_read_header,
archive_read_format_tar_read_data,
archive_read_format_tar_skip,
Modified: head/lib/libarchive/archive_read_support_format_zip.c
==============================================================================
--- head/lib/libarchive/archive_read_support_format_zip.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_read_support_format_zip.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -153,7 +153,9 @@ archive_read_support_format_zip(struct a
r = __archive_read_register_format(a,
zip,
+ "zip",
archive_read_format_zip_bid,
+ NULL,
archive_read_format_zip_read_header,
archive_read_format_zip_read_data,
archive_read_format_zip_read_data_skip,
Modified: head/lib/libarchive/archive_util.c
==============================================================================
--- head/lib/libarchive/archive_util.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_util.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2009 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
@@ -186,3 +187,195 @@ __archive_errx(int retvalue, const char
write(2, "\n", 1);
exit(retvalue);
}
+
+/*
+ * Parse option strings
+ * Detail of option format.
+ * - The option can accept:
+ * "opt-name", "!opt-name", "opt-name=value".
+ *
+ * - The option entries are separated by comma.
+ * e.g "compression=9,opt=XXX,opt-b=ZZZ"
+ *
+ * - The name of option string consist of '-' and alphabet
+ * but character '-' cannot be used for the first character.
+ * (Regular expression is [a-z][-a-z]+)
+ *
+ * - For a specfic format/filter, using the format name with ':'.
+ * e.g "zip:compression=9"
+ * (This "compression=9" option entry is for "zip" format only)
+ *
+ * If another entries follow it, those are not for
+ * the specfic format/filter.
+ * e.g handle "zip:compression=9,opt=XXX,opt-b=ZZZ"
+ * "zip" format/filter handler will get "compression=9"
+ * all format/filter handler will get "opt=XXX"
+ * all format/filter handler will get "opt-b=ZZZ"
+ *
+ * - Whitespace and tab are bypassed.
+ *
+ */
+int
+__archive_parse_options(const char *p, const char *fn, int keysize, char *key,
+ int valsize, char *val)
+{
+ const char *p_org;
+ int apply;
+ int kidx, vidx;
+ int negative;
+ enum {
+ /* Requested for initialization. */
+ INIT,
+ /* Finding format/filter-name and option-name. */
+ F_BOTH,
+ /* Finding option-name only.
+ * (already detected format/filter-name) */
+ F_NAME,
+ /* Getting option-value. */
+ G_VALUE,
+ } state;
+
+ p_org = p;
+ state = INIT;
+ kidx = vidx = negative = 0;
+ apply = 1;
+ while (*p) {
+ switch (state) {
+ case INIT:
+ kidx = vidx = 0;
+ negative = 0;
+ apply = 1;
+ state = F_BOTH;
+ break;
+ case F_BOTH:
+ case F_NAME:
+ if ((*p >= 'a' && *p <= 'z') ||
+ (*p >= '0' && *p <= '9') || *p == '-') {
+ if (kidx == 0 && !(*p >= 'a' && *p <= 'z'))
+ /* Illegal sequence. */
+ return (-1);
+ if (kidx >= keysize -1)
+ /* Too many characters. */
+ return (-1);
+ key[kidx++] = *p++;
+ } else if (*p == '!') {
+ if (kidx != 0)
+ /* Illegal sequence. */
+ return (-1);
+ negative = 1;
+ ++p;
+ } else if (*p == ',') {
+ if (kidx == 0)
+ /* Illegal sequence. */
+ return (-1);
+ if (!negative)
+ val[vidx++] = '1';
+ /* We have got boolean option data. */
+ ++p;
+ if (apply)
+ goto complete;
+ else
+ /* This option does not apply to the
+ * format which the fn variable
+ * indicate. */
+ state = INIT;
+ } else if (*p == ':') {
+ /* obuf data is format name */
+ if (state == F_NAME)
+ /* We already found it. */
+ return (-1);
+ if (kidx == 0)
+ /* Illegal sequence. */
+ return (-1);
+ if (negative)
+ /* We cannot accept "!format-name:". */
+ return (-1);
+ key[kidx] = '\0';
+ if (strcmp(fn, key) != 0)
+ /* This option does not apply to the
+ * format which the fn variable
+ * indicate. */
+ apply = 0;
+ kidx = 0;
+ ++p;
+ state = F_NAME;
+ } else if (*p == '=') {
+ if (kidx == 0)
+ /* Illegal sequence. */
+ return (-1);
+ if (negative)
+ /* We cannot accept "!opt-name=value". */
+ return (-1);
+ ++p;
+ state = G_VALUE;
+ } else if (*p == ' ') {
+ /* Pass the space character */
+ ++p;
+ } else {
+ /* Illegal character. */
+ return (-1);
+ }
+ break;
+ case G_VALUE:
+ if (*p == ',') {
+ if (vidx == 0)
+ /* Illegal sequence. */
+ return (-1);
+ /* We have got option data. */
+ ++p;
+ if (apply)
+ goto complete;
+ else
+ /* This option does not apply to the
+ * format which the fn variable
+ * indicate. */
+ state = INIT;
+ } else if (*p == ' ') {
+ /* Pass the space character */
+ ++p;
+ } else {
+ if (vidx >= valsize -1)
+ /* Too many characters. */
+ return (-1);
+ val[vidx++] = *p++;
+ }
+ break;
+ }
+ }
+
+ switch (state) {
+ case F_BOTH:
+ case F_NAME:
+ if (kidx != 0) {
+ if (!negative)
+ val[vidx++] = '1';
+ /* We have got boolean option. */
+ if (apply)
+ /* This option apply to the format which the
+ * fn variable indicate. */
+ goto complete;
+ }
+ break;
+ case G_VALUE:
+ if (vidx == 0)
+ /* Illegal sequence. */
+ return (-1);
+ /* We have got option value. */
+ if (apply)
+ /* This option apply to the format which the fn
+ * variable indicate. */
+ goto complete;
+ break;
+ case INIT:/* nothing */
+ break;
+ }
+
+ /* End of Option string. */
+ return (0);
+
+complete:
+ key[kidx] = '\0';
+ val[vidx] = '\0';
+ /* Return a size which we've consumed for detecting option */
+ return ((int)(p - p_org));
+}
Modified: head/lib/libarchive/archive_write.c
==============================================================================
--- head/lib/libarchive/archive_write.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -125,6 +125,87 @@ archive_write_new(void)
}
/*
+ * Set write options for the format. Returns 0 if successful.
+ */
+int
+archive_write_set_format_options(struct archive *_a, const char *s)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ char key[64], val[64];
+ int len, r;
+
+ if (a->format_options == NULL)
+ /* This format does not support option. */
+ return (ARCHIVE_OK);
+
+ while ((len = __archive_parse_options(s, a->format_name,
+ sizeof(key), key, sizeof(val), val)) > 0) {
+ if (val[0] == '\0')
+ r = a->format_options(a, key, NULL);
+ else
+ r = a->format_options(a, key, val);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ s += len;
+ }
+ if (len < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Illegal format options.");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Set write options for the compressor. Returns 0 if successful.
+ */
+int
+archive_write_set_compressor_options(struct archive *_a, const char *s)
+{
+ struct archive_write *a = (struct archive_write *)_a;
+ char key[64], val[64];
+ int len, r;
+
+ if (a->compressor.options == NULL)
+ /* This compressor does not support option. */
+ return (ARCHIVE_OK);
+
+ while ((len = __archive_parse_options(s, a->archive.compression_name,
+ sizeof(key), key, sizeof(val), val)) > 0) {
+ if (val[0] == '\0')
+ r = a->compressor.options(a, key, NULL);
+ else
+ r = a->compressor.options(a, key, val);
+ if (r == ARCHIVE_FATAL)
+ return (r);
+ s += len;
+ }
+ if (len < 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Illegal format options.");
+ return (ARCHIVE_WARN);
+ }
+ return (ARCHIVE_OK);
+}
+
+/*
+ * Set write options for the format and the compressor. Returns 0 if successful.
+ */
+int
+archive_write_set_options(struct archive *_a, const char *s)
+{
+ int r;
+
+ r = archive_write_set_format_options(_a, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ r = archive_write_set_compressor_options(_a, s);
+ if (r != ARCHIVE_OK)
+ return (r);
+ return (ARCHIVE_OK);
+}
+
+/*
* Set the block size. Returns 0 if successful.
*/
int
Modified: head/lib/libarchive/archive_write_private.h
==============================================================================
--- head/lib/libarchive/archive_write_private.h Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_private.h Fri Mar 6 05:58:56 2009 (r189438)
@@ -77,6 +77,8 @@ struct archive_write {
void *data;
void *config;
int (*init)(struct archive_write *);
+ int (*options)(struct archive_write *,
+ const char *key, const char *value);
int (*finish)(struct archive_write *);
int (*write)(struct archive_write *, const void *, size_t);
} compressor;
@@ -86,7 +88,10 @@ struct archive_write {
* initialized by archive_write_set_format_XXX() calls.
*/
void *format_data;
+ const char *format_name;
int (*format_init)(struct archive_write *);
+ int (*format_options)(struct archive_write *,
+ const char *key, const char *value);
int (*format_finish)(struct archive_write *);
int (*format_destroy)(struct archive_write *);
int (*format_finish_entry)(struct archive_write *);
Modified: head/lib/libarchive/archive_write_set_compression_gzip.c
==============================================================================
--- head/lib/libarchive/archive_write_set_compression_gzip.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_compression_gzip.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -61,6 +61,8 @@ struct private_data {
unsigned char *compressed;
size_t compressed_buffer_size;
unsigned long crc;
+ /* Options */
+ int compression_level;
};
@@ -73,6 +75,8 @@ struct private_data {
static int archive_compressor_gzip_finish(struct archive_write *);
static int archive_compressor_gzip_init(struct archive_write *);
+static int archive_compressor_gzip_options(struct archive_write *,
+ const char *, const char *);
static int archive_compressor_gzip_write(struct archive_write *,
const void *, size_t);
static int drive_compressor(struct archive_write *, struct private_data *,
@@ -143,6 +147,7 @@ archive_compressor_gzip_init(struct arch
state->compressed_buffer_size = a->bytes_per_block;
state->compressed = (unsigned char *)malloc(state->compressed_buffer_size);
state->crc = crc32(0L, NULL, 0);
+ state->compression_level = Z_DEFAULT_COMPRESSION;
if (state->compressed == NULL) {
archive_set_error(&a->archive, ENOMEM,
@@ -169,12 +174,13 @@ archive_compressor_gzip_init(struct arch
state->stream.next_out += 10;
state->stream.avail_out -= 10;
+ a->compressor.options = archive_compressor_gzip_options;
a->compressor.write = archive_compressor_gzip_write;
a->compressor.finish = archive_compressor_gzip_finish;
/* Initialize compression library. */
ret = deflateInit2(&(state->stream),
- Z_DEFAULT_COMPRESSION,
+ state->compression_level,
Z_DEFLATED,
-15 /* < 0 to suppress zlib header */,
8,
@@ -213,6 +219,57 @@ archive_compressor_gzip_init(struct arch
}
/*
+ * Set write options.
+ */
+static int
+archive_compressor_gzip_options(struct archive_write *a, const char *key,
+ const char *value)
+{
+ struct private_data *state;
+ int ret;
+
+ state = (struct private_data *)a->compressor.data;
+ if (strcmp(key, "compression-level") == 0) {
+ int level;
+
+ if (value == NULL || !(value[0] >= '0' && value[0] <= '9') ||
+ value[1] != '\0')
+ return (ARCHIVE_WARN);
+ level = value[0] - '0';
+ if (level == state->compression_level)
+ return (ARCHIVE_OK);
+
+ ret = deflateParams(&(state->stream), level,
+ Z_DEFAULT_STRATEGY);
+ if (ret == Z_OK) {
+ state->compression_level = level;
+ return (ARCHIVE_OK);
+ }
+ switch (ret) {
+ case Z_STREAM_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error updating params "
+ "compression library: state was inconsistent "
+ "or parameter was invalid");
+ break;
+ case Z_BUF_ERROR:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error updating params "
+ "compression library: out buffer was zero");
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Internal error updatng params "
+ "compression library");
+ break;
+ }
+ return (ARCHIVE_FATAL);
+ }
+
+ return (ARCHIVE_WARN);
+}
+
+/*
* Write data to the compressed stream.
*/
static int
Modified: head/lib/libarchive/archive_write_set_format_ar.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_ar.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_ar.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -125,6 +125,7 @@ archive_write_set_format_ar(struct archi
memset(ar, 0, sizeof(*ar));
a->format_data = ar;
+ a->format_name = "ar";
a->format_write_header = archive_write_ar_header;
a->format_write_data = archive_write_ar_data;
a->format_finish = archive_write_ar_finish;
Modified: head/lib/libarchive/archive_write_set_format_cpio.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_cpio.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_cpio.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -92,6 +92,7 @@ archive_write_set_format_cpio(struct arc
a->format_data = cpio;
a->pad_uncompressed = 1;
+ a->format_name = "cpio";
a->format_write_header = archive_write_cpio_header;
a->format_write_data = archive_write_cpio_data;
a->format_finish_entry = archive_write_cpio_finish_entry;
Modified: head/lib/libarchive/archive_write_set_format_cpio_newc.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_cpio_newc.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_cpio_newc.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -97,6 +97,7 @@ archive_write_set_format_cpio_newc(struc
a->format_data = cpio;
a->pad_uncompressed = 1;
+ a->format_name = "cpio";
a->format_write_header = archive_write_newc_header;
a->format_write_data = archive_write_newc_data;
a->format_finish_entry = archive_write_newc_finish_entry;
Modified: head/lib/libarchive/archive_write_set_format_mtree.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_mtree.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_mtree.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -107,6 +107,20 @@ archive_write_mtree_header(struct archiv
return (ARCHIVE_OK);
}
+#if 0
+static void
+strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
+{
+ static const char hex[] = "0123456789abcdef";
+ int i;
+
+ for (i = 0; i < n; i++) {
+ archive_strappend_char(s, hex[bin[i] >> 4]);
+ archive_strappend_char(s, hex[bin[i] & 0x0f]);
+ }
+}
+#endif
+
static int
archive_write_mtree_finish_entry(struct archive_write *a)
{
@@ -248,6 +262,7 @@ archive_write_set_format_mtree(struct ar
a->format_destroy = archive_write_mtree_destroy;
a->pad_uncompressed = 0;
+ a->format_name = "mtree";
a->format_write_header = archive_write_mtree_header;
a->format_finish = archive_write_mtree_finish;
a->format_write_data = archive_write_mtree_data;
Modified: head/lib/libarchive/archive_write_set_format_pax.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_pax.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_pax.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -111,6 +111,7 @@ archive_write_set_format_pax(struct arch
a->format_data = pax;
a->pad_uncompressed = 1;
+ a->format_name = "pax";
a->format_write_header = archive_write_pax_header;
a->format_write_data = archive_write_pax_data;
a->format_finish = archive_write_pax_finish;
Modified: head/lib/libarchive/archive_write_set_format_shar.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_shar.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_shar.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -121,6 +121,7 @@ archive_write_set_format_shar(struct arc
a->format_data = shar;
a->pad_uncompressed = 0;
+ a->format_name = "shar";
a->format_write_header = archive_write_shar_header;
a->format_finish = archive_write_shar_finish;
a->format_destroy = archive_write_shar_destroy;
Modified: head/lib/libarchive/archive_write_set_format_ustar.c
==============================================================================
--- head/lib/libarchive/archive_write_set_format_ustar.c Fri Mar 6 05:40:09 2009 (r189437)
+++ head/lib/libarchive/archive_write_set_format_ustar.c Fri Mar 6 05:58:56 2009 (r189438)
@@ -181,6 +181,7 @@ archive_write_set_format_ustar(struct ar
a->format_data = ustar;
a->pad_uncompressed = 1; /* Mimic gtar in this respect. */
+ a->format_name = "ustar";
a->format_write_header = archive_write_ustar_header;
a->format_write_data = archive_write_ustar_data;
a->format_finish = archive_write_ustar_finish;
More information about the svn-src-all
mailing list