1 /*- 2 * Copyright (c) 2010-2012 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 26 #include "archive_platform.h" 27 __FBSDID("$FreeBSD$"); 28 29 #ifdef HAVE_ERRNO_H 30 #include <errno.h> 31 #endif 32 #ifdef HAVE_LIMITS_H 33 #include <limits.h> 34 #endif 35 #include <stdlib.h> 36 #if HAVE_LIBXML_XMLWRITER_H 37 #include <libxml/xmlwriter.h> 38 #endif 39 #ifdef HAVE_BZLIB_H 40 #include <bzlib.h> 41 #endif 42 #if HAVE_LZMA_H 43 #include <lzma.h> 44 #endif 45 #ifdef HAVE_ZLIB_H 46 #include <zlib.h> 47 #endif 48 49 #include "archive.h" 50 #include "archive_digest_private.h" 51 #include "archive_endian.h" 52 #include "archive_entry.h" 53 #include "archive_entry_locale.h" 54 #include "archive_private.h" 55 #include "archive_rb.h" 56 #include "archive_string.h" 57 #include "archive_write_private.h" 58 59 /* 60 * Differences to xar utility. 61 * - Subdocument is not supported yet. 62 * - ACL is not supported yet. 63 * - When writing an XML element <link type="<file-type>">, <file-type> 64 * which is a file type a symbolic link is referencing is always marked 65 * as "broken". Xar utility uses stat(2) to get the file type, but, in 66 * libarchive format writer, we should not use it; if it is needed, we 67 * should get about it at archive_read_disk.c. 68 * - It is possible to appear both <flags> and <ext2> elements. 69 * Xar utility generates <flags> on BSD platform and <ext2> on Linux 70 * platform. 71 * 72 */ 73 74 #if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\ 75 LIBXML_VERSION >= 20703) ||\ 76 !defined(HAVE_ZLIB_H) || \ 77 !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1) 78 /* 79 * xar needs several external libraries. 80 * o libxml2 81 * o openssl or MD5/SHA1 hash function 82 * o zlib 83 * o bzlib2 (option) 84 * o liblzma (option) 85 */ 86 int 87 archive_write_set_format_xar(struct archive *_a) 88 { 89 struct archive_write *a = (struct archive_write *)_a; 90 91 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 92 "Xar not supported on this platform"); 93 return (ARCHIVE_WARN); 94 } 95 96 #else /* Support xar format */ 97 98 /*#define DEBUG_PRINT_TOC 1 */ 99 100 #define BAD_CAST_CONST (const xmlChar *) 101 102 #define HEADER_MAGIC 0x78617221 103 #define HEADER_SIZE 28 104 #define HEADER_VERSION 1 105 106 enum sumalg { 107 CKSUM_NONE = 0, 108 CKSUM_SHA1 = 1, 109 CKSUM_MD5 = 2 110 }; 111 112 #define MD5_SIZE 16 113 #define SHA1_SIZE 20 114 #define MAX_SUM_SIZE 20 115 #define MD5_NAME "md5" 116 #define SHA1_NAME "sha1" 117 118 enum enctype { 119 NONE, 120 GZIP, 121 BZIP2, 122 LZMA, 123 XZ, 124 }; 125 126 struct chksumwork { 127 enum sumalg alg; 128 #ifdef ARCHIVE_HAS_MD5 129 archive_md5_ctx md5ctx; 130 #endif 131 #ifdef ARCHIVE_HAS_SHA1 132 archive_sha1_ctx sha1ctx; 133 #endif 134 }; 135 136 enum la_zaction { 137 ARCHIVE_Z_FINISH, 138 ARCHIVE_Z_RUN 139 }; 140 141 /* 142 * Universal zstream. 143 */ 144 struct la_zstream { 145 const unsigned char *next_in; 146 size_t avail_in; 147 uint64_t total_in; 148 149 unsigned char *next_out; 150 size_t avail_out; 151 uint64_t total_out; 152 153 int valid; 154 void *real_stream; 155 int (*code) (struct archive *a, 156 struct la_zstream *lastrm, 157 enum la_zaction action); 158 int (*end)(struct archive *a, 159 struct la_zstream *lastrm); 160 }; 161 162 struct chksumval { 163 enum sumalg alg; 164 size_t len; 165 unsigned char val[MAX_SUM_SIZE]; 166 }; 167 168 struct heap_data { 169 int id; 170 struct heap_data *next; 171 uint64_t temp_offset; 172 uint64_t length; /* archived size. */ 173 uint64_t size; /* extracted size. */ 174 enum enctype compression; 175 struct chksumval a_sum; /* archived checksum. */ 176 struct chksumval e_sum; /* extracted checksum. */ 177 }; 178 179 struct file { 180 struct archive_rb_node rbnode; 181 182 int id; 183 struct archive_entry *entry; 184 185 struct archive_rb_tree rbtree; 186 struct file *next; 187 struct file *chnext; 188 struct file *hlnext; 189 /* For hardlinked files. 190 * Use only when archive_entry_nlink() > 1 */ 191 struct file *hardlink_target; 192 struct file *parent; /* parent directory entry */ 193 /* 194 * To manage sub directory files. 195 * We use 'chnext' (a member of struct file) to chain. 196 */ 197 struct { 198 struct file *first; 199 struct file **last; 200 } children; 201 202 /* For making a directory tree. */ 203 struct archive_string parentdir; 204 struct archive_string basename; 205 struct archive_string symlink; 206 207 int ea_idx; 208 struct { 209 struct heap_data *first; 210 struct heap_data **last; 211 } xattr; 212 struct heap_data data; 213 struct archive_string script; 214 215 signed int virtual:1; 216 signed int dir:1; 217 }; 218 219 struct hardlink { 220 struct archive_rb_node rbnode; 221 int nlink; 222 struct { 223 struct file *first; 224 struct file **last; 225 } file_list; 226 }; 227 228 struct xar { 229 int temp_fd; 230 uint64_t temp_offset; 231 232 int file_idx; 233 struct file *root; 234 struct file *cur_dirent; 235 struct archive_string cur_dirstr; 236 struct file *cur_file; 237 uint64_t bytes_remaining; 238 struct archive_string tstr; 239 struct archive_string vstr; 240 241 enum sumalg opt_toc_sumalg; 242 enum sumalg opt_sumalg; 243 enum enctype opt_compression; 244 int opt_compression_level; 245 uint32_t opt_threads; 246 247 struct chksumwork a_sumwrk; /* archived checksum. */ 248 struct chksumwork e_sumwrk; /* extracted checksum. */ 249 struct la_zstream stream; 250 struct archive_string_conv *sconv; 251 /* 252 * Compressed data buffer. 253 */ 254 unsigned char wbuff[1024 * 64]; 255 size_t wbuff_remaining; 256 257 struct heap_data toc; 258 /* 259 * The list of all file entries is used to manage struct file 260 * objects. 261 * We use 'next' (a member of struct file) to chain. 262 */ 263 struct { 264 struct file *first; 265 struct file **last; 266 } file_list; 267 /* 268 * The list of hard-linked file entries. 269 * We use 'hlnext' (a member of struct file) to chain. 270 */ 271 struct archive_rb_tree hardlink_rbtree; 272 }; 273 274 static int xar_options(struct archive_write *, 275 const char *, const char *); 276 static int xar_write_header(struct archive_write *, 277 struct archive_entry *); 278 static ssize_t xar_write_data(struct archive_write *, 279 const void *, size_t); 280 static int xar_finish_entry(struct archive_write *); 281 static int xar_close(struct archive_write *); 282 static int xar_free(struct archive_write *); 283 284 static struct file *file_new(struct archive_write *a, struct archive_entry *); 285 static void file_free(struct file *); 286 static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *, 287 const char *); 288 static int file_add_child_tail(struct file *, struct file *); 289 static struct file *file_find_child(struct file *, const char *); 290 static int file_gen_utility_names(struct archive_write *, 291 struct file *); 292 static int get_path_component(char *, int, const char *); 293 static int file_tree(struct archive_write *, struct file **); 294 static void file_register(struct xar *, struct file *); 295 static void file_init_register(struct xar *); 296 static void file_free_register(struct xar *); 297 static int file_register_hardlink(struct archive_write *, 298 struct file *); 299 static void file_connect_hardlink_files(struct xar *); 300 static void file_init_hardlinks(struct xar *); 301 static void file_free_hardlinks(struct xar *); 302 303 static void checksum_init(struct chksumwork *, enum sumalg); 304 static void checksum_update(struct chksumwork *, const void *, size_t); 305 static void checksum_final(struct chksumwork *, struct chksumval *); 306 static int compression_init_encoder_gzip(struct archive *, 307 struct la_zstream *, int, int); 308 static int compression_code_gzip(struct archive *, 309 struct la_zstream *, enum la_zaction); 310 static int compression_end_gzip(struct archive *, struct la_zstream *); 311 static int compression_init_encoder_bzip2(struct archive *, 312 struct la_zstream *, int); 313 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 314 static int compression_code_bzip2(struct archive *, 315 struct la_zstream *, enum la_zaction); 316 static int compression_end_bzip2(struct archive *, struct la_zstream *); 317 #endif 318 static int compression_init_encoder_lzma(struct archive *, 319 struct la_zstream *, int); 320 static int compression_init_encoder_xz(struct archive *, 321 struct la_zstream *, int, int); 322 #if defined(HAVE_LZMA_H) 323 static int compression_code_lzma(struct archive *, 324 struct la_zstream *, enum la_zaction); 325 static int compression_end_lzma(struct archive *, struct la_zstream *); 326 #endif 327 static int xar_compression_init_encoder(struct archive_write *); 328 static int compression_code(struct archive *, 329 struct la_zstream *, enum la_zaction); 330 static int compression_end(struct archive *, 331 struct la_zstream *); 332 static int save_xattrs(struct archive_write *, struct file *); 333 static int getalgsize(enum sumalg); 334 static const char *getalgname(enum sumalg); 335 336 int 337 archive_write_set_format_xar(struct archive *_a) 338 { 339 struct archive_write *a = (struct archive_write *)_a; 340 struct xar *xar; 341 342 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, 343 ARCHIVE_STATE_NEW, "archive_write_set_format_xar"); 344 345 /* If another format was already registered, unregister it. */ 346 if (a->format_free != NULL) 347 (a->format_free)(a); 348 349 xar = calloc(1, sizeof(*xar)); 350 if (xar == NULL) { 351 archive_set_error(&a->archive, ENOMEM, 352 "Can't allocate xar data"); 353 return (ARCHIVE_FATAL); 354 } 355 xar->temp_fd = -1; 356 file_init_register(xar); 357 file_init_hardlinks(xar); 358 archive_string_init(&(xar->tstr)); 359 archive_string_init(&(xar->vstr)); 360 361 /* 362 * Create the root directory. 363 */ 364 xar->root = file_create_virtual_dir(a, xar, ""); 365 if (xar->root == NULL) { 366 free(xar); 367 archive_set_error(&a->archive, ENOMEM, 368 "Can't allocate xar data"); 369 return (ARCHIVE_FATAL); 370 } 371 xar->root->parent = xar->root; 372 file_register(xar, xar->root); 373 xar->cur_dirent = xar->root; 374 archive_string_init(&(xar->cur_dirstr)); 375 archive_string_ensure(&(xar->cur_dirstr), 1); 376 xar->cur_dirstr.s[0] = 0; 377 378 /* 379 * Initialize option. 380 */ 381 /* Set default checksum type. */ 382 xar->opt_toc_sumalg = CKSUM_SHA1; 383 xar->opt_sumalg = CKSUM_SHA1; 384 /* Set default compression type, level, and number of threads. */ 385 xar->opt_compression = GZIP; 386 xar->opt_compression_level = 6; 387 xar->opt_threads = 1; 388 389 a->format_data = xar; 390 391 a->format_name = "xar"; 392 a->format_options = xar_options; 393 a->format_write_header = xar_write_header; 394 a->format_write_data = xar_write_data; 395 a->format_finish_entry = xar_finish_entry; 396 a->format_close = xar_close; 397 a->format_free = xar_free; 398 a->archive.archive_format = ARCHIVE_FORMAT_XAR; 399 a->archive.archive_format_name = "xar"; 400 401 return (ARCHIVE_OK); 402 } 403 404 static int 405 xar_options(struct archive_write *a, const char *key, const char *value) 406 { 407 struct xar *xar; 408 409 xar = (struct xar *)a->format_data; 410 411 if (strcmp(key, "checksum") == 0) { 412 if (value == NULL) 413 xar->opt_sumalg = CKSUM_NONE; 414 else if (strcmp(value, "none") == 0) 415 xar->opt_sumalg = CKSUM_NONE; 416 else if (strcmp(value, "sha1") == 0) 417 xar->opt_sumalg = CKSUM_SHA1; 418 else if (strcmp(value, "md5") == 0) 419 xar->opt_sumalg = CKSUM_MD5; 420 else { 421 archive_set_error(&(a->archive), 422 ARCHIVE_ERRNO_MISC, 423 "Unknown checksum name: `%s'", 424 value); 425 return (ARCHIVE_FAILED); 426 } 427 return (ARCHIVE_OK); 428 } 429 if (strcmp(key, "compression") == 0) { 430 const char *name = NULL; 431 432 if (value == NULL) 433 xar->opt_compression = NONE; 434 else if (strcmp(value, "none") == 0) 435 xar->opt_compression = NONE; 436 else if (strcmp(value, "gzip") == 0) 437 xar->opt_compression = GZIP; 438 else if (strcmp(value, "bzip2") == 0) 439 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 440 xar->opt_compression = BZIP2; 441 #else 442 name = "bzip2"; 443 #endif 444 else if (strcmp(value, "lzma") == 0) 445 #if HAVE_LZMA_H 446 xar->opt_compression = LZMA; 447 #else 448 name = "lzma"; 449 #endif 450 else if (strcmp(value, "xz") == 0) 451 #if HAVE_LZMA_H 452 xar->opt_compression = XZ; 453 #else 454 name = "xz"; 455 #endif 456 else { 457 archive_set_error(&(a->archive), 458 ARCHIVE_ERRNO_MISC, 459 "Unknown compression name: `%s'", 460 value); 461 return (ARCHIVE_FAILED); 462 } 463 if (name != NULL) { 464 archive_set_error(&(a->archive), 465 ARCHIVE_ERRNO_MISC, 466 "`%s' compression not supported " 467 "on this platform", 468 name); 469 return (ARCHIVE_FAILED); 470 } 471 return (ARCHIVE_OK); 472 } 473 if (strcmp(key, "compression-level") == 0) { 474 if (value == NULL || 475 !(value[0] >= '0' && value[0] <= '9') || 476 value[1] != '\0') { 477 archive_set_error(&(a->archive), 478 ARCHIVE_ERRNO_MISC, 479 "Illegal value `%s'", 480 value); 481 return (ARCHIVE_FAILED); 482 } 483 xar->opt_compression_level = value[0] - '0'; 484 return (ARCHIVE_OK); 485 } 486 if (strcmp(key, "toc-checksum") == 0) { 487 if (value == NULL) 488 xar->opt_toc_sumalg = CKSUM_NONE; 489 else if (strcmp(value, "none") == 0) 490 xar->opt_toc_sumalg = CKSUM_NONE; 491 else if (strcmp(value, "sha1") == 0) 492 xar->opt_toc_sumalg = CKSUM_SHA1; 493 else if (strcmp(value, "md5") == 0) 494 xar->opt_toc_sumalg = CKSUM_MD5; 495 else { 496 archive_set_error(&(a->archive), 497 ARCHIVE_ERRNO_MISC, 498 "Unknown checksum name: `%s'", 499 value); 500 return (ARCHIVE_FAILED); 501 } 502 return (ARCHIVE_OK); 503 } 504 if (strcmp(key, "threads") == 0) { 505 char *endptr; 506 507 if (value == NULL) 508 return (ARCHIVE_FAILED); 509 errno = 0; 510 xar->opt_threads = (int)strtoul(value, &endptr, 10); 511 if (errno != 0 || *endptr != '\0') { 512 xar->opt_threads = 1; 513 archive_set_error(&(a->archive), 514 ARCHIVE_ERRNO_MISC, 515 "Illegal value `%s'", 516 value); 517 return (ARCHIVE_FAILED); 518 } 519 if (xar->opt_threads == 0) { 520 #ifdef HAVE_LZMA_STREAM_ENCODER_MT 521 xar->opt_threads = lzma_cputhreads(); 522 #else 523 xar->opt_threads = 1; 524 #endif 525 } 526 } 527 528 /* Note: The "warn" return is just to inform the options 529 * supervisor that we didn't handle it. It will generate 530 * a suitable error if no one used this option. */ 531 return (ARCHIVE_WARN); 532 } 533 534 static int 535 xar_write_header(struct archive_write *a, struct archive_entry *entry) 536 { 537 struct xar *xar; 538 struct file *file; 539 struct archive_entry *file_entry; 540 int r, r2; 541 542 xar = (struct xar *)a->format_data; 543 xar->cur_file = NULL; 544 xar->bytes_remaining = 0; 545 546 if (xar->sconv == NULL) { 547 xar->sconv = archive_string_conversion_to_charset( 548 &a->archive, "UTF-8", 1); 549 if (xar->sconv == NULL) 550 return (ARCHIVE_FATAL); 551 } 552 553 file = file_new(a, entry); 554 if (file == NULL) { 555 archive_set_error(&a->archive, ENOMEM, 556 "Can't allocate data"); 557 return (ARCHIVE_FATAL); 558 } 559 r2 = file_gen_utility_names(a, file); 560 if (r2 < ARCHIVE_WARN) 561 return (r2); 562 563 /* 564 * Ignore a path which looks like the top of directory name 565 * since we have already made the root directory of an Xar archive. 566 */ 567 if (archive_strlen(&(file->parentdir)) == 0 && 568 archive_strlen(&(file->basename)) == 0) { 569 file_free(file); 570 return (r2); 571 } 572 573 /* Add entry into tree */ 574 file_entry = file->entry; 575 r = file_tree(a, &file); 576 if (r != ARCHIVE_OK) 577 return (r); 578 /* There is the same file in tree and 579 * the current file is older than the file in tree. 580 * So we don't need the current file data anymore. */ 581 if (file->entry != file_entry) 582 return (r2); 583 if (file->id == 0) 584 file_register(xar, file); 585 586 /* A virtual file, which is a directory, does not have 587 * any contents and we won't store it into a archive 588 * file other than its name. */ 589 if (file->virtual) 590 return (r2); 591 592 /* 593 * Prepare to save the contents of the file. 594 */ 595 if (xar->temp_fd == -1) { 596 int algsize; 597 xar->temp_offset = 0; 598 xar->temp_fd = __archive_mktemp(NULL); 599 if (xar->temp_fd < 0) { 600 archive_set_error(&a->archive, errno, 601 "Couldn't create temporary file"); 602 return (ARCHIVE_FATAL); 603 } 604 algsize = getalgsize(xar->opt_toc_sumalg); 605 if (algsize > 0) { 606 if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) { 607 archive_set_error(&(a->archive), errno, 608 "lseek failed"); 609 return (ARCHIVE_FATAL); 610 } 611 xar->temp_offset = algsize; 612 } 613 } 614 615 if (archive_entry_hardlink(file->entry) == NULL) { 616 r = save_xattrs(a, file); 617 if (r != ARCHIVE_OK) 618 return (ARCHIVE_FATAL); 619 } 620 621 /* Non regular files contents are unneeded to be saved to 622 * a temporary file. */ 623 if (archive_entry_filetype(file->entry) != AE_IFREG) 624 return (r2); 625 626 /* 627 * Set the current file to cur_file to read its contents. 628 */ 629 xar->cur_file = file; 630 631 if (archive_entry_nlink(file->entry) > 1) { 632 r = file_register_hardlink(a, file); 633 if (r != ARCHIVE_OK) 634 return (r); 635 if (archive_entry_hardlink(file->entry) != NULL) { 636 archive_entry_unset_size(file->entry); 637 return (r2); 638 } 639 } 640 641 /* Save a offset of current file in temporary file. */ 642 file->data.temp_offset = xar->temp_offset; 643 file->data.size = archive_entry_size(file->entry); 644 file->data.compression = xar->opt_compression; 645 xar->bytes_remaining = archive_entry_size(file->entry); 646 checksum_init(&(xar->a_sumwrk), xar->opt_sumalg); 647 checksum_init(&(xar->e_sumwrk), xar->opt_sumalg); 648 r = xar_compression_init_encoder(a); 649 650 if (r != ARCHIVE_OK) 651 return (r); 652 else 653 return (r2); 654 } 655 656 static int 657 write_to_temp(struct archive_write *a, const void *buff, size_t s) 658 { 659 struct xar *xar; 660 const unsigned char *p; 661 ssize_t ws; 662 663 xar = (struct xar *)a->format_data; 664 p = (const unsigned char *)buff; 665 while (s) { 666 ws = write(xar->temp_fd, p, s); 667 if (ws < 0) { 668 archive_set_error(&(a->archive), errno, 669 "fwrite function failed"); 670 return (ARCHIVE_FATAL); 671 } 672 s -= ws; 673 p += ws; 674 xar->temp_offset += ws; 675 } 676 return (ARCHIVE_OK); 677 } 678 679 static ssize_t 680 xar_write_data(struct archive_write *a, const void *buff, size_t s) 681 { 682 struct xar *xar; 683 enum la_zaction run; 684 size_t size = 0; 685 size_t rsize; 686 int r; 687 688 xar = (struct xar *)a->format_data; 689 690 if (s > xar->bytes_remaining) 691 s = (size_t)xar->bytes_remaining; 692 if (s == 0 || xar->cur_file == NULL) 693 return (0); 694 if (xar->cur_file->data.compression == NONE) { 695 checksum_update(&(xar->e_sumwrk), buff, s); 696 checksum_update(&(xar->a_sumwrk), buff, s); 697 size = rsize = s; 698 } else { 699 xar->stream.next_in = (const unsigned char *)buff; 700 xar->stream.avail_in = s; 701 if (xar->bytes_remaining > s) 702 run = ARCHIVE_Z_RUN; 703 else 704 run = ARCHIVE_Z_FINISH; 705 /* Compress file data. */ 706 for (;;) { 707 r = compression_code(&(a->archive), &(xar->stream), 708 run); 709 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) 710 return (ARCHIVE_FATAL); 711 if (xar->stream.avail_out == 0 || 712 run == ARCHIVE_Z_FINISH) { 713 size = sizeof(xar->wbuff) - 714 xar->stream.avail_out; 715 checksum_update(&(xar->a_sumwrk), xar->wbuff, 716 size); 717 xar->cur_file->data.length += size; 718 if (write_to_temp(a, xar->wbuff, 719 size) != ARCHIVE_OK) 720 return (ARCHIVE_FATAL); 721 if (r == ARCHIVE_OK) { 722 /* Output buffer was full */ 723 xar->stream.next_out = xar->wbuff; 724 xar->stream.avail_out = 725 sizeof(xar->wbuff); 726 } else { 727 /* ARCHIVE_EOF - We are done */ 728 break; 729 } 730 } else { 731 /* Compressor wants more input */ 732 break; 733 } 734 } 735 rsize = s - xar->stream.avail_in; 736 checksum_update(&(xar->e_sumwrk), buff, rsize); 737 } 738 #if !defined(_WIN32) || defined(__CYGWIN__) 739 if (xar->bytes_remaining == 740 (uint64_t)archive_entry_size(xar->cur_file->entry)) { 741 /* 742 * Get the path of a shell script if so. 743 */ 744 const unsigned char *b = (const unsigned char *)buff; 745 746 archive_string_empty(&(xar->cur_file->script)); 747 if (rsize > 2 && b[0] == '#' && b[1] == '!') { 748 size_t i, end, off; 749 750 off = 2; 751 if (b[off] == ' ') 752 off++; 753 #ifdef PATH_MAX 754 if ((rsize - off) > PATH_MAX) 755 end = off + PATH_MAX; 756 else 757 #endif 758 end = rsize; 759 /* Find the end of a script path. */ 760 for (i = off; i < end && b[i] != '\0' && 761 b[i] != '\n' && b[i] != '\r' && 762 b[i] != ' ' && b[i] != '\t'; i++) 763 ; 764 archive_strncpy(&(xar->cur_file->script), b + off, 765 i - off); 766 } 767 } 768 #endif 769 770 if (xar->cur_file->data.compression == NONE) { 771 if (write_to_temp(a, buff, size) != ARCHIVE_OK) 772 return (ARCHIVE_FATAL); 773 xar->cur_file->data.length += size; 774 } 775 xar->bytes_remaining -= rsize; 776 777 return (rsize); 778 } 779 780 static int 781 xar_finish_entry(struct archive_write *a) 782 { 783 struct xar *xar; 784 struct file *file; 785 size_t s; 786 ssize_t w; 787 788 xar = (struct xar *)a->format_data; 789 if (xar->cur_file == NULL) 790 return (ARCHIVE_OK); 791 792 while (xar->bytes_remaining > 0) { 793 s = (size_t)xar->bytes_remaining; 794 if (s > a->null_length) 795 s = a->null_length; 796 w = xar_write_data(a, a->nulls, s); 797 if (w > 0) 798 xar->bytes_remaining -= w; 799 else 800 return (w); 801 } 802 file = xar->cur_file; 803 checksum_final(&(xar->e_sumwrk), &(file->data.e_sum)); 804 checksum_final(&(xar->a_sumwrk), &(file->data.a_sum)); 805 xar->cur_file = NULL; 806 807 return (ARCHIVE_OK); 808 } 809 810 static int 811 xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer, 812 const char *key, const char *value, 813 const char *attrkey, const char *attrvalue) 814 { 815 int r; 816 817 r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key)); 818 if (r < 0) { 819 archive_set_error(&a->archive, 820 ARCHIVE_ERRNO_MISC, 821 "xmlTextWriterStartElement() failed: %d", r); 822 return (ARCHIVE_FATAL); 823 } 824 if (attrkey != NULL && attrvalue != NULL) { 825 r = xmlTextWriterWriteAttribute(writer, 826 BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue)); 827 if (r < 0) { 828 archive_set_error(&a->archive, 829 ARCHIVE_ERRNO_MISC, 830 "xmlTextWriterWriteAttribute() failed: %d", r); 831 return (ARCHIVE_FATAL); 832 } 833 } 834 if (value != NULL) { 835 r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value)); 836 if (r < 0) { 837 archive_set_error(&a->archive, 838 ARCHIVE_ERRNO_MISC, 839 "xmlTextWriterWriteString() failed: %d", r); 840 return (ARCHIVE_FATAL); 841 } 842 } 843 r = xmlTextWriterEndElement(writer); 844 if (r < 0) { 845 archive_set_error(&a->archive, 846 ARCHIVE_ERRNO_MISC, 847 "xmlTextWriterEndElement() failed: %d", r); 848 return (ARCHIVE_FATAL); 849 } 850 return (ARCHIVE_OK); 851 } 852 853 static int 854 xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer, 855 const char *key, const char *value) 856 { 857 int r; 858 859 if (value == NULL) 860 return (ARCHIVE_OK); 861 862 r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key)); 863 if (r < 0) { 864 archive_set_error(&a->archive, 865 ARCHIVE_ERRNO_MISC, 866 "xmlTextWriterStartElement() failed: %d", r); 867 return (ARCHIVE_FATAL); 868 } 869 if (value != NULL) { 870 r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value)); 871 if (r < 0) { 872 archive_set_error(&a->archive, 873 ARCHIVE_ERRNO_MISC, 874 "xmlTextWriterWriteString() failed: %d", r); 875 return (ARCHIVE_FATAL); 876 } 877 } 878 r = xmlTextWriterEndElement(writer); 879 if (r < 0) { 880 archive_set_error(&a->archive, 881 ARCHIVE_ERRNO_MISC, 882 "xmlTextWriterEndElement() failed: %d", r); 883 return (ARCHIVE_FATAL); 884 } 885 return (ARCHIVE_OK); 886 } 887 888 static int 889 xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer, 890 const char *key, const char *fmt, ...) 891 { 892 struct xar *xar; 893 va_list ap; 894 895 xar = (struct xar *)a->format_data; 896 va_start(ap, fmt); 897 archive_string_empty(&xar->vstr); 898 archive_string_vsprintf(&xar->vstr, fmt, ap); 899 va_end(ap); 900 return (xmlwrite_string(a, writer, key, xar->vstr.s)); 901 } 902 903 static int 904 xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer, 905 const char *key, time_t t, int z) 906 { 907 char timestr[100]; 908 struct tm tm; 909 #if defined(HAVE__GMTIME64_S) 910 __time64_t tmptime; 911 #endif 912 913 #if defined(HAVE_GMTIME_R) 914 gmtime_r(&t, &tm); 915 #elif defined(HAVE__GMTIME64_S) 916 tmptime = t; 917 _gmtime64_s(&tm, &tmptime); 918 #else 919 memcpy(&tm, gmtime(&t), sizeof(tm)); 920 #endif 921 memset(×tr, 0, sizeof(timestr)); 922 /* Do not use %F and %T for portability. */ 923 strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm); 924 if (z) 925 strcat(timestr, "Z"); 926 return (xmlwrite_string(a, writer, key, timestr)); 927 } 928 929 static int 930 xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer, 931 const char *key, mode_t mode) 932 { 933 char ms[5]; 934 935 ms[0] = '0'; 936 ms[1] = '0' + ((mode >> 6) & 07); 937 ms[2] = '0' + ((mode >> 3) & 07); 938 ms[3] = '0' + (mode & 07); 939 ms[4] = '\0'; 940 941 return (xmlwrite_string(a, writer, key, ms)); 942 } 943 944 static int 945 xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer, 946 const char *key, struct chksumval *sum) 947 { 948 const char *algname; 949 int algsize; 950 char buff[MAX_SUM_SIZE*2 + 1]; 951 char *p; 952 unsigned char *s; 953 int i, r; 954 955 if (sum->len > 0) { 956 algname = getalgname(sum->alg); 957 algsize = getalgsize(sum->alg); 958 if (algname != NULL) { 959 const char *hex = "0123456789abcdef"; 960 p = buff; 961 s = sum->val; 962 for (i = 0; i < algsize; i++) { 963 *p++ = hex[(*s >> 4)]; 964 *p++ = hex[(*s & 0x0f)]; 965 s++; 966 } 967 *p = '\0'; 968 r = xmlwrite_string_attr(a, writer, 969 key, buff, 970 "style", algname); 971 if (r < 0) 972 return (ARCHIVE_FATAL); 973 } 974 } 975 return (ARCHIVE_OK); 976 } 977 978 static int 979 xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer, 980 struct heap_data *heap) 981 { 982 const char *encname; 983 int r; 984 985 r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length); 986 if (r < 0) 987 return (ARCHIVE_FATAL); 988 r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset); 989 if (r < 0) 990 return (ARCHIVE_FATAL); 991 r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size); 992 if (r < 0) 993 return (ARCHIVE_FATAL); 994 switch (heap->compression) { 995 case GZIP: 996 encname = "application/x-gzip"; break; 997 case BZIP2: 998 encname = "application/x-bzip2"; break; 999 case LZMA: 1000 encname = "application/x-lzma"; break; 1001 case XZ: 1002 encname = "application/x-xz"; break; 1003 default: 1004 encname = "application/octet-stream"; break; 1005 } 1006 r = xmlwrite_string_attr(a, writer, "encoding", NULL, 1007 "style", encname); 1008 if (r < 0) 1009 return (ARCHIVE_FATAL); 1010 r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum)); 1011 if (r < 0) 1012 return (ARCHIVE_FATAL); 1013 r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum)); 1014 if (r < 0) 1015 return (ARCHIVE_FATAL); 1016 return (ARCHIVE_OK); 1017 } 1018 1019 /* 1020 * xar utility records fflags as following xml elements: 1021 * <flags> 1022 * <UserNoDump/> 1023 * ..... 1024 * </flags> 1025 * or 1026 * <ext2> 1027 * <NoDump/> 1028 * ..... 1029 * </ext2> 1030 * If xar is running on BSD platform, records <flags>..</flags>; 1031 * if xar is running on linux platform, records <ext2>..</ext2>; 1032 * otherwise does not record. 1033 * 1034 * Our implements records both <flags> and <ext2> if it's necessary. 1035 */ 1036 static int 1037 make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer, 1038 const char *element, const char *fflags_text) 1039 { 1040 static const struct flagentry { 1041 const char *name; 1042 const char *xarname; 1043 } 1044 flagbsd[] = { 1045 { "sappnd", "SystemAppend"}, 1046 { "sappend", "SystemAppend"}, 1047 { "arch", "SystemArchived"}, 1048 { "archived", "SystemArchived"}, 1049 { "schg", "SystemImmutable"}, 1050 { "schange", "SystemImmutable"}, 1051 { "simmutable", "SystemImmutable"}, 1052 { "nosunlnk", "SystemNoUnlink"}, 1053 { "nosunlink", "SystemNoUnlink"}, 1054 { "snapshot", "SystemSnapshot"}, 1055 { "uappnd", "UserAppend"}, 1056 { "uappend", "UserAppend"}, 1057 { "uchg", "UserImmutable"}, 1058 { "uchange", "UserImmutable"}, 1059 { "uimmutable", "UserImmutable"}, 1060 { "nodump", "UserNoDump"}, 1061 { "noopaque", "UserOpaque"}, 1062 { "nouunlnk", "UserNoUnlink"}, 1063 { "nouunlink", "UserNoUnlink"}, 1064 { NULL, NULL} 1065 }, 1066 flagext2[] = { 1067 { "sappnd", "AppendOnly"}, 1068 { "sappend", "AppendOnly"}, 1069 { "schg", "Immutable"}, 1070 { "schange", "Immutable"}, 1071 { "simmutable", "Immutable"}, 1072 { "nodump", "NoDump"}, 1073 { "nouunlnk", "Undelete"}, 1074 { "nouunlink", "Undelete"}, 1075 { "btree", "BTree"}, 1076 { "comperr", "CompError"}, 1077 { "compress", "Compress"}, 1078 { "noatime", "NoAtime"}, 1079 { "compdirty", "CompDirty"}, 1080 { "comprblk", "CompBlock"}, 1081 { "dirsync", "DirSync"}, 1082 { "hashidx", "HashIndexed"}, 1083 { "imagic", "iMagic"}, 1084 { "journal", "Journaled"}, 1085 { "securedeletion", "SecureDeletion"}, 1086 { "sync", "Synchronous"}, 1087 { "notail", "NoTail"}, 1088 { "topdir", "TopDir"}, 1089 { "reserved", "Reserved"}, 1090 { NULL, NULL} 1091 }; 1092 const struct flagentry *fe, *flagentry; 1093 #define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd)) 1094 const struct flagentry *avail[FLAGENTRY_MAXSIZE]; 1095 const char *p; 1096 int i, n, r; 1097 1098 if (strcmp(element, "ext2") == 0) 1099 flagentry = flagext2; 1100 else 1101 flagentry = flagbsd; 1102 n = 0; 1103 p = fflags_text; 1104 do { 1105 const char *cp; 1106 1107 cp = strchr(p, ','); 1108 if (cp == NULL) 1109 cp = p + strlen(p); 1110 1111 for (fe = flagentry; fe->name != NULL; fe++) { 1112 if (fe->name[cp - p] != '\0' 1113 || p[0] != fe->name[0]) 1114 continue; 1115 if (strncmp(p, fe->name, cp - p) == 0) { 1116 avail[n++] = fe; 1117 break; 1118 } 1119 } 1120 if (*cp == ',') 1121 p = cp + 1; 1122 else 1123 p = NULL; 1124 } while (p != NULL); 1125 1126 if (n > 0) { 1127 r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element)); 1128 if (r < 0) { 1129 archive_set_error(&a->archive, 1130 ARCHIVE_ERRNO_MISC, 1131 "xmlTextWriterStartElement() failed: %d", r); 1132 return (ARCHIVE_FATAL); 1133 } 1134 for (i = 0; i < n; i++) { 1135 r = xmlwrite_string(a, writer, 1136 avail[i]->xarname, NULL); 1137 if (r != ARCHIVE_OK) 1138 return (r); 1139 } 1140 1141 r = xmlTextWriterEndElement(writer); 1142 if (r < 0) { 1143 archive_set_error(&a->archive, 1144 ARCHIVE_ERRNO_MISC, 1145 "xmlTextWriterEndElement() failed: %d", r); 1146 return (ARCHIVE_FATAL); 1147 } 1148 } 1149 return (ARCHIVE_OK); 1150 } 1151 1152 static int 1153 make_file_entry(struct archive_write *a, xmlTextWriterPtr writer, 1154 struct file *file) 1155 { 1156 struct xar *xar; 1157 const char *filetype, *filelink, *fflags; 1158 struct archive_string linkto; 1159 struct heap_data *heap; 1160 unsigned char *tmp; 1161 const char *p; 1162 size_t len; 1163 int r, r2, l, ll; 1164 1165 xar = (struct xar *)a->format_data; 1166 r2 = ARCHIVE_OK; 1167 1168 /* 1169 * Make a file name entry, "<name>". 1170 */ 1171 l = ll = archive_strlen(&(file->basename)); 1172 tmp = malloc(l); 1173 if (tmp == NULL) { 1174 archive_set_error(&a->archive, ENOMEM, 1175 "Can't allocate memory"); 1176 return (ARCHIVE_FATAL); 1177 } 1178 r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll); 1179 free(tmp); 1180 if (r < 0) { 1181 r = xmlTextWriterStartElement(writer, BAD_CAST("name")); 1182 if (r < 0) { 1183 archive_set_error(&a->archive, 1184 ARCHIVE_ERRNO_MISC, 1185 "xmlTextWriterStartElement() failed: %d", r); 1186 return (ARCHIVE_FATAL); 1187 } 1188 r = xmlTextWriterWriteAttribute(writer, 1189 BAD_CAST("enctype"), BAD_CAST("base64")); 1190 if (r < 0) { 1191 archive_set_error(&a->archive, 1192 ARCHIVE_ERRNO_MISC, 1193 "xmlTextWriterWriteAttribute() failed: %d", r); 1194 return (ARCHIVE_FATAL); 1195 } 1196 r = xmlTextWriterWriteBase64(writer, file->basename.s, 1197 0, archive_strlen(&(file->basename))); 1198 if (r < 0) { 1199 archive_set_error(&a->archive, 1200 ARCHIVE_ERRNO_MISC, 1201 "xmlTextWriterWriteBase64() failed: %d", r); 1202 return (ARCHIVE_FATAL); 1203 } 1204 r = xmlTextWriterEndElement(writer); 1205 if (r < 0) { 1206 archive_set_error(&a->archive, 1207 ARCHIVE_ERRNO_MISC, 1208 "xmlTextWriterEndElement() failed: %d", r); 1209 return (ARCHIVE_FATAL); 1210 } 1211 } else { 1212 r = xmlwrite_string(a, writer, "name", file->basename.s); 1213 if (r < 0) 1214 return (ARCHIVE_FATAL); 1215 } 1216 1217 /* 1218 * Make a file type entry, "<type>". 1219 */ 1220 filelink = NULL; 1221 archive_string_init(&linkto); 1222 switch (archive_entry_filetype(file->entry)) { 1223 case AE_IFDIR: 1224 filetype = "directory"; break; 1225 case AE_IFLNK: 1226 filetype = "symlink"; break; 1227 case AE_IFCHR: 1228 filetype = "character special"; break; 1229 case AE_IFBLK: 1230 filetype = "block special"; break; 1231 case AE_IFSOCK: 1232 filetype = "socket"; break; 1233 case AE_IFIFO: 1234 filetype = "fifo"; break; 1235 case AE_IFREG: 1236 default: 1237 if (file->hardlink_target != NULL) { 1238 filetype = "hardlink"; 1239 filelink = "link"; 1240 if (file->hardlink_target == file) 1241 archive_strcpy(&linkto, "original"); 1242 else 1243 archive_string_sprintf(&linkto, "%d", 1244 file->hardlink_target->id); 1245 } else 1246 filetype = "file"; 1247 break; 1248 } 1249 r = xmlwrite_string_attr(a, writer, "type", filetype, 1250 filelink, linkto.s); 1251 archive_string_free(&linkto); 1252 if (r < 0) 1253 return (ARCHIVE_FATAL); 1254 1255 /* 1256 * On a virtual directory, we record "name" and "type" only. 1257 */ 1258 if (file->virtual) 1259 return (ARCHIVE_OK); 1260 1261 switch (archive_entry_filetype(file->entry)) { 1262 case AE_IFLNK: 1263 /* 1264 * xar utility has checked a file type, which 1265 * a symbolic-link file has referenced. 1266 * For example: 1267 * <link type="directory">../ref/</link> 1268 * The symlink target file is "../ref/" and its 1269 * file type is a directory. 1270 * 1271 * <link type="file">../f</link> 1272 * The symlink target file is "../f" and its 1273 * file type is a regular file. 1274 * 1275 * But our implementation cannot do it, and then we 1276 * always record that a attribute "type" is "broken", 1277 * for example: 1278 * <link type="broken">foo/bar</link> 1279 * It means "foo/bar" is not reachable. 1280 */ 1281 r = xmlwrite_string_attr(a, writer, "link", 1282 file->symlink.s, 1283 "type", "broken"); 1284 if (r < 0) 1285 return (ARCHIVE_FATAL); 1286 break; 1287 case AE_IFCHR: 1288 case AE_IFBLK: 1289 r = xmlTextWriterStartElement(writer, BAD_CAST("device")); 1290 if (r < 0) { 1291 archive_set_error(&a->archive, 1292 ARCHIVE_ERRNO_MISC, 1293 "xmlTextWriterStartElement() failed: %d", r); 1294 return (ARCHIVE_FATAL); 1295 } 1296 r = xmlwrite_fstring(a, writer, "major", 1297 "%d", archive_entry_rdevmajor(file->entry)); 1298 if (r < 0) 1299 return (ARCHIVE_FATAL); 1300 r = xmlwrite_fstring(a, writer, "minor", 1301 "%d", archive_entry_rdevminor(file->entry)); 1302 if (r < 0) 1303 return (ARCHIVE_FATAL); 1304 r = xmlTextWriterEndElement(writer); 1305 if (r < 0) { 1306 archive_set_error(&a->archive, 1307 ARCHIVE_ERRNO_MISC, 1308 "xmlTextWriterEndElement() failed: %d", r); 1309 return (ARCHIVE_FATAL); 1310 } 1311 break; 1312 default: 1313 break; 1314 } 1315 1316 /* 1317 * Make a inode entry, "<inode>". 1318 */ 1319 r = xmlwrite_fstring(a, writer, "inode", 1320 "%jd", archive_entry_ino64(file->entry)); 1321 if (r < 0) 1322 return (ARCHIVE_FATAL); 1323 if (archive_entry_dev(file->entry) != 0) { 1324 r = xmlwrite_fstring(a, writer, "deviceno", 1325 "%d", archive_entry_dev(file->entry)); 1326 if (r < 0) 1327 return (ARCHIVE_FATAL); 1328 } 1329 1330 /* 1331 * Make a file mode entry, "<mode>". 1332 */ 1333 r = xmlwrite_mode(a, writer, "mode", 1334 archive_entry_mode(file->entry)); 1335 if (r < 0) 1336 return (ARCHIVE_FATAL); 1337 1338 /* 1339 * Make a user entry, "<uid>" and "<user>. 1340 */ 1341 r = xmlwrite_fstring(a, writer, "uid", 1342 "%d", archive_entry_uid(file->entry)); 1343 if (r < 0) 1344 return (ARCHIVE_FATAL); 1345 r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv); 1346 if (r != 0) { 1347 if (errno == ENOMEM) { 1348 archive_set_error(&a->archive, ENOMEM, 1349 "Can't allocate memory for Uname"); 1350 return (ARCHIVE_FATAL); 1351 } 1352 archive_set_error(&a->archive, 1353 ARCHIVE_ERRNO_FILE_FORMAT, 1354 "Can't translate uname '%s' to UTF-8", 1355 archive_entry_uname(file->entry)); 1356 r2 = ARCHIVE_WARN; 1357 } 1358 if (len > 0) { 1359 r = xmlwrite_string(a, writer, "user", p); 1360 if (r < 0) 1361 return (ARCHIVE_FATAL); 1362 } 1363 1364 /* 1365 * Make a group entry, "<gid>" and "<group>. 1366 */ 1367 r = xmlwrite_fstring(a, writer, "gid", 1368 "%d", archive_entry_gid(file->entry)); 1369 if (r < 0) 1370 return (ARCHIVE_FATAL); 1371 r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv); 1372 if (r != 0) { 1373 if (errno == ENOMEM) { 1374 archive_set_error(&a->archive, ENOMEM, 1375 "Can't allocate memory for Gname"); 1376 return (ARCHIVE_FATAL); 1377 } 1378 archive_set_error(&a->archive, 1379 ARCHIVE_ERRNO_FILE_FORMAT, 1380 "Can't translate gname '%s' to UTF-8", 1381 archive_entry_gname(file->entry)); 1382 r2 = ARCHIVE_WARN; 1383 } 1384 if (len > 0) { 1385 r = xmlwrite_string(a, writer, "group", p); 1386 if (r < 0) 1387 return (ARCHIVE_FATAL); 1388 } 1389 1390 /* 1391 * Make a ctime entry, "<ctime>". 1392 */ 1393 if (archive_entry_ctime_is_set(file->entry)) { 1394 r = xmlwrite_time(a, writer, "ctime", 1395 archive_entry_ctime(file->entry), 1); 1396 if (r < 0) 1397 return (ARCHIVE_FATAL); 1398 } 1399 1400 /* 1401 * Make a mtime entry, "<mtime>". 1402 */ 1403 if (archive_entry_mtime_is_set(file->entry)) { 1404 r = xmlwrite_time(a, writer, "mtime", 1405 archive_entry_mtime(file->entry), 1); 1406 if (r < 0) 1407 return (ARCHIVE_FATAL); 1408 } 1409 1410 /* 1411 * Make a atime entry, "<atime>". 1412 */ 1413 if (archive_entry_atime_is_set(file->entry)) { 1414 r = xmlwrite_time(a, writer, "atime", 1415 archive_entry_atime(file->entry), 1); 1416 if (r < 0) 1417 return (ARCHIVE_FATAL); 1418 } 1419 1420 /* 1421 * Make fflags entries, "<flags>" and "<ext2>". 1422 */ 1423 fflags = archive_entry_fflags_text(file->entry); 1424 if (fflags != NULL) { 1425 r = make_fflags_entry(a, writer, "flags", fflags); 1426 if (r < 0) 1427 return (r); 1428 r = make_fflags_entry(a, writer, "ext2", fflags); 1429 if (r < 0) 1430 return (r); 1431 } 1432 1433 /* 1434 * Make extended attribute entries, "<ea>". 1435 */ 1436 archive_entry_xattr_reset(file->entry); 1437 for (heap = file->xattr.first; heap != NULL; heap = heap->next) { 1438 const char *name; 1439 const void *value; 1440 size_t size; 1441 1442 archive_entry_xattr_next(file->entry, 1443 &name, &value, &size); 1444 r = xmlTextWriterStartElement(writer, BAD_CAST("ea")); 1445 if (r < 0) { 1446 archive_set_error(&a->archive, 1447 ARCHIVE_ERRNO_MISC, 1448 "xmlTextWriterStartElement() failed: %d", r); 1449 return (ARCHIVE_FATAL); 1450 } 1451 r = xmlTextWriterWriteFormatAttribute(writer, 1452 BAD_CAST("id"), "%d", heap->id); 1453 if (r < 0) { 1454 archive_set_error(&a->archive, 1455 ARCHIVE_ERRNO_MISC, 1456 "xmlTextWriterWriteAttribute() failed: %d", r); 1457 return (ARCHIVE_FATAL); 1458 } 1459 r = xmlwrite_heap(a, writer, heap); 1460 if (r < 0) 1461 return (ARCHIVE_FATAL); 1462 r = xmlwrite_string(a, writer, "name", name); 1463 if (r < 0) 1464 return (ARCHIVE_FATAL); 1465 1466 r = xmlTextWriterEndElement(writer); 1467 if (r < 0) { 1468 archive_set_error(&a->archive, 1469 ARCHIVE_ERRNO_MISC, 1470 "xmlTextWriterEndElement() failed: %d", r); 1471 return (ARCHIVE_FATAL); 1472 } 1473 } 1474 1475 /* 1476 * Make a file data entry, "<data>". 1477 */ 1478 if (file->data.length > 0) { 1479 r = xmlTextWriterStartElement(writer, BAD_CAST("data")); 1480 if (r < 0) { 1481 archive_set_error(&a->archive, 1482 ARCHIVE_ERRNO_MISC, 1483 "xmlTextWriterStartElement() failed: %d", r); 1484 return (ARCHIVE_FATAL); 1485 } 1486 1487 r = xmlwrite_heap(a, writer, &(file->data)); 1488 if (r < 0) 1489 return (ARCHIVE_FATAL); 1490 1491 r = xmlTextWriterEndElement(writer); 1492 if (r < 0) { 1493 archive_set_error(&a->archive, 1494 ARCHIVE_ERRNO_MISC, 1495 "xmlTextWriterEndElement() failed: %d", r); 1496 return (ARCHIVE_FATAL); 1497 } 1498 } 1499 1500 if (archive_strlen(&file->script) > 0) { 1501 r = xmlTextWriterStartElement(writer, BAD_CAST("content")); 1502 if (r < 0) { 1503 archive_set_error(&a->archive, 1504 ARCHIVE_ERRNO_MISC, 1505 "xmlTextWriterStartElement() failed: %d", r); 1506 return (ARCHIVE_FATAL); 1507 } 1508 1509 r = xmlwrite_string(a, writer, 1510 "interpreter", file->script.s); 1511 if (r < 0) 1512 return (ARCHIVE_FATAL); 1513 1514 r = xmlwrite_string(a, writer, "type", "script"); 1515 if (r < 0) 1516 return (ARCHIVE_FATAL); 1517 1518 r = xmlTextWriterEndElement(writer); 1519 if (r < 0) { 1520 archive_set_error(&a->archive, 1521 ARCHIVE_ERRNO_MISC, 1522 "xmlTextWriterEndElement() failed: %d", r); 1523 return (ARCHIVE_FATAL); 1524 } 1525 } 1526 1527 return (r2); 1528 } 1529 1530 /* 1531 * Make the TOC 1532 */ 1533 static int 1534 make_toc(struct archive_write *a) 1535 { 1536 struct xar *xar; 1537 struct file *np; 1538 xmlBufferPtr bp; 1539 xmlTextWriterPtr writer; 1540 int algsize; 1541 int r, ret; 1542 1543 xar = (struct xar *)a->format_data; 1544 1545 ret = ARCHIVE_FATAL; 1546 1547 /* 1548 * Initialize xml writer. 1549 */ 1550 writer = NULL; 1551 bp = xmlBufferCreate(); 1552 if (bp == NULL) { 1553 archive_set_error(&a->archive, ENOMEM, 1554 "xmlBufferCreate() " 1555 "couldn't create xml buffer"); 1556 goto exit_toc; 1557 } 1558 writer = xmlNewTextWriterMemory(bp, 0); 1559 if (writer == NULL) { 1560 archive_set_error(&a->archive, 1561 ARCHIVE_ERRNO_MISC, 1562 "xmlNewTextWriterMemory() " 1563 "couldn't create xml writer"); 1564 goto exit_toc; 1565 } 1566 r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); 1567 if (r < 0) { 1568 archive_set_error(&a->archive, 1569 ARCHIVE_ERRNO_MISC, 1570 "xmlTextWriterStartDocument() failed: %d", r); 1571 goto exit_toc; 1572 } 1573 r = xmlTextWriterSetIndent(writer, 4); 1574 if (r < 0) { 1575 archive_set_error(&a->archive, 1576 ARCHIVE_ERRNO_MISC, 1577 "xmlTextWriterSetIndent() failed: %d", r); 1578 goto exit_toc; 1579 } 1580 1581 /* 1582 * Start recording TOC 1583 */ 1584 r = xmlTextWriterStartElement(writer, BAD_CAST("xar")); 1585 if (r < 0) { 1586 archive_set_error(&a->archive, 1587 ARCHIVE_ERRNO_MISC, 1588 "xmlTextWriterStartElement() failed: %d", r); 1589 goto exit_toc; 1590 } 1591 r = xmlTextWriterStartElement(writer, BAD_CAST("toc")); 1592 if (r < 0) { 1593 archive_set_error(&a->archive, 1594 ARCHIVE_ERRNO_MISC, 1595 "xmlTextWriterStartDocument() failed: %d", r); 1596 goto exit_toc; 1597 } 1598 1599 /* 1600 * Record the creation time of the archive file. 1601 */ 1602 r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0); 1603 if (r < 0) 1604 goto exit_toc; 1605 1606 /* 1607 * Record the checksum value of TOC 1608 */ 1609 algsize = getalgsize(xar->opt_toc_sumalg); 1610 if (algsize) { 1611 /* 1612 * Record TOC checksum 1613 */ 1614 r = xmlTextWriterStartElement(writer, BAD_CAST("checksum")); 1615 if (r < 0) { 1616 archive_set_error(&a->archive, 1617 ARCHIVE_ERRNO_MISC, 1618 "xmlTextWriterStartElement() failed: %d", r); 1619 goto exit_toc; 1620 } 1621 r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"), 1622 BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg))); 1623 if (r < 0) { 1624 archive_set_error(&a->archive, 1625 ARCHIVE_ERRNO_MISC, 1626 "xmlTextWriterWriteAttribute() failed: %d", r); 1627 goto exit_toc; 1628 } 1629 1630 /* 1631 * Record the offset of the value of checksum of TOC 1632 */ 1633 r = xmlwrite_string(a, writer, "offset", "0"); 1634 if (r < 0) 1635 goto exit_toc; 1636 1637 /* 1638 * Record the size of the value of checksum of TOC 1639 */ 1640 r = xmlwrite_fstring(a, writer, "size", "%d", algsize); 1641 if (r < 0) 1642 goto exit_toc; 1643 1644 r = xmlTextWriterEndElement(writer); 1645 if (r < 0) { 1646 archive_set_error(&a->archive, 1647 ARCHIVE_ERRNO_MISC, 1648 "xmlTextWriterEndElement() failed: %d", r); 1649 goto exit_toc; 1650 } 1651 } 1652 1653 np = xar->root; 1654 do { 1655 if (np != np->parent) { 1656 r = make_file_entry(a, writer, np); 1657 if (r != ARCHIVE_OK) 1658 goto exit_toc; 1659 } 1660 1661 if (np->dir && np->children.first != NULL) { 1662 /* Enter to sub directories. */ 1663 np = np->children.first; 1664 r = xmlTextWriterStartElement(writer, 1665 BAD_CAST("file")); 1666 if (r < 0) { 1667 archive_set_error(&a->archive, 1668 ARCHIVE_ERRNO_MISC, 1669 "xmlTextWriterStartElement() " 1670 "failed: %d", r); 1671 goto exit_toc; 1672 } 1673 r = xmlTextWriterWriteFormatAttribute( 1674 writer, BAD_CAST("id"), "%d", np->id); 1675 if (r < 0) { 1676 archive_set_error(&a->archive, 1677 ARCHIVE_ERRNO_MISC, 1678 "xmlTextWriterWriteAttribute() " 1679 "failed: %d", r); 1680 goto exit_toc; 1681 } 1682 continue; 1683 } 1684 while (np != np->parent) { 1685 r = xmlTextWriterEndElement(writer); 1686 if (r < 0) { 1687 archive_set_error(&a->archive, 1688 ARCHIVE_ERRNO_MISC, 1689 "xmlTextWriterEndElement() " 1690 "failed: %d", r); 1691 goto exit_toc; 1692 } 1693 if (np->chnext == NULL) { 1694 /* Return to the parent directory. */ 1695 np = np->parent; 1696 } else { 1697 np = np->chnext; 1698 r = xmlTextWriterStartElement(writer, 1699 BAD_CAST("file")); 1700 if (r < 0) { 1701 archive_set_error(&a->archive, 1702 ARCHIVE_ERRNO_MISC, 1703 "xmlTextWriterStartElement() " 1704 "failed: %d", r); 1705 goto exit_toc; 1706 } 1707 r = xmlTextWriterWriteFormatAttribute( 1708 writer, BAD_CAST("id"), "%d", np->id); 1709 if (r < 0) { 1710 archive_set_error(&a->archive, 1711 ARCHIVE_ERRNO_MISC, 1712 "xmlTextWriterWriteAttribute() " 1713 "failed: %d", r); 1714 goto exit_toc; 1715 } 1716 break; 1717 } 1718 } 1719 } while (np != np->parent); 1720 1721 r = xmlTextWriterEndDocument(writer); 1722 if (r < 0) { 1723 archive_set_error(&a->archive, 1724 ARCHIVE_ERRNO_MISC, 1725 "xmlTextWriterEndDocument() failed: %d", r); 1726 goto exit_toc; 1727 } 1728 #if DEBUG_PRINT_TOC 1729 fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n", 1730 strlen((const char *)bp->content), bp->content); 1731 #endif 1732 1733 /* 1734 * Compress the TOC and calculate the sum of the TOC. 1735 */ 1736 xar->toc.temp_offset = xar->temp_offset; 1737 xar->toc.size = bp->use; 1738 checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg); 1739 1740 r = compression_init_encoder_gzip(&(a->archive), 1741 &(xar->stream), 6, 1); 1742 if (r != ARCHIVE_OK) 1743 goto exit_toc; 1744 xar->stream.next_in = bp->content; 1745 xar->stream.avail_in = bp->use; 1746 xar->stream.total_in = 0; 1747 xar->stream.next_out = xar->wbuff; 1748 xar->stream.avail_out = sizeof(xar->wbuff); 1749 xar->stream.total_out = 0; 1750 for (;;) { 1751 size_t size; 1752 1753 r = compression_code(&(a->archive), 1754 &(xar->stream), ARCHIVE_Z_FINISH); 1755 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) 1756 goto exit_toc; 1757 size = sizeof(xar->wbuff) - xar->stream.avail_out; 1758 checksum_update(&(xar->a_sumwrk), xar->wbuff, size); 1759 if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK) 1760 goto exit_toc; 1761 if (r == ARCHIVE_EOF) 1762 break; 1763 xar->stream.next_out = xar->wbuff; 1764 xar->stream.avail_out = sizeof(xar->wbuff); 1765 } 1766 r = compression_end(&(a->archive), &(xar->stream)); 1767 if (r != ARCHIVE_OK) 1768 goto exit_toc; 1769 xar->toc.length = xar->stream.total_out; 1770 xar->toc.compression = GZIP; 1771 checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum)); 1772 1773 ret = ARCHIVE_OK; 1774 exit_toc: 1775 if (writer) 1776 xmlFreeTextWriter(writer); 1777 if (bp) 1778 xmlBufferFree(bp); 1779 1780 return (ret); 1781 } 1782 1783 static int 1784 flush_wbuff(struct archive_write *a) 1785 { 1786 struct xar *xar; 1787 int r; 1788 size_t s; 1789 1790 xar = (struct xar *)a->format_data; 1791 s = sizeof(xar->wbuff) - xar->wbuff_remaining; 1792 r = __archive_write_output(a, xar->wbuff, s); 1793 if (r != ARCHIVE_OK) 1794 return (r); 1795 xar->wbuff_remaining = sizeof(xar->wbuff); 1796 return (r); 1797 } 1798 1799 static int 1800 copy_out(struct archive_write *a, uint64_t offset, uint64_t length) 1801 { 1802 struct xar *xar; 1803 int r; 1804 1805 xar = (struct xar *)a->format_data; 1806 if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) { 1807 archive_set_error(&(a->archive), errno, "lseek failed"); 1808 return (ARCHIVE_FATAL); 1809 } 1810 while (length) { 1811 size_t rsize; 1812 ssize_t rs; 1813 unsigned char *wb; 1814 1815 if (length > xar->wbuff_remaining) 1816 rsize = xar->wbuff_remaining; 1817 else 1818 rsize = (size_t)length; 1819 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); 1820 rs = read(xar->temp_fd, wb, rsize); 1821 if (rs < 0) { 1822 archive_set_error(&(a->archive), errno, 1823 "Can't read temporary file(%jd)", 1824 (intmax_t)rs); 1825 return (ARCHIVE_FATAL); 1826 } 1827 if (rs == 0) { 1828 archive_set_error(&(a->archive), 0, 1829 "Truncated xar archive"); 1830 return (ARCHIVE_FATAL); 1831 } 1832 xar->wbuff_remaining -= rs; 1833 length -= rs; 1834 if (xar->wbuff_remaining == 0) { 1835 r = flush_wbuff(a); 1836 if (r != ARCHIVE_OK) 1837 return (r); 1838 } 1839 } 1840 return (ARCHIVE_OK); 1841 } 1842 1843 static int 1844 xar_close(struct archive_write *a) 1845 { 1846 struct xar *xar; 1847 unsigned char *wb; 1848 uint64_t length; 1849 int r; 1850 1851 xar = (struct xar *)a->format_data; 1852 1853 /* Empty! */ 1854 if (xar->root->children.first == NULL) 1855 return (ARCHIVE_OK); 1856 1857 /* Save the length of all file extended attributes and contents. */ 1858 length = xar->temp_offset; 1859 1860 /* Connect hardlinked files */ 1861 file_connect_hardlink_files(xar); 1862 1863 /* Make the TOC */ 1864 r = make_toc(a); 1865 if (r != ARCHIVE_OK) 1866 return (r); 1867 /* 1868 * Make the xar header on wbuff(write buffer). 1869 */ 1870 wb = xar->wbuff; 1871 xar->wbuff_remaining = sizeof(xar->wbuff); 1872 archive_be32enc(&wb[0], HEADER_MAGIC); 1873 archive_be16enc(&wb[4], HEADER_SIZE); 1874 archive_be16enc(&wb[6], HEADER_VERSION); 1875 archive_be64enc(&wb[8], xar->toc.length); 1876 archive_be64enc(&wb[16], xar->toc.size); 1877 archive_be32enc(&wb[24], xar->toc.a_sum.alg); 1878 xar->wbuff_remaining -= HEADER_SIZE; 1879 1880 /* 1881 * Write the TOC 1882 */ 1883 r = copy_out(a, xar->toc.temp_offset, xar->toc.length); 1884 if (r != ARCHIVE_OK) 1885 return (r); 1886 1887 /* Write the checksum value of the TOC. */ 1888 if (xar->toc.a_sum.len) { 1889 if (xar->wbuff_remaining < xar->toc.a_sum.len) { 1890 r = flush_wbuff(a); 1891 if (r != ARCHIVE_OK) 1892 return (r); 1893 } 1894 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); 1895 memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len); 1896 xar->wbuff_remaining -= xar->toc.a_sum.len; 1897 } 1898 1899 /* 1900 * Write all file extended attributes and contents. 1901 */ 1902 r = copy_out(a, xar->toc.a_sum.len, length); 1903 if (r != ARCHIVE_OK) 1904 return (r); 1905 r = flush_wbuff(a); 1906 return (r); 1907 } 1908 1909 static int 1910 xar_free(struct archive_write *a) 1911 { 1912 struct xar *xar; 1913 1914 xar = (struct xar *)a->format_data; 1915 1916 /* Close the temporary file. */ 1917 if (xar->temp_fd >= 0) 1918 close(xar->temp_fd); 1919 1920 archive_string_free(&(xar->cur_dirstr)); 1921 archive_string_free(&(xar->tstr)); 1922 archive_string_free(&(xar->vstr)); 1923 file_free_hardlinks(xar); 1924 file_free_register(xar); 1925 compression_end(&(a->archive), &(xar->stream)); 1926 free(xar); 1927 1928 return (ARCHIVE_OK); 1929 } 1930 1931 static int 1932 file_cmp_node(const struct archive_rb_node *n1, 1933 const struct archive_rb_node *n2) 1934 { 1935 const struct file *f1 = (const struct file *)n1; 1936 const struct file *f2 = (const struct file *)n2; 1937 1938 return (strcmp(f1->basename.s, f2->basename.s)); 1939 } 1940 1941 static int 1942 file_cmp_key(const struct archive_rb_node *n, const void *key) 1943 { 1944 const struct file *f = (const struct file *)n; 1945 1946 return (strcmp(f->basename.s, (const char *)key)); 1947 } 1948 1949 static struct file * 1950 file_new(struct archive_write *a, struct archive_entry *entry) 1951 { 1952 struct file *file; 1953 static const struct archive_rb_tree_ops rb_ops = { 1954 file_cmp_node, file_cmp_key 1955 }; 1956 1957 file = calloc(1, sizeof(*file)); 1958 if (file == NULL) 1959 return (NULL); 1960 1961 if (entry != NULL) 1962 file->entry = archive_entry_clone(entry); 1963 else 1964 file->entry = archive_entry_new2(&a->archive); 1965 if (file->entry == NULL) { 1966 free(file); 1967 return (NULL); 1968 } 1969 __archive_rb_tree_init(&(file->rbtree), &rb_ops); 1970 file->children.first = NULL; 1971 file->children.last = &(file->children.first); 1972 file->xattr.first = NULL; 1973 file->xattr.last = &(file->xattr.first); 1974 archive_string_init(&(file->parentdir)); 1975 archive_string_init(&(file->basename)); 1976 archive_string_init(&(file->symlink)); 1977 archive_string_init(&(file->script)); 1978 if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR) 1979 file->dir = 1; 1980 1981 return (file); 1982 } 1983 1984 static void 1985 file_free(struct file *file) 1986 { 1987 struct heap_data *heap, *next_heap; 1988 1989 heap = file->xattr.first; 1990 while (heap != NULL) { 1991 next_heap = heap->next; 1992 free(heap); 1993 heap = next_heap; 1994 } 1995 archive_string_free(&(file->parentdir)); 1996 archive_string_free(&(file->basename)); 1997 archive_string_free(&(file->symlink)); 1998 archive_string_free(&(file->script)); 1999 archive_entry_free(file->entry); 2000 free(file); 2001 } 2002 2003 static struct file * 2004 file_create_virtual_dir(struct archive_write *a, struct xar *xar, 2005 const char *pathname) 2006 { 2007 struct file *file; 2008 2009 (void)xar; /* UNUSED */ 2010 2011 file = file_new(a, NULL); 2012 if (file == NULL) 2013 return (NULL); 2014 archive_entry_set_pathname(file->entry, pathname); 2015 archive_entry_set_mode(file->entry, 0555 | AE_IFDIR); 2016 2017 file->dir = 1; 2018 file->virtual = 1; 2019 2020 return (file); 2021 } 2022 2023 static int 2024 file_add_child_tail(struct file *parent, struct file *child) 2025 { 2026 if (!__archive_rb_tree_insert_node( 2027 &(parent->rbtree), (struct archive_rb_node *)child)) 2028 return (0); 2029 child->chnext = NULL; 2030 *parent->children.last = child; 2031 parent->children.last = &(child->chnext); 2032 child->parent = parent; 2033 return (1); 2034 } 2035 2036 /* 2037 * Find a entry from `parent' 2038 */ 2039 static struct file * 2040 file_find_child(struct file *parent, const char *child_name) 2041 { 2042 struct file *np; 2043 2044 np = (struct file *)__archive_rb_tree_find_node( 2045 &(parent->rbtree), child_name); 2046 return (np); 2047 } 2048 2049 #if defined(_WIN32) || defined(__CYGWIN__) 2050 static void 2051 cleanup_backslash(char *utf8, size_t len) 2052 { 2053 2054 /* Convert a path-separator from '\' to '/' */ 2055 while (*utf8 != '\0' && len) { 2056 if (*utf8 == '\\') 2057 *utf8 = '/'; 2058 ++utf8; 2059 --len; 2060 } 2061 } 2062 #else 2063 #define cleanup_backslash(p, len) /* nop */ 2064 #endif 2065 2066 /* 2067 * Generate a parent directory name and a base name from a pathname. 2068 */ 2069 static int 2070 file_gen_utility_names(struct archive_write *a, struct file *file) 2071 { 2072 struct xar *xar; 2073 const char *pp; 2074 char *p, *dirname, *slash; 2075 size_t len; 2076 int r = ARCHIVE_OK; 2077 2078 xar = (struct xar *)a->format_data; 2079 archive_string_empty(&(file->parentdir)); 2080 archive_string_empty(&(file->basename)); 2081 archive_string_empty(&(file->symlink)); 2082 2083 if (file->parent == file)/* virtual root */ 2084 return (ARCHIVE_OK); 2085 2086 if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv) 2087 != 0) { 2088 if (errno == ENOMEM) { 2089 archive_set_error(&a->archive, ENOMEM, 2090 "Can't allocate memory for Pathname"); 2091 return (ARCHIVE_FATAL); 2092 } 2093 archive_set_error(&a->archive, 2094 ARCHIVE_ERRNO_FILE_FORMAT, 2095 "Can't translate pathname '%s' to UTF-8", 2096 archive_entry_pathname(file->entry)); 2097 r = ARCHIVE_WARN; 2098 } 2099 archive_strncpy(&(file->parentdir), pp, len); 2100 len = file->parentdir.length; 2101 p = dirname = file->parentdir.s; 2102 /* 2103 * Convert a path-separator from '\' to '/' 2104 */ 2105 cleanup_backslash(p, len); 2106 2107 /* 2108 * Remove leading '/', '../' and './' elements 2109 */ 2110 while (*p) { 2111 if (p[0] == '/') { 2112 p++; 2113 len--; 2114 } else if (p[0] != '.') 2115 break; 2116 else if (p[1] == '.' && p[2] == '/') { 2117 p += 3; 2118 len -= 3; 2119 } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) { 2120 p += 2; 2121 len -= 2; 2122 } else if (p[1] == '\0') { 2123 p++; 2124 len--; 2125 } else 2126 break; 2127 } 2128 if (p != dirname) { 2129 memmove(dirname, p, len+1); 2130 p = dirname; 2131 } 2132 /* 2133 * Remove "/","/." and "/.." elements from tail. 2134 */ 2135 while (len > 0) { 2136 size_t ll = len; 2137 2138 if (p[len-1] == '/') { 2139 p[len-1] = '\0'; 2140 len--; 2141 } 2142 if (len > 1 && p[len-2] == '/' && p[len-1] == '.') { 2143 p[len-2] = '\0'; 2144 len -= 2; 2145 } 2146 if (len > 2 && p[len-3] == '/' && p[len-2] == '.' && 2147 p[len-1] == '.') { 2148 p[len-3] = '\0'; 2149 len -= 3; 2150 } 2151 if (ll == len) 2152 break; 2153 } 2154 while (*p) { 2155 if (p[0] == '/') { 2156 if (p[1] == '/') 2157 /* Convert '//' --> '/' */ 2158 memmove(p, p+1, strlen(p+1) + 1); 2159 else if (p[1] == '.' && p[2] == '/') 2160 /* Convert '/./' --> '/' */ 2161 memmove(p, p+2, strlen(p+2) + 1); 2162 else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { 2163 /* Convert 'dir/dir1/../dir2/' 2164 * --> 'dir/dir2/' 2165 */ 2166 char *rp = p -1; 2167 while (rp >= dirname) { 2168 if (*rp == '/') 2169 break; 2170 --rp; 2171 } 2172 if (rp > dirname) { 2173 strcpy(rp, p+3); 2174 p = rp; 2175 } else { 2176 strcpy(dirname, p+4); 2177 p = dirname; 2178 } 2179 } else 2180 p++; 2181 } else 2182 p++; 2183 } 2184 p = dirname; 2185 len = strlen(p); 2186 2187 if (archive_entry_filetype(file->entry) == AE_IFLNK) { 2188 size_t len2; 2189 /* Convert symlink name too. */ 2190 if (archive_entry_symlink_l(file->entry, &pp, &len2, 2191 xar->sconv) != 0) { 2192 if (errno == ENOMEM) { 2193 archive_set_error(&a->archive, ENOMEM, 2194 "Can't allocate memory for Linkname"); 2195 return (ARCHIVE_FATAL); 2196 } 2197 archive_set_error(&a->archive, 2198 ARCHIVE_ERRNO_FILE_FORMAT, 2199 "Can't translate symlink '%s' to UTF-8", 2200 archive_entry_symlink(file->entry)); 2201 r = ARCHIVE_WARN; 2202 } 2203 archive_strncpy(&(file->symlink), pp, len2); 2204 cleanup_backslash(file->symlink.s, file->symlink.length); 2205 } 2206 /* 2207 * - Count up directory elements. 2208 * - Find out the position which points the last position of 2209 * path separator('/'). 2210 */ 2211 slash = NULL; 2212 for (; *p != '\0'; p++) 2213 if (*p == '/') 2214 slash = p; 2215 if (slash == NULL) { 2216 /* The pathname doesn't have a parent directory. */ 2217 file->parentdir.length = len; 2218 archive_string_copy(&(file->basename), &(file->parentdir)); 2219 archive_string_empty(&(file->parentdir)); 2220 *file->parentdir.s = '\0'; 2221 return (r); 2222 } 2223 2224 /* Make a basename from dirname and slash */ 2225 *slash = '\0'; 2226 file->parentdir.length = slash - dirname; 2227 archive_strcpy(&(file->basename), slash + 1); 2228 return (r); 2229 } 2230 2231 static int 2232 get_path_component(char *name, int n, const char *fn) 2233 { 2234 char *p; 2235 int l; 2236 2237 p = strchr(fn, '/'); 2238 if (p == NULL) { 2239 if ((l = strlen(fn)) == 0) 2240 return (0); 2241 } else 2242 l = p - fn; 2243 if (l > n -1) 2244 return (-1); 2245 memcpy(name, fn, l); 2246 name[l] = '\0'; 2247 2248 return (l); 2249 } 2250 2251 /* 2252 * Add a new entry into the tree. 2253 */ 2254 static int 2255 file_tree(struct archive_write *a, struct file **filepp) 2256 { 2257 #if defined(_WIN32) && !defined(__CYGWIN__) 2258 char name[_MAX_FNAME];/* Included null terminator size. */ 2259 #elif defined(NAME_MAX) && NAME_MAX >= 255 2260 char name[NAME_MAX+1]; 2261 #else 2262 char name[256]; 2263 #endif 2264 struct xar *xar = (struct xar *)a->format_data; 2265 struct file *dent, *file, *np; 2266 struct archive_entry *ent; 2267 const char *fn, *p; 2268 int l; 2269 2270 file = *filepp; 2271 dent = xar->root; 2272 if (file->parentdir.length > 0) 2273 fn = p = file->parentdir.s; 2274 else 2275 fn = p = ""; 2276 2277 /* 2278 * If the path of the parent directory of `file' entry is 2279 * the same as the path of `cur_dirent', add isoent to 2280 * `cur_dirent'. 2281 */ 2282 if (archive_strlen(&(xar->cur_dirstr)) 2283 == archive_strlen(&(file->parentdir)) && 2284 strcmp(xar->cur_dirstr.s, fn) == 0) { 2285 if (!file_add_child_tail(xar->cur_dirent, file)) { 2286 np = (struct file *)__archive_rb_tree_find_node( 2287 &(xar->cur_dirent->rbtree), 2288 file->basename.s); 2289 goto same_entry; 2290 } 2291 return (ARCHIVE_OK); 2292 } 2293 2294 for (;;) { 2295 l = get_path_component(name, sizeof(name), fn); 2296 if (l == 0) { 2297 np = NULL; 2298 break; 2299 } 2300 if (l < 0) { 2301 archive_set_error(&a->archive, 2302 ARCHIVE_ERRNO_MISC, 2303 "A name buffer is too small"); 2304 file_free(file); 2305 *filepp = NULL; 2306 return (ARCHIVE_FATAL); 2307 } 2308 2309 np = file_find_child(dent, name); 2310 if (np == NULL || fn[0] == '\0') 2311 break; 2312 2313 /* Find next subdirectory. */ 2314 if (!np->dir) { 2315 /* NOT Directory! */ 2316 archive_set_error(&a->archive, 2317 ARCHIVE_ERRNO_MISC, 2318 "`%s' is not directory, we cannot insert `%s' ", 2319 archive_entry_pathname(np->entry), 2320 archive_entry_pathname(file->entry)); 2321 file_free(file); 2322 *filepp = NULL; 2323 return (ARCHIVE_FAILED); 2324 } 2325 fn += l; 2326 if (fn[0] == '/') 2327 fn++; 2328 dent = np; 2329 } 2330 if (np == NULL) { 2331 /* 2332 * Create virtual parent directories. 2333 */ 2334 while (fn[0] != '\0') { 2335 struct file *vp; 2336 struct archive_string as; 2337 2338 archive_string_init(&as); 2339 archive_strncat(&as, p, fn - p + l); 2340 if (as.s[as.length-1] == '/') { 2341 as.s[as.length-1] = '\0'; 2342 as.length--; 2343 } 2344 vp = file_create_virtual_dir(a, xar, as.s); 2345 if (vp == NULL) { 2346 archive_string_free(&as); 2347 archive_set_error(&a->archive, ENOMEM, 2348 "Can't allocate memory"); 2349 file_free(file); 2350 *filepp = NULL; 2351 return (ARCHIVE_FATAL); 2352 } 2353 archive_string_free(&as); 2354 if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED) 2355 return (ARCHIVE_FATAL); 2356 file_add_child_tail(dent, vp); 2357 file_register(xar, vp); 2358 np = vp; 2359 2360 fn += l; 2361 if (fn[0] == '/') 2362 fn++; 2363 l = get_path_component(name, sizeof(name), fn); 2364 if (l < 0) { 2365 archive_string_free(&as); 2366 archive_set_error(&a->archive, 2367 ARCHIVE_ERRNO_MISC, 2368 "A name buffer is too small"); 2369 file_free(file); 2370 *filepp = NULL; 2371 return (ARCHIVE_FATAL); 2372 } 2373 dent = np; 2374 } 2375 2376 /* Found out the parent directory where isoent can be 2377 * inserted. */ 2378 xar->cur_dirent = dent; 2379 archive_string_empty(&(xar->cur_dirstr)); 2380 archive_string_ensure(&(xar->cur_dirstr), 2381 archive_strlen(&(dent->parentdir)) + 2382 archive_strlen(&(dent->basename)) + 2); 2383 if (archive_strlen(&(dent->parentdir)) + 2384 archive_strlen(&(dent->basename)) == 0) 2385 xar->cur_dirstr.s[0] = 0; 2386 else { 2387 if (archive_strlen(&(dent->parentdir)) > 0) { 2388 archive_string_copy(&(xar->cur_dirstr), 2389 &(dent->parentdir)); 2390 archive_strappend_char(&(xar->cur_dirstr), '/'); 2391 } 2392 archive_string_concat(&(xar->cur_dirstr), 2393 &(dent->basename)); 2394 } 2395 2396 if (!file_add_child_tail(dent, file)) { 2397 np = (struct file *)__archive_rb_tree_find_node( 2398 &(dent->rbtree), file->basename.s); 2399 goto same_entry; 2400 } 2401 return (ARCHIVE_OK); 2402 } 2403 2404 same_entry: 2405 /* 2406 * We have already has the entry the filename of which is 2407 * the same. 2408 */ 2409 if (archive_entry_filetype(np->entry) != 2410 archive_entry_filetype(file->entry)) { 2411 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2412 "Found duplicate entries `%s' and its file type is " 2413 "different", 2414 archive_entry_pathname(np->entry)); 2415 file_free(file); 2416 *filepp = NULL; 2417 return (ARCHIVE_FAILED); 2418 } 2419 2420 /* Swap files. */ 2421 ent = np->entry; 2422 np->entry = file->entry; 2423 file->entry = ent; 2424 np->virtual = 0; 2425 2426 file_free(file); 2427 *filepp = np; 2428 return (ARCHIVE_OK); 2429 } 2430 2431 static void 2432 file_register(struct xar *xar, struct file *file) 2433 { 2434 file->id = xar->file_idx++; 2435 file->next = NULL; 2436 *xar->file_list.last = file; 2437 xar->file_list.last = &(file->next); 2438 } 2439 2440 static void 2441 file_init_register(struct xar *xar) 2442 { 2443 xar->file_list.first = NULL; 2444 xar->file_list.last = &(xar->file_list.first); 2445 } 2446 2447 static void 2448 file_free_register(struct xar *xar) 2449 { 2450 struct file *file, *file_next; 2451 2452 file = xar->file_list.first; 2453 while (file != NULL) { 2454 file_next = file->next; 2455 file_free(file); 2456 file = file_next; 2457 } 2458 } 2459 2460 /* 2461 * Register entry to get a hardlink target. 2462 */ 2463 static int 2464 file_register_hardlink(struct archive_write *a, struct file *file) 2465 { 2466 struct xar *xar = (struct xar *)a->format_data; 2467 struct hardlink *hl; 2468 const char *pathname; 2469 2470 archive_entry_set_nlink(file->entry, 1); 2471 pathname = archive_entry_hardlink(file->entry); 2472 if (pathname == NULL) { 2473 /* This `file` is a hardlink target. */ 2474 hl = malloc(sizeof(*hl)); 2475 if (hl == NULL) { 2476 archive_set_error(&a->archive, ENOMEM, 2477 "Can't allocate memory"); 2478 return (ARCHIVE_FATAL); 2479 } 2480 hl->nlink = 1; 2481 /* A hardlink target must be the first position. */ 2482 file->hlnext = NULL; 2483 hl->file_list.first = file; 2484 hl->file_list.last = &(file->hlnext); 2485 __archive_rb_tree_insert_node(&(xar->hardlink_rbtree), 2486 (struct archive_rb_node *)hl); 2487 } else { 2488 hl = (struct hardlink *)__archive_rb_tree_find_node( 2489 &(xar->hardlink_rbtree), pathname); 2490 if (hl != NULL) { 2491 /* Insert `file` entry into the tail. */ 2492 file->hlnext = NULL; 2493 *hl->file_list.last = file; 2494 hl->file_list.last = &(file->hlnext); 2495 hl->nlink++; 2496 } 2497 archive_entry_unset_size(file->entry); 2498 } 2499 2500 return (ARCHIVE_OK); 2501 } 2502 2503 /* 2504 * Hardlinked files have to have the same location of extent. 2505 * We have to find out hardlink target entries for entries which 2506 * have a hardlink target name. 2507 */ 2508 static void 2509 file_connect_hardlink_files(struct xar *xar) 2510 { 2511 struct archive_rb_node *n; 2512 struct hardlink *hl; 2513 struct file *target, *nf; 2514 2515 ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) { 2516 hl = (struct hardlink *)n; 2517 2518 /* The first entry must be a hardlink target. */ 2519 target = hl->file_list.first; 2520 archive_entry_set_nlink(target->entry, hl->nlink); 2521 if (hl->nlink > 1) 2522 /* It means this file is a hardlink 2523 * target itself. */ 2524 target->hardlink_target = target; 2525 for (nf = target->hlnext; 2526 nf != NULL; nf = nf->hlnext) { 2527 nf->hardlink_target = target; 2528 archive_entry_set_nlink(nf->entry, hl->nlink); 2529 } 2530 } 2531 } 2532 2533 static int 2534 file_hd_cmp_node(const struct archive_rb_node *n1, 2535 const struct archive_rb_node *n2) 2536 { 2537 const struct hardlink *h1 = (const struct hardlink *)n1; 2538 const struct hardlink *h2 = (const struct hardlink *)n2; 2539 2540 return (strcmp(archive_entry_pathname(h1->file_list.first->entry), 2541 archive_entry_pathname(h2->file_list.first->entry))); 2542 } 2543 2544 static int 2545 file_hd_cmp_key(const struct archive_rb_node *n, const void *key) 2546 { 2547 const struct hardlink *h = (const struct hardlink *)n; 2548 2549 return (strcmp(archive_entry_pathname(h->file_list.first->entry), 2550 (const char *)key)); 2551 } 2552 2553 2554 static void 2555 file_init_hardlinks(struct xar *xar) 2556 { 2557 static const struct archive_rb_tree_ops rb_ops = { 2558 file_hd_cmp_node, file_hd_cmp_key, 2559 }; 2560 2561 __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops); 2562 } 2563 2564 static void 2565 file_free_hardlinks(struct xar *xar) 2566 { 2567 struct archive_rb_node *n, *tmp; 2568 2569 ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) { 2570 __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n); 2571 free(n); 2572 } 2573 } 2574 2575 static void 2576 checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg) 2577 { 2578 sumwrk->alg = sum_alg; 2579 switch (sum_alg) { 2580 case CKSUM_NONE: 2581 break; 2582 case CKSUM_SHA1: 2583 archive_sha1_init(&(sumwrk->sha1ctx)); 2584 break; 2585 case CKSUM_MD5: 2586 archive_md5_init(&(sumwrk->md5ctx)); 2587 break; 2588 } 2589 } 2590 2591 static void 2592 checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size) 2593 { 2594 2595 switch (sumwrk->alg) { 2596 case CKSUM_NONE: 2597 break; 2598 case CKSUM_SHA1: 2599 archive_sha1_update(&(sumwrk->sha1ctx), buff, size); 2600 break; 2601 case CKSUM_MD5: 2602 archive_md5_update(&(sumwrk->md5ctx), buff, size); 2603 break; 2604 } 2605 } 2606 2607 static void 2608 checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval) 2609 { 2610 2611 switch (sumwrk->alg) { 2612 case CKSUM_NONE: 2613 sumval->len = 0; 2614 break; 2615 case CKSUM_SHA1: 2616 archive_sha1_final(&(sumwrk->sha1ctx), sumval->val); 2617 sumval->len = SHA1_SIZE; 2618 break; 2619 case CKSUM_MD5: 2620 archive_md5_final(&(sumwrk->md5ctx), sumval->val); 2621 sumval->len = MD5_SIZE; 2622 break; 2623 } 2624 sumval->alg = sumwrk->alg; 2625 } 2626 2627 #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) 2628 static int 2629 compression_unsupported_encoder(struct archive *a, 2630 struct la_zstream *lastrm, const char *name) 2631 { 2632 2633 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2634 "%s compression not supported on this platform", name); 2635 lastrm->valid = 0; 2636 lastrm->real_stream = NULL; 2637 return (ARCHIVE_FAILED); 2638 } 2639 #endif 2640 2641 static int 2642 compression_init_encoder_gzip(struct archive *a, 2643 struct la_zstream *lastrm, int level, int withheader) 2644 { 2645 z_stream *strm; 2646 2647 if (lastrm->valid) 2648 compression_end(a, lastrm); 2649 strm = calloc(1, sizeof(*strm)); 2650 if (strm == NULL) { 2651 archive_set_error(a, ENOMEM, 2652 "Can't allocate memory for gzip stream"); 2653 return (ARCHIVE_FATAL); 2654 } 2655 /* zlib.h is not const-correct, so we need this one bit 2656 * of ugly hackery to convert a const * pointer to 2657 * a non-const pointer. */ 2658 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 2659 strm->avail_in = lastrm->avail_in; 2660 strm->total_in = (uLong)lastrm->total_in; 2661 strm->next_out = lastrm->next_out; 2662 strm->avail_out = lastrm->avail_out; 2663 strm->total_out = (uLong)lastrm->total_out; 2664 if (deflateInit2(strm, level, Z_DEFLATED, 2665 (withheader)?15:-15, 2666 8, Z_DEFAULT_STRATEGY) != Z_OK) { 2667 free(strm); 2668 lastrm->real_stream = NULL; 2669 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2670 "Internal error initializing compression library"); 2671 return (ARCHIVE_FATAL); 2672 } 2673 lastrm->real_stream = strm; 2674 lastrm->valid = 1; 2675 lastrm->code = compression_code_gzip; 2676 lastrm->end = compression_end_gzip; 2677 return (ARCHIVE_OK); 2678 } 2679 2680 static int 2681 compression_code_gzip(struct archive *a, 2682 struct la_zstream *lastrm, enum la_zaction action) 2683 { 2684 z_stream *strm; 2685 int r; 2686 2687 strm = (z_stream *)lastrm->real_stream; 2688 /* zlib.h is not const-correct, so we need this one bit 2689 * of ugly hackery to convert a const * pointer to 2690 * a non-const pointer. */ 2691 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 2692 strm->avail_in = lastrm->avail_in; 2693 strm->total_in = (uLong)lastrm->total_in; 2694 strm->next_out = lastrm->next_out; 2695 strm->avail_out = lastrm->avail_out; 2696 strm->total_out = (uLong)lastrm->total_out; 2697 r = deflate(strm, 2698 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); 2699 lastrm->next_in = strm->next_in; 2700 lastrm->avail_in = strm->avail_in; 2701 lastrm->total_in = strm->total_in; 2702 lastrm->next_out = strm->next_out; 2703 lastrm->avail_out = strm->avail_out; 2704 lastrm->total_out = strm->total_out; 2705 switch (r) { 2706 case Z_OK: 2707 return (ARCHIVE_OK); 2708 case Z_STREAM_END: 2709 return (ARCHIVE_EOF); 2710 default: 2711 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2712 "GZip compression failed:" 2713 " deflate() call returned status %d", r); 2714 return (ARCHIVE_FATAL); 2715 } 2716 } 2717 2718 static int 2719 compression_end_gzip(struct archive *a, struct la_zstream *lastrm) 2720 { 2721 z_stream *strm; 2722 int r; 2723 2724 strm = (z_stream *)lastrm->real_stream; 2725 r = deflateEnd(strm); 2726 free(strm); 2727 lastrm->real_stream = NULL; 2728 lastrm->valid = 0; 2729 if (r != Z_OK) { 2730 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2731 "Failed to clean up compressor"); 2732 return (ARCHIVE_FATAL); 2733 } 2734 return (ARCHIVE_OK); 2735 } 2736 2737 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 2738 static int 2739 compression_init_encoder_bzip2(struct archive *a, 2740 struct la_zstream *lastrm, int level) 2741 { 2742 bz_stream *strm; 2743 2744 if (lastrm->valid) 2745 compression_end(a, lastrm); 2746 strm = calloc(1, sizeof(*strm)); 2747 if (strm == NULL) { 2748 archive_set_error(a, ENOMEM, 2749 "Can't allocate memory for bzip2 stream"); 2750 return (ARCHIVE_FATAL); 2751 } 2752 /* bzlib.h is not const-correct, so we need this one bit 2753 * of ugly hackery to convert a const * pointer to 2754 * a non-const pointer. */ 2755 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 2756 strm->avail_in = lastrm->avail_in; 2757 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 2758 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 2759 strm->next_out = (char *)lastrm->next_out; 2760 strm->avail_out = lastrm->avail_out; 2761 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 2762 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 2763 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { 2764 free(strm); 2765 lastrm->real_stream = NULL; 2766 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2767 "Internal error initializing compression library"); 2768 return (ARCHIVE_FATAL); 2769 } 2770 lastrm->real_stream = strm; 2771 lastrm->valid = 1; 2772 lastrm->code = compression_code_bzip2; 2773 lastrm->end = compression_end_bzip2; 2774 return (ARCHIVE_OK); 2775 } 2776 2777 static int 2778 compression_code_bzip2(struct archive *a, 2779 struct la_zstream *lastrm, enum la_zaction action) 2780 { 2781 bz_stream *strm; 2782 int r; 2783 2784 strm = (bz_stream *)lastrm->real_stream; 2785 /* bzlib.h is not const-correct, so we need this one bit 2786 * of ugly hackery to convert a const * pointer to 2787 * a non-const pointer. */ 2788 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 2789 strm->avail_in = lastrm->avail_in; 2790 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 2791 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 2792 strm->next_out = (char *)lastrm->next_out; 2793 strm->avail_out = lastrm->avail_out; 2794 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 2795 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 2796 r = BZ2_bzCompress(strm, 2797 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); 2798 lastrm->next_in = (const unsigned char *)strm->next_in; 2799 lastrm->avail_in = strm->avail_in; 2800 lastrm->total_in = 2801 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) 2802 + (uint64_t)(uint32_t)strm->total_in_lo32; 2803 lastrm->next_out = (unsigned char *)strm->next_out; 2804 lastrm->avail_out = strm->avail_out; 2805 lastrm->total_out = 2806 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) 2807 + (uint64_t)(uint32_t)strm->total_out_lo32; 2808 switch (r) { 2809 case BZ_RUN_OK: /* Non-finishing */ 2810 case BZ_FINISH_OK: /* Finishing: There's more work to do */ 2811 return (ARCHIVE_OK); 2812 case BZ_STREAM_END: /* Finishing: all done */ 2813 /* Only occurs in finishing case */ 2814 return (ARCHIVE_EOF); 2815 default: 2816 /* Any other return value indicates an error */ 2817 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2818 "Bzip2 compression failed:" 2819 " BZ2_bzCompress() call returned status %d", r); 2820 return (ARCHIVE_FATAL); 2821 } 2822 } 2823 2824 static int 2825 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) 2826 { 2827 bz_stream *strm; 2828 int r; 2829 2830 strm = (bz_stream *)lastrm->real_stream; 2831 r = BZ2_bzCompressEnd(strm); 2832 free(strm); 2833 lastrm->real_stream = NULL; 2834 lastrm->valid = 0; 2835 if (r != BZ_OK) { 2836 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2837 "Failed to clean up compressor"); 2838 return (ARCHIVE_FATAL); 2839 } 2840 return (ARCHIVE_OK); 2841 } 2842 2843 #else 2844 static int 2845 compression_init_encoder_bzip2(struct archive *a, 2846 struct la_zstream *lastrm, int level) 2847 { 2848 2849 (void) level; /* UNUSED */ 2850 if (lastrm->valid) 2851 compression_end(a, lastrm); 2852 return (compression_unsupported_encoder(a, lastrm, "bzip2")); 2853 } 2854 #endif 2855 2856 #if defined(HAVE_LZMA_H) 2857 static int 2858 compression_init_encoder_lzma(struct archive *a, 2859 struct la_zstream *lastrm, int level) 2860 { 2861 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 2862 lzma_stream *strm; 2863 lzma_options_lzma lzma_opt; 2864 int r; 2865 2866 if (lastrm->valid) 2867 compression_end(a, lastrm); 2868 if (lzma_lzma_preset(&lzma_opt, level)) { 2869 lastrm->real_stream = NULL; 2870 archive_set_error(a, ENOMEM, 2871 "Internal error initializing compression library"); 2872 return (ARCHIVE_FATAL); 2873 } 2874 strm = calloc(1, sizeof(*strm)); 2875 if (strm == NULL) { 2876 archive_set_error(a, ENOMEM, 2877 "Can't allocate memory for lzma stream"); 2878 return (ARCHIVE_FATAL); 2879 } 2880 *strm = lzma_init_data; 2881 r = lzma_alone_encoder(strm, &lzma_opt); 2882 switch (r) { 2883 case LZMA_OK: 2884 lastrm->real_stream = strm; 2885 lastrm->valid = 1; 2886 lastrm->code = compression_code_lzma; 2887 lastrm->end = compression_end_lzma; 2888 r = ARCHIVE_OK; 2889 break; 2890 case LZMA_MEM_ERROR: 2891 free(strm); 2892 lastrm->real_stream = NULL; 2893 archive_set_error(a, ENOMEM, 2894 "Internal error initializing compression library: " 2895 "Cannot allocate memory"); 2896 r = ARCHIVE_FATAL; 2897 break; 2898 default: 2899 free(strm); 2900 lastrm->real_stream = NULL; 2901 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2902 "Internal error initializing compression library: " 2903 "It's a bug in liblzma"); 2904 r = ARCHIVE_FATAL; 2905 break; 2906 } 2907 return (r); 2908 } 2909 2910 static int 2911 compression_init_encoder_xz(struct archive *a, 2912 struct la_zstream *lastrm, int level, int threads) 2913 { 2914 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 2915 lzma_stream *strm; 2916 lzma_filter *lzmafilters; 2917 lzma_options_lzma lzma_opt; 2918 int r; 2919 #ifdef HAVE_LZMA_STREAM_ENCODER_MT 2920 lzma_mt mt_options; 2921 #endif 2922 2923 (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */ 2924 2925 if (lastrm->valid) 2926 compression_end(a, lastrm); 2927 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); 2928 if (strm == NULL) { 2929 archive_set_error(a, ENOMEM, 2930 "Can't allocate memory for xz stream"); 2931 return (ARCHIVE_FATAL); 2932 } 2933 lzmafilters = (lzma_filter *)(strm+1); 2934 if (level > 6) 2935 level = 6; 2936 if (lzma_lzma_preset(&lzma_opt, level)) { 2937 free(strm); 2938 lastrm->real_stream = NULL; 2939 archive_set_error(a, ENOMEM, 2940 "Internal error initializing compression library"); 2941 return (ARCHIVE_FATAL); 2942 } 2943 lzmafilters[0].id = LZMA_FILTER_LZMA2; 2944 lzmafilters[0].options = &lzma_opt; 2945 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ 2946 2947 *strm = lzma_init_data; 2948 #ifdef HAVE_LZMA_STREAM_ENCODER_MT 2949 if (threads > 1) { 2950 memset(&mt_options, 0, sizeof(mt_options)); 2951 mt_options.threads = threads; 2952 mt_options.timeout = 300; 2953 mt_options.filters = lzmafilters; 2954 mt_options.check = LZMA_CHECK_CRC64; 2955 r = lzma_stream_encoder_mt(strm, &mt_options); 2956 } else 2957 #endif 2958 r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64); 2959 switch (r) { 2960 case LZMA_OK: 2961 lastrm->real_stream = strm; 2962 lastrm->valid = 1; 2963 lastrm->code = compression_code_lzma; 2964 lastrm->end = compression_end_lzma; 2965 r = ARCHIVE_OK; 2966 break; 2967 case LZMA_MEM_ERROR: 2968 free(strm); 2969 lastrm->real_stream = NULL; 2970 archive_set_error(a, ENOMEM, 2971 "Internal error initializing compression library: " 2972 "Cannot allocate memory"); 2973 r = ARCHIVE_FATAL; 2974 break; 2975 default: 2976 free(strm); 2977 lastrm->real_stream = NULL; 2978 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2979 "Internal error initializing compression library: " 2980 "It's a bug in liblzma"); 2981 r = ARCHIVE_FATAL; 2982 break; 2983 } 2984 return (r); 2985 } 2986 2987 static int 2988 compression_code_lzma(struct archive *a, 2989 struct la_zstream *lastrm, enum la_zaction action) 2990 { 2991 lzma_stream *strm; 2992 int r; 2993 2994 strm = (lzma_stream *)lastrm->real_stream; 2995 strm->next_in = lastrm->next_in; 2996 strm->avail_in = lastrm->avail_in; 2997 strm->total_in = lastrm->total_in; 2998 strm->next_out = lastrm->next_out; 2999 strm->avail_out = lastrm->avail_out; 3000 strm->total_out = lastrm->total_out; 3001 r = lzma_code(strm, 3002 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); 3003 lastrm->next_in = strm->next_in; 3004 lastrm->avail_in = strm->avail_in; 3005 lastrm->total_in = strm->total_in; 3006 lastrm->next_out = strm->next_out; 3007 lastrm->avail_out = strm->avail_out; 3008 lastrm->total_out = strm->total_out; 3009 switch (r) { 3010 case LZMA_OK: 3011 /* Non-finishing case */ 3012 return (ARCHIVE_OK); 3013 case LZMA_STREAM_END: 3014 /* This return can only occur in finishing case. */ 3015 return (ARCHIVE_EOF); 3016 case LZMA_MEMLIMIT_ERROR: 3017 archive_set_error(a, ENOMEM, 3018 "lzma compression error:" 3019 " %ju MiB would have been needed", 3020 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) 3021 / (1024 * 1024))); 3022 return (ARCHIVE_FATAL); 3023 default: 3024 /* Any other return value indicates an error */ 3025 archive_set_error(a, ARCHIVE_ERRNO_MISC, 3026 "lzma compression failed:" 3027 " lzma_code() call returned status %d", r); 3028 return (ARCHIVE_FATAL); 3029 } 3030 } 3031 3032 static int 3033 compression_end_lzma(struct archive *a, struct la_zstream *lastrm) 3034 { 3035 lzma_stream *strm; 3036 3037 (void)a; /* UNUSED */ 3038 strm = (lzma_stream *)lastrm->real_stream; 3039 lzma_end(strm); 3040 free(strm); 3041 lastrm->valid = 0; 3042 lastrm->real_stream = NULL; 3043 return (ARCHIVE_OK); 3044 } 3045 #else 3046 static int 3047 compression_init_encoder_lzma(struct archive *a, 3048 struct la_zstream *lastrm, int level) 3049 { 3050 3051 (void) level; /* UNUSED */ 3052 if (lastrm->valid) 3053 compression_end(a, lastrm); 3054 return (compression_unsupported_encoder(a, lastrm, "lzma")); 3055 } 3056 static int 3057 compression_init_encoder_xz(struct archive *a, 3058 struct la_zstream *lastrm, int level, int threads) 3059 { 3060 3061 (void) level; /* UNUSED */ 3062 (void) threads; /* UNUSED */ 3063 if (lastrm->valid) 3064 compression_end(a, lastrm); 3065 return (compression_unsupported_encoder(a, lastrm, "xz")); 3066 } 3067 #endif 3068 3069 static int 3070 xar_compression_init_encoder(struct archive_write *a) 3071 { 3072 struct xar *xar; 3073 int r; 3074 3075 xar = (struct xar *)a->format_data; 3076 switch (xar->opt_compression) { 3077 case GZIP: 3078 r = compression_init_encoder_gzip( 3079 &(a->archive), &(xar->stream), 3080 xar->opt_compression_level, 1); 3081 break; 3082 case BZIP2: 3083 r = compression_init_encoder_bzip2( 3084 &(a->archive), &(xar->stream), 3085 xar->opt_compression_level); 3086 break; 3087 case LZMA: 3088 r = compression_init_encoder_lzma( 3089 &(a->archive), &(xar->stream), 3090 xar->opt_compression_level); 3091 break; 3092 case XZ: 3093 r = compression_init_encoder_xz( 3094 &(a->archive), &(xar->stream), 3095 xar->opt_compression_level, xar->opt_threads); 3096 break; 3097 default: 3098 r = ARCHIVE_OK; 3099 break; 3100 } 3101 if (r == ARCHIVE_OK) { 3102 xar->stream.total_in = 0; 3103 xar->stream.next_out = xar->wbuff; 3104 xar->stream.avail_out = sizeof(xar->wbuff); 3105 xar->stream.total_out = 0; 3106 } 3107 3108 return (r); 3109 } 3110 3111 static int 3112 compression_code(struct archive *a, struct la_zstream *lastrm, 3113 enum la_zaction action) 3114 { 3115 if (lastrm->valid) 3116 return (lastrm->code(a, lastrm, action)); 3117 return (ARCHIVE_OK); 3118 } 3119 3120 static int 3121 compression_end(struct archive *a, struct la_zstream *lastrm) 3122 { 3123 if (lastrm->valid) 3124 return (lastrm->end(a, lastrm)); 3125 return (ARCHIVE_OK); 3126 } 3127 3128 3129 static int 3130 save_xattrs(struct archive_write *a, struct file *file) 3131 { 3132 struct xar *xar; 3133 const char *name; 3134 const void *value; 3135 struct heap_data *heap; 3136 size_t size; 3137 int count, r; 3138 3139 xar = (struct xar *)a->format_data; 3140 count = archive_entry_xattr_reset(file->entry); 3141 if (count == 0) 3142 return (ARCHIVE_OK); 3143 while (count--) { 3144 archive_entry_xattr_next(file->entry, 3145 &name, &value, &size); 3146 checksum_init(&(xar->a_sumwrk), xar->opt_sumalg); 3147 checksum_init(&(xar->e_sumwrk), xar->opt_sumalg); 3148 3149 heap = calloc(1, sizeof(*heap)); 3150 if (heap == NULL) { 3151 archive_set_error(&a->archive, ENOMEM, 3152 "Can't allocate memory for xattr"); 3153 return (ARCHIVE_FATAL); 3154 } 3155 heap->id = file->ea_idx++; 3156 heap->temp_offset = xar->temp_offset; 3157 heap->size = size;/* save a extracted size */ 3158 heap->compression = xar->opt_compression; 3159 /* Get a extracted sumcheck value. */ 3160 checksum_update(&(xar->e_sumwrk), value, size); 3161 checksum_final(&(xar->e_sumwrk), &(heap->e_sum)); 3162 3163 /* 3164 * Not compression to xattr is simple way. 3165 */ 3166 if (heap->compression == NONE) { 3167 checksum_update(&(xar->a_sumwrk), value, size); 3168 checksum_final(&(xar->a_sumwrk), &(heap->a_sum)); 3169 if (write_to_temp(a, value, size) 3170 != ARCHIVE_OK) { 3171 free(heap); 3172 return (ARCHIVE_FATAL); 3173 } 3174 heap->length = size; 3175 /* Add heap to the tail of file->xattr. */ 3176 heap->next = NULL; 3177 *file->xattr.last = heap; 3178 file->xattr.last = &(heap->next); 3179 /* Next xattr */ 3180 continue; 3181 } 3182 3183 /* 3184 * Init compression library. 3185 */ 3186 r = xar_compression_init_encoder(a); 3187 if (r != ARCHIVE_OK) { 3188 free(heap); 3189 return (ARCHIVE_FATAL); 3190 } 3191 3192 xar->stream.next_in = (const unsigned char *)value; 3193 xar->stream.avail_in = size; 3194 for (;;) { 3195 r = compression_code(&(a->archive), 3196 &(xar->stream), ARCHIVE_Z_FINISH); 3197 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) { 3198 free(heap); 3199 return (ARCHIVE_FATAL); 3200 } 3201 size = sizeof(xar->wbuff) - xar->stream.avail_out; 3202 checksum_update(&(xar->a_sumwrk), 3203 xar->wbuff, size); 3204 if (write_to_temp(a, xar->wbuff, size) 3205 != ARCHIVE_OK) { 3206 free(heap); 3207 return (ARCHIVE_FATAL); 3208 } 3209 if (r == ARCHIVE_OK) { 3210 xar->stream.next_out = xar->wbuff; 3211 xar->stream.avail_out = sizeof(xar->wbuff); 3212 } else { 3213 checksum_final(&(xar->a_sumwrk), 3214 &(heap->a_sum)); 3215 heap->length = xar->stream.total_out; 3216 /* Add heap to the tail of file->xattr. */ 3217 heap->next = NULL; 3218 *file->xattr.last = heap; 3219 file->xattr.last = &(heap->next); 3220 break; 3221 } 3222 } 3223 /* Clean up compression library. */ 3224 r = compression_end(&(a->archive), &(xar->stream)); 3225 if (r != ARCHIVE_OK) 3226 return (ARCHIVE_FATAL); 3227 } 3228 return (ARCHIVE_OK); 3229 } 3230 3231 static int 3232 getalgsize(enum sumalg sumalg) 3233 { 3234 switch (sumalg) { 3235 default: 3236 case CKSUM_NONE: 3237 return (0); 3238 case CKSUM_SHA1: 3239 return (SHA1_SIZE); 3240 case CKSUM_MD5: 3241 return (MD5_SIZE); 3242 } 3243 } 3244 3245 static const char * 3246 getalgname(enum sumalg sumalg) 3247 { 3248 switch (sumalg) { 3249 default: 3250 case CKSUM_NONE: 3251 return (NULL); 3252 case CKSUM_SHA1: 3253 return (SHA1_NAME); 3254 case CKSUM_MD5: 3255 return (MD5_NAME); 3256 } 3257 } 3258 3259 #endif /* Support xar format */ 3260