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