2
* Copyright (c) 2007 Joerg Sonnenberger
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: head/lib/libarchive/archive_read_support_compression_program.c 201112 2009-12-28 06:59:35Z kientzle $");
29
#ifdef HAVE_SYS_WAIT_H
30
# include <sys/wait.h>
55
#include "archive_private.h"
56
#include "archive_read_private.h"
59
archive_read_support_compression_program(struct archive *a, const char *cmd)
61
return (archive_read_support_compression_program_signature(a, cmd, NULL, 0));
65
/* This capability is only available on POSIX systems. */
66
#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
67
!(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
70
* On non-Posix systems, allow the program to build, but choke if
71
* this function is actually invoked.
74
archive_read_support_compression_program_signature(struct archive *_a,
75
const char *cmd, void *signature, size_t signature_len)
77
(void)_a; /* UNUSED */
78
(void)cmd; /* UNUSED */
79
(void)signature; /* UNUSED */
80
(void)signature_len; /* UNUSED */
82
archive_set_error(_a, -1,
83
"External compression programs not supported on this platform");
84
return (ARCHIVE_FATAL);
88
__archive_read_program(struct archive_read_filter *self, const char *cmd)
90
(void)self; /* UNUSED */
91
(void)cmd; /* UNUSED */
93
archive_set_error(&self->archive->archive, -1,
94
"External compression programs not supported on this platform");
95
return (ARCHIVE_FATAL);
100
#include "filter_fork.h"
103
* The bidder object stores the command and the signature to watch for.
104
* The 'inhibit' entry here is used to ensure that unchecked filters never
105
* bid twice in the same pipeline.
107
struct program_bidder {
110
size_t signature_len;
114
static int program_bidder_bid(struct archive_read_filter_bidder *,
115
struct archive_read_filter *upstream);
116
static int program_bidder_init(struct archive_read_filter *);
117
static int program_bidder_free(struct archive_read_filter_bidder *);
120
* The actual filter needs to track input and output data.
122
struct program_filter {
127
int child_stdin, child_stdout;
133
static ssize_t program_filter_read(struct archive_read_filter *,
135
static int program_filter_close(struct archive_read_filter *);
138
archive_read_support_compression_program_signature(struct archive *_a,
139
const char *cmd, const void *signature, size_t signature_len)
141
struct archive_read *a = (struct archive_read *)_a;
142
struct archive_read_filter_bidder *bidder;
143
struct program_bidder *state;
146
* Get a bidder object from the read core.
148
bidder = __archive_read_get_bidder(a);
150
return (ARCHIVE_FATAL);
153
* Allocate our private state.
155
state = (struct program_bidder *)calloc(sizeof (*state), 1);
157
return (ARCHIVE_FATAL);
158
state->cmd = strdup(cmd);
159
if (signature != NULL && signature_len > 0) {
160
state->signature_len = signature_len;
161
state->signature = malloc(signature_len);
162
memcpy(state->signature, signature, signature_len);
166
* Fill in the bidder object.
168
bidder->data = state;
169
bidder->bid = program_bidder_bid;
170
bidder->init = program_bidder_init;
171
bidder->options = NULL;
172
bidder->free = program_bidder_free;
177
program_bidder_free(struct archive_read_filter_bidder *self)
179
struct program_bidder *state = (struct program_bidder *)self->data;
181
free(state->signature);
187
* If we do have a signature, bid only if that matches.
189
* If there's no signature, we bid INT_MAX the first time
190
* we're called, then never bid again.
193
program_bidder_bid(struct archive_read_filter_bidder *self,
194
struct archive_read_filter *upstream)
196
struct program_bidder *state = self->data;
199
/* If we have a signature, use that to match. */
200
if (state->signature_len > 0) {
201
p = __archive_read_filter_ahead(upstream,
202
state->signature_len, NULL);
205
/* No match, so don't bid. */
206
if (memcmp(p, state->signature, state->signature_len) != 0)
208
return ((int)state->signature_len * 8);
211
/* Otherwise, bid once and then never bid again. */
219
* Shut down the child, return ARCHIVE_OK if it exited normally.
221
* Note that the return value is sticky; if we're called again,
222
* we won't reap the child again, but we will return the same status
223
* (including error message if the child came to a bad end).
226
child_stop(struct archive_read_filter *self, struct program_filter *state)
228
/* Close our side of the I/O with the child. */
229
if (state->child_stdin != -1) {
230
close(state->child_stdin);
231
state->child_stdin = -1;
233
if (state->child_stdout != -1) {
234
close(state->child_stdout);
235
state->child_stdout = -1;
238
if (state->child != 0) {
239
/* Reap the child. */
241
state->waitpid_return
242
= waitpid(state->child, &state->exit_status, 0);
243
} while (state->waitpid_return == -1 && errno == EINTR);
247
if (state->waitpid_return < 0) {
248
/* waitpid() failed? This is ugly. */
249
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
250
"Child process exited badly");
251
return (ARCHIVE_WARN);
254
#if !defined(_WIN32) || defined(__CYGWIN__)
255
if (WIFSIGNALED(state->exit_status)) {
257
/* If the child died because we stopped reading before
258
* it was done, that's okay. Some archive formats
259
* have padding at the end that we routinely ignore. */
260
/* The alternative to this would be to add a step
261
* before close(child_stdout) above to read from the
262
* child until the child has no more to write. */
263
if (WTERMSIG(state->exit_status) == SIGPIPE)
266
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
267
"Child process exited with signal %d",
268
WTERMSIG(state->exit_status));
269
return (ARCHIVE_WARN);
271
#endif /* !_WIN32 || __CYGWIN__ */
273
if (WIFEXITED(state->exit_status)) {
274
if (WEXITSTATUS(state->exit_status) == 0)
277
archive_set_error(&self->archive->archive,
279
"Child process exited with status %d",
280
WEXITSTATUS(state->exit_status));
281
return (ARCHIVE_WARN);
284
return (ARCHIVE_WARN);
288
* Use select() to decide whether the child is ready for read or write.
291
child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
293
struct program_filter *state = self->data;
294
ssize_t ret, requested, avail;
297
requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len;
301
ret = read(state->child_stdout, buf, requested);
302
} while (ret == -1 && errno == EINTR);
306
if (ret == 0 || (ret == -1 && errno == EPIPE))
307
/* Child has closed its output; reap the child
308
* and return the status. */
309
return (child_stop(self, state));
310
if (ret == -1 && errno != EAGAIN)
313
if (state->child_stdin == -1) {
314
/* Block until child has some I/O ready. */
315
__archive_check_child(state->child_stdin,
316
state->child_stdout);
320
/* Get some more data from upstream. */
321
p = __archive_read_filter_ahead(self->upstream, 1, &avail);
323
close(state->child_stdin);
324
state->child_stdin = -1;
325
fcntl(state->child_stdout, F_SETFL, 0);
332
ret = write(state->child_stdin, p, avail);
333
} while (ret == -1 && errno == EINTR);
336
/* Consume whatever we managed to write. */
337
__archive_read_filter_consume(self->upstream, ret);
338
} else if (ret == -1 && errno == EAGAIN) {
339
/* Block until child has some I/O ready. */
340
__archive_check_child(state->child_stdin,
341
state->child_stdout);
344
close(state->child_stdin);
345
state->child_stdin = -1;
346
fcntl(state->child_stdout, F_SETFL, 0);
347
/* If it was a bad error, we're done; otherwise
348
* it was EPIPE or EOF, and we can still read
350
if (ret == -1 && errno != EPIPE)
357
__archive_read_program(struct archive_read_filter *self, const char *cmd)
359
struct program_filter *state;
360
static const size_t out_buf_len = 65536;
363
const char *prefix = "Program: ";
365
state = (struct program_filter *)calloc(1, sizeof(*state));
366
out_buf = (char *)malloc(out_buf_len);
367
description = (char *)malloc(strlen(prefix) + strlen(cmd) + 1);
368
if (state == NULL || out_buf == NULL || description == NULL) {
369
archive_set_error(&self->archive->archive, ENOMEM,
370
"Can't allocate input data");
374
return (ARCHIVE_FATAL);
377
self->code = ARCHIVE_COMPRESSION_PROGRAM;
378
state->description = description;
379
strcpy(state->description, prefix);
380
strcat(state->description, cmd);
381
self->name = state->description;
383
state->out_buf = out_buf;
384
state->out_buf_len = out_buf_len;
386
if ((state->child = __archive_create_child(cmd,
387
&state->child_stdin, &state->child_stdout)) == -1) {
388
free(state->out_buf);
390
archive_set_error(&self->archive->archive, EINVAL,
391
"Can't initialise filter");
392
return (ARCHIVE_FATAL);
396
self->read = program_filter_read;
398
self->close = program_filter_close;
400
/* XXX Check that we can read at least one byte? */
405
program_bidder_init(struct archive_read_filter *self)
407
struct program_bidder *bidder_state;
409
bidder_state = (struct program_bidder *)self->bidder->data;
410
return (__archive_read_program(self, bidder_state->cmd));
414
program_filter_read(struct archive_read_filter *self, const void **buff)
416
struct program_filter *state;
421
state = (struct program_filter *)self->data;
425
while (state->child_stdout != -1 && total < state->out_buf_len) {
426
bytes = child_read(self, p, state->out_buf_len - total);
428
/* No recovery is possible if we can no longer
429
* read from the child. */
430
return (ARCHIVE_FATAL);
432
/* We got EOF from the child. */
438
*buff = state->out_buf;
443
program_filter_close(struct archive_read_filter *self)
445
struct program_filter *state;
448
state = (struct program_filter *)self->data;
449
e = child_stop(self, state);
451
/* Release our private data. */
452
free(state->out_buf);
453
free(state->description);
459
#endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */