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