2 * Copyright (c) 2009 Michihiro NAKAJIMA
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
25 #include "archive_platform.h"
26 __FBSDID("$FreeBSD$");
34 #if HAVE_LIBXML_XMLREADER_H
35 #include <libxml/xmlreader.h>
54 #include "archive_digest_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"
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)
66 * xar needs several external libraries.
67 * o libxml2 or expat --- XML parser
68 * o openssl or MD5/SHA1 hash function
74 archive_read_support_format_xar(struct archive
*_a
)
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");
80 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
81 "Xar not supported on this platform");
82 return (ARCHIVE_WARN
);
85 #else /* Support xar format */
88 /* #define DEBUG_PRINT_TOC 1 */
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; \
99 #define PRINT_TOC(d, outbytes)
102 #define HEADER_MAGIC 0x78617221
103 #define HEADER_SIZE 28
104 #define HEADER_VERSION 1
111 #define MAX_SUM_SIZE 20
124 unsigned char val
[MAX_SUM_SIZE
];
129 #ifdef ARCHIVE_HAS_MD5
130 archive_md5_ctx md5ctx
;
132 #ifdef ARCHIVE_HAS_SHA1
133 archive_sha1_ctx sha1ctx
;
139 struct archive_string name
;
144 enum enctype encoding
;
145 struct chksumval a_sum
;
146 struct chksumval e_sum
;
147 struct archive_string fstype
;
151 struct xar_file
*next
;
152 struct xar_file
*hdnext
;
153 struct xar_file
*parent
;
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
177 enum enctype encoding
;
178 struct chksumval a_sum
;
179 struct chksumval e_sum
;
180 struct archive_string pathname
;
181 struct archive_string symlink
;
185 struct archive_string uname
;
187 struct archive_string gname
;
194 struct archive_string fflags_text
;
197 struct archive_string hardlink
;
198 struct xattr
*xattr_list
;
206 struct xar_file
*files
;
210 struct xar_file
**files
;
229 FILE_DATA_A_CHECKSUM
,
230 FILE_DATA_E_CHECKSUM
,
260 FILE_ACL_APPLEEXTENDED
,
261 /* BSD 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. */
275 FILE_EXT2_SecureDeletion
,
278 FILE_EXT2_Synchronous
,
280 FILE_EXT2_AppendOnly
,
285 FILE_EXT2_NoCompBlock
,
288 FILE_EXT2_HashIndexed
,
299 struct unknown_tag
*next
;
300 struct archive_string name
;
304 uint64_t offset
; /* Current position in the file. */
308 #define OUTBUFF_SIZE (1024 * 64)
309 unsigned char *outbuff
;
311 enum xmlstatus xmlsts
;
312 enum xmlstatus xmlsts_unknown
;
313 struct unknown_tag
*unknowntags
;
319 uint64_t toc_remaining
;
321 uint64_t toc_chksum_offset
;
322 uint64_t toc_chksum_size
;
327 enum enctype rd_encoding
;
330 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
334 #if HAVE_LZMA_H && HAVE_LIBLZMA
335 lzma_stream lzstream
;
337 #elif HAVE_LZMADEC_H && HAVE_LIBLZMADEC
338 lzmadec_stream lzstream
;
344 struct chksumwork a_sumwrk
;
345 struct chksumwork e_sumwrk
;
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
;
354 uint64_t entry_total
;
355 uint64_t entry_remaining
;
356 size_t entry_unconsumed
;
358 enum enctype entry_encoding
;
359 struct chksumval entry_a_sum
;
360 struct chksumval entry_e_sum
;
362 struct archive_string_conv
*sconv
;
366 struct xmlattr
*next
;
371 struct xmlattr_list
{
372 struct xmlattr
*first
;
373 struct xmlattr
**last
;
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
{
435 struct archive_read
*archive
;
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
*);
446 archive_read_support_format_xar(struct archive
*_a
)
449 struct archive_read
*a
= (struct archive_read
*)_a
;
452 archive_check_magic(_a
, ARCHIVE_READ_MAGIC
,
453 ARCHIVE_STATE_NEW
, "archive_read_support_format_xar");
455 xar
= (struct xar
*)calloc(1, sizeof(*xar
));
457 archive_set_error(&a
->archive
, ENOMEM
,
458 "Can't allocate xar data");
459 return (ARCHIVE_FATAL
);
462 r
= __archive_read_register_format(a
,
480 xar_bid(struct archive_read
*a
, int best_bid
)
482 const unsigned char *b
;
485 (void)best_bid
; /* UNUSED */
487 b
= __archive_read_ahead(a
, HEADER_SIZE
, NULL
);
495 if (archive_be32dec(b
) != HEADER_MAGIC
)
501 if (archive_be16dec(b
+4) != HEADER_SIZE
)
505 * Verify header version
507 if (archive_be16dec(b
+6) != HEADER_VERSION
)
511 * Verify type of checksum
513 switch (archive_be32dec(b
+24)) {
527 read_toc(struct archive_read
*a
)
530 struct xar_file
*file
;
531 const unsigned char *b
;
532 uint64_t toc_compressed_size
;
533 uint64_t toc_uncompressed_size
;
534 uint32_t toc_chksum_alg
;
538 xar
= (struct xar
*)(a
->format
->data
);
543 b
= __archive_read_ahead(a
, HEADER_SIZE
, &bytes
);
546 if (bytes
< HEADER_SIZE
) {
547 archive_set_error(&a
->archive
,
548 ARCHIVE_ERRNO_FILE_FORMAT
,
549 "Truncated archive header");
550 return (ARCHIVE_FATAL
);
553 if (archive_be32dec(b
) != HEADER_MAGIC
) {
554 archive_set_error(&a
->archive
,
555 ARCHIVE_ERRNO_FILE_FORMAT
,
556 "Invalid header magic");
557 return (ARCHIVE_FATAL
);
559 if (archive_be16dec(b
+6) != HEADER_VERSION
) {
560 archive_set_error(&a
->archive
,
561 ARCHIVE_ERRNO_FILE_FORMAT
,
562 "Unsupported header version(%d)",
563 archive_be16dec(b
+6));
564 return (ARCHIVE_FATAL
);
566 toc_compressed_size
= archive_be64dec(b
+8);
567 xar
->toc_remaining
= toc_compressed_size
;
568 toc_uncompressed_size
= archive_be64dec(b
+16);
569 toc_chksum_alg
= archive_be32dec(b
+24);
570 __archive_read_consume(a
, HEADER_SIZE
);
571 xar
->offset
+= HEADER_SIZE
;
575 * Read TOC(Table of Contents).
577 /* Initialize reading contents. */
578 r
= move_reading_point(a
, HEADER_SIZE
);
581 r
= rd_contents_init(a
, GZIP
, toc_chksum_alg
, CKSUM_NONE
);
585 #ifdef HAVE_LIBXML_XMLREADER_H
586 r
= xml2_read_toc(a
);
587 #elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
588 r
= expat_read_toc(a
);
593 /* Set 'The HEAP' base. */
594 xar
->h_base
= xar
->offset
;
595 if (xar
->toc_total
!= toc_uncompressed_size
) {
596 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
597 "TOC uncompressed size error");
598 return (ARCHIVE_FATAL
);
604 if (toc_chksum_alg
!= CKSUM_NONE
) {
605 r
= move_reading_point(a
, xar
->toc_chksum_offset
);
608 b
= __archive_read_ahead(a
,
609 (size_t)xar
->toc_chksum_size
, &bytes
);
612 if ((uint64_t)bytes
< xar
->toc_chksum_size
) {
613 archive_set_error(&a
->archive
,
614 ARCHIVE_ERRNO_FILE_FORMAT
,
615 "Truncated archive file");
616 return (ARCHIVE_FATAL
);
618 r
= checksum_final(a
, b
,
619 (size_t)xar
->toc_chksum_size
, NULL
, 0);
620 __archive_read_consume(a
, xar
->toc_chksum_size
);
621 xar
->offset
+= xar
->toc_chksum_size
;
623 return (ARCHIVE_FATAL
);
627 * Connect hardlinked files.
629 for (file
= xar
->hdlink_orgs
; file
!= NULL
; file
= file
->hdnext
) {
630 struct hdlink
**hdlink
;
632 for (hdlink
= &(xar
->hdlink_list
); *hdlink
!= NULL
;
633 hdlink
= &((*hdlink
)->next
)) {
634 if ((*hdlink
)->id
== file
->id
) {
635 struct hdlink
*hltmp
;
637 int nlink
= (*hdlink
)->cnt
+ 1;
640 for (f2
= (*hdlink
)->files
; f2
!= NULL
;
644 &(f2
->hardlink
), &(file
->pathname
));
646 /* Remove resolved files from hdlist_list. */
648 *hdlink
= hltmp
->next
;
654 a
->archive
.archive_format
= ARCHIVE_FORMAT_XAR
;
655 a
->archive
.archive_format_name
= "xar";
661 xar_read_header(struct archive_read
*a
, struct archive_entry
*entry
)
664 struct xar_file
*file
;
668 xar
= (struct xar
*)(a
->format
->data
);
671 if (xar
->offset
== 0) {
672 /* Create a character conversion object. */
673 if (xar
->sconv
== NULL
) {
674 xar
->sconv
= archive_string_conversion_from_charset(
675 &(a
->archive
), "UTF-8", 1);
676 if (xar
->sconv
== NULL
)
677 return (ARCHIVE_FATAL
);
687 file
= xar
->file
= heap_get_entry(&(xar
->file_queue
));
689 xar
->end_of_file
= 1;
690 return (ARCHIVE_EOF
);
692 if ((file
->mode
& AE_IFMT
) != AE_IFDIR
)
694 if (file
->has
!= (HAS_PATHNAME
| HAS_TYPE
))
697 * If a file type is a directory and it does not have
698 * any metadata, do not export.
702 archive_entry_set_atime(entry
, file
->atime
, 0);
703 archive_entry_set_ctime(entry
, file
->ctime
, 0);
704 archive_entry_set_mtime(entry
, file
->mtime
, 0);
705 archive_entry_set_gid(entry
, file
->gid
);
706 if (file
->gname
.length
> 0 &&
707 archive_entry_copy_gname_l(entry
, file
->gname
.s
,
708 archive_strlen(&(file
->gname
)), xar
->sconv
) != 0) {
709 if (errno
== ENOMEM
) {
710 archive_set_error(&a
->archive
, ENOMEM
,
711 "Can't allocate memory for Gname");
712 return (ARCHIVE_FATAL
);
714 archive_set_error(&a
->archive
,
715 ARCHIVE_ERRNO_FILE_FORMAT
,
716 "Gname cannot be converted from %s to current locale.",
717 archive_string_conversion_charset_name(xar
->sconv
));
720 archive_entry_set_uid(entry
, file
->uid
);
721 if (file
->uname
.length
> 0 &&
722 archive_entry_copy_uname_l(entry
, file
->uname
.s
,
723 archive_strlen(&(file
->uname
)), xar
->sconv
) != 0) {
724 if (errno
== ENOMEM
) {
725 archive_set_error(&a
->archive
, ENOMEM
,
726 "Can't allocate memory for Uname");
727 return (ARCHIVE_FATAL
);
729 archive_set_error(&a
->archive
,
730 ARCHIVE_ERRNO_FILE_FORMAT
,
731 "Uname cannot be converted from %s to current locale.",
732 archive_string_conversion_charset_name(xar
->sconv
));
735 archive_entry_set_mode(entry
, file
->mode
);
736 if (archive_entry_copy_pathname_l(entry
, file
->pathname
.s
,
737 archive_strlen(&(file
->pathname
)), xar
->sconv
) != 0) {
738 if (errno
== ENOMEM
) {
739 archive_set_error(&a
->archive
, ENOMEM
,
740 "Can't allocate memory for Pathname");
741 return (ARCHIVE_FATAL
);
743 archive_set_error(&a
->archive
,
744 ARCHIVE_ERRNO_FILE_FORMAT
,
745 "Pathname cannot be converted from %s to current locale.",
746 archive_string_conversion_charset_name(xar
->sconv
));
751 if (file
->symlink
.length
> 0 &&
752 archive_entry_copy_symlink_l(entry
, file
->symlink
.s
,
753 archive_strlen(&(file
->symlink
)), xar
->sconv
) != 0) {
754 if (errno
== ENOMEM
) {
755 archive_set_error(&a
->archive
, ENOMEM
,
756 "Can't allocate memory for Linkname");
757 return (ARCHIVE_FATAL
);
759 archive_set_error(&a
->archive
,
760 ARCHIVE_ERRNO_FILE_FORMAT
,
761 "Linkname cannot be converted from %s to current locale.",
762 archive_string_conversion_charset_name(xar
->sconv
));
765 /* Set proper nlink. */
766 if ((file
->mode
& AE_IFMT
) == AE_IFDIR
)
767 archive_entry_set_nlink(entry
, file
->subdirs
+ 2);
769 archive_entry_set_nlink(entry
, file
->nlink
);
770 archive_entry_set_size(entry
, file
->size
);
771 if (archive_strlen(&(file
->hardlink
)) > 0)
772 archive_entry_set_hardlink(entry
, file
->hardlink
.s
);
773 archive_entry_set_ino64(entry
, file
->ino64
);
774 if (file
->has
& HAS_DEV
)
775 archive_entry_set_dev(entry
, file
->dev
);
776 if (file
->has
& HAS_DEVMAJOR
)
777 archive_entry_set_devmajor(entry
, file
->devmajor
);
778 if (file
->has
& HAS_DEVMINOR
)
779 archive_entry_set_devminor(entry
, file
->devminor
);
780 if (archive_strlen(&(file
->fflags_text
)) > 0)
781 archive_entry_copy_fflags_text(entry
, file
->fflags_text
.s
);
784 xar
->entry_total
= 0;
785 xar
->entry_remaining
= file
->length
;
786 xar
->entry_size
= file
->size
;
787 xar
->entry_encoding
= file
->encoding
;
788 xar
->entry_a_sum
= file
->a_sum
;
789 xar
->entry_e_sum
= file
->e_sum
;
791 * Read extended attributes.
793 xattr
= file
->xattr_list
;
794 while (xattr
!= NULL
) {
796 size_t outbytes
, used
;
798 r
= move_reading_point(a
, xattr
->offset
);
801 r
= rd_contents_init(a
, xattr
->encoding
,
802 xattr
->a_sum
.alg
, xattr
->e_sum
.alg
);
806 r
= rd_contents(a
, &d
, &outbytes
, &used
, xattr
->length
);
809 if (outbytes
!= xattr
->size
) {
810 archive_set_error(&(a
->archive
), ARCHIVE_ERRNO_MISC
,
811 "Decompressed size error");
815 r
= checksum_final(a
,
816 xattr
->a_sum
.val
, xattr
->a_sum
.len
,
817 xattr
->e_sum
.val
, xattr
->e_sum
.len
);
820 archive_entry_xattr_add_entry(entry
,
821 xattr
->name
.s
, d
, outbytes
);
824 if (r
!= ARCHIVE_OK
) {
829 if (xar
->entry_remaining
> 0)
830 /* Move reading point to the beginning of current
832 r
= move_reading_point(a
, file
->offset
);
841 xar_read_data(struct archive_read
*a
,
842 const void **buff
, size_t *size
, int64_t *offset
)
848 xar
= (struct xar
*)(a
->format
->data
);
850 if (xar
->entry_unconsumed
) {
851 __archive_read_consume(a
, xar
->entry_unconsumed
);
852 xar
->entry_unconsumed
= 0;
855 if (xar
->end_of_file
|| xar
->entry_remaining
<= 0) {
857 goto abort_read_data
;
860 if (xar
->entry_init
) {
861 r
= rd_contents_init(a
, xar
->entry_encoding
,
862 xar
->entry_a_sum
.alg
, xar
->entry_e_sum
.alg
);
863 if (r
!= ARCHIVE_OK
) {
864 xar
->entry_remaining
= 0;
871 r
= rd_contents(a
, buff
, size
, &used
, xar
->entry_remaining
);
873 goto abort_read_data
;
875 *offset
= xar
->entry_total
;
876 xar
->entry_total
+= *size
;
879 xar
->entry_remaining
-= used
;
880 xar
->entry_unconsumed
= used
;
882 if (xar
->entry_remaining
== 0) {
883 if (xar
->entry_total
!= xar
->entry_size
) {
884 archive_set_error(&(a
->archive
), ARCHIVE_ERRNO_MISC
,
885 "Decompressed size error");
887 goto abort_read_data
;
889 r
= checksum_final(a
,
890 xar
->entry_a_sum
.val
, xar
->entry_a_sum
.len
,
891 xar
->entry_e_sum
.val
, xar
->entry_e_sum
.len
);
893 goto abort_read_data
;
900 *offset
= xar
->total
;
905 xar_read_data_skip(struct archive_read
*a
)
908 int64_t bytes_skipped
;
910 xar
= (struct xar
*)(a
->format
->data
);
911 if (xar
->end_of_file
)
912 return (ARCHIVE_EOF
);
913 bytes_skipped
= __archive_read_consume(a
, xar
->entry_remaining
+
914 xar
->entry_unconsumed
);
915 if (bytes_skipped
< 0)
916 return (ARCHIVE_FATAL
);
917 xar
->offset
+= bytes_skipped
;
918 xar
->entry_unconsumed
= 0;
923 xar_cleanup(struct archive_read
*a
)
926 struct hdlink
*hdlink
;
930 xar
= (struct xar
*)(a
->format
->data
);
931 r
= decompression_cleanup(a
);
932 hdlink
= xar
->hdlink_list
;
933 while (hdlink
!= NULL
) {
934 struct hdlink
*next
= hdlink
->next
;
939 for (i
= 0; i
< xar
->file_queue
.used
; i
++)
940 file_free(xar
->file_queue
.files
[i
]);
941 while (xar
->unknowntags
!= NULL
) {
942 struct unknown_tag
*tag
;
944 tag
= xar
->unknowntags
;
945 xar
->unknowntags
= tag
->next
;
946 archive_string_free(&(tag
->name
));
951 a
->format
->data
= NULL
;
956 move_reading_point(struct archive_read
*a
, uint64_t offset
)
960 xar
= (struct xar
*)(a
->format
->data
);
961 if (xar
->offset
- xar
->h_base
!= offset
) {
962 /* Seek forward to the start of file contents. */
965 step
= offset
- (xar
->offset
- xar
->h_base
);
967 step
= __archive_read_consume(a
, step
);
972 int64_t pos
= __archive_read_seek(a
, offset
, SEEK_SET
);
973 if (pos
== ARCHIVE_FAILED
) {
974 archive_set_error(&(a
->archive
),
977 return (ARCHIVE_FAILED
);
986 rd_contents_init(struct archive_read
*a
, enum enctype encoding
,
987 int a_sum_alg
, int e_sum_alg
)
991 /* Init decompress library. */
992 if ((r
= decompression_init(a
, encoding
)) != ARCHIVE_OK
)
994 /* Init checksum library. */
995 checksum_init(a
, a_sum_alg
, e_sum_alg
);
1000 rd_contents(struct archive_read
*a
, const void **buff
, size_t *size
,
1001 size_t *used
, uint64_t remaining
)
1003 const unsigned char *b
;
1006 /* Get whatever bytes are immediately available. */
1007 b
= __archive_read_ahead(a
, 1, &bytes
);
1009 return ((int)bytes
);
1011 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
1012 "Truncated archive file");
1013 return (ARCHIVE_FATAL
);
1015 if ((uint64_t)bytes
> remaining
)
1016 bytes
= (ssize_t
)remaining
;
1019 * Decompress contents of file.
1022 if (decompress(a
, buff
, size
, b
, used
) != ARCHIVE_OK
)
1023 return (ARCHIVE_FATAL
);
1026 * Update checksum of a compressed data and a extracted data.
1028 checksum_update(a
, b
, *used
, *buff
, *size
);
1030 return (ARCHIVE_OK
);
1034 * Note that this implementation does not (and should not!) obey
1035 * locale settings; you cannot simply substitute strtol here, since
1036 * it does obey locale.
1040 atol10(const char *p
, size_t char_cnt
)
1047 while (digit
>= 0 && digit
< 10 && char_cnt
-- > 0) {
1048 l
= (l
* 10) + digit
;
1055 atol8(const char *p
, size_t char_cnt
)
1061 while (char_cnt
-- > 0) {
1062 if (*p
>= '0' && *p
<= '7')
1074 atohex(unsigned char *b
, size_t bsize
, const char *p
, size_t psize
)
1076 size_t fbsize
= bsize
;
1078 while (bsize
&& psize
> 1) {
1081 if (p
[0] >= 'a' && p
[0] <= 'z')
1082 x
= (p
[0] - 'a' + 0x0a) << 4;
1083 else if (p
[0] >= 'A' && p
[0] <= 'Z')
1084 x
= (p
[0] - 'A' + 0x0a) << 4;
1085 else if (p
[0] >= '0' && p
[0] <= '9')
1086 x
= (p
[0] - '0') << 4;
1089 if (p
[1] >= 'a' && p
[1] <= 'z')
1090 x
|= p
[1] - 'a' + 0x0a;
1091 else if (p
[1] >= 'A' && p
[1] <= 'Z')
1092 x
|= p
[1] - 'A' + 0x0a;
1093 else if (p
[1] >= '0' && p
[1] <= '9')
1103 return (fbsize
- bsize
);
1107 time_from_tm(struct tm
*t
)
1110 /* Use platform timegm() if available. */
1112 #elif HAVE__MKGMTIME64
1113 return (_mkgmtime64(t
));
1115 /* Else use direct calculation using POSIX assumptions. */
1116 /* First, fix up tm_yday based on the year/month/day. */
1118 /* Then we can compute timegm() from first principles. */
1122 + t
->tm_yday
* 86400
1123 + (t
->tm_year
- 70) * 31536000
1124 + ((t
->tm_year
- 69) / 4) * 86400
1125 - ((t
->tm_year
- 1) / 100) * 86400
1126 + ((t
->tm_year
+ 299) / 400) * 86400);
1131 parse_time(const char *p
, size_t n
)
1137 memset(&tm
, 0, sizeof(tm
));
1140 data
= atol10(p
, 4);
1143 tm
.tm_year
= (int)data
- 1900;
1147 data
= atol10(p
, 2);
1148 if (data
< 1 || data
> 12)
1150 tm
.tm_mon
= (int)data
-1;
1154 data
= atol10(p
, 2);
1155 if (data
< 1 || data
> 31)
1157 tm
.tm_mday
= (int)data
;
1161 data
= atol10(p
, 2);
1162 if (data
< 0 || data
> 23)
1164 tm
.tm_hour
= (int)data
;
1168 data
= atol10(p
, 2);
1169 if (data
< 0 || data
> 59)
1171 tm
.tm_min
= (int)data
;
1175 data
= atol10(p
, 2);
1176 if (data
< 0 || data
> 60)
1178 tm
.tm_sec
= (int)data
;
1185 t
= time_from_tm(&tm
);
1191 heap_add_entry(struct archive_read
*a
,
1192 struct heap_queue
*heap
, struct xar_file
*file
)
1194 uint64_t file_id
, parent_id
;
1197 /* Expand our pending files list as necessary. */
1198 if (heap
->used
>= heap
->allocated
) {
1199 struct xar_file
**new_pending_files
;
1200 int new_size
= heap
->allocated
* 2;
1202 if (heap
->allocated
< 1024)
1204 /* Overflow might keep us from growing the list. */
1205 if (new_size
<= heap
->allocated
) {
1206 archive_set_error(&a
->archive
,
1207 ENOMEM
, "Out of memory");
1208 return (ARCHIVE_FATAL
);
1210 new_pending_files
= (struct xar_file
**)
1211 malloc(new_size
* sizeof(new_pending_files
[0]));
1212 if (new_pending_files
== NULL
) {
1213 archive_set_error(&a
->archive
,
1214 ENOMEM
, "Out of memory");
1215 return (ARCHIVE_FATAL
);
1217 memcpy(new_pending_files
, heap
->files
,
1218 heap
->allocated
* sizeof(new_pending_files
[0]));
1219 if (heap
->files
!= NULL
)
1221 heap
->files
= new_pending_files
;
1222 heap
->allocated
= new_size
;
1228 * Start with hole at end, walk it up tree to find insertion point.
1230 hole
= heap
->used
++;
1232 parent
= (hole
- 1)/2;
1233 parent_id
= heap
->files
[parent
]->id
;
1234 if (file_id
>= parent_id
) {
1235 heap
->files
[hole
] = file
;
1236 return (ARCHIVE_OK
);
1238 /* Move parent into hole <==> move hole up tree. */
1239 heap
->files
[hole
] = heap
->files
[parent
];
1242 heap
->files
[0] = file
;
1244 return (ARCHIVE_OK
);
1247 static struct xar_file
*
1248 heap_get_entry(struct heap_queue
*heap
)
1250 uint64_t a_id
, b_id
, c_id
;
1252 struct xar_file
*r
, *tmp
;
1258 * The first file in the list is the earliest; we'll return this.
1263 * Move the last item in the heap to the root of the tree
1265 heap
->files
[0] = heap
->files
[--(heap
->used
)];
1268 * Rebalance the heap.
1270 a
= 0; /* Starting element and its heap key */
1271 a_id
= heap
->files
[a
]->id
;
1273 b
= a
+ a
+ 1; /* First child */
1274 if (b
>= heap
->used
)
1276 b_id
= heap
->files
[b
]->id
;
1277 c
= b
+ 1; /* Use second child if it is smaller. */
1278 if (c
< heap
->used
) {
1279 c_id
= heap
->files
[c
]->id
;
1287 tmp
= heap
->files
[a
];
1288 heap
->files
[a
] = heap
->files
[b
];
1289 heap
->files
[b
] = tmp
;
1295 add_link(struct archive_read
*a
, struct xar
*xar
, struct xar_file
*file
)
1297 struct hdlink
*hdlink
;
1299 for (hdlink
= xar
->hdlink_list
; hdlink
!= NULL
; hdlink
= hdlink
->next
) {
1300 if (hdlink
->id
== file
->link
) {
1301 file
->hdnext
= hdlink
->files
;
1303 hdlink
->files
= file
;
1304 return (ARCHIVE_OK
);
1307 hdlink
= malloc(sizeof(*hdlink
));
1308 if (hdlink
== NULL
) {
1309 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
1310 return (ARCHIVE_FATAL
);
1312 file
->hdnext
= NULL
;
1313 hdlink
->id
= file
->link
;
1315 hdlink
->files
= file
;
1316 hdlink
->next
= xar
->hdlink_list
;
1317 xar
->hdlink_list
= hdlink
;
1318 return (ARCHIVE_OK
);
1322 _checksum_init(struct chksumwork
*sumwrk
, int sum_alg
)
1324 sumwrk
->alg
= sum_alg
;
1329 archive_sha1_init(&(sumwrk
->sha1ctx
));
1332 archive_md5_init(&(sumwrk
->md5ctx
));
1338 _checksum_update(struct chksumwork
*sumwrk
, const void *buff
, size_t size
)
1341 switch (sumwrk
->alg
) {
1345 archive_sha1_update(&(sumwrk
->sha1ctx
), buff
, size
);
1348 archive_md5_update(&(sumwrk
->md5ctx
), buff
, size
);
1354 _checksum_final(struct chksumwork
*sumwrk
, const void *val
, size_t len
)
1356 unsigned char sum
[MAX_SUM_SIZE
];
1359 switch (sumwrk
->alg
) {
1363 archive_sha1_final(&(sumwrk
->sha1ctx
), sum
);
1364 if (len
!= SHA1_SIZE
||
1365 memcmp(val
, sum
, SHA1_SIZE
) != 0)
1369 archive_md5_final(&(sumwrk
->md5ctx
), sum
);
1370 if (len
!= MD5_SIZE
||
1371 memcmp(val
, sum
, MD5_SIZE
) != 0)
1379 checksum_init(struct archive_read
*a
, int a_sum_alg
, int e_sum_alg
)
1383 xar
= (struct xar
*)(a
->format
->data
);
1384 _checksum_init(&(xar
->a_sumwrk
), a_sum_alg
);
1385 _checksum_init(&(xar
->e_sumwrk
), e_sum_alg
);
1389 checksum_update(struct archive_read
*a
, const void *abuff
, size_t asize
,
1390 const void *ebuff
, size_t esize
)
1394 xar
= (struct xar
*)(a
->format
->data
);
1395 _checksum_update(&(xar
->a_sumwrk
), abuff
, asize
);
1396 _checksum_update(&(xar
->e_sumwrk
), ebuff
, esize
);
1400 checksum_final(struct archive_read
*a
, const void *a_sum_val
,
1401 size_t a_sum_len
, const void *e_sum_val
, size_t e_sum_len
)
1406 xar
= (struct xar
*)(a
->format
->data
);
1407 r
= _checksum_final(&(xar
->a_sumwrk
), a_sum_val
, a_sum_len
);
1408 if (r
== ARCHIVE_OK
)
1409 r
= _checksum_final(&(xar
->e_sumwrk
), e_sum_val
, e_sum_len
);
1410 if (r
!= ARCHIVE_OK
)
1411 archive_set_error(&(a
->archive
), ARCHIVE_ERRNO_MISC
,
1417 decompression_init(struct archive_read
*a
, enum enctype encoding
)
1423 xar
= (struct xar
*)(a
->format
->data
);
1424 xar
->rd_encoding
= encoding
;
1429 if (xar
->stream_valid
)
1430 r
= inflateReset(&(xar
->stream
));
1432 r
= inflateInit(&(xar
->stream
));
1434 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
1435 "Couldn't initialize zlib stream.");
1436 return (ARCHIVE_FATAL
);
1438 xar
->stream_valid
= 1;
1439 xar
->stream
.total_in
= 0;
1440 xar
->stream
.total_out
= 0;
1442 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1444 if (xar
->bzstream_valid
) {
1445 BZ2_bzDecompressEnd(&(xar
->bzstream
));
1446 xar
->bzstream_valid
= 0;
1448 r
= BZ2_bzDecompressInit(&(xar
->bzstream
), 0, 0);
1449 if (r
== BZ_MEM_ERROR
)
1450 r
= BZ2_bzDecompressInit(&(xar
->bzstream
), 0, 1);
1452 int err
= ARCHIVE_ERRNO_MISC
;
1455 case BZ_PARAM_ERROR
:
1456 detail
= "invalid setup parameter";
1460 detail
= "out of memory";
1462 case BZ_CONFIG_ERROR
:
1463 detail
= "mis-compiled library";
1466 archive_set_error(&a
->archive
, err
,
1467 "Internal error initializing decompressor: %s",
1468 detail
== NULL
? "??" : detail
);
1469 xar
->bzstream_valid
= 0;
1470 return (ARCHIVE_FATAL
);
1472 xar
->bzstream_valid
= 1;
1473 xar
->bzstream
.total_in_lo32
= 0;
1474 xar
->bzstream
.total_in_hi32
= 0;
1475 xar
->bzstream
.total_out_lo32
= 0;
1476 xar
->bzstream
.total_out_hi32
= 0;
1479 #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1480 #if LZMA_VERSION_MAJOR >= 5
1481 /* Effectively disable the limiter. */
1482 #define LZMA_MEMLIMIT UINT64_MAX
1484 /* NOTE: This needs to check memory size which running system has. */
1485 #define LZMA_MEMLIMIT (1U << 30)
1489 if (xar
->lzstream_valid
) {
1490 lzma_end(&(xar
->lzstream
));
1491 xar
->lzstream_valid
= 0;
1493 if (xar
->entry_encoding
== XZ
)
1494 r
= lzma_stream_decoder(&(xar
->lzstream
),
1495 LZMA_MEMLIMIT
,/* memlimit */
1498 r
= lzma_alone_decoder(&(xar
->lzstream
),
1499 LZMA_MEMLIMIT
);/* memlimit */
1502 case LZMA_MEM_ERROR
:
1503 archive_set_error(&a
->archive
,
1505 "Internal error initializing "
1506 "compression library: "
1507 "Cannot allocate memory");
1509 case LZMA_OPTIONS_ERROR
:
1510 archive_set_error(&a
->archive
,
1512 "Internal error initializing "
1513 "compression library: "
1514 "Invalid or unsupported options");
1517 archive_set_error(&a
->archive
,
1519 "Internal error initializing "
1523 return (ARCHIVE_FATAL
);
1525 xar
->lzstream_valid
= 1;
1526 xar
->lzstream
.total_in
= 0;
1527 xar
->lzstream
.total_out
= 0;
1529 #elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
1531 if (xar
->lzstream_valid
)
1532 lzmadec_end(&(xar
->lzstream
));
1533 r
= lzmadec_init(&(xar
->lzstream
));
1534 if (r
!= LZMADEC_OK
) {
1536 case LZMADEC_HEADER_ERROR
:
1537 archive_set_error(&a
->archive
,
1539 "Internal error initializing "
1540 "compression library: "
1543 case LZMADEC_MEM_ERROR
:
1544 archive_set_error(&a
->archive
,
1546 "Internal error initializing "
1547 "compression library: "
1551 return (ARCHIVE_FATAL
);
1553 xar
->lzstream_valid
= 1;
1554 xar
->lzstream
.total_in
= 0;
1555 xar
->lzstream
.total_out
= 0;
1559 * Unsupported compression.
1562 #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1565 #if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1566 #if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
1571 switch (xar
->entry_encoding
) {
1572 case BZIP2
: detail
= "bzip2"; break;
1573 case LZMA
: detail
= "lzma"; break;
1574 case XZ
: detail
= "xz"; break;
1575 default: detail
= "??"; break;
1577 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
1578 "%s compression not supported on this platform",
1580 return (ARCHIVE_FAILED
);
1582 return (ARCHIVE_OK
);
1586 decompress(struct archive_read
*a
, const void **buff
, size_t *outbytes
,
1587 const void *b
, size_t *used
)
1591 size_t avail_in
, avail_out
;
1594 xar
= (struct xar
*)(a
->format
->data
);
1596 outbuff
= (void *)(uintptr_t)*buff
;
1597 if (outbuff
== NULL
) {
1598 if (xar
->outbuff
== NULL
) {
1599 xar
->outbuff
= malloc(OUTBUFF_SIZE
);
1600 if (xar
->outbuff
== NULL
) {
1601 archive_set_error(&a
->archive
, ENOMEM
,
1602 "Couldn't allocate memory for out buffer");
1603 return (ARCHIVE_FATAL
);
1606 outbuff
= xar
->outbuff
;
1608 avail_out
= OUTBUFF_SIZE
;
1610 avail_out
= *outbytes
;
1611 switch (xar
->rd_encoding
) {
1613 xar
->stream
.next_in
= (Bytef
*)(uintptr_t)b
;
1614 xar
->stream
.avail_in
= avail_in
;
1615 xar
->stream
.next_out
= (unsigned char *)outbuff
;
1616 xar
->stream
.avail_out
= avail_out
;
1617 r
= inflate(&(xar
->stream
), 0);
1619 case Z_OK
: /* Decompressor made some progress.*/
1620 case Z_STREAM_END
: /* Found end of stream. */
1623 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
1624 "File decompression failed (%d)", r
);
1625 return (ARCHIVE_FATAL
);
1627 *used
= avail_in
- xar
->stream
.avail_in
;
1628 *outbytes
= avail_out
- xar
->stream
.avail_out
;
1630 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1632 xar
->bzstream
.next_in
= (char *)(uintptr_t)b
;
1633 xar
->bzstream
.avail_in
= avail_in
;
1634 xar
->bzstream
.next_out
= (char *)outbuff
;
1635 xar
->bzstream
.avail_out
= avail_out
;
1636 r
= BZ2_bzDecompress(&(xar
->bzstream
));
1638 case BZ_STREAM_END
: /* Found end of stream. */
1639 switch (BZ2_bzDecompressEnd(&(xar
->bzstream
))) {
1643 archive_set_error(&(a
->archive
),
1645 "Failed to clean up decompressor");
1646 return (ARCHIVE_FATAL
);
1648 xar
->bzstream_valid
= 0;
1650 case BZ_OK
: /* Decompressor made some progress. */
1653 archive_set_error(&(a
->archive
),
1655 "bzip decompression failed");
1656 return (ARCHIVE_FATAL
);
1658 *used
= avail_in
- xar
->bzstream
.avail_in
;
1659 *outbytes
= avail_out
- xar
->bzstream
.avail_out
;
1662 #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1665 xar
->lzstream
.next_in
= b
;
1666 xar
->lzstream
.avail_in
= avail_in
;
1667 xar
->lzstream
.next_out
= (unsigned char *)outbuff
;
1668 xar
->lzstream
.avail_out
= avail_out
;
1669 r
= lzma_code(&(xar
->lzstream
), LZMA_RUN
);
1671 case LZMA_STREAM_END
: /* Found end of stream. */
1672 lzma_end(&(xar
->lzstream
));
1673 xar
->lzstream_valid
= 0;
1675 case LZMA_OK
: /* Decompressor made some progress. */
1678 archive_set_error(&(a
->archive
),
1680 "%s decompression failed(%d)",
1681 (xar
->entry_encoding
== XZ
)?"xz":"lzma",
1683 return (ARCHIVE_FATAL
);
1685 *used
= avail_in
- xar
->lzstream
.avail_in
;
1686 *outbytes
= avail_out
- xar
->lzstream
.avail_out
;
1688 #elif defined(HAVE_LZMADEC_H) && defined(HAVE_LIBLZMADEC)
1690 xar
->lzstream
.next_in
= (unsigned char *)(uintptr_t)b
;
1691 xar
->lzstream
.avail_in
= avail_in
;
1692 xar
->lzstream
.next_out
= (unsigned char *)outbuff
;
1693 xar
->lzstream
.avail_out
= avail_out
;
1694 r
= lzmadec_decode(&(xar
->lzstream
), 0);
1696 case LZMADEC_STREAM_END
: /* Found end of stream. */
1697 switch (lzmadec_end(&(xar
->lzstream
))) {
1701 archive_set_error(&(a
->archive
),
1703 "Failed to clean up lzmadec decompressor");
1704 return (ARCHIVE_FATAL
);
1706 xar
->lzstream_valid
= 0;
1708 case LZMADEC_OK
: /* Decompressor made some progress. */
1711 archive_set_error(&(a
->archive
),
1713 "lzmadec decompression failed(%d)",
1715 return (ARCHIVE_FATAL
);
1717 *used
= avail_in
- xar
->lzstream
.avail_in
;
1718 *outbytes
= avail_out
- xar
->lzstream
.avail_out
;
1721 #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR)
1724 #if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA)
1725 #if !defined(HAVE_LZMADEC_H) || !defined(HAVE_LIBLZMADEC)
1732 if (outbuff
== xar
->outbuff
) {
1735 *outbytes
= avail_in
;
1737 if (avail_out
> avail_in
)
1738 avail_out
= avail_in
;
1739 memcpy(outbuff
, b
, avail_out
);
1741 *outbytes
= avail_out
;
1745 return (ARCHIVE_OK
);
1749 decompression_cleanup(struct archive_read
*a
)
1754 xar
= (struct xar
*)(a
->format
->data
);
1756 if (xar
->stream_valid
) {
1757 if (inflateEnd(&(xar
->stream
)) != Z_OK
) {
1758 archive_set_error(&a
->archive
,
1760 "Failed to clean up zlib decompressor");
1764 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1765 if (xar
->bzstream_valid
) {
1766 if (BZ2_bzDecompressEnd(&(xar
->bzstream
)) != BZ_OK
) {
1767 archive_set_error(&a
->archive
,
1769 "Failed to clean up bzip2 decompressor");
1774 #if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1775 if (xar
->lzstream_valid
)
1776 lzma_end(&(xar
->lzstream
));
1777 #elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA)
1778 if (xar
->lzstream_valid
) {
1779 if (lzmadec_end(&(xar
->lzstream
)) != LZMADEC_OK
) {
1780 archive_set_error(&a
->archive
,
1782 "Failed to clean up lzmadec decompressor");
1791 xmlattr_cleanup(struct xmlattr_list
*list
)
1793 struct xmlattr
*attr
, *next
;
1796 while (attr
!= NULL
) {
1804 list
->last
= &(list
->first
);
1808 file_new(struct archive_read
*a
, struct xar
*xar
, struct xmlattr_list
*list
)
1810 struct xar_file
*file
;
1811 struct xmlattr
*attr
;
1813 file
= calloc(1, sizeof(*file
));
1815 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
1816 return (ARCHIVE_FATAL
);
1818 file
->parent
= xar
->file
;
1819 file
->mode
= 0777 | AE_IFREG
;
1820 file
->atime
= time(NULL
);
1821 file
->mtime
= time(NULL
);
1824 for (attr
= list
->first
; attr
!= NULL
; attr
= attr
->next
) {
1825 if (strcmp(attr
->name
, "id") == 0)
1826 file
->id
= atol10(attr
->value
, strlen(attr
->value
));
1829 if (heap_add_entry(a
, &(xar
->file_queue
), file
) != ARCHIVE_OK
)
1830 return (ARCHIVE_FATAL
);
1831 return (ARCHIVE_OK
);
1835 file_free(struct xar_file
*file
)
1837 struct xattr
*xattr
;
1839 archive_string_free(&(file
->pathname
));
1840 archive_string_free(&(file
->symlink
));
1841 archive_string_free(&(file
->uname
));
1842 archive_string_free(&(file
->gname
));
1843 archive_string_free(&(file
->hardlink
));
1844 xattr
= file
->xattr_list
;
1845 while (xattr
!= NULL
) {
1857 xattr_new(struct archive_read
*a
, struct xar
*xar
, struct xmlattr_list
*list
)
1859 struct xattr
*xattr
, **nx
;
1860 struct xmlattr
*attr
;
1862 xattr
= calloc(1, sizeof(*xattr
));
1863 if (xattr
== NULL
) {
1864 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
1865 return (ARCHIVE_FATAL
);
1868 for (attr
= list
->first
; attr
!= NULL
; attr
= attr
->next
) {
1869 if (strcmp(attr
->name
, "id") == 0)
1870 xattr
->id
= atol10(attr
->value
, strlen(attr
->value
));
1872 /* Chain to xattr list. */
1873 for (nx
= &(xar
->file
->xattr_list
);
1874 *nx
!= NULL
; nx
= &((*nx
)->next
)) {
1875 if (xattr
->id
< (*nx
)->id
)
1881 return (ARCHIVE_OK
);
1885 xattr_free(struct xattr
*xattr
)
1887 archive_string_free(&(xattr
->name
));
1892 getencoding(struct xmlattr_list
*list
)
1894 struct xmlattr
*attr
;
1895 enum enctype encoding
= NONE
;
1897 for (attr
= list
->first
; attr
!= NULL
; attr
= attr
->next
) {
1898 if (strcmp(attr
->name
, "style") == 0) {
1899 if (strcmp(attr
->value
, "application/octet-stream") == 0)
1901 else if (strcmp(attr
->value
, "application/x-gzip") == 0)
1903 else if (strcmp(attr
->value
, "application/x-bzip2") == 0)
1905 else if (strcmp(attr
->value
, "application/x-lzma") == 0)
1907 else if (strcmp(attr
->value
, "application/x-xz") == 0)
1915 getsumalgorithm(struct xmlattr_list
*list
)
1917 struct xmlattr
*attr
;
1918 int alg
= CKSUM_NONE
;
1920 for (attr
= list
->first
; attr
!= NULL
; attr
= attr
->next
) {
1921 if (strcmp(attr
->name
, "style") == 0) {
1922 const char *v
= attr
->value
;
1923 if ((v
[0] == 'S' || v
[0] == 's') &&
1924 (v
[1] == 'H' || v
[1] == 'h') &&
1925 (v
[2] == 'A' || v
[2] == 'a') &&
1926 v
[3] == '1' && v
[4] == '\0')
1928 if ((v
[0] == 'M' || v
[0] == 'm') &&
1929 (v
[1] == 'D' || v
[1] == 'd') &&
1930 v
[2] == '5' && v
[3] == '\0')
1938 unknowntag_start(struct archive_read
*a
, struct xar
*xar
, const char *name
)
1940 struct unknown_tag
*tag
;
1942 tag
= malloc(sizeof(*tag
));
1944 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
1945 return (ARCHIVE_FATAL
);
1947 tag
->next
= xar
->unknowntags
;
1948 archive_string_init(&(tag
->name
));
1949 archive_strcpy(&(tag
->name
), name
);
1950 if (xar
->unknowntags
== NULL
) {
1952 fprintf(stderr
, "UNKNOWNTAG_START:%s\n", name
);
1954 xar
->xmlsts_unknown
= xar
->xmlsts
;
1955 xar
->xmlsts
= UNKNOWN
;
1957 xar
->unknowntags
= tag
;
1958 return (ARCHIVE_OK
);
1962 unknowntag_end(struct xar
*xar
, const char *name
)
1964 struct unknown_tag
*tag
;
1966 tag
= xar
->unknowntags
;
1967 if (tag
== NULL
|| name
== NULL
)
1969 if (strcmp(tag
->name
.s
, name
) == 0) {
1970 xar
->unknowntags
= tag
->next
;
1971 archive_string_free(&(tag
->name
));
1973 if (xar
->unknowntags
== NULL
) {
1975 fprintf(stderr
, "UNKNOWNTAG_END:%s\n", name
);
1977 xar
->xmlsts
= xar
->xmlsts_unknown
;
1983 xml_start(struct archive_read
*a
, const char *name
, struct xmlattr_list
*list
)
1986 struct xmlattr
*attr
;
1988 xar
= (struct xar
*)(a
->format
->data
);
1991 fprintf(stderr
, "xml_sta:[%s]\n", name
);
1992 for (attr
= list
->first
; attr
!= NULL
; attr
= attr
->next
)
1993 fprintf(stderr
, " attr:\"%s\"=\"%s\"\n",
1994 attr
->name
, attr
->value
);
1996 xar
->base64text
= 0;
1997 switch (xar
->xmlsts
) {
1999 if (strcmp(name
, "xar") == 0)
2002 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2003 return (ARCHIVE_FATAL
);
2006 if (strcmp(name
, "toc") == 0)
2009 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2010 return (ARCHIVE_FATAL
);
2013 if (strcmp(name
, "creation-time") == 0)
2014 xar
->xmlsts
= TOC_CREATION_TIME
;
2015 else if (strcmp(name
, "checksum") == 0)
2016 xar
->xmlsts
= TOC_CHECKSUM
;
2017 else if (strcmp(name
, "file") == 0) {
2018 if (file_new(a
, xar
, list
) != ARCHIVE_OK
)
2019 return (ARCHIVE_FATAL
);
2020 xar
->xmlsts
= TOC_FILE
;
2023 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2024 return (ARCHIVE_FATAL
);
2027 if (strcmp(name
, "offset") == 0)
2028 xar
->xmlsts
= TOC_CHECKSUM_OFFSET
;
2029 else if (strcmp(name
, "size") == 0)
2030 xar
->xmlsts
= TOC_CHECKSUM_SIZE
;
2032 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2033 return (ARCHIVE_FATAL
);
2036 if (strcmp(name
, "file") == 0) {
2037 if (file_new(a
, xar
, list
) != ARCHIVE_OK
)
2038 return (ARCHIVE_FATAL
);
2040 else if (strcmp(name
, "data") == 0)
2041 xar
->xmlsts
= FILE_DATA
;
2042 else if (strcmp(name
, "ea") == 0) {
2043 if (xattr_new(a
, xar
, list
) != ARCHIVE_OK
)
2044 return (ARCHIVE_FATAL
);
2045 xar
->xmlsts
= FILE_EA
;
2047 else if (strcmp(name
, "ctime") == 0)
2048 xar
->xmlsts
= FILE_CTIME
;
2049 else if (strcmp(name
, "mtime") == 0)
2050 xar
->xmlsts
= FILE_MTIME
;
2051 else if (strcmp(name
, "atime") == 0)
2052 xar
->xmlsts
= FILE_ATIME
;
2053 else if (strcmp(name
, "group") == 0)
2054 xar
->xmlsts
= FILE_GROUP
;
2055 else if (strcmp(name
, "gid") == 0)
2056 xar
->xmlsts
= FILE_GID
;
2057 else if (strcmp(name
, "user") == 0)
2058 xar
->xmlsts
= FILE_USER
;
2059 else if (strcmp(name
, "uid") == 0)
2060 xar
->xmlsts
= FILE_UID
;
2061 else if (strcmp(name
, "mode") == 0)
2062 xar
->xmlsts
= FILE_MODE
;
2063 else if (strcmp(name
, "device") == 0)
2064 xar
->xmlsts
= FILE_DEVICE
;
2065 else if (strcmp(name
, "deviceno") == 0)
2066 xar
->xmlsts
= FILE_DEVICENO
;
2067 else if (strcmp(name
, "inode") == 0)
2068 xar
->xmlsts
= FILE_INODE
;
2069 else if (strcmp(name
, "link") == 0)
2070 xar
->xmlsts
= FILE_LINK
;
2071 else if (strcmp(name
, "type") == 0) {
2072 xar
->xmlsts
= FILE_TYPE
;
2073 for (attr
= list
->first
; attr
!= NULL
;
2074 attr
= attr
->next
) {
2075 if (strcmp(attr
->name
, "link") != 0)
2077 if (strcmp(attr
->value
, "original") == 0) {
2078 xar
->file
->hdnext
= xar
->hdlink_orgs
;
2079 xar
->hdlink_orgs
= xar
->file
;
2081 xar
->file
->link
= (unsigned)atol10(attr
->value
,
2082 strlen(attr
->value
));
2083 if (xar
->file
->link
> 0)
2084 if (add_link(a
, xar
, xar
->file
) != ARCHIVE_OK
) {
2085 return (ARCHIVE_FATAL
);
2090 else if (strcmp(name
, "name") == 0) {
2091 xar
->xmlsts
= FILE_NAME
;
2092 for (attr
= list
->first
; attr
!= NULL
;
2093 attr
= attr
->next
) {
2094 if (strcmp(attr
->name
, "enctype") == 0 &&
2095 strcmp(attr
->value
, "base64") == 0)
2096 xar
->base64text
= 1;
2099 else if (strcmp(name
, "acl") == 0)
2100 xar
->xmlsts
= FILE_ACL
;
2101 else if (strcmp(name
, "flags") == 0)
2102 xar
->xmlsts
= FILE_FLAGS
;
2103 else if (strcmp(name
, "ext2") == 0)
2104 xar
->xmlsts
= FILE_EXT2
;
2106 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2107 return (ARCHIVE_FATAL
);
2110 if (strcmp(name
, "length") == 0)
2111 xar
->xmlsts
= FILE_DATA_LENGTH
;
2112 else if (strcmp(name
, "offset") == 0)
2113 xar
->xmlsts
= FILE_DATA_OFFSET
;
2114 else if (strcmp(name
, "size") == 0)
2115 xar
->xmlsts
= FILE_DATA_SIZE
;
2116 else if (strcmp(name
, "encoding") == 0) {
2117 xar
->xmlsts
= FILE_DATA_ENCODING
;
2118 xar
->file
->encoding
= getencoding(list
);
2120 else if (strcmp(name
, "archived-checksum") == 0) {
2121 xar
->xmlsts
= FILE_DATA_A_CHECKSUM
;
2122 xar
->file
->a_sum
.alg
= getsumalgorithm(list
);
2124 else if (strcmp(name
, "extracted-checksum") == 0) {
2125 xar
->xmlsts
= FILE_DATA_E_CHECKSUM
;
2126 xar
->file
->e_sum
.alg
= getsumalgorithm(list
);
2128 else if (strcmp(name
, "content") == 0)
2129 xar
->xmlsts
= FILE_DATA_CONTENT
;
2131 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2132 return (ARCHIVE_FATAL
);
2135 if (strcmp(name
, "major") == 0)
2136 xar
->xmlsts
= FILE_DEVICE_MAJOR
;
2137 else if (strcmp(name
, "minor") == 0)
2138 xar
->xmlsts
= FILE_DEVICE_MINOR
;
2140 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2141 return (ARCHIVE_FATAL
);
2143 case FILE_DATA_CONTENT
:
2144 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2145 return (ARCHIVE_FATAL
);
2148 if (strcmp(name
, "length") == 0)
2149 xar
->xmlsts
= FILE_EA_LENGTH
;
2150 else if (strcmp(name
, "offset") == 0)
2151 xar
->xmlsts
= FILE_EA_OFFSET
;
2152 else if (strcmp(name
, "size") == 0)
2153 xar
->xmlsts
= FILE_EA_SIZE
;
2154 else if (strcmp(name
, "encoding") == 0) {
2155 xar
->xmlsts
= FILE_EA_ENCODING
;
2156 xar
->xattr
->encoding
= getencoding(list
);
2157 } else if (strcmp(name
, "archived-checksum") == 0)
2158 xar
->xmlsts
= FILE_EA_A_CHECKSUM
;
2159 else if (strcmp(name
, "extracted-checksum") == 0)
2160 xar
->xmlsts
= FILE_EA_E_CHECKSUM
;
2161 else if (strcmp(name
, "name") == 0)
2162 xar
->xmlsts
= FILE_EA_NAME
;
2163 else if (strcmp(name
, "fstype") == 0)
2164 xar
->xmlsts
= FILE_EA_FSTYPE
;
2166 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2167 return (ARCHIVE_FATAL
);
2170 if (strcmp(name
, "appleextended") == 0)
2171 xar
->xmlsts
= FILE_ACL_APPLEEXTENDED
;
2172 else if (strcmp(name
, "default") == 0)
2173 xar
->xmlsts
= FILE_ACL_DEFAULT
;
2174 else if (strcmp(name
, "access") == 0)
2175 xar
->xmlsts
= FILE_ACL_ACCESS
;
2177 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2178 return (ARCHIVE_FATAL
);
2181 if (!xml_parse_file_flags(xar
, name
))
2182 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2183 return (ARCHIVE_FATAL
);
2186 if (!xml_parse_file_ext2(xar
, name
))
2187 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2188 return (ARCHIVE_FATAL
);
2190 case TOC_CREATION_TIME
:
2191 case TOC_CHECKSUM_OFFSET
:
2192 case TOC_CHECKSUM_SIZE
:
2193 case FILE_DATA_LENGTH
:
2194 case FILE_DATA_OFFSET
:
2195 case FILE_DATA_SIZE
:
2196 case FILE_DATA_ENCODING
:
2197 case FILE_DATA_A_CHECKSUM
:
2198 case FILE_DATA_E_CHECKSUM
:
2199 case FILE_EA_LENGTH
:
2200 case FILE_EA_OFFSET
:
2202 case FILE_EA_ENCODING
:
2203 case FILE_EA_A_CHECKSUM
:
2204 case FILE_EA_E_CHECKSUM
:
2206 case FILE_EA_FSTYPE
:
2215 case FILE_DEVICE_MAJOR
:
2216 case FILE_DEVICE_MINOR
:
2222 case FILE_ACL_DEFAULT
:
2223 case FILE_ACL_ACCESS
:
2224 case FILE_ACL_APPLEEXTENDED
:
2225 case FILE_FLAGS_USER_NODUMP
:
2226 case FILE_FLAGS_USER_IMMUTABLE
:
2227 case FILE_FLAGS_USER_APPEND
:
2228 case FILE_FLAGS_USER_OPAQUE
:
2229 case FILE_FLAGS_USER_NOUNLINK
:
2230 case FILE_FLAGS_SYS_ARCHIVED
:
2231 case FILE_FLAGS_SYS_IMMUTABLE
:
2232 case FILE_FLAGS_SYS_APPEND
:
2233 case FILE_FLAGS_SYS_NOUNLINK
:
2234 case FILE_FLAGS_SYS_SNAPSHOT
:
2235 case FILE_EXT2_SecureDeletion
:
2236 case FILE_EXT2_Undelete
:
2237 case FILE_EXT2_Compress
:
2238 case FILE_EXT2_Synchronous
:
2239 case FILE_EXT2_Immutable
:
2240 case FILE_EXT2_AppendOnly
:
2241 case FILE_EXT2_NoDump
:
2242 case FILE_EXT2_NoAtime
:
2243 case FILE_EXT2_CompDirty
:
2244 case FILE_EXT2_CompBlock
:
2245 case FILE_EXT2_NoCompBlock
:
2246 case FILE_EXT2_CompError
:
2247 case FILE_EXT2_BTree
:
2248 case FILE_EXT2_HashIndexed
:
2249 case FILE_EXT2_iMagic
:
2250 case FILE_EXT2_Journaled
:
2251 case FILE_EXT2_NoTail
:
2252 case FILE_EXT2_DirSync
:
2253 case FILE_EXT2_TopDir
:
2254 case FILE_EXT2_Reserved
:
2256 if (unknowntag_start(a
, xar
, name
) != ARCHIVE_OK
)
2257 return (ARCHIVE_FATAL
);
2260 return (ARCHIVE_OK
);
2264 xml_end(void *userData
, const char *name
)
2266 struct archive_read
*a
;
2269 a
= (struct archive_read
*)userData
;
2270 xar
= (struct xar
*)(a
->format
->data
);
2273 fprintf(stderr
, "xml_end:[%s]\n", name
);
2275 switch (xar
->xmlsts
) {
2279 if (strcmp(name
, "xar") == 0)
2283 if (strcmp(name
, "toc") == 0)
2286 case TOC_CREATION_TIME
:
2287 if (strcmp(name
, "creation-time") == 0)
2291 if (strcmp(name
, "checksum") == 0)
2294 case TOC_CHECKSUM_OFFSET
:
2295 if (strcmp(name
, "offset") == 0)
2296 xar
->xmlsts
= TOC_CHECKSUM
;
2298 case TOC_CHECKSUM_SIZE
:
2299 if (strcmp(name
, "size") == 0)
2300 xar
->xmlsts
= TOC_CHECKSUM
;
2303 if (strcmp(name
, "file") == 0) {
2304 if (xar
->file
->parent
!= NULL
&&
2305 ((xar
->file
->mode
& AE_IFMT
) == AE_IFDIR
))
2306 xar
->file
->parent
->subdirs
++;
2307 xar
->file
= xar
->file
->parent
;
2308 if (xar
->file
== NULL
)
2313 if (strcmp(name
, "data") == 0)
2314 xar
->xmlsts
= TOC_FILE
;
2316 case FILE_DATA_LENGTH
:
2317 if (strcmp(name
, "length") == 0)
2318 xar
->xmlsts
= FILE_DATA
;
2320 case FILE_DATA_OFFSET
:
2321 if (strcmp(name
, "offset") == 0)
2322 xar
->xmlsts
= FILE_DATA
;
2324 case FILE_DATA_SIZE
:
2325 if (strcmp(name
, "size") == 0)
2326 xar
->xmlsts
= FILE_DATA
;
2328 case FILE_DATA_ENCODING
:
2329 if (strcmp(name
, "encoding") == 0)
2330 xar
->xmlsts
= FILE_DATA
;
2332 case FILE_DATA_A_CHECKSUM
:
2333 if (strcmp(name
, "archived-checksum") == 0)
2334 xar
->xmlsts
= FILE_DATA
;
2336 case FILE_DATA_E_CHECKSUM
:
2337 if (strcmp(name
, "extracted-checksum") == 0)
2338 xar
->xmlsts
= FILE_DATA
;
2340 case FILE_DATA_CONTENT
:
2341 if (strcmp(name
, "content") == 0)
2342 xar
->xmlsts
= FILE_DATA
;
2345 if (strcmp(name
, "ea") == 0) {
2346 xar
->xmlsts
= TOC_FILE
;
2350 case FILE_EA_LENGTH
:
2351 if (strcmp(name
, "length") == 0)
2352 xar
->xmlsts
= FILE_EA
;
2354 case FILE_EA_OFFSET
:
2355 if (strcmp(name
, "offset") == 0)
2356 xar
->xmlsts
= FILE_EA
;
2359 if (strcmp(name
, "size") == 0)
2360 xar
->xmlsts
= FILE_EA
;
2362 case FILE_EA_ENCODING
:
2363 if (strcmp(name
, "encoding") == 0)
2364 xar
->xmlsts
= FILE_EA
;
2366 case FILE_EA_A_CHECKSUM
:
2367 if (strcmp(name
, "archived-checksum") == 0)
2368 xar
->xmlsts
= FILE_EA
;
2370 case FILE_EA_E_CHECKSUM
:
2371 if (strcmp(name
, "extracted-checksum") == 0)
2372 xar
->xmlsts
= FILE_EA
;
2375 if (strcmp(name
, "name") == 0)
2376 xar
->xmlsts
= FILE_EA
;
2378 case FILE_EA_FSTYPE
:
2379 if (strcmp(name
, "fstype") == 0)
2380 xar
->xmlsts
= FILE_EA
;
2383 if (strcmp(name
, "ctime") == 0)
2384 xar
->xmlsts
= TOC_FILE
;
2387 if (strcmp(name
, "mtime") == 0)
2388 xar
->xmlsts
= TOC_FILE
;
2391 if (strcmp(name
, "atime") == 0)
2392 xar
->xmlsts
= TOC_FILE
;
2395 if (strcmp(name
, "group") == 0)
2396 xar
->xmlsts
= TOC_FILE
;
2399 if (strcmp(name
, "gid") == 0)
2400 xar
->xmlsts
= TOC_FILE
;
2403 if (strcmp(name
, "user") == 0)
2404 xar
->xmlsts
= TOC_FILE
;
2407 if (strcmp(name
, "uid") == 0)
2408 xar
->xmlsts
= TOC_FILE
;
2411 if (strcmp(name
, "mode") == 0)
2412 xar
->xmlsts
= TOC_FILE
;
2415 if (strcmp(name
, "device") == 0)
2416 xar
->xmlsts
= TOC_FILE
;
2418 case FILE_DEVICE_MAJOR
:
2419 if (strcmp(name
, "major") == 0)
2420 xar
->xmlsts
= FILE_DEVICE
;
2422 case FILE_DEVICE_MINOR
:
2423 if (strcmp(name
, "minor") == 0)
2424 xar
->xmlsts
= FILE_DEVICE
;
2427 if (strcmp(name
, "deviceno") == 0)
2428 xar
->xmlsts
= TOC_FILE
;
2431 if (strcmp(name
, "inode") == 0)
2432 xar
->xmlsts
= TOC_FILE
;
2435 if (strcmp(name
, "link") == 0)
2436 xar
->xmlsts
= TOC_FILE
;
2439 if (strcmp(name
, "type") == 0)
2440 xar
->xmlsts
= TOC_FILE
;
2443 if (strcmp(name
, "name") == 0)
2444 xar
->xmlsts
= TOC_FILE
;
2447 if (strcmp(name
, "acl") == 0)
2448 xar
->xmlsts
= TOC_FILE
;
2450 case FILE_ACL_DEFAULT
:
2451 if (strcmp(name
, "default") == 0)
2452 xar
->xmlsts
= FILE_ACL
;
2454 case FILE_ACL_ACCESS
:
2455 if (strcmp(name
, "access") == 0)
2456 xar
->xmlsts
= FILE_ACL
;
2458 case FILE_ACL_APPLEEXTENDED
:
2459 if (strcmp(name
, "appleextended") == 0)
2460 xar
->xmlsts
= FILE_ACL
;
2463 if (strcmp(name
, "flags") == 0)
2464 xar
->xmlsts
= TOC_FILE
;
2466 case FILE_FLAGS_USER_NODUMP
:
2467 if (strcmp(name
, "UserNoDump") == 0)
2468 xar
->xmlsts
= FILE_FLAGS
;
2470 case FILE_FLAGS_USER_IMMUTABLE
:
2471 if (strcmp(name
, "UserImmutable") == 0)
2472 xar
->xmlsts
= FILE_FLAGS
;
2474 case FILE_FLAGS_USER_APPEND
:
2475 if (strcmp(name
, "UserAppend") == 0)
2476 xar
->xmlsts
= FILE_FLAGS
;
2478 case FILE_FLAGS_USER_OPAQUE
:
2479 if (strcmp(name
, "UserOpaque") == 0)
2480 xar
->xmlsts
= FILE_FLAGS
;
2482 case FILE_FLAGS_USER_NOUNLINK
:
2483 if (strcmp(name
, "UserNoUnlink") == 0)
2484 xar
->xmlsts
= FILE_FLAGS
;
2486 case FILE_FLAGS_SYS_ARCHIVED
:
2487 if (strcmp(name
, "SystemArchived") == 0)
2488 xar
->xmlsts
= FILE_FLAGS
;
2490 case FILE_FLAGS_SYS_IMMUTABLE
:
2491 if (strcmp(name
, "SystemImmutable") == 0)
2492 xar
->xmlsts
= FILE_FLAGS
;
2494 case FILE_FLAGS_SYS_APPEND
:
2495 if (strcmp(name
, "SystemAppend") == 0)
2496 xar
->xmlsts
= FILE_FLAGS
;
2498 case FILE_FLAGS_SYS_NOUNLINK
:
2499 if (strcmp(name
, "SystemNoUnlink") == 0)
2500 xar
->xmlsts
= FILE_FLAGS
;
2502 case FILE_FLAGS_SYS_SNAPSHOT
:
2503 if (strcmp(name
, "SystemSnapshot") == 0)
2504 xar
->xmlsts
= FILE_FLAGS
;
2507 if (strcmp(name
, "ext2") == 0)
2508 xar
->xmlsts
= TOC_FILE
;
2510 case FILE_EXT2_SecureDeletion
:
2511 if (strcmp(name
, "SecureDeletion") == 0)
2512 xar
->xmlsts
= FILE_EXT2
;
2514 case FILE_EXT2_Undelete
:
2515 if (strcmp(name
, "Undelete") == 0)
2516 xar
->xmlsts
= FILE_EXT2
;
2518 case FILE_EXT2_Compress
:
2519 if (strcmp(name
, "Compress") == 0)
2520 xar
->xmlsts
= FILE_EXT2
;
2522 case FILE_EXT2_Synchronous
:
2523 if (strcmp(name
, "Synchronous") == 0)
2524 xar
->xmlsts
= FILE_EXT2
;
2526 case FILE_EXT2_Immutable
:
2527 if (strcmp(name
, "Immutable") == 0)
2528 xar
->xmlsts
= FILE_EXT2
;
2530 case FILE_EXT2_AppendOnly
:
2531 if (strcmp(name
, "AppendOnly") == 0)
2532 xar
->xmlsts
= FILE_EXT2
;
2534 case FILE_EXT2_NoDump
:
2535 if (strcmp(name
, "NoDump") == 0)
2536 xar
->xmlsts
= FILE_EXT2
;
2538 case FILE_EXT2_NoAtime
:
2539 if (strcmp(name
, "NoAtime") == 0)
2540 xar
->xmlsts
= FILE_EXT2
;
2542 case FILE_EXT2_CompDirty
:
2543 if (strcmp(name
, "CompDirty") == 0)
2544 xar
->xmlsts
= FILE_EXT2
;
2546 case FILE_EXT2_CompBlock
:
2547 if (strcmp(name
, "CompBlock") == 0)
2548 xar
->xmlsts
= FILE_EXT2
;
2550 case FILE_EXT2_NoCompBlock
:
2551 if (strcmp(name
, "NoCompBlock") == 0)
2552 xar
->xmlsts
= FILE_EXT2
;
2554 case FILE_EXT2_CompError
:
2555 if (strcmp(name
, "CompError") == 0)
2556 xar
->xmlsts
= FILE_EXT2
;
2558 case FILE_EXT2_BTree
:
2559 if (strcmp(name
, "BTree") == 0)
2560 xar
->xmlsts
= FILE_EXT2
;
2562 case FILE_EXT2_HashIndexed
:
2563 if (strcmp(name
, "HashIndexed") == 0)
2564 xar
->xmlsts
= FILE_EXT2
;
2566 case FILE_EXT2_iMagic
:
2567 if (strcmp(name
, "iMagic") == 0)
2568 xar
->xmlsts
= FILE_EXT2
;
2570 case FILE_EXT2_Journaled
:
2571 if (strcmp(name
, "Journaled") == 0)
2572 xar
->xmlsts
= FILE_EXT2
;
2574 case FILE_EXT2_NoTail
:
2575 if (strcmp(name
, "NoTail") == 0)
2576 xar
->xmlsts
= FILE_EXT2
;
2578 case FILE_EXT2_DirSync
:
2579 if (strcmp(name
, "DirSync") == 0)
2580 xar
->xmlsts
= FILE_EXT2
;
2582 case FILE_EXT2_TopDir
:
2583 if (strcmp(name
, "TopDir") == 0)
2584 xar
->xmlsts
= FILE_EXT2
;
2586 case FILE_EXT2_Reserved
:
2587 if (strcmp(name
, "Reserved") == 0)
2588 xar
->xmlsts
= FILE_EXT2
;
2591 unknowntag_end(xar
, name
);
2596 static const int base64
[256] = {
2597 -1, -1, -1, -1, -1, -1, -1, -1,
2598 -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */
2599 -1, -1, -1, -1, -1, -1, -1, -1,
2600 -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */
2601 -1, -1, -1, -1, -1, -1, -1, -1,
2602 -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */
2603 52, 53, 54, 55, 56, 57, 58, 59,
2604 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */
2605 -1, 0, 1, 2, 3, 4, 5, 6,
2606 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */
2607 15, 16, 17, 18, 19, 20, 21, 22,
2608 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */
2609 -1, 26, 27, 28, 29, 30, 31, 32,
2610 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */
2611 41, 42, 43, 44, 45, 46, 47, 48,
2612 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */
2613 -1, -1, -1, -1, -1, -1, -1, -1,
2614 -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */
2615 -1, -1, -1, -1, -1, -1, -1, -1,
2616 -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */
2617 -1, -1, -1, -1, -1, -1, -1, -1,
2618 -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */
2619 -1, -1, -1, -1, -1, -1, -1, -1,
2620 -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */
2621 -1, -1, -1, -1, -1, -1, -1, -1,
2622 -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */
2623 -1, -1, -1, -1, -1, -1, -1, -1,
2624 -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */
2625 -1, -1, -1, -1, -1, -1, -1, -1,
2626 -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */
2627 -1, -1, -1, -1, -1, -1, -1, -1,
2628 -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */
2632 strappend_base64(struct xar
*xar
,
2633 struct archive_string
*as
, const char *s
, size_t l
)
2635 unsigned char buff
[256];
2637 const unsigned char *b
;
2640 (void)xar
; /* UNUSED */
2643 b
= (const unsigned char *)s
;
2648 if (base64
[b
[0]] < 0 || base64
[b
[1]] < 0)
2650 n
= base64
[*b
++] << 18;
2651 n
|= base64
[*b
++] << 12;
2659 n
|= base64
[*b
++] << 6;
2660 *out
++ = (n
>> 8) & 0xFF;
2672 if (len
+3 >= sizeof(buff
)) {
2673 archive_strncat(as
, (const char *)buff
, len
);
2679 archive_strncat(as
, (const char *)buff
, len
);
2683 xml_data(void *userData
, const char *s
, int len
)
2685 struct archive_read
*a
;
2688 a
= (struct archive_read
*)userData
;
2689 xar
= (struct xar
*)(a
->format
->data
);
2694 if (len
> (int)(sizeof(buff
)-1))
2695 len
= (int)(sizeof(buff
)-1);
2696 strncpy(buff
, s
, len
);
2698 fprintf(stderr
, "\tlen=%d:\"%s\"\n", len
, buff
);
2701 switch (xar
->xmlsts
) {
2702 case TOC_CHECKSUM_OFFSET
:
2703 xar
->toc_chksum_offset
= atol10(s
, len
);
2705 case TOC_CHECKSUM_SIZE
:
2706 xar
->toc_chksum_size
= atol10(s
, len
);
2711 if (xar
->file
== NULL
)
2714 switch (xar
->xmlsts
) {
2716 if (xar
->file
->parent
!= NULL
) {
2717 archive_string_concat(&(xar
->file
->pathname
),
2718 &(xar
->file
->parent
->pathname
));
2719 archive_strappend_char(&(xar
->file
->pathname
), '/');
2721 xar
->file
->has
|= HAS_PATHNAME
;
2722 if (xar
->base64text
) {
2723 strappend_base64(xar
,
2724 &(xar
->file
->pathname
), s
, len
);
2726 archive_strncat(&(xar
->file
->pathname
), s
, len
);
2729 xar
->file
->has
|= HAS_SYMLINK
;
2730 archive_strncpy(&(xar
->file
->symlink
), s
, len
);
2733 if (strncmp("file", s
, len
) == 0 ||
2734 strncmp("hardlink", s
, len
) == 0)
2736 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFREG
;
2737 if (strncmp("directory", s
, len
) == 0)
2739 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFDIR
;
2740 if (strncmp("symlink", s
, len
) == 0)
2742 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFLNK
;
2743 if (strncmp("character special", s
, len
) == 0)
2745 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFCHR
;
2746 if (strncmp("block special", s
, len
) == 0)
2748 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFBLK
;
2749 if (strncmp("socket", s
, len
) == 0)
2751 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFSOCK
;
2752 if (strncmp("fifo", s
, len
) == 0)
2754 (xar
->file
->mode
& ~AE_IFMT
) | AE_IFIFO
;
2755 xar
->file
->has
|= HAS_TYPE
;
2758 xar
->file
->has
|= HAS_INO
;
2759 xar
->file
->ino64
= atol10(s
, len
);
2761 case FILE_DEVICE_MAJOR
:
2762 xar
->file
->has
|= HAS_DEVMAJOR
;
2763 xar
->file
->devmajor
= (dev_t
)atol10(s
, len
);
2765 case FILE_DEVICE_MINOR
:
2766 xar
->file
->has
|= HAS_DEVMINOR
;
2767 xar
->file
->devminor
= (dev_t
)atol10(s
, len
);
2770 xar
->file
->has
|= HAS_DEV
;
2771 xar
->file
->dev
= (dev_t
)atol10(s
, len
);
2774 xar
->file
->has
|= HAS_MODE
;
2776 (xar
->file
->mode
& AE_IFMT
) |
2777 ((mode_t
)(atol8(s
, len
)) & ~AE_IFMT
);
2780 xar
->file
->has
|= HAS_GID
;
2781 archive_strncpy(&(xar
->file
->gname
), s
, len
);
2784 xar
->file
->has
|= HAS_GID
;
2785 xar
->file
->gid
= atol10(s
, len
);
2788 xar
->file
->has
|= HAS_UID
;
2789 archive_strncpy(&(xar
->file
->uname
), s
, len
);
2792 xar
->file
->has
|= HAS_UID
;
2793 xar
->file
->uid
= atol10(s
, len
);
2796 xar
->file
->has
|= HAS_TIME
;
2797 xar
->file
->ctime
= parse_time(s
, len
);
2800 xar
->file
->has
|= HAS_TIME
;
2801 xar
->file
->mtime
= parse_time(s
, len
);
2804 xar
->file
->has
|= HAS_TIME
;
2805 xar
->file
->atime
= parse_time(s
, len
);
2807 case FILE_DATA_LENGTH
:
2808 xar
->file
->has
|= HAS_DATA
;
2809 xar
->file
->length
= atol10(s
, len
);
2811 case FILE_DATA_OFFSET
:
2812 xar
->file
->has
|= HAS_DATA
;
2813 xar
->file
->offset
= atol10(s
, len
);
2815 case FILE_DATA_SIZE
:
2816 xar
->file
->has
|= HAS_DATA
;
2817 xar
->file
->size
= atol10(s
, len
);
2819 case FILE_DATA_A_CHECKSUM
:
2820 xar
->file
->a_sum
.len
= atohex(xar
->file
->a_sum
.val
,
2821 sizeof(xar
->file
->a_sum
.val
), s
, len
);
2823 case FILE_DATA_E_CHECKSUM
:
2824 xar
->file
->e_sum
.len
= atohex(xar
->file
->e_sum
.val
,
2825 sizeof(xar
->file
->e_sum
.val
), s
, len
);
2827 case FILE_EA_LENGTH
:
2828 xar
->file
->has
|= HAS_XATTR
;
2829 xar
->xattr
->length
= atol10(s
, len
);
2831 case FILE_EA_OFFSET
:
2832 xar
->file
->has
|= HAS_XATTR
;
2833 xar
->xattr
->offset
= atol10(s
, len
);
2836 xar
->file
->has
|= HAS_XATTR
;
2837 xar
->xattr
->size
= atol10(s
, len
);
2839 case FILE_EA_A_CHECKSUM
:
2840 xar
->file
->has
|= HAS_XATTR
;
2841 xar
->xattr
->a_sum
.len
= atohex(xar
->xattr
->a_sum
.val
,
2842 sizeof(xar
->xattr
->a_sum
.val
), s
, len
);
2844 case FILE_EA_E_CHECKSUM
:
2845 xar
->file
->has
|= HAS_XATTR
;
2846 xar
->xattr
->e_sum
.len
= atohex(xar
->xattr
->e_sum
.val
,
2847 sizeof(xar
->xattr
->e_sum
.val
), s
, len
);
2850 xar
->file
->has
|= HAS_XATTR
;
2851 archive_strncpy(&(xar
->xattr
->name
), s
, len
);
2853 case FILE_EA_FSTYPE
:
2854 xar
->file
->has
|= HAS_XATTR
;
2855 archive_strncpy(&(xar
->xattr
->fstype
), s
, len
);
2858 case FILE_ACL_DEFAULT
:
2859 case FILE_ACL_ACCESS
:
2860 case FILE_ACL_APPLEEXTENDED
:
2861 xar
->file
->has
|= HAS_ACL
;
2867 case TOC_CREATION_TIME
:
2869 case TOC_CHECKSUM_OFFSET
:
2870 case TOC_CHECKSUM_SIZE
:
2873 case FILE_DATA_ENCODING
:
2874 case FILE_DATA_CONTENT
:
2877 case FILE_EA_ENCODING
:
2880 case FILE_FLAGS_USER_NODUMP
:
2881 case FILE_FLAGS_USER_IMMUTABLE
:
2882 case FILE_FLAGS_USER_APPEND
:
2883 case FILE_FLAGS_USER_OPAQUE
:
2884 case FILE_FLAGS_USER_NOUNLINK
:
2885 case FILE_FLAGS_SYS_ARCHIVED
:
2886 case FILE_FLAGS_SYS_IMMUTABLE
:
2887 case FILE_FLAGS_SYS_APPEND
:
2888 case FILE_FLAGS_SYS_NOUNLINK
:
2889 case FILE_FLAGS_SYS_SNAPSHOT
:
2891 case FILE_EXT2_SecureDeletion
:
2892 case FILE_EXT2_Undelete
:
2893 case FILE_EXT2_Compress
:
2894 case FILE_EXT2_Synchronous
:
2895 case FILE_EXT2_Immutable
:
2896 case FILE_EXT2_AppendOnly
:
2897 case FILE_EXT2_NoDump
:
2898 case FILE_EXT2_NoAtime
:
2899 case FILE_EXT2_CompDirty
:
2900 case FILE_EXT2_CompBlock
:
2901 case FILE_EXT2_NoCompBlock
:
2902 case FILE_EXT2_CompError
:
2903 case FILE_EXT2_BTree
:
2904 case FILE_EXT2_HashIndexed
:
2905 case FILE_EXT2_iMagic
:
2906 case FILE_EXT2_Journaled
:
2907 case FILE_EXT2_NoTail
:
2908 case FILE_EXT2_DirSync
:
2909 case FILE_EXT2_TopDir
:
2910 case FILE_EXT2_Reserved
:
2920 xml_parse_file_flags(struct xar
*xar
, const char *name
)
2922 const char *flag
= NULL
;
2924 if (strcmp(name
, "UserNoDump") == 0) {
2925 xar
->xmlsts
= FILE_FLAGS_USER_NODUMP
;
2928 else if (strcmp(name
, "UserImmutable") == 0) {
2929 xar
->xmlsts
= FILE_FLAGS_USER_IMMUTABLE
;
2930 flag
= "uimmutable";
2932 else if (strcmp(name
, "UserAppend") == 0) {
2933 xar
->xmlsts
= FILE_FLAGS_USER_APPEND
;
2936 else if (strcmp(name
, "UserOpaque") == 0) {
2937 xar
->xmlsts
= FILE_FLAGS_USER_OPAQUE
;
2940 else if (strcmp(name
, "UserNoUnlink") == 0) {
2941 xar
->xmlsts
= FILE_FLAGS_USER_NOUNLINK
;
2944 else if (strcmp(name
, "SystemArchived") == 0) {
2945 xar
->xmlsts
= FILE_FLAGS_SYS_ARCHIVED
;
2948 else if (strcmp(name
, "SystemImmutable") == 0) {
2949 xar
->xmlsts
= FILE_FLAGS_SYS_IMMUTABLE
;
2950 flag
= "simmutable";
2952 else if (strcmp(name
, "SystemAppend") == 0) {
2953 xar
->xmlsts
= FILE_FLAGS_SYS_APPEND
;
2956 else if (strcmp(name
, "SystemNoUnlink") == 0) {
2957 xar
->xmlsts
= FILE_FLAGS_SYS_NOUNLINK
;
2960 else if (strcmp(name
, "SystemSnapshot") == 0) {
2961 xar
->xmlsts
= FILE_FLAGS_SYS_SNAPSHOT
;
2967 xar
->file
->has
|= HAS_FFLAGS
;
2968 if (archive_strlen(&(xar
->file
->fflags_text
)) > 0)
2969 archive_strappend_char(&(xar
->file
->fflags_text
), ',');
2970 archive_strcat(&(xar
->file
->fflags_text
), flag
);
2978 xml_parse_file_ext2(struct xar
*xar
, const char *name
)
2980 const char *flag
= NULL
;
2982 if (strcmp(name
, "SecureDeletion") == 0) {
2983 xar
->xmlsts
= FILE_EXT2_SecureDeletion
;
2984 flag
= "securedeletion";
2986 else if (strcmp(name
, "Undelete") == 0) {
2987 xar
->xmlsts
= FILE_EXT2_Undelete
;
2990 else if (strcmp(name
, "Compress") == 0) {
2991 xar
->xmlsts
= FILE_EXT2_Compress
;
2994 else if (strcmp(name
, "Synchronous") == 0) {
2995 xar
->xmlsts
= FILE_EXT2_Synchronous
;
2998 else if (strcmp(name
, "Immutable") == 0) {
2999 xar
->xmlsts
= FILE_EXT2_Immutable
;
3000 flag
= "simmutable";
3002 else if (strcmp(name
, "AppendOnly") == 0) {
3003 xar
->xmlsts
= FILE_EXT2_AppendOnly
;
3006 else if (strcmp(name
, "NoDump") == 0) {
3007 xar
->xmlsts
= FILE_EXT2_NoDump
;
3010 else if (strcmp(name
, "NoAtime") == 0) {
3011 xar
->xmlsts
= FILE_EXT2_NoAtime
;
3014 else if (strcmp(name
, "CompDirty") == 0) {
3015 xar
->xmlsts
= FILE_EXT2_CompDirty
;
3018 else if (strcmp(name
, "CompBlock") == 0) {
3019 xar
->xmlsts
= FILE_EXT2_CompBlock
;
3022 else if (strcmp(name
, "NoCompBlock") == 0) {
3023 xar
->xmlsts
= FILE_EXT2_NoCompBlock
;
3024 flag
= "nocomprblk";
3026 else if (strcmp(name
, "CompError") == 0) {
3027 xar
->xmlsts
= FILE_EXT2_CompError
;
3030 else if (strcmp(name
, "BTree") == 0) {
3031 xar
->xmlsts
= FILE_EXT2_BTree
;
3034 else if (strcmp(name
, "HashIndexed") == 0) {
3035 xar
->xmlsts
= FILE_EXT2_HashIndexed
;
3038 else if (strcmp(name
, "iMagic") == 0) {
3039 xar
->xmlsts
= FILE_EXT2_iMagic
;
3042 else if (strcmp(name
, "Journaled") == 0) {
3043 xar
->xmlsts
= FILE_EXT2_Journaled
;
3046 else if (strcmp(name
, "NoTail") == 0) {
3047 xar
->xmlsts
= FILE_EXT2_NoTail
;
3050 else if (strcmp(name
, "DirSync") == 0) {
3051 xar
->xmlsts
= FILE_EXT2_DirSync
;
3054 else if (strcmp(name
, "TopDir") == 0) {
3055 xar
->xmlsts
= FILE_EXT2_TopDir
;
3058 else if (strcmp(name
, "Reserved") == 0) {
3059 xar
->xmlsts
= FILE_EXT2_Reserved
;
3065 if (archive_strlen(&(xar
->file
->fflags_text
)) > 0)
3066 archive_strappend_char(&(xar
->file
->fflags_text
), ',');
3067 archive_strcat(&(xar
->file
->fflags_text
), flag
);
3071 #ifdef HAVE_LIBXML_XMLREADER_H
3074 xml2_xmlattr_setup(struct archive_read
*a
,
3075 struct xmlattr_list
*list
, xmlTextReaderPtr reader
)
3077 struct xmlattr
*attr
;
3081 list
->last
= &(list
->first
);
3082 r
= xmlTextReaderMoveToFirstAttribute(reader
);
3084 attr
= malloc(sizeof*(attr
));
3086 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
3087 return (ARCHIVE_FATAL
);
3089 attr
->name
= strdup(
3090 (const char *)xmlTextReaderConstLocalName(reader
));
3091 if (attr
->name
== NULL
) {
3093 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
3094 return (ARCHIVE_FATAL
);
3096 attr
->value
= strdup(
3097 (const char *)xmlTextReaderConstValue(reader
));
3098 if (attr
->value
== NULL
) {
3101 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
3102 return (ARCHIVE_FATAL
);
3106 list
->last
= &(attr
->next
);
3107 r
= xmlTextReaderMoveToNextAttribute(reader
);
3113 xml2_read_cb(void *context
, char *buffer
, int len
)
3115 struct archive_read
*a
;
3122 a
= (struct archive_read
*)context
;
3123 xar
= (struct xar
*)(a
->format
->data
);
3125 if (xar
->toc_remaining
<= 0)
3129 r
= rd_contents(a
, &d
, &outbytes
, &used
, xar
->toc_remaining
);
3130 if (r
!= ARCHIVE_OK
)
3132 __archive_read_consume(a
, used
);
3133 xar
->toc_remaining
-= used
;
3134 xar
->offset
+= used
;
3135 xar
->toc_total
+= outbytes
;
3136 PRINT_TOC(buffer
, len
);
3138 return ((int)outbytes
);
3142 xml2_close_cb(void *context
)
3145 (void)context
; /* UNUSED */
3150 xml2_error_hdr(void *arg
, const char *msg
, xmlParserSeverities severity
,
3151 xmlTextReaderLocatorPtr locator
)
3153 struct archive_read
*a
;
3155 (void)locator
; /* UNUSED */
3156 a
= (struct archive_read
*)arg
;
3158 case XML_PARSER_SEVERITY_VALIDITY_WARNING
:
3159 case XML_PARSER_SEVERITY_WARNING
:
3160 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
3161 "XML Parsing error: %s", msg
);
3163 case XML_PARSER_SEVERITY_VALIDITY_ERROR
:
3164 case XML_PARSER_SEVERITY_ERROR
:
3165 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
3166 "XML Parsing error: %s", msg
);
3172 xml2_read_toc(struct archive_read
*a
)
3174 xmlTextReaderPtr reader
;
3175 struct xmlattr_list list
;
3178 reader
= xmlReaderForIO(xml2_read_cb
, xml2_close_cb
, a
, NULL
, NULL
, 0);
3179 if (reader
== NULL
) {
3180 archive_set_error(&a
->archive
, ENOMEM
,
3181 "Couldn't allocate memory for xml parser");
3182 return (ARCHIVE_FATAL
);
3184 xmlTextReaderSetErrorHandler(reader
, xml2_error_hdr
, a
);
3186 while ((r
= xmlTextReaderRead(reader
)) == 1) {
3187 const char *name
, *value
;
3190 type
= xmlTextReaderNodeType(reader
);
3191 name
= (const char *)xmlTextReaderConstLocalName(reader
);
3193 case XML_READER_TYPE_ELEMENT
:
3194 empty
= xmlTextReaderIsEmptyElement(reader
);
3195 r
= xml2_xmlattr_setup(a
, &list
, reader
);
3196 if (r
== ARCHIVE_OK
)
3197 r
= xml_start(a
, name
, &list
);
3198 xmlattr_cleanup(&list
);
3199 if (r
!= ARCHIVE_OK
)
3204 case XML_READER_TYPE_END_ELEMENT
:
3207 case XML_READER_TYPE_TEXT
:
3208 value
= (const char *)xmlTextReaderConstValue(reader
);
3209 xml_data(a
, value
, strlen(value
));
3211 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE
:
3218 xmlFreeTextReader(reader
);
3221 return ((r
== 0)?ARCHIVE_OK
:ARCHIVE_FATAL
);
3224 #elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H)
3227 expat_xmlattr_setup(struct archive_read
*a
,
3228 struct xmlattr_list
*list
, const XML_Char
**atts
)
3230 struct xmlattr
*attr
;
3234 list
->last
= &(list
->first
);
3236 return (ARCHIVE_OK
);
3237 while (atts
[0] != NULL
&& atts
[1] != NULL
) {
3238 attr
= malloc(sizeof*(attr
));
3239 name
= strdup(atts
[0]);
3240 value
= strdup(atts
[1]);
3241 if (attr
== NULL
|| name
== NULL
|| value
== NULL
) {
3242 archive_set_error(&a
->archive
, ENOMEM
, "Out of memory");
3243 return (ARCHIVE_FATAL
);
3246 attr
->value
= value
;
3249 list
->last
= &(attr
->next
);
3252 return (ARCHIVE_OK
);
3256 expat_start_cb(void *userData
, const XML_Char
*name
, const XML_Char
**atts
)
3258 struct expat_userData
*ud
= (struct expat_userData
*)userData
;
3259 struct archive_read
*a
= ud
->archive
;
3260 struct xmlattr_list list
;
3263 r
= expat_xmlattr_setup(a
, &list
, atts
);
3264 if (r
== ARCHIVE_OK
)
3265 r
= xml_start(a
, (const char *)name
, &list
);
3266 xmlattr_cleanup(&list
);
3271 expat_end_cb(void *userData
, const XML_Char
*name
)
3273 struct expat_userData
*ud
= (struct expat_userData
*)userData
;
3275 xml_end(ud
->archive
, (const char *)name
);
3279 expat_data_cb(void *userData
, const XML_Char
*s
, int len
)
3281 struct expat_userData
*ud
= (struct expat_userData
*)userData
;
3283 xml_data(ud
->archive
, s
, len
);
3287 expat_read_toc(struct archive_read
*a
)
3291 struct expat_userData ud
;
3293 ud
.state
= ARCHIVE_OK
;
3296 xar
= (struct xar
*)(a
->format
->data
);
3298 /* Initialize XML Parser library. */
3299 parser
= XML_ParserCreate(NULL
);
3300 if (parser
== NULL
) {
3301 archive_set_error(&a
->archive
, ENOMEM
,
3302 "Couldn't allocate memory for xml parser");
3303 return (ARCHIVE_FATAL
);
3305 XML_SetUserData(parser
, &ud
);
3306 XML_SetElementHandler(parser
, expat_start_cb
, expat_end_cb
);
3307 XML_SetCharacterDataHandler(parser
, expat_data_cb
);
3310 while (xar
->toc_remaining
&& ud
.state
== ARCHIVE_OK
) {
3318 r
= rd_contents(a
, &d
, &outbytes
, &used
, xar
->toc_remaining
);
3319 if (r
!= ARCHIVE_OK
)
3321 xar
->toc_remaining
-= used
;
3322 xar
->offset
+= used
;
3323 xar
->toc_total
+= outbytes
;
3324 PRINT_TOC(d
, outbytes
);
3326 xr
= XML_Parse(parser
, d
, outbytes
, xar
->toc_remaining
== 0);
3327 __archive_read_consume(a
, used
);
3328 if (xr
== XML_STATUS_ERROR
) {
3329 XML_ParserFree(parser
);
3330 archive_set_error(&a
->archive
, ARCHIVE_ERRNO_MISC
,
3331 "XML Parsing failed");
3332 return (ARCHIVE_FATAL
);
3335 XML_ParserFree(parser
);
3338 #endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */
3340 #endif /* Support xar format */