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