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