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