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