archive_read_support_format_xar.c revision 311041
1/*-
2 * Copyright (c) 2009 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#include "archive_platform.h"
26__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_read_support_format_xar.c 311041 2017-01-02 01:41:31Z mm $");
27
28#ifdef HAVE_ERRNO_H
29#include <errno.h>
30#endif
31#ifdef HAVE_STDLIB_H
32#include <stdlib.h>
33#endif
34#if HAVE_LIBXML_XMLREADER_H
35#include <libxml/xmlreader.h>
36#elif HAVE_BSDXML_H
37#include <bsdxml.h>
38#elif HAVE_EXPAT_H
39#include <expat.h>
40#endif
41#ifdef HAVE_BZLIB_H
42#include <bzlib.h>
43#endif
44#if HAVE_LZMA_H
45#include <lzma.h>
46#endif
47#ifdef HAVE_ZLIB_H
48#include <zlib.h>
49#endif
50
51#include "archive.h"
52#include "archive_digest_private.h"
53#include "archive_endian.h"
54#include "archive_entry.h"
55#include "archive_entry_locale.h"
56#include "archive_private.h"
57#include "archive_read_private.h"
58
59#if (!defined(HAVE_LIBXML_XMLREADER_H) && \
60     !defined(HAVE_BSDXML_H) && !defined(HAVE_EXPAT_H)) ||\
61	!defined(HAVE_ZLIB_H) || \
62	!defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
63/*
64 * xar needs several external libraries.
65 *   o libxml2 or expat --- XML parser
66 *   o openssl or MD5/SHA1 hash function
67 *   o zlib
68 *   o bzlib2 (option)
69 *   o liblzma (option)
70 */
71int
72archive_read_support_format_xar(struct archive *_a)
73{
74	struct archive_read *a = (struct archive_read *)_a;
75	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
76	    ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
77
78	archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
79	    "Xar not supported on this platform");
80	return (ARCHIVE_WARN);
81}
82
83#else	/* Support xar format */
84
85/* #define DEBUG 1 */
86/* #define DEBUG_PRINT_TOC 1 */
87#if DEBUG_PRINT_TOC
88#define PRINT_TOC(d, outbytes)	do {				\
89	unsigned char *x = (unsigned char *)(uintptr_t)d;	\
90	unsigned char c = x[outbytes-1];			\
91	x[outbytes - 1] = 0;					\
92	fprintf(stderr, "%s", x);				\
93	fprintf(stderr, "%c", c);				\
94	x[outbytes - 1] = c;					\
95} while (0)
96#else
97#define PRINT_TOC(d, outbytes)
98#endif
99
100#define HEADER_MAGIC	0x78617221
101#define HEADER_SIZE	28
102#define HEADER_VERSION	1
103#define CKSUM_NONE	0
104#define CKSUM_SHA1	1
105#define CKSUM_MD5	2
106
107#define MD5_SIZE	16
108#define SHA1_SIZE	20
109#define MAX_SUM_SIZE	20
110
111enum enctype {
112	NONE,
113	GZIP,
114	BZIP2,
115	LZMA,
116	XZ,
117};
118
119struct chksumval {
120	int			 alg;
121	size_t			 len;
122	unsigned char		 val[MAX_SUM_SIZE];
123};
124
125struct chksumwork {
126	int			 alg;
127#ifdef ARCHIVE_HAS_MD5
128	archive_md5_ctx		 md5ctx;
129#endif
130#ifdef ARCHIVE_HAS_SHA1
131	archive_sha1_ctx	 sha1ctx;
132#endif
133};
134
135struct xattr {
136	struct xattr		*next;
137	struct archive_string	 name;
138	uint64_t		 id;
139	uint64_t		 length;
140	uint64_t		 offset;
141	uint64_t		 size;
142	enum enctype		 encoding;
143	struct chksumval	 a_sum;
144	struct chksumval	 e_sum;
145	struct archive_string	 fstype;
146};
147
148struct xar_file {
149	struct xar_file		*next;
150	struct xar_file		*hdnext;
151	struct xar_file		*parent;
152	int			 subdirs;
153
154	unsigned int		 has;
155#define HAS_DATA		0x00001
156#define HAS_PATHNAME		0x00002
157#define HAS_SYMLINK		0x00004
158#define HAS_TIME		0x00008
159#define HAS_UID			0x00010
160#define HAS_GID			0x00020
161#define HAS_MODE		0x00040
162#define HAS_TYPE		0x00080
163#define HAS_DEV			0x00100
164#define HAS_DEVMAJOR		0x00200
165#define HAS_DEVMINOR		0x00400
166#define HAS_INO			0x00800
167#define HAS_FFLAGS		0x01000
168#define HAS_XATTR		0x02000
169#define HAS_ACL			0x04000
170
171	uint64_t		 id;
172	uint64_t		 length;
173	uint64_t		 offset;
174	uint64_t		 size;
175	enum enctype		 encoding;
176	struct chksumval	 a_sum;
177	struct chksumval	 e_sum;
178	struct archive_string	 pathname;
179	struct archive_string	 symlink;
180	time_t			 ctime;
181	time_t			 mtime;
182	time_t			 atime;
183	struct archive_string	 uname;
184	int64_t			 uid;
185	struct archive_string	 gname;
186	int64_t			 gid;
187	mode_t			 mode;
188	dev_t			 dev;
189	dev_t			 devmajor;
190	dev_t			 devminor;
191	int64_t			 ino64;
192	struct archive_string	 fflags_text;
193	unsigned int		 link;
194	unsigned int		 nlink;
195	struct archive_string	 hardlink;
196	struct xattr		*xattr_list;
197};
198
199struct hdlink {
200	struct hdlink		 *next;
201
202	unsigned int		 id;
203	int			 cnt;
204	struct xar_file		 *files;
205};
206
207struct heap_queue {
208	struct xar_file		**files;
209	int			 allocated;
210	int			 used;
211};
212
213enum xmlstatus {
214	INIT,
215	XAR,
216	TOC,
217	TOC_CREATION_TIME,
218	TOC_CHECKSUM,
219	TOC_CHECKSUM_OFFSET,
220	TOC_CHECKSUM_SIZE,
221	TOC_FILE,
222	FILE_DATA,
223	FILE_DATA_LENGTH,
224	FILE_DATA_OFFSET,
225	FILE_DATA_SIZE,
226	FILE_DATA_ENCODING,
227	FILE_DATA_A_CHECKSUM,
228	FILE_DATA_E_CHECKSUM,
229	FILE_DATA_CONTENT,
230	FILE_EA,
231	FILE_EA_LENGTH,
232	FILE_EA_OFFSET,
233	FILE_EA_SIZE,
234	FILE_EA_ENCODING,
235	FILE_EA_A_CHECKSUM,
236	FILE_EA_E_CHECKSUM,
237	FILE_EA_NAME,
238	FILE_EA_FSTYPE,
239	FILE_CTIME,
240	FILE_MTIME,
241	FILE_ATIME,
242	FILE_GROUP,
243	FILE_GID,
244	FILE_USER,
245	FILE_UID,
246	FILE_MODE,
247	FILE_DEVICE,
248	FILE_DEVICE_MAJOR,
249	FILE_DEVICE_MINOR,
250	FILE_DEVICENO,
251	FILE_INODE,
252	FILE_LINK,
253	FILE_TYPE,
254	FILE_NAME,
255	FILE_ACL,
256	FILE_ACL_DEFAULT,
257	FILE_ACL_ACCESS,
258	FILE_ACL_APPLEEXTENDED,
259	/* BSD file flags. */
260	FILE_FLAGS,
261	FILE_FLAGS_USER_NODUMP,
262	FILE_FLAGS_USER_IMMUTABLE,
263	FILE_FLAGS_USER_APPEND,
264	FILE_FLAGS_USER_OPAQUE,
265	FILE_FLAGS_USER_NOUNLINK,
266	FILE_FLAGS_SYS_ARCHIVED,
267	FILE_FLAGS_SYS_IMMUTABLE,
268	FILE_FLAGS_SYS_APPEND,
269	FILE_FLAGS_SYS_NOUNLINK,
270	FILE_FLAGS_SYS_SNAPSHOT,
271	/* Linux file flags. */
272	FILE_EXT2,
273	FILE_EXT2_SecureDeletion,
274	FILE_EXT2_Undelete,
275	FILE_EXT2_Compress,
276	FILE_EXT2_Synchronous,
277	FILE_EXT2_Immutable,
278	FILE_EXT2_AppendOnly,
279	FILE_EXT2_NoDump,
280	FILE_EXT2_NoAtime,
281	FILE_EXT2_CompDirty,
282	FILE_EXT2_CompBlock,
283	FILE_EXT2_NoCompBlock,
284	FILE_EXT2_CompError,
285	FILE_EXT2_BTree,
286	FILE_EXT2_HashIndexed,
287	FILE_EXT2_iMagic,
288	FILE_EXT2_Journaled,
289	FILE_EXT2_NoTail,
290	FILE_EXT2_DirSync,
291	FILE_EXT2_TopDir,
292	FILE_EXT2_Reserved,
293	UNKNOWN,
294};
295
296struct unknown_tag {
297	struct unknown_tag	*next;
298	struct archive_string	 name;
299};
300
301struct xar {
302	uint64_t		 offset; /* Current position in the file. */
303	int64_t			 total;
304	uint64_t		 h_base;
305	int			 end_of_file;
306#define OUTBUFF_SIZE	(1024 * 64)
307	unsigned char		*outbuff;
308
309	enum xmlstatus		 xmlsts;
310	enum xmlstatus		 xmlsts_unknown;
311	struct unknown_tag	*unknowntags;
312	int			 base64text;
313
314	/*
315	 * TOC
316	 */
317	uint64_t		 toc_remaining;
318	uint64_t		 toc_total;
319	uint64_t		 toc_chksum_offset;
320	uint64_t		 toc_chksum_size;
321
322	/*
323	 * For Decoding data.
324	 */
325	enum enctype 		 rd_encoding;
326	z_stream		 stream;
327	int			 stream_valid;
328#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
329	bz_stream		 bzstream;
330	int			 bzstream_valid;
331#endif
332#if HAVE_LZMA_H && HAVE_LIBLZMA
333	lzma_stream		 lzstream;
334	int			 lzstream_valid;
335#endif
336	/*
337	 * For Checksum data.
338	 */
339	struct chksumwork	 a_sumwrk;
340	struct chksumwork	 e_sumwrk;
341
342	struct xar_file		*file;	/* current reading file. */
343	struct xattr		*xattr; /* current reading extended attribute. */
344	struct heap_queue	 file_queue;
345	struct xar_file		*hdlink_orgs;
346	struct hdlink		*hdlink_list;
347
348	int	 		 entry_init;
349	uint64_t		 entry_total;
350	uint64_t		 entry_remaining;
351	size_t			 entry_unconsumed;
352	uint64_t		 entry_size;
353	enum enctype 		 entry_encoding;
354	struct chksumval	 entry_a_sum;
355	struct chksumval	 entry_e_sum;
356
357	struct archive_string_conv *sconv;
358};
359
360struct xmlattr {
361	struct xmlattr	*next;
362	char		*name;
363	char		*value;
364};
365
366struct xmlattr_list {
367	struct xmlattr	*first;
368	struct xmlattr	**last;
369};
370
371static int	xar_bid(struct archive_read *, int);
372static int	xar_read_header(struct archive_read *,
373		    struct archive_entry *);
374static int	xar_read_data(struct archive_read *,
375		    const void **, size_t *, int64_t *);
376static int	xar_read_data_skip(struct archive_read *);
377static int	xar_cleanup(struct archive_read *);
378static int	move_reading_point(struct archive_read *, uint64_t);
379static int	rd_contents_init(struct archive_read *,
380		    enum enctype, int, int);
381static int	rd_contents(struct archive_read *, const void **,
382		    size_t *, size_t *, uint64_t);
383static uint64_t	atol10(const char *, size_t);
384static int64_t	atol8(const char *, size_t);
385static size_t	atohex(unsigned char *, size_t, const char *, size_t);
386static time_t	parse_time(const char *p, size_t n);
387static int	heap_add_entry(struct archive_read *a,
388    struct heap_queue *, struct xar_file *);
389static struct xar_file *heap_get_entry(struct heap_queue *);
390static int	add_link(struct archive_read *,
391    struct xar *, struct xar_file *);
392static void	checksum_init(struct archive_read *, int, int);
393static void	checksum_update(struct archive_read *, const void *,
394		    size_t, const void *, size_t);
395static int	checksum_final(struct archive_read *, const void *,
396		    size_t, const void *, size_t);
397static int	decompression_init(struct archive_read *, enum enctype);
398static int	decompress(struct archive_read *, const void **,
399		    size_t *, const void *, size_t *);
400static int	decompression_cleanup(struct archive_read *);
401static void	xmlattr_cleanup(struct xmlattr_list *);
402static int	file_new(struct archive_read *,
403    struct xar *, struct xmlattr_list *);
404static void	file_free(struct xar_file *);
405static int	xattr_new(struct archive_read *,
406    struct xar *, struct xmlattr_list *);
407static void	xattr_free(struct xattr *);
408static int	getencoding(struct xmlattr_list *);
409static int	getsumalgorithm(struct xmlattr_list *);
410static int	unknowntag_start(struct archive_read *,
411    struct xar *, const char *);
412static void	unknowntag_end(struct xar *, const char *);
413static int	xml_start(struct archive_read *,
414    const char *, struct xmlattr_list *);
415static void	xml_end(void *, const char *);
416static void	xml_data(void *, const char *, int);
417static int	xml_parse_file_flags(struct xar *, const char *);
418static int	xml_parse_file_ext2(struct xar *, const char *);
419#if defined(HAVE_LIBXML_XMLREADER_H)
420static int	xml2_xmlattr_setup(struct archive_read *,
421    struct xmlattr_list *, xmlTextReaderPtr);
422static int	xml2_read_cb(void *, char *, int);
423static int	xml2_close_cb(void *);
424static void	xml2_error_hdr(void *, const char *, xmlParserSeverities,
425		    xmlTextReaderLocatorPtr);
426static int	xml2_read_toc(struct archive_read *);
427#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
428struct expat_userData {
429	int state;
430	struct archive_read *archive;
431};
432static int	expat_xmlattr_setup(struct archive_read *,
433    struct xmlattr_list *, const XML_Char **);
434static void	expat_start_cb(void *, const XML_Char *, const XML_Char **);
435static void	expat_end_cb(void *, const XML_Char *);
436static void	expat_data_cb(void *, const XML_Char *, int);
437static int	expat_read_toc(struct archive_read *);
438#endif
439
440int
441archive_read_support_format_xar(struct archive *_a)
442{
443	struct xar *xar;
444	struct archive_read *a = (struct archive_read *)_a;
445	int r;
446
447	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
448	    ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
449
450	xar = (struct xar *)calloc(1, sizeof(*xar));
451	if (xar == NULL) {
452		archive_set_error(&a->archive, ENOMEM,
453		    "Can't allocate xar data");
454		return (ARCHIVE_FATAL);
455	}
456
457	r = __archive_read_register_format(a,
458	    xar,
459	    "xar",
460	    xar_bid,
461	    NULL,
462	    xar_read_header,
463	    xar_read_data,
464	    xar_read_data_skip,
465	    NULL,
466	    xar_cleanup,
467	    NULL,
468	    NULL);
469	if (r != ARCHIVE_OK)
470		free(xar);
471	return (r);
472}
473
474static int
475xar_bid(struct archive_read *a, int best_bid)
476{
477	const unsigned char *b;
478	int bid;
479
480	(void)best_bid; /* UNUSED */
481
482	b = __archive_read_ahead(a, HEADER_SIZE, NULL);
483	if (b == NULL)
484		return (-1);
485
486	bid = 0;
487	/*
488	 * Verify magic code
489	 */
490	if (archive_be32dec(b) != HEADER_MAGIC)
491		return (0);
492	bid += 32;
493	/*
494	 * Verify header size
495	 */
496	if (archive_be16dec(b+4) != HEADER_SIZE)
497		return (0);
498	bid += 16;
499	/*
500	 * Verify header version
501	 */
502	if (archive_be16dec(b+6) != HEADER_VERSION)
503		return (0);
504	bid += 16;
505	/*
506	 * Verify type of checksum
507	 */
508	switch (archive_be32dec(b+24)) {
509	case CKSUM_NONE:
510	case CKSUM_SHA1:
511	case CKSUM_MD5:
512		bid += 32;
513		break;
514	default:
515		return (0);
516	}
517
518	return (bid);
519}
520
521static int
522read_toc(struct archive_read *a)
523{
524	struct xar *xar;
525	struct xar_file *file;
526	const unsigned char *b;
527	uint64_t toc_compressed_size;
528	uint64_t toc_uncompressed_size;
529	uint32_t toc_chksum_alg;
530	ssize_t bytes;
531	int r;
532
533	xar = (struct xar *)(a->format->data);
534
535	/*
536	 * Read xar header.
537	 */
538	b = __archive_read_ahead(a, HEADER_SIZE, &bytes);
539	if (bytes < 0)
540		return ((int)bytes);
541	if (bytes < HEADER_SIZE) {
542		archive_set_error(&a->archive,
543		    ARCHIVE_ERRNO_FILE_FORMAT,
544		    "Truncated archive header");
545		return (ARCHIVE_FATAL);
546	}
547
548	if (archive_be32dec(b) != HEADER_MAGIC) {
549		archive_set_error(&a->archive,
550		    ARCHIVE_ERRNO_FILE_FORMAT,
551		    "Invalid header magic");
552		return (ARCHIVE_FATAL);
553	}
554	if (archive_be16dec(b+6) != HEADER_VERSION) {
555		archive_set_error(&a->archive,
556		    ARCHIVE_ERRNO_FILE_FORMAT,
557		    "Unsupported header version(%d)",
558		    archive_be16dec(b+6));
559		return (ARCHIVE_FATAL);
560	}
561	toc_compressed_size = archive_be64dec(b+8);
562	xar->toc_remaining = toc_compressed_size;
563	toc_uncompressed_size = archive_be64dec(b+16);
564	toc_chksum_alg = archive_be32dec(b+24);
565	__archive_read_consume(a, HEADER_SIZE);
566	xar->offset += HEADER_SIZE;
567	xar->toc_total = 0;
568
569	/*
570	 * Read TOC(Table of Contents).
571	 */
572	/* Initialize reading contents. */
573	r = move_reading_point(a, HEADER_SIZE);
574	if (r != ARCHIVE_OK)
575		return (r);
576	r = rd_contents_init(a, GZIP, toc_chksum_alg, CKSUM_NONE);
577	if (r != ARCHIVE_OK)
578		return (r);
579
580#ifdef HAVE_LIBXML_XMLREADER_H
581	r = xml2_read_toc(a);
582#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
583	r = expat_read_toc(a);
584#endif
585	if (r != ARCHIVE_OK)
586		return (r);
587
588	/* Set 'The HEAP' base. */
589	xar->h_base = xar->offset;
590	if (xar->toc_total != toc_uncompressed_size) {
591		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
592		    "TOC uncompressed size error");
593		return (ARCHIVE_FATAL);
594	}
595
596	/*
597	 * Checksum TOC
598	 */
599	if (toc_chksum_alg != CKSUM_NONE) {
600		r = move_reading_point(a, xar->toc_chksum_offset);
601		if (r != ARCHIVE_OK)
602			return (r);
603		b = __archive_read_ahead(a,
604			(size_t)xar->toc_chksum_size, &bytes);
605		if (bytes < 0)
606			return ((int)bytes);
607		if ((uint64_t)bytes < xar->toc_chksum_size) {
608			archive_set_error(&a->archive,
609			    ARCHIVE_ERRNO_FILE_FORMAT,
610			    "Truncated archive file");
611			return (ARCHIVE_FATAL);
612		}
613		r = checksum_final(a, b,
614			(size_t)xar->toc_chksum_size, NULL, 0);
615		__archive_read_consume(a, xar->toc_chksum_size);
616		xar->offset += xar->toc_chksum_size;
617		if (r != ARCHIVE_OK)
618			return (ARCHIVE_FATAL);
619	}
620
621	/*
622	 * Connect hardlinked files.
623	 */
624	for (file = xar->hdlink_orgs; file != NULL; file = file->hdnext) {
625		struct hdlink **hdlink;
626
627		for (hdlink = &(xar->hdlink_list); *hdlink != NULL;
628		    hdlink = &((*hdlink)->next)) {
629			if ((*hdlink)->id == file->id) {
630				struct hdlink *hltmp;
631				struct xar_file *f2;
632				int nlink = (*hdlink)->cnt + 1;
633
634				file->nlink = nlink;
635				for (f2 = (*hdlink)->files; f2 != NULL;
636				    f2 = f2->hdnext) {
637					f2->nlink = nlink;
638					archive_string_copy(
639					    &(f2->hardlink), &(file->pathname));
640				}
641				/* Remove resolved files from hdlist_list. */
642				hltmp = *hdlink;
643				*hdlink = hltmp->next;
644				free(hltmp);
645				break;
646			}
647		}
648	}
649	a->archive.archive_format = ARCHIVE_FORMAT_XAR;
650	a->archive.archive_format_name = "xar";
651
652	return (ARCHIVE_OK);
653}
654
655static int
656xar_read_header(struct archive_read *a, struct archive_entry *entry)
657{
658	struct xar *xar;
659	struct xar_file *file;
660	struct xattr *xattr;
661	int r;
662
663	xar = (struct xar *)(a->format->data);
664	r = ARCHIVE_OK;
665
666	if (xar->offset == 0) {
667		/* Create a character conversion object. */
668		if (xar->sconv == NULL) {
669			xar->sconv = archive_string_conversion_from_charset(
670			    &(a->archive), "UTF-8", 1);
671			if (xar->sconv == NULL)
672				return (ARCHIVE_FATAL);
673		}
674
675		/* Read TOC. */
676		r = read_toc(a);
677		if (r != ARCHIVE_OK)
678			return (r);
679	}
680
681	for (;;) {
682		file = xar->file = heap_get_entry(&(xar->file_queue));
683		if (file == NULL) {
684			xar->end_of_file = 1;
685			return (ARCHIVE_EOF);
686		}
687		if ((file->mode & AE_IFMT) != AE_IFDIR)
688			break;
689		if (file->has != (HAS_PATHNAME | HAS_TYPE))
690			break;
691		/*
692		 * If a file type is a directory and it does not have
693		 * any metadata, do not export.
694		 */
695		file_free(file);
696	}
697	archive_entry_set_atime(entry, file->atime, 0);
698	archive_entry_set_ctime(entry, file->ctime, 0);
699	archive_entry_set_mtime(entry, file->mtime, 0);
700	archive_entry_set_gid(entry, file->gid);
701	if (file->gname.length > 0 &&
702	    archive_entry_copy_gname_l(entry, file->gname.s,
703		archive_strlen(&(file->gname)), xar->sconv) != 0) {
704		if (errno == ENOMEM) {
705			archive_set_error(&a->archive, ENOMEM,
706			    "Can't allocate memory for Gname");
707			return (ARCHIVE_FATAL);
708		}
709		archive_set_error(&a->archive,
710		    ARCHIVE_ERRNO_FILE_FORMAT,
711		    "Gname cannot be converted from %s to current locale.",
712		    archive_string_conversion_charset_name(xar->sconv));
713		r = ARCHIVE_WARN;
714	}
715	archive_entry_set_uid(entry, file->uid);
716	if (file->uname.length > 0 &&
717	    archive_entry_copy_uname_l(entry, file->uname.s,
718		archive_strlen(&(file->uname)), xar->sconv) != 0) {
719		if (errno == ENOMEM) {
720			archive_set_error(&a->archive, ENOMEM,
721			    "Can't allocate memory for Uname");
722			return (ARCHIVE_FATAL);
723		}
724		archive_set_error(&a->archive,
725		    ARCHIVE_ERRNO_FILE_FORMAT,
726		    "Uname cannot be converted from %s to current locale.",
727		    archive_string_conversion_charset_name(xar->sconv));
728		r = ARCHIVE_WARN;
729	}
730	archive_entry_set_mode(entry, file->mode);
731	if (archive_entry_copy_pathname_l(entry, file->pathname.s,
732	    archive_strlen(&(file->pathname)), xar->sconv) != 0) {
733		if (errno == ENOMEM) {
734			archive_set_error(&a->archive, ENOMEM,
735			    "Can't allocate memory for Pathname");
736			return (ARCHIVE_FATAL);
737		}
738		archive_set_error(&a->archive,
739		    ARCHIVE_ERRNO_FILE_FORMAT,
740		    "Pathname cannot be converted from %s to current locale.",
741		    archive_string_conversion_charset_name(xar->sconv));
742		r = ARCHIVE_WARN;
743	}
744
745
746	if (file->symlink.length > 0 &&
747	    archive_entry_copy_symlink_l(entry, file->symlink.s,
748		archive_strlen(&(file->symlink)), xar->sconv) != 0) {
749		if (errno == ENOMEM) {
750			archive_set_error(&a->archive, ENOMEM,
751			    "Can't allocate memory for Linkname");
752			return (ARCHIVE_FATAL);
753		}
754		archive_set_error(&a->archive,
755		    ARCHIVE_ERRNO_FILE_FORMAT,
756		    "Linkname cannot be converted from %s to current locale.",
757		    archive_string_conversion_charset_name(xar->sconv));
758		r = ARCHIVE_WARN;
759	}
760	/* Set proper nlink. */
761	if ((file->mode & AE_IFMT) == AE_IFDIR)
762		archive_entry_set_nlink(entry, file->subdirs + 2);
763	else
764		archive_entry_set_nlink(entry, file->nlink);
765	archive_entry_set_size(entry, file->size);
766	if (archive_strlen(&(file->hardlink)) > 0)
767		archive_entry_set_hardlink(entry, file->hardlink.s);
768	archive_entry_set_ino64(entry, file->ino64);
769	if (file->has & HAS_DEV)
770		archive_entry_set_dev(entry, file->dev);
771	if (file->has & HAS_DEVMAJOR)
772		archive_entry_set_devmajor(entry, file->devmajor);
773	if (file->has & HAS_DEVMINOR)
774		archive_entry_set_devminor(entry, file->devminor);
775	if (archive_strlen(&(file->fflags_text)) > 0)
776		archive_entry_copy_fflags_text(entry, file->fflags_text.s);
777
778	xar->entry_init = 1;
779	xar->entry_total = 0;
780	xar->entry_remaining = file->length;
781	xar->entry_size = file->size;
782	xar->entry_encoding = file->encoding;
783	xar->entry_a_sum = file->a_sum;
784	xar->entry_e_sum = file->e_sum;
785	/*
786	 * Read extended attributes.
787	 */
788	xattr = file->xattr_list;
789	while (xattr != NULL) {
790		const void *d;
791		size_t outbytes, used;
792
793		r = move_reading_point(a, xattr->offset);
794		if (r != ARCHIVE_OK)
795			break;
796		r = rd_contents_init(a, xattr->encoding,
797		    xattr->a_sum.alg, xattr->e_sum.alg);
798		if (r != ARCHIVE_OK)
799			break;
800		d = NULL;
801		r = rd_contents(a, &d, &outbytes, &used, xattr->length);
802		if (r != ARCHIVE_OK)
803			break;
804		if (outbytes != xattr->size) {
805			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
806			    "Decompressed size error");
807			r = ARCHIVE_FATAL;
808			break;
809		}
810		r = checksum_final(a,
811		    xattr->a_sum.val, xattr->a_sum.len,
812		    xattr->e_sum.val, xattr->e_sum.len);
813		if (r != ARCHIVE_OK)
814			break;
815		archive_entry_xattr_add_entry(entry,
816		    xattr->name.s, d, outbytes);
817		xattr = xattr->next;
818	}
819	if (r != ARCHIVE_OK) {
820		file_free(file);
821		return (r);
822	}
823
824	if (xar->entry_remaining > 0)
825		/* Move reading point to the beginning of current
826		 * file contents. */
827		r = move_reading_point(a, file->offset);
828	else
829		r = ARCHIVE_OK;
830
831	file_free(file);
832	return (r);
833}
834
835static int
836xar_read_data(struct archive_read *a,
837    const void **buff, size_t *size, int64_t *offset)
838{
839	struct xar *xar;
840	size_t used;
841	int r;
842
843	xar = (struct xar *)(a->format->data);
844
845	if (xar->entry_unconsumed) {
846		__archive_read_consume(a, xar->entry_unconsumed);
847		xar->entry_unconsumed = 0;
848	}
849
850	if (xar->end_of_file || xar->entry_remaining <= 0) {
851		r = ARCHIVE_EOF;
852		goto abort_read_data;
853	}
854
855	if (xar->entry_init) {
856		r = rd_contents_init(a, xar->entry_encoding,
857		    xar->entry_a_sum.alg, xar->entry_e_sum.alg);
858		if (r != ARCHIVE_OK) {
859			xar->entry_remaining = 0;
860			return (r);
861		}
862		xar->entry_init = 0;
863	}
864
865	*buff = NULL;
866	r = rd_contents(a, buff, size, &used, xar->entry_remaining);
867	if (r != ARCHIVE_OK)
868		goto abort_read_data;
869
870	*offset = xar->entry_total;
871	xar->entry_total += *size;
872	xar->total += *size;
873	xar->offset += used;
874	xar->entry_remaining -= used;
875	xar->entry_unconsumed = used;
876
877	if (xar->entry_remaining == 0) {
878		if (xar->entry_total != xar->entry_size) {
879			archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
880			    "Decompressed size error");
881			r = ARCHIVE_FATAL;
882			goto abort_read_data;
883		}
884		r = checksum_final(a,
885		    xar->entry_a_sum.val, xar->entry_a_sum.len,
886		    xar->entry_e_sum.val, xar->entry_e_sum.len);
887		if (r != ARCHIVE_OK)
888			goto abort_read_data;
889	}
890
891	return (ARCHIVE_OK);
892abort_read_data:
893	*buff = NULL;
894	*size = 0;
895	*offset = xar->total;
896	return (r);
897}
898
899static int
900xar_read_data_skip(struct archive_read *a)
901{
902	struct xar *xar;
903	int64_t bytes_skipped;
904
905	xar = (struct xar *)(a->format->data);
906	if (xar->end_of_file)
907		return (ARCHIVE_EOF);
908	bytes_skipped = __archive_read_consume(a, xar->entry_remaining +
909		xar->entry_unconsumed);
910	if (bytes_skipped < 0)
911		return (ARCHIVE_FATAL);
912	xar->offset += bytes_skipped;
913	xar->entry_unconsumed = 0;
914	return (ARCHIVE_OK);
915}
916
917static int
918xar_cleanup(struct archive_read *a)
919{
920	struct xar *xar;
921	struct hdlink *hdlink;
922	int i;
923	int r;
924
925	xar = (struct xar *)(a->format->data);
926	r = decompression_cleanup(a);
927	hdlink = xar->hdlink_list;
928	while (hdlink != NULL) {
929		struct hdlink *next = hdlink->next;
930
931		free(hdlink);
932		hdlink = next;
933	}
934	for (i = 0; i < xar->file_queue.used; i++)
935		file_free(xar->file_queue.files[i]);
936	while (xar->unknowntags != NULL) {
937		struct unknown_tag *tag;
938
939		tag = xar->unknowntags;
940		xar->unknowntags = tag->next;
941		archive_string_free(&(tag->name));
942		free(tag);
943	}
944	free(xar->outbuff);
945	free(xar);
946	a->format->data = NULL;
947	return (r);
948}
949
950static int
951move_reading_point(struct archive_read *a, uint64_t offset)
952{
953	struct xar *xar;
954
955	xar = (struct xar *)(a->format->data);
956	if (xar->offset - xar->h_base != offset) {
957		/* Seek forward to the start of file contents. */
958		int64_t step;
959
960		step = offset - (xar->offset - xar->h_base);
961		if (step > 0) {
962			step = __archive_read_consume(a, step);
963			if (step < 0)
964				return ((int)step);
965			xar->offset += step;
966		} else {
967			int64_t pos = __archive_read_seek(a, offset, SEEK_SET);
968			if (pos == ARCHIVE_FAILED) {
969				archive_set_error(&(a->archive),
970				    ARCHIVE_ERRNO_MISC,
971				    "Cannot seek.");
972				return (ARCHIVE_FAILED);
973			}
974			xar->offset = pos;
975		}
976	}
977	return (ARCHIVE_OK);
978}
979
980static int
981rd_contents_init(struct archive_read *a, enum enctype encoding,
982    int a_sum_alg, int e_sum_alg)
983{
984	int r;
985
986	/* Init decompress library. */
987	if ((r = decompression_init(a, encoding)) != ARCHIVE_OK)
988		return (r);
989	/* Init checksum library. */
990	checksum_init(a, a_sum_alg, e_sum_alg);
991	return (ARCHIVE_OK);
992}
993
994static int
995rd_contents(struct archive_read *a, const void **buff, size_t *size,
996    size_t *used, uint64_t remaining)
997{
998	const unsigned char *b;
999	ssize_t bytes;
1000
1001	/* Get whatever bytes are immediately available. */
1002	b = __archive_read_ahead(a, 1, &bytes);
1003	if (bytes < 0)
1004		return ((int)bytes);
1005	if (bytes == 0) {
1006		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1007		    "Truncated archive file");
1008		return (ARCHIVE_FATAL);
1009	}
1010	if ((uint64_t)bytes > remaining)
1011		bytes = (ssize_t)remaining;
1012
1013	/*
1014	 * Decompress contents of file.
1015	 */
1016	*used = bytes;
1017	if (decompress(a, buff, size, b, used) != ARCHIVE_OK)
1018		return (ARCHIVE_FATAL);
1019
1020	/*
1021	 * Update checksum of a compressed data and a extracted data.
1022	 */
1023	checksum_update(a, b, *used, *buff, *size);
1024
1025	return (ARCHIVE_OK);
1026}
1027
1028/*
1029 * Note that this implementation does not (and should not!) obey
1030 * locale settings; you cannot simply substitute strtol here, since
1031 * it does obey locale.
1032 */
1033
1034static uint64_t
1035atol10(const char *p, size_t char_cnt)
1036{
1037	uint64_t l;
1038	int digit;
1039
1040	l = 0;
1041	digit = *p - '0';
1042	while (digit >= 0 && digit < 10  && char_cnt-- > 0) {
1043		l = (l * 10) + digit;
1044		digit = *++p - '0';
1045	}
1046	return (l);
1047}
1048
1049static int64_t
1050atol8(const char *p, size_t char_cnt)
1051{
1052	int64_t l;
1053	int digit;
1054
1055	l = 0;
1056	while (char_cnt-- > 0) {
1057		if (*p >= '0' && *p <= '7')
1058			digit = *p - '0';
1059		else
1060			break;
1061		p++;
1062		l <<= 3;
1063		l |= digit;
1064	}
1065	return (l);
1066}
1067
1068static size_t
1069atohex(unsigned char *b, size_t bsize, const char *p, size_t psize)
1070{
1071	size_t fbsize = bsize;
1072
1073	while (bsize && psize > 1) {
1074		unsigned char x;
1075
1076		if (p[0] >= 'a' && p[0] <= 'z')
1077			x = (p[0] - 'a' + 0x0a) << 4;
1078		else if (p[0] >= 'A' && p[0] <= 'Z')
1079			x = (p[0] - 'A' + 0x0a) << 4;
1080		else if (p[0] >= '0' && p[0] <= '9')
1081			x = (p[0] - '0') << 4;
1082		else
1083			return (-1);
1084		if (p[1] >= 'a' && p[1] <= 'z')
1085			x |= p[1] - 'a' + 0x0a;
1086		else if (p[1] >= 'A' && p[1] <= 'Z')
1087			x |= p[1] - 'A' + 0x0a;
1088		else if (p[1] >= '0' && p[1] <= '9')
1089			x |= p[1] - '0';
1090		else
1091			return (-1);
1092
1093		*b++ = x;
1094		bsize--;
1095		p += 2;
1096		psize -= 2;
1097	}
1098	return (fbsize - bsize);
1099}
1100
1101static time_t
1102time_from_tm(struct tm *t)
1103{
1104#if HAVE_TIMEGM
1105        /* Use platform timegm() if available. */
1106        return (timegm(t));
1107#elif HAVE__MKGMTIME64
1108        return (_mkgmtime64(t));
1109#else
1110        /* Else use direct calculation using POSIX assumptions. */
1111        /* First, fix up tm_yday based on the year/month/day. */
1112        mktime(t);
1113        /* Then we can compute timegm() from first principles. */
1114        return (t->tm_sec
1115            + t->tm_min * 60
1116            + t->tm_hour * 3600
1117            + t->tm_yday * 86400
1118            + (t->tm_year - 70) * 31536000
1119            + ((t->tm_year - 69) / 4) * 86400
1120            - ((t->tm_year - 1) / 100) * 86400
1121            + ((t->tm_year + 299) / 400) * 86400);
1122#endif
1123}
1124
1125static time_t
1126parse_time(const char *p, size_t n)
1127{
1128	struct tm tm;
1129	time_t t = 0;
1130	int64_t data;
1131
1132	memset(&tm, 0, sizeof(tm));
1133	if (n != 20)
1134		return (t);
1135	data = atol10(p, 4);
1136	if (data < 1900)
1137		return (t);
1138	tm.tm_year = (int)data - 1900;
1139	p += 4;
1140	if (*p++ != '-')
1141		return (t);
1142	data = atol10(p, 2);
1143	if (data < 1 || data > 12)
1144		return (t);
1145	tm.tm_mon = (int)data -1;
1146	p += 2;
1147	if (*p++ != '-')
1148		return (t);
1149	data = atol10(p, 2);
1150	if (data < 1 || data > 31)
1151		return (t);
1152	tm.tm_mday = (int)data;
1153	p += 2;
1154	if (*p++ != 'T')
1155		return (t);
1156	data = atol10(p, 2);
1157	if (data < 0 || data > 23)
1158		return (t);
1159	tm.tm_hour = (int)data;
1160	p += 2;
1161	if (*p++ != ':')
1162		return (t);
1163	data = atol10(p, 2);
1164	if (data < 0 || data > 59)
1165		return (t);
1166	tm.tm_min = (int)data;
1167	p += 2;
1168	if (*p++ != ':')
1169		return (t);
1170	data = atol10(p, 2);
1171	if (data < 0 || data > 60)
1172		return (t);
1173	tm.tm_sec = (int)data;
1174#if 0
1175	p += 2;
1176	if (*p != 'Z')
1177		return (t);
1178#endif
1179
1180	t = time_from_tm(&tm);
1181
1182	return (t);
1183}
1184
1185static int
1186heap_add_entry(struct archive_read *a,
1187    struct heap_queue *heap, struct xar_file *file)
1188{
1189	uint64_t file_id, parent_id;
1190	int hole, parent;
1191
1192	/* Expand our pending files list as necessary. */
1193	if (heap->used >= heap->allocated) {
1194		struct xar_file **new_pending_files;
1195		int new_size = heap->allocated * 2;
1196
1197		if (heap->allocated < 1024)
1198			new_size = 1024;
1199		/* Overflow might keep us from growing the list. */
1200		if (new_size <= heap->allocated) {
1201			archive_set_error(&a->archive,
1202			    ENOMEM, "Out of memory");
1203			return (ARCHIVE_FATAL);
1204		}
1205		new_pending_files = (struct xar_file **)
1206		    malloc(new_size * sizeof(new_pending_files[0]));
1207		if (new_pending_files == NULL) {
1208			archive_set_error(&a->archive,
1209			    ENOMEM, "Out of memory");
1210			return (ARCHIVE_FATAL);
1211		}
1212		memcpy(new_pending_files, heap->files,
1213		    heap->allocated * sizeof(new_pending_files[0]));
1214		if (heap->files != NULL)
1215			free(heap->files);
1216		heap->files = new_pending_files;
1217		heap->allocated = new_size;
1218	}
1219
1220	file_id = file->id;
1221
1222	/*
1223	 * Start with hole at end, walk it up tree to find insertion point.
1224	 */
1225	hole = heap->used++;
1226	while (hole > 0) {
1227		parent = (hole - 1)/2;
1228		parent_id = heap->files[parent]->id;
1229		if (file_id >= parent_id) {
1230			heap->files[hole] = file;
1231			return (ARCHIVE_OK);
1232		}
1233		/* Move parent into hole <==> move hole up tree. */
1234		heap->files[hole] = heap->files[parent];
1235		hole = parent;
1236	}
1237	heap->files[0] = file;
1238
1239	return (ARCHIVE_OK);
1240}
1241
1242static struct xar_file *
1243heap_get_entry(struct heap_queue *heap)
1244{
1245	uint64_t a_id, b_id, c_id;
1246	int a, b, c;
1247	struct xar_file *r, *tmp;
1248
1249	if (heap->used < 1)
1250		return (NULL);
1251
1252	/*
1253	 * The first file in the list is the earliest; we'll return this.
1254	 */
1255	r = heap->files[0];
1256
1257	/*
1258	 * Move the last item in the heap to the root of the tree
1259	 */
1260	heap->files[0] = heap->files[--(heap->used)];
1261
1262	/*
1263	 * Rebalance the heap.
1264	 */
1265	a = 0; /* Starting element and its heap key */
1266	a_id = heap->files[a]->id;
1267	for (;;) {
1268		b = a + a + 1; /* First child */
1269		if (b >= heap->used)
1270			return (r);
1271		b_id = heap->files[b]->id;
1272		c = b + 1; /* Use second child if it is smaller. */
1273		if (c < heap->used) {
1274			c_id = heap->files[c]->id;
1275			if (c_id < b_id) {
1276				b = c;
1277				b_id = c_id;
1278			}
1279		}
1280		if (a_id <= b_id)
1281			return (r);
1282		tmp = heap->files[a];
1283		heap->files[a] = heap->files[b];
1284		heap->files[b] = tmp;
1285		a = b;
1286	}
1287}
1288
1289static int
1290add_link(struct archive_read *a, struct xar *xar, struct xar_file *file)
1291{
1292	struct hdlink *hdlink;
1293
1294	for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) {
1295		if (hdlink->id == file->link) {
1296			file->hdnext = hdlink->files;
1297			hdlink->cnt++;
1298			hdlink->files = file;
1299			return (ARCHIVE_OK);
1300		}
1301	}
1302	hdlink = malloc(sizeof(*hdlink));
1303	if (hdlink == NULL) {
1304		archive_set_error(&a->archive, ENOMEM, "Out of memory");
1305		return (ARCHIVE_FATAL);
1306	}
1307	file->hdnext = NULL;
1308	hdlink->id = file->link;
1309	hdlink->cnt = 1;
1310	hdlink->files = file;
1311	hdlink->next = xar->hdlink_list;
1312	xar->hdlink_list = hdlink;
1313	return (ARCHIVE_OK);
1314}
1315
1316static void
1317_checksum_init(struct chksumwork *sumwrk, int sum_alg)
1318{
1319	sumwrk->alg = sum_alg;
1320	switch (sum_alg) {
1321	case CKSUM_NONE:
1322		break;
1323	case CKSUM_SHA1:
1324		archive_sha1_init(&(sumwrk->sha1ctx));
1325		break;
1326	case CKSUM_MD5:
1327		archive_md5_init(&(sumwrk->md5ctx));
1328		break;
1329	}
1330}
1331
1332static void
1333_checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
1334{
1335
1336	switch (sumwrk->alg) {
1337	case CKSUM_NONE:
1338		break;
1339	case CKSUM_SHA1:
1340		archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
1341		break;
1342	case CKSUM_MD5:
1343		archive_md5_update(&(sumwrk->md5ctx), buff, size);
1344		break;
1345	}
1346}
1347
1348static int
1349_checksum_final(struct chksumwork *sumwrk, const void *val, size_t len)
1350{
1351	unsigned char sum[MAX_SUM_SIZE];
1352	int r = ARCHIVE_OK;
1353
1354	switch (sumwrk->alg) {
1355	case CKSUM_NONE:
1356		break;
1357	case CKSUM_SHA1:
1358		archive_sha1_final(&(sumwrk->sha1ctx), sum);
1359		if (len != SHA1_SIZE ||
1360		    memcmp(val, sum, SHA1_SIZE) != 0)
1361			r = ARCHIVE_FAILED;
1362		break;
1363	case CKSUM_MD5:
1364		archive_md5_final(&(sumwrk->md5ctx), sum);
1365		if (len != MD5_SIZE ||
1366		    memcmp(val, sum, MD5_SIZE) != 0)
1367			r = ARCHIVE_FAILED;
1368		break;
1369	}
1370	return (r);
1371}
1372
1373static void
1374checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg)
1375{
1376	struct xar *xar;
1377
1378	xar = (struct xar *)(a->format->data);
1379	_checksum_init(&(xar->a_sumwrk), a_sum_alg);
1380	_checksum_init(&(xar->e_sumwrk), e_sum_alg);
1381}
1382
1383static void
1384checksum_update(struct archive_read *a, const void *abuff, size_t asize,
1385    const void *ebuff, size_t esize)
1386{
1387	struct xar *xar;
1388
1389	xar = (struct xar *)(a->format->data);
1390	_checksum_update(&(xar->a_sumwrk), abuff, asize);
1391	_checksum_update(&(xar->e_sumwrk), ebuff, esize);
1392}
1393
1394static int
1395checksum_final(struct archive_read *a, const void *a_sum_val,
1396    size_t a_sum_len, const void *e_sum_val, size_t e_sum_len)
1397{
1398	struct xar *xar;
1399	int r;
1400
1401	xar = (struct xar *)(a->format->data);
1402	r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len);
1403	if (r == ARCHIVE_OK)
1404		r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len);
1405	if (r != ARCHIVE_OK)
1406		archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
1407		    "Sumcheck error");
1408	return (r);
1409}
1410
1411static int
1412decompression_init(struct archive_read *a, enum enctype encoding)
1413{
1414	struct xar *xar;
1415	const char *detail;
1416	int r;
1417
1418	xar = (struct xar *)(a->format->data);
1419	xar->rd_encoding = encoding;
1420	switch (encoding) {
1421	case NONE:
1422		break;
1423	case GZIP:
1424		if (xar->stream_valid)
1425			r = inflateReset(&(xar->stream));
1426		else
1427			r = inflateInit(&(xar->stream));
1428		if (r != Z_OK) {
1429			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1430			    "Couldn't initialize zlib stream.");
1431			return (ARCHIVE_FATAL);
1432		}
1433		xar->stream_valid = 1;
1434		xar->stream.total_in = 0;
1435		xar->stream.total_out = 0;
1436		break;
1437#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1438	case BZIP2:
1439		if (xar->bzstream_valid) {
1440			BZ2_bzDecompressEnd(&(xar->bzstream));
1441			xar->bzstream_valid = 0;
1442		}
1443		r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0);
1444		if (r == BZ_MEM_ERROR)
1445			r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1);
1446		if (r != BZ_OK) {
1447			int err = ARCHIVE_ERRNO_MISC;
1448			detail = NULL;
1449			switch (r) {
1450			case BZ_PARAM_ERROR:
1451				detail = "invalid setup parameter";
1452				break;
1453			case BZ_MEM_ERROR:
1454				err = ENOMEM;
1455				detail = "out of memory";
1456				break;
1457			case BZ_CONFIG_ERROR:
1458				detail = "mis-compiled library";
1459				break;
1460			}
1461			archive_set_error(&a->archive, err,
1462			    "Internal error initializing decompressor: %s",
1463			    detail == NULL ? "??" : detail);
1464			xar->bzstream_valid = 0;
1465			return (ARCHIVE_FATAL);
1466		}
1467		xar->bzstream_valid = 1;
1468		xar->bzstream.total_in_lo32 = 0;
1469		xar->bzstream.total_in_hi32 = 0;
1470		xar->bzstream.total_out_lo32 = 0;
1471		xar->bzstream.total_out_hi32 = 0;
1472		break;
1473#endif
1474#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1475#if LZMA_VERSION_MAJOR >= 5
1476/* Effectively disable the limiter. */
1477#define LZMA_MEMLIMIT   UINT64_MAX
1478#else
1479/* NOTE: This needs to check memory size which running system has. */
1480#define LZMA_MEMLIMIT   (1U << 30)
1481#endif
1482	case XZ:
1483	case LZMA:
1484		if (xar->lzstream_valid) {
1485			lzma_end(&(xar->lzstream));
1486			xar->lzstream_valid = 0;
1487		}
1488		if (xar->entry_encoding == XZ)
1489			r = lzma_stream_decoder(&(xar->lzstream),
1490			    LZMA_MEMLIMIT,/* memlimit */
1491			    LZMA_CONCATENATED);
1492		else
1493			r = lzma_alone_decoder(&(xar->lzstream),
1494			    LZMA_MEMLIMIT);/* memlimit */
1495		if (r != LZMA_OK) {
1496			switch (r) {
1497			case LZMA_MEM_ERROR:
1498				archive_set_error(&a->archive,
1499				    ENOMEM,
1500				    "Internal error initializing "
1501				    "compression library: "
1502				    "Cannot allocate memory");
1503				break;
1504			case LZMA_OPTIONS_ERROR:
1505				archive_set_error(&a->archive,
1506				    ARCHIVE_ERRNO_MISC,
1507				    "Internal error initializing "
1508				    "compression library: "
1509				    "Invalid or unsupported options");
1510				break;
1511			default:
1512				archive_set_error(&a->archive,
1513				    ARCHIVE_ERRNO_MISC,
1514				    "Internal error initializing "
1515				    "lzma library");
1516				break;
1517			}
1518			return (ARCHIVE_FATAL);
1519		}
1520		xar->lzstream_valid = 1;
1521		xar->lzstream.total_in = 0;
1522		xar->lzstream.total_out = 0;
1523		break;
1524#endif
1525	/*
1526	 * Unsupported compression.
1527	 */
1528	default:
1529#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1530	case BZIP2:
1531#endif
1532#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1533	case LZMA:
1534	case XZ:
1535#endif
1536		switch (xar->entry_encoding) {
1537		case BZIP2: detail = "bzip2"; break;
1538		case LZMA: detail = "lzma"; break;
1539		case XZ: detail = "xz"; break;
1540		default: detail = "??"; break;
1541		}
1542		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1543		    "%s compression not supported on this platform",
1544		    detail);
1545		return (ARCHIVE_FAILED);
1546	}
1547	return (ARCHIVE_OK);
1548}
1549
1550static int
1551decompress(struct archive_read *a, const void **buff, size_t *outbytes,
1552    const void *b, size_t *used)
1553{
1554	struct xar *xar;
1555	void *outbuff;
1556	size_t avail_in, avail_out;
1557	int r;
1558
1559	xar = (struct xar *)(a->format->data);
1560	avail_in = *used;
1561	outbuff = (void *)(uintptr_t)*buff;
1562	if (outbuff == NULL) {
1563		if (xar->outbuff == NULL) {
1564			xar->outbuff = malloc(OUTBUFF_SIZE);
1565			if (xar->outbuff == NULL) {
1566				archive_set_error(&a->archive, ENOMEM,
1567				    "Couldn't allocate memory for out buffer");
1568				return (ARCHIVE_FATAL);
1569			}
1570		}
1571		outbuff = xar->outbuff;
1572		*buff = outbuff;
1573		avail_out = OUTBUFF_SIZE;
1574	} else
1575		avail_out = *outbytes;
1576	switch (xar->rd_encoding) {
1577	case GZIP:
1578		xar->stream.next_in = (Bytef *)(uintptr_t)b;
1579		xar->stream.avail_in = avail_in;
1580		xar->stream.next_out = (unsigned char *)outbuff;
1581		xar->stream.avail_out = avail_out;
1582		r = inflate(&(xar->stream), 0);
1583		switch (r) {
1584		case Z_OK: /* Decompressor made some progress.*/
1585		case Z_STREAM_END: /* Found end of stream. */
1586			break;
1587		default:
1588			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1589			    "File decompression failed (%d)", r);
1590			return (ARCHIVE_FATAL);
1591		}
1592		*used = avail_in - xar->stream.avail_in;
1593		*outbytes = avail_out - xar->stream.avail_out;
1594		break;
1595#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1596	case BZIP2:
1597		xar->bzstream.next_in = (char *)(uintptr_t)b;
1598		xar->bzstream.avail_in = avail_in;
1599		xar->bzstream.next_out = (char *)outbuff;
1600		xar->bzstream.avail_out = avail_out;
1601		r = BZ2_bzDecompress(&(xar->bzstream));
1602		switch (r) {
1603		case BZ_STREAM_END: /* Found end of stream. */
1604			switch (BZ2_bzDecompressEnd(&(xar->bzstream))) {
1605			case BZ_OK:
1606				break;
1607			default:
1608				archive_set_error(&(a->archive),
1609				    ARCHIVE_ERRNO_MISC,
1610				    "Failed to clean up decompressor");
1611				return (ARCHIVE_FATAL);
1612			}
1613			xar->bzstream_valid = 0;
1614			/* FALLTHROUGH */
1615		case BZ_OK: /* Decompressor made some progress. */
1616			break;
1617		default:
1618			archive_set_error(&(a->archive),
1619			    ARCHIVE_ERRNO_MISC,
1620			    "bzip decompression failed");
1621			return (ARCHIVE_FATAL);
1622		}
1623		*used = avail_in - xar->bzstream.avail_in;
1624		*outbytes = avail_out - xar->bzstream.avail_out;
1625		break;
1626#endif
1627#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1628	case LZMA:
1629	case XZ:
1630		xar->lzstream.next_in = b;
1631		xar->lzstream.avail_in = avail_in;
1632		xar->lzstream.next_out = (unsigned char *)outbuff;
1633		xar->lzstream.avail_out = avail_out;
1634		r = lzma_code(&(xar->lzstream), LZMA_RUN);
1635		switch (r) {
1636		case LZMA_STREAM_END: /* Found end of stream. */
1637			lzma_end(&(xar->lzstream));
1638			xar->lzstream_valid = 0;
1639			/* FALLTHROUGH */
1640		case LZMA_OK: /* Decompressor made some progress. */
1641			break;
1642		default:
1643			archive_set_error(&(a->archive),
1644			    ARCHIVE_ERRNO_MISC,
1645			    "%s decompression failed(%d)",
1646			    (xar->entry_encoding == XZ)?"xz":"lzma",
1647			    r);
1648			return (ARCHIVE_FATAL);
1649		}
1650		*used = avail_in - xar->lzstream.avail_in;
1651		*outbytes = avail_out - xar->lzstream.avail_out;
1652		break;
1653#endif
1654#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1655	case BZIP2:
1656#endif
1657#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1658	case LZMA:
1659	case XZ:
1660#endif
1661	case NONE:
1662	default:
1663		if (outbuff == xar->outbuff) {
1664			*buff = b;
1665			*used = avail_in;
1666			*outbytes = avail_in;
1667		} else {
1668			if (avail_out > avail_in)
1669				avail_out = avail_in;
1670			memcpy(outbuff, b, avail_out);
1671			*used = avail_out;
1672			*outbytes = avail_out;
1673		}
1674		break;
1675	}
1676	return (ARCHIVE_OK);
1677}
1678
1679static int
1680decompression_cleanup(struct archive_read *a)
1681{
1682	struct xar *xar;
1683	int r;
1684
1685	xar = (struct xar *)(a->format->data);
1686	r = ARCHIVE_OK;
1687	if (xar->stream_valid) {
1688		if (inflateEnd(&(xar->stream)) != Z_OK) {
1689			archive_set_error(&a->archive,
1690			    ARCHIVE_ERRNO_MISC,
1691			    "Failed to clean up zlib decompressor");
1692			r = ARCHIVE_FATAL;
1693		}
1694	}
1695#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1696	if (xar->bzstream_valid) {
1697		if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) {
1698			archive_set_error(&a->archive,
1699			    ARCHIVE_ERRNO_MISC,
1700			    "Failed to clean up bzip2 decompressor");
1701			r = ARCHIVE_FATAL;
1702		}
1703	}
1704#endif
1705#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1706	if (xar->lzstream_valid)
1707		lzma_end(&(xar->lzstream));
1708#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1709	if (xar->lzstream_valid) {
1710		if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) {
1711			archive_set_error(&a->archive,
1712			    ARCHIVE_ERRNO_MISC,
1713			    "Failed to clean up lzmadec decompressor");
1714			r = ARCHIVE_FATAL;
1715		}
1716	}
1717#endif
1718	return (r);
1719}
1720
1721static void
1722xmlattr_cleanup(struct xmlattr_list *list)
1723{
1724	struct xmlattr *attr, *next;
1725
1726	attr = list->first;
1727	while (attr != NULL) {
1728		next = attr->next;
1729		free(attr->name);
1730		free(attr->value);
1731		free(attr);
1732		attr = next;
1733	}
1734	list->first = NULL;
1735	list->last = &(list->first);
1736}
1737
1738static int
1739file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
1740{
1741	struct xar_file *file;
1742	struct xmlattr *attr;
1743
1744	file = calloc(1, sizeof(*file));
1745	if (file == NULL) {
1746		archive_set_error(&a->archive, ENOMEM, "Out of memory");
1747		return (ARCHIVE_FATAL);
1748	}
1749	file->parent = xar->file;
1750	file->mode = 0777 | AE_IFREG;
1751	file->atime = time(NULL);
1752	file->mtime = time(NULL);
1753	xar->file = file;
1754	xar->xattr = NULL;
1755	for (attr = list->first; attr != NULL; attr = attr->next) {
1756		if (strcmp(attr->name, "id") == 0)
1757			file->id = atol10(attr->value, strlen(attr->value));
1758	}
1759	file->nlink = 1;
1760	if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK)
1761		return (ARCHIVE_FATAL);
1762	return (ARCHIVE_OK);
1763}
1764
1765static void
1766file_free(struct xar_file *file)
1767{
1768	struct xattr *xattr;
1769
1770	archive_string_free(&(file->pathname));
1771	archive_string_free(&(file->symlink));
1772	archive_string_free(&(file->uname));
1773	archive_string_free(&(file->gname));
1774	archive_string_free(&(file->hardlink));
1775	xattr = file->xattr_list;
1776	while (xattr != NULL) {
1777		struct xattr *next;
1778
1779		next = xattr->next;
1780		xattr_free(xattr);
1781		xattr = next;
1782	}
1783
1784	free(file);
1785}
1786
1787static int
1788xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list)
1789{
1790	struct xattr *xattr, **nx;
1791	struct xmlattr *attr;
1792
1793	xattr = calloc(1, sizeof(*xattr));
1794	if (xattr == NULL) {
1795		archive_set_error(&a->archive, ENOMEM, "Out of memory");
1796		return (ARCHIVE_FATAL);
1797	}
1798	xar->xattr = xattr;
1799	for (attr = list->first; attr != NULL; attr = attr->next) {
1800		if (strcmp(attr->name, "id") == 0)
1801			xattr->id = atol10(attr->value, strlen(attr->value));
1802	}
1803	/* Chain to xattr list. */
1804	for (nx = &(xar->file->xattr_list);
1805	    *nx != NULL; nx = &((*nx)->next)) {
1806		if (xattr->id < (*nx)->id)
1807			break;
1808	}
1809	xattr->next = *nx;
1810	*nx = xattr;
1811
1812	return (ARCHIVE_OK);
1813}
1814
1815static void
1816xattr_free(struct xattr *xattr)
1817{
1818	archive_string_free(&(xattr->name));
1819	free(xattr);
1820}
1821
1822static int
1823getencoding(struct xmlattr_list *list)
1824{
1825	struct xmlattr *attr;
1826	enum enctype encoding = NONE;
1827
1828	for (attr = list->first; attr != NULL; attr = attr->next) {
1829		if (strcmp(attr->name, "style") == 0) {
1830			if (strcmp(attr->value, "application/octet-stream") == 0)
1831				encoding = NONE;
1832			else if (strcmp(attr->value, "application/x-gzip") == 0)
1833				encoding = GZIP;
1834			else if (strcmp(attr->value, "application/x-bzip2") == 0)
1835				encoding = BZIP2;
1836			else if (strcmp(attr->value, "application/x-lzma") == 0)
1837				encoding = LZMA;
1838			else if (strcmp(attr->value, "application/x-xz") == 0)
1839				encoding = XZ;
1840		}
1841	}
1842	return (encoding);
1843}
1844
1845static int
1846getsumalgorithm(struct xmlattr_list *list)
1847{
1848	struct xmlattr *attr;
1849	int alg = CKSUM_NONE;
1850
1851	for (attr = list->first; attr != NULL; attr = attr->next) {
1852		if (strcmp(attr->name, "style") == 0) {
1853			const char *v = attr->value;
1854			if ((v[0] == 'S' || v[0] == 's') &&
1855			    (v[1] == 'H' || v[1] == 'h') &&
1856			    (v[2] == 'A' || v[2] == 'a') &&
1857			    v[3] == '1' && v[4] == '\0')
1858				alg = CKSUM_SHA1;
1859			if ((v[0] == 'M' || v[0] == 'm') &&
1860			    (v[1] == 'D' || v[1] == 'd') &&
1861			    v[2] == '5' && v[3] == '\0')
1862				alg = CKSUM_MD5;
1863		}
1864	}
1865	return (alg);
1866}
1867
1868static int
1869unknowntag_start(struct archive_read *a, struct xar *xar, const char *name)
1870{
1871	struct unknown_tag *tag;
1872
1873	tag = malloc(sizeof(*tag));
1874	if (tag == NULL) {
1875		archive_set_error(&a->archive, ENOMEM, "Out of memory");
1876		return (ARCHIVE_FATAL);
1877	}
1878	tag->next = xar->unknowntags;
1879	archive_string_init(&(tag->name));
1880	archive_strcpy(&(tag->name), name);
1881	if (xar->unknowntags == NULL) {
1882#if DEBUG
1883		fprintf(stderr, "UNKNOWNTAG_START:%s\n", name);
1884#endif
1885		xar->xmlsts_unknown = xar->xmlsts;
1886		xar->xmlsts = UNKNOWN;
1887	}
1888	xar->unknowntags = tag;
1889	return (ARCHIVE_OK);
1890}
1891
1892static void
1893unknowntag_end(struct xar *xar, const char *name)
1894{
1895	struct unknown_tag *tag;
1896
1897	tag = xar->unknowntags;
1898	if (tag == NULL || name == NULL)
1899		return;
1900	if (strcmp(tag->name.s, name) == 0) {
1901		xar->unknowntags = tag->next;
1902		archive_string_free(&(tag->name));
1903		free(tag);
1904		if (xar->unknowntags == NULL) {
1905#if DEBUG
1906			fprintf(stderr, "UNKNOWNTAG_END:%s\n", name);
1907#endif
1908			xar->xmlsts = xar->xmlsts_unknown;
1909		}
1910	}
1911}
1912
1913static int
1914xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list)
1915{
1916	struct xar *xar;
1917	struct xmlattr *attr;
1918
1919	xar = (struct xar *)(a->format->data);
1920
1921#if DEBUG
1922	fprintf(stderr, "xml_sta:[%s]\n", name);
1923	for (attr = list->first; attr != NULL; attr = attr->next)
1924		fprintf(stderr, "    attr:\"%s\"=\"%s\"\n",
1925		    attr->name, attr->value);
1926#endif
1927	xar->base64text = 0;
1928	switch (xar->xmlsts) {
1929	case INIT:
1930		if (strcmp(name, "xar") == 0)
1931			xar->xmlsts = XAR;
1932		else
1933			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
1934				return (ARCHIVE_FATAL);
1935		break;
1936	case XAR:
1937		if (strcmp(name, "toc") == 0)
1938			xar->xmlsts = TOC;
1939		else
1940			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
1941				return (ARCHIVE_FATAL);
1942		break;
1943	case TOC:
1944		if (strcmp(name, "creation-time") == 0)
1945			xar->xmlsts = TOC_CREATION_TIME;
1946		else if (strcmp(name, "checksum") == 0)
1947			xar->xmlsts = TOC_CHECKSUM;
1948		else if (strcmp(name, "file") == 0) {
1949			if (file_new(a, xar, list) != ARCHIVE_OK)
1950				return (ARCHIVE_FATAL);
1951			xar->xmlsts = TOC_FILE;
1952		}
1953		else
1954			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
1955				return (ARCHIVE_FATAL);
1956		break;
1957	case TOC_CHECKSUM:
1958		if (strcmp(name, "offset") == 0)
1959			xar->xmlsts = TOC_CHECKSUM_OFFSET;
1960		else if (strcmp(name, "size") == 0)
1961			xar->xmlsts = TOC_CHECKSUM_SIZE;
1962		else
1963			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
1964				return (ARCHIVE_FATAL);
1965		break;
1966	case TOC_FILE:
1967		if (strcmp(name, "file") == 0) {
1968			if (file_new(a, xar, list) != ARCHIVE_OK)
1969				return (ARCHIVE_FATAL);
1970		}
1971		else if (strcmp(name, "data") == 0)
1972			xar->xmlsts = FILE_DATA;
1973		else if (strcmp(name, "ea") == 0) {
1974			if (xattr_new(a, xar, list) != ARCHIVE_OK)
1975				return (ARCHIVE_FATAL);
1976			xar->xmlsts = FILE_EA;
1977		}
1978		else if (strcmp(name, "ctime") == 0)
1979			xar->xmlsts = FILE_CTIME;
1980		else if (strcmp(name, "mtime") == 0)
1981			xar->xmlsts = FILE_MTIME;
1982		else if (strcmp(name, "atime") == 0)
1983			xar->xmlsts = FILE_ATIME;
1984		else if (strcmp(name, "group") == 0)
1985			xar->xmlsts = FILE_GROUP;
1986		else if (strcmp(name, "gid") == 0)
1987			xar->xmlsts = FILE_GID;
1988		else if (strcmp(name, "user") == 0)
1989			xar->xmlsts = FILE_USER;
1990		else if (strcmp(name, "uid") == 0)
1991			xar->xmlsts = FILE_UID;
1992		else if (strcmp(name, "mode") == 0)
1993			xar->xmlsts = FILE_MODE;
1994		else if (strcmp(name, "device") == 0)
1995			xar->xmlsts = FILE_DEVICE;
1996		else if (strcmp(name, "deviceno") == 0)
1997			xar->xmlsts = FILE_DEVICENO;
1998		else if (strcmp(name, "inode") == 0)
1999			xar->xmlsts = FILE_INODE;
2000		else if (strcmp(name, "link") == 0)
2001			xar->xmlsts = FILE_LINK;
2002		else if (strcmp(name, "type") == 0) {
2003			xar->xmlsts = FILE_TYPE;
2004			for (attr = list->first; attr != NULL;
2005			    attr = attr->next) {
2006				if (strcmp(attr->name, "link") != 0)
2007					continue;
2008				if (strcmp(attr->value, "original") == 0) {
2009					xar->file->hdnext = xar->hdlink_orgs;
2010					xar->hdlink_orgs = xar->file;
2011				} else {
2012					xar->file->link = (unsigned)atol10(attr->value,
2013					    strlen(attr->value));
2014					if (xar->file->link > 0)
2015						if (add_link(a, xar, xar->file) != ARCHIVE_OK) {
2016							return (ARCHIVE_FATAL);
2017						};
2018				}
2019			}
2020		}
2021		else if (strcmp(name, "name") == 0) {
2022			xar->xmlsts = FILE_NAME;
2023			for (attr = list->first; attr != NULL;
2024			    attr = attr->next) {
2025				if (strcmp(attr->name, "enctype") == 0 &&
2026				    strcmp(attr->value, "base64") == 0)
2027					xar->base64text = 1;
2028			}
2029		}
2030		else if (strcmp(name, "acl") == 0)
2031			xar->xmlsts = FILE_ACL;
2032		else if (strcmp(name, "flags") == 0)
2033			xar->xmlsts = FILE_FLAGS;
2034		else if (strcmp(name, "ext2") == 0)
2035			xar->xmlsts = FILE_EXT2;
2036		else
2037			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2038				return (ARCHIVE_FATAL);
2039		break;
2040	case FILE_DATA:
2041		if (strcmp(name, "length") == 0)
2042			xar->xmlsts = FILE_DATA_LENGTH;
2043		else if (strcmp(name, "offset") == 0)
2044			xar->xmlsts = FILE_DATA_OFFSET;
2045		else if (strcmp(name, "size") == 0)
2046			xar->xmlsts = FILE_DATA_SIZE;
2047		else if (strcmp(name, "encoding") == 0) {
2048			xar->xmlsts = FILE_DATA_ENCODING;
2049			xar->file->encoding = getencoding(list);
2050		}
2051		else if (strcmp(name, "archived-checksum") == 0) {
2052			xar->xmlsts = FILE_DATA_A_CHECKSUM;
2053			xar->file->a_sum.alg = getsumalgorithm(list);
2054		}
2055		else if (strcmp(name, "extracted-checksum") == 0) {
2056			xar->xmlsts = FILE_DATA_E_CHECKSUM;
2057			xar->file->e_sum.alg = getsumalgorithm(list);
2058		}
2059		else if (strcmp(name, "content") == 0)
2060			xar->xmlsts = FILE_DATA_CONTENT;
2061		else
2062			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2063				return (ARCHIVE_FATAL);
2064		break;
2065	case FILE_DEVICE:
2066		if (strcmp(name, "major") == 0)
2067			xar->xmlsts = FILE_DEVICE_MAJOR;
2068		else if (strcmp(name, "minor") == 0)
2069			xar->xmlsts = FILE_DEVICE_MINOR;
2070		else
2071			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2072				return (ARCHIVE_FATAL);
2073		break;
2074	case FILE_DATA_CONTENT:
2075		if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2076			return (ARCHIVE_FATAL);
2077		break;
2078	case FILE_EA:
2079		if (strcmp(name, "length") == 0)
2080			xar->xmlsts = FILE_EA_LENGTH;
2081		else if (strcmp(name, "offset") == 0)
2082			xar->xmlsts = FILE_EA_OFFSET;
2083		else if (strcmp(name, "size") == 0)
2084			xar->xmlsts = FILE_EA_SIZE;
2085		else if (strcmp(name, "encoding") == 0) {
2086			xar->xmlsts = FILE_EA_ENCODING;
2087			xar->xattr->encoding = getencoding(list);
2088		} else if (strcmp(name, "archived-checksum") == 0)
2089			xar->xmlsts = FILE_EA_A_CHECKSUM;
2090		else if (strcmp(name, "extracted-checksum") == 0)
2091			xar->xmlsts = FILE_EA_E_CHECKSUM;
2092		else if (strcmp(name, "name") == 0)
2093			xar->xmlsts = FILE_EA_NAME;
2094		else if (strcmp(name, "fstype") == 0)
2095			xar->xmlsts = FILE_EA_FSTYPE;
2096		else
2097			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2098				return (ARCHIVE_FATAL);
2099		break;
2100	case FILE_ACL:
2101		if (strcmp(name, "appleextended") == 0)
2102			xar->xmlsts = FILE_ACL_APPLEEXTENDED;
2103		else if (strcmp(name, "default") == 0)
2104			xar->xmlsts = FILE_ACL_DEFAULT;
2105		else if (strcmp(name, "access") == 0)
2106			xar->xmlsts = FILE_ACL_ACCESS;
2107		else
2108			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2109				return (ARCHIVE_FATAL);
2110		break;
2111	case FILE_FLAGS:
2112		if (!xml_parse_file_flags(xar, name))
2113			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2114				return (ARCHIVE_FATAL);
2115		break;
2116	case FILE_EXT2:
2117		if (!xml_parse_file_ext2(xar, name))
2118			if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2119				return (ARCHIVE_FATAL);
2120		break;
2121	case TOC_CREATION_TIME:
2122	case TOC_CHECKSUM_OFFSET:
2123	case TOC_CHECKSUM_SIZE:
2124	case FILE_DATA_LENGTH:
2125	case FILE_DATA_OFFSET:
2126	case FILE_DATA_SIZE:
2127	case FILE_DATA_ENCODING:
2128	case FILE_DATA_A_CHECKSUM:
2129	case FILE_DATA_E_CHECKSUM:
2130	case FILE_EA_LENGTH:
2131	case FILE_EA_OFFSET:
2132	case FILE_EA_SIZE:
2133	case FILE_EA_ENCODING:
2134	case FILE_EA_A_CHECKSUM:
2135	case FILE_EA_E_CHECKSUM:
2136	case FILE_EA_NAME:
2137	case FILE_EA_FSTYPE:
2138	case FILE_CTIME:
2139	case FILE_MTIME:
2140	case FILE_ATIME:
2141	case FILE_GROUP:
2142	case FILE_GID:
2143	case FILE_USER:
2144	case FILE_UID:
2145	case FILE_INODE:
2146	case FILE_DEVICE_MAJOR:
2147	case FILE_DEVICE_MINOR:
2148	case FILE_DEVICENO:
2149	case FILE_MODE:
2150	case FILE_TYPE:
2151	case FILE_LINK:
2152	case FILE_NAME:
2153	case FILE_ACL_DEFAULT:
2154	case FILE_ACL_ACCESS:
2155	case FILE_ACL_APPLEEXTENDED:
2156	case FILE_FLAGS_USER_NODUMP:
2157	case FILE_FLAGS_USER_IMMUTABLE:
2158	case FILE_FLAGS_USER_APPEND:
2159	case FILE_FLAGS_USER_OPAQUE:
2160	case FILE_FLAGS_USER_NOUNLINK:
2161	case FILE_FLAGS_SYS_ARCHIVED:
2162	case FILE_FLAGS_SYS_IMMUTABLE:
2163	case FILE_FLAGS_SYS_APPEND:
2164	case FILE_FLAGS_SYS_NOUNLINK:
2165	case FILE_FLAGS_SYS_SNAPSHOT:
2166	case FILE_EXT2_SecureDeletion:
2167	case FILE_EXT2_Undelete:
2168	case FILE_EXT2_Compress:
2169	case FILE_EXT2_Synchronous:
2170	case FILE_EXT2_Immutable:
2171	case FILE_EXT2_AppendOnly:
2172	case FILE_EXT2_NoDump:
2173	case FILE_EXT2_NoAtime:
2174	case FILE_EXT2_CompDirty:
2175	case FILE_EXT2_CompBlock:
2176	case FILE_EXT2_NoCompBlock:
2177	case FILE_EXT2_CompError:
2178	case FILE_EXT2_BTree:
2179	case FILE_EXT2_HashIndexed:
2180	case FILE_EXT2_iMagic:
2181	case FILE_EXT2_Journaled:
2182	case FILE_EXT2_NoTail:
2183	case FILE_EXT2_DirSync:
2184	case FILE_EXT2_TopDir:
2185	case FILE_EXT2_Reserved:
2186	case UNKNOWN:
2187		if (unknowntag_start(a, xar, name) != ARCHIVE_OK)
2188			return (ARCHIVE_FATAL);
2189		break;
2190	}
2191	return (ARCHIVE_OK);
2192}
2193
2194static void
2195xml_end(void *userData, const char *name)
2196{
2197	struct archive_read *a;
2198	struct xar *xar;
2199
2200	a = (struct archive_read *)userData;
2201	xar = (struct xar *)(a->format->data);
2202
2203#if DEBUG
2204	fprintf(stderr, "xml_end:[%s]\n", name);
2205#endif
2206	switch (xar->xmlsts) {
2207	case INIT:
2208		break;
2209	case XAR:
2210		if (strcmp(name, "xar") == 0)
2211			xar->xmlsts = INIT;
2212		break;
2213	case TOC:
2214		if (strcmp(name, "toc") == 0)
2215			xar->xmlsts = XAR;
2216		break;
2217	case TOC_CREATION_TIME:
2218		if (strcmp(name, "creation-time") == 0)
2219			xar->xmlsts = TOC;
2220		break;
2221	case TOC_CHECKSUM:
2222		if (strcmp(name, "checksum") == 0)
2223			xar->xmlsts = TOC;
2224		break;
2225	case TOC_CHECKSUM_OFFSET:
2226		if (strcmp(name, "offset") == 0)
2227			xar->xmlsts = TOC_CHECKSUM;
2228		break;
2229	case TOC_CHECKSUM_SIZE:
2230		if (strcmp(name, "size") == 0)
2231			xar->xmlsts = TOC_CHECKSUM;
2232		break;
2233	case TOC_FILE:
2234		if (strcmp(name, "file") == 0) {
2235			if (xar->file->parent != NULL &&
2236			    ((xar->file->mode & AE_IFMT) == AE_IFDIR))
2237				xar->file->parent->subdirs++;
2238			xar->file = xar->file->parent;
2239			if (xar->file == NULL)
2240				xar->xmlsts = TOC;
2241		}
2242		break;
2243	case FILE_DATA:
2244		if (strcmp(name, "data") == 0)
2245			xar->xmlsts = TOC_FILE;
2246		break;
2247	case FILE_DATA_LENGTH:
2248		if (strcmp(name, "length") == 0)
2249			xar->xmlsts = FILE_DATA;
2250		break;
2251	case FILE_DATA_OFFSET:
2252		if (strcmp(name, "offset") == 0)
2253			xar->xmlsts = FILE_DATA;
2254		break;
2255	case FILE_DATA_SIZE:
2256		if (strcmp(name, "size") == 0)
2257			xar->xmlsts = FILE_DATA;
2258		break;
2259	case FILE_DATA_ENCODING:
2260		if (strcmp(name, "encoding") == 0)
2261			xar->xmlsts = FILE_DATA;
2262		break;
2263	case FILE_DATA_A_CHECKSUM:
2264		if (strcmp(name, "archived-checksum") == 0)
2265			xar->xmlsts = FILE_DATA;
2266		break;
2267	case FILE_DATA_E_CHECKSUM:
2268		if (strcmp(name, "extracted-checksum") == 0)
2269			xar->xmlsts = FILE_DATA;
2270		break;
2271	case FILE_DATA_CONTENT:
2272		if (strcmp(name, "content") == 0)
2273			xar->xmlsts = FILE_DATA;
2274		break;
2275	case FILE_EA:
2276		if (strcmp(name, "ea") == 0) {
2277			xar->xmlsts = TOC_FILE;
2278			xar->xattr = NULL;
2279		}
2280		break;
2281	case FILE_EA_LENGTH:
2282		if (strcmp(name, "length") == 0)
2283			xar->xmlsts = FILE_EA;
2284		break;
2285	case FILE_EA_OFFSET:
2286		if (strcmp(name, "offset") == 0)
2287			xar->xmlsts = FILE_EA;
2288		break;
2289	case FILE_EA_SIZE:
2290		if (strcmp(name, "size") == 0)
2291			xar->xmlsts = FILE_EA;
2292		break;
2293	case FILE_EA_ENCODING:
2294		if (strcmp(name, "encoding") == 0)
2295			xar->xmlsts = FILE_EA;
2296		break;
2297	case FILE_EA_A_CHECKSUM:
2298		if (strcmp(name, "archived-checksum") == 0)
2299			xar->xmlsts = FILE_EA;
2300		break;
2301	case FILE_EA_E_CHECKSUM:
2302		if (strcmp(name, "extracted-checksum") == 0)
2303			xar->xmlsts = FILE_EA;
2304		break;
2305	case FILE_EA_NAME:
2306		if (strcmp(name, "name") == 0)
2307			xar->xmlsts = FILE_EA;
2308		break;
2309	case FILE_EA_FSTYPE:
2310		if (strcmp(name, "fstype") == 0)
2311			xar->xmlsts = FILE_EA;
2312		break;
2313	case FILE_CTIME:
2314		if (strcmp(name, "ctime") == 0)
2315			xar->xmlsts = TOC_FILE;
2316		break;
2317	case FILE_MTIME:
2318		if (strcmp(name, "mtime") == 0)
2319			xar->xmlsts = TOC_FILE;
2320		break;
2321	case FILE_ATIME:
2322		if (strcmp(name, "atime") == 0)
2323			xar->xmlsts = TOC_FILE;
2324		break;
2325	case FILE_GROUP:
2326		if (strcmp(name, "group") == 0)
2327			xar->xmlsts = TOC_FILE;
2328		break;
2329	case FILE_GID:
2330		if (strcmp(name, "gid") == 0)
2331			xar->xmlsts = TOC_FILE;
2332		break;
2333	case FILE_USER:
2334		if (strcmp(name, "user") == 0)
2335			xar->xmlsts = TOC_FILE;
2336		break;
2337	case FILE_UID:
2338		if (strcmp(name, "uid") == 0)
2339			xar->xmlsts = TOC_FILE;
2340		break;
2341	case FILE_MODE:
2342		if (strcmp(name, "mode") == 0)
2343			xar->xmlsts = TOC_FILE;
2344		break;
2345	case FILE_DEVICE:
2346		if (strcmp(name, "device") == 0)
2347			xar->xmlsts = TOC_FILE;
2348		break;
2349	case FILE_DEVICE_MAJOR:
2350		if (strcmp(name, "major") == 0)
2351			xar->xmlsts = FILE_DEVICE;
2352		break;
2353	case FILE_DEVICE_MINOR:
2354		if (strcmp(name, "minor") == 0)
2355			xar->xmlsts = FILE_DEVICE;
2356		break;
2357	case FILE_DEVICENO:
2358		if (strcmp(name, "deviceno") == 0)
2359			xar->xmlsts = TOC_FILE;
2360		break;
2361	case FILE_INODE:
2362		if (strcmp(name, "inode") == 0)
2363			xar->xmlsts = TOC_FILE;
2364		break;
2365	case FILE_LINK:
2366		if (strcmp(name, "link") == 0)
2367			xar->xmlsts = TOC_FILE;
2368		break;
2369	case FILE_TYPE:
2370		if (strcmp(name, "type") == 0)
2371			xar->xmlsts = TOC_FILE;
2372		break;
2373	case FILE_NAME:
2374		if (strcmp(name, "name") == 0)
2375			xar->xmlsts = TOC_FILE;
2376		break;
2377	case FILE_ACL:
2378		if (strcmp(name, "acl") == 0)
2379			xar->xmlsts = TOC_FILE;
2380		break;
2381	case FILE_ACL_DEFAULT:
2382		if (strcmp(name, "default") == 0)
2383			xar->xmlsts = FILE_ACL;
2384		break;
2385	case FILE_ACL_ACCESS:
2386		if (strcmp(name, "access") == 0)
2387			xar->xmlsts = FILE_ACL;
2388		break;
2389	case FILE_ACL_APPLEEXTENDED:
2390		if (strcmp(name, "appleextended") == 0)
2391			xar->xmlsts = FILE_ACL;
2392		break;
2393	case FILE_FLAGS:
2394		if (strcmp(name, "flags") == 0)
2395			xar->xmlsts = TOC_FILE;
2396		break;
2397	case FILE_FLAGS_USER_NODUMP:
2398		if (strcmp(name, "UserNoDump") == 0)
2399			xar->xmlsts = FILE_FLAGS;
2400		break;
2401	case FILE_FLAGS_USER_IMMUTABLE:
2402		if (strcmp(name, "UserImmutable") == 0)
2403			xar->xmlsts = FILE_FLAGS;
2404		break;
2405	case FILE_FLAGS_USER_APPEND:
2406		if (strcmp(name, "UserAppend") == 0)
2407			xar->xmlsts = FILE_FLAGS;
2408		break;
2409	case FILE_FLAGS_USER_OPAQUE:
2410		if (strcmp(name, "UserOpaque") == 0)
2411			xar->xmlsts = FILE_FLAGS;
2412		break;
2413	case FILE_FLAGS_USER_NOUNLINK:
2414		if (strcmp(name, "UserNoUnlink") == 0)
2415			xar->xmlsts = FILE_FLAGS;
2416		break;
2417	case FILE_FLAGS_SYS_ARCHIVED:
2418		if (strcmp(name, "SystemArchived") == 0)
2419			xar->xmlsts = FILE_FLAGS;
2420		break;
2421	case FILE_FLAGS_SYS_IMMUTABLE:
2422		if (strcmp(name, "SystemImmutable") == 0)
2423			xar->xmlsts = FILE_FLAGS;
2424		break;
2425	case FILE_FLAGS_SYS_APPEND:
2426		if (strcmp(name, "SystemAppend") == 0)
2427			xar->xmlsts = FILE_FLAGS;
2428		break;
2429	case FILE_FLAGS_SYS_NOUNLINK:
2430		if (strcmp(name, "SystemNoUnlink") == 0)
2431			xar->xmlsts = FILE_FLAGS;
2432		break;
2433	case FILE_FLAGS_SYS_SNAPSHOT:
2434		if (strcmp(name, "SystemSnapshot") == 0)
2435			xar->xmlsts = FILE_FLAGS;
2436		break;
2437	case FILE_EXT2:
2438		if (strcmp(name, "ext2") == 0)
2439			xar->xmlsts = TOC_FILE;
2440		break;
2441	case FILE_EXT2_SecureDeletion:
2442		if (strcmp(name, "SecureDeletion") == 0)
2443			xar->xmlsts = FILE_EXT2;
2444		break;
2445	case FILE_EXT2_Undelete:
2446		if (strcmp(name, "Undelete") == 0)
2447			xar->xmlsts = FILE_EXT2;
2448		break;
2449	case FILE_EXT2_Compress:
2450		if (strcmp(name, "Compress") == 0)
2451			xar->xmlsts = FILE_EXT2;
2452		break;
2453	case FILE_EXT2_Synchronous:
2454		if (strcmp(name, "Synchronous") == 0)
2455			xar->xmlsts = FILE_EXT2;
2456		break;
2457	case FILE_EXT2_Immutable:
2458		if (strcmp(name, "Immutable") == 0)
2459			xar->xmlsts = FILE_EXT2;
2460		break;
2461	case FILE_EXT2_AppendOnly:
2462		if (strcmp(name, "AppendOnly") == 0)
2463			xar->xmlsts = FILE_EXT2;
2464		break;
2465	case FILE_EXT2_NoDump:
2466		if (strcmp(name, "NoDump") == 0)
2467			xar->xmlsts = FILE_EXT2;
2468		break;
2469	case FILE_EXT2_NoAtime:
2470		if (strcmp(name, "NoAtime") == 0)
2471			xar->xmlsts = FILE_EXT2;
2472		break;
2473	case FILE_EXT2_CompDirty:
2474		if (strcmp(name, "CompDirty") == 0)
2475			xar->xmlsts = FILE_EXT2;
2476		break;
2477	case FILE_EXT2_CompBlock:
2478		if (strcmp(name, "CompBlock") == 0)
2479			xar->xmlsts = FILE_EXT2;
2480		break;
2481	case FILE_EXT2_NoCompBlock:
2482		if (strcmp(name, "NoCompBlock") == 0)
2483			xar->xmlsts = FILE_EXT2;
2484		break;
2485	case FILE_EXT2_CompError:
2486		if (strcmp(name, "CompError") == 0)
2487			xar->xmlsts = FILE_EXT2;
2488		break;
2489	case FILE_EXT2_BTree:
2490		if (strcmp(name, "BTree") == 0)
2491			xar->xmlsts = FILE_EXT2;
2492		break;
2493	case FILE_EXT2_HashIndexed:
2494		if (strcmp(name, "HashIndexed") == 0)
2495			xar->xmlsts = FILE_EXT2;
2496		break;
2497	case FILE_EXT2_iMagic:
2498		if (strcmp(name, "iMagic") == 0)
2499			xar->xmlsts = FILE_EXT2;
2500		break;
2501	case FILE_EXT2_Journaled:
2502		if (strcmp(name, "Journaled") == 0)
2503			xar->xmlsts = FILE_EXT2;
2504		break;
2505	case FILE_EXT2_NoTail:
2506		if (strcmp(name, "NoTail") == 0)
2507			xar->xmlsts = FILE_EXT2;
2508		break;
2509	case FILE_EXT2_DirSync:
2510		if (strcmp(name, "DirSync") == 0)
2511			xar->xmlsts = FILE_EXT2;
2512		break;
2513	case FILE_EXT2_TopDir:
2514		if (strcmp(name, "TopDir") == 0)
2515			xar->xmlsts = FILE_EXT2;
2516		break;
2517	case FILE_EXT2_Reserved:
2518		if (strcmp(name, "Reserved") == 0)
2519			xar->xmlsts = FILE_EXT2;
2520		break;
2521	case UNKNOWN:
2522		unknowntag_end(xar, name);
2523		break;
2524	}
2525}
2526
2527static const int base64[256] = {
2528	-1, -1, -1, -1, -1, -1, -1, -1,
2529	-1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */
2530	-1, -1, -1, -1, -1, -1, -1, -1,
2531	-1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */
2532	-1, -1, -1, -1, -1, -1, -1, -1,
2533	-1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */
2534	52, 53, 54, 55, 56, 57, 58, 59,
2535	60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */
2536	-1,  0,  1,  2,  3,  4,  5,  6,
2537	 7,  8,  9, 10, 11, 12, 13, 14, /* 40 - 4F */
2538	15, 16, 17, 18, 19, 20, 21, 22,
2539	23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */
2540	-1, 26, 27, 28, 29, 30, 31, 32,
2541	33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
2542	41, 42, 43, 44, 45, 46, 47, 48,
2543	49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */
2544	-1, -1, -1, -1, -1, -1, -1, -1,
2545	-1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */
2546	-1, -1, -1, -1, -1, -1, -1, -1,
2547	-1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */
2548	-1, -1, -1, -1, -1, -1, -1, -1,
2549	-1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */
2550	-1, -1, -1, -1, -1, -1, -1, -1,
2551	-1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */
2552	-1, -1, -1, -1, -1, -1, -1, -1,
2553	-1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */
2554	-1, -1, -1, -1, -1, -1, -1, -1,
2555	-1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */
2556	-1, -1, -1, -1, -1, -1, -1, -1,
2557	-1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */
2558	-1, -1, -1, -1, -1, -1, -1, -1,
2559	-1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */
2560};
2561
2562static void
2563strappend_base64(struct xar *xar,
2564    struct archive_string *as, const char *s, size_t l)
2565{
2566	unsigned char buff[256];
2567	unsigned char *out;
2568	const unsigned char *b;
2569	size_t len;
2570
2571	(void)xar; /* UNUSED */
2572	len = 0;
2573	out = buff;
2574	b = (const unsigned char *)s;
2575	while (l > 0) {
2576		int n = 0;
2577
2578		if (l > 0) {
2579			if (base64[b[0]] < 0 || base64[b[1]] < 0)
2580				break;
2581			n = base64[*b++] << 18;
2582			n |= base64[*b++] << 12;
2583			*out++ = n >> 16;
2584			len++;
2585			l -= 2;
2586		}
2587		if (l > 0) {
2588			if (base64[*b] < 0)
2589				break;
2590			n |= base64[*b++] << 6;
2591			*out++ = (n >> 8) & 0xFF;
2592			len++;
2593			--l;
2594		}
2595		if (l > 0) {
2596			if (base64[*b] < 0)
2597				break;
2598			n |= base64[*b++];
2599			*out++ = n & 0xFF;
2600			len++;
2601			--l;
2602		}
2603		if (len+3 >= sizeof(buff)) {
2604			archive_strncat(as, (const char *)buff, len);
2605			len = 0;
2606			out = buff;
2607		}
2608	}
2609	if (len > 0)
2610		archive_strncat(as, (const char *)buff, len);
2611}
2612
2613static void
2614xml_data(void *userData, const char *s, int len)
2615{
2616	struct archive_read *a;
2617	struct xar *xar;
2618
2619	a = (struct archive_read *)userData;
2620	xar = (struct xar *)(a->format->data);
2621
2622#if DEBUG
2623	{
2624		char buff[1024];
2625		if (len > (int)(sizeof(buff)-1))
2626			len = (int)(sizeof(buff)-1);
2627		strncpy(buff, s, len);
2628		buff[len] = 0;
2629		fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff);
2630	}
2631#endif
2632	switch (xar->xmlsts) {
2633	case TOC_CHECKSUM_OFFSET:
2634		xar->toc_chksum_offset = atol10(s, len);
2635		break;
2636	case TOC_CHECKSUM_SIZE:
2637		xar->toc_chksum_size = atol10(s, len);
2638		break;
2639	default:
2640		break;
2641	}
2642	if (xar->file == NULL)
2643		return;
2644
2645	switch (xar->xmlsts) {
2646	case FILE_NAME:
2647		if (xar->file->parent != NULL) {
2648			archive_string_concat(&(xar->file->pathname),
2649			    &(xar->file->parent->pathname));
2650			archive_strappend_char(&(xar->file->pathname), '/');
2651		}
2652		xar->file->has |= HAS_PATHNAME;
2653		if (xar->base64text) {
2654			strappend_base64(xar,
2655			    &(xar->file->pathname), s, len);
2656		} else
2657			archive_strncat(&(xar->file->pathname), s, len);
2658		break;
2659	case FILE_LINK:
2660		xar->file->has |= HAS_SYMLINK;
2661		archive_strncpy(&(xar->file->symlink), s, len);
2662		break;
2663	case FILE_TYPE:
2664		if (strncmp("file", s, len) == 0 ||
2665		    strncmp("hardlink", s, len) == 0)
2666			xar->file->mode =
2667			    (xar->file->mode & ~AE_IFMT) | AE_IFREG;
2668		if (strncmp("directory", s, len) == 0)
2669			xar->file->mode =
2670			    (xar->file->mode & ~AE_IFMT) | AE_IFDIR;
2671		if (strncmp("symlink", s, len) == 0)
2672			xar->file->mode =
2673			    (xar->file->mode & ~AE_IFMT) | AE_IFLNK;
2674		if (strncmp("character special", s, len) == 0)
2675			xar->file->mode =
2676			    (xar->file->mode & ~AE_IFMT) | AE_IFCHR;
2677		if (strncmp("block special", s, len) == 0)
2678			xar->file->mode =
2679			    (xar->file->mode & ~AE_IFMT) | AE_IFBLK;
2680		if (strncmp("socket", s, len) == 0)
2681			xar->file->mode =
2682			    (xar->file->mode & ~AE_IFMT) | AE_IFSOCK;
2683		if (strncmp("fifo", s, len) == 0)
2684			xar->file->mode =
2685			    (xar->file->mode & ~AE_IFMT) | AE_IFIFO;
2686		xar->file->has |= HAS_TYPE;
2687		break;
2688	case FILE_INODE:
2689		xar->file->has |= HAS_INO;
2690		xar->file->ino64 = atol10(s, len);
2691		break;
2692	case FILE_DEVICE_MAJOR:
2693		xar->file->has |= HAS_DEVMAJOR;
2694		xar->file->devmajor = (dev_t)atol10(s, len);
2695		break;
2696	case FILE_DEVICE_MINOR:
2697		xar->file->has |= HAS_DEVMINOR;
2698		xar->file->devminor = (dev_t)atol10(s, len);
2699		break;
2700	case FILE_DEVICENO:
2701		xar->file->has |= HAS_DEV;
2702		xar->file->dev = (dev_t)atol10(s, len);
2703		break;
2704	case FILE_MODE:
2705		xar->file->has |= HAS_MODE;
2706		xar->file->mode =
2707		    (xar->file->mode & AE_IFMT) |
2708		    ((mode_t)(atol8(s, len)) & ~AE_IFMT);
2709		break;
2710	case FILE_GROUP:
2711		xar->file->has |= HAS_GID;
2712		archive_strncpy(&(xar->file->gname), s, len);
2713		break;
2714	case FILE_GID:
2715		xar->file->has |= HAS_GID;
2716		xar->file->gid = atol10(s, len);
2717		break;
2718	case FILE_USER:
2719		xar->file->has |= HAS_UID;
2720		archive_strncpy(&(xar->file->uname), s, len);
2721		break;
2722	case FILE_UID:
2723		xar->file->has |= HAS_UID;
2724		xar->file->uid = atol10(s, len);
2725		break;
2726	case FILE_CTIME:
2727		xar->file->has |= HAS_TIME;
2728		xar->file->ctime = parse_time(s, len);
2729		break;
2730	case FILE_MTIME:
2731		xar->file->has |= HAS_TIME;
2732		xar->file->mtime = parse_time(s, len);
2733		break;
2734	case FILE_ATIME:
2735		xar->file->has |= HAS_TIME;
2736		xar->file->atime = parse_time(s, len);
2737		break;
2738	case FILE_DATA_LENGTH:
2739		xar->file->has |= HAS_DATA;
2740		xar->file->length = atol10(s, len);
2741		break;
2742	case FILE_DATA_OFFSET:
2743		xar->file->has |= HAS_DATA;
2744		xar->file->offset = atol10(s, len);
2745		break;
2746	case FILE_DATA_SIZE:
2747		xar->file->has |= HAS_DATA;
2748		xar->file->size = atol10(s, len);
2749		break;
2750	case FILE_DATA_A_CHECKSUM:
2751		xar->file->a_sum.len = atohex(xar->file->a_sum.val,
2752		    sizeof(xar->file->a_sum.val), s, len);
2753		break;
2754	case FILE_DATA_E_CHECKSUM:
2755		xar->file->e_sum.len = atohex(xar->file->e_sum.val,
2756		    sizeof(xar->file->e_sum.val), s, len);
2757		break;
2758	case FILE_EA_LENGTH:
2759		xar->file->has |= HAS_XATTR;
2760		xar->xattr->length = atol10(s, len);
2761		break;
2762	case FILE_EA_OFFSET:
2763		xar->file->has |= HAS_XATTR;
2764		xar->xattr->offset = atol10(s, len);
2765		break;
2766	case FILE_EA_SIZE:
2767		xar->file->has |= HAS_XATTR;
2768		xar->xattr->size = atol10(s, len);
2769		break;
2770	case FILE_EA_A_CHECKSUM:
2771		xar->file->has |= HAS_XATTR;
2772		xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val,
2773		    sizeof(xar->xattr->a_sum.val), s, len);
2774		break;
2775	case FILE_EA_E_CHECKSUM:
2776		xar->file->has |= HAS_XATTR;
2777		xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val,
2778		    sizeof(xar->xattr->e_sum.val), s, len);
2779		break;
2780	case FILE_EA_NAME:
2781		xar->file->has |= HAS_XATTR;
2782		archive_strncpy(&(xar->xattr->name), s, len);
2783		break;
2784	case FILE_EA_FSTYPE:
2785		xar->file->has |= HAS_XATTR;
2786		archive_strncpy(&(xar->xattr->fstype), s, len);
2787		break;
2788		break;
2789	case FILE_ACL_DEFAULT:
2790	case FILE_ACL_ACCESS:
2791	case FILE_ACL_APPLEEXTENDED:
2792		xar->file->has |= HAS_ACL;
2793		/* TODO */
2794		break;
2795	case INIT:
2796	case XAR:
2797	case TOC:
2798	case TOC_CREATION_TIME:
2799	case TOC_CHECKSUM:
2800	case TOC_CHECKSUM_OFFSET:
2801	case TOC_CHECKSUM_SIZE:
2802	case TOC_FILE:
2803	case FILE_DATA:
2804	case FILE_DATA_ENCODING:
2805	case FILE_DATA_CONTENT:
2806	case FILE_DEVICE:
2807	case FILE_EA:
2808	case FILE_EA_ENCODING:
2809	case FILE_ACL:
2810	case FILE_FLAGS:
2811	case FILE_FLAGS_USER_NODUMP:
2812	case FILE_FLAGS_USER_IMMUTABLE:
2813	case FILE_FLAGS_USER_APPEND:
2814	case FILE_FLAGS_USER_OPAQUE:
2815	case FILE_FLAGS_USER_NOUNLINK:
2816	case FILE_FLAGS_SYS_ARCHIVED:
2817	case FILE_FLAGS_SYS_IMMUTABLE:
2818	case FILE_FLAGS_SYS_APPEND:
2819	case FILE_FLAGS_SYS_NOUNLINK:
2820	case FILE_FLAGS_SYS_SNAPSHOT:
2821	case FILE_EXT2:
2822	case FILE_EXT2_SecureDeletion:
2823	case FILE_EXT2_Undelete:
2824	case FILE_EXT2_Compress:
2825	case FILE_EXT2_Synchronous:
2826	case FILE_EXT2_Immutable:
2827	case FILE_EXT2_AppendOnly:
2828	case FILE_EXT2_NoDump:
2829	case FILE_EXT2_NoAtime:
2830	case FILE_EXT2_CompDirty:
2831	case FILE_EXT2_CompBlock:
2832	case FILE_EXT2_NoCompBlock:
2833	case FILE_EXT2_CompError:
2834	case FILE_EXT2_BTree:
2835	case FILE_EXT2_HashIndexed:
2836	case FILE_EXT2_iMagic:
2837	case FILE_EXT2_Journaled:
2838	case FILE_EXT2_NoTail:
2839	case FILE_EXT2_DirSync:
2840	case FILE_EXT2_TopDir:
2841	case FILE_EXT2_Reserved:
2842	case UNKNOWN:
2843		break;
2844	}
2845}
2846
2847/*
2848 * BSD file flags.
2849 */
2850static int
2851xml_parse_file_flags(struct xar *xar, const char *name)
2852{
2853	const char *flag = NULL;
2854
2855	if (strcmp(name, "UserNoDump") == 0) {
2856		xar->xmlsts = FILE_FLAGS_USER_NODUMP;
2857		flag = "nodump";
2858	}
2859	else if (strcmp(name, "UserImmutable") == 0) {
2860		xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE;
2861		flag = "uimmutable";
2862	}
2863	else if (strcmp(name, "UserAppend") == 0) {
2864		xar->xmlsts = FILE_FLAGS_USER_APPEND;
2865		flag = "uappend";
2866	}
2867	else if (strcmp(name, "UserOpaque") == 0) {
2868		xar->xmlsts = FILE_FLAGS_USER_OPAQUE;
2869		flag = "opaque";
2870	}
2871	else if (strcmp(name, "UserNoUnlink") == 0) {
2872		xar->xmlsts = FILE_FLAGS_USER_NOUNLINK;
2873		flag = "nouunlink";
2874	}
2875	else if (strcmp(name, "SystemArchived") == 0) {
2876		xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED;
2877		flag = "archived";
2878	}
2879	else if (strcmp(name, "SystemImmutable") == 0) {
2880		xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE;
2881		flag = "simmutable";
2882	}
2883	else if (strcmp(name, "SystemAppend") == 0) {
2884		xar->xmlsts = FILE_FLAGS_SYS_APPEND;
2885		flag = "sappend";
2886	}
2887	else if (strcmp(name, "SystemNoUnlink") == 0) {
2888		xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK;
2889		flag = "nosunlink";
2890	}
2891	else if (strcmp(name, "SystemSnapshot") == 0) {
2892		xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT;
2893		flag = "snapshot";
2894	}
2895
2896	if (flag == NULL)
2897		return (0);
2898	xar->file->has |= HAS_FFLAGS;
2899	if (archive_strlen(&(xar->file->fflags_text)) > 0)
2900		archive_strappend_char(&(xar->file->fflags_text), ',');
2901	archive_strcat(&(xar->file->fflags_text), flag);
2902	return (1);
2903}
2904
2905/*
2906 * Linux file flags.
2907 */
2908static int
2909xml_parse_file_ext2(struct xar *xar, const char *name)
2910{
2911	const char *flag = NULL;
2912
2913	if (strcmp(name, "SecureDeletion") == 0) {
2914		xar->xmlsts = FILE_EXT2_SecureDeletion;
2915		flag = "securedeletion";
2916	}
2917	else if (strcmp(name, "Undelete") == 0) {
2918		xar->xmlsts = FILE_EXT2_Undelete;
2919		flag = "nouunlink";
2920	}
2921	else if (strcmp(name, "Compress") == 0) {
2922		xar->xmlsts = FILE_EXT2_Compress;
2923		flag = "compress";
2924	}
2925	else if (strcmp(name, "Synchronous") == 0) {
2926		xar->xmlsts = FILE_EXT2_Synchronous;
2927		flag = "sync";
2928	}
2929	else if (strcmp(name, "Immutable") == 0) {
2930		xar->xmlsts = FILE_EXT2_Immutable;
2931		flag = "simmutable";
2932	}
2933	else if (strcmp(name, "AppendOnly") == 0) {
2934		xar->xmlsts = FILE_EXT2_AppendOnly;
2935		flag = "sappend";
2936	}
2937	else if (strcmp(name, "NoDump") == 0) {
2938		xar->xmlsts = FILE_EXT2_NoDump;
2939		flag = "nodump";
2940	}
2941	else if (strcmp(name, "NoAtime") == 0) {
2942		xar->xmlsts = FILE_EXT2_NoAtime;
2943		flag = "noatime";
2944	}
2945	else if (strcmp(name, "CompDirty") == 0) {
2946		xar->xmlsts = FILE_EXT2_CompDirty;
2947		flag = "compdirty";
2948	}
2949	else if (strcmp(name, "CompBlock") == 0) {
2950		xar->xmlsts = FILE_EXT2_CompBlock;
2951		flag = "comprblk";
2952	}
2953	else if (strcmp(name, "NoCompBlock") == 0) {
2954		xar->xmlsts = FILE_EXT2_NoCompBlock;
2955		flag = "nocomprblk";
2956	}
2957	else if (strcmp(name, "CompError") == 0) {
2958		xar->xmlsts = FILE_EXT2_CompError;
2959		flag = "comperr";
2960	}
2961	else if (strcmp(name, "BTree") == 0) {
2962		xar->xmlsts = FILE_EXT2_BTree;
2963		flag = "btree";
2964	}
2965	else if (strcmp(name, "HashIndexed") == 0) {
2966		xar->xmlsts = FILE_EXT2_HashIndexed;
2967		flag = "hashidx";
2968	}
2969	else if (strcmp(name, "iMagic") == 0) {
2970		xar->xmlsts = FILE_EXT2_iMagic;
2971		flag = "imagic";
2972	}
2973	else if (strcmp(name, "Journaled") == 0) {
2974		xar->xmlsts = FILE_EXT2_Journaled;
2975		flag = "journal";
2976	}
2977	else if (strcmp(name, "NoTail") == 0) {
2978		xar->xmlsts = FILE_EXT2_NoTail;
2979		flag = "notail";
2980	}
2981	else if (strcmp(name, "DirSync") == 0) {
2982		xar->xmlsts = FILE_EXT2_DirSync;
2983		flag = "dirsync";
2984	}
2985	else if (strcmp(name, "TopDir") == 0) {
2986		xar->xmlsts = FILE_EXT2_TopDir;
2987		flag = "topdir";
2988	}
2989	else if (strcmp(name, "Reserved") == 0) {
2990		xar->xmlsts = FILE_EXT2_Reserved;
2991		flag = "reserved";
2992	}
2993
2994	if (flag == NULL)
2995		return (0);
2996	if (archive_strlen(&(xar->file->fflags_text)) > 0)
2997		archive_strappend_char(&(xar->file->fflags_text), ',');
2998	archive_strcat(&(xar->file->fflags_text), flag);
2999	return (1);
3000}
3001
3002#ifdef HAVE_LIBXML_XMLREADER_H
3003
3004static int
3005xml2_xmlattr_setup(struct archive_read *a,
3006    struct xmlattr_list *list, xmlTextReaderPtr reader)
3007{
3008	struct xmlattr *attr;
3009	int r;
3010
3011	list->first = NULL;
3012	list->last = &(list->first);
3013	r = xmlTextReaderMoveToFirstAttribute(reader);
3014	while (r == 1) {
3015		attr = malloc(sizeof*(attr));
3016		if (attr == NULL) {
3017			archive_set_error(&a->archive, ENOMEM, "Out of memory");
3018			return (ARCHIVE_FATAL);
3019		}
3020		attr->name = strdup(
3021		    (const char *)xmlTextReaderConstLocalName(reader));
3022		if (attr->name == NULL) {
3023			free(attr);
3024			archive_set_error(&a->archive, ENOMEM, "Out of memory");
3025			return (ARCHIVE_FATAL);
3026		}
3027		attr->value = strdup(
3028		    (const char *)xmlTextReaderConstValue(reader));
3029		if (attr->value == NULL) {
3030			free(attr->name);
3031			free(attr);
3032			archive_set_error(&a->archive, ENOMEM, "Out of memory");
3033			return (ARCHIVE_FATAL);
3034		}
3035		attr->next = NULL;
3036		*list->last = attr;
3037		list->last = &(attr->next);
3038		r = xmlTextReaderMoveToNextAttribute(reader);
3039	}
3040	return (r);
3041}
3042
3043static int
3044xml2_read_cb(void *context, char *buffer, int len)
3045{
3046	struct archive_read *a;
3047	struct xar *xar;
3048	const void *d;
3049	size_t outbytes;
3050	size_t used;
3051	int r;
3052
3053	a = (struct archive_read *)context;
3054	xar = (struct xar *)(a->format->data);
3055
3056	if (xar->toc_remaining <= 0)
3057		return (0);
3058	d = buffer;
3059	outbytes = len;
3060	r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
3061	if (r != ARCHIVE_OK)
3062		return (r);
3063	__archive_read_consume(a, used);
3064	xar->toc_remaining -= used;
3065	xar->offset += used;
3066	xar->toc_total += outbytes;
3067	PRINT_TOC(buffer, len);
3068
3069	return ((int)outbytes);
3070}
3071
3072static int
3073xml2_close_cb(void *context)
3074{
3075
3076	(void)context; /* UNUSED */
3077	return (0);
3078}
3079
3080static void
3081xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity,
3082    xmlTextReaderLocatorPtr locator)
3083{
3084	struct archive_read *a;
3085
3086	(void)locator; /* UNUSED */
3087	a = (struct archive_read *)arg;
3088	switch (severity) {
3089	case XML_PARSER_SEVERITY_VALIDITY_WARNING:
3090	case XML_PARSER_SEVERITY_WARNING:
3091		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3092		    "XML Parsing error: %s", msg);
3093		break;
3094	case XML_PARSER_SEVERITY_VALIDITY_ERROR:
3095	case XML_PARSER_SEVERITY_ERROR:
3096		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3097		    "XML Parsing error: %s", msg);
3098		break;
3099	}
3100}
3101
3102static int
3103xml2_read_toc(struct archive_read *a)
3104{
3105	xmlTextReaderPtr reader;
3106	struct xmlattr_list list;
3107	int r;
3108
3109	reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0);
3110	if (reader == NULL) {
3111		archive_set_error(&a->archive, ENOMEM,
3112		    "Couldn't allocate memory for xml parser");
3113		return (ARCHIVE_FATAL);
3114	}
3115	xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a);
3116
3117	while ((r = xmlTextReaderRead(reader)) == 1) {
3118		const char *name, *value;
3119		int type, empty;
3120
3121		type = xmlTextReaderNodeType(reader);
3122		name = (const char *)xmlTextReaderConstLocalName(reader);
3123		switch (type) {
3124		case XML_READER_TYPE_ELEMENT:
3125			empty = xmlTextReaderIsEmptyElement(reader);
3126			r = xml2_xmlattr_setup(a, &list, reader);
3127			if (r == ARCHIVE_OK)
3128				r = xml_start(a, name, &list);
3129			xmlattr_cleanup(&list);
3130			if (r != ARCHIVE_OK)
3131				return (r);
3132			if (empty)
3133				xml_end(a, name);
3134			break;
3135		case XML_READER_TYPE_END_ELEMENT:
3136			xml_end(a, name);
3137			break;
3138		case XML_READER_TYPE_TEXT:
3139			value = (const char *)xmlTextReaderConstValue(reader);
3140			xml_data(a, value, strlen(value));
3141			break;
3142		case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
3143		default:
3144			break;
3145		}
3146		if (r < 0)
3147			break;
3148	}
3149	xmlFreeTextReader(reader);
3150	xmlCleanupParser();
3151
3152	return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL);
3153}
3154
3155#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
3156
3157static int
3158expat_xmlattr_setup(struct archive_read *a,
3159    struct xmlattr_list *list, const XML_Char **atts)
3160{
3161	struct xmlattr *attr;
3162	char *name, *value;
3163
3164	list->first = NULL;
3165	list->last = &(list->first);
3166	if (atts == NULL)
3167		return (ARCHIVE_OK);
3168	while (atts[0] != NULL && atts[1] != NULL) {
3169		attr = malloc(sizeof*(attr));
3170		name = strdup(atts[0]);
3171		value = strdup(atts[1]);
3172		if (attr == NULL || name == NULL || value == NULL) {
3173			archive_set_error(&a->archive, ENOMEM, "Out of memory");
3174			return (ARCHIVE_FATAL);
3175		}
3176		attr->name = name;
3177		attr->value = value;
3178		attr->next = NULL;
3179		*list->last = attr;
3180		list->last = &(attr->next);
3181		atts += 2;
3182	}
3183	return (ARCHIVE_OK);
3184}
3185
3186static void
3187expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts)
3188{
3189	struct expat_userData *ud = (struct expat_userData *)userData;
3190	struct archive_read *a = ud->archive;
3191	struct xmlattr_list list;
3192	int r;
3193
3194	r = expat_xmlattr_setup(a, &list, atts);
3195	if (r == ARCHIVE_OK)
3196		r = xml_start(a, (const char *)name, &list);
3197	xmlattr_cleanup(&list);
3198	ud->state = r;
3199}
3200
3201static void
3202expat_end_cb(void *userData, const XML_Char *name)
3203{
3204	struct expat_userData *ud = (struct expat_userData *)userData;
3205
3206	xml_end(ud->archive, (const char *)name);
3207}
3208
3209static void
3210expat_data_cb(void *userData, const XML_Char *s, int len)
3211{
3212	struct expat_userData *ud = (struct expat_userData *)userData;
3213
3214	xml_data(ud->archive, s, len);
3215}
3216
3217static int
3218expat_read_toc(struct archive_read *a)
3219{
3220	struct xar *xar;
3221	XML_Parser parser;
3222	struct expat_userData ud;
3223
3224	ud.state = ARCHIVE_OK;
3225	ud.archive = a;
3226
3227	xar = (struct xar *)(a->format->data);
3228
3229	/* Initialize XML Parser library. */
3230	parser = XML_ParserCreate(NULL);
3231	if (parser == NULL) {
3232		archive_set_error(&a->archive, ENOMEM,
3233		    "Couldn't allocate memory for xml parser");
3234		return (ARCHIVE_FATAL);
3235	}
3236	XML_SetUserData(parser, &ud);
3237	XML_SetElementHandler(parser, expat_start_cb, expat_end_cb);
3238	XML_SetCharacterDataHandler(parser, expat_data_cb);
3239	xar->xmlsts = INIT;
3240
3241	while (xar->toc_remaining && ud.state == ARCHIVE_OK) {
3242		enum XML_Status xr;
3243		const void *d;
3244		size_t outbytes;
3245		size_t used;
3246		int r;
3247
3248		d = NULL;
3249		r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining);
3250		if (r != ARCHIVE_OK)
3251			return (r);
3252		xar->toc_remaining -= used;
3253		xar->offset += used;
3254		xar->toc_total += outbytes;
3255		PRINT_TOC(d, outbytes);
3256
3257		xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0);
3258		__archive_read_consume(a, used);
3259		if (xr == XML_STATUS_ERROR) {
3260			XML_ParserFree(parser);
3261			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
3262			    "XML Parsing failed");
3263			return (ARCHIVE_FATAL);
3264		}
3265	}
3266	XML_ParserFree(parser);
3267	return (ud.state);
3268}
3269#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
3270
3271#endif /* Support xar format */
3272