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