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