1248590Smm/*- 2248590Smm * Copyright (c) 2003-2012 Tim Kientzle 3248590Smm * All rights reserved. 4248590Smm * 5248590Smm * Redistribution and use in source and binary forms, with or without 6248590Smm * modification, are permitted provided that the following conditions 7248590Smm * are met: 8248590Smm * 1. Redistributions of source code must retain the above copyright 9248590Smm * notice, this list of conditions and the following disclaimer. 10248590Smm * 2. Redistributions in binary form must reproduce the above copyright 11248590Smm * notice, this list of conditions and the following disclaimer in the 12248590Smm * documentation and/or other materials provided with the distribution. 13248590Smm * 14248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17248590Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24248590Smm */ 25248590Smm 26248590Smm#include "archive_platform.h" 27248590Smm__FBSDID("$FreeBSD$"); 28248590Smm 29248590Smm#ifdef HAVE_ERRNO_H 30248590Smm#include <errno.h> 31248590Smm#endif 32248590Smm 33248590Smm#include "archive.h" 34248590Smm#include "archive_private.h" 35248590Smm#include "archive_read_private.h" 36248590Smm 37248590Smmint 38248590Smmarchive_read_append_filter(struct archive *_a, int code) 39248590Smm{ 40248590Smm int r1, r2, number_bidders, i; 41248590Smm char str[20]; 42248590Smm struct archive_read_filter_bidder *bidder; 43248590Smm struct archive_read_filter *filter; 44248590Smm struct archive_read *a = (struct archive_read *)_a; 45248590Smm 46248590Smm r1 = r2 = (ARCHIVE_OK); 47248590Smm switch (code) 48248590Smm { 49248590Smm case ARCHIVE_FILTER_NONE: 50248590Smm /* No filter to add, so do nothing. 51248590Smm * NOTE: An initial "NONE" type filter is always set at the end of the 52248590Smm * filter chain. 53248590Smm */ 54248590Smm r1 = (ARCHIVE_OK); 55248590Smm break; 56248590Smm case ARCHIVE_FILTER_GZIP: 57248590Smm strcpy(str, "gzip"); 58248590Smm r1 = archive_read_support_filter_gzip(_a); 59248590Smm break; 60248590Smm case ARCHIVE_FILTER_BZIP2: 61248590Smm strcpy(str, "bzip2"); 62248590Smm r1 = archive_read_support_filter_bzip2(_a); 63248590Smm break; 64248590Smm case ARCHIVE_FILTER_COMPRESS: 65248590Smm strcpy(str, "compress (.Z)"); 66248590Smm r1 = archive_read_support_filter_compress(_a); 67248590Smm break; 68248590Smm case ARCHIVE_FILTER_PROGRAM: 69248590Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 70248590Smm "Cannot append program filter using archive_read_append_filter"); 71248590Smm return (ARCHIVE_FATAL); 72248590Smm case ARCHIVE_FILTER_LZMA: 73248590Smm strcpy(str, "lzma"); 74248590Smm r1 = archive_read_support_filter_lzma(_a); 75248590Smm break; 76248590Smm case ARCHIVE_FILTER_XZ: 77248590Smm strcpy(str, "xz"); 78248590Smm r1 = archive_read_support_filter_xz(_a); 79248590Smm break; 80248590Smm case ARCHIVE_FILTER_UU: 81248590Smm strcpy(str, "uu"); 82248590Smm r1 = archive_read_support_filter_uu(_a); 83248590Smm break; 84248590Smm case ARCHIVE_FILTER_RPM: 85248590Smm strcpy(str, "rpm"); 86248590Smm r1 = archive_read_support_filter_rpm(_a); 87248590Smm break; 88248590Smm case ARCHIVE_FILTER_LZIP: 89248590Smm strcpy(str, "lzip"); 90248590Smm r1 = archive_read_support_filter_lzip(_a); 91248590Smm break; 92248590Smm case ARCHIVE_FILTER_LRZIP: 93248590Smm strcpy(str, "lrzip"); 94248590Smm r1 = archive_read_support_filter_lrzip(_a); 95248590Smm break; 96248590Smm default: 97248590Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 98248590Smm "Invalid filter code specified"); 99248590Smm return (ARCHIVE_FATAL); 100248590Smm } 101248590Smm 102248590Smm if (code != ARCHIVE_FILTER_NONE) 103248590Smm { 104248590Smm number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); 105248590Smm 106248590Smm bidder = a->bidders; 107248590Smm for (i = 0; i < number_bidders; i++, bidder++) 108248590Smm { 109248590Smm if (!bidder->name || !strcmp(bidder->name, str)) 110248590Smm break; 111248590Smm } 112248590Smm if (!bidder->name || strcmp(bidder->name, str)) 113248590Smm { 114248590Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 115248590Smm "Internal error: Unable to append filter"); 116248590Smm return (ARCHIVE_FATAL); 117248590Smm } 118248590Smm 119248590Smm filter 120248590Smm = (struct archive_read_filter *)calloc(1, sizeof(*filter)); 121248590Smm if (filter == NULL) 122248590Smm { 123248590Smm archive_set_error(&a->archive, ENOMEM, "Out of memory"); 124248590Smm return (ARCHIVE_FATAL); 125248590Smm } 126248590Smm filter->bidder = bidder; 127248590Smm filter->archive = a; 128248590Smm filter->upstream = a->filter; 129248590Smm a->filter = filter; 130248590Smm r2 = (bidder->init)(a->filter); 131248590Smm if (r2 != ARCHIVE_OK) { 132248590Smm __archive_read_close_filters(a); 133248590Smm __archive_read_free_filters(a); 134248590Smm return (ARCHIVE_FATAL); 135248590Smm } 136248590Smm } 137248590Smm 138248590Smm a->bypass_filter_bidding = 1; 139248590Smm return (r1 < r2) ? r1 : r2; 140248590Smm} 141248590Smm 142248590Smmint 143248590Smmarchive_read_append_filter_program(struct archive *_a, const char *cmd) 144248590Smm{ 145248590Smm return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0)); 146248590Smm} 147248590Smm 148248590Smmint 149248590Smmarchive_read_append_filter_program_signature(struct archive *_a, 150248590Smm const char *cmd, const void *signature, size_t signature_len) 151248590Smm{ 152248590Smm int r, number_bidders, i; 153248590Smm struct archive_read_filter_bidder *bidder; 154248590Smm struct archive_read_filter *filter; 155248590Smm struct archive_read *a = (struct archive_read *)_a; 156248590Smm 157248590Smm if (archive_read_support_filter_program_signature(_a, cmd, signature, 158248590Smm signature_len) != (ARCHIVE_OK)) 159248590Smm return (ARCHIVE_FATAL); 160248590Smm 161248590Smm number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); 162248590Smm 163248590Smm bidder = a->bidders; 164248590Smm for (i = 0; i < number_bidders; i++, bidder++) 165248590Smm { 166248590Smm /* Program bidder name set to filter name after initialization */ 167248590Smm if (bidder->data && !bidder->name) 168248590Smm break; 169248590Smm } 170248590Smm if (!bidder->data) 171248590Smm { 172248590Smm archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 173248590Smm "Internal error: Unable to append program filter"); 174248590Smm return (ARCHIVE_FATAL); 175248590Smm } 176248590Smm 177248590Smm filter 178248590Smm = (struct archive_read_filter *)calloc(1, sizeof(*filter)); 179248590Smm if (filter == NULL) 180248590Smm { 181248590Smm archive_set_error(&a->archive, ENOMEM, "Out of memory"); 182248590Smm return (ARCHIVE_FATAL); 183248590Smm } 184248590Smm filter->bidder = bidder; 185248590Smm filter->archive = a; 186248590Smm filter->upstream = a->filter; 187248590Smm a->filter = filter; 188248590Smm r = (bidder->init)(a->filter); 189248590Smm if (r != ARCHIVE_OK) { 190248590Smm __archive_read_close_filters(a); 191248590Smm __archive_read_free_filters(a); 192248590Smm return (ARCHIVE_FATAL); 193248590Smm } 194248590Smm bidder->name = a->filter->name; 195248590Smm 196248590Smm a->bypass_filter_bidding = 1; 197248590Smm return r; 198248590Smm} 199