libarchive-static 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. data/ext/Makefile +6 -0
  2. data/ext/extconf.rb +61 -0
  3. data/ext/libarchive-0.1.1/COPYING.libarchive +60 -0
  4. data/ext/libarchive-0.1.1/LICENSE.libbzip2 +42 -0
  5. data/ext/libarchive-0.1.1/README.txt +143 -0
  6. data/ext/libarchive-0.1.1/ext/Makefile.in +0 -0
  7. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +31 -0
  8. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.h +6 -0
  9. data/ext/libarchive-0.1.1/ext/archive_read_support_format.c +32 -0
  10. data/ext/libarchive-0.1.1/ext/archive_read_support_format.h +6 -0
  11. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +29 -0
  12. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.h +6 -0
  13. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +32 -0
  14. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.h +6 -0
  15. data/ext/libarchive-0.1.1/ext/config.h.in +22 -0
  16. data/ext/libarchive-0.1.1/ext/configure +3904 -0
  17. data/ext/libarchive-0.1.1/ext/configure.in +11 -0
  18. data/ext/libarchive-0.1.1/ext/depend +19 -0
  19. data/ext/libarchive-0.1.1/ext/extconf.rb +6 -0
  20. data/ext/libarchive-0.1.1/ext/install-sh +250 -0
  21. data/ext/libarchive-0.1.1/ext/libarchive.c +89 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_archive.c +84 -0
  23. data/ext/libarchive-0.1.1/ext/libarchive_entry.c +1015 -0
  24. data/ext/libarchive-0.1.1/ext/libarchive_internal.h +155 -0
  25. data/ext/libarchive-0.1.1/ext/libarchive_reader.c +328 -0
  26. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +52 -0
  27. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +246 -0
  28. data/ext/libarchive-0.1.1/libarchive.c +1762 -0
  29. data/ext/libarchive-2.8.4/Makefile.in +7076 -0
  30. data/ext/libarchive-2.8.4/build/autoconf/check_stdcall_func.m4 +51 -0
  31. data/ext/libarchive-2.8.4/build/autoconf/compile +143 -0
  32. data/ext/libarchive-2.8.4/build/autoconf/config.guess +1502 -0
  33. data/ext/libarchive-2.8.4/build/autoconf/config.sub +1708 -0
  34. data/ext/libarchive-2.8.4/build/autoconf/depcomp +630 -0
  35. data/ext/libarchive-2.8.4/build/autoconf/install-sh +291 -0
  36. data/ext/libarchive-2.8.4/build/autoconf/la_uid_t.m4 +20 -0
  37. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +8406 -0
  38. data/ext/libarchive-2.8.4/build/autoconf/missing +376 -0
  39. data/ext/libarchive-2.8.4/build/pkgconfig/libarchive.pc.in +10 -0
  40. data/ext/libarchive-2.8.4/config.h.in +772 -0
  41. data/ext/libarchive-2.8.4/configure +17916 -0
  42. data/ext/libarchive-2.8.4/libarchive/archive.h +741 -0
  43. data/ext/libarchive-2.8.4/libarchive/archive_check_magic.c +134 -0
  44. data/ext/libarchive-2.8.4/libarchive/archive_crc32.h +66 -0
  45. data/ext/libarchive-2.8.4/libarchive/archive_endian.h +162 -0
  46. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +2202 -0
  47. data/ext/libarchive-2.8.4/libarchive/archive_entry.h +524 -0
  48. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_bhfi.c +74 -0
  49. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_stat.c +77 -0
  50. data/ext/libarchive-2.8.4/libarchive/archive_entry_link_resolver.c +405 -0
  51. data/ext/libarchive-2.8.4/libarchive/archive_entry_private.h +184 -0
  52. data/ext/libarchive-2.8.4/libarchive/archive_entry_stat.c +118 -0
  53. data/ext/libarchive-2.8.4/libarchive/archive_entry_strmode.c +87 -0
  54. data/ext/libarchive-2.8.4/libarchive/archive_entry_xattr.c +158 -0
  55. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +281 -0
  56. data/ext/libarchive-2.8.4/libarchive/archive_platform.h +165 -0
  57. data/ext/libarchive-2.8.4/libarchive/archive_private.h +124 -0
  58. data/ext/libarchive-2.8.4/libarchive/archive_read.c +1249 -0
  59. data/ext/libarchive-2.8.4/libarchive/archive_read_data_into_fd.c +93 -0
  60. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +198 -0
  61. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +570 -0
  62. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_private.h +62 -0
  63. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_set_standard_lookup.c +303 -0
  64. data/ext/libarchive-2.8.4/libarchive/archive_read_extract.c +182 -0
  65. data/ext/libarchive-2.8.4/libarchive/archive_read_open_fd.c +190 -0
  66. data/ext/libarchive-2.8.4/libarchive/archive_read_open_file.c +165 -0
  67. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +272 -0
  68. data/ext/libarchive-2.8.4/libarchive/archive_read_open_memory.c +156 -0
  69. data/ext/libarchive-2.8.4/libarchive/archive_read_private.h +199 -0
  70. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_all.c +60 -0
  71. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c +353 -0
  72. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c +444 -0
  73. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c +465 -0
  74. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_none.c +40 -0
  75. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_program.c +459 -0
  76. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c +287 -0
  77. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c +627 -0
  78. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c +708 -0
  79. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_all.c +43 -0
  80. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_ar.c +584 -0
  81. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +777 -0
  82. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_empty.c +93 -0
  83. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_iso9660.c +2830 -0
  84. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +1304 -0
  85. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_raw.c +185 -0
  86. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_tar.c +2418 -0
  87. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_xar.c +3151 -0
  88. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +903 -0
  89. data/ext/libarchive-2.8.4/libarchive/archive_string.c +453 -0
  90. data/ext/libarchive-2.8.4/libarchive/archive_string.h +148 -0
  91. data/ext/libarchive-2.8.4/libarchive/archive_string_sprintf.c +164 -0
  92. data/ext/libarchive-2.8.4/libarchive/archive_util.c +391 -0
  93. data/ext/libarchive-2.8.4/libarchive/archive_virtual.c +94 -0
  94. data/ext/libarchive-2.8.4/libarchive/archive_windows.c +1236 -0
  95. data/ext/libarchive-2.8.4/libarchive/archive_windows.h +347 -0
  96. data/ext/libarchive-2.8.4/libarchive/archive_write.c +466 -0
  97. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +2628 -0
  98. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_private.h +38 -0
  99. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_set_standard_lookup.c +262 -0
  100. data/ext/libarchive-2.8.4/libarchive/archive_write_open_fd.c +141 -0
  101. data/ext/libarchive-2.8.4/libarchive/archive_write_open_file.c +105 -0
  102. data/ext/libarchive-2.8.4/libarchive/archive_write_open_filename.c +162 -0
  103. data/ext/libarchive-2.8.4/libarchive/archive_write_open_memory.c +126 -0
  104. data/ext/libarchive-2.8.4/libarchive/archive_write_private.h +122 -0
  105. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +408 -0
  106. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c +492 -0
  107. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +477 -0
  108. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +257 -0
  109. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +347 -0
  110. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +438 -0
  111. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format.c +72 -0
  112. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ar.c +550 -0
  113. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_by_name.c +76 -0
  114. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +344 -0
  115. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +295 -0
  116. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +1050 -0
  117. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_pax.c +1386 -0
  118. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_shar.c +626 -0
  119. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ustar.c +587 -0
  120. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +667 -0
  121. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +154 -0
  122. data/ext/libarchive-2.8.4/libarchive/filter_fork.c +161 -0
  123. data/ext/libarchive-2.8.4/libarchive/filter_fork.h +41 -0
  124. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +113 -0
  125. data/ext/libarchive-static-makefile +80 -0
  126. data/ext/libarchive-static-wrapper-makefile +22 -0
  127. data/ext/zlib-1.2.5/Makefile.in +257 -0
  128. data/ext/zlib-1.2.5/adler32.c +169 -0
  129. data/ext/zlib-1.2.5/compress.c +80 -0
  130. data/ext/zlib-1.2.5/configure +596 -0
  131. data/ext/zlib-1.2.5/crc32.c +442 -0
  132. data/ext/zlib-1.2.5/crc32.h +441 -0
  133. data/ext/zlib-1.2.5/deflate.c +1834 -0
  134. data/ext/zlib-1.2.5/deflate.h +342 -0
  135. data/ext/zlib-1.2.5/example.c +565 -0
  136. data/ext/zlib-1.2.5/gzclose.c +25 -0
  137. data/ext/zlib-1.2.5/gzguts.h +132 -0
  138. data/ext/zlib-1.2.5/gzlib.c +537 -0
  139. data/ext/zlib-1.2.5/gzread.c +653 -0
  140. data/ext/zlib-1.2.5/gzwrite.c +531 -0
  141. data/ext/zlib-1.2.5/infback.c +632 -0
  142. data/ext/zlib-1.2.5/inffast.c +340 -0
  143. data/ext/zlib-1.2.5/inffast.h +11 -0
  144. data/ext/zlib-1.2.5/inffixed.h +94 -0
  145. data/ext/zlib-1.2.5/inflate.c +1480 -0
  146. data/ext/zlib-1.2.5/inflate.h +122 -0
  147. data/ext/zlib-1.2.5/inftrees.c +330 -0
  148. data/ext/zlib-1.2.5/inftrees.h +62 -0
  149. data/ext/zlib-1.2.5/minigzip.c +440 -0
  150. data/ext/zlib-1.2.5/trees.c +1244 -0
  151. data/ext/zlib-1.2.5/trees.h +128 -0
  152. data/ext/zlib-1.2.5/uncompr.c +59 -0
  153. data/ext/zlib-1.2.5/zconf.h +428 -0
  154. data/ext/zlib-1.2.5/zlib.h +1613 -0
  155. data/ext/zlib-1.2.5/zutil.c +318 -0
  156. data/ext/zlib-1.2.5/zutil.h +274 -0
  157. metadata +211 -0
