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