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