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