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