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