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 94 enum la_zaction { 95 ARCHIVE_Z_FINISH, 96 ARCHIVE_Z_RUN 97 }; 98 99 /* 100 * A stream object of universal compressor. 101 */ 102 struct 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 126 struct 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 137 struct coder { 138 unsigned codec; 139 size_t prop_size; 140 uint8_t *props; 141 }; 142 143 struct 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 171 struct _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 218 static int _7z_options(struct archive_write *, 219 const char *, const char *); 220 static int _7z_write_header(struct archive_write *, 221 struct archive_entry *); 222 static ssize_t _7z_write_data(struct archive_write *, 223 const void *, size_t); 224 static int _7z_finish_entry(struct archive_write *); 225 static int _7z_close(struct archive_write *); 226 static int _7z_free(struct archive_write *); 227 static int file_cmp_node(const struct archive_rb_node *, 228 const struct archive_rb_node *); 229 static int file_cmp_key(const struct archive_rb_node *, const void *); 230 static int file_new(struct archive_write *a, struct archive_entry *, 231 struct file **); 232 static void file_free(struct file *); 233 static void file_register(struct _7zip *, struct file *); 234 static void file_register_empty(struct _7zip *, struct file *); 235 static void file_init_register(struct _7zip *); 236 static void file_init_register_empty(struct _7zip *); 237 static void file_free_register(struct _7zip *); 238 static ssize_t compress_out(struct archive_write *, const void *, size_t , 239 enum la_zaction); 240 static int compression_init_encoder_copy(struct archive *, 241 struct la_zstream *); 242 static int compression_code_copy(struct archive *, 243 struct la_zstream *, enum la_zaction); 244 static int compression_end_copy(struct archive *, struct la_zstream *); 245 static int compression_init_encoder_deflate(struct archive *, 246 struct la_zstream *, int, int); 247 #ifdef HAVE_ZLIB_H 248 static int compression_code_deflate(struct archive *, 249 struct la_zstream *, enum la_zaction); 250 static int compression_end_deflate(struct archive *, struct la_zstream *); 251 #endif 252 static int compression_init_encoder_bzip2(struct archive *, 253 struct la_zstream *, int); 254 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 255 static int compression_code_bzip2(struct archive *, 256 struct la_zstream *, enum la_zaction); 257 static int compression_end_bzip2(struct archive *, struct la_zstream *); 258 #endif 259 static int compression_init_encoder_lzma1(struct archive *, 260 struct la_zstream *, int); 261 static int compression_init_encoder_lzma2(struct archive *, 262 struct la_zstream *, int); 263 #if defined(HAVE_LZMA_H) 264 static int compression_code_lzma(struct archive *, 265 struct la_zstream *, enum la_zaction); 266 static int compression_end_lzma(struct archive *, struct la_zstream *); 267 #endif 268 static int compression_init_encoder_ppmd(struct archive *, 269 struct la_zstream *, unsigned, uint32_t); 270 static int compression_code_ppmd(struct archive *, 271 struct la_zstream *, enum la_zaction); 272 static int compression_end_ppmd(struct archive *, struct la_zstream *); 273 static int _7z_compression_init_encoder(struct archive_write *, unsigned, 274 int); 275 static int compression_code(struct archive *, 276 struct la_zstream *, enum la_zaction); 277 static int compression_end(struct archive *, 278 struct la_zstream *); 279 static int enc_uint64(struct archive_write *, uint64_t); 280 static int make_header(struct archive_write *, uint64_t, uint64_t, 281 uint64_t, int, struct coder *); 282 static int make_streamsInfo(struct archive_write *, uint64_t, uint64_t, 283 uint64_t, int, struct coder *, int, uint32_t); 284 285 int 286 archive_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 339 static 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 423 static 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 */ 519 static int 520 write_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 556 static ssize_t 557 compress_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 603 static 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 623 static 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 650 static int 651 flush_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 666 static int 667 copy_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 711 static 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(zip->opt_compression == _7Z_LZMA2 || 759 zip->opt_compression == _7Z_COPY) 760 header_compression = zip->opt_compression; 761 762 /* If the stored file is only one, do not encode the header. 763 * This is the same way 7z command does. */ 764 if (zip->total_number_entry == 1) 765 header_compression = _7Z_COPY; 766 #else 767 header_compression = _7Z_COPY; 768 #endif 769 r = _7z_compression_init_encoder(a, header_compression, 770 zip->opt_compression_level); 771 if (r < 0) 772 return (r); 773 zip->crc32flg = PRECODE_CRC32; 774 zip->precode_crc32 = 0; 775 r = make_header(a, data_offset, data_size, data_unpacksize, 776 1, &(zip->coder)); 777 if (r < 0) 778 return (r); 779 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); 780 if (r < 0) 781 return (r); 782 header_offset = data_offset + data_size; 783 header_size = zip->stream.total_out; 784 header_crc32 = zip->precode_crc32; 785 header_unpacksize = zip->stream.total_in; 786 787 if (header_compression != _7Z_COPY) { 788 /* 789 * Encode the header in order to reduce the size 790 * of the archive. 791 */ 792 free(zip->coder.props); 793 zip->coder.codec = header_compression; 794 zip->coder.prop_size = zip->stream.prop_size; 795 zip->coder.props = zip->stream.props; 796 zip->stream.prop_size = 0; 797 zip->stream.props = NULL; 798 799 r = _7z_compression_init_encoder(a, _7Z_COPY, 0); 800 if (r < 0) 801 return (r); 802 zip->crc32flg = ENCODED_CRC32; 803 zip->encoded_crc32 = 0; 804 805 /* 806 * Make EncodedHeader. 807 */ 808 r = enc_uint64(a, kEncodedHeader); 809 if (r < 0) 810 return (r); 811 r = make_streamsInfo(a, header_offset, header_size, 812 header_unpacksize, 1, &(zip->coder), 0, 813 header_crc32); 814 if (r < 0) 815 return (r); 816 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH); 817 if (r < 0) 818 return (r); 819 header_offset = header_offset + header_size; 820 header_size = zip->stream.total_out; 821 header_crc32 = zip->encoded_crc32; 822 } 823 zip->crc32flg = 0; 824 } else { 825 header_offset = header_size = 0; 826 header_crc32 = 0; 827 } 828 829 length = zip->temp_offset; 830 831 /* 832 * Make the zip header on wbuff(write buffer). 833 */ 834 wb = zip->wbuff; 835 zip->wbuff_remaining = sizeof(zip->wbuff); 836 memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6); 837 wb[6] = 0;/* Major version. */ 838 wb[7] = 3;/* Minor version. */ 839 archive_le64enc(&wb[12], header_offset);/* Next Header Offset */ 840 archive_le64enc(&wb[20], header_size);/* Next Header Size */ 841 archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */ 842 archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */ 843 zip->wbuff_remaining -= 32; 844 845 /* 846 * Read all file contents and an encoded header from the temporary 847 * file and write out it. 848 */ 849 r = copy_out(a, 0, length); 850 if (r != ARCHIVE_OK) 851 return (r); 852 r = flush_wbuff(a); 853 return (r); 854 } 855 856 /* 857 * Encode 64 bits value into 7-Zip's encoded UINT64 value. 858 */ 859 static int 860 enc_uint64(struct archive_write *a, uint64_t val) 861 { 862 unsigned mask = 0x80; 863 uint8_t numdata[9]; 864 int i; 865 866 numdata[0] = 0; 867 for (i = 1; i < (int)sizeof(numdata); i++) { 868 if (val < mask) { 869 numdata[0] |= (uint8_t)val; 870 break; 871 } 872 numdata[i] = (uint8_t)val; 873 val >>= 8; 874 numdata[0] |= mask; 875 mask >>= 1; 876 } 877 return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN)); 878 } 879 880 static int 881 make_substreamsInfo(struct archive_write *a, struct coder *coders) 882 { 883 struct _7zip *zip = (struct _7zip *)a->format_data; 884 struct file *file; 885 int r; 886 887 /* 888 * Make SubStreamsInfo. 889 */ 890 r = enc_uint64(a, kSubStreamsInfo); 891 if (r < 0) 892 return (r); 893 894 if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) { 895 /* 896 * Make NumUnPackStream. 897 */ 898 r = enc_uint64(a, kNumUnPackStream); 899 if (r < 0) 900 return (r); 901 902 /* Write numUnpackStreams */ 903 r = enc_uint64(a, zip->total_number_nonempty_entry); 904 if (r < 0) 905 return (r); 906 907 /* 908 * Make kSize. 909 */ 910 r = enc_uint64(a, kSize); 911 if (r < 0) 912 return (r); 913 file = zip->file_list.first; 914 for (;file != NULL; file = file->next) { 915 if (file->next == NULL || 916 file->next->size == 0) 917 break; 918 r = enc_uint64(a, file->size); 919 if (r < 0) 920 return (r); 921 } 922 } 923 924 /* 925 * Make CRC. 926 */ 927 r = enc_uint64(a, kCRC); 928 if (r < 0) 929 return (r); 930 931 932 /* All are defined */ 933 r = enc_uint64(a, 1); 934 if (r < 0) 935 return (r); 936 file = zip->file_list.first; 937 for (;file != NULL; file = file->next) { 938 uint8_t crc[4]; 939 if (file->size == 0) 940 break; 941 archive_le32enc(crc, file->crc32); 942 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); 943 if (r < 0) 944 return (r); 945 } 946 947 /* Write End. */ 948 r = enc_uint64(a, kEnd); 949 if (r < 0) 950 return (r); 951 return (ARCHIVE_OK); 952 } 953 954 static int 955 make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size, 956 uint64_t unpack_size, int num_coder, struct coder *coders, int substrm, 957 uint32_t header_crc) 958 { 959 struct _7zip *zip = (struct _7zip *)a->format_data; 960 uint8_t codec_buff[8]; 961 int numFolders, fi; 962 int codec_size; 963 int i, r; 964 965 if (coders->codec == _7Z_COPY) 966 numFolders = (int)zip->total_number_nonempty_entry; 967 else 968 numFolders = 1; 969 970 /* 971 * Make PackInfo. 972 */ 973 r = enc_uint64(a, kPackInfo); 974 if (r < 0) 975 return (r); 976 977 /* Write PackPos. */ 978 r = enc_uint64(a, offset); 979 if (r < 0) 980 return (r); 981 982 /* Write NumPackStreams. */ 983 r = enc_uint64(a, numFolders); 984 if (r < 0) 985 return (r); 986 987 /* Make Size. */ 988 r = enc_uint64(a, kSize); 989 if (r < 0) 990 return (r); 991 992 if (numFolders > 1) { 993 struct file *file = zip->file_list.first; 994 for (;file != NULL; file = file->next) { 995 if (file->size == 0) 996 break; 997 r = enc_uint64(a, file->size); 998 if (r < 0) 999 return (r); 1000 } 1001 } else { 1002 /* Write size. */ 1003 r = enc_uint64(a, pack_size); 1004 if (r < 0) 1005 return (r); 1006 } 1007 1008 r = enc_uint64(a, kEnd); 1009 if (r < 0) 1010 return (r); 1011 1012 /* 1013 * Make UnPackInfo. 1014 */ 1015 r = enc_uint64(a, kUnPackInfo); 1016 if (r < 0) 1017 return (r); 1018 1019 /* 1020 * Make Folder. 1021 */ 1022 r = enc_uint64(a, kFolder); 1023 if (r < 0) 1024 return (r); 1025 1026 /* Write NumFolders. */ 1027 r = enc_uint64(a, numFolders); 1028 if (r < 0) 1029 return (r); 1030 1031 /* Write External. */ 1032 r = enc_uint64(a, 0); 1033 if (r < 0) 1034 return (r); 1035 1036 for (fi = 0; fi < numFolders; fi++) { 1037 /* Write NumCoders. */ 1038 r = enc_uint64(a, num_coder); 1039 if (r < 0) 1040 return (r); 1041 1042 for (i = 0; i < num_coder; i++) { 1043 unsigned codec_id = coders[i].codec; 1044 1045 /* Write Codec flag. */ 1046 archive_be64enc(codec_buff, codec_id); 1047 for (codec_size = 8; codec_size > 0; codec_size--) { 1048 if (codec_buff[8 - codec_size]) 1049 break; 1050 } 1051 if (codec_size == 0) 1052 codec_size = 1; 1053 if (coders[i].prop_size) 1054 r = enc_uint64(a, codec_size | 0x20); 1055 else 1056 r = enc_uint64(a, codec_size); 1057 if (r < 0) 1058 return (r); 1059 1060 /* Write Codec ID. */ 1061 codec_size &= 0x0f; 1062 r = (int)compress_out(a, &codec_buff[8-codec_size], 1063 codec_size, ARCHIVE_Z_RUN); 1064 if (r < 0) 1065 return (r); 1066 1067 if (coders[i].prop_size) { 1068 /* Write Codec property size. */ 1069 r = enc_uint64(a, coders[i].prop_size); 1070 if (r < 0) 1071 return (r); 1072 1073 /* Write Codec properties. */ 1074 r = (int)compress_out(a, coders[i].props, 1075 coders[i].prop_size, ARCHIVE_Z_RUN); 1076 if (r < 0) 1077 return (r); 1078 } 1079 } 1080 } 1081 1082 /* 1083 * Make CodersUnPackSize. 1084 */ 1085 r = enc_uint64(a, kCodersUnPackSize); 1086 if (r < 0) 1087 return (r); 1088 1089 if (numFolders > 1) { 1090 struct file *file = zip->file_list.first; 1091 for (;file != NULL; file = file->next) { 1092 if (file->size == 0) 1093 break; 1094 r = enc_uint64(a, file->size); 1095 if (r < 0) 1096 return (r); 1097 } 1098 1099 } else { 1100 /* Write UnPackSize. */ 1101 r = enc_uint64(a, unpack_size); 1102 if (r < 0) 1103 return (r); 1104 } 1105 1106 if (!substrm) { 1107 uint8_t crc[4]; 1108 /* 1109 * Make CRC. 1110 */ 1111 r = enc_uint64(a, kCRC); 1112 if (r < 0) 1113 return (r); 1114 1115 /* All are defined */ 1116 r = enc_uint64(a, 1); 1117 if (r < 0) 1118 return (r); 1119 archive_le32enc(crc, header_crc); 1120 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN); 1121 if (r < 0) 1122 return (r); 1123 } 1124 1125 /* Write End. */ 1126 r = enc_uint64(a, kEnd); 1127 if (r < 0) 1128 return (r); 1129 1130 if (substrm) { 1131 /* 1132 * Make SubStreamsInfo. 1133 */ 1134 r = make_substreamsInfo(a, coders); 1135 if (r < 0) 1136 return (r); 1137 } 1138 1139 1140 /* Write End. */ 1141 r = enc_uint64(a, kEnd); 1142 if (r < 0) 1143 return (r); 1144 1145 return (ARCHIVE_OK); 1146 } 1147 1148 1149 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000) 1150 static uint64_t 1151 utcToFiletime(time_t t, long ns) 1152 { 1153 uint64_t fileTime; 1154 1155 fileTime = t; 1156 fileTime *= 10000000; 1157 fileTime += ns / 100; 1158 fileTime += EPOC_TIME; 1159 return (fileTime); 1160 } 1161 1162 static int 1163 make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti) 1164 { 1165 uint8_t filetime[8]; 1166 struct _7zip *zip = (struct _7zip *)a->format_data; 1167 struct file *file; 1168 int r; 1169 uint8_t b, mask; 1170 1171 /* 1172 * Make Time Bools. 1173 */ 1174 if (zip->total_number_time_defined[ti] == zip->total_number_entry) { 1175 /* Write Time Type. */ 1176 r = enc_uint64(a, type); 1177 if (r < 0) 1178 return (r); 1179 /* Write EmptyStream Size. */ 1180 r = enc_uint64(a, 2 + zip->total_number_entry * 8); 1181 if (r < 0) 1182 return (r); 1183 /* All are defined. */ 1184 r = enc_uint64(a, 1); 1185 if (r < 0) 1186 return (r); 1187 } else { 1188 if (zip->total_number_time_defined[ti] == 0) 1189 return (ARCHIVE_OK); 1190 1191 /* Write Time Type. */ 1192 r = enc_uint64(a, type); 1193 if (r < 0) 1194 return (r); 1195 /* Write EmptyStream Size. */ 1196 r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3) 1197 + zip->total_number_time_defined[ti] * 8); 1198 if (r < 0) 1199 return (r); 1200 1201 /* All are not defined. */ 1202 r = enc_uint64(a, 0); 1203 if (r < 0) 1204 return (r); 1205 1206 b = 0; 1207 mask = 0x80; 1208 file = zip->file_list.first; 1209 for (;file != NULL; file = file->next) { 1210 if (file->flg & flg) 1211 b |= mask; 1212 mask >>= 1; 1213 if (mask == 0) { 1214 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1215 if (r < 0) 1216 return (r); 1217 mask = 0x80; 1218 b = 0; 1219 } 1220 } 1221 if (mask != 0x80) { 1222 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1223 if (r < 0) 1224 return (r); 1225 } 1226 } 1227 1228 /* External. */ 1229 r = enc_uint64(a, 0); 1230 if (r < 0) 1231 return (r); 1232 1233 1234 /* 1235 * Make Times. 1236 */ 1237 file = zip->file_list.first; 1238 for (;file != NULL; file = file->next) { 1239 if ((file->flg & flg) == 0) 1240 continue; 1241 archive_le64enc(filetime, utcToFiletime(file->times[ti].time, 1242 file->times[ti].time_ns)); 1243 r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN); 1244 if (r < 0) 1245 return (r); 1246 } 1247 1248 return (ARCHIVE_OK); 1249 } 1250 1251 static int 1252 make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size, 1253 uint64_t unpack_size, int codernum, struct coder *coders) 1254 { 1255 struct _7zip *zip = (struct _7zip *)a->format_data; 1256 struct file *file; 1257 int r; 1258 uint8_t b, mask; 1259 1260 /* 1261 * Make FilesInfo. 1262 */ 1263 r = enc_uint64(a, kHeader); 1264 if (r < 0) 1265 return (r); 1266 1267 /* 1268 * If there are empty files only, do not write MainStreamInfo. 1269 */ 1270 if (zip->total_number_nonempty_entry) { 1271 /* 1272 * Make MainStreamInfo. 1273 */ 1274 r = enc_uint64(a, kMainStreamsInfo); 1275 if (r < 0) 1276 return (r); 1277 r = make_streamsInfo(a, offset, pack_size, unpack_size, 1278 codernum, coders, 1, 0); 1279 if (r < 0) 1280 return (r); 1281 } 1282 1283 /* 1284 * Make FilesInfo. 1285 */ 1286 r = enc_uint64(a, kFilesInfo); 1287 if (r < 0) 1288 return (r); 1289 1290 /* Write numFiles. */ 1291 r = enc_uint64(a, zip->total_number_entry); 1292 if (r < 0) 1293 return (r); 1294 1295 if (zip->total_number_empty_entry > 0) { 1296 /* Make EmptyStream. */ 1297 r = enc_uint64(a, kEmptyStream); 1298 if (r < 0) 1299 return (r); 1300 1301 /* Write EmptyStream Size. */ 1302 r = enc_uint64(a, (zip->total_number_entry+7)>>3); 1303 if (r < 0) 1304 return (r); 1305 1306 b = 0; 1307 mask = 0x80; 1308 file = zip->file_list.first; 1309 for (;file != NULL; file = file->next) { 1310 if (file->size == 0) 1311 b |= mask; 1312 mask >>= 1; 1313 if (mask == 0) { 1314 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1315 if (r < 0) 1316 return (r); 1317 mask = 0x80; 1318 b = 0; 1319 } 1320 } 1321 if (mask != 0x80) { 1322 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1323 if (r < 0) 1324 return (r); 1325 } 1326 } 1327 1328 if (zip->total_number_empty_entry > zip->total_number_dir_entry) { 1329 /* Make EmptyFile. */ 1330 r = enc_uint64(a, kEmptyFile); 1331 if (r < 0) 1332 return (r); 1333 1334 /* Write EmptyFile Size. */ 1335 r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3); 1336 if (r < 0) 1337 return (r); 1338 1339 b = 0; 1340 mask = 0x80; 1341 file = zip->file_list.first; 1342 for (;file != NULL; file = file->next) { 1343 if (file->size) 1344 continue; 1345 if (!file->dir) 1346 b |= mask; 1347 mask >>= 1; 1348 if (mask == 0) { 1349 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1350 if (r < 0) 1351 return (r); 1352 mask = 0x80; 1353 b = 0; 1354 } 1355 } 1356 if (mask != 0x80) { 1357 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN); 1358 if (r < 0) 1359 return (r); 1360 } 1361 } 1362 1363 /* Make Name. */ 1364 r = enc_uint64(a, kName); 1365 if (r < 0) 1366 return (r); 1367 1368 /* Write Name size. */ 1369 r = enc_uint64(a, zip->total_bytes_entry_name+1); 1370 if (r < 0) 1371 return (r); 1372 1373 /* Write dmy byte. */ 1374 r = enc_uint64(a, 0); 1375 if (r < 0) 1376 return (r); 1377 1378 file = zip->file_list.first; 1379 for (;file != NULL; file = file->next) { 1380 r = (int)compress_out(a, file->utf16name, file->name_len+2, 1381 ARCHIVE_Z_RUN); 1382 if (r < 0) 1383 return (r); 1384 } 1385 1386 /* Make MTime. */ 1387 r = make_time(a, kMTime, MTIME_IS_SET, MTIME); 1388 if (r < 0) 1389 return (r); 1390 1391 /* Make CTime. */ 1392 r = make_time(a, kCTime, CTIME_IS_SET, CTIME); 1393 if (r < 0) 1394 return (r); 1395 1396 /* Make ATime. */ 1397 r = make_time(a, kATime, ATIME_IS_SET, ATIME); 1398 if (r < 0) 1399 return (r); 1400 1401 /* Make Attributes. */ 1402 r = enc_uint64(a, kAttributes); 1403 if (r < 0) 1404 return (r); 1405 1406 /* Write Attributes size. */ 1407 r = enc_uint64(a, 2 + zip->total_number_entry * 4); 1408 if (r < 0) 1409 return (r); 1410 1411 /* Write "All Are Defined". */ 1412 r = enc_uint64(a, 1); 1413 if (r < 0) 1414 return (r); 1415 1416 /* Write dmy byte. */ 1417 r = enc_uint64(a, 0); 1418 if (r < 0) 1419 return (r); 1420 1421 file = zip->file_list.first; 1422 for (;file != NULL; file = file->next) { 1423 /* 1424 * High 16bits is unix mode. 1425 * Low 16bits is Windows attributes. 1426 */ 1427 uint32_t encattr, attr; 1428 if (file->dir) 1429 attr = 0x8010; 1430 else 1431 attr = 0x8020; 1432 if ((file->mode & 0222) == 0) 1433 attr |= 1;/* Read Only. */ 1434 attr |= ((uint32_t)file->mode) << 16; 1435 archive_le32enc(&encattr, attr); 1436 r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN); 1437 if (r < 0) 1438 return (r); 1439 } 1440 1441 /* Write End. */ 1442 r = enc_uint64(a, kEnd); 1443 if (r < 0) 1444 return (r); 1445 1446 /* Write End. */ 1447 r = enc_uint64(a, kEnd); 1448 if (r < 0) 1449 return (r); 1450 1451 return (ARCHIVE_OK); 1452 } 1453 1454 1455 static int 1456 _7z_free(struct archive_write *a) 1457 { 1458 struct _7zip *zip = (struct _7zip *)a->format_data; 1459 1460 /* Close the temporary file. */ 1461 if (zip->temp_fd >= 0) 1462 close(zip->temp_fd); 1463 1464 file_free_register(zip); 1465 compression_end(&(a->archive), &(zip->stream)); 1466 free(zip->coder.props); 1467 free(zip); 1468 1469 return (ARCHIVE_OK); 1470 } 1471 1472 static int 1473 file_cmp_node(const struct archive_rb_node *n1, 1474 const struct archive_rb_node *n2) 1475 { 1476 const struct file *f1 = (const struct file *)n1; 1477 const struct file *f2 = (const struct file *)n2; 1478 1479 if (f1->name_len == f2->name_len) 1480 return (memcmp(f1->utf16name, f2->utf16name, f1->name_len)); 1481 return (f1->name_len > f2->name_len)?1:-1; 1482 } 1483 1484 static int 1485 file_cmp_key(const struct archive_rb_node *n, const void *key) 1486 { 1487 const struct file *f = (const struct file *)n; 1488 1489 return (f->name_len - *(const char *)key); 1490 } 1491 1492 static int 1493 file_new(struct archive_write *a, struct archive_entry *entry, 1494 struct file **newfile) 1495 { 1496 struct _7zip *zip; 1497 struct file *file; 1498 const char *u16; 1499 size_t u16len; 1500 int ret = ARCHIVE_OK; 1501 1502 zip = (struct _7zip *)a->format_data; 1503 *newfile = NULL; 1504 1505 file = calloc(1, sizeof(*file)); 1506 if (file == NULL) { 1507 archive_set_error(&a->archive, ENOMEM, 1508 "Can't allocate memory"); 1509 return (ARCHIVE_FATAL); 1510 } 1511 1512 if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) { 1513 if (errno == ENOMEM) { 1514 free(file); 1515 archive_set_error(&a->archive, ENOMEM, 1516 "Can't allocate memory for UTF-16LE"); 1517 return (ARCHIVE_FATAL); 1518 } 1519 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 1520 "A filename cannot be converted to UTF-16LE;" 1521 "You should disable making Joliet extension"); 1522 ret = ARCHIVE_WARN; 1523 } 1524 file->utf16name = malloc(u16len + 2); 1525 if (file->utf16name == NULL) { 1526 free(file); 1527 archive_set_error(&a->archive, ENOMEM, 1528 "Can't allocate memory for Name"); 1529 return (ARCHIVE_FATAL); 1530 } 1531 memcpy(file->utf16name, u16, u16len); 1532 file->utf16name[u16len+0] = 0; 1533 file->utf16name[u16len+1] = 0; 1534 file->name_len = (unsigned)u16len; 1535 file->mode = archive_entry_mode(entry); 1536 if (archive_entry_filetype(entry) == AE_IFREG) 1537 file->size = archive_entry_size(entry); 1538 else 1539 archive_entry_set_size(entry, 0); 1540 if (archive_entry_filetype(entry) == AE_IFDIR) 1541 file->dir = 1; 1542 else if (archive_entry_filetype(entry) == AE_IFLNK) 1543 file->size = strlen(archive_entry_symlink(entry)); 1544 if (archive_entry_mtime_is_set(entry)) { 1545 file->flg |= MTIME_IS_SET; 1546 file->times[MTIME].time = archive_entry_mtime(entry); 1547 file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry); 1548 } 1549 if (archive_entry_atime_is_set(entry)) { 1550 file->flg |= ATIME_IS_SET; 1551 file->times[ATIME].time = archive_entry_atime(entry); 1552 file->times[ATIME].time_ns = archive_entry_atime_nsec(entry); 1553 } 1554 if (archive_entry_ctime_is_set(entry)) { 1555 file->flg |= CTIME_IS_SET; 1556 file->times[CTIME].time = archive_entry_ctime(entry); 1557 file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry); 1558 } 1559 1560 *newfile = file; 1561 return (ret); 1562 } 1563 1564 static void 1565 file_free(struct file *file) 1566 { 1567 free(file->utf16name); 1568 free(file); 1569 } 1570 1571 static void 1572 file_register(struct _7zip *zip, struct file *file) 1573 { 1574 file->next = NULL; 1575 *zip->file_list.last = file; 1576 zip->file_list.last = &(file->next); 1577 } 1578 1579 static void 1580 file_init_register(struct _7zip *zip) 1581 { 1582 zip->file_list.first = NULL; 1583 zip->file_list.last = &(zip->file_list.first); 1584 } 1585 1586 static void 1587 file_free_register(struct _7zip *zip) 1588 { 1589 struct file *file, *file_next; 1590 1591 file = zip->file_list.first; 1592 while (file != NULL) { 1593 file_next = file->next; 1594 file_free(file); 1595 file = file_next; 1596 } 1597 } 1598 1599 static void 1600 file_register_empty(struct _7zip *zip, struct file *file) 1601 { 1602 file->next = NULL; 1603 *zip->empty_list.last = file; 1604 zip->empty_list.last = &(file->next); 1605 } 1606 1607 static void 1608 file_init_register_empty(struct _7zip *zip) 1609 { 1610 zip->empty_list.first = NULL; 1611 zip->empty_list.last = &(zip->empty_list.first); 1612 } 1613 1614 #if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\ 1615 !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H) 1616 static int 1617 compression_unsupported_encoder(struct archive *a, 1618 struct la_zstream *lastrm, const char *name) 1619 { 1620 1621 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1622 "%s compression not supported on this platform", name); 1623 lastrm->valid = 0; 1624 lastrm->real_stream = NULL; 1625 return (ARCHIVE_FAILED); 1626 } 1627 #endif 1628 1629 /* 1630 * _7_COPY compressor. 1631 */ 1632 static int 1633 compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm) 1634 { 1635 1636 if (lastrm->valid) 1637 compression_end(a, lastrm); 1638 lastrm->valid = 1; 1639 lastrm->code = compression_code_copy; 1640 lastrm->end = compression_end_copy; 1641 return (ARCHIVE_OK); 1642 } 1643 1644 static int 1645 compression_code_copy(struct archive *a, 1646 struct la_zstream *lastrm, enum la_zaction action) 1647 { 1648 size_t bytes; 1649 1650 (void)a; /* UNUSED */ 1651 if (lastrm->avail_out > lastrm->avail_in) 1652 bytes = lastrm->avail_in; 1653 else 1654 bytes = lastrm->avail_out; 1655 if (bytes) { 1656 memcpy(lastrm->next_out, lastrm->next_in, bytes); 1657 lastrm->next_in += bytes; 1658 lastrm->avail_in -= bytes; 1659 lastrm->total_in += bytes; 1660 lastrm->next_out += bytes; 1661 lastrm->avail_out -= bytes; 1662 lastrm->total_out += bytes; 1663 } 1664 if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0) 1665 return (ARCHIVE_EOF); 1666 return (ARCHIVE_OK); 1667 } 1668 1669 static int 1670 compression_end_copy(struct archive *a, struct la_zstream *lastrm) 1671 { 1672 (void)a; /* UNUSED */ 1673 lastrm->valid = 0; 1674 return (ARCHIVE_OK); 1675 } 1676 1677 /* 1678 * _7_DEFLATE compressor. 1679 */ 1680 #ifdef HAVE_ZLIB_H 1681 static int 1682 compression_init_encoder_deflate(struct archive *a, 1683 struct la_zstream *lastrm, int level, int withheader) 1684 { 1685 z_stream *strm; 1686 1687 if (lastrm->valid) 1688 compression_end(a, lastrm); 1689 strm = calloc(1, sizeof(*strm)); 1690 if (strm == NULL) { 1691 archive_set_error(a, ENOMEM, 1692 "Can't allocate memory for gzip stream"); 1693 return (ARCHIVE_FATAL); 1694 } 1695 /* zlib.h is not const-correct, so we need this one bit 1696 * of ugly hackery to convert a const * pointer to 1697 * a non-const pointer. */ 1698 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 1699 strm->avail_in = (uInt)lastrm->avail_in; 1700 strm->total_in = (uLong)lastrm->total_in; 1701 strm->next_out = lastrm->next_out; 1702 strm->avail_out = (uInt)lastrm->avail_out; 1703 strm->total_out = (uLong)lastrm->total_out; 1704 if (deflateInit2(strm, level, Z_DEFLATED, 1705 (withheader)?15:-15, 1706 8, Z_DEFAULT_STRATEGY) != Z_OK) { 1707 free(strm); 1708 lastrm->real_stream = NULL; 1709 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1710 "Internal error initializing compression library"); 1711 return (ARCHIVE_FATAL); 1712 } 1713 lastrm->real_stream = strm; 1714 lastrm->valid = 1; 1715 lastrm->code = compression_code_deflate; 1716 lastrm->end = compression_end_deflate; 1717 return (ARCHIVE_OK); 1718 } 1719 1720 static int 1721 compression_code_deflate(struct archive *a, 1722 struct la_zstream *lastrm, enum la_zaction action) 1723 { 1724 z_stream *strm; 1725 int r; 1726 1727 strm = (z_stream *)lastrm->real_stream; 1728 /* zlib.h is not const-correct, so we need this one bit 1729 * of ugly hackery to convert a const * pointer to 1730 * a non-const pointer. */ 1731 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in; 1732 strm->avail_in = (uInt)lastrm->avail_in; 1733 strm->total_in = (uLong)lastrm->total_in; 1734 strm->next_out = lastrm->next_out; 1735 strm->avail_out = (uInt)lastrm->avail_out; 1736 strm->total_out = (uLong)lastrm->total_out; 1737 r = deflate(strm, 1738 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH); 1739 lastrm->next_in = strm->next_in; 1740 lastrm->avail_in = strm->avail_in; 1741 lastrm->total_in = strm->total_in; 1742 lastrm->next_out = strm->next_out; 1743 lastrm->avail_out = strm->avail_out; 1744 lastrm->total_out = strm->total_out; 1745 switch (r) { 1746 case Z_OK: 1747 return (ARCHIVE_OK); 1748 case Z_STREAM_END: 1749 return (ARCHIVE_EOF); 1750 default: 1751 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1752 "GZip compression failed:" 1753 " deflate() call returned status %d", r); 1754 return (ARCHIVE_FATAL); 1755 } 1756 } 1757 1758 static int 1759 compression_end_deflate(struct archive *a, struct la_zstream *lastrm) 1760 { 1761 z_stream *strm; 1762 int r; 1763 1764 strm = (z_stream *)lastrm->real_stream; 1765 r = deflateEnd(strm); 1766 free(strm); 1767 lastrm->real_stream = NULL; 1768 lastrm->valid = 0; 1769 if (r != Z_OK) { 1770 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1771 "Failed to clean up compressor"); 1772 return (ARCHIVE_FATAL); 1773 } 1774 return (ARCHIVE_OK); 1775 } 1776 #else 1777 static int 1778 compression_init_encoder_deflate(struct archive *a, 1779 struct la_zstream *lastrm, int level, int withheader) 1780 { 1781 1782 (void) level; /* UNUSED */ 1783 (void) withheader; /* UNUSED */ 1784 if (lastrm->valid) 1785 compression_end(a, lastrm); 1786 return (compression_unsupported_encoder(a, lastrm, "deflate")); 1787 } 1788 #endif 1789 1790 /* 1791 * _7_BZIP2 compressor. 1792 */ 1793 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR) 1794 static int 1795 compression_init_encoder_bzip2(struct archive *a, 1796 struct la_zstream *lastrm, int level) 1797 { 1798 bz_stream *strm; 1799 1800 if (lastrm->valid) 1801 compression_end(a, lastrm); 1802 strm = calloc(1, sizeof(*strm)); 1803 if (strm == NULL) { 1804 archive_set_error(a, ENOMEM, 1805 "Can't allocate memory for bzip2 stream"); 1806 return (ARCHIVE_FATAL); 1807 } 1808 /* bzlib.h is not const-correct, so we need this one bit 1809 * of ugly hackery to convert a const * pointer to 1810 * a non-const pointer. */ 1811 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 1812 strm->avail_in = lastrm->avail_in; 1813 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 1814 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 1815 strm->next_out = (char *)lastrm->next_out; 1816 strm->avail_out = lastrm->avail_out; 1817 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 1818 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 1819 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) { 1820 free(strm); 1821 lastrm->real_stream = NULL; 1822 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1823 "Internal error initializing compression library"); 1824 return (ARCHIVE_FATAL); 1825 } 1826 lastrm->real_stream = strm; 1827 lastrm->valid = 1; 1828 lastrm->code = compression_code_bzip2; 1829 lastrm->end = compression_end_bzip2; 1830 return (ARCHIVE_OK); 1831 } 1832 1833 static int 1834 compression_code_bzip2(struct archive *a, 1835 struct la_zstream *lastrm, enum la_zaction action) 1836 { 1837 bz_stream *strm; 1838 int r; 1839 1840 strm = (bz_stream *)lastrm->real_stream; 1841 /* bzlib.h is not const-correct, so we need this one bit 1842 * of ugly hackery to convert a const * pointer to 1843 * a non-const pointer. */ 1844 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in; 1845 strm->avail_in = lastrm->avail_in; 1846 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff); 1847 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32); 1848 strm->next_out = (char *)lastrm->next_out; 1849 strm->avail_out = lastrm->avail_out; 1850 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff); 1851 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32); 1852 r = BZ2_bzCompress(strm, 1853 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN); 1854 lastrm->next_in = (const unsigned char *)strm->next_in; 1855 lastrm->avail_in = strm->avail_in; 1856 lastrm->total_in = 1857 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32) 1858 + (uint64_t)(uint32_t)strm->total_in_lo32; 1859 lastrm->next_out = (unsigned char *)strm->next_out; 1860 lastrm->avail_out = strm->avail_out; 1861 lastrm->total_out = 1862 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32) 1863 + (uint64_t)(uint32_t)strm->total_out_lo32; 1864 switch (r) { 1865 case BZ_RUN_OK: /* Non-finishing */ 1866 case BZ_FINISH_OK: /* Finishing: There's more work to do */ 1867 return (ARCHIVE_OK); 1868 case BZ_STREAM_END: /* Finishing: all done */ 1869 /* Only occurs in finishing case */ 1870 return (ARCHIVE_EOF); 1871 default: 1872 /* Any other return value indicates an error */ 1873 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1874 "Bzip2 compression failed:" 1875 " BZ2_bzCompress() call returned status %d", r); 1876 return (ARCHIVE_FATAL); 1877 } 1878 } 1879 1880 static int 1881 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm) 1882 { 1883 bz_stream *strm; 1884 int r; 1885 1886 strm = (bz_stream *)lastrm->real_stream; 1887 r = BZ2_bzCompressEnd(strm); 1888 free(strm); 1889 lastrm->real_stream = NULL; 1890 lastrm->valid = 0; 1891 if (r != BZ_OK) { 1892 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1893 "Failed to clean up compressor"); 1894 return (ARCHIVE_FATAL); 1895 } 1896 return (ARCHIVE_OK); 1897 } 1898 1899 #else 1900 static int 1901 compression_init_encoder_bzip2(struct archive *a, 1902 struct la_zstream *lastrm, int level) 1903 { 1904 1905 (void) level; /* UNUSED */ 1906 if (lastrm->valid) 1907 compression_end(a, lastrm); 1908 return (compression_unsupported_encoder(a, lastrm, "bzip2")); 1909 } 1910 #endif 1911 1912 /* 1913 * _7_LZMA1, _7_LZMA2 compressor. 1914 */ 1915 #if defined(HAVE_LZMA_H) 1916 static int 1917 compression_init_encoder_lzma(struct archive *a, 1918 struct la_zstream *lastrm, int level, uint64_t filter_id) 1919 { 1920 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT; 1921 lzma_stream *strm; 1922 lzma_filter *lzmafilters; 1923 lzma_options_lzma lzma_opt; 1924 int r; 1925 1926 if (lastrm->valid) 1927 compression_end(a, lastrm); 1928 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2); 1929 if (strm == NULL) { 1930 archive_set_error(a, ENOMEM, 1931 "Can't allocate memory for lzma stream"); 1932 return (ARCHIVE_FATAL); 1933 } 1934 lzmafilters = (lzma_filter *)(strm+1); 1935 if (level > 9) 1936 level = 9; 1937 if (lzma_lzma_preset(&lzma_opt, level)) { 1938 free(strm); 1939 lastrm->real_stream = NULL; 1940 archive_set_error(a, ENOMEM, 1941 "Internal error initializing compression library"); 1942 return (ARCHIVE_FATAL); 1943 } 1944 lzmafilters[0].id = filter_id; 1945 lzmafilters[0].options = &lzma_opt; 1946 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */ 1947 1948 r = lzma_properties_size(&(lastrm->prop_size), lzmafilters); 1949 if (r != LZMA_OK) { 1950 free(strm); 1951 lastrm->real_stream = NULL; 1952 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1953 "lzma_properties_size failed"); 1954 return (ARCHIVE_FATAL); 1955 } 1956 if (lastrm->prop_size) { 1957 lastrm->props = malloc(lastrm->prop_size); 1958 if (lastrm->props == NULL) { 1959 free(strm); 1960 lastrm->real_stream = NULL; 1961 archive_set_error(a, ENOMEM, 1962 "Cannot allocate memory"); 1963 return (ARCHIVE_FATAL); 1964 } 1965 r = lzma_properties_encode(lzmafilters, lastrm->props); 1966 if (r != LZMA_OK) { 1967 free(strm); 1968 lastrm->real_stream = NULL; 1969 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1970 "lzma_properties_encode failed"); 1971 return (ARCHIVE_FATAL); 1972 } 1973 } 1974 1975 *strm = lzma_init_data; 1976 r = lzma_raw_encoder(strm, lzmafilters); 1977 switch (r) { 1978 case LZMA_OK: 1979 lastrm->real_stream = strm; 1980 lastrm->valid = 1; 1981 lastrm->code = compression_code_lzma; 1982 lastrm->end = compression_end_lzma; 1983 r = ARCHIVE_OK; 1984 break; 1985 case LZMA_MEM_ERROR: 1986 free(strm); 1987 lastrm->real_stream = NULL; 1988 archive_set_error(a, ENOMEM, 1989 "Internal error initializing compression library: " 1990 "Cannot allocate memory"); 1991 r = ARCHIVE_FATAL; 1992 break; 1993 default: 1994 free(strm); 1995 lastrm->real_stream = NULL; 1996 archive_set_error(a, ARCHIVE_ERRNO_MISC, 1997 "Internal error initializing compression library: " 1998 "It's a bug in liblzma"); 1999 r = ARCHIVE_FATAL; 2000 break; 2001 } 2002 return (r); 2003 } 2004 2005 static int 2006 compression_init_encoder_lzma1(struct archive *a, 2007 struct la_zstream *lastrm, int level) 2008 { 2009 return compression_init_encoder_lzma(a, lastrm, level, 2010 LZMA_FILTER_LZMA1); 2011 } 2012 2013 static int 2014 compression_init_encoder_lzma2(struct archive *a, 2015 struct la_zstream *lastrm, int level) 2016 { 2017 return compression_init_encoder_lzma(a, lastrm, level, 2018 LZMA_FILTER_LZMA2); 2019 } 2020 2021 static int 2022 compression_code_lzma(struct archive *a, 2023 struct la_zstream *lastrm, enum la_zaction action) 2024 { 2025 lzma_stream *strm; 2026 int r; 2027 2028 strm = (lzma_stream *)lastrm->real_stream; 2029 strm->next_in = lastrm->next_in; 2030 strm->avail_in = lastrm->avail_in; 2031 strm->total_in = lastrm->total_in; 2032 strm->next_out = lastrm->next_out; 2033 strm->avail_out = lastrm->avail_out; 2034 strm->total_out = lastrm->total_out; 2035 r = lzma_code(strm, 2036 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN); 2037 lastrm->next_in = strm->next_in; 2038 lastrm->avail_in = strm->avail_in; 2039 lastrm->total_in = strm->total_in; 2040 lastrm->next_out = strm->next_out; 2041 lastrm->avail_out = strm->avail_out; 2042 lastrm->total_out = strm->total_out; 2043 switch (r) { 2044 case LZMA_OK: 2045 /* Non-finishing case */ 2046 return (ARCHIVE_OK); 2047 case LZMA_STREAM_END: 2048 /* This return can only occur in finishing case. */ 2049 return (ARCHIVE_EOF); 2050 case LZMA_MEMLIMIT_ERROR: 2051 archive_set_error(a, ENOMEM, 2052 "lzma compression error:" 2053 " %ju MiB would have been needed", 2054 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1) 2055 / (1024 * 1024))); 2056 return (ARCHIVE_FATAL); 2057 default: 2058 /* Any other return value indicates an error */ 2059 archive_set_error(a, ARCHIVE_ERRNO_MISC, 2060 "lzma compression failed:" 2061 " lzma_code() call returned status %d", r); 2062 return (ARCHIVE_FATAL); 2063 } 2064 } 2065 2066 static int 2067 compression_end_lzma(struct archive *a, struct la_zstream *lastrm) 2068 { 2069 lzma_stream *strm; 2070 2071 (void)a; /* UNUSED */ 2072 strm = (lzma_stream *)lastrm->real_stream; 2073 lzma_end(strm); 2074 free(strm); 2075 lastrm->valid = 0; 2076 lastrm->real_stream = NULL; 2077 return (ARCHIVE_OK); 2078 } 2079 #else 2080 static int 2081 compression_init_encoder_lzma1(struct archive *a, 2082 struct la_zstream *lastrm, int level) 2083 { 2084 2085 (void) level; /* UNUSED */ 2086 if (lastrm->valid) 2087 compression_end(a, lastrm); 2088 return (compression_unsupported_encoder(a, lastrm, "lzma")); 2089 } 2090 static int 2091 compression_init_encoder_lzma2(struct archive *a, 2092 struct la_zstream *lastrm, int level) 2093 { 2094 2095 (void) level; /* UNUSED */ 2096 if (lastrm->valid) 2097 compression_end(a, lastrm); 2098 return (compression_unsupported_encoder(a, lastrm, "lzma")); 2099 } 2100 #endif 2101 2102 /* 2103 * _7_PPMD compressor. 2104 */ 2105 static void 2106 ppmd_write(void *p, Byte b) 2107 { 2108 struct archive_write *a = ((IByteOut *)p)->a; 2109 struct _7zip *zip = (struct _7zip *)(a->format_data); 2110 struct la_zstream *lastrm = &(zip->stream); 2111 struct ppmd_stream *strm; 2112 2113 if (lastrm->avail_out) { 2114 *lastrm->next_out++ = b; 2115 lastrm->avail_out--; 2116 lastrm->total_out++; 2117 return; 2118 } 2119 strm = (struct ppmd_stream *)lastrm->real_stream; 2120 if (strm->buff_ptr < strm->buff_end) { 2121 *strm->buff_ptr++ = b; 2122 strm->buff_bytes++; 2123 } 2124 } 2125 2126 static int 2127 compression_init_encoder_ppmd(struct archive *a, 2128 struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize) 2129 { 2130 struct ppmd_stream *strm; 2131 uint8_t *props; 2132 int r; 2133 2134 if (lastrm->valid) 2135 compression_end(a, lastrm); 2136 strm = calloc(1, sizeof(*strm)); 2137 if (strm == NULL) { 2138 archive_set_error(a, ENOMEM, 2139 "Can't allocate memory for PPMd"); 2140 return (ARCHIVE_FATAL); 2141 } 2142 strm->buff = malloc(32); 2143 if (strm->buff == NULL) { 2144 free(strm); 2145 archive_set_error(a, ENOMEM, 2146 "Can't allocate memory for PPMd"); 2147 return (ARCHIVE_FATAL); 2148 } 2149 strm->buff_ptr = strm->buff; 2150 strm->buff_end = strm->buff + 32; 2151 2152 props = malloc(1+4); 2153 if (props == NULL) { 2154 free(strm->buff); 2155 free(strm); 2156 archive_set_error(a, ENOMEM, 2157 "Coludn't allocate memory for PPMd"); 2158 return (ARCHIVE_FATAL); 2159 } 2160 props[0] = maxOrder; 2161 archive_le32enc(props+1, msize); 2162 __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context); 2163 r = __archive_ppmd7_functions.Ppmd7_Alloc( 2164 &strm->ppmd7_context, msize); 2165 if (r == 0) { 2166 free(strm->buff); 2167 free(strm); 2168 free(props); 2169 archive_set_error(a, ENOMEM, 2170 "Coludn't allocate memory for PPMd"); 2171 return (ARCHIVE_FATAL); 2172 } 2173 __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder); 2174 strm->byteout.a = (struct archive_write *)a; 2175 strm->byteout.Write = ppmd_write; 2176 strm->range_enc.Stream = &(strm->byteout); 2177 __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc)); 2178 strm->stat = 0; 2179 2180 lastrm->real_stream = strm; 2181 lastrm->valid = 1; 2182 lastrm->code = compression_code_ppmd; 2183 lastrm->end = compression_end_ppmd; 2184 lastrm->prop_size = 5; 2185 lastrm->props = props; 2186 return (ARCHIVE_OK); 2187 } 2188 2189 static int 2190 compression_code_ppmd(struct archive *a, 2191 struct la_zstream *lastrm, enum la_zaction action) 2192 { 2193 struct ppmd_stream *strm; 2194 2195 (void)a; /* UNUSED */ 2196 2197 strm = (struct ppmd_stream *)lastrm->real_stream; 2198 2199 /* Copy encoded data if there are remaining bytes from previous call. */ 2200 if (strm->buff_bytes) { 2201 uint8_t *p = strm->buff_ptr - strm->buff_bytes; 2202 while (lastrm->avail_out && strm->buff_bytes) { 2203 *lastrm->next_out++ = *p++; 2204 lastrm->avail_out--; 2205 lastrm->total_out++; 2206 strm->buff_bytes--; 2207 } 2208 if (strm->buff_bytes) 2209 return (ARCHIVE_OK); 2210 if (strm->stat == 1) 2211 return (ARCHIVE_EOF); 2212 strm->buff_ptr = strm->buff; 2213 } 2214 while (lastrm->avail_in && lastrm->avail_out) { 2215 __archive_ppmd7_functions.Ppmd7_EncodeSymbol( 2216 &(strm->ppmd7_context), &(strm->range_enc), 2217 *lastrm->next_in++); 2218 lastrm->avail_in--; 2219 lastrm->total_in++; 2220 } 2221 if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) { 2222 __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData( 2223 &(strm->range_enc)); 2224 strm->stat = 1; 2225 /* Return EOF if there are no remaining bytes. */ 2226 if (strm->buff_bytes == 0) 2227 return (ARCHIVE_EOF); 2228 } 2229 return (ARCHIVE_OK); 2230 } 2231 2232 static int 2233 compression_end_ppmd(struct archive *a, struct la_zstream *lastrm) 2234 { 2235 struct ppmd_stream *strm; 2236 2237 (void)a; /* UNUSED */ 2238 2239 strm = (struct ppmd_stream *)lastrm->real_stream; 2240 __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context); 2241 free(strm->buff); 2242 free(strm); 2243 lastrm->real_stream = NULL; 2244 lastrm->valid = 0; 2245 return (ARCHIVE_OK); 2246 } 2247 2248 /* 2249 * Universal compressor initializer. 2250 */ 2251 static int 2252 _7z_compression_init_encoder(struct archive_write *a, unsigned compression, 2253 int compression_level) 2254 { 2255 struct _7zip *zip; 2256 int r; 2257 2258 zip = (struct _7zip *)a->format_data; 2259 switch (compression) { 2260 case _7Z_DEFLATE: 2261 r = compression_init_encoder_deflate( 2262 &(a->archive), &(zip->stream), 2263 compression_level, 0); 2264 break; 2265 case _7Z_BZIP2: 2266 r = compression_init_encoder_bzip2( 2267 &(a->archive), &(zip->stream), 2268 compression_level); 2269 break; 2270 case _7Z_LZMA1: 2271 r = compression_init_encoder_lzma1( 2272 &(a->archive), &(zip->stream), 2273 compression_level); 2274 break; 2275 case _7Z_LZMA2: 2276 r = compression_init_encoder_lzma2( 2277 &(a->archive), &(zip->stream), 2278 compression_level); 2279 break; 2280 case _7Z_PPMD: 2281 r = compression_init_encoder_ppmd( 2282 &(a->archive), &(zip->stream), 2283 PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE); 2284 break; 2285 case _7Z_COPY: 2286 default: 2287 r = compression_init_encoder_copy( 2288 &(a->archive), &(zip->stream)); 2289 break; 2290 } 2291 if (r == ARCHIVE_OK) { 2292 zip->stream.total_in = 0; 2293 zip->stream.next_out = zip->wbuff; 2294 zip->stream.avail_out = sizeof(zip->wbuff); 2295 zip->stream.total_out = 0; 2296 } 2297 2298 return (r); 2299 } 2300 2301 static int 2302 compression_code(struct archive *a, struct la_zstream *lastrm, 2303 enum la_zaction action) 2304 { 2305 if (lastrm->valid) 2306 return (lastrm->code(a, lastrm, action)); 2307 return (ARCHIVE_OK); 2308 } 2309 2310 static int 2311 compression_end(struct archive *a, struct la_zstream *lastrm) 2312 { 2313 if (lastrm->valid) { 2314 lastrm->prop_size = 0; 2315 free(lastrm->props); 2316 lastrm->props = NULL; 2317 return (lastrm->end(a, lastrm)); 2318 } 2319 return (ARCHIVE_OK); 2320 } 2321 2322 2323