/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 client { |
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 ARCHIVE_OK; |
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 | if (length > (uint64_t)(INT64_MAX - f->bytes_written)) |
244 | 0 | return(ARCHIVE_FATAL); |
245 | 0 | r = (f->write)(f, buff, length); |
246 | 0 | f->bytes_written += (int64_t)length; |
247 | 0 | return (r); |
248 | 0 | } |
249 | | |
250 | | /* |
251 | | * Recursive function for opening the filter chain |
252 | | * Last filter is opened first |
253 | | */ |
254 | | static int |
255 | | __archive_write_open_filter(struct archive_write_filter *f) |
256 | 0 | { |
257 | 0 | int ret; |
258 | |
|
259 | 0 | ret = ARCHIVE_OK; |
260 | 0 | if (f->next_filter != NULL) |
261 | 0 | ret = __archive_write_open_filter(f->next_filter); |
262 | 0 | if (ret != ARCHIVE_OK) |
263 | 0 | return (ret); |
264 | 0 | if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW) |
265 | 0 | return (ARCHIVE_FATAL); |
266 | 0 | if (f->open == NULL) { |
267 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; |
268 | 0 | return (ARCHIVE_OK); |
269 | 0 | } |
270 | 0 | ret = (f->open)(f); |
271 | 0 | if (ret == ARCHIVE_OK) |
272 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN; |
273 | 0 | else |
274 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; |
275 | 0 | return (ret); |
276 | 0 | } |
277 | | |
278 | | /* |
279 | | * Open all filters |
280 | | */ |
281 | | static int |
282 | | __archive_write_filters_open(struct archive_write *a) |
283 | 0 | { |
284 | 0 | return (__archive_write_open_filter(a->filter_first)); |
285 | 0 | } |
286 | | |
287 | | /* |
288 | | * Close all filters |
289 | | */ |
290 | | static int |
291 | | __archive_write_filters_close(struct archive_write *a) |
292 | 0 | { |
293 | 0 | struct archive_write_filter *f; |
294 | 0 | int ret, ret1; |
295 | 0 | ret = ARCHIVE_OK; |
296 | 0 | for (f = a->filter_first; f != NULL; f = f->next_filter) { |
297 | | /* Do not close filters that are not open */ |
298 | 0 | if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) { |
299 | 0 | if (f->close != NULL) { |
300 | 0 | ret1 = (f->close)(f); |
301 | 0 | if (ret1 < ret) |
302 | 0 | ret = ret1; |
303 | 0 | if (ret1 == ARCHIVE_OK) { |
304 | 0 | f->state = |
305 | 0 | ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
306 | 0 | } else { |
307 | 0 | f->state = |
308 | 0 | ARCHIVE_WRITE_FILTER_STATE_FATAL; |
309 | 0 | } |
310 | 0 | } else |
311 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
312 | 0 | } |
313 | 0 | } |
314 | 0 | return (ret); |
315 | 0 | } |
316 | | |
317 | | int |
318 | | __archive_write_output(struct archive_write *a, const void *buff, size_t length) |
319 | 0 | { |
320 | 0 | return (__archive_write_filter(a->filter_first, buff, length)); |
321 | 0 | } |
322 | | |
323 | | static int |
324 | | __archive_write_filters_flush(struct archive_write *a) |
325 | 0 | { |
326 | 0 | struct archive_write_filter *f; |
327 | 0 | int ret, ret1; |
328 | |
|
329 | 0 | ret = ARCHIVE_OK; |
330 | 0 | for (f = a->filter_first; f != NULL; f = f->next_filter) { |
331 | 0 | if (f->flush != NULL && f->bytes_written > 0) { |
332 | 0 | ret1 = (f->flush)(f); |
333 | 0 | if (ret1 < ret) |
334 | 0 | ret = ret1; |
335 | 0 | if (ret1 < ARCHIVE_WARN) |
336 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL; |
337 | 0 | } |
338 | 0 | } |
339 | 0 | return (ret); |
340 | 0 | } |
341 | | |
342 | | int |
343 | | __archive_write_nulls(struct archive_write *a, uint64_t length) |
344 | 0 | { |
345 | 0 | if (length == 0) |
346 | 0 | return (ARCHIVE_OK); |
347 | | |
348 | 0 | while (length > 0) { |
349 | 0 | size_t to_write = length < a->null_length ? length : a->null_length; |
350 | 0 | int r = __archive_write_output(a, a->nulls, to_write); |
351 | 0 | if (r < ARCHIVE_OK) |
352 | 0 | return (r); |
353 | 0 | length -= to_write; |
354 | 0 | } |
355 | 0 | return (ARCHIVE_OK); |
356 | 0 | } |
357 | | |
358 | | static int |
359 | | archive_write_client_open(struct archive_write_filter *f) |
360 | 0 | { |
361 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
362 | 0 | struct client *client; |
363 | 0 | void *buffer; |
364 | 0 | size_t buffer_size; |
365 | |
|
366 | 0 | f->bytes_per_block = archive_write_get_bytes_per_block(f->archive); |
367 | 0 | f->bytes_in_last_block = |
368 | 0 | archive_write_get_bytes_in_last_block(f->archive); |
369 | 0 | buffer_size = f->bytes_per_block; |
370 | |
|
371 | 0 | client = calloc(1, sizeof(*client)); |
372 | 0 | buffer = malloc(buffer_size); |
373 | 0 | if (client == NULL || buffer == NULL) { |
374 | 0 | free(client); |
375 | 0 | free(buffer); |
376 | 0 | archive_set_error(f->archive, ENOMEM, |
377 | 0 | "Can't allocate data for output buffering"); |
378 | 0 | return (ARCHIVE_FATAL); |
379 | 0 | } |
380 | | |
381 | 0 | client->buffer_size = buffer_size; |
382 | 0 | client->buffer = buffer; |
383 | 0 | client->next = client->buffer; |
384 | 0 | client->avail = client->buffer_size; |
385 | 0 | f->data = client; |
386 | |
|
387 | 0 | if (a->client_opener == NULL) |
388 | 0 | return (ARCHIVE_OK); |
389 | 0 | return (a->client_opener(f->archive, a->client_data)); |
390 | 0 | } |
391 | | |
392 | | static int |
393 | | archive_write_client_write(struct archive_write_filter *f, |
394 | | const void *_buff, size_t length) |
395 | 0 | { |
396 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
397 | 0 | struct client *client = f->data; |
398 | 0 | const char *buff = (const char *)_buff; |
399 | 0 | ssize_t remaining, to_copy; |
400 | 0 | ssize_t bytes_written; |
401 | |
|
402 | 0 | remaining = length; |
403 | | |
404 | | /* |
405 | | * If there is no buffer for blocking, just pass the data |
406 | | * straight through to the client write callback. In |
407 | | * particular, this supports "no write delay" operation for |
408 | | * special applications. Just set the block size to zero. |
409 | | */ |
410 | 0 | if (client->buffer_size == 0) { |
411 | 0 | while (remaining > 0) { |
412 | 0 | bytes_written = (a->client_writer)(&a->archive, |
413 | 0 | a->client_data, buff, remaining); |
414 | 0 | if (bytes_written <= 0) |
415 | 0 | return (ARCHIVE_FATAL); |
416 | 0 | remaining -= bytes_written; |
417 | 0 | buff += bytes_written; |
418 | 0 | } |
419 | 0 | return (ARCHIVE_OK); |
420 | 0 | } |
421 | | |
422 | | /* If the copy buffer isn't empty, try to fill it. */ |
423 | 0 | if (client->avail < client->buffer_size) { |
424 | | /* If buffer is not empty... */ |
425 | | /* ... copy data into buffer ... */ |
426 | 0 | to_copy = ((size_t)remaining > client->avail) ? |
427 | 0 | client->avail : (size_t)remaining; |
428 | 0 | memcpy(client->next, buff, to_copy); |
429 | 0 | client->next += to_copy; |
430 | 0 | client->avail -= to_copy; |
431 | 0 | buff += to_copy; |
432 | 0 | remaining -= to_copy; |
433 | | /* ... if it's full, write it out. */ |
434 | 0 | if (client->avail == 0) { |
435 | 0 | char *p = client->buffer; |
436 | 0 | size_t to_write = client->buffer_size; |
437 | 0 | while (to_write > 0) { |
438 | 0 | bytes_written = (a->client_writer)(&a->archive, |
439 | 0 | a->client_data, p, to_write); |
440 | 0 | if (bytes_written <= 0) |
441 | 0 | return (ARCHIVE_FATAL); |
442 | 0 | if ((size_t)bytes_written > to_write) { |
443 | 0 | archive_set_error(&(a->archive), |
444 | 0 | -1, "write overrun"); |
445 | 0 | return (ARCHIVE_FATAL); |
446 | 0 | } |
447 | 0 | p += bytes_written; |
448 | 0 | to_write -= bytes_written; |
449 | 0 | } |
450 | 0 | client->next = client->buffer; |
451 | 0 | client->avail = client->buffer_size; |
452 | 0 | } |
453 | 0 | } |
454 | | |
455 | 0 | while ((size_t)remaining >= client->buffer_size) { |
456 | | /* Write out full blocks directly to client. */ |
457 | 0 | bytes_written = (a->client_writer)(&a->archive, |
458 | 0 | a->client_data, buff, client->buffer_size); |
459 | 0 | if (bytes_written <= 0) |
460 | 0 | return (ARCHIVE_FATAL); |
461 | 0 | buff += bytes_written; |
462 | 0 | remaining -= bytes_written; |
463 | 0 | } |
464 | | |
465 | 0 | if (remaining > 0) { |
466 | | /* Copy last bit into copy buffer. */ |
467 | 0 | memcpy(client->next, buff, remaining); |
468 | 0 | client->next += remaining; |
469 | 0 | client->avail -= remaining; |
470 | 0 | } |
471 | 0 | return (ARCHIVE_OK); |
472 | 0 | } |
473 | | |
474 | | static int |
475 | | archive_write_client_free(struct archive_write_filter *f) |
476 | 0 | { |
477 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
478 | 0 | struct client *client = f->data; |
479 | |
|
480 | 0 | if (a->client_freer) |
481 | 0 | (*a->client_freer)(&a->archive, a->client_data); |
482 | 0 | a->client_data = NULL; |
483 | | |
484 | | /* Clear passphrase. */ |
485 | 0 | if (a->passphrase != NULL) { |
486 | 0 | memset(a->passphrase, 0, strlen(a->passphrase)); |
487 | 0 | free(a->passphrase); |
488 | 0 | a->passphrase = NULL; |
489 | 0 | } |
490 | | |
491 | | /* Free state. */ |
492 | 0 | if (client != NULL) { |
493 | 0 | free(client->buffer); |
494 | 0 | free(client); |
495 | 0 | f->data = NULL; |
496 | 0 | } |
497 | |
|
498 | 0 | return (ARCHIVE_OK); |
499 | 0 | } |
500 | | |
501 | | static int |
502 | | archive_write_client_close(struct archive_write_filter *f) |
503 | 0 | { |
504 | 0 | struct archive_write *a = (struct archive_write *)f->archive; |
505 | 0 | struct client *client = f->data; |
506 | 0 | ssize_t block_length; |
507 | 0 | ssize_t target_block_length; |
508 | 0 | ssize_t bytes_written; |
509 | 0 | size_t to_write; |
510 | 0 | char *p; |
511 | 0 | int ret = ARCHIVE_OK; |
512 | | |
513 | | /* If there's pending data, pad and write the last block */ |
514 | 0 | if (client->next != client->buffer) { |
515 | 0 | block_length = client->buffer_size - client->avail; |
516 | | |
517 | | /* Tricky calculation to determine size of last block */ |
518 | 0 | if (a->bytes_in_last_block <= 0) |
519 | | /* Default or Zero: pad to full block */ |
520 | 0 | target_block_length = a->bytes_per_block; |
521 | 0 | else |
522 | | /* Round to next multiple of bytes_in_last_block. */ |
523 | 0 | target_block_length = a->bytes_in_last_block * |
524 | 0 | ( (block_length + a->bytes_in_last_block - 1) / |
525 | 0 | a->bytes_in_last_block); |
526 | 0 | if (target_block_length > a->bytes_per_block) |
527 | 0 | target_block_length = a->bytes_per_block; |
528 | 0 | if (block_length < target_block_length) { |
529 | 0 | memset(client->next, 0, |
530 | 0 | target_block_length - block_length); |
531 | 0 | block_length = target_block_length; |
532 | 0 | } |
533 | 0 | p = client->buffer; |
534 | 0 | to_write = block_length; |
535 | 0 | while (to_write > 0) { |
536 | 0 | bytes_written = (a->client_writer)(&a->archive, |
537 | 0 | a->client_data, p, to_write); |
538 | 0 | if (bytes_written <= 0) { |
539 | 0 | ret = ARCHIVE_FATAL; |
540 | 0 | break; |
541 | 0 | } |
542 | 0 | if ((size_t)bytes_written > to_write) { |
543 | 0 | archive_set_error(&(a->archive), |
544 | 0 | -1, "write overrun"); |
545 | 0 | ret = ARCHIVE_FATAL; |
546 | 0 | break; |
547 | 0 | } |
548 | 0 | p += bytes_written; |
549 | 0 | to_write -= bytes_written; |
550 | 0 | } |
551 | 0 | } |
552 | 0 | if (a->client_closer) |
553 | 0 | (*a->client_closer)(&a->archive, a->client_data); |
554 | | |
555 | | /* Clear the close handler myself not to be called again. */ |
556 | 0 | f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED; |
557 | 0 | return (ret); |
558 | 0 | } |
559 | | |
560 | | /* |
561 | | * Open the archive using the current settings. |
562 | | */ |
563 | | int |
564 | | archive_write_open2(struct archive *_a, void *client_data, |
565 | | archive_open_callback *opener, archive_write_callback *writer, |
566 | | archive_close_callback *closer, archive_free_callback *freer) |
567 | 0 | { |
568 | 0 | struct archive_write *a = (struct archive_write *)_a; |
569 | 0 | struct archive_write_filter *client_filter; |
570 | 0 | int ret, r1; |
571 | |
|
572 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
573 | 0 | ARCHIVE_STATE_NEW, "archive_write_open"); |
574 | 0 | archive_clear_error(&a->archive); |
575 | |
|
576 | 0 | a->client_writer = writer; |
577 | 0 | a->client_opener = opener; |
578 | 0 | a->client_closer = closer; |
579 | 0 | a->client_freer = freer; |
580 | 0 | a->client_data = client_data; |
581 | |
|
582 | 0 | client_filter = __archive_write_allocate_filter(_a); |
583 | |
|
584 | 0 | if (client_filter == NULL) |
585 | 0 | return (ARCHIVE_FATAL); |
586 | | |
587 | 0 | client_filter->open = archive_write_client_open; |
588 | 0 | client_filter->write = archive_write_client_write; |
589 | 0 | client_filter->close = archive_write_client_close; |
590 | 0 | client_filter->free = archive_write_client_free; |
591 | |
|
592 | 0 | ret = __archive_write_filters_open(a); |
593 | 0 | if (ret < ARCHIVE_WARN) { |
594 | 0 | r1 = __archive_write_filters_close(a); |
595 | 0 | __archive_write_filters_free(_a); |
596 | 0 | return (r1 < ret ? r1 : ret); |
597 | 0 | } |
598 | | |
599 | 0 | a->archive.state = ARCHIVE_STATE_HEADER; |
600 | 0 | if (a->format_init) |
601 | 0 | ret = (a->format_init)(a); |
602 | 0 | return (ret); |
603 | 0 | } |
604 | | |
605 | | int |
606 | | archive_write_open(struct archive *_a, void *client_data, |
607 | | archive_open_callback *opener, archive_write_callback *writer, |
608 | | archive_close_callback *closer) |
609 | 0 | { |
610 | 0 | return archive_write_open2(_a, client_data, opener, writer, |
611 | 0 | closer, NULL); |
612 | 0 | } |
613 | | |
614 | | /* |
615 | | * Close out the archive. |
616 | | */ |
617 | | static int |
618 | | _archive_write_close(struct archive *_a) |
619 | 0 | { |
620 | 0 | struct archive_write *a = (struct archive_write *)_a; |
621 | 0 | int r = ARCHIVE_OK, r1 = ARCHIVE_OK; |
622 | |
|
623 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
624 | 0 | ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, |
625 | 0 | "archive_write_close"); |
626 | 0 | if (a->archive.state == ARCHIVE_STATE_NEW |
627 | 0 | || a->archive.state == ARCHIVE_STATE_CLOSED) |
628 | 0 | return (ARCHIVE_OK); /* Okay to close() when not open. */ |
629 | | |
630 | 0 | archive_clear_error(&a->archive); |
631 | | |
632 | | /* Finish the last entry if a finish callback is specified */ |
633 | 0 | if (a->archive.state == ARCHIVE_STATE_DATA |
634 | 0 | && a->format_finish_entry != NULL) |
635 | 0 | r = ((a->format_finish_entry)(a)); |
636 | | |
637 | | /* Finish off the archive. */ |
638 | | /* TODO: have format closers invoke compression close. */ |
639 | 0 | if (a->format_close != NULL) { |
640 | 0 | r1 = (a->format_close)(a); |
641 | 0 | if (r1 < r) |
642 | 0 | r = r1; |
643 | 0 | } |
644 | | |
645 | | /* Finish the compression and close the stream. */ |
646 | 0 | r1 = __archive_write_filters_close(a); |
647 | 0 | if (r1 < r) |
648 | 0 | r = r1; |
649 | |
|
650 | 0 | if (a->archive.state != ARCHIVE_STATE_FATAL) |
651 | 0 | a->archive.state = ARCHIVE_STATE_CLOSED; |
652 | 0 | return (r); |
653 | 0 | } |
654 | | |
655 | | static int |
656 | | _archive_write_filter_count(struct archive *_a) |
657 | 0 | { |
658 | 0 | struct archive_write *a = (struct archive_write *)_a; |
659 | 0 | struct archive_write_filter *p = a->filter_first; |
660 | 0 | int count = 0; |
661 | 0 | while(p) { |
662 | 0 | count++; |
663 | 0 | p = p->next_filter; |
664 | 0 | } |
665 | 0 | return count; |
666 | 0 | } |
667 | | |
668 | | void |
669 | | __archive_write_filters_free(struct archive *_a) |
670 | 0 | { |
671 | 0 | struct archive_write *a = (struct archive_write *)_a; |
672 | 0 | int r = ARCHIVE_OK, r1; |
673 | |
|
674 | 0 | while (a->filter_first != NULL) { |
675 | 0 | struct archive_write_filter *next |
676 | 0 | = a->filter_first->next_filter; |
677 | 0 | if (a->filter_first->free != NULL) { |
678 | 0 | r1 = (*a->filter_first->free)(a->filter_first); |
679 | 0 | if (r > r1) |
680 | 0 | r = r1; |
681 | 0 | } |
682 | 0 | free(a->filter_first); |
683 | 0 | a->filter_first = next; |
684 | 0 | } |
685 | 0 | a->filter_last = NULL; |
686 | 0 | } |
687 | | |
688 | | int |
689 | | __archive_write_unregister_format(struct archive_write *a) |
690 | 0 | { |
691 | 0 | int r = ARCHIVE_OK; |
692 | |
|
693 | 0 | if (a->format_free != NULL) |
694 | 0 | r = (a->format_free)(a); |
695 | |
|
696 | 0 | a->format_data = NULL; |
697 | 0 | a->format_name = NULL; |
698 | 0 | a->format_init = NULL; |
699 | 0 | a->format_options = NULL; |
700 | 0 | a->format_finish_entry = NULL; |
701 | 0 | a->format_write_header = NULL; |
702 | 0 | a->format_write_data = NULL; |
703 | 0 | a->format_close = NULL; |
704 | 0 | a->format_free = NULL; |
705 | 0 | a->archive.archive_format = 0; |
706 | 0 | a->archive.archive_format_name = NULL; |
707 | |
|
708 | 0 | return (r); |
709 | 0 | } |
710 | | |
711 | | /* |
712 | | * Destroy the archive structure. |
713 | | * |
714 | | * Be careful: user might just call write_new and then write_free. |
715 | | * Don't assume we actually wrote anything or performed any non-trivial |
716 | | * initialization. |
717 | | */ |
718 | | static int |
719 | | _archive_write_free(struct archive *_a) |
720 | 0 | { |
721 | 0 | struct archive_write *a = (struct archive_write *)_a; |
722 | 0 | int r = ARCHIVE_OK, r1; |
723 | |
|
724 | 0 | if (_a == NULL) |
725 | 0 | return (ARCHIVE_OK); |
726 | | /* It is okay to call free() in state FATAL. */ |
727 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
728 | 0 | ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free"); |
729 | 0 | if (a->archive.state != ARCHIVE_STATE_FATAL) |
730 | 0 | r = archive_write_close(&a->archive); |
731 | | |
732 | | /* Release format resources. */ |
733 | 0 | r1 = __archive_write_unregister_format(a); |
734 | 0 | if (r1 < r) |
735 | 0 | r = r1; |
736 | |
|
737 | 0 | __archive_write_filters_free(_a); |
738 | | |
739 | | /* Release various dynamic buffers. */ |
740 | 0 | free((void *)(uintptr_t)(const void *)a->nulls); |
741 | 0 | archive_string_free(&a->archive.error_string); |
742 | 0 | if (a->passphrase != NULL) { |
743 | | /* A passphrase should be cleaned. */ |
744 | 0 | memset(a->passphrase, 0, strlen(a->passphrase)); |
745 | 0 | free(a->passphrase); |
746 | 0 | } |
747 | 0 | a->archive.magic = 0; |
748 | 0 | __archive_clean(&a->archive); |
749 | 0 | free(a); |
750 | 0 | return (r); |
751 | 0 | } |
752 | | |
753 | | /* |
754 | | * Write the appropriate header. |
755 | | */ |
756 | | static int |
757 | | _archive_write_header(struct archive *_a, struct archive_entry *entry) |
758 | 0 | { |
759 | 0 | struct archive_write *a = (struct archive_write *)_a; |
760 | 0 | int ret, r2; |
761 | |
|
762 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
763 | 0 | ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header"); |
764 | 0 | archive_clear_error(&a->archive); |
765 | |
|
766 | 0 | if (a->format_write_header == NULL) { |
767 | 0 | archive_set_error(&(a->archive), -1, |
768 | 0 | "Format must be set before you can write to an archive"); |
769 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
770 | 0 | return (ARCHIVE_FATAL); |
771 | 0 | } |
772 | | |
773 | | /* In particular, "retry" and "fatal" get returned immediately. */ |
774 | 0 | ret = archive_write_finish_entry(&a->archive); |
775 | 0 | if (ret == ARCHIVE_FATAL) { |
776 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
777 | 0 | return (ARCHIVE_FATAL); |
778 | 0 | } |
779 | 0 | if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN) |
780 | 0 | return (ret); |
781 | | |
782 | 0 | if (a->skip_file_set && |
783 | 0 | archive_entry_dev_is_set(entry) && |
784 | 0 | archive_entry_ino_is_set(entry) && |
785 | 0 | archive_entry_dev(entry) == (dev_t)a->skip_file_dev && |
786 | 0 | archive_entry_ino64(entry) == a->skip_file_ino) { |
787 | 0 | archive_set_error(&a->archive, EIO, |
788 | 0 | "Can't add archive to itself"); |
789 | 0 | return (ARCHIVE_FAILED); |
790 | 0 | } |
791 | | |
792 | | /* Flush filters at boundary. */ |
793 | 0 | r2 = __archive_write_filters_flush(a); |
794 | 0 | if (r2 == ARCHIVE_FAILED) { |
795 | 0 | return (ARCHIVE_FAILED); |
796 | 0 | } |
797 | 0 | if (r2 == ARCHIVE_FATAL) { |
798 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
799 | 0 | return (ARCHIVE_FATAL); |
800 | 0 | } |
801 | 0 | if (r2 < ret) |
802 | 0 | ret = r2; |
803 | | |
804 | | /* Format and write header. */ |
805 | 0 | r2 = ((a->format_write_header)(a, entry)); |
806 | 0 | if (r2 == ARCHIVE_FAILED) { |
807 | 0 | return (ARCHIVE_FAILED); |
808 | 0 | } |
809 | 0 | if (r2 == ARCHIVE_FATAL) { |
810 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
811 | 0 | return (ARCHIVE_FATAL); |
812 | 0 | } |
813 | 0 | if (r2 < ret) |
814 | 0 | ret = r2; |
815 | |
|
816 | 0 | a->archive.state = ARCHIVE_STATE_DATA; |
817 | 0 | return (ret); |
818 | 0 | } |
819 | | |
820 | | static int |
821 | | _archive_write_finish_entry(struct archive *_a) |
822 | 0 | { |
823 | 0 | struct archive_write *a = (struct archive_write *)_a; |
824 | 0 | int ret = ARCHIVE_OK; |
825 | |
|
826 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
827 | 0 | ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA, |
828 | 0 | "archive_write_finish_entry"); |
829 | 0 | if (a->archive.state & ARCHIVE_STATE_DATA |
830 | 0 | && a->format_finish_entry != NULL) |
831 | 0 | ret = (a->format_finish_entry)(a); |
832 | 0 | if (ret == ARCHIVE_FATAL) |
833 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
834 | 0 | else |
835 | 0 | a->archive.state = ARCHIVE_STATE_HEADER; |
836 | 0 | return (ret); |
837 | 0 | } |
838 | | |
839 | | /* |
840 | | * Note that the compressor is responsible for blocking. |
841 | | */ |
842 | | static ssize_t |
843 | | _archive_write_data(struct archive *_a, const void *buff, size_t s) |
844 | 0 | { |
845 | 0 | struct archive_write *a = (struct archive_write *)_a; |
846 | 0 | const size_t max_write = INT_MAX; |
847 | 0 | ssize_t ret; |
848 | |
|
849 | 0 | archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC, |
850 | 0 | ARCHIVE_STATE_DATA, "archive_write_data"); |
851 | | /* In particular, this catches attempts to pass negative values. */ |
852 | 0 | if (s > max_write) |
853 | 0 | s = max_write; |
854 | 0 | archive_clear_error(&a->archive); |
855 | 0 | ret = (a->format_write_data)(a, buff, s); |
856 | 0 | if (ret == ARCHIVE_FATAL) |
857 | 0 | a->archive.state = ARCHIVE_STATE_FATAL; |
858 | 0 | return (ret); |
859 | 0 | } |
860 | | |
861 | | static struct archive_write_filter * |
862 | | filter_lookup(struct archive *_a, int n) |
863 | 0 | { |
864 | 0 | struct archive_write *a = (struct archive_write *)_a; |
865 | 0 | struct archive_write_filter *f = a->filter_first; |
866 | 0 | if (n == -1) |
867 | 0 | return a->filter_last; |
868 | 0 | if (n < 0) |
869 | 0 | return NULL; |
870 | 0 | while (n > 0 && f != NULL) { |
871 | 0 | f = f->next_filter; |
872 | 0 | --n; |
873 | 0 | } |
874 | 0 | return f; |
875 | 0 | } |
876 | | |
877 | | static int |
878 | | _archive_filter_code(struct archive *_a, int n) |
879 | 0 | { |
880 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
881 | 0 | return f == NULL ? -1 : f->code; |
882 | 0 | } |
883 | | |
884 | | static const char * |
885 | | _archive_filter_name(struct archive *_a, int n) |
886 | 0 | { |
887 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
888 | 0 | return f != NULL ? f->name : NULL; |
889 | 0 | } |
890 | | |
891 | | static int64_t |
892 | | _archive_filter_bytes(struct archive *_a, int n) |
893 | 0 | { |
894 | 0 | struct archive_write_filter *f = filter_lookup(_a, n); |
895 | 0 | return f == NULL ? -1 : f->bytes_written; |
896 | 0 | } |