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