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