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 unsigned int virtual:1; 216 unsigned 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 910 #if defined(HAVE_GMTIME_S) 911 gmtime_s(&tm, &t); 912 #elif defined(HAVE_GMTIME_R) 913 gmtime_r(&t, &tm); 914 #else 915 memcpy(&tm, gmtime(&t), sizeof(tm)); 916 #endif 917 memset(×tr, 0, sizeof(timestr)); 918 /* Do not use %F and %T for portability. */ 919 strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm); 920 if (z) 921 strcat(timestr, "Z"); 922 return (xmlwrite_string(a, writer, key, timestr)); 923 } 924 925 static int 926 xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer, 927 const char *key, mode_t mode) 928 { 929 char ms[5]; 930 931 ms[0] = '0'; 932 ms[1] = '0' + ((mode >> 6) & 07); 933 ms[2] = '0' + ((mode >> 3) & 07); 934 ms[3] = '0' + (mode & 07); 935 ms[4] = '\0'; 936 937 return (xmlwrite_string(a, writer, key, ms)); 938 } 939 940 static int 941 xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer, 942 const char *key, struct chksumval *sum) 943 { 944 const char *algname; 945 int algsize; 946 char buff[MAX_SUM_SIZE*2 + 1]; 947 char *p; 948 unsigned char *s; 949 int i, r; 950 951 if (sum->len > 0) { 952 algname = getalgname(sum->alg); 953 algsize = getalgsize(sum->alg); 954 if (algname != NULL) { 955 const char *hex = "0123456789abcdef"; 956 p = buff; 957 s = sum->val; 958 for (i = 0; i < algsize; i++) { 959 *p++ = hex[(*s >> 4)]; 960 *p++ = hex[(*s & 0x0f)]; 961 s++; 962 } 963 *p = '\0'; 964 r = xmlwrite_string_attr(a, writer, 965 key, buff, 966 "style", algname); 967 if (r < 0) 968 return (ARCHIVE_FATAL); 969 } 970 } 971 return (ARCHIVE_OK); 972 } 973 974 static int 975 xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer, 976 struct heap_data *heap) 977 { 978 const char *encname; 979 int r; 980 981 r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length); 982 if (r < 0) 983 return (ARCHIVE_FATAL); 984 r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset); 985 if (r < 0) 986 return (ARCHIVE_FATAL); 987 r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size); 988 if (r < 0) 989 return (ARCHIVE_FATAL); 990 switch (heap->compression) { 991 case GZIP: 992 encname = "application/x-gzip"; break; 993 case BZIP2: 994 encname = "application/x-bzip2"; break; 995 case LZMA: 996 encname = "application/x-lzma"; break; 997 case XZ: 998 encname = "application/x-xz"; break; 999 default: 1000 encname = "application/octet-stream"; break; 1001 } 1002 r = xmlwrite_string_attr(a, writer, "encoding", NULL, 1003 "style", encname); 1004 if (r < 0) 1005 return (ARCHIVE_FATAL); 1006 r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum)); 1007 if (r < 0) 1008 return (ARCHIVE_FATAL); 1009 r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum)); 1010 if (r < 0) 1011 return (ARCHIVE_FATAL); 1012 return (ARCHIVE_OK); 1013 } 1014 1015 /* 1016 * xar utility records fflags as following xml elements: 1017 * <flags> 1018 * <UserNoDump/> 1019 * ..... 1020 * </flags> 1021 * or 1022 * <ext2> 1023 * <NoDump/> 1024 * ..... 1025 * </ext2> 1026 * If xar is running on BSD platform, records <flags>..</flags>; 1027 * if xar is running on linux platform, records <ext2>..</ext2>; 1028 * otherwise does not record. 1029 * 1030 * Our implements records both <flags> and <ext2> if it's necessary. 1031 */ 1032 static int 1033 make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer, 1034 const char *element, const char *fflags_text) 1035 { 1036 static const struct flagentry { 1037 const char *name; 1038 const char *xarname; 1039 } 1040 flagbsd[] = { 1041 { "sappnd", "SystemAppend"}, 1042 { "sappend", "SystemAppend"}, 1043 { "arch", "SystemArchived"}, 1044 { "archived", "SystemArchived"}, 1045 { "schg", "SystemImmutable"}, 1046 { "schange", "SystemImmutable"}, 1047 { "simmutable", "SystemImmutable"}, 1048 { "nosunlnk", "SystemNoUnlink"}, 1049 { "nosunlink", "SystemNoUnlink"}, 1050 { "snapshot", "SystemSnapshot"}, 1051 { "uappnd", "UserAppend"}, 1052 { "uappend", "UserAppend"}, 1053 { "uchg", "UserImmutable"}, 1054 { "uchange", "UserImmutable"}, 1055 { "uimmutable", "UserImmutable"}, 1056 { "nodump", "UserNoDump"}, 1057 { "noopaque", "UserOpaque"}, 1058 { "nouunlnk", "UserNoUnlink"}, 1059 { "nouunlink", "UserNoUnlink"}, 1060 { NULL, NULL} 1061 }, 1062 flagext2[] = { 1063 { "sappnd", "AppendOnly"}, 1064 { "sappend", "AppendOnly"}, 1065 { "schg", "Immutable"}, 1066 { "schange", "Immutable"}, 1067 { "simmutable", "Immutable"}, 1068 { "nodump", "NoDump"}, 1069 { "nouunlnk", "Undelete"}, 1070 { "nouunlink", "Undelete"}, 1071 { "btree", "BTree"}, 1072 { "comperr", "CompError"}, 1073 { "compress", "Compress"}, 1074 { "noatime", "NoAtime"}, 1075 { "compdirty", "CompDirty"}, 1076 { "comprblk", "CompBlock"}, 1077 { "dirsync", "DirSync"}, 1078 { "hashidx", "HashIndexed"}, 1079 { "imagic", "iMagic"}, 1080 { "journal", "Journaled"}, 1081 { "securedeletion", "SecureDeletion"}, 1082 { "sync", "Synchronous"}, 1083 { "notail", "NoTail"}, 1084 { "topdir", "TopDir"}, 1085 { "reserved", "Reserved"}, 1086 { NULL, NULL} 1087 }; 1088 const struct flagentry *fe, *flagentry; 1089 #define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd)) 1090 const struct flagentry *avail[FLAGENTRY_MAXSIZE]; 1091 const char *p; 1092 int i, n, r; 1093 1094 if (strcmp(element, "ext2") == 0) 1095 flagentry = flagext2; 1096 else 1097 flagentry = flagbsd; 1098 n = 0; 1099 p = fflags_text; 1100 do { 1101 const char *cp; 1102 1103 cp = strchr(p, ','); 1104 if (cp == NULL) 1105 cp = p + strlen(p); 1106 1107 for (fe = flagentry; fe->name != NULL; fe++) { 1108 if (fe->name[cp - p] != '\0' 1109 || p[0] != fe->name[0]) 1110 continue; 1111 if (strncmp(p, fe->name, cp - p) == 0) { 1112 avail[n++] = fe; 1113 break; 1114 } 1115 } 1116 if (*cp == ',') 1117 p = cp + 1; 1118 else 1119 p = NULL; 1120 } while (p != NULL); 1121 1122 if (n > 0) { 1123 r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element)); 1124 if (r < 0) { 1125 archive_set_error(&a->archive, 1126 ARCHIVE_ERRNO_MISC, 1127 "xmlTextWriterStartElement() failed: %d", r); 1128 return (ARCHIVE_FATAL); 1129 } 1130 for (i = 0; i < n; i++) { 1131 r = xmlwrite_string(a, writer, 1132 avail[i]->xarname, NULL); 1133 if (r != ARCHIVE_OK) 1134 return (r); 1135 } 1136 1137 r = xmlTextWriterEndElement(writer); 1138 if (r < 0) { 1139 archive_set_error(&a->archive, 1140 ARCHIVE_ERRNO_MISC, 1141 "xmlTextWriterEndElement() failed: %d", r); 1142 return (ARCHIVE_FATAL); 1143 } 1144 } 1145 return (ARCHIVE_OK); 1146 } 1147 1148 static int 1149 make_file_entry(struct archive_write *a, xmlTextWriterPtr writer, 1150 struct file *file) 1151 { 1152 struct xar *xar; 1153 const char *filetype, *filelink, *fflags; 1154 struct archive_string linkto; 1155 struct heap_data *heap; 1156 unsigned char *tmp; 1157 const char *p; 1158 size_t len; 1159 int r, r2, l, ll; 1160 1161 xar = (struct xar *)a->format_data; 1162 r2 = ARCHIVE_OK; 1163 1164 /* 1165 * Make a file name entry, "<name>". 1166 */ 1167 l = ll = archive_strlen(&(file->basename)); 1168 tmp = malloc(l); 1169 if (tmp == NULL) { 1170 archive_set_error(&a->archive, ENOMEM, 1171 "Can't allocate memory"); 1172 return (ARCHIVE_FATAL); 1173 } 1174 r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll); 1175 free(tmp); 1176 if (r < 0) { 1177 r = xmlTextWriterStartElement(writer, BAD_CAST("name")); 1178 if (r < 0) { 1179 archive_set_error(&a->archive, 1180 ARCHIVE_ERRNO_MISC, 1181 "xmlTextWriterStartElement() failed: %d", r); 1182 return (ARCHIVE_FATAL); 1183 } 1184 r = xmlTextWriterWriteAttribute(writer, 1185 BAD_CAST("enctype"), BAD_CAST("base64")); 1186 if (r < 0) { 1187 archive_set_error(&a->archive, 1188 ARCHIVE_ERRNO_MISC, 1189 "xmlTextWriterWriteAttribute() failed: %d", r); 1190 return (ARCHIVE_FATAL); 1191 } 1192 r = xmlTextWriterWriteBase64(writer, file->basename.s, 1193 0, archive_strlen(&(file->basename))); 1194 if (r < 0) { 1195 archive_set_error(&a->archive, 1196 ARCHIVE_ERRNO_MISC, 1197 "xmlTextWriterWriteBase64() failed: %d", r); 1198 return (ARCHIVE_FATAL); 1199 } 1200 r = xmlTextWriterEndElement(writer); 1201 if (r < 0) { 1202 archive_set_error(&a->archive, 1203 ARCHIVE_ERRNO_MISC, 1204 "xmlTextWriterEndElement() failed: %d", r); 1205 return (ARCHIVE_FATAL); 1206 } 1207 } else { 1208 r = xmlwrite_string(a, writer, "name", file->basename.s); 1209 if (r < 0) 1210 return (ARCHIVE_FATAL); 1211 } 1212 1213 /* 1214 * Make a file type entry, "<type>". 1215 */ 1216 filelink = NULL; 1217 archive_string_init(&linkto); 1218 switch (archive_entry_filetype(file->entry)) { 1219 case AE_IFDIR: 1220 filetype = "directory"; break; 1221 case AE_IFLNK: 1222 filetype = "symlink"; break; 1223 case AE_IFCHR: 1224 filetype = "character special"; break; 1225 case AE_IFBLK: 1226 filetype = "block special"; break; 1227 case AE_IFSOCK: 1228 filetype = "socket"; break; 1229 case AE_IFIFO: 1230 filetype = "fifo"; break; 1231 case AE_IFREG: 1232 default: 1233 if (file->hardlink_target != NULL) { 1234 filetype = "hardlink"; 1235 filelink = "link"; 1236 if (file->hardlink_target == file) 1237 archive_strcpy(&linkto, "original"); 1238 else 1239 archive_string_sprintf(&linkto, "%d", 1240 file->hardlink_target->id); 1241 } else 1242 filetype = "file"; 1243 break; 1244 } 1245 r = xmlwrite_string_attr(a, writer, "type", filetype, 1246 filelink, linkto.s); 1247 archive_string_free(&linkto); 1248 if (r < 0) 1249 return (ARCHIVE_FATAL); 1250 1251 /* 1252 * On a virtual directory, we record "name" and "type" only. 1253 */ 1254 if (file->virtual) 1255 return (ARCHIVE_OK); 1256 1257 switch (archive_entry_filetype(file->entry)) { 1258 case AE_IFLNK: 1259 /* 1260 * xar utility has checked a file type, which 1261 * a symbolic-link file has referenced. 1262 * For example: 1263 * <link type="directory">../ref/</link> 1264 * The symlink target file is "../ref/" and its 1265 * file type is a directory. 1266 * 1267 * <link type="file">../f</link> 1268 * The symlink target file is "../f" and its 1269 * file type is a regular file. 1270 * 1271 * But our implementation cannot do it, and then we 1272 * always record that a attribute "type" is "broken", 1273 * for example: 1274 * <link type="broken">foo/bar</link> 1275 * It means "foo/bar" is not reachable. 1276 */ 1277 r = xmlwrite_string_attr(a, writer, "link", 1278 file->symlink.s, 1279 "type", "broken"); 1280 if (r < 0) 1281 return (ARCHIVE_FATAL); 1282 break; 1283 case AE_IFCHR: 1284 case AE_IFBLK: 1285 r = xmlTextWriterStartElement(writer, BAD_CAST("device")); 1286 if (r < 0) { 1287 archive_set_error(&a->archive, 1288 ARCHIVE_ERRNO_MISC, 1289 "xmlTextWriterStartElement() failed: %d", r); 1290 return (ARCHIVE_FATAL); 1291 } 1292 r = xmlwrite_fstring(a, writer, "major", 1293 "%d", archive_entry_rdevmajor(file->entry)); 1294 if (r < 0) 1295 return (ARCHIVE_FATAL); 1296 r = xmlwrite_fstring(a, writer, "minor", 1297 "%d", archive_entry_rdevminor(file->entry)); 1298 if (r < 0) 1299 return (ARCHIVE_FATAL); 1300 r = xmlTextWriterEndElement(writer); 1301 if (r < 0) { 1302 archive_set_error(&a->archive, 1303 ARCHIVE_ERRNO_MISC, 1304 "xmlTextWriterEndElement() failed: %d", r); 1305 return (ARCHIVE_FATAL); 1306 } 1307 break; 1308 default: 1309 break; 1310 } 1311 1312 /* 1313 * Make a inode entry, "<inode>". 1314 */ 1315 r = xmlwrite_fstring(a, writer, "inode", 1316 "%jd", archive_entry_ino64(file->entry)); 1317 if (r < 0) 1318 return (ARCHIVE_FATAL); 1319 if (archive_entry_dev(file->entry) != 0) { 1320 r = xmlwrite_fstring(a, writer, "deviceno", 1321 "%d", archive_entry_dev(file->entry)); 1322 if (r < 0) 1323 return (ARCHIVE_FATAL); 1324 } 1325 1326 /* 1327 * Make a file mode entry, "<mode>". 1328 */ 1329 r = xmlwrite_mode(a, writer, "mode", 1330 archive_entry_mode(file->entry)); 1331 if (r < 0) 1332 return (ARCHIVE_FATAL); 1333 1334 /* 1335 * Make a user entry, "<uid>" and "<user>. 1336 */ 1337 r = xmlwrite_fstring(a, writer, "uid", 1338 "%d", archive_entry_uid(file->entry)); 1339 if (r < 0) 1340 return (ARCHIVE_FATAL); 1341 r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv); 1342 if (r != 0) { 1343 if (errno == ENOMEM) { 1344 archive_set_error(&a->archive, ENOMEM, 1345 "Can't allocate memory for Uname"); 1346 return (ARCHIVE_FATAL); 1347 } 1348 archive_set_error(&a->archive, 1349 ARCHIVE_ERRNO_FILE_FORMAT, 1350 "Can't translate uname '%s' to UTF-8", 1351 archive_entry_uname(file->entry)); 1352 r2 = ARCHIVE_WARN; 1353 } 1354 if (len > 0) { 1355 r = xmlwrite_string(a, writer, "user", p); 1356 if (r < 0) 1357 return (ARCHIVE_FATAL); 1358 } 1359 1360 /* 1361 * Make a group entry, "<gid>" and "<group>. 1362 */ 1363 r = xmlwrite_fstring(a, writer, "gid", 1364 "%d", archive_entry_gid(file->entry)); 1365 if (r < 0) 1366 return (ARCHIVE_FATAL); 1367 r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv); 1368 if (r != 0) { 1369 if (errno == ENOMEM) { 1370 archive_set_error(&a->archive, ENOMEM, 1371 "Can't allocate memory for Gname"); 1372 return (ARCHIVE_FATAL); 1373 } 1374 archive_set_error(&a->archive, 1375 ARCHIVE_ERRNO_FILE_FORMAT, 1376 "Can't translate gname '%s' to UTF-8", 1377 archive_entry_gname(file->entry)); 1378 r2 = ARCHIVE_WARN; 1379 } 1380 if (len > 0) { 1381 r = xmlwrite_string(a, writer, "group", p); 1382 if (r < 0) 1383 return (ARCHIVE_FATAL); 1384 } 1385 1386 /* 1387 * Make a ctime entry, "<ctime>". 1388 */ 1389 if (archive_entry_ctime_is_set(file->entry)) { 1390 r = xmlwrite_time(a, writer, "ctime", 1391 archive_entry_ctime(file->entry), 1); 1392 if (r < 0) 1393 return (ARCHIVE_FATAL); 1394 } 1395 1396 /* 1397 * Make a mtime entry, "<mtime>". 1398 */ 1399 if (archive_entry_mtime_is_set(file->entry)) { 1400 r = xmlwrite_time(a, writer, "mtime", 1401 archive_entry_mtime(file->entry), 1); 1402 if (r < 0) 1403 return (ARCHIVE_FATAL); 1404 } 1405 1406 /* 1407 * Make a atime entry, "<atime>". 1408 */ 1409 if (archive_entry_atime_is_set(file->entry)) { 1410 r = xmlwrite_time(a, writer, "atime", 1411 archive_entry_atime(file->entry), 1); 1412 if (r < 0) 1413 return (ARCHIVE_FATAL); 1414 } 1415 1416 /* 1417 * Make fflags entries, "<flags>" and "<ext2>". 1418 */ 1419 fflags = archive_entry_fflags_text(file->entry); 1420 if (fflags != NULL) { 1421 r = make_fflags_entry(a, writer, "flags", fflags); 1422 if (r < 0) 1423 return (r); 1424 r = make_fflags_entry(a, writer, "ext2", fflags); 1425 if (r < 0) 1426 return (r); 1427 } 1428 1429 /* 1430 * Make extended attribute entries, "<ea>". 1431 */ 1432 archive_entry_xattr_reset(file->entry); 1433 for (heap = file->xattr.first; heap != NULL; heap = heap->next) { 1434 const char *name; 1435 const void *value; 1436 size_t size; 1437 1438 archive_entry_xattr_next(file->entry, 1439 &name, &value, &size); 1440 r = xmlTextWriterStartElement(writer, BAD_CAST("ea")); 1441 if (r < 0) { 1442 archive_set_error(&a->archive, 1443 ARCHIVE_ERRNO_MISC, 1444 "xmlTextWriterStartElement() failed: %d", r); 1445 return (ARCHIVE_FATAL); 1446 } 1447 r = xmlTextWriterWriteFormatAttribute(writer, 1448 BAD_CAST("id"), "%d", heap->id); 1449 if (r < 0) { 1450 archive_set_error(&a->archive, 1451 ARCHIVE_ERRNO_MISC, 1452 "xmlTextWriterWriteAttribute() failed: %d", r); 1453 return (ARCHIVE_FATAL); 1454 } 1455 r = xmlwrite_heap(a, writer, heap); 1456 if (r < 0) 1457 return (ARCHIVE_FATAL); 1458 r = xmlwrite_string(a, writer, "name", name); 1459 if (r < 0) 1460 return (ARCHIVE_FATAL); 1461 1462 r = xmlTextWriterEndElement(writer); 1463 if (r < 0) { 1464 archive_set_error(&a->archive, 1465 ARCHIVE_ERRNO_MISC, 1466 "xmlTextWriterEndElement() failed: %d", r); 1467 return (ARCHIVE_FATAL); 1468 } 1469 } 1470 1471 /* 1472 * Make a file data entry, "<data>". 1473 */ 1474 if (file->data.length > 0) { 1475 r = xmlTextWriterStartElement(writer, BAD_CAST("data")); 1476 if (r < 0) { 1477 archive_set_error(&a->archive, 1478 ARCHIVE_ERRNO_MISC, 1479 "xmlTextWriterStartElement() failed: %d", r); 1480 return (ARCHIVE_FATAL); 1481 } 1482 1483 r = xmlwrite_heap(a, writer, &(file->data)); 1484 if (r < 0) 1485 return (ARCHIVE_FATAL); 1486 1487 r = xmlTextWriterEndElement(writer); 1488 if (r < 0) { 1489 archive_set_error(&a->archive, 1490 ARCHIVE_ERRNO_MISC, 1491 "xmlTextWriterEndElement() failed: %d", r); 1492 return (ARCHIVE_FATAL); 1493 } 1494 } 1495 1496 if (archive_strlen(&file->script) > 0) { 1497 r = xmlTextWriterStartElement(writer, BAD_CAST("content")); 1498 if (r < 0) { 1499 archive_set_error(&a->archive, 1500 ARCHIVE_ERRNO_MISC, 1501 "xmlTextWriterStartElement() failed: %d", r); 1502 return (ARCHIVE_FATAL); 1503 } 1504 1505 r = xmlwrite_string(a, writer, 1506 "interpreter", file->script.s); 1507 if (r < 0) 1508 return (ARCHIVE_FATAL); 1509 1510 r = xmlwrite_string(a, writer, "type", "script"); 1511 if (r < 0) 1512 return (ARCHIVE_FATAL); 1513 1514 r = xmlTextWriterEndElement(writer); 1515 if (r < 0) { 1516 archive_set_error(&a->archive, 1517 ARCHIVE_ERRNO_MISC, 1518 "xmlTextWriterEndElement() failed: %d", r); 1519 return (ARCHIVE_FATAL); 1520 } 1521 } 1522 1523 return (r2); 1524 } 1525 1526 /* 1527 * Make the TOC 1528 */ 1529 static int 1530 make_toc(struct archive_write *a) 1531 { 1532 struct xar *xar; 1533 struct file *np; 1534 xmlBufferPtr bp; 1535 xmlTextWriterPtr writer; 1536 int algsize; 1537 int r, ret; 1538 1539 xar = (struct xar *)a->format_data; 1540 1541 ret = ARCHIVE_FATAL; 1542 1543 /* 1544 * Initialize xml writer. 1545 */ 1546 writer = NULL; 1547 bp = xmlBufferCreate(); 1548 if (bp == NULL) { 1549 archive_set_error(&a->archive, ENOMEM, 1550 "xmlBufferCreate() " 1551 "couldn't create xml buffer"); 1552 goto exit_toc; 1553 } 1554 writer = xmlNewTextWriterMemory(bp, 0); 1555 if (writer == NULL) { 1556 archive_set_error(&a->archive, 1557 ARCHIVE_ERRNO_MISC, 1558 "xmlNewTextWriterMemory() " 1559 "couldn't create xml writer"); 1560 goto exit_toc; 1561 } 1562 r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); 1563 if (r < 0) { 1564 archive_set_error(&a->archive, 1565 ARCHIVE_ERRNO_MISC, 1566 "xmlTextWriterStartDocument() failed: %d", r); 1567 goto exit_toc; 1568 } 1569 r = xmlTextWriterSetIndent(writer, 4); 1570 if (r < 0) { 1571 archive_set_error(&a->archive, 1572 ARCHIVE_ERRNO_MISC, 1573 "xmlTextWriterSetIndent() failed: %d", r); 1574 goto exit_toc; 1575 } 1576 1577 /* 1578 * Start recording TOC 1579 */ 1580 r = xmlTextWriterStartElement(writer, BAD_CAST("xar")); 1581 if (r < 0) { 1582 archive_set_error(&a->archive, 1583 ARCHIVE_ERRNO_MISC, 1584 "xmlTextWriterStartElement() failed: %d", r); 1585 goto exit_toc; 1586 } 1587 r = xmlTextWriterStartElement(writer, BAD_CAST("toc")); 1588 if (r < 0) { 1589 archive_set_error(&a->archive, 1590 ARCHIVE_ERRNO_MISC, 1591 "xmlTextWriterStartDocument() failed: %d", r); 1592 goto exit_toc; 1593 } 1594 1595 /* 1596 * Record the creation time of the archive file. 1597 */ 1598 r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0); 1599 if (r < 0) 1600 goto exit_toc; 1601 1602 /* 1603 * Record the checksum value of TOC 1604 */ 1605 algsize = getalgsize(xar->opt_toc_sumalg); 1606 if (algsize) { 1607 /* 1608 * Record TOC checksum 1609 */ 1610 r = xmlTextWriterStartElement(writer, BAD_CAST("checksum")); 1611 if (r < 0) { 1612 archive_set_error(&a->archive, 1613 ARCHIVE_ERRNO_MISC, 1614 "xmlTextWriterStartElement() failed: %d", r); 1615 goto exit_toc; 1616 } 1617 r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"), 1618 BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg))); 1619 if (r < 0) { 1620 archive_set_error(&a->archive, 1621 ARCHIVE_ERRNO_MISC, 1622 "xmlTextWriterWriteAttribute() failed: %d", r); 1623 goto exit_toc; 1624 } 1625 1626 /* 1627 * Record the offset of the value of checksum of TOC 1628 */ 1629 r = xmlwrite_string(a, writer, "offset", "0"); 1630 if (r < 0) 1631 goto exit_toc; 1632 1633 /* 1634 * Record the size of the value of checksum of TOC 1635 */ 1636 r = xmlwrite_fstring(a, writer, "size", "%d", algsize); 1637 if (r < 0) 1638 goto exit_toc; 1639 1640 r = xmlTextWriterEndElement(writer); 1641 if (r < 0) { 1642 archive_set_error(&a->archive, 1643 ARCHIVE_ERRNO_MISC, 1644 "xmlTextWriterEndElement() failed: %d", r); 1645 goto exit_toc; 1646 } 1647 } 1648 1649 np = xar->root; 1650 do { 1651 if (np != np->parent) { 1652 r = make_file_entry(a, writer, np); 1653 if (r != ARCHIVE_OK) 1654 goto exit_toc; 1655 } 1656 1657 if (np->dir && np->children.first != NULL) { 1658 /* Enter to sub directories. */ 1659 np = np->children.first; 1660 r = xmlTextWriterStartElement(writer, 1661 BAD_CAST("file")); 1662 if (r < 0) { 1663 archive_set_error(&a->archive, 1664 ARCHIVE_ERRNO_MISC, 1665 "xmlTextWriterStartElement() " 1666 "failed: %d", r); 1667 goto exit_toc; 1668 } 1669 r = xmlTextWriterWriteFormatAttribute( 1670 writer, BAD_CAST("id"), "%d", np->id); 1671 if (r < 0) { 1672 archive_set_error(&a->archive, 1673 ARCHIVE_ERRNO_MISC, 1674 "xmlTextWriterWriteAttribute() " 1675 "failed: %d", r); 1676 goto exit_toc; 1677 } 1678 continue; 1679 } 1680 while (np != np->parent) { 1681 r = xmlTextWriterEndElement(writer); 1682 if (r < 0) { 1683 archive_set_error(&a->archive, 1684 ARCHIVE_ERRNO_MISC, 1685 "xmlTextWriterEndElement() " 1686 "failed: %d", r); 1687 goto exit_toc; 1688 } 1689 if (np->chnext == NULL) { 1690 /* Return to the parent directory. */ 1691 np = np->parent; 1692 } else { 1693 np = np->chnext; 1694 r = xmlTextWriterStartElement(writer, 1695 BAD_CAST("file")); 1696 if (r < 0) { 1697 archive_set_error(&a->archive, 1698 ARCHIVE_ERRNO_MISC, 1699 "xmlTextWriterStartElement() " 1700 "failed: %d", r); 1701 goto exit_toc; 1702 } 1703 r = xmlTextWriterWriteFormatAttribute( 1704 writer, BAD_CAST("id"), "%d", np->id); 1705 if (r < 0) { 1706 archive_set_error(&a->archive, 1707 ARCHIVE_ERRNO_MISC, 1708 "xmlTextWriterWriteAttribute() " 1709 "failed: %d", r); 1710 goto exit_toc; 1711 } 1712 break; 1713 } 1714 } 1715 } while (np != np->parent); 1716 1717 r = xmlTextWriterEndDocument(writer); 1718 if (r < 0) { 1719 archive_set_error(&a->archive, 1720 ARCHIVE_ERRNO_MISC, 1721 "xmlTextWriterEndDocument() failed: %d", r); 1722 goto exit_toc; 1723 } 1724 #if DEBUG_PRINT_TOC 1725 fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n", 1726 strlen((const char *)bp->content), bp->content); 1727 #endif 1728 1729 /* 1730 * Compress the TOC and calculate the sum of the TOC. 1731 */ 1732 xar->toc.temp_offset = xar->temp_offset; 1733 xar->toc.size = bp->use; 1734 checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg); 1735 1736 r = compression_init_encoder_gzip(&(a->archive), 1737 &(xar->stream), 6, 1); 1738 if (r != ARCHIVE_OK) 1739 goto exit_toc; 1740 xar->stream.next_in = bp->content; 1741 xar->stream.avail_in = bp->use; 1742 xar->stream.total_in = 0; 1743 xar->stream.next_out = xar->wbuff; 1744 xar->stream.avail_out = sizeof(xar->wbuff); 1745 xar->stream.total_out = 0; 1746 for (;;) { 1747 size_t size; 1748 1749 r = compression_code(&(a->archive), 1750 &(xar->stream), ARCHIVE_Z_FINISH); 1751 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) 1752 goto exit_toc; 1753 size = sizeof(xar->wbuff) - xar->stream.avail_out; 1754 checksum_update(&(xar->a_sumwrk), xar->wbuff, size); 1755 if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK) 1756 goto exit_toc; 1757 if (r == ARCHIVE_EOF) 1758 break; 1759 xar->stream.next_out = xar->wbuff; 1760 xar->stream.avail_out = sizeof(xar->wbuff); 1761 } 1762 r = compression_end(&(a->archive), &(xar->stream)); 1763 if (r != ARCHIVE_OK) 1764 goto exit_toc; 1765 xar->toc.length = xar->stream.total_out; 1766 xar->toc.compression = GZIP; 1767 checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum)); 1768 1769 ret = ARCHIVE_OK; 1770 exit_toc: 1771 if (writer) 1772 xmlFreeTextWriter(writer); 1773 if (bp) 1774 xmlBufferFree(bp); 1775 1776 return (ret); 1777 } 1778 1779 static int 1780 flush_wbuff(struct archive_write *a) 1781 { 1782 struct xar *xar; 1783 int r; 1784 size_t s; 1785 1786 xar = (struct xar *)a->format_data; 1787 s = sizeof(xar->wbuff) - xar->wbuff_remaining; 1788 r = __archive_write_output(a, xar->wbuff, s); 1789 if (r != ARCHIVE_OK) 1790 return (r); 1791 xar->wbuff_remaining = sizeof(xar->wbuff); 1792 return (r); 1793 } 1794 1795 static int 1796 copy_out(struct archive_write *a, uint64_t offset, uint64_t length) 1797 { 1798 struct xar *xar; 1799 int r; 1800 1801 xar = (struct xar *)a->format_data; 1802 if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) { 1803 archive_set_error(&(a->archive), errno, "lseek failed"); 1804 return (ARCHIVE_FATAL); 1805 } 1806 while (length) { 1807 size_t rsize; 1808 ssize_t rs; 1809 unsigned char *wb; 1810 1811 if (length > xar->wbuff_remaining) 1812 rsize = xar->wbuff_remaining; 1813 else 1814 rsize = (size_t)length; 1815 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); 1816 rs = read(xar->temp_fd, wb, rsize); 1817 if (rs < 0) { 1818 archive_set_error(&(a->archive), errno, 1819 "Can't read temporary file(%jd)", 1820 (intmax_t)rs); 1821 return (ARCHIVE_FATAL); 1822 } 1823 if (rs == 0) { 1824 archive_set_error(&(a->archive), 0, 1825 "Truncated xar archive"); 1826 return (ARCHIVE_FATAL); 1827 } 1828 xar->wbuff_remaining -= rs; 1829 length -= rs; 1830 if (xar->wbuff_remaining == 0) { 1831 r = flush_wbuff(a); 1832 if (r != ARCHIVE_OK) 1833 return (r); 1834 } 1835 } 1836 return (ARCHIVE_OK); 1837 } 1838 1839 static int 1840 xar_close(struct archive_write *a) 1841 { 1842 struct xar *xar; 1843 unsigned char *wb; 1844 uint64_t length; 1845 int r; 1846 1847 xar = (struct xar *)a->format_data; 1848 1849 /* Empty! */ 1850 if (xar->root->children.first == NULL) 1851 return (ARCHIVE_OK); 1852 1853 /* Save the length of all file extended attributes and contents. */ 1854 length = xar->temp_offset; 1855 1856 /* Connect hardlinked files */ 1857 file_connect_hardlink_files(xar); 1858 1859 /* Make the TOC */ 1860 r = make_toc(a); 1861 if (r != ARCHIVE_OK) 1862 return (r); 1863 /* 1864 * Make the xar header on wbuff(write buffer). 1865 */ 1866 wb = xar->wbuff; 1867 xar->wbuff_remaining = sizeof(xar->wbuff); 1868 archive_be32enc(&wb[0], HEADER_MAGIC); 1869 archive_be16enc(&wb[4], HEADER_SIZE); 1870 archive_be16enc(&wb[6], HEADER_VERSION); 1871 archive_be64enc(&wb[8], xar->toc.length); 1872 archive_be64enc(&wb[16], xar->toc.size); 1873 archive_be32enc(&wb[24], xar->toc.a_sum.alg); 1874 xar->wbuff_remaining -= HEADER_SIZE; 1875 1876 /* 1877 * Write the TOC 1878 */ 1879 r = copy_out(a, xar->toc.temp_offset, xar->toc.length); 1880 if (r != ARCHIVE_OK) 1881 return (r); 1882 1883 /* Write the checksum value of the TOC. */ 1884 if (xar->toc.a_sum.len) { 1885 if (xar->wbuff_remaining < xar->toc.a_sum.len) { 1886 r = flush_wbuff(a); 1887 if (r != ARCHIVE_OK) 1888 return (r); 1889 } 1890 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining); 1891 memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len); 1892 xar->wbuff_remaining -= xar->toc.a_sum.len; 1893 } 1894 1895 /* 1896 * Write all file extended attributes and contents. 1897 */ 1898 r = copy_out(a, xar->toc.a_sum.len, length); 1899 if (r != ARCHIVE_OK) 1900 return (r); 1901 r = flush_wbuff(a); 1902 return (r); 1903 } 1904 1905 static int 1906 xar_free(struct archive_write *a) 1907 { 1908 struct xar *xar; 1909 1910 xar = (struct xar *)a->format_data; 1911 1912 /* Close the temporary file. */ 1913 if (xar->temp_fd >= 0) 1914 close(xar->temp_fd); 1915 1916 archive_string_free(&(xar->cur_dirstr)); 1917 archive_string_free(&(xar->tstr)); 1918 archive_string_free(&(xar->vstr)); 1919 file_free_hardlinks(xar); 1920 file_free_register(xar); 1921 compression_end(&(a->archive), &(xar->stream)); 1922 free(xar); 1923 1924 return (ARCHIVE_OK); 1925 } 1926 1927 static int 1928 file_cmp_node(const struct archive_rb_node *n1, 1929 const struct archive_rb_node *n2) 1930 { 1931 const struct file *f1 = (const struct file *)n1; 1932 const struct file *f2 = (const struct file *)n2; 1933 1934 return (strcmp(f1->basename.s, f2->basename.s)); 1935 } 1936 1937 static int 1938 file_cmp_key(const struct archive_rb_node *n, const void *key) 1939 { 1940 const struct file *f = (const struct file *)n; 1941 1942 return (strcmp(f->basename.s, (const char *)key)); 1943 } 1944 1945 static struct file * 1946 file_new(struct archive_write *a, struct archive_entry *entry) 1947 { 1948 struct file *file; 1949 static const struct archive_rb_tree_ops rb_ops = { 1950 file_cmp_node, file_cmp_key 1951 }; 1952 1953 file = calloc(1, sizeof(*file)); 1954 if (file == NULL) 1955 return (NULL); 1956 1957 if (entry != NULL) 1958 file->entry = archive_entry_clone(entry); 1959 else 1960 file->entry = archive_entry_new2(&a->archive); 1961 if (file->entry == NULL) { 1962 free(file); 1963 return (NULL); 1964 } 1965 __archive_rb_tree_init(&(file->rbtree), &rb_ops); 1966 file->children.first = NULL; 1967 file->children.last = &(file->children.first); 1968 file->xattr.first = NULL; 1969 file->xattr.last = &(file->xattr.first); 1970 archive_string_init(&(file->parentdir)); 1971 archive_string_init(&(file->basename)); 1972 archive_string_init(&(file->symlink)); 1973 archive_string_init(&(file->script)); 1974 if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR) 1975 file->dir = 1; 1976 1977 return (file); 1978 } 1979 1980 static void 1981 file_free(struct file *file) 1982 { 1983 struct heap_data *heap, *next_heap; 1984 1985 heap = file->xattr.first; 1986 while (heap != NULL) { 1987 next_heap = heap->next; 1988 free(heap); 1989 heap = next_heap; 1990 } 1991 archive_string_free(&(file->parentdir)); 1992 archive_string_free(&(file->basename)); 1993 archive_string_free(&(file->symlink)); 1994 archive_string_free(&(file->script)); 1995 archive_entry_free(file->entry); 1996 free(file); 1997 } 1998 1999 static struct file * 2000 file_create_virtual_dir(struct archive_write *a, struct xar *xar, 2001 const char *pathname) 2002 { 2003 struct file *file; 2004 2005 (void)xar; /* UNUSED */ 2006 2007 file = file_new(a, NULL); 2008 if (file == NULL) 2009 return (NULL); 2010 archive_entry_set_pathname(file->entry, pathname); 2011 archive_entry_set_mode(file->entry, 0555 | AE_IFDIR); 2012 2013 file->dir = 1; 2014 file->virtual = 1; 2015 2016 return (file); 2017 } 2018 2019 static int 2020 file_add_child_tail(struct file *parent, struct file *child) 2021 { 2022 if (!__archive_rb_tree_insert_node( 2023 &(parent->rbtree), (struct archive_rb_node *)child)) 2024 return (0); 2025 child->chnext = NULL; 2026 *parent->children.last = child; 2027 parent->children.last = &(child->chnext); 2028 child->parent = parent; 2029 return (1); 2030 } 2031 2032 /* 2033 * Find a entry from `parent' 2034 */ 2035 static struct file * 2036 file_find_child(struct file *parent, const char *child_name) 2037 { 2038 struct file *np; 2039 2040 np = (struct file *)__archive_rb_tree_find_node( 2041 &(parent->rbtree), child_name); 2042 return (np); 2043 } 2044 2045 #if defined(_WIN32) || defined(__CYGWIN__) 2046 static void 2047 cleanup_backslash(char *utf8, size_t len) 2048 { 2049 2050 /* Convert a path-separator from '\' to '/' */ 2051 while (*utf8 != '\0' && len) { 2052 if (*utf8 == '\\') 2053 *utf8 = '/'; 2054 ++utf8; 2055 --len; 2056 } 2057 } 2058 #else 2059 #define cleanup_backslash(p, len) /* nop */ 2060 #endif 2061 2062 /* 2063 * Generate a parent directory name and a base name from a pathname. 2064 */ 2065 static int 2066 file_gen_utility_names(struct archive_write *a, struct file *file) 2067 { 2068 struct xar *xar; 2069 const char *pp; 2070 char *p, *dirname, *slash; 2071 size_t len; 2072 int r = ARCHIVE_OK; 2073 2074 xar = (struct xar *)a->format_data; 2075 archive_string_empty(&(file->parentdir)); 2076 archive_string_empty(&(file->basename)); 2077 archive_string_empty(&(file->symlink)); 2078 2079 if (file->parent == file)/* virtual root */ 2080 return (ARCHIVE_OK); 2081 2082 if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv) 2083 != 0) { 2084 if (errno == ENOMEM) { 2085 archive_set_error(&a->archive, ENOMEM, 2086 "Can't allocate memory for Pathname"); 2087 return (ARCHIVE_FATAL); 2088 } 2089 archive_set_error(&a->archive, 2090 ARCHIVE_ERRNO_FILE_FORMAT, 2091 "Can't translate pathname '%s' to UTF-8", 2092 archive_entry_pathname(file->entry)); 2093 r = ARCHIVE_WARN; 2094 } 2095 archive_strncpy(&(file->parentdir), pp, len); 2096 len = file->parentdir.length; 2097 p = dirname = file->parentdir.s; 2098 /* 2099 * Convert a path-separator from '\' to '/' 2100 */ 2101 cleanup_backslash(p, len); 2102 2103 /* 2104 * Remove leading '/', '../' and './' elements 2105 */ 2106 while (*p) { 2107 if (p[0] == '/') { 2108 p++; 2109 len--; 2110 } else if (p[0] != '.') 2111 break; 2112 else if (p[1] == '.' && p[2] == '/') { 2113 p += 3; 2114 len -= 3; 2115 } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) { 2116 p += 2; 2117 len -= 2; 2118 } else if (p[1] == '\0') { 2119 p++; 2120 len--; 2121 } else 2122 break; 2123 } 2124 if (p != dirname) { 2125 memmove(dirname, p, len+1); 2126 p = dirname; 2127 } 2128 /* 2129 * Remove "/","/." and "/.." elements from tail. 2130 */ 2131 while (len > 0) { 2132 size_t ll = len; 2133 2134 if (p[len-1] == '/') { 2135 p[len-1] = '\0'; 2136 len--; 2137 } 2138 if (len > 1 && p[len-2] == '/' && p[len-1] == '.') { 2139 p[len-2] = '\0'; 2140 len -= 2; 2141 } 2142 if (len > 2 && p[len-3] == '/' && p[len-2] == '.' && 2143 p[len-1] == '.') { 2144 p[len-3] = '\0'; 2145 len -= 3; 2146 } 2147 if (ll == len) 2148 break; 2149 } 2150 while (*p) { 2151 if (p[0] == '/') { 2152 if (p[1] == '/') 2153 /* Convert '//' --> '/' */ 2154 memmove(p, p+1, strlen(p+1) + 1); 2155 else if (p[1] == '.' && p[2] == '/') 2156 /* Convert '/./' --> '/' */ 2157 memmove(p, p+2, strlen(p+2) + 1); 2158 else if (p[1] == '.' && p[2] == '.' && p[3] == '/') { 2159 /* Convert 'dir/dir1/../dir2/' 2160 * --> 'dir/dir2/' 2161 */ 2162 char *rp = p -1; 2163 while (rp >= dirname) { 2164 if (*rp == '/') 2165 break; 2166 --rp; 2167 } 2168 if (rp > dirname) { 2169 strcpy(rp, p+3); 2170 p = rp; 2171 } else { 2172 strcpy(dirname, p+4); 2173 p = dirname; 2174 } 2175 } else 2176 p++; 2177 } else 2178 p++; 2179 } 2180 p = dirname; 2181 len = strlen(p); 2182 2183 if (archive_entry_filetype(file->entry) == AE_IFLNK) { 2184 size_t len2; 2185 /* Convert symlink name too. */ 2186 if (archive_entry_symlink_l(file->entry, &pp, &len2, 2187 xar->sconv) != 0) { 2188 if (errno == ENOMEM) { 2189 archive_set_error(&a->archive, ENOMEM, 2190 "Can't allocate memory for Linkname"); 2191 return (ARCHIVE_FATAL); 2192 } 2193 archive_set_error(&a->archive, 2194 ARCHIVE_ERRNO_FILE_FORMAT, 2195 "Can't translate symlink '%s' to UTF-8", 2196 archive_entry_symlink(file->entry)); 2197 r = ARCHIVE_WARN; 2198 } 2199 archive_strncpy(&(file->symlink), pp, len2); 2200 cleanup_backslash(file->symlink.s, file->symlink.length); 2201 } 2202 /* 2203 * - Count up directory elements. 2204 * - Find out the position which points the last position of 2205 * path separator('/'). 2206 */ 2207 slash = NULL; 2208 for (; *p != '\0'; p++) 2209 if (*p == '/') 2210 slash = p; 2211 if (slash == NULL) { 2212 /* The pathname doesn't have a parent directory. */ 2213 file->parentdir.length = len; 2214 archive_string_copy(&(file->basename), &(file->parentdir)); 2215 archive_string_empty(&(file->parentdir)); 2216 *file->parentdir.s = '\0'; 2217 return (r); 2218 } 2219 2220 /* Make a basename from dirname and slash */ 2221 *slash = '\0'; 2222 file->parentdir.length = slash - dirname; 2223 archive_strcpy(&(file->basename), slash + 1); 2224 return (r); 2225 } 2226 2227 static int 2228 get_path_component(char *name, int n, const char *fn) 2229 { 2230 char *p; 2231 int l; 2232 2233 p = strchr(fn, '/'); 2234 if (p == NULL) { 2235 if ((l = strlen(fn)) == 0) 2236 return (0); 2237 } else 2238 l = p - fn; 2239 if (l > n -1) 2240 return (-1); 2241 memcpy(name, fn, l); 2242 name[l] = '\0'; 2243 2244 return (l); 2245 } 2246 2247 /* 2248 * Add a new entry into the tree. 2249 */ 2250 static int 2251 file_tree(struct archive_write *a, struct file **filepp) 2252 { 2253 #if defined(_WIN32) && !defined(__CYGWIN__) 2254 char name[_MAX_FNAME];/* Included null terminator size. */ 2255 #elif defined(NAME_MAX) && NAME_MAX >= 255 2256 char name[NAME_MAX+1]; 2257 #else 2258 char name[256]; 2259 #endif 2260 struct xar *xar = (struct xar *)a->format_data; 2261 struct file *dent, *file, *np; 2262 struct archive_entry *ent; 2263 const char *fn, *p; 2264 int l; 2265 2266 file = *filepp; 2267 dent = xar->root; 2268 if (file->parentdir.length > 0) 2269 fn = p = file->parentdir.s; 2270 else 2271 fn = p = ""; 2272 2273 /* 2274 * If the path of the parent directory of `file' entry is 2275 * the same as the path of `cur_dirent', add isoent to 2276 * `cur_dirent'. 2277 */ 2278 if (archive_strlen(&(xar->cur_dirstr)) 2279 == archive_strlen(&(file->parentdir)) && 2280 strcmp(xar->cur_dirstr.s, fn) == 0) { 2281 if (!file_add_child_tail(xar->cur_dirent, file)) { 2282 np = (struct file *)__archive_rb_tree_find_node( 2283 &(xar->cur_dirent->rbtree), 2284 file->basename.s); 2285 goto same_entry; 2286 } 2287 return (ARCHIVE_OK); 2288 } 2289 2290 for (;;) { 2291 l = get_path_component(name, sizeof(name), fn); 2292 if (l == 0) { 2293 np = NULL; 2294 break; 2295 } 2296 if (l < 0) { 2297 archive_set_error(&a->archive, 2298 ARCHIVE_ERRNO_MISC, 2299 "A name buffer is too small"); 2300 file_free(file); 2301 *filepp = NULL; 2302 return (ARCHIVE_FATAL); 2303 } 2304 2305 np = file_find_child(dent, name); 2306 if (np == NULL || fn[0] == '\0') 2307 break; 2308 2309 /* Find next subdirectory. */ 2310 if (!np->dir) { 2311 /* NOT Directory! */ 2312 archive_set_error(&a->archive, 2313 ARCHIVE_ERRNO_MISC, 2314 "`%s' is not directory, we cannot insert `%s' ", 2315 archive_entry_pathname(np->entry), 2316 archive_entry_pathname(file->entry)); 2317 file_free(file); 2318 *filepp = NULL; 2319 return (ARCHIVE_FAILED); 2320 } 2321 fn += l; 2322 if (fn[0] == '/') 2323 fn++; 2324 dent = np; 2325 } 2326 if (np == NULL) { 2327 /* 2328 * Create virtual parent directories. 2329 */ 2330 while (fn[0] != '\0') { 2331 struct file *vp; 2332 struct archive_string as; 2333 2334 archive_string_init(&as); 2335 archive_strncat(&as, p, fn - p + l); 2336 if (as.s[as.length-1] == '/') { 2337 as.s[as.length-1] = '\0'; 2338 as.length--; 2339 } 2340 vp = file_create_virtual_dir(a, xar, as.s); 2341 if (vp == NULL) { 2342 archive_string_free(&as); 2343 archive_set_error(&a->archive, ENOMEM, 2344 "Can't allocate memory"); 2345 file_free(file); 2346 *filepp = NULL; 2347 return (ARCHIVE_FATAL); 2348 } 2349 archive_string_free(&as); 2350 if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED) 2351 return (ARCHIVE_FATAL); 2352 file_add_child_tail(dent, vp); 2353 file_register(xar, vp); 2354 np = vp; 2355 2356 fn += l; 2357 if (fn[0] == '/') 2358 fn++; 2359 l = get_path_component(name, sizeof(name), fn); 2360 if (l < 0) { 2361 archive_string_free(&as); 2362 archive_set_error(&a->archive, 2363 ARCHIVE_ERRNO_MISC, 2364 "A name buffer is too small"); 2365 file_free(file); 2366 *filepp = NULL; 2367 return (ARCHIVE_FATAL); 2368 } 2369 dent = np; 2370 } 2371 2372 /* Found out the parent directory where isoent can be 2373 * inserted. */ 2374 xar->cur_dirent = dent; 2375 archive_string_empty(&(xar->cur_dirstr)); 2376 archive_string_ensure(&(xar->cur_dirstr), 2377 archive_strlen(&(dent->parentdir)) + 2378 archive_strlen(&(dent->basename)) + 2); 2379 if (archive_strlen(&(dent->parentdir)) + 2380 archive_strlen(&(dent->basename)) == 0) 2381 xar->cur_dirstr.s[0] = 0; 2382 else { 2383 if (archive_strlen(&(dent->parentdir)) > 0) { 2384 archive_string_copy(&(xar->cur_dirstr), 2385 &(dent->parentdir)); 2386 archive_strappend_char(&(xar->cur_dirstr), '/'); 2387 } 2388 archive_string_concat(&(xar->cur_dirstr), 2389 &(dent->basename)); 2390 } 2391 2392 if (!file_add_child_tail(dent, file)) { 2393 np = (struct file *)__archive_rb_tree_find_node( 2394 &(dent->rbtree), file->basename.s); 2395 goto same_entry; 2396 } 2397 return (ARCHIVE_OK); 2398 } 2399 2400 same_entry: 2401 /* 2402 * We have already has the entry the filename of which is 2403 * the same. 2404 */ 2405 if (archive_entry_filetype(np->entry) != 2406 archive_entry_filetype(file->entry)) { 2407 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 2408 "Found duplicate entries `%s' and its file type is " 2409 "different", 2410 archive_entry_pathname(np->entry)); 2411 file_free(file); 2412 *filepp = NULL; 2413 return (ARCHIVE_FAILED); 2414 } 2415 2416 /* Swap files. */ 2417 ent = np->entry; 2418 np->entry = file->entry; 2419 file->entry = ent; 2420 np->virtual = 0; 2421 2422 file_free(file); 2423 *filepp = np; 2424 return (ARCHIVE_OK); 2425 } 2426 2427 static void 2428 file_register(struct xar *xar, struct file *file) 2429 { 2430 file->id = xar->file_idx++; 2431 file->next = NULL; 2432 *xar->file_list.last = file; 2433 xar->file_list.last = &(file->next); 2434 } 2435 2436 static void 2437 file_init_register(struct xar *xar) 2438 { 2439 xar->file_list.first = NULL; 2440 xar->file_list.last = &(xar->file_list.first); 2441 } 2442 2443 static void 2444 file_free_register(struct xar *xar) 2445 { 2446 struct file *file, *file_next; 2447 2448 file = xar->file_list.first; 2449 while (file != NULL) { 2450 file_next = file->next; 2451 file_free(file); 2452 file = file_next; 2453 } 2454 } 2455 2456 /* 2457 * Register entry to get a hardlink target. 2458 */ 2459 static int 2460 file_register_hardlink(struct archive_write *a, struct file *file) 2461 { 2462 struct xar *xar = (struct xar *)a->format_data; 2463 struct hardlink *hl; 2464 const char *pathname; 2465 2466 archive_entry_set_nlink(file->entry, 1); 2467 pathname = archive_entry_hardlink(file->entry); 2468 if (pathname == NULL) { 2469 /* This `file` is a hardlink target. */ 2470 hl = malloc(sizeof(*hl)); 2471 if (hl == NULL) { 2472 archive_set_error(&a->archive, ENOMEM, 2473 "Can't allocate memory"); 2474 return (ARCHIVE_FATAL); 2475 } 2476 hl->nlink = 1; 2477 /* A hardlink target must be the first position. */ 2478 file->hlnext = NULL; 2479 hl->file_list.first = file; 2480 hl->file_list.last = &(file->hlnext); 2481 __archive_rb_tree_insert_node(&(xar->hardlink_rbtree), 2482 (struct archive_rb_node *)hl); 2483 } else { 2484 hl = (struct hardlink *)__archive_rb_tree_find_node( 2485 &(xar->hardlink_rbtree), pathname); 2486 if (hl != NULL) { 2487 /* Insert `file` entry into the tail. */ 2488 file->hlnext = NULL; 2489 *hl->file_list.last = file; 2490 hl->file_list.last = &(file->hlnext); 2491 hl->nlink++; 2492 } 2493 archive_entry_unset_size(file->entry); 2494 } 2495 2496 return (ARCHIVE_OK); 2497 } 2498 2499 /* 2500 * Hardlinked files have to have the same location of extent. 2501 * We have to find out hardlink target entries for entries which 2502 * have a hardlink target name. 2503 */ 2504 static void 2505 file_connect_hardlink_files(struct xar *xar) 2506 { 2507 struct archive_rb_node *n; 2508 struct hardlink *hl; 2509 struct file *target, *nf; 2510 2511 ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) { 2512 hl = (struct hardlink *)n; 2513 2514 /* The first entry must be a hardlink target. */ 2515 target = hl->file_list.first; 2516 archive_entry_set_nlink(target->entry, hl->nlink); 2517 if (hl->nlink > 1) 2518 /* It means this file is a hardlink 2519 * target itself. */ 2520 target->hardlink_target = target; 2521 for (nf = target->hlnext; 2522 nf != NULL; nf = nf->hlnext) { 2523 nf->hardlink_target = target; 2524 archive_entry_set_nlink(nf->entry, hl->nlink); 2525 } 2526 } 2527 } 2528 2529 static int 2530 file_hd_cmp_node(const struct archive_rb_node *n1, 2531 const struct archive_rb_node *n2) 2532 { 2533 const struct hardlink *h1 = (const struct hardlink *)n1; 2534 const struct hardlink *h2 = (const struct hardlink *)n2; 2535 2536 return (strcmp(archive_entry_pathname(h1->file_list.first->entry), 2537 archive_entry_pathname(h2->file_list.first->entry))); 2538 } 2539 2540 static int 2541 file_hd_cmp_key(const struct archive_rb_node *n, const void *key) 2542 { 2543 const struct hardlink *h = (const struct hardlink *)n; 2544 2545 return (strcmp(archive_entry_pathname(h->file_list.first->entry), 2546 (const char *)key)); 2547 } 2548 2549 2550 static void 2551 file_init_hardlinks(struct xar *xar) 2552 { 2553 static const struct archive_rb_tree_ops rb_ops = { 2554 file_hd_cmp_node, file_hd_cmp_key, 2555 }; 2556 2557 __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops); 2558 } 2559 2560 static void 2561 file_free_hardlinks(struct xar *xar) 2562 { 2563 struct archive_rb_node *n, *tmp; 2564 2565 ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) { 2566 __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n); 2567 free(n); 2568 } 2569 } 2570 2571 static void 2572 checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg) 2573 { 2574 sumwrk->alg = sum_alg; 2575 switch (sum_alg) { 2576 case CKSUM_NONE: 2577 break; 2578 case CKSUM_SHA1: 2579 archive_sha1_init(&(sumwrk->sha1ctx)); 2580 break; 2581 case CKSUM_MD5: 2582 archive_md5_init(&(sumwrk->md5ctx)); 2583 break; 2584 } 2585 } 2586 2587 static void 2588 checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size) 2589 { 2590 2591 switch (sumwrk->alg) { 2592 case CKSUM_NONE: 2593 break; 2594 case CKSUM_SHA1: 2595 archive_sha1_update(&(sumwrk->sha1ctx), buff, size); 2596 break; 2597 case CKSUM_MD5: 2598 archive_md5_update(&(sumwrk->md5ctx), buff, size); 2599 break; 2600 } 2601 } 2602 2603 static void 2604 checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval) 2605 { 2606 2607 switch (sumwrk->alg) { 2608 case CKSUM_NONE: 2609 sumval->len = 0; 2610 break; 2611 case CKSUM_SHA1: 2612 archive_sha1_final(&(sumwrk->sha1ctx), sumval->val); 2613 sumval->len = SHA1_SIZE; 2614 break; 2615 case CKSUM_MD5: 2616 archive_md5_final(&(sumwrk->md5ctx), sumval->val); 2617 sumval->len = MD5_SIZE; 2618 break; 2619 } 2620 sumval->alg = sumwrk->alg; 2621 } 2622 2623 #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) 2624 static int 2625 compression_unsupported_encoder(struct archive *a, 2626 struct la_zstream *lastrm, const char *name) 2627 { 2628 2629 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2630 "%s compression not supported on this platform", name); 2631 lastrm->valid = 0; 2632 lastrm->real_stream = NULL; 2633 return (ARCHIVE_FAILED); 2634 } 2635 #endif 2636 2637 static int 2638 compression_init_encoder_gzip(struct archive *a, 2639 struct la_zstream *lastrm, int level, int withheader) 2640 { 2641 z_stream *strm; 2642 2643 if (lastrm->valid) 2644 compression_end(a, lastrm); 2645 strm = calloc(1, sizeof(*strm)); 2646 if (strm == NULL) { 2647 archive_set_error(a, ENOMEM, 2648 "Can't allocate memory for gzip stream"); 2649 return (ARCHIVE_FATAL); 2650 } 2651 /* zlib.h is not const-correct, so we need this one bit 2652 * of ugly hackery to convert a const * pointer to 2653 * a non-const pointer. */ 2654 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 2655 strm->avail_in = lastrm->avail_in; 2656 strm->total_in = (uLong)lastrm->total_in; 2657 strm->next_out = lastrm->next_out; 2658 strm->avail_out = lastrm->avail_out; 2659 strm->total_out = (uLong)lastrm->total_out; 2660 if (deflateInit2(strm, level, Z_DEFLATED, 2661 (withheader)?15:-15, 2662 8, Z_DEFAULT_STRATEGY) != Z_OK) { 2663 free(strm); 2664 lastrm->real_stream = NULL; 2665 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2666 "Internal error initializing compression library"); 2667 return (ARCHIVE_FATAL); 2668 } 2669 lastrm->real_stream = strm; 2670 lastrm->valid = 1; 2671 lastrm->code = compression_code_gzip; 2672 lastrm->end = compression_end_gzip; 2673 return (ARCHIVE_OK); 2674 } 2675 2676 static int 2677 compression_code_gzip(struct archive *a, 2678 struct la_zstream *lastrm, enum la_zaction action) 2679 { 2680 z_stream *strm; 2681 int r; 2682 2683 strm = (z_stream *)lastrm->real_stream; 2684 /* zlib.h is not const-correct, so we need this one bit 2685 * of ugly hackery to convert a const * pointer to 2686 * a non-const pointer. */ 2687 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 2688 strm->avail_in = lastrm->avail_in; 2689 strm->total_in = (uLong)lastrm->total_in; 2690 strm->next_out = lastrm->next_out; 2691 strm->avail_out = lastrm->avail_out; 2692 strm->total_out = (uLong)lastrm->total_out; 2693 r = deflate(strm, 2694 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); 2695 lastrm->next_in = strm->next_in; 2696 lastrm->avail_in = strm->avail_in; 2697 lastrm->total_in = strm->total_in; 2698 lastrm->next_out = strm->next_out; 2699 lastrm->avail_out = strm->avail_out; 2700 lastrm->total_out = strm->total_out; 2701 switch (r) { 2702 case Z_OK: 2703 return (ARCHIVE_OK); 2704 case Z_STREAM_END: 2705 return (ARCHIVE_EOF); 2706 default: 2707 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2708 "GZip compression failed:" 2709 " deflate() call returned status %d", r); 2710 return (ARCHIVE_FATAL); 2711 } 2712 } 2713 2714 static int 2715 compression_end_gzip(struct archive *a, struct la_zstream *lastrm) 2716 { 2717 z_stream *strm; 2718 int r; 2719 2720 strm = (z_stream *)lastrm->real_stream; 2721 r = deflateEnd(strm); 2722 free(strm); 2723 lastrm->real_stream = NULL; 2724 lastrm->valid = 0; 2725 if (r != Z_OK) { 2726 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2727 "Failed to clean up compressor"); 2728 return (ARCHIVE_FATAL); 2729 } 2730 return (ARCHIVE_OK); 2731 } 2732 2733 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 2734 static int 2735 compression_init_encoder_bzip2(struct archive *a, 2736 struct la_zstream *lastrm, int level) 2737 { 2738 bz_stream *strm; 2739 2740 if (lastrm->valid) 2741 compression_end(a, lastrm); 2742 strm = calloc(1, sizeof(*strm)); 2743 if (strm == NULL) { 2744 archive_set_error(a, ENOMEM, 2745 "Can't allocate memory for bzip2 stream"); 2746 return (ARCHIVE_FATAL); 2747 } 2748 /* bzlib.h is not const-correct, so we need this one bit 2749 * of ugly hackery to convert a const * pointer to 2750 * a non-const pointer. */ 2751 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 2752 strm->avail_in = lastrm->avail_in; 2753 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 2754 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 2755 strm->next_out = (char *)lastrm->next_out; 2756 strm->avail_out = lastrm->avail_out; 2757 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 2758 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 2759 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { 2760 free(strm); 2761 lastrm->real_stream = NULL; 2762 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2763 "Internal error initializing compression library"); 2764 return (ARCHIVE_FATAL); 2765 } 2766 lastrm->real_stream = strm; 2767 lastrm->valid = 1; 2768 lastrm->code = compression_code_bzip2; 2769 lastrm->end = compression_end_bzip2; 2770 return (ARCHIVE_OK); 2771 } 2772 2773 static int 2774 compression_code_bzip2(struct archive *a, 2775 struct la_zstream *lastrm, enum la_zaction action) 2776 { 2777 bz_stream *strm; 2778 int r; 2779 2780 strm = (bz_stream *)lastrm->real_stream; 2781 /* bzlib.h is not const-correct, so we need this one bit 2782 * of ugly hackery to convert a const * pointer to 2783 * a non-const pointer. */ 2784 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 2785 strm->avail_in = lastrm->avail_in; 2786 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 2787 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 2788 strm->next_out = (char *)lastrm->next_out; 2789 strm->avail_out = lastrm->avail_out; 2790 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 2791 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 2792 r = BZ2_bzCompress(strm, 2793 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); 2794 lastrm->next_in = (const unsigned char *)strm->next_in; 2795 lastrm->avail_in = strm->avail_in; 2796 lastrm->total_in = 2797 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) 2798 + (uint64_t)(uint32_t)strm->total_in_lo32; 2799 lastrm->next_out = (unsigned char *)strm->next_out; 2800 lastrm->avail_out = strm->avail_out; 2801 lastrm->total_out = 2802 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) 2803 + (uint64_t)(uint32_t)strm->total_out_lo32; 2804 switch (r) { 2805 case BZ_RUN_OK: /* Non-finishing */ 2806 case BZ_FINISH_OK: /* Finishing: There's more work to do */ 2807 return (ARCHIVE_OK); 2808 case BZ_STREAM_END: /* Finishing: all done */ 2809 /* Only occurs in finishing case */ 2810 return (ARCHIVE_EOF); 2811 default: 2812 /* Any other return value indicates an error */ 2813 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2814 "Bzip2 compression failed:" 2815 " BZ2_bzCompress() call returned status %d", r); 2816 return (ARCHIVE_FATAL); 2817 } 2818 } 2819 2820 static int 2821 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) 2822 { 2823 bz_stream *strm; 2824 int r; 2825 2826 strm = (bz_stream *)lastrm->real_stream; 2827 r = BZ2_bzCompressEnd(strm); 2828 free(strm); 2829 lastrm->real_stream = NULL; 2830 lastrm->valid = 0; 2831 if (r != BZ_OK) { 2832 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2833 "Failed to clean up compressor"); 2834 return (ARCHIVE_FATAL); 2835 } 2836 return (ARCHIVE_OK); 2837 } 2838 2839 #else 2840 static int 2841 compression_init_encoder_bzip2(struct archive *a, 2842 struct la_zstream *lastrm, int level) 2843 { 2844 2845 (void) level; /* UNUSED */ 2846 if (lastrm->valid) 2847 compression_end(a, lastrm); 2848 return (compression_unsupported_encoder(a, lastrm, "bzip2")); 2849 } 2850 #endif 2851 2852 #if defined(HAVE_LZMA_H) 2853 static int 2854 compression_init_encoder_lzma(struct archive *a, 2855 struct la_zstream *lastrm, int level) 2856 { 2857 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 2858 lzma_stream *strm; 2859 lzma_options_lzma lzma_opt; 2860 int r; 2861 2862 if (lastrm->valid) 2863 compression_end(a, lastrm); 2864 if (lzma_lzma_preset(&lzma_opt, level)) { 2865 lastrm->real_stream = NULL; 2866 archive_set_error(a, ENOMEM, 2867 "Internal error initializing compression library"); 2868 return (ARCHIVE_FATAL); 2869 } 2870 strm = calloc(1, sizeof(*strm)); 2871 if (strm == NULL) { 2872 archive_set_error(a, ENOMEM, 2873 "Can't allocate memory for lzma stream"); 2874 return (ARCHIVE_FATAL); 2875 } 2876 *strm = lzma_init_data; 2877 r = lzma_alone_encoder(strm, &lzma_opt); 2878 switch (r) { 2879 case LZMA_OK: 2880 lastrm->real_stream = strm; 2881 lastrm->valid = 1; 2882 lastrm->code = compression_code_lzma; 2883 lastrm->end = compression_end_lzma; 2884 r = ARCHIVE_OK; 2885 break; 2886 case LZMA_MEM_ERROR: 2887 free(strm); 2888 lastrm->real_stream = NULL; 2889 archive_set_error(a, ENOMEM, 2890 "Internal error initializing compression library: " 2891 "Cannot allocate memory"); 2892 r = ARCHIVE_FATAL; 2893 break; 2894 default: 2895 free(strm); 2896 lastrm->real_stream = NULL; 2897 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2898 "Internal error initializing compression library: " 2899 "It's a bug in liblzma"); 2900 r = ARCHIVE_FATAL; 2901 break; 2902 } 2903 return (r); 2904 } 2905 2906 static int 2907 compression_init_encoder_xz(struct archive *a, 2908 struct la_zstream *lastrm, int level, int threads) 2909 { 2910 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 2911 lzma_stream *strm; 2912 lzma_filter *lzmafilters; 2913 lzma_options_lzma lzma_opt; 2914 int r; 2915 #ifdef HAVE_LZMA_STREAM_ENCODER_MT 2916 lzma_mt mt_options; 2917 #endif 2918 2919 (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */ 2920 2921 if (lastrm->valid) 2922 compression_end(a, lastrm); 2923 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); 2924 if (strm == NULL) { 2925 archive_set_error(a, ENOMEM, 2926 "Can't allocate memory for xz stream"); 2927 return (ARCHIVE_FATAL); 2928 } 2929 lzmafilters = (lzma_filter *)(strm+1); 2930 if (level > 9) 2931 level = 9; 2932 if (lzma_lzma_preset(&lzma_opt, level)) { 2933 free(strm); 2934 lastrm->real_stream = NULL; 2935 archive_set_error(a, ENOMEM, 2936 "Internal error initializing compression library"); 2937 return (ARCHIVE_FATAL); 2938 } 2939 lzmafilters[0].id = LZMA_FILTER_LZMA2; 2940 lzmafilters[0].options = &lzma_opt; 2941 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ 2942 2943 *strm = lzma_init_data; 2944 #ifdef HAVE_LZMA_STREAM_ENCODER_MT 2945 if (threads > 1) { 2946 memset(&mt_options, 0, sizeof(mt_options)); 2947 mt_options.threads = threads; 2948 mt_options.timeout = 300; 2949 mt_options.filters = lzmafilters; 2950 mt_options.check = LZMA_CHECK_CRC64; 2951 r = lzma_stream_encoder_mt(strm, &mt_options); 2952 } else 2953 #endif 2954 r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64); 2955 switch (r) { 2956 case LZMA_OK: 2957 lastrm->real_stream = strm; 2958 lastrm->valid = 1; 2959 lastrm->code = compression_code_lzma; 2960 lastrm->end = compression_end_lzma; 2961 r = ARCHIVE_OK; 2962 break; 2963 case LZMA_MEM_ERROR: 2964 free(strm); 2965 lastrm->real_stream = NULL; 2966 archive_set_error(a, ENOMEM, 2967 "Internal error initializing compression library: " 2968 "Cannot allocate memory"); 2969 r = ARCHIVE_FATAL; 2970 break; 2971 default: 2972 free(strm); 2973 lastrm->real_stream = NULL; 2974 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2975 "Internal error initializing compression library: " 2976 "It's a bug in liblzma"); 2977 r = ARCHIVE_FATAL; 2978 break; 2979 } 2980 return (r); 2981 } 2982 2983 static int 2984 compression_code_lzma(struct archive *a, 2985 struct la_zstream *lastrm, enum la_zaction action) 2986 { 2987 lzma_stream *strm; 2988 int r; 2989 2990 strm = (lzma_stream *)lastrm->real_stream; 2991 strm->next_in = lastrm->next_in; 2992 strm->avail_in = lastrm->avail_in; 2993 strm->total_in = lastrm->total_in; 2994 strm->next_out = lastrm->next_out; 2995 strm->avail_out = lastrm->avail_out; 2996 strm->total_out = lastrm->total_out; 2997 r = lzma_code(strm, 2998 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); 2999 lastrm->next_in = strm->next_in; 3000 lastrm->avail_in = strm->avail_in; 3001 lastrm->total_in = strm->total_in; 3002 lastrm->next_out = strm->next_out; 3003 lastrm->avail_out = strm->avail_out; 3004 lastrm->total_out = strm->total_out; 3005 switch (r) { 3006 case LZMA_OK: 3007 /* Non-finishing case */ 3008 return (ARCHIVE_OK); 3009 case LZMA_STREAM_END: 3010 /* This return can only occur in finishing case. */ 3011 return (ARCHIVE_EOF); 3012 case LZMA_MEMLIMIT_ERROR: 3013 archive_set_error(a, ENOMEM, 3014 "lzma compression error:" 3015 " %ju MiB would have been needed", 3016 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) 3017 / (1024 * 1024))); 3018 return (ARCHIVE_FATAL); 3019 default: 3020 /* Any other return value indicates an error */ 3021 archive_set_error(a, ARCHIVE_ERRNO_MISC, 3022 "lzma compression failed:" 3023 " lzma_code() call returned status %d", r); 3024 return (ARCHIVE_FATAL); 3025 } 3026 } 3027 3028 static int 3029 compression_end_lzma(struct archive *a, struct la_zstream *lastrm) 3030 { 3031 lzma_stream *strm; 3032 3033 (void)a; /* UNUSED */ 3034 strm = (lzma_stream *)lastrm->real_stream; 3035 lzma_end(strm); 3036 free(strm); 3037 lastrm->valid = 0; 3038 lastrm->real_stream = NULL; 3039 return (ARCHIVE_OK); 3040 } 3041 #else 3042 static int 3043 compression_init_encoder_lzma(struct archive *a, 3044 struct la_zstream *lastrm, int level) 3045 { 3046 3047 (void) level; /* UNUSED */ 3048 if (lastrm->valid) 3049 compression_end(a, lastrm); 3050 return (compression_unsupported_encoder(a, lastrm, "lzma")); 3051 } 3052 static int 3053 compression_init_encoder_xz(struct archive *a, 3054 struct la_zstream *lastrm, int level, int threads) 3055 { 3056 3057 (void) level; /* UNUSED */ 3058 (void) threads; /* UNUSED */ 3059 if (lastrm->valid) 3060 compression_end(a, lastrm); 3061 return (compression_unsupported_encoder(a, lastrm, "xz")); 3062 } 3063 #endif 3064 3065 static int 3066 xar_compression_init_encoder(struct archive_write *a) 3067 { 3068 struct xar *xar; 3069 int r; 3070 3071 xar = (struct xar *)a->format_data; 3072 switch (xar->opt_compression) { 3073 case GZIP: 3074 r = compression_init_encoder_gzip( 3075 &(a->archive), &(xar->stream), 3076 xar->opt_compression_level, 1); 3077 break; 3078 case BZIP2: 3079 r = compression_init_encoder_bzip2( 3080 &(a->archive), &(xar->stream), 3081 xar->opt_compression_level); 3082 break; 3083 case LZMA: 3084 r = compression_init_encoder_lzma( 3085 &(a->archive), &(xar->stream), 3086 xar->opt_compression_level); 3087 break; 3088 case XZ: 3089 r = compression_init_encoder_xz( 3090 &(a->archive), &(xar->stream), 3091 xar->opt_compression_level, xar->opt_threads); 3092 break; 3093 default: 3094 r = ARCHIVE_OK; 3095 break; 3096 } 3097 if (r == ARCHIVE_OK) { 3098 xar->stream.total_in = 0; 3099 xar->stream.next_out = xar->wbuff; 3100 xar->stream.avail_out = sizeof(xar->wbuff); 3101 xar->stream.total_out = 0; 3102 } 3103 3104 return (r); 3105 } 3106 3107 static int 3108 compression_code(struct archive *a, struct la_zstream *lastrm, 3109 enum la_zaction action) 3110 { 3111 if (lastrm->valid) 3112 return (lastrm->code(a, lastrm, action)); 3113 return (ARCHIVE_OK); 3114 } 3115 3116 static int 3117 compression_end(struct archive *a, struct la_zstream *lastrm) 3118 { 3119 if (lastrm->valid) 3120 return (lastrm->end(a, lastrm)); 3121 return (ARCHIVE_OK); 3122 } 3123 3124 3125 static int 3126 save_xattrs(struct archive_write *a, struct file *file) 3127 { 3128 struct xar *xar; 3129 const char *name; 3130 const void *value; 3131 struct heap_data *heap; 3132 size_t size; 3133 int count, r; 3134 3135 xar = (struct xar *)a->format_data; 3136 count = archive_entry_xattr_reset(file->entry); 3137 if (count == 0) 3138 return (ARCHIVE_OK); 3139 while (count--) { 3140 archive_entry_xattr_next(file->entry, 3141 &name, &value, &size); 3142 checksum_init(&(xar->a_sumwrk), xar->opt_sumalg); 3143 checksum_init(&(xar->e_sumwrk), xar->opt_sumalg); 3144 3145 heap = calloc(1, sizeof(*heap)); 3146 if (heap == NULL) { 3147 archive_set_error(&a->archive, ENOMEM, 3148 "Can't allocate memory for xattr"); 3149 return (ARCHIVE_FATAL); 3150 } 3151 heap->id = file->ea_idx++; 3152 heap->temp_offset = xar->temp_offset; 3153 heap->size = size;/* save a extracted size */ 3154 heap->compression = xar->opt_compression; 3155 /* Get a extracted sumcheck value. */ 3156 checksum_update(&(xar->e_sumwrk), value, size); 3157 checksum_final(&(xar->e_sumwrk), &(heap->e_sum)); 3158 3159 /* 3160 * Not compression to xattr is simple way. 3161 */ 3162 if (heap->compression == NONE) { 3163 checksum_update(&(xar->a_sumwrk), value, size); 3164 checksum_final(&(xar->a_sumwrk), &(heap->a_sum)); 3165 if (write_to_temp(a, value, size) 3166 != ARCHIVE_OK) { 3167 free(heap); 3168 return (ARCHIVE_FATAL); 3169 } 3170 heap->length = size; 3171 /* Add heap to the tail of file->xattr. */ 3172 heap->next = NULL; 3173 *file->xattr.last = heap; 3174 file->xattr.last = &(heap->next); 3175 /* Next xattr */ 3176 continue; 3177 } 3178 3179 /* 3180 * Init compression library. 3181 */ 3182 r = xar_compression_init_encoder(a); 3183 if (r != ARCHIVE_OK) { 3184 free(heap); 3185 return (ARCHIVE_FATAL); 3186 } 3187 3188 xar->stream.next_in = (const unsigned char *)value; 3189 xar->stream.avail_in = size; 3190 for (;;) { 3191 r = compression_code(&(a->archive), 3192 &(xar->stream), ARCHIVE_Z_FINISH); 3193 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) { 3194 free(heap); 3195 return (ARCHIVE_FATAL); 3196 } 3197 size = sizeof(xar->wbuff) - xar->stream.avail_out; 3198 checksum_update(&(xar->a_sumwrk), 3199 xar->wbuff, size); 3200 if (write_to_temp(a, xar->wbuff, size) 3201 != ARCHIVE_OK) { 3202 free(heap); 3203 return (ARCHIVE_FATAL); 3204 } 3205 if (r == ARCHIVE_OK) { 3206 xar->stream.next_out = xar->wbuff; 3207 xar->stream.avail_out = sizeof(xar->wbuff); 3208 } else { 3209 checksum_final(&(xar->a_sumwrk), 3210 &(heap->a_sum)); 3211 heap->length = xar->stream.total_out; 3212 /* Add heap to the tail of file->xattr. */ 3213 heap->next = NULL; 3214 *file->xattr.last = heap; 3215 file->xattr.last = &(heap->next); 3216 break; 3217 } 3218 } 3219 /* Clean up compression library. */ 3220 r = compression_end(&(a->archive), &(xar->stream)); 3221 if (r != ARCHIVE_OK) 3222 return (ARCHIVE_FATAL); 3223 } 3224 return (ARCHIVE_OK); 3225 } 3226 3227 static int 3228 getalgsize(enum sumalg sumalg) 3229 { 3230 switch (sumalg) { 3231 default: 3232 case CKSUM_NONE: 3233 return (0); 3234 case CKSUM_SHA1: 3235 return (SHA1_SIZE); 3236 case CKSUM_MD5: 3237 return (MD5_SIZE); 3238 } 3239 } 3240 3241 static const char * 3242 getalgname(enum sumalg sumalg) 3243 { 3244 switch (sumalg) { 3245 default: 3246 case CKSUM_NONE: 3247 return (NULL); 3248 case CKSUM_SHA1: 3249 return (SHA1_NAME); 3250 case CKSUM_MD5: 3251 return (MD5_NAME); 3252 } 3253 } 3254 3255 #endif /* Support xar format */ 3256