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