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