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