/src/CMake/Utilities/cmlibarchive/libarchive/archive_write.c
Line | Count | Source |
1 | | /*- |
2 | | * Copyright (c) 2003-2010 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 | | |
28 | | /* |
29 | | * This file contains the "essential" portions of the write API, that |
30 | | * is, stuff that will essentially always be used by any client that |
31 | | * actually needs to write an archive. Optional pieces have been, as |
32 | | * far as possible, separated out into separate files to reduce |
33 | | * needlessly bloating statically-linked clients. |
34 | | */ |
35 | | |
36 | | #ifdef HAVE_SYS_WAIT_H |
37 | | #include <sys/wait.h> |
38 | | #endif |
39 | | #ifdef HAVE_ERRNO_H |
40 | | #include <errno.h> |
41 | | #endif |
42 | | #ifdef HAVE_LIMITS_H |
43 | | #include <limits.h> |
44 | | #endif |
45 | | #include <stdio.h> |
46 | | #ifdef HAVE_STDLIB_H |
47 | | #include <stdlib.h> |
48 | | #endif |
49 | | #ifdef HAVE_STRING_H |
50 | | #include <string.h> |
51 | | #endif |
52 | | #include <time.h> |
53 | | #ifdef HAVE_UNISTD_H |
54 | | #include <unistd.h> |
55 | | #endif |
56 | | |
57 | | #include "archive.h" |
58 | | #include "archive_entry.h" |
59 | | #include "archive_private.h" |
60 | | #include "archive_write_private.h" |
61 | | |
62 | | static int _archive_filter_code(struct archive *, int); |
63 | | static const char *_archive_filter_name(struct archive *, int); |
64 | | static int64_t _archive_filter_bytes(struct archive *, int); |
65 | | static int _archive_write_filter_count(struct archive *); |
66 | | static int _archive_write_close(struct archive *); |
67 | | static int _archive_write_free(struct archive *); |
68 | | static int _archive_write_header(struct archive *, struct archive_entry *); |
69 | | static int _archive_write_finish_entry(struct archive *); |
70 | | static ssize_t _archive_write_data(struct archive *, const void *, size_t); |
71 | | |
72 | | struct archive_none { |
73 | | size_t buffer_size; |
74 | | size_t avail; |
75 | | char *buffer; |
76 | | char *next; |
77 | | }; |
78 | | |
79 | | static const struct archive_vtable |
80 | | archive_write_vtable = { |
81 | | .archive_close = _archive_write_close, |
82 | | .archive_filter_bytes = _archive_filter_bytes, |
83 | | .archive_filter_code = _archive_filter_code, |
84 | | .archive_filter_name = _archive_filter_name, |
85 | | .archive_filter_count = _archive_write_filter_count, |
86 | | .archive_free = _archive_write_free, |
87 | | .archive_write_header = _archive_write_header, |
88 | | .archive_write_finish_entry = _archive_write_finish_entry, |
89 | | .archive_write_data = _archive_write_data, |
90 | | }; |
91 | | |
92 | | /* |
93 | | * Allocate, initialize and return an archive object. |
94 | | */ |
95 | | struct archive * |
96 | | archive_write_new(void) |
97 | 0 | { |
98 | 0 | struct archive_write *a; |
99 | 0 | unsigned char *nulls; |
100 | |
|
101 | 0 | a = calloc(1, sizeof(*a)); |
102 | 0 | if (a == NULL) |
103 | 0 | return (NULL); |
104 | 0 | a->archive.magic = ARCHIVE_WRITE_MAGIC; |
105 | 0 | a->archive.state = ARCHIVE_STATE_NEW; |
106 | 0 | a->archive.vtable = &archive_write_vtable; |
107 | | /* |
108 | | * The value 10240 here matches the traditional tar default, |
109 | | * but is otherwise arbitrary. |
110 | | * TODO: Set the default block size from the format selected. |
111 | | */ |
112 | 0 | a->bytes_per_block = 10240; |
113 | 0 | a->bytes_in_last_block = -1; /* Default */ |
114 | | |
115 | | /* Initialize a block of nulls for padding purposes. */ |
116 | 0 | a->null_length = 1024; |
117 | 0 | nulls = calloc(a->null_length, sizeof(unsigned char)); |
118 | 0 | if (nulls == NULL) { |
119 | 0 | free(a); |
120 | 0 | return (NULL); |
121 | 0 | } |
122 | 0 | a->nulls = nulls; |
123 | 0 | return (&a->archive); |
124 | 0 | } |
125 | | |
126 | | /* |
127 | | * Set the block size. Returns 0 if successful. |
128 | | */ |
129 | | int |
130 | | archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block) |
131 | 0 | { |
132 | 0 | struct archive_write *a = (struct archive_write *)_a; |
133 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
134 | 0 | ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block"); |
135 | | |
136 | 0 | if (bytes_per_block < 0) { |
137 | | // Do nothing if the bytes_per_block is negative |
138 | 0 | return 0; |
139 | 0 | } |
140 | 0 | a->bytes_per_block = bytes_per_block; |
141 | 0 | return (ARCHIVE_OK); |
142 | 0 | } |
143 | | |
144 | | /* |
145 | | * Get the current block size. |
146 | | */ |
147 | | int |
148 | | archive_write_get_bytes_per_block(struct archive *_a) |
149 | 0 | { |
150 | 0 | struct archive_write *a = (struct archive_write *)_a; |
151 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
152 | 0 | ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block"); |
153 | 0 | if (a->bytes_per_block < 0) { |
154 | | // Don't return a negative value |
155 | 0 | return 1; |
156 | 0 | } |
157 | 0 | return (a->bytes_per_block); |
158 | 0 | } |
159 | | |
160 | | /* |
161 | | * Set the size for the last block. |
162 | | * Returns 0 if successful. |
163 | | */ |
164 | | int |
165 | | archive_write_set_bytes_in_last_block(struct archive *_a, int bytes) |
166 | 0 | { |
167 | 0 | struct archive_write *a = (struct archive_write *)_a; |
168 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
169 | 0 | ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block"); |
170 | 0 | a->bytes_in_last_block = bytes; |
171 | 0 | return (ARCHIVE_OK); |
172 | 0 | } |
173 | | |
174 | | /* |
175 | | * Return the value set above. -1 indicates it has not been set. |
176 | | */ |
177 | | int |
178 | | archive_write_get_bytes_in_last_block(struct archive *_a) |
179 | 0 | { |
180 | 0 | struct archive_write *a = (struct archive_write *)_a; |
181 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
182 | 0 | ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block"); |
183 | 0 | return (a->bytes_in_last_block); |
184 | 0 | } |
185 | | |
186 | | /* |
187 | | * dev/ino of a file to be rejected. Used to prevent adding |
188 | | * an archive to itself recursively. |
189 | | */ |
190 | | int |
191 | | archive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i) |
192 | 0 | { |
193 | 0 | struct archive_write *a = (struct archive_write *)_a; |
194 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
195 | 0 | ARCHIVE_STATE_ANY, "archive_write_set_skip_file"); |
196 | 0 | a->skip_file_set = 1; |
197 | 0 | a->skip_file_dev = d; |
198 | 0 | a->skip_file_ino = i; |
199 | 0 | return (ARCHIVE_OK); |
200 | 0 | } |
201 | | |
202 | | /* |
203 | | * Allocate and return the next filter structure. |
204 | | */ |
205 | | struct archive_write_filter * |
206 | | __archive_write_allocate_filter(struct archive *_a) |
207 | 0 | { |
208 | 0 | struct archive_write *a = (struct archive_write *)_a; |
209 | 0 | struct archive_write_filter *f; |
210 | |
|
211 | 0 | f = calloc(1, sizeof(*f)); |
212 | |
|
213 | 0 | if (f == NULL) |
214 | 0 | return (NULL); |
215 | | |
216 | 0 | f->archive = _a; |
217 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_NEW; |
218 | 0 | if (a->filter_first == NULL) |
219 | 0 | a->filter_first = f; |
220 | 0 | else |
221 | 0 | a->filter_last->next_filter = f; |
222 | 0 | a->filter_last = f; |
223 | 0 | return f; |
224 | 0 | } |
225 | | |
226 | | /* |
227 | | * Write data to a particular filter. |
228 | | */ |
229 | | int |
230 | | __archive_write_filter(struct archive_write_filter *f, |
231 | | const void *buff, size_t length) |
232 | 0 | { |
233 | 0 | int r; |
234 | | /* Never write to non-open filters */ |
235 | 0 | if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN) |
236 | 0 | return(ARCHIVE_FATAL); |
237 | 0 | if (length == 0) |
238 | 0 | return(ARCHIVE_OK); |
239 | 0 | if (f->write == NULL) |
240 | | /* If unset, a fatal error has already occurred, so this filter |
241 | | * didn't open. We cannot write anything. */ |
242 | 0 | return(ARCHIVE_FATAL); |
243 | 0 | r = (f->write)(f, buff, length); |
244 | 0 | f->bytes_written += length; |
245 | 0 | return (r); |
246 | 0 | } |
247 | | |
248 | | /* |
249 | | * Recursive function for opening the filter chain |
250 | | * Last filter is opened first |
251 | | */ |
252 | | static int |
253 | | __archive_write_open_filter(struct archive_write_filter *f) |
254 | 0 | { |
255 | 0 | int ret; |
256 | |
|
257 | 0 | ret = ARCHIVE_OK; |
258 | 0 | if (f->next_filter != NULL) |
259 | 0 | ret = __archive_write_open_filter(f->next_filter); |
260 | 0 | if (ret != ARCHIVE_OK) |
261 | 0 | return (ret); |
262 | 0 | if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) |
263 | 0 | return (ARCHIVE_FATAL); |
264 | 0 | if (f->open == NULL) { |
265 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; |
266 | 0 | return (ARCHIVE_OK); |
267 | 0 | } |
268 | 0 | ret = (f->open)(f); |
269 | 0 | if (ret == ARCHIVE_OK) |
270 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; |
271 | 0 | else |
272 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; |
273 | 0 | return (ret); |
274 | 0 | } |
275 | | |
276 | | /* |
277 | | * Open all filters |
278 | | */ |
279 | | static int |
280 | | __archive_write_filters_open(struct archive_write *a) |
281 | 0 | { |
282 | 0 | return (__archive_write_open_filter(a->filter_first)); |
283 | 0 | } |
284 | | |
285 | | /* |
286 | | * Close all filters |
287 | | */ |
288 | | static int |
289 | | __archive_write_filters_close(struct archive_write *a) |
290 | 0 | { |
291 | 0 | struct archive_write_filter *f; |
292 | 0 | int ret, ret1; |
293 | 0 | ret = ARCHIVE_OK; |
294 | 0 | for (f = a->filter_first; f != NULL; f = f->next_filter) { |
295 | | /* Do not close filters that are not open */ |
296 | 0 | if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { |
297 | 0 | if (f->close != NULL) { |
298 | 0 | ret1 = (f->close)(f); |
299 | 0 | if (ret1 < ret) |
300 | 0 | ret = ret1; |
301 | 0 | if (ret1 == ARCHIVE_OK) { |
302 | 0 | f->state = |
303 | 0 | ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
304 | 0 | } else { |
305 | 0 | f->state = |
306 | 0 | ARCHIVE_WRITE_FILTER_STATE_FATAL; |
307 | 0 | } |
308 | 0 | } else |
309 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
310 | 0 | } |
311 | 0 | } |
312 | 0 | return (ret); |
313 | 0 | } |
314 | | |
315 | | int |
316 | | __archive_write_output(struct archive_write *a, const void *buff, size_t length) |
317 | 0 | { |
318 | 0 | return (__archive_write_filter(a->filter_first, buff, length)); |
319 | 0 | } |
320 | | |
321 | | static int |
322 | | __archive_write_filters_flush(struct archive_write *a) |
323 | 0 | { |
324 | 0 | struct archive_write_filter *f; |
325 | 0 | int ret, ret1; |
326 | |
|
327 | 0 | ret = ARCHIVE_OK; |
328 | 0 | for (f = a->filter_first; f != NULL; f = f->next_filter) { |
329 | 0 | if (f->flush != NULL && f->bytes_written > 0) { |
330 | 0 | ret1 = (f->flush)(f); |
331 | 0 | if (ret1 < ret) |
332 | 0 | ret = ret1; |
333 | 0 | if (ret1 < ARCHIVE_WARN) |
334 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; |
335 | 0 | } |
336 | 0 | } |
337 | 0 | return (ret); |
338 | 0 | } |
339 | | |
340 | | int |
341 | | __archive_write_nulls(struct archive_write *a, size_t length) |
342 | 0 | { |
343 | 0 | if (length == 0) |
344 | 0 | return (ARCHIVE_OK); |
345 | | |
346 | 0 | while (length > 0) { |
347 | 0 | size_t to_write = length < a->null_length ? length : a->null_length; |
348 | 0 | int r = __archive_write_output(a, a->nulls, to_write); |
349 | 0 | if (r < ARCHIVE_OK) |
350 | 0 | return (r); |
351 | 0 | length -= to_write; |
352 | 0 | } |
353 | 0 | return (ARCHIVE_OK); |
354 | 0 | } |
355 | | |
356 | | static int |
357 | | archive_write_client_open(struct archive_write_filter *f) |
358 | 0 | { |
359 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
360 | 0 | struct archive_none *state; |
361 | 0 | void *buffer; |
362 | 0 | size_t buffer_size; |
363 | |
|
364 | 0 | f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); |
365 | 0 | f->bytes_in_last_block = |
366 | 0 | archive_write_get_bytes_in_last_block(f->archive); |
367 | 0 | buffer_size = f->bytes_per_block; |
368 | |
|
369 | 0 | state = calloc(1, sizeof(*state)); |
370 | 0 | buffer = malloc(buffer_size); |
371 | 0 | if (state == NULL || buffer == NULL) { |
372 | 0 | free(state); |
373 | 0 | free(buffer); |
374 | 0 | archive_set_error(f->archive, ENOMEM, |
375 | 0 | "Can't allocate data for output buffering"); |
376 | 0 | return (ARCHIVE_FATAL); |
377 | 0 | } |
378 | | |
379 | 0 | state->buffer_size = buffer_size; |
380 | 0 | state->buffer = buffer; |
381 | 0 | state->next = state->buffer; |
382 | 0 | state->avail = state->buffer_size; |
383 | 0 | f->data = state; |
384 | |
|
385 | 0 | if (a->client_opener == NULL) |
386 | 0 | return (ARCHIVE_OK); |
387 | 0 | return (a->client_opener(f->archive, a->client_data)); |
388 | 0 | } |
389 | | |
390 | | static int |
391 | | archive_write_client_write(struct archive_write_filter *f, |
392 | | const void *_buff, size_t length) |
393 | 0 | { |
394 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
395 | 0 | struct archive_none *state = (struct archive_none *)f->data; |
396 | 0 | const char *buff = (const char *)_buff; |
397 | 0 | ssize_t remaining, to_copy; |
398 | 0 | ssize_t bytes_written; |
399 | |
|
400 | 0 | remaining = length; |
401 | | |
402 | | /* |
403 | | * If there is no buffer for blocking, just pass the data |
404 | | * straight through to the client write callback. In |
405 | | * particular, this supports "no write delay" operation for |
406 | | * special applications. Just set the block size to zero. |
407 | | */ |
408 | 0 | if (state->buffer_size == 0) { |
409 | 0 | while (remaining > 0) { |
410 | 0 | bytes_written = (a->client_writer)(&a->archive, |
411 | 0 | a->client_data, buff, remaining); |
412 | 0 | if (bytes_written <= 0) |
413 | 0 | return (ARCHIVE_FATAL); |
414 | 0 | remaining -= bytes_written; |
415 | 0 | buff += bytes_written; |
416 | 0 | } |
417 | 0 | return (ARCHIVE_OK); |
418 | 0 | } |
419 | | |
420 | | /* If the copy buffer isn't empty, try to fill it. */ |
421 | 0 | if (state->avail < state->buffer_size) { |
422 | | /* If buffer is not empty... */ |
423 | | /* ... copy data into buffer ... */ |
424 | 0 | to_copy = ((size_t)remaining > state->avail) ? |
425 | 0 | state->avail : (size_t)remaining; |
426 | 0 | memcpy(state->next, buff, to_copy); |
427 | 0 | state->next += to_copy; |
428 | 0 | state->avail -= to_copy; |
429 | 0 | buff += to_copy; |
430 | 0 | remaining -= to_copy; |
431 | | /* ... if it's full, write it out. */ |
432 | 0 | if (state->avail == 0) { |
433 | 0 | char *p = state->buffer; |
434 | 0 | size_t to_write = state->buffer_size; |
435 | 0 | while (to_write > 0) { |
436 | 0 | bytes_written = (a->client_writer)(&a->archive, |
437 | 0 | a->client_data, p, to_write); |
438 | 0 | if (bytes_written <= 0) |
439 | 0 | return (ARCHIVE_FATAL); |
440 | 0 | if ((size_t)bytes_written > to_write) { |
441 | 0 | archive_set_error(&(a->archive), |
442 | 0 | -1, "write overrun"); |
443 | 0 | return (ARCHIVE_FATAL); |
444 | 0 | } |
445 | 0 | p += bytes_written; |
446 | 0 | to_write -= bytes_written; |
447 | 0 | } |
448 | 0 | state->next = state->buffer; |
449 | 0 | state->avail = state->buffer_size; |
450 | 0 | } |
451 | 0 | } |
452 | | |
453 | 0 | while ((size_t)remaining >= state->buffer_size) { |
454 | | /* Write out full blocks directly to client. */ |
455 | 0 | bytes_written = (a->client_writer)(&a->archive, |
456 | 0 | a->client_data, buff, state->buffer_size); |
457 | 0 | if (bytes_written <= 0) |
458 | 0 | return (ARCHIVE_FATAL); |
459 | 0 | buff += bytes_written; |
460 | 0 | remaining -= bytes_written; |
461 | 0 | } |
462 | | |
463 | 0 | if (remaining > 0) { |
464 | | /* Copy last bit into copy buffer. */ |
465 | 0 | memcpy(state->next, buff, remaining); |
466 | 0 | state->next += remaining; |
467 | 0 | state->avail -= remaining; |
468 | 0 | } |
469 | 0 | return (ARCHIVE_OK); |
470 | 0 | } |
471 | | |
472 | | static int |
473 | | archive_write_client_free(struct archive_write_filter *f) |
474 | 0 | { |
475 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
476 | 0 | struct archive_none *state = (struct archive_none *)f->data; |
477 | |
|
478 | 0 | if (a->client_freer) |
479 | 0 | (*a->client_freer)(&a->archive, a->client_data); |
480 | 0 | a->client_data = NULL; |
481 | | |
482 | | /* Clear passphrase. */ |
483 | 0 | if (a->passphrase != NULL) { |
484 | 0 | memset(a->passphrase, 0, strlen(a->passphrase)); |
485 | 0 | free(a->passphrase); |
486 | 0 | a->passphrase = NULL; |
487 | 0 | } |
488 | | |
489 | | /* Free state. */ |
490 | 0 | if (state != NULL) { |
491 | 0 | free(state->buffer); |
492 | 0 | free(state); |
493 | 0 | f->data = NULL; |
494 | 0 | } |
495 | |
|
496 | 0 | return (ARCHIVE_OK); |
497 | 0 | } |
498 | | |
499 | | static int |
500 | | archive_write_client_close(struct archive_write_filter *f) |
501 | 0 | { |
502 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
503 | 0 | struct archive_none *state = (struct archive_none *)f->data; |
504 | 0 | ssize_t block_length; |
505 | 0 | ssize_t target_block_length; |
506 | 0 | ssize_t bytes_written; |
507 | 0 | size_t to_write; |
508 | 0 | char *p; |
509 | 0 | int ret = ARCHIVE_OK; |
510 | | |
511 | | /* If there's pending data, pad and write the last block */ |
512 | 0 | if (state->next != state->buffer) { |
513 | 0 | block_length = state->buffer_size - state->avail; |
514 | | |
515 | | /* Tricky calculation to determine size of last block */ |
516 | 0 | if (a->bytes_in_last_block <= 0) |
517 | | /* Default or Zero: pad to full block */ |
518 | 0 | target_block_length = a->bytes_per_block; |
519 | 0 | else |
520 | | /* Round to next multiple of bytes_in_last_block. */ |
521 | 0 | target_block_length = a->bytes_in_last_block * |
522 | 0 | ( (block_length + a->bytes_in_last_block - 1) / |
523 | 0 | a->bytes_in_last_block); |
524 | 0 | if (target_block_length > a->bytes_per_block) |
525 | 0 | target_block_length = a->bytes_per_block; |
526 | 0 | if (block_length < target_block_length) { |
527 | 0 | memset(state->next, 0, |
528 | 0 | target_block_length - block_length); |
529 | 0 | block_length = target_block_length; |
530 | 0 | } |
531 | 0 | p = state->buffer; |
532 | 0 | to_write = block_length; |
533 | 0 | while (to_write > 0) { |
534 | 0 | bytes_written = (a->client_writer)(&a->archive, |
535 | 0 | a->client_data, p, to_write); |
536 | 0 | if (bytes_written <= 0) { |
537 | 0 | ret = ARCHIVE_FATAL; |
538 | 0 | break; |
539 | 0 | } |
540 | 0 | if ((size_t)bytes_written > to_write) { |
541 | 0 | archive_set_error(&(a->archive), |
542 | 0 | -1, "write overrun"); |
543 | 0 | ret = ARCHIVE_FATAL; |
544 | 0 | break; |
545 | 0 | } |
546 | 0 | p += bytes_written; |
547 | 0 | to_write -= bytes_written; |
548 | 0 | } |
549 | 0 | } |
550 | 0 | if (a->client_closer) |
551 | 0 | (*a->client_closer)(&a->archive, a->client_data); |
552 | | |
553 | | /* Clear the close handler myself not to be called again. */ |
554 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
555 | 0 | return (ret); |
556 | 0 | } |
557 | | |
558 | | /* |
559 | | * Open the archive using the current settings. |
560 | | */ |
561 | | int |
562 | | archive_write_open2(struct archive *_a, void *client_data, |
563 | | archive_open_callback *opener, archive_write_callback *writer, |
564 | | archive_close_callback *closer, archive_free_callback *freer) |
565 | 0 | { |
566 | 0 | struct archive_write *a = (struct archive_write *)_a; |
567 | 0 | struct archive_write_filter *client_filter; |
568 | 0 | int ret, r1; |
569 | |
|
570 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
571 | 0 | ARCHIVE_STATE_NEW, "archive_write_open"); |
572 | 0 | archive_clear_error(&a->archive); |
573 | |
|
574 | 0 | a->client_writer = writer; |
575 | 0 | a->client_opener = opener; |
576 | 0 | a->client_closer = closer; |
577 | 0 | a->client_freer = freer; |
578 | 0 | a->client_data = client_data; |
579 | |
|
580 | 0 | client_filter = __archive_write_allocate_filter(_a); |
581 | |
|
582 | 0 | if (client_filter == NULL) |
583 | 0 | return (ARCHIVE_FATAL); |
584 | | |
585 | 0 | client_filter->open = archive_write_client_open; |
586 | 0 | client_filter->write = archive_write_client_write; |
587 | 0 | client_filter->close = archive_write_client_close; |
588 | 0 | client_filter->free = archive_write_client_free; |
589 | |
|
590 | 0 | ret = __archive_write_filters_open(a); |
591 | 0 | if (ret < ARCHIVE_WARN) { |
592 | 0 | r1 = __archive_write_filters_close(a); |
593 | 0 | __archive_write_filters_free(_a); |
594 | 0 | return (r1 < ret ? r1 : ret); |
595 | 0 | } |
596 | | |
597 | 0 | a->archive.state = ARCHIVE_STATE_HEADER; |
598 | 0 | if (a->format_init) |
599 | 0 | ret = (a->format_init)(a); |
600 | 0 | return (ret); |
601 | 0 | } |
602 | | |
603 | | int |
604 | | archive_write_open(struct archive *_a, void *client_data, |
605 | | archive_open_callback *opener, archive_write_callback *writer, |
606 | | archive_close_callback *closer) |
607 | 0 | { |
608 | 0 | return archive_write_open2(_a, client_data, opener, writer, |
609 | 0 | closer, NULL); |
610 | 0 | } |
611 | | |
612 | | /* |
613 | | * Close out the archive. |
614 | | */ |
615 | | static int |
616 | | _archive_write_close(struct archive *_a) |
617 | 0 | { |
618 | 0 | struct archive_write *a = (struct archive_write *)_a; |
619 | 0 | int r = ARCHIVE_OK, r1 = ARCHIVE_OK; |
620 | |
|
621 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
622 | 0 | ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, |
623 | 0 | "archive_write_close"); |
624 | 0 | if (a->archive.state == ARCHIVE_STATE_NEW |
625 | 0 | || a->archive.state == ARCHIVE_STATE_CLOSED) |
626 | 0 | return (ARCHIVE_OK); /* Okay to close() when not open. */ |
627 | | |
628 | 0 | archive_clear_error(&a->archive); |
629 | | |
630 | | /* Finish the last entry if a finish callback is specified */ |
631 | 0 | if (a->archive.state == ARCHIVE_STATE_DATA |
632 | 0 | && a->format_finish_entry != NULL) |
633 | 0 | r = ((a->format_finish_entry)(a)); |
634 | | |
635 | | /* Finish off the archive. */ |
636 | | /* TODO: have format closers invoke compression close. */ |
637 | 0 | if (a->format_close != NULL) { |
638 | 0 | r1 = (a->format_close)(a); |
639 | 0 | if (r1 < r) |
640 | 0 | r = r1; |
641 | 0 | } |
642 | | |
643 | | /* Finish the compression and close the stream. */ |
644 | 0 | r1 = __archive_write_filters_close(a); |
645 | 0 | if (r1 < r) |
646 | 0 | r = r1; |
647 | |
|
648 | 0 | if (a->archive.state != ARCHIVE_STATE_FATAL) |
649 | 0 | a->archive.state = ARCHIVE_STATE_CLOSED; |
650 | 0 | return (r); |
651 | 0 | } |
652 | | |
653 | | static int |
654 | | _archive_write_filter_count(struct archive *_a) |
655 | 0 | { |
656 | 0 | struct archive_write *a = (struct archive_write *)_a; |
657 | 0 | struct archive_write_filter *p = a->filter_first; |
658 | 0 | int count = 0; |
659 | 0 | while(p) { |
660 | 0 | count++; |
661 | 0 | p = p->next_filter; |
662 | 0 | } |
663 | 0 | return count; |
664 | 0 | } |
665 | | |
666 | | void |
667 | | __archive_write_filters_free(struct archive *_a) |
668 | 0 | { |
669 | 0 | struct archive_write *a = (struct archive_write *)_a; |
670 | 0 | int r = ARCHIVE_OK, r1; |
671 | |
|
672 | 0 | while (a->filter_first != NULL) { |
673 | 0 | struct archive_write_filter *next |
674 | 0 | = a->filter_first->next_filter; |
675 | 0 | if (a->filter_first->free != NULL) { |
676 | 0 | r1 = (*a->filter_first->free)(a->filter_first); |
677 | 0 | if (r > r1) |
678 | 0 | r = r1; |
679 | 0 | } |
680 | 0 | free(a->filter_first); |
681 | 0 | a->filter_first = next; |
682 | 0 | } |
683 | 0 | a->filter_last = NULL; |
684 | 0 | } |
685 | | |
686 | | /* |
687 | | * Destroy the archive structure. |
688 | | * |
689 | | * Be careful: user might just call write_new and then write_free. |
690 | | * Don't assume we actually wrote anything or performed any non-trivial |
691 | | * initialization. |
692 | | */ |
693 | | static int |
694 | | _archive_write_free(struct archive *_a) |
695 | 0 | { |
696 | 0 | struct archive_write *a = (struct archive_write *)_a; |
697 | 0 | int r = ARCHIVE_OK, r1; |
698 | |
|
699 | 0 | if (_a == NULL) |
700 | 0 | return (ARCHIVE_OK); |
701 | | /* It is okay to call free() in state FATAL. */ |
702 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
703 | 0 | ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free"); |
704 | 0 | if (a->archive.state != ARCHIVE_STATE_FATAL) |
705 | 0 | r = archive_write_close(&a->archive); |
706 | | |
707 | | /* Release format resources. */ |
708 | 0 | if (a->format_free != NULL) { |
709 | 0 | r1 = (a->format_free)(a); |
710 | 0 | if (r1 < r) |
711 | 0 | r = r1; |
712 | 0 | } |
713 | |
|
714 | 0 | __archive_write_filters_free(_a); |
715 | | |
716 | | /* Release various dynamic buffers. */ |
717 | 0 | free((void *)(uintptr_t)(const void *)a->nulls); |
718 | 0 | archive_string_free(&a->archive.error_string); |
719 | 0 | if (a->passphrase != NULL) { |
720 | | /* A passphrase should be cleaned. */ |
721 | 0 | memset(a->passphrase, 0, strlen(a->passphrase)); |
722 | 0 | free(a->passphrase); |
723 | 0 | } |
724 | 0 | a->archive.magic = 0; |
725 | 0 | __archive_clean(&a->archive); |
726 | 0 | free(a); |
727 | 0 | return (r); |
728 | 0 | } |
729 | | |
730 | | /* |
731 | | * Write the appropriate header. |
732 | | */ |
733 | | static int |
734 | | _archive_write_header(struct archive *_a, struct archive_entry *entry) |
735 | 0 | { |
736 | 0 | struct archive_write *a = (struct archive_write *)_a; |
737 | 0 | int ret, r2; |
738 | |
|
739 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
740 | 0 | ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); |
741 | 0 | archive_clear_error(&a->archive); |
742 | |
|
743 | 0 | if (a->format_write_header == NULL) { |
744 | 0 | archive_set_error(&(a->archive), -1, |
745 | 0 | "Format must be set before you can write to an archive."); |
746 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
747 | 0 | return (ARCHIVE_FATAL); |
748 | 0 | } |
749 | | |
750 | | /* In particular, "retry" and "fatal" get returned immediately. */ |
751 | 0 | ret = archive_write_finish_entry(&a->archive); |
752 | 0 | if (ret == ARCHIVE_FATAL) { |
753 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
754 | 0 | return (ARCHIVE_FATAL); |
755 | 0 | } |
756 | 0 | if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) |
757 | 0 | return (ret); |
758 | | |
759 | 0 | if (a->skip_file_set && |
760 | 0 | archive_entry_dev_is_set(entry) && |
761 | 0 | archive_entry_ino_is_set(entry) && |
762 | 0 | archive_entry_dev(entry) == (dev_t)a->skip_file_dev && |
763 | 0 | archive_entry_ino64(entry) == a->skip_file_ino) { |
764 | 0 | archive_set_error(&a->archive, 0, |
765 | 0 | "Can't add archive to itself"); |
766 | 0 | return (ARCHIVE_FAILED); |
767 | 0 | } |
768 | | |
769 | | /* Flush filters at boundary. */ |
770 | 0 | r2 = __archive_write_filters_flush(a); |
771 | 0 | if (r2 == ARCHIVE_FAILED) { |
772 | 0 | return (ARCHIVE_FAILED); |
773 | 0 | } |
774 | 0 | if (r2 == ARCHIVE_FATAL) { |
775 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
776 | 0 | return (ARCHIVE_FATAL); |
777 | 0 | } |
778 | 0 | if (r2 < ret) |
779 | 0 | ret = r2; |
780 | | |
781 | | /* Format and write header. */ |
782 | 0 | r2 = ((a->format_write_header)(a, entry)); |
783 | 0 | if (r2 == ARCHIVE_FAILED) { |
784 | 0 | return (ARCHIVE_FAILED); |
785 | 0 | } |
786 | 0 | if (r2 == ARCHIVE_FATAL) { |
787 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
788 | 0 | return (ARCHIVE_FATAL); |
789 | 0 | } |
790 | 0 | if (r2 < ret) |
791 | 0 | ret = r2; |
792 | |
|
793 | 0 | a->archive.state = ARCHIVE_STATE_DATA; |
794 | 0 | return (ret); |
795 | 0 | } |
796 | | |
797 | | static int |
798 | | _archive_write_finish_entry(struct archive *_a) |
799 | 0 | { |
800 | 0 | struct archive_write *a = (struct archive_write *)_a; |
801 | 0 | int ret = ARCHIVE_OK; |
802 | |
|
803 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
804 | 0 | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, |
805 | 0 | "archive_write_finish_entry"); |
806 | 0 | if (a->archive.state & ARCHIVE_STATE_DATA |
807 | 0 | && a->format_finish_entry != NULL) |
808 | 0 | ret = (a->format_finish_entry)(a); |
809 | 0 | if (ret == ARCHIVE_FATAL) |
810 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
811 | 0 | else |
812 | 0 | a->archive.state = ARCHIVE_STATE_HEADER; |
813 | 0 | return (ret); |
814 | 0 | } |
815 | | |
816 | | /* |
817 | | * Note that the compressor is responsible for blocking. |
818 | | */ |
819 | | static ssize_t |
820 | | _archive_write_data(struct archive *_a, const void *buff, size_t s) |
821 | 0 | { |
822 | 0 | struct archive_write *a = (struct archive_write *)_a; |
823 | 0 | const size_t max_write = INT_MAX; |
824 | 0 | ssize_t ret; |
825 | |
|
826 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
827 | 0 | ARCHIVE_STATE_DATA, "archive_write_data"); |
828 | | /* In particular, this catches attempts to pass negative values. */ |
829 | 0 | if (s > max_write) |
830 | 0 | s = max_write; |
831 | 0 | archive_clear_error(&a->archive); |
832 | 0 | ret = (a->format_write_data)(a, buff, s); |
833 | 0 | if (ret == ARCHIVE_FATAL) |
834 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
835 | 0 | return (ret); |
836 | 0 | } |
837 | | |
838 | | static struct archive_write_filter * |
839 | | filter_lookup(struct archive *_a, int n) |
840 | 0 | { |
841 | 0 | struct archive_write *a = (struct archive_write *)_a; |
842 | 0 | struct archive_write_filter *f = a->filter_first; |
843 | 0 | if (n == -1) |
844 | 0 | return a->filter_last; |
845 | 0 | if (n < 0) |
846 | 0 | return NULL; |
847 | 0 | while (n > 0 && f != NULL) { |
848 | 0 | f = f->next_filter; |
849 | 0 | --n; |
850 | 0 | } |
851 | 0 | return f; |
852 | 0 | } |
853 | | |
854 | | static int |
855 | | _archive_filter_code(struct archive *_a, int n) |
856 | 0 | { |
857 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
858 | 0 | return f == NULL ? -1 : f->code; |
859 | 0 | } |
860 | | |
861 | | static const char * |
862 | | _archive_filter_name(struct archive *_a, int n) |
863 | 0 | { |
864 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
865 | 0 | return f != NULL ? f->name : NULL; |
866 | 0 | } |
867 | | |
868 | | static int64_t |
869 | | _archive_filter_bytes(struct archive *_a, int n) |
870 | 0 | { |
871 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
872 | 0 | return f == NULL ? -1 : f->bytes_written; |
873 | 0 | } |