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