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