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