archive_write_set_format_7zip.c revision 346104
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 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
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		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 */
518static int
519write_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
555static ssize_t
556compress_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
602static 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
622static 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
649static int
650flush_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
665static int
666copy_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
710static 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 */
853static int
854enc_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
874static int
875make_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
948static int
949make_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)
1144static uint64_t
1145utcToFiletime(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
1156static int
1157make_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
1245static int
1246make_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
1449static 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
1466static int
1467file_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
1478static int
1479file_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
1486static int
1487file_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
1558static void
1559file_free(struct file *file)
1560{
1561	free(file->utf16name);
1562	free(file);
1563}
1564
1565static void
1566file_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
1573static void
1574file_init_register(struct _7zip *zip)
1575{
1576	zip->file_list.first = NULL;
1577	zip->file_list.last = &(zip->file_list.first);
1578}
1579
1580static void
1581file_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
1593static void
1594file_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
1601static void
1602file_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)
1610static int
1611compression_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 */
1626static int
1627compression_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
1638static int
1639compression_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
1663static int
1664compression_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
1675static int
1676compression_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
1714static int
1715compression_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
1752static int
1753compression_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
1771static int
1772compression_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)
1788static int
1789compression_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
1827static int
1828compression_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
1874static int
1875compression_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
1894static int
1895compression_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)
1910static int
1911compression_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
1999static int
2000compression_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
2007static int
2008compression_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
2015static int
2016compression_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
2060static int
2061compression_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
2074static int
2075compression_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}
2084static int
2085compression_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 */
2099static void
2100ppmd_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
2120static int
2121compression_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
2183static int
2184compression_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
2226static int
2227compression_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 */
2245static 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
2295static int
2296compression_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
2304static int
2305compression_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