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