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