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