1 /*- 2 * Copyright (c) 2003-2012 Tim Kientzle 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 __FBSDID("$FreeBSD$"); 28 29 #ifdef HAVE_ERRNO_H 30 #include <errno.h> 31 #endif 32 33 #include "archive.h" 34 #include "archive_private.h" 35 #include "archive_read_private.h" 36 37 int 38 archive_read_append_filter(struct archive *_a, int code) 39 { 40 int r1, r2, number_bidders, i; 41 char str[20]; 42 struct archive_read_filter_bidder *bidder; 43 struct archive_read_filter *filter; 44 struct archive_read *a = (struct archive_read *)_a; 45 46 r1 = r2 = (ARCHIVE_OK); 47 switch (code) 48 { 49 case ARCHIVE_FILTER_NONE: 50 /* No filter to add, so do nothing. 51 * NOTE: An initial "NONE" type filter is always set at the end of the 52 * filter chain. 53 */ 54 r1 = (ARCHIVE_OK); 55 break; 56 case ARCHIVE_FILTER_GZIP: 57 strcpy(str, "gzip"); 58 r1 = archive_read_support_filter_gzip(_a); 59 break; 60 case ARCHIVE_FILTER_BZIP2: 61 strcpy(str, "bzip2"); 62 r1 = archive_read_support_filter_bzip2(_a); 63 break; 64 case ARCHIVE_FILTER_COMPRESS: 65 strcpy(str, "compress (.Z)"); 66 r1 = archive_read_support_filter_compress(_a); 67 break; 68 case ARCHIVE_FILTER_PROGRAM: 69 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 70 "Cannot append program filter using archive_read_append_filter"); 71 return (ARCHIVE_FATAL); 72 case ARCHIVE_FILTER_LZMA: 73 strcpy(str, "lzma"); 74 r1 = archive_read_support_filter_lzma(_a); 75 break; 76 case ARCHIVE_FILTER_XZ: 77 strcpy(str, "xz"); 78 r1 = archive_read_support_filter_xz(_a); 79 break; 80 case ARCHIVE_FILTER_UU: 81 strcpy(str, "uu"); 82 r1 = archive_read_support_filter_uu(_a); 83 break; 84 case ARCHIVE_FILTER_RPM: 85 strcpy(str, "rpm"); 86 r1 = archive_read_support_filter_rpm(_a); 87 break; 88 case ARCHIVE_FILTER_LZIP: 89 strcpy(str, "lzip"); 90 r1 = archive_read_support_filter_lzip(_a); 91 break; 92 case ARCHIVE_FILTER_LRZIP: 93 strcpy(str, "lrzip"); 94 r1 = archive_read_support_filter_lrzip(_a); 95 break; 96 default: 97 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 98 "Invalid filter code specified"); 99 return (ARCHIVE_FATAL); 100 } 101 102 if (code != ARCHIVE_FILTER_NONE) 103 { 104 number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); 105 106 bidder = a->bidders; 107 for (i = 0; i < number_bidders; i++, bidder++) 108 { 109 if (!bidder->name || !strcmp(bidder->name, str)) 110 break; 111 } 112 if (!bidder->name || strcmp(bidder->name, str)) 113 { 114 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 115 "Internal error: Unable to append filter"); 116 return (ARCHIVE_FATAL); 117 } 118 119 filter 120 = (struct archive_read_filter *)calloc(1, sizeof(*filter)); 121 if (filter == NULL) 122 { 123 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 124 return (ARCHIVE_FATAL); 125 } 126 filter->bidder = bidder; 127 filter->archive = a; 128 filter->upstream = a->filter; 129 a->filter = filter; 130 r2 = (bidder->init)(a->filter); 131 if (r2 != ARCHIVE_OK) { 132 __archive_read_close_filters(a); 133 __archive_read_free_filters(a); 134 return (ARCHIVE_FATAL); 135 } 136 } 137 138 a->bypass_filter_bidding = 1; 139 return (r1 < r2) ? r1 : r2; 140 } 141 142 int 143 archive_read_append_filter_program(struct archive *_a, const char *cmd) 144 { 145 return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0)); 146 } 147 148 int 149 archive_read_append_filter_program_signature(struct archive *_a, 150 const char *cmd, const void *signature, size_t signature_len) 151 { 152 int r, number_bidders, i; 153 struct archive_read_filter_bidder *bidder; 154 struct archive_read_filter *filter; 155 struct archive_read *a = (struct archive_read *)_a; 156 157 if (archive_read_support_filter_program_signature(_a, cmd, signature, 158 signature_len) != (ARCHIVE_OK)) 159 return (ARCHIVE_FATAL); 160 161 number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]); 162 163 bidder = a->bidders; 164 for (i = 0; i < number_bidders; i++, bidder++) 165 { 166 /* Program bidder name set to filter name after initialization */ 167 if (bidder->data && !bidder->name) 168 break; 169 } 170 if (!bidder->data) 171 { 172 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, 173 "Internal error: Unable to append program filter"); 174 return (ARCHIVE_FATAL); 175 } 176 177 filter 178 = (struct archive_read_filter *)calloc(1, sizeof(*filter)); 179 if (filter == NULL) 180 { 181 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 182 return (ARCHIVE_FATAL); 183 } 184 filter->bidder = bidder; 185 filter->archive = a; 186 filter->upstream = a->filter; 187 a->filter = filter; 188 r = (bidder->init)(a->filter); 189 if (r != ARCHIVE_OK) { 190 __archive_read_close_filters(a); 191 __archive_read_free_filters(a); 192 return (ARCHIVE_FATAL); 193 } 194 bidder->name = a->filter->name; 195 196 a->bypass_filter_bidding = 1; 197 return r; 198 } 199