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