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