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