]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libarchive/libarchive/archive_write_set_format_7zip.c
Merge from vendor branch: update libpcap to 1.2.1.
[FreeBSD/FreeBSD.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[1024 * 64];
203         size_t                   wbuff_remaining;
204
205         /*
206          * The list of the file entries which has its contents is used to
207          * manage struct file objects.
208          * We use 'next' a menber of struct file to chain.
209          */
210         struct {
211                 struct file     *first;
212                 struct file     **last;
213         }                        file_list, empty_list;
214         struct archive_rb_tree   rbtree;/* for empty files */
215 };
216
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, 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, bytes) != ARCHIVE_OK)
584                         return (ARCHIVE_FATAL);
585                 if ((zip->crc32flg & ENCODED_CRC32) && bytes)
586                         zip->encoded_crc32 = crc32(zip->encoded_crc32,
587                             zip->wbuff, bytes);
588         }
589
590         return (s);
591 }
592
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 = 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 = 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 mask, byte;
1155
1156         /*
1157          * Make Time Bools.
1158          */
1159         if (zip->total_number_time_defined[ti] == zip->total_number_entry) {
1160                 /* Write Time Type. */
1161                 r = enc_uint64(a, type);
1162                 if (r < 0)
1163                         return (r);
1164                 /* Write EmptyStream Size. */
1165                 r = enc_uint64(a, 2 + zip->total_number_entry * 8);
1166                 if (r < 0)
1167                         return (r);
1168                 /* All are defined. */
1169                 r = enc_uint64(a, 1);
1170                 if (r < 0)
1171                         return (r);
1172         } else {
1173                 if (zip->total_number_time_defined[ti] == 0)
1174                         return (ARCHIVE_OK);
1175
1176                 /* Write Time Type. */
1177                 r = enc_uint64(a, type);
1178                 if (r < 0)
1179                         return (r);
1180                 /* Write EmptyStream Size. */
1181                 r = enc_uint64(a, 2 + ((zip->total_number_entry + 7) >> 3)
1182                         + zip->total_number_time_defined[ti] * 8);
1183                 if (r < 0)
1184                         return (r);
1185
1186                 /* All are not defined. */
1187                 r = enc_uint64(a, 0);
1188                 if (r < 0)
1189                         return (r);
1190
1191                 byte = 0;
1192                 mask = 0x80;
1193                 file = zip->file_list.first;
1194                 for (;file != NULL; file = file->next) {
1195                         if (file->flg & flg)
1196                                 byte |= mask;
1197                         mask >>= 1;
1198                         if (mask == 0) {
1199                                 r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1200                                 if (r < 0)
1201                                         return (r);
1202                                 mask = 0x80;
1203                                 byte = 0;
1204                         }
1205                 }
1206                 if (mask != 0x80) {
1207                         r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1208                         if (r < 0)
1209                                 return (r);
1210                 }
1211         }
1212
1213         /* External. */
1214         r = enc_uint64(a, 0);
1215         if (r < 0)
1216                 return (r);
1217
1218
1219         /*
1220          * Make Times.
1221          */
1222         file = zip->file_list.first;
1223         for (;file != NULL; file = file->next) {
1224                 if ((file->flg & flg) == 0)
1225                         continue;
1226                 archive_le64enc(filetime, utcToFiletime(file->times[ti].time,
1227                         file->times[ti].time_ns));
1228                 r = compress_out(a, filetime, 8, ARCHIVE_Z_RUN);
1229                 if (r < 0)
1230                         return (r);
1231         }
1232
1233         return (ARCHIVE_OK);
1234 }
1235
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 mask, byte;
1244
1245         /*
1246          * Make FilesInfo.
1247          */
1248         r = enc_uint64(a, kHeader);
1249         if (r < 0)
1250                 return (r);
1251
1252         /*
1253          * If there are empty files only, do not write MainStreamInfo.
1254          */
1255         if (zip->total_number_nonempty_entry) {
1256                 /*
1257                  * Make MainStreamInfo.
1258                  */
1259                 r = enc_uint64(a, kMainStreamsInfo);
1260                 if (r < 0)
1261                         return (r);
1262                 r = make_streamsInfo(a, offset, pack_size, unpack_size,
1263                       codernum, coders, 1, 0);
1264                 if (r < 0)
1265                         return (r);
1266         }
1267
1268         /*
1269          * Make FilesInfo.
1270          */
1271         r = enc_uint64(a, kFilesInfo);
1272         if (r < 0)
1273                 return (r);
1274
1275         /* Write numFiles. */
1276         r = enc_uint64(a, zip->total_number_entry);
1277         if (r < 0)
1278                 return (r);
1279
1280         if (zip->total_number_empty_entry > 0) {
1281                 /* Make EmptyStream. */
1282                 r = enc_uint64(a, kEmptyStream);
1283                 if (r < 0)
1284                         return (r);
1285
1286                 /* Write EmptyStream Size. */
1287                 r = enc_uint64(a, (zip->total_number_entry+7)>>3);
1288                 if (r < 0)
1289                         return (r);
1290
1291                 byte = 0;
1292                 mask = 0x80;
1293                 file = zip->file_list.first;
1294                 for (;file != NULL; file = file->next) {
1295                         if (file->size == 0)
1296                                 byte |= mask;
1297                         mask >>= 1;
1298                         if (mask == 0) {
1299                                 r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1300                                 if (r < 0)
1301                                         return (r);
1302                                 mask = 0x80;
1303                                 byte = 0;
1304                         }
1305                 }
1306                 if (mask != 0x80) {
1307                         r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1308                         if (r < 0)
1309                                 return (r);
1310                 }
1311         }
1312
1313         if (zip->total_number_empty_entry > zip->total_number_dir_entry) {
1314                 /* Make EmptyFile. */
1315                 r = enc_uint64(a, kEmptyFile);
1316                 if (r < 0)
1317                         return (r);
1318
1319                 /* Write EmptyFile Size. */
1320                 r = enc_uint64(a, (zip->total_number_empty_entry + 7) >> 3);
1321                 if (r < 0)
1322                         return (r);
1323
1324                 byte = 0;
1325                 mask = 0x80;
1326                 file = zip->file_list.first;
1327                 for (;file != NULL; file = file->next) {
1328                         if (file->size)
1329                                 continue;
1330                         if (!file->dir)
1331                                 byte |= mask;
1332                         mask >>= 1;
1333                         if (mask == 0) {
1334                                 r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1335                                 if (r < 0)
1336                                         return (r);
1337                                 mask = 0x80;
1338                                 byte = 0;
1339                         }
1340                 }
1341                 if (mask != 0x80) {
1342                         r = compress_out(a, &byte, 1, ARCHIVE_Z_RUN);
1343                         if (r < 0)
1344                                 return (r);
1345                 }
1346         }
1347
1348         /* Make Name. */
1349         r = enc_uint64(a, kName);
1350         if (r < 0)
1351                 return (r);
1352
1353         /* Write Nume size. */
1354         r = enc_uint64(a, zip->total_bytes_entry_name+1);
1355         if (r < 0)
1356                 return (r);
1357
1358         /* Write dmy byte. */
1359         r = enc_uint64(a, 0);
1360         if (r < 0)
1361                 return (r);
1362
1363         file = zip->file_list.first;
1364         for (;file != NULL; file = file->next) {
1365                 r = compress_out(a, file->utf16name, file->name_len+2,
1366                         ARCHIVE_Z_RUN);
1367                 if (r < 0)
1368                         return (r);
1369         }
1370
1371         /* Make MTime. */
1372         r = make_time(a, kMTime, MTIME_IS_SET, MTIME);
1373         if (r < 0)
1374                 return (r);
1375
1376         /* Make CTime. */
1377         r = make_time(a, kCTime, CTIME_IS_SET, CTIME);
1378         if (r < 0)
1379                 return (r);
1380
1381         /* Make ATime. */
1382         r = make_time(a, kATime, ATIME_IS_SET, ATIME);
1383         if (r < 0)
1384                 return (r);
1385
1386         /* Make Attributes. */
1387         r = enc_uint64(a, kAttributes);
1388         if (r < 0)
1389                 return (r);
1390
1391         /* Write Attributes size. */
1392         r = enc_uint64(a, 2 + zip->total_number_entry * 4);
1393         if (r < 0)
1394                 return (r);
1395
1396         /* Write "All Are Defined". */
1397         r = enc_uint64(a, 1);
1398         if (r < 0)
1399                 return (r);
1400
1401         /* Write dmy byte. */
1402         r = enc_uint64(a, 0);
1403         if (r < 0)
1404                 return (r);
1405
1406         file = zip->file_list.first;
1407         for (;file != NULL; file = file->next) {
1408                 /*
1409                  * High 16bits is unix mode.
1410                  * Low 16bits is Windows attributes.
1411                  */
1412                 uint32_t encattr, attr;
1413                 if (file->dir)
1414                         attr = 0x8010;
1415                 else
1416                         attr = 0x8020;
1417                 if ((file->mode & 0222) == 0)
1418                         attr |= 1;/* Read Only. */
1419                 attr |= ((uint32_t)file->mode) << 16;
1420                 archive_le32enc(&encattr, attr);
1421                 r = compress_out(a, &encattr, 4, ARCHIVE_Z_RUN);
1422                 if (r < 0)
1423                         return (r);
1424         }
1425
1426         /* Write End. */
1427         r = enc_uint64(a, kEnd);
1428         if (r < 0)
1429                 return (r);
1430
1431         /* Write End. */
1432         r = enc_uint64(a, kEnd);
1433         if (r < 0)
1434                 return (r);
1435
1436         return (ARCHIVE_OK);
1437 }
1438
1439
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                         archive_set_error(&a->archive, ENOMEM,
1496                             "Can't allocate memory for UTF-16LE");
1497                         return (ARCHIVE_FATAL);
1498                 }
1499                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1500                     "A filename cannot be converted to UTF-16LE;"
1501                     "You should disable making Joliet extension");
1502                 ret = ARCHIVE_WARN;
1503         }
1504         file->utf16name = malloc(u16len + 2);
1505         if (file->utf16name == NULL) {
1506                 archive_set_error(&a->archive, ENOMEM,
1507                     "Can't allocate memory for Name");
1508                 return (ARCHIVE_FATAL);
1509         }
1510         memcpy(file->utf16name, u16, u16len);
1511         file->utf16name[u16len+0] = 0;
1512         file->utf16name[u16len+1] = 0;
1513         file->name_len = u16len;
1514         file->mode = archive_entry_mode(entry);
1515         if (archive_entry_filetype(entry) == AE_IFREG)
1516                 file->size = archive_entry_size(entry);
1517         else
1518                 archive_entry_set_size(entry, 0);
1519         if (archive_entry_filetype(entry) == AE_IFDIR)
1520                 file->dir = 1;
1521         else if (archive_entry_filetype(entry) == AE_IFLNK)
1522                 file->size = strlen(archive_entry_symlink(entry));
1523         if (archive_entry_mtime_is_set(entry)) {
1524                 file->flg |= MTIME_IS_SET;
1525                 file->times[MTIME].time = archive_entry_mtime(entry);
1526                 file->times[MTIME].time_ns = archive_entry_mtime_nsec(entry);
1527         }
1528         if (archive_entry_atime_is_set(entry)) {
1529                 file->flg |= ATIME_IS_SET;
1530                 file->times[ATIME].time = archive_entry_atime(entry);
1531                 file->times[ATIME].time_ns = archive_entry_atime_nsec(entry);
1532         }
1533         if (archive_entry_ctime_is_set(entry)) {
1534                 file->flg |= CTIME_IS_SET;
1535                 file->times[CTIME].time = archive_entry_ctime(entry);
1536                 file->times[CTIME].time_ns = archive_entry_ctime_nsec(entry);
1537         }
1538
1539         *newfile = file;
1540         return (ret);
1541 }
1542
1543 static void
1544 file_free(struct file *file)
1545 {
1546         free(file->utf16name);
1547         free(file);
1548 }
1549
1550 static void
1551 file_register(struct _7zip *zip, struct file *file)
1552 {
1553         file->next = NULL;
1554         *zip->file_list.last = file;
1555         zip->file_list.last = &(file->next);
1556 }
1557
1558 static void
1559 file_init_register(struct _7zip *zip)
1560 {
1561         zip->file_list.first = NULL;
1562         zip->file_list.last = &(zip->file_list.first);
1563 }
1564
1565 static void
1566 file_free_register(struct _7zip *zip)
1567 {
1568         struct file *file, *file_next;
1569
1570         file = zip->file_list.first;
1571         while (file != NULL) {
1572                 file_next = file->next;
1573                 file_free(file);
1574                 file = file_next;
1575         }
1576 }
1577
1578 static void
1579 file_register_empty(struct _7zip *zip, struct file *file)
1580 {
1581         file->next = NULL;
1582         *zip->empty_list.last = file;
1583         zip->empty_list.last = &(file->next);
1584 }
1585
1586 static void
1587 file_init_register_empty(struct _7zip *zip)
1588 {
1589         zip->empty_list.first = NULL;
1590         zip->empty_list.last = &(zip->empty_list.first);
1591 }
1592
1593 #if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\
1594          !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
1595 static int
1596 compression_unsupported_encoder(struct archive *a,
1597     struct la_zstream *lastrm, const char *name)
1598 {
1599
1600         archive_set_error(a, ARCHIVE_ERRNO_MISC,
1601             "%s compression not supported on this platform", name);
1602         lastrm->valid = 0;
1603         lastrm->real_stream = NULL;
1604         return (ARCHIVE_FAILED);
1605 }
1606 #endif
1607
1608 /*
1609  * _7_COPY compressor.
1610  */
1611 static int
1612 compression_init_encoder_copy(struct archive *a, struct la_zstream *lastrm)
1613 {
1614
1615         if (lastrm->valid)
1616                 compression_end(a, lastrm);
1617         lastrm->valid = 1;
1618         lastrm->code = compression_code_copy;
1619         lastrm->end = compression_end_copy;
1620         return (ARCHIVE_OK);
1621 }
1622
1623 static int
1624 compression_code_copy(struct archive *a,
1625     struct la_zstream *lastrm, enum la_zaction action)
1626 {
1627         size_t bytes;
1628
1629         (void)a; /* UNUSED */
1630         if (lastrm->avail_out > lastrm->avail_in)
1631                 bytes = lastrm->avail_in;
1632         else
1633                 bytes = lastrm->avail_out;
1634         if (bytes) {
1635                 memcpy(lastrm->next_out, lastrm->next_in, bytes);
1636                 lastrm->next_in += bytes;
1637                 lastrm->avail_in -= bytes;
1638                 lastrm->total_in += bytes;
1639                 lastrm->next_out += bytes;
1640                 lastrm->avail_out -= bytes;
1641                 lastrm->total_out += bytes;
1642         }
1643         if (action == ARCHIVE_Z_FINISH && lastrm->avail_in == 0)
1644                 return (ARCHIVE_EOF);
1645         return (ARCHIVE_OK);
1646 }
1647
1648 static int
1649 compression_end_copy(struct archive *a, struct la_zstream *lastrm)
1650 {
1651         (void)a; /* UNUSED */
1652         lastrm->valid = 0;
1653         return (ARCHIVE_OK);
1654 }
1655
1656 /*
1657  * _7_DEFLATE compressor.
1658  */
1659 #ifdef HAVE_ZLIB_H
1660 static int
1661 compression_init_encoder_deflate(struct archive *a,
1662     struct la_zstream *lastrm, int level, int withheader)
1663 {
1664         z_stream *strm;
1665
1666         if (lastrm->valid)
1667                 compression_end(a, lastrm);
1668         strm = calloc(1, sizeof(*strm));
1669         if (strm == NULL) {
1670                 archive_set_error(a, ENOMEM,
1671                     "Can't allocate memory for gzip stream");
1672                 return (ARCHIVE_FATAL);
1673         }
1674         /* zlib.h is not const-correct, so we need this one bit
1675          * of ugly hackery to convert a const * pointer to
1676          * a non-const pointer. */
1677         strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1678         strm->avail_in = lastrm->avail_in;
1679         strm->total_in = lastrm->total_in;
1680         strm->next_out = lastrm->next_out;
1681         strm->avail_out = lastrm->avail_out;
1682         strm->total_out = lastrm->total_out;
1683         if (deflateInit2(strm, level, Z_DEFLATED,
1684             (withheader)?15:-15,
1685             8, Z_DEFAULT_STRATEGY) != Z_OK) {
1686                 free(strm);
1687                 lastrm->real_stream = NULL;
1688                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1689                     "Internal error initializing compression library");
1690                 return (ARCHIVE_FATAL);
1691         }
1692         lastrm->real_stream = strm;
1693         lastrm->valid = 1;
1694         lastrm->code = compression_code_deflate;
1695         lastrm->end = compression_end_deflate;
1696         return (ARCHIVE_OK);
1697 }
1698
1699 static int
1700 compression_code_deflate(struct archive *a,
1701     struct la_zstream *lastrm, enum la_zaction action)
1702 {
1703         z_stream *strm;
1704         int r;
1705
1706         strm = (z_stream *)lastrm->real_stream;
1707         /* zlib.h is not const-correct, so we need this one bit
1708          * of ugly hackery to convert a const * pointer to
1709          * a non-const pointer. */
1710         strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
1711         strm->avail_in = lastrm->avail_in;
1712         strm->total_in = lastrm->total_in;
1713         strm->next_out = lastrm->next_out;
1714         strm->avail_out = lastrm->avail_out;
1715         strm->total_out = lastrm->total_out;
1716         r = deflate(strm,
1717             (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
1718         lastrm->next_in = strm->next_in;
1719         lastrm->avail_in = strm->avail_in;
1720         lastrm->total_in = strm->total_in;
1721         lastrm->next_out = strm->next_out;
1722         lastrm->avail_out = strm->avail_out;
1723         lastrm->total_out = strm->total_out;
1724         switch (r) {
1725         case Z_OK:
1726                 return (ARCHIVE_OK);
1727         case Z_STREAM_END:
1728                 return (ARCHIVE_EOF);
1729         default:
1730                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1731                     "GZip compression failed:"
1732                     " deflate() call returned status %d", r);
1733                 return (ARCHIVE_FATAL);
1734         }
1735 }
1736
1737 static int
1738 compression_end_deflate(struct archive *a, struct la_zstream *lastrm)
1739 {
1740         z_stream *strm;
1741         int r;
1742
1743         strm = (z_stream *)lastrm->real_stream;
1744         r = deflateEnd(strm);
1745         free(strm);
1746         lastrm->real_stream = NULL;
1747         lastrm->valid = 0;
1748         if (r != Z_OK) {
1749                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1750                     "Failed to clean up compressor");
1751                 return (ARCHIVE_FATAL);
1752         }
1753         return (ARCHIVE_OK);
1754 }
1755 #else
1756 static int
1757 compression_init_encoder_deflate(struct archive *a,
1758     struct la_zstream *lastrm, int level, int withheader)
1759 {
1760
1761         (void) level; /* UNUSED */
1762         (void) withheader; /* UNUSED */
1763         if (lastrm->valid)
1764                 compression_end(a, lastrm);
1765         return (compression_unsupported_encoder(a, lastrm, "deflate"));
1766 }
1767 #endif
1768
1769 /*
1770  * _7_BZIP2 compressor.
1771  */
1772 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
1773 static int
1774 compression_init_encoder_bzip2(struct archive *a,
1775     struct la_zstream *lastrm, int level)
1776 {
1777         bz_stream *strm;
1778
1779         if (lastrm->valid)
1780                 compression_end(a, lastrm);
1781         strm = calloc(1, sizeof(*strm));
1782         if (strm == NULL) {
1783                 archive_set_error(a, ENOMEM,
1784                     "Can't allocate memory for bzip2 stream");
1785                 return (ARCHIVE_FATAL);
1786         }
1787         /* bzlib.h is not const-correct, so we need this one bit
1788          * of ugly hackery to convert a const * pointer to
1789          * a non-const pointer. */
1790         strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1791         strm->avail_in = lastrm->avail_in;
1792         strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1793         strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1794         strm->next_out = (char *)lastrm->next_out;
1795         strm->avail_out = lastrm->avail_out;
1796         strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1797         strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1798         if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
1799                 free(strm);
1800                 lastrm->real_stream = NULL;
1801                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1802                     "Internal error initializing compression library");
1803                 return (ARCHIVE_FATAL);
1804         }
1805         lastrm->real_stream = strm;
1806         lastrm->valid = 1;
1807         lastrm->code = compression_code_bzip2;
1808         lastrm->end = compression_end_bzip2;
1809         return (ARCHIVE_OK);
1810 }
1811
1812 static int
1813 compression_code_bzip2(struct archive *a,
1814     struct la_zstream *lastrm, enum la_zaction action)
1815 {
1816         bz_stream *strm;
1817         int r;
1818
1819         strm = (bz_stream *)lastrm->real_stream;
1820         /* bzlib.h is not const-correct, so we need this one bit
1821          * of ugly hackery to convert a const * pointer to
1822          * a non-const pointer. */
1823         strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
1824         strm->avail_in = lastrm->avail_in;
1825         strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
1826         strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
1827         strm->next_out = (char *)lastrm->next_out;
1828         strm->avail_out = lastrm->avail_out;
1829         strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
1830         strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
1831         r = BZ2_bzCompress(strm,
1832             (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
1833         lastrm->next_in = (const unsigned char *)strm->next_in;
1834         lastrm->avail_in = strm->avail_in;
1835         lastrm->total_in =
1836             (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
1837             + (uint64_t)(uint32_t)strm->total_in_lo32;
1838         lastrm->next_out = (unsigned char *)strm->next_out;
1839         lastrm->avail_out = strm->avail_out;
1840         lastrm->total_out =
1841             (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
1842             + (uint64_t)(uint32_t)strm->total_out_lo32;
1843         switch (r) {
1844         case BZ_RUN_OK:     /* Non-finishing */
1845         case BZ_FINISH_OK:  /* Finishing: There's more work to do */
1846                 return (ARCHIVE_OK);
1847         case BZ_STREAM_END: /* Finishing: all done */
1848                 /* Only occurs in finishing case */
1849                 return (ARCHIVE_EOF);
1850         default:
1851                 /* Any other return value indicates an error */
1852                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1853                     "Bzip2 compression failed:"
1854                     " BZ2_bzCompress() call returned status %d", r);
1855                 return (ARCHIVE_FATAL);
1856         }
1857 }
1858
1859 static int
1860 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
1861 {
1862         bz_stream *strm;
1863         int r;
1864
1865         strm = (bz_stream *)lastrm->real_stream;
1866         r = BZ2_bzCompressEnd(strm);
1867         free(strm);
1868         lastrm->real_stream = NULL;
1869         lastrm->valid = 0;
1870         if (r != BZ_OK) {
1871                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1872                     "Failed to clean up compressor");
1873                 return (ARCHIVE_FATAL);
1874         }
1875         return (ARCHIVE_OK);
1876 }
1877
1878 #else
1879 static int
1880 compression_init_encoder_bzip2(struct archive *a,
1881     struct la_zstream *lastrm, int level)
1882 {
1883
1884         (void) level; /* UNUSED */
1885         if (lastrm->valid)
1886                 compression_end(a, lastrm);
1887         return (compression_unsupported_encoder(a, lastrm, "bzip2"));
1888 }
1889 #endif
1890
1891 /*
1892  * _7_LZMA1, _7_LZMA2 compressor.
1893  */
1894 #if defined(HAVE_LZMA_H)
1895 static int
1896 compression_init_encoder_lzma(struct archive *a,
1897     struct la_zstream *lastrm, int level, uint64_t filter_id)
1898 {
1899         static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
1900         lzma_stream *strm;
1901         lzma_filter *lzmafilters;
1902         lzma_options_lzma lzma_opt;
1903         int r;
1904
1905         if (lastrm->valid)
1906                 compression_end(a, lastrm);
1907         strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
1908         if (strm == NULL) {
1909                 archive_set_error(a, ENOMEM,
1910                     "Can't allocate memory for lzma stream");
1911                 return (ARCHIVE_FATAL);
1912         }
1913         lzmafilters = (lzma_filter *)(strm+1);
1914         if (level > 6)
1915                 level = 6;
1916         if (lzma_lzma_preset(&lzma_opt, level)) {
1917                 lastrm->real_stream = NULL;
1918                 archive_set_error(a, ENOMEM,
1919                     "Internal error initializing compression library");
1920                 return (ARCHIVE_FATAL);
1921         }
1922         lzmafilters[0].id = filter_id;
1923         lzmafilters[0].options = &lzma_opt;
1924         lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
1925
1926         r = lzma_properties_size(&(lastrm->prop_size), lzmafilters);
1927         if (r != LZMA_OK) {
1928                 free(strm);
1929                 lastrm->real_stream = NULL;
1930                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1931                     "lzma_properties_size failed");
1932                 return (ARCHIVE_FATAL);
1933         }
1934         if (lastrm->prop_size) {
1935                 lastrm->props = malloc(lastrm->prop_size);
1936                 if (lastrm->props == NULL) {
1937                         free(strm);
1938                         lastrm->real_stream = NULL;
1939                         archive_set_error(a, ENOMEM,
1940                             "Cannot allocate memory");
1941                         return (ARCHIVE_FATAL);
1942                 }
1943                 r = lzma_properties_encode(lzmafilters,  lastrm->props);
1944                 if (r != LZMA_OK) {
1945                         free(strm);
1946                         lastrm->real_stream = NULL;
1947                         archive_set_error(a, ARCHIVE_ERRNO_MISC,
1948                             "lzma_properties_encode failed");
1949                         return (ARCHIVE_FATAL);
1950                 }
1951         }
1952
1953         *strm = lzma_init_data;
1954         r = lzma_raw_encoder(strm, lzmafilters);
1955         switch (r) {
1956         case LZMA_OK:
1957                 lastrm->real_stream = strm;
1958                 lastrm->valid = 1;
1959                 lastrm->code = compression_code_lzma;
1960                 lastrm->end = compression_end_lzma;
1961                 r = ARCHIVE_OK;
1962                 break;
1963         case LZMA_MEM_ERROR:
1964                 free(strm);
1965                 lastrm->real_stream = NULL;
1966                 archive_set_error(a, ENOMEM,
1967                     "Internal error initializing compression library: "
1968                     "Cannot allocate memory");
1969                 r =  ARCHIVE_FATAL;
1970                 break;
1971         default:
1972                 free(strm);
1973                 lastrm->real_stream = NULL;
1974                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
1975                     "Internal error initializing compression library: "
1976                     "It's a bug in liblzma");
1977                 r =  ARCHIVE_FATAL;
1978                 break;
1979         }
1980         return (r);
1981 }
1982
1983 static int
1984 compression_init_encoder_lzma1(struct archive *a,
1985     struct la_zstream *lastrm, int level)
1986 {
1987         return compression_init_encoder_lzma(a, lastrm, level,
1988                     LZMA_FILTER_LZMA1);
1989 }
1990
1991 static int
1992 compression_init_encoder_lzma2(struct archive *a,
1993     struct la_zstream *lastrm, int level)
1994 {
1995         return compression_init_encoder_lzma(a, lastrm, level,
1996                     LZMA_FILTER_LZMA2);
1997 }
1998
1999 static int
2000 compression_code_lzma(struct archive *a,
2001     struct la_zstream *lastrm, enum la_zaction action)
2002 {
2003         lzma_stream *strm;
2004         int r;
2005
2006         strm = (lzma_stream *)lastrm->real_stream;
2007         strm->next_in = lastrm->next_in;
2008         strm->avail_in = lastrm->avail_in;
2009         strm->total_in = lastrm->total_in;
2010         strm->next_out = lastrm->next_out;
2011         strm->avail_out = lastrm->avail_out;
2012         strm->total_out = lastrm->total_out;
2013         r = lzma_code(strm,
2014             (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
2015         lastrm->next_in = strm->next_in;
2016         lastrm->avail_in = strm->avail_in;
2017         lastrm->total_in = strm->total_in;
2018         lastrm->next_out = strm->next_out;
2019         lastrm->avail_out = strm->avail_out;
2020         lastrm->total_out = strm->total_out;
2021         switch (r) {
2022         case LZMA_OK:
2023                 /* Non-finishing case */
2024                 return (ARCHIVE_OK);
2025         case LZMA_STREAM_END:
2026                 /* This return can only occur in finishing case. */
2027                 return (ARCHIVE_EOF);
2028         case LZMA_MEMLIMIT_ERROR:
2029                 archive_set_error(a, ENOMEM,
2030                     "lzma compression error:"
2031                     " %ju MiB would have been needed",
2032                     (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
2033                         / (1024 * 1024)));
2034                 return (ARCHIVE_FATAL);
2035         default:
2036                 /* Any other return value indicates an error */
2037                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2038                     "lzma compression failed:"
2039                     " lzma_code() call returned status %d", r);
2040                 return (ARCHIVE_FATAL);
2041         }
2042 }
2043
2044 static int
2045 compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
2046 {
2047         lzma_stream *strm;
2048
2049         (void)a; /* UNUSED */
2050         strm = (lzma_stream *)lastrm->real_stream;
2051         lzma_end(strm);
2052         free(strm);
2053         lastrm->valid = 0;
2054         lastrm->real_stream = NULL;
2055         return (ARCHIVE_OK);
2056 }
2057 #else
2058 static int
2059 compression_init_encoder_lzma1(struct archive *a,
2060     struct la_zstream *lastrm, int level)
2061 {
2062
2063         (void) level; /* UNUSED */
2064         if (lastrm->valid)
2065                 compression_end(a, lastrm);
2066         return (compression_unsupported_encoder(a, lastrm, "lzma"));
2067 }
2068 static int
2069 compression_init_encoder_lzma2(struct archive *a,
2070     struct la_zstream *lastrm, int level)
2071 {
2072
2073         (void) level; /* UNUSED */
2074         if (lastrm->valid)
2075                 compression_end(a, lastrm);
2076         return (compression_unsupported_encoder(a, lastrm, "lzma"));
2077 }
2078 #endif
2079
2080 /*
2081  * _7_PPMD compressor.
2082  */
2083 static void *
2084 ppmd_alloc(void *p, size_t size)
2085 {
2086         (void)p;
2087         return malloc(size);
2088 }
2089 static void
2090 ppmd_free(void *p, void *address)
2091 {
2092         (void)p;
2093         free(address);
2094 }
2095 static ISzAlloc g_szalloc = { ppmd_alloc, ppmd_free };
2096 static void
2097 ppmd_write(void *p, Byte b)
2098 {
2099         struct archive_write *a = ((IByteOut *)p)->a;
2100         struct _7zip *zip = (struct _7zip *)(a->format_data);
2101         struct la_zstream *lastrm = &(zip->stream);
2102         struct ppmd_stream *strm;
2103
2104         if (lastrm->avail_out) {
2105                 *lastrm->next_out++ = b;
2106                 lastrm->avail_out--;
2107                 lastrm->total_out++;
2108                 return;
2109         }
2110         strm = (struct ppmd_stream *)lastrm->real_stream;
2111         if (strm->buff_ptr < strm->buff_end) {
2112                 *strm->buff_ptr++ = b;
2113                 strm->buff_bytes++;
2114         }
2115 }
2116
2117 static int
2118 compression_init_encoder_ppmd(struct archive *a,
2119     struct la_zstream *lastrm, unsigned maxOrder, uint32_t msize)
2120 {
2121         struct ppmd_stream *strm;
2122         uint8_t *props;
2123         int r;
2124
2125         if (lastrm->valid)
2126                 compression_end(a, lastrm);
2127         strm = calloc(1, sizeof(*strm));
2128         if (strm == NULL) {
2129                 archive_set_error(a, ENOMEM,
2130                     "Can't allocate memory for PPMd");
2131                 return (ARCHIVE_FATAL);
2132         }
2133         strm->buff = malloc(32);
2134         if (strm->buff == NULL) {
2135                 free(strm);
2136                 archive_set_error(a, ENOMEM,
2137                     "Can't allocate memory for PPMd");
2138                 return (ARCHIVE_FATAL);
2139         }
2140         strm->buff_ptr = strm->buff;
2141         strm->buff_end = strm->buff + 32;
2142
2143         props = malloc(1+4);
2144         if (props == NULL) {
2145                 free(strm->buff);
2146                 free(strm);
2147                 archive_set_error(a, ENOMEM,
2148                     "Coludn't allocate memory for PPMd");
2149                 return (ARCHIVE_FATAL);
2150         }
2151         props[0] = maxOrder;
2152         archive_le32enc(props+1, msize);
2153         __archive_ppmd7_functions.Ppmd7_Construct(&strm->ppmd7_context);
2154         r = __archive_ppmd7_functions.Ppmd7_Alloc(
2155                 &strm->ppmd7_context, msize, &g_szalloc);
2156         if (r == 0) {
2157                 free(strm->buff);
2158                 free(strm);
2159                 free(props);
2160                 archive_set_error(a, ENOMEM,
2161                     "Coludn't allocate memory for PPMd");
2162                 return (ARCHIVE_FATAL);
2163         }
2164         __archive_ppmd7_functions.Ppmd7_Init(&(strm->ppmd7_context), maxOrder);
2165         strm->byteout.a = (struct archive_write *)a;
2166         strm->byteout.Write = ppmd_write;
2167         strm->range_enc.Stream = &(strm->byteout);
2168         __archive_ppmd7_functions.Ppmd7z_RangeEnc_Init(&(strm->range_enc));
2169         strm->stat = 0;
2170
2171         lastrm->real_stream = strm;
2172         lastrm->valid = 1;
2173         lastrm->code = compression_code_ppmd;
2174         lastrm->end = compression_end_ppmd;
2175         lastrm->prop_size = 5;
2176         lastrm->props = props;
2177         return (ARCHIVE_OK);
2178 }
2179
2180 static int
2181 compression_code_ppmd(struct archive *a,
2182     struct la_zstream *lastrm, enum la_zaction action)
2183 {
2184         struct ppmd_stream *strm;
2185
2186         (void)a; /* UNUSED */
2187
2188         strm = (struct ppmd_stream *)lastrm->real_stream;
2189
2190         /* Copy encoded data if there are remaining bytes from previous call. */
2191         if (strm->buff_bytes) {
2192                 uint8_t *p = strm->buff_ptr - strm->buff_bytes;
2193                 while (lastrm->avail_out && strm->buff_bytes) {
2194                         *lastrm->next_out++ = *p++;
2195                         lastrm->avail_out--;
2196                         lastrm->total_out++;
2197                         strm->buff_bytes--;
2198                 }
2199                 if (strm->buff_bytes)
2200                         return (ARCHIVE_OK);
2201                 if (strm->stat == 1)
2202                         return (ARCHIVE_EOF);
2203                 strm->buff_ptr = strm->buff;
2204         }
2205         while (lastrm->avail_in && lastrm->avail_out) {
2206                 __archive_ppmd7_functions.Ppmd7_EncodeSymbol(
2207                         &(strm->ppmd7_context), &(strm->range_enc),
2208                         *lastrm->next_in++);
2209                 lastrm->avail_in--;
2210                 lastrm->total_in++;
2211         }
2212         if (lastrm->avail_in == 0 && action == ARCHIVE_Z_FINISH) {
2213                 __archive_ppmd7_functions.Ppmd7z_RangeEnc_FlushData(
2214                         &(strm->range_enc));
2215                 strm->stat = 1;
2216                 /* Return EOF if there are no remaining bytes. */
2217                 if (strm->buff_bytes == 0)
2218                         return (ARCHIVE_EOF);
2219         }
2220         return (ARCHIVE_OK);
2221 }
2222
2223 static int
2224 compression_end_ppmd(struct archive *a, struct la_zstream *lastrm)
2225 {
2226         struct ppmd_stream *strm;
2227
2228         (void)a; /* UNUSED */
2229
2230         strm = (struct ppmd_stream *)lastrm->real_stream;
2231         __archive_ppmd7_functions.Ppmd7_Free(&strm->ppmd7_context, &g_szalloc);
2232         free(strm->buff);
2233         free(strm);
2234         lastrm->real_stream = NULL;
2235         lastrm->valid = 0;
2236         return (ARCHIVE_OK);
2237 }
2238
2239 /*
2240  * Universal compressor initializer.
2241  */
2242 static int
2243 _7z_compression_init_encoder(struct archive_write *a, unsigned compression,
2244     int compression_level)
2245 {
2246         struct _7zip *zip;
2247         int r;
2248
2249         zip = (struct _7zip *)a->format_data;
2250         switch (compression) {
2251         case _7Z_DEFLATE:
2252                 r = compression_init_encoder_deflate(
2253                     &(a->archive), &(zip->stream),
2254                     compression_level, 0);
2255                 break;
2256         case _7Z_BZIP2:
2257                 r = compression_init_encoder_bzip2(
2258                     &(a->archive), &(zip->stream),
2259                     compression_level);
2260                 break;
2261         case _7Z_LZMA1:
2262                 r = compression_init_encoder_lzma1(
2263                     &(a->archive), &(zip->stream),
2264                     compression_level);
2265                 break;
2266         case _7Z_LZMA2:
2267                 r = compression_init_encoder_lzma2(
2268                     &(a->archive), &(zip->stream),
2269                     compression_level);
2270                 break;
2271         case _7Z_PPMD:
2272                 r = compression_init_encoder_ppmd(
2273                     &(a->archive), &(zip->stream),
2274                     PPMD7_DEFAULT_ORDER, PPMD7_DEFAULT_MEM_SIZE);
2275                 break;
2276         case _7Z_COPY:
2277         default:
2278                 r = compression_init_encoder_copy(
2279                     &(a->archive), &(zip->stream));
2280                 break;
2281         }
2282         if (r == ARCHIVE_OK) {
2283                 zip->stream.total_in = 0;
2284                 zip->stream.next_out = zip->wbuff;
2285                 zip->stream.avail_out = sizeof(zip->wbuff);
2286                 zip->stream.total_out = 0;
2287         }
2288
2289         return (r);
2290 }
2291
2292 static int
2293 compression_code(struct archive *a, struct la_zstream *lastrm,
2294     enum la_zaction action)
2295 {
2296         if (lastrm->valid)
2297                 return (lastrm->code(a, lastrm, action));
2298         return (ARCHIVE_OK);
2299 }
2300
2301 static int
2302 compression_end(struct archive *a, struct la_zstream *lastrm)
2303 {
2304         if (lastrm->valid) {
2305                 lastrm->prop_size = 0;
2306                 free(lastrm->props);
2307                 lastrm->props = NULL;
2308                 return (lastrm->end(a, lastrm));
2309         }
2310         return (ARCHIVE_OK);
2311 }
2312
2313