archive_read_support_format_xar.c revision 342360
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 342360 2018-12-21 23:33:05Z 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, used; 802 803 r = move_reading_point(a, xattr->offset); 804 if (r != ARCHIVE_OK) 805 break; 806 r = rd_contents_init(a, xattr->encoding, 807 xattr->a_sum.alg, xattr->e_sum.alg); 808 if (r != ARCHIVE_OK) 809 break; 810 d = NULL; 811 r = rd_contents(a, &d, &outbytes, &used, xattr->length); 812 if (r != ARCHIVE_OK) 813 break; 814 if (outbytes != xattr->size) { 815 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 816 "Decompressed size error"); 817 r = ARCHIVE_FATAL; 818 break; 819 } 820 r = checksum_final(a, 821 xattr->a_sum.val, xattr->a_sum.len, 822 xattr->e_sum.val, xattr->e_sum.len); 823 if (r != ARCHIVE_OK) 824 break; 825 archive_entry_xattr_add_entry(entry, 826 xattr->name.s, d, outbytes); 827 xattr = xattr->next; 828 } 829 if (r != ARCHIVE_OK) { 830 file_free(file); 831 return (r); 832 } 833 834 if (xar->entry_remaining > 0) 835 /* Move reading point to the beginning of current 836 * file contents. */ 837 r = move_reading_point(a, file->offset); 838 else 839 r = ARCHIVE_OK; 840 841 file_free(file); 842 return (r); 843} 844 845static int 846xar_read_data(struct archive_read *a, 847 const void **buff, size_t *size, int64_t *offset) 848{ 849 struct xar *xar; 850 size_t used; 851 int r; 852 853 xar = (struct xar *)(a->format->data); 854 855 if (xar->entry_unconsumed) { 856 __archive_read_consume(a, xar->entry_unconsumed); 857 xar->entry_unconsumed = 0; 858 } 859 860 if (xar->end_of_file || xar->entry_remaining <= 0) { 861 r = ARCHIVE_EOF; 862 goto abort_read_data; 863 } 864 865 if (xar->entry_init) { 866 r = rd_contents_init(a, xar->entry_encoding, 867 xar->entry_a_sum.alg, xar->entry_e_sum.alg); 868 if (r != ARCHIVE_OK) { 869 xar->entry_remaining = 0; 870 return (r); 871 } 872 xar->entry_init = 0; 873 } 874 875 *buff = NULL; 876 r = rd_contents(a, buff, size, &used, xar->entry_remaining); 877 if (r != ARCHIVE_OK) 878 goto abort_read_data; 879 880 *offset = xar->entry_total; 881 xar->entry_total += *size; 882 xar->total += *size; 883 xar->offset += used; 884 xar->entry_remaining -= used; 885 xar->entry_unconsumed = used; 886 887 if (xar->entry_remaining == 0) { 888 if (xar->entry_total != xar->entry_size) { 889 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 890 "Decompressed size error"); 891 r = ARCHIVE_FATAL; 892 goto abort_read_data; 893 } 894 r = checksum_final(a, 895 xar->entry_a_sum.val, xar->entry_a_sum.len, 896 xar->entry_e_sum.val, xar->entry_e_sum.len); 897 if (r != ARCHIVE_OK) 898 goto abort_read_data; 899 } 900 901 return (ARCHIVE_OK); 902abort_read_data: 903 *buff = NULL; 904 *size = 0; 905 *offset = xar->total; 906 return (r); 907} 908 909static int 910xar_read_data_skip(struct archive_read *a) 911{ 912 struct xar *xar; 913 int64_t bytes_skipped; 914 915 xar = (struct xar *)(a->format->data); 916 if (xar->end_of_file) 917 return (ARCHIVE_EOF); 918 bytes_skipped = __archive_read_consume(a, xar->entry_remaining + 919 xar->entry_unconsumed); 920 if (bytes_skipped < 0) 921 return (ARCHIVE_FATAL); 922 xar->offset += bytes_skipped; 923 xar->entry_unconsumed = 0; 924 return (ARCHIVE_OK); 925} 926 927static int 928xar_cleanup(struct archive_read *a) 929{ 930 struct xar *xar; 931 struct hdlink *hdlink; 932 int i; 933 int r; 934 935 xar = (struct xar *)(a->format->data); 936 checksum_cleanup(a); 937 r = decompression_cleanup(a); 938 hdlink = xar->hdlink_list; 939 while (hdlink != NULL) { 940 struct hdlink *next = hdlink->next; 941 942 free(hdlink); 943 hdlink = next; 944 } 945 for (i = 0; i < xar->file_queue.used; i++) 946 file_free(xar->file_queue.files[i]); 947 free(xar->file_queue.files); 948 while (xar->unknowntags != NULL) { 949 struct unknown_tag *tag; 950 951 tag = xar->unknowntags; 952 xar->unknowntags = tag->next; 953 archive_string_free(&(tag->name)); 954 free(tag); 955 } 956 free(xar->outbuff); 957 free(xar); 958 a->format->data = NULL; 959 return (r); 960} 961 962static int 963move_reading_point(struct archive_read *a, uint64_t offset) 964{ 965 struct xar *xar; 966 967 xar = (struct xar *)(a->format->data); 968 if (xar->offset - xar->h_base != offset) { 969 /* Seek forward to the start of file contents. */ 970 int64_t step; 971 972 step = offset - (xar->offset - xar->h_base); 973 if (step > 0) { 974 step = __archive_read_consume(a, step); 975 if (step < 0) 976 return ((int)step); 977 xar->offset += step; 978 } else { 979 int64_t pos = __archive_read_seek(a, xar->h_base + offset, SEEK_SET); 980 if (pos == ARCHIVE_FAILED) { 981 archive_set_error(&(a->archive), 982 ARCHIVE_ERRNO_MISC, 983 "Cannot seek."); 984 return (ARCHIVE_FAILED); 985 } 986 xar->offset = pos; 987 } 988 } 989 return (ARCHIVE_OK); 990} 991 992static int 993rd_contents_init(struct archive_read *a, enum enctype encoding, 994 int a_sum_alg, int e_sum_alg) 995{ 996 int r; 997 998 /* Init decompress library. */ 999 if ((r = decompression_init(a, encoding)) != ARCHIVE_OK) 1000 return (r); 1001 /* Init checksum library. */ 1002 checksum_init(a, a_sum_alg, e_sum_alg); 1003 return (ARCHIVE_OK); 1004} 1005 1006static int 1007rd_contents(struct archive_read *a, const void **buff, size_t *size, 1008 size_t *used, uint64_t remaining) 1009{ 1010 const unsigned char *b; 1011 ssize_t bytes; 1012 1013 /* Get whatever bytes are immediately available. */ 1014 b = __archive_read_ahead(a, 1, &bytes); 1015 if (bytes < 0) 1016 return ((int)bytes); 1017 if (bytes == 0) { 1018 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1019 "Truncated archive file"); 1020 return (ARCHIVE_FATAL); 1021 } 1022 if ((uint64_t)bytes > remaining) 1023 bytes = (ssize_t)remaining; 1024 1025 /* 1026 * Decompress contents of file. 1027 */ 1028 *used = bytes; 1029 if (decompress(a, buff, size, b, used) != ARCHIVE_OK) 1030 return (ARCHIVE_FATAL); 1031 1032 /* 1033 * Update checksum of a compressed data and a extracted data. 1034 */ 1035 checksum_update(a, b, *used, *buff, *size); 1036 1037 return (ARCHIVE_OK); 1038} 1039 1040/* 1041 * Note that this implementation does not (and should not!) obey 1042 * locale settings; you cannot simply substitute strtol here, since 1043 * it does obey locale. 1044 */ 1045 1046static uint64_t 1047atol10(const char *p, size_t char_cnt) 1048{ 1049 uint64_t l; 1050 int digit; 1051 1052 if (char_cnt == 0) 1053 return (0); 1054 1055 l = 0; 1056 digit = *p - '0'; 1057 while (digit >= 0 && digit < 10 && char_cnt-- > 0) { 1058 l = (l * 10) + digit; 1059 digit = *++p - '0'; 1060 } 1061 return (l); 1062} 1063 1064static int64_t 1065atol8(const char *p, size_t char_cnt) 1066{ 1067 int64_t l; 1068 int digit; 1069 1070 if (char_cnt == 0) 1071 return (0); 1072 1073 l = 0; 1074 while (char_cnt-- > 0) { 1075 if (*p >= '0' && *p <= '7') 1076 digit = *p - '0'; 1077 else 1078 break; 1079 p++; 1080 l <<= 3; 1081 l |= digit; 1082 } 1083 return (l); 1084} 1085 1086static size_t 1087atohex(unsigned char *b, size_t bsize, const char *p, size_t psize) 1088{ 1089 size_t fbsize = bsize; 1090 1091 while (bsize && psize > 1) { 1092 unsigned char x; 1093 1094 if (p[0] >= 'a' && p[0] <= 'z') 1095 x = (p[0] - 'a' + 0x0a) << 4; 1096 else if (p[0] >= 'A' && p[0] <= 'Z') 1097 x = (p[0] - 'A' + 0x0a) << 4; 1098 else if (p[0] >= '0' && p[0] <= '9') 1099 x = (p[0] - '0') << 4; 1100 else 1101 return (-1); 1102 if (p[1] >= 'a' && p[1] <= 'z') 1103 x |= p[1] - 'a' + 0x0a; 1104 else if (p[1] >= 'A' && p[1] <= 'Z') 1105 x |= p[1] - 'A' + 0x0a; 1106 else if (p[1] >= '0' && p[1] <= '9') 1107 x |= p[1] - '0'; 1108 else 1109 return (-1); 1110 1111 *b++ = x; 1112 bsize--; 1113 p += 2; 1114 psize -= 2; 1115 } 1116 return (fbsize - bsize); 1117} 1118 1119static time_t 1120time_from_tm(struct tm *t) 1121{ 1122#if HAVE_TIMEGM 1123 /* Use platform timegm() if available. */ 1124 return (timegm(t)); 1125#elif HAVE__MKGMTIME64 1126 return (_mkgmtime64(t)); 1127#else 1128 /* Else use direct calculation using POSIX assumptions. */ 1129 /* First, fix up tm_yday based on the year/month/day. */ 1130 mktime(t); 1131 /* Then we can compute timegm() from first principles. */ 1132 return (t->tm_sec 1133 + t->tm_min * 60 1134 + t->tm_hour * 3600 1135 + t->tm_yday * 86400 1136 + (t->tm_year - 70) * 31536000 1137 + ((t->tm_year - 69) / 4) * 86400 1138 - ((t->tm_year - 1) / 100) * 86400 1139 + ((t->tm_year + 299) / 400) * 86400); 1140#endif 1141} 1142 1143static time_t 1144parse_time(const char *p, size_t n) 1145{ 1146 struct tm tm; 1147 time_t t = 0; 1148 int64_t data; 1149 1150 memset(&tm, 0, sizeof(tm)); 1151 if (n != 20) 1152 return (t); 1153 data = atol10(p, 4); 1154 if (data < 1900) 1155 return (t); 1156 tm.tm_year = (int)data - 1900; 1157 p += 4; 1158 if (*p++ != '-') 1159 return (t); 1160 data = atol10(p, 2); 1161 if (data < 1 || data > 12) 1162 return (t); 1163 tm.tm_mon = (int)data -1; 1164 p += 2; 1165 if (*p++ != '-') 1166 return (t); 1167 data = atol10(p, 2); 1168 if (data < 1 || data > 31) 1169 return (t); 1170 tm.tm_mday = (int)data; 1171 p += 2; 1172 if (*p++ != 'T') 1173 return (t); 1174 data = atol10(p, 2); 1175 if (data < 0 || data > 23) 1176 return (t); 1177 tm.tm_hour = (int)data; 1178 p += 2; 1179 if (*p++ != ':') 1180 return (t); 1181 data = atol10(p, 2); 1182 if (data < 0 || data > 59) 1183 return (t); 1184 tm.tm_min = (int)data; 1185 p += 2; 1186 if (*p++ != ':') 1187 return (t); 1188 data = atol10(p, 2); 1189 if (data < 0 || data > 60) 1190 return (t); 1191 tm.tm_sec = (int)data; 1192#if 0 1193 p += 2; 1194 if (*p != 'Z') 1195 return (t); 1196#endif 1197 1198 t = time_from_tm(&tm); 1199 1200 return (t); 1201} 1202 1203static int 1204heap_add_entry(struct archive_read *a, 1205 struct heap_queue *heap, struct xar_file *file) 1206{ 1207 uint64_t file_id, parent_id; 1208 int hole, parent; 1209 1210 /* Expand our pending files list as necessary. */ 1211 if (heap->used >= heap->allocated) { 1212 struct xar_file **new_pending_files; 1213 int new_size = heap->allocated * 2; 1214 1215 if (heap->allocated < 1024) 1216 new_size = 1024; 1217 /* Overflow might keep us from growing the list. */ 1218 if (new_size <= heap->allocated) { 1219 archive_set_error(&a->archive, 1220 ENOMEM, "Out of memory"); 1221 return (ARCHIVE_FATAL); 1222 } 1223 new_pending_files = (struct xar_file **) 1224 malloc(new_size * sizeof(new_pending_files[0])); 1225 if (new_pending_files == NULL) { 1226 archive_set_error(&a->archive, 1227 ENOMEM, "Out of memory"); 1228 return (ARCHIVE_FATAL); 1229 } 1230 memcpy(new_pending_files, heap->files, 1231 heap->allocated * sizeof(new_pending_files[0])); 1232 if (heap->files != NULL) 1233 free(heap->files); 1234 heap->files = new_pending_files; 1235 heap->allocated = new_size; 1236 } 1237 1238 file_id = file->id; 1239 1240 /* 1241 * Start with hole at end, walk it up tree to find insertion point. 1242 */ 1243 hole = heap->used++; 1244 while (hole > 0) { 1245 parent = (hole - 1)/2; 1246 parent_id = heap->files[parent]->id; 1247 if (file_id >= parent_id) { 1248 heap->files[hole] = file; 1249 return (ARCHIVE_OK); 1250 } 1251 /* Move parent into hole <==> move hole up tree. */ 1252 heap->files[hole] = heap->files[parent]; 1253 hole = parent; 1254 } 1255 heap->files[0] = file; 1256 1257 return (ARCHIVE_OK); 1258} 1259 1260static struct xar_file * 1261heap_get_entry(struct heap_queue *heap) 1262{ 1263 uint64_t a_id, b_id, c_id; 1264 int a, b, c; 1265 struct xar_file *r, *tmp; 1266 1267 if (heap->used < 1) 1268 return (NULL); 1269 1270 /* 1271 * The first file in the list is the earliest; we'll return this. 1272 */ 1273 r = heap->files[0]; 1274 1275 /* 1276 * Move the last item in the heap to the root of the tree 1277 */ 1278 heap->files[0] = heap->files[--(heap->used)]; 1279 1280 /* 1281 * Rebalance the heap. 1282 */ 1283 a = 0; /* Starting element and its heap key */ 1284 a_id = heap->files[a]->id; 1285 for (;;) { 1286 b = a + a + 1; /* First child */ 1287 if (b >= heap->used) 1288 return (r); 1289 b_id = heap->files[b]->id; 1290 c = b + 1; /* Use second child if it is smaller. */ 1291 if (c < heap->used) { 1292 c_id = heap->files[c]->id; 1293 if (c_id < b_id) { 1294 b = c; 1295 b_id = c_id; 1296 } 1297 } 1298 if (a_id <= b_id) 1299 return (r); 1300 tmp = heap->files[a]; 1301 heap->files[a] = heap->files[b]; 1302 heap->files[b] = tmp; 1303 a = b; 1304 } 1305} 1306 1307static int 1308add_link(struct archive_read *a, struct xar *xar, struct xar_file *file) 1309{ 1310 struct hdlink *hdlink; 1311 1312 for (hdlink = xar->hdlink_list; hdlink != NULL; hdlink = hdlink->next) { 1313 if (hdlink->id == file->link) { 1314 file->hdnext = hdlink->files; 1315 hdlink->cnt++; 1316 hdlink->files = file; 1317 return (ARCHIVE_OK); 1318 } 1319 } 1320 hdlink = malloc(sizeof(*hdlink)); 1321 if (hdlink == NULL) { 1322 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 1323 return (ARCHIVE_FATAL); 1324 } 1325 file->hdnext = NULL; 1326 hdlink->id = file->link; 1327 hdlink->cnt = 1; 1328 hdlink->files = file; 1329 hdlink->next = xar->hdlink_list; 1330 xar->hdlink_list = hdlink; 1331 return (ARCHIVE_OK); 1332} 1333 1334static void 1335_checksum_init(struct chksumwork *sumwrk, int sum_alg) 1336{ 1337 sumwrk->alg = sum_alg; 1338 switch (sum_alg) { 1339 case CKSUM_NONE: 1340 break; 1341 case CKSUM_SHA1: 1342 archive_sha1_init(&(sumwrk->sha1ctx)); 1343 break; 1344 case CKSUM_MD5: 1345 archive_md5_init(&(sumwrk->md5ctx)); 1346 break; 1347 } 1348} 1349 1350static void 1351_checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size) 1352{ 1353 1354 switch (sumwrk->alg) { 1355 case CKSUM_NONE: 1356 break; 1357 case CKSUM_SHA1: 1358 archive_sha1_update(&(sumwrk->sha1ctx), buff, size); 1359 break; 1360 case CKSUM_MD5: 1361 archive_md5_update(&(sumwrk->md5ctx), buff, size); 1362 break; 1363 } 1364} 1365 1366static int 1367_checksum_final(struct chksumwork *sumwrk, const void *val, size_t len) 1368{ 1369 unsigned char sum[MAX_SUM_SIZE]; 1370 int r = ARCHIVE_OK; 1371 1372 switch (sumwrk->alg) { 1373 case CKSUM_NONE: 1374 break; 1375 case CKSUM_SHA1: 1376 archive_sha1_final(&(sumwrk->sha1ctx), sum); 1377 if (len != SHA1_SIZE || 1378 memcmp(val, sum, SHA1_SIZE) != 0) 1379 r = ARCHIVE_FAILED; 1380 break; 1381 case CKSUM_MD5: 1382 archive_md5_final(&(sumwrk->md5ctx), sum); 1383 if (len != MD5_SIZE || 1384 memcmp(val, sum, MD5_SIZE) != 0) 1385 r = ARCHIVE_FAILED; 1386 break; 1387 } 1388 return (r); 1389} 1390 1391static void 1392checksum_init(struct archive_read *a, int a_sum_alg, int e_sum_alg) 1393{ 1394 struct xar *xar; 1395 1396 xar = (struct xar *)(a->format->data); 1397 _checksum_init(&(xar->a_sumwrk), a_sum_alg); 1398 _checksum_init(&(xar->e_sumwrk), e_sum_alg); 1399} 1400 1401static void 1402checksum_update(struct archive_read *a, const void *abuff, size_t asize, 1403 const void *ebuff, size_t esize) 1404{ 1405 struct xar *xar; 1406 1407 xar = (struct xar *)(a->format->data); 1408 _checksum_update(&(xar->a_sumwrk), abuff, asize); 1409 _checksum_update(&(xar->e_sumwrk), ebuff, esize); 1410} 1411 1412static int 1413checksum_final(struct archive_read *a, const void *a_sum_val, 1414 size_t a_sum_len, const void *e_sum_val, size_t e_sum_len) 1415{ 1416 struct xar *xar; 1417 int r; 1418 1419 xar = (struct xar *)(a->format->data); 1420 r = _checksum_final(&(xar->a_sumwrk), a_sum_val, a_sum_len); 1421 if (r == ARCHIVE_OK) 1422 r = _checksum_final(&(xar->e_sumwrk), e_sum_val, e_sum_len); 1423 if (r != ARCHIVE_OK) 1424 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 1425 "Sumcheck error"); 1426 return (r); 1427} 1428 1429static int 1430decompression_init(struct archive_read *a, enum enctype encoding) 1431{ 1432 struct xar *xar; 1433 const char *detail; 1434 int r; 1435 1436 xar = (struct xar *)(a->format->data); 1437 xar->rd_encoding = encoding; 1438 switch (encoding) { 1439 case NONE: 1440 break; 1441 case GZIP: 1442 if (xar->stream_valid) 1443 r = inflateReset(&(xar->stream)); 1444 else 1445 r = inflateInit(&(xar->stream)); 1446 if (r != Z_OK) { 1447 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1448 "Couldn't initialize zlib stream."); 1449 return (ARCHIVE_FATAL); 1450 } 1451 xar->stream_valid = 1; 1452 xar->stream.total_in = 0; 1453 xar->stream.total_out = 0; 1454 break; 1455#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 1456 case BZIP2: 1457 if (xar->bzstream_valid) { 1458 BZ2_bzDecompressEnd(&(xar->bzstream)); 1459 xar->bzstream_valid = 0; 1460 } 1461 r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 0); 1462 if (r == BZ_MEM_ERROR) 1463 r = BZ2_bzDecompressInit(&(xar->bzstream), 0, 1); 1464 if (r != BZ_OK) { 1465 int err = ARCHIVE_ERRNO_MISC; 1466 detail = NULL; 1467 switch (r) { 1468 case BZ_PARAM_ERROR: 1469 detail = "invalid setup parameter"; 1470 break; 1471 case BZ_MEM_ERROR: 1472 err = ENOMEM; 1473 detail = "out of memory"; 1474 break; 1475 case BZ_CONFIG_ERROR: 1476 detail = "mis-compiled library"; 1477 break; 1478 } 1479 archive_set_error(&a->archive, err, 1480 "Internal error initializing decompressor: %s", 1481 detail == NULL ? "??" : detail); 1482 xar->bzstream_valid = 0; 1483 return (ARCHIVE_FATAL); 1484 } 1485 xar->bzstream_valid = 1; 1486 xar->bzstream.total_in_lo32 = 0; 1487 xar->bzstream.total_in_hi32 = 0; 1488 xar->bzstream.total_out_lo32 = 0; 1489 xar->bzstream.total_out_hi32 = 0; 1490 break; 1491#endif 1492#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) 1493#if LZMA_VERSION_MAJOR >= 5 1494/* Effectively disable the limiter. */ 1495#define LZMA_MEMLIMIT UINT64_MAX 1496#else 1497/* NOTE: This needs to check memory size which running system has. */ 1498#define LZMA_MEMLIMIT (1U << 30) 1499#endif 1500 case XZ: 1501 case LZMA: 1502 if (xar->lzstream_valid) { 1503 lzma_end(&(xar->lzstream)); 1504 xar->lzstream_valid = 0; 1505 } 1506 if (xar->entry_encoding == XZ) 1507 r = lzma_stream_decoder(&(xar->lzstream), 1508 LZMA_MEMLIMIT,/* memlimit */ 1509 LZMA_CONCATENATED); 1510 else 1511 r = lzma_alone_decoder(&(xar->lzstream), 1512 LZMA_MEMLIMIT);/* memlimit */ 1513 if (r != LZMA_OK) { 1514 switch (r) { 1515 case LZMA_MEM_ERROR: 1516 archive_set_error(&a->archive, 1517 ENOMEM, 1518 "Internal error initializing " 1519 "compression library: " 1520 "Cannot allocate memory"); 1521 break; 1522 case LZMA_OPTIONS_ERROR: 1523 archive_set_error(&a->archive, 1524 ARCHIVE_ERRNO_MISC, 1525 "Internal error initializing " 1526 "compression library: " 1527 "Invalid or unsupported options"); 1528 break; 1529 default: 1530 archive_set_error(&a->archive, 1531 ARCHIVE_ERRNO_MISC, 1532 "Internal error initializing " 1533 "lzma library"); 1534 break; 1535 } 1536 return (ARCHIVE_FATAL); 1537 } 1538 xar->lzstream_valid = 1; 1539 xar->lzstream.total_in = 0; 1540 xar->lzstream.total_out = 0; 1541 break; 1542#endif 1543 /* 1544 * Unsupported compression. 1545 */ 1546 default: 1547#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) 1548 case BZIP2: 1549#endif 1550#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA) 1551 case LZMA: 1552 case XZ: 1553#endif 1554 switch (xar->entry_encoding) { 1555 case BZIP2: detail = "bzip2"; break; 1556 case LZMA: detail = "lzma"; break; 1557 case XZ: detail = "xz"; break; 1558 default: detail = "??"; break; 1559 } 1560 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1561 "%s compression not supported on this platform", 1562 detail); 1563 return (ARCHIVE_FAILED); 1564 } 1565 return (ARCHIVE_OK); 1566} 1567 1568static int 1569decompress(struct archive_read *a, const void **buff, size_t *outbytes, 1570 const void *b, size_t *used) 1571{ 1572 struct xar *xar; 1573 void *outbuff; 1574 size_t avail_in, avail_out; 1575 int r; 1576 1577 xar = (struct xar *)(a->format->data); 1578 avail_in = *used; 1579 outbuff = (void *)(uintptr_t)*buff; 1580 if (outbuff == NULL) { 1581 if (xar->outbuff == NULL) { 1582 xar->outbuff = malloc(OUTBUFF_SIZE); 1583 if (xar->outbuff == NULL) { 1584 archive_set_error(&a->archive, ENOMEM, 1585 "Couldn't allocate memory for out buffer"); 1586 return (ARCHIVE_FATAL); 1587 } 1588 } 1589 outbuff = xar->outbuff; 1590 *buff = outbuff; 1591 avail_out = OUTBUFF_SIZE; 1592 } else 1593 avail_out = *outbytes; 1594 switch (xar->rd_encoding) { 1595 case GZIP: 1596 xar->stream.next_in = (Bytef *)(uintptr_t)b; 1597 xar->stream.avail_in = avail_in; 1598 xar->stream.next_out = (unsigned char *)outbuff; 1599 xar->stream.avail_out = avail_out; 1600 r = inflate(&(xar->stream), 0); 1601 switch (r) { 1602 case Z_OK: /* Decompressor made some progress.*/ 1603 case Z_STREAM_END: /* Found end of stream. */ 1604 break; 1605 default: 1606 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1607 "File decompression failed (%d)", r); 1608 return (ARCHIVE_FATAL); 1609 } 1610 *used = avail_in - xar->stream.avail_in; 1611 *outbytes = avail_out - xar->stream.avail_out; 1612 break; 1613#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 1614 case BZIP2: 1615 xar->bzstream.next_in = (char *)(uintptr_t)b; 1616 xar->bzstream.avail_in = avail_in; 1617 xar->bzstream.next_out = (char *)outbuff; 1618 xar->bzstream.avail_out = avail_out; 1619 r = BZ2_bzDecompress(&(xar->bzstream)); 1620 switch (r) { 1621 case BZ_STREAM_END: /* Found end of stream. */ 1622 switch (BZ2_bzDecompressEnd(&(xar->bzstream))) { 1623 case BZ_OK: 1624 break; 1625 default: 1626 archive_set_error(&(a->archive), 1627 ARCHIVE_ERRNO_MISC, 1628 "Failed to clean up decompressor"); 1629 return (ARCHIVE_FATAL); 1630 } 1631 xar->bzstream_valid = 0; 1632 /* FALLTHROUGH */ 1633 case BZ_OK: /* Decompressor made some progress. */ 1634 break; 1635 default: 1636 archive_set_error(&(a->archive), 1637 ARCHIVE_ERRNO_MISC, 1638 "bzip decompression failed"); 1639 return (ARCHIVE_FATAL); 1640 } 1641 *used = avail_in - xar->bzstream.avail_in; 1642 *outbytes = avail_out - xar->bzstream.avail_out; 1643 break; 1644#endif 1645#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) 1646 case LZMA: 1647 case XZ: 1648 xar->lzstream.next_in = b; 1649 xar->lzstream.avail_in = avail_in; 1650 xar->lzstream.next_out = (unsigned char *)outbuff; 1651 xar->lzstream.avail_out = avail_out; 1652 r = lzma_code(&(xar->lzstream), LZMA_RUN); 1653 switch (r) { 1654 case LZMA_STREAM_END: /* Found end of stream. */ 1655 lzma_end(&(xar->lzstream)); 1656 xar->lzstream_valid = 0; 1657 /* FALLTHROUGH */ 1658 case LZMA_OK: /* Decompressor made some progress. */ 1659 break; 1660 default: 1661 archive_set_error(&(a->archive), 1662 ARCHIVE_ERRNO_MISC, 1663 "%s decompression failed(%d)", 1664 (xar->entry_encoding == XZ)?"xz":"lzma", 1665 r); 1666 return (ARCHIVE_FATAL); 1667 } 1668 *used = avail_in - xar->lzstream.avail_in; 1669 *outbytes = avail_out - xar->lzstream.avail_out; 1670 break; 1671#endif 1672#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) 1673 case BZIP2: 1674#endif 1675#if !defined(HAVE_LZMA_H) || !defined(HAVE_LIBLZMA) 1676 case LZMA: 1677 case XZ: 1678#endif 1679 case NONE: 1680 default: 1681 if (outbuff == xar->outbuff) { 1682 *buff = b; 1683 *used = avail_in; 1684 *outbytes = avail_in; 1685 } else { 1686 if (avail_out > avail_in) 1687 avail_out = avail_in; 1688 memcpy(outbuff, b, avail_out); 1689 *used = avail_out; 1690 *outbytes = avail_out; 1691 } 1692 break; 1693 } 1694 return (ARCHIVE_OK); 1695} 1696 1697static int 1698decompression_cleanup(struct archive_read *a) 1699{ 1700 struct xar *xar; 1701 int r; 1702 1703 xar = (struct xar *)(a->format->data); 1704 r = ARCHIVE_OK; 1705 if (xar->stream_valid) { 1706 if (inflateEnd(&(xar->stream)) != Z_OK) { 1707 archive_set_error(&a->archive, 1708 ARCHIVE_ERRNO_MISC, 1709 "Failed to clean up zlib decompressor"); 1710 r = ARCHIVE_FATAL; 1711 } 1712 } 1713#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 1714 if (xar->bzstream_valid) { 1715 if (BZ2_bzDecompressEnd(&(xar->bzstream)) != BZ_OK) { 1716 archive_set_error(&a->archive, 1717 ARCHIVE_ERRNO_MISC, 1718 "Failed to clean up bzip2 decompressor"); 1719 r = ARCHIVE_FATAL; 1720 } 1721 } 1722#endif 1723#if defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) 1724 if (xar->lzstream_valid) 1725 lzma_end(&(xar->lzstream)); 1726#elif defined(HAVE_LZMA_H) && defined(HAVE_LIBLZMA) 1727 if (xar->lzstream_valid) { 1728 if (lzmadec_end(&(xar->lzstream)) != LZMADEC_OK) { 1729 archive_set_error(&a->archive, 1730 ARCHIVE_ERRNO_MISC, 1731 "Failed to clean up lzmadec decompressor"); 1732 r = ARCHIVE_FATAL; 1733 } 1734 } 1735#endif 1736 return (r); 1737} 1738 1739static void 1740checksum_cleanup(struct archive_read *a) { 1741 struct xar *xar; 1742 1743 xar = (struct xar *)(a->format->data); 1744 1745 _checksum_final(&(xar->a_sumwrk), NULL, 0); 1746 _checksum_final(&(xar->e_sumwrk), NULL, 0); 1747} 1748 1749static void 1750xmlattr_cleanup(struct xmlattr_list *list) 1751{ 1752 struct xmlattr *attr, *next; 1753 1754 attr = list->first; 1755 while (attr != NULL) { 1756 next = attr->next; 1757 free(attr->name); 1758 free(attr->value); 1759 free(attr); 1760 attr = next; 1761 } 1762 list->first = NULL; 1763 list->last = &(list->first); 1764} 1765 1766static int 1767file_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list) 1768{ 1769 struct xar_file *file; 1770 struct xmlattr *attr; 1771 1772 file = calloc(1, sizeof(*file)); 1773 if (file == NULL) { 1774 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 1775 return (ARCHIVE_FATAL); 1776 } 1777 file->parent = xar->file; 1778 file->mode = 0777 | AE_IFREG; 1779 file->atime = 0; 1780 file->mtime = 0; 1781 xar->file = file; 1782 xar->xattr = NULL; 1783 for (attr = list->first; attr != NULL; attr = attr->next) { 1784 if (strcmp(attr->name, "id") == 0) 1785 file->id = atol10(attr->value, strlen(attr->value)); 1786 } 1787 file->nlink = 1; 1788 if (heap_add_entry(a, &(xar->file_queue), file) != ARCHIVE_OK) 1789 return (ARCHIVE_FATAL); 1790 return (ARCHIVE_OK); 1791} 1792 1793static void 1794file_free(struct xar_file *file) 1795{ 1796 struct xattr *xattr; 1797 1798 archive_string_free(&(file->pathname)); 1799 archive_string_free(&(file->symlink)); 1800 archive_string_free(&(file->uname)); 1801 archive_string_free(&(file->gname)); 1802 archive_string_free(&(file->hardlink)); 1803 xattr = file->xattr_list; 1804 while (xattr != NULL) { 1805 struct xattr *next; 1806 1807 next = xattr->next; 1808 xattr_free(xattr); 1809 xattr = next; 1810 } 1811 1812 free(file); 1813} 1814 1815static int 1816xattr_new(struct archive_read *a, struct xar *xar, struct xmlattr_list *list) 1817{ 1818 struct xattr *xattr, **nx; 1819 struct xmlattr *attr; 1820 1821 xattr = calloc(1, sizeof(*xattr)); 1822 if (xattr == NULL) { 1823 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 1824 return (ARCHIVE_FATAL); 1825 } 1826 xar->xattr = xattr; 1827 for (attr = list->first; attr != NULL; attr = attr->next) { 1828 if (strcmp(attr->name, "id") == 0) 1829 xattr->id = atol10(attr->value, strlen(attr->value)); 1830 } 1831 /* Chain to xattr list. */ 1832 for (nx = &(xar->file->xattr_list); 1833 *nx != NULL; nx = &((*nx)->next)) { 1834 if (xattr->id < (*nx)->id) 1835 break; 1836 } 1837 xattr->next = *nx; 1838 *nx = xattr; 1839 1840 return (ARCHIVE_OK); 1841} 1842 1843static void 1844xattr_free(struct xattr *xattr) 1845{ 1846 archive_string_free(&(xattr->name)); 1847 free(xattr); 1848} 1849 1850static int 1851getencoding(struct xmlattr_list *list) 1852{ 1853 struct xmlattr *attr; 1854 enum enctype encoding = NONE; 1855 1856 for (attr = list->first; attr != NULL; attr = attr->next) { 1857 if (strcmp(attr->name, "style") == 0) { 1858 if (strcmp(attr->value, "application/octet-stream") == 0) 1859 encoding = NONE; 1860 else if (strcmp(attr->value, "application/x-gzip") == 0) 1861 encoding = GZIP; 1862 else if (strcmp(attr->value, "application/x-bzip2") == 0) 1863 encoding = BZIP2; 1864 else if (strcmp(attr->value, "application/x-lzma") == 0) 1865 encoding = LZMA; 1866 else if (strcmp(attr->value, "application/x-xz") == 0) 1867 encoding = XZ; 1868 } 1869 } 1870 return (encoding); 1871} 1872 1873static int 1874getsumalgorithm(struct xmlattr_list *list) 1875{ 1876 struct xmlattr *attr; 1877 int alg = CKSUM_NONE; 1878 1879 for (attr = list->first; attr != NULL; attr = attr->next) { 1880 if (strcmp(attr->name, "style") == 0) { 1881 const char *v = attr->value; 1882 if ((v[0] == 'S' || v[0] == 's') && 1883 (v[1] == 'H' || v[1] == 'h') && 1884 (v[2] == 'A' || v[2] == 'a') && 1885 v[3] == '1' && v[4] == '\0') 1886 alg = CKSUM_SHA1; 1887 if ((v[0] == 'M' || v[0] == 'm') && 1888 (v[1] == 'D' || v[1] == 'd') && 1889 v[2] == '5' && v[3] == '\0') 1890 alg = CKSUM_MD5; 1891 } 1892 } 1893 return (alg); 1894} 1895 1896static int 1897unknowntag_start(struct archive_read *a, struct xar *xar, const char *name) 1898{ 1899 struct unknown_tag *tag; 1900 1901 tag = malloc(sizeof(*tag)); 1902 if (tag == NULL) { 1903 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 1904 return (ARCHIVE_FATAL); 1905 } 1906 tag->next = xar->unknowntags; 1907 archive_string_init(&(tag->name)); 1908 archive_strcpy(&(tag->name), name); 1909 if (xar->unknowntags == NULL) { 1910#if DEBUG 1911 fprintf(stderr, "UNKNOWNTAG_START:%s\n", name); 1912#endif 1913 xar->xmlsts_unknown = xar->xmlsts; 1914 xar->xmlsts = UNKNOWN; 1915 } 1916 xar->unknowntags = tag; 1917 return (ARCHIVE_OK); 1918} 1919 1920static void 1921unknowntag_end(struct xar *xar, const char *name) 1922{ 1923 struct unknown_tag *tag; 1924 1925 tag = xar->unknowntags; 1926 if (tag == NULL || name == NULL) 1927 return; 1928 if (strcmp(tag->name.s, name) == 0) { 1929 xar->unknowntags = tag->next; 1930 archive_string_free(&(tag->name)); 1931 free(tag); 1932 if (xar->unknowntags == NULL) { 1933#if DEBUG 1934 fprintf(stderr, "UNKNOWNTAG_END:%s\n", name); 1935#endif 1936 xar->xmlsts = xar->xmlsts_unknown; 1937 } 1938 } 1939} 1940 1941static int 1942xml_start(struct archive_read *a, const char *name, struct xmlattr_list *list) 1943{ 1944 struct xar *xar; 1945 struct xmlattr *attr; 1946 1947 xar = (struct xar *)(a->format->data); 1948 1949#if DEBUG 1950 fprintf(stderr, "xml_sta:[%s]\n", name); 1951 for (attr = list->first; attr != NULL; attr = attr->next) 1952 fprintf(stderr, " attr:\"%s\"=\"%s\"\n", 1953 attr->name, attr->value); 1954#endif 1955 xar->base64text = 0; 1956 switch (xar->xmlsts) { 1957 case INIT: 1958 if (strcmp(name, "xar") == 0) 1959 xar->xmlsts = XAR; 1960 else 1961 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 1962 return (ARCHIVE_FATAL); 1963 break; 1964 case XAR: 1965 if (strcmp(name, "toc") == 0) 1966 xar->xmlsts = TOC; 1967 else 1968 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 1969 return (ARCHIVE_FATAL); 1970 break; 1971 case TOC: 1972 if (strcmp(name, "creation-time") == 0) 1973 xar->xmlsts = TOC_CREATION_TIME; 1974 else if (strcmp(name, "checksum") == 0) 1975 xar->xmlsts = TOC_CHECKSUM; 1976 else if (strcmp(name, "file") == 0) { 1977 if (file_new(a, xar, list) != ARCHIVE_OK) 1978 return (ARCHIVE_FATAL); 1979 xar->xmlsts = TOC_FILE; 1980 } 1981 else 1982 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 1983 return (ARCHIVE_FATAL); 1984 break; 1985 case TOC_CHECKSUM: 1986 if (strcmp(name, "offset") == 0) 1987 xar->xmlsts = TOC_CHECKSUM_OFFSET; 1988 else if (strcmp(name, "size") == 0) 1989 xar->xmlsts = TOC_CHECKSUM_SIZE; 1990 else 1991 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 1992 return (ARCHIVE_FATAL); 1993 break; 1994 case TOC_FILE: 1995 if (strcmp(name, "file") == 0) { 1996 if (file_new(a, xar, list) != ARCHIVE_OK) 1997 return (ARCHIVE_FATAL); 1998 } 1999 else if (strcmp(name, "data") == 0) 2000 xar->xmlsts = FILE_DATA; 2001 else if (strcmp(name, "ea") == 0) { 2002 if (xattr_new(a, xar, list) != ARCHIVE_OK) 2003 return (ARCHIVE_FATAL); 2004 xar->xmlsts = FILE_EA; 2005 } 2006 else if (strcmp(name, "ctime") == 0) 2007 xar->xmlsts = FILE_CTIME; 2008 else if (strcmp(name, "mtime") == 0) 2009 xar->xmlsts = FILE_MTIME; 2010 else if (strcmp(name, "atime") == 0) 2011 xar->xmlsts = FILE_ATIME; 2012 else if (strcmp(name, "group") == 0) 2013 xar->xmlsts = FILE_GROUP; 2014 else if (strcmp(name, "gid") == 0) 2015 xar->xmlsts = FILE_GID; 2016 else if (strcmp(name, "user") == 0) 2017 xar->xmlsts = FILE_USER; 2018 else if (strcmp(name, "uid") == 0) 2019 xar->xmlsts = FILE_UID; 2020 else if (strcmp(name, "mode") == 0) 2021 xar->xmlsts = FILE_MODE; 2022 else if (strcmp(name, "device") == 0) 2023 xar->xmlsts = FILE_DEVICE; 2024 else if (strcmp(name, "deviceno") == 0) 2025 xar->xmlsts = FILE_DEVICENO; 2026 else if (strcmp(name, "inode") == 0) 2027 xar->xmlsts = FILE_INODE; 2028 else if (strcmp(name, "link") == 0) 2029 xar->xmlsts = FILE_LINK; 2030 else if (strcmp(name, "type") == 0) { 2031 xar->xmlsts = FILE_TYPE; 2032 for (attr = list->first; attr != NULL; 2033 attr = attr->next) { 2034 if (strcmp(attr->name, "link") != 0) 2035 continue; 2036 if (strcmp(attr->value, "original") == 0) { 2037 xar->file->hdnext = xar->hdlink_orgs; 2038 xar->hdlink_orgs = xar->file; 2039 } else { 2040 xar->file->link = (unsigned)atol10(attr->value, 2041 strlen(attr->value)); 2042 if (xar->file->link > 0) 2043 if (add_link(a, xar, xar->file) != ARCHIVE_OK) { 2044 return (ARCHIVE_FATAL); 2045 }; 2046 } 2047 } 2048 } 2049 else if (strcmp(name, "name") == 0) { 2050 xar->xmlsts = FILE_NAME; 2051 for (attr = list->first; attr != NULL; 2052 attr = attr->next) { 2053 if (strcmp(attr->name, "enctype") == 0 && 2054 strcmp(attr->value, "base64") == 0) 2055 xar->base64text = 1; 2056 } 2057 } 2058 else if (strcmp(name, "acl") == 0) 2059 xar->xmlsts = FILE_ACL; 2060 else if (strcmp(name, "flags") == 0) 2061 xar->xmlsts = FILE_FLAGS; 2062 else if (strcmp(name, "ext2") == 0) 2063 xar->xmlsts = FILE_EXT2; 2064 else 2065 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2066 return (ARCHIVE_FATAL); 2067 break; 2068 case FILE_DATA: 2069 if (strcmp(name, "length") == 0) 2070 xar->xmlsts = FILE_DATA_LENGTH; 2071 else if (strcmp(name, "offset") == 0) 2072 xar->xmlsts = FILE_DATA_OFFSET; 2073 else if (strcmp(name, "size") == 0) 2074 xar->xmlsts = FILE_DATA_SIZE; 2075 else if (strcmp(name, "encoding") == 0) { 2076 xar->xmlsts = FILE_DATA_ENCODING; 2077 xar->file->encoding = getencoding(list); 2078 } 2079 else if (strcmp(name, "archived-checksum") == 0) { 2080 xar->xmlsts = FILE_DATA_A_CHECKSUM; 2081 xar->file->a_sum.alg = getsumalgorithm(list); 2082 } 2083 else if (strcmp(name, "extracted-checksum") == 0) { 2084 xar->xmlsts = FILE_DATA_E_CHECKSUM; 2085 xar->file->e_sum.alg = getsumalgorithm(list); 2086 } 2087 else if (strcmp(name, "content") == 0) 2088 xar->xmlsts = FILE_DATA_CONTENT; 2089 else 2090 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2091 return (ARCHIVE_FATAL); 2092 break; 2093 case FILE_DEVICE: 2094 if (strcmp(name, "major") == 0) 2095 xar->xmlsts = FILE_DEVICE_MAJOR; 2096 else if (strcmp(name, "minor") == 0) 2097 xar->xmlsts = FILE_DEVICE_MINOR; 2098 else 2099 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2100 return (ARCHIVE_FATAL); 2101 break; 2102 case FILE_DATA_CONTENT: 2103 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2104 return (ARCHIVE_FATAL); 2105 break; 2106 case FILE_EA: 2107 if (strcmp(name, "length") == 0) 2108 xar->xmlsts = FILE_EA_LENGTH; 2109 else if (strcmp(name, "offset") == 0) 2110 xar->xmlsts = FILE_EA_OFFSET; 2111 else if (strcmp(name, "size") == 0) 2112 xar->xmlsts = FILE_EA_SIZE; 2113 else if (strcmp(name, "encoding") == 0) { 2114 xar->xmlsts = FILE_EA_ENCODING; 2115 xar->xattr->encoding = getencoding(list); 2116 } else if (strcmp(name, "archived-checksum") == 0) 2117 xar->xmlsts = FILE_EA_A_CHECKSUM; 2118 else if (strcmp(name, "extracted-checksum") == 0) 2119 xar->xmlsts = FILE_EA_E_CHECKSUM; 2120 else if (strcmp(name, "name") == 0) 2121 xar->xmlsts = FILE_EA_NAME; 2122 else if (strcmp(name, "fstype") == 0) 2123 xar->xmlsts = FILE_EA_FSTYPE; 2124 else 2125 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2126 return (ARCHIVE_FATAL); 2127 break; 2128 case FILE_ACL: 2129 if (strcmp(name, "appleextended") == 0) 2130 xar->xmlsts = FILE_ACL_APPLEEXTENDED; 2131 else if (strcmp(name, "default") == 0) 2132 xar->xmlsts = FILE_ACL_DEFAULT; 2133 else if (strcmp(name, "access") == 0) 2134 xar->xmlsts = FILE_ACL_ACCESS; 2135 else 2136 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2137 return (ARCHIVE_FATAL); 2138 break; 2139 case FILE_FLAGS: 2140 if (!xml_parse_file_flags(xar, name)) 2141 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2142 return (ARCHIVE_FATAL); 2143 break; 2144 case FILE_EXT2: 2145 if (!xml_parse_file_ext2(xar, name)) 2146 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2147 return (ARCHIVE_FATAL); 2148 break; 2149 case TOC_CREATION_TIME: 2150 case TOC_CHECKSUM_OFFSET: 2151 case TOC_CHECKSUM_SIZE: 2152 case FILE_DATA_LENGTH: 2153 case FILE_DATA_OFFSET: 2154 case FILE_DATA_SIZE: 2155 case FILE_DATA_ENCODING: 2156 case FILE_DATA_A_CHECKSUM: 2157 case FILE_DATA_E_CHECKSUM: 2158 case FILE_EA_LENGTH: 2159 case FILE_EA_OFFSET: 2160 case FILE_EA_SIZE: 2161 case FILE_EA_ENCODING: 2162 case FILE_EA_A_CHECKSUM: 2163 case FILE_EA_E_CHECKSUM: 2164 case FILE_EA_NAME: 2165 case FILE_EA_FSTYPE: 2166 case FILE_CTIME: 2167 case FILE_MTIME: 2168 case FILE_ATIME: 2169 case FILE_GROUP: 2170 case FILE_GID: 2171 case FILE_USER: 2172 case FILE_UID: 2173 case FILE_INODE: 2174 case FILE_DEVICE_MAJOR: 2175 case FILE_DEVICE_MINOR: 2176 case FILE_DEVICENO: 2177 case FILE_MODE: 2178 case FILE_TYPE: 2179 case FILE_LINK: 2180 case FILE_NAME: 2181 case FILE_ACL_DEFAULT: 2182 case FILE_ACL_ACCESS: 2183 case FILE_ACL_APPLEEXTENDED: 2184 case FILE_FLAGS_USER_NODUMP: 2185 case FILE_FLAGS_USER_IMMUTABLE: 2186 case FILE_FLAGS_USER_APPEND: 2187 case FILE_FLAGS_USER_OPAQUE: 2188 case FILE_FLAGS_USER_NOUNLINK: 2189 case FILE_FLAGS_SYS_ARCHIVED: 2190 case FILE_FLAGS_SYS_IMMUTABLE: 2191 case FILE_FLAGS_SYS_APPEND: 2192 case FILE_FLAGS_SYS_NOUNLINK: 2193 case FILE_FLAGS_SYS_SNAPSHOT: 2194 case FILE_EXT2_SecureDeletion: 2195 case FILE_EXT2_Undelete: 2196 case FILE_EXT2_Compress: 2197 case FILE_EXT2_Synchronous: 2198 case FILE_EXT2_Immutable: 2199 case FILE_EXT2_AppendOnly: 2200 case FILE_EXT2_NoDump: 2201 case FILE_EXT2_NoAtime: 2202 case FILE_EXT2_CompDirty: 2203 case FILE_EXT2_CompBlock: 2204 case FILE_EXT2_NoCompBlock: 2205 case FILE_EXT2_CompError: 2206 case FILE_EXT2_BTree: 2207 case FILE_EXT2_HashIndexed: 2208 case FILE_EXT2_iMagic: 2209 case FILE_EXT2_Journaled: 2210 case FILE_EXT2_NoTail: 2211 case FILE_EXT2_DirSync: 2212 case FILE_EXT2_TopDir: 2213 case FILE_EXT2_Reserved: 2214 case UNKNOWN: 2215 if (unknowntag_start(a, xar, name) != ARCHIVE_OK) 2216 return (ARCHIVE_FATAL); 2217 break; 2218 } 2219 return (ARCHIVE_OK); 2220} 2221 2222static void 2223xml_end(void *userData, const char *name) 2224{ 2225 struct archive_read *a; 2226 struct xar *xar; 2227 2228 a = (struct archive_read *)userData; 2229 xar = (struct xar *)(a->format->data); 2230 2231#if DEBUG 2232 fprintf(stderr, "xml_end:[%s]\n", name); 2233#endif 2234 switch (xar->xmlsts) { 2235 case INIT: 2236 break; 2237 case XAR: 2238 if (strcmp(name, "xar") == 0) 2239 xar->xmlsts = INIT; 2240 break; 2241 case TOC: 2242 if (strcmp(name, "toc") == 0) 2243 xar->xmlsts = XAR; 2244 break; 2245 case TOC_CREATION_TIME: 2246 if (strcmp(name, "creation-time") == 0) 2247 xar->xmlsts = TOC; 2248 break; 2249 case TOC_CHECKSUM: 2250 if (strcmp(name, "checksum") == 0) 2251 xar->xmlsts = TOC; 2252 break; 2253 case TOC_CHECKSUM_OFFSET: 2254 if (strcmp(name, "offset") == 0) 2255 xar->xmlsts = TOC_CHECKSUM; 2256 break; 2257 case TOC_CHECKSUM_SIZE: 2258 if (strcmp(name, "size") == 0) 2259 xar->xmlsts = TOC_CHECKSUM; 2260 break; 2261 case TOC_FILE: 2262 if (strcmp(name, "file") == 0) { 2263 if (xar->file->parent != NULL && 2264 ((xar->file->mode & AE_IFMT) == AE_IFDIR)) 2265 xar->file->parent->subdirs++; 2266 xar->file = xar->file->parent; 2267 if (xar->file == NULL) 2268 xar->xmlsts = TOC; 2269 } 2270 break; 2271 case FILE_DATA: 2272 if (strcmp(name, "data") == 0) 2273 xar->xmlsts = TOC_FILE; 2274 break; 2275 case FILE_DATA_LENGTH: 2276 if (strcmp(name, "length") == 0) 2277 xar->xmlsts = FILE_DATA; 2278 break; 2279 case FILE_DATA_OFFSET: 2280 if (strcmp(name, "offset") == 0) 2281 xar->xmlsts = FILE_DATA; 2282 break; 2283 case FILE_DATA_SIZE: 2284 if (strcmp(name, "size") == 0) 2285 xar->xmlsts = FILE_DATA; 2286 break; 2287 case FILE_DATA_ENCODING: 2288 if (strcmp(name, "encoding") == 0) 2289 xar->xmlsts = FILE_DATA; 2290 break; 2291 case FILE_DATA_A_CHECKSUM: 2292 if (strcmp(name, "archived-checksum") == 0) 2293 xar->xmlsts = FILE_DATA; 2294 break; 2295 case FILE_DATA_E_CHECKSUM: 2296 if (strcmp(name, "extracted-checksum") == 0) 2297 xar->xmlsts = FILE_DATA; 2298 break; 2299 case FILE_DATA_CONTENT: 2300 if (strcmp(name, "content") == 0) 2301 xar->xmlsts = FILE_DATA; 2302 break; 2303 case FILE_EA: 2304 if (strcmp(name, "ea") == 0) { 2305 xar->xmlsts = TOC_FILE; 2306 xar->xattr = NULL; 2307 } 2308 break; 2309 case FILE_EA_LENGTH: 2310 if (strcmp(name, "length") == 0) 2311 xar->xmlsts = FILE_EA; 2312 break; 2313 case FILE_EA_OFFSET: 2314 if (strcmp(name, "offset") == 0) 2315 xar->xmlsts = FILE_EA; 2316 break; 2317 case FILE_EA_SIZE: 2318 if (strcmp(name, "size") == 0) 2319 xar->xmlsts = FILE_EA; 2320 break; 2321 case FILE_EA_ENCODING: 2322 if (strcmp(name, "encoding") == 0) 2323 xar->xmlsts = FILE_EA; 2324 break; 2325 case FILE_EA_A_CHECKSUM: 2326 if (strcmp(name, "archived-checksum") == 0) 2327 xar->xmlsts = FILE_EA; 2328 break; 2329 case FILE_EA_E_CHECKSUM: 2330 if (strcmp(name, "extracted-checksum") == 0) 2331 xar->xmlsts = FILE_EA; 2332 break; 2333 case FILE_EA_NAME: 2334 if (strcmp(name, "name") == 0) 2335 xar->xmlsts = FILE_EA; 2336 break; 2337 case FILE_EA_FSTYPE: 2338 if (strcmp(name, "fstype") == 0) 2339 xar->xmlsts = FILE_EA; 2340 break; 2341 case FILE_CTIME: 2342 if (strcmp(name, "ctime") == 0) 2343 xar->xmlsts = TOC_FILE; 2344 break; 2345 case FILE_MTIME: 2346 if (strcmp(name, "mtime") == 0) 2347 xar->xmlsts = TOC_FILE; 2348 break; 2349 case FILE_ATIME: 2350 if (strcmp(name, "atime") == 0) 2351 xar->xmlsts = TOC_FILE; 2352 break; 2353 case FILE_GROUP: 2354 if (strcmp(name, "group") == 0) 2355 xar->xmlsts = TOC_FILE; 2356 break; 2357 case FILE_GID: 2358 if (strcmp(name, "gid") == 0) 2359 xar->xmlsts = TOC_FILE; 2360 break; 2361 case FILE_USER: 2362 if (strcmp(name, "user") == 0) 2363 xar->xmlsts = TOC_FILE; 2364 break; 2365 case FILE_UID: 2366 if (strcmp(name, "uid") == 0) 2367 xar->xmlsts = TOC_FILE; 2368 break; 2369 case FILE_MODE: 2370 if (strcmp(name, "mode") == 0) 2371 xar->xmlsts = TOC_FILE; 2372 break; 2373 case FILE_DEVICE: 2374 if (strcmp(name, "device") == 0) 2375 xar->xmlsts = TOC_FILE; 2376 break; 2377 case FILE_DEVICE_MAJOR: 2378 if (strcmp(name, "major") == 0) 2379 xar->xmlsts = FILE_DEVICE; 2380 break; 2381 case FILE_DEVICE_MINOR: 2382 if (strcmp(name, "minor") == 0) 2383 xar->xmlsts = FILE_DEVICE; 2384 break; 2385 case FILE_DEVICENO: 2386 if (strcmp(name, "deviceno") == 0) 2387 xar->xmlsts = TOC_FILE; 2388 break; 2389 case FILE_INODE: 2390 if (strcmp(name, "inode") == 0) 2391 xar->xmlsts = TOC_FILE; 2392 break; 2393 case FILE_LINK: 2394 if (strcmp(name, "link") == 0) 2395 xar->xmlsts = TOC_FILE; 2396 break; 2397 case FILE_TYPE: 2398 if (strcmp(name, "type") == 0) 2399 xar->xmlsts = TOC_FILE; 2400 break; 2401 case FILE_NAME: 2402 if (strcmp(name, "name") == 0) 2403 xar->xmlsts = TOC_FILE; 2404 break; 2405 case FILE_ACL: 2406 if (strcmp(name, "acl") == 0) 2407 xar->xmlsts = TOC_FILE; 2408 break; 2409 case FILE_ACL_DEFAULT: 2410 if (strcmp(name, "default") == 0) 2411 xar->xmlsts = FILE_ACL; 2412 break; 2413 case FILE_ACL_ACCESS: 2414 if (strcmp(name, "access") == 0) 2415 xar->xmlsts = FILE_ACL; 2416 break; 2417 case FILE_ACL_APPLEEXTENDED: 2418 if (strcmp(name, "appleextended") == 0) 2419 xar->xmlsts = FILE_ACL; 2420 break; 2421 case FILE_FLAGS: 2422 if (strcmp(name, "flags") == 0) 2423 xar->xmlsts = TOC_FILE; 2424 break; 2425 case FILE_FLAGS_USER_NODUMP: 2426 if (strcmp(name, "UserNoDump") == 0) 2427 xar->xmlsts = FILE_FLAGS; 2428 break; 2429 case FILE_FLAGS_USER_IMMUTABLE: 2430 if (strcmp(name, "UserImmutable") == 0) 2431 xar->xmlsts = FILE_FLAGS; 2432 break; 2433 case FILE_FLAGS_USER_APPEND: 2434 if (strcmp(name, "UserAppend") == 0) 2435 xar->xmlsts = FILE_FLAGS; 2436 break; 2437 case FILE_FLAGS_USER_OPAQUE: 2438 if (strcmp(name, "UserOpaque") == 0) 2439 xar->xmlsts = FILE_FLAGS; 2440 break; 2441 case FILE_FLAGS_USER_NOUNLINK: 2442 if (strcmp(name, "UserNoUnlink") == 0) 2443 xar->xmlsts = FILE_FLAGS; 2444 break; 2445 case FILE_FLAGS_SYS_ARCHIVED: 2446 if (strcmp(name, "SystemArchived") == 0) 2447 xar->xmlsts = FILE_FLAGS; 2448 break; 2449 case FILE_FLAGS_SYS_IMMUTABLE: 2450 if (strcmp(name, "SystemImmutable") == 0) 2451 xar->xmlsts = FILE_FLAGS; 2452 break; 2453 case FILE_FLAGS_SYS_APPEND: 2454 if (strcmp(name, "SystemAppend") == 0) 2455 xar->xmlsts = FILE_FLAGS; 2456 break; 2457 case FILE_FLAGS_SYS_NOUNLINK: 2458 if (strcmp(name, "SystemNoUnlink") == 0) 2459 xar->xmlsts = FILE_FLAGS; 2460 break; 2461 case FILE_FLAGS_SYS_SNAPSHOT: 2462 if (strcmp(name, "SystemSnapshot") == 0) 2463 xar->xmlsts = FILE_FLAGS; 2464 break; 2465 case FILE_EXT2: 2466 if (strcmp(name, "ext2") == 0) 2467 xar->xmlsts = TOC_FILE; 2468 break; 2469 case FILE_EXT2_SecureDeletion: 2470 if (strcmp(name, "SecureDeletion") == 0) 2471 xar->xmlsts = FILE_EXT2; 2472 break; 2473 case FILE_EXT2_Undelete: 2474 if (strcmp(name, "Undelete") == 0) 2475 xar->xmlsts = FILE_EXT2; 2476 break; 2477 case FILE_EXT2_Compress: 2478 if (strcmp(name, "Compress") == 0) 2479 xar->xmlsts = FILE_EXT2; 2480 break; 2481 case FILE_EXT2_Synchronous: 2482 if (strcmp(name, "Synchronous") == 0) 2483 xar->xmlsts = FILE_EXT2; 2484 break; 2485 case FILE_EXT2_Immutable: 2486 if (strcmp(name, "Immutable") == 0) 2487 xar->xmlsts = FILE_EXT2; 2488 break; 2489 case FILE_EXT2_AppendOnly: 2490 if (strcmp(name, "AppendOnly") == 0) 2491 xar->xmlsts = FILE_EXT2; 2492 break; 2493 case FILE_EXT2_NoDump: 2494 if (strcmp(name, "NoDump") == 0) 2495 xar->xmlsts = FILE_EXT2; 2496 break; 2497 case FILE_EXT2_NoAtime: 2498 if (strcmp(name, "NoAtime") == 0) 2499 xar->xmlsts = FILE_EXT2; 2500 break; 2501 case FILE_EXT2_CompDirty: 2502 if (strcmp(name, "CompDirty") == 0) 2503 xar->xmlsts = FILE_EXT2; 2504 break; 2505 case FILE_EXT2_CompBlock: 2506 if (strcmp(name, "CompBlock") == 0) 2507 xar->xmlsts = FILE_EXT2; 2508 break; 2509 case FILE_EXT2_NoCompBlock: 2510 if (strcmp(name, "NoCompBlock") == 0) 2511 xar->xmlsts = FILE_EXT2; 2512 break; 2513 case FILE_EXT2_CompError: 2514 if (strcmp(name, "CompError") == 0) 2515 xar->xmlsts = FILE_EXT2; 2516 break; 2517 case FILE_EXT2_BTree: 2518 if (strcmp(name, "BTree") == 0) 2519 xar->xmlsts = FILE_EXT2; 2520 break; 2521 case FILE_EXT2_HashIndexed: 2522 if (strcmp(name, "HashIndexed") == 0) 2523 xar->xmlsts = FILE_EXT2; 2524 break; 2525 case FILE_EXT2_iMagic: 2526 if (strcmp(name, "iMagic") == 0) 2527 xar->xmlsts = FILE_EXT2; 2528 break; 2529 case FILE_EXT2_Journaled: 2530 if (strcmp(name, "Journaled") == 0) 2531 xar->xmlsts = FILE_EXT2; 2532 break; 2533 case FILE_EXT2_NoTail: 2534 if (strcmp(name, "NoTail") == 0) 2535 xar->xmlsts = FILE_EXT2; 2536 break; 2537 case FILE_EXT2_DirSync: 2538 if (strcmp(name, "DirSync") == 0) 2539 xar->xmlsts = FILE_EXT2; 2540 break; 2541 case FILE_EXT2_TopDir: 2542 if (strcmp(name, "TopDir") == 0) 2543 xar->xmlsts = FILE_EXT2; 2544 break; 2545 case FILE_EXT2_Reserved: 2546 if (strcmp(name, "Reserved") == 0) 2547 xar->xmlsts = FILE_EXT2; 2548 break; 2549 case UNKNOWN: 2550 unknowntag_end(xar, name); 2551 break; 2552 } 2553} 2554 2555static const int base64[256] = { 2556 -1, -1, -1, -1, -1, -1, -1, -1, 2557 -1, -1, -1, -1, -1, -1, -1, -1, /* 00 - 0F */ 2558 -1, -1, -1, -1, -1, -1, -1, -1, 2559 -1, -1, -1, -1, -1, -1, -1, -1, /* 10 - 1F */ 2560 -1, -1, -1, -1, -1, -1, -1, -1, 2561 -1, -1, -1, 62, -1, -1, -1, 63, /* 20 - 2F */ 2562 52, 53, 54, 55, 56, 57, 58, 59, 2563 60, 61, -1, -1, -1, -1, -1, -1, /* 30 - 3F */ 2564 -1, 0, 1, 2, 3, 4, 5, 6, 2565 7, 8, 9, 10, 11, 12, 13, 14, /* 40 - 4F */ 2566 15, 16, 17, 18, 19, 20, 21, 22, 2567 23, 24, 25, -1, -1, -1, -1, -1, /* 50 - 5F */ 2568 -1, 26, 27, 28, 29, 30, 31, 32, 2569 33, 34, 35, 36, 37, 38, 39, 40, /* 60 - 6F */ 2570 41, 42, 43, 44, 45, 46, 47, 48, 2571 49, 50, 51, -1, -1, -1, -1, -1, /* 70 - 7F */ 2572 -1, -1, -1, -1, -1, -1, -1, -1, 2573 -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 8F */ 2574 -1, -1, -1, -1, -1, -1, -1, -1, 2575 -1, -1, -1, -1, -1, -1, -1, -1, /* 90 - 9F */ 2576 -1, -1, -1, -1, -1, -1, -1, -1, 2577 -1, -1, -1, -1, -1, -1, -1, -1, /* A0 - AF */ 2578 -1, -1, -1, -1, -1, -1, -1, -1, 2579 -1, -1, -1, -1, -1, -1, -1, -1, /* B0 - BF */ 2580 -1, -1, -1, -1, -1, -1, -1, -1, 2581 -1, -1, -1, -1, -1, -1, -1, -1, /* C0 - CF */ 2582 -1, -1, -1, -1, -1, -1, -1, -1, 2583 -1, -1, -1, -1, -1, -1, -1, -1, /* D0 - DF */ 2584 -1, -1, -1, -1, -1, -1, -1, -1, 2585 -1, -1, -1, -1, -1, -1, -1, -1, /* E0 - EF */ 2586 -1, -1, -1, -1, -1, -1, -1, -1, 2587 -1, -1, -1, -1, -1, -1, -1, -1, /* F0 - FF */ 2588}; 2589 2590static void 2591strappend_base64(struct xar *xar, 2592 struct archive_string *as, const char *s, size_t l) 2593{ 2594 unsigned char buff[256]; 2595 unsigned char *out; 2596 const unsigned char *b; 2597 size_t len; 2598 2599 (void)xar; /* UNUSED */ 2600 len = 0; 2601 out = buff; 2602 b = (const unsigned char *)s; 2603 while (l > 0) { 2604 int n = 0; 2605 2606 if (l > 0) { 2607 if (base64[b[0]] < 0 || base64[b[1]] < 0) 2608 break; 2609 n = base64[*b++] << 18; 2610 n |= base64[*b++] << 12; 2611 *out++ = n >> 16; 2612 len++; 2613 l -= 2; 2614 } 2615 if (l > 0) { 2616 if (base64[*b] < 0) 2617 break; 2618 n |= base64[*b++] << 6; 2619 *out++ = (n >> 8) & 0xFF; 2620 len++; 2621 --l; 2622 } 2623 if (l > 0) { 2624 if (base64[*b] < 0) 2625 break; 2626 n |= base64[*b++]; 2627 *out++ = n & 0xFF; 2628 len++; 2629 --l; 2630 } 2631 if (len+3 >= sizeof(buff)) { 2632 archive_strncat(as, (const char *)buff, len); 2633 len = 0; 2634 out = buff; 2635 } 2636 } 2637 if (len > 0) 2638 archive_strncat(as, (const char *)buff, len); 2639} 2640 2641static int 2642is_string(const char *known, const char *data, size_t len) 2643{ 2644 if (strlen(known) != len) 2645 return -1; 2646 return memcmp(data, known, len); 2647} 2648 2649static void 2650xml_data(void *userData, const char *s, int len) 2651{ 2652 struct archive_read *a; 2653 struct xar *xar; 2654 2655 a = (struct archive_read *)userData; 2656 xar = (struct xar *)(a->format->data); 2657 2658#if DEBUG 2659 { 2660 char buff[1024]; 2661 if (len > (int)(sizeof(buff)-1)) 2662 len = (int)(sizeof(buff)-1); 2663 strncpy(buff, s, len); 2664 buff[len] = 0; 2665 fprintf(stderr, "\tlen=%d:\"%s\"\n", len, buff); 2666 } 2667#endif 2668 switch (xar->xmlsts) { 2669 case TOC_CHECKSUM_OFFSET: 2670 xar->toc_chksum_offset = atol10(s, len); 2671 break; 2672 case TOC_CHECKSUM_SIZE: 2673 xar->toc_chksum_size = atol10(s, len); 2674 break; 2675 default: 2676 break; 2677 } 2678 if (xar->file == NULL) 2679 return; 2680 2681 switch (xar->xmlsts) { 2682 case FILE_NAME: 2683 if (xar->file->parent != NULL) { 2684 archive_string_concat(&(xar->file->pathname), 2685 &(xar->file->parent->pathname)); 2686 archive_strappend_char(&(xar->file->pathname), '/'); 2687 } 2688 xar->file->has |= HAS_PATHNAME; 2689 if (xar->base64text) { 2690 strappend_base64(xar, 2691 &(xar->file->pathname), s, len); 2692 } else 2693 archive_strncat(&(xar->file->pathname), s, len); 2694 break; 2695 case FILE_LINK: 2696 xar->file->has |= HAS_SYMLINK; 2697 archive_strncpy(&(xar->file->symlink), s, len); 2698 break; 2699 case FILE_TYPE: 2700 if (is_string("file", s, len) == 0 || 2701 is_string("hardlink", s, len) == 0) 2702 xar->file->mode = 2703 (xar->file->mode & ~AE_IFMT) | AE_IFREG; 2704 if (is_string("directory", s, len) == 0) 2705 xar->file->mode = 2706 (xar->file->mode & ~AE_IFMT) | AE_IFDIR; 2707 if (is_string("symlink", s, len) == 0) 2708 xar->file->mode = 2709 (xar->file->mode & ~AE_IFMT) | AE_IFLNK; 2710 if (is_string("character special", s, len) == 0) 2711 xar->file->mode = 2712 (xar->file->mode & ~AE_IFMT) | AE_IFCHR; 2713 if (is_string("block special", s, len) == 0) 2714 xar->file->mode = 2715 (xar->file->mode & ~AE_IFMT) | AE_IFBLK; 2716 if (is_string("socket", s, len) == 0) 2717 xar->file->mode = 2718 (xar->file->mode & ~AE_IFMT) | AE_IFSOCK; 2719 if (is_string("fifo", s, len) == 0) 2720 xar->file->mode = 2721 (xar->file->mode & ~AE_IFMT) | AE_IFIFO; 2722 xar->file->has |= HAS_TYPE; 2723 break; 2724 case FILE_INODE: 2725 xar->file->has |= HAS_INO; 2726 xar->file->ino64 = atol10(s, len); 2727 break; 2728 case FILE_DEVICE_MAJOR: 2729 xar->file->has |= HAS_DEVMAJOR; 2730 xar->file->devmajor = (dev_t)atol10(s, len); 2731 break; 2732 case FILE_DEVICE_MINOR: 2733 xar->file->has |= HAS_DEVMINOR; 2734 xar->file->devminor = (dev_t)atol10(s, len); 2735 break; 2736 case FILE_DEVICENO: 2737 xar->file->has |= HAS_DEV; 2738 xar->file->dev = (dev_t)atol10(s, len); 2739 break; 2740 case FILE_MODE: 2741 xar->file->has |= HAS_MODE; 2742 xar->file->mode = 2743 (xar->file->mode & AE_IFMT) | 2744 ((mode_t)(atol8(s, len)) & ~AE_IFMT); 2745 break; 2746 case FILE_GROUP: 2747 xar->file->has |= HAS_GID; 2748 archive_strncpy(&(xar->file->gname), s, len); 2749 break; 2750 case FILE_GID: 2751 xar->file->has |= HAS_GID; 2752 xar->file->gid = atol10(s, len); 2753 break; 2754 case FILE_USER: 2755 xar->file->has |= HAS_UID; 2756 archive_strncpy(&(xar->file->uname), s, len); 2757 break; 2758 case FILE_UID: 2759 xar->file->has |= HAS_UID; 2760 xar->file->uid = atol10(s, len); 2761 break; 2762 case FILE_CTIME: 2763 xar->file->has |= HAS_TIME | HAS_CTIME; 2764 xar->file->ctime = parse_time(s, len); 2765 break; 2766 case FILE_MTIME: 2767 xar->file->has |= HAS_TIME | HAS_MTIME; 2768 xar->file->mtime = parse_time(s, len); 2769 break; 2770 case FILE_ATIME: 2771 xar->file->has |= HAS_TIME | HAS_ATIME; 2772 xar->file->atime = parse_time(s, len); 2773 break; 2774 case FILE_DATA_LENGTH: 2775 xar->file->has |= HAS_DATA; 2776 xar->file->length = atol10(s, len); 2777 break; 2778 case FILE_DATA_OFFSET: 2779 xar->file->has |= HAS_DATA; 2780 xar->file->offset = atol10(s, len); 2781 break; 2782 case FILE_DATA_SIZE: 2783 xar->file->has |= HAS_DATA; 2784 xar->file->size = atol10(s, len); 2785 break; 2786 case FILE_DATA_A_CHECKSUM: 2787 xar->file->a_sum.len = atohex(xar->file->a_sum.val, 2788 sizeof(xar->file->a_sum.val), s, len); 2789 break; 2790 case FILE_DATA_E_CHECKSUM: 2791 xar->file->e_sum.len = atohex(xar->file->e_sum.val, 2792 sizeof(xar->file->e_sum.val), s, len); 2793 break; 2794 case FILE_EA_LENGTH: 2795 xar->file->has |= HAS_XATTR; 2796 xar->xattr->length = atol10(s, len); 2797 break; 2798 case FILE_EA_OFFSET: 2799 xar->file->has |= HAS_XATTR; 2800 xar->xattr->offset = atol10(s, len); 2801 break; 2802 case FILE_EA_SIZE: 2803 xar->file->has |= HAS_XATTR; 2804 xar->xattr->size = atol10(s, len); 2805 break; 2806 case FILE_EA_A_CHECKSUM: 2807 xar->file->has |= HAS_XATTR; 2808 xar->xattr->a_sum.len = atohex(xar->xattr->a_sum.val, 2809 sizeof(xar->xattr->a_sum.val), s, len); 2810 break; 2811 case FILE_EA_E_CHECKSUM: 2812 xar->file->has |= HAS_XATTR; 2813 xar->xattr->e_sum.len = atohex(xar->xattr->e_sum.val, 2814 sizeof(xar->xattr->e_sum.val), s, len); 2815 break; 2816 case FILE_EA_NAME: 2817 xar->file->has |= HAS_XATTR; 2818 archive_strncpy(&(xar->xattr->name), s, len); 2819 break; 2820 case FILE_EA_FSTYPE: 2821 xar->file->has |= HAS_XATTR; 2822 archive_strncpy(&(xar->xattr->fstype), s, len); 2823 break; 2824 break; 2825 case FILE_ACL_DEFAULT: 2826 case FILE_ACL_ACCESS: 2827 case FILE_ACL_APPLEEXTENDED: 2828 xar->file->has |= HAS_ACL; 2829 /* TODO */ 2830 break; 2831 case INIT: 2832 case XAR: 2833 case TOC: 2834 case TOC_CREATION_TIME: 2835 case TOC_CHECKSUM: 2836 case TOC_CHECKSUM_OFFSET: 2837 case TOC_CHECKSUM_SIZE: 2838 case TOC_FILE: 2839 case FILE_DATA: 2840 case FILE_DATA_ENCODING: 2841 case FILE_DATA_CONTENT: 2842 case FILE_DEVICE: 2843 case FILE_EA: 2844 case FILE_EA_ENCODING: 2845 case FILE_ACL: 2846 case FILE_FLAGS: 2847 case FILE_FLAGS_USER_NODUMP: 2848 case FILE_FLAGS_USER_IMMUTABLE: 2849 case FILE_FLAGS_USER_APPEND: 2850 case FILE_FLAGS_USER_OPAQUE: 2851 case FILE_FLAGS_USER_NOUNLINK: 2852 case FILE_FLAGS_SYS_ARCHIVED: 2853 case FILE_FLAGS_SYS_IMMUTABLE: 2854 case FILE_FLAGS_SYS_APPEND: 2855 case FILE_FLAGS_SYS_NOUNLINK: 2856 case FILE_FLAGS_SYS_SNAPSHOT: 2857 case FILE_EXT2: 2858 case FILE_EXT2_SecureDeletion: 2859 case FILE_EXT2_Undelete: 2860 case FILE_EXT2_Compress: 2861 case FILE_EXT2_Synchronous: 2862 case FILE_EXT2_Immutable: 2863 case FILE_EXT2_AppendOnly: 2864 case FILE_EXT2_NoDump: 2865 case FILE_EXT2_NoAtime: 2866 case FILE_EXT2_CompDirty: 2867 case FILE_EXT2_CompBlock: 2868 case FILE_EXT2_NoCompBlock: 2869 case FILE_EXT2_CompError: 2870 case FILE_EXT2_BTree: 2871 case FILE_EXT2_HashIndexed: 2872 case FILE_EXT2_iMagic: 2873 case FILE_EXT2_Journaled: 2874 case FILE_EXT2_NoTail: 2875 case FILE_EXT2_DirSync: 2876 case FILE_EXT2_TopDir: 2877 case FILE_EXT2_Reserved: 2878 case UNKNOWN: 2879 break; 2880 } 2881} 2882 2883/* 2884 * BSD file flags. 2885 */ 2886static int 2887xml_parse_file_flags(struct xar *xar, const char *name) 2888{ 2889 const char *flag = NULL; 2890 2891 if (strcmp(name, "UserNoDump") == 0) { 2892 xar->xmlsts = FILE_FLAGS_USER_NODUMP; 2893 flag = "nodump"; 2894 } 2895 else if (strcmp(name, "UserImmutable") == 0) { 2896 xar->xmlsts = FILE_FLAGS_USER_IMMUTABLE; 2897 flag = "uimmutable"; 2898 } 2899 else if (strcmp(name, "UserAppend") == 0) { 2900 xar->xmlsts = FILE_FLAGS_USER_APPEND; 2901 flag = "uappend"; 2902 } 2903 else if (strcmp(name, "UserOpaque") == 0) { 2904 xar->xmlsts = FILE_FLAGS_USER_OPAQUE; 2905 flag = "opaque"; 2906 } 2907 else if (strcmp(name, "UserNoUnlink") == 0) { 2908 xar->xmlsts = FILE_FLAGS_USER_NOUNLINK; 2909 flag = "nouunlink"; 2910 } 2911 else if (strcmp(name, "SystemArchived") == 0) { 2912 xar->xmlsts = FILE_FLAGS_SYS_ARCHIVED; 2913 flag = "archived"; 2914 } 2915 else if (strcmp(name, "SystemImmutable") == 0) { 2916 xar->xmlsts = FILE_FLAGS_SYS_IMMUTABLE; 2917 flag = "simmutable"; 2918 } 2919 else if (strcmp(name, "SystemAppend") == 0) { 2920 xar->xmlsts = FILE_FLAGS_SYS_APPEND; 2921 flag = "sappend"; 2922 } 2923 else if (strcmp(name, "SystemNoUnlink") == 0) { 2924 xar->xmlsts = FILE_FLAGS_SYS_NOUNLINK; 2925 flag = "nosunlink"; 2926 } 2927 else if (strcmp(name, "SystemSnapshot") == 0) { 2928 xar->xmlsts = FILE_FLAGS_SYS_SNAPSHOT; 2929 flag = "snapshot"; 2930 } 2931 2932 if (flag == NULL) 2933 return (0); 2934 xar->file->has |= HAS_FFLAGS; 2935 if (archive_strlen(&(xar->file->fflags_text)) > 0) 2936 archive_strappend_char(&(xar->file->fflags_text), ','); 2937 archive_strcat(&(xar->file->fflags_text), flag); 2938 return (1); 2939} 2940 2941/* 2942 * Linux file flags. 2943 */ 2944static int 2945xml_parse_file_ext2(struct xar *xar, const char *name) 2946{ 2947 const char *flag = NULL; 2948 2949 if (strcmp(name, "SecureDeletion") == 0) { 2950 xar->xmlsts = FILE_EXT2_SecureDeletion; 2951 flag = "securedeletion"; 2952 } 2953 else if (strcmp(name, "Undelete") == 0) { 2954 xar->xmlsts = FILE_EXT2_Undelete; 2955 flag = "nouunlink"; 2956 } 2957 else if (strcmp(name, "Compress") == 0) { 2958 xar->xmlsts = FILE_EXT2_Compress; 2959 flag = "compress"; 2960 } 2961 else if (strcmp(name, "Synchronous") == 0) { 2962 xar->xmlsts = FILE_EXT2_Synchronous; 2963 flag = "sync"; 2964 } 2965 else if (strcmp(name, "Immutable") == 0) { 2966 xar->xmlsts = FILE_EXT2_Immutable; 2967 flag = "simmutable"; 2968 } 2969 else if (strcmp(name, "AppendOnly") == 0) { 2970 xar->xmlsts = FILE_EXT2_AppendOnly; 2971 flag = "sappend"; 2972 } 2973 else if (strcmp(name, "NoDump") == 0) { 2974 xar->xmlsts = FILE_EXT2_NoDump; 2975 flag = "nodump"; 2976 } 2977 else if (strcmp(name, "NoAtime") == 0) { 2978 xar->xmlsts = FILE_EXT2_NoAtime; 2979 flag = "noatime"; 2980 } 2981 else if (strcmp(name, "CompDirty") == 0) { 2982 xar->xmlsts = FILE_EXT2_CompDirty; 2983 flag = "compdirty"; 2984 } 2985 else if (strcmp(name, "CompBlock") == 0) { 2986 xar->xmlsts = FILE_EXT2_CompBlock; 2987 flag = "comprblk"; 2988 } 2989 else if (strcmp(name, "NoCompBlock") == 0) { 2990 xar->xmlsts = FILE_EXT2_NoCompBlock; 2991 flag = "nocomprblk"; 2992 } 2993 else if (strcmp(name, "CompError") == 0) { 2994 xar->xmlsts = FILE_EXT2_CompError; 2995 flag = "comperr"; 2996 } 2997 else if (strcmp(name, "BTree") == 0) { 2998 xar->xmlsts = FILE_EXT2_BTree; 2999 flag = "btree"; 3000 } 3001 else if (strcmp(name, "HashIndexed") == 0) { 3002 xar->xmlsts = FILE_EXT2_HashIndexed; 3003 flag = "hashidx"; 3004 } 3005 else if (strcmp(name, "iMagic") == 0) { 3006 xar->xmlsts = FILE_EXT2_iMagic; 3007 flag = "imagic"; 3008 } 3009 else if (strcmp(name, "Journaled") == 0) { 3010 xar->xmlsts = FILE_EXT2_Journaled; 3011 flag = "journal"; 3012 } 3013 else if (strcmp(name, "NoTail") == 0) { 3014 xar->xmlsts = FILE_EXT2_NoTail; 3015 flag = "notail"; 3016 } 3017 else if (strcmp(name, "DirSync") == 0) { 3018 xar->xmlsts = FILE_EXT2_DirSync; 3019 flag = "dirsync"; 3020 } 3021 else if (strcmp(name, "TopDir") == 0) { 3022 xar->xmlsts = FILE_EXT2_TopDir; 3023 flag = "topdir"; 3024 } 3025 else if (strcmp(name, "Reserved") == 0) { 3026 xar->xmlsts = FILE_EXT2_Reserved; 3027 flag = "reserved"; 3028 } 3029 3030 if (flag == NULL) 3031 return (0); 3032 if (archive_strlen(&(xar->file->fflags_text)) > 0) 3033 archive_strappend_char(&(xar->file->fflags_text), ','); 3034 archive_strcat(&(xar->file->fflags_text), flag); 3035 return (1); 3036} 3037 3038#ifdef HAVE_LIBXML_XMLREADER_H 3039 3040static int 3041xml2_xmlattr_setup(struct archive_read *a, 3042 struct xmlattr_list *list, xmlTextReaderPtr reader) 3043{ 3044 struct xmlattr *attr; 3045 int r; 3046 3047 list->first = NULL; 3048 list->last = &(list->first); 3049 r = xmlTextReaderMoveToFirstAttribute(reader); 3050 while (r == 1) { 3051 attr = malloc(sizeof*(attr)); 3052 if (attr == NULL) { 3053 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 3054 return (ARCHIVE_FATAL); 3055 } 3056 attr->name = strdup( 3057 (const char *)xmlTextReaderConstLocalName(reader)); 3058 if (attr->name == NULL) { 3059 free(attr); 3060 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 3061 return (ARCHIVE_FATAL); 3062 } 3063 attr->value = strdup( 3064 (const char *)xmlTextReaderConstValue(reader)); 3065 if (attr->value == NULL) { 3066 free(attr->name); 3067 free(attr); 3068 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 3069 return (ARCHIVE_FATAL); 3070 } 3071 attr->next = NULL; 3072 *list->last = attr; 3073 list->last = &(attr->next); 3074 r = xmlTextReaderMoveToNextAttribute(reader); 3075 } 3076 return (r); 3077} 3078 3079static int 3080xml2_read_cb(void *context, char *buffer, int len) 3081{ 3082 struct archive_read *a; 3083 struct xar *xar; 3084 const void *d; 3085 size_t outbytes; 3086 size_t used = 0; 3087 int r; 3088 3089 a = (struct archive_read *)context; 3090 xar = (struct xar *)(a->format->data); 3091 3092 if (xar->toc_remaining <= 0) 3093 return (0); 3094 d = buffer; 3095 outbytes = len; 3096 r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining); 3097 if (r != ARCHIVE_OK) 3098 return (r); 3099 __archive_read_consume(a, used); 3100 xar->toc_remaining -= used; 3101 xar->offset += used; 3102 xar->toc_total += outbytes; 3103 PRINT_TOC(buffer, len); 3104 3105 return ((int)outbytes); 3106} 3107 3108static int 3109xml2_close_cb(void *context) 3110{ 3111 3112 (void)context; /* UNUSED */ 3113 return (0); 3114} 3115 3116static void 3117xml2_error_hdr(void *arg, const char *msg, xmlParserSeverities severity, 3118 xmlTextReaderLocatorPtr locator) 3119{ 3120 struct archive_read *a; 3121 3122 (void)locator; /* UNUSED */ 3123 a = (struct archive_read *)arg; 3124 switch (severity) { 3125 case XML_PARSER_SEVERITY_VALIDITY_WARNING: 3126 case XML_PARSER_SEVERITY_WARNING: 3127 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 3128 "XML Parsing error: %s", msg); 3129 break; 3130 case XML_PARSER_SEVERITY_VALIDITY_ERROR: 3131 case XML_PARSER_SEVERITY_ERROR: 3132 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 3133 "XML Parsing error: %s", msg); 3134 break; 3135 } 3136} 3137 3138static int 3139xml2_read_toc(struct archive_read *a) 3140{ 3141 xmlTextReaderPtr reader; 3142 struct xmlattr_list list; 3143 int r; 3144 3145 reader = xmlReaderForIO(xml2_read_cb, xml2_close_cb, a, NULL, NULL, 0); 3146 if (reader == NULL) { 3147 archive_set_error(&a->archive, ENOMEM, 3148 "Couldn't allocate memory for xml parser"); 3149 return (ARCHIVE_FATAL); 3150 } 3151 xmlTextReaderSetErrorHandler(reader, xml2_error_hdr, a); 3152 3153 while ((r = xmlTextReaderRead(reader)) == 1) { 3154 const char *name, *value; 3155 int type, empty; 3156 3157 type = xmlTextReaderNodeType(reader); 3158 name = (const char *)xmlTextReaderConstLocalName(reader); 3159 switch (type) { 3160 case XML_READER_TYPE_ELEMENT: 3161 empty = xmlTextReaderIsEmptyElement(reader); 3162 r = xml2_xmlattr_setup(a, &list, reader); 3163 if (r == ARCHIVE_OK) 3164 r = xml_start(a, name, &list); 3165 xmlattr_cleanup(&list); 3166 if (r != ARCHIVE_OK) 3167 return (r); 3168 if (empty) 3169 xml_end(a, name); 3170 break; 3171 case XML_READER_TYPE_END_ELEMENT: 3172 xml_end(a, name); 3173 break; 3174 case XML_READER_TYPE_TEXT: 3175 value = (const char *)xmlTextReaderConstValue(reader); 3176 xml_data(a, value, strlen(value)); 3177 break; 3178 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: 3179 default: 3180 break; 3181 } 3182 if (r < 0) 3183 break; 3184 } 3185 xmlFreeTextReader(reader); 3186 xmlCleanupParser(); 3187 3188 return ((r == 0)?ARCHIVE_OK:ARCHIVE_FATAL); 3189} 3190 3191#elif defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) 3192 3193static int 3194expat_xmlattr_setup(struct archive_read *a, 3195 struct xmlattr_list *list, const XML_Char **atts) 3196{ 3197 struct xmlattr *attr; 3198 char *name, *value; 3199 3200 list->first = NULL; 3201 list->last = &(list->first); 3202 if (atts == NULL) 3203 return (ARCHIVE_OK); 3204 while (atts[0] != NULL && atts[1] != NULL) { 3205 attr = malloc(sizeof*(attr)); 3206 name = strdup(atts[0]); 3207 value = strdup(atts[1]); 3208 if (attr == NULL || name == NULL || value == NULL) { 3209 archive_set_error(&a->archive, ENOMEM, "Out of memory"); 3210 free(attr); 3211 free(name); 3212 free(value); 3213 return (ARCHIVE_FATAL); 3214 } 3215 attr->name = name; 3216 attr->value = value; 3217 attr->next = NULL; 3218 *list->last = attr; 3219 list->last = &(attr->next); 3220 atts += 2; 3221 } 3222 return (ARCHIVE_OK); 3223} 3224 3225static void 3226expat_start_cb(void *userData, const XML_Char *name, const XML_Char **atts) 3227{ 3228 struct expat_userData *ud = (struct expat_userData *)userData; 3229 struct archive_read *a = ud->archive; 3230 struct xmlattr_list list; 3231 int r; 3232 3233 r = expat_xmlattr_setup(a, &list, atts); 3234 if (r == ARCHIVE_OK) 3235 r = xml_start(a, (const char *)name, &list); 3236 xmlattr_cleanup(&list); 3237 ud->state = r; 3238} 3239 3240static void 3241expat_end_cb(void *userData, const XML_Char *name) 3242{ 3243 struct expat_userData *ud = (struct expat_userData *)userData; 3244 3245 xml_end(ud->archive, (const char *)name); 3246} 3247 3248static void 3249expat_data_cb(void *userData, const XML_Char *s, int len) 3250{ 3251 struct expat_userData *ud = (struct expat_userData *)userData; 3252 3253 xml_data(ud->archive, s, len); 3254} 3255 3256static int 3257expat_read_toc(struct archive_read *a) 3258{ 3259 struct xar *xar; 3260 XML_Parser parser; 3261 struct expat_userData ud; 3262 3263 ud.state = ARCHIVE_OK; 3264 ud.archive = a; 3265 3266 xar = (struct xar *)(a->format->data); 3267 3268 /* Initialize XML Parser library. */ 3269 parser = XML_ParserCreate(NULL); 3270 if (parser == NULL) { 3271 archive_set_error(&a->archive, ENOMEM, 3272 "Couldn't allocate memory for xml parser"); 3273 return (ARCHIVE_FATAL); 3274 } 3275 XML_SetUserData(parser, &ud); 3276 XML_SetElementHandler(parser, expat_start_cb, expat_end_cb); 3277 XML_SetCharacterDataHandler(parser, expat_data_cb); 3278 xar->xmlsts = INIT; 3279 3280 while (xar->toc_remaining && ud.state == ARCHIVE_OK) { 3281 enum XML_Status xr; 3282 const void *d; 3283 size_t outbytes; 3284 size_t used; 3285 int r; 3286 3287 d = NULL; 3288 r = rd_contents(a, &d, &outbytes, &used, xar->toc_remaining); 3289 if (r != ARCHIVE_OK) 3290 return (r); 3291 xar->toc_remaining -= used; 3292 xar->offset += used; 3293 xar->toc_total += outbytes; 3294 PRINT_TOC(d, outbytes); 3295 3296 xr = XML_Parse(parser, d, outbytes, xar->toc_remaining == 0); 3297 __archive_read_consume(a, used); 3298 if (xr == XML_STATUS_ERROR) { 3299 XML_ParserFree(parser); 3300 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 3301 "XML Parsing failed"); 3302 return (ARCHIVE_FATAL); 3303 } 3304 } 3305 XML_ParserFree(parser); 3306 return (ud.state); 3307} 3308#endif /* defined(HAVE_BSDXML_H) || defined(HAVE_EXPAT_H) */ 3309 3310#endif /* Support xar format */ 3311