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