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_pathmatch.h"
44 #include "archive_rb.h"
45 #include "archive_string.h"
46 
47 struct match {
48 	struct match		*next;
49 	int			 matches;
50 	struct archive_mstring	 pattern;
51 };
52 
53 struct match_list {
54 	struct match		*first;
55 	struct match		**last;
56 	int			 count;
57 	int			 unmatched_count;
58 	struct match		*unmatched_next;
59 	int			 unmatched_eof;
60 };
61 
62 struct match_file {
63 	struct archive_rb_node	 node;
64 	struct match_file	*next;
65 	struct archive_mstring	 pathname;
66 	int			 flag;
67 	time_t			 mtime_sec;
68 	long			 mtime_nsec;
69 	time_t			 ctime_sec;
70 	long			 ctime_nsec;
71 };
72 
73 struct entry_list {
74 	struct match_file	*first;
75 	struct match_file	**last;
76 	int			 count;
77 };
78 
79 struct id_array {
80 	size_t			 size;/* Allocated size */
81 	size_t			 count;
82 	int64_t			*ids;
83 };
84 
85 #define PATTERN_IS_SET		1
86 #define TIME_IS_SET		2
87 #define ID_IS_SET		4
88 
89 struct archive_match {
90 	struct archive		 archive;
91 
92 	/* exclusion/inclusion set flag. */
93 	int			 setflag;
94 
95 	/*
96 	 * Matching filename patterns.
97 	 */
98 	struct match_list	 exclusions;
99 	struct match_list	 inclusions;
100 
101 	/*
102 	 * Matching time stamps.
103 	 */
104 	time_t			 now;
105 	int			 newer_mtime_filter;
106 	time_t			 newer_mtime_sec;
107 	long			 newer_mtime_nsec;
108 	int			 newer_ctime_filter;
109 	time_t			 newer_ctime_sec;
110 	long			 newer_ctime_nsec;
111 	int			 older_mtime_filter;
112 	time_t			 older_mtime_sec;
113 	long			 older_mtime_nsec;
114 	int			 older_ctime_filter;
115 	time_t			 older_ctime_sec;
116 	long			 older_ctime_nsec;
117 	/*
118 	 * Matching time stamps with its filename.
119 	 */
120 	struct archive_rb_tree	 exclusion_tree;
121 	struct entry_list 	 exclusion_entry_list;
122 
123 	/*
124 	 * Matching file owners.
125 	 */
126 	struct id_array 	 inclusion_uids;
127 	struct id_array 	 inclusion_gids;
128 	struct match_list	 inclusion_unames;
129 	struct match_list	 inclusion_gnames;
130 };
131 
132 static int	add_pattern_from_file(struct archive_match *,
133 		    struct match_list *, int, const void *, int);
134 static int	add_entry(struct archive_match *, int,
135 		    struct archive_entry *);
136 static int	add_owner_id(struct archive_match *, struct id_array *,
137 		    int64_t);
138 static int	add_owner_name(struct archive_match *, struct match_list *,
139 		    int, const void *);
140 static int	add_pattern_mbs(struct archive_match *, struct match_list *,
141 		    const char *);
142 static int	add_pattern_wcs(struct archive_match *, struct match_list *,
143 		    const wchar_t *);
144 static int	cmp_key_mbs(const struct archive_rb_node *, const void *);
145 static int	cmp_key_wcs(const struct archive_rb_node *, const void *);
146 static int	cmp_node_mbs(const struct archive_rb_node *,
147 		    const struct archive_rb_node *);
148 static int	cmp_node_wcs(const struct archive_rb_node *,
149 		    const struct archive_rb_node *);
150 static void	entry_list_add(struct entry_list *, struct match_file *);
151 static void	entry_list_free(struct entry_list *);
152 static void	entry_list_init(struct entry_list *);
153 static int	error_nomem(struct archive_match *);
154 static void	match_list_add(struct match_list *, struct match *);
155 static void	match_list_free(struct match_list *);
156 static void	match_list_init(struct match_list *);
157 static int	match_list_unmatched_inclusions_next(struct archive_match *,
158 		    struct match_list *, int, const void **);
159 static int	match_owner_id(struct id_array *, int64_t);
160 #if !defined(_WIN32) || defined(__CYGWIN__)
161 static int	match_owner_name_mbs(struct archive_match *,
162 		    struct match_list *, const char *);
163 #else
164 static int	match_owner_name_wcs(struct archive_match *,
165 		    struct match_list *, const wchar_t *);
166 #endif
167 static int	match_path_exclusion(struct archive_match *,
168 		    struct match *, int, const void *);
169 static int	match_path_inclusion(struct archive_match *,
170 		    struct match *, int, const void *);
171 static int	owner_excluded(struct archive_match *,
172 		    struct archive_entry *);
173 static int	path_excluded(struct archive_match *, int, const void *);
174 static int	set_timefilter(struct archive_match *, int, time_t, long,
175 		    time_t, long);
176 static int	set_timefilter_pathname_mbs(struct archive_match *,
177 		    int, const char *);
178 static int	set_timefilter_pathname_wcs(struct archive_match *,
179 		    int, const wchar_t *);
180 static int	set_timefilter_date(struct archive_match *, int, const char *);
181 static int	set_timefilter_date_w(struct archive_match *, int,
182 		    const wchar_t *);
183 static int	time_excluded(struct archive_match *,
184 		    struct archive_entry *);
185 static int	validate_time_flag(struct archive *, int, const char *);
186 
187 time_t __archive_get_date(time_t now, const char *);
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  * Utilty 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 	if (r != ARCHIVE_OK) {
584 		archive_copy_error(&(a->archive), ar);
585 		archive_read_free(ar);
586 		return (r);
587 	}
588 	if (mbs)
589 		r = archive_read_open_filename(ar, pathname, 512*20);
590 	else
591 		r = archive_read_open_filename_w(ar, pathname, 512*20);
592 	if (r != ARCHIVE_OK) {
593 		archive_copy_error(&(a->archive), ar);
594 		archive_read_free(ar);
595 		return (r);
596 	}
597 	r = archive_read_next_header(ar, &ae);
598 	if (r != ARCHIVE_OK) {
599 		archive_copy_error(&(a->archive), ar);
600 		archive_read_free(ar);
601 		return (r);
602 	}
603 
604 	archive_string_init(&as);
605 
606 	while ((r = archive_read_data_block(ar, &buff, &size, &offset))
607 	    == ARCHIVE_OK) {
608 		const char *b = (const char *)buff;
609 
610 		while (size) {
611 			const char *s = (const char *)b;
612 			size_t length = 0;
613 			int found_separator = 0;
614 
615 			while (length < size) {
616 				if (nullSeparator) {
617 					if (*b == '\0') {
618 						found_separator = 1;
619 						break;
620 					}
621 				} else {
622 			            	if (*b == 0x0d || *b == 0x0a) {
623 						found_separator = 1;
624 						break;
625 					}
626 				}
627 				b++;
628 				length++;
629 			}
630 			if (!found_separator) {
631 				archive_strncat(&as, s, length);
632 				/* Read next data block. */
633 				break;
634 			}
635 			b++;
636 			size -= length + 1;
637 			archive_strncat(&as, s, length);
638 
639 			/* If the line is not empty, add the pattern. */
640 			if (archive_strlen(&as) > 0) {
641 				/* Add pattern. */
642 				r = add_pattern_mbs(a, mlist, as.s);
643 				if (r != ARCHIVE_OK) {
644 					archive_read_free(ar);
645 					archive_string_free(&as);
646 					return (r);
647 				}
648 				archive_string_empty(&as);
649 			}
650 		}
651 	}
652 
653 	/* If something error happend, report it immediately. */
654 	if (r < ARCHIVE_OK) {
655 		archive_copy_error(&(a->archive), ar);
656 		archive_read_free(ar);
657 		archive_string_free(&as);
658 		return (r);
659 	}
660 
661 	/* If the line is not empty, add the pattern. */
662 	if (r == ARCHIVE_EOF && archive_strlen(&as) > 0) {
663 		/* Add pattern. */
664 		r = add_pattern_mbs(a, mlist, as.s);
665 		if (r != ARCHIVE_OK) {
666 			archive_read_free(ar);
667 			archive_string_free(&as);
668 			return (r);
669 		}
670 	}
671 	archive_read_free(ar);
672 	archive_string_free(&as);
673 	return (ARCHIVE_OK);
674 }
675 
676 /*
677  * Test if pathname is excluded by inclusion/exclusion patterns.
678  */
679 static int
680 path_excluded(struct archive_match *a, int mbs, const void *pathname)
681 {
682 	struct match *match;
683 	struct match *matched;
684 	int r;
685 
686 	if (a == NULL)
687 		return (0);
688 
689 	/* Mark off any unmatched inclusions. */
690 	/* In particular, if a filename does appear in the archive and
691 	 * is explicitly included and excluded, then we don't report
692 	 * it as missing even though we don't extract it.
693 	 */
694 	matched = NULL;
695 	for (match = a->inclusions.first; match != NULL;
696 	    match = match->next){
697 		if (match->matches == 0 &&
698 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
699 			if (r < 0)
700 				return (r);
701 			a->inclusions.unmatched_count--;
702 			match->matches++;
703 			matched = match;
704 		}
705 	}
706 
707 	/* Exclusions take priority */
708 	for (match = a->exclusions.first; match != NULL;
709 	    match = match->next){
710 		r = match_path_exclusion(a, match, mbs, pathname);
711 		if (r)
712 			return (r);
713 	}
714 
715 	/* It's not excluded and we found an inclusion above, so it's
716 	 * included. */
717 	if (matched != NULL)
718 		return (0);
719 
720 
721 	/* We didn't find an unmatched inclusion, check the remaining ones. */
722 	for (match = a->inclusions.first; match != NULL;
723 	    match = match->next){
724 		/* We looked at previously-unmatched inclusions already. */
725 		if (match->matches > 0 &&
726 		    (r = match_path_inclusion(a, match, mbs, pathname)) != 0) {
727 			if (r < 0)
728 				return (r);
729 			match->matches++;
730 			return (0);
731 		}
732 	}
733 
734 	/* If there were inclusions, default is to exclude. */
735 	if (a->inclusions.first != NULL)
736 	    return (1);
737 
738 	/* No explicit inclusions, default is to match. */
739 	return (0);
740 }
741 
742 /*
743  * This is a little odd, but it matches the default behavior of
744  * gtar.  In particular, 'a*b' will match 'foo/a1111/222b/bar'
745  *
746  */
747 static int
748 match_path_exclusion(struct archive_match *a, struct match *m,
749     int mbs, const void *pn)
750 {
751 	int flag = PATHMATCH_NO_ANCHOR_START | PATHMATCH_NO_ANCHOR_END;
752 	int r;
753 
754 	if (mbs) {
755 		const char *p;
756 		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
757 		if (r == 0)
758 			return (archive_pathmatch(p, (const char *)pn, flag));
759 	} else {
760 		const wchar_t *p;
761 		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
762 		if (r == 0)
763 			return (archive_pathmatch_w(p, (const wchar_t *)pn,
764 				flag));
765 	}
766 	if (errno == ENOMEM)
767 		return (error_nomem(a));
768 	return (0);
769 }
770 
771 /*
772  * Again, mimic gtar:  inclusions are always anchored (have to match
773  * the beginning of the path) even though exclusions are not anchored.
774  */
775 static int
776 match_path_inclusion(struct archive_match *a, struct match *m,
777     int mbs, const void *pn)
778 {
779 	int flag = PATHMATCH_NO_ANCHOR_END;
780 	int r;
781 
782 	if (mbs) {
783 		const char *p;
784 		r = archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p);
785 		if (r == 0)
786 			return (archive_pathmatch(p, (const char *)pn, flag));
787 	} else {
788 		const wchar_t *p;
789 		r = archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p);
790 		if (r == 0)
791 			return (archive_pathmatch_w(p, (const wchar_t *)pn,
792 				flag));
793 	}
794 	if (errno == ENOMEM)
795 		return (error_nomem(a));
796 	return (0);
797 }
798 
799 static void
800 match_list_init(struct match_list *list)
801 {
802 	list->first = NULL;
803 	list->last = &(list->first);
804 	list->count = 0;
805 }
806 
807 static void
808 match_list_free(struct match_list *list)
809 {
810 	struct match *p, *q;
811 
812 	for (p = list->first; p != NULL; ) {
813 		q = p;
814 		p = p->next;
815 		archive_mstring_clean(&(q->pattern));
816 		free(q);
817 	}
818 }
819 
820 static void
821 match_list_add(struct match_list *list, struct match *m)
822 {
823 	*list->last = m;
824 	list->last = &(m->next);
825 	list->count++;
826 	list->unmatched_count++;
827 }
828 
829 static int
830 match_list_unmatched_inclusions_next(struct archive_match *a,
831     struct match_list *list, int mbs, const void **vp)
832 {
833 	struct match *m;
834 
835 	*vp = NULL;
836 	if (list->unmatched_eof) {
837 		list->unmatched_eof = 0;
838 		return (ARCHIVE_EOF);
839 	}
840 	if (list->unmatched_next == NULL) {
841 		if (list->unmatched_count == 0)
842 			return (ARCHIVE_EOF);
843 		list->unmatched_next = list->first;
844 	}
845 
846 	for (m = list->unmatched_next; m != NULL; m = m->next) {
847 		int r;
848 
849 		if (m->matches)
850 			continue;
851 		if (mbs) {
852 			const char *p;
853 			r = archive_mstring_get_mbs(&(a->archive),
854 				&(m->pattern), &p);
855 			if (r < 0 && errno == ENOMEM)
856 				return (error_nomem(a));
857 			if (p == NULL)
858 				p = "";
859 			*vp = p;
860 		} else {
861 			const wchar_t *p;
862 			r = archive_mstring_get_wcs(&(a->archive),
863 				&(m->pattern), &p);
864 			if (r < 0 && errno == ENOMEM)
865 				return (error_nomem(a));
866 			if (p == NULL)
867 				p = L"";
868 			*vp = p;
869 		}
870 		list->unmatched_next = m->next;
871 		if (list->unmatched_next == NULL)
872 			/* To return EOF next time. */
873 			list->unmatched_eof = 1;
874 		return (ARCHIVE_OK);
875 	}
876 	list->unmatched_next = NULL;
877 	return (ARCHIVE_EOF);
878 }
879 
880 /*
881  * Utility functions to manage inclusion timestamps.
882  */
883 int
884 archive_match_include_time(struct archive *_a, int flag, time_t sec,
885     long nsec)
886 {
887 	int r;
888 
889 	r = validate_time_flag(_a, flag, "archive_match_include_time");
890 	if (r != ARCHIVE_OK)
891 		return (r);
892 	return set_timefilter((struct archive_match *)_a, flag,
893 			sec, nsec, sec, nsec);
894 }
895 
896 int
897 archive_match_include_date(struct archive *_a, int flag,
898     const char *datestr)
899 {
900 	int r;
901 
902 	r = validate_time_flag(_a, flag, "archive_match_include_date");
903 	if (r != ARCHIVE_OK)
904 		return (r);
905 	return set_timefilter_date((struct archive_match *)_a, flag, datestr);
906 }
907 
908 int
909 archive_match_include_date_w(struct archive *_a, int flag,
910     const wchar_t *datestr)
911 {
912 	int r;
913 
914 	r = validate_time_flag(_a, flag, "archive_match_include_date_w");
915 	if (r != ARCHIVE_OK)
916 		return (r);
917 
918 	return set_timefilter_date_w((struct archive_match *)_a, flag, datestr);
919 }
920 
921 int
922 archive_match_include_file_time(struct archive *_a, int flag,
923     const char *pathname)
924 {
925 	int r;
926 
927 	r = validate_time_flag(_a, flag, "archive_match_include_file_time");
928 	if (r != ARCHIVE_OK)
929 		return (r);
930 	return set_timefilter_pathname_mbs((struct archive_match *)_a,
931 			flag, pathname);
932 }
933 
934 int
935 archive_match_include_file_time_w(struct archive *_a, int flag,
936     const wchar_t *pathname)
937 {
938 	int r;
939 
940 	r = validate_time_flag(_a, flag, "archive_match_include_file_time_w");
941 	if (r != ARCHIVE_OK)
942 		return (r);
943 	return set_timefilter_pathname_wcs((struct archive_match *)_a,
944 			flag, pathname);
945 }
946 
947 int
948 archive_match_exclude_entry(struct archive *_a, int flag,
949     struct archive_entry *entry)
950 {
951 	struct archive_match *a;
952 	int r;
953 
954 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
955 	    ARCHIVE_STATE_NEW, "archive_match_time_include_entry");
956 	a = (struct archive_match *)_a;
957 
958 	if (entry == NULL) {
959 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
960 		return (ARCHIVE_FAILED);
961 	}
962 	r = validate_time_flag(_a, flag, "archive_match_exclude_entry");
963 	if (r != ARCHIVE_OK)
964 		return (r);
965 	return (add_entry(a, flag, entry));
966 }
967 
968 /*
969  * Test function for time stamps.
970  *
971  * Returns 1 if archive entry is excluded.
972  * Returns 0 if archive entry is not excluded.
973  * Returns <0 if something error happened.
974  */
975 int
976 archive_match_time_excluded(struct archive *_a,
977     struct archive_entry *entry)
978 {
979 	struct archive_match *a;
980 
981 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
982 	    ARCHIVE_STATE_NEW, "archive_match_time_excluded_ae");
983 
984 	a = (struct archive_match *)_a;
985 	if (entry == NULL) {
986 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
987 		return (ARCHIVE_FAILED);
988 	}
989 
990 	/* If we don't have inclusion time set at all, the entry is always
991 	 * not excluded. */
992 	if ((a->setflag & TIME_IS_SET) == 0)
993 		return (0);
994 	return (time_excluded(a, entry));
995 }
996 
997 static int
998 validate_time_flag(struct archive *_a, int flag, const char *_fn)
999 {
1000 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1001 	    ARCHIVE_STATE_NEW, _fn);
1002 
1003 	/* Check a type of time. */
1004 	if (flag &
1005 	   ((~(ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) & 0xff00)) {
1006 		archive_set_error(_a, EINVAL, "Invalid time flag");
1007 		return (ARCHIVE_FAILED);
1008 	}
1009 	if ((flag & (ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME)) == 0) {
1010 		archive_set_error(_a, EINVAL, "No time flag");
1011 		return (ARCHIVE_FAILED);
1012 	}
1013 
1014 	/* Check a type of comparison. */
1015 	if (flag &
1016 	   ((~(ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
1017 			| ARCHIVE_MATCH_EQUAL)) & 0x00ff)) {
1018 		archive_set_error(_a, EINVAL, "Invalid comparison flag");
1019 		return (ARCHIVE_FAILED);
1020 	}
1021 	if ((flag & (ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER
1022 	    | ARCHIVE_MATCH_EQUAL)) == 0) {
1023 		archive_set_error(_a, EINVAL, "No comparison flag");
1024 		return (ARCHIVE_FAILED);
1025 	}
1026 
1027 	return (ARCHIVE_OK);
1028 }
1029 
1030 #define JUST_EQUAL(t) (((t) &  (ARCHIVE_MATCH_EQUAL |\
1031 	ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_OLDER)) == ARCHIVE_MATCH_EQUAL)
1032 static int
1033 set_timefilter(struct archive_match *a, int timetype,
1034     time_t mtime_sec, long mtime_nsec, time_t ctime_sec, long ctime_nsec)
1035 {
1036 	if (timetype & ARCHIVE_MATCH_MTIME) {
1037 		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
1038 			a->newer_mtime_filter = timetype;
1039 			a->newer_mtime_sec = mtime_sec;
1040 			a->newer_mtime_nsec = mtime_nsec;
1041 			a->setflag |= TIME_IS_SET;
1042 		}
1043 		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
1044 			a->older_mtime_filter = timetype;
1045 			a->older_mtime_sec = mtime_sec;
1046 			a->older_mtime_nsec = mtime_nsec;
1047 			a->setflag |= TIME_IS_SET;
1048 		}
1049 	}
1050 	if (timetype & ARCHIVE_MATCH_CTIME) {
1051 		if ((timetype & ARCHIVE_MATCH_NEWER) || JUST_EQUAL(timetype)) {
1052 			a->newer_ctime_filter = timetype;
1053 			a->newer_ctime_sec = ctime_sec;
1054 			a->newer_ctime_nsec = ctime_nsec;
1055 			a->setflag |= TIME_IS_SET;
1056 		}
1057 		if ((timetype & ARCHIVE_MATCH_OLDER) || JUST_EQUAL(timetype)) {
1058 			a->older_ctime_filter = timetype;
1059 			a->older_ctime_sec = ctime_sec;
1060 			a->older_ctime_nsec = ctime_nsec;
1061 			a->setflag |= TIME_IS_SET;
1062 		}
1063 	}
1064 	return (ARCHIVE_OK);
1065 }
1066 
1067 static int
1068 set_timefilter_date(struct archive_match *a, int timetype, const char *datestr)
1069 {
1070 	time_t t;
1071 
1072 	if (datestr == NULL || *datestr == '\0') {
1073 		archive_set_error(&(a->archive), EINVAL, "date is empty");
1074 		return (ARCHIVE_FAILED);
1075 	}
1076 	t = get_date(a->now, datestr);
1077 	if (t == (time_t)-1) {
1078 		archive_set_error(&(a->archive), EINVAL, "invalid date string");
1079 		return (ARCHIVE_FAILED);
1080 	}
1081 	return set_timefilter(a, timetype, t, 0, t, 0);
1082 }
1083 
1084 static int
1085 set_timefilter_date_w(struct archive_match *a, int timetype,
1086     const wchar_t *datestr)
1087 {
1088 	struct archive_string as;
1089 	time_t t;
1090 
1091 	if (datestr == NULL || *datestr == L'\0') {
1092 		archive_set_error(&(a->archive), EINVAL, "date is empty");
1093 		return (ARCHIVE_FAILED);
1094 	}
1095 
1096 	archive_string_init(&as);
1097 	if (archive_string_append_from_wcs(&as, datestr, wcslen(datestr)) < 0) {
1098 		archive_string_free(&as);
1099 		if (errno == ENOMEM)
1100 			return (error_nomem(a));
1101 		archive_set_error(&(a->archive), -1,
1102 		    "Failed to convert WCS to MBS");
1103 		return (ARCHIVE_FAILED);
1104 	}
1105 	t = get_date(a->now, as.s);
1106 	archive_string_free(&as);
1107 	if (t == (time_t)-1) {
1108 		archive_set_error(&(a->archive), EINVAL, "invalid date string");
1109 		return (ARCHIVE_FAILED);
1110 	}
1111 	return set_timefilter(a, timetype, t, 0, t, 0);
1112 }
1113 
1114 #if defined(_WIN32) && !defined(__CYGWIN__)
1115 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
1116 static int
1117 set_timefilter_find_data(struct archive_match *a, int timetype,
1118     DWORD ftLastWriteTime_dwHighDateTime, DWORD ftLastWriteTime_dwLowDateTime,
1119     DWORD ftCreationTime_dwHighDateTime, DWORD ftCreationTime_dwLowDateTime)
1120 {
1121 	ULARGE_INTEGER utc;
1122 	time_t ctime_sec, mtime_sec;
1123 	long ctime_ns, mtime_ns;
1124 
1125 	utc.HighPart = ftCreationTime_dwHighDateTime;
1126 	utc.LowPart = ftCreationTime_dwLowDateTime;
1127 	if (utc.QuadPart >= EPOC_TIME) {
1128 		utc.QuadPart -= EPOC_TIME;
1129 		ctime_sec = (time_t)(utc.QuadPart / 10000000);
1130 		ctime_ns = (long)(utc.QuadPart % 10000000) * 100;
1131 	} else {
1132 		ctime_sec = 0;
1133 		ctime_ns = 0;
1134 	}
1135 	utc.HighPart = ftLastWriteTime_dwHighDateTime;
1136 	utc.LowPart = ftLastWriteTime_dwLowDateTime;
1137 	if (utc.QuadPart >= EPOC_TIME) {
1138 		utc.QuadPart -= EPOC_TIME;
1139 		mtime_sec = (time_t)(utc.QuadPart / 10000000);
1140 		mtime_ns = (long)(utc.QuadPart % 10000000) * 100;
1141 	} else {
1142 		mtime_sec = 0;
1143 		mtime_ns = 0;
1144 	}
1145 	return set_timefilter(a, timetype,
1146 			mtime_sec, mtime_ns, ctime_sec, ctime_ns);
1147 }
1148 
1149 static int
1150 set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
1151     const char *path)
1152 {
1153 	/* NOTE: stat() on Windows cannot handle nano seconds. */
1154 	HANDLE h;
1155 	WIN32_FIND_DATA d;
1156 
1157 	if (path == NULL || *path == '\0') {
1158 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1159 		return (ARCHIVE_FAILED);
1160 	}
1161 	h = FindFirstFileA(path, &d);
1162 	if (h == INVALID_HANDLE_VALUE) {
1163 		la_dosmaperr(GetLastError());
1164 		archive_set_error(&(a->archive), errno,
1165 		    "Failed to FindFirstFileA");
1166 		return (ARCHIVE_FAILED);
1167 	}
1168 	FindClose(h);
1169 	return set_timefilter_find_data(a, timetype,
1170 	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
1171 	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
1172 }
1173 
1174 static int
1175 set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
1176     const wchar_t *path)
1177 {
1178 	HANDLE h;
1179 	WIN32_FIND_DATAW d;
1180 
1181 	if (path == NULL || *path == L'\0') {
1182 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1183 		return (ARCHIVE_FAILED);
1184 	}
1185 	h = FindFirstFileW(path, &d);
1186 	if (h == INVALID_HANDLE_VALUE) {
1187 		la_dosmaperr(GetLastError());
1188 		archive_set_error(&(a->archive), errno,
1189 		    "Failed to FindFirstFile");
1190 		return (ARCHIVE_FAILED);
1191 	}
1192 	FindClose(h);
1193 	return set_timefilter_find_data(a, timetype,
1194 	    d.ftLastWriteTime.dwHighDateTime, d.ftLastWriteTime.dwLowDateTime,
1195 	    d.ftCreationTime.dwHighDateTime, d.ftCreationTime.dwLowDateTime);
1196 }
1197 
1198 #else /* _WIN32 && !__CYGWIN__ */
1199 
1200 static int
1201 set_timefilter_stat(struct archive_match *a, int timetype, struct stat *st)
1202 {
1203 	struct archive_entry *ae;
1204 	time_t ctime_sec, mtime_sec;
1205 	long ctime_ns, mtime_ns;
1206 
1207 	ae = archive_entry_new();
1208 	if (ae == NULL)
1209 		return (error_nomem(a));
1210 	archive_entry_copy_stat(ae, st);
1211 	ctime_sec = archive_entry_ctime(ae);
1212 	ctime_ns = archive_entry_ctime_nsec(ae);
1213 	mtime_sec = archive_entry_mtime(ae);
1214 	mtime_ns = archive_entry_mtime_nsec(ae);
1215 	archive_entry_free(ae);
1216 	return set_timefilter(a, timetype, mtime_sec, mtime_ns,
1217 			ctime_sec, ctime_ns);
1218 }
1219 
1220 static int
1221 set_timefilter_pathname_mbs(struct archive_match *a, int timetype,
1222     const char *path)
1223 {
1224 	struct stat st;
1225 
1226 	if (path == NULL || *path == '\0') {
1227 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1228 		return (ARCHIVE_FAILED);
1229 	}
1230 	if (stat(path, &st) != 0) {
1231 		archive_set_error(&(a->archive), errno, "Failed to stat()");
1232 		return (ARCHIVE_FAILED);
1233 	}
1234 	return (set_timefilter_stat(a, timetype, &st));
1235 }
1236 
1237 static int
1238 set_timefilter_pathname_wcs(struct archive_match *a, int timetype,
1239     const wchar_t *path)
1240 {
1241 	struct archive_string as;
1242 	int r;
1243 
1244 	if (path == NULL || *path == L'\0') {
1245 		archive_set_error(&(a->archive), EINVAL, "pathname is empty");
1246 		return (ARCHIVE_FAILED);
1247 	}
1248 
1249 	/* Convert WCS filename to MBS filename. */
1250 	archive_string_init(&as);
1251 	if (archive_string_append_from_wcs(&as, path, wcslen(path)) < 0) {
1252 		archive_string_free(&as);
1253 		if (errno == ENOMEM)
1254 			return (error_nomem(a));
1255 		archive_set_error(&(a->archive), -1,
1256 		    "Failed to convert WCS to MBS");
1257 		return (ARCHIVE_FAILED);
1258 	}
1259 
1260 	r = set_timefilter_pathname_mbs(a, timetype, as.s);
1261 	archive_string_free(&as);
1262 
1263 	return (r);
1264 }
1265 #endif /* _WIN32 && !__CYGWIN__ */
1266 
1267 /*
1268  * Call back funtions for archive_rb.
1269  */
1270 static int
1271 cmp_node_mbs(const struct archive_rb_node *n1,
1272     const struct archive_rb_node *n2)
1273 {
1274 	struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
1275 	struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
1276 	const char *p1, *p2;
1277 
1278 	archive_mstring_get_mbs(NULL, &(f1->pathname), &p1);
1279 	archive_mstring_get_mbs(NULL, &(f2->pathname), &p2);
1280 	if (p1 == NULL)
1281 		return (1);
1282 	if (p2 == NULL)
1283 		return (-1);
1284 	return (strcmp(p1, p2));
1285 }
1286 
1287 static int
1288 cmp_key_mbs(const struct archive_rb_node *n, const void *key)
1289 {
1290 	struct match_file *f = (struct match_file *)(uintptr_t)n;
1291 	const char *p;
1292 
1293 	archive_mstring_get_mbs(NULL, &(f->pathname), &p);
1294 	if (p == NULL)
1295 		return (-1);
1296 	return (strcmp(p, (const char *)key));
1297 }
1298 
1299 static int
1300 cmp_node_wcs(const struct archive_rb_node *n1,
1301     const struct archive_rb_node *n2)
1302 {
1303 	struct match_file *f1 = (struct match_file *)(uintptr_t)n1;
1304 	struct match_file *f2 = (struct match_file *)(uintptr_t)n2;
1305 	const wchar_t *p1, *p2;
1306 
1307 	archive_mstring_get_wcs(NULL, &(f1->pathname), &p1);
1308 	archive_mstring_get_wcs(NULL, &(f2->pathname), &p2);
1309 	if (p1 == NULL)
1310 		return (1);
1311 	if (p2 == NULL)
1312 		return (-1);
1313 	return (wcscmp(p1, p2));
1314 }
1315 
1316 static int
1317 cmp_key_wcs(const struct archive_rb_node *n, const void *key)
1318 {
1319 	struct match_file *f = (struct match_file *)(uintptr_t)n;
1320 	const wchar_t *p;
1321 
1322 	archive_mstring_get_wcs(NULL, &(f->pathname), &p);
1323 	if (p == NULL)
1324 		return (-1);
1325 	return (wcscmp(p, (const wchar_t *)key));
1326 }
1327 
1328 static void
1329 entry_list_init(struct entry_list *list)
1330 {
1331 	list->first = NULL;
1332 	list->last = &(list->first);
1333 	list->count = 0;
1334 }
1335 
1336 static void
1337 entry_list_free(struct entry_list *list)
1338 {
1339 	struct match_file *p, *q;
1340 
1341 	for (p = list->first; p != NULL; ) {
1342 		q = p;
1343 		p = p->next;
1344 		archive_mstring_clean(&(q->pathname));
1345 		free(q);
1346 	}
1347 }
1348 
1349 static void
1350 entry_list_add(struct entry_list *list, struct match_file *file)
1351 {
1352 	*list->last = file;
1353 	list->last = &(file->next);
1354 	list->count++;
1355 }
1356 
1357 static int
1358 add_entry(struct archive_match *a, int flag,
1359     struct archive_entry *entry)
1360 {
1361 	struct match_file *f;
1362 	const void *pathname;
1363 	int r;
1364 
1365 	f = calloc(1, sizeof(*f));
1366 	if (f == NULL)
1367 		return (error_nomem(a));
1368 
1369 #if defined(_WIN32) && !defined(__CYGWIN__)
1370 	pathname = archive_entry_pathname_w(entry);
1371 	if (pathname == NULL) {
1372 		free(f);
1373 		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
1374 		return (ARCHIVE_FAILED);
1375 	}
1376 	archive_mstring_copy_wcs(&(f->pathname), pathname);
1377 	a->exclusion_tree.rbt_ops = &rb_ops_wcs;
1378 #else
1379 	pathname = archive_entry_pathname(entry);
1380 	if (pathname == NULL) {
1381 		free(f);
1382 		archive_set_error(&(a->archive), EINVAL, "pathname is NULL");
1383 		return (ARCHIVE_FAILED);
1384 	}
1385 	archive_mstring_copy_mbs(&(f->pathname), pathname);
1386 	a->exclusion_tree.rbt_ops = &rb_ops_mbs;
1387 #endif
1388 	f->flag = flag;
1389 	f->mtime_sec = archive_entry_mtime(entry);
1390 	f->mtime_nsec = archive_entry_mtime_nsec(entry);
1391 	f->ctime_sec = archive_entry_ctime(entry);
1392 	f->ctime_nsec = archive_entry_ctime_nsec(entry);
1393 	r = __archive_rb_tree_insert_node(&(a->exclusion_tree), &(f->node));
1394 	if (!r) {
1395 		struct match_file *f2;
1396 
1397 		/* Get the duplicated file. */
1398 		f2 = (struct match_file *)__archive_rb_tree_find_node(
1399 			&(a->exclusion_tree), pathname);
1400 
1401 		/*
1402 		 * We always overwrite comparison condision.
1403 		 * If you do not want to overwrite it, you should not
1404 		 * call archive_match_exclude_entry(). We cannot know
1405 		 * what behavior you really expect since overwriting
1406 		 * condition might be different with the flag.
1407 		 */
1408 		if (f2 != NULL) {
1409 			f2->flag = f->flag;
1410 			f2->mtime_sec = f->mtime_sec;
1411 			f2->mtime_nsec = f->mtime_nsec;
1412 			f2->ctime_sec = f->ctime_sec;
1413 			f2->ctime_nsec = f->ctime_nsec;
1414 		}
1415 		/* Release the duplicated file. */
1416 		archive_mstring_clean(&(f->pathname));
1417 		free(f);
1418 		return (ARCHIVE_OK);
1419 	}
1420 	entry_list_add(&(a->exclusion_entry_list), f);
1421 	a->setflag |= TIME_IS_SET;
1422 	return (ARCHIVE_OK);
1423 }
1424 
1425 /*
1426  * Test if entry is excluded by its timestamp.
1427  */
1428 static int
1429 time_excluded(struct archive_match *a, struct archive_entry *entry)
1430 {
1431 	struct match_file *f;
1432 	const void *pathname;
1433 	time_t sec;
1434 	long nsec;
1435 
1436 	/*
1437 	 * If this file/dir is excluded by a time comparison, skip it.
1438 	 */
1439 	if (a->newer_ctime_filter) {
1440 		/* If ctime is not set, use mtime instead. */
1441 		if (archive_entry_ctime_is_set(entry))
1442 			sec = archive_entry_ctime(entry);
1443 		else
1444 			sec = archive_entry_mtime(entry);
1445 		if (sec < a->newer_ctime_sec)
1446 			return (1); /* Too old, skip it. */
1447 		if (sec == a->newer_ctime_sec) {
1448 			if (archive_entry_ctime_is_set(entry))
1449 				nsec = archive_entry_ctime_nsec(entry);
1450 			else
1451 				nsec = archive_entry_mtime_nsec(entry);
1452 			if (nsec < a->newer_ctime_nsec)
1453 				return (1); /* Too old, skip it. */
1454 			if (nsec == a->newer_ctime_nsec &&
1455 			    (a->newer_ctime_filter & ARCHIVE_MATCH_EQUAL)
1456 			      == 0)
1457 				return (1); /* Equal, skip it. */
1458 		}
1459 	}
1460 	if (a->older_ctime_filter) {
1461 		/* If ctime is not set, use mtime instead. */
1462 		if (archive_entry_ctime_is_set(entry))
1463 			sec = archive_entry_ctime(entry);
1464 		else
1465 			sec = archive_entry_mtime(entry);
1466 		if (sec > a->older_ctime_sec)
1467 			return (1); /* Too new, skip it. */
1468 		if (sec == a->older_ctime_sec) {
1469 			if (archive_entry_ctime_is_set(entry))
1470 				nsec = archive_entry_ctime_nsec(entry);
1471 			else
1472 				nsec = archive_entry_mtime_nsec(entry);
1473 			if (nsec > a->older_ctime_nsec)
1474 				return (1); /* Too new, skip it. */
1475 			if (nsec == a->older_ctime_nsec &&
1476 			    (a->older_ctime_filter & ARCHIVE_MATCH_EQUAL)
1477 			      == 0)
1478 				return (1); /* Eeual, skip it. */
1479 		}
1480 	}
1481 	if (a->newer_mtime_filter) {
1482 		sec = archive_entry_mtime(entry);
1483 		if (sec < a->newer_mtime_sec)
1484 			return (1); /* Too old, skip it. */
1485 		if (sec == a->newer_mtime_sec) {
1486 			nsec = archive_entry_mtime_nsec(entry);
1487 			if (nsec < a->newer_mtime_nsec)
1488 				return (1); /* Too old, skip it. */
1489 			if (nsec == a->newer_mtime_nsec &&
1490 			    (a->newer_mtime_filter & ARCHIVE_MATCH_EQUAL)
1491 			       == 0)
1492 				return (1); /* Equal, skip it. */
1493 		}
1494 	}
1495 	if (a->older_mtime_filter) {
1496 		sec = archive_entry_mtime(entry);
1497 		if (sec > a->older_mtime_sec)
1498 			return (1); /* Too new, skip it. */
1499 		nsec = archive_entry_mtime_nsec(entry);
1500 		if (sec == a->older_mtime_sec) {
1501 			if (nsec > a->older_mtime_nsec)
1502 				return (1); /* Too new, skip it. */
1503 			if (nsec == a->older_mtime_nsec &&
1504 			    (a->older_mtime_filter & ARCHIVE_MATCH_EQUAL)
1505 			       == 0)
1506 				return (1); /* Equal, skip it. */
1507 		}
1508 	}
1509 
1510 	/* If there is no excluson list, include the file. */
1511 	if (a->exclusion_entry_list.count == 0)
1512 		return (0);
1513 
1514 #if defined(_WIN32) && !defined(__CYGWIN__)
1515 	pathname = archive_entry_pathname_w(entry);
1516 	a->exclusion_tree.rbt_ops = &rb_ops_wcs;
1517 #else
1518 	pathname = archive_entry_pathname(entry);
1519 	a->exclusion_tree.rbt_ops = &rb_ops_mbs;
1520 #endif
1521 	if (pathname == NULL)
1522 		return (0);
1523 
1524 	f = (struct match_file *)__archive_rb_tree_find_node(
1525 		&(a->exclusion_tree), pathname);
1526 	/* If the file wasn't rejected, include it. */
1527 	if (f == NULL)
1528 		return (0);
1529 
1530 	if (f->flag & ARCHIVE_MATCH_CTIME) {
1531 		sec = archive_entry_ctime(entry);
1532 		if (f->ctime_sec > sec) {
1533 			if (f->flag & ARCHIVE_MATCH_OLDER)
1534 				return (1);
1535 		} else if (f->ctime_sec < sec) {
1536 			if (f->flag & ARCHIVE_MATCH_NEWER)
1537 				return (1);
1538 		} else {
1539 			nsec = archive_entry_ctime_nsec(entry);
1540 			if (f->ctime_nsec > nsec) {
1541 				if (f->flag & ARCHIVE_MATCH_OLDER)
1542 					return (1);
1543 			} else if (f->ctime_nsec < nsec) {
1544 				if (f->flag & ARCHIVE_MATCH_NEWER)
1545 					return (1);
1546 			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
1547 				return (1);
1548 		}
1549 	}
1550 	if (f->flag & ARCHIVE_MATCH_MTIME) {
1551 		sec = archive_entry_mtime(entry);
1552 		if (f->mtime_sec > sec) {
1553 			if (f->flag & ARCHIVE_MATCH_OLDER)
1554 				return (1);
1555 		} else if (f->mtime_sec < sec) {
1556 			if (f->flag & ARCHIVE_MATCH_NEWER)
1557 				return (1);
1558 		} else {
1559 			nsec = archive_entry_mtime_nsec(entry);
1560 			if (f->mtime_nsec > nsec) {
1561 				if (f->flag & ARCHIVE_MATCH_OLDER)
1562 					return (1);
1563 			} else if (f->mtime_nsec < nsec) {
1564 				if (f->flag & ARCHIVE_MATCH_NEWER)
1565 					return (1);
1566 			} else if (f->flag & ARCHIVE_MATCH_EQUAL)
1567 				return (1);
1568 		}
1569 	}
1570 	return (0);
1571 }
1572 
1573 /*
1574  * Utility functions to manage inclusion owners
1575  */
1576 
1577 int
1578 archive_match_include_uid(struct archive *_a, int64_t uid)
1579 {
1580 	struct archive_match *a;
1581 
1582 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1583 	    ARCHIVE_STATE_NEW, "archive_match_include_uid");
1584 	a = (struct archive_match *)_a;
1585 	return (add_owner_id(a, &(a->inclusion_uids), uid));
1586 }
1587 
1588 int
1589 archive_match_include_gid(struct archive *_a, int64_t gid)
1590 {
1591 	struct archive_match *a;
1592 
1593 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1594 	    ARCHIVE_STATE_NEW, "archive_match_include_gid");
1595 	a = (struct archive_match *)_a;
1596 	return (add_owner_id(a, &(a->inclusion_gids), gid));
1597 }
1598 
1599 int
1600 archive_match_include_uname(struct archive *_a, const char *uname)
1601 {
1602 	struct archive_match *a;
1603 
1604 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1605 	    ARCHIVE_STATE_NEW, "archive_match_include_uname");
1606 	a = (struct archive_match *)_a;
1607 	return (add_owner_name(a, &(a->inclusion_unames), 1, uname));
1608 }
1609 
1610 int
1611 archive_match_include_uname_w(struct archive *_a, const wchar_t *uname)
1612 {
1613 	struct archive_match *a;
1614 
1615 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1616 	    ARCHIVE_STATE_NEW, "archive_match_include_uname_w");
1617 	a = (struct archive_match *)_a;
1618 	return (add_owner_name(a, &(a->inclusion_unames), 0, uname));
1619 }
1620 
1621 int
1622 archive_match_include_gname(struct archive *_a, const char *gname)
1623 {
1624 	struct archive_match *a;
1625 
1626 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1627 	    ARCHIVE_STATE_NEW, "archive_match_include_gname");
1628 	a = (struct archive_match *)_a;
1629 	return (add_owner_name(a, &(a->inclusion_gnames), 1, gname));
1630 }
1631 
1632 int
1633 archive_match_include_gname_w(struct archive *_a, const wchar_t *gname)
1634 {
1635 	struct archive_match *a;
1636 
1637 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1638 	    ARCHIVE_STATE_NEW, "archive_match_include_gname_w");
1639 	a = (struct archive_match *)_a;
1640 	return (add_owner_name(a, &(a->inclusion_gnames), 0, gname));
1641 }
1642 
1643 /*
1644  * Test function for owner(uid, gid, uname, gname).
1645  *
1646  * Returns 1 if archive entry is excluded.
1647  * Returns 0 if archive entry is not excluded.
1648  * Returns <0 if something error happened.
1649  */
1650 int
1651 archive_match_owner_excluded(struct archive *_a,
1652     struct archive_entry *entry)
1653 {
1654 	struct archive_match *a;
1655 
1656 	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
1657 	    ARCHIVE_STATE_NEW, "archive_match_id_excluded_ae");
1658 
1659 	a = (struct archive_match *)_a;
1660 	if (entry == NULL) {
1661 		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
1662 		return (ARCHIVE_FAILED);
1663 	}
1664 
1665 	/* If we don't have inclusion id set at all, the entry is always
1666 	 * not excluded. */
1667 	if ((a->setflag & ID_IS_SET) == 0)
1668 		return (0);
1669 	return (owner_excluded(a, entry));
1670 }
1671 
1672 static int
1673 add_owner_id(struct archive_match *a, struct id_array *ids, int64_t id)
1674 {
1675 	unsigned i;
1676 
1677 	if (ids->count + 1 >= ids->size) {
1678 		if (ids->size == 0)
1679 			ids->size = 8;
1680 		else
1681 			ids->size *= 2;
1682 		ids->ids = realloc(ids->ids, sizeof(*ids->ids) * ids->size);
1683 		if (ids->ids == NULL)
1684 			return (error_nomem(a));
1685 	}
1686 
1687 	/* Find an insert point. */
1688 	for (i = 0; i < ids->count; i++) {
1689 		if (ids->ids[i] >= id)
1690 			break;
1691 	}
1692 
1693 	/* Add oowner id. */
1694 	if (i == ids->count)
1695 		ids->ids[ids->count++] = id;
1696 	else if (ids->ids[i] != id) {
1697 		memmove(&(ids->ids[i+1]), &(ids->ids[i]),
1698 		    (ids->count - i) * sizeof(ids->ids[0]));
1699 		ids->ids[i] = id;
1700 		ids->count++;
1701 	}
1702 	a->setflag |= ID_IS_SET;
1703 	return (ARCHIVE_OK);
1704 }
1705 
1706 static int
1707 match_owner_id(struct id_array *ids, int64_t id)
1708 {
1709 	unsigned b, m, t;
1710 
1711 	t = 0;
1712 	b = ids->count;
1713 	while (t < b) {
1714 		m = (t + b)>>1;
1715 		if (ids->ids[m] == id)
1716 			return (1);
1717 		if (ids->ids[m] < id)
1718 			t = m + 1;
1719 		else
1720 			b = m;
1721 	}
1722 	return (0);
1723 }
1724 
1725 static int
1726 add_owner_name(struct archive_match *a, struct match_list *list,
1727     int mbs, const void *name)
1728 {
1729 	struct match *match;
1730 
1731 	match = calloc(1, sizeof(*match));
1732 	if (match == NULL)
1733 		return (error_nomem(a));
1734 	if (mbs)
1735 		archive_mstring_copy_mbs(&(match->pattern), name);
1736 	else
1737 		archive_mstring_copy_wcs(&(match->pattern), name);
1738 	match_list_add(list, match);
1739 	a->setflag |= ID_IS_SET;
1740 	return (ARCHIVE_OK);
1741 }
1742 
1743 #if !defined(_WIN32) || defined(__CYGWIN__)
1744 static int
1745 match_owner_name_mbs(struct archive_match *a, struct match_list *list,
1746     const char *name)
1747 {
1748 	struct match *m;
1749 	const char *p;
1750 
1751 	if (name == NULL || *name == '\0')
1752 		return (0);
1753 	for (m = list->first; m; m = m->next) {
1754 		if (archive_mstring_get_mbs(&(a->archive), &(m->pattern), &p)
1755 		    < 0 && errno == ENOMEM)
1756 			return (error_nomem(a));
1757 		if (p != NULL && strcmp(p, name) == 0) {
1758 			m->matches++;
1759 			return (1);
1760 		}
1761 	}
1762 	return (0);
1763 }
1764 #else
1765 static int
1766 match_owner_name_wcs(struct archive_match *a, struct match_list *list,
1767     const wchar_t *name)
1768 {
1769 	struct match *m;
1770 	const wchar_t *p;
1771 
1772 	if (name == NULL || *name == L'\0')
1773 		return (0);
1774 	for (m = list->first; m; m = m->next) {
1775 		if (archive_mstring_get_wcs(&(a->archive), &(m->pattern), &p)
1776 		    < 0 && errno == ENOMEM)
1777 			return (error_nomem(a));
1778 		if (p != NULL && wcscmp(p, name) == 0) {
1779 			m->matches++;
1780 			return (1);
1781 		}
1782 	}
1783 	return (0);
1784 }
1785 #endif
1786 
1787 /*
1788  * Test if entry is excluded by uid, gid, uname or gname.
1789  */
1790 static int
1791 owner_excluded(struct archive_match *a, struct archive_entry *entry)
1792 {
1793 	int r;
1794 
1795 	if (a->inclusion_uids.count) {
1796 		if (!match_owner_id(&(a->inclusion_uids),
1797 		    archive_entry_uid(entry)))
1798 			return (1);
1799 	}
1800 
1801 	if (a->inclusion_gids.count) {
1802 		if (!match_owner_id(&(a->inclusion_gids),
1803 		    archive_entry_gid(entry)))
1804 			return (1);
1805 	}
1806 
1807 	if (a->inclusion_unames.count) {
1808 #if defined(_WIN32) && !defined(__CYGWIN__)
1809 		r = match_owner_name_wcs(a, &(a->inclusion_unames),
1810 			archive_entry_uname_w(entry));
1811 #else
1812 		r = match_owner_name_mbs(a, &(a->inclusion_unames),
1813 			archive_entry_uname(entry));
1814 #endif
1815 		if (!r)
1816 			return (1);
1817 		else if (r < 0)
1818 			return (r);
1819 	}
1820 
1821 	if (a->inclusion_gnames.count) {
1822 #if defined(_WIN32) && !defined(__CYGWIN__)
1823 		r = match_owner_name_wcs(a, &(a->inclusion_gnames),
1824 			archive_entry_gname_w(entry));
1825 #else
1826 		r = match_owner_name_mbs(a, &(a->inclusion_gnames),
1827 			archive_entry_gname(entry));
1828 #endif
1829 		if (!r)
1830 			return (1);
1831 		else if (r < 0)
1832 			return (r);
1833 	}
1834 	return (0);
1835 }
1836 
1837