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