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