2 * Copyright (c) 2011-2012 Michihiro NAKAJIMA
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
26 #include "archive_platform.h"
27 __FBSDID("$FreeBSD$");
45 #include "archive_crc32.h"
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"
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
68 * 7-Zip header property IDs.
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
82 #define kCodersUnPackSize 0x0C
83 #define kNumUnPackStream 0x0D
84 #define kEmptyStream 0x0E
85 #define kEmptyFile 0x0F
91 #define kAttributes 0x15
92 #define kEncodedHeader 0x17
100 * A stream object of universal compressor.
103 const uint8_t *next_in;
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);
123 #define PPMD7_DEFAULT_ORDER 6
124 #define PPMD7_DEFAULT_MEM_SIZE (1 << 24)
128 CPpmd7 ppmd7_context;
129 CPpmd7z_RangeEnc range_enc;
144 struct archive_rb_node rbnode;
148 uint8_t *utf16name;/* UTF16-LE name. */
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)
173 uint64_t temp_offset;
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;
189 #define PRECODE_CRC32 1
190 #define ENCODED_CRC32 2
192 unsigned opt_compression;
193 int opt_compression_level;
195 struct la_zstream stream;
198 struct archive_string_conv *sconv;
201 * Compressed data buffer.
203 unsigned char wbuff[512 * 20 * 6];
204 size_t wbuff_remaining;
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.
214 } file_list, empty_list;
215 struct archive_rb_tree rbtree;/* for empty files */
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 *,
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 ,
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);
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 *);
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 *);
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 *);
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,
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);
286 archive_write_set_format_7zip(struct archive *_a)
288 static const struct archive_rb_tree_ops rb_ops = {
289 file_cmp_node, file_cmp_key
291 struct archive_write *a = (struct archive_write *)_a;
294 archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
295 ARCHIVE_STATE_NEW, "archive_write_set_format_7zip");
297 /* If another format was already registered, unregister it. */
298 if (a->format_free != NULL)
301 zip = calloc(1, sizeof(*zip));
303 archive_set_error(&a->archive, ENOMEM,
304 "Can't allocate 7-Zip data");
305 return (ARCHIVE_FATAL);
308 __archive_rb_tree_init(&(zip->rbtree), &rb_ops);
309 file_init_register(zip);
310 file_init_register_empty(zip);
312 /* Set default compression type and its level. */
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;
320 zip->opt_compression = _7Z_COPY;
322 zip->opt_compression_level = 6;
324 a->format_data = zip;
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";
340 _7z_options(struct archive_write *a, const char *key, const char *value)
344 zip = (struct _7zip *)a->format_data;
346 if (strcmp(key, "compression") == 0) {
347 const char *name = NULL;
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)
357 zip->opt_compression = _7Z_DEFLATE;
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;
368 else if (strcmp(value, "lzma1") == 0 ||
369 strcmp(value, "LZMA1") == 0)
371 zip->opt_compression = _7Z_LZMA1;
375 else if (strcmp(value, "lzma2") == 0 ||
376 strcmp(value, "LZMA2") == 0)
378 zip->opt_compression = _7Z_LZMA2;
382 else if (strcmp(value, "ppmd") == 0 ||
383 strcmp(value, "PPMD") == 0 ||
384 strcmp(value, "PPMd") == 0)
385 zip->opt_compression = _7Z_PPMD;
387 archive_set_error(&(a->archive),
389 "Unknown compression name: `%s'",
391 return (ARCHIVE_FAILED);
394 archive_set_error(&(a->archive),
396 "`%s' compression not supported "
399 return (ARCHIVE_FAILED);
403 if (strcmp(key, "compression-level") == 0) {
405 !(value[0] >= '0' && value[0] <= '9') ||
407 archive_set_error(&(a->archive),
409 "Illegal value `%s'",
411 return (ARCHIVE_FAILED);
413 zip->opt_compression_level = value[0] - '0';
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);
424 _7z_write_header(struct archive_write *a, struct archive_entry *entry)
430 zip = (struct _7zip *)a->format_data;
431 zip->cur_file = NULL;
432 zip->entry_bytes_remaining = 0;
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);
441 r = file_new(a, entry, &file);
442 if (r < ARCHIVE_WARN) {
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. */
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]++;
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++;
469 zip->total_number_dir_entry++;
471 file_register_empty(zip, file);
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);
483 return (ARCHIVE_FATAL);
487 /* Register a non-empty file. */
488 file_register(zip, file);
491 * Set the current file to cur_file to read its contents.
493 zip->cur_file = file;
496 /* Save a offset of current file in temporary file. */
497 zip->entry_bytes_remaining = file->size;
498 zip->entry_crc32 = 0;
501 * Store a symbolic link name as file contents.
503 if (archive_entry_filetype(entry) == AE_IFLNK) {
505 const void *p = (const void *)archive_entry_symlink(entry);
506 bytes = compress_out(a, p, (size_t)file->size, ARCHIVE_Z_RUN);
509 zip->entry_crc32 = crc32(zip->entry_crc32, p, (unsigned)bytes);
510 zip->entry_bytes_remaining -= bytes;
517 * Write data to a temporary file.
520 write_to_temp(struct archive_write *a, const void *buff, size_t s)
523 const unsigned char *p;
526 zip = (struct _7zip *)a->format_data;
529 * Open a temporary file.
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);
541 p = (const unsigned char *)buff;
543 ws = write(zip->temp_fd, p, s);
545 archive_set_error(&(a->archive), errno,
546 "fwrite function failed");
547 return (ARCHIVE_FATAL);
551 zip->temp_offset += ws;
557 compress_out(struct archive_write *a, const void *buff, size_t s,
560 struct _7zip *zip = (struct _7zip *)a->format_data;
563 if (run == ARCHIVE_Z_FINISH && zip->stream.total_in == 0 && s == 0)
566 if ((zip->crc32flg & PRECODE_CRC32) && s)
567 zip->precode_crc32 = crc32(zip->precode_crc32, buff,
569 zip->stream.next_in = (const unsigned char *)buff;
570 zip->stream.avail_in = s;
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))
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)
588 if (zip->stream.avail_in == 0)
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);
604 _7z_write_data(struct archive_write *a, const void *buff, size_t s)
609 zip = (struct _7zip *)a->format_data;
611 if (s > zip->entry_bytes_remaining)
612 s = (size_t)zip->entry_bytes_remaining;
613 if (s == 0 || zip->cur_file == NULL)
615 bytes = compress_out(a, buff, s, ARCHIVE_Z_RUN);
618 zip->entry_crc32 = crc32(zip->entry_crc32, buff, (unsigned)bytes);
619 zip->entry_bytes_remaining -= bytes;
624 _7z_finish_entry(struct archive_write *a)
630 zip = (struct _7zip *)a->format_data;
631 if (zip->cur_file == NULL)
634 while (zip->entry_bytes_remaining > 0) {
635 s = (size_t)zip->entry_bytes_remaining;
636 if (s > a->null_length)
638 r = _7z_write_data(a, a->nulls, s);
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;
651 flush_wbuff(struct archive_write *a)
657 zip = (struct _7zip *)a->format_data;
658 s = sizeof(zip->wbuff) - zip->wbuff_remaining;
659 r = __archive_write_output(a, zip->wbuff, s);
662 zip->wbuff_remaining = sizeof(zip->wbuff);
667 copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
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);
683 if (length > zip->wbuff_remaining)
684 rsize = zip->wbuff_remaining;
686 rsize = (size_t)length;
687 wb = zip->wbuff + (sizeof(zip->wbuff) - zip->wbuff_remaining);
688 rs = read(zip->temp_fd, wb, rsize);
690 archive_set_error(&(a->archive), errno,
691 "Can't read temporary file(%jd)",
693 return (ARCHIVE_FATAL);
696 archive_set_error(&(a->archive), 0,
697 "Truncated 7-Zip archive");
698 return (ARCHIVE_FATAL);
700 zip->wbuff_remaining -= rs;
702 if (zip->wbuff_remaining == 0) {
712 _7z_close(struct archive_write *a)
716 uint64_t header_offset, header_size, header_unpacksize;
718 uint32_t header_crc32;
721 zip = (struct _7zip *)a->format_data;
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;
728 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
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;
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;
747 /* Connect a directory file list. */
748 ARCHIVE_RB_TREE_FOREACH(n, &(zip->rbtree)) {
749 file_register(zip, (struct file *)n);
753 * NOTE: 7z command supports just LZMA1, LZMA2 and COPY for
754 * the compression type for encoding the header.
757 header_compression = _7Z_LZMA1;
758 /* If the stored file is only one, do not encode the header.
759 * This is the same way 7z command does. */
760 if (zip->total_number_entry == 1)
761 header_compression = _7Z_COPY;
763 header_compression = _7Z_COPY;
765 r = _7z_compression_init_encoder(a, header_compression, 6);
768 zip->crc32flg = PRECODE_CRC32;
769 zip->precode_crc32 = 0;
770 r = make_header(a, data_offset, data_size, data_unpacksize,
774 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
777 header_offset = data_offset + data_size;
778 header_size = zip->stream.total_out;
779 header_crc32 = zip->precode_crc32;
780 header_unpacksize = zip->stream.total_in;
782 if (header_compression != _7Z_COPY) {
784 * Encode the header in order to reduce the size
787 free(zip->coder.props);
788 zip->coder.codec = header_compression;
789 zip->coder.prop_size = zip->stream.prop_size;
790 zip->coder.props = zip->stream.props;
791 zip->stream.prop_size = 0;
792 zip->stream.props = NULL;
794 r = _7z_compression_init_encoder(a, _7Z_COPY, 0);
797 zip->crc32flg = ENCODED_CRC32;
798 zip->encoded_crc32 = 0;
801 * Make EncodedHeader.
803 r = enc_uint64(a, kEncodedHeader);
806 r = make_streamsInfo(a, header_offset, header_size,
807 header_unpacksize, 1, &(zip->coder), 0,
811 r = (int)compress_out(a, NULL, 0, ARCHIVE_Z_FINISH);
814 header_offset = header_offset + header_size;
815 header_size = zip->stream.total_out;
816 header_crc32 = zip->encoded_crc32;
820 header_offset = header_size = 0;
824 length = zip->temp_offset;
827 * Make the zip header on wbuff(write buffer).
830 zip->wbuff_remaining = sizeof(zip->wbuff);
831 memcpy(&wb[0], "7z\xBC\xAF\x27\x1C", 6);
832 wb[6] = 0;/* Major version. */
833 wb[7] = 3;/* Minor version. */
834 archive_le64enc(&wb[12], header_offset);/* Next Header Offset */
835 archive_le64enc(&wb[20], header_size);/* Next Header Size */
836 archive_le32enc(&wb[28], header_crc32);/* Next Header CRC */
837 archive_le32enc(&wb[8], crc32(0, &wb[12], 20));/* Start Header CRC */
838 zip->wbuff_remaining -= 32;
841 * Read all file contents and an encoded header from the temporary
842 * file and write out it.
844 r = copy_out(a, 0, length);
852 * Encode 64 bits value into 7-Zip's encoded UINT64 value.
855 enc_uint64(struct archive_write *a, uint64_t val)
857 unsigned mask = 0x80;
862 for (i = 1; i < (int)sizeof(numdata); i++) {
864 numdata[0] |= (uint8_t)val;
867 numdata[i] = (uint8_t)val;
872 return ((int)compress_out(a, numdata, i, ARCHIVE_Z_RUN));
876 make_substreamsInfo(struct archive_write *a, struct coder *coders)
878 struct _7zip *zip = (struct _7zip *)a->format_data;
883 * Make SubStreamsInfo.
885 r = enc_uint64(a, kSubStreamsInfo);
889 if (zip->total_number_nonempty_entry > 1 && coders->codec != _7Z_COPY) {
891 * Make NumUnPackStream.
893 r = enc_uint64(a, kNumUnPackStream);
897 /* Write numUnpackStreams */
898 r = enc_uint64(a, zip->total_number_nonempty_entry);
905 r = enc_uint64(a, kSize);
908 file = zip->file_list.first;
909 for (;file != NULL; file = file->next) {
910 if (file->next == NULL ||
911 file->next->size == 0)
913 r = enc_uint64(a, file->size);
922 r = enc_uint64(a, kCRC);
927 /* All are defined */
928 r = enc_uint64(a, 1);
931 file = zip->file_list.first;
932 for (;file != NULL; file = file->next) {
936 archive_le32enc(crc, file->crc32);
937 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
943 r = enc_uint64(a, kEnd);
950 make_streamsInfo(struct archive_write *a, uint64_t offset, uint64_t pack_size,
951 uint64_t unpack_size, int num_coder, struct coder *coders, int substrm,
954 struct _7zip *zip = (struct _7zip *)a->format_data;
955 uint8_t codec_buff[8];
960 if (coders->codec == _7Z_COPY)
961 numFolders = (int)zip->total_number_nonempty_entry;
968 r = enc_uint64(a, kPackInfo);
973 r = enc_uint64(a, offset);
977 /* Write NumPackStreams. */
978 r = enc_uint64(a, numFolders);
983 r = enc_uint64(a, kSize);
987 if (numFolders > 1) {
988 struct file *file = zip->file_list.first;
989 for (;file != NULL; file = file->next) {
992 r = enc_uint64(a, file->size);
998 r = enc_uint64(a, pack_size);
1003 r = enc_uint64(a, kEnd);
1010 r = enc_uint64(a, kUnPackInfo);
1017 r = enc_uint64(a, kFolder);
1021 /* Write NumFolders. */
1022 r = enc_uint64(a, numFolders);
1026 /* Write External. */
1027 r = enc_uint64(a, 0);
1031 for (fi = 0; fi < numFolders; fi++) {
1032 /* Write NumCoders. */
1033 r = enc_uint64(a, num_coder);
1037 for (i = 0; i < num_coder; i++) {
1038 unsigned codec_id = coders[i].codec;
1040 /* Write Codec flag. */
1041 archive_be64enc(codec_buff, codec_id);
1042 for (codec_size = 8; codec_size > 0; codec_size--) {
1043 if (codec_buff[8 - codec_size])
1046 if (codec_size == 0)
1048 if (coders[i].prop_size)
1049 r = enc_uint64(a, codec_size | 0x20);
1051 r = enc_uint64(a, codec_size);
1055 /* Write Codec ID. */
1057 r = (int)compress_out(a, &codec_buff[8-codec_size],
1058 codec_size, ARCHIVE_Z_RUN);
1062 if (coders[i].prop_size) {
1063 /* Write Codec property size. */
1064 r = enc_uint64(a, coders[i].prop_size);
1068 /* Write Codec properties. */
1069 r = (int)compress_out(a, coders[i].props,
1070 coders[i].prop_size, ARCHIVE_Z_RUN);
1078 * Make CodersUnPackSize.
1080 r = enc_uint64(a, kCodersUnPackSize);
1084 if (numFolders > 1) {
1085 struct file *file = zip->file_list.first;
1086 for (;file != NULL; file = file->next) {
1087 if (file->size == 0)
1089 r = enc_uint64(a, file->size);
1095 /* Write UnPackSize. */
1096 r = enc_uint64(a, unpack_size);
1106 r = enc_uint64(a, kCRC);
1110 /* All are defined */
1111 r = enc_uint64(a, 1);
1114 archive_le32enc(crc, header_crc);
1115 r = (int)compress_out(a, crc, 4, ARCHIVE_Z_RUN);
1121 r = enc_uint64(a, kEnd);
1127 * Make SubStreamsInfo.
1129 r = make_substreamsInfo(a, coders);
1136 r = enc_uint64(a, kEnd);
1140 return (ARCHIVE_OK);
1144 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1146 utcToFiletime(time_t t, long ns)
1151 fileTime *= 10000000;
1152 fileTime += ns / 100;
1153 fileTime += EPOC_TIME;
1158 make_time(struct archive_write *a, uint8_t type, unsigned flg, int ti)
1160 uint8_t filetime[8];
1161 struct _7zip *zip = (struct _7zip *)a->format_data;
1169 if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
1170 /* Write Time Type. */
1171 r = enc_uint64(a, type);
1174 /* Write EmptyStream Size. */
1175 r = enc_uint64(a, 2 + zip->total_number_entry * 8);
1178 /* All are defined. */
1179 r = enc_uint64(a, 1);
1183 if (zip->total_number_time_defined[ti] == 0)
1184 return (ARCHIVE_OK);
1186 /* Write Time Type. */
1187 r = enc_uint64(a, type);
1190 /* Write EmptyStream Size. */
1191 r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
1192 + zip->total_number_time_defined[ti] * 8);
1196 /* All are not defined. */
1197 r = enc_uint64(a, 0);
1203 file = zip->file_list.first;
1204 for (;file != NULL; file = file->next) {
1205 if (file->flg & flg)
1209 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1217 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1224 r = enc_uint64(a, 0);
1232 file = zip->file_list.first;
1233 for (;file != NULL; file = file->next) {
1234 if ((file->flg & flg) == 0)
1236 archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
1237 file->times[ti].time_ns));
1238 r = (int)compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
1243 return (ARCHIVE_OK);
1247 make_header(struct archive_write *a, uint64_t offset, uint64_t pack_size,
1248 uint64_t unpack_size, int codernum, struct coder *coders)
1250 struct _7zip *zip = (struct _7zip *)a->format_data;
1258 r = enc_uint64(a, kHeader);
1263 * If there are empty files only, do not write MainStreamInfo.
1265 if (zip->total_number_nonempty_entry) {
1267 * Make MainStreamInfo.
1269 r = enc_uint64(a, kMainStreamsInfo);
1272 r = make_streamsInfo(a, offset, pack_size, unpack_size,
1273 codernum, coders, 1, 0);
1281 r = enc_uint64(a, kFilesInfo);
1285 /* Write numFiles. */
1286 r = enc_uint64(a, zip->total_number_entry);
1290 if (zip->total_number_empty_entry > 0) {
1291 /* Make EmptyStream. */
1292 r = enc_uint64(a, kEmptyStream);
1296 /* Write EmptyStream Size. */
1297 r = enc_uint64(a, (zip->total_number_entry+7)>>3);
1303 file = zip->file_list.first;
1304 for (;file != NULL; file = file->next) {
1305 if (file->size == 0)
1309 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1317 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1323 if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
1324 /* Make EmptyFile. */
1325 r = enc_uint64(a, kEmptyFile);
1329 /* Write EmptyFile Size. */
1330 r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
1336 file = zip->file_list.first;
1337 for (;file != NULL; file = file->next) {
1344 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1352 r = (int)compress_out(a, &b, 1, ARCHIVE_Z_RUN);
1359 r = enc_uint64(a, kName);
1363 /* Write Name size. */
1364 r = enc_uint64(a, zip->total_bytes_entry_name+1);
1368 /* Write dmy byte. */
1369 r = enc_uint64(a, 0);
1373 file = zip->file_list.first;
1374 for (;file != NULL; file = file->next) {
1375 r = (int)compress_out(a, file->utf16name, file->name_len+2,
1382 r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
1387 r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
1392 r = make_time(a, kATime, ATIME_IS_SET, ATIME);
1396 /* Make Attributes. */
1397 r = enc_uint64(a, kAttributes);
1401 /* Write Attributes size. */
1402 r = enc_uint64(a, 2 + zip->total_number_entry * 4);
1406 /* Write "All Are Defined". */
1407 r = enc_uint64(a, 1);
1411 /* Write dmy byte. */
1412 r = enc_uint64(a, 0);
1416 file = zip->file_list.first;
1417 for (;file != NULL; file = file->next) {
1419 * High 16bits is unix mode.
1420 * Low 16bits is Windows attributes.
1422 uint32_t encattr, attr;
1427 if ((file->mode & 0222) == 0)
1428 attr |= 1;/* Read Only. */
1429 attr |= ((uint32_t)file->mode) << 16;
1430 archive_le32enc(&encattr, attr);
1431 r = (int)compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
1437 r = enc_uint64(a, kEnd);
1442 r = enc_uint64(a, kEnd);
1446 return (ARCHIVE_OK);
1451 _7z_free(struct archive_write *a)
1453 struct _7zip *zip = (struct _7zip *)a->format_data;
1455 /* Close the temporary file. */
1456 if (zip->temp_fd >= 0)
1457 close(zip->temp_fd);
1459 file_free_register(zip);
1460 compression_end(&(a->archive), &(zip->stream));
1461 free(zip->coder.props);
1464 return (ARCHIVE_OK);
1468 file_cmp_node(const struct archive_rb_node *n1,
1469 const struct archive_rb_node *n2)
1471 const struct file *f1 = (const struct file *)n1;
1472 const struct file *f2 = (const struct file *)n2;
1474 if (f1->name_len == f2->name_len)
1475 return (memcmp(f1->utf16name, f2->utf16name, f1->name_len));
1476 return (f1->name_len > f2->name_len)?1:-1;
1480 file_cmp_key(const struct archive_rb_node *n, const void *key)
1482 const struct file *f = (const struct file *)n;
1484 return (f->name_len - *(const char *)key);
1488 file_new(struct archive_write *a, struct archive_entry *entry,
1489 struct file **newfile)
1495 int ret = ARCHIVE_OK;
1497 zip = (struct _7zip *)a->format_data;
1500 file = calloc(1, sizeof(*file));
1502 archive_set_error(&a->archive, ENOMEM,
1503 "Can't allocate memory");
1504 return (ARCHIVE_FATAL);
1507 if (0 > archive_entry_pathname_l(entry, &u16, &u16len, zip->sconv)) {
1508 if (errno == ENOMEM) {
1510 archive_set_error(&a->archive, ENOMEM,
1511 "Can't allocate memory for UTF-16LE");
1512 return (ARCHIVE_FATAL);
1514 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1515 "A filename cannot be converted to UTF-16LE;"
1516 "You should disable making Joliet extension");
1519 file->utf16name = malloc(u16len + 2);
1520 if (file->utf16name == NULL) {
1522 archive_set_error(&a->archive, ENOMEM,
1523 "Can't allocate memory for Name");
1524 return (ARCHIVE_FATAL);
1526 memcpy(file->utf16name, u16, u16len);
1527 file->utf16name[u16len+0] = 0;
1528 file->utf16name[u16len+1] = 0;
1529 file->name_len = (unsigned)u16len;
1530 file->mode = archive_entry_mode(entry);
1531 if (archive_entry_filetype(entry) == AE_IFREG)
1532 file->size = archive_entry_size(entry);
1534 archive_entry_set_size(entry, 0);
1535 if (archive_entry_filetype(entry) == AE_IFDIR)
1537 else if (archive_entry_filetype(entry) == AE_IFLNK)
1538 file->size = strlen(archive_entry_symlink(entry));
1539 if (archive_entry_mtime_is_set(entry)) {
1540 file->flg |= MTIME_IS_SET;
1541 file->times[MTIME].time = archive_entry_mtime(entry);
1542 file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
1544 if (archive_entry_atime_is_set(entry)) {
1545 file->flg |= ATIME_IS_SET;
1546 file->times[ATIME].time = archive_entry_atime(entry);
1547 file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
1549 if (archive_entry_ctime_is_set(entry)) {
1550 file->flg |= CTIME_IS_SET;
1551 file->times[CTIME].time = archive_entry_ctime(entry);
1552 file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
1560 file_free(struct file *file)
1562 free(file->utf16name);
1567 file_register(struct _7zip *zip, struct file *file)
1570 *zip->file_list.last = file;
1571 zip->file_list.last = &(file->next);
1575 file_init_register(struct _7zip *zip)
1577 zip->file_list.first = NULL;
1578 zip->file_list.last = &(zip->file_list.first);
1582 file_free_register(struct _7zip *zip)
1584 struct file *file, *file_next;
1586 file = zip->file_list.first;
1587 while (file != NULL) {
1588 file_next = file->next;
1595 file_register_empty(struct _7zip *zip, struct file *file)
1598 *zip->empty_list.last = file;
1599 zip->empty_list.last = &(file->next);
1603 file_init_register_empty(struct _7zip *zip)
1605 zip->empty_list.first = NULL;
1606 zip->empty_list.last = &(zip->empty_list.first);
1609 #if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\
1610 !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
1612 compression_unsupported_encoder(struct archive *a,
1613 struct la_zstream *lastrm, const char *name)
1616 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1617 "%s compression not supported on this platform", name);
1619 lastrm->real_stream = NULL;
1620 return (ARCHIVE_FAILED);
1625 * _7_COPY compressor.
1628 compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
1632 compression_end(a, lastrm);
1634 lastrm->code = compression_code_copy;
1635 lastrm->end = compression_end_copy;
1636 return (ARCHIVE_OK);
1640 compression_code_copy(struct archive *a,
1641 struct la_zstream *lastrm, enum la_zaction action)
1645 (void)a; /* UNUSED */
1646 if (lastrm->avail_out > lastrm->avail_in)
1647 bytes = lastrm->avail_in;
1649 bytes = lastrm->avail_out;
1651 memcpy(lastrm->next_out, lastrm->next_in, bytes);
1652 lastrm->next_in += bytes;
1653 lastrm->avail_in -= bytes;
1654 lastrm->total_in += bytes;
1655 lastrm->next_out += bytes;
1656 lastrm->avail_out -= bytes;
1657 lastrm->total_out += bytes;
1659 if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
1660 return (ARCHIVE_EOF);
1661 return (ARCHIVE_OK);
1665 compression_end_copy(struct archive *a, struct la_zstream *lastrm)
1667 (void)a; /* UNUSED */
1669 return (ARCHIVE_OK);
1673 * _7_DEFLATE compressor.
1677 compression_init_encoder_deflate(struct archive *a,
1678 struct la_zstream *lastrm, int level, int withheader)
1683 compression_end(a, lastrm);
1684 strm = calloc(1, sizeof(*strm));
1686 archive_set_error(a, ENOMEM,
1687 "Can't allocate memory for gzip stream");
1688 return (ARCHIVE_FATAL);
1690 /* zlib.h is not const-correct, so we need this one bit
1691 * of ugly hackery to convert a const * pointer to
1692 * a non-const pointer. */
1693 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1694 strm->avail_in = (uInt)lastrm->avail_in;
1695 strm->total_in = (uLong)lastrm->total_in;
1696 strm->next_out = lastrm->next_out;
1697 strm->avail_out = (uInt)lastrm->avail_out;
1698 strm->total_out = (uLong)lastrm->total_out;
1699 if (deflateInit2(strm, level, Z_DEFLATED,
1700 (withheader)?15:-15,
1701 8, Z_DEFAULT_STRATEGY) != Z_OK) {
1703 lastrm->real_stream = NULL;
1704 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1705 "Internal error initializing compression library");
1706 return (ARCHIVE_FATAL);
1708 lastrm->real_stream = strm;
1710 lastrm->code = compression_code_deflate;
1711 lastrm->end = compression_end_deflate;
1712 return (ARCHIVE_OK);
1716 compression_code_deflate(struct archive *a,
1717 struct la_zstream *lastrm, enum la_zaction action)
1722 strm = (z_stream *)lastrm->real_stream;
1723 /* zlib.h is not const-correct, so we need this one bit
1724 * of ugly hackery to convert a const * pointer to
1725 * a non-const pointer. */
1726 strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1727 strm->avail_in = (uInt)lastrm->avail_in;
1728 strm->total_in = (uLong)lastrm->total_in;
1729 strm->next_out = lastrm->next_out;
1730 strm->avail_out = (uInt)lastrm->avail_out;
1731 strm->total_out = (uLong)lastrm->total_out;
1733 (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
1734 lastrm->next_in = strm->next_in;
1735 lastrm->avail_in = strm->avail_in;
1736 lastrm->total_in = strm->total_in;
1737 lastrm->next_out = strm->next_out;
1738 lastrm->avail_out = strm->avail_out;
1739 lastrm->total_out = strm->total_out;
1742 return (ARCHIVE_OK);
1744 return (ARCHIVE_EOF);
1746 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1747 "GZip compression failed:"
1748 " deflate() call returned status %d", r);
1749 return (ARCHIVE_FATAL);
1754 compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
1759 strm = (z_stream *)lastrm->real_stream;
1760 r = deflateEnd(strm);
1762 lastrm->real_stream = NULL;
1765 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1766 "Failed to clean up compressor");
1767 return (ARCHIVE_FATAL);
1769 return (ARCHIVE_OK);
1773 compression_init_encoder_deflate(struct archive *a,
1774 struct la_zstream *lastrm, int level, int withheader)
1777 (void) level; /* UNUSED */
1778 (void) withheader; /* UNUSED */
1780 compression_end(a, lastrm);
1781 return (compression_unsupported_encoder(a, lastrm, "deflate"));
1786 * _7_BZIP2 compressor.
1788 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1790 compression_init_encoder_bzip2(struct archive *a,
1791 struct la_zstream *lastrm, int level)
1796 compression_end(a, lastrm);
1797 strm = calloc(1, sizeof(*strm));
1799 archive_set_error(a, ENOMEM,
1800 "Can't allocate memory for bzip2 stream");
1801 return (ARCHIVE_FATAL);
1803 /* bzlib.h is not const-correct, so we need this one bit
1804 * of ugly hackery to convert a const * pointer to
1805 * a non-const pointer. */
1806 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1807 strm->avail_in = lastrm->avail_in;
1808 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1809 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1810 strm->next_out = (char *)lastrm->next_out;
1811 strm->avail_out = lastrm->avail_out;
1812 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1813 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1814 if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
1816 lastrm->real_stream = NULL;
1817 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1818 "Internal error initializing compression library");
1819 return (ARCHIVE_FATAL);
1821 lastrm->real_stream = strm;
1823 lastrm->code = compression_code_bzip2;
1824 lastrm->end = compression_end_bzip2;
1825 return (ARCHIVE_OK);
1829 compression_code_bzip2(struct archive *a,
1830 struct la_zstream *lastrm, enum la_zaction action)
1835 strm = (bz_stream *)lastrm->real_stream;
1836 /* bzlib.h is not const-correct, so we need this one bit
1837 * of ugly hackery to convert a const * pointer to
1838 * a non-const pointer. */
1839 strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1840 strm->avail_in = lastrm->avail_in;
1841 strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1842 strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1843 strm->next_out = (char *)lastrm->next_out;
1844 strm->avail_out = lastrm->avail_out;
1845 strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1846 strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1847 r = BZ2_bzCompress(strm,
1848 (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
1849 lastrm->next_in = (const unsigned char *)strm->next_in;
1850 lastrm->avail_in = strm->avail_in;
1852 (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
1853 + (uint64_t)(uint32_t)strm->total_in_lo32;
1854 lastrm->next_out = (unsigned char *)strm->next_out;
1855 lastrm->avail_out = strm->avail_out;
1857 (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
1858 + (uint64_t)(uint32_t)strm->total_out_lo32;
1860 case BZ_RUN_OK: /* Non-finishing */
1861 case BZ_FINISH_OK: /* Finishing: There's more work to do */
1862 return (ARCHIVE_OK);
1863 case BZ_STREAM_END: /* Finishing: all done */
1864 /* Only occurs in finishing case */
1865 return (ARCHIVE_EOF);
1867 /* Any other return value indicates an error */
1868 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1869 "Bzip2 compression failed:"
1870 " BZ2_bzCompress() call returned status %d", r);
1871 return (ARCHIVE_FATAL);
1876 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
1881 strm = (bz_stream *)lastrm->real_stream;
1882 r = BZ2_bzCompressEnd(strm);
1884 lastrm->real_stream = NULL;
1887 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1888 "Failed to clean up compressor");
1889 return (ARCHIVE_FATAL);
1891 return (ARCHIVE_OK);
1896 compression_init_encoder_bzip2(struct archive *a,
1897 struct la_zstream *lastrm, int level)
1900 (void) level; /* UNUSED */
1902 compression_end(a, lastrm);
1903 return (compression_unsupported_encoder(a, lastrm, "bzip2"));
1908 * _7_LZMA1, _7_LZMA2 compressor.
1910 #if defined(HAVE_LZMA_H)
1912 compression_init_encoder_lzma(struct archive *a,
1913 struct la_zstream *lastrm, int level, uint64_t filter_id)
1915 static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
1917 lzma_filter *lzmafilters;
1918 lzma_options_lzma lzma_opt;
1922 compression_end(a, lastrm);
1923 strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
1925 archive_set_error(a, ENOMEM,
1926 "Can't allocate memory for lzma stream");
1927 return (ARCHIVE_FATAL);
1929 lzmafilters = (lzma_filter *)(strm+1);
1932 if (lzma_lzma_preset(&lzma_opt, level)) {
1934 lastrm->real_stream = NULL;
1935 archive_set_error(a, ENOMEM,
1936 "Internal error initializing compression library");
1937 return (ARCHIVE_FATAL);
1939 lzmafilters[0].id = filter_id;
1940 lzmafilters[0].options = &lzma_opt;
1941 lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
1943 r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
1946 lastrm->real_stream = NULL;
1947 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1948 "lzma_properties_size failed");
1949 return (ARCHIVE_FATAL);
1951 if (lastrm->prop_size) {
1952 lastrm->props = malloc(lastrm->prop_size);
1953 if (lastrm->props == NULL) {
1955 lastrm->real_stream = NULL;
1956 archive_set_error(a, ENOMEM,
1957 "Cannot allocate memory");
1958 return (ARCHIVE_FATAL);
1960 r = lzma_properties_encode(lzmafilters, lastrm->props);
1963 lastrm->real_stream = NULL;
1964 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1965 "lzma_properties_encode failed");
1966 return (ARCHIVE_FATAL);
1970 *strm = lzma_init_data;
1971 r = lzma_raw_encoder(strm, lzmafilters);
1974 lastrm->real_stream = strm;
1976 lastrm->code = compression_code_lzma;
1977 lastrm->end = compression_end_lzma;
1980 case LZMA_MEM_ERROR:
1982 lastrm->real_stream = NULL;
1983 archive_set_error(a, ENOMEM,
1984 "Internal error initializing compression library: "
1985 "Cannot allocate memory");
1990 lastrm->real_stream = NULL;
1991 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1992 "Internal error initializing compression library: "
1993 "It's a bug in liblzma");
2001 compression_init_encoder_lzma1(struct archive *a,
2002 struct la_zstream *lastrm, int level)
2004 return compression_init_encoder_lzma(a, lastrm, level,
2009 compression_init_encoder_lzma2(struct archive *a,
2010 struct la_zstream *lastrm, int level)
2012 return compression_init_encoder_lzma(a, lastrm, level,
2017 compression_code_lzma(struct archive *a,
2018 struct la_zstream *lastrm, enum la_zaction action)
2023 strm = (lzma_stream *)lastrm->real_stream;
2024 strm->next_in = lastrm->next_in;
2025 strm->avail_in = lastrm->avail_in;
2026 strm->total_in = lastrm->total_in;
2027 strm->next_out = lastrm->next_out;
2028 strm->avail_out = lastrm->avail_out;
2029 strm->total_out = lastrm->total_out;
2031 (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
2032 lastrm->next_in = strm->next_in;
2033 lastrm->avail_in = strm->avail_in;
2034 lastrm->total_in = strm->total_in;
2035 lastrm->next_out = strm->next_out;
2036 lastrm->avail_out = strm->avail_out;
2037 lastrm->total_out = strm->total_out;
2040 /* Non-finishing case */
2041 return (ARCHIVE_OK);
2042 case LZMA_STREAM_END:
2043 /* This return can only occur in finishing case. */
2044 return (ARCHIVE_EOF);
2045 case LZMA_MEMLIMIT_ERROR:
2046 archive_set_error(a, ENOMEM,
2047 "lzma compression error:"
2048 " %ju MiB would have been needed",
2049 (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
2051 return (ARCHIVE_FATAL);
2053 /* Any other return value indicates an error */
2054 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2055 "lzma compression failed:"
2056 " lzma_code() call returned status %d", r);
2057 return (ARCHIVE_FATAL);
2062 compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
2066 (void)a; /* UNUSED */
2067 strm = (lzma_stream *)lastrm->real_stream;
2071 lastrm->real_stream = NULL;
2072 return (ARCHIVE_OK);
2076 compression_init_encoder_lzma1(struct archive *a,
2077 struct la_zstream *lastrm, int level)
2080 (void) level; /* UNUSED */
2082 compression_end(a, lastrm);
2083 return (compression_unsupported_encoder(a, lastrm, "lzma"));
2086 compression_init_encoder_lzma2(struct archive *a,
2087 struct la_zstream *lastrm, int level)
2090 (void) level; /* UNUSED */
2092 compression_end(a, lastrm);
2093 return (compression_unsupported_encoder(a, lastrm, "lzma"));
2098 * _7_PPMD compressor.
2101 ppmd_write(void *p, Byte b)
2103 struct archive_write *a = ((IByteOut *)p)->a;
2104 struct _7zip *zip = (struct _7zip *)(a->format_data);
2105 struct la_zstream *lastrm = &(zip->stream);
2106 struct ppmd_stream *strm;
2108 if (lastrm->avail_out) {
2109 *lastrm->next_out++ = b;
2110 lastrm->avail_out--;
2111 lastrm->total_out++;
2114 strm = (struct ppmd_stream *)lastrm->real_stream;
2115 if (strm->buff_ptr < strm->buff_end) {
2116 *strm->buff_ptr++ = b;
2122 compression_init_encoder_ppmd(struct archive *a,
2123 struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
2125 struct ppmd_stream *strm;
2130 compression_end(a, lastrm);
2131 strm = calloc(1, sizeof(*strm));
2133 archive_set_error(a, ENOMEM,
2134 "Can't allocate memory for PPMd");
2135 return (ARCHIVE_FATAL);
2137 strm->buff = malloc(32);
2138 if (strm->buff == NULL) {
2140 archive_set_error(a, ENOMEM,
2141 "Can't allocate memory for PPMd");
2142 return (ARCHIVE_FATAL);
2144 strm->buff_ptr = strm->buff;
2145 strm->buff_end = strm->buff + 32;
2147 props = malloc(1+4);
2148 if (props == NULL) {
2151 archive_set_error(a, ENOMEM,
2152 "Coludn't allocate memory for PPMd");
2153 return (ARCHIVE_FATAL);
2155 props[0] = maxOrder;
2156 archive_le32enc(props+1, msize);
2157 __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
2158 r = __archive_ppmd7_functions.Ppmd7_Alloc(
2159 &strm->ppmd7_context, msize);
2164 archive_set_error(a, ENOMEM,
2165 "Coludn't allocate memory for PPMd");
2166 return (ARCHIVE_FATAL);
2168 __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
2169 strm->byteout.a = (struct archive_write *)a;
2170 strm->byteout.Write = ppmd_write;
2171 strm->range_enc.Stream = &(strm->byteout);
2172 __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
2175 lastrm->real_stream = strm;
2177 lastrm->code = compression_code_ppmd;
2178 lastrm->end = compression_end_ppmd;
2179 lastrm->prop_size = 5;
2180 lastrm->props = props;
2181 return (ARCHIVE_OK);
2185 compression_code_ppmd(struct archive *a,
2186 struct la_zstream *lastrm, enum la_zaction action)
2188 struct ppmd_stream *strm;
2190 (void)a; /* UNUSED */
2192 strm = (struct ppmd_stream *)lastrm->real_stream;
2194 /* Copy encoded data if there are remaining bytes from previous call. */
2195 if (strm->buff_bytes) {
2196 uint8_t *p = strm->buff_ptr - strm->buff_bytes;
2197 while (lastrm->avail_out && strm->buff_bytes) {
2198 *lastrm->next_out++ = *p++;
2199 lastrm->avail_out--;
2200 lastrm->total_out++;
2203 if (strm->buff_bytes)
2204 return (ARCHIVE_OK);
2205 if (strm->stat == 1)
2206 return (ARCHIVE_EOF);
2207 strm->buff_ptr = strm->buff;
2209 while (lastrm->avail_in && lastrm->avail_out) {
2210 __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
2211 &(strm->ppmd7_context), &(strm->range_enc),
2212 *lastrm->next_in++);
2216 if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
2217 __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
2218 &(strm->range_enc));
2220 /* Return EOF if there are no remaining bytes. */
2221 if (strm->buff_bytes == 0)
2222 return (ARCHIVE_EOF);
2224 return (ARCHIVE_OK);
2228 compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
2230 struct ppmd_stream *strm;
2232 (void)a; /* UNUSED */
2234 strm = (struct ppmd_stream *)lastrm->real_stream;
2235 __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context);
2238 lastrm->real_stream = NULL;
2240 return (ARCHIVE_OK);
2244 * Universal compressor initializer.
2247 _7z_compression_init_encoder(struct archive_write *a, unsigned compression,
2248 int compression_level)
2253 zip = (struct _7zip *)a->format_data;
2254 switch (compression) {
2256 r = compression_init_encoder_deflate(
2257 &(a->archive), &(zip->stream),
2258 compression_level, 0);
2261 r = compression_init_encoder_bzip2(
2262 &(a->archive), &(zip->stream),
2266 r = compression_init_encoder_lzma1(
2267 &(a->archive), &(zip->stream),
2271 r = compression_init_encoder_lzma2(
2272 &(a->archive), &(zip->stream),
2276 r = compression_init_encoder_ppmd(
2277 &(a->archive), &(zip->stream),
2278 PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
2282 r = compression_init_encoder_copy(
2283 &(a->archive), &(zip->stream));
2286 if (r == ARCHIVE_OK) {
2287 zip->stream.total_in = 0;
2288 zip->stream.next_out = zip->wbuff;
2289 zip->stream.avail_out = sizeof(zip->wbuff);
2290 zip->stream.total_out = 0;
2297 compression_code(struct archive *a, struct la_zstream *lastrm,
2298 enum la_zaction action)
2301 return (lastrm->code(a, lastrm, action));
2302 return (ARCHIVE_OK);
2306 compression_end(struct archive *a, struct la_zstream *lastrm)
2308 if (lastrm->valid) {
2309 lastrm->prop_size = 0;
2310 free(lastrm->props);
2311 lastrm->props = NULL;
2312 return (lastrm->end(a, lastrm));
2314 return (ARCHIVE_OK);