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