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