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