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