1 /*- 2 * Copyright (c) 2011-2012 Michihiro NAKAJIMA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "archive_platform.h" 27 28 #ifdef HAVE_ERRNO_H 29 #include <errno.h> 30 #endif 31 #ifdef HAVE_LIMITS_H 32 #include <limits.h> 33 #endif 34 #ifdef HAVE_STDLIB_H 35 #include <stdlib.h> 36 #endif 37 #ifdef HAVE_UNISTD_H 38 #include <unistd.h> 39 #endif 40 #ifdef HAVE_BZLIB_H 41 #include <bzlib.h> 42 #endif 43 #if HAVE_LZMA_H 44 #include <lzma.h> 45 #endif 46 #ifdef HAVE_ZLIB_H 47 #include <zlib.h> 48 #endif 49 #ifdef HAVE_ZSTD_H 50 #include <zstd.h> 51 #endif 52 53 #include "archive.h" 54 #ifndef HAVE_ZLIB_H 55 #include "archive_crc32.h" 56 #endif 57 #include "archive_endian.h" 58 #include "archive_entry.h" 59 #include "archive_entry_locale.h" 60 #include "archive_ppmd7_private.h" 61 #include "archive_private.h" 62 #include "archive_rb.h" 63 #include "archive_string.h" 64 #include "archive_time_private.h" 65 #include "archive_write_private.h" 66 #include "archive_write_set_format_private.h" 67 68 /* 69 * Codec ID 70 */ 71 #define _7Z_COPY 0 72 #define _7Z_LZMA1 0x030101 73 #define _7Z_LZMA2 0x21 74 #define _7Z_DEFLATE 0x040108 75 #define _7Z_BZIP2 0x040202 76 #define _7Z_PPMD 0x030401 77 78 #define _7Z_ZSTD 0x4F71101 /* Copied from https://github.com/mcmilk/7-Zip-zstd.git */ 79 80 /* 81 * 7-Zip header property IDs. 82 */ 83 #define kEnd 0x00 84 #define kHeader 0x01 85 #define kArchiveProperties 0x02 86 #define kAdditionalStreamsInfo 0x03 87 #define kMainStreamsInfo 0x04 88 #define kFilesInfo 0x05 89 #define kPackInfo 0x06 90 #define kUnPackInfo 0x07 91 #define kSubStreamsInfo 0x08 92 #define kSize 0x09 93 #define kCRC 0x0A 94 #define kFolder 0x0B 95 #define kCodersUnPackSize 0x0C 96 #define kNumUnPackStream 0x0D 97 #define kEmptyStream 0x0E 98 #define kEmptyFile 0x0F 99 #define kAnti 0x10 100 #define kName 0x11 101 #define kCTime 0x12 102 #define kATime 0x13 103 #define kMTime 0x14 104 #define kAttributes 0x15 105 #define kEncodedHeader 0x17 106 107 // Check that some windows file attribute constants are defined. 108 // Reference: https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants 109 #ifndef FILE_ATTRIBUTE_READONLY 110 #define FILE_ATTRIBUTE_READONLY 0x00000001 111 #endif 112 113 #ifndef FILE_ATTRIBUTE_DIRECTORY 114 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 115 #endif 116 117 #ifndef FILE_ATTRIBUTE_ARCHIVE 118 #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 119 #endif 120 121 // This value is defined in 7zip with the comment "trick for Unix". 122 // 123 // 7z archives created on unix have this bit set in the high 16 bits of 124 // the attr field along with the unix permissions. 125 #define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 126 127 // Many systems define min or MIN, but not all. 128 #define sevenzipmin(a,b) ((a) < (b) ? (a) : (b)) 129 130 enum la_zaction { 131 ARCHIVE_Z_FINISH, 132 ARCHIVE_Z_RUN 133 }; 134 135 /* 136 * A stream object of universal compressor. 137 */ 138 struct la_zstream { 139 const uint8_t *next_in; 140 size_t avail_in; 141 uint64_t total_in; 142 143 uint8_t *next_out; 144 size_t avail_out; 145 uint64_t total_out; 146 147 uint32_t prop_size; 148 uint8_t *props; 149 150 int valid; 151 void *real_stream; 152 int (*code) (struct archive *a, 153 struct la_zstream *lastrm, 154 enum la_zaction action); 155 int (*end)(struct archive *a, 156 struct la_zstream *lastrm); 157 }; 158 159 #define PPMD7_DEFAULT_ORDER 6 160 #define PPMD7_DEFAULT_MEM_SIZE (1 << 24) 161 162 struct ppmd_stream { 163 int stat; 164 CPpmd7 ppmd7_context; 165 CPpmd7z_RangeEnc range_enc; 166 IByteOut byteout; 167 uint8_t *buff; 168 uint8_t *buff_ptr; 169 uint8_t *buff_end; 170 size_t buff_bytes; 171 }; 172 173 struct coder { 174 unsigned codec; 175 size_t prop_size; 176 uint8_t *props; 177 }; 178 179 struct file { 180 struct archive_rb_node rbnode; 181 182 struct file *next; 183 unsigned name_len; 184 uint8_t *utf16name;/* UTF16-LE name. */ 185 uint64_t size; 186 unsigned flg; 187 #define MTIME_IS_SET (1<<0) 188 #define ATIME_IS_SET (1<<1) 189 #define CTIME_IS_SET (1<<2) 190 #define CRC32_IS_SET (1<<3) 191 #define HAS_STREAM (1<<4) 192 193 struct { 194 time_t time; 195 long time_ns; 196 } times[3]; 197 #define MTIME 0 198 #define ATIME 1 199 #define CTIME 2 200 201 mode_t mode; 202 uint32_t crc32; 203 204 unsigned dir:1; 205 }; 206 207 struct _7zip { 208 int temp_fd; 209 uint64_t temp_offset; 210 211 struct file *cur_file; 212 size_t total_number_entry; 213 size_t total_number_nonempty_entry; 214 size_t total_number_empty_entry; 215 size_t total_number_dir_entry; 216 size_t total_bytes_entry_name; 217 size_t total_number_time_defined[3]; 218 uint64_t total_bytes_compressed; 219 uint64_t total_bytes_uncompressed; 220 uint64_t entry_bytes_remaining; 221 uint32_t entry_crc32; 222 uint32_t precode_crc32; 223 uint32_t encoded_crc32; 224 int crc32flg; 225 #define PRECODE_CRC32 1 226 #define ENCODED_CRC32 2 227 228 unsigned opt_compression; 229 230 int opt_compression_level; 231 int opt_zstd_compression_level; // This requires a different default value. 232 233 int opt_threads; 234 235 struct la_zstream stream; 236 struct coder coder; 237 238 struct archive_string_conv *sconv; 239 240 /* 241 * Compressed data buffer. 242 */ 243 unsigned char wbuff[512 * 20 * 6]; 244 size_t wbuff_remaining; 245 246 /* 247 * The list of the file entries which has its contents is used to 248 * manage struct file objects. 249 * We use 'next' (a member of struct file) to chain. 250 */ 251 struct { 252 struct file *first; 253 struct file **last; 254 } file_list, empty_list; 255 struct archive_rb_tree rbtree;/* for empty files */ 256 }; 257 258 static int _7z_options(struct archive_write *, 259 const char *, const char *); 260 static int _7z_write_header(struct archive_write *, 261 struct archive_entry *); 262 static ssize_t _7z_write_data(struct archive_write *, 263 const void *, size_t); 264 static int _7z_finish_entry(struct archive_write *); 265 static int _7z_close(struct archive_write *); 266 static int _7z_free(struct archive_write *); 267 static int file_cmp_node(const struct archive_rb_node *, 268 const struct archive_rb_node *); 269 static int file_cmp_key(const struct archive_rb_node *, const void *); 270 static int file_new(struct archive_write *a, struct archive_entry *, 271 struct file **); 272 static void file_free(struct file *); 273 static void file_register(struct _7zip *, struct file *); 274 static void file_register_empty(struct _7zip *, struct file *); 275 static void file_init_register(struct _7zip *); 276 static void file_init_register_empty(struct _7zip *); 277 static void file_free_register(struct _7zip *); 278 static ssize_t compress_out(struct archive_write *, const void *, size_t , 279 enum la_zaction); 280 static int compression_init_encoder_copy(struct archive *, 281 struct la_zstream *); 282 static int compression_code_copy(struct archive *, 283 struct la_zstream *, enum la_zaction); 284 static int compression_end_copy(struct archive *, struct la_zstream *); 285 static int compression_init_encoder_deflate(struct archive *, 286 struct la_zstream *, int, int); 287 #ifdef HAVE_ZLIB_H 288 static int compression_code_deflate(struct archive *, 289 struct la_zstream *, enum la_zaction); 290 static int compression_end_deflate(struct archive *, struct la_zstream *); 291 #endif 292 static int compression_init_encoder_bzip2(struct archive *, 293 struct la_zstream *, int); 294 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 295 static int compression_code_bzip2(struct archive *, 296 struct la_zstream *, enum la_zaction); 297 static int compression_end_bzip2(struct archive *, struct la_zstream *); 298 #endif 299 static int compression_init_encoder_lzma1(struct archive *, 300 struct la_zstream *, int); 301 static int compression_init_encoder_lzma2(struct archive *, 302 struct la_zstream *, int); 303 #if defined(HAVE_LZMA_H) 304 static int compression_code_lzma(struct archive *, 305 struct la_zstream *, enum la_zaction); 306 static int compression_end_lzma(struct archive *, struct la_zstream *); 307 #endif 308 static int compression_init_encoder_ppmd(struct archive *, 309 struct la_zstream *, uint8_t, uint32_t); 310 static int compression_code_ppmd(struct archive *, 311 struct la_zstream *, enum la_zaction); 312 static int compression_end_ppmd(struct archive *, struct la_zstream *); 313 static int _7z_compression_init_encoder(struct archive_write *, unsigned, 314 int); 315 static int compression_init_encoder_zstd(struct archive *, 316 struct la_zstream *, int, int); 317 #if defined(HAVE_ZSTD_H) 318 static int compression_code_zstd(struct archive *, 319 struct la_zstream *, enum la_zaction); 320 static int compression_end_zstd(struct archive *, struct la_zstream *); 321 #endif 322 static int compression_code(struct archive *, 323 struct la_zstream *, enum la_zaction); 324 static int compression_end(struct archive *, 325 struct la_zstream *); 326 static int enc_uint64(struct archive_write *, uint64_t); 327 static int make_header(struct archive_write *, uint64_t, uint64_t, 328 uint64_t, int, struct coder *); 329 static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t, 330 uint64_t, int, struct coder *, int, uint32_t); 331 332 static int 333 string_to_number(const char *string, intmax_t *numberp) 334 { 335 char *end; 336 337 if (string == NULL || *string == '\0') 338 return (ARCHIVE_WARN); 339 errno = 0; 340 *numberp = strtoimax(string, &end, 10); 341 if (end == string || *end != '\0' || errno == EOVERFLOW) { 342 *numberp = 0; 343 return (ARCHIVE_WARN); 344 } 345 return (ARCHIVE_OK); 346 } 347 348 int 349 archive_write_set_format_7zip(struct archive *_a) 350 { 351 static const struct archive_rb_tree_ops rb_ops = { 352 file_cmp_node, file_cmp_key 353 }; 354 struct archive_write *a = (struct archive_write *)_a; 355 struct _7zip *zip; 356 357 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, 358 ARCHIVE_STATE_NEW, "archive_write_set_format_7zip"); 359 360 /* If another format was already registered, unregister it. */ 361 if (a->format_free != NULL) 362 (a->format_free)(a); 363 364 zip = calloc(1, sizeof(*zip)); 365 if (zip == NULL) { 366 archive_set_error(&a->archive, ENOMEM, 367 "Can't allocate 7-Zip data"); 368 return (ARCHIVE_FATAL); 369 } 370 zip->temp_fd = -1; 371 __archive_rb_tree_init(&(zip->rbtree), &rb_ops); 372 file_init_register(zip); 373 file_init_register_empty(zip); 374 375 /* Set default compression type and its level. */ 376 #if HAVE_LZMA_H 377 zip->opt_compression = _7Z_LZMA1; 378 #elif defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 379 zip->opt_compression = _7Z_BZIP2; 380 #elif defined(HAVE_ZLIB_H) 381 zip->opt_compression = _7Z_DEFLATE; 382 #elif HAVE_ZSTD_H 383 zip->opt_compression = _7Z_ZSTD; 384 #else 385 zip->opt_compression = _7Z_COPY; 386 #endif 387 388 zip->opt_compression_level = 6; 389 390 #ifdef ZSTD_CLEVEL_DEFAULT 391 // Zstandard compression needs a different default 392 // value than other encoders. 393 zip->opt_zstd_compression_level = ZSTD_CLEVEL_DEFAULT; 394 #else 395 zip->opt_zstd_compression_level = 3; 396 #endif 397 398 zip->opt_threads = 1; 399 400 a->format_data = zip; 401 402 a->format_name = "7zip"; 403 a->format_options = _7z_options; 404 a->format_write_header = _7z_write_header; 405 a->format_write_data = _7z_write_data; 406 a->format_finish_entry = _7z_finish_entry; 407 a->format_close = _7z_close; 408 a->format_free = _7z_free; 409 a->archive.archive_format = ARCHIVE_FORMAT_7ZIP; 410 a->archive.archive_format_name = "7zip"; 411 412 return (ARCHIVE_OK); 413 } 414 415 static int 416 _7z_options(struct archive_write *a, const char *key, const char *value) 417 { 418 struct _7zip *zip; 419 420 zip = (struct _7zip *)a->format_data; 421 422 if (strcmp(key, "compression") == 0) { 423 const char *name = NULL; 424 425 if (value == NULL || strcmp(value, "copy") == 0 || 426 strcmp(value, "COPY") == 0 || 427 strcmp(value, "store") == 0 || 428 strcmp(value, "STORE") == 0) 429 zip->opt_compression = _7Z_COPY; 430 else if (strcmp(value, "deflate") == 0 || 431 strcmp(value, "DEFLATE") == 0) 432 #if HAVE_ZLIB_H 433 zip->opt_compression = _7Z_DEFLATE; 434 #else 435 name = "deflate"; 436 #endif 437 else if (strcmp(value, "bzip2") == 0 || 438 strcmp(value, "BZIP2") == 0) 439 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 440 zip->opt_compression = _7Z_BZIP2; 441 #else 442 name = "bzip2"; 443 #endif 444 else if (strcmp(value, "lzma1") == 0 || 445 strcmp(value, "LZMA1") == 0) 446 #if HAVE_LZMA_H 447 zip->opt_compression = _7Z_LZMA1; 448 #else 449 name = "lzma1"; 450 #endif 451 else if (strcmp(value, "lzma2") == 0 || 452 strcmp(value, "LZMA2") == 0) 453 #if HAVE_LZMA_H 454 zip->opt_compression = _7Z_LZMA2; 455 #else 456 name = "lzma2"; 457 #endif 458 else if (strcmp(value, "zstd") == 0 || 459 strcmp(value, "ZSTD") == 0) 460 #if HAVE_ZSTD_H 461 zip->opt_compression = _7Z_ZSTD; 462 #else 463 name = "zstd"; 464 #endif 465 else if (strcmp(value, "ppmd") == 0 || 466 strcmp(value, "PPMD") == 0 || 467 strcmp(value, "PPMd") == 0) 468 zip->opt_compression = _7Z_PPMD; 469 else { 470 archive_set_error(&(a->archive), 471 ARCHIVE_ERRNO_MISC, 472 "Unknown compression name: `%s'", 473 value); 474 return (ARCHIVE_FAILED); 475 } 476 if (name != NULL) { 477 archive_set_error(&(a->archive), 478 ARCHIVE_ERRNO_MISC, 479 "`%s' compression not supported " 480 "on this platform", 481 name); 482 return (ARCHIVE_FAILED); 483 } 484 return (ARCHIVE_OK); 485 } 486 if (strcmp(key, "compression-level") == 0) { 487 if (value == NULL || *value == '\0') { 488 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 489 "Invalid compression-level option value `%s'", value); 490 return (ARCHIVE_FAILED); 491 } 492 493 char *end = NULL; 494 errno = 0; 495 long lvl = strtol(value, &end, 10); 496 if (errno != 0 || end == NULL || *end != '\0') { 497 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 498 "parsing compression-level option value failed `%s'", value); 499 return (ARCHIVE_FAILED); 500 } 501 502 #if HAVE_ZSTD_H && HAVE_ZSTD_compressStream && HAVE_ZSTD_minCLevel 503 int min_level = sevenzipmin(0, ZSTD_minCLevel()); 504 #else 505 const int min_level = 0; 506 #endif 507 508 #if HAVE_ZSTD_H && HAVE_ZSTD_compressStream 509 int max_level = ZSTD_maxCLevel(); 510 #else 511 const int max_level = 9; 512 #endif 513 514 if (lvl < min_level || lvl > max_level) { 515 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 516 "compression-level option value `%ld' out of range", lvl); 517 return (ARCHIVE_FAILED); 518 } 519 520 // Note: we don't know here if this value is for zstd (negative to ~22), 521 // or zlib-style 0-9. If zstd is enabled but not in use, we will need to 522 // validate opt_compression_level before use. 523 zip->opt_compression_level = (int)lvl; 524 525 zip->opt_zstd_compression_level = (int)lvl; 526 return (ARCHIVE_OK); 527 } 528 if (strcmp(key, "threads") == 0) { 529 intmax_t threads; 530 if (string_to_number(value, &threads) != ARCHIVE_OK) { 531 return (ARCHIVE_WARN); 532 } 533 if (threads < 0 || threads > INT_MAX) { 534 return (ARCHIVE_WARN); 535 } 536 if (threads == 0) { 537 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) 538 threads = sysconf(_SC_NPROCESSORS_ONLN); 539 #elif !defined(__CYGWIN__) && defined(_WIN32_WINNT) && \ 540 _WIN32_WINNT >= 0x0601 /* _WIN32_WINNT_WIN7 */ 541 DWORD winCores = GetActiveProcessorCount( 542 ALL_PROCESSOR_GROUPS); 543 threads = (intmax_t)winCores; 544 #else 545 threads = 1; 546 #endif 547 } 548 549 zip->opt_threads = (int)threads; 550 return (ARCHIVE_OK); 551 } 552 553 /* Note: The "warn" return is just to inform the options 554 * supervisor that we didn't handle it. It will generate 555 * a suitable error if no one used this option. */ 556 return (ARCHIVE_WARN); 557 } 558 559 static int 560 _7z_write_header(struct archive_write *a, struct archive_entry *entry) 561 { 562 struct _7zip *zip; 563 struct file *file; 564 int r; 565 566 zip = (struct _7zip *)a->format_data; 567 zip->cur_file = NULL; 568 zip->entry_bytes_remaining = 0; 569 570 if (zip->sconv == NULL) { 571 zip->sconv = archive_string_conversion_to_charset( 572 &a->archive, "UTF-16LE", 1); 573 if (zip->sconv == NULL) 574 return (ARCHIVE_FATAL); 575 } 576 577 r = file_new(a, entry, &file); 578 if (r < ARCHIVE_WARN) { 579 if (file != NULL) 580 file_free(file); 581 return (r); 582 } 583 if (file->size == 0 && file->dir) { 584 if (!__archive_rb_tree_insert_node(&(zip->rbtree), 585 (struct archive_rb_node *)file)) { 586 /* We have already had the same file. */ 587 file_free(file); 588 return (ARCHIVE_OK); 589 } 590 } 591 592 if (file->flg & MTIME_IS_SET) 593 zip->total_number_time_defined[MTIME]++; 594 if (file->flg & CTIME_IS_SET) 595 zip->total_number_time_defined[CTIME]++; 596 if (file->flg & ATIME_IS_SET) 597 zip->total_number_time_defined[ATIME]++; 598 599 zip->total_number_entry++; 600 zip->total_bytes_entry_name += file->name_len + 2; 601 if (file->size == 0) { 602 /* Count up the number of empty files. */ 603 zip->total_number_empty_entry++; 604 if (file->dir) 605 zip->total_number_dir_entry++; 606 else 607 file_register_empty(zip, file); 608 return (r); 609 } 610 611 /* 612 * Init compression. 613 */ 614 if ((zip->total_number_entry - zip->total_number_empty_entry) == 1) { 615 616 int level = zip->opt_compression_level; 617 #if HAVE_ZSTD_H 618 if (zip->opt_compression == _7Z_ZSTD) { 619 level = zip->opt_zstd_compression_level; 620 } else if (level < 0 || level > 9) { 621 archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC, 622 "compression-level option value `%d' out of range 0-9", level); 623 file_free(file); 624 return (ARCHIVE_FATAL); 625 } 626 #endif 627 628 r = _7z_compression_init_encoder(a, zip->opt_compression, level); 629 if (r < 0) { 630 file_free(file); 631 return (ARCHIVE_FATAL); 632 } 633 } 634 635 /* Register a non-empty file. */ 636 file_register(zip, file); 637 638 /* 639 * Set the current file to cur_file to read its contents. 640 */ 641 zip->cur_file = file; 642 643 644 /* Save a offset of current file in temporary file. */ 645 zip->entry_bytes_remaining = file->size; 646 zip->entry_crc32 = 0; 647 648 /* 649 * Store a symbolic link name as file contents. 650 */ 651 if (archive_entry_filetype(entry) == AE_IFLNK) { 652 ssize_t bytes; 653 const void *p = (const void *)archive_entry_symlink_utf8(entry); 654 bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN); 655 if (bytes < 0) 656 return ((int)bytes); 657 zip->entry_crc32 = crc32(zip->entry_crc32, p, (unsigned)bytes); 658 zip->entry_bytes_remaining -= bytes; 659 } 660 661 return (r); 662 } 663 664 /* 665 * Write data to a temporary file. 666 */ 667 static int 668 write_to_temp(struct archive_write *a, const void *buff, size_t s) 669 { 670 struct _7zip *zip; 671 const unsigned char *p; 672 ssize_t ws; 673 674 zip = (struct _7zip *)a->format_data; 675 676 /* 677 * Open a temporary file. 678 */ 679 if (zip->temp_fd == -1) { 680 zip->temp_offset = 0; 681 zip->temp_fd = __archive_mktemp(NULL); 682 if (zip->temp_fd < 0) { 683 archive_set_error(&a->archive, errno, 684 "Couldn't create temporary file"); 685 return (ARCHIVE_FATAL); 686 } 687 } 688 689 p = (const unsigned char *)buff; 690 while (s) { 691 ws = write(zip->temp_fd, p, s); 692 if (ws < 0) { 693 archive_set_error(&(a->archive), errno, 694 "write function failed"); 695 return (ARCHIVE_FATAL); 696 } 697 s -= ws; 698 p += ws; 699 zip->temp_offset += ws; 700 } 701 return (ARCHIVE_OK); 702 } 703 704 static ssize_t 705 compress_out(struct archive_write *a, const void *buff, size_t s, 706 enum la_zaction run) 707 { 708 struct _7zip *zip = (struct _7zip *)a->format_data; 709 int r; 710 711 if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0) 712 return (0); 713 714 if ((zip->crc32flg & PRECODE_CRC32) && s) 715 zip->precode_crc32 = crc32(zip->precode_crc32, buff, 716 (unsigned)s); 717 zip->stream.next_in = (const unsigned char *)buff; 718 zip->stream.avail_in = s; 719 for (;;) { 720 /* Compress file data. */ 721 r = compression_code(&(a->archive), &(zip->stream), run); 722 if (r != ARCHIVE_OK && r != ARCHIVE_EOF) 723 return (ARCHIVE_FATAL); 724 if (zip->stream.avail_out == 0) { 725 if (write_to_temp(a, zip->wbuff, sizeof(zip->wbuff)) 726 != ARCHIVE_OK) 727 return (ARCHIVE_FATAL); 728 zip->stream.next_out = zip->wbuff; 729 zip->stream.avail_out = sizeof(zip->wbuff); 730 if (zip->crc32flg & ENCODED_CRC32) 731 zip->encoded_crc32 = crc32(zip->encoded_crc32, 732 zip->wbuff, sizeof(zip->wbuff)); 733 if (run == ARCHIVE_Z_FINISH && r != ARCHIVE_EOF) 734 continue; 735 } 736 if (zip->stream.avail_in == 0) 737 break; 738 } 739 if (run == ARCHIVE_Z_FINISH) { 740 uint64_t bytes = sizeof(zip->wbuff) - zip->stream.avail_out; 741 if (write_to_temp(a, zip->wbuff, (size_t)bytes) != ARCHIVE_OK) 742 return (ARCHIVE_FATAL); 743 if ((zip->crc32flg & ENCODED_CRC32) && bytes) 744 zip->encoded_crc32 = crc32(zip->encoded_crc32, 745 zip->wbuff, (unsigned)bytes); 746 } 747 748 return (s); 749 } 750 751 static ssize_t 752 _7z_write_data(struct archive_write *a, const void *buff, size_t s) 753 { 754 struct _7zip *zip; 755 ssize_t bytes; 756 757 zip = (struct _7zip *)a->format_data; 758 759 if (s > zip->entry_bytes_remaining) 760 s = (size_t)zip->entry_bytes_remaining; 761 if (s == 0 || zip->cur_file == NULL) 762 return (0); 763 bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN); 764 if (bytes < 0) 765 return (bytes); 766 zip->entry_crc32 = crc32(zip->entry_crc32, buff, (unsigned)bytes); 767 zip->entry_bytes_remaining -= bytes; 768 return (bytes); 769 } 770 771 static int 772 _7z_finish_entry(struct archive_write *a) 773 { 774 struct _7zip *zip; 775 size_t s; 776 ssize_t r; 777 778 zip = (struct _7zip *)a->format_data; 779 if (zip->cur_file == NULL) 780 return (ARCHIVE_OK); 781 782 while (zip->entry_bytes_remaining > 0) { 783 s = (size_t)zip->entry_bytes_remaining; 784 if (s > a->null_length) 785 s = a->null_length; 786 r = _7z_write_data(a, a->nulls, s); 787 if (r < 0) 788 return ((int)r); 789 } 790 zip->total_bytes_compressed += zip->stream.total_in; 791 zip->total_bytes_uncompressed += zip->stream.total_out; 792 zip->cur_file->crc32 = zip->entry_crc32; 793 zip->cur_file = NULL; 794 795 return (ARCHIVE_OK); 796 } 797 798 static int 799 flush_wbuff(struct archive_write *a) 800 { 801 struct _7zip *zip; 802 int r; 803 size_t s; 804 805 zip = (struct _7zip *)a->format_data; 806 s = sizeof(zip->wbuff) - zip->wbuff_remaining; 807 r = __archive_write_output(a, zip->wbuff, s); 808 if (r != ARCHIVE_OK) 809 return (r); 810 zip->wbuff_remaining = sizeof(zip->wbuff); 811 return (r); 812 } 813 814 static int 815 copy_out(struct archive_write *a, uint64_t offset, uint64_t length) 816 { 817 struct _7zip *zip; 818 int r; 819 820 zip = (struct _7zip *)a->format_data; 821 if (zip->temp_offset > 0 && 822 lseek(zip->temp_fd, offset, SEEK_SET) < 0) { 823 archive_set_error(&(a->archive), errno, "lseek failed"); 824 return (ARCHIVE_FATAL); 825 } 826 while (length) { 827 size_t rsize; 828 ssize_t rs; 829 unsigned char *wb; 830 831 if (length > zip->wbuff_remaining) 832 rsize = zip->wbuff_remaining; 833 else 834 rsize = (size_t)length; 835 wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining); 836 rs = read(zip->temp_fd, wb, rsize); 837 if (rs < 0) { 838 archive_set_error(&(a->archive), errno, 839 "Can't read temporary file(%jd)", 840 (intmax_t)rs); 841 return (ARCHIVE_FATAL); 842 } 843 if (rs == 0) { 844 archive_set_error(&(a->archive), 0, 845 "Truncated 7-Zip archive"); 846 return (ARCHIVE_FATAL); 847 } 848 zip->wbuff_remaining -= rs; 849 length -= rs; 850 if (zip->wbuff_remaining == 0) { 851 r = flush_wbuff(a); 852 if (r != ARCHIVE_OK) 853 return (r); 854 } 855 } 856 return (ARCHIVE_OK); 857 } 858 859 static int 860 _7z_close(struct archive_write *a) 861 { 862 struct _7zip *zip; 863 unsigned char *wb; 864 uint64_t header_offset, header_size, header_unpacksize; 865 uint64_t length; 866 uint32_t header_crc32; 867 int r; 868 869 zip = (struct _7zip *)a->format_data; 870 871 if (zip->total_number_entry > 0) { 872 struct archive_rb_node *n; 873 uint64_t data_offset, data_size, data_unpacksize; 874 unsigned header_compression; 875 876 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); 877 if (r < 0) 878 return (r); 879 data_offset = 0; 880 data_size = zip->stream.total_out; 881 data_unpacksize = zip->stream.total_in; 882 zip->coder.codec = zip->opt_compression; 883 zip->coder.prop_size = zip->stream.prop_size; 884 zip->coder.props = zip->stream.props; 885 zip->stream.prop_size = 0; 886 zip->stream.props = NULL; 887 zip->total_number_nonempty_entry = 888 zip->total_number_entry - zip->total_number_empty_entry; 889 890 /* Connect an empty file list. */ 891 if (zip->empty_list.first != NULL) { 892 *zip->file_list.last = zip->empty_list.first; 893 zip->file_list.last = zip->empty_list.last; 894 } 895 /* Connect a directory file list. */ 896 ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) { 897 file_register(zip, (struct file *)n); 898 } 899 900 /* 901 * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for 902 * the compression type for encoding the header. 903 */ 904 #if HAVE_LZMA_H 905 header_compression = _7Z_LZMA1; 906 if(zip->opt_compression == _7Z_LZMA2 || 907 zip->opt_compression == _7Z_COPY) 908 header_compression = zip->opt_compression; 909 910 /* If the stored file is only one, do not encode the header. 911 * This is the same way 7z command does. */ 912 if (zip->total_number_entry == 1) 913 header_compression = _7Z_COPY; 914 #else 915 header_compression = _7Z_COPY; 916 #endif 917 918 int level = zip->opt_compression_level; 919 if (level < 0) level = 0; 920 else if (level > 9) level = 9; 921 922 r = _7z_compression_init_encoder(a, header_compression, level); 923 if (r < 0) 924 return (r); 925 zip->crc32flg = PRECODE_CRC32; 926 zip->precode_crc32 = 0; 927 r = make_header(a, data_offset, data_size, data_unpacksize, 928 1, &(zip->coder)); 929 if (r < 0) 930 return (r); 931 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); 932 if (r < 0) 933 return (r); 934 header_offset = data_offset + data_size; 935 header_size = zip->stream.total_out; 936 header_crc32 = zip->precode_crc32; 937 header_unpacksize = zip->stream.total_in; 938 939 if (header_compression != _7Z_COPY) { 940 /* 941 * Encode the header in order to reduce the size 942 * of the archive. 943 */ 944 free(zip->coder.props); 945 zip->coder.codec = header_compression; 946 zip->coder.prop_size = zip->stream.prop_size; 947 zip->coder.props = zip->stream.props; 948 zip->stream.prop_size = 0; 949 zip->stream.props = NULL; 950 951 r = _7z_compression_init_encoder(a, _7Z_COPY, 0); 952 if (r < 0) 953 return (r); 954 zip->crc32flg = ENCODED_CRC32; 955 zip->encoded_crc32 = 0; 956 957 /* 958 * Make EncodedHeader. 959 */ 960 r = enc_uint64(a, kEncodedHeader); 961 if (r < 0) 962 return (r); 963 r = make_streamsInfo(a, header_offset, header_size, 964 header_unpacksize, 1, &(zip->coder), 0, 965 header_crc32); 966 if (r < 0) 967 return (r); 968 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); 969 if (r < 0) 970 return (r); 971 header_offset = header_offset + header_size; 972 header_size = zip->stream.total_out; 973 header_crc32 = zip->encoded_crc32; 974 } 975 zip->crc32flg = 0; 976 } else { 977 header_offset = header_size = 0; 978 header_crc32 = 0; 979 } 980 981 length = zip->temp_offset; 982 983 /* 984 * Make the zip header on wbuff(write buffer). 985 */ 986 wb = zip->wbuff; 987 zip->wbuff_remaining = sizeof(zip->wbuff); 988 memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6); 989 wb[6] = 0;/* Major version. */ 990 wb[7] = 3;/* Minor version. */ 991 archive_le64enc(&wb[12], header_offset);/* Next Header Offset */ 992 archive_le64enc(&wb[20], header_size);/* Next Header Size */ 993 archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */ 994 archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */ 995 zip->wbuff_remaining -= 32; 996 997 /* 998 * Read all file contents and an encoded header from the temporary 999 * file and write out it. 1000 */ 1001 r = copy_out(a, 0, length); 1002 if (r != ARCHIVE_OK) 1003 return (r); 1004 r = flush_wbuff(a); 1005 return (r); 1006 } 1007 1008 /* 1009 * Encode 64 bits value into 7-Zip's encoded UINT64 value. 1010 */ 1011 static int 1012 enc_uint64(struct archive_write *a, uint64_t val) 1013 { 1014 unsigned mask = 0x80; 1015 uint8_t numdata[9]; 1016 int i; 1017 1018 numdata[0] = 0; 1019 for (i = 1; i < (int)sizeof(numdata); i++) { 1020 if (val < mask) { 1021 numdata[0] |= (uint8_t)val; 1022 break; 1023 } 1024 numdata[i] = (uint8_t)val; 1025 val >>= 8; 1026 numdata[0] |= mask; 1027 mask >>= 1; 1028 } 1029 return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN)); 1030 } 1031 1032 static int 1033 make_substreamsInfo(struct archive_write *a, struct coder *coders) 1034 { 1035 struct _7zip *zip = (struct _7zip *)a->format_data; 1036 struct file *file; 1037 int r; 1038 1039 /* 1040 * Make SubStreamsInfo. 1041 */ 1042 r = enc_uint64(a, kSubStreamsInfo); 1043 if (r < 0) 1044 return (r); 1045 1046 if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) { 1047 /* 1048 * Make NumUnPackStream. 1049 */ 1050 r = enc_uint64(a, kNumUnPackStream); 1051 if (r < 0) 1052 return (r); 1053 1054 /* Write numUnpackStreams */ 1055 r = enc_uint64(a, zip->total_number_nonempty_entry); 1056 if (r < 0) 1057 return (r); 1058 1059 /* 1060 * Make kSize. 1061 */ 1062 r = enc_uint64(a, kSize); 1063 if (r < 0) 1064 return (r); 1065 file = zip->file_list.first; 1066 for (;file != NULL; file = file->next) { 1067 if (file->next == NULL || 1068 file->next->size == 0) 1069 break; 1070 r = enc_uint64(a, file->size); 1071 if (r < 0) 1072 return (r); 1073 } 1074 } 1075 1076 /* 1077 * Make CRC. 1078 */ 1079 r = enc_uint64(a, kCRC); 1080 if (r < 0) 1081 return (r); 1082 1083 1084 /* All are defined */ 1085 r = enc_uint64(a, 1); 1086 if (r < 0) 1087 return (r); 1088 file = zip->file_list.first; 1089 for (;file != NULL; file = file->next) { 1090 uint8_t crc[4]; 1091 if (file->size == 0) 1092 break; 1093 archive_le32enc(crc, file->crc32); 1094 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); 1095 if (r < 0) 1096 return (r); 1097 } 1098 1099 /* Write End. */ 1100 r = enc_uint64(a, kEnd); 1101 if (r < 0) 1102 return (r); 1103 return (ARCHIVE_OK); 1104 } 1105 1106 static int 1107 make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size, 1108 uint64_t unpack_size, int num_coder, struct coder *coders, int substrm, 1109 uint32_t header_crc) 1110 { 1111 struct _7zip *zip = (struct _7zip *)a->format_data; 1112 uint8_t codec_buff[8]; 1113 int numFolders, fi; 1114 int codec_size; 1115 int i, r; 1116 1117 if (coders->codec == _7Z_COPY) 1118 numFolders = (int)zip->total_number_nonempty_entry; 1119 else 1120 numFolders = 1; 1121 1122 /* 1123 * Make PackInfo. 1124 */ 1125 r = enc_uint64(a, kPackInfo); 1126 if (r < 0) 1127 return (r); 1128 1129 /* Write PackPos. */ 1130 r = enc_uint64(a, offset); 1131 if (r < 0) 1132 return (r); 1133 1134 /* Write NumPackStreams. */ 1135 r = enc_uint64(a, numFolders); 1136 if (r < 0) 1137 return (r); 1138 1139 /* Make Size. */ 1140 r = enc_uint64(a, kSize); 1141 if (r < 0) 1142 return (r); 1143 1144 if (numFolders > 1) { 1145 struct file *file = zip->file_list.first; 1146 for (;file != NULL; file = file->next) { 1147 if (file->size == 0) 1148 break; 1149 r = enc_uint64(a, file->size); 1150 if (r < 0) 1151 return (r); 1152 } 1153 } else { 1154 /* Write size. */ 1155 r = enc_uint64(a, pack_size); 1156 if (r < 0) 1157 return (r); 1158 } 1159 1160 r = enc_uint64(a, kEnd); 1161 if (r < 0) 1162 return (r); 1163 1164 /* 1165 * Make UnPackInfo. 1166 */ 1167 r = enc_uint64(a, kUnPackInfo); 1168 if (r < 0) 1169 return (r); 1170 1171 /* 1172 * Make Folder. 1173 */ 1174 r = enc_uint64(a, kFolder); 1175 if (r < 0) 1176 return (r); 1177 1178 /* Write NumFolders. */ 1179 r = enc_uint64(a, numFolders); 1180 if (r < 0) 1181 return (r); 1182 1183 /* Write External. */ 1184 r = enc_uint64(a, 0); 1185 if (r < 0) 1186 return (r); 1187 1188 for (fi = 0; fi < numFolders; fi++) { 1189 /* Write NumCoders. */ 1190 r = enc_uint64(a, num_coder); 1191 if (r < 0) 1192 return (r); 1193 1194 for (i = 0; i < num_coder; i++) { 1195 unsigned codec_id = coders[i].codec; 1196 1197 /* Write Codec flag. */ 1198 archive_be64enc(codec_buff, codec_id); 1199 for (codec_size = 8; codec_size > 0; codec_size--) { 1200 if (codec_buff[8 - codec_size]) 1201 break; 1202 } 1203 if (codec_size == 0) 1204 codec_size = 1; 1205 if (coders[i].prop_size) 1206 r = enc_uint64(a, codec_size | 0x20); 1207 else 1208 r = enc_uint64(a, codec_size); 1209 if (r < 0) 1210 return (r); 1211 1212 /* Write Codec ID. */ 1213 codec_size &= 0x0f; 1214 r = (int)compress_out(a, &codec_buff[8-codec_size], 1215 codec_size, ARCHIVE_Z_RUN); 1216 if (r < 0) 1217 return (r); 1218 1219 if (coders[i].prop_size) { 1220 /* Write Codec property size. */ 1221 r = enc_uint64(a, coders[i].prop_size); 1222 if (r < 0) 1223 return (r); 1224 1225 /* Write Codec properties. */ 1226 r = (int)compress_out(a, coders[i].props, 1227 coders[i].prop_size, ARCHIVE_Z_RUN); 1228 if (r < 0) 1229 return (r); 1230 } 1231 } 1232 } 1233 1234 /* 1235 * Make CodersUnPackSize. 1236 */ 1237 r = enc_uint64(a, kCodersUnPackSize); 1238 if (r < 0) 1239 return (r); 1240 1241 if (numFolders > 1) { 1242 struct file *file = zip->file_list.first; 1243 for (;file != NULL; file = file->next) { 1244 if (file->size == 0) 1245 break; 1246 r = enc_uint64(a, file->size); 1247 if (r < 0) 1248 return (r); 1249 } 1250 1251 } else { 1252 /* Write UnPackSize. */ 1253 r = enc_uint64(a, unpack_size); 1254 if (r < 0) 1255 return (r); 1256 } 1257 1258 if (!substrm) { 1259 uint8_t crc[4]; 1260 /* 1261 * Make CRC. 1262 */ 1263 r = enc_uint64(a, kCRC); 1264 if (r < 0) 1265 return (r); 1266 1267 /* All are defined */ 1268 r = enc_uint64(a, 1); 1269 if (r < 0) 1270 return (r); 1271 archive_le32enc(crc, header_crc); 1272 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); 1273 if (r < 0) 1274 return (r); 1275 } 1276 1277 /* Write End. */ 1278 r = enc_uint64(a, kEnd); 1279 if (r < 0) 1280 return (r); 1281 1282 if (substrm) { 1283 /* 1284 * Make SubStreamsInfo. 1285 */ 1286 r = make_substreamsInfo(a, coders); 1287 if (r < 0) 1288 return (r); 1289 } 1290 1291 1292 /* Write End. */ 1293 r = enc_uint64(a, kEnd); 1294 if (r < 0) 1295 return (r); 1296 1297 return (ARCHIVE_OK); 1298 } 1299 1300 static int 1301 make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti) 1302 { 1303 uint8_t filetime[8]; 1304 struct _7zip *zip = (struct _7zip *)a->format_data; 1305 struct file *file; 1306 int r; 1307 uint8_t b, mask; 1308 1309 /* 1310 * Make Time Bools. 1311 */ 1312 if (zip->total_number_time_defined[ti] == zip->total_number_entry) { 1313 /* Write Time Type. */ 1314 r = enc_uint64(a, type); 1315 if (r < 0) 1316 return (r); 1317 /* Write EmptyStream Size. */ 1318 r = enc_uint64(a, 2 + zip->total_number_entry * 8); 1319 if (r < 0) 1320 return (r); 1321 /* All are defined. */ 1322 r = enc_uint64(a, 1); 1323 if (r < 0) 1324 return (r); 1325 } else { 1326 if (zip->total_number_time_defined[ti] == 0) 1327 return (ARCHIVE_OK); 1328 1329 /* Write Time Type. */ 1330 r = enc_uint64(a, type); 1331 if (r < 0) 1332 return (r); 1333 /* Write EmptyStream Size. */ 1334 r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3) 1335 + zip->total_number_time_defined[ti] * 8); 1336 if (r < 0) 1337 return (r); 1338 1339 /* All are not defined. */ 1340 r = enc_uint64(a, 0); 1341 if (r < 0) 1342 return (r); 1343 1344 b = 0; 1345 mask = 0x80; 1346 file = zip->file_list.first; 1347 for (;file != NULL; file = file->next) { 1348 if (file->flg & flg) 1349 b |= mask; 1350 mask >>= 1; 1351 if (mask == 0) { 1352 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1353 if (r < 0) 1354 return (r); 1355 mask = 0x80; 1356 b = 0; 1357 } 1358 } 1359 if (mask != 0x80) { 1360 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1361 if (r < 0) 1362 return (r); 1363 } 1364 } 1365 1366 /* External. */ 1367 r = enc_uint64(a, 0); 1368 if (r < 0) 1369 return (r); 1370 1371 /* 1372 * Make Times. 1373 */ 1374 file = zip->file_list.first; 1375 for (;file != NULL; file = file->next) { 1376 if ((file->flg & flg) == 0) 1377 continue; 1378 archive_le64enc(filetime, unix_to_ntfs(file->times[ti].time, 1379 file->times[ti].time_ns)); 1380 r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN); 1381 if (r < 0) 1382 return (r); 1383 } 1384 1385 return (ARCHIVE_OK); 1386 } 1387 1388 static int 1389 make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size, 1390 uint64_t unpack_size, int codernum, struct coder *coders) 1391 { 1392 struct _7zip *zip = (struct _7zip *)a->format_data; 1393 struct file *file; 1394 int r; 1395 uint8_t b, mask; 1396 1397 /* 1398 * Make FilesInfo. 1399 */ 1400 r = enc_uint64(a, kHeader); 1401 if (r < 0) 1402 return (r); 1403 1404 /* 1405 * If there are empty files only, do not write MainStreamInfo. 1406 */ 1407 if (zip->total_number_nonempty_entry) { 1408 /* 1409 * Make MainStreamInfo. 1410 */ 1411 r = enc_uint64(a, kMainStreamsInfo); 1412 if (r < 0) 1413 return (r); 1414 r = make_streamsInfo(a, offset, pack_size, unpack_size, 1415 codernum, coders, 1, 0); 1416 if (r < 0) 1417 return (r); 1418 } 1419 1420 /* 1421 * Make FilesInfo. 1422 */ 1423 r = enc_uint64(a, kFilesInfo); 1424 if (r < 0) 1425 return (r); 1426 1427 /* Write numFiles. */ 1428 r = enc_uint64(a, zip->total_number_entry); 1429 if (r < 0) 1430 return (r); 1431 1432 if (zip->total_number_empty_entry > 0) { 1433 /* Make EmptyStream. */ 1434 r = enc_uint64(a, kEmptyStream); 1435 if (r < 0) 1436 return (r); 1437 1438 /* Write EmptyStream Size. */ 1439 r = enc_uint64(a, (zip->total_number_entry+7)>>3); 1440 if (r < 0) 1441 return (r); 1442 1443 b = 0; 1444 mask = 0x80; 1445 file = zip->file_list.first; 1446 for (;file != NULL; file = file->next) { 1447 if (file->size == 0) 1448 b |= mask; 1449 mask >>= 1; 1450 if (mask == 0) { 1451 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1452 if (r < 0) 1453 return (r); 1454 mask = 0x80; 1455 b = 0; 1456 } 1457 } 1458 if (mask != 0x80) { 1459 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1460 if (r < 0) 1461 return (r); 1462 } 1463 } 1464 1465 if (zip->total_number_empty_entry > zip->total_number_dir_entry) { 1466 /* Make EmptyFile. */ 1467 r = enc_uint64(a, kEmptyFile); 1468 if (r < 0) 1469 return (r); 1470 1471 /* Write EmptyFile Size. */ 1472 r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3); 1473 if (r < 0) 1474 return (r); 1475 1476 b = 0; 1477 mask = 0x80; 1478 file = zip->file_list.first; 1479 for (;file != NULL; file = file->next) { 1480 if (file->size) 1481 continue; 1482 if (!file->dir) 1483 b |= mask; 1484 mask >>= 1; 1485 if (mask == 0) { 1486 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1487 if (r < 0) 1488 return (r); 1489 mask = 0x80; 1490 b = 0; 1491 } 1492 } 1493 if (mask != 0x80) { 1494 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1495 if (r < 0) 1496 return (r); 1497 } 1498 } 1499 1500 /* Make Name. */ 1501 r = enc_uint64(a, kName); 1502 if (r < 0) 1503 return (r); 1504 1505 /* Write Name size. */ 1506 r = enc_uint64(a, zip->total_bytes_entry_name+1); 1507 if (r < 0) 1508 return (r); 1509 1510 /* Write dmy byte. */ 1511 r = enc_uint64(a, 0); 1512 if (r < 0) 1513 return (r); 1514 1515 file = zip->file_list.first; 1516 for (;file != NULL; file = file->next) { 1517 r = (int)compress_out(a, file->utf16name, file->name_len+2, 1518 ARCHIVE_Z_RUN); 1519 if (r < 0) 1520 return (r); 1521 } 1522 1523 /* Make MTime. */ 1524 r = make_time(a, kMTime, MTIME_IS_SET, MTIME); 1525 if (r < 0) 1526 return (r); 1527 1528 /* Make CTime. */ 1529 r = make_time(a, kCTime, CTIME_IS_SET, CTIME); 1530 if (r < 0) 1531 return (r); 1532 1533 /* Make ATime. */ 1534 r = make_time(a, kATime, ATIME_IS_SET, ATIME); 1535 if (r < 0) 1536 return (r); 1537 1538 /* Make Attributes. */ 1539 r = enc_uint64(a, kAttributes); 1540 if (r < 0) 1541 return (r); 1542 1543 /* Write Attributes size. */ 1544 r = enc_uint64(a, 2 + zip->total_number_entry * 4); 1545 if (r < 0) 1546 return (r); 1547 1548 /* Write "All Are Defined". */ 1549 r = enc_uint64(a, 1); 1550 if (r < 0) 1551 return (r); 1552 1553 /* Write dmy byte. */ 1554 r = enc_uint64(a, 0); 1555 if (r < 0) 1556 return (r); 1557 1558 file = zip->file_list.first; 1559 for (;file != NULL; file = file->next) { 1560 /* 1561 * High 16bits is unix mode. 1562 * Low 16bits is Windows attributes. 1563 */ 1564 uint32_t encattr, attr = 0; 1565 1566 if (file->dir) 1567 attr |= FILE_ATTRIBUTE_DIRECTORY; 1568 else 1569 attr |= FILE_ATTRIBUTE_ARCHIVE; 1570 1571 if ((file->mode & 0222) == 0) 1572 attr |= FILE_ATTRIBUTE_READONLY; 1573 1574 attr |= FILE_ATTRIBUTE_UNIX_EXTENSION; 1575 attr |= ((uint32_t)file->mode) << 16; 1576 1577 archive_le32enc(&encattr, attr); 1578 r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN); 1579 if (r < 0) 1580 return (r); 1581 } 1582 1583 /* Write End. */ 1584 r = enc_uint64(a, kEnd); 1585 if (r < 0) 1586 return (r); 1587 1588 /* Write End. */ 1589 r = enc_uint64(a, kEnd); 1590 if (r < 0) 1591 return (r); 1592 1593 return (ARCHIVE_OK); 1594 } 1595 1596 1597 static int 1598 _7z_free(struct archive_write *a) 1599 { 1600 struct _7zip *zip = (struct _7zip *)a->format_data; 1601 1602 /* Close the temporary file. */ 1603 if (zip->temp_fd >= 0) 1604 close(zip->temp_fd); 1605 1606 file_free_register(zip); 1607 compression_end(&(a->archive), &(zip->stream)); 1608 free(zip->coder.props); 1609 free(zip); 1610 1611 return (ARCHIVE_OK); 1612 } 1613 1614 static int 1615 file_cmp_node(const struct archive_rb_node *n1, 1616 const struct archive_rb_node *n2) 1617 { 1618 const struct file *f1 = (const struct file *)n1; 1619 const struct file *f2 = (const struct file *)n2; 1620 1621 if (f1->name_len == f2->name_len) 1622 return (memcmp(f1->utf16name, f2->utf16name, f1->name_len)); 1623 return (f1->name_len > f2->name_len)?1:-1; 1624 } 1625 1626 static int 1627 file_cmp_key(const struct archive_rb_node *n, const void *key) 1628 { 1629 const struct file *f = (const struct file *)n; 1630 1631 return (f->name_len - *(const char *)key); 1632 } 1633 1634 static int 1635 file_new(struct archive_write *a, struct archive_entry *entry, 1636 struct file **newfile) 1637 { 1638 struct _7zip *zip; 1639 struct file *file; 1640 const char *u16; 1641 size_t u16len; 1642 int ret = ARCHIVE_OK; 1643 1644 zip = (struct _7zip *)a->format_data; 1645 *newfile = NULL; 1646 1647 file = calloc(1, sizeof(*file)); 1648 if (file == NULL) { 1649 archive_set_error(&a->archive, ENOMEM, 1650 "Can't allocate memory"); 1651 return (ARCHIVE_FATAL); 1652 } 1653 1654 if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) { 1655 if (errno == ENOMEM) { 1656 free(file); 1657 archive_set_error(&a->archive, ENOMEM, 1658 "Can't allocate memory for UTF-16LE"); 1659 return (ARCHIVE_FATAL); 1660 } 1661 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1662 "A filename cannot be converted to UTF-16LE;" 1663 "You should disable making Joliet extension"); 1664 ret = ARCHIVE_WARN; 1665 } 1666 file->utf16name = malloc(u16len + 2); 1667 if (file->utf16name == NULL) { 1668 free(file); 1669 archive_set_error(&a->archive, ENOMEM, 1670 "Can't allocate memory for Name"); 1671 return (ARCHIVE_FATAL); 1672 } 1673 memcpy(file->utf16name, u16, u16len); 1674 file->utf16name[u16len+0] = 0; 1675 file->utf16name[u16len+1] = 0; 1676 file->name_len = (unsigned)u16len; 1677 file->mode = archive_entry_mode(entry); 1678 if (archive_entry_filetype(entry) == AE_IFREG) 1679 file->size = archive_entry_size(entry); 1680 else 1681 archive_entry_set_size(entry, 0); 1682 if (archive_entry_filetype(entry) == AE_IFDIR) 1683 file->dir = 1; 1684 else if (archive_entry_filetype(entry) == AE_IFLNK) { 1685 const char* linkpath; 1686 linkpath = archive_entry_symlink_utf8(entry); 1687 if (linkpath == NULL) { 1688 free(file); 1689 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1690 "symlink path could not be converted to UTF-8"); 1691 return (ARCHIVE_FAILED); 1692 } 1693 else 1694 file->size = strlen(linkpath); 1695 } 1696 if (archive_entry_mtime_is_set(entry)) { 1697 file->flg |= MTIME_IS_SET; 1698 file->times[MTIME].time = archive_entry_mtime(entry); 1699 file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry); 1700 } 1701 if (archive_entry_atime_is_set(entry)) { 1702 file->flg |= ATIME_IS_SET; 1703 file->times[ATIME].time = archive_entry_atime(entry); 1704 file->times[ATIME].time_ns = archive_entry_atime_nsec(entry); 1705 } 1706 if (archive_entry_ctime_is_set(entry)) { 1707 file->flg |= CTIME_IS_SET; 1708 file->times[CTIME].time = archive_entry_ctime(entry); 1709 file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry); 1710 } 1711 1712 *newfile = file; 1713 return (ret); 1714 } 1715 1716 static void 1717 file_free(struct file *file) 1718 { 1719 free(file->utf16name); 1720 free(file); 1721 } 1722 1723 static void 1724 file_register(struct _7zip *zip, struct file *file) 1725 { 1726 file->next = NULL; 1727 *zip->file_list.last = file; 1728 zip->file_list.last = &(file->next); 1729 } 1730 1731 static void 1732 file_init_register(struct _7zip *zip) 1733 { 1734 zip->file_list.first = NULL; 1735 zip->file_list.last = &(zip->file_list.first); 1736 } 1737 1738 static void 1739 file_free_register(struct _7zip *zip) 1740 { 1741 struct file *file, *file_next; 1742 1743 file = zip->file_list.first; 1744 while (file != NULL) { 1745 file_next = file->next; 1746 file_free(file); 1747 file = file_next; 1748 } 1749 } 1750 1751 static void 1752 file_register_empty(struct _7zip *zip, struct file *file) 1753 { 1754 file->next = NULL; 1755 *zip->empty_list.last = file; 1756 zip->empty_list.last = &(file->next); 1757 } 1758 1759 static void 1760 file_init_register_empty(struct _7zip *zip) 1761 { 1762 zip->empty_list.first = NULL; 1763 zip->empty_list.last = &(zip->empty_list.first); 1764 } 1765 1766 #if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\ 1767 !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) ||\ 1768 !(HAVE_ZSTD_H && HAVE_ZSTD_compressStream) 1769 static int 1770 compression_unsupported_encoder(struct archive *a, 1771 struct la_zstream *lastrm, const char *name) 1772 { 1773 1774 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1775 "%s compression not supported on this platform", name); 1776 lastrm->valid = 0; 1777 lastrm->real_stream = NULL; 1778 return (ARCHIVE_FAILED); 1779 } 1780 #endif 1781 1782 /* 1783 * _7_COPY compressor. 1784 */ 1785 static int 1786 compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm) 1787 { 1788 1789 if (lastrm->valid) 1790 compression_end(a, lastrm); 1791 lastrm->valid = 1; 1792 lastrm->code = compression_code_copy; 1793 lastrm->end = compression_end_copy; 1794 return (ARCHIVE_OK); 1795 } 1796 1797 static int 1798 compression_code_copy(struct archive *a, 1799 struct la_zstream *lastrm, enum la_zaction action) 1800 { 1801 size_t bytes; 1802 1803 (void)a; /* UNUSED */ 1804 if (lastrm->avail_out > lastrm->avail_in) 1805 bytes = lastrm->avail_in; 1806 else 1807 bytes = lastrm->avail_out; 1808 if (bytes) { 1809 memcpy(lastrm->next_out, lastrm->next_in, bytes); 1810 lastrm->next_in += bytes; 1811 lastrm->avail_in -= bytes; 1812 lastrm->total_in += bytes; 1813 lastrm->next_out += bytes; 1814 lastrm->avail_out -= bytes; 1815 lastrm->total_out += bytes; 1816 } 1817 if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0) 1818 return (ARCHIVE_EOF); 1819 return (ARCHIVE_OK); 1820 } 1821 1822 static int 1823 compression_end_copy(struct archive *a, struct la_zstream *lastrm) 1824 { 1825 (void)a; /* UNUSED */ 1826 lastrm->valid = 0; 1827 return (ARCHIVE_OK); 1828 } 1829 1830 /* 1831 * _7_DEFLATE compressor. 1832 */ 1833 #ifdef HAVE_ZLIB_H 1834 static int 1835 compression_init_encoder_deflate(struct archive *a, 1836 struct la_zstream *lastrm, int level, int withheader) 1837 { 1838 z_stream *strm; 1839 1840 if (lastrm->valid) 1841 compression_end(a, lastrm); 1842 strm = calloc(1, sizeof(*strm)); 1843 if (strm == NULL) { 1844 archive_set_error(a, ENOMEM, 1845 "Can't allocate memory for gzip stream"); 1846 return (ARCHIVE_FATAL); 1847 } 1848 /* zlib.h is not const-correct, so we need this one bit 1849 * of ugly hackery to convert a const * pointer to 1850 * a non-const pointer. */ 1851 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 1852 strm->avail_in = (uInt)lastrm->avail_in; 1853 strm->total_in = (uLong)lastrm->total_in; 1854 strm->next_out = lastrm->next_out; 1855 strm->avail_out = (uInt)lastrm->avail_out; 1856 strm->total_out = (uLong)lastrm->total_out; 1857 if (deflateInit2(strm, level, Z_DEFLATED, 1858 (withheader)?15:-15, 1859 8, Z_DEFAULT_STRATEGY) != Z_OK) { 1860 free(strm); 1861 lastrm->real_stream = NULL; 1862 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1863 "Internal error initializing compression library"); 1864 return (ARCHIVE_FATAL); 1865 } 1866 lastrm->real_stream = strm; 1867 lastrm->valid = 1; 1868 lastrm->code = compression_code_deflate; 1869 lastrm->end = compression_end_deflate; 1870 return (ARCHIVE_OK); 1871 } 1872 1873 static int 1874 compression_code_deflate(struct archive *a, 1875 struct la_zstream *lastrm, enum la_zaction action) 1876 { 1877 z_stream *strm; 1878 int r; 1879 1880 strm = (z_stream *)lastrm->real_stream; 1881 /* zlib.h is not const-correct, so we need this one bit 1882 * of ugly hackery to convert a const * pointer to 1883 * a non-const pointer. */ 1884 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 1885 strm->avail_in = (uInt)lastrm->avail_in; 1886 strm->total_in = (uLong)lastrm->total_in; 1887 strm->next_out = lastrm->next_out; 1888 strm->avail_out = (uInt)lastrm->avail_out; 1889 strm->total_out = (uLong)lastrm->total_out; 1890 r = deflate(strm, 1891 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); 1892 lastrm->next_in = strm->next_in; 1893 lastrm->avail_in = strm->avail_in; 1894 lastrm->total_in = strm->total_in; 1895 lastrm->next_out = strm->next_out; 1896 lastrm->avail_out = strm->avail_out; 1897 lastrm->total_out = strm->total_out; 1898 switch (r) { 1899 case Z_OK: 1900 return (ARCHIVE_OK); 1901 case Z_STREAM_END: 1902 return (ARCHIVE_EOF); 1903 default: 1904 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1905 "GZip compression failed:" 1906 " deflate() call returned status %d", r); 1907 return (ARCHIVE_FATAL); 1908 } 1909 } 1910 1911 static int 1912 compression_end_deflate(struct archive *a, struct la_zstream *lastrm) 1913 { 1914 z_stream *strm; 1915 int r; 1916 1917 strm = (z_stream *)lastrm->real_stream; 1918 r = deflateEnd(strm); 1919 free(strm); 1920 lastrm->real_stream = NULL; 1921 lastrm->valid = 0; 1922 if (r != Z_OK) { 1923 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1924 "Failed to clean up compressor"); 1925 return (ARCHIVE_FATAL); 1926 } 1927 return (ARCHIVE_OK); 1928 } 1929 #else 1930 static int 1931 compression_init_encoder_deflate(struct archive *a, 1932 struct la_zstream *lastrm, int level, int withheader) 1933 { 1934 1935 (void) level; /* UNUSED */ 1936 (void) withheader; /* UNUSED */ 1937 if (lastrm->valid) 1938 compression_end(a, lastrm); 1939 return (compression_unsupported_encoder(a, lastrm, "deflate")); 1940 } 1941 #endif 1942 1943 /* 1944 * _7_BZIP2 compressor. 1945 */ 1946 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 1947 static int 1948 compression_init_encoder_bzip2(struct archive *a, 1949 struct la_zstream *lastrm, int level) 1950 { 1951 bz_stream *strm; 1952 1953 if (lastrm->valid) 1954 compression_end(a, lastrm); 1955 strm = calloc(1, sizeof(*strm)); 1956 if (strm == NULL) { 1957 archive_set_error(a, ENOMEM, 1958 "Can't allocate memory for bzip2 stream"); 1959 return (ARCHIVE_FATAL); 1960 } 1961 /* bzlib.h is not const-correct, so we need this one bit 1962 * of ugly hackery to convert a const * pointer to 1963 * a non-const pointer. */ 1964 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 1965 strm->avail_in = (uint32_t)lastrm->avail_in; 1966 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 1967 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 1968 strm->next_out = (char *)lastrm->next_out; 1969 strm->avail_out = (uint32_t)lastrm->avail_out; 1970 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 1971 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 1972 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { 1973 free(strm); 1974 lastrm->real_stream = NULL; 1975 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1976 "Internal error initializing compression library"); 1977 return (ARCHIVE_FATAL); 1978 } 1979 lastrm->real_stream = strm; 1980 lastrm->valid = 1; 1981 lastrm->code = compression_code_bzip2; 1982 lastrm->end = compression_end_bzip2; 1983 return (ARCHIVE_OK); 1984 } 1985 1986 static int 1987 compression_code_bzip2(struct archive *a, 1988 struct la_zstream *lastrm, enum la_zaction action) 1989 { 1990 bz_stream *strm; 1991 int r; 1992 1993 strm = (bz_stream *)lastrm->real_stream; 1994 /* bzlib.h is not const-correct, so we need this one bit 1995 * of ugly hackery to convert a const * pointer to 1996 * a non-const pointer. */ 1997 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 1998 strm->avail_in = (uint32_t)lastrm->avail_in; 1999 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 2000 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 2001 strm->next_out = (char *)lastrm->next_out; 2002 strm->avail_out = (uint32_t)lastrm->avail_out; 2003 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 2004 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 2005 r = BZ2_bzCompress(strm, 2006 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); 2007 lastrm->next_in = (const unsigned char *)strm->next_in; 2008 lastrm->avail_in = strm->avail_in; 2009 lastrm->total_in = 2010 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) 2011 + (uint64_t)(uint32_t)strm->total_in_lo32; 2012 lastrm->next_out = (unsigned char *)strm->next_out; 2013 lastrm->avail_out = strm->avail_out; 2014 lastrm->total_out = 2015 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) 2016 + (uint64_t)(uint32_t)strm->total_out_lo32; 2017 switch (r) { 2018 case BZ_RUN_OK: /* Non-finishing */ 2019 case BZ_FINISH_OK: /* Finishing: There's more work to do */ 2020 return (ARCHIVE_OK); 2021 case BZ_STREAM_END: /* Finishing: all done */ 2022 /* Only occurs in finishing case */ 2023 return (ARCHIVE_EOF); 2024 default: 2025 /* Any other return value indicates an error */ 2026 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2027 "Bzip2 compression failed:" 2028 " BZ2_bzCompress() call returned status %d", r); 2029 return (ARCHIVE_FATAL); 2030 } 2031 } 2032 2033 static int 2034 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) 2035 { 2036 bz_stream *strm; 2037 int r; 2038 2039 strm = (bz_stream *)lastrm->real_stream; 2040 r = BZ2_bzCompressEnd(strm); 2041 free(strm); 2042 lastrm->real_stream = NULL; 2043 lastrm->valid = 0; 2044 if (r != BZ_OK) { 2045 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2046 "Failed to clean up compressor"); 2047 return (ARCHIVE_FATAL); 2048 } 2049 return (ARCHIVE_OK); 2050 } 2051 2052 #else 2053 static int 2054 compression_init_encoder_bzip2(struct archive *a, 2055 struct la_zstream *lastrm, int level) 2056 { 2057 2058 (void) level; /* UNUSED */ 2059 if (lastrm->valid) 2060 compression_end(a, lastrm); 2061 return (compression_unsupported_encoder(a, lastrm, "bzip2")); 2062 } 2063 #endif 2064 2065 /* 2066 * _7_LZMA1, _7_LZMA2 compressor. 2067 */ 2068 #if defined(HAVE_LZMA_H) 2069 static int 2070 compression_init_encoder_lzma(struct archive *a, 2071 struct la_zstream *lastrm, int level, uint64_t filter_id) 2072 { 2073 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 2074 lzma_stream *strm; 2075 lzma_filter *lzmafilters; 2076 lzma_options_lzma lzma_opt; 2077 int r; 2078 2079 if (lastrm->valid) 2080 compression_end(a, lastrm); 2081 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); 2082 if (strm == NULL) { 2083 archive_set_error(a, ENOMEM, 2084 "Can't allocate memory for lzma stream"); 2085 return (ARCHIVE_FATAL); 2086 } 2087 lzmafilters = (lzma_filter *)(strm+1); 2088 if (level > 9) 2089 level = 9; 2090 if (lzma_lzma_preset(&lzma_opt, level)) { 2091 free(strm); 2092 lastrm->real_stream = NULL; 2093 archive_set_error(a, ENOMEM, 2094 "Internal error initializing compression library"); 2095 return (ARCHIVE_FATAL); 2096 } 2097 lzmafilters[0].id = filter_id; 2098 lzmafilters[0].options = &lzma_opt; 2099 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ 2100 2101 r = lzma_properties_size(&(lastrm->prop_size), lzmafilters); 2102 if (r != LZMA_OK) { 2103 free(strm); 2104 lastrm->real_stream = NULL; 2105 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2106 "lzma_properties_size failed"); 2107 return (ARCHIVE_FATAL); 2108 } 2109 if (lastrm->prop_size) { 2110 lastrm->props = malloc(lastrm->prop_size); 2111 if (lastrm->props == NULL) { 2112 free(strm); 2113 lastrm->real_stream = NULL; 2114 archive_set_error(a, ENOMEM, 2115 "Cannot allocate memory"); 2116 return (ARCHIVE_FATAL); 2117 } 2118 r = lzma_properties_encode(lzmafilters, lastrm->props); 2119 if (r != LZMA_OK) { 2120 free(strm); 2121 lastrm->real_stream = NULL; 2122 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2123 "lzma_properties_encode failed"); 2124 return (ARCHIVE_FATAL); 2125 } 2126 } 2127 2128 *strm = lzma_init_data; 2129 r = lzma_raw_encoder(strm, lzmafilters); 2130 switch (r) { 2131 case LZMA_OK: 2132 lastrm->real_stream = strm; 2133 lastrm->valid = 1; 2134 lastrm->code = compression_code_lzma; 2135 lastrm->end = compression_end_lzma; 2136 r = ARCHIVE_OK; 2137 break; 2138 case LZMA_MEM_ERROR: 2139 free(strm); 2140 lastrm->real_stream = NULL; 2141 archive_set_error(a, ENOMEM, 2142 "Internal error initializing compression library: " 2143 "Cannot allocate memory"); 2144 r = ARCHIVE_FATAL; 2145 break; 2146 default: 2147 free(strm); 2148 lastrm->real_stream = NULL; 2149 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2150 "Internal error initializing compression library: " 2151 "It's a bug in liblzma"); 2152 r = ARCHIVE_FATAL; 2153 break; 2154 } 2155 return (r); 2156 } 2157 2158 static int 2159 compression_init_encoder_lzma1(struct archive *a, 2160 struct la_zstream *lastrm, int level) 2161 { 2162 return compression_init_encoder_lzma(a, lastrm, level, 2163 LZMA_FILTER_LZMA1); 2164 } 2165 2166 static int 2167 compression_init_encoder_lzma2(struct archive *a, 2168 struct la_zstream *lastrm, int level) 2169 { 2170 return compression_init_encoder_lzma(a, lastrm, level, 2171 LZMA_FILTER_LZMA2); 2172 } 2173 2174 static int 2175 compression_code_lzma(struct archive *a, 2176 struct la_zstream *lastrm, enum la_zaction action) 2177 { 2178 lzma_stream *strm; 2179 int r; 2180 2181 strm = (lzma_stream *)lastrm->real_stream; 2182 strm->next_in = lastrm->next_in; 2183 strm->avail_in = lastrm->avail_in; 2184 strm->total_in = lastrm->total_in; 2185 strm->next_out = lastrm->next_out; 2186 strm->avail_out = lastrm->avail_out; 2187 strm->total_out = lastrm->total_out; 2188 r = lzma_code(strm, 2189 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); 2190 lastrm->next_in = strm->next_in; 2191 lastrm->avail_in = strm->avail_in; 2192 lastrm->total_in = strm->total_in; 2193 lastrm->next_out = strm->next_out; 2194 lastrm->avail_out = strm->avail_out; 2195 lastrm->total_out = strm->total_out; 2196 switch (r) { 2197 case LZMA_OK: 2198 /* Non-finishing case */ 2199 return (ARCHIVE_OK); 2200 case LZMA_STREAM_END: 2201 /* This return can only occur in finishing case. */ 2202 return (ARCHIVE_EOF); 2203 case LZMA_MEMLIMIT_ERROR: 2204 archive_set_error(a, ENOMEM, 2205 "lzma compression error:" 2206 " %ju MiB would have been needed", 2207 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) 2208 / (1024 * 1024))); 2209 return (ARCHIVE_FATAL); 2210 default: 2211 /* Any other return value indicates an error */ 2212 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2213 "lzma compression failed:" 2214 " lzma_code() call returned status %d", r); 2215 return (ARCHIVE_FATAL); 2216 } 2217 } 2218 2219 static int 2220 compression_end_lzma(struct archive *a, struct la_zstream *lastrm) 2221 { 2222 lzma_stream *strm; 2223 2224 (void)a; /* UNUSED */ 2225 strm = (lzma_stream *)lastrm->real_stream; 2226 lzma_end(strm); 2227 free(strm); 2228 lastrm->valid = 0; 2229 lastrm->real_stream = NULL; 2230 return (ARCHIVE_OK); 2231 } 2232 #else 2233 static int 2234 compression_init_encoder_lzma1(struct archive *a, 2235 struct la_zstream *lastrm, int level) 2236 { 2237 2238 (void) level; /* UNUSED */ 2239 if (lastrm->valid) 2240 compression_end(a, lastrm); 2241 return (compression_unsupported_encoder(a, lastrm, "lzma")); 2242 } 2243 static int 2244 compression_init_encoder_lzma2(struct archive *a, 2245 struct la_zstream *lastrm, int level) 2246 { 2247 2248 (void) level; /* UNUSED */ 2249 if (lastrm->valid) 2250 compression_end(a, lastrm); 2251 return (compression_unsupported_encoder(a, lastrm, "lzma")); 2252 } 2253 #endif 2254 2255 /* 2256 * _7_PPMD compressor. 2257 */ 2258 static void 2259 ppmd_write(void *p, Byte b) 2260 { 2261 struct archive_write *a = ((IByteOut *)p)->a; 2262 struct _7zip *zip = (struct _7zip *)(a->format_data); 2263 struct la_zstream *lastrm = &(zip->stream); 2264 struct ppmd_stream *strm; 2265 2266 if (lastrm->avail_out) { 2267 *lastrm->next_out++ = b; 2268 lastrm->avail_out--; 2269 lastrm->total_out++; 2270 return; 2271 } 2272 strm = (struct ppmd_stream *)lastrm->real_stream; 2273 if (strm->buff_ptr < strm->buff_end) { 2274 *strm->buff_ptr++ = b; 2275 strm->buff_bytes++; 2276 } 2277 } 2278 2279 static int 2280 compression_init_encoder_ppmd(struct archive *a, 2281 struct la_zstream *lastrm, uint8_t maxOrder, uint32_t msize) 2282 { 2283 struct ppmd_stream *strm; 2284 uint8_t *props; 2285 int r; 2286 2287 if (lastrm->valid) 2288 compression_end(a, lastrm); 2289 strm = calloc(1, sizeof(*strm)); 2290 if (strm == NULL) { 2291 archive_set_error(a, ENOMEM, 2292 "Can't allocate memory for PPMd"); 2293 return (ARCHIVE_FATAL); 2294 } 2295 strm->buff = malloc(32); 2296 if (strm->buff == NULL) { 2297 free(strm); 2298 archive_set_error(a, ENOMEM, 2299 "Can't allocate memory for PPMd"); 2300 return (ARCHIVE_FATAL); 2301 } 2302 strm->buff_ptr = strm->buff; 2303 strm->buff_end = strm->buff + 32; 2304 2305 props = malloc(1+4); 2306 if (props == NULL) { 2307 free(strm->buff); 2308 free(strm); 2309 archive_set_error(a, ENOMEM, 2310 "Coludn't allocate memory for PPMd"); 2311 return (ARCHIVE_FATAL); 2312 } 2313 props[0] = maxOrder; 2314 archive_le32enc(props+1, msize); 2315 __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context); 2316 r = __archive_ppmd7_functions.Ppmd7_Alloc( 2317 &strm->ppmd7_context, msize); 2318 if (r == 0) { 2319 free(strm->buff); 2320 free(strm); 2321 free(props); 2322 archive_set_error(a, ENOMEM, 2323 "Coludn't allocate memory for PPMd"); 2324 return (ARCHIVE_FATAL); 2325 } 2326 __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder); 2327 strm->byteout.a = (struct archive_write *)a; 2328 strm->byteout.Write = ppmd_write; 2329 strm->range_enc.Stream = &(strm->byteout); 2330 __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc)); 2331 strm->stat = 0; 2332 2333 lastrm->real_stream = strm; 2334 lastrm->valid = 1; 2335 lastrm->code = compression_code_ppmd; 2336 lastrm->end = compression_end_ppmd; 2337 lastrm->prop_size = 5; 2338 lastrm->props = props; 2339 return (ARCHIVE_OK); 2340 } 2341 2342 static int 2343 compression_code_ppmd(struct archive *a, 2344 struct la_zstream *lastrm, enum la_zaction action) 2345 { 2346 struct ppmd_stream *strm; 2347 2348 (void)a; /* UNUSED */ 2349 2350 strm = (struct ppmd_stream *)lastrm->real_stream; 2351 2352 /* Copy encoded data if there are remaining bytes from previous call. */ 2353 if (strm->buff_bytes) { 2354 uint8_t *p = strm->buff_ptr - strm->buff_bytes; 2355 while (lastrm->avail_out && strm->buff_bytes) { 2356 *lastrm->next_out++ = *p++; 2357 lastrm->avail_out--; 2358 lastrm->total_out++; 2359 strm->buff_bytes--; 2360 } 2361 if (strm->buff_bytes) 2362 return (ARCHIVE_OK); 2363 if (strm->stat == 1) 2364 return (ARCHIVE_EOF); 2365 strm->buff_ptr = strm->buff; 2366 } 2367 while (lastrm->avail_in && lastrm->avail_out) { 2368 __archive_ppmd7_functions.Ppmd7_EncodeSymbol( 2369 &(strm->ppmd7_context), &(strm->range_enc), 2370 *lastrm->next_in++); 2371 lastrm->avail_in--; 2372 lastrm->total_in++; 2373 } 2374 if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) { 2375 __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData( 2376 &(strm->range_enc)); 2377 strm->stat = 1; 2378 /* Return EOF if there are no remaining bytes. */ 2379 if (strm->buff_bytes == 0) 2380 return (ARCHIVE_EOF); 2381 } 2382 return (ARCHIVE_OK); 2383 } 2384 2385 static int 2386 compression_end_ppmd(struct archive *a, struct la_zstream *lastrm) 2387 { 2388 struct ppmd_stream *strm; 2389 2390 (void)a; /* UNUSED */ 2391 2392 strm = (struct ppmd_stream *)lastrm->real_stream; 2393 __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context); 2394 free(strm->buff); 2395 free(strm); 2396 lastrm->real_stream = NULL; 2397 lastrm->valid = 0; 2398 return (ARCHIVE_OK); 2399 } 2400 2401 #if HAVE_ZSTD_H && HAVE_ZSTD_compressStream 2402 static int 2403 compression_init_encoder_zstd(struct archive *a, struct la_zstream *lastrm, int level, int threads) 2404 { 2405 if (lastrm->valid) 2406 compression_end(a, lastrm); 2407 2408 ZSTD_CStream *strm = ZSTD_createCStream(); 2409 if (strm == NULL) { 2410 archive_set_error(a, ENOMEM, 2411 "Can't allocate memory for zstd stream"); 2412 return (ARCHIVE_FATAL); 2413 } 2414 2415 if (ZSTD_isError(ZSTD_initCStream(strm, level))) { 2416 ZSTD_freeCStream(strm); 2417 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2418 "Internal error initializing zstd compressor object"); 2419 return (ARCHIVE_FATAL); 2420 } 2421 2422 ZSTD_CCtx_setParameter(strm, ZSTD_c_nbWorkers, threads); 2423 2424 // p7zip-zstd fails to unpack archives that don't have prop_size 5. 2425 // 7-Zip-zstd fails to unpack archives that don't have prop_size 3 or 5. 2426 // So let's use 5... 2427 lastrm->prop_size = 5; 2428 lastrm->props = calloc(5, 1); 2429 if (lastrm->props == NULL) { 2430 ZSTD_freeCStream(strm); 2431 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2432 "Internal error initializing zstd compressor properties"); 2433 return (ARCHIVE_FATAL); 2434 } 2435 2436 // Refer to the DProps struct in 7-Zip-zstd's ZstdDecoder.h: 2437 // https://github.com/mcmilk/7-Zip-zstd/blob/79b2c78e9e7735ddf90147129b75cf2797ff6522/CPP/7zip/Compress/ZstdDecoder.h#L34S 2438 lastrm->props[0] = ZSTD_VERSION_MAJOR; 2439 lastrm->props[1] = ZSTD_VERSION_MINOR; 2440 lastrm->props[2] = level; 2441 // lastrm->props[3] and lastrm->props[4] are reserved. Leave them as 0. 2442 2443 lastrm->real_stream = strm; 2444 lastrm->valid = 1; 2445 lastrm->code = compression_code_zstd; 2446 lastrm->end = compression_end_zstd; 2447 2448 return (ARCHIVE_OK); 2449 } 2450 2451 static int 2452 compression_code_zstd(struct archive *a, 2453 struct la_zstream *lastrm, enum la_zaction action) 2454 { 2455 ZSTD_CStream *strm = (ZSTD_CStream *)lastrm->real_stream; 2456 2457 ZSTD_outBuffer out = { .dst = lastrm->next_out, .size = lastrm->avail_out, .pos = 0 }; 2458 ZSTD_inBuffer in = { .src = lastrm->next_in, .size = lastrm->avail_in, .pos = 0 }; 2459 2460 size_t zret; 2461 2462 ZSTD_EndDirective mode = (action == ARCHIVE_Z_RUN) ? ZSTD_e_continue : ZSTD_e_end; 2463 2464 zret = ZSTD_compressStream2(strm, &out, &in, mode); 2465 if (ZSTD_isError(zret)) { 2466 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2467 "zstd compression failed, ZSTD_compressStream2 returned: %s", 2468 ZSTD_getErrorName(zret)); 2469 return (ARCHIVE_FATAL); 2470 } 2471 2472 lastrm->next_in += in.pos; 2473 lastrm->avail_in -= in.pos; 2474 lastrm->total_in += in.pos; 2475 2476 lastrm->next_out += out.pos; 2477 lastrm->avail_out -= out.pos; 2478 lastrm->total_out += out.pos; 2479 2480 if (action == ARCHIVE_Z_FINISH && zret == 0) 2481 return (ARCHIVE_EOF); // All done. 2482 2483 return (ARCHIVE_OK); // More work to do. 2484 } 2485 2486 static int 2487 compression_end_zstd(struct archive *a, struct la_zstream *lastrm) 2488 { 2489 ZSTD_CStream *strm; 2490 2491 (void)a; /* UNUSED */ 2492 strm = (ZSTD_CStream *)lastrm->real_stream; 2493 ZSTD_freeCStream(strm); 2494 lastrm->valid = 0; 2495 lastrm->real_stream = NULL; 2496 return (ARCHIVE_OK); 2497 } 2498 2499 #else 2500 2501 static int 2502 compression_init_encoder_zstd(struct archive *a, struct la_zstream *lastrm, int level, int threads) 2503 { 2504 (void) level; /* UNUSED */ 2505 (void) threads; /* UNUSED */ 2506 if (lastrm->valid) 2507 compression_end(a, lastrm); 2508 return (compression_unsupported_encoder(a, lastrm, "zstd")); 2509 } 2510 #endif 2511 2512 /* 2513 * Universal compressor initializer. 2514 */ 2515 static int 2516 _7z_compression_init_encoder(struct archive_write *a, unsigned compression, 2517 int compression_level) 2518 { 2519 struct _7zip *zip; 2520 int r; 2521 2522 zip = (struct _7zip *)a->format_data; 2523 switch (compression) { 2524 case _7Z_DEFLATE: 2525 r = compression_init_encoder_deflate( 2526 &(a->archive), &(zip->stream), 2527 compression_level, 0); 2528 break; 2529 case _7Z_BZIP2: 2530 r = compression_init_encoder_bzip2( 2531 &(a->archive), &(zip->stream), 2532 compression_level); 2533 break; 2534 case _7Z_LZMA1: 2535 r = compression_init_encoder_lzma1( 2536 &(a->archive), &(zip->stream), 2537 compression_level); 2538 break; 2539 case _7Z_LZMA2: 2540 r = compression_init_encoder_lzma2( 2541 &(a->archive), &(zip->stream), 2542 compression_level); 2543 break; 2544 case _7Z_PPMD: 2545 r = compression_init_encoder_ppmd( 2546 &(a->archive), &(zip->stream), 2547 PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE); 2548 break; 2549 case _7Z_ZSTD: 2550 r = compression_init_encoder_zstd( 2551 &(a->archive), &(zip->stream), 2552 compression_level, zip->opt_threads); 2553 break; 2554 case _7Z_COPY: 2555 default: 2556 r = compression_init_encoder_copy( 2557 &(a->archive), &(zip->stream)); 2558 break; 2559 } 2560 if (r == ARCHIVE_OK) { 2561 zip->stream.total_in = 0; 2562 zip->stream.next_out = zip->wbuff; 2563 zip->stream.avail_out = sizeof(zip->wbuff); 2564 zip->stream.total_out = 0; 2565 } 2566 2567 return (r); 2568 } 2569 2570 static int 2571 compression_code(struct archive *a, struct la_zstream *lastrm, 2572 enum la_zaction action) 2573 { 2574 if (lastrm->valid) 2575 return (lastrm->code(a, lastrm, action)); 2576 return (ARCHIVE_OK); 2577 } 2578 2579 static int 2580 compression_end(struct archive *a, struct la_zstream *lastrm) 2581 { 2582 if (lastrm->valid) { 2583 lastrm->prop_size = 0; 2584 free(lastrm->props); 2585 lastrm->props = NULL; 2586 return (lastrm->end(a, lastrm)); 2587 } 2588 return (ARCHIVE_OK); 2589 } 2590