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