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