@@ -0,0 +1,459 @@
1
+ /*-
2
+ * Copyright (c) 2007 Joerg Sonnenberger
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: head/lib/libarchive/archive_read_support_compression_program.c 201112 2009-12-28 06:59:35Z kientzle $");
28
+
29
+ #ifdef HAVE_SYS_WAIT_H
30
+ # include <sys/wait.h>
31
+ #endif
32
+ #ifdef HAVE_ERRNO_H
33
+ # include <errno.h>
34
+ #endif
35
+ #ifdef HAVE_FCNTL_H
36
+ # include <fcntl.h>
37
+ #endif
38
+ #ifdef HAVE_LIMITS_H
39
+ # include <limits.h>
40
+ #endif
41
+ #ifdef HAVE_SIGNAL_H
42
+ # include <signal.h>
43
+ #endif
44
+ #ifdef HAVE_STDLIB_H
45
+ # include <stdlib.h>
46
+ #endif
47
+ #ifdef HAVE_STRING_H
48
+ # include <string.h>
49
+ #endif
50
+ #ifdef HAVE_UNISTD_H
51
+ # include <unistd.h>
52
+ #endif
53
+
54
+ #include "archive.h"
55
+ #include "archive_private.h"
56
+ #include "archive_read_private.h"
57
+
58
+ int
59
+ archive_read_support_compression_program(struct archive *a, const char *cmd)
60
+ {
61
+ return (archive_read_support_compression_program_signature(a, cmd, NULL, 0));
62
+ }
63
+
64
+
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__))
68
+
69
+ /*
70
+ * On non-Posix systems, allow the program to build, but choke if
71
+ * this function is actually invoked.
72
+ */
73
+ int
74
+ archive_read_support_compression_program_signature(struct archive *_a,
75
+ const char *cmd, void *signature, size_t signature_len)
76
+ {
77
+ (void)_a; /* UNUSED */
78
+ (void)cmd; /* UNUSED */
79
+ (void)signature; /* UNUSED */
80
+ (void)signature_len; /* UNUSED */
81
+
82
+ archive_set_error(_a, -1,
83
+ "External compression programs not supported on this platform");
84
+ return (ARCHIVE_FATAL);
85
+ }
86
+
87
+ int
88
+ __archive_read_program(struct archive_read_filter *self, const char *cmd)
89
+ {
90
+ (void)self; /* UNUSED */
91
+ (void)cmd; /* UNUSED */
92
+
93
+ archive_set_error(&self->archive->archive, -1,
94
+ "External compression programs not supported on this platform");
95
+ return (ARCHIVE_FATAL);
96
+ }
97
+
98
+ #else
99
+
100
+ #include "filter_fork.h"
101
+
102
+ /*
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.
106
+ */
107
+ struct program_bidder {
108
+ char *cmd;
109
+ void *signature;
110
+ size_t signature_len;
111
+ int inhibit;
112
+ };
113
+
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 *);
118
+
119
+ /*
120
+ * The actual filter needs to track input and output data.
121
+ */
122
+ struct program_filter {
123
+ char *description;
124
+ pid_t child;
125
+ int exit_status;
126
+ int waitpid_return;
127
+ int child_stdin, child_stdout;
128
+
129
+ char *out_buf;
130
+ size_t out_buf_len;
131
+ };
132
+
133
+ static ssize_t program_filter_read(struct archive_read_filter *,
134
+ const void **);
135
+ static int program_filter_close(struct archive_read_filter *);
136
+
137
+ int
138
+ archive_read_support_compression_program_signature(struct archive *_a,
139
+ const char *cmd, const void *signature, size_t signature_len)
140
+ {
141
+ struct archive_read *a = (struct archive_read *)_a;
142
+ struct archive_read_filter_bidder *bidder;
143
+ struct program_bidder *state;
144
+
145
+ /*
146
+ * Get a bidder object from the read core.
147
+ */
148
+ bidder = __archive_read_get_bidder(a);
149
+ if (bidder == NULL)
150
+ return (ARCHIVE_FATAL);
151
+
152
+ /*
153
+ * Allocate our private state.
154
+ */
155
+ state = (struct program_bidder *)calloc(sizeof (*state), 1);
156
+ if (state == NULL)
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);
163
+ }
164
+
165
+ /*
166
+ * Fill in the bidder object.
167
+ */
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;
173
+ return (ARCHIVE_OK);
174
+ }
175
+
176
+ static int
177
+ program_bidder_free(struct archive_read_filter_bidder *self)
178
+ {
179
+ struct program_bidder *state = (struct program_bidder *)self->data;
180
+ free(state->cmd);
181
+ free(state->signature);
182
+ free(self->data);
183
+ return (ARCHIVE_OK);
184
+ }
185
+
186
+ /*
187
+ * If we do have a signature, bid only if that matches.
188
+ *
189
+ * If there's no signature, we bid INT_MAX the first time
190
+ * we're called, then never bid again.
191
+ */
192
+ static int
193
+ program_bidder_bid(struct archive_read_filter_bidder *self,
194
+ struct archive_read_filter *upstream)
195
+ {
196
+ struct program_bidder *state = self->data;
197
+ const char *p;
198
+
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);
203
+ if (p == NULL)
204
+ return (0);
205
+ /* No match, so don't bid. */
206
+ if (memcmp(p, state->signature, state->signature_len) != 0)
207
+ return (0);
208
+ return ((int)state->signature_len * 8);
209
+ }
210
+
211
+ /* Otherwise, bid once and then never bid again. */
212
+ if (state->inhibit)
213
+ return (0);
214
+ state->inhibit = 1;
215
+ return (INT_MAX);
216
+ }
217
+
218
+ /*
219
+ * Shut down the child, return ARCHIVE_OK if it exited normally.
220
+ *
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).
224
+ */
225
+ static int
226
+ child_stop(struct archive_read_filter *self, struct program_filter *state)
227
+ {
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;
232
+ }
233
+ if (state->child_stdout != -1) {
234
+ close(state->child_stdout);
235
+ state->child_stdout = -1;
236
+ }
237
+
238
+ if (state->child != 0) {
239
+ /* Reap the child. */
240
+ do {
241
+ state->waitpid_return
242
+ = waitpid(state->child, &state->exit_status, 0);
243
+ } while (state->waitpid_return == -1 && errno == EINTR);
244
+ state->child = 0;
245
+ }
246
+
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);
252
+ }
253
+
254
+ #if !defined(_WIN32) || defined(__CYGWIN__)
255
+ if (WIFSIGNALED(state->exit_status)) {
256
+ #ifdef SIGPIPE
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)
264
+ return (ARCHIVE_OK);
265
+ #endif
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);
270
+ }
271
+ #endif /* !_WIN32 || __CYGWIN__ */
272
+
273
+ if (WIFEXITED(state->exit_status)) {
274
+ if (WEXITSTATUS(state->exit_status) == 0)
275
+ return (ARCHIVE_OK);
276
+
277
+ archive_set_error(&self->archive->archive,
278
+ ARCHIVE_ERRNO_MISC,
279
+ "Child process exited with status %d",
280
+ WEXITSTATUS(state->exit_status));
281
+ return (ARCHIVE_WARN);
282
+ }
283
+
284
+ return (ARCHIVE_WARN);
285
+ }
286
+
287
+ /*
288
+ * Use select() to decide whether the child is ready for read or write.
289
+ */
290
+ static ssize_t
291
+ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
292
+ {
293
+ struct program_filter *state = self->data;
294
+ ssize_t ret, requested, avail;
295
+ const char *p;
296
+
297
+ requested = buf_len > SSIZE_MAX ? SSIZE_MAX : buf_len;
298
+
299
+ for (;;) {
300
+ do {
301
+ ret = read(state->child_stdout, buf, requested);
302
+ } while (ret == -1 && errno == EINTR);
303
+
304
+ if (ret > 0)
305
+ return (ret);
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)
311
+ return (-1);
312
+
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);
317
+ continue;
318
+ }
319
+
320
+ /* Get some more data from upstream. */
321
+ p = __archive_read_filter_ahead(self->upstream, 1, &avail);
322
+ if (p == NULL) {
323
+ close(state->child_stdin);
324
+ state->child_stdin = -1;
325
+ fcntl(state->child_stdout, F_SETFL, 0);
326
+ if (avail < 0)
327
+ return (avail);
328
+ continue;
329
+ }
330
+
331
+ do {
332
+ ret = write(state->child_stdin, p, avail);
333
+ } while (ret == -1 && errno == EINTR);
334
+
335
+ if (ret > 0) {
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);
342
+ } else {
343
+ /* Write failed. */
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
349
+ * from the child. */
350
+ if (ret == -1 && errno != EPIPE)
351
+ return (-1);
352
+ }
353
+ }
354
+ }
355
+
356
+ int
357
+ __archive_read_program(struct archive_read_filter *self, const char *cmd)
358
+ {
359
+ struct program_filter *state;
360
+ static const size_t out_buf_len = 65536;
361
+ char *out_buf;
362
+ char *description;
363
+ const char *prefix = "Program: ";
364
+
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");
371
+ free(state);
372
+ free(out_buf);
373
+ free(description);
374
+ return (ARCHIVE_FATAL);
375
+ }
376
+
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;
382
+
383
+ state->out_buf = out_buf;
384
+ state->out_buf_len = out_buf_len;
385
+
386
+ if ((state->child = __archive_create_child(cmd,
387
+ &state->child_stdin, &state->child_stdout)) == -1) {
388
+ free(state->out_buf);
389
+ free(state);
390
+ archive_set_error(&self->archive->archive, EINVAL,
391
+ "Can't initialise filter");
392
+ return (ARCHIVE_FATAL);
393
+ }
394
+
395
+ self->data = state;
396
+ self->read = program_filter_read;
397
+ self->skip = NULL;
398
+ self->close = program_filter_close;
399
+
400
+ /* XXX Check that we can read at least one byte? */
401
+ return (ARCHIVE_OK);
402
+ }
403
+
404
+ static int
405
+ program_bidder_init(struct archive_read_filter *self)
406
+ {
407
+ struct program_bidder *bidder_state;
408
+
409
+ bidder_state = (struct program_bidder *)self->bidder->data;
410
+ return (__archive_read_program(self, bidder_state->cmd));
411
+ }
412
+
413
+ static ssize_t
414
+ program_filter_read(struct archive_read_filter *self, const void **buff)
415
+ {
416
+ struct program_filter *state;
417
+ ssize_t bytes;
418
+ size_t total;
419
+ char *p;
420
+
421
+ state = (struct program_filter *)self->data;
422
+
423
+ total = 0;
424
+ p = state->out_buf;
425
+ while (state->child_stdout != -1 && total < state->out_buf_len) {
426
+ bytes = child_read(self, p, state->out_buf_len - total);
427
+ if (bytes < 0)
428
+ /* No recovery is possible if we can no longer
429
+ * read from the child. */
430
+ return (ARCHIVE_FATAL);
431
+ if (bytes == 0)
432
+ /* We got EOF from the child. */
433
+ break;
434
+ total += bytes;
435
+ p += bytes;
436
+ }
437
+
438
+ *buff = state->out_buf;
439
+ return (total);
440
+ }
441
+
442
+ static int
443
+ program_filter_close(struct archive_read_filter *self)
444
+ {
445
+ struct program_filter *state;
446
+ int e;
447
+
448
+ state = (struct program_filter *)self->data;
449
+ e = child_stop(self, state);
450
+
451
+ /* Release our private data. */
452
+ free(state->out_buf);
453
+ free(state->description);
454
+ free(state);
455
+
456
+ return (e);
457
+ }
458
+
459
+ #endif /* !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) */