1228753Smm/*-
2232153Smm * Copyright (c) 2003-2010 Tim Kientzle
3228753Smm * All rights reserved.
4228753Smm *
5228753Smm * Redistribution and use in source and binary forms, with or without
6228753Smm * modification, are permitted provided that the following conditions
7228753Smm * are met:
8228753Smm * 1. Redistributions of source code must retain the above copyright
9228753Smm *    notice, this list of conditions and the following disclaimer.
10228753Smm * 2. Redistributions in binary form must reproduce the above copyright
11228753Smm *    notice, this list of conditions and the following disclaimer in the
12228753Smm *    documentation and/or other materials provided with the distribution.
13228753Smm *
14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24228753Smm */
25228753Smm
26228753Smm#include "archive_platform.h"
27228763Smm__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_write.c 370535 2021-09-10 08:34:36Z git2svn $");
28228753Smm
29228753Smm/*
30228753Smm * This file contains the "essential" portions of the write API, that
31228753Smm * is, stuff that will essentially always be used by any client that
32232153Smm * actually needs to write an archive.  Optional pieces have been, as
33228753Smm * far as possible, separated out into separate files to reduce
34228753Smm * needlessly bloating statically-linked clients.
35228753Smm */
36228753Smm
37228753Smm#ifdef HAVE_SYS_WAIT_H
38228753Smm#include <sys/wait.h>
39228753Smm#endif
40232153Smm#ifdef HAVE_ERRNO_H
41232153Smm#include <errno.h>
42232153Smm#endif
43228753Smm#ifdef HAVE_LIMITS_H
44228753Smm#include <limits.h>
45228753Smm#endif
46228753Smm#include <stdio.h>
47228753Smm#ifdef HAVE_STDLIB_H
48228753Smm#include <stdlib.h>
49228753Smm#endif
50228753Smm#ifdef HAVE_STRING_H
51228753Smm#include <string.h>
52228753Smm#endif
53228753Smm#include <time.h>
54228753Smm#ifdef HAVE_UNISTD_H
55228753Smm#include <unistd.h>
56228753Smm#endif
57228753Smm
58228753Smm#include "archive.h"
59228753Smm#include "archive_entry.h"
60228753Smm#include "archive_private.h"
61228753Smm#include "archive_write_private.h"
62228753Smm
63228753Smmstatic struct archive_vtable *archive_write_vtable(void);
64228753Smm
65232153Smmstatic int	_archive_filter_code(struct archive *, int);
66232153Smmstatic const char *_archive_filter_name(struct archive *, int);
67232153Smmstatic int64_t	_archive_filter_bytes(struct archive *, int);
68232153Smmstatic int  _archive_write_filter_count(struct archive *);
69228753Smmstatic int	_archive_write_close(struct archive *);
70228773Smmstatic int	_archive_write_free(struct archive *);
71228753Smmstatic int	_archive_write_header(struct archive *, struct archive_entry *);
72228753Smmstatic int	_archive_write_finish_entry(struct archive *);
73228753Smmstatic ssize_t	_archive_write_data(struct archive *, const void *, size_t);
74228753Smm
75232153Smmstruct archive_none {
76232153Smm	size_t buffer_size;
77232153Smm	size_t avail;
78232153Smm	char *buffer;
79232153Smm	char *next;
80232153Smm};
81232153Smm
82228753Smmstatic struct archive_vtable *
83228753Smmarchive_write_vtable(void)
84228753Smm{
85228753Smm	static struct archive_vtable av;
86228753Smm	static int inited = 0;
87228753Smm
88228753Smm	if (!inited) {
89228753Smm		av.archive_close = _archive_write_close;
90232153Smm		av.archive_filter_bytes = _archive_filter_bytes;
91232153Smm		av.archive_filter_code = _archive_filter_code;
92232153Smm		av.archive_filter_name = _archive_filter_name;
93232153Smm		av.archive_filter_count = _archive_write_filter_count;
94228773Smm		av.archive_free = _archive_write_free;
95228753Smm		av.archive_write_header = _archive_write_header;
96228753Smm		av.archive_write_finish_entry = _archive_write_finish_entry;
97228753Smm		av.archive_write_data = _archive_write_data;
98232153Smm		inited = 1;
99228753Smm	}
100228753Smm	return (&av);
101228753Smm}
102228753Smm
103228753Smm/*
104228753Smm * Allocate, initialize and return an archive object.
105228753Smm */
106228753Smmstruct archive *
107228753Smmarchive_write_new(void)
108228753Smm{
109228753Smm	struct archive_write *a;
110228753Smm	unsigned char *nulls;
111228753Smm
112311041Smm	a = (struct archive_write *)calloc(1, sizeof(*a));
113228753Smm	if (a == NULL)
114228753Smm		return (NULL);
115228753Smm	a->archive.magic = ARCHIVE_WRITE_MAGIC;
116228753Smm	a->archive.state = ARCHIVE_STATE_NEW;
117228753Smm	a->archive.vtable = archive_write_vtable();
118228753Smm	/*
119228753Smm	 * The value 10240 here matches the traditional tar default,
120228753Smm	 * but is otherwise arbitrary.
121228753Smm	 * TODO: Set the default block size from the format selected.
122228753Smm	 */
123228753Smm	a->bytes_per_block = 10240;
124228753Smm	a->bytes_in_last_block = -1;	/* Default */
125228753Smm
126228753Smm	/* Initialize a block of nulls for padding purposes. */
127228753Smm	a->null_length = 1024;
128311041Smm	nulls = (unsigned char *)calloc(1, a->null_length);
129228753Smm	if (nulls == NULL) {
130228753Smm		free(a);
131228753Smm		return (NULL);
132228753Smm	}
133228753Smm	a->nulls = nulls;
134228753Smm	return (&a->archive);
135228753Smm}
136228753Smm
137228753Smm/*
138228753Smm * Set the block size.  Returns 0 if successful.
139228753Smm */
140228753Smmint
141228753Smmarchive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
142228753Smm{
143228753Smm	struct archive_write *a = (struct archive_write *)_a;
144232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
145228753Smm	    ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
146228753Smm	a->bytes_per_block = bytes_per_block;
147228753Smm	return (ARCHIVE_OK);
148228753Smm}
149228753Smm
150228753Smm/*
151228753Smm * Get the current block size.  -1 if it has never been set.
152228753Smm */
153228753Smmint
154228753Smmarchive_write_get_bytes_per_block(struct archive *_a)
155228753Smm{
156228753Smm	struct archive_write *a = (struct archive_write *)_a;
157232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
158228753Smm	    ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
159228753Smm	return (a->bytes_per_block);
160228753Smm}
161228753Smm
162228753Smm/*
163228753Smm * Set the size for the last block.
164228753Smm * Returns 0 if successful.
165228753Smm */
166228753Smmint
167228753Smmarchive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
168228753Smm{
169228753Smm	struct archive_write *a = (struct archive_write *)_a;
170232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
171228753Smm	    ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
172228753Smm	a->bytes_in_last_block = bytes;
173228753Smm	return (ARCHIVE_OK);
174228753Smm}
175228753Smm
176228753Smm/*
177228753Smm * Return the value set above.  -1 indicates it has not been set.
178228753Smm */
179228753Smmint
180228753Smmarchive_write_get_bytes_in_last_block(struct archive *_a)
181228753Smm{
182228753Smm	struct archive_write *a = (struct archive_write *)_a;
183232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
184228753Smm	    ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
185228753Smm	return (a->bytes_in_last_block);
186228753Smm}
187228753Smm
188228753Smm/*
189228753Smm * dev/ino of a file to be rejected.  Used to prevent adding
190228753Smm * an archive to itself recursively.
191228753Smm */
192228753Smmint
193328827Smmarchive_write_set_skip_file(struct archive *_a, la_int64_t d, la_int64_t i)
194228753Smm{
195228753Smm	struct archive_write *a = (struct archive_write *)_a;
196232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
197228753Smm	    ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
198232153Smm	a->skip_file_set = 1;
199228753Smm	a->skip_file_dev = d;
200228753Smm	a->skip_file_ino = i;
201228753Smm	return (ARCHIVE_OK);
202228753Smm}
203228753Smm
204232153Smm/*
205232153Smm * Allocate and return the next filter structure.
206232153Smm */
207232153Smmstruct archive_write_filter *
208232153Smm__archive_write_allocate_filter(struct archive *_a)
209232153Smm{
210232153Smm	struct archive_write *a = (struct archive_write *)_a;
211232153Smm	struct archive_write_filter *f;
212228753Smm
213232153Smm	f = calloc(1, sizeof(*f));
214232153Smm	f->archive = _a;
215358088Smm	f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
216232153Smm	if (a->filter_first == NULL)
217232153Smm		a->filter_first = f;
218232153Smm	else
219232153Smm		a->filter_last->next_filter = f;
220232153Smm	a->filter_last = f;
221232153Smm	return f;
222232153Smm}
223232153Smm
224228753Smm/*
225232153Smm * Write data to a particular filter.
226232153Smm */
227232153Smmint
228232153Smm__archive_write_filter(struct archive_write_filter *f,
229232153Smm    const void *buff, size_t length)
230232153Smm{
231232153Smm	int r;
232358088Smm	/* Never write to non-open filters */
233358088Smm	if (f->state != ARCHIVE_WRITE_FILTER_STATE_OPEN)
234358088Smm		return(ARCHIVE_FATAL);
235232153Smm	if (length == 0)
236232153Smm		return(ARCHIVE_OK);
237248616Smm	if (f->write == NULL)
238313570Smm		/* If unset, a fatal error has already occurred, so this filter
239248616Smm		 * didn't open. We cannot write anything. */
240248616Smm		return(ARCHIVE_FATAL);
241232153Smm	r = (f->write)(f, buff, length);
242232153Smm	f->bytes_written += length;
243232153Smm	return (r);
244232153Smm}
245232153Smm
246232153Smm/*
247358088Smm * Recursive function for opening the filter chain
248358088Smm * Last filter is opened first
249232153Smm */
250358088Smmstatic int
251232153Smm__archive_write_open_filter(struct archive_write_filter *f)
252232153Smm{
253358088Smm	int ret;
254358088Smm
255358088Smm	ret = ARCHIVE_OK;
256358088Smm	if (f->next_filter != NULL)
257358088Smm		ret = __archive_write_open_filter(f->next_filter);
258358088Smm	if (ret != ARCHIVE_OK)
259358088Smm		return (ret);
260358088Smm	if (f->state != ARCHIVE_WRITE_FILTER_STATE_NEW)
261358088Smm		return (ARCHIVE_FATAL);
262358088Smm	if (f->open == NULL) {
263358088Smm		f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
264232153Smm		return (ARCHIVE_OK);
265358088Smm	}
266358088Smm	ret = (f->open)(f);
267358088Smm	if (ret == ARCHIVE_OK)
268358088Smm		f->state = ARCHIVE_WRITE_FILTER_STATE_OPEN;
269358088Smm	else
270358088Smm		f->state = ARCHIVE_WRITE_FILTER_STATE_FATAL;
271358088Smm	return (ret);
272232153Smm}
273232153Smm
274232153Smm/*
275358088Smm * Open all filters
276232153Smm */
277358088Smmstatic int
278358088Smm__archive_write_filters_open(struct archive_write *a)
279232153Smm{
280358088Smm	return (__archive_write_open_filter(a->filter_first));
281232153Smm}
282232153Smm
283358088Smm/*
284358088Smm * Close all filtes
285358088Smm */
286358088Smmstatic int
287358088Smm__archive_write_filters_close(struct archive_write *a)
288358088Smm{
289358088Smm	struct archive_write_filter *f;
290358088Smm	int ret, ret1;
291358088Smm	ret = ARCHIVE_OK;
292358088Smm	for (f = a->filter_first; f != NULL; f = f->next_filter) {
293358088Smm		/* Do not close filters that are not open */
294358088Smm		if (f->state == ARCHIVE_WRITE_FILTER_STATE_OPEN) {
295358088Smm			if (f->close != NULL) {
296358088Smm				ret1 = (f->close)(f);
297358088Smm				if (ret1 < ret)
298358088Smm					ret = ret1;
299358088Smm				if (ret1 == ARCHIVE_OK) {
300358088Smm					f->state =
301358088Smm					    ARCHIVE_WRITE_FILTER_STATE_CLOSED;
302358088Smm				} else {
303358088Smm					f->state =
304358088Smm					    ARCHIVE_WRITE_FILTER_STATE_FATAL;
305358088Smm				}
306358088Smm			} else
307358088Smm				f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
308358088Smm		}
309358088Smm	}
310358088Smm	return (ret);
311358088Smm}
312358088Smm
313232153Smmint
314232153Smm__archive_write_output(struct archive_write *a, const void *buff, size_t length)
315232153Smm{
316232153Smm	return (__archive_write_filter(a->filter_first, buff, length));
317232153Smm}
318232153Smm
319232153Smmint
320232153Smm__archive_write_nulls(struct archive_write *a, size_t length)
321232153Smm{
322232153Smm	if (length == 0)
323232153Smm		return (ARCHIVE_OK);
324232153Smm
325232153Smm	while (length > 0) {
326232153Smm		size_t to_write = length < a->null_length ? length : a->null_length;
327232153Smm		int r = __archive_write_output(a, a->nulls, to_write);
328232153Smm		if (r < ARCHIVE_OK)
329232153Smm			return (r);
330232153Smm		length -= to_write;
331232153Smm	}
332232153Smm	return (ARCHIVE_OK);
333232153Smm}
334232153Smm
335232153Smmstatic int
336232153Smmarchive_write_client_open(struct archive_write_filter *f)
337232153Smm{
338232153Smm	struct archive_write *a = (struct archive_write *)f->archive;
339232153Smm	struct archive_none *state;
340232153Smm	void *buffer;
341232153Smm	size_t buffer_size;
342358088Smm	int ret;
343232153Smm
344232153Smm	f->bytes_per_block = archive_write_get_bytes_per_block(f->archive);
345232153Smm	f->bytes_in_last_block =
346232153Smm	    archive_write_get_bytes_in_last_block(f->archive);
347232153Smm	buffer_size = f->bytes_per_block;
348232153Smm
349232153Smm	state = (struct archive_none *)calloc(1, sizeof(*state));
350232153Smm	buffer = (char *)malloc(buffer_size);
351232153Smm	if (state == NULL || buffer == NULL) {
352232153Smm		free(state);
353232153Smm		free(buffer);
354232153Smm		archive_set_error(f->archive, ENOMEM,
355232153Smm		    "Can't allocate data for output buffering");
356232153Smm		return (ARCHIVE_FATAL);
357232153Smm	}
358232153Smm
359232153Smm	state->buffer_size = buffer_size;
360232153Smm	state->buffer = buffer;
361232153Smm	state->next = state->buffer;
362232153Smm	state->avail = state->buffer_size;
363232153Smm	f->data = state;
364232153Smm
365232153Smm	if (a->client_opener == NULL)
366232153Smm		return (ARCHIVE_OK);
367358088Smm	ret = a->client_opener(f->archive, a->client_data);
368358088Smm	if (ret != ARCHIVE_OK) {
369358088Smm		free(state->buffer);
370358088Smm		free(state);
371358088Smm		f->data = NULL;
372358088Smm	}
373358088Smm	return (ret);
374232153Smm}
375232153Smm
376232153Smmstatic int
377232153Smmarchive_write_client_write(struct archive_write_filter *f,
378232153Smm    const void *_buff, size_t length)
379232153Smm{
380232153Smm	struct archive_write *a = (struct archive_write *)f->archive;
381232153Smm        struct archive_none *state = (struct archive_none *)f->data;
382232153Smm	const char *buff = (const char *)_buff;
383232153Smm	ssize_t remaining, to_copy;
384232153Smm	ssize_t bytes_written;
385232153Smm
386232153Smm	remaining = length;
387232153Smm
388232153Smm	/*
389232153Smm	 * If there is no buffer for blocking, just pass the data
390232153Smm	 * straight through to the client write callback.  In
391232153Smm	 * particular, this supports "no write delay" operation for
392232153Smm	 * special applications.  Just set the block size to zero.
393232153Smm	 */
394232153Smm	if (state->buffer_size == 0) {
395232153Smm		while (remaining > 0) {
396232153Smm			bytes_written = (a->client_writer)(&a->archive,
397232153Smm			    a->client_data, buff, remaining);
398232153Smm			if (bytes_written <= 0)
399232153Smm				return (ARCHIVE_FATAL);
400232153Smm			remaining -= bytes_written;
401232153Smm			buff += bytes_written;
402232153Smm		}
403232153Smm		return (ARCHIVE_OK);
404232153Smm	}
405232153Smm
406232153Smm	/* If the copy buffer isn't empty, try to fill it. */
407232153Smm	if (state->avail < state->buffer_size) {
408232153Smm		/* If buffer is not empty... */
409232153Smm		/* ... copy data into buffer ... */
410232153Smm		to_copy = ((size_t)remaining > state->avail) ?
411232153Smm			state->avail : (size_t)remaining;
412232153Smm		memcpy(state->next, buff, to_copy);
413232153Smm		state->next += to_copy;
414232153Smm		state->avail -= to_copy;
415232153Smm		buff += to_copy;
416232153Smm		remaining -= to_copy;
417232153Smm		/* ... if it's full, write it out. */
418232153Smm		if (state->avail == 0) {
419232153Smm			char *p = state->buffer;
420232153Smm			size_t to_write = state->buffer_size;
421232153Smm			while (to_write > 0) {
422232153Smm				bytes_written = (a->client_writer)(&a->archive,
423232153Smm				    a->client_data, p, to_write);
424232153Smm				if (bytes_written <= 0)
425232153Smm					return (ARCHIVE_FATAL);
426232153Smm				if ((size_t)bytes_written > to_write) {
427232153Smm					archive_set_error(&(a->archive),
428232153Smm					    -1, "write overrun");
429232153Smm					return (ARCHIVE_FATAL);
430232153Smm				}
431232153Smm				p += bytes_written;
432232153Smm				to_write -= bytes_written;
433232153Smm			}
434232153Smm			state->next = state->buffer;
435232153Smm			state->avail = state->buffer_size;
436232153Smm		}
437232153Smm	}
438232153Smm
439238856Smm	while ((size_t)remaining >= state->buffer_size) {
440232153Smm		/* Write out full blocks directly to client. */
441232153Smm		bytes_written = (a->client_writer)(&a->archive,
442232153Smm		    a->client_data, buff, state->buffer_size);
443232153Smm		if (bytes_written <= 0)
444232153Smm			return (ARCHIVE_FATAL);
445232153Smm		buff += bytes_written;
446232153Smm		remaining -= bytes_written;
447232153Smm	}
448232153Smm
449232153Smm	if (remaining > 0) {
450232153Smm		/* Copy last bit into copy buffer. */
451232153Smm		memcpy(state->next, buff, remaining);
452232153Smm		state->next += remaining;
453232153Smm		state->avail -= remaining;
454232153Smm	}
455232153Smm	return (ARCHIVE_OK);
456232153Smm}
457232153Smm
458232153Smmstatic int
459368707Smmarchive_write_client_free(struct archive_write_filter *f)
460368707Smm{
461368707Smm	struct archive_write *a = (struct archive_write *)f->archive;
462368707Smm
463368707Smm	if (a->client_freer)
464368707Smm		(*a->client_freer)(&a->archive, a->client_data);
465368707Smm	a->client_data = NULL;
466368707Smm
467368707Smm	/* Clear passphrase. */
468368707Smm	if (a->passphrase != NULL) {
469368707Smm		memset(a->passphrase, 0, strlen(a->passphrase));
470368707Smm		free(a->passphrase);
471368707Smm		a->passphrase = NULL;
472368707Smm	}
473368707Smm
474368707Smm	return (ARCHIVE_OK);
475368707Smm}
476368707Smm
477368707Smmstatic int
478232153Smmarchive_write_client_close(struct archive_write_filter *f)
479232153Smm{
480232153Smm	struct archive_write *a = (struct archive_write *)f->archive;
481232153Smm	struct archive_none *state = (struct archive_none *)f->data;
482232153Smm	ssize_t block_length;
483232153Smm	ssize_t target_block_length;
484232153Smm	ssize_t bytes_written;
485370535Sgit2svn	size_t to_write;
486370535Sgit2svn	char *p;
487232153Smm	int ret = ARCHIVE_OK;
488232153Smm
489232153Smm	/* If there's pending data, pad and write the last block */
490232153Smm	if (state->next != state->buffer) {
491232153Smm		block_length = state->buffer_size - state->avail;
492232153Smm
493232153Smm		/* Tricky calculation to determine size of last block */
494232153Smm		if (a->bytes_in_last_block <= 0)
495232153Smm			/* Default or Zero: pad to full block */
496232153Smm			target_block_length = a->bytes_per_block;
497232153Smm		else
498232153Smm			/* Round to next multiple of bytes_in_last_block. */
499232153Smm			target_block_length = a->bytes_in_last_block *
500232153Smm			    ( (block_length + a->bytes_in_last_block - 1) /
501232153Smm			        a->bytes_in_last_block);
502232153Smm		if (target_block_length > a->bytes_per_block)
503232153Smm			target_block_length = a->bytes_per_block;
504232153Smm		if (block_length < target_block_length) {
505232153Smm			memset(state->next, 0,
506232153Smm			    target_block_length - block_length);
507232153Smm			block_length = target_block_length;
508232153Smm		}
509370535Sgit2svn		p = state->buffer;
510370535Sgit2svn		to_write = block_length;
511370535Sgit2svn		while (to_write > 0) {
512370535Sgit2svn			bytes_written = (a->client_writer)(&a->archive,
513370535Sgit2svn			    a->client_data, p, to_write);
514370535Sgit2svn			if (bytes_written <= 0) {
515370535Sgit2svn				ret = ARCHIVE_FATAL;
516370535Sgit2svn				break;
517370535Sgit2svn			}
518370535Sgit2svn			if ((size_t)bytes_written > to_write) {
519370535Sgit2svn				archive_set_error(&(a->archive),
520370535Sgit2svn						  -1, "write overrun");
521370535Sgit2svn				ret = ARCHIVE_FATAL;
522370535Sgit2svn				break;
523370535Sgit2svn			}
524370535Sgit2svn			p += bytes_written;
525370535Sgit2svn			to_write -= bytes_written;
526370535Sgit2svn		}
527232153Smm	}
528232153Smm	if (a->client_closer)
529232153Smm		(*a->client_closer)(&a->archive, a->client_data);
530232153Smm	free(state->buffer);
531232153Smm	free(state);
532368707Smm
533358088Smm	/* Clear the close handler myself not to be called again. */
534358088Smm	f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
535232153Smm	return (ret);
536232153Smm}
537232153Smm
538232153Smm/*
539228753Smm * Open the archive using the current settings.
540228753Smm */
541228753Smmint
542368707Smmarchive_write_open2(struct archive *_a, void *client_data,
543228753Smm    archive_open_callback *opener, archive_write_callback *writer,
544368707Smm    archive_close_callback *closer, archive_free_callback *freer)
545228753Smm{
546228753Smm	struct archive_write *a = (struct archive_write *)_a;
547232153Smm	struct archive_write_filter *client_filter;
548232153Smm	int ret, r1;
549228753Smm
550232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
551228753Smm	    ARCHIVE_STATE_NEW, "archive_write_open");
552228753Smm	archive_clear_error(&a->archive);
553232153Smm
554228753Smm	a->client_writer = writer;
555228753Smm	a->client_opener = opener;
556228753Smm	a->client_closer = closer;
557368707Smm	a->client_freer = freer;
558232153Smm	a->client_data = client_data;
559232153Smm
560232153Smm	client_filter = __archive_write_allocate_filter(_a);
561232153Smm	client_filter->open = archive_write_client_open;
562232153Smm	client_filter->write = archive_write_client_write;
563232153Smm	client_filter->close = archive_write_client_close;
564368707Smm	client_filter->free = archive_write_client_free;
565232153Smm
566358088Smm	ret = __archive_write_filters_open(a);
567232153Smm	if (ret < ARCHIVE_WARN) {
568358088Smm		r1 = __archive_write_filters_close(a);
569358088Smm		__archive_write_filters_free(_a);
570232153Smm		return (r1 < ret ? r1 : ret);
571232153Smm	}
572232153Smm
573232153Smm	a->archive.state = ARCHIVE_STATE_HEADER;
574232153Smm	if (a->format_init)
575228753Smm		ret = (a->format_init)(a);
576228753Smm	return (ret);
577228753Smm}
578228753Smm
579368707Smmint
580368707Smmarchive_write_open(struct archive *_a, void *client_data,
581368707Smm    archive_open_callback *opener, archive_write_callback *writer,
582368707Smm    archive_close_callback *closer)
583368707Smm{
584368707Smm	return archive_write_open2(_a, client_data, opener, writer,
585368707Smm	    closer, NULL);
586368707Smm}
587368707Smm
588228753Smm/*
589228753Smm * Close out the archive.
590228753Smm */
591228753Smmstatic int
592228753Smm_archive_write_close(struct archive *_a)
593228753Smm{
594228753Smm	struct archive_write *a = (struct archive_write *)_a;
595228753Smm	int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
596228753Smm
597232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
598232153Smm	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
599232153Smm	    "archive_write_close");
600232153Smm	if (a->archive.state == ARCHIVE_STATE_NEW
601232153Smm	    || a->archive.state == ARCHIVE_STATE_CLOSED)
602232153Smm		return (ARCHIVE_OK); /* Okay to close() when not open. */
603228753Smm
604232153Smm	archive_clear_error(&a->archive);
605232153Smm
606299529Smm	/* Finish the last entry if a finish callback is specified */
607299529Smm	if (a->archive.state == ARCHIVE_STATE_DATA
608299529Smm	    && a->format_finish_entry != NULL)
609228753Smm		r = ((a->format_finish_entry)(a));
610228753Smm
611228753Smm	/* Finish off the archive. */
612232153Smm	/* TODO: have format closers invoke compression close. */
613232153Smm	if (a->format_close != NULL) {
614232153Smm		r1 = (a->format_close)(a);
615228753Smm		if (r1 < r)
616228753Smm			r = r1;
617228753Smm	}
618228753Smm
619232153Smm	/* Finish the compression and close the stream. */
620358088Smm	r1 = __archive_write_filters_close(a);
621232153Smm	if (r1 < r)
622232153Smm		r = r1;
623228753Smm
624232153Smm	if (a->archive.state != ARCHIVE_STATE_FATAL)
625232153Smm		a->archive.state = ARCHIVE_STATE_CLOSED;
626232153Smm	return (r);
627232153Smm}
628232153Smm
629232153Smmstatic int
630232153Smm_archive_write_filter_count(struct archive *_a)
631232153Smm{
632232153Smm	struct archive_write *a = (struct archive_write *)_a;
633232153Smm	struct archive_write_filter *p = a->filter_first;
634232153Smm	int count = 0;
635232153Smm	while(p) {
636232153Smm		count++;
637232153Smm		p = p->next_filter;
638228753Smm	}
639232153Smm	return count;
640232153Smm}
641228753Smm
642232153Smmvoid
643232153Smm__archive_write_filters_free(struct archive *_a)
644232153Smm{
645232153Smm	struct archive_write *a = (struct archive_write *)_a;
646232153Smm	int r = ARCHIVE_OK, r1;
647232153Smm
648232153Smm	while (a->filter_first != NULL) {
649232153Smm		struct archive_write_filter *next
650232153Smm		    = a->filter_first->next_filter;
651232153Smm		if (a->filter_first->free != NULL) {
652232153Smm			r1 = (*a->filter_first->free)(a->filter_first);
653232153Smm			if (r > r1)
654232153Smm				r = r1;
655232153Smm		}
656232153Smm		free(a->filter_first);
657232153Smm		a->filter_first = next;
658228753Smm	}
659232153Smm	a->filter_last = NULL;
660228753Smm}
661228753Smm
662228753Smm/*
663228753Smm * Destroy the archive structure.
664232153Smm *
665232153Smm * Be careful: user might just call write_new and then write_free.
666232153Smm * Don't assume we actually wrote anything or performed any non-trivial
667232153Smm * initialization.
668228753Smm */
669228753Smmstatic int
670228773Smm_archive_write_free(struct archive *_a)
671228753Smm{
672228753Smm	struct archive_write *a = (struct archive_write *)_a;
673232153Smm	int r = ARCHIVE_OK, r1;
674228753Smm
675232153Smm	if (_a == NULL)
676232153Smm		return (ARCHIVE_OK);
677232153Smm	/* It is okay to call free() in state FATAL. */
678232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
679232153Smm	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
680232153Smm	if (a->archive.state != ARCHIVE_STATE_FATAL)
681228753Smm		r = archive_write_close(&a->archive);
682228753Smm
683232153Smm	/* Release format resources. */
684232153Smm	if (a->format_free != NULL) {
685232153Smm		r1 = (a->format_free)(a);
686232153Smm		if (r1 < r)
687232153Smm			r = r1;
688232153Smm	}
689232153Smm
690232153Smm	__archive_write_filters_free(_a);
691232153Smm
692228753Smm	/* Release various dynamic buffers. */
693228753Smm	free((void *)(uintptr_t)(const void *)a->nulls);
694228753Smm	archive_string_free(&a->archive.error_string);
695299529Smm	if (a->passphrase != NULL) {
696299529Smm		/* A passphrase should be cleaned. */
697299529Smm		memset(a->passphrase, 0, strlen(a->passphrase));
698299529Smm		free(a->passphrase);
699299529Smm	}
700228753Smm	a->archive.magic = 0;
701232153Smm	__archive_clean(&a->archive);
702228753Smm	free(a);
703228753Smm	return (r);
704228753Smm}
705228753Smm
706228753Smm/*
707228753Smm * Write the appropriate header.
708228753Smm */
709228753Smmstatic int
710228753Smm_archive_write_header(struct archive *_a, struct archive_entry *entry)
711228753Smm{
712228753Smm	struct archive_write *a = (struct archive_write *)_a;
713228753Smm	int ret, r2;
714228753Smm
715232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
716228753Smm	    ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
717228753Smm	archive_clear_error(&a->archive);
718228753Smm
719232153Smm	if (a->format_write_header == NULL) {
720232153Smm		archive_set_error(&(a->archive), -1,
721232153Smm		    "Format must be set before you can write to an archive.");
722232153Smm		a->archive.state = ARCHIVE_STATE_FATAL;
723232153Smm		return (ARCHIVE_FATAL);
724232153Smm	}
725232153Smm
726228753Smm	/* In particular, "retry" and "fatal" get returned immediately. */
727228753Smm	ret = archive_write_finish_entry(&a->archive);
728232153Smm	if (ret == ARCHIVE_FATAL) {
729232153Smm		a->archive.state = ARCHIVE_STATE_FATAL;
730232153Smm		return (ARCHIVE_FATAL);
731232153Smm	}
732228753Smm	if (ret < ARCHIVE_OK && ret != ARCHIVE_WARN)
733228753Smm		return (ret);
734228753Smm
735232153Smm	if (a->skip_file_set &&
736232153Smm	    archive_entry_dev_is_set(entry) &&
737232153Smm	    archive_entry_ino_is_set(entry) &&
738238856Smm	    archive_entry_dev(entry) == (dev_t)a->skip_file_dev &&
739228753Smm	    archive_entry_ino64(entry) == a->skip_file_ino) {
740228753Smm		archive_set_error(&a->archive, 0,
741228753Smm		    "Can't add archive to itself");
742228753Smm		return (ARCHIVE_FAILED);
743228753Smm	}
744228753Smm
745228753Smm	/* Format and write header. */
746228753Smm	r2 = ((a->format_write_header)(a, entry));
747299529Smm	if (r2 == ARCHIVE_FAILED) {
748299529Smm		return (ARCHIVE_FAILED);
749299529Smm	}
750232153Smm	if (r2 == ARCHIVE_FATAL) {
751232153Smm		a->archive.state = ARCHIVE_STATE_FATAL;
752232153Smm		return (ARCHIVE_FATAL);
753232153Smm	}
754228753Smm	if (r2 < ret)
755228753Smm		ret = r2;
756228753Smm
757228753Smm	a->archive.state = ARCHIVE_STATE_DATA;
758228753Smm	return (ret);
759228753Smm}
760228753Smm
761228753Smmstatic int
762228753Smm_archive_write_finish_entry(struct archive *_a)
763228753Smm{
764228753Smm	struct archive_write *a = (struct archive_write *)_a;
765228753Smm	int ret = ARCHIVE_OK;
766228753Smm
767232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
768228753Smm	    ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
769228753Smm	    "archive_write_finish_entry");
770299529Smm	if (a->archive.state & ARCHIVE_STATE_DATA
771299529Smm	    && a->format_finish_entry != NULL)
772228753Smm		ret = (a->format_finish_entry)(a);
773228753Smm	a->archive.state = ARCHIVE_STATE_HEADER;
774228753Smm	return (ret);
775228753Smm}
776228753Smm
777228753Smm/*
778228753Smm * Note that the compressor is responsible for blocking.
779228753Smm */
780228753Smmstatic ssize_t
781228753Smm_archive_write_data(struct archive *_a, const void *buff, size_t s)
782228753Smm{
783228753Smm	struct archive_write *a = (struct archive_write *)_a;
784248664Smm	const size_t max_write = INT_MAX;
785248664Smm
786232153Smm	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
787228753Smm	    ARCHIVE_STATE_DATA, "archive_write_data");
788248664Smm	/* In particular, this catches attempts to pass negative values. */
789248664Smm	if (s > max_write)
790248664Smm		s = max_write;
791228753Smm	archive_clear_error(&a->archive);
792228753Smm	return ((a->format_write_data)(a, buff, s));
793228753Smm}
794232153Smm
795232153Smmstatic struct archive_write_filter *
796232153Smmfilter_lookup(struct archive *_a, int n)
797232153Smm{
798232153Smm	struct archive_write *a = (struct archive_write *)_a;
799232153Smm	struct archive_write_filter *f = a->filter_first;
800232153Smm	if (n == -1)
801232153Smm		return a->filter_last;
802232153Smm	if (n < 0)
803232153Smm		return NULL;
804232153Smm	while (n > 0 && f != NULL) {
805232153Smm		f = f->next_filter;
806232153Smm		--n;
807232153Smm	}
808232153Smm	return f;
809232153Smm}
810232153Smm
811232153Smmstatic int
812232153Smm_archive_filter_code(struct archive *_a, int n)
813232153Smm{
814232153Smm	struct archive_write_filter *f = filter_lookup(_a, n);
815232153Smm	return f == NULL ? -1 : f->code;
816232153Smm}
817232153Smm
818232153Smmstatic const char *
819232153Smm_archive_filter_name(struct archive *_a, int n)
820232153Smm{
821232153Smm	struct archive_write_filter *f = filter_lookup(_a, n);
822299529Smm	return f != NULL ? f->name : NULL;
823232153Smm}
824232153Smm
825232153Smmstatic int64_t
826232153Smm_archive_filter_bytes(struct archive *_a, int n)
827232153Smm{
828232153Smm	struct archive_write_filter *f = filter_lookup(_a, n);
829232153Smm	return f == NULL ? -1 : f->bytes_written;
830232153Smm}
831