2 * Copyright (c) 2003-2012 Tim Kientzle
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 #include "archive_platform.h"
27 __FBSDID("$FreeBSD$");
34 #include "archive_private.h"
35 #include "archive_read_private.h"
38 archive_read_append_filter(struct archive *_a, int code)
40 int r1, r2, number_bidders, i;
42 struct archive_read_filter_bidder *bidder;
43 struct archive_read_filter *filter;
44 struct archive_read *a = (struct archive_read *)_a;
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
56 case ARCHIVE_FILTER_GZIP:
58 r1 = archive_read_support_filter_gzip(_a);
60 case ARCHIVE_FILTER_BZIP2:
62 r1 = archive_read_support_filter_bzip2(_a);
64 case ARCHIVE_FILTER_COMPRESS:
65 strcpy(str, "compress (.Z)");
66 r1 = archive_read_support_filter_compress(_a);
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:
74 r1 = archive_read_support_filter_lzma(_a);
76 case ARCHIVE_FILTER_XZ:
78 r1 = archive_read_support_filter_xz(_a);
80 case ARCHIVE_FILTER_UU:
82 r1 = archive_read_support_filter_uu(_a);
84 case ARCHIVE_FILTER_RPM:
86 r1 = archive_read_support_filter_rpm(_a);
88 case ARCHIVE_FILTER_LZ4:
90 r1 = archive_read_support_filter_lz4(_a);
92 case ARCHIVE_FILTER_LZIP:
94 r1 = archive_read_support_filter_lzip(_a);
96 case ARCHIVE_FILTER_LRZIP:
98 r1 = archive_read_support_filter_lrzip(_a);
101 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
102 "Invalid filter code specified");
103 return (ARCHIVE_FATAL);
106 if (code != ARCHIVE_FILTER_NONE)
108 number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
111 for (i = 0; i < number_bidders; i++, bidder++)
113 if (!bidder->name || !strcmp(bidder->name, str))
116 if (!bidder->name || strcmp(bidder->name, str))
118 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
119 "Internal error: Unable to append filter");
120 return (ARCHIVE_FATAL);
124 = (struct archive_read_filter *)calloc(1, sizeof(*filter));
127 archive_set_error(&a->archive, ENOMEM, "Out of memory");
128 return (ARCHIVE_FATAL);
130 filter->bidder = bidder;
132 filter->upstream = a->filter;
134 r2 = (bidder->init)(a->filter);
135 if (r2 != ARCHIVE_OK) {
136 __archive_read_close_filters(a);
137 __archive_read_free_filters(a);
138 return (ARCHIVE_FATAL);
142 a->bypass_filter_bidding = 1;
143 return (r1 < r2) ? r1 : r2;
147 archive_read_append_filter_program(struct archive *_a, const char *cmd)
149 return (archive_read_append_filter_program_signature(_a, cmd, NULL, 0));
153 archive_read_append_filter_program_signature(struct archive *_a,
154 const char *cmd, const void *signature, size_t signature_len)
156 int r, number_bidders, i;
157 struct archive_read_filter_bidder *bidder;
158 struct archive_read_filter *filter;
159 struct archive_read *a = (struct archive_read *)_a;
161 if (archive_read_support_filter_program_signature(_a, cmd, signature,
162 signature_len) != (ARCHIVE_OK))
163 return (ARCHIVE_FATAL);
165 number_bidders = sizeof(a->bidders) / sizeof(a->bidders[0]);
168 for (i = 0; i < number_bidders; i++, bidder++)
170 /* Program bidder name set to filter name after initialization */
171 if (bidder->data && !bidder->name)
176 archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
177 "Internal error: Unable to append program filter");
178 return (ARCHIVE_FATAL);
182 = (struct archive_read_filter *)calloc(1, sizeof(*filter));
185 archive_set_error(&a->archive, ENOMEM, "Out of memory");
186 return (ARCHIVE_FATAL);
188 filter->bidder = bidder;
190 filter->upstream = a->filter;
192 r = (bidder->init)(a->filter);
193 if (r != ARCHIVE_OK) {
194 __archive_read_close_filters(a);
195 __archive_read_free_filters(a);
196 return (ARCHIVE_FATAL);
198 bidder->name = a->filter->name;
200 a->bypass_filter_bidding = 1;