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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1559 file_free(struct file *file)
1560 {
1561 	free(file->utf16name);
1562 	free(file);
1563 }
1564 
1565 static void
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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