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