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