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