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