archive_write_set_format_xar.c revision 358090
1/*-
2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "archive_platform.h"
27__FBSDID("$FreeBSD$");
28
29#ifdef HAVE_ERRNO_H
30#include <errno.h>
31#endif
32#ifdef HAVE_LIMITS_H
33#include <limits.h>
34#endif
35#include <stdlib.h>
36#if HAVE_LIBXML_XMLWRITER_H
37#include <libxml/xmlwriter.h>
38#endif
39#ifdef HAVE_BZLIB_H
40#include <bzlib.h>
41#endif
42#if HAVE_LZMA_H
43#include <lzma.h>
44#endif
45#ifdef HAVE_ZLIB_H
46#include <zlib.h>
47#endif
48
49#include "archive.h"
50#include "archive_digest_private.h"
51#include "archive_endian.h"
52#include "archive_entry.h"
53#include "archive_entry_locale.h"
54#include "archive_private.h"
55#include "archive_rb.h"
56#include "archive_string.h"
57#include "archive_write_private.h"
58
59/*
60 * Differences to xar utility.
61 * - Subdocument is not supported yet.
62 * - ACL is not supported yet.
63 * - When writing an XML element <link type="<file-type>">, <file-type>
64 *   which is a file type a symbolic link is referencing is always marked
65 *   as "broken". Xar utility uses stat(2) to get the file type, but, in
66 *   libarchive format writer, we should not use it; if it is needed, we
67 *   should get about it at archive_read_disk.c.
68 * - It is possible to appear both <flags> and <ext2> elements.
69 *   Xar utility generates <flags> on BSD platform and <ext2> on Linux
70 *   platform.
71 *
72 */
73
74#if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
75	LIBXML_VERSION >= 20703) ||\
76	!defined(HAVE_ZLIB_H) || \
77	!defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
78/*
79 * xar needs several external libraries.
80 *   o libxml2
81 *   o openssl or MD5/SHA1 hash function
82 *   o zlib
83 *   o bzlib2 (option)
84 *   o liblzma (option)
85 */
86int
87archive_write_set_format_xar(struct archive *_a)
88{
89	struct archive_write *a = (struct archive_write *)_a;
90
91	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
92	    "Xar not supported on this platform");
93	return (ARCHIVE_WARN);
94}
95
96#else	/* Support xar format */
97
98/*#define DEBUG_PRINT_TOC		1 */
99
100#define BAD_CAST_CONST (const xmlChar *)
101
102#define HEADER_MAGIC	0x78617221
103#define HEADER_SIZE	28
104#define HEADER_VERSION	1
105
106enum sumalg {
107	CKSUM_NONE = 0,
108	CKSUM_SHA1 = 1,
109	CKSUM_MD5 = 2
110};
111
112#define MD5_SIZE	16
113#define SHA1_SIZE	20
114#define MAX_SUM_SIZE	20
115#define MD5_NAME	"md5"
116#define SHA1_NAME	"sha1"
117
118enum enctype {
119	NONE,
120	GZIP,
121	BZIP2,
122	LZMA,
123	XZ,
124};
125
126struct chksumwork {
127	enum sumalg		 alg;
128#ifdef ARCHIVE_HAS_MD5
129	archive_md5_ctx		 md5ctx;
130#endif
131#ifdef ARCHIVE_HAS_SHA1
132	archive_sha1_ctx	 sha1ctx;
133#endif
134};
135
136enum la_zaction {
137	ARCHIVE_Z_FINISH,
138	ARCHIVE_Z_RUN
139};
140
141/*
142 * Universal zstream.
143 */
144struct la_zstream {
145	const unsigned char	*next_in;
146	size_t			 avail_in;
147	uint64_t		 total_in;
148
149	unsigned char		*next_out;
150	size_t			 avail_out;
151	uint64_t		 total_out;
152
153	int			 valid;
154	void			*real_stream;
155	int			 (*code) (struct archive *a,
156				    struct la_zstream *lastrm,
157				    enum la_zaction action);
158	int			 (*end)(struct archive *a,
159				    struct la_zstream *lastrm);
160};
161
162struct chksumval {
163	enum sumalg		 alg;
164	size_t			 len;
165	unsigned char		 val[MAX_SUM_SIZE];
166};
167
168struct heap_data {
169	int			 id;
170	struct heap_data	*next;
171	uint64_t		 temp_offset;
172	uint64_t		 length;	/* archived size.	*/
173	uint64_t		 size;		/* extracted size.	*/
174	enum enctype		 compression;
175	struct chksumval	 a_sum;		/* archived checksum.	*/
176	struct chksumval	 e_sum;		/* extracted checksum.	*/
177};
178
179struct file {
180	struct archive_rb_node	 rbnode;
181
182	int			 id;
183	struct archive_entry	*entry;
184
185	struct archive_rb_tree	 rbtree;
186	struct file		*next;
187	struct file		*chnext;
188	struct file		*hlnext;
189	/* For hardlinked files.
190	 * Use only when archive_entry_nlink() > 1 */
191	struct file		*hardlink_target;
192	struct file		*parent;	/* parent directory entry */
193	/*
194	 * To manage sub directory files.
195	 * We use 'chnext' (a member of struct file) to chain.
196	 */
197	struct {
198		struct file	*first;
199		struct file	**last;
200	}			 children;
201
202	/* For making a directory tree. */
203        struct archive_string    parentdir;
204        struct archive_string    basename;
205        struct archive_string    symlink;
206
207	int			 ea_idx;
208	struct {
209		struct heap_data *first;
210		struct heap_data **last;
211	}			 xattr;
212	struct heap_data	 data;
213        struct archive_string    script;
214
215	signed int		 virtual:1;
216	signed int		 dir:1;
217};
218
219struct hardlink {
220	struct archive_rb_node	 rbnode;
221	int			 nlink;
222	struct {
223		struct file	*first;
224		struct file	**last;
225	}			 file_list;
226};
227
228struct xar {
229	int			 temp_fd;
230	uint64_t		 temp_offset;
231
232	int			 file_idx;
233	struct file		*root;
234	struct file		*cur_dirent;
235	struct archive_string	 cur_dirstr;
236	struct file		*cur_file;
237	uint64_t		 bytes_remaining;
238	struct archive_string	 tstr;
239	struct archive_string	 vstr;
240
241	enum sumalg		 opt_toc_sumalg;
242	enum sumalg		 opt_sumalg;
243	enum enctype		 opt_compression;
244	int			 opt_compression_level;
245	uint32_t		 opt_threads;
246
247	struct chksumwork	 a_sumwrk;	/* archived checksum.	*/
248	struct chksumwork	 e_sumwrk;	/* extracted checksum.	*/
249	struct la_zstream	 stream;
250	struct archive_string_conv *sconv;
251	/*
252	 * Compressed data buffer.
253	 */
254	unsigned char		 wbuff[1024 * 64];
255	size_t			 wbuff_remaining;
256
257	struct heap_data	 toc;
258	/*
259	 * The list of all file entries is used to manage struct file
260	 * objects.
261	 * We use 'next' (a member of struct file) to chain.
262	 */
263	struct {
264		struct file	*first;
265		struct file	**last;
266	}			 file_list;
267	/*
268	 * The list of hard-linked file entries.
269	 * We use 'hlnext' (a member of struct file) to chain.
270	 */
271	struct archive_rb_tree	 hardlink_rbtree;
272};
273
274static int	xar_options(struct archive_write *,
275		    const char *, const char *);
276static int	xar_write_header(struct archive_write *,
277		    struct archive_entry *);
278static ssize_t	xar_write_data(struct archive_write *,
279		    const void *, size_t);
280static int	xar_finish_entry(struct archive_write *);
281static int	xar_close(struct archive_write *);
282static int	xar_free(struct archive_write *);
283
284static struct file *file_new(struct archive_write *a, struct archive_entry *);
285static void	file_free(struct file *);
286static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
287		    const char *);
288static int	file_add_child_tail(struct file *, struct file *);
289static struct file *file_find_child(struct file *, const char *);
290static int	file_gen_utility_names(struct archive_write *,
291		    struct file *);
292static int	get_path_component(char *, int, const char *);
293static int	file_tree(struct archive_write *, struct file **);
294static void	file_register(struct xar *, struct file *);
295static void	file_init_register(struct xar *);
296static void	file_free_register(struct xar *);
297static int	file_register_hardlink(struct archive_write *,
298		    struct file *);
299static void	file_connect_hardlink_files(struct xar *);
300static void	file_init_hardlinks(struct xar *);
301static void	file_free_hardlinks(struct xar *);
302
303static void	checksum_init(struct chksumwork *, enum sumalg);
304static void	checksum_update(struct chksumwork *, const void *, size_t);
305static void	checksum_final(struct chksumwork *, struct chksumval *);
306static int	compression_init_encoder_gzip(struct archive *,
307		    struct la_zstream *, int, int);
308static int	compression_code_gzip(struct archive *,
309		    struct la_zstream *, enum la_zaction);
310static int	compression_end_gzip(struct archive *, struct la_zstream *);
311static int	compression_init_encoder_bzip2(struct archive *,
312		    struct la_zstream *, int);
313#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
314static int	compression_code_bzip2(struct archive *,
315		    struct la_zstream *, enum la_zaction);
316static int	compression_end_bzip2(struct archive *, struct la_zstream *);
317#endif
318static int	compression_init_encoder_lzma(struct archive *,
319		    struct la_zstream *, int);
320static int	compression_init_encoder_xz(struct archive *,
321		    struct la_zstream *, int, int);
322#if defined(HAVE_LZMA_H)
323static int	compression_code_lzma(struct archive *,
324		    struct la_zstream *, enum la_zaction);
325static int	compression_end_lzma(struct archive *, struct la_zstream *);
326#endif
327static int	xar_compression_init_encoder(struct archive_write *);
328static int	compression_code(struct archive *,
329		    struct la_zstream *, enum la_zaction);
330static int	compression_end(struct archive *,
331		    struct la_zstream *);
332static int	save_xattrs(struct archive_write *, struct file *);
333static int	getalgsize(enum sumalg);
334static const char *getalgname(enum sumalg);
335
336int
337archive_write_set_format_xar(struct archive *_a)
338{
339	struct archive_write *a = (struct archive_write *)_a;
340	struct xar *xar;
341
342	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
343	    ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
344
345	/* If another format was already registered, unregister it. */
346	if (a->format_free != NULL)
347		(a->format_free)(a);
348
349	xar = calloc(1, sizeof(*xar));
350	if (xar == NULL) {
351		archive_set_error(&a->archive, ENOMEM,
352		    "Can't allocate xar data");
353		return (ARCHIVE_FATAL);
354	}
355	xar->temp_fd = -1;
356	file_init_register(xar);
357	file_init_hardlinks(xar);
358	archive_string_init(&(xar->tstr));
359	archive_string_init(&(xar->vstr));
360
361	/*
362	 * Create the root directory.
363	 */
364	xar->root = file_create_virtual_dir(a, xar, "");
365	if (xar->root == NULL) {
366		free(xar);
367		archive_set_error(&a->archive, ENOMEM,
368		    "Can't allocate xar data");
369		return (ARCHIVE_FATAL);
370	}
371	xar->root->parent = xar->root;
372	file_register(xar, xar->root);
373	xar->cur_dirent = xar->root;
374	archive_string_init(&(xar->cur_dirstr));
375	archive_string_ensure(&(xar->cur_dirstr), 1);
376	xar->cur_dirstr.s[0] = 0;
377
378	/*
379	 * Initialize option.
380	 */
381	/* Set default checksum type. */
382	xar->opt_toc_sumalg = CKSUM_SHA1;
383	xar->opt_sumalg = CKSUM_SHA1;
384	/* Set default compression type, level, and number of threads. */
385	xar->opt_compression = GZIP;
386	xar->opt_compression_level = 6;
387	xar->opt_threads = 1;
388
389	a->format_data = xar;
390
391	a->format_name = "xar";
392	a->format_options = xar_options;
393	a->format_write_header = xar_write_header;
394	a->format_write_data = xar_write_data;
395	a->format_finish_entry = xar_finish_entry;
396	a->format_close = xar_close;
397	a->format_free = xar_free;
398	a->archive.archive_format = ARCHIVE_FORMAT_XAR;
399	a->archive.archive_format_name = "xar";
400
401	return (ARCHIVE_OK);
402}
403
404static int
405xar_options(struct archive_write *a, const char *key, const char *value)
406{
407	struct xar *xar;
408
409	xar = (struct xar *)a->format_data;
410
411	if (strcmp(key, "checksum") == 0) {
412		if (value == NULL)
413			xar->opt_sumalg = CKSUM_NONE;
414		else if (strcmp(value, "none") == 0)
415			xar->opt_sumalg = CKSUM_NONE;
416		else if (strcmp(value, "sha1") == 0)
417			xar->opt_sumalg = CKSUM_SHA1;
418		else if (strcmp(value, "md5") == 0)
419			xar->opt_sumalg = CKSUM_MD5;
420		else {
421			archive_set_error(&(a->archive),
422			    ARCHIVE_ERRNO_MISC,
423			    "Unknown checksum name: `%s'",
424			    value);
425			return (ARCHIVE_FAILED);
426		}
427		return (ARCHIVE_OK);
428	}
429	if (strcmp(key, "compression") == 0) {
430		const char *name = NULL;
431
432		if (value == NULL)
433			xar->opt_compression = NONE;
434		else if (strcmp(value, "none") == 0)
435			xar->opt_compression = NONE;
436		else if (strcmp(value, "gzip") == 0)
437			xar->opt_compression = GZIP;
438		else if (strcmp(value, "bzip2") == 0)
439#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
440			xar->opt_compression = BZIP2;
441#else
442			name = "bzip2";
443#endif
444		else if (strcmp(value, "lzma") == 0)
445#if HAVE_LZMA_H
446			xar->opt_compression = LZMA;
447#else
448			name = "lzma";
449#endif
450		else if (strcmp(value, "xz") == 0)
451#if HAVE_LZMA_H
452			xar->opt_compression = XZ;
453#else
454			name = "xz";
455#endif
456		else {
457			archive_set_error(&(a->archive),
458			    ARCHIVE_ERRNO_MISC,
459			    "Unknown compression name: `%s'",
460			    value);
461			return (ARCHIVE_FAILED);
462		}
463		if (name != NULL) {
464			archive_set_error(&(a->archive),
465			    ARCHIVE_ERRNO_MISC,
466			    "`%s' compression not supported "
467			    "on this platform",
468			    name);
469			return (ARCHIVE_FAILED);
470		}
471		return (ARCHIVE_OK);
472	}
473	if (strcmp(key, "compression-level") == 0) {
474		if (value == NULL ||
475		    !(value[0] >= '0' && value[0] <= '9') ||
476		    value[1] != '\0') {
477			archive_set_error(&(a->archive),
478			    ARCHIVE_ERRNO_MISC,
479			    "Illegal value `%s'",
480			    value);
481			return (ARCHIVE_FAILED);
482		}
483		xar->opt_compression_level = value[0] - '0';
484		return (ARCHIVE_OK);
485	}
486	if (strcmp(key, "toc-checksum") == 0) {
487		if (value == NULL)
488			xar->opt_toc_sumalg = CKSUM_NONE;
489		else if (strcmp(value, "none") == 0)
490			xar->opt_toc_sumalg = CKSUM_NONE;
491		else if (strcmp(value, "sha1") == 0)
492			xar->opt_toc_sumalg = CKSUM_SHA1;
493		else if (strcmp(value, "md5") == 0)
494			xar->opt_toc_sumalg = CKSUM_MD5;
495		else {
496			archive_set_error(&(a->archive),
497			    ARCHIVE_ERRNO_MISC,
498			    "Unknown checksum name: `%s'",
499			    value);
500			return (ARCHIVE_FAILED);
501		}
502		return (ARCHIVE_OK);
503	}
504	if (strcmp(key, "threads") == 0) {
505		char *endptr;
506
507		if (value == NULL)
508			return (ARCHIVE_FAILED);
509		errno = 0;
510		xar->opt_threads = (int)strtoul(value, &endptr, 10);
511		if (errno != 0 || *endptr != '\0') {
512			xar->opt_threads = 1;
513			archive_set_error(&(a->archive),
514			    ARCHIVE_ERRNO_MISC,
515			    "Illegal value `%s'",
516			    value);
517			return (ARCHIVE_FAILED);
518		}
519		if (xar->opt_threads == 0) {
520#ifdef HAVE_LZMA_STREAM_ENCODER_MT
521			xar->opt_threads = lzma_cputhreads();
522#else
523			xar->opt_threads = 1;
524#endif
525		}
526	}
527
528	/* Note: The "warn" return is just to inform the options
529	 * supervisor that we didn't handle it.  It will generate
530	 * a suitable error if no one used this option. */
531	return (ARCHIVE_WARN);
532}
533
534static int
535xar_write_header(struct archive_write *a, struct archive_entry *entry)
536{
537	struct xar *xar;
538	struct file *file;
539	struct archive_entry *file_entry;
540	int r, r2;
541
542	xar = (struct xar *)a->format_data;
543	xar->cur_file = NULL;
544	xar->bytes_remaining = 0;
545
546	if (xar->sconv == NULL) {
547		xar->sconv = archive_string_conversion_to_charset(
548		    &a->archive, "UTF-8", 1);
549		if (xar->sconv == NULL)
550			return (ARCHIVE_FATAL);
551	}
552
553	file = file_new(a, entry);
554	if (file == NULL) {
555		archive_set_error(&a->archive, ENOMEM,
556		    "Can't allocate data");
557		return (ARCHIVE_FATAL);
558	}
559	r2 = file_gen_utility_names(a, file);
560	if (r2 < ARCHIVE_WARN)
561		return (r2);
562
563	/*
564	 * Ignore a path which looks like the top of directory name
565	 * since we have already made the root directory of an Xar archive.
566	 */
567	if (archive_strlen(&(file->parentdir)) == 0 &&
568	    archive_strlen(&(file->basename)) == 0) {
569		file_free(file);
570		return (r2);
571	}
572
573	/* Add entry into tree */
574	file_entry = file->entry;
575	r = file_tree(a, &file);
576	if (r != ARCHIVE_OK)
577		return (r);
578	/* There is the same file in tree and
579	 * the current file is older than the file in tree.
580	 * So we don't need the current file data anymore. */
581	if (file->entry != file_entry)
582		return (r2);
583	if (file->id == 0)
584		file_register(xar, file);
585
586	/* A virtual file, which is a directory, does not have
587	 * any contents and we won't store it into a archive
588	 * file other than its name. */
589	if (file->virtual)
590		return (r2);
591
592	/*
593	 * Prepare to save the contents of the file.
594	 */
595	if (xar->temp_fd == -1) {
596		int algsize;
597		xar->temp_offset = 0;
598		xar->temp_fd = __archive_mktemp(NULL);
599		if (xar->temp_fd < 0) {
600			archive_set_error(&a->archive, errno,
601			    "Couldn't create temporary file");
602			return (ARCHIVE_FATAL);
603		}
604		algsize = getalgsize(xar->opt_toc_sumalg);
605		if (algsize > 0) {
606			if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
607				archive_set_error(&(a->archive), errno,
608				    "lseek failed");
609				return (ARCHIVE_FATAL);
610			}
611			xar->temp_offset = algsize;
612		}
613	}
614
615	if (archive_entry_hardlink(file->entry) == NULL) {
616		r = save_xattrs(a, file);
617		if (r != ARCHIVE_OK)
618			return (ARCHIVE_FATAL);
619	}
620
621	/* Non regular files contents are unneeded to be saved to
622	 * a temporary file. */
623	if (archive_entry_filetype(file->entry) != AE_IFREG)
624		return (r2);
625
626	/*
627	 * Set the current file to cur_file to read its contents.
628	 */
629	xar->cur_file = file;
630
631	if (archive_entry_nlink(file->entry) > 1) {
632		r = file_register_hardlink(a, file);
633		if (r != ARCHIVE_OK)
634			return (r);
635		if (archive_entry_hardlink(file->entry) != NULL) {
636			archive_entry_unset_size(file->entry);
637			return (r2);
638		}
639	}
640
641	/* Save a offset of current file in temporary file. */
642	file->data.temp_offset = xar->temp_offset;
643	file->data.size = archive_entry_size(file->entry);
644	file->data.compression = xar->opt_compression;
645	xar->bytes_remaining = archive_entry_size(file->entry);
646	checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
647	checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
648	r = xar_compression_init_encoder(a);
649
650	if (r != ARCHIVE_OK)
651		return (r);
652	else
653		return (r2);
654}
655
656static int
657write_to_temp(struct archive_write *a, const void *buff, size_t s)
658{
659	struct xar *xar;
660	const unsigned char *p;
661	ssize_t ws;
662
663	xar = (struct xar *)a->format_data;
664	p = (const unsigned char *)buff;
665	while (s) {
666		ws = write(xar->temp_fd, p, s);
667		if (ws < 0) {
668			archive_set_error(&(a->archive), errno,
669			    "fwrite function failed");
670			return (ARCHIVE_FATAL);
671		}
672		s -= ws;
673		p += ws;
674		xar->temp_offset += ws;
675	}
676	return (ARCHIVE_OK);
677}
678
679static ssize_t
680xar_write_data(struct archive_write *a, const void *buff, size_t s)
681{
682	struct xar *xar;
683	enum la_zaction run;
684	size_t size, rsize;
685	int r;
686
687	xar = (struct xar *)a->format_data;
688
689	if (s > xar->bytes_remaining)
690		s = (size_t)xar->bytes_remaining;
691	if (s == 0 || xar->cur_file == NULL)
692		return (0);
693	if (xar->cur_file->data.compression == NONE) {
694		checksum_update(&(xar->e_sumwrk), buff, s);
695		checksum_update(&(xar->a_sumwrk), buff, s);
696		size = rsize = s;
697	} else {
698		xar->stream.next_in = (const unsigned char *)buff;
699		xar->stream.avail_in = s;
700		if (xar->bytes_remaining > s)
701			run = ARCHIVE_Z_RUN;
702		else
703			run = ARCHIVE_Z_FINISH;
704		/* Compress file data. */
705		for (;;) {
706			r = compression_code(&(a->archive), &(xar->stream),
707			    run);
708			if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
709				return (ARCHIVE_FATAL);
710			if (xar->stream.avail_out == 0 ||
711			    run == ARCHIVE_Z_FINISH) {
712				size = sizeof(xar->wbuff) -
713				    xar->stream.avail_out;
714				checksum_update(&(xar->a_sumwrk), xar->wbuff,
715				    size);
716				xar->cur_file->data.length += size;
717				if (write_to_temp(a, xar->wbuff,
718				    size) != ARCHIVE_OK)
719					return (ARCHIVE_FATAL);
720				if (r == ARCHIVE_OK) {
721					/* Output buffer was full */
722					xar->stream.next_out = xar->wbuff;
723					xar->stream.avail_out =
724					    sizeof(xar->wbuff);
725				} else {
726					/* ARCHIVE_EOF - We are done */
727					break;
728				}
729			} else {
730				/* Compressor wants more input */
731				break;
732			}
733		}
734		rsize = s - xar->stream.avail_in;
735		checksum_update(&(xar->e_sumwrk), buff, rsize);
736	}
737#if !defined(_WIN32) || defined(__CYGWIN__)
738	if (xar->bytes_remaining ==
739	    (uint64_t)archive_entry_size(xar->cur_file->entry)) {
740		/*
741		 * Get the path of a shell script if so.
742		 */
743		const unsigned char *b = (const unsigned char *)buff;
744
745		archive_string_empty(&(xar->cur_file->script));
746		if (rsize > 2 && b[0] == '#' && b[1] == '!') {
747			size_t i, end, off;
748
749			off = 2;
750			if (b[off] == ' ')
751				off++;
752#ifdef PATH_MAX
753			if ((rsize - off) > PATH_MAX)
754				end = off + PATH_MAX;
755			else
756#endif
757				end = rsize;
758			/* Find the end of a script path. */
759			for (i = off; i < end && b[i] != '\0' &&
760			    b[i] != '\n' && b[i] != '\r' &&
761			    b[i] != ' ' && b[i] != '\t'; i++)
762				;
763			archive_strncpy(&(xar->cur_file->script), b + off,
764			    i - off);
765		}
766	}
767#endif
768
769	if (xar->cur_file->data.compression == NONE) {
770		if (write_to_temp(a, buff, size) != ARCHIVE_OK)
771			return (ARCHIVE_FATAL);
772		xar->cur_file->data.length += size;
773	}
774	xar->bytes_remaining -= rsize;
775
776	return (rsize);
777}
778
779static int
780xar_finish_entry(struct archive_write *a)
781{
782	struct xar *xar;
783	struct file *file;
784	size_t s;
785	ssize_t w;
786
787	xar = (struct xar *)a->format_data;
788	if (xar->cur_file == NULL)
789		return (ARCHIVE_OK);
790
791	while (xar->bytes_remaining > 0) {
792		s = (size_t)xar->bytes_remaining;
793		if (s > a->null_length)
794			s = a->null_length;
795		w = xar_write_data(a, a->nulls, s);
796		if (w > 0)
797			xar->bytes_remaining -= w;
798		else
799			return (w);
800	}
801	file = xar->cur_file;
802	checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
803	checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
804	xar->cur_file = NULL;
805
806	return (ARCHIVE_OK);
807}
808
809static int
810xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
811	const char *key, const char *value,
812	const char *attrkey, const char *attrvalue)
813{
814	int r;
815
816	r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
817	if (r < 0) {
818		archive_set_error(&a->archive,
819		    ARCHIVE_ERRNO_MISC,
820		    "xmlTextWriterStartElement() failed: %d", r);
821		return (ARCHIVE_FATAL);
822	}
823	if (attrkey != NULL && attrvalue != NULL) {
824		r = xmlTextWriterWriteAttribute(writer,
825		    BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue));
826		if (r < 0) {
827			archive_set_error(&a->archive,
828			    ARCHIVE_ERRNO_MISC,
829			    "xmlTextWriterWriteAttribute() failed: %d", r);
830			return (ARCHIVE_FATAL);
831		}
832	}
833	if (value != NULL) {
834		r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
835		if (r < 0) {
836			archive_set_error(&a->archive,
837			    ARCHIVE_ERRNO_MISC,
838			    "xmlTextWriterWriteString() failed: %d", r);
839			return (ARCHIVE_FATAL);
840		}
841	}
842	r = xmlTextWriterEndElement(writer);
843	if (r < 0) {
844		archive_set_error(&a->archive,
845		    ARCHIVE_ERRNO_MISC,
846		    "xmlTextWriterEndElement() failed: %d", r);
847		return (ARCHIVE_FATAL);
848	}
849	return (ARCHIVE_OK);
850}
851
852static int
853xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
854	const char *key, const char *value)
855{
856	int r;
857
858	if (value == NULL)
859		return (ARCHIVE_OK);
860
861	r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
862	if (r < 0) {
863		archive_set_error(&a->archive,
864		    ARCHIVE_ERRNO_MISC,
865		    "xmlTextWriterStartElement() failed: %d", r);
866		return (ARCHIVE_FATAL);
867	}
868	if (value != NULL) {
869		r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
870		if (r < 0) {
871			archive_set_error(&a->archive,
872			    ARCHIVE_ERRNO_MISC,
873			    "xmlTextWriterWriteString() failed: %d", r);
874			return (ARCHIVE_FATAL);
875		}
876	}
877	r = xmlTextWriterEndElement(writer);
878	if (r < 0) {
879		archive_set_error(&a->archive,
880		    ARCHIVE_ERRNO_MISC,
881		    "xmlTextWriterEndElement() failed: %d", r);
882		return (ARCHIVE_FATAL);
883	}
884	return (ARCHIVE_OK);
885}
886
887static int
888xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
889	const char *key, const char *fmt, ...)
890{
891	struct xar *xar;
892	va_list ap;
893
894	xar = (struct xar *)a->format_data;
895	va_start(ap, fmt);
896	archive_string_empty(&xar->vstr);
897	archive_string_vsprintf(&xar->vstr, fmt, ap);
898	va_end(ap);
899	return (xmlwrite_string(a, writer, key, xar->vstr.s));
900}
901
902static int
903xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
904	const char *key, time_t t, int z)
905{
906	char timestr[100];
907	struct tm tm;
908#if defined(HAVE__GMTIME64_S)
909	__time64_t tmptime;
910#endif
911
912#if defined(HAVE_GMTIME_R)
913	gmtime_r(&t, &tm);
914#elif defined(HAVE__GMTIME64_S)
915	tmptime = t;
916	_gmtime64_s(&tm, &tmptime);
917#else
918	memcpy(&tm, gmtime(&t), sizeof(tm));
919#endif
920	memset(&timestr, 0, sizeof(timestr));
921	/* Do not use %F and %T for portability. */
922	strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
923	if (z)
924		strcat(timestr, "Z");
925	return (xmlwrite_string(a, writer, key, timestr));
926}
927
928static int
929xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
930	const char *key, mode_t mode)
931{
932	char ms[5];
933
934	ms[0] = '0';
935	ms[1] = '0' + ((mode >> 6) & 07);
936	ms[2] = '0' + ((mode >> 3) & 07);
937	ms[3] = '0' + (mode & 07);
938	ms[4] = '\0';
939
940	return (xmlwrite_string(a, writer, key, ms));
941}
942
943static int
944xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
945	const char *key, struct chksumval *sum)
946{
947	const char *algname;
948	int algsize;
949	char buff[MAX_SUM_SIZE*2 + 1];
950	char *p;
951	unsigned char *s;
952	int i, r;
953
954	if (sum->len > 0) {
955		algname = getalgname(sum->alg);
956		algsize = getalgsize(sum->alg);
957		if (algname != NULL) {
958			const char *hex = "0123456789abcdef";
959			p = buff;
960			s = sum->val;
961			for (i = 0; i < algsize; i++) {
962				*p++ = hex[(*s >> 4)];
963				*p++ = hex[(*s & 0x0f)];
964				s++;
965			}
966			*p = '\0';
967			r = xmlwrite_string_attr(a, writer,
968			    key, buff,
969			    "style", algname);
970			if (r < 0)
971				return (ARCHIVE_FATAL);
972		}
973	}
974	return (ARCHIVE_OK);
975}
976
977static int
978xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
979	struct heap_data *heap)
980{
981	const char *encname;
982	int r;
983
984	r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
985	if (r < 0)
986		return (ARCHIVE_FATAL);
987	r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
988	if (r < 0)
989		return (ARCHIVE_FATAL);
990	r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
991	if (r < 0)
992		return (ARCHIVE_FATAL);
993	switch (heap->compression) {
994	case GZIP:
995		encname = "application/x-gzip"; break;
996	case BZIP2:
997		encname = "application/x-bzip2"; break;
998	case LZMA:
999		encname = "application/x-lzma"; break;
1000	case XZ:
1001		encname = "application/x-xz"; break;
1002	default:
1003		encname = "application/octet-stream"; break;
1004	}
1005	r = xmlwrite_string_attr(a, writer, "encoding", NULL,
1006	    "style", encname);
1007	if (r < 0)
1008		return (ARCHIVE_FATAL);
1009	r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
1010	if (r < 0)
1011		return (ARCHIVE_FATAL);
1012	r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
1013	if (r < 0)
1014		return (ARCHIVE_FATAL);
1015	return (ARCHIVE_OK);
1016}
1017
1018/*
1019 * xar utility records fflags as following xml elements:
1020 *   <flags>
1021 *     <UserNoDump/>
1022 *     .....
1023 *   </flags>
1024 * or
1025 *   <ext2>
1026 *     <NoDump/>
1027 *     .....
1028 *   </ext2>
1029 * If xar is running on BSD platform, records <flags>..</flags>;
1030 * if xar is running on linux platform, records <ext2>..</ext2>;
1031 * otherwise does not record.
1032 *
1033 * Our implements records both <flags> and <ext2> if it's necessary.
1034 */
1035static int
1036make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
1037    const char *element, const char *fflags_text)
1038{
1039	static const struct flagentry {
1040		const char	*name;
1041		const char	*xarname;
1042	}
1043	flagbsd[] = {
1044		{ "sappnd",	"SystemAppend"},
1045		{ "sappend",	"SystemAppend"},
1046		{ "arch",	"SystemArchived"},
1047		{ "archived",	"SystemArchived"},
1048		{ "schg",	"SystemImmutable"},
1049		{ "schange",	"SystemImmutable"},
1050		{ "simmutable",	"SystemImmutable"},
1051		{ "nosunlnk",	"SystemNoUnlink"},
1052		{ "nosunlink",	"SystemNoUnlink"},
1053		{ "snapshot",	"SystemSnapshot"},
1054		{ "uappnd",	"UserAppend"},
1055		{ "uappend",	"UserAppend"},
1056		{ "uchg",	"UserImmutable"},
1057		{ "uchange",	"UserImmutable"},
1058		{ "uimmutable",	"UserImmutable"},
1059		{ "nodump",	"UserNoDump"},
1060		{ "noopaque",	"UserOpaque"},
1061		{ "nouunlnk",	"UserNoUnlink"},
1062		{ "nouunlink",	"UserNoUnlink"},
1063		{ NULL, NULL}
1064	},
1065	flagext2[] = {
1066		{ "sappnd",	"AppendOnly"},
1067		{ "sappend",	"AppendOnly"},
1068		{ "schg",	"Immutable"},
1069		{ "schange",	"Immutable"},
1070		{ "simmutable",	"Immutable"},
1071		{ "nodump",	"NoDump"},
1072		{ "nouunlnk",	"Undelete"},
1073		{ "nouunlink",	"Undelete"},
1074		{ "btree",	"BTree"},
1075		{ "comperr",	"CompError"},
1076		{ "compress",	"Compress"},
1077		{ "noatime",	"NoAtime"},
1078		{ "compdirty",	"CompDirty"},
1079		{ "comprblk",	"CompBlock"},
1080		{ "dirsync",	"DirSync"},
1081		{ "hashidx",	"HashIndexed"},
1082		{ "imagic",	"iMagic"},
1083		{ "journal",	"Journaled"},
1084		{ "securedeletion",	"SecureDeletion"},
1085		{ "sync",	"Synchronous"},
1086		{ "notail",	"NoTail"},
1087		{ "topdir",	"TopDir"},
1088		{ "reserved",	"Reserved"},
1089		{ NULL, NULL}
1090	};
1091	const struct flagentry *fe, *flagentry;
1092#define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
1093	const struct flagentry *avail[FLAGENTRY_MAXSIZE];
1094	const char *p;
1095	int i, n, r;
1096
1097	if (strcmp(element, "ext2") == 0)
1098		flagentry = flagext2;
1099	else
1100		flagentry = flagbsd;
1101	n = 0;
1102	p = fflags_text;
1103	do {
1104		const char *cp;
1105
1106		cp = strchr(p, ',');
1107		if (cp == NULL)
1108			cp = p + strlen(p);
1109
1110		for (fe = flagentry; fe->name != NULL; fe++) {
1111			if (fe->name[cp - p] != '\0'
1112			    || p[0] != fe->name[0])
1113				continue;
1114			if (strncmp(p, fe->name, cp - p) == 0) {
1115				avail[n++] = fe;
1116				break;
1117			}
1118		}
1119		if (*cp == ',')
1120			p = cp + 1;
1121		else
1122			p = NULL;
1123	} while (p != NULL);
1124
1125	if (n > 0) {
1126		r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element));
1127		if (r < 0) {
1128			archive_set_error(&a->archive,
1129			    ARCHIVE_ERRNO_MISC,
1130			    "xmlTextWriterStartElement() failed: %d", r);
1131			return (ARCHIVE_FATAL);
1132		}
1133		for (i = 0; i < n; i++) {
1134			r = xmlwrite_string(a, writer,
1135			    avail[i]->xarname, NULL);
1136			if (r != ARCHIVE_OK)
1137				return (r);
1138		}
1139
1140		r = xmlTextWriterEndElement(writer);
1141		if (r < 0) {
1142			archive_set_error(&a->archive,
1143			    ARCHIVE_ERRNO_MISC,
1144			    "xmlTextWriterEndElement() failed: %d", r);
1145			return (ARCHIVE_FATAL);
1146		}
1147	}
1148	return (ARCHIVE_OK);
1149}
1150
1151static int
1152make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
1153    struct file *file)
1154{
1155	struct xar *xar;
1156	const char *filetype, *filelink, *fflags;
1157	struct archive_string linkto;
1158	struct heap_data *heap;
1159	unsigned char *tmp;
1160	const char *p;
1161	size_t len;
1162	int r, r2, l, ll;
1163
1164	xar = (struct xar *)a->format_data;
1165	r2 = ARCHIVE_OK;
1166
1167	/*
1168	 * Make a file name entry, "<name>".
1169	 */
1170	l = ll = archive_strlen(&(file->basename));
1171	tmp = malloc(l);
1172	if (tmp == NULL) {
1173		archive_set_error(&a->archive, ENOMEM,
1174		    "Can't allocate memory");
1175		return (ARCHIVE_FATAL);
1176	}
1177	r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
1178	free(tmp);
1179	if (r < 0) {
1180		r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
1181		if (r < 0) {
1182			archive_set_error(&a->archive,
1183			    ARCHIVE_ERRNO_MISC,
1184			    "xmlTextWriterStartElement() failed: %d", r);
1185			return (ARCHIVE_FATAL);
1186		}
1187		r = xmlTextWriterWriteAttribute(writer,
1188		    BAD_CAST("enctype"), BAD_CAST("base64"));
1189		if (r < 0) {
1190			archive_set_error(&a->archive,
1191			    ARCHIVE_ERRNO_MISC,
1192			    "xmlTextWriterWriteAttribute() failed: %d", r);
1193			return (ARCHIVE_FATAL);
1194		}
1195		r = xmlTextWriterWriteBase64(writer, file->basename.s,
1196		    0, archive_strlen(&(file->basename)));
1197		if (r < 0) {
1198			archive_set_error(&a->archive,
1199			    ARCHIVE_ERRNO_MISC,
1200			    "xmlTextWriterWriteBase64() failed: %d", r);
1201			return (ARCHIVE_FATAL);
1202		}
1203		r = xmlTextWriterEndElement(writer);
1204		if (r < 0) {
1205			archive_set_error(&a->archive,
1206			    ARCHIVE_ERRNO_MISC,
1207			    "xmlTextWriterEndElement() failed: %d", r);
1208			return (ARCHIVE_FATAL);
1209		}
1210	} else {
1211		r = xmlwrite_string(a, writer, "name", file->basename.s);
1212		if (r < 0)
1213			return (ARCHIVE_FATAL);
1214	}
1215
1216	/*
1217	 * Make a file type entry, "<type>".
1218	 */
1219	filelink = NULL;
1220	archive_string_init(&linkto);
1221	switch (archive_entry_filetype(file->entry)) {
1222	case AE_IFDIR:
1223		filetype = "directory"; break;
1224	case AE_IFLNK:
1225		filetype = "symlink"; break;
1226	case AE_IFCHR:
1227		filetype = "character special"; break;
1228	case AE_IFBLK:
1229		filetype = "block special"; break;
1230	case AE_IFSOCK:
1231		filetype = "socket"; break;
1232	case AE_IFIFO:
1233		filetype = "fifo"; break;
1234	case AE_IFREG:
1235	default:
1236		if (file->hardlink_target != NULL) {
1237			filetype = "hardlink";
1238			filelink = "link";
1239			if (file->hardlink_target == file)
1240				archive_strcpy(&linkto, "original");
1241			else
1242				archive_string_sprintf(&linkto, "%d",
1243				    file->hardlink_target->id);
1244		} else
1245			filetype = "file";
1246		break;
1247	}
1248	r = xmlwrite_string_attr(a, writer, "type", filetype,
1249	    filelink, linkto.s);
1250	archive_string_free(&linkto);
1251	if (r < 0)
1252		return (ARCHIVE_FATAL);
1253
1254	/*
1255	 * On a virtual directory, we record "name" and "type" only.
1256	 */
1257	if (file->virtual)
1258		return (ARCHIVE_OK);
1259
1260	switch (archive_entry_filetype(file->entry)) {
1261	case AE_IFLNK:
1262		/*
1263		 * xar utility has checked a file type, which
1264		 * a symbolic-link file has referenced.
1265		 * For example:
1266		 *   <link type="directory">../ref/</link>
1267		 *   The symlink target file is "../ref/" and its
1268		 *   file type is a directory.
1269		 *
1270		 *   <link type="file">../f</link>
1271		 *   The symlink target file is "../f" and its
1272		 *   file type is a regular file.
1273		 *
1274		 * But our implementation cannot do it, and then we
1275		 * always record that a attribute "type" is "broken",
1276		 * for example:
1277		 *   <link type="broken">foo/bar</link>
1278		 *   It means "foo/bar" is not reachable.
1279		 */
1280		r = xmlwrite_string_attr(a, writer, "link",
1281		    file->symlink.s,
1282		    "type", "broken");
1283		if (r < 0)
1284			return (ARCHIVE_FATAL);
1285		break;
1286	case AE_IFCHR:
1287	case AE_IFBLK:
1288		r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
1289		if (r < 0) {
1290			archive_set_error(&a->archive,
1291			    ARCHIVE_ERRNO_MISC,
1292			    "xmlTextWriterStartElement() failed: %d", r);
1293			return (ARCHIVE_FATAL);
1294		}
1295		r = xmlwrite_fstring(a, writer, "major",
1296		    "%d", archive_entry_rdevmajor(file->entry));
1297		if (r < 0)
1298			return (ARCHIVE_FATAL);
1299		r = xmlwrite_fstring(a, writer, "minor",
1300		    "%d", archive_entry_rdevminor(file->entry));
1301		if (r < 0)
1302			return (ARCHIVE_FATAL);
1303		r = xmlTextWriterEndElement(writer);
1304		if (r < 0) {
1305			archive_set_error(&a->archive,
1306			    ARCHIVE_ERRNO_MISC,
1307			    "xmlTextWriterEndElement() failed: %d", r);
1308			return (ARCHIVE_FATAL);
1309		}
1310		break;
1311	default:
1312		break;
1313	}
1314
1315	/*
1316	 * Make a inode entry, "<inode>".
1317	 */
1318	r = xmlwrite_fstring(a, writer, "inode",
1319	    "%jd", archive_entry_ino64(file->entry));
1320	if (r < 0)
1321		return (ARCHIVE_FATAL);
1322	if (archive_entry_dev(file->entry) != 0) {
1323		r = xmlwrite_fstring(a, writer, "deviceno",
1324		    "%d", archive_entry_dev(file->entry));
1325		if (r < 0)
1326			return (ARCHIVE_FATAL);
1327	}
1328
1329	/*
1330	 * Make a file mode entry, "<mode>".
1331	 */
1332	r = xmlwrite_mode(a, writer, "mode",
1333	    archive_entry_mode(file->entry));
1334	if (r < 0)
1335		return (ARCHIVE_FATAL);
1336
1337	/*
1338	 * Make a user entry, "<uid>" and "<user>.
1339	 */
1340	r = xmlwrite_fstring(a, writer, "uid",
1341	    "%d", archive_entry_uid(file->entry));
1342	if (r < 0)
1343		return (ARCHIVE_FATAL);
1344	r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
1345	if (r != 0) {
1346		if (errno == ENOMEM) {
1347			archive_set_error(&a->archive, ENOMEM,
1348			    "Can't allocate memory for Uname");
1349			return (ARCHIVE_FATAL);
1350		}
1351		archive_set_error(&a->archive,
1352		    ARCHIVE_ERRNO_FILE_FORMAT,
1353		    "Can't translate uname '%s' to UTF-8",
1354		    archive_entry_uname(file->entry));
1355		r2 = ARCHIVE_WARN;
1356	}
1357	if (len > 0) {
1358		r = xmlwrite_string(a, writer, "user", p);
1359		if (r < 0)
1360			return (ARCHIVE_FATAL);
1361	}
1362
1363	/*
1364	 * Make a group entry, "<gid>" and "<group>.
1365	 */
1366	r = xmlwrite_fstring(a, writer, "gid",
1367	    "%d", archive_entry_gid(file->entry));
1368	if (r < 0)
1369		return (ARCHIVE_FATAL);
1370	r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
1371	if (r != 0) {
1372		if (errno == ENOMEM) {
1373			archive_set_error(&a->archive, ENOMEM,
1374			    "Can't allocate memory for Gname");
1375			return (ARCHIVE_FATAL);
1376		}
1377		archive_set_error(&a->archive,
1378		    ARCHIVE_ERRNO_FILE_FORMAT,
1379		    "Can't translate gname '%s' to UTF-8",
1380		    archive_entry_gname(file->entry));
1381		r2 = ARCHIVE_WARN;
1382	}
1383	if (len > 0) {
1384		r = xmlwrite_string(a, writer, "group", p);
1385		if (r < 0)
1386			return (ARCHIVE_FATAL);
1387	}
1388
1389	/*
1390	 * Make a ctime entry, "<ctime>".
1391	 */
1392	if (archive_entry_ctime_is_set(file->entry)) {
1393		r = xmlwrite_time(a, writer, "ctime",
1394		    archive_entry_ctime(file->entry), 1);
1395		if (r < 0)
1396			return (ARCHIVE_FATAL);
1397	}
1398
1399	/*
1400	 * Make a mtime entry, "<mtime>".
1401	 */
1402	if (archive_entry_mtime_is_set(file->entry)) {
1403		r = xmlwrite_time(a, writer, "mtime",
1404		    archive_entry_mtime(file->entry), 1);
1405		if (r < 0)
1406			return (ARCHIVE_FATAL);
1407	}
1408
1409	/*
1410	 * Make a atime entry, "<atime>".
1411	 */
1412	if (archive_entry_atime_is_set(file->entry)) {
1413		r = xmlwrite_time(a, writer, "atime",
1414		    archive_entry_atime(file->entry), 1);
1415		if (r < 0)
1416			return (ARCHIVE_FATAL);
1417	}
1418
1419	/*
1420	 * Make fflags entries, "<flags>" and "<ext2>".
1421	 */
1422	fflags = archive_entry_fflags_text(file->entry);
1423	if (fflags != NULL) {
1424		r = make_fflags_entry(a, writer, "flags", fflags);
1425		if (r < 0)
1426			return (r);
1427		r = make_fflags_entry(a, writer, "ext2", fflags);
1428		if (r < 0)
1429			return (r);
1430	}
1431
1432	/*
1433	 * Make extended attribute entries, "<ea>".
1434	 */
1435	archive_entry_xattr_reset(file->entry);
1436	for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
1437		const char *name;
1438		const void *value;
1439		size_t size;
1440
1441		archive_entry_xattr_next(file->entry,
1442		    &name, &value, &size);
1443		r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
1444		if (r < 0) {
1445			archive_set_error(&a->archive,
1446			    ARCHIVE_ERRNO_MISC,
1447			    "xmlTextWriterStartElement() failed: %d", r);
1448			return (ARCHIVE_FATAL);
1449		}
1450		r = xmlTextWriterWriteFormatAttribute(writer,
1451		    BAD_CAST("id"), "%d", heap->id);
1452		if (r < 0) {
1453			archive_set_error(&a->archive,
1454			    ARCHIVE_ERRNO_MISC,
1455			    "xmlTextWriterWriteAttribute() failed: %d", r);
1456			return (ARCHIVE_FATAL);
1457		}
1458		r = xmlwrite_heap(a, writer, heap);
1459		if (r < 0)
1460			return (ARCHIVE_FATAL);
1461		r = xmlwrite_string(a, writer, "name", name);
1462		if (r < 0)
1463			return (ARCHIVE_FATAL);
1464
1465		r = xmlTextWriterEndElement(writer);
1466		if (r < 0) {
1467			archive_set_error(&a->archive,
1468			    ARCHIVE_ERRNO_MISC,
1469			    "xmlTextWriterEndElement() failed: %d", r);
1470			return (ARCHIVE_FATAL);
1471		}
1472	}
1473
1474	/*
1475	 * Make a file data entry, "<data>".
1476	 */
1477	if (file->data.length > 0) {
1478		r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
1479		if (r < 0) {
1480			archive_set_error(&a->archive,
1481			    ARCHIVE_ERRNO_MISC,
1482			    "xmlTextWriterStartElement() failed: %d", r);
1483			return (ARCHIVE_FATAL);
1484		}
1485
1486		r = xmlwrite_heap(a, writer, &(file->data));
1487		if (r < 0)
1488			return (ARCHIVE_FATAL);
1489
1490		r = xmlTextWriterEndElement(writer);
1491		if (r < 0) {
1492			archive_set_error(&a->archive,
1493			    ARCHIVE_ERRNO_MISC,
1494			    "xmlTextWriterEndElement() failed: %d", r);
1495			return (ARCHIVE_FATAL);
1496		}
1497	}
1498
1499	if (archive_strlen(&file->script) > 0) {
1500		r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
1501		if (r < 0) {
1502			archive_set_error(&a->archive,
1503			    ARCHIVE_ERRNO_MISC,
1504			    "xmlTextWriterStartElement() failed: %d", r);
1505			return (ARCHIVE_FATAL);
1506		}
1507
1508		r = xmlwrite_string(a, writer,
1509		    "interpreter", file->script.s);
1510		if (r < 0)
1511			return (ARCHIVE_FATAL);
1512
1513		r = xmlwrite_string(a, writer, "type", "script");
1514		if (r < 0)
1515			return (ARCHIVE_FATAL);
1516
1517		r = xmlTextWriterEndElement(writer);
1518		if (r < 0) {
1519			archive_set_error(&a->archive,
1520			    ARCHIVE_ERRNO_MISC,
1521			    "xmlTextWriterEndElement() failed: %d", r);
1522			return (ARCHIVE_FATAL);
1523		}
1524	}
1525
1526	return (r2);
1527}
1528
1529/*
1530 * Make the TOC
1531 */
1532static int
1533make_toc(struct archive_write *a)
1534{
1535	struct xar *xar;
1536	struct file *np;
1537	xmlBufferPtr bp;
1538	xmlTextWriterPtr writer;
1539	int algsize;
1540	int r, ret;
1541
1542	xar = (struct xar *)a->format_data;
1543
1544	ret = ARCHIVE_FATAL;
1545
1546	/*
1547	 * Initialize xml writer.
1548	 */
1549	writer = NULL;
1550	bp = xmlBufferCreate();
1551	if (bp == NULL) {
1552		archive_set_error(&a->archive, ENOMEM,
1553		    "xmlBufferCreate() "
1554		    "couldn't create xml buffer");
1555		goto exit_toc;
1556	}
1557	writer = xmlNewTextWriterMemory(bp, 0);
1558	if (writer == NULL) {
1559		archive_set_error(&a->archive,
1560		    ARCHIVE_ERRNO_MISC,
1561		    "xmlNewTextWriterMemory() "
1562		    "couldn't create xml writer");
1563		goto exit_toc;
1564	}
1565	r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
1566	if (r < 0) {
1567		archive_set_error(&a->archive,
1568		    ARCHIVE_ERRNO_MISC,
1569		    "xmlTextWriterStartDocument() failed: %d", r);
1570		goto exit_toc;
1571	}
1572	r = xmlTextWriterSetIndent(writer, 4);
1573	if (r < 0) {
1574		archive_set_error(&a->archive,
1575		    ARCHIVE_ERRNO_MISC,
1576		    "xmlTextWriterSetIndent() failed: %d", r);
1577		goto exit_toc;
1578	}
1579
1580	/*
1581	 * Start recording TOC
1582	 */
1583	r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
1584	if (r < 0) {
1585		archive_set_error(&a->archive,
1586		    ARCHIVE_ERRNO_MISC,
1587		    "xmlTextWriterStartElement() failed: %d", r);
1588		goto exit_toc;
1589	}
1590	r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
1591	if (r < 0) {
1592		archive_set_error(&a->archive,
1593		    ARCHIVE_ERRNO_MISC,
1594		    "xmlTextWriterStartDocument() failed: %d", r);
1595		goto exit_toc;
1596	}
1597
1598	/*
1599	 * Record the creation time of the archive file.
1600	 */
1601	r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
1602	if (r < 0)
1603		goto exit_toc;
1604
1605	/*
1606	 * Record the checksum value of TOC
1607	 */
1608	algsize = getalgsize(xar->opt_toc_sumalg);
1609	if (algsize) {
1610		/*
1611		 * Record TOC checksum
1612		 */
1613		r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
1614		if (r < 0) {
1615			archive_set_error(&a->archive,
1616			    ARCHIVE_ERRNO_MISC,
1617			    "xmlTextWriterStartElement() failed: %d", r);
1618			goto exit_toc;
1619		}
1620		r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
1621		    BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg)));
1622		if (r < 0) {
1623			archive_set_error(&a->archive,
1624			    ARCHIVE_ERRNO_MISC,
1625			    "xmlTextWriterWriteAttribute() failed: %d", r);
1626			goto exit_toc;
1627		}
1628
1629		/*
1630		 * Record the offset of the value of checksum of TOC
1631		 */
1632		r = xmlwrite_string(a, writer, "offset", "0");
1633		if (r < 0)
1634			goto exit_toc;
1635
1636		/*
1637		 * Record the size of the value of checksum of TOC
1638		 */
1639		r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
1640		if (r < 0)
1641			goto exit_toc;
1642
1643		r = xmlTextWriterEndElement(writer);
1644		if (r < 0) {
1645			archive_set_error(&a->archive,
1646			    ARCHIVE_ERRNO_MISC,
1647			    "xmlTextWriterEndElement() failed: %d", r);
1648			goto exit_toc;
1649		}
1650	}
1651
1652	np = xar->root;
1653	do {
1654		if (np != np->parent) {
1655			r = make_file_entry(a, writer, np);
1656			if (r != ARCHIVE_OK)
1657				goto exit_toc;
1658		}
1659
1660		if (np->dir && np->children.first != NULL) {
1661			/* Enter to sub directories. */
1662			np = np->children.first;
1663			r = xmlTextWriterStartElement(writer,
1664			    BAD_CAST("file"));
1665			if (r < 0) {
1666				archive_set_error(&a->archive,
1667				    ARCHIVE_ERRNO_MISC,
1668				    "xmlTextWriterStartElement() "
1669				    "failed: %d", r);
1670				goto exit_toc;
1671			}
1672			r = xmlTextWriterWriteFormatAttribute(
1673			    writer, BAD_CAST("id"), "%d", np->id);
1674			if (r < 0) {
1675				archive_set_error(&a->archive,
1676				    ARCHIVE_ERRNO_MISC,
1677				    "xmlTextWriterWriteAttribute() "
1678				    "failed: %d", r);
1679				goto exit_toc;
1680			}
1681			continue;
1682		}
1683		while (np != np->parent) {
1684			r = xmlTextWriterEndElement(writer);
1685			if (r < 0) {
1686				archive_set_error(&a->archive,
1687				    ARCHIVE_ERRNO_MISC,
1688				    "xmlTextWriterEndElement() "
1689				    "failed: %d", r);
1690				goto exit_toc;
1691			}
1692			if (np->chnext == NULL) {
1693				/* Return to the parent directory. */
1694				np = np->parent;
1695			} else {
1696				np = np->chnext;
1697				r = xmlTextWriterStartElement(writer,
1698				    BAD_CAST("file"));
1699				if (r < 0) {
1700					archive_set_error(&a->archive,
1701					    ARCHIVE_ERRNO_MISC,
1702					    "xmlTextWriterStartElement() "
1703					    "failed: %d", r);
1704					goto exit_toc;
1705				}
1706				r = xmlTextWriterWriteFormatAttribute(
1707				    writer, BAD_CAST("id"), "%d", np->id);
1708				if (r < 0) {
1709					archive_set_error(&a->archive,
1710					    ARCHIVE_ERRNO_MISC,
1711					    "xmlTextWriterWriteAttribute() "
1712					    "failed: %d", r);
1713					goto exit_toc;
1714				}
1715				break;
1716			}
1717		}
1718	} while (np != np->parent);
1719
1720	r = xmlTextWriterEndDocument(writer);
1721	if (r < 0) {
1722		archive_set_error(&a->archive,
1723		    ARCHIVE_ERRNO_MISC,
1724		    "xmlTextWriterEndDocument() failed: %d", r);
1725		goto exit_toc;
1726	}
1727#if DEBUG_PRINT_TOC
1728	fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
1729	    strlen((const char *)bp->content), bp->content);
1730#endif
1731
1732	/*
1733	 * Compress the TOC and calculate the sum of the TOC.
1734	 */
1735	xar->toc.temp_offset = xar->temp_offset;
1736	xar->toc.size = bp->use;
1737	checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
1738
1739	r = compression_init_encoder_gzip(&(a->archive),
1740	    &(xar->stream), 6, 1);
1741	if (r != ARCHIVE_OK)
1742		goto exit_toc;
1743	xar->stream.next_in = bp->content;
1744	xar->stream.avail_in = bp->use;
1745	xar->stream.total_in = 0;
1746	xar->stream.next_out = xar->wbuff;
1747	xar->stream.avail_out = sizeof(xar->wbuff);
1748	xar->stream.total_out = 0;
1749	for (;;) {
1750		size_t size;
1751
1752		r = compression_code(&(a->archive),
1753		    &(xar->stream), ARCHIVE_Z_FINISH);
1754		if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
1755			goto exit_toc;
1756		size = sizeof(xar->wbuff) - xar->stream.avail_out;
1757		checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
1758		if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
1759			goto exit_toc;
1760		if (r == ARCHIVE_EOF)
1761			break;
1762		xar->stream.next_out = xar->wbuff;
1763		xar->stream.avail_out = sizeof(xar->wbuff);
1764	}
1765	r = compression_end(&(a->archive), &(xar->stream));
1766	if (r != ARCHIVE_OK)
1767		goto exit_toc;
1768	xar->toc.length = xar->stream.total_out;
1769	xar->toc.compression = GZIP;
1770	checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
1771
1772	ret = ARCHIVE_OK;
1773exit_toc:
1774	if (writer)
1775		xmlFreeTextWriter(writer);
1776	if (bp)
1777		xmlBufferFree(bp);
1778
1779	return (ret);
1780}
1781
1782static int
1783flush_wbuff(struct archive_write *a)
1784{
1785	struct xar *xar;
1786	int r;
1787	size_t s;
1788
1789	xar = (struct xar *)a->format_data;
1790	s = sizeof(xar->wbuff) - xar->wbuff_remaining;
1791	r = __archive_write_output(a, xar->wbuff, s);
1792	if (r != ARCHIVE_OK)
1793		return (r);
1794	xar->wbuff_remaining = sizeof(xar->wbuff);
1795	return (r);
1796}
1797
1798static int
1799copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
1800{
1801	struct xar *xar;
1802	int r;
1803
1804	xar = (struct xar *)a->format_data;
1805	if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
1806		archive_set_error(&(a->archive), errno, "lseek failed");
1807		return (ARCHIVE_FATAL);
1808	}
1809	while (length) {
1810		size_t rsize;
1811		ssize_t rs;
1812		unsigned char *wb;
1813
1814		if (length > xar->wbuff_remaining)
1815			rsize = xar->wbuff_remaining;
1816		else
1817			rsize = (size_t)length;
1818		wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1819		rs = read(xar->temp_fd, wb, rsize);
1820		if (rs < 0) {
1821			archive_set_error(&(a->archive), errno,
1822			    "Can't read temporary file(%jd)",
1823			    (intmax_t)rs);
1824			return (ARCHIVE_FATAL);
1825		}
1826		if (rs == 0) {
1827			archive_set_error(&(a->archive), 0,
1828			    "Truncated xar archive");
1829			return (ARCHIVE_FATAL);
1830		}
1831		xar->wbuff_remaining -= rs;
1832		length -= rs;
1833		if (xar->wbuff_remaining == 0) {
1834			r = flush_wbuff(a);
1835			if (r != ARCHIVE_OK)
1836				return (r);
1837		}
1838	}
1839	return (ARCHIVE_OK);
1840}
1841
1842static int
1843xar_close(struct archive_write *a)
1844{
1845	struct xar *xar;
1846	unsigned char *wb;
1847	uint64_t length;
1848	int r;
1849
1850	xar = (struct xar *)a->format_data;
1851
1852	/* Empty! */
1853	if (xar->root->children.first == NULL)
1854		return (ARCHIVE_OK);
1855
1856	/* Save the length of all file extended attributes and contents. */
1857	length = xar->temp_offset;
1858
1859	/* Connect hardlinked files */
1860	file_connect_hardlink_files(xar);
1861
1862	/* Make the TOC */
1863	r = make_toc(a);
1864	if (r != ARCHIVE_OK)
1865		return (r);
1866	/*
1867	 * Make the xar header on wbuff(write buffer).
1868	 */
1869	wb = xar->wbuff;
1870	xar->wbuff_remaining = sizeof(xar->wbuff);
1871	archive_be32enc(&wb[0], HEADER_MAGIC);
1872	archive_be16enc(&wb[4], HEADER_SIZE);
1873	archive_be16enc(&wb[6], HEADER_VERSION);
1874	archive_be64enc(&wb[8], xar->toc.length);
1875	archive_be64enc(&wb[16], xar->toc.size);
1876	archive_be32enc(&wb[24], xar->toc.a_sum.alg);
1877	xar->wbuff_remaining -= HEADER_SIZE;
1878
1879	/*
1880	 * Write the TOC
1881	 */
1882	r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
1883	if (r != ARCHIVE_OK)
1884		return (r);
1885
1886	/* Write the checksum value of the TOC. */
1887	if (xar->toc.a_sum.len) {
1888		if (xar->wbuff_remaining < xar->toc.a_sum.len) {
1889			r = flush_wbuff(a);
1890			if (r != ARCHIVE_OK)
1891				return (r);
1892		}
1893		wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1894		memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
1895		xar->wbuff_remaining -= xar->toc.a_sum.len;
1896	}
1897
1898	/*
1899	 * Write all file extended attributes and contents.
1900	 */
1901	r = copy_out(a, xar->toc.a_sum.len, length);
1902	if (r != ARCHIVE_OK)
1903		return (r);
1904	r = flush_wbuff(a);
1905	return (r);
1906}
1907
1908static int
1909xar_free(struct archive_write *a)
1910{
1911	struct xar *xar;
1912
1913	xar = (struct xar *)a->format_data;
1914
1915	/* Close the temporary file. */
1916	if (xar->temp_fd >= 0)
1917		close(xar->temp_fd);
1918
1919	archive_string_free(&(xar->cur_dirstr));
1920	archive_string_free(&(xar->tstr));
1921	archive_string_free(&(xar->vstr));
1922	file_free_hardlinks(xar);
1923	file_free_register(xar);
1924	compression_end(&(a->archive), &(xar->stream));
1925	free(xar);
1926
1927	return (ARCHIVE_OK);
1928}
1929
1930static int
1931file_cmp_node(const struct archive_rb_node *n1,
1932    const struct archive_rb_node *n2)
1933{
1934	const struct file *f1 = (const struct file *)n1;
1935	const struct file *f2 = (const struct file *)n2;
1936
1937	return (strcmp(f1->basename.s, f2->basename.s));
1938}
1939
1940static int
1941file_cmp_key(const struct archive_rb_node *n, const void *key)
1942{
1943	const struct file *f = (const struct file *)n;
1944
1945	return (strcmp(f->basename.s, (const char *)key));
1946}
1947
1948static struct file *
1949file_new(struct archive_write *a, struct archive_entry *entry)
1950{
1951	struct file *file;
1952	static const struct archive_rb_tree_ops rb_ops = {
1953		file_cmp_node, file_cmp_key
1954	};
1955
1956	file = calloc(1, sizeof(*file));
1957	if (file == NULL)
1958		return (NULL);
1959
1960	if (entry != NULL)
1961		file->entry = archive_entry_clone(entry);
1962	else
1963		file->entry = archive_entry_new2(&a->archive);
1964	if (file->entry == NULL) {
1965		free(file);
1966		return (NULL);
1967	}
1968	__archive_rb_tree_init(&(file->rbtree), &rb_ops);
1969	file->children.first = NULL;
1970	file->children.last = &(file->children.first);
1971	file->xattr.first = NULL;
1972	file->xattr.last = &(file->xattr.first);
1973	archive_string_init(&(file->parentdir));
1974	archive_string_init(&(file->basename));
1975	archive_string_init(&(file->symlink));
1976	archive_string_init(&(file->script));
1977	if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
1978		file->dir = 1;
1979
1980	return (file);
1981}
1982
1983static void
1984file_free(struct file *file)
1985{
1986	struct heap_data *heap, *next_heap;
1987
1988	heap = file->xattr.first;
1989	while (heap != NULL) {
1990		next_heap = heap->next;
1991		free(heap);
1992		heap = next_heap;
1993	}
1994	archive_string_free(&(file->parentdir));
1995	archive_string_free(&(file->basename));
1996	archive_string_free(&(file->symlink));
1997	archive_string_free(&(file->script));
1998	archive_entry_free(file->entry);
1999	free(file);
2000}
2001
2002static struct file *
2003file_create_virtual_dir(struct archive_write *a, struct xar *xar,
2004    const char *pathname)
2005{
2006	struct file *file;
2007
2008	(void)xar; /* UNUSED */
2009
2010	file = file_new(a, NULL);
2011	if (file == NULL)
2012		return (NULL);
2013	archive_entry_set_pathname(file->entry, pathname);
2014	archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
2015
2016	file->dir = 1;
2017	file->virtual = 1;
2018
2019	return (file);
2020}
2021
2022static int
2023file_add_child_tail(struct file *parent, struct file *child)
2024{
2025	if (!__archive_rb_tree_insert_node(
2026	    &(parent->rbtree), (struct archive_rb_node *)child))
2027		return (0);
2028	child->chnext = NULL;
2029	*parent->children.last = child;
2030	parent->children.last = &(child->chnext);
2031	child->parent = parent;
2032	return (1);
2033}
2034
2035/*
2036 * Find a entry from `parent'
2037 */
2038static struct file *
2039file_find_child(struct file *parent, const char *child_name)
2040{
2041	struct file *np;
2042
2043	np = (struct file *)__archive_rb_tree_find_node(
2044	    &(parent->rbtree), child_name);
2045	return (np);
2046}
2047
2048#if defined(_WIN32) || defined(__CYGWIN__)
2049static void
2050cleanup_backslash(char *utf8, size_t len)
2051{
2052
2053	/* Convert a path-separator from '\' to  '/' */
2054	while (*utf8 != '\0' && len) {
2055		if (*utf8 == '\\')
2056			*utf8 = '/';
2057		++utf8;
2058		--len;
2059	}
2060}
2061#else
2062#define cleanup_backslash(p, len)	/* nop */
2063#endif
2064
2065/*
2066 * Generate a parent directory name and a base name from a pathname.
2067 */
2068static int
2069file_gen_utility_names(struct archive_write *a, struct file *file)
2070{
2071	struct xar *xar;
2072	const char *pp;
2073	char *p, *dirname, *slash;
2074	size_t len;
2075	int r = ARCHIVE_OK;
2076
2077	xar = (struct xar *)a->format_data;
2078	archive_string_empty(&(file->parentdir));
2079	archive_string_empty(&(file->basename));
2080	archive_string_empty(&(file->symlink));
2081
2082	if (file->parent == file)/* virtual root */
2083		return (ARCHIVE_OK);
2084
2085	if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
2086	    != 0) {
2087		if (errno == ENOMEM) {
2088			archive_set_error(&a->archive, ENOMEM,
2089			    "Can't allocate memory for Pathname");
2090			return (ARCHIVE_FATAL);
2091		}
2092		archive_set_error(&a->archive,
2093		    ARCHIVE_ERRNO_FILE_FORMAT,
2094		    "Can't translate pathname '%s' to UTF-8",
2095		    archive_entry_pathname(file->entry));
2096		r = ARCHIVE_WARN;
2097	}
2098	archive_strncpy(&(file->parentdir), pp, len);
2099	len = file->parentdir.length;
2100	p = dirname = file->parentdir.s;
2101	/*
2102	 * Convert a path-separator from '\' to  '/'
2103	 */
2104	cleanup_backslash(p, len);
2105
2106	/*
2107	 * Remove leading '/', '../' and './' elements
2108	 */
2109	while (*p) {
2110		if (p[0] == '/') {
2111			p++;
2112			len--;
2113		} else if (p[0] != '.')
2114			break;
2115		else if (p[1] == '.' && p[2] == '/') {
2116			p += 3;
2117			len -= 3;
2118		} else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
2119			p += 2;
2120			len -= 2;
2121		} else if (p[1] == '\0') {
2122			p++;
2123			len--;
2124		} else
2125			break;
2126	}
2127	if (p != dirname) {
2128		memmove(dirname, p, len+1);
2129		p = dirname;
2130	}
2131	/*
2132	 * Remove "/","/." and "/.." elements from tail.
2133	 */
2134	while (len > 0) {
2135		size_t ll = len;
2136
2137		if (p[len-1] == '/') {
2138			p[len-1] = '\0';
2139			len--;
2140		}
2141		if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
2142			p[len-2] = '\0';
2143			len -= 2;
2144		}
2145		if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
2146		    p[len-1] == '.') {
2147			p[len-3] = '\0';
2148			len -= 3;
2149		}
2150		if (ll == len)
2151			break;
2152	}
2153	while (*p) {
2154		if (p[0] == '/') {
2155			if (p[1] == '/')
2156				/* Convert '//' --> '/' */
2157				strcpy(p, p+1);
2158			else if (p[1] == '.' && p[2] == '/')
2159				/* Convert '/./' --> '/' */
2160				strcpy(p, p+2);
2161			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
2162				/* Convert 'dir/dir1/../dir2/'
2163				 *     --> 'dir/dir2/'
2164				 */
2165				char *rp = p -1;
2166				while (rp >= dirname) {
2167					if (*rp == '/')
2168						break;
2169					--rp;
2170				}
2171				if (rp > dirname) {
2172					strcpy(rp, p+3);
2173					p = rp;
2174				} else {
2175					strcpy(dirname, p+4);
2176					p = dirname;
2177				}
2178			} else
2179				p++;
2180		} else
2181			p++;
2182	}
2183	p = dirname;
2184	len = strlen(p);
2185
2186	if (archive_entry_filetype(file->entry) == AE_IFLNK) {
2187		size_t len2;
2188		/* Convert symlink name too. */
2189		if (archive_entry_symlink_l(file->entry, &pp, &len2,
2190		    xar->sconv) != 0) {
2191			if (errno == ENOMEM) {
2192				archive_set_error(&a->archive, ENOMEM,
2193				    "Can't allocate memory for Linkname");
2194				return (ARCHIVE_FATAL);
2195			}
2196			archive_set_error(&a->archive,
2197			    ARCHIVE_ERRNO_FILE_FORMAT,
2198			    "Can't translate symlink '%s' to UTF-8",
2199			    archive_entry_symlink(file->entry));
2200			r = ARCHIVE_WARN;
2201		}
2202		archive_strncpy(&(file->symlink), pp, len2);
2203		cleanup_backslash(file->symlink.s, file->symlink.length);
2204	}
2205	/*
2206	 * - Count up directory elements.
2207	 * - Find out the position which points the last position of
2208	 *   path separator('/').
2209	 */
2210	slash = NULL;
2211	for (; *p != '\0'; p++)
2212		if (*p == '/')
2213			slash = p;
2214	if (slash == NULL) {
2215		/* The pathname doesn't have a parent directory. */
2216		file->parentdir.length = len;
2217		archive_string_copy(&(file->basename), &(file->parentdir));
2218		archive_string_empty(&(file->parentdir));
2219		*file->parentdir.s = '\0';
2220		return (r);
2221	}
2222
2223	/* Make a basename from dirname and slash */
2224	*slash  = '\0';
2225	file->parentdir.length = slash - dirname;
2226	archive_strcpy(&(file->basename),  slash + 1);
2227	return (r);
2228}
2229
2230static int
2231get_path_component(char *name, int n, const char *fn)
2232{
2233	char *p;
2234	int l;
2235
2236	p = strchr(fn, '/');
2237	if (p == NULL) {
2238		if ((l = strlen(fn)) == 0)
2239			return (0);
2240	} else
2241		l = p - fn;
2242	if (l > n -1)
2243		return (-1);
2244	memcpy(name, fn, l);
2245	name[l] = '\0';
2246
2247	return (l);
2248}
2249
2250/*
2251 * Add a new entry into the tree.
2252 */
2253static int
2254file_tree(struct archive_write *a, struct file **filepp)
2255{
2256#if defined(_WIN32) && !defined(__CYGWIN__)
2257	char name[_MAX_FNAME];/* Included null terminator size. */
2258#elif defined(NAME_MAX) && NAME_MAX >= 255
2259	char name[NAME_MAX+1];
2260#else
2261	char name[256];
2262#endif
2263	struct xar *xar = (struct xar *)a->format_data;
2264	struct file *dent, *file, *np;
2265	struct archive_entry *ent;
2266	const char *fn, *p;
2267	int l;
2268
2269	file = *filepp;
2270	dent = xar->root;
2271	if (file->parentdir.length > 0)
2272		fn = p = file->parentdir.s;
2273	else
2274		fn = p = "";
2275
2276	/*
2277	 * If the path of the parent directory of `file' entry is
2278	 * the same as the path of `cur_dirent', add isoent to
2279	 * `cur_dirent'.
2280	 */
2281	if (archive_strlen(&(xar->cur_dirstr))
2282	      == archive_strlen(&(file->parentdir)) &&
2283	    strcmp(xar->cur_dirstr.s, fn) == 0) {
2284		if (!file_add_child_tail(xar->cur_dirent, file)) {
2285			np = (struct file *)__archive_rb_tree_find_node(
2286			    &(xar->cur_dirent->rbtree),
2287			    file->basename.s);
2288			goto same_entry;
2289		}
2290		return (ARCHIVE_OK);
2291	}
2292
2293	for (;;) {
2294		l = get_path_component(name, sizeof(name), fn);
2295		if (l == 0) {
2296			np = NULL;
2297			break;
2298		}
2299		if (l < 0) {
2300			archive_set_error(&a->archive,
2301			    ARCHIVE_ERRNO_MISC,
2302			    "A name buffer is too small");
2303			file_free(file);
2304			*filepp = NULL;
2305			return (ARCHIVE_FATAL);
2306		}
2307
2308		np = file_find_child(dent, name);
2309		if (np == NULL || fn[0] == '\0')
2310			break;
2311
2312		/* Find next subdirectory. */
2313		if (!np->dir) {
2314			/* NOT Directory! */
2315			archive_set_error(&a->archive,
2316			    ARCHIVE_ERRNO_MISC,
2317			    "`%s' is not directory, we cannot insert `%s' ",
2318			    archive_entry_pathname(np->entry),
2319			    archive_entry_pathname(file->entry));
2320			file_free(file);
2321			*filepp = NULL;
2322			return (ARCHIVE_FAILED);
2323		}
2324		fn += l;
2325		if (fn[0] == '/')
2326			fn++;
2327		dent = np;
2328	}
2329	if (np == NULL) {
2330		/*
2331		 * Create virtual parent directories.
2332		 */
2333		while (fn[0] != '\0') {
2334			struct file *vp;
2335			struct archive_string as;
2336
2337			archive_string_init(&as);
2338			archive_strncat(&as, p, fn - p + l);
2339			if (as.s[as.length-1] == '/') {
2340				as.s[as.length-1] = '\0';
2341				as.length--;
2342			}
2343			vp = file_create_virtual_dir(a, xar, as.s);
2344			if (vp == NULL) {
2345				archive_string_free(&as);
2346				archive_set_error(&a->archive, ENOMEM,
2347				    "Can't allocate memory");
2348				file_free(file);
2349				*filepp = NULL;
2350				return (ARCHIVE_FATAL);
2351			}
2352			archive_string_free(&as);
2353			if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
2354				return (ARCHIVE_FATAL);
2355			file_add_child_tail(dent, vp);
2356			file_register(xar, vp);
2357			np = vp;
2358
2359			fn += l;
2360			if (fn[0] == '/')
2361				fn++;
2362			l = get_path_component(name, sizeof(name), fn);
2363			if (l < 0) {
2364				archive_string_free(&as);
2365				archive_set_error(&a->archive,
2366				    ARCHIVE_ERRNO_MISC,
2367				    "A name buffer is too small");
2368				file_free(file);
2369				*filepp = NULL;
2370				return (ARCHIVE_FATAL);
2371			}
2372			dent = np;
2373		}
2374
2375		/* Found out the parent directory where isoent can be
2376		 * inserted. */
2377		xar->cur_dirent = dent;
2378		archive_string_empty(&(xar->cur_dirstr));
2379		archive_string_ensure(&(xar->cur_dirstr),
2380		    archive_strlen(&(dent->parentdir)) +
2381		    archive_strlen(&(dent->basename)) + 2);
2382		if (archive_strlen(&(dent->parentdir)) +
2383		    archive_strlen(&(dent->basename)) == 0)
2384			xar->cur_dirstr.s[0] = 0;
2385		else {
2386			if (archive_strlen(&(dent->parentdir)) > 0) {
2387				archive_string_copy(&(xar->cur_dirstr),
2388				    &(dent->parentdir));
2389				archive_strappend_char(&(xar->cur_dirstr), '/');
2390			}
2391			archive_string_concat(&(xar->cur_dirstr),
2392			    &(dent->basename));
2393		}
2394
2395		if (!file_add_child_tail(dent, file)) {
2396			np = (struct file *)__archive_rb_tree_find_node(
2397			    &(dent->rbtree), file->basename.s);
2398			goto same_entry;
2399		}
2400		return (ARCHIVE_OK);
2401	}
2402
2403same_entry:
2404	/*
2405	 * We have already has the entry the filename of which is
2406	 * the same.
2407	 */
2408	if (archive_entry_filetype(np->entry) !=
2409	    archive_entry_filetype(file->entry)) {
2410		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2411		    "Found duplicate entries `%s' and its file type is "
2412		    "different",
2413		    archive_entry_pathname(np->entry));
2414		file_free(file);
2415		*filepp = NULL;
2416		return (ARCHIVE_FAILED);
2417	}
2418
2419	/* Swap files. */
2420	ent = np->entry;
2421	np->entry = file->entry;
2422	file->entry = ent;
2423	np->virtual = 0;
2424
2425	file_free(file);
2426	*filepp = np;
2427	return (ARCHIVE_OK);
2428}
2429
2430static void
2431file_register(struct xar *xar, struct file *file)
2432{
2433	file->id = xar->file_idx++;
2434        file->next = NULL;
2435        *xar->file_list.last = file;
2436        xar->file_list.last = &(file->next);
2437}
2438
2439static void
2440file_init_register(struct xar *xar)
2441{
2442	xar->file_list.first = NULL;
2443	xar->file_list.last = &(xar->file_list.first);
2444}
2445
2446static void
2447file_free_register(struct xar *xar)
2448{
2449	struct file *file, *file_next;
2450
2451	file = xar->file_list.first;
2452	while (file != NULL) {
2453		file_next = file->next;
2454		file_free(file);
2455		file = file_next;
2456	}
2457}
2458
2459/*
2460 * Register entry to get a hardlink target.
2461 */
2462static int
2463file_register_hardlink(struct archive_write *a, struct file *file)
2464{
2465	struct xar *xar = (struct xar *)a->format_data;
2466	struct hardlink *hl;
2467	const char *pathname;
2468
2469	archive_entry_set_nlink(file->entry, 1);
2470	pathname = archive_entry_hardlink(file->entry);
2471	if (pathname == NULL) {
2472		/* This `file` is a hardlink target. */
2473		hl = malloc(sizeof(*hl));
2474		if (hl == NULL) {
2475			archive_set_error(&a->archive, ENOMEM,
2476			    "Can't allocate memory");
2477			return (ARCHIVE_FATAL);
2478		}
2479		hl->nlink = 1;
2480		/* A hardlink target must be the first position. */
2481		file->hlnext = NULL;
2482		hl->file_list.first = file;
2483		hl->file_list.last = &(file->hlnext);
2484		__archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
2485		    (struct archive_rb_node *)hl);
2486	} else {
2487		hl = (struct hardlink *)__archive_rb_tree_find_node(
2488		    &(xar->hardlink_rbtree), pathname);
2489		if (hl != NULL) {
2490			/* Insert `file` entry into the tail. */
2491			file->hlnext = NULL;
2492			*hl->file_list.last = file;
2493			hl->file_list.last = &(file->hlnext);
2494			hl->nlink++;
2495		}
2496		archive_entry_unset_size(file->entry);
2497	}
2498
2499	return (ARCHIVE_OK);
2500}
2501
2502/*
2503 * Hardlinked files have to have the same location of extent.
2504 * We have to find out hardlink target entries for entries which
2505 * have a hardlink target name.
2506 */
2507static void
2508file_connect_hardlink_files(struct xar *xar)
2509{
2510	struct archive_rb_node *n;
2511	struct hardlink *hl;
2512	struct file *target, *nf;
2513
2514	ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
2515		hl = (struct hardlink *)n;
2516
2517		/* The first entry must be a hardlink target. */
2518		target = hl->file_list.first;
2519		archive_entry_set_nlink(target->entry, hl->nlink);
2520		if (hl->nlink > 1)
2521			/* It means this file is a hardlink
2522			 * target itself. */
2523			target->hardlink_target = target;
2524		for (nf = target->hlnext;
2525		    nf != NULL; nf = nf->hlnext) {
2526			nf->hardlink_target = target;
2527			archive_entry_set_nlink(nf->entry, hl->nlink);
2528		}
2529	}
2530}
2531
2532static int
2533file_hd_cmp_node(const struct archive_rb_node *n1,
2534    const struct archive_rb_node *n2)
2535{
2536	const struct hardlink *h1 = (const struct hardlink *)n1;
2537	const struct hardlink *h2 = (const struct hardlink *)n2;
2538
2539	return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
2540		       archive_entry_pathname(h2->file_list.first->entry)));
2541}
2542
2543static int
2544file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
2545{
2546	const struct hardlink *h = (const struct hardlink *)n;
2547
2548	return (strcmp(archive_entry_pathname(h->file_list.first->entry),
2549		       (const char *)key));
2550}
2551
2552
2553static void
2554file_init_hardlinks(struct xar *xar)
2555{
2556	static const struct archive_rb_tree_ops rb_ops = {
2557		file_hd_cmp_node, file_hd_cmp_key,
2558	};
2559
2560	__archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
2561}
2562
2563static void
2564file_free_hardlinks(struct xar *xar)
2565{
2566	struct archive_rb_node *n, *tmp;
2567
2568	ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
2569		__archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
2570		free(n);
2571	}
2572}
2573
2574static void
2575checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
2576{
2577	sumwrk->alg = sum_alg;
2578	switch (sum_alg) {
2579	case CKSUM_NONE:
2580		break;
2581	case CKSUM_SHA1:
2582		archive_sha1_init(&(sumwrk->sha1ctx));
2583		break;
2584	case CKSUM_MD5:
2585		archive_md5_init(&(sumwrk->md5ctx));
2586		break;
2587	}
2588}
2589
2590static void
2591checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
2592{
2593
2594	switch (sumwrk->alg) {
2595	case CKSUM_NONE:
2596		break;
2597	case CKSUM_SHA1:
2598		archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
2599		break;
2600	case CKSUM_MD5:
2601		archive_md5_update(&(sumwrk->md5ctx), buff, size);
2602		break;
2603	}
2604}
2605
2606static void
2607checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
2608{
2609
2610	switch (sumwrk->alg) {
2611	case CKSUM_NONE:
2612		sumval->len = 0;
2613		break;
2614	case CKSUM_SHA1:
2615		archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
2616		sumval->len = SHA1_SIZE;
2617		break;
2618	case CKSUM_MD5:
2619		archive_md5_final(&(sumwrk->md5ctx), sumval->val);
2620		sumval->len = MD5_SIZE;
2621		break;
2622	}
2623	sumval->alg = sumwrk->alg;
2624}
2625
2626#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
2627static int
2628compression_unsupported_encoder(struct archive *a,
2629    struct la_zstream *lastrm, const char *name)
2630{
2631
2632	archive_set_error(a, ARCHIVE_ERRNO_MISC,
2633	    "%s compression not supported on this platform", name);
2634	lastrm->valid = 0;
2635	lastrm->real_stream = NULL;
2636	return (ARCHIVE_FAILED);
2637}
2638#endif
2639
2640static int
2641compression_init_encoder_gzip(struct archive *a,
2642    struct la_zstream *lastrm, int level, int withheader)
2643{
2644	z_stream *strm;
2645
2646	if (lastrm->valid)
2647		compression_end(a, lastrm);
2648	strm = calloc(1, sizeof(*strm));
2649	if (strm == NULL) {
2650		archive_set_error(a, ENOMEM,
2651		    "Can't allocate memory for gzip stream");
2652		return (ARCHIVE_FATAL);
2653	}
2654	/* zlib.h is not const-correct, so we need this one bit
2655	 * of ugly hackery to convert a const * pointer to
2656	 * a non-const pointer. */
2657	strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2658	strm->avail_in = lastrm->avail_in;
2659	strm->total_in = (uLong)lastrm->total_in;
2660	strm->next_out = lastrm->next_out;
2661	strm->avail_out = lastrm->avail_out;
2662	strm->total_out = (uLong)lastrm->total_out;
2663	if (deflateInit2(strm, level, Z_DEFLATED,
2664	    (withheader)?15:-15,
2665	    8, Z_DEFAULT_STRATEGY) != Z_OK) {
2666		free(strm);
2667		lastrm->real_stream = NULL;
2668		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2669		    "Internal error initializing compression library");
2670		return (ARCHIVE_FATAL);
2671	}
2672	lastrm->real_stream = strm;
2673	lastrm->valid = 1;
2674	lastrm->code = compression_code_gzip;
2675	lastrm->end = compression_end_gzip;
2676	return (ARCHIVE_OK);
2677}
2678
2679static int
2680compression_code_gzip(struct archive *a,
2681    struct la_zstream *lastrm, enum la_zaction action)
2682{
2683	z_stream *strm;
2684	int r;
2685
2686	strm = (z_stream *)lastrm->real_stream;
2687	/* zlib.h is not const-correct, so we need this one bit
2688	 * of ugly hackery to convert a const * pointer to
2689	 * a non-const pointer. */
2690	strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2691	strm->avail_in = lastrm->avail_in;
2692	strm->total_in = (uLong)lastrm->total_in;
2693	strm->next_out = lastrm->next_out;
2694	strm->avail_out = lastrm->avail_out;
2695	strm->total_out = (uLong)lastrm->total_out;
2696	r = deflate(strm,
2697	    (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
2698	lastrm->next_in = strm->next_in;
2699	lastrm->avail_in = strm->avail_in;
2700	lastrm->total_in = strm->total_in;
2701	lastrm->next_out = strm->next_out;
2702	lastrm->avail_out = strm->avail_out;
2703	lastrm->total_out = strm->total_out;
2704	switch (r) {
2705	case Z_OK:
2706		return (ARCHIVE_OK);
2707	case Z_STREAM_END:
2708		return (ARCHIVE_EOF);
2709	default:
2710		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2711		    "GZip compression failed:"
2712		    " deflate() call returned status %d", r);
2713		return (ARCHIVE_FATAL);
2714	}
2715}
2716
2717static int
2718compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
2719{
2720	z_stream *strm;
2721	int r;
2722
2723	strm = (z_stream *)lastrm->real_stream;
2724	r = deflateEnd(strm);
2725	free(strm);
2726	lastrm->real_stream = NULL;
2727	lastrm->valid = 0;
2728	if (r != Z_OK) {
2729		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2730		    "Failed to clean up compressor");
2731		return (ARCHIVE_FATAL);
2732	}
2733	return (ARCHIVE_OK);
2734}
2735
2736#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
2737static int
2738compression_init_encoder_bzip2(struct archive *a,
2739    struct la_zstream *lastrm, int level)
2740{
2741	bz_stream *strm;
2742
2743	if (lastrm->valid)
2744		compression_end(a, lastrm);
2745	strm = calloc(1, sizeof(*strm));
2746	if (strm == NULL) {
2747		archive_set_error(a, ENOMEM,
2748		    "Can't allocate memory for bzip2 stream");
2749		return (ARCHIVE_FATAL);
2750	}
2751	/* bzlib.h is not const-correct, so we need this one bit
2752	 * of ugly hackery to convert a const * pointer to
2753	 * a non-const pointer. */
2754	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2755	strm->avail_in = lastrm->avail_in;
2756	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2757	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2758	strm->next_out = (char *)lastrm->next_out;
2759	strm->avail_out = lastrm->avail_out;
2760	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2761	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2762	if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
2763		free(strm);
2764		lastrm->real_stream = NULL;
2765		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2766		    "Internal error initializing compression library");
2767		return (ARCHIVE_FATAL);
2768	}
2769	lastrm->real_stream = strm;
2770	lastrm->valid = 1;
2771	lastrm->code = compression_code_bzip2;
2772	lastrm->end = compression_end_bzip2;
2773	return (ARCHIVE_OK);
2774}
2775
2776static int
2777compression_code_bzip2(struct archive *a,
2778    struct la_zstream *lastrm, enum la_zaction action)
2779{
2780	bz_stream *strm;
2781	int r;
2782
2783	strm = (bz_stream *)lastrm->real_stream;
2784	/* bzlib.h is not const-correct, so we need this one bit
2785	 * of ugly hackery to convert a const * pointer to
2786	 * a non-const pointer. */
2787	strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2788	strm->avail_in = lastrm->avail_in;
2789	strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2790	strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2791	strm->next_out = (char *)lastrm->next_out;
2792	strm->avail_out = lastrm->avail_out;
2793	strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2794	strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2795	r = BZ2_bzCompress(strm,
2796	    (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
2797	lastrm->next_in = (const unsigned char *)strm->next_in;
2798	lastrm->avail_in = strm->avail_in;
2799	lastrm->total_in =
2800	    (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
2801	    + (uint64_t)(uint32_t)strm->total_in_lo32;
2802	lastrm->next_out = (unsigned char *)strm->next_out;
2803	lastrm->avail_out = strm->avail_out;
2804	lastrm->total_out =
2805	    (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
2806	    + (uint64_t)(uint32_t)strm->total_out_lo32;
2807	switch (r) {
2808	case BZ_RUN_OK:     /* Non-finishing */
2809	case BZ_FINISH_OK:  /* Finishing: There's more work to do */
2810		return (ARCHIVE_OK);
2811	case BZ_STREAM_END: /* Finishing: all done */
2812		/* Only occurs in finishing case */
2813		return (ARCHIVE_EOF);
2814	default:
2815		/* Any other return value indicates an error */
2816		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2817		    "Bzip2 compression failed:"
2818		    " BZ2_bzCompress() call returned status %d", r);
2819		return (ARCHIVE_FATAL);
2820	}
2821}
2822
2823static int
2824compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
2825{
2826	bz_stream *strm;
2827	int r;
2828
2829	strm = (bz_stream *)lastrm->real_stream;
2830	r = BZ2_bzCompressEnd(strm);
2831	free(strm);
2832	lastrm->real_stream = NULL;
2833	lastrm->valid = 0;
2834	if (r != BZ_OK) {
2835		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2836		    "Failed to clean up compressor");
2837		return (ARCHIVE_FATAL);
2838	}
2839	return (ARCHIVE_OK);
2840}
2841
2842#else
2843static int
2844compression_init_encoder_bzip2(struct archive *a,
2845    struct la_zstream *lastrm, int level)
2846{
2847
2848	(void) level; /* UNUSED */
2849	if (lastrm->valid)
2850		compression_end(a, lastrm);
2851	return (compression_unsupported_encoder(a, lastrm, "bzip2"));
2852}
2853#endif
2854
2855#if defined(HAVE_LZMA_H)
2856static int
2857compression_init_encoder_lzma(struct archive *a,
2858    struct la_zstream *lastrm, int level)
2859{
2860	static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2861	lzma_stream *strm;
2862	lzma_options_lzma lzma_opt;
2863	int r;
2864
2865	if (lastrm->valid)
2866		compression_end(a, lastrm);
2867	if (lzma_lzma_preset(&lzma_opt, level)) {
2868		lastrm->real_stream = NULL;
2869		archive_set_error(a, ENOMEM,
2870		    "Internal error initializing compression library");
2871		return (ARCHIVE_FATAL);
2872	}
2873	strm = calloc(1, sizeof(*strm));
2874	if (strm == NULL) {
2875		archive_set_error(a, ENOMEM,
2876		    "Can't allocate memory for lzma stream");
2877		return (ARCHIVE_FATAL);
2878	}
2879	*strm = lzma_init_data;
2880	r = lzma_alone_encoder(strm, &lzma_opt);
2881	switch (r) {
2882	case LZMA_OK:
2883		lastrm->real_stream = strm;
2884		lastrm->valid = 1;
2885		lastrm->code = compression_code_lzma;
2886		lastrm->end = compression_end_lzma;
2887		r = ARCHIVE_OK;
2888		break;
2889	case LZMA_MEM_ERROR:
2890		free(strm);
2891		lastrm->real_stream = NULL;
2892		archive_set_error(a, ENOMEM,
2893		    "Internal error initializing compression library: "
2894		    "Cannot allocate memory");
2895		r =  ARCHIVE_FATAL;
2896		break;
2897        default:
2898		free(strm);
2899		lastrm->real_stream = NULL;
2900		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2901		    "Internal error initializing compression library: "
2902		    "It's a bug in liblzma");
2903		r =  ARCHIVE_FATAL;
2904		break;
2905	}
2906	return (r);
2907}
2908
2909static int
2910compression_init_encoder_xz(struct archive *a,
2911    struct la_zstream *lastrm, int level, int threads)
2912{
2913	static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2914	lzma_stream *strm;
2915	lzma_filter *lzmafilters;
2916	lzma_options_lzma lzma_opt;
2917	int r;
2918#ifdef HAVE_LZMA_STREAM_ENCODER_MT
2919	lzma_mt mt_options;
2920#endif
2921
2922	(void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */
2923
2924	if (lastrm->valid)
2925		compression_end(a, lastrm);
2926	strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
2927	if (strm == NULL) {
2928		archive_set_error(a, ENOMEM,
2929		    "Can't allocate memory for xz stream");
2930		return (ARCHIVE_FATAL);
2931	}
2932	lzmafilters = (lzma_filter *)(strm+1);
2933	if (level > 6)
2934		level = 6;
2935	if (lzma_lzma_preset(&lzma_opt, level)) {
2936		free(strm);
2937		lastrm->real_stream = NULL;
2938		archive_set_error(a, ENOMEM,
2939		    "Internal error initializing compression library");
2940		return (ARCHIVE_FATAL);
2941	}
2942	lzmafilters[0].id = LZMA_FILTER_LZMA2;
2943	lzmafilters[0].options = &lzma_opt;
2944	lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
2945
2946	*strm = lzma_init_data;
2947#ifdef HAVE_LZMA_STREAM_ENCODER_MT
2948	if (threads > 1) {
2949		memset(&mt_options, 0, sizeof(mt_options));
2950		mt_options.threads = threads;
2951		mt_options.timeout = 300;
2952		mt_options.filters = lzmafilters;
2953		mt_options.check = LZMA_CHECK_CRC64;
2954		r = lzma_stream_encoder_mt(strm, &mt_options);
2955	} else
2956#endif
2957		r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
2958	switch (r) {
2959	case LZMA_OK:
2960		lastrm->real_stream = strm;
2961		lastrm->valid = 1;
2962		lastrm->code = compression_code_lzma;
2963		lastrm->end = compression_end_lzma;
2964		r = ARCHIVE_OK;
2965		break;
2966	case LZMA_MEM_ERROR:
2967		free(strm);
2968		lastrm->real_stream = NULL;
2969		archive_set_error(a, ENOMEM,
2970		    "Internal error initializing compression library: "
2971		    "Cannot allocate memory");
2972		r =  ARCHIVE_FATAL;
2973		break;
2974        default:
2975		free(strm);
2976		lastrm->real_stream = NULL;
2977		archive_set_error(a, ARCHIVE_ERRNO_MISC,
2978		    "Internal error initializing compression library: "
2979		    "It's a bug in liblzma");
2980		r =  ARCHIVE_FATAL;
2981		break;
2982	}
2983	return (r);
2984}
2985
2986static int
2987compression_code_lzma(struct archive *a,
2988    struct la_zstream *lastrm, enum la_zaction action)
2989{
2990	lzma_stream *strm;
2991	int r;
2992
2993	strm = (lzma_stream *)lastrm->real_stream;
2994	strm->next_in = lastrm->next_in;
2995	strm->avail_in = lastrm->avail_in;
2996	strm->total_in = lastrm->total_in;
2997	strm->next_out = lastrm->next_out;
2998	strm->avail_out = lastrm->avail_out;
2999	strm->total_out = lastrm->total_out;
3000	r = lzma_code(strm,
3001	    (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
3002	lastrm->next_in = strm->next_in;
3003	lastrm->avail_in = strm->avail_in;
3004	lastrm->total_in = strm->total_in;
3005	lastrm->next_out = strm->next_out;
3006	lastrm->avail_out = strm->avail_out;
3007	lastrm->total_out = strm->total_out;
3008	switch (r) {
3009	case LZMA_OK:
3010		/* Non-finishing case */
3011		return (ARCHIVE_OK);
3012	case LZMA_STREAM_END:
3013		/* This return can only occur in finishing case. */
3014		return (ARCHIVE_EOF);
3015	case LZMA_MEMLIMIT_ERROR:
3016		archive_set_error(a, ENOMEM,
3017		    "lzma compression error:"
3018		    " %ju MiB would have been needed",
3019		    (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
3020			/ (1024 * 1024)));
3021		return (ARCHIVE_FATAL);
3022	default:
3023		/* Any other return value indicates an error */
3024		archive_set_error(a, ARCHIVE_ERRNO_MISC,
3025		    "lzma compression failed:"
3026		    " lzma_code() call returned status %d", r);
3027		return (ARCHIVE_FATAL);
3028	}
3029}
3030
3031static int
3032compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
3033{
3034	lzma_stream *strm;
3035
3036	(void)a; /* UNUSED */
3037	strm = (lzma_stream *)lastrm->real_stream;
3038	lzma_end(strm);
3039	free(strm);
3040	lastrm->valid = 0;
3041	lastrm->real_stream = NULL;
3042	return (ARCHIVE_OK);
3043}
3044#else
3045static int
3046compression_init_encoder_lzma(struct archive *a,
3047    struct la_zstream *lastrm, int level)
3048{
3049
3050	(void) level; /* UNUSED */
3051	if (lastrm->valid)
3052		compression_end(a, lastrm);
3053	return (compression_unsupported_encoder(a, lastrm, "lzma"));
3054}
3055static int
3056compression_init_encoder_xz(struct archive *a,
3057    struct la_zstream *lastrm, int level, int threads)
3058{
3059
3060	(void) level; /* UNUSED */
3061	(void) threads; /* UNUSED */
3062	if (lastrm->valid)
3063		compression_end(a, lastrm);
3064	return (compression_unsupported_encoder(a, lastrm, "xz"));
3065}
3066#endif
3067
3068static int
3069xar_compression_init_encoder(struct archive_write *a)
3070{
3071	struct xar *xar;
3072	int r;
3073
3074	xar = (struct xar *)a->format_data;
3075	switch (xar->opt_compression) {
3076	case GZIP:
3077		r = compression_init_encoder_gzip(
3078		    &(a->archive), &(xar->stream),
3079		    xar->opt_compression_level, 1);
3080		break;
3081	case BZIP2:
3082		r = compression_init_encoder_bzip2(
3083		    &(a->archive), &(xar->stream),
3084		    xar->opt_compression_level);
3085		break;
3086	case LZMA:
3087		r = compression_init_encoder_lzma(
3088		    &(a->archive), &(xar->stream),
3089		    xar->opt_compression_level);
3090		break;
3091	case XZ:
3092		r = compression_init_encoder_xz(
3093		    &(a->archive), &(xar->stream),
3094		    xar->opt_compression_level, xar->opt_threads);
3095		break;
3096	default:
3097		r = ARCHIVE_OK;
3098		break;
3099	}
3100	if (r == ARCHIVE_OK) {
3101		xar->stream.total_in = 0;
3102		xar->stream.next_out = xar->wbuff;
3103		xar->stream.avail_out = sizeof(xar->wbuff);
3104		xar->stream.total_out = 0;
3105	}
3106
3107	return (r);
3108}
3109
3110static int
3111compression_code(struct archive *a, struct la_zstream *lastrm,
3112    enum la_zaction action)
3113{
3114	if (lastrm->valid)
3115		return (lastrm->code(a, lastrm, action));
3116	return (ARCHIVE_OK);
3117}
3118
3119static int
3120compression_end(struct archive *a, struct la_zstream *lastrm)
3121{
3122	if (lastrm->valid)
3123		return (lastrm->end(a, lastrm));
3124	return (ARCHIVE_OK);
3125}
3126
3127
3128static int
3129save_xattrs(struct archive_write *a, struct file *file)
3130{
3131	struct xar *xar;
3132	const char *name;
3133	const void *value;
3134	struct heap_data *heap;
3135	size_t size;
3136	int count, r;
3137
3138	xar = (struct xar *)a->format_data;
3139	count = archive_entry_xattr_reset(file->entry);
3140	if (count == 0)
3141		return (ARCHIVE_OK);
3142	while (count--) {
3143		archive_entry_xattr_next(file->entry,
3144		    &name, &value, &size);
3145		checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
3146		checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
3147
3148		heap = calloc(1, sizeof(*heap));
3149		if (heap == NULL) {
3150			archive_set_error(&a->archive, ENOMEM,
3151			    "Can't allocate memory for xattr");
3152			return (ARCHIVE_FATAL);
3153		}
3154		heap->id = file->ea_idx++;
3155		heap->temp_offset = xar->temp_offset;
3156		heap->size = size;/* save a extracted size */
3157		heap->compression = xar->opt_compression;
3158		/* Get a extracted sumcheck value. */
3159		checksum_update(&(xar->e_sumwrk), value, size);
3160		checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
3161
3162		/*
3163		 * Not compression to xattr is simple way.
3164		 */
3165		if (heap->compression == NONE) {
3166			checksum_update(&(xar->a_sumwrk), value, size);
3167			checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
3168			if (write_to_temp(a, value, size)
3169			    != ARCHIVE_OK) {
3170				free(heap);
3171				return (ARCHIVE_FATAL);
3172			}
3173			heap->length = size;
3174			/* Add heap to the tail of file->xattr. */
3175			heap->next = NULL;
3176			*file->xattr.last = heap;
3177			file->xattr.last = &(heap->next);
3178			/* Next xattr */
3179			continue;
3180		}
3181
3182		/*
3183		 * Init compression library.
3184		 */
3185		r = xar_compression_init_encoder(a);
3186		if (r != ARCHIVE_OK) {
3187			free(heap);
3188			return (ARCHIVE_FATAL);
3189		}
3190
3191		xar->stream.next_in = (const unsigned char *)value;
3192		xar->stream.avail_in = size;
3193		for (;;) {
3194			r = compression_code(&(a->archive),
3195			    &(xar->stream), ARCHIVE_Z_FINISH);
3196			if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
3197				free(heap);
3198				return (ARCHIVE_FATAL);
3199			}
3200			size = sizeof(xar->wbuff) - xar->stream.avail_out;
3201			checksum_update(&(xar->a_sumwrk),
3202			    xar->wbuff, size);
3203			if (write_to_temp(a, xar->wbuff, size)
3204			    != ARCHIVE_OK)
3205				return (ARCHIVE_FATAL);
3206			if (r == ARCHIVE_OK) {
3207				xar->stream.next_out = xar->wbuff;
3208				xar->stream.avail_out = sizeof(xar->wbuff);
3209			} else {
3210				checksum_final(&(xar->a_sumwrk),
3211				    &(heap->a_sum));
3212				heap->length = xar->stream.total_out;
3213				/* Add heap to the tail of file->xattr. */
3214				heap->next = NULL;
3215				*file->xattr.last = heap;
3216				file->xattr.last = &(heap->next);
3217				break;
3218			}
3219		}
3220		/* Clean up compression library. */
3221		r = compression_end(&(a->archive), &(xar->stream));
3222		if (r != ARCHIVE_OK)
3223			return (ARCHIVE_FATAL);
3224	}
3225	return (ARCHIVE_OK);
3226}
3227
3228static int
3229getalgsize(enum sumalg sumalg)
3230{
3231	switch (sumalg) {
3232	default:
3233	case CKSUM_NONE:
3234		return (0);
3235	case CKSUM_SHA1:
3236		return (SHA1_SIZE);
3237	case CKSUM_MD5:
3238		return (MD5_SIZE);
3239	}
3240}
3241
3242static const char *
3243getalgname(enum sumalg sumalg)
3244{
3245	switch (sumalg) {
3246	default:
3247	case CKSUM_NONE:
3248		return (NULL);
3249	case CKSUM_SHA1:
3250		return (SHA1_NAME);
3251	case CKSUM_MD5:
3252		return (MD5_NAME);
3253	}
3254}
3255
3256#endif /* Support xar format */
3257