Date: Fri, 6 Mar 2009 05:58:56 +0000 (UTC) From: Tim Kientzle <kientzle@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r189438 - head/lib/libarchive Message-ID: <200903060558.n265wuv1009950@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903060558.n265wuv1009950>