1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * Copyright (c) 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$");
29 
30 #ifdef HAVE_ERRNO_H
31 #include <errno.h>
32 #endif
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #endif
39 
40 #include "archive.h"
41 #include "archive_private.h"
42 #include "archive_entry.h"
43 #include "archive_getdate.h"
44 #include "archive_pathmatch.h"
45 #include "archive_rb.h"
46 #include "archive_string.h"
47 
48 struct match {
49 	struct match		*next;
50 	int			 matches;
51 	struct archive_mstring	 pattern;
52 };
53 
54 struct match_list {
55 	struct match		*first;
56 	struct match		**last;
57 	int			 count;
58 	int			 unmatched_count;
59 	struct match		*unmatched_next;
60 	int			 unmatched_eof;
61 };
62 
63 struct match_file {
64 	struct archive_rb_node	 node;
65 	struct match_file	*next;
66 	struct archive_mstring	 pathname;
67 	int			 flag;
68 	time_t			 mtime_sec;
69 	long			 mtime_nsec;
70 	time_t			 ctime_sec;
71 	long			 ctime_nsec;
72 };
73 
74 struct entry_list {
75 	struct match_file	*first;
76 	struct match_file	**last;
77 	int			 count;
78 };
79 
80 struct id_array {
81 	size_t			 size;/* Allocated size */
82 	size_t			 count;
83 	int64_t			*ids;
84 };
85 
86 #define PATTERN_IS_SET		1
87 #define TIME_IS_SET		2
88 #define ID_IS_SET		4
89 
90 struct archive_match {
91 	struct archive		 archive;
92 
93 	/* exclusion/inclusion set flag. */
94 	int			 setflag;
95 
96 	/*
97 	 * Matching filename patterns.
98 	 */
99 	struct match_list	 exclusions;
100 	struct match_list	 inclusions;
101 
102 	/*
103 	 * Matching time stamps.
104 	 */
105 	time_t			 now;
106 	int			 newer_mtime_filter;
107 	time_t			 newer_mtime_sec;
108 	long			 newer_mtime_nsec;
109 	int			 newer_ctime_filter;
110 	time_t			 newer_ctime_sec;
111 	long			 newer_ctime_nsec;
112 	int			 older_mtime_filter;
113 	time_t			 older_mtime_sec;
114 	long			 older_mtime_nsec;
115 	int			 older_ctime_filter;
116 	time_t			 older_ctime_sec;
117 	long			 older_ctime_nsec;
118 	/*
119 	 * Matching time stamps with its filename.
120 	 */
121 	struct archive_rb_tree	 exclusion_tree;
122 	struct entry_list 	 exclusion_entry_list;
123 
124 	/*
125 	 * Matching file owners.
126 	 */
127 	struct id_array 	 inclusion_uids;
128 	struct id_array 	 inclusion_gids;
129 	struct match_list	 inclusion_unames;
130 	struct match_list	 inclusion_gnames;
131 };
132 
133 static int	add_pattern_from_file(struct archive_match *,
134 		    struct match_list *, int, const void *, int);
135 static int	add_entry(struct archive_match *, int,
136 		    struct archive_entry *);
137 static int	add_owner_id(struct archive_match *, struct id_array *,
138 		    int64_t);
139 static int	add_owner_name(struct archive_match *, struct match_list *,
140 		    int, const void *);
141 static int	add_pattern_mbs(struct archive_match *, struct match_list *,
142 		    const char *);
143 static int	add_pattern_wcs(struct archive_match *, struct match_list *,
144 		    const wchar_t *);
145 static int	cmp_key_mbs(const struct archive_rb_node *, const void *);
146 static int	cmp_key_wcs(const struct archive_rb_node *, const void *);
147 static int	cmp_node_mbs(const struct archive_rb_node *,
148 		    const struct archive_rb_node *);
149 static int	cmp_node_wcs(const struct archive_rb_node *,
150 		    const struct archive_rb_node *);
151 static void	entry_list_add(struct entry_list *, struct match_file *);
152 static void	entry_list_free(struct entry_list *);
153 static void	entry_list_init(struct entry_list *);
154 static int	error_nomem(struct archive_match *);
155 static void	match_list_add(struct match_list *, struct match *);
156 static void	match_list_free(struct match_list *);
157 static void	match_list_init(struct match_list *);
158 static int	match_list_unmatched_inclusions_next(struct archive_match *,
159 		    struct match_list *, int, const void **);
160 static int	match_owner_id(struct id_array *, int64_t);
161 #if !defined(_WIN32) || defined(__CYGWIN__)
162 static int	match_owner_name_mbs(struct archive_match *,
163 		    struct match_list *, const char *);
164 #else
165 static int	match_owner_name_wcs(struct archive_match *,
166 		    struct match_list *, const wchar_t *);
167 #endif
168 static int	match_path_exclusion(struct archive_match *,
169 		    struct match *, int, const void *);
170 static int	match_path_inclusion(struct archive_match *,
171 		    struct match *, int, const void *);
172 static int	owner_excluded(struct archive_match *,
173 		    struct archive_entry *);
174 static int	path_excluded(struct archive_match *, int, const void *);
175 static int	set_timefilter(struct archive_match *, int, time_t, long,
176 		    time_t, long);
177 static int	set_timefilter_pathname_mbs(struct archive_match *,
178 		    int, const char *);
179 static int	set_timefilter_pathname_wcs(struct archive_match *,
180 		    int, const wchar_t *);
181 static int	set_timefilter_date(struct archive_match *, int, const char *);
182 static int	set_timefilter_date_w(struct archive_match *, int,
183 		    const wchar_t *);
184 static int	time_excluded(struct archive_match *,
185 		    struct archive_entry *);
186 static int	validate_time_flag(struct archive *, int, const char *);
187 
188 #define get_date __archive_get_date
189 
190 static const struct archive_rb_tree_ops rb_ops_mbs = {
191 	cmp_node_mbs, cmp_key_mbs
192 };
193 
194 static const struct archive_rb_tree_ops rb_ops_wcs = {
195 	cmp_node_wcs, cmp_key_wcs
196 };
197 
198 /*
199  * The matching logic here needs to be re-thought.  I started out to
200  * try to mimic gtar's matching logic, but it's not entirely
201  * consistent.  In particular 'tar -t' and 'tar -x' interpret patterns
202  * on the command line as anchored, but --exclude doesn't.
203  */
204 
205 static int
206 error_nomem(struct archive_match *a)
207 {
208 	archive_set_error(&(a->archive), ENOMEM, "No memory");
209 	a->archive.state = ARCHIVE_STATE_FATAL;
210 	return (ARCHIVE_FATAL);
211 }
212 
213 /*
214  * Create an ARCHIVE_MATCH object.
215  */
216 struct archive *
217 archive_match_new(void)
218 {
219 	struct archive_match *a;
220 
221 	a = (struct archive_match *)calloc(1, sizeof(*a));
222 	if (a == NULL)
223 		return (NULL);
224 	a->archive.magic = ARCHIVE_MATCH_MAGIC;
225 	a->archive.state = ARCHIVE_STATE_NEW;
226 	match_list_init(&(a->inclusions));
227 	match_list_init(&(a->exclusions));
228 	__archive_rb_tree_init(&(a->exclusion_tree), &rb_ops_mbs);
229 	entry_list_init(&(a->exclusion_entry_list));
230 	match_list_init(&(a->inclusion_unames));
231 	match_list_init(&(a->inclusion_gnames));
232 	time(&a->now);
233 	return (&(a->archive));
234 }
235 
236 /*
237  * Free an ARCHIVE_MATCH object.
238  */
239 int
240 archive_match_free(struct archive *_a)
241 {
242 	struct archive_match *a;
243 
244 	if (_a == NULL)
245 		return (ARCHIVE_OK);
246 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
247 	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_match_free");
248 	a = (struct archive_match *)_a;
249 	match_list_free(&(a->inclusions));
250 	match_list_free(&(a->exclusions));
251 	entry_list_free(&(a->exclusion_entry_list));
252 	free(a->inclusion_uids.ids);
253 	free(a->inclusion_gids.ids);
254 	match_list_free(&(a->inclusion_unames));
255 	match_list_free(&(a->inclusion_gnames));
256 	free(a);
257 	return (ARCHIVE_OK);
258 }
259 
260 /*
261  * Convenience function to perform all exclusion tests.
262  *
263  * Returns 1 if archive entry is excluded.
264  * Returns 0 if archive entry is not excluded.
265  * Returns <0 if something error happened.
266  */
267 int
268 archive_match_excluded(struct archive *_a, struct archive_entry *entry)
269 {
270 	struct archive_match *a;
271 	int r;
272 
273 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
274 	    ARCHIVE_STATE_NEW, "archive_match_excluded_ae");
275 
276 	a = (struct archive_match *)_a;
277 	if (entry == NULL) {
278 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
279 		return (ARCHIVE_FAILED);
280 	}
281 
282 	r = 0;
283 	if (a->setflag & PATTERN_IS_SET) {
284 #if defined(_WIN32) && !defined(__CYGWIN__)
285 		r = path_excluded(a, 0, archive_entry_pathname_w(entry));
286 #else
287 		r = path_excluded(a, 1, archive_entry_pathname(entry));
288 #endif
289 		if (r != 0)
290 			return (r);
291 	}
292 
293 	if (a->setflag & TIME_IS_SET) {
294 		r = time_excluded(a, entry);
295 		if (r != 0)
296 			return (r);
297 	}
298 
299 	if (a->setflag & ID_IS_SET)
300 		r = owner_excluded(a, entry);
301 	return (r);
302 }
303 
304 /*
305  * Utility functions to manage exclusion/inclusion patterns
306  */
307 
308 int
309 archive_match_exclude_pattern(struct archive *_a, const char *pattern)
310 {
311 	struct archive_match *a;
312 	int r;
313 
314 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
315 	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern");
316 	a = (struct archive_match *)_a;
317 
318 	if (pattern == NULL || *pattern == '\0') {
319 		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
320 		return (ARCHIVE_FAILED);
321 	}
322 	if ((r = add_pattern_mbs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
323 		return (r);
324 	return (ARCHIVE_OK);
325 }
326 
327 int
328 archive_match_exclude_pattern_w(struct archive *_a, const wchar_t *pattern)
329 {
330 	struct archive_match *a;
331 	int r;
332 
333 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
334 	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_w");
335 	a = (struct archive_match *)_a;
336 
337 	if (pattern == NULL || *pattern == L'\0') {
338 		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
339 		return (ARCHIVE_FAILED);
340 	}
341 	if ((r = add_pattern_wcs(a, &(a->exclusions), pattern)) != ARCHIVE_OK)
342 		return (r);
343 	return (ARCHIVE_OK);
344 }
345 
346 int
347 archive_match_exclude_pattern_from_file(struct archive *_a,
348     const char *pathname, int nullSeparator)
349 {
350 	struct archive_match *a;
351 
352 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
353 	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file");
354 	a = (struct archive_match *)_a;
355 
356 	return add_pattern_from_file(a, &(a->exclusions), 1, pathname,
357 		nullSeparator);
358 }
359 
360 int
361 archive_match_exclude_pattern_from_file_w(struct archive *_a,
362     const wchar_t *pathname, int nullSeparator)
363 {
364 	struct archive_match *a;
365 
366 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
367 	    ARCHIVE_STATE_NEW, "archive_match_exclude_pattern_from_file_w");
368 	a = (struct archive_match *)_a;
369 
370 	return add_pattern_from_file(a, &(a->exclusions), 0, pathname,
371 		nullSeparator);
372 }
373 
374 int
375 archive_match_include_pattern(struct archive *_a, const char *pattern)
376 {
377 	struct archive_match *a;
378 	int r;
379 
380 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
381 	    ARCHIVE_STATE_NEW, "archive_match_include_pattern");
382 	a = (struct archive_match *)_a;
383 
384 	if (pattern == NULL || *pattern == '\0') {
385 		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
386 		return (ARCHIVE_FAILED);
387 	}
388 	if ((r = add_pattern_mbs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
389 		return (r);
390 	return (ARCHIVE_OK);
391 }
392 
393 int
394 archive_match_include_pattern_w(struct archive *_a, const wchar_t *pattern)
395 {
396 	struct archive_match *a;
397 	int r;
398 
399 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
400 	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_w");
401 	a = (struct archive_match *)_a;
402 
403 	if (pattern == NULL || *pattern == L'\0') {
404 		archive_set_error(&(a->archive), EINVAL, "pattern is empty");
405 		return (ARCHIVE_FAILED);
406 	}
407 	if ((r = add_pattern_wcs(a, &(a->inclusions), pattern)) != ARCHIVE_OK)
408 		return (r);
409 	return (ARCHIVE_OK);
410 }
411 
412 int
413 archive_match_include_pattern_from_file(struct archive *_a,
414     const char *pathname, int nullSeparator)
415 {
416 	struct archive_match *a;
417 
418 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
419 	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file");
420 	a = (struct archive_match *)_a;
421 
422 	return add_pattern_from_file(a, &(a->inclusions), 1, pathname,
423 		nullSeparator);
424 }
425 
426 int
427 archive_match_include_pattern_from_file_w(struct archive *_a,
428     const wchar_t *pathname, int nullSeparator)
429 {
430 	struct archive_match *a;
431 
432 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
433 	    ARCHIVE_STATE_NEW, "archive_match_include_pattern_from_file_w");
434 	a = (struct archive_match *)_a;
435 
436 	return add_pattern_from_file(a, &(a->inclusions), 0, pathname,
437 		nullSeparator);
438 }
439 
440 /*
441  * Test functions for pathname patterns.
442  *
443  * Returns 1 if archive entry is excluded.
444  * Returns 0 if archive entry is not excluded.
445  * Returns <0 if something error happened.
446  */
447 int
448 archive_match_path_excluded(struct archive *_a,
449     struct archive_entry *entry)
450 {
451 	struct archive_match *a;
452 
453 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
454 	    ARCHIVE_STATE_NEW, "archive_match_path_excluded");
455 
456 	a = (struct archive_match *)_a;
457 	if (entry == NULL) {
458 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
459 		return (ARCHIVE_FAILED);
460 	}
461 
462 	/* If we don't have exclusion/inclusion pattern set at all,
463 	 * the entry is always not excluded. */
464 	if ((a->setflag & PATTERN_IS_SET) == 0)
465 		return (0);
466 #if defined(_WIN32) && !defined(__CYGWIN__)
467 	return (path_excluded(a, 0, archive_entry_pathname_w(entry)));
468 #else
469 	return (path_excluded(a, 1, archive_entry_pathname(entry)));
470 #endif
471 }
472 
473 /*
474  * Utility functions to get statistic information for inclusion patterns.
475  */
476 int
477 archive_match_path_unmatched_inclusions(struct archive *_a)
478 {
479 	struct archive_match *a;
480 
481 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
482 	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions");
483 	a = (struct archive_match *)_a;
484 
485 	return (a->inclusions.unmatched_count);
486 }
487 
488 int
489 archive_match_path_unmatched_inclusions_next(struct archive *_a,
490     const char **_p)
491 {
492 	struct archive_match *a;
493 	const void *v;
494 	int r;
495 
496 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
497 	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next");
498 	a = (struct archive_match *)_a;
499 
500 	r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 1, &v);
501 	*_p = (const char *)v;
502 	return (r);
503 }
504 
505 int
506 archive_match_path_unmatched_inclusions_next_w(struct archive *_a,
507     const wchar_t **_p)
508 {
509 	struct archive_match *a;
510 	const void *v;
511 	int r;
512 
513 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
514 	    ARCHIVE_STATE_NEW, "archive_match_unmatched_inclusions_next_w");
515 	a = (struct archive_match *)_a;
516 
517 	r = match_list_unmatched_inclusions_next(a, &(a->inclusions), 0, &v);
518 	*_p = (const wchar_t *)v;
519 	return (r);
520 }
521 
522 /*
523  * Add inclusion/exclusion patterns.
524  */
525 static int
526 add_pattern_mbs(struct archive_match *a, struct match_list *list,
527     const char *pattern)
528 {
529 	struct match *match;
530 	size_t len;
531 
532 	match = calloc(1, sizeof(*match));
533 	if (match == NULL)
534 		return (error_nomem(a));
535 	/* Both "foo/" and "foo" should match "foo/bar". */
536 	len = strlen(pattern);
537 	if (len && pattern[len - 1] == '/')
538 		--len;
539 	archive_mstring_copy_mbs_len(&(match->pattern), pattern, len);
540 	match_list_add(list, match);
541 	a->setflag |= PATTERN_IS_SET;
542 	return (ARCHIVE_OK);
543 }
544 
545 static int
546 add_pattern_wcs(struct archive_match *a, struct match_list *list,
547     const wchar_t *pattern)
548 {
549 	struct match *match;
550 	size_t len;
551 
552 	match = calloc(1, sizeof(*match));
553 	if (match == NULL)
554 		return (error_nomem(a));
555 	/* Both "foo/" and "foo" should match "foo/bar". */
556 	len = wcslen(pattern);
557 	if (len && pattern[len - 1] == L'/')
558 		--len;
559 	archive_mstring_copy_wcs_len(&(match->pattern), pattern, len);
560 	match_list_add(list, match);
561 	a->setflag |= PATTERN_IS_SET;
562 	return (ARCHIVE_OK);
563 }
564 
565 static int
566 add_pattern_from_file(struct archive_match *a, struct match_list *mlist,
567     int mbs, const void *pathname, int nullSeparator)
568 {
569 	struct archive *ar;
570 	struct archive_entry *ae;
571 	struct archive_string as;
572 	const void *buff;
573 	size_t size;
574 	int64_t offset;
575 	int r;
576 
577 	ar = archive_read_new();
578 	if (ar == NULL) {
579 		archive_set_error(&(a->archive), ENOMEM, "No memory");
580 		return (ARCHIVE_FATAL);
581 	}
582 	r = archive_read_support_format_raw(ar);
583 	r = archive_read_support_format_empty(ar);
584 	if (r != ARCHIVE_OK) {
585 		archive_copy_error(&(a->archive), ar);
586 		archive_read_free(ar);
587 		return (r);
588 	}
589 	if (mbs)
590 		r = archive_read_open_filename(ar, pathname, 512*20);
591 	else
592 		r = archive_read_open_filename_w(ar, pathname, 512*20);
593 	if (r != ARCHIVE_OK) {
594 		archive_copy_error(&(a->archive), ar);
595 		archive_read_free(ar);
596 		return (r);
597 	}
598 	r = archive_read_next_header(ar, &ae);
599 	if (r != ARCHIVE_OK) {
600 		archive_read_free(ar);
601 		if (r == ARCHIVE_EOF) {
602 			return (ARCHIVE_OK);
603 		} else {
604 			archive_copy_error(&(a->archive), ar);
605 			return (r);
606 		}
607 	}
608 
609 	archive_string_init(&as);
610 
611 	while ((r = archive_read_data_block(ar, &buff, &size, &offset))
612 	    == ARCHIVE_OK) {
613 		const char *b = (const char *)buff;
614 
615 		while (size) {
616 			const char *s = (const char *)b;
617 			size_t length = 0;
618 			int found_separator = 0;
619 
620 			while (length < size) {
621 				if (nullSeparator) {
622 					if (*b == '\0') {
623 						found_separator = 1;
624 						break;
625 					}
626 				} else {
627 			            	if (*b == 0x0d || *b == 0x0a) {
628 						found_separator = 1;
629 						break;
630 					}
631 				}
632 				b++;
633 				length++;
634 			}
635 			if (!found_separator) {
636 				archive_strncat(&as, s, length);
637 				/* Read next data block. */
638 				break;
639 			}
640 			b++;
641 			size -= length + 1;
642 			archive_strncat(&as, s, length);
643 
644 			/* If the line is not empty, add the pattern. */
645 			if (archive_strlen(&as) > 0) {
646 				/* Add pattern. */
647 				r = add_pattern_mbs(a, mlist, as.s);
648 				if (r != ARCHIVE_OK) {
649 					archive_read_free(ar);
650 					archive_string_free(&as);
651 					return (r);
652 				}
653 				archive_string_empty(&as);
654 			}
655 		}
656 	}
657 
658 	/* If an error occurred, report it immediately. */
659 	if (r < ARCHIVE_OK) {
660 		archive_copy_error(&(a->archive), ar);
661 		archive_read_free(ar);
662 		archive_string_free(&as);
663 		return (r);
664 	}
665 
666 	/* If the line is not empty, add the pattern. */
667 	if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
668 		/* Add pattern. */
669 		r = add_pattern_mbs(a, mlist, as.s);
670 		if (r != ARCHIVE_OK) {
671 			archive_read_free(ar);
672 			archive_string_free(&as);
673 			return (r);
674 		}
675 	}
676 	archive_read_free(ar);
677 	archive_string_free(&as);
678 	return (ARCHIVE_OK);
679 }
680 
681 /*
682  * Test if pathname is excluded by inclusion/exclusion patterns.
683  */
684 static int
685 path_excluded(struct archive_match *a, int mbs, const void *pathname)
686 {
687 	struct match *match;
688 	struct match *matched;
689 	int r;
690 
691 	if (a == NULL)
692 		return (0);
693 
694 	/* Mark off any unmatched inclusions. */
695 	/* In particular, if a filename does appear in the archive and
696 	 * is explicitly included and excluded, then we don't report
697 	 * it as missing even though we don't extract it.
698 	 */
699 	matched = NULL;
700 	for (match = a->inclusions.first; match != NULL;
701 	    match = match->next){
702 		if (match->matches == 0 &&
703 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
704 			if (r < 0)
705 				return (r);
706 			a->inclusions.unmatched_count--;
707 			match->matches++;
708 			matched = match;
709 		}
710 	}
711 
712 	/* Exclusions take priority */
713 	for (match = a->exclusions.first; match != NULL;
714 	    match = match->next){
715 		r = match_path_exclusion(a, match, mbs, pathname);
716 		if (r)
717 			return (r);
718 	}
719 
720 	/* It's not excluded and we found an inclusion above, so it's
721 	 * included. */
722 	if (matched != NULL)
723 		return (0);
724 
725 
726 	/* We didn't find an unmatched inclusion, check the remaining ones. */
727 	for (match = a->inclusions.first; match != NULL;
728 	    match = match->next){
729 		/* We looked at previously-unmatched inclusions already. */
730 		if (match->matches > 0 &&
731 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
732 			if (r < 0)
733 				return (r);
734 			match->matches++;
735 			return (0);
736 		}
737 	}
738 
739 	/* If there were inclusions, default is to exclude. */
740 	if (a->inclusions.first != NULL)
741 	    return (1);
742 
743 	/* No explicit inclusions, default is to match. */
744 	return (0);
745 }
746 
747 /*
748  * This is a little odd, but it matches the default behavior of
749  * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
750  *
751  */
752 static int
753 match_path_exclusion(struct archive_match *a, struct match *m,
754     int mbs, const void *pn)
755 {
756 	int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
757 	int r;
758 
759 	if (mbs) {
760 		const char *p;
761 		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
762 		if (r == 0)
763 			return (archive_pathmatch(p, (const char *)pn, flag));
764 	} else {
765 		const wchar_t *p;
766 		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
767 		if (r == 0)
768 			return (archive_pathmatch_w(p, (const wchar_t *)pn,
769 				flag));
770 	}
771 	if (errno == ENOMEM)
772 		return (error_nomem(a));
773 	return (0);
774 }
775 
776 /*
777  * Again, mimic gtar:  inclusions are always anchored (have to match
778  * the beginning of the path) even though exclusions are not anchored.
779  */
780 static int
781 match_path_inclusion(struct archive_match *a, struct match *m,
782     int mbs, const void *pn)
783 {
784 	int flag = PATHMATCH_NO_ANCHOR_END;
785 	int r;
786 
787 	if (mbs) {
788 		const char *p;
789 		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
790 		if (r == 0)
791 			return (archive_pathmatch(p, (const char *)pn, flag));
792 	} else {
793 		const wchar_t *p;
794 		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
795 		if (r == 0)
796 			return (archive_pathmatch_w(p, (const wchar_t *)pn,
797 				flag));
798 	}
799 	if (errno == ENOMEM)
800 		return (error_nomem(a));
801 	return (0);
802 }
803 
804 static void
805 match_list_init(struct match_list *list)
806 {
807 	list->first = NULL;
808 	list->last = &(list->first);
809 	list->count = 0;
810 }
811 
812 static void
813 match_list_free(struct match_list *list)
814 {
815 	struct match *p, *q;
816 
817 	for (p = list->first; p != NULL; ) {
818 		q = p;
819 		p = p->next;
820 		archive_mstring_clean(&(q->pattern));
821 		free(q);
822 	}
823 }
824 
825 static void
826 match_list_add(struct match_list *list, struct match *m)
827 {
828 	*list->last = m;
829 	list->last = &(m->next);
830 	list->count++;
831 	list->unmatched_count++;
832 }
833 
834 static int
835 match_list_unmatched_inclusions_next(struct archive_match *a,
836     struct match_list *list, int mbs, const void **vp)
837 {
838 	struct match *m;
839 
840 	*vp = NULL;
841 	if (list->unmatched_eof) {
842 		list->unmatched_eof = 0;
843 		return (ARCHIVE_EOF);
844 	}
845 	if (list->unmatched_next == NULL) {
846 		if (list->unmatched_count == 0)
847 			return (ARCHIVE_EOF);
848 		list->unmatched_next = list->first;
849 	}
850 
851 	for (m = list->unmatched_next; m != NULL; m = m->next) {
852 		int r;
853 
854 		if (m->matches)
855 			continue;
856 		if (mbs) {
857 			const char *p;
858 			r = archive_mstring_get_mbs(&(a->archive),
859 				&(m->pattern), &p);
860 			if (r < 0 && errno == ENOMEM)
861 				return (error_nomem(a));
862 			if (p == NULL)
863 				p = "";
864 			*vp = p;
865 		} else {
866 			const wchar_t *p;
867 			r = archive_mstring_get_wcs(&(a->archive),
868 				&(m->pattern), &p);
869 			if (r < 0 && errno == ENOMEM)
870 				return (error_nomem(a));
871 			if (p == NULL)
872 				p = L"";
873 			*vp = p;
874 		}
875 		list->unmatched_next = m->next;
876 		if (list->unmatched_next == NULL)
877 			/* To return EOF next time. */
878 			list->unmatched_eof = 1;
879 		return (ARCHIVE_OK);
880 	}
881 	list->unmatched_next = NULL;
882 	return (ARCHIVE_EOF);
883 }
884 
885 /*
886  * Utility functions to manage inclusion timestamps.
887  */
888 int
889 archive_match_include_time(struct archive *_a, int flag, time_t sec,
890     long nsec)
891 {
892 	int r;
893 
894 	r = validate_time_flag(_a, flag, "archive_match_include_time");
895 	if (r != ARCHIVE_OK)
896 		return (r);
897 	return set_timefilter((struct archive_match *)_a, flag,
898 			sec, nsec, sec, nsec);
899 }
900 
901 int
902 archive_match_include_date(struct archive *_a, int flag,
903     const char *datestr)
904 {
905 	int r;
906 
907 	r = validate_time_flag(_a, flag, "archive_match_include_date");
908 	if (r != ARCHIVE_OK)
909 		return (r);
910 	return set_timefilter_date((struct archive_match *)_a, flag, datestr);
911 }
912 
913 int
914 archive_match_include_date_w(struct archive *_a, int flag,
915     const wchar_t *datestr)
916 {
917 	int r;
918 
919 	r = validate_time_flag(_a, flag, "archive_match_include_date_w");
920 	if (r != ARCHIVE_OK)
921 		return (r);
922 
923 	return set_timefilter_date_w((struct archive_match *)_a, flag, datestr);
924 }
925 
926 int
927 archive_match_include_file_time(struct archive *_a, int flag,
928     const char *pathname)
929 {
930 	int r;
931 
932 	r = validate_time_flag(_a, flag, "archive_match_include_file_time");
933 	if (r != ARCHIVE_OK)
934 		return (r);
935 	return set_timefilter_pathname_mbs((struct archive_match *)_a,
936 			flag, pathname);
937 }
938 
939 int
940 archive_match_include_file_time_w(struct archive *_a, int flag,
941     const wchar_t *pathname)
942 {
943 	int r;
944 
945 	r = validate_time_flag(_a, flag, "archive_match_include_file_time_w");
946 	if (r != ARCHIVE_OK)
947 		return (r);
948 	return set_timefilter_pathname_wcs((struct archive_match *)_a,
949 			flag, pathname);
950 }
951 
952 int
953 archive_match_exclude_entry(struct archive *_a, int flag,
954     struct archive_entry *entry)
955 {
956 	struct archive_match *a;
957 	int r;
958 
959 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
960 	    ARCHIVE_STATE_NEW, "archive_match_time_include_entry");
961 	a = (struct archive_match *)_a;
962 
963 	if (entry == NULL) {
964 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
965 		return (ARCHIVE_FAILED);
966 	}
967 	r = validate_time_flag(_a, flag, "archive_match_exclude_entry");
968 	if (r != ARCHIVE_OK)
969 		return (r);
970 	return (add_entry(a, flag, entry));
971 }
972 
973 /*
974  * Test function for time stamps.
975  *
976  * Returns 1 if archive entry is excluded.
977  * Returns 0 if archive entry is not excluded.
978  * Returns <0 if something error happened.
979  */
980 int
981 archive_match_time_excluded(struct archive *_a,
982     struct archive_entry *entry)
983 {
984 	struct archive_match *a;
985 
986 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
987 	    ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae");
988 
989 	a = (struct archive_match *)_a;
990 	if (entry == NULL) {
991 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
992 		return (ARCHIVE_FAILED);
993 	}
994 
995 	/* If we don't have inclusion time set at all, the entry is always
996 	 * not excluded. */
997 	if ((a->setflag & TIME_IS_SET) == 0)
998 		return (0);
999 	return (time_excluded(a, entry));
1000 }
1001 
1002 static int
1003 validate_time_flag(struct archive *_a, int flag, const char *_fn)
1004 {
1005 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1006 	    ARCHIVE_STATE_NEW, _fn);
1007 
1008 	/* Check a type of time. */
1009 	if (flag &
1010 	   ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) {
1011 		archive_set_error(_a, EINVAL, "Invalid time flag");
1012 		return (ARCHIVE_FAILED);
1013 	}
1014 	if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) == 0) {
1015 		archive_set_error(_a, EINVAL, "No time flag");
1016 		return (ARCHIVE_FAILED);
1017 	}
1018 
1019 	/* Check a type of comparison. */
1020 	if (flag &
1021 	   ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
1022 			| ARCHIVE_MATCH_EQUAL)) & 0x00ff)) {
1023 		archive_set_error(_a, EINVAL, "Invalid comparison flag");
1024 		return (ARCHIVE_FAILED);
1025 	}
1026 	if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
1027 	    | ARCHIVE_MATCH_EQUAL)) == 0) {
1028 		archive_set_error(_a, EINVAL, "No comparison flag");
1029 		return (ARCHIVE_FAILED);
1030 	}
1031 
1032 	return (ARCHIVE_OK);
1033 }
1034 
1035 #define JUST_EQUAL(t) (((t) &  (ARCHIVE_MATCH_EQUAL |\
1036 	ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) == ARCHIVE_MATCH_EQUAL)
1037 static int
1038 set_timefilter(struct archive_match *a, int timetype,
1039     time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec)
1040 {
1041 	if (timetype & ARCHIVE_MATCH_MTIME) {
1042 		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
1043 			a->newer_mtime_filter = timetype;
1044 			a->newer_mtime_sec = mtime_sec;
1045 			a->newer_mtime_nsec = mtime_nsec;
1046 			a->setflag |= TIME_IS_SET;
1047 		}
1048 		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
1049 			a->older_mtime_filter = timetype;
1050 			a->older_mtime_sec = mtime_sec;
1051 			a->older_mtime_nsec = mtime_nsec;
1052 			a->setflag |= TIME_IS_SET;
1053 		}
1054 	}
1055 	if (timetype & ARCHIVE_MATCH_CTIME) {
1056 		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
1057 			a->newer_ctime_filter = timetype;
1058 			a->newer_ctime_sec = ctime_sec;
1059 			a->newer_ctime_nsec = ctime_nsec;
1060 			a->setflag |= TIME_IS_SET;
1061 		}
1062 		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
1063 			a->older_ctime_filter = timetype;
1064 			a->older_ctime_sec = ctime_sec;
1065 			a->older_ctime_nsec = ctime_nsec;
1066 			a->setflag |= TIME_IS_SET;
1067 		}
1068 	}
1069 	return (ARCHIVE_OK);
1070 }
1071 
1072 static int
1073 set_timefilter_date(struct archive_match *a, int timetype, const char *datestr)
1074 {
1075 	time_t t;
1076 
1077 	if (datestr == NULL || *datestr == '\0') {
1078 		archive_set_error(&(a->archive), EINVAL, "date is empty");
1079 		return (ARCHIVE_FAILED);
1080 	}
1081 	t = get_date(a->now, datestr);
1082 	if (t == (time_t)-1) {
1083 		archive_set_error(&(a->archive), EINVAL, "invalid date string");
1084 		return (ARCHIVE_FAILED);
1085 	}
1086 	return set_timefilter(a, timetype, t, 0, t, 0);
1087 }
1088 
1089 static int
1090 set_timefilter_date_w(struct archive_match *a, int timetype,
1091     const wchar_t *datestr)
1092 {
1093 	struct archive_string as;
1094 	time_t t;
1095 
1096 	if (datestr == NULL || *datestr == L'\0') {
1097 		archive_set_error(&(a->archive), EINVAL, "date is empty");
1098 		return (ARCHIVE_FAILED);
1099 	}
1100 
1101 	archive_string_init(&as);
1102 	if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
1103 		archive_string_free(&as);
1104 		if (errno == ENOMEM)
1105 			return (error_nomem(a));
1106 		archive_set_error(&(a->archive), -1,
1107 		    "Failed to convert WCS to MBS");
1108 		return (ARCHIVE_FAILED);
1109 	}
1110 	t = get_date(a->now, as.s);
1111 	archive_string_free(&as);
1112 	if (t == (time_t)-1) {
1113 		archive_set_error(&(a->archive), EINVAL, "invalid date string");
1114 		return (ARCHIVE_FAILED);
1115 	}
1116 	return set_timefilter(a, timetype, t, 0, t, 0);
1117 }
1118 
1119 #if defined(_WIN32) && !defined(__CYGWIN__)
1120 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1121 static int
1122 set_timefilter_find_data(struct archive_match *a, int timetype,
1123     DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateTime,
1124     DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTime)
1125 {
1126 	ULARGE_INTEGER utc;
1127 	time_t ctime_sec, mtime_sec;
1128 	long ctime_ns, mtime_ns;
1129 
1130 	utc.HighPart = ftCreationTime_dwHighDateTime;
1131 	utc.LowPart = ftCreationTime_dwLowDateTime;
1132 	if (utc.QuadPart >= EPOC_TIME) {
1133 		utc.QuadPart -= EPOC_TIME;
1134 		ctime_sec = (time_t)(utc.QuadPart / 10000000);
1135 		ctime_ns = (long)(utc.QuadPart % 10000000) * 100;
1136 	} else {
1137 		ctime_sec = 0;
1138 		ctime_ns = 0;
1139 	}
1140 	utc.HighPart = ftLastWriteTime_dwHighDateTime;
1141 	utc.LowPart = ftLastWriteTime_dwLowDateTime;
1142 	if (utc.QuadPart >= EPOC_TIME) {
1143 		utc.QuadPart -= EPOC_TIME;
1144 		mtime_sec = (time_t)(utc.QuadPart / 10000000);
1145 		mtime_ns = (long)(utc.QuadPart % 10000000) * 100;
1146 	} else {
1147 		mtime_sec = 0;
1148 		mtime_ns = 0;
1149 	}
1150 	return set_timefilter(a, timetype,
1151 			mtime_sec, mtime_ns, ctime_sec, ctime_ns);
1152 }
1153 
1154 static int
1155 set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
1156     const char *path)
1157 {
1158 	/* NOTE: stat() on Windows cannot handle nano seconds. */
1159 	HANDLE h;
1160 	WIN32_FIND_DATAA d;
1161 
1162 	if (path == NULL || *path == '\0') {
1163 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1164 		return (ARCHIVE_FAILED);
1165 	}
1166 	h = FindFirstFileA(path, &d);
1167 	if (h == INVALID_HANDLE_VALUE) {
1168 		la_dosmaperr(GetLastError());
1169 		archive_set_error(&(a->archive), errno,
1170 		    "Failed to FindFirstFileA");
1171 		return (ARCHIVE_FAILED);
1172 	}
1173 	FindClose(h);
1174 	return set_timefilter_find_data(a, timetype,
1175 	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
1176 	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
1177 }
1178 
1179 static int
1180 set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
1181     const wchar_t *path)
1182 {
1183 	HANDLE h;
1184 	WIN32_FIND_DATAW d;
1185 
1186 	if (path == NULL || *path == L'\0') {
1187 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1188 		return (ARCHIVE_FAILED);
1189 	}
1190 	h = FindFirstFileW(path, &d);
1191 	if (h == INVALID_HANDLE_VALUE) {
1192 		la_dosmaperr(GetLastError());
1193 		archive_set_error(&(a->archive), errno,
1194 		    "Failed to FindFirstFile");
1195 		return (ARCHIVE_FAILED);
1196 	}
1197 	FindClose(h);
1198 	return set_timefilter_find_data(a, timetype,
1199 	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
1200 	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
1201 }
1202 
1203 #else /* _WIN32 && !__CYGWIN__ */
1204 
1205 static int
1206 set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st)
1207 {
1208 	struct archive_entry *ae;
1209 	time_t ctime_sec, mtime_sec;
1210 	long ctime_ns, mtime_ns;
1211 
1212 	ae = archive_entry_new();
1213 	if (ae == NULL)
1214 		return (error_nomem(a));
1215 	archive_entry_copy_stat(ae, st);
1216 	ctime_sec = archive_entry_ctime(ae);
1217 	ctime_ns = archive_entry_ctime_nsec(ae);
1218 	mtime_sec = archive_entry_mtime(ae);
1219 	mtime_ns = archive_entry_mtime_nsec(ae);
1220 	archive_entry_free(ae);
1221 	return set_timefilter(a, timetype, mtime_sec, mtime_ns,
1222 			ctime_sec, ctime_ns);
1223 }
1224 
1225 static int
1226 set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
1227     const char *path)
1228 {
1229 	struct stat st;
1230 
1231 	if (path == NULL || *path == '\0') {
1232 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1233 		return (ARCHIVE_FAILED);
1234 	}
1235 	if (stat(path, &st) != 0) {
1236 		archive_set_error(&(a->archive), errno, "Failed to stat()");
1237 		return (ARCHIVE_FAILED);
1238 	}
1239 	return (set_timefilter_stat(a, timetype, &st));
1240 }
1241 
1242 static int
1243 set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
1244     const wchar_t *path)
1245 {
1246 	struct archive_string as;
1247 	int r;
1248 
1249 	if (path == NULL || *path == L'\0') {
1250 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1251 		return (ARCHIVE_FAILED);
1252 	}
1253 
1254 	/* Convert WCS filename to MBS filename. */
1255 	archive_string_init(&as);
1256 	if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
1257 		archive_string_free(&as);
1258 		if (errno == ENOMEM)
1259 			return (error_nomem(a));
1260 		archive_set_error(&(a->archive), -1,
1261 		    "Failed to convert WCS to MBS");
1262 		return (ARCHIVE_FAILED);
1263 	}
1264 
1265 	r = set_timefilter_pathname_mbs(a, timetype, as.s);
1266 	archive_string_free(&as);
1267 
1268 	return (r);
1269 }
1270 #endif /* _WIN32 && !__CYGWIN__ */
1271 
1272 /*
1273  * Call back functions for archive_rb.
1274  */
1275 static int
1276 cmp_node_mbs(const struct archive_rb_node *n1,
1277     const struct archive_rb_node *n2)
1278 {
1279 	struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
1280 	struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
1281 	const char *p1, *p2;
1282 
1283 	archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
1284 	archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
1285 	if (p1 == NULL)
1286 		return (1);
1287 	if (p2 == NULL)
1288 		return (-1);
1289 	return (strcmp(p1, p2));
1290 }
1291 
1292 static int
1293 cmp_key_mbs(const struct archive_rb_node *n, const void *key)
1294 {
1295 	struct match_file *f = (struct match_file *)(uintptr_t)n;
1296 	const char *p;
1297 
1298 	archive_mstring_get_mbs(NULL, &(f->pathname), &p);
1299 	if (p == NULL)
1300 		return (-1);
1301 	return (strcmp(p, (const char *)key));
1302 }
1303 
1304 static int
1305 cmp_node_wcs(const struct archive_rb_node *n1,
1306     const struct archive_rb_node *n2)
1307 {
1308 	struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
1309 	struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
1310 	const wchar_t *p1, *p2;
1311 
1312 	archive_mstring_get_wcs(NULL, &(f1->pathname), &p1);
1313 	archive_mstring_get_wcs(NULL, &(f2->pathname), &p2);
1314 	if (p1 == NULL)
1315 		return (1);
1316 	if (p2 == NULL)
1317 		return (-1);
1318 	return (wcscmp(p1, p2));
1319 }
1320 
1321 static int
1322 cmp_key_wcs(const struct archive_rb_node *n, const void *key)
1323 {
1324 	struct match_file *f = (struct match_file *)(uintptr_t)n;
1325 	const wchar_t *p;
1326 
1327 	archive_mstring_get_wcs(NULL, &(f->pathname), &p);
1328 	if (p == NULL)
1329 		return (-1);
1330 	return (wcscmp(p, (const wchar_t *)key));
1331 }
1332 
1333 static void
1334 entry_list_init(struct entry_list *list)
1335 {
1336 	list->first = NULL;
1337 	list->last = &(list->first);
1338 	list->count = 0;
1339 }
1340 
1341 static void
1342 entry_list_free(struct entry_list *list)
1343 {
1344 	struct match_file *p, *q;
1345 
1346 	for (p = list->first; p != NULL; ) {
1347 		q = p;
1348 		p = p->next;
1349 		archive_mstring_clean(&(q->pathname));
1350 		free(q);
1351 	}
1352 }
1353 
1354 static void
1355 entry_list_add(struct entry_list *list, struct match_file *file)
1356 {
1357 	*list->last = file;
1358 	list->last = &(file->next);
1359 	list->count++;
1360 }
1361 
1362 static int
1363 add_entry(struct archive_match *a, int flag,
1364     struct archive_entry *entry)
1365 {
1366 	struct match_file *f;
1367 	const void *pathname;
1368 	int r;
1369 
1370 	f = calloc(1, sizeof(*f));
1371 	if (f == NULL)
1372 		return (error_nomem(a));
1373 
1374 #if defined(_WIN32) && !defined(__CYGWIN__)
1375 	pathname = archive_entry_pathname_w(entry);
1376 	if (pathname == NULL) {
1377 		free(f);
1378 		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
1379 		return (ARCHIVE_FAILED);
1380 	}
1381 	archive_mstring_copy_wcs(&(f->pathname), pathname);
1382 	a->exclusion_tree.rbt_ops = &rb_ops_wcs;
1383 #else
1384 	(void)rb_ops_wcs;
1385 	pathname = archive_entry_pathname(entry);
1386 	if (pathname == NULL) {
1387 		free(f);
1388 		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
1389 		return (ARCHIVE_FAILED);
1390 	}
1391 	archive_mstring_copy_mbs(&(f->pathname), pathname);
1392 	a->exclusion_tree.rbt_ops = &rb_ops_mbs;
1393 #endif
1394 	f->flag = flag;
1395 	f->mtime_sec = archive_entry_mtime(entry);
1396 	f->mtime_nsec = archive_entry_mtime_nsec(entry);
1397 	f->ctime_sec = archive_entry_ctime(entry);
1398 	f->ctime_nsec = archive_entry_ctime_nsec(entry);
1399 	r = __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node));
1400 	if (!r) {
1401 		struct match_file *f2;
1402 
1403 		/* Get the duplicated file. */
1404 		f2 = (struct match_file *)__archive_rb_tree_find_node(
1405 			&(a->exclusion_tree), pathname);
1406 
1407 		/*
1408 		 * We always overwrite comparison condition.
1409 		 * If you do not want to overwrite it, you should not
1410 		 * call archive_match_exclude_entry(). We cannot know
1411 		 * what behavior you really expect since overwriting
1412 		 * condition might be different with the flag.
1413 		 */
1414 		if (f2 != NULL) {
1415 			f2->flag = f->flag;
1416 			f2->mtime_sec = f->mtime_sec;
1417 			f2->mtime_nsec = f->mtime_nsec;
1418 			f2->ctime_sec = f->ctime_sec;
1419 			f2->ctime_nsec = f->ctime_nsec;
1420 		}
1421 		/* Release the duplicated file. */
1422 		archive_mstring_clean(&(f->pathname));
1423 		free(f);
1424 		return (ARCHIVE_OK);
1425 	}
1426 	entry_list_add(&(a->exclusion_entry_list), f);
1427 	a->setflag |= TIME_IS_SET;
1428 	return (ARCHIVE_OK);
1429 }
1430 
1431 /*
1432  * Test if entry is excluded by its timestamp.
1433  */
1434 static int
1435 time_excluded(struct archive_match *a, struct archive_entry *entry)
1436 {
1437 	struct match_file *f;
1438 	const void *pathname;
1439 	time_t sec;
1440 	long nsec;
1441 
1442 	/*
1443 	 * If this file/dir is excluded by a time comparison, skip it.
1444 	 */
1445 	if (a->newer_ctime_filter) {
1446 		/* If ctime is not set, use mtime instead. */
1447 		if (archive_entry_ctime_is_set(entry))
1448 			sec = archive_entry_ctime(entry);
1449 		else
1450 			sec = archive_entry_mtime(entry);
1451 		if (sec < a->newer_ctime_sec)
1452 			return (1); /* Too old, skip it. */
1453 		if (sec == a->newer_ctime_sec) {
1454 			if (archive_entry_ctime_is_set(entry))
1455 				nsec = archive_entry_ctime_nsec(entry);
1456 			else
1457 				nsec = archive_entry_mtime_nsec(entry);
1458 			if (nsec < a->newer_ctime_nsec)
1459 				return (1); /* Too old, skip it. */
1460 			if (nsec == a->newer_ctime_nsec &&
1461 			    (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL)
1462 			      == 0)
1463 				return (1); /* Equal, skip it. */
1464 		}
1465 	}
1466 	if (a->older_ctime_filter) {
1467 		/* If ctime is not set, use mtime instead. */
1468 		if (archive_entry_ctime_is_set(entry))
1469 			sec = archive_entry_ctime(entry);
1470 		else
1471 			sec = archive_entry_mtime(entry);
1472 		if (sec > a->older_ctime_sec)
1473 			return (1); /* Too new, skip it. */
1474 		if (sec == a->older_ctime_sec) {
1475 			if (archive_entry_ctime_is_set(entry))
1476 				nsec = archive_entry_ctime_nsec(entry);
1477 			else
1478 				nsec = archive_entry_mtime_nsec(entry);
1479 			if (nsec > a->older_ctime_nsec)
1480 				return (1); /* Too new, skip it. */
1481 			if (nsec == a->older_ctime_nsec &&
1482 			    (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL)
1483 			      == 0)
1484 				return (1); /* Equal, skip it. */
1485 		}
1486 	}
1487 	if (a->newer_mtime_filter) {
1488 		sec = archive_entry_mtime(entry);
1489 		if (sec < a->newer_mtime_sec)
1490 			return (1); /* Too old, skip it. */
1491 		if (sec == a->newer_mtime_sec) {
1492 			nsec = archive_entry_mtime_nsec(entry);
1493 			if (nsec < a->newer_mtime_nsec)
1494 				return (1); /* Too old, skip it. */
1495 			if (nsec == a->newer_mtime_nsec &&
1496 			    (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL)
1497 			       == 0)
1498 				return (1); /* Equal, skip it. */
1499 		}
1500 	}
1501 	if (a->older_mtime_filter) {
1502 		sec = archive_entry_mtime(entry);
1503 		if (sec > a->older_mtime_sec)
1504 			return (1); /* Too new, skip it. */
1505 		nsec = archive_entry_mtime_nsec(entry);
1506 		if (sec == a->older_mtime_sec) {
1507 			if (nsec > a->older_mtime_nsec)
1508 				return (1); /* Too new, skip it. */
1509 			if (nsec == a->older_mtime_nsec &&
1510 			    (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL)
1511 			       == 0)
1512 				return (1); /* Equal, skip it. */
1513 		}
1514 	}
1515 
1516 	/* If there is no exclusion list, include the file. */
1517 	if (a->exclusion_entry_list.count == 0)
1518 		return (0);
1519 
1520 #if defined(_WIN32) && !defined(__CYGWIN__)
1521 	pathname = archive_entry_pathname_w(entry);
1522 	a->exclusion_tree.rbt_ops = &rb_ops_wcs;
1523 #else
1524 	(void)rb_ops_wcs;
1525 	pathname = archive_entry_pathname(entry);
1526 	a->exclusion_tree.rbt_ops = &rb_ops_mbs;
1527 #endif
1528 	if (pathname == NULL)
1529 		return (0);
1530 
1531 	f = (struct match_file *)__archive_rb_tree_find_node(
1532 		&(a->exclusion_tree), pathname);
1533 	/* If the file wasn't rejected, include it. */
1534 	if (f == NULL)
1535 		return (0);
1536 
1537 	if (f->flag & ARCHIVE_MATCH_CTIME) {
1538 		sec = archive_entry_ctime(entry);
1539 		if (f->ctime_sec > sec) {
1540 			if (f->flag & ARCHIVE_MATCH_OLDER)
1541 				return (1);
1542 		} else if (f->ctime_sec < sec) {
1543 			if (f->flag & ARCHIVE_MATCH_NEWER)
1544 				return (1);
1545 		} else {
1546 			nsec = archive_entry_ctime_nsec(entry);
1547 			if (f->ctime_nsec > nsec) {
1548 				if (f->flag & ARCHIVE_MATCH_OLDER)
1549 					return (1);
1550 			} else if (f->ctime_nsec < nsec) {
1551 				if (f->flag & ARCHIVE_MATCH_NEWER)
1552 					return (1);
1553 			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
1554 				return (1);
1555 		}
1556 	}
1557 	if (f->flag & ARCHIVE_MATCH_MTIME) {
1558 		sec = archive_entry_mtime(entry);
1559 		if (f->mtime_sec > sec) {
1560 			if (f->flag & ARCHIVE_MATCH_OLDER)
1561 				return (1);
1562 		} else if (f->mtime_sec < sec) {
1563 			if (f->flag & ARCHIVE_MATCH_NEWER)
1564 				return (1);
1565 		} else {
1566 			nsec = archive_entry_mtime_nsec(entry);
1567 			if (f->mtime_nsec > nsec) {
1568 				if (f->flag & ARCHIVE_MATCH_OLDER)
1569 					return (1);
1570 			} else if (f->mtime_nsec < nsec) {
1571 				if (f->flag & ARCHIVE_MATCH_NEWER)
1572 					return (1);
1573 			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
1574 				return (1);
1575 		}
1576 	}
1577 	return (0);
1578 }
1579 
1580 /*
1581  * Utility functions to manage inclusion owners
1582  */
1583 
1584 int
1585 archive_match_include_uid(struct archive *_a, la_int64_t uid)
1586 {
1587 	struct archive_match *a;
1588 
1589 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1590 	    ARCHIVE_STATE_NEW, "archive_match_include_uid");
1591 	a = (struct archive_match *)_a;
1592 	return (add_owner_id(a, &(a->inclusion_uids), uid));
1593 }
1594 
1595 int
1596 archive_match_include_gid(struct archive *_a, la_int64_t gid)
1597 {
1598 	struct archive_match *a;
1599 
1600 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1601 	    ARCHIVE_STATE_NEW, "archive_match_include_gid");
1602 	a = (struct archive_match *)_a;
1603 	return (add_owner_id(a, &(a->inclusion_gids), gid));
1604 }
1605 
1606 int
1607 archive_match_include_uname(struct archive *_a, const char *uname)
1608 {
1609 	struct archive_match *a;
1610 
1611 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1612 	    ARCHIVE_STATE_NEW, "archive_match_include_uname");
1613 	a = (struct archive_match *)_a;
1614 	return (add_owner_name(a, &(a->inclusion_unames), 1, uname));
1615 }
1616 
1617 int
1618 archive_match_include_uname_w(struct archive *_a, const wchar_t *uname)
1619 {
1620 	struct archive_match *a;
1621 
1622 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1623 	    ARCHIVE_STATE_NEW, "archive_match_include_uname_w");
1624 	a = (struct archive_match *)_a;
1625 	return (add_owner_name(a, &(a->inclusion_unames), 0, uname));
1626 }
1627 
1628 int
1629 archive_match_include_gname(struct archive *_a, const char *gname)
1630 {
1631 	struct archive_match *a;
1632 
1633 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1634 	    ARCHIVE_STATE_NEW, "archive_match_include_gname");
1635 	a = (struct archive_match *)_a;
1636 	return (add_owner_name(a, &(a->inclusion_gnames), 1, gname));
1637 }
1638 
1639 int
1640 archive_match_include_gname_w(struct archive *_a, const wchar_t *gname)
1641 {
1642 	struct archive_match *a;
1643 
1644 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1645 	    ARCHIVE_STATE_NEW, "archive_match_include_gname_w");
1646 	a = (struct archive_match *)_a;
1647 	return (add_owner_name(a, &(a->inclusion_gnames), 0, gname));
1648 }
1649 
1650 /*
1651  * Test function for owner(uid, gid, uname, gname).
1652  *
1653  * Returns 1 if archive entry is excluded.
1654  * Returns 0 if archive entry is not excluded.
1655  * Returns <0 if something error happened.
1656  */
1657 int
1658 archive_match_owner_excluded(struct archive *_a,
1659     struct archive_entry *entry)
1660 {
1661 	struct archive_match *a;
1662 
1663 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1664 	    ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae");
1665 
1666 	a = (struct archive_match *)_a;
1667 	if (entry == NULL) {
1668 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
1669 		return (ARCHIVE_FAILED);
1670 	}
1671 
1672 	/* If we don't have inclusion id set at all, the entry is always
1673 	 * not excluded. */
1674 	if ((a->setflag & ID_IS_SET) == 0)
1675 		return (0);
1676 	return (owner_excluded(a, entry));
1677 }
1678 
1679 static int
1680 add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
1681 {
1682 	unsigned i;
1683 
1684 	if (ids->count + 1 >= ids->size) {
1685 		void *p;
1686 
1687 		if (ids->size == 0)
1688 			ids->size = 8;
1689 		else
1690 			ids->size *= 2;
1691 		p = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
1692 		if (p == NULL)
1693 			return (error_nomem(a));
1694 		ids->ids = (int64_t *)p;
1695 	}
1696 
1697 	/* Find an insert point. */
1698 	for (i = 0; i < ids->count; i++) {
1699 		if (ids->ids[i] >= id)
1700 			break;
1701 	}
1702 
1703 	/* Add owner id. */
1704 	if (i == ids->count)
1705 		ids->ids[ids->count++] = id;
1706 	else if (ids->ids[i] != id) {
1707 		memmove(&(ids->ids[i+1]), &(ids->ids[i]),
1708 		    (ids->count - i) * sizeof(ids->ids[0]));
1709 		ids->ids[i] = id;
1710 		ids->count++;
1711 	}
1712 	a->setflag |= ID_IS_SET;
1713 	return (ARCHIVE_OK);
1714 }
1715 
1716 static int
1717 match_owner_id(struct id_array *ids, int64_t id)
1718 {
1719 	unsigned b, m, t;
1720 
1721 	t = 0;
1722 	b = (unsigned)ids->count;
1723 	while (t < b) {
1724 		m = (t + b)>>1;
1725 		if (ids->ids[m] == id)
1726 			return (1);
1727 		if (ids->ids[m] < id)
1728 			t = m + 1;
1729 		else
1730 			b = m;
1731 	}
1732 	return (0);
1733 }
1734 
1735 static int
1736 add_owner_name(struct archive_match *a, struct match_list *list,
1737     int mbs, const void *name)
1738 {
1739 	struct match *match;
1740 
1741 	match = calloc(1, sizeof(*match));
1742 	if (match == NULL)
1743 		return (error_nomem(a));
1744 	if (mbs)
1745 		archive_mstring_copy_mbs(&(match->pattern), name);
1746 	else
1747 		archive_mstring_copy_wcs(&(match->pattern), name);
1748 	match_list_add(list, match);
1749 	a->setflag |= ID_IS_SET;
1750 	return (ARCHIVE_OK);
1751 }
1752 
1753 #if !defined(_WIN32) || defined(__CYGWIN__)
1754 static int
1755 match_owner_name_mbs(struct archive_match *a, struct match_list *list,
1756     const char *name)
1757 {
1758 	struct match *m;
1759 	const char *p;
1760 
1761 	if (name == NULL || *name == '\0')
1762 		return (0);
1763 	for (m = list->first; m; m = m->next) {
1764 		if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
1765 		    < 0 && errno == ENOMEM)
1766 			return (error_nomem(a));
1767 		if (p != NULL && strcmp(p, name) == 0) {
1768 			m->matches++;
1769 			return (1);
1770 		}
1771 	}
1772 	return (0);
1773 }
1774 #else
1775 static int
1776 match_owner_name_wcs(struct archive_match *a, struct match_list *list,
1777     const wchar_t *name)
1778 {
1779 	struct match *m;
1780 	const wchar_t *p;
1781 
1782 	if (name == NULL || *name == L'\0')
1783 		return (0);
1784 	for (m = list->first; m; m = m->next) {
1785 		if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p)
1786 		    < 0 && errno == ENOMEM)
1787 			return (error_nomem(a));
1788 		if (p != NULL && wcscmp(p, name) == 0) {
1789 			m->matches++;
1790 			return (1);
1791 		}
1792 	}
1793 	return (0);
1794 }
1795 #endif
1796 
1797 /*
1798  * Test if entry is excluded by uid, gid, uname or gname.
1799  */
1800 static int
1801 owner_excluded(struct archive_match *a, struct archive_entry *entry)
1802 {
1803 	int r;
1804 
1805 	if (a->inclusion_uids.count) {
1806 		if (!match_owner_id(&(a->inclusion_uids),
1807 		    archive_entry_uid(entry)))
1808 			return (1);
1809 	}
1810 
1811 	if (a->inclusion_gids.count) {
1812 		if (!match_owner_id(&(a->inclusion_gids),
1813 		    archive_entry_gid(entry)))
1814 			return (1);
1815 	}
1816 
1817 	if (a->inclusion_unames.count) {
1818 #if defined(_WIN32) && !defined(__CYGWIN__)
1819 		r = match_owner_name_wcs(a, &(a->inclusion_unames),
1820 			archive_entry_uname_w(entry));
1821 #else
1822 		r = match_owner_name_mbs(a, &(a->inclusion_unames),
1823 			archive_entry_uname(entry));
1824 #endif
1825 		if (!r)
1826 			return (1);
1827 		else if (r < 0)
1828 			return (r);
1829 	}
1830 
1831 	if (a->inclusion_gnames.count) {
1832 #if defined(_WIN32) && !defined(__CYGWIN__)
1833 		r = match_owner_name_wcs(a, &(a->inclusion_gnames),
1834 			archive_entry_gname_w(entry));
1835 #else
1836 		r = match_owner_name_mbs(a, &(a->inclusion_gnames),
1837 			archive_entry_gname(entry));
1838 #endif
1839 		if (!r)
1840 			return (1);
1841 		else if (r < 0)
1842 			return (r);
1843 	}
1844 	return (0);
1845 }
1846 
1847