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