1/*-
2 * Copyright (c) 2008 Joerg Sonnenberger
3 * Copyright (c) 2009-2012 Michihiro NAKAJIMA
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "archive_platform.h"
28
29#ifdef HAVE_SYS_TYPES_H
30#include <sys/types.h>
31#endif
32#include <errno.h>
33#include <stdlib.h>
34#include <string.h>
35
36#include "archive.h"
37#include "archive_digest_private.h"
38#include "archive_entry.h"
39#include "archive_entry_private.h"
40#include "archive_private.h"
41#include "archive_rb.h"
42#include "archive_string.h"
43#include "archive_write_private.h"
44
45#define INDENTNAMELEN	15
46#define MAXLINELEN	80
47#define SET_KEYS	\
48	(F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
49
50struct attr_counter {
51	struct attr_counter *prev;
52	struct attr_counter *next;
53	struct mtree_entry *m_entry;
54	int count;
55};
56
57struct att_counter_set {
58	struct attr_counter *uid_list;
59	struct attr_counter *gid_list;
60	struct attr_counter *mode_list;
61	struct attr_counter *flags_list;
62};
63
64struct mtree_chain {
65	struct mtree_entry *first;
66	struct mtree_entry **last;
67};
68
69/*
70 * The Data only for a directory file.
71 */
72struct dir_info {
73	struct archive_rb_tree rbtree;
74	struct mtree_chain children;
75	struct mtree_entry *chnext;
76	int virtual;
77};
78
79/*
80 * The Data only for a regular file.
81 */
82struct reg_info {
83	int compute_sum;
84	uint32_t crc;
85	struct ae_digest digest;
86};
87
88struct mtree_entry {
89	struct archive_rb_node rbnode;
90	struct mtree_entry *next;
91	struct mtree_entry *parent;
92	struct dir_info *dir_info;
93	struct reg_info *reg_info;
94
95	struct archive_string parentdir;
96	struct archive_string basename;
97	struct archive_string pathname;
98	struct archive_string symlink;
99	struct archive_string uname;
100	struct archive_string gname;
101	struct archive_string fflags_text;
102	unsigned int nlink;
103	mode_t filetype;
104	mode_t mode;
105	int64_t size;
106	int64_t uid;
107	int64_t gid;
108	time_t mtime;
109	long mtime_nsec;
110	unsigned long fflags_set;
111	unsigned long fflags_clear;
112	dev_t rdevmajor;
113	dev_t rdevminor;
114	dev_t devmajor;
115	dev_t devminor;
116	int64_t ino;
117};
118
119struct mtree_writer {
120	struct mtree_entry *mtree_entry;
121	struct mtree_entry *root;
122	struct mtree_entry *cur_dirent;
123	struct archive_string cur_dirstr;
124	struct mtree_chain file_list;
125
126	struct archive_string ebuf;
127	struct archive_string buf;
128	int first;
129	uint64_t entry_bytes_remaining;
130
131	/*
132	 * Set global value.
133	 */
134	struct {
135		int		processing;
136		mode_t		type;
137		int		keys;
138		int64_t		uid;
139		int64_t		gid;
140		mode_t		mode;
141		unsigned long	fflags_set;
142		unsigned long	fflags_clear;
143	} set;
144	struct att_counter_set	acs;
145	int classic;
146	int depth;
147
148	/* check sum */
149	int compute_sum;
150	uint32_t crc;
151	uint64_t crc_len;
152#ifdef ARCHIVE_HAS_MD5
153	archive_md5_ctx md5ctx;
154#endif
155#ifdef ARCHIVE_HAS_RMD160
156	archive_rmd160_ctx rmd160ctx;
157#endif
158#ifdef ARCHIVE_HAS_SHA1
159	archive_sha1_ctx sha1ctx;
160#endif
161#ifdef ARCHIVE_HAS_SHA256
162	archive_sha256_ctx sha256ctx;
163#endif
164#ifdef ARCHIVE_HAS_SHA384
165	archive_sha384_ctx sha384ctx;
166#endif
167#ifdef ARCHIVE_HAS_SHA512
168	archive_sha512_ctx sha512ctx;
169#endif
170	/* Keyword options */
171	int keys;
172#define	F_CKSUM		0x00000001		/* checksum */
173#define	F_DEV		0x00000002		/* device type */
174#define	F_DONE		0x00000004		/* directory done */
175#define	F_FLAGS		0x00000008		/* file flags */
176#define	F_GID		0x00000010		/* gid */
177#define	F_GNAME		0x00000020		/* group name */
178#define	F_IGN		0x00000040		/* ignore */
179#define	F_MAGIC		0x00000080		/* name has magic chars */
180#define	F_MD5		0x00000100		/* MD5 digest */
181#define	F_MODE		0x00000200		/* mode */
182#define	F_NLINK		0x00000400		/* number of links */
183#define	F_NOCHANGE 	0x00000800		/* If owner/mode "wrong", do
184						 * not change */
185#define	F_OPT		0x00001000		/* existence optional */
186#define	F_RMD160 	0x00002000		/* RIPEMD160 digest */
187#define	F_SHA1		0x00004000		/* SHA-1 digest */
188#define	F_SIZE		0x00008000		/* size */
189#define	F_SLINK		0x00010000		/* symbolic link */
190#define	F_TAGS		0x00020000		/* tags */
191#define	F_TIME		0x00040000		/* modification time */
192#define	F_TYPE		0x00080000		/* file type */
193#define	F_UID		0x00100000		/* uid */
194#define	F_UNAME		0x00200000		/* user name */
195#define	F_VISIT		0x00400000		/* file visited */
196#define	F_SHA256	0x00800000		/* SHA-256 digest */
197#define	F_SHA384	0x01000000		/* SHA-384 digest */
198#define	F_SHA512	0x02000000		/* SHA-512 digest */
199#define	F_INO		0x04000000		/* inode number */
200#define	F_RESDEV	0x08000000		/* device ID on which the
201						 * entry resides */
202
203	/* Options */
204	int dironly;		/* If it is set, ignore all files except
205				 * directory files, like mtree(8) -d option. */
206	int indent;		/* If it is set, indent output data. */
207	int output_global_set;	/* If it is set, use /set keyword to set
208				 * global values. When generating mtree
209				 * classic format, it is set by default. */
210};
211
212#define DEFAULT_KEYS	(F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
213			 | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
214			 | F_UNAME)
215#define attr_counter_set_reset	attr_counter_set_free
216
217static void attr_counter_free(struct attr_counter **);
218static int attr_counter_inc(struct attr_counter **, struct attr_counter *,
219	struct attr_counter *, struct mtree_entry *);
220static struct attr_counter * attr_counter_new(struct mtree_entry *,
221	struct attr_counter *);
222static int attr_counter_set_collect(struct mtree_writer *,
223	struct mtree_entry *);
224static void attr_counter_set_free(struct mtree_writer *);
225static int get_global_set_keys(struct mtree_writer *, struct mtree_entry *);
226static int mtree_entry_add_child_tail(struct mtree_entry *,
227	struct mtree_entry *);
228static int mtree_entry_create_virtual_dir(struct archive_write *, const char *,
229	struct mtree_entry **);
230static int mtree_entry_cmp_node(const struct archive_rb_node *,
231	const struct archive_rb_node *);
232static int mtree_entry_cmp_key(const struct archive_rb_node *, const void *);
233static int mtree_entry_exchange_same_entry(struct archive_write *,
234    struct mtree_entry *, struct mtree_entry *);
235static void mtree_entry_free(struct mtree_entry *);
236static int mtree_entry_new(struct archive_write *, struct archive_entry *,
237	struct mtree_entry **);
238static void mtree_entry_register_free(struct mtree_writer *);
239static void mtree_entry_register_init(struct mtree_writer *);
240static int mtree_entry_setup_filenames(struct archive_write *,
241	struct mtree_entry *, struct archive_entry *);
242static int mtree_entry_tree_add(struct archive_write *, struct mtree_entry **);
243static void sum_init(struct mtree_writer *);
244static void sum_update(struct mtree_writer *, const void *, size_t);
245static void sum_final(struct mtree_writer *, struct reg_info *);
246static void sum_write(struct archive_string *, struct reg_info *);
247static int write_mtree_entry(struct archive_write *, struct mtree_entry *);
248static int write_dot_dot_entry(struct archive_write *, struct mtree_entry *);
249
250#define	COMPUTE_CRC(var, ch)	(var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
251static const uint32_t crctab[] = {
252	0x0,
253	0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
254	0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
255	0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
256	0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
257	0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
258	0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
259	0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
260	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
261	0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
262	0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
263	0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
264	0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
265	0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
266	0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
267	0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
268	0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
269	0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
270	0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
271	0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
272	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
273	0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
274	0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
275	0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
276	0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
277	0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
278	0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
279	0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
280	0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
281	0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
282	0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
283	0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
284	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
285	0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
286	0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
287	0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
288	0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
289	0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
290	0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
291	0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
292	0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
293	0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
294	0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
295	0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
296	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
297	0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
298	0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
299	0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
300	0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
301	0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
302	0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
303	0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
304};
305
306static const unsigned char safe_char[256] = {
307	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
308	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
309	/* !"$%&'()*+,-./  EXCLUSION:0x20( ) 0x23(#) */
310	0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
311	/* 0123456789:;<>?  EXCLUSION:0x3d(=) */
312	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
313	/* @ABCDEFGHIJKLMNO */
314	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
315	/* PQRSTUVWXYZ[]^_ EXCLUSION:0x5c(\)  */
316	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 50 - 5F */
317	/* `abcdefghijklmno */
318	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
319	/* pqrstuvwxyz{|}~ */
320	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
321	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
322	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
323	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
324	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
325	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
326	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
327	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
328	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
329};
330
331static void
332mtree_quote(struct archive_string *s, const char *str)
333{
334	const char *start;
335	char buf[4];
336	unsigned char c;
337
338	for (start = str; *str != '\0'; ++str) {
339		if (safe_char[*(const unsigned char *)str])
340			continue;
341		if (start != str)
342			archive_strncat(s, start, str - start);
343		c = (unsigned char)*str;
344		buf[0] = '\\';
345		buf[1] = (c / 64) + '0';
346		buf[2] = (c / 8 % 8) + '0';
347		buf[3] = (c % 8) + '0';
348		archive_strncat(s, buf, 4);
349		start = str + 1;
350	}
351
352	if (start != str)
353		archive_strncat(s, start, str - start);
354}
355
356/*
357 * Indent a line as the mtree utility does so it is readable for people.
358 */
359static void
360mtree_indent(struct mtree_writer *mtree)
361{
362	int i, fn, nd, pd;
363	const char *r, *s, *x;
364
365	if (mtree->classic) {
366		if (mtree->indent) {
367			nd = 0;
368			pd = mtree->depth * 4;
369		} else {
370			nd = mtree->depth?4:0;
371			pd = 0;
372		}
373	} else
374		nd = pd = 0;
375	fn = 1;
376	s = r = mtree->ebuf.s;
377	x = NULL;
378	while (*r == ' ')
379		r++;
380	while ((r = strchr(r, ' ')) != NULL) {
381		if (fn) {
382			fn = 0;
383			for (i = 0; i < nd + pd; i++)
384				archive_strappend_char(&mtree->buf, ' ');
385			archive_strncat(&mtree->buf, s, r - s);
386			if (nd + (r -s) > INDENTNAMELEN) {
387				archive_strncat(&mtree->buf, " \\\n", 3);
388				for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
389					archive_strappend_char(&mtree->buf, ' ');
390			} else {
391				for (i = (int)(r -s + nd);
392				    i < (INDENTNAMELEN + 1); i++)
393					archive_strappend_char(&mtree->buf, ' ');
394			}
395			s = ++r;
396			x = NULL;
397			continue;
398		}
399		if (pd + (r - s) <= MAXLINELEN - 3 - INDENTNAMELEN)
400			x = r++;
401		else {
402			if (x == NULL)
403				x = r;
404			archive_strncat(&mtree->buf, s, x - s);
405			archive_strncat(&mtree->buf, " \\\n", 3);
406			for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
407				archive_strappend_char(&mtree->buf, ' ');
408			s = r = ++x;
409			x = NULL;
410		}
411	}
412	if (fn) {
413		for (i = 0; i < nd + pd; i++)
414			archive_strappend_char(&mtree->buf, ' ');
415		archive_strcat(&mtree->buf, s);
416		s += strlen(s);
417	}
418	if (x != NULL && pd + strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
419		/* Last keyword is longer. */
420		archive_strncat(&mtree->buf, s, x - s);
421		archive_strncat(&mtree->buf, " \\\n", 3);
422		for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
423			archive_strappend_char(&mtree->buf, ' ');
424		s = ++x;
425	}
426	archive_strcat(&mtree->buf, s);
427	archive_string_empty(&mtree->ebuf);
428}
429
430/*
431 * Write /set keyword.
432 * Set the most used value of uid, gid, mode and fflags, which are
433 * collected by the attr_counter_set_collect() function.
434 */
435static void
436write_global(struct mtree_writer *mtree)
437{
438	struct archive_string setstr;
439	struct archive_string unsetstr;
440	struct att_counter_set *acs;
441	int keys, oldkeys, effkeys;
442
443	archive_string_init(&setstr);
444	archive_string_init(&unsetstr);
445	keys = mtree->keys & SET_KEYS;
446	oldkeys = mtree->set.keys;
447	effkeys = keys;
448	acs = &mtree->acs;
449	if (mtree->set.processing) {
450		/*
451		 * Check if the global data needs updating.
452		 */
453		effkeys &= ~F_TYPE;
454		if (acs->uid_list == NULL)
455			effkeys &= ~(F_UNAME | F_UID);
456		else if (oldkeys & (F_UNAME | F_UID)) {
457			if (acs->uid_list->count < 2 ||
458			    mtree->set.uid == acs->uid_list->m_entry->uid)
459				effkeys &= ~(F_UNAME | F_UID);
460		}
461		if (acs->gid_list == NULL)
462			effkeys &= ~(F_GNAME | F_GID);
463		else if (oldkeys & (F_GNAME | F_GID)) {
464			if (acs->gid_list->count < 2 ||
465			    mtree->set.gid == acs->gid_list->m_entry->gid)
466				effkeys &= ~(F_GNAME | F_GID);
467		}
468		if (acs->mode_list == NULL)
469			effkeys &= ~F_MODE;
470		else if (oldkeys & F_MODE) {
471			if (acs->mode_list->count < 2 ||
472			    mtree->set.mode == acs->mode_list->m_entry->mode)
473				effkeys &= ~F_MODE;
474		}
475		if (acs->flags_list == NULL)
476			effkeys &= ~F_FLAGS;
477		else if ((oldkeys & F_FLAGS) != 0) {
478			if (acs->flags_list->count < 2 ||
479			    (acs->flags_list->m_entry->fflags_set ==
480				mtree->set.fflags_set &&
481			     acs->flags_list->m_entry->fflags_clear ==
482				mtree->set.fflags_clear))
483				effkeys &= ~F_FLAGS;
484		}
485	} else {
486		if (acs->uid_list == NULL)
487			keys &= ~(F_UNAME | F_UID);
488		if (acs->gid_list == NULL)
489			keys &= ~(F_GNAME | F_GID);
490		if (acs->mode_list == NULL)
491			keys &= ~F_MODE;
492		if (acs->flags_list == NULL)
493			keys &= ~F_FLAGS;
494	}
495	if ((keys & effkeys & F_TYPE) != 0) {
496		if (mtree->dironly) {
497			archive_strcat(&setstr, " type=dir");
498			mtree->set.type = AE_IFDIR;
499		} else {
500			archive_strcat(&setstr, " type=file");
501			mtree->set.type = AE_IFREG;
502		}
503	}
504	if ((keys & effkeys & F_UNAME) != 0) {
505		if (archive_strlen(&(acs->uid_list->m_entry->uname)) > 0) {
506			archive_strcat(&setstr, " uname=");
507			mtree_quote(&setstr, acs->uid_list->m_entry->uname.s);
508		} else {
509			keys &= ~F_UNAME;
510			if ((oldkeys & F_UNAME) != 0)
511				archive_strcat(&unsetstr, " uname");
512		}
513	}
514	if ((keys & effkeys & F_UID) != 0) {
515		mtree->set.uid = acs->uid_list->m_entry->uid;
516		archive_string_sprintf(&setstr, " uid=%jd",
517		    (intmax_t)mtree->set.uid);
518	}
519	if ((keys & effkeys & F_GNAME) != 0) {
520		if (archive_strlen(&(acs->gid_list->m_entry->gname)) > 0) {
521			archive_strcat(&setstr, " gname=");
522			mtree_quote(&setstr, acs->gid_list->m_entry->gname.s);
523		} else {
524			keys &= ~F_GNAME;
525			if ((oldkeys & F_GNAME) != 0)
526				archive_strcat(&unsetstr, " gname");
527		}
528	}
529	if ((keys & effkeys & F_GID) != 0) {
530		mtree->set.gid = acs->gid_list->m_entry->gid;
531		archive_string_sprintf(&setstr, " gid=%jd",
532		    (intmax_t)mtree->set.gid);
533	}
534	if ((keys & effkeys & F_MODE) != 0) {
535		mtree->set.mode = acs->mode_list->m_entry->mode;
536		archive_string_sprintf(&setstr, " mode=%o",
537		    (unsigned int)mtree->set.mode);
538	}
539	if ((keys & effkeys & F_FLAGS) != 0) {
540		if (archive_strlen(
541		    &(acs->flags_list->m_entry->fflags_text)) > 0) {
542			archive_strcat(&setstr, " flags=");
543			mtree_quote(&setstr,
544			    acs->flags_list->m_entry->fflags_text.s);
545			mtree->set.fflags_set =
546			    acs->flags_list->m_entry->fflags_set;
547			mtree->set.fflags_clear =
548			    acs->flags_list->m_entry->fflags_clear;
549		} else {
550			keys &= ~F_FLAGS;
551			if ((oldkeys & F_FLAGS) != 0)
552				archive_strcat(&unsetstr, " flags");
553		}
554	}
555	if (unsetstr.length > 0)
556		archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
557	archive_string_free(&unsetstr);
558	if (setstr.length > 0)
559		archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
560	archive_string_free(&setstr);
561	mtree->set.keys = keys;
562	mtree->set.processing = 1;
563}
564
565static struct attr_counter *
566attr_counter_new(struct mtree_entry *me, struct attr_counter *prev)
567{
568	struct attr_counter *ac;
569
570	ac = malloc(sizeof(*ac));
571	if (ac != NULL) {
572		ac->prev = prev;
573		ac->next = NULL;
574		ac->count = 1;
575		ac->m_entry = me;
576	}
577	return (ac);
578}
579
580static void
581attr_counter_free(struct attr_counter **top)
582{
583	struct attr_counter *ac, *tac;
584
585	if (*top == NULL)
586		return;
587	ac = *top;
588        while (ac != NULL) {
589		tac = ac->next;
590		free(ac);
591		ac = tac;
592	}
593	*top = NULL;
594}
595
596static int
597attr_counter_inc(struct attr_counter **top, struct attr_counter *ac,
598    struct attr_counter *last, struct mtree_entry *me)
599{
600	struct attr_counter *pac;
601
602	if (ac != NULL) {
603		ac->count++;
604		if (*top == ac || ac->prev->count >= ac->count)
605			return (0);
606		for (pac = ac->prev; pac; pac = pac->prev) {
607			if (pac->count >= ac->count)
608				break;
609		}
610		ac->prev->next = ac->next;
611		if (ac->next != NULL)
612			ac->next->prev = ac->prev;
613		if (pac != NULL) {
614			ac->prev = pac;
615			ac->next = pac->next;
616			pac->next = ac;
617			if (ac->next != NULL)
618				ac->next->prev = ac;
619		} else {
620			ac->prev = NULL;
621			ac->next = *top;
622			*top = ac;
623			ac->next->prev = ac;
624		}
625	} else if (last != NULL) {
626		ac = attr_counter_new(me, last);
627		if (ac == NULL)
628			return (-1);
629		last->next = ac;
630	}
631	return (0);
632}
633
634/*
635 * Tabulate uid, gid, mode and fflags of a entry in order to be used for /set.
636 */
637static int
638attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
639{
640	struct attr_counter *ac, *last;
641	struct att_counter_set *acs = &mtree->acs;
642	int keys = mtree->keys;
643
644	if (keys & (F_UNAME | F_UID)) {
645		if (acs->uid_list == NULL) {
646			acs->uid_list = attr_counter_new(me, NULL);
647			if (acs->uid_list == NULL)
648				return (-1);
649		} else {
650			last = NULL;
651			for (ac = acs->uid_list; ac; ac = ac->next) {
652				if (ac->m_entry->uid == me->uid)
653					break;
654				last = ac;
655			}
656			if (attr_counter_inc(&acs->uid_list, ac, last, me) < 0)
657				return (-1);
658		}
659	}
660	if (keys & (F_GNAME | F_GID)) {
661		if (acs->gid_list == NULL) {
662			acs->gid_list = attr_counter_new(me, NULL);
663			if (acs->gid_list == NULL)
664				return (-1);
665		} else {
666			last = NULL;
667			for (ac = acs->gid_list; ac; ac = ac->next) {
668				if (ac->m_entry->gid == me->gid)
669					break;
670				last = ac;
671			}
672			if (attr_counter_inc(&acs->gid_list, ac, last, me) < 0)
673				return (-1);
674		}
675	}
676	if (keys & F_MODE) {
677		if (acs->mode_list == NULL) {
678			acs->mode_list = attr_counter_new(me, NULL);
679			if (acs->mode_list == NULL)
680				return (-1);
681		} else {
682			last = NULL;
683			for (ac = acs->mode_list; ac; ac = ac->next) {
684				if (ac->m_entry->mode == me->mode)
685					break;
686				last = ac;
687			}
688			if (attr_counter_inc(&acs->mode_list, ac, last, me) < 0)
689				return (-1);
690		}
691	}
692	if (keys & F_FLAGS) {
693		if (acs->flags_list == NULL) {
694			acs->flags_list = attr_counter_new(me, NULL);
695			if (acs->flags_list == NULL)
696				return (-1);
697		} else {
698			last = NULL;
699			for (ac = acs->flags_list; ac; ac = ac->next) {
700				if (ac->m_entry->fflags_set == me->fflags_set &&
701				    ac->m_entry->fflags_clear ==
702							me->fflags_clear)
703					break;
704				last = ac;
705			}
706			if (attr_counter_inc(&acs->flags_list, ac, last, me) < 0)
707				return (-1);
708		}
709	}
710
711	return (0);
712}
713
714static void
715attr_counter_set_free(struct mtree_writer *mtree)
716{
717	struct att_counter_set *acs = &mtree->acs;
718
719	attr_counter_free(&acs->uid_list);
720	attr_counter_free(&acs->gid_list);
721	attr_counter_free(&acs->mode_list);
722	attr_counter_free(&acs->flags_list);
723}
724
725static int
726get_global_set_keys(struct mtree_writer *mtree, struct mtree_entry *me)
727{
728	int keys;
729
730	keys = mtree->keys;
731
732	/*
733	 * If a keyword has been set by /set, we do not need to
734	 * output it.
735	 */
736	if (mtree->set.keys == 0)
737		return (keys);/* /set is not used. */
738
739	if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
740	     mtree->set.gid == me->gid)
741		keys &= ~(F_GNAME | F_GID);
742	if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
743	     mtree->set.uid == me->uid)
744		keys &= ~(F_UNAME | F_UID);
745	if (mtree->set.keys & F_FLAGS) {
746		if (mtree->set.fflags_set == me->fflags_set &&
747		    mtree->set.fflags_clear == me->fflags_clear)
748			keys &= ~F_FLAGS;
749	}
750	if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
751		keys &= ~F_MODE;
752
753	switch (me->filetype) {
754	case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
755	case AE_IFBLK: case AE_IFIFO:
756		break;
757	case AE_IFDIR:
758		if ((mtree->set.keys & F_TYPE) != 0 &&
759		    mtree->set.type == AE_IFDIR)
760			keys &= ~F_TYPE;
761		break;
762	case AE_IFREG:
763	default:	/* Handle unknown file types as regular files. */
764		if ((mtree->set.keys & F_TYPE) != 0 &&
765		    mtree->set.type == AE_IFREG)
766			keys &= ~F_TYPE;
767		break;
768	}
769
770	return (keys);
771}
772
773static int
774mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
775    struct mtree_entry **m_entry)
776{
777	struct mtree_entry *me;
778	const char *s;
779	int r;
780	static const struct archive_rb_tree_ops rb_ops = {
781		mtree_entry_cmp_node, mtree_entry_cmp_key
782	};
783
784	me = calloc(1, sizeof(*me));
785	if (me == NULL) {
786		archive_set_error(&a->archive, ENOMEM,
787		    "Can't allocate memory for a mtree entry");
788		*m_entry = NULL;
789		return (ARCHIVE_FATAL);
790	}
791
792	r = mtree_entry_setup_filenames(a, me, entry);
793	if (r < ARCHIVE_WARN) {
794		mtree_entry_free(me);
795		*m_entry = NULL;
796		return (r);
797	}
798
799	if ((s = archive_entry_symlink(entry)) != NULL)
800		archive_strcpy(&me->symlink, s);
801	me->nlink = archive_entry_nlink(entry);
802	me->filetype = archive_entry_filetype(entry);
803	me->mode = archive_entry_mode(entry) & 07777;
804	me->uid = archive_entry_uid(entry);
805	me->gid = archive_entry_gid(entry);
806	if ((s = archive_entry_uname(entry)) != NULL)
807		archive_strcpy(&me->uname, s);
808	if ((s = archive_entry_gname(entry)) != NULL)
809		archive_strcpy(&me->gname, s);
810	if ((s = archive_entry_fflags_text(entry)) != NULL)
811		archive_strcpy(&me->fflags_text, s);
812	archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
813	me->mtime = archive_entry_mtime(entry);
814	me->mtime_nsec = archive_entry_mtime_nsec(entry);
815	me->rdevmajor = archive_entry_rdevmajor(entry);
816	me->rdevminor = archive_entry_rdevminor(entry);
817	me->devmajor = archive_entry_devmajor(entry);
818	me->devminor = archive_entry_devminor(entry);
819	me->ino = archive_entry_ino(entry);
820	me->size = archive_entry_size(entry);
821	if (me->filetype == AE_IFDIR) {
822		me->dir_info = calloc(1, sizeof(*me->dir_info));
823		if (me->dir_info == NULL) {
824			mtree_entry_free(me);
825			archive_set_error(&a->archive, ENOMEM,
826			    "Can't allocate memory for a mtree entry");
827			*m_entry = NULL;
828			return (ARCHIVE_FATAL);
829		}
830		__archive_rb_tree_init(&me->dir_info->rbtree, &rb_ops);
831		me->dir_info->children.first = NULL;
832		me->dir_info->children.last = &(me->dir_info->children.first);
833		me->dir_info->chnext = NULL;
834	} else if (me->filetype == AE_IFREG) {
835		me->reg_info = calloc(1, sizeof(*me->reg_info));
836		if (me->reg_info == NULL) {
837			mtree_entry_free(me);
838			archive_set_error(&a->archive, ENOMEM,
839			    "Can't allocate memory for a mtree entry");
840			*m_entry = NULL;
841			return (ARCHIVE_FATAL);
842		}
843		me->reg_info->compute_sum = 0;
844	}
845
846	*m_entry = me;
847	return (ARCHIVE_OK);
848}
849
850static void
851mtree_entry_free(struct mtree_entry *me)
852{
853	archive_string_free(&me->parentdir);
854	archive_string_free(&me->basename);
855	archive_string_free(&me->pathname);
856	archive_string_free(&me->symlink);
857	archive_string_free(&me->uname);
858	archive_string_free(&me->gname);
859	archive_string_free(&me->fflags_text);
860	free(me->dir_info);
861	free(me->reg_info);
862	free(me);
863}
864
865static int
866archive_write_mtree_header(struct archive_write *a,
867    struct archive_entry *entry)
868{
869	struct mtree_writer *mtree= a->format_data;
870	struct mtree_entry *mtree_entry;
871	int r, r2;
872
873	if (mtree->first) {
874		mtree->first = 0;
875		archive_strcat(&mtree->buf, "#mtree\n");
876		if ((mtree->keys & SET_KEYS) == 0)
877			mtree->output_global_set = 0;/* Disabled. */
878	}
879
880	mtree->entry_bytes_remaining = archive_entry_size(entry);
881
882	/* While directory only mode, we do not handle non directory files. */
883	if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
884		return (ARCHIVE_OK);
885
886	r2 = mtree_entry_new(a, entry, &mtree_entry);
887	if (r2 < ARCHIVE_WARN)
888		return (r2);
889	r = mtree_entry_tree_add(a, &mtree_entry);
890	if (r < ARCHIVE_WARN) {
891		mtree_entry_free(mtree_entry);
892		return (r);
893	}
894	mtree->mtree_entry = mtree_entry;
895
896	/* If the current file is a regular file, we have to
897	 * compute the sum of its content.
898	 * Initialize a bunch of checksum context. */
899	if (mtree_entry->reg_info)
900		sum_init(mtree);
901
902	return (r2);
903}
904
905static int
906write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
907{
908	struct mtree_writer *mtree = a->format_data;
909	struct archive_string *str;
910	int keys, ret;
911
912	if (me->dir_info) {
913		if (mtree->classic) {
914			/*
915			 * Output a comment line to describe the full
916			 * pathname of the entry as mtree utility does
917			 * while generating classic format.
918			 */
919			if (!mtree->dironly)
920				archive_strappend_char(&mtree->buf, '\n');
921			if (me->parentdir.s)
922				archive_string_sprintf(&mtree->buf,
923				    "# %s/%s\n",
924				    me->parentdir.s, me->basename.s);
925			else
926				archive_string_sprintf(&mtree->buf,
927				    "# %s\n",
928				    me->basename.s);
929		}
930		if (mtree->output_global_set)
931			write_global(mtree);
932	}
933	archive_string_empty(&mtree->ebuf);
934	str = (mtree->indent || mtree->classic)? &mtree->ebuf : &mtree->buf;
935
936	if (!mtree->classic && me->parentdir.s) {
937		/*
938		 * If generating format is not classic one(v1), output
939		 * a full pathname.
940		 */
941		mtree_quote(str, me->parentdir.s);
942		archive_strappend_char(str, '/');
943	}
944	mtree_quote(str, me->basename.s);
945
946	keys = get_global_set_keys(mtree, me);
947	if ((keys & F_NLINK) != 0 &&
948	    me->nlink != 1 && me->filetype != AE_IFDIR)
949		archive_string_sprintf(str, " nlink=%u", me->nlink);
950
951	if ((keys & F_GNAME) != 0 && archive_strlen(&me->gname) > 0) {
952		archive_strcat(str, " gname=");
953		mtree_quote(str, me->gname.s);
954	}
955	if ((keys & F_UNAME) != 0 && archive_strlen(&me->uname) > 0) {
956		archive_strcat(str, " uname=");
957		mtree_quote(str, me->uname.s);
958	}
959	if ((keys & F_FLAGS) != 0) {
960		if (archive_strlen(&me->fflags_text) > 0) {
961			archive_strcat(str, " flags=");
962			mtree_quote(str, me->fflags_text.s);
963		} else if (mtree->set.processing &&
964		    (mtree->set.keys & F_FLAGS) != 0)
965			/* Overwrite the global parameter. */
966			archive_strcat(str, " flags=none");
967	}
968	if ((keys & F_TIME) != 0)
969		archive_string_sprintf(str, " time=%jd.%jd",
970		    (intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
971	if ((keys & F_MODE) != 0)
972		archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
973	if ((keys & F_GID) != 0)
974		archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
975	if ((keys & F_UID) != 0)
976		archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
977
978	if ((keys & F_INO) != 0)
979		archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
980	if ((keys & F_RESDEV) != 0) {
981		archive_string_sprintf(str,
982		    " resdevice=native,%ju,%ju",
983		    (uintmax_t)me->devmajor,
984		    (uintmax_t)me->devminor);
985	}
986
987	switch (me->filetype) {
988	case AE_IFLNK:
989		if ((keys & F_TYPE) != 0)
990			archive_strcat(str, " type=link");
991		if ((keys & F_SLINK) != 0) {
992			archive_strcat(str, " link=");
993			mtree_quote(str, me->symlink.s);
994		}
995		break;
996	case AE_IFSOCK:
997		if ((keys & F_TYPE) != 0)
998			archive_strcat(str, " type=socket");
999		break;
1000	case AE_IFCHR:
1001		if ((keys & F_TYPE) != 0)
1002			archive_strcat(str, " type=char");
1003		if ((keys & F_DEV) != 0) {
1004			archive_string_sprintf(str,
1005			    " device=native,%ju,%ju",
1006			    (uintmax_t)me->rdevmajor,
1007			    (uintmax_t)me->rdevminor);
1008		}
1009		break;
1010	case AE_IFBLK:
1011		if ((keys & F_TYPE) != 0)
1012			archive_strcat(str, " type=block");
1013		if ((keys & F_DEV) != 0) {
1014			archive_string_sprintf(str,
1015			    " device=native,%ju,%ju",
1016			    (uintmax_t)me->rdevmajor,
1017			    (uintmax_t)me->rdevminor);
1018		}
1019		break;
1020	case AE_IFDIR:
1021		if ((keys & F_TYPE) != 0)
1022			archive_strcat(str, " type=dir");
1023		break;
1024	case AE_IFIFO:
1025		if ((keys & F_TYPE) != 0)
1026			archive_strcat(str, " type=fifo");
1027		break;
1028	case AE_IFREG:
1029	default:	/* Handle unknown file types as regular files. */
1030		if ((keys & F_TYPE) != 0)
1031			archive_strcat(str, " type=file");
1032		if ((keys & F_SIZE) != 0)
1033			archive_string_sprintf(str, " size=%jd",
1034			    (intmax_t)me->size);
1035		break;
1036	}
1037
1038	/* Write a bunch of sum. */
1039	if (me->reg_info)
1040		sum_write(str, me->reg_info);
1041
1042	archive_strappend_char(str, '\n');
1043	if (mtree->indent || mtree->classic)
1044		mtree_indent(mtree);
1045
1046	if (mtree->buf.length > 32768) {
1047		ret = __archive_write_output(
1048			a, mtree->buf.s, mtree->buf.length);
1049		archive_string_empty(&mtree->buf);
1050	} else
1051		ret = ARCHIVE_OK;
1052	return (ret);
1053}
1054
1055static int
1056write_dot_dot_entry(struct archive_write *a, struct mtree_entry *n)
1057{
1058	struct mtree_writer *mtree = a->format_data;
1059	int ret;
1060
1061	if (n->parentdir.s) {
1062		if (mtree->indent) {
1063			int i, pd = mtree->depth * 4;
1064			for (i = 0; i < pd; i++)
1065				archive_strappend_char(&mtree->buf, ' ');
1066		}
1067		archive_string_sprintf(&mtree->buf, "# %s/%s\n",
1068			n->parentdir.s, n->basename.s);
1069	}
1070
1071	if (mtree->indent) {
1072		archive_string_empty(&mtree->ebuf);
1073		archive_strncat(&mtree->ebuf, "..\n\n", (mtree->dironly)?3:4);
1074		mtree_indent(mtree);
1075	} else
1076		archive_strncat(&mtree->buf, "..\n\n", (mtree->dironly)?3:4);
1077
1078	if (mtree->buf.length > 32768) {
1079		ret = __archive_write_output(
1080			a, mtree->buf.s, mtree->buf.length);
1081		archive_string_empty(&mtree->buf);
1082	} else
1083		ret = ARCHIVE_OK;
1084	return (ret);
1085}
1086
1087/*
1088 * Write mtree entries saved at attr_counter_set_collect() function.
1089 */
1090static int
1091write_mtree_entry_tree(struct archive_write *a)
1092{
1093	struct mtree_writer *mtree = a->format_data;
1094	struct mtree_entry *np = mtree->root;
1095	struct archive_rb_node *n;
1096	int ret;
1097
1098	do {
1099		if (mtree->output_global_set) {
1100			/*
1101			 * Collect attribute information to know which value
1102			 * is frequently used among the children.
1103			 */
1104			attr_counter_set_reset(mtree);
1105			ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
1106				struct mtree_entry *e = (struct mtree_entry *)n;
1107				if (attr_counter_set_collect(mtree, e) < 0) {
1108					archive_set_error(&a->archive, ENOMEM,
1109					    "Can't allocate memory");
1110					return (ARCHIVE_FATAL);
1111				}
1112			}
1113		}
1114		if (!np->dir_info->virtual || mtree->classic) {
1115			ret = write_mtree_entry(a, np);
1116			if (ret != ARCHIVE_OK)
1117				return (ARCHIVE_FATAL);
1118		} else {
1119			/* Whenever output_global_set is enabled
1120			 * output global value(/set keywords)
1121			 * even if the directory entry is not allowed
1122			 * to be written because the global values
1123			 * can be used for the children. */
1124			if (mtree->output_global_set)
1125				write_global(mtree);
1126		}
1127		/*
1128		 * Output the attribute of all files except directory files.
1129		 */
1130		mtree->depth++;
1131		ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
1132			struct mtree_entry *e = (struct mtree_entry *)n;
1133
1134			if (e->dir_info)
1135				mtree_entry_add_child_tail(np, e);
1136			else {
1137				ret = write_mtree_entry(a, e);
1138				if (ret != ARCHIVE_OK)
1139					return (ARCHIVE_FATAL);
1140			}
1141		}
1142		mtree->depth--;
1143
1144		if (np->dir_info->children.first != NULL) {
1145			/*
1146			 * Descend the tree.
1147			 */
1148			np = np->dir_info->children.first;
1149			if (mtree->indent)
1150				mtree->depth++;
1151			continue;
1152		} else if (mtree->classic) {
1153			/*
1154			 * While printing mtree classic, if there are not
1155			 * any directory files(except "." and "..") in the
1156			 * directory, output two dots ".." as returning
1157			 * the parent directory.
1158			 */
1159			ret = write_dot_dot_entry(a, np);
1160			if (ret != ARCHIVE_OK)
1161				return (ARCHIVE_FATAL);
1162		}
1163
1164		while (np != np->parent) {
1165			if (np->dir_info->chnext == NULL) {
1166				/*
1167				 * Ascend the tree; go back to the parent.
1168				 */
1169				if (mtree->indent)
1170					mtree->depth--;
1171				if (mtree->classic) {
1172					ret = write_dot_dot_entry(a,
1173						np->parent);
1174					if (ret != ARCHIVE_OK)
1175						return (ARCHIVE_FATAL);
1176				}
1177				np = np->parent;
1178			} else {
1179				/*
1180				 * Switch to next mtree entry in the directory.
1181				 */
1182				np = np->dir_info->chnext;
1183				break;
1184			}
1185		}
1186	} while (np != np->parent);
1187
1188	return (ARCHIVE_OK);
1189}
1190
1191static int
1192archive_write_mtree_finish_entry(struct archive_write *a)
1193{
1194	struct mtree_writer *mtree = a->format_data;
1195	struct mtree_entry *me;
1196
1197	if ((me = mtree->mtree_entry) == NULL)
1198		return (ARCHIVE_OK);
1199	mtree->mtree_entry = NULL;
1200
1201	if (me->reg_info)
1202		sum_final(mtree, me->reg_info);
1203
1204	return (ARCHIVE_OK);
1205}
1206
1207static int
1208archive_write_mtree_close(struct archive_write *a)
1209{
1210	struct mtree_writer *mtree= a->format_data;
1211	int ret;
1212
1213	if (mtree->root != NULL) {
1214		ret = write_mtree_entry_tree(a);
1215		if (ret != ARCHIVE_OK)
1216			return (ARCHIVE_FATAL);
1217	}
1218
1219	archive_write_set_bytes_in_last_block(&a->archive, 1);
1220
1221	return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
1222}
1223
1224static ssize_t
1225archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
1226{
1227	struct mtree_writer *mtree= a->format_data;
1228
1229	if (n > mtree->entry_bytes_remaining)
1230		n = (size_t)mtree->entry_bytes_remaining;
1231	mtree->entry_bytes_remaining -= n;
1232
1233	/* We don't need to compute a regular file sum */
1234	if (mtree->mtree_entry == NULL)
1235		return (n);
1236
1237	if (mtree->mtree_entry->filetype == AE_IFREG)
1238		sum_update(mtree, buff, n);
1239
1240	return (n);
1241}
1242
1243static int
1244archive_write_mtree_free(struct archive_write *a)
1245{
1246	struct mtree_writer *mtree= a->format_data;
1247
1248	if (mtree == NULL)
1249		return (ARCHIVE_OK);
1250
1251	/* Make sure we do not leave any entries. */
1252	mtree_entry_register_free(mtree);
1253	archive_string_free(&mtree->cur_dirstr);
1254	archive_string_free(&mtree->ebuf);
1255	archive_string_free(&mtree->buf);
1256	attr_counter_set_free(mtree);
1257	free(mtree);
1258	a->format_data = NULL;
1259	return (ARCHIVE_OK);
1260}
1261
1262static int
1263archive_write_mtree_options(struct archive_write *a, const char *key,
1264    const char *value)
1265{
1266	struct mtree_writer *mtree= a->format_data;
1267	int keybit = 0;
1268
1269	switch (key[0]) {
1270	case 'a':
1271		if (strcmp(key, "all") == 0)
1272			keybit = ~0;
1273		break;
1274	case 'c':
1275		if (strcmp(key, "cksum") == 0)
1276			keybit = F_CKSUM;
1277		break;
1278	case 'd':
1279		if (strcmp(key, "device") == 0)
1280			keybit = F_DEV;
1281		else if (strcmp(key, "dironly") == 0) {
1282			mtree->dironly = (value != NULL)? 1: 0;
1283			return (ARCHIVE_OK);
1284		}
1285		break;
1286	case 'f':
1287		if (strcmp(key, "flags") == 0)
1288			keybit = F_FLAGS;
1289		break;
1290	case 'g':
1291		if (strcmp(key, "gid") == 0)
1292			keybit = F_GID;
1293		else if (strcmp(key, "gname") == 0)
1294			keybit = F_GNAME;
1295		break;
1296	case 'i':
1297		if (strcmp(key, "indent") == 0) {
1298			mtree->indent = (value != NULL)? 1: 0;
1299			return (ARCHIVE_OK);
1300		} else if (strcmp(key, "inode") == 0) {
1301			keybit = F_INO;
1302		}
1303		break;
1304	case 'l':
1305		if (strcmp(key, "link") == 0)
1306			keybit = F_SLINK;
1307		break;
1308	case 'm':
1309		if (strcmp(key, "md5") == 0 ||
1310		    strcmp(key, "md5digest") == 0)
1311			keybit = F_MD5;
1312		if (strcmp(key, "mode") == 0)
1313			keybit = F_MODE;
1314		break;
1315	case 'n':
1316		if (strcmp(key, "nlink") == 0)
1317			keybit = F_NLINK;
1318		break;
1319	case 'r':
1320		if (strcmp(key, "resdevice") == 0) {
1321			keybit = F_RESDEV;
1322		} else if (strcmp(key, "ripemd160digest") == 0 ||
1323		    strcmp(key, "rmd160") == 0 ||
1324		    strcmp(key, "rmd160digest") == 0)
1325			keybit = F_RMD160;
1326		break;
1327	case 's':
1328		if (strcmp(key, "sha1") == 0 ||
1329		    strcmp(key, "sha1digest") == 0)
1330			keybit = F_SHA1;
1331		if (strcmp(key, "sha256") == 0 ||
1332		    strcmp(key, "sha256digest") == 0)
1333			keybit = F_SHA256;
1334		if (strcmp(key, "sha384") == 0 ||
1335		    strcmp(key, "sha384digest") == 0)
1336			keybit = F_SHA384;
1337		if (strcmp(key, "sha512") == 0 ||
1338		    strcmp(key, "sha512digest") == 0)
1339			keybit = F_SHA512;
1340		if (strcmp(key, "size") == 0)
1341			keybit = F_SIZE;
1342		break;
1343	case 't':
1344		if (strcmp(key, "time") == 0)
1345			keybit = F_TIME;
1346		else if (strcmp(key, "type") == 0)
1347			keybit = F_TYPE;
1348		break;
1349	case 'u':
1350		if (strcmp(key, "uid") == 0)
1351			keybit = F_UID;
1352		else if (strcmp(key, "uname") == 0)
1353			keybit = F_UNAME;
1354		else if (strcmp(key, "use-set") == 0) {
1355			mtree->output_global_set = (value != NULL)? 1: 0;
1356			return (ARCHIVE_OK);
1357		}
1358		break;
1359	}
1360	if (keybit != 0) {
1361		if (value != NULL)
1362			mtree->keys |= keybit;
1363		else
1364			mtree->keys &= ~keybit;
1365		return (ARCHIVE_OK);
1366	}
1367
1368	/* Note: The "warn" return is just to inform the options
1369	 * supervisor that we didn't handle it.  It will generate
1370	 * a suitable error if no one used this option. */
1371	return (ARCHIVE_WARN);
1372}
1373
1374static int
1375archive_write_set_format_mtree_default(struct archive *_a, const char *fn)
1376{
1377	struct archive_write *a = (struct archive_write *)_a;
1378	struct mtree_writer *mtree;
1379
1380	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, fn);
1381
1382	if (a->format_free != NULL)
1383		(a->format_free)(a);
1384
1385	if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
1386		archive_set_error(&a->archive, ENOMEM,
1387		    "Can't allocate mtree data");
1388		return (ARCHIVE_FATAL);
1389	}
1390
1391	mtree->mtree_entry = NULL;
1392	mtree->first = 1;
1393	memset(&(mtree->set), 0, sizeof(mtree->set));
1394	mtree->keys = DEFAULT_KEYS;
1395	mtree->dironly = 0;
1396	mtree->indent = 0;
1397	archive_string_init(&mtree->ebuf);
1398	archive_string_init(&mtree->buf);
1399	mtree_entry_register_init(mtree);
1400	a->format_data = mtree;
1401	a->format_free = archive_write_mtree_free;
1402	a->format_name = "mtree";
1403	a->format_options = archive_write_mtree_options;
1404	a->format_write_header = archive_write_mtree_header;
1405	a->format_close = archive_write_mtree_close;
1406	a->format_write_data = archive_write_mtree_data;
1407	a->format_finish_entry = archive_write_mtree_finish_entry;
1408	a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
1409	a->archive.archive_format_name = "mtree";
1410
1411	return (ARCHIVE_OK);
1412}
1413
1414int
1415archive_write_set_format_mtree(struct archive *_a)
1416{
1417	return archive_write_set_format_mtree_default(_a,
1418		"archive_write_set_format_mtree");
1419}
1420
1421int
1422archive_write_set_format_mtree_classic(struct archive *_a)
1423{
1424	int r;
1425
1426	r = archive_write_set_format_mtree_default(_a,
1427		"archive_write_set_format_mtree_classic");
1428	if (r == ARCHIVE_OK) {
1429		struct archive_write *a = (struct archive_write *)_a;
1430		struct mtree_writer *mtree;
1431
1432		mtree = (struct mtree_writer *)a->format_data;
1433
1434		/* Set to output a mtree archive in classic format. */
1435		mtree->classic = 1;
1436		/* Basically, mtree classic format uses '/set' global
1437		 * value. */
1438		mtree->output_global_set = 1;
1439	}
1440	return (r);
1441}
1442
1443static void
1444sum_init(struct mtree_writer *mtree)
1445{
1446
1447	mtree->compute_sum = 0;
1448
1449	if (mtree->keys & F_CKSUM) {
1450		mtree->compute_sum |= F_CKSUM;
1451		mtree->crc = 0;
1452		mtree->crc_len = 0;
1453	}
1454#ifdef ARCHIVE_HAS_MD5
1455	if (mtree->keys & F_MD5) {
1456		if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
1457			mtree->compute_sum |= F_MD5;
1458		else
1459			mtree->keys &= ~F_MD5;/* Not supported. */
1460	}
1461#endif
1462#ifdef ARCHIVE_HAS_RMD160
1463	if (mtree->keys & F_RMD160) {
1464		if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
1465			mtree->compute_sum |= F_RMD160;
1466		else
1467			mtree->keys &= ~F_RMD160;/* Not supported. */
1468	}
1469#endif
1470#ifdef ARCHIVE_HAS_SHA1
1471	if (mtree->keys & F_SHA1) {
1472		if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
1473			mtree->compute_sum |= F_SHA1;
1474		else
1475			mtree->keys &= ~F_SHA1;/* Not supported. */
1476	}
1477#endif
1478#ifdef ARCHIVE_HAS_SHA256
1479	if (mtree->keys & F_SHA256) {
1480		if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
1481			mtree->compute_sum |= F_SHA256;
1482		else
1483			mtree->keys &= ~F_SHA256;/* Not supported. */
1484	}
1485#endif
1486#ifdef ARCHIVE_HAS_SHA384
1487	if (mtree->keys & F_SHA384) {
1488		if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
1489			mtree->compute_sum |= F_SHA384;
1490		else
1491			mtree->keys &= ~F_SHA384;/* Not supported. */
1492	}
1493#endif
1494#ifdef ARCHIVE_HAS_SHA512
1495	if (mtree->keys & F_SHA512) {
1496		if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
1497			mtree->compute_sum |= F_SHA512;
1498		else
1499			mtree->keys &= ~F_SHA512;/* Not supported. */
1500	}
1501#endif
1502}
1503
1504static void
1505sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
1506{
1507	if (mtree->compute_sum & F_CKSUM) {
1508		/*
1509		 * Compute a POSIX 1003.2 checksum
1510		 */
1511		const unsigned char *p;
1512		size_t nn;
1513
1514		for (nn = n, p = buff; nn--; ++p)
1515			COMPUTE_CRC(mtree->crc, *p);
1516		mtree->crc_len += n;
1517	}
1518#ifdef ARCHIVE_HAS_MD5
1519	if (mtree->compute_sum & F_MD5)
1520		archive_md5_update(&mtree->md5ctx, buff, n);
1521#endif
1522#ifdef ARCHIVE_HAS_RMD160
1523	if (mtree->compute_sum & F_RMD160)
1524		archive_rmd160_update(&mtree->rmd160ctx, buff, n);
1525#endif
1526#ifdef ARCHIVE_HAS_SHA1
1527	if (mtree->compute_sum & F_SHA1)
1528		archive_sha1_update(&mtree->sha1ctx, buff, n);
1529#endif
1530#ifdef ARCHIVE_HAS_SHA256
1531	if (mtree->compute_sum & F_SHA256)
1532		archive_sha256_update(&mtree->sha256ctx, buff, n);
1533#endif
1534#ifdef ARCHIVE_HAS_SHA384
1535	if (mtree->compute_sum & F_SHA384)
1536		archive_sha384_update(&mtree->sha384ctx, buff, n);
1537#endif
1538#ifdef ARCHIVE_HAS_SHA512
1539	if (mtree->compute_sum & F_SHA512)
1540		archive_sha512_update(&mtree->sha512ctx, buff, n);
1541#endif
1542}
1543
1544static void
1545sum_final(struct mtree_writer *mtree, struct reg_info *reg)
1546{
1547
1548	if (mtree->compute_sum & F_CKSUM) {
1549		uint64_t len;
1550		/* Include the length of the file. */
1551		for (len = mtree->crc_len; len != 0; len >>= 8)
1552			COMPUTE_CRC(mtree->crc, len & 0xff);
1553		reg->crc = ~mtree->crc;
1554	}
1555#ifdef ARCHIVE_HAS_MD5
1556	if (mtree->compute_sum & F_MD5)
1557		archive_md5_final(&mtree->md5ctx, reg->digest.md5);
1558#endif
1559#ifdef ARCHIVE_HAS_RMD160
1560	if (mtree->compute_sum & F_RMD160)
1561		archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
1562#endif
1563#ifdef ARCHIVE_HAS_SHA1
1564	if (mtree->compute_sum & F_SHA1)
1565		archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
1566#endif
1567#ifdef ARCHIVE_HAS_SHA256
1568	if (mtree->compute_sum & F_SHA256)
1569		archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
1570#endif
1571#ifdef ARCHIVE_HAS_SHA384
1572	if (mtree->compute_sum & F_SHA384)
1573		archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
1574#endif
1575#ifdef ARCHIVE_HAS_SHA512
1576	if (mtree->compute_sum & F_SHA512)
1577		archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
1578#endif
1579	/* Save what types of sum are computed. */
1580	reg->compute_sum = mtree->compute_sum;
1581}
1582
1583#if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
1584    defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
1585    defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
1586static void
1587strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
1588{
1589	static const char hex[] = "0123456789abcdef";
1590	int i;
1591
1592	for (i = 0; i < n; i++) {
1593		archive_strappend_char(s, hex[bin[i] >> 4]);
1594		archive_strappend_char(s, hex[bin[i] & 0x0f]);
1595	}
1596}
1597#endif
1598
1599static void
1600sum_write(struct archive_string *str, struct reg_info *reg)
1601{
1602
1603	if (reg->compute_sum & F_CKSUM) {
1604		archive_string_sprintf(str, " cksum=%ju",
1605		    (uintmax_t)reg->crc);
1606	}
1607
1608#define append_digest(_s, _r, _t) \
1609	strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
1610
1611#ifdef ARCHIVE_HAS_MD5
1612	if (reg->compute_sum & F_MD5) {
1613		archive_strcat(str, " md5digest=");
1614		append_digest(str, reg, md5);
1615	}
1616#endif
1617#ifdef ARCHIVE_HAS_RMD160
1618	if (reg->compute_sum & F_RMD160) {
1619		archive_strcat(str, " rmd160digest=");
1620		append_digest(str, reg, rmd160);
1621	}
1622#endif
1623#ifdef ARCHIVE_HAS_SHA1
1624	if (reg->compute_sum & F_SHA1) {
1625		archive_strcat(str, " sha1digest=");
1626		append_digest(str, reg, sha1);
1627	}
1628#endif
1629#ifdef ARCHIVE_HAS_SHA256
1630	if (reg->compute_sum & F_SHA256) {
1631		archive_strcat(str, " sha256digest=");
1632		append_digest(str, reg, sha256);
1633	}
1634#endif
1635#ifdef ARCHIVE_HAS_SHA384
1636	if (reg->compute_sum & F_SHA384) {
1637		archive_strcat(str, " sha384digest=");
1638		append_digest(str, reg, sha384);
1639	}
1640#endif
1641#ifdef ARCHIVE_HAS_SHA512
1642	if (reg->compute_sum & F_SHA512) {
1643		archive_strcat(str, " sha512digest=");
1644		append_digest(str, reg, sha512);
1645	}
1646#endif
1647#undef append_digest
1648}
1649
1650static int
1651mtree_entry_cmp_node(const struct archive_rb_node *n1,
1652    const struct archive_rb_node *n2)
1653{
1654	const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
1655	const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
1656
1657	return (strcmp(e2->basename.s, e1->basename.s));
1658}
1659
1660static int
1661mtree_entry_cmp_key(const struct archive_rb_node *n, const void *key)
1662{
1663	const struct mtree_entry *e = (const struct mtree_entry *)n;
1664
1665	return (strcmp((const char *)key, e->basename.s));
1666}
1667
1668#if defined(_WIN32) || defined(__CYGWIN__)
1669static int
1670cleanup_backslash_1(char *p)
1671{
1672	int mb, dos;
1673
1674	mb = dos = 0;
1675	while (*p) {
1676		if (*(unsigned char *)p > 127)
1677			mb = 1;
1678		if (*p == '\\') {
1679			/* If we have not met any multi-byte characters,
1680			 * we can replace '\' with '/'. */
1681			if (!mb)
1682				*p = '/';
1683			dos = 1;
1684		}
1685		p++;
1686	}
1687	if (!mb || !dos)
1688		return (0);
1689	return (-1);
1690}
1691
1692static void
1693cleanup_backslash_2(wchar_t *p)
1694{
1695
1696	/* Convert a path-separator from '\' to  '/' */
1697	while (*p != L'\0') {
1698		if (*p == L'\\')
1699			*p = L'/';
1700		p++;
1701	}
1702}
1703#endif
1704
1705/*
1706 * Generate a parent directory name and a base name from a pathname.
1707 */
1708static int
1709mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
1710    struct archive_entry *entry)
1711{
1712	const char *pathname;
1713	char *p, *dirname, *slash;
1714	size_t len;
1715	int ret = ARCHIVE_OK;
1716
1717	archive_strcpy(&file->pathname, archive_entry_pathname(entry));
1718#if defined(_WIN32) || defined(__CYGWIN__)
1719	/*
1720	 * Convert a path-separator from '\' to  '/'
1721	 */
1722	if (cleanup_backslash_1(file->pathname.s) != 0) {
1723		const wchar_t *wp = archive_entry_pathname_w(entry);
1724		struct archive_wstring ws;
1725
1726		if (wp != NULL) {
1727			int r;
1728			archive_string_init(&ws);
1729			archive_wstrcpy(&ws, wp);
1730			cleanup_backslash_2(ws.s);
1731			archive_string_empty(&(file->pathname));
1732			r = archive_string_append_from_wcs(&(file->pathname),
1733			    ws.s, ws.length);
1734			archive_wstring_free(&ws);
1735			if (r < 0 && errno == ENOMEM) {
1736				archive_set_error(&a->archive, ENOMEM,
1737				    "Can't allocate memory");
1738				return (ARCHIVE_FATAL);
1739			}
1740		}
1741	}
1742#else
1743	(void)a; /* UNUSED */
1744#endif
1745	pathname =  file->pathname.s;
1746	if (strcmp(pathname, ".") == 0) {
1747		archive_strcpy(&file->basename, ".");
1748		return (ARCHIVE_OK);
1749	}
1750
1751	archive_strcpy(&(file->parentdir), pathname);
1752
1753	len = file->parentdir.length;
1754	p = dirname = file->parentdir.s;
1755
1756	/*
1757	 * Remove leading '/' and '../' elements
1758	 */
1759	while (*p) {
1760		if (p[0] == '/') {
1761			p++;
1762			len--;
1763		} else if (p[0] != '.')
1764			break;
1765		else if (p[1] == '.' && p[2] == '/') {
1766			p += 3;
1767			len -= 3;
1768		} else
1769			break;
1770	}
1771	if (p != dirname) {
1772		memmove(dirname, p, len+1);
1773		p = dirname;
1774	}
1775	/*
1776	 * Remove "/","/." and "/.." elements from tail.
1777	 */
1778	while (len > 0) {
1779		size_t ll = len;
1780
1781		if (len > 0 && p[len-1] == '/') {
1782			p[len-1] = '\0';
1783			len--;
1784		}
1785		if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
1786			p[len-2] = '\0';
1787			len -= 2;
1788		}
1789		if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
1790		    p[len-1] == '.') {
1791			p[len-3] = '\0';
1792			len -= 3;
1793		}
1794		if (ll == len)
1795			break;
1796	}
1797	while (*p) {
1798		if (p[0] == '/') {
1799			if (p[1] == '/')
1800				/* Convert '//' --> '/' */
1801				memmove(p, p+1, strlen(p+1) + 1);
1802			else if (p[1] == '.' && p[2] == '/')
1803				/* Convert '/./' --> '/' */
1804				memmove(p, p+2, strlen(p+2) + 1);
1805			else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
1806				/* Convert 'dir/dir1/../dir2/'
1807				 *     --> 'dir/dir2/'
1808				 */
1809				char *rp = p -1;
1810				while (rp >= dirname) {
1811					if (*rp == '/')
1812						break;
1813					--rp;
1814				}
1815				if (rp > dirname) {
1816					strcpy(rp, p+3);
1817					p = rp;
1818				} else {
1819					strcpy(dirname, p+4);
1820					p = dirname;
1821				}
1822			} else
1823				p++;
1824		} else
1825			p++;
1826	}
1827	p = dirname;
1828	len = strlen(p);
1829
1830	/*
1831	 * Add "./" prefix.
1832	 * NOTE: If the pathname does not have a path separator, we have
1833	 * to add "./" to the head of the pathname because mtree reader
1834	 * will suppose that it is v1(a.k.a classic) mtree format and
1835	 * change the directory unexpectedly and so it will make a wrong
1836	 * path.
1837	 */
1838	if (strcmp(p, ".") != 0 && strncmp(p, "./", 2) != 0) {
1839		struct archive_string as;
1840		archive_string_init(&as);
1841		archive_strcpy(&as, "./");
1842		archive_strncat(&as, p, len);
1843		archive_string_empty(&file->parentdir);
1844		archive_string_concat(&file->parentdir, &as);
1845		archive_string_free(&as);
1846		p = file->parentdir.s;
1847		len = archive_strlen(&file->parentdir);
1848	}
1849
1850	/*
1851	 * Find out the position which points the last position of
1852	 * path separator('/').
1853	 */
1854	slash = NULL;
1855	for (; *p != '\0'; p++) {
1856		if (*p == '/')
1857			slash = p;
1858	}
1859	if (slash == NULL) {
1860		/* The pathname doesn't have a parent directory. */
1861		file->parentdir.length = len;
1862		archive_string_copy(&(file->basename), &(file->parentdir));
1863		archive_string_empty(&(file->parentdir));
1864		*file->parentdir.s = '\0';
1865		return (ret);
1866	}
1867
1868	/* Make a basename from file->parentdir.s and slash */
1869	*slash  = '\0';
1870	file->parentdir.length = slash - file->parentdir.s;
1871	archive_strcpy(&(file->basename),  slash + 1);
1872	return (ret);
1873}
1874
1875static int
1876mtree_entry_create_virtual_dir(struct archive_write *a, const char *pathname,
1877    struct mtree_entry **m_entry)
1878{
1879	struct archive_entry *entry;
1880	struct mtree_entry *file;
1881	int r;
1882
1883	entry = archive_entry_new();
1884	if (entry == NULL) {
1885		*m_entry = NULL;
1886		archive_set_error(&a->archive, ENOMEM,
1887		    "Can't allocate memory");
1888		return (ARCHIVE_FATAL);
1889	}
1890	archive_entry_copy_pathname(entry, pathname);
1891	archive_entry_set_mode(entry, AE_IFDIR | 0755);
1892	archive_entry_set_mtime(entry, time(NULL), 0);
1893
1894	r = mtree_entry_new(a, entry, &file);
1895	archive_entry_free(entry);
1896	if (r < ARCHIVE_WARN) {
1897		*m_entry = NULL;
1898		archive_set_error(&a->archive, ENOMEM,
1899		    "Can't allocate memory");
1900		return (ARCHIVE_FATAL);
1901	}
1902
1903	file->dir_info->virtual = 1;
1904
1905	*m_entry = file;
1906	return (ARCHIVE_OK);
1907}
1908
1909static void
1910mtree_entry_register_add(struct mtree_writer *mtree, struct mtree_entry *file)
1911{
1912        file->next = NULL;
1913        *mtree->file_list.last = file;
1914        mtree->file_list.last = &(file->next);
1915}
1916
1917static void
1918mtree_entry_register_init(struct mtree_writer *mtree)
1919{
1920	mtree->file_list.first = NULL;
1921	mtree->file_list.last = &(mtree->file_list.first);
1922}
1923
1924static void
1925mtree_entry_register_free(struct mtree_writer *mtree)
1926{
1927	struct mtree_entry *file, *file_next;
1928
1929	file = mtree->file_list.first;
1930	while (file != NULL) {
1931		file_next = file->next;
1932		mtree_entry_free(file);
1933		file = file_next;
1934	}
1935}
1936
1937static int
1938mtree_entry_add_child_tail(struct mtree_entry *parent,
1939    struct mtree_entry *child)
1940{
1941	child->dir_info->chnext = NULL;
1942	*parent->dir_info->children.last = child;
1943	parent->dir_info->children.last = &(child->dir_info->chnext);
1944	return (1);
1945}
1946
1947/*
1948 * Find a entry from a parent entry with the name.
1949 */
1950static struct mtree_entry *
1951mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
1952{
1953	struct mtree_entry *np;
1954
1955	if (parent == NULL)
1956		return (NULL);
1957	np = (struct mtree_entry *)__archive_rb_tree_find_node(
1958	    &(parent->dir_info->rbtree), child_name);
1959	return (np);
1960}
1961
1962static int
1963get_path_component(char *name, size_t n, const char *fn)
1964{
1965	char *p;
1966	size_t l;
1967
1968	p = strchr(fn, '/');
1969	if (p == NULL) {
1970		if ((l = strlen(fn)) == 0)
1971			return (0);
1972	} else
1973		l = p - fn;
1974	if (l > n -1)
1975		return (-1);
1976	memcpy(name, fn, l);
1977	name[l] = '\0';
1978
1979	return ((int)l);
1980}
1981
1982/*
1983 * Add a new entry into the tree.
1984 */
1985static int
1986mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
1987{
1988#if defined(_WIN32) && !defined(__CYGWIN__)
1989	char name[_MAX_FNAME];/* Included null terminator size. */
1990#elif defined(NAME_MAX) && NAME_MAX >= 255
1991	char name[NAME_MAX+1];
1992#else
1993	char name[256];
1994#endif
1995	struct mtree_writer *mtree = (struct mtree_writer *)a->format_data;
1996	struct mtree_entry *dent, *file, *np;
1997	const char *fn, *p;
1998	int l, r;
1999
2000	file = *filep;
2001	if (file->parentdir.length == 0 && file->basename.length == 1 &&
2002	    file->basename.s[0] == '.') {
2003		file->parent = file;
2004		if (mtree->root != NULL) {
2005			np = mtree->root;
2006			goto same_entry;
2007		}
2008		mtree->root = file;
2009		mtree_entry_register_add(mtree, file);
2010		return (ARCHIVE_OK);
2011	}
2012
2013	if (file->parentdir.length == 0) {
2014		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2015		    "Internal programming error "
2016		    "in generating canonical name for %s",
2017		    file->pathname.s);
2018		return (ARCHIVE_FAILED);
2019	}
2020
2021	fn = p = file->parentdir.s;
2022
2023	/*
2024	 * If the path of the parent directory of `file' entry is
2025	 * the same as the path of `cur_dirent', add `file' entry to
2026	 * `cur_dirent'.
2027	 */
2028	if (archive_strlen(&(mtree->cur_dirstr))
2029	      == archive_strlen(&(file->parentdir)) &&
2030	    strcmp(mtree->cur_dirstr.s, fn) == 0) {
2031		if (!__archive_rb_tree_insert_node(
2032		    &(mtree->cur_dirent->dir_info->rbtree),
2033		    (struct archive_rb_node *)file)) {
2034			/* There is the same name in the tree. */
2035			np = (struct mtree_entry *)__archive_rb_tree_find_node(
2036			    &(mtree->cur_dirent->dir_info->rbtree),
2037			    file->basename.s);
2038			goto same_entry;
2039		}
2040		file->parent = mtree->cur_dirent;
2041		mtree_entry_register_add(mtree, file);
2042		return (ARCHIVE_OK);
2043	}
2044
2045	dent = mtree->root;
2046	for (;;) {
2047		l = get_path_component(name, sizeof(name), fn);
2048		if (l == 0) {
2049			np = NULL;
2050			break;
2051		}
2052		if (l < 0) {
2053			archive_set_error(&a->archive,
2054			    ARCHIVE_ERRNO_MISC,
2055			    "A name buffer is too small");
2056			return (ARCHIVE_FATAL);
2057		}
2058		if (l == 1 && name[0] == '.' && dent != NULL &&
2059		    dent == mtree->root) {
2060			fn += l;
2061			if (fn[0] == '/')
2062				fn++;
2063			continue;
2064		}
2065
2066		np = mtree_entry_find_child(dent, name);
2067		if (np == NULL || fn[0] == '\0')
2068			break;
2069
2070		/* Find next sub directory. */
2071		if (!np->dir_info) {
2072			/* NOT Directory! */
2073			archive_set_error(&a->archive,
2074			    ARCHIVE_ERRNO_MISC,
2075			    "`%s' is not directory, we cannot insert `%s' ",
2076			    np->pathname.s, file->pathname.s);
2077			return (ARCHIVE_FAILED);
2078		}
2079		fn += l;
2080		if (fn[0] == '/')
2081			fn++;
2082		dent = np;
2083	}
2084	if (np == NULL) {
2085		/*
2086		 * Create virtual parent directories.
2087		 */
2088		while (fn[0] != '\0') {
2089			struct mtree_entry *vp;
2090			struct archive_string as;
2091
2092			archive_string_init(&as);
2093			archive_strncat(&as, p, fn - p + l);
2094			if (as.s[as.length-1] == '/') {
2095				as.s[as.length-1] = '\0';
2096				as.length--;
2097			}
2098			r = mtree_entry_create_virtual_dir(a, as.s, &vp);
2099			archive_string_free(&as);
2100			if (r < ARCHIVE_WARN)
2101				return (r);
2102
2103			if (strcmp(vp->pathname.s, ".") == 0) {
2104				vp->parent = vp;
2105				mtree->root = vp;
2106			} else {
2107				__archive_rb_tree_insert_node(
2108				    &(dent->dir_info->rbtree),
2109				    (struct archive_rb_node *)vp);
2110				vp->parent = dent;
2111			}
2112			mtree_entry_register_add(mtree, vp);
2113			np = vp;
2114
2115			fn += l;
2116			if (fn[0] == '/')
2117				fn++;
2118			l = get_path_component(name, sizeof(name), fn);
2119			if (l < 0) {
2120				archive_string_free(&as);
2121				archive_set_error(&a->archive,
2122				    ARCHIVE_ERRNO_MISC,
2123				    "A name buffer is too small");
2124				return (ARCHIVE_FATAL);
2125			}
2126			dent = np;
2127		}
2128
2129		/* Found out the parent directory where `file' can be
2130		 * inserted. */
2131		mtree->cur_dirent = dent;
2132		archive_string_empty(&(mtree->cur_dirstr));
2133		archive_string_ensure(&(mtree->cur_dirstr),
2134		    archive_strlen(&(dent->parentdir)) +
2135		    archive_strlen(&(dent->basename)) + 2);
2136		if (archive_strlen(&(dent->parentdir)) +
2137		    archive_strlen(&(dent->basename)) == 0)
2138			mtree->cur_dirstr.s[0] = 0;
2139		else {
2140			if (archive_strlen(&(dent->parentdir)) > 0) {
2141				archive_string_copy(&(mtree->cur_dirstr),
2142				    &(dent->parentdir));
2143				archive_strappend_char(
2144				    &(mtree->cur_dirstr), '/');
2145			}
2146			archive_string_concat(&(mtree->cur_dirstr),
2147			    &(dent->basename));
2148		}
2149
2150		if (!__archive_rb_tree_insert_node(
2151		    &(dent->dir_info->rbtree),
2152		    (struct archive_rb_node *)file)) {
2153			np = (struct mtree_entry *)__archive_rb_tree_find_node(
2154			    &(dent->dir_info->rbtree), file->basename.s);
2155			goto same_entry;
2156		}
2157		file->parent = dent;
2158		mtree_entry_register_add(mtree, file);
2159		return (ARCHIVE_OK);
2160	}
2161
2162same_entry:
2163	/*
2164	 * We have already has the entry the filename of which is
2165	 * the same.
2166	 */
2167	r = mtree_entry_exchange_same_entry(a, np, file);
2168	if (r < ARCHIVE_WARN)
2169		return (r);
2170	if (np->dir_info)
2171		np->dir_info->virtual = 0;
2172	*filep = np;
2173	mtree_entry_free(file);
2174	return (ARCHIVE_WARN);
2175}
2176
2177static int
2178mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
2179    struct mtree_entry *file)
2180{
2181
2182	if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
2183		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2184		    "Found duplicate entries `%s' and its file type is "
2185		    "different",
2186		    np->pathname.s);
2187		return (ARCHIVE_FAILED);
2188	}
2189
2190	/* Update the existent mtree entry's attributes by the new one's. */
2191	archive_string_empty(&np->symlink);
2192	archive_string_concat(&np->symlink, &file->symlink);
2193	archive_string_empty(&np->uname);
2194	archive_string_concat(&np->uname, &file->uname);
2195	archive_string_empty(&np->gname);
2196	archive_string_concat(&np->gname, &file->gname);
2197	archive_string_empty(&np->fflags_text);
2198	archive_string_concat(&np->fflags_text, &file->fflags_text);
2199	np->nlink = file->nlink;
2200	np->filetype = file->filetype;
2201	np->mode = file->mode;
2202	np->size = file->size;
2203	np->uid = file->uid;
2204	np->gid = file->gid;
2205	np->fflags_set = file->fflags_set;
2206	np->fflags_clear = file->fflags_clear;
2207	np->mtime = file->mtime;
2208	np->mtime_nsec = file->mtime_nsec;
2209	np->rdevmajor = file->rdevmajor;
2210	np->rdevminor = file->rdevminor;
2211	np->devmajor = file->devmajor;
2212	np->devminor = file->devminor;
2213	np->ino = file->ino;
2214
2215	return (ARCHIVE_WARN);
2216}
2217