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