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