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