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