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