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