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