]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/archive_write_set_format_xar.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / archive_write_set_format_xar.c
1 /*-
2  * Copyright (c) 2010-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 #ifdef HAVE_LIMITS_H
33 #include <limits.h>
34 #endif
35 #include <stdlib.h>
36 #if HAVE_LIBXML_XMLWRITER_H
37 #include <libxml/xmlwriter.h>
38 #endif
39 #ifdef HAVE_BZLIB_H
40 #include <bzlib.h>
41 #endif
42 #if HAVE_LZMA_H
43 #include <lzma.h>
44 #endif
45 #ifdef HAVE_ZLIB_H
46 #include <zlib.h>
47 #endif
48
49 #include "archive.h"
50 #include "archive_digest_private.h"
51 #include "archive_endian.h"
52 #include "archive_entry.h"
53 #include "archive_entry_locale.h"
54 #include "archive_private.h"
55 #include "archive_rb.h"
56 #include "archive_string.h"
57 #include "archive_write_private.h"
58
59 /*
60  * Differences to xar utility.
61  * - Subdocument is not supported yet.
62  * - ACL is not supported yet.
63  * - When writing an XML element <link type="<file-type>">, <file-type>
64  *   which is a file type a symbolic link is referencing is always marked
65  *   as "broken". Xar utility uses stat(2) to get the file type, but, in
66  *   libarchive format writer, we should not use it; if it is needed, we
67  *   should get about it at archive_read_disk.c.
68  * - It is possible to appear both <flags> and <ext2> elements.
69  *   Xar utility generates <flags> on BSD platform and <ext2> on Linux
70  *   platform.
71  *
72  */
73
74 #if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
75         LIBXML_VERSION >= 20703) ||\
76         !defined(HAVE_ZLIB_H) || \
77         !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
78 /*
79  * xar needs several external libraries.
80  *   o libxml2
81  *   o openssl or MD5/SHA1 hash function
82  *   o zlib
83  *   o bzlib2 (option)
84  *   o liblzma (option)
85  */
86 int
87 archive_write_set_format_xar(struct archive *_a)
88 {
89         struct archive_write *a = (struct archive_write *)_a;
90
91         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
92             "Xar not supported on this platform");
93         return (ARCHIVE_WARN);
94 }
95
96 #else   /* Support xar format */
97
98 /*#define DEBUG_PRINT_TOC               1 */
99
100 #define BAD_CAST_CONST (const xmlChar *)
101
102 #define HEADER_MAGIC    0x78617221
103 #define HEADER_SIZE     28
104 #define HEADER_VERSION  1
105
106 enum sumalg {
107         CKSUM_NONE = 0,
108         CKSUM_SHA1 = 1,
109         CKSUM_MD5 = 2
110 };
111
112 #define MD5_SIZE        16
113 #define SHA1_SIZE       20
114 #define MAX_SUM_SIZE    20
115 #define MD5_NAME        "md5"
116 #define SHA1_NAME       "sha1"
117
118 enum enctype {
119         NONE,
120         GZIP,
121         BZIP2,
122         LZMA,
123         XZ,
124 };
125
126 struct chksumwork {
127         enum sumalg              alg;
128 #ifdef ARCHIVE_HAS_MD5
129         archive_md5_ctx          md5ctx;
130 #endif
131 #ifdef ARCHIVE_HAS_SHA1
132         archive_sha1_ctx         sha1ctx;
133 #endif
134 };
135
136 enum la_zaction {
137         ARCHIVE_Z_FINISH,
138         ARCHIVE_Z_RUN
139 };
140
141 /*
142  * Universal zstream.
143  */
144 struct la_zstream {
145         const unsigned char     *next_in;
146         size_t                   avail_in;
147         uint64_t                 total_in;
148
149         unsigned char           *next_out;
150         size_t                   avail_out;
151         uint64_t                 total_out;
152
153         int                      valid;
154         void                    *real_stream;
155         int                      (*code) (struct archive *a,
156                                     struct la_zstream *lastrm,
157                                     enum la_zaction action);
158         int                      (*end)(struct archive *a,
159                                     struct la_zstream *lastrm);
160 };
161
162 struct chksumval {
163         enum sumalg              alg;
164         size_t                   len;
165         unsigned char            val[MAX_SUM_SIZE];
166 };
167
168 struct heap_data {
169         int                      id;
170         struct heap_data        *next;
171         uint64_t                 temp_offset;
172         uint64_t                 length;        /* archived size.       */
173         uint64_t                 size;          /* extracted size.      */
174         enum enctype             compression;
175         struct chksumval         a_sum;         /* archived checksum.   */
176         struct chksumval         e_sum;         /* extracted checksum.  */
177 };
178
179 struct file {
180         struct archive_rb_node   rbnode;
181
182         int                      id;
183         struct archive_entry    *entry;
184
185         struct archive_rb_tree   rbtree;
186         struct file             *next;
187         struct file             *chnext;
188         struct file             *hlnext;
189         /* For hardlinked files.
190          * Use only when archive_entry_nlink() > 1 */
191         struct file             *hardlink_target;
192         struct file             *parent;        /* parent directory entry */
193         /*
194          * To manage sub directory files.
195          * We use 'chnext' (a member of struct file) to chain.
196          */
197         struct {
198                 struct file     *first;
199                 struct file     **last;
200         }                        children;
201
202         /* For making a directory tree. */
203         struct archive_string    parentdir;
204         struct archive_string    basename;
205         struct archive_string    symlink;
206
207         int                      ea_idx;
208         struct {
209                 struct heap_data *first;
210                 struct heap_data **last;
211         }                        xattr;
212         struct heap_data         data;
213         struct archive_string    script;
214
215         signed int               virtual:1;
216         signed int               dir:1;
217 };
218
219 struct hardlink {
220         struct archive_rb_node   rbnode;
221         int                      nlink;
222         struct {
223                 struct file     *first;
224                 struct file     **last;
225         }                        file_list;
226 };
227
228 struct xar {
229         int                      temp_fd;
230         uint64_t                 temp_offset;
231
232         int                      file_idx;
233         struct file             *root;
234         struct file             *cur_dirent;
235         struct archive_string    cur_dirstr;
236         struct file             *cur_file;
237         uint64_t                 bytes_remaining;
238         struct archive_string    tstr;
239         struct archive_string    vstr;
240
241         enum sumalg              opt_toc_sumalg;
242         enum sumalg              opt_sumalg;
243         enum enctype             opt_compression;
244         int                      opt_compression_level;
245         uint32_t                 opt_threads;
246
247         struct chksumwork        a_sumwrk;      /* archived checksum.   */
248         struct chksumwork        e_sumwrk;      /* extracted checksum.  */
249         struct la_zstream        stream;
250         struct archive_string_conv *sconv;
251         /*
252          * Compressed data buffer.
253          */
254         unsigned char            wbuff[1024 * 64];
255         size_t                   wbuff_remaining;
256
257         struct heap_data         toc;
258         /*
259          * The list of all file entries is used to manage struct file
260          * objects.
261          * We use 'next' (a member of struct file) to chain.
262          */
263         struct {
264                 struct file     *first;
265                 struct file     **last;
266         }                        file_list;
267         /*
268          * The list of hard-linked file entries.
269          * We use 'hlnext' (a member of struct file) to chain.
270          */
271         struct archive_rb_tree   hardlink_rbtree;
272 };
273
274 static int      xar_options(struct archive_write *,
275                     const char *, const char *);
276 static int      xar_write_header(struct archive_write *,
277                     struct archive_entry *);
278 static ssize_t  xar_write_data(struct archive_write *,
279                     const void *, size_t);
280 static int      xar_finish_entry(struct archive_write *);
281 static int      xar_close(struct archive_write *);
282 static int      xar_free(struct archive_write *);
283
284 static struct file *file_new(struct archive_write *a, struct archive_entry *);
285 static void     file_free(struct file *);
286 static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
287                     const char *);
288 static int      file_add_child_tail(struct file *, struct file *);
289 static struct file *file_find_child(struct file *, const char *);
290 static int      file_gen_utility_names(struct archive_write *,
291                     struct file *);
292 static int      get_path_component(char *, int, const char *);
293 static int      file_tree(struct archive_write *, struct file **);
294 static void     file_register(struct xar *, struct file *);
295 static void     file_init_register(struct xar *);
296 static void     file_free_register(struct xar *);
297 static int      file_register_hardlink(struct archive_write *,
298                     struct file *);
299 static void     file_connect_hardlink_files(struct xar *);
300 static void     file_init_hardlinks(struct xar *);
301 static void     file_free_hardlinks(struct xar *);
302
303 static void     checksum_init(struct chksumwork *, enum sumalg);
304 static void     checksum_update(struct chksumwork *, const void *, size_t);
305 static void     checksum_final(struct chksumwork *, struct chksumval *);
306 static int      compression_init_encoder_gzip(struct archive *,
307                     struct la_zstream *, int, int);
308 static int      compression_code_gzip(struct archive *,
309                     struct la_zstream *, enum la_zaction);
310 static int      compression_end_gzip(struct archive *, struct la_zstream *);
311 static int      compression_init_encoder_bzip2(struct archive *,
312                     struct la_zstream *, int);
313 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
314 static int      compression_code_bzip2(struct archive *,
315                     struct la_zstream *, enum la_zaction);
316 static int      compression_end_bzip2(struct archive *, struct la_zstream *);
317 #endif
318 static int      compression_init_encoder_lzma(struct archive *,
319                     struct la_zstream *, int);
320 static int      compression_init_encoder_xz(struct archive *,
321                     struct la_zstream *, int, int);
322 #if defined(HAVE_LZMA_H)
323 static int      compression_code_lzma(struct archive *,
324                     struct la_zstream *, enum la_zaction);
325 static int      compression_end_lzma(struct archive *, struct la_zstream *);
326 #endif
327 static int      xar_compression_init_encoder(struct archive_write *);
328 static int      compression_code(struct archive *,
329                     struct la_zstream *, enum la_zaction);
330 static int      compression_end(struct archive *,
331                     struct la_zstream *);
332 static int      save_xattrs(struct archive_write *, struct file *);
333 static int      getalgsize(enum sumalg);
334 static const char *getalgname(enum sumalg);
335
336 int
337 archive_write_set_format_xar(struct archive *_a)
338 {
339         struct archive_write *a = (struct archive_write *)_a;
340         struct xar *xar;
341
342         archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
343             ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
344
345         /* If another format was already registered, unregister it. */
346         if (a->format_free != NULL)
347                 (a->format_free)(a);
348
349         xar = calloc(1, sizeof(*xar));
350         if (xar == NULL) {
351                 archive_set_error(&a->archive, ENOMEM,
352                     "Can't allocate xar data");
353                 return (ARCHIVE_FATAL);
354         }
355         xar->temp_fd = -1;
356         file_init_register(xar);
357         file_init_hardlinks(xar);
358         archive_string_init(&(xar->tstr));
359         archive_string_init(&(xar->vstr));
360
361         /*
362          * Create the root directory.
363          */
364         xar->root = file_create_virtual_dir(a, xar, "");
365         if (xar->root == NULL) {
366                 free(xar);
367                 archive_set_error(&a->archive, ENOMEM,
368                     "Can't allocate xar data");
369                 return (ARCHIVE_FATAL);
370         }
371         xar->root->parent = xar->root;
372         file_register(xar, xar->root);
373         xar->cur_dirent = xar->root;
374         archive_string_init(&(xar->cur_dirstr));
375         archive_string_ensure(&(xar->cur_dirstr), 1);
376         xar->cur_dirstr.s[0] = 0;
377
378         /*
379          * Initialize option.
380          */
381         /* Set default checksum type. */
382         xar->opt_toc_sumalg = CKSUM_SHA1;
383         xar->opt_sumalg = CKSUM_SHA1;
384         /* Set default compression type, level, and number of threads. */
385         xar->opt_compression = GZIP;
386         xar->opt_compression_level = 6;
387         xar->opt_threads = 1;
388
389         a->format_data = xar;
390
391         a->format_name = "xar";
392         a->format_options = xar_options;
393         a->format_write_header = xar_write_header;
394         a->format_write_data = xar_write_data;
395         a->format_finish_entry = xar_finish_entry;
396         a->format_close = xar_close;
397         a->format_free = xar_free;
398         a->archive.archive_format = ARCHIVE_FORMAT_XAR;
399         a->archive.archive_format_name = "xar";
400
401         return (ARCHIVE_OK);
402 }
403
404 static int
405 xar_options(struct archive_write *a, const char *key, const char *value)
406 {
407         struct xar *xar;
408
409         xar = (struct xar *)a->format_data;
410
411         if (strcmp(key, "checksum") == 0) {
412                 if (value == NULL)
413                         xar->opt_sumalg = CKSUM_NONE;
414                 else if (strcmp(value, "none") == 0)
415                         xar->opt_sumalg = CKSUM_NONE;
416                 else if (strcmp(value, "sha1") == 0)
417                         xar->opt_sumalg = CKSUM_SHA1;
418                 else if (strcmp(value, "md5") == 0)
419                         xar->opt_sumalg = CKSUM_MD5;
420                 else {
421                         archive_set_error(&(a->archive),
422                             ARCHIVE_ERRNO_MISC,
423                             "Unknown checksum name: `%s'",
424                             value);
425                         return (ARCHIVE_FAILED);
426                 }
427                 return (ARCHIVE_OK);
428         }
429         if (strcmp(key, "compression") == 0) {
430                 const char *name = NULL;
431
432                 if (value == NULL)
433                         xar->opt_compression = NONE;
434                 else if (strcmp(value, "none") == 0)
435                         xar->opt_compression = NONE;
436                 else if (strcmp(value, "gzip") == 0)
437                         xar->opt_compression = GZIP;
438                 else if (strcmp(value, "bzip2") == 0)
439 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
440                         xar->opt_compression = BZIP2;
441 #else
442                         name = "bzip2";
443 #endif
444                 else if (strcmp(value, "lzma") == 0)
445 #if HAVE_LZMA_H
446                         xar->opt_compression = LZMA;
447 #else
448                         name = "lzma";
449 #endif
450                 else if (strcmp(value, "xz") == 0)
451 #if HAVE_LZMA_H
452                         xar->opt_compression = XZ;
453 #else
454                         name = "xz";
455 #endif
456                 else {
457                         archive_set_error(&(a->archive),
458                             ARCHIVE_ERRNO_MISC,
459                             "Unknown compression name: `%s'",
460                             value);
461                         return (ARCHIVE_FAILED);
462                 }
463                 if (name != NULL) {
464                         archive_set_error(&(a->archive),
465                             ARCHIVE_ERRNO_MISC,
466                             "`%s' compression not supported "
467                             "on this platform",
468                             name);
469                         return (ARCHIVE_FAILED);
470                 }
471                 return (ARCHIVE_OK);
472         }
473         if (strcmp(key, "compression-level") == 0) {
474                 if (value == NULL ||
475                     !(value[0] >= '0' && value[0] <= '9') ||
476                     value[1] != '\0') {
477                         archive_set_error(&(a->archive),
478                             ARCHIVE_ERRNO_MISC,
479                             "Illegal value `%s'",
480                             value);
481                         return (ARCHIVE_FAILED);
482                 }
483                 xar->opt_compression_level = value[0] - '0';
484                 return (ARCHIVE_OK);
485         }
486         if (strcmp(key, "toc-checksum") == 0) {
487                 if (value == NULL)
488                         xar->opt_toc_sumalg = CKSUM_NONE;
489                 else if (strcmp(value, "none") == 0)
490                         xar->opt_toc_sumalg = CKSUM_NONE;
491                 else if (strcmp(value, "sha1") == 0)
492                         xar->opt_toc_sumalg = CKSUM_SHA1;
493                 else if (strcmp(value, "md5") == 0)
494                         xar->opt_toc_sumalg = CKSUM_MD5;
495                 else {
496                         archive_set_error(&(a->archive),
497                             ARCHIVE_ERRNO_MISC,
498                             "Unknown checksum name: `%s'",
499                             value);
500                         return (ARCHIVE_FAILED);
501                 }
502                 return (ARCHIVE_OK);
503         }
504         if (strcmp(key, "threads") == 0) {
505                 char *endptr;
506
507                 if (value == NULL)
508                         return (ARCHIVE_FAILED);
509                 errno = 0;
510                 xar->opt_threads = (int)strtoul(value, &endptr, 10);
511                 if (errno != 0 || *endptr != '\0') {
512                         xar->opt_threads = 1;
513                         archive_set_error(&(a->archive),
514                             ARCHIVE_ERRNO_MISC,
515                             "Illegal value `%s'",
516                             value);
517                         return (ARCHIVE_FAILED);
518                 }
519                 if (xar->opt_threads == 0) {
520 #ifdef HAVE_LZMA_STREAM_ENCODER_MT
521                         xar->opt_threads = lzma_cputhreads();
522 #else
523                         xar->opt_threads = 1;
524 #endif
525                 }
526         }
527
528         /* Note: The "warn" return is just to inform the options
529          * supervisor that we didn't handle it.  It will generate
530          * a suitable error if no one used this option. */
531         return (ARCHIVE_WARN);
532 }
533
534 static int
535 xar_write_header(struct archive_write *a, struct archive_entry *entry)
536 {
537         struct xar *xar;
538         struct file *file;
539         struct archive_entry *file_entry;
540         int r, r2;
541
542         xar = (struct xar *)a->format_data;
543         xar->cur_file = NULL;
544         xar->bytes_remaining = 0;
545
546         if (xar->sconv == NULL) {
547                 xar->sconv = archive_string_conversion_to_charset(
548                     &a->archive, "UTF-8", 1);
549                 if (xar->sconv == NULL)
550                         return (ARCHIVE_FATAL);
551         }
552
553         file = file_new(a, entry);
554         if (file == NULL) {
555                 archive_set_error(&a->archive, ENOMEM,
556                     "Can't allocate data");
557                 return (ARCHIVE_FATAL);
558         }
559         r2 = file_gen_utility_names(a, file);
560         if (r2 < ARCHIVE_WARN)
561                 return (r2);
562
563         /*
564          * Ignore a path which looks like the top of directory name
565          * since we have already made the root directory of an Xar archive.
566          */
567         if (archive_strlen(&(file->parentdir)) == 0 &&
568             archive_strlen(&(file->basename)) == 0) {
569                 file_free(file);
570                 return (r2);
571         }
572
573         /* Add entry into tree */
574         file_entry = file->entry;
575         r = file_tree(a, &file);
576         if (r != ARCHIVE_OK)
577                 return (r);
578         /* There is the same file in tree and
579          * the current file is older than the file in tree.
580          * So we don't need the current file data anymore. */
581         if (file->entry != file_entry)
582                 return (r2);
583         if (file->id == 0)
584                 file_register(xar, file);
585
586         /* A virtual file, which is a directory, does not have
587          * any contents and we won't store it into a archive
588          * file other than its name. */
589         if (file->virtual)
590                 return (r2);
591
592         /*
593          * Prepare to save the contents of the file.
594          */
595         if (xar->temp_fd == -1) {
596                 int algsize;
597                 xar->temp_offset = 0;
598                 xar->temp_fd = __archive_mktemp(NULL);
599                 if (xar->temp_fd < 0) {
600                         archive_set_error(&a->archive, errno,
601                             "Couldn't create temporary file");
602                         return (ARCHIVE_FATAL);
603                 }
604                 algsize = getalgsize(xar->opt_toc_sumalg);
605                 if (algsize > 0) {
606                         if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
607                                 archive_set_error(&(a->archive), errno,
608                                     "lseek failed");
609                                 return (ARCHIVE_FATAL);
610                         }
611                         xar->temp_offset = algsize;
612                 }
613         }
614
615         if (archive_entry_hardlink(file->entry) == NULL) {
616                 r = save_xattrs(a, file);
617                 if (r != ARCHIVE_OK)
618                         return (ARCHIVE_FATAL);
619         }
620
621         /* Non regular files contents are unneeded to be saved to
622          * a temporary file. */
623         if (archive_entry_filetype(file->entry) != AE_IFREG)
624                 return (r2);
625
626         /*
627          * Set the current file to cur_file to read its contents.
628          */
629         xar->cur_file = file;
630
631         if (archive_entry_nlink(file->entry) > 1) {
632                 r = file_register_hardlink(a, file);
633                 if (r != ARCHIVE_OK)
634                         return (r);
635                 if (archive_entry_hardlink(file->entry) != NULL) {
636                         archive_entry_unset_size(file->entry);
637                         return (r2);
638                 }
639         }
640
641         /* Save a offset of current file in temporary file. */
642         file->data.temp_offset = xar->temp_offset;
643         file->data.size = archive_entry_size(file->entry);
644         file->data.compression = xar->opt_compression;
645         xar->bytes_remaining = archive_entry_size(file->entry);
646         checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
647         checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
648         r = xar_compression_init_encoder(a);
649
650         if (r != ARCHIVE_OK)
651                 return (r);
652         else
653                 return (r2);
654 }
655
656 static int
657 write_to_temp(struct archive_write *a, const void *buff, size_t s)
658 {
659         struct xar *xar;
660         const unsigned char *p;
661         ssize_t ws;
662
663         xar = (struct xar *)a->format_data;
664         p = (const unsigned char *)buff;
665         while (s) {
666                 ws = write(xar->temp_fd, p, s);
667                 if (ws < 0) {
668                         archive_set_error(&(a->archive), errno,
669                             "fwrite function failed");
670                         return (ARCHIVE_FATAL);
671                 }
672                 s -= ws;
673                 p += ws;
674                 xar->temp_offset += ws;
675         }
676         return (ARCHIVE_OK);
677 }
678
679 static ssize_t
680 xar_write_data(struct archive_write *a, const void *buff, size_t s)
681 {
682         struct xar *xar;
683         enum la_zaction run;
684         size_t size = 0;
685         size_t rsize;
686         int r;
687
688         xar = (struct xar *)a->format_data;
689
690         if (s > xar->bytes_remaining)
691                 s = (size_t)xar->bytes_remaining;
692         if (s == 0 || xar->cur_file == NULL)
693                 return (0);
694         if (xar->cur_file->data.compression == NONE) {
695                 checksum_update(&(xar->e_sumwrk), buff, s);
696                 checksum_update(&(xar->a_sumwrk), buff, s);
697                 size = rsize = s;
698         } else {
699                 xar->stream.next_in = (const unsigned char *)buff;
700                 xar->stream.avail_in = s;
701                 if (xar->bytes_remaining > s)
702                         run = ARCHIVE_Z_RUN;
703                 else
704                         run = ARCHIVE_Z_FINISH;
705                 /* Compress file data. */
706                 for (;;) {
707                         r = compression_code(&(a->archive), &(xar->stream),
708                             run);
709                         if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
710                                 return (ARCHIVE_FATAL);
711                         if (xar->stream.avail_out == 0 ||
712                             run == ARCHIVE_Z_FINISH) {
713                                 size = sizeof(xar->wbuff) -
714                                     xar->stream.avail_out;
715                                 checksum_update(&(xar->a_sumwrk), xar->wbuff,
716                                     size);
717                                 xar->cur_file->data.length += size;
718                                 if (write_to_temp(a, xar->wbuff,
719                                     size) != ARCHIVE_OK)
720                                         return (ARCHIVE_FATAL);
721                                 if (r == ARCHIVE_OK) {
722                                         /* Output buffer was full */
723                                         xar->stream.next_out = xar->wbuff;
724                                         xar->stream.avail_out =
725                                             sizeof(xar->wbuff);
726                                 } else {
727                                         /* ARCHIVE_EOF - We are done */
728                                         break;
729                                 }
730                         } else {
731                                 /* Compressor wants more input */
732                                 break;
733                         }
734                 }
735                 rsize = s - xar->stream.avail_in;
736                 checksum_update(&(xar->e_sumwrk), buff, rsize);
737         }
738 #if !defined(_WIN32) || defined(__CYGWIN__)
739         if (xar->bytes_remaining ==
740             (uint64_t)archive_entry_size(xar->cur_file->entry)) {
741                 /*
742                  * Get the path of a shell script if so.
743                  */
744                 const unsigned char *b = (const unsigned char *)buff;
745
746                 archive_string_empty(&(xar->cur_file->script));
747                 if (rsize > 2 && b[0] == '#' && b[1] == '!') {
748                         size_t i, end, off;
749
750                         off = 2;
751                         if (b[off] == ' ')
752                                 off++;
753 #ifdef PATH_MAX
754                         if ((rsize - off) > PATH_MAX)
755                                 end = off + PATH_MAX;
756                         else
757 #endif
758                                 end = rsize;
759                         /* Find the end of a script path. */
760                         for (i = off; i < end && b[i] != '\0' &&
761                             b[i] != '\n' && b[i] != '\r' &&
762                             b[i] != ' ' && b[i] != '\t'; i++)
763                                 ;
764                         archive_strncpy(&(xar->cur_file->script), b + off,
765                             i - off);
766                 }
767         }
768 #endif
769
770         if (xar->cur_file->data.compression == NONE) {
771                 if (write_to_temp(a, buff, size) != ARCHIVE_OK)
772                         return (ARCHIVE_FATAL);
773                 xar->cur_file->data.length += size;
774         }
775         xar->bytes_remaining -= rsize;
776
777         return (rsize);
778 }
779
780 static int
781 xar_finish_entry(struct archive_write *a)
782 {
783         struct xar *xar;
784         struct file *file;
785         size_t s;
786         ssize_t w;
787
788         xar = (struct xar *)a->format_data;
789         if (xar->cur_file == NULL)
790                 return (ARCHIVE_OK);
791
792         while (xar->bytes_remaining > 0) {
793                 s = (size_t)xar->bytes_remaining;
794                 if (s > a->null_length)
795                         s = a->null_length;
796                 w = xar_write_data(a, a->nulls, s);
797                 if (w > 0)
798                         xar->bytes_remaining -= w;
799                 else
800                         return (w);
801         }
802         file = xar->cur_file;
803         checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
804         checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
805         xar->cur_file = NULL;
806
807         return (ARCHIVE_OK);
808 }
809
810 static int
811 xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
812         const char *key, const char *value,
813         const char *attrkey, const char *attrvalue)
814 {
815         int r;
816
817         r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
818         if (r < 0) {
819                 archive_set_error(&a->archive,
820                     ARCHIVE_ERRNO_MISC,
821                     "xmlTextWriterStartElement() failed: %d", r);
822                 return (ARCHIVE_FATAL);
823         }
824         if (attrkey != NULL && attrvalue != NULL) {
825                 r = xmlTextWriterWriteAttribute(writer,
826                     BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue));
827                 if (r < 0) {
828                         archive_set_error(&a->archive,
829                             ARCHIVE_ERRNO_MISC,
830                             "xmlTextWriterWriteAttribute() failed: %d", r);
831                         return (ARCHIVE_FATAL);
832                 }
833         }
834         if (value != NULL) {
835                 r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
836                 if (r < 0) {
837                         archive_set_error(&a->archive,
838                             ARCHIVE_ERRNO_MISC,
839                             "xmlTextWriterWriteString() failed: %d", r);
840                         return (ARCHIVE_FATAL);
841                 }
842         }
843         r = xmlTextWriterEndElement(writer);
844         if (r < 0) {
845                 archive_set_error(&a->archive,
846                     ARCHIVE_ERRNO_MISC,
847                     "xmlTextWriterEndElement() failed: %d", r);
848                 return (ARCHIVE_FATAL);
849         }
850         return (ARCHIVE_OK);
851 }
852
853 static int
854 xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
855         const char *key, const char *value)
856 {
857         int r;
858
859         if (value == NULL)
860                 return (ARCHIVE_OK);
861
862         r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
863         if (r < 0) {
864                 archive_set_error(&a->archive,
865                     ARCHIVE_ERRNO_MISC,
866                     "xmlTextWriterStartElement() failed: %d", r);
867                 return (ARCHIVE_FATAL);
868         }
869         if (value != NULL) {
870                 r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
871                 if (r < 0) {
872                         archive_set_error(&a->archive,
873                             ARCHIVE_ERRNO_MISC,
874                             "xmlTextWriterWriteString() failed: %d", r);
875                         return (ARCHIVE_FATAL);
876                 }
877         }
878         r = xmlTextWriterEndElement(writer);
879         if (r < 0) {
880                 archive_set_error(&a->archive,
881                     ARCHIVE_ERRNO_MISC,
882                     "xmlTextWriterEndElement() failed: %d", r);
883                 return (ARCHIVE_FATAL);
884         }
885         return (ARCHIVE_OK);
886 }
887
888 static int
889 xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
890         const char *key, const char *fmt, ...)
891 {
892         struct xar *xar;
893         va_list ap;
894
895         xar = (struct xar *)a->format_data;
896         va_start(ap, fmt);
897         archive_string_empty(&xar->vstr);
898         archive_string_vsprintf(&xar->vstr, fmt, ap);
899         va_end(ap);
900         return (xmlwrite_string(a, writer, key, xar->vstr.s));
901 }
902
903 static int
904 xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
905         const char *key, time_t t, int z)
906 {
907         char timestr[100];
908         struct tm tm;
909 #if defined(HAVE__GMTIME64_S)
910         __time64_t tmptime;
911 #endif
912
913 #if defined(HAVE_GMTIME_R)
914         gmtime_r(&t, &tm);
915 #elif defined(HAVE__GMTIME64_S)
916         tmptime = t;
917         _gmtime64_s(&tm, &tmptime);
918 #else
919         memcpy(&tm, gmtime(&t), sizeof(tm));
920 #endif
921         memset(&timestr, 0, sizeof(timestr));
922         /* Do not use %F and %T for portability. */
923         strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
924         if (z)
925                 strcat(timestr, "Z");
926         return (xmlwrite_string(a, writer, key, timestr));
927 }
928
929 static int
930 xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
931         const char *key, mode_t mode)
932 {
933         char ms[5];
934
935         ms[0] = '0';
936         ms[1] = '0' + ((mode >> 6) & 07);
937         ms[2] = '0' + ((mode >> 3) & 07);
938         ms[3] = '0' + (mode & 07);
939         ms[4] = '\0';
940
941         return (xmlwrite_string(a, writer, key, ms));
942 }
943
944 static int
945 xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
946         const char *key, struct chksumval *sum)
947 {
948         const char *algname;
949         int algsize;
950         char buff[MAX_SUM_SIZE*2 + 1];
951         char *p;
952         unsigned char *s;
953         int i, r;
954
955         if (sum->len > 0) {
956                 algname = getalgname(sum->alg);
957                 algsize = getalgsize(sum->alg);
958                 if (algname != NULL) {
959                         const char *hex = "0123456789abcdef";
960                         p = buff;
961                         s = sum->val;
962                         for (i = 0; i < algsize; i++) {
963                                 *p++ = hex[(*s >> 4)];
964                                 *p++ = hex[(*s & 0x0f)];
965                                 s++;
966                         }
967                         *p = '\0';
968                         r = xmlwrite_string_attr(a, writer,
969                             key, buff,
970                             "style", algname);
971                         if (r < 0)
972                                 return (ARCHIVE_FATAL);
973                 }
974         }
975         return (ARCHIVE_OK);
976 }
977
978 static int
979 xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
980         struct heap_data *heap)
981 {
982         const char *encname;
983         int r;
984
985         r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
986         if (r < 0)
987                 return (ARCHIVE_FATAL);
988         r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
989         if (r < 0)
990                 return (ARCHIVE_FATAL);
991         r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
992         if (r < 0)
993                 return (ARCHIVE_FATAL);
994         switch (heap->compression) {
995         case GZIP:
996                 encname = "application/x-gzip"; break;
997         case BZIP2:
998                 encname = "application/x-bzip2"; break;
999         case LZMA:
1000                 encname = "application/x-lzma"; break;
1001         case XZ:
1002                 encname = "application/x-xz"; break;
1003         default:
1004                 encname = "application/octet-stream"; break;
1005         }
1006         r = xmlwrite_string_attr(a, writer, "encoding", NULL,
1007             "style", encname);
1008         if (r < 0)
1009                 return (ARCHIVE_FATAL);
1010         r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
1011         if (r < 0)
1012                 return (ARCHIVE_FATAL);
1013         r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
1014         if (r < 0)
1015                 return (ARCHIVE_FATAL);
1016         return (ARCHIVE_OK);
1017 }
1018
1019 /*
1020  * xar utility records fflags as following xml elements:
1021  *   <flags>
1022  *     <UserNoDump/>
1023  *     .....
1024  *   </flags>
1025  * or
1026  *   <ext2>
1027  *     <NoDump/>
1028  *     .....
1029  *   </ext2>
1030  * If xar is running on BSD platform, records <flags>..</flags>;
1031  * if xar is running on linux platform, records <ext2>..</ext2>;
1032  * otherwise does not record.
1033  *
1034  * Our implements records both <flags> and <ext2> if it's necessary.
1035  */
1036 static int
1037 make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
1038     const char *element, const char *fflags_text)
1039 {
1040         static const struct flagentry {
1041                 const char      *name;
1042                 const char      *xarname;
1043         }
1044         flagbsd[] = {
1045                 { "sappnd",     "SystemAppend"},
1046                 { "sappend",    "SystemAppend"},
1047                 { "arch",       "SystemArchived"},
1048                 { "archived",   "SystemArchived"},
1049                 { "schg",       "SystemImmutable"},
1050                 { "schange",    "SystemImmutable"},
1051                 { "simmutable", "SystemImmutable"},
1052                 { "nosunlnk",   "SystemNoUnlink"},
1053                 { "nosunlink",  "SystemNoUnlink"},
1054                 { "snapshot",   "SystemSnapshot"},
1055                 { "uappnd",     "UserAppend"},
1056                 { "uappend",    "UserAppend"},
1057                 { "uchg",       "UserImmutable"},
1058                 { "uchange",    "UserImmutable"},
1059                 { "uimmutable", "UserImmutable"},
1060                 { "nodump",     "UserNoDump"},
1061                 { "noopaque",   "UserOpaque"},
1062                 { "nouunlnk",   "UserNoUnlink"},
1063                 { "nouunlink",  "UserNoUnlink"},
1064                 { NULL, NULL}
1065         },
1066         flagext2[] = {
1067                 { "sappnd",     "AppendOnly"},
1068                 { "sappend",    "AppendOnly"},
1069                 { "schg",       "Immutable"},
1070                 { "schange",    "Immutable"},
1071                 { "simmutable", "Immutable"},
1072                 { "nodump",     "NoDump"},
1073                 { "nouunlnk",   "Undelete"},
1074                 { "nouunlink",  "Undelete"},
1075                 { "btree",      "BTree"},
1076                 { "comperr",    "CompError"},
1077                 { "compress",   "Compress"},
1078                 { "noatime",    "NoAtime"},
1079                 { "compdirty",  "CompDirty"},
1080                 { "comprblk",   "CompBlock"},
1081                 { "dirsync",    "DirSync"},
1082                 { "hashidx",    "HashIndexed"},
1083                 { "imagic",     "iMagic"},
1084                 { "journal",    "Journaled"},
1085                 { "securedeletion",     "SecureDeletion"},
1086                 { "sync",       "Synchronous"},
1087                 { "notail",     "NoTail"},
1088                 { "topdir",     "TopDir"},
1089                 { "reserved",   "Reserved"},
1090                 { NULL, NULL}
1091         };
1092         const struct flagentry *fe, *flagentry;
1093 #define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
1094         const struct flagentry *avail[FLAGENTRY_MAXSIZE];
1095         const char *p;
1096         int i, n, r;
1097
1098         if (strcmp(element, "ext2") == 0)
1099                 flagentry = flagext2;
1100         else
1101                 flagentry = flagbsd;
1102         n = 0;
1103         p = fflags_text;
1104         do {
1105                 const char *cp;
1106
1107                 cp = strchr(p, ',');
1108                 if (cp == NULL)
1109                         cp = p + strlen(p);
1110
1111                 for (fe = flagentry; fe->name != NULL; fe++) {
1112                         if (fe->name[cp - p] != '\0'
1113                             || p[0] != fe->name[0])
1114                                 continue;
1115                         if (strncmp(p, fe->name, cp - p) == 0) {
1116                                 avail[n++] = fe;
1117                                 break;
1118                         }
1119                 }
1120                 if (*cp == ',')
1121                         p = cp + 1;
1122                 else
1123                         p = NULL;
1124         } while (p != NULL);
1125
1126         if (n > 0) {
1127                 r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element));
1128                 if (r < 0) {
1129                         archive_set_error(&a->archive,
1130                             ARCHIVE_ERRNO_MISC,
1131                             "xmlTextWriterStartElement() failed: %d", r);
1132                         return (ARCHIVE_FATAL);
1133                 }
1134                 for (i = 0; i < n; i++) {
1135                         r = xmlwrite_string(a, writer,
1136                             avail[i]->xarname, NULL);
1137                         if (r != ARCHIVE_OK)
1138                                 return (r);
1139                 }
1140
1141                 r = xmlTextWriterEndElement(writer);
1142                 if (r < 0) {
1143                         archive_set_error(&a->archive,
1144                             ARCHIVE_ERRNO_MISC,
1145                             "xmlTextWriterEndElement() failed: %d", r);
1146                         return (ARCHIVE_FATAL);
1147                 }
1148         }
1149         return (ARCHIVE_OK);
1150 }
1151
1152 static int
1153 make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
1154     struct file *file)
1155 {
1156         struct xar *xar;
1157         const char *filetype, *filelink, *fflags;
1158         struct archive_string linkto;
1159         struct heap_data *heap;
1160         unsigned char *tmp;
1161         const char *p;
1162         size_t len;
1163         int r, r2, l, ll;
1164
1165         xar = (struct xar *)a->format_data;
1166         r2 = ARCHIVE_OK;
1167
1168         /*
1169          * Make a file name entry, "<name>".
1170          */
1171         l = ll = archive_strlen(&(file->basename));
1172         tmp = malloc(l);
1173         if (tmp == NULL) {
1174                 archive_set_error(&a->archive, ENOMEM,
1175                     "Can't allocate memory");
1176                 return (ARCHIVE_FATAL);
1177         }
1178         r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
1179         free(tmp);
1180         if (r < 0) {
1181                 r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
1182                 if (r < 0) {
1183                         archive_set_error(&a->archive,
1184                             ARCHIVE_ERRNO_MISC,
1185                             "xmlTextWriterStartElement() failed: %d", r);
1186                         return (ARCHIVE_FATAL);
1187                 }
1188                 r = xmlTextWriterWriteAttribute(writer,
1189                     BAD_CAST("enctype"), BAD_CAST("base64"));
1190                 if (r < 0) {
1191                         archive_set_error(&a->archive,
1192                             ARCHIVE_ERRNO_MISC,
1193                             "xmlTextWriterWriteAttribute() failed: %d", r);
1194                         return (ARCHIVE_FATAL);
1195                 }
1196                 r = xmlTextWriterWriteBase64(writer, file->basename.s,
1197                     0, archive_strlen(&(file->basename)));
1198                 if (r < 0) {
1199                         archive_set_error(&a->archive,
1200                             ARCHIVE_ERRNO_MISC,
1201                             "xmlTextWriterWriteBase64() failed: %d", r);
1202                         return (ARCHIVE_FATAL);
1203                 }
1204                 r = xmlTextWriterEndElement(writer);
1205                 if (r < 0) {
1206                         archive_set_error(&a->archive,
1207                             ARCHIVE_ERRNO_MISC,
1208                             "xmlTextWriterEndElement() failed: %d", r);
1209                         return (ARCHIVE_FATAL);
1210                 }
1211         } else {
1212                 r = xmlwrite_string(a, writer, "name", file->basename.s);
1213                 if (r < 0)
1214                         return (ARCHIVE_FATAL);
1215         }
1216
1217         /*
1218          * Make a file type entry, "<type>".
1219          */
1220         filelink = NULL;
1221         archive_string_init(&linkto);
1222         switch (archive_entry_filetype(file->entry)) {
1223         case AE_IFDIR:
1224                 filetype = "directory"; break;
1225         case AE_IFLNK:
1226                 filetype = "symlink"; break;
1227         case AE_IFCHR:
1228                 filetype = "character special"; break;
1229         case AE_IFBLK:
1230                 filetype = "block special"; break;
1231         case AE_IFSOCK:
1232                 filetype = "socket"; break;
1233         case AE_IFIFO:
1234                 filetype = "fifo"; break;
1235         case AE_IFREG:
1236         default:
1237                 if (file->hardlink_target != NULL) {
1238                         filetype = "hardlink";
1239                         filelink = "link";
1240                         if (file->hardlink_target == file)
1241                                 archive_strcpy(&linkto, "original");
1242                         else
1243                                 archive_string_sprintf(&linkto, "%d",
1244                                     file->hardlink_target->id);
1245                 } else
1246                         filetype = "file";
1247                 break;
1248         }
1249         r = xmlwrite_string_attr(a, writer, "type", filetype,
1250             filelink, linkto.s);
1251         archive_string_free(&linkto);
1252         if (r < 0)
1253                 return (ARCHIVE_FATAL);
1254
1255         /*
1256          * On a virtual directory, we record "name" and "type" only.
1257          */
1258         if (file->virtual)
1259                 return (ARCHIVE_OK);
1260
1261         switch (archive_entry_filetype(file->entry)) {
1262         case AE_IFLNK:
1263                 /*
1264                  * xar utility has checked a file type, which
1265                  * a symbolic-link file has referenced.
1266                  * For example:
1267                  *   <link type="directory">../ref/</link>
1268                  *   The symlink target file is "../ref/" and its
1269                  *   file type is a directory.
1270                  *
1271                  *   <link type="file">../f</link>
1272                  *   The symlink target file is "../f" and its
1273                  *   file type is a regular file.
1274                  *
1275                  * But our implementation cannot do it, and then we
1276                  * always record that a attribute "type" is "broken",
1277                  * for example:
1278                  *   <link type="broken">foo/bar</link>
1279                  *   It means "foo/bar" is not reachable.
1280                  */
1281                 r = xmlwrite_string_attr(a, writer, "link",
1282                     file->symlink.s,
1283                     "type", "broken");
1284                 if (r < 0)
1285                         return (ARCHIVE_FATAL);
1286                 break;
1287         case AE_IFCHR:
1288         case AE_IFBLK:
1289                 r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
1290                 if (r < 0) {
1291                         archive_set_error(&a->archive,
1292                             ARCHIVE_ERRNO_MISC,
1293                             "xmlTextWriterStartElement() failed: %d", r);
1294                         return (ARCHIVE_FATAL);
1295                 }
1296                 r = xmlwrite_fstring(a, writer, "major",
1297                     "%d", archive_entry_rdevmajor(file->entry));
1298                 if (r < 0)
1299                         return (ARCHIVE_FATAL);
1300                 r = xmlwrite_fstring(a, writer, "minor",
1301                     "%d", archive_entry_rdevminor(file->entry));
1302                 if (r < 0)
1303                         return (ARCHIVE_FATAL);
1304                 r = xmlTextWriterEndElement(writer);
1305                 if (r < 0) {
1306                         archive_set_error(&a->archive,
1307                             ARCHIVE_ERRNO_MISC,
1308                             "xmlTextWriterEndElement() failed: %d", r);
1309                         return (ARCHIVE_FATAL);
1310                 }
1311                 break;
1312         default:
1313                 break;
1314         }
1315
1316         /*
1317          * Make a inode entry, "<inode>".
1318          */
1319         r = xmlwrite_fstring(a, writer, "inode",
1320             "%jd", archive_entry_ino64(file->entry));
1321         if (r < 0)
1322                 return (ARCHIVE_FATAL);
1323         if (archive_entry_dev(file->entry) != 0) {
1324                 r = xmlwrite_fstring(a, writer, "deviceno",
1325                     "%d", archive_entry_dev(file->entry));
1326                 if (r < 0)
1327                         return (ARCHIVE_FATAL);
1328         }
1329
1330         /*
1331          * Make a file mode entry, "<mode>".
1332          */
1333         r = xmlwrite_mode(a, writer, "mode",
1334             archive_entry_mode(file->entry));
1335         if (r < 0)
1336                 return (ARCHIVE_FATAL);
1337
1338         /*
1339          * Make a user entry, "<uid>" and "<user>.
1340          */
1341         r = xmlwrite_fstring(a, writer, "uid",
1342             "%d", archive_entry_uid(file->entry));
1343         if (r < 0)
1344                 return (ARCHIVE_FATAL);
1345         r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
1346         if (r != 0) {
1347                 if (errno == ENOMEM) {
1348                         archive_set_error(&a->archive, ENOMEM,
1349                             "Can't allocate memory for Uname");
1350                         return (ARCHIVE_FATAL);
1351                 }
1352                 archive_set_error(&a->archive,
1353                     ARCHIVE_ERRNO_FILE_FORMAT,
1354                     "Can't translate uname '%s' to UTF-8",
1355                     archive_entry_uname(file->entry));
1356                 r2 = ARCHIVE_WARN;
1357         }
1358         if (len > 0) {
1359                 r = xmlwrite_string(a, writer, "user", p);
1360                 if (r < 0)
1361                         return (ARCHIVE_FATAL);
1362         }
1363
1364         /*
1365          * Make a group entry, "<gid>" and "<group>.
1366          */
1367         r = xmlwrite_fstring(a, writer, "gid",
1368             "%d", archive_entry_gid(file->entry));
1369         if (r < 0)
1370                 return (ARCHIVE_FATAL);
1371         r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
1372         if (r != 0) {
1373                 if (errno == ENOMEM) {
1374                         archive_set_error(&a->archive, ENOMEM,
1375                             "Can't allocate memory for Gname");
1376                         return (ARCHIVE_FATAL);
1377                 }
1378                 archive_set_error(&a->archive,
1379                     ARCHIVE_ERRNO_FILE_FORMAT,
1380                     "Can't translate gname '%s' to UTF-8",
1381                     archive_entry_gname(file->entry));
1382                 r2 = ARCHIVE_WARN;
1383         }
1384         if (len > 0) {
1385                 r = xmlwrite_string(a, writer, "group", p);
1386                 if (r < 0)
1387                         return (ARCHIVE_FATAL);
1388         }
1389
1390         /*
1391          * Make a ctime entry, "<ctime>".
1392          */
1393         if (archive_entry_ctime_is_set(file->entry)) {
1394                 r = xmlwrite_time(a, writer, "ctime",
1395                     archive_entry_ctime(file->entry), 1);
1396                 if (r < 0)
1397                         return (ARCHIVE_FATAL);
1398         }
1399
1400         /*
1401          * Make a mtime entry, "<mtime>".
1402          */
1403         if (archive_entry_mtime_is_set(file->entry)) {
1404                 r = xmlwrite_time(a, writer, "mtime",
1405                     archive_entry_mtime(file->entry), 1);
1406                 if (r < 0)
1407                         return (ARCHIVE_FATAL);
1408         }
1409
1410         /*
1411          * Make a atime entry, "<atime>".
1412          */
1413         if (archive_entry_atime_is_set(file->entry)) {
1414                 r = xmlwrite_time(a, writer, "atime",
1415                     archive_entry_atime(file->entry), 1);
1416                 if (r < 0)
1417                         return (ARCHIVE_FATAL);
1418         }
1419
1420         /*
1421          * Make fflags entries, "<flags>" and "<ext2>".
1422          */
1423         fflags = archive_entry_fflags_text(file->entry);
1424         if (fflags != NULL) {
1425                 r = make_fflags_entry(a, writer, "flags", fflags);
1426                 if (r < 0)
1427                         return (r);
1428                 r = make_fflags_entry(a, writer, "ext2", fflags);
1429                 if (r < 0)
1430                         return (r);
1431         }
1432
1433         /*
1434          * Make extended attribute entries, "<ea>".
1435          */
1436         archive_entry_xattr_reset(file->entry);
1437         for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
1438                 const char *name;
1439                 const void *value;
1440                 size_t size;
1441
1442                 archive_entry_xattr_next(file->entry,
1443                     &name, &value, &size);
1444                 r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
1445                 if (r < 0) {
1446                         archive_set_error(&a->archive,
1447                             ARCHIVE_ERRNO_MISC,
1448                             "xmlTextWriterStartElement() failed: %d", r);
1449                         return (ARCHIVE_FATAL);
1450                 }
1451                 r = xmlTextWriterWriteFormatAttribute(writer,
1452                     BAD_CAST("id"), "%d", heap->id);
1453                 if (r < 0) {
1454                         archive_set_error(&a->archive,
1455                             ARCHIVE_ERRNO_MISC,
1456                             "xmlTextWriterWriteAttribute() failed: %d", r);
1457                         return (ARCHIVE_FATAL);
1458                 }
1459                 r = xmlwrite_heap(a, writer, heap);
1460                 if (r < 0)
1461                         return (ARCHIVE_FATAL);
1462                 r = xmlwrite_string(a, writer, "name", name);
1463                 if (r < 0)
1464                         return (ARCHIVE_FATAL);
1465
1466                 r = xmlTextWriterEndElement(writer);
1467                 if (r < 0) {
1468                         archive_set_error(&a->archive,
1469                             ARCHIVE_ERRNO_MISC,
1470                             "xmlTextWriterEndElement() failed: %d", r);
1471                         return (ARCHIVE_FATAL);
1472                 }
1473         }
1474
1475         /*
1476          * Make a file data entry, "<data>".
1477          */
1478         if (file->data.length > 0) {
1479                 r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
1480                 if (r < 0) {
1481                         archive_set_error(&a->archive,
1482                             ARCHIVE_ERRNO_MISC,
1483                             "xmlTextWriterStartElement() failed: %d", r);
1484                         return (ARCHIVE_FATAL);
1485                 }
1486
1487                 r = xmlwrite_heap(a, writer, &(file->data));
1488                 if (r < 0)
1489                         return (ARCHIVE_FATAL);
1490
1491                 r = xmlTextWriterEndElement(writer);
1492                 if (r < 0) {
1493                         archive_set_error(&a->archive,
1494                             ARCHIVE_ERRNO_MISC,
1495                             "xmlTextWriterEndElement() failed: %d", r);
1496                         return (ARCHIVE_FATAL);
1497                 }
1498         }
1499
1500         if (archive_strlen(&file->script) > 0) {
1501                 r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
1502                 if (r < 0) {
1503                         archive_set_error(&a->archive,
1504                             ARCHIVE_ERRNO_MISC,
1505                             "xmlTextWriterStartElement() failed: %d", r);
1506                         return (ARCHIVE_FATAL);
1507                 }
1508
1509                 r = xmlwrite_string(a, writer,
1510                     "interpreter", file->script.s);
1511                 if (r < 0)
1512                         return (ARCHIVE_FATAL);
1513
1514                 r = xmlwrite_string(a, writer, "type", "script");
1515                 if (r < 0)
1516                         return (ARCHIVE_FATAL);
1517
1518                 r = xmlTextWriterEndElement(writer);
1519                 if (r < 0) {
1520                         archive_set_error(&a->archive,
1521                             ARCHIVE_ERRNO_MISC,
1522                             "xmlTextWriterEndElement() failed: %d", r);
1523                         return (ARCHIVE_FATAL);
1524                 }
1525         }
1526
1527         return (r2);
1528 }
1529
1530 /*
1531  * Make the TOC
1532  */
1533 static int
1534 make_toc(struct archive_write *a)
1535 {
1536         struct xar *xar;
1537         struct file *np;
1538         xmlBufferPtr bp;
1539         xmlTextWriterPtr writer;
1540         int algsize;
1541         int r, ret;
1542
1543         xar = (struct xar *)a->format_data;
1544
1545         ret = ARCHIVE_FATAL;
1546
1547         /*
1548          * Initialize xml writer.
1549          */
1550         writer = NULL;
1551         bp = xmlBufferCreate();
1552         if (bp == NULL) {
1553                 archive_set_error(&a->archive, ENOMEM,
1554                     "xmlBufferCreate() "
1555                     "couldn't create xml buffer");
1556                 goto exit_toc;
1557         }
1558         writer = xmlNewTextWriterMemory(bp, 0);
1559         if (writer == NULL) {
1560                 archive_set_error(&a->archive,
1561                     ARCHIVE_ERRNO_MISC,
1562                     "xmlNewTextWriterMemory() "
1563                     "couldn't create xml writer");
1564                 goto exit_toc;
1565         }
1566         r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
1567         if (r < 0) {
1568                 archive_set_error(&a->archive,
1569                     ARCHIVE_ERRNO_MISC,
1570                     "xmlTextWriterStartDocument() failed: %d", r);
1571                 goto exit_toc;
1572         }
1573         r = xmlTextWriterSetIndent(writer, 4);
1574         if (r < 0) {
1575                 archive_set_error(&a->archive,
1576                     ARCHIVE_ERRNO_MISC,
1577                     "xmlTextWriterSetIndent() failed: %d", r);
1578                 goto exit_toc;
1579         }
1580
1581         /*
1582          * Start recording TOC
1583          */
1584         r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
1585         if (r < 0) {
1586                 archive_set_error(&a->archive,
1587                     ARCHIVE_ERRNO_MISC,
1588                     "xmlTextWriterStartElement() failed: %d", r);
1589                 goto exit_toc;
1590         }
1591         r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
1592         if (r < 0) {
1593                 archive_set_error(&a->archive,
1594                     ARCHIVE_ERRNO_MISC,
1595                     "xmlTextWriterStartDocument() failed: %d", r);
1596                 goto exit_toc;
1597         }
1598
1599         /*
1600          * Record the creation time of the archive file.
1601          */
1602         r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
1603         if (r < 0)
1604                 goto exit_toc;
1605
1606         /*
1607          * Record the checksum value of TOC
1608          */
1609         algsize = getalgsize(xar->opt_toc_sumalg);
1610         if (algsize) {
1611                 /*
1612                  * Record TOC checksum
1613                  */
1614                 r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
1615                 if (r < 0) {
1616                         archive_set_error(&a->archive,
1617                             ARCHIVE_ERRNO_MISC,
1618                             "xmlTextWriterStartElement() failed: %d", r);
1619                         goto exit_toc;
1620                 }
1621                 r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
1622                     BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg)));
1623                 if (r < 0) {
1624                         archive_set_error(&a->archive,
1625                             ARCHIVE_ERRNO_MISC,
1626                             "xmlTextWriterWriteAttribute() failed: %d", r);
1627                         goto exit_toc;
1628                 }
1629
1630                 /*
1631                  * Record the offset of the value of checksum of TOC
1632                  */
1633                 r = xmlwrite_string(a, writer, "offset", "0");
1634                 if (r < 0)
1635                         goto exit_toc;
1636
1637                 /*
1638                  * Record the size of the value of checksum of TOC
1639                  */
1640                 r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
1641                 if (r < 0)
1642                         goto exit_toc;
1643
1644                 r = xmlTextWriterEndElement(writer);
1645                 if (r < 0) {
1646                         archive_set_error(&a->archive,
1647                             ARCHIVE_ERRNO_MISC,
1648                             "xmlTextWriterEndElement() failed: %d", r);
1649                         goto exit_toc;
1650                 }
1651         }
1652
1653         np = xar->root;
1654         do {
1655                 if (np != np->parent) {
1656                         r = make_file_entry(a, writer, np);
1657                         if (r != ARCHIVE_OK)
1658                                 goto exit_toc;
1659                 }
1660
1661                 if (np->dir && np->children.first != NULL) {
1662                         /* Enter to sub directories. */
1663                         np = np->children.first;
1664                         r = xmlTextWriterStartElement(writer,
1665                             BAD_CAST("file"));
1666                         if (r < 0) {
1667                                 archive_set_error(&a->archive,
1668                                     ARCHIVE_ERRNO_MISC,
1669                                     "xmlTextWriterStartElement() "
1670                                     "failed: %d", r);
1671                                 goto exit_toc;
1672                         }
1673                         r = xmlTextWriterWriteFormatAttribute(
1674                             writer, BAD_CAST("id"), "%d", np->id);
1675                         if (r < 0) {
1676                                 archive_set_error(&a->archive,
1677                                     ARCHIVE_ERRNO_MISC,
1678                                     "xmlTextWriterWriteAttribute() "
1679                                     "failed: %d", r);
1680                                 goto exit_toc;
1681                         }
1682                         continue;
1683                 }
1684                 while (np != np->parent) {
1685                         r = xmlTextWriterEndElement(writer);
1686                         if (r < 0) {
1687                                 archive_set_error(&a->archive,
1688                                     ARCHIVE_ERRNO_MISC,
1689                                     "xmlTextWriterEndElement() "
1690                                     "failed: %d", r);
1691                                 goto exit_toc;
1692                         }
1693                         if (np->chnext == NULL) {
1694                                 /* Return to the parent directory. */
1695                                 np = np->parent;
1696                         } else {
1697                                 np = np->chnext;
1698                                 r = xmlTextWriterStartElement(writer,
1699                                     BAD_CAST("file"));
1700                                 if (r < 0) {
1701                                         archive_set_error(&a->archive,
1702                                             ARCHIVE_ERRNO_MISC,
1703                                             "xmlTextWriterStartElement() "
1704                                             "failed: %d", r);
1705                                         goto exit_toc;
1706                                 }
1707                                 r = xmlTextWriterWriteFormatAttribute(
1708                                     writer, BAD_CAST("id"), "%d", np->id);
1709                                 if (r < 0) {
1710                                         archive_set_error(&a->archive,
1711                                             ARCHIVE_ERRNO_MISC,
1712                                             "xmlTextWriterWriteAttribute() "
1713                                             "failed: %d", r);
1714                                         goto exit_toc;
1715                                 }
1716                                 break;
1717                         }
1718                 }
1719         } while (np != np->parent);
1720
1721         r = xmlTextWriterEndDocument(writer);
1722         if (r < 0) {
1723                 archive_set_error(&a->archive,
1724                     ARCHIVE_ERRNO_MISC,
1725                     "xmlTextWriterEndDocument() failed: %d", r);
1726                 goto exit_toc;
1727         }
1728 #if DEBUG_PRINT_TOC
1729         fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
1730             strlen((const char *)bp->content), bp->content);
1731 #endif
1732
1733         /*
1734          * Compress the TOC and calculate the sum of the TOC.
1735          */
1736         xar->toc.temp_offset = xar->temp_offset;
1737         xar->toc.size = bp->use;
1738         checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
1739
1740         r = compression_init_encoder_gzip(&(a->archive),
1741             &(xar->stream), 6, 1);
1742         if (r != ARCHIVE_OK)
1743                 goto exit_toc;
1744         xar->stream.next_in = bp->content;
1745         xar->stream.avail_in = bp->use;
1746         xar->stream.total_in = 0;
1747         xar->stream.next_out = xar->wbuff;
1748         xar->stream.avail_out = sizeof(xar->wbuff);
1749         xar->stream.total_out = 0;
1750         for (;;) {
1751                 size_t size;
1752
1753                 r = compression_code(&(a->archive),
1754                     &(xar->stream), ARCHIVE_Z_FINISH);
1755                 if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
1756                         goto exit_toc;
1757                 size = sizeof(xar->wbuff) - xar->stream.avail_out;
1758                 checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
1759                 if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
1760                         goto exit_toc;
1761                 if (r == ARCHIVE_EOF)
1762                         break;
1763                 xar->stream.next_out = xar->wbuff;
1764                 xar->stream.avail_out = sizeof(xar->wbuff);
1765         }
1766         r = compression_end(&(a->archive), &(xar->stream));
1767         if (r != ARCHIVE_OK)
1768                 goto exit_toc;
1769         xar->toc.length = xar->stream.total_out;
1770         xar->toc.compression = GZIP;
1771         checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
1772
1773         ret = ARCHIVE_OK;
1774 exit_toc:
1775         if (writer)
1776                 xmlFreeTextWriter(writer);
1777         if (bp)
1778                 xmlBufferFree(bp);
1779
1780         return (ret);
1781 }
1782
1783 static int
1784 flush_wbuff(struct archive_write *a)
1785 {
1786         struct xar *xar;
1787         int r;
1788         size_t s;
1789
1790         xar = (struct xar *)a->format_data;
1791         s = sizeof(xar->wbuff) - xar->wbuff_remaining;
1792         r = __archive_write_output(a, xar->wbuff, s);
1793         if (r != ARCHIVE_OK)
1794                 return (r);
1795         xar->wbuff_remaining = sizeof(xar->wbuff);
1796         return (r);
1797 }
1798
1799 static int
1800 copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
1801 {
1802         struct xar *xar;
1803         int r;
1804
1805         xar = (struct xar *)a->format_data;
1806         if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
1807                 archive_set_error(&(a->archive), errno, "lseek failed");
1808                 return (ARCHIVE_FATAL);
1809         }
1810         while (length) {
1811                 size_t rsize;
1812                 ssize_t rs;
1813                 unsigned char *wb;
1814
1815                 if (length > xar->wbuff_remaining)
1816                         rsize = xar->wbuff_remaining;
1817                 else
1818                         rsize = (size_t)length;
1819                 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1820                 rs = read(xar->temp_fd, wb, rsize);
1821                 if (rs < 0) {
1822                         archive_set_error(&(a->archive), errno,
1823                             "Can't read temporary file(%jd)",
1824                             (intmax_t)rs);
1825                         return (ARCHIVE_FATAL);
1826                 }
1827                 if (rs == 0) {
1828                         archive_set_error(&(a->archive), 0,
1829                             "Truncated xar archive");
1830                         return (ARCHIVE_FATAL);
1831                 }
1832                 xar->wbuff_remaining -= rs;
1833                 length -= rs;
1834                 if (xar->wbuff_remaining == 0) {
1835                         r = flush_wbuff(a);
1836                         if (r != ARCHIVE_OK)
1837                                 return (r);
1838                 }
1839         }
1840         return (ARCHIVE_OK);
1841 }
1842
1843 static int
1844 xar_close(struct archive_write *a)
1845 {
1846         struct xar *xar;
1847         unsigned char *wb;
1848         uint64_t length;
1849         int r;
1850
1851         xar = (struct xar *)a->format_data;
1852
1853         /* Empty! */
1854         if (xar->root->children.first == NULL)
1855                 return (ARCHIVE_OK);
1856
1857         /* Save the length of all file extended attributes and contents. */
1858         length = xar->temp_offset;
1859
1860         /* Connect hardlinked files */
1861         file_connect_hardlink_files(xar);
1862
1863         /* Make the TOC */
1864         r = make_toc(a);
1865         if (r != ARCHIVE_OK)
1866                 return (r);
1867         /*
1868          * Make the xar header on wbuff(write buffer).
1869          */
1870         wb = xar->wbuff;
1871         xar->wbuff_remaining = sizeof(xar->wbuff);
1872         archive_be32enc(&wb[0], HEADER_MAGIC);
1873         archive_be16enc(&wb[4], HEADER_SIZE);
1874         archive_be16enc(&wb[6], HEADER_VERSION);
1875         archive_be64enc(&wb[8], xar->toc.length);
1876         archive_be64enc(&wb[16], xar->toc.size);
1877         archive_be32enc(&wb[24], xar->toc.a_sum.alg);
1878         xar->wbuff_remaining -= HEADER_SIZE;
1879
1880         /*
1881          * Write the TOC
1882          */
1883         r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
1884         if (r != ARCHIVE_OK)
1885                 return (r);
1886
1887         /* Write the checksum value of the TOC. */
1888         if (xar->toc.a_sum.len) {
1889                 if (xar->wbuff_remaining < xar->toc.a_sum.len) {
1890                         r = flush_wbuff(a);
1891                         if (r != ARCHIVE_OK)
1892                                 return (r);
1893                 }
1894                 wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1895                 memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
1896                 xar->wbuff_remaining -= xar->toc.a_sum.len;
1897         }
1898
1899         /*
1900          * Write all file extended attributes and contents.
1901          */
1902         r = copy_out(a, xar->toc.a_sum.len, length);
1903         if (r != ARCHIVE_OK)
1904                 return (r);
1905         r = flush_wbuff(a);
1906         return (r);
1907 }
1908
1909 static int
1910 xar_free(struct archive_write *a)
1911 {
1912         struct xar *xar;
1913
1914         xar = (struct xar *)a->format_data;
1915
1916         /* Close the temporary file. */
1917         if (xar->temp_fd >= 0)
1918                 close(xar->temp_fd);
1919
1920         archive_string_free(&(xar->cur_dirstr));
1921         archive_string_free(&(xar->tstr));
1922         archive_string_free(&(xar->vstr));
1923         file_free_hardlinks(xar);
1924         file_free_register(xar);
1925         compression_end(&(a->archive), &(xar->stream));
1926         free(xar);
1927
1928         return (ARCHIVE_OK);
1929 }
1930
1931 static int
1932 file_cmp_node(const struct archive_rb_node *n1,
1933     const struct archive_rb_node *n2)
1934 {
1935         const struct file *f1 = (const struct file *)n1;
1936         const struct file *f2 = (const struct file *)n2;
1937
1938         return (strcmp(f1->basename.s, f2->basename.s));
1939 }
1940
1941 static int
1942 file_cmp_key(const struct archive_rb_node *n, const void *key)
1943 {
1944         const struct file *f = (const struct file *)n;
1945
1946         return (strcmp(f->basename.s, (const char *)key));
1947 }
1948
1949 static struct file *
1950 file_new(struct archive_write *a, struct archive_entry *entry)
1951 {
1952         struct file *file;
1953         static const struct archive_rb_tree_ops rb_ops = {
1954                 file_cmp_node, file_cmp_key
1955         };
1956
1957         file = calloc(1, sizeof(*file));
1958         if (file == NULL)
1959                 return (NULL);
1960
1961         if (entry != NULL)
1962                 file->entry = archive_entry_clone(entry);
1963         else
1964                 file->entry = archive_entry_new2(&a->archive);
1965         if (file->entry == NULL) {
1966                 free(file);
1967                 return (NULL);
1968         }
1969         __archive_rb_tree_init(&(file->rbtree), &rb_ops);
1970         file->children.first = NULL;
1971         file->children.last = &(file->children.first);
1972         file->xattr.first = NULL;
1973         file->xattr.last = &(file->xattr.first);
1974         archive_string_init(&(file->parentdir));
1975         archive_string_init(&(file->basename));
1976         archive_string_init(&(file->symlink));
1977         archive_string_init(&(file->script));
1978         if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
1979                 file->dir = 1;
1980
1981         return (file);
1982 }
1983
1984 static void
1985 file_free(struct file *file)
1986 {
1987         struct heap_data *heap, *next_heap;
1988
1989         heap = file->xattr.first;
1990         while (heap != NULL) {
1991                 next_heap = heap->next;
1992                 free(heap);
1993                 heap = next_heap;
1994         }
1995         archive_string_free(&(file->parentdir));
1996         archive_string_free(&(file->basename));
1997         archive_string_free(&(file->symlink));
1998         archive_string_free(&(file->script));
1999         archive_entry_free(file->entry);
2000         free(file);
2001 }
2002
2003 static struct file *
2004 file_create_virtual_dir(struct archive_write *a, struct xar *xar,
2005     const char *pathname)
2006 {
2007         struct file *file;
2008
2009         (void)xar; /* UNUSED */
2010
2011         file = file_new(a, NULL);
2012         if (file == NULL)
2013                 return (NULL);
2014         archive_entry_set_pathname(file->entry, pathname);
2015         archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
2016
2017         file->dir = 1;
2018         file->virtual = 1;
2019
2020         return (file);
2021 }
2022
2023 static int
2024 file_add_child_tail(struct file *parent, struct file *child)
2025 {
2026         if (!__archive_rb_tree_insert_node(
2027             &(parent->rbtree), (struct archive_rb_node *)child))
2028                 return (0);
2029         child->chnext = NULL;
2030         *parent->children.last = child;
2031         parent->children.last = &(child->chnext);
2032         child->parent = parent;
2033         return (1);
2034 }
2035
2036 /*
2037  * Find a entry from `parent'
2038  */
2039 static struct file *
2040 file_find_child(struct file *parent, const char *child_name)
2041 {
2042         struct file *np;
2043
2044         np = (struct file *)__archive_rb_tree_find_node(
2045             &(parent->rbtree), child_name);
2046         return (np);
2047 }
2048
2049 #if defined(_WIN32) || defined(__CYGWIN__)
2050 static void
2051 cleanup_backslash(char *utf8, size_t len)
2052 {
2053
2054         /* Convert a path-separator from '\' to  '/' */
2055         while (*utf8 != '\0' && len) {
2056                 if (*utf8 == '\\')
2057                         *utf8 = '/';
2058                 ++utf8;
2059                 --len;
2060         }
2061 }
2062 #else
2063 #define cleanup_backslash(p, len)       /* nop */
2064 #endif
2065
2066 /*
2067  * Generate a parent directory name and a base name from a pathname.
2068  */
2069 static int
2070 file_gen_utility_names(struct archive_write *a, struct file *file)
2071 {
2072         struct xar *xar;
2073         const char *pp;
2074         char *p, *dirname, *slash;
2075         size_t len;
2076         int r = ARCHIVE_OK;
2077
2078         xar = (struct xar *)a->format_data;
2079         archive_string_empty(&(file->parentdir));
2080         archive_string_empty(&(file->basename));
2081         archive_string_empty(&(file->symlink));
2082
2083         if (file->parent == file)/* virtual root */
2084                 return (ARCHIVE_OK);
2085
2086         if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
2087             != 0) {
2088                 if (errno == ENOMEM) {
2089                         archive_set_error(&a->archive, ENOMEM,
2090                             "Can't allocate memory for Pathname");
2091                         return (ARCHIVE_FATAL);
2092                 }
2093                 archive_set_error(&a->archive,
2094                     ARCHIVE_ERRNO_FILE_FORMAT,
2095                     "Can't translate pathname '%s' to UTF-8",
2096                     archive_entry_pathname(file->entry));
2097                 r = ARCHIVE_WARN;
2098         }
2099         archive_strncpy(&(file->parentdir), pp, len);
2100         len = file->parentdir.length;
2101         p = dirname = file->parentdir.s;
2102         /*
2103          * Convert a path-separator from '\' to  '/'
2104          */
2105         cleanup_backslash(p, len);
2106
2107         /*
2108          * Remove leading '/', '../' and './' elements
2109          */
2110         while (*p) {
2111                 if (p[0] == '/') {
2112                         p++;
2113                         len--;
2114                 } else if (p[0] != '.')
2115                         break;
2116                 else if (p[1] == '.' && p[2] == '/') {
2117                         p += 3;
2118                         len -= 3;
2119                 } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
2120                         p += 2;
2121                         len -= 2;
2122                 } else if (p[1] == '\0') {
2123                         p++;
2124                         len--;
2125                 } else
2126                         break;
2127         }
2128         if (p != dirname) {
2129                 memmove(dirname, p, len+1);
2130                 p = dirname;
2131         }
2132         /*
2133          * Remove "/","/." and "/.." elements from tail.
2134          */
2135         while (len > 0) {
2136                 size_t ll = len;
2137
2138                 if (p[len-1] == '/') {
2139                         p[len-1] = '\0';
2140                         len--;
2141                 }
2142                 if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
2143                         p[len-2] = '\0';
2144                         len -= 2;
2145                 }
2146                 if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
2147                     p[len-1] == '.') {
2148                         p[len-3] = '\0';
2149                         len -= 3;
2150                 }
2151                 if (ll == len)
2152                         break;
2153         }
2154         while (*p) {
2155                 if (p[0] == '/') {
2156                         if (p[1] == '/')
2157                                 /* Convert '//' --> '/' */
2158                                 strcpy(p, p+1);
2159                         else if (p[1] == '.' && p[2] == '/')
2160                                 /* Convert '/./' --> '/' */
2161                                 strcpy(p, p+2);
2162                         else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
2163                                 /* Convert 'dir/dir1/../dir2/'
2164                                  *     --> 'dir/dir2/'
2165                                  */
2166                                 char *rp = p -1;
2167                                 while (rp >= dirname) {
2168                                         if (*rp == '/')
2169                                                 break;
2170                                         --rp;
2171                                 }
2172                                 if (rp > dirname) {
2173                                         strcpy(rp, p+3);
2174                                         p = rp;
2175                                 } else {
2176                                         strcpy(dirname, p+4);
2177                                         p = dirname;
2178                                 }
2179                         } else
2180                                 p++;
2181                 } else
2182                         p++;
2183         }
2184         p = dirname;
2185         len = strlen(p);
2186
2187         if (archive_entry_filetype(file->entry) == AE_IFLNK) {
2188                 size_t len2;
2189                 /* Convert symlink name too. */
2190                 if (archive_entry_symlink_l(file->entry, &pp, &len2,
2191                     xar->sconv) != 0) {
2192                         if (errno == ENOMEM) {
2193                                 archive_set_error(&a->archive, ENOMEM,
2194                                     "Can't allocate memory for Linkname");
2195                                 return (ARCHIVE_FATAL);
2196                         }
2197                         archive_set_error(&a->archive,
2198                             ARCHIVE_ERRNO_FILE_FORMAT,
2199                             "Can't translate symlink '%s' to UTF-8",
2200                             archive_entry_symlink(file->entry));
2201                         r = ARCHIVE_WARN;
2202                 }
2203                 archive_strncpy(&(file->symlink), pp, len2);
2204                 cleanup_backslash(file->symlink.s, file->symlink.length);
2205         }
2206         /*
2207          * - Count up directory elements.
2208          * - Find out the position which points the last position of
2209          *   path separator('/').
2210          */
2211         slash = NULL;
2212         for (; *p != '\0'; p++)
2213                 if (*p == '/')
2214                         slash = p;
2215         if (slash == NULL) {
2216                 /* The pathname doesn't have a parent directory. */
2217                 file->parentdir.length = len;
2218                 archive_string_copy(&(file->basename), &(file->parentdir));
2219                 archive_string_empty(&(file->parentdir));
2220                 *file->parentdir.s = '\0';
2221                 return (r);
2222         }
2223
2224         /* Make a basename from dirname and slash */
2225         *slash  = '\0';
2226         file->parentdir.length = slash - dirname;
2227         archive_strcpy(&(file->basename),  slash + 1);
2228         return (r);
2229 }
2230
2231 static int
2232 get_path_component(char *name, int n, const char *fn)
2233 {
2234         char *p;
2235         int l;
2236
2237         p = strchr(fn, '/');
2238         if (p == NULL) {
2239                 if ((l = strlen(fn)) == 0)
2240                         return (0);
2241         } else
2242                 l = p - fn;
2243         if (l > n -1)
2244                 return (-1);
2245         memcpy(name, fn, l);
2246         name[l] = '\0';
2247
2248         return (l);
2249 }
2250
2251 /*
2252  * Add a new entry into the tree.
2253  */
2254 static int
2255 file_tree(struct archive_write *a, struct file **filepp)
2256 {
2257 #if defined(_WIN32) && !defined(__CYGWIN__)
2258         char name[_MAX_FNAME];/* Included null terminator size. */
2259 #elif defined(NAME_MAX) && NAME_MAX >= 255
2260         char name[NAME_MAX+1];
2261 #else
2262         char name[256];
2263 #endif
2264         struct xar *xar = (struct xar *)a->format_data;
2265         struct file *dent, *file, *np;
2266         struct archive_entry *ent;
2267         const char *fn, *p;
2268         int l;
2269
2270         file = *filepp;
2271         dent = xar->root;
2272         if (file->parentdir.length > 0)
2273                 fn = p = file->parentdir.s;
2274         else
2275                 fn = p = "";
2276
2277         /*
2278          * If the path of the parent directory of `file' entry is
2279          * the same as the path of `cur_dirent', add isoent to
2280          * `cur_dirent'.
2281          */
2282         if (archive_strlen(&(xar->cur_dirstr))
2283               == archive_strlen(&(file->parentdir)) &&
2284             strcmp(xar->cur_dirstr.s, fn) == 0) {
2285                 if (!file_add_child_tail(xar->cur_dirent, file)) {
2286                         np = (struct file *)__archive_rb_tree_find_node(
2287                             &(xar->cur_dirent->rbtree),
2288                             file->basename.s);
2289                         goto same_entry;
2290                 }
2291                 return (ARCHIVE_OK);
2292         }
2293
2294         for (;;) {
2295                 l = get_path_component(name, sizeof(name), fn);
2296                 if (l == 0) {
2297                         np = NULL;
2298                         break;
2299                 }
2300                 if (l < 0) {
2301                         archive_set_error(&a->archive,
2302                             ARCHIVE_ERRNO_MISC,
2303                             "A name buffer is too small");
2304                         file_free(file);
2305                         *filepp = NULL;
2306                         return (ARCHIVE_FATAL);
2307                 }
2308
2309                 np = file_find_child(dent, name);
2310                 if (np == NULL || fn[0] == '\0')
2311                         break;
2312
2313                 /* Find next subdirectory. */
2314                 if (!np->dir) {
2315                         /* NOT Directory! */
2316                         archive_set_error(&a->archive,
2317                             ARCHIVE_ERRNO_MISC,
2318                             "`%s' is not directory, we cannot insert `%s' ",
2319                             archive_entry_pathname(np->entry),
2320                             archive_entry_pathname(file->entry));
2321                         file_free(file);
2322                         *filepp = NULL;
2323                         return (ARCHIVE_FAILED);
2324                 }
2325                 fn += l;
2326                 if (fn[0] == '/')
2327                         fn++;
2328                 dent = np;
2329         }
2330         if (np == NULL) {
2331                 /*
2332                  * Create virtual parent directories.
2333                  */
2334                 while (fn[0] != '\0') {
2335                         struct file *vp;
2336                         struct archive_string as;
2337
2338                         archive_string_init(&as);
2339                         archive_strncat(&as, p, fn - p + l);
2340                         if (as.s[as.length-1] == '/') {
2341                                 as.s[as.length-1] = '\0';
2342                                 as.length--;
2343                         }
2344                         vp = file_create_virtual_dir(a, xar, as.s);
2345                         if (vp == NULL) {
2346                                 archive_string_free(&as);
2347                                 archive_set_error(&a->archive, ENOMEM,
2348                                     "Can't allocate memory");
2349                                 file_free(file);
2350                                 *filepp = NULL;
2351                                 return (ARCHIVE_FATAL);
2352                         }
2353                         archive_string_free(&as);
2354                         if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
2355                                 return (ARCHIVE_FATAL);
2356                         file_add_child_tail(dent, vp);
2357                         file_register(xar, vp);
2358                         np = vp;
2359
2360                         fn += l;
2361                         if (fn[0] == '/')
2362                                 fn++;
2363                         l = get_path_component(name, sizeof(name), fn);
2364                         if (l < 0) {
2365                                 archive_string_free(&as);
2366                                 archive_set_error(&a->archive,
2367                                     ARCHIVE_ERRNO_MISC,
2368                                     "A name buffer is too small");
2369                                 file_free(file);
2370                                 *filepp = NULL;
2371                                 return (ARCHIVE_FATAL);
2372                         }
2373                         dent = np;
2374                 }
2375
2376                 /* Found out the parent directory where isoent can be
2377                  * inserted. */
2378                 xar->cur_dirent = dent;
2379                 archive_string_empty(&(xar->cur_dirstr));
2380                 archive_string_ensure(&(xar->cur_dirstr),
2381                     archive_strlen(&(dent->parentdir)) +
2382                     archive_strlen(&(dent->basename)) + 2);
2383                 if (archive_strlen(&(dent->parentdir)) +
2384                     archive_strlen(&(dent->basename)) == 0)
2385                         xar->cur_dirstr.s[0] = 0;
2386                 else {
2387                         if (archive_strlen(&(dent->parentdir)) > 0) {
2388                                 archive_string_copy(&(xar->cur_dirstr),
2389                                     &(dent->parentdir));
2390                                 archive_strappend_char(&(xar->cur_dirstr), '/');
2391                         }
2392                         archive_string_concat(&(xar->cur_dirstr),
2393                             &(dent->basename));
2394                 }
2395
2396                 if (!file_add_child_tail(dent, file)) {
2397                         np = (struct file *)__archive_rb_tree_find_node(
2398                             &(dent->rbtree), file->basename.s);
2399                         goto same_entry;
2400                 }
2401                 return (ARCHIVE_OK);
2402         }
2403
2404 same_entry:
2405         /*
2406          * We have already has the entry the filename of which is
2407          * the same.
2408          */
2409         if (archive_entry_filetype(np->entry) !=
2410             archive_entry_filetype(file->entry)) {
2411                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2412                     "Found duplicate entries `%s' and its file type is "
2413                     "different",
2414                     archive_entry_pathname(np->entry));
2415                 file_free(file);
2416                 *filepp = NULL;
2417                 return (ARCHIVE_FAILED);
2418         }
2419
2420         /* Swap files. */
2421         ent = np->entry;
2422         np->entry = file->entry;
2423         file->entry = ent;
2424         np->virtual = 0;
2425
2426         file_free(file);
2427         *filepp = np;
2428         return (ARCHIVE_OK);
2429 }
2430
2431 static void
2432 file_register(struct xar *xar, struct file *file)
2433 {
2434         file->id = xar->file_idx++;
2435         file->next = NULL;
2436         *xar->file_list.last = file;
2437         xar->file_list.last = &(file->next);
2438 }
2439
2440 static void
2441 file_init_register(struct xar *xar)
2442 {
2443         xar->file_list.first = NULL;
2444         xar->file_list.last = &(xar->file_list.first);
2445 }
2446
2447 static void
2448 file_free_register(struct xar *xar)
2449 {
2450         struct file *file, *file_next;
2451
2452         file = xar->file_list.first;
2453         while (file != NULL) {
2454                 file_next = file->next;
2455                 file_free(file);
2456                 file = file_next;
2457         }
2458 }
2459
2460 /*
2461  * Register entry to get a hardlink target.
2462  */
2463 static int
2464 file_register_hardlink(struct archive_write *a, struct file *file)
2465 {
2466         struct xar *xar = (struct xar *)a->format_data;
2467         struct hardlink *hl;
2468         const char *pathname;
2469
2470         archive_entry_set_nlink(file->entry, 1);
2471         pathname = archive_entry_hardlink(file->entry);
2472         if (pathname == NULL) {
2473                 /* This `file` is a hardlink target. */
2474                 hl = malloc(sizeof(*hl));
2475                 if (hl == NULL) {
2476                         archive_set_error(&a->archive, ENOMEM,
2477                             "Can't allocate memory");
2478                         return (ARCHIVE_FATAL);
2479                 }
2480                 hl->nlink = 1;
2481                 /* A hardlink target must be the first position. */
2482                 file->hlnext = NULL;
2483                 hl->file_list.first = file;
2484                 hl->file_list.last = &(file->hlnext);
2485                 __archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
2486                     (struct archive_rb_node *)hl);
2487         } else {
2488                 hl = (struct hardlink *)__archive_rb_tree_find_node(
2489                     &(xar->hardlink_rbtree), pathname);
2490                 if (hl != NULL) {
2491                         /* Insert `file` entry into the tail. */
2492                         file->hlnext = NULL;
2493                         *hl->file_list.last = file;
2494                         hl->file_list.last = &(file->hlnext);
2495                         hl->nlink++;
2496                 }
2497                 archive_entry_unset_size(file->entry);
2498         }
2499
2500         return (ARCHIVE_OK);
2501 }
2502
2503 /*
2504  * Hardlinked files have to have the same location of extent.
2505  * We have to find out hardlink target entries for entries which
2506  * have a hardlink target name.
2507  */
2508 static void
2509 file_connect_hardlink_files(struct xar *xar)
2510 {
2511         struct archive_rb_node *n;
2512         struct hardlink *hl;
2513         struct file *target, *nf;
2514
2515         ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
2516                 hl = (struct hardlink *)n;
2517
2518                 /* The first entry must be a hardlink target. */
2519                 target = hl->file_list.first;
2520                 archive_entry_set_nlink(target->entry, hl->nlink);
2521                 if (hl->nlink > 1)
2522                         /* It means this file is a hardlink
2523                          * target itself. */
2524                         target->hardlink_target = target;
2525                 for (nf = target->hlnext;
2526                     nf != NULL; nf = nf->hlnext) {
2527                         nf->hardlink_target = target;
2528                         archive_entry_set_nlink(nf->entry, hl->nlink);
2529                 }
2530         }
2531 }
2532
2533 static int
2534 file_hd_cmp_node(const struct archive_rb_node *n1,
2535     const struct archive_rb_node *n2)
2536 {
2537         const struct hardlink *h1 = (const struct hardlink *)n1;
2538         const struct hardlink *h2 = (const struct hardlink *)n2;
2539
2540         return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
2541                        archive_entry_pathname(h2->file_list.first->entry)));
2542 }
2543
2544 static int
2545 file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
2546 {
2547         const struct hardlink *h = (const struct hardlink *)n;
2548
2549         return (strcmp(archive_entry_pathname(h->file_list.first->entry),
2550                        (const char *)key));
2551 }
2552
2553
2554 static void
2555 file_init_hardlinks(struct xar *xar)
2556 {
2557         static const struct archive_rb_tree_ops rb_ops = {
2558                 file_hd_cmp_node, file_hd_cmp_key,
2559         };
2560
2561         __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
2562 }
2563
2564 static void
2565 file_free_hardlinks(struct xar *xar)
2566 {
2567         struct archive_rb_node *n, *tmp;
2568
2569         ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
2570                 __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
2571                 free(n);
2572         }
2573 }
2574
2575 static void
2576 checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
2577 {
2578         sumwrk->alg = sum_alg;
2579         switch (sum_alg) {
2580         case CKSUM_NONE:
2581                 break;
2582         case CKSUM_SHA1:
2583                 archive_sha1_init(&(sumwrk->sha1ctx));
2584                 break;
2585         case CKSUM_MD5:
2586                 archive_md5_init(&(sumwrk->md5ctx));
2587                 break;
2588         }
2589 }
2590
2591 static void
2592 checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
2593 {
2594
2595         switch (sumwrk->alg) {
2596         case CKSUM_NONE:
2597                 break;
2598         case CKSUM_SHA1:
2599                 archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
2600                 break;
2601         case CKSUM_MD5:
2602                 archive_md5_update(&(sumwrk->md5ctx), buff, size);
2603                 break;
2604         }
2605 }
2606
2607 static void
2608 checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
2609 {
2610
2611         switch (sumwrk->alg) {
2612         case CKSUM_NONE:
2613                 sumval->len = 0;
2614                 break;
2615         case CKSUM_SHA1:
2616                 archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
2617                 sumval->len = SHA1_SIZE;
2618                 break;
2619         case CKSUM_MD5:
2620                 archive_md5_final(&(sumwrk->md5ctx), sumval->val);
2621                 sumval->len = MD5_SIZE;
2622                 break;
2623         }
2624         sumval->alg = sumwrk->alg;
2625 }
2626
2627 #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
2628 static int
2629 compression_unsupported_encoder(struct archive *a,
2630     struct la_zstream *lastrm, const char *name)
2631 {
2632
2633         archive_set_error(a, ARCHIVE_ERRNO_MISC,
2634             "%s compression not supported on this platform", name);
2635         lastrm->valid = 0;
2636         lastrm->real_stream = NULL;
2637         return (ARCHIVE_FAILED);
2638 }
2639 #endif
2640
2641 static int
2642 compression_init_encoder_gzip(struct archive *a,
2643     struct la_zstream *lastrm, int level, int withheader)
2644 {
2645         z_stream *strm;
2646
2647         if (lastrm->valid)
2648                 compression_end(a, lastrm);
2649         strm = calloc(1, sizeof(*strm));
2650         if (strm == NULL) {
2651                 archive_set_error(a, ENOMEM,
2652                     "Can't allocate memory for gzip stream");
2653                 return (ARCHIVE_FATAL);
2654         }
2655         /* zlib.h is not const-correct, so we need this one bit
2656          * of ugly hackery to convert a const * pointer to
2657          * a non-const pointer. */
2658         strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2659         strm->avail_in = lastrm->avail_in;
2660         strm->total_in = (uLong)lastrm->total_in;
2661         strm->next_out = lastrm->next_out;
2662         strm->avail_out = lastrm->avail_out;
2663         strm->total_out = (uLong)lastrm->total_out;
2664         if (deflateInit2(strm, level, Z_DEFLATED,
2665             (withheader)?15:-15,
2666             8, Z_DEFAULT_STRATEGY) != Z_OK) {
2667                 free(strm);
2668                 lastrm->real_stream = NULL;
2669                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2670                     "Internal error initializing compression library");
2671                 return (ARCHIVE_FATAL);
2672         }
2673         lastrm->real_stream = strm;
2674         lastrm->valid = 1;
2675         lastrm->code = compression_code_gzip;
2676         lastrm->end = compression_end_gzip;
2677         return (ARCHIVE_OK);
2678 }
2679
2680 static int
2681 compression_code_gzip(struct archive *a,
2682     struct la_zstream *lastrm, enum la_zaction action)
2683 {
2684         z_stream *strm;
2685         int r;
2686
2687         strm = (z_stream *)lastrm->real_stream;
2688         /* zlib.h is not const-correct, so we need this one bit
2689          * of ugly hackery to convert a const * pointer to
2690          * a non-const pointer. */
2691         strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2692         strm->avail_in = lastrm->avail_in;
2693         strm->total_in = (uLong)lastrm->total_in;
2694         strm->next_out = lastrm->next_out;
2695         strm->avail_out = lastrm->avail_out;
2696         strm->total_out = (uLong)lastrm->total_out;
2697         r = deflate(strm,
2698             (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
2699         lastrm->next_in = strm->next_in;
2700         lastrm->avail_in = strm->avail_in;
2701         lastrm->total_in = strm->total_in;
2702         lastrm->next_out = strm->next_out;
2703         lastrm->avail_out = strm->avail_out;
2704         lastrm->total_out = strm->total_out;
2705         switch (r) {
2706         case Z_OK:
2707                 return (ARCHIVE_OK);
2708         case Z_STREAM_END:
2709                 return (ARCHIVE_EOF);
2710         default:
2711                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2712                     "GZip compression failed:"
2713                     " deflate() call returned status %d", r);
2714                 return (ARCHIVE_FATAL);
2715         }
2716 }
2717
2718 static int
2719 compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
2720 {
2721         z_stream *strm;
2722         int r;
2723
2724         strm = (z_stream *)lastrm->real_stream;
2725         r = deflateEnd(strm);
2726         free(strm);
2727         lastrm->real_stream = NULL;
2728         lastrm->valid = 0;
2729         if (r != Z_OK) {
2730                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2731                     "Failed to clean up compressor");
2732                 return (ARCHIVE_FATAL);
2733         }
2734         return (ARCHIVE_OK);
2735 }
2736
2737 #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
2738 static int
2739 compression_init_encoder_bzip2(struct archive *a,
2740     struct la_zstream *lastrm, int level)
2741 {
2742         bz_stream *strm;
2743
2744         if (lastrm->valid)
2745                 compression_end(a, lastrm);
2746         strm = calloc(1, sizeof(*strm));
2747         if (strm == NULL) {
2748                 archive_set_error(a, ENOMEM,
2749                     "Can't allocate memory for bzip2 stream");
2750                 return (ARCHIVE_FATAL);
2751         }
2752         /* bzlib.h is not const-correct, so we need this one bit
2753          * of ugly hackery to convert a const * pointer to
2754          * a non-const pointer. */
2755         strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2756         strm->avail_in = lastrm->avail_in;
2757         strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2758         strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2759         strm->next_out = (char *)lastrm->next_out;
2760         strm->avail_out = lastrm->avail_out;
2761         strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2762         strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2763         if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
2764                 free(strm);
2765                 lastrm->real_stream = NULL;
2766                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2767                     "Internal error initializing compression library");
2768                 return (ARCHIVE_FATAL);
2769         }
2770         lastrm->real_stream = strm;
2771         lastrm->valid = 1;
2772         lastrm->code = compression_code_bzip2;
2773         lastrm->end = compression_end_bzip2;
2774         return (ARCHIVE_OK);
2775 }
2776
2777 static int
2778 compression_code_bzip2(struct archive *a,
2779     struct la_zstream *lastrm, enum la_zaction action)
2780 {
2781         bz_stream *strm;
2782         int r;
2783
2784         strm = (bz_stream *)lastrm->real_stream;
2785         /* bzlib.h is not const-correct, so we need this one bit
2786          * of ugly hackery to convert a const * pointer to
2787          * a non-const pointer. */
2788         strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2789         strm->avail_in = lastrm->avail_in;
2790         strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2791         strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2792         strm->next_out = (char *)lastrm->next_out;
2793         strm->avail_out = lastrm->avail_out;
2794         strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2795         strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2796         r = BZ2_bzCompress(strm,
2797             (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
2798         lastrm->next_in = (const unsigned char *)strm->next_in;
2799         lastrm->avail_in = strm->avail_in;
2800         lastrm->total_in =
2801             (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
2802             + (uint64_t)(uint32_t)strm->total_in_lo32;
2803         lastrm->next_out = (unsigned char *)strm->next_out;
2804         lastrm->avail_out = strm->avail_out;
2805         lastrm->total_out =
2806             (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
2807             + (uint64_t)(uint32_t)strm->total_out_lo32;
2808         switch (r) {
2809         case BZ_RUN_OK:     /* Non-finishing */
2810         case BZ_FINISH_OK:  /* Finishing: There's more work to do */
2811                 return (ARCHIVE_OK);
2812         case BZ_STREAM_END: /* Finishing: all done */
2813                 /* Only occurs in finishing case */
2814                 return (ARCHIVE_EOF);
2815         default:
2816                 /* Any other return value indicates an error */
2817                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2818                     "Bzip2 compression failed:"
2819                     " BZ2_bzCompress() call returned status %d", r);
2820                 return (ARCHIVE_FATAL);
2821         }
2822 }
2823
2824 static int
2825 compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
2826 {
2827         bz_stream *strm;
2828         int r;
2829
2830         strm = (bz_stream *)lastrm->real_stream;
2831         r = BZ2_bzCompressEnd(strm);
2832         free(strm);
2833         lastrm->real_stream = NULL;
2834         lastrm->valid = 0;
2835         if (r != BZ_OK) {
2836                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2837                     "Failed to clean up compressor");
2838                 return (ARCHIVE_FATAL);
2839         }
2840         return (ARCHIVE_OK);
2841 }
2842
2843 #else
2844 static int
2845 compression_init_encoder_bzip2(struct archive *a,
2846     struct la_zstream *lastrm, int level)
2847 {
2848
2849         (void) level; /* UNUSED */
2850         if (lastrm->valid)
2851                 compression_end(a, lastrm);
2852         return (compression_unsupported_encoder(a, lastrm, "bzip2"));
2853 }
2854 #endif
2855
2856 #if defined(HAVE_LZMA_H)
2857 static int
2858 compression_init_encoder_lzma(struct archive *a,
2859     struct la_zstream *lastrm, int level)
2860 {
2861         static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2862         lzma_stream *strm;
2863         lzma_options_lzma lzma_opt;
2864         int r;
2865
2866         if (lastrm->valid)
2867                 compression_end(a, lastrm);
2868         if (lzma_lzma_preset(&lzma_opt, level)) {
2869                 lastrm->real_stream = NULL;
2870                 archive_set_error(a, ENOMEM,
2871                     "Internal error initializing compression library");
2872                 return (ARCHIVE_FATAL);
2873         }
2874         strm = calloc(1, sizeof(*strm));
2875         if (strm == NULL) {
2876                 archive_set_error(a, ENOMEM,
2877                     "Can't allocate memory for lzma stream");
2878                 return (ARCHIVE_FATAL);
2879         }
2880         *strm = lzma_init_data;
2881         r = lzma_alone_encoder(strm, &lzma_opt);
2882         switch (r) {
2883         case LZMA_OK:
2884                 lastrm->real_stream = strm;
2885                 lastrm->valid = 1;
2886                 lastrm->code = compression_code_lzma;
2887                 lastrm->end = compression_end_lzma;
2888                 r = ARCHIVE_OK;
2889                 break;
2890         case LZMA_MEM_ERROR:
2891                 free(strm);
2892                 lastrm->real_stream = NULL;
2893                 archive_set_error(a, ENOMEM,
2894                     "Internal error initializing compression library: "
2895                     "Cannot allocate memory");
2896                 r =  ARCHIVE_FATAL;
2897                 break;
2898         default:
2899                 free(strm);
2900                 lastrm->real_stream = NULL;
2901                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2902                     "Internal error initializing compression library: "
2903                     "It's a bug in liblzma");
2904                 r =  ARCHIVE_FATAL;
2905                 break;
2906         }
2907         return (r);
2908 }
2909
2910 static int
2911 compression_init_encoder_xz(struct archive *a,
2912     struct la_zstream *lastrm, int level, int threads)
2913 {
2914         static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2915         lzma_stream *strm;
2916         lzma_filter *lzmafilters;
2917         lzma_options_lzma lzma_opt;
2918         int r;
2919 #ifdef HAVE_LZMA_STREAM_ENCODER_MT
2920         lzma_mt mt_options;
2921 #endif
2922
2923         (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */
2924
2925         if (lastrm->valid)
2926                 compression_end(a, lastrm);
2927         strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
2928         if (strm == NULL) {
2929                 archive_set_error(a, ENOMEM,
2930                     "Can't allocate memory for xz stream");
2931                 return (ARCHIVE_FATAL);
2932         }
2933         lzmafilters = (lzma_filter *)(strm+1);
2934         if (level > 9)
2935                 level = 9;
2936         if (lzma_lzma_preset(&lzma_opt, level)) {
2937                 free(strm);
2938                 lastrm->real_stream = NULL;
2939                 archive_set_error(a, ENOMEM,
2940                     "Internal error initializing compression library");
2941                 return (ARCHIVE_FATAL);
2942         }
2943         lzmafilters[0].id = LZMA_FILTER_LZMA2;
2944         lzmafilters[0].options = &lzma_opt;
2945         lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
2946
2947         *strm = lzma_init_data;
2948 #ifdef HAVE_LZMA_STREAM_ENCODER_MT
2949         if (threads > 1) {
2950                 memset(&mt_options, 0, sizeof(mt_options));
2951                 mt_options.threads = threads;
2952                 mt_options.timeout = 300;
2953                 mt_options.filters = lzmafilters;
2954                 mt_options.check = LZMA_CHECK_CRC64;
2955                 r = lzma_stream_encoder_mt(strm, &mt_options);
2956         } else
2957 #endif
2958                 r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
2959         switch (r) {
2960         case LZMA_OK:
2961                 lastrm->real_stream = strm;
2962                 lastrm->valid = 1;
2963                 lastrm->code = compression_code_lzma;
2964                 lastrm->end = compression_end_lzma;
2965                 r = ARCHIVE_OK;
2966                 break;
2967         case LZMA_MEM_ERROR:
2968                 free(strm);
2969                 lastrm->real_stream = NULL;
2970                 archive_set_error(a, ENOMEM,
2971                     "Internal error initializing compression library: "
2972                     "Cannot allocate memory");
2973                 r =  ARCHIVE_FATAL;
2974                 break;
2975         default:
2976                 free(strm);
2977                 lastrm->real_stream = NULL;
2978                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
2979                     "Internal error initializing compression library: "
2980                     "It's a bug in liblzma");
2981                 r =  ARCHIVE_FATAL;
2982                 break;
2983         }
2984         return (r);
2985 }
2986
2987 static int
2988 compression_code_lzma(struct archive *a,
2989     struct la_zstream *lastrm, enum la_zaction action)
2990 {
2991         lzma_stream *strm;
2992         int r;
2993
2994         strm = (lzma_stream *)lastrm->real_stream;
2995         strm->next_in = lastrm->next_in;
2996         strm->avail_in = lastrm->avail_in;
2997         strm->total_in = lastrm->total_in;
2998         strm->next_out = lastrm->next_out;
2999         strm->avail_out = lastrm->avail_out;
3000         strm->total_out = lastrm->total_out;
3001         r = lzma_code(strm,
3002             (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
3003         lastrm->next_in = strm->next_in;
3004         lastrm->avail_in = strm->avail_in;
3005         lastrm->total_in = strm->total_in;
3006         lastrm->next_out = strm->next_out;
3007         lastrm->avail_out = strm->avail_out;
3008         lastrm->total_out = strm->total_out;
3009         switch (r) {
3010         case LZMA_OK:
3011                 /* Non-finishing case */
3012                 return (ARCHIVE_OK);
3013         case LZMA_STREAM_END:
3014                 /* This return can only occur in finishing case. */
3015                 return (ARCHIVE_EOF);
3016         case LZMA_MEMLIMIT_ERROR:
3017                 archive_set_error(a, ENOMEM,
3018                     "lzma compression error:"
3019                     " %ju MiB would have been needed",
3020                     (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
3021                         / (1024 * 1024)));
3022                 return (ARCHIVE_FATAL);
3023         default:
3024                 /* Any other return value indicates an error */
3025                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
3026                     "lzma compression failed:"
3027                     " lzma_code() call returned status %d", r);
3028                 return (ARCHIVE_FATAL);
3029         }
3030 }
3031
3032 static int
3033 compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
3034 {
3035         lzma_stream *strm;
3036
3037         (void)a; /* UNUSED */
3038         strm = (lzma_stream *)lastrm->real_stream;
3039         lzma_end(strm);
3040         free(strm);
3041         lastrm->valid = 0;
3042         lastrm->real_stream = NULL;
3043         return (ARCHIVE_OK);
3044 }
3045 #else
3046 static int
3047 compression_init_encoder_lzma(struct archive *a,
3048     struct la_zstream *lastrm, int level)
3049 {
3050
3051         (void) level; /* UNUSED */
3052         if (lastrm->valid)
3053                 compression_end(a, lastrm);
3054         return (compression_unsupported_encoder(a, lastrm, "lzma"));
3055 }
3056 static int
3057 compression_init_encoder_xz(struct archive *a,
3058     struct la_zstream *lastrm, int level, int threads)
3059 {
3060
3061         (void) level; /* UNUSED */
3062         (void) threads; /* UNUSED */
3063         if (lastrm->valid)
3064                 compression_end(a, lastrm);
3065         return (compression_unsupported_encoder(a, lastrm, "xz"));
3066 }
3067 #endif
3068
3069 static int
3070 xar_compression_init_encoder(struct archive_write *a)
3071 {
3072         struct xar *xar;
3073         int r;
3074
3075         xar = (struct xar *)a->format_data;
3076         switch (xar->opt_compression) {
3077         case GZIP:
3078                 r = compression_init_encoder_gzip(
3079                     &(a->archive), &(xar->stream),
3080                     xar->opt_compression_level, 1);
3081                 break;
3082         case BZIP2:
3083                 r = compression_init_encoder_bzip2(
3084                     &(a->archive), &(xar->stream),
3085                     xar->opt_compression_level);
3086                 break;
3087         case LZMA:
3088                 r = compression_init_encoder_lzma(
3089                     &(a->archive), &(xar->stream),
3090                     xar->opt_compression_level);
3091                 break;
3092         case XZ:
3093                 r = compression_init_encoder_xz(
3094                     &(a->archive), &(xar->stream),
3095                     xar->opt_compression_level, xar->opt_threads);
3096                 break;
3097         default:
3098                 r = ARCHIVE_OK;
3099                 break;
3100         }
3101         if (r == ARCHIVE_OK) {
3102                 xar->stream.total_in = 0;
3103                 xar->stream.next_out = xar->wbuff;
3104                 xar->stream.avail_out = sizeof(xar->wbuff);
3105                 xar->stream.total_out = 0;
3106         }
3107
3108         return (r);
3109 }
3110
3111 static int
3112 compression_code(struct archive *a, struct la_zstream *lastrm,
3113     enum la_zaction action)
3114 {
3115         if (lastrm->valid)
3116                 return (lastrm->code(a, lastrm, action));
3117         return (ARCHIVE_OK);
3118 }
3119
3120 static int
3121 compression_end(struct archive *a, struct la_zstream *lastrm)
3122 {
3123         if (lastrm->valid)
3124                 return (lastrm->end(a, lastrm));
3125         return (ARCHIVE_OK);
3126 }
3127
3128
3129 static int
3130 save_xattrs(struct archive_write *a, struct file *file)
3131 {
3132         struct xar *xar;
3133         const char *name;
3134         const void *value;
3135         struct heap_data *heap;
3136         size_t size;
3137         int count, r;
3138
3139         xar = (struct xar *)a->format_data;
3140         count = archive_entry_xattr_reset(file->entry);
3141         if (count == 0)
3142                 return (ARCHIVE_OK);
3143         while (count--) {
3144                 archive_entry_xattr_next(file->entry,
3145                     &name, &value, &size);
3146                 checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
3147                 checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
3148
3149                 heap = calloc(1, sizeof(*heap));
3150                 if (heap == NULL) {
3151                         archive_set_error(&a->archive, ENOMEM,
3152                             "Can't allocate memory for xattr");
3153                         return (ARCHIVE_FATAL);
3154                 }
3155                 heap->id = file->ea_idx++;
3156                 heap->temp_offset = xar->temp_offset;
3157                 heap->size = size;/* save a extracted size */
3158                 heap->compression = xar->opt_compression;
3159                 /* Get a extracted sumcheck value. */
3160                 checksum_update(&(xar->e_sumwrk), value, size);
3161                 checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
3162
3163                 /*
3164                  * Not compression to xattr is simple way.
3165                  */
3166                 if (heap->compression == NONE) {
3167                         checksum_update(&(xar->a_sumwrk), value, size);
3168                         checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
3169                         if (write_to_temp(a, value, size)
3170                             != ARCHIVE_OK) {
3171                                 free(heap);
3172                                 return (ARCHIVE_FATAL);
3173                         }
3174                         heap->length = size;
3175                         /* Add heap to the tail of file->xattr. */
3176                         heap->next = NULL;
3177                         *file->xattr.last = heap;
3178                         file->xattr.last = &(heap->next);
3179                         /* Next xattr */
3180                         continue;
3181                 }
3182
3183                 /*
3184                  * Init compression library.
3185                  */
3186                 r = xar_compression_init_encoder(a);
3187                 if (r != ARCHIVE_OK) {
3188                         free(heap);
3189                         return (ARCHIVE_FATAL);
3190                 }
3191
3192                 xar->stream.next_in = (const unsigned char *)value;
3193                 xar->stream.avail_in = size;
3194                 for (;;) {
3195                         r = compression_code(&(a->archive),
3196                             &(xar->stream), ARCHIVE_Z_FINISH);
3197                         if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
3198                                 free(heap);
3199                                 return (ARCHIVE_FATAL);
3200                         }
3201                         size = sizeof(xar->wbuff) - xar->stream.avail_out;
3202                         checksum_update(&(xar->a_sumwrk),
3203                             xar->wbuff, size);
3204                         if (write_to_temp(a, xar->wbuff, size)
3205                             != ARCHIVE_OK)
3206                                 return (ARCHIVE_FATAL);
3207                         if (r == ARCHIVE_OK) {
3208                                 xar->stream.next_out = xar->wbuff;
3209                                 xar->stream.avail_out = sizeof(xar->wbuff);
3210                         } else {
3211                                 checksum_final(&(xar->a_sumwrk),
3212                                     &(heap->a_sum));
3213                                 heap->length = xar->stream.total_out;
3214                                 /* Add heap to the tail of file->xattr. */
3215                                 heap->next = NULL;
3216                                 *file->xattr.last = heap;
3217                                 file->xattr.last = &(heap->next);
3218                                 break;
3219                         }
3220                 }
3221                 /* Clean up compression library. */
3222                 r = compression_end(&(a->archive), &(xar->stream));
3223                 if (r != ARCHIVE_OK)
3224                         return (ARCHIVE_FATAL);
3225         }
3226         return (ARCHIVE_OK);
3227 }
3228
3229 static int
3230 getalgsize(enum sumalg sumalg)
3231 {
3232         switch (sumalg) {
3233         default:
3234         case CKSUM_NONE:
3235                 return (0);
3236         case CKSUM_SHA1:
3237                 return (SHA1_SIZE);
3238         case CKSUM_MD5:
3239                 return (MD5_SIZE);
3240         }
3241 }
3242
3243 static const char *
3244 getalgname(enum sumalg sumalg)
3245 {
3246         switch (sumalg) {
3247         default:
3248         case CKSUM_NONE:
3249                 return (NULL);
3250         case CKSUM_SHA1:
3251                 return (SHA1_NAME);
3252         case CKSUM_MD5:
3253                 return (MD5_NAME);
3254         }
3255 }
3256
3257 #endif /* Support xar format */