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