1 /*-
2  * Copyright (c) 2012 Michihiro NAKAJIMA
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include "test.h"
27 
28 #define __LIBARCHIVE_BUILD 1
29 #include "archive_getdate.h"
30 
31 static void
32 test_newer_time(void)
33 {
34 	struct archive_entry *ae;
35 	struct archive *m;
36 
37 	if (!assert((m = archive_match_new()) != NULL))
38 		return;
39 	if (!assert((ae = archive_entry_new()) != NULL)) {
40 		archive_match_free(m);
41 		return;
42 	}
43 
44 	assertEqualIntA(m, 0, archive_match_include_time(m,
45 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
46 	    ARCHIVE_MATCH_NEWER, 7880, 0));
47 
48 	archive_entry_copy_pathname(ae, "file1");
49 	archive_entry_set_mtime(ae, 7880, 0);
50 	archive_entry_set_ctime(ae, 7880, 0);
51 	failure("Both Its mtime and ctime should be excluded");
52 	assertEqualInt(1, archive_match_time_excluded(m, ae));
53 	assertEqualInt(1, archive_match_excluded(m, ae));
54 	archive_entry_set_mtime(ae, 7879, 999);
55 	archive_entry_set_ctime(ae, 7879, 999);
56 	failure("Both Its mtime and ctime should be excluded");
57 	assertEqualInt(1, archive_match_time_excluded(m, ae));
58 	assertEqualInt(1, archive_match_excluded(m, ae));
59 
60 	archive_entry_set_mtime(ae, 7881, 0);
61 	archive_entry_set_ctime(ae, 7881, 0);
62 	failure("Both Its mtime and ctime should not be excluded");
63 	assertEqualInt(0, archive_match_time_excluded(m, ae));
64 	assertEqualInt(0, archive_match_excluded(m, ae));
65 
66 	archive_entry_set_mtime(ae, 7880, 1);
67 	archive_entry_set_ctime(ae, 7880, 0);
68 	failure("Its mtime should be excluded");
69 	assertEqualInt(1, archive_match_time_excluded(m, ae));
70 	assertEqualInt(1, archive_match_excluded(m, ae));
71 
72 	archive_entry_set_mtime(ae, 7880, 0);
73 	archive_entry_set_ctime(ae, 7880, 1);
74 	failure("Its ctime should be excluded");
75 	assertEqualInt(1, archive_match_time_excluded(m, ae));
76 	assertEqualInt(1, archive_match_excluded(m, ae));
77 
78 	/* Clean up. */
79 	archive_entry_free(ae);
80 	archive_match_free(m);
81 }
82 
83 static void
84 test_newer_time_str(void)
85 {
86 	struct archive_entry *ae;
87 	struct archive *m;
88 	time_t now, t;
89 
90 	if (!assert((m = archive_match_new()) != NULL))
91 		return;
92 	if (!assert((ae = archive_entry_new()) != NULL)) {
93 		archive_match_free(m);
94 		return;
95 	}
96 
97 	time(&now);
98 
99 	assertEqualIntA(m, 0, archive_match_include_date(m,
100 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
101 	    ARCHIVE_MATCH_NEWER, "1980/2/1 0:0:0 UTC"));
102 
103 	/* Test1: Allow newer time. */
104 	archive_entry_copy_pathname(ae, "file1");
105 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
106 	archive_entry_set_mtime(ae, t, 0);
107 	archive_entry_set_ctime(ae, t, 0);
108 	failure("Both Its mtime and ctime should be excluded");
109 	assertEqualInt(1, archive_match_time_excluded(m, ae));
110 	assertEqualInt(1, archive_match_excluded(m, ae));
111 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
112 	archive_entry_set_mtime(ae, t, 0);
113 	archive_entry_set_ctime(ae, t, 0);
114 	failure("Both Its mtime and ctime should be excluded");
115 	assertEqualInt(1, archive_match_time_excluded(m, ae));
116 	assertEqualInt(1, archive_match_excluded(m, ae));
117 
118 	t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
119 	archive_entry_set_mtime(ae, t, 0);
120 	archive_entry_set_ctime(ae, t, 0);
121 	failure("Both Its mtime and ctime should not be excluded");
122 	assertEqualInt(0, archive_match_time_excluded(m, ae));
123 	assertEqualInt(0, archive_match_excluded(m, ae));
124 
125 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
126 	archive_entry_set_mtime(ae, t, 1);
127 	archive_entry_set_ctime(ae, t, 0);
128 	failure("Its mtime should be excluded");
129 	assertEqualInt(1, archive_match_time_excluded(m, ae));
130 	assertEqualInt(1, archive_match_excluded(m, ae));
131 
132 	archive_entry_set_mtime(ae, t, 0);
133 	archive_entry_set_ctime(ae, t, 1);
134 	failure("Its ctime should be excluded");
135 	assertEqualInt(1, archive_match_time_excluded(m, ae));
136 	assertEqualInt(1, archive_match_excluded(m, ae));
137 
138 
139 	/* Test2: Allow equal or newer time. */
140 	assertEqualIntA(m, 0, archive_match_include_date(m,
141 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
142 	    ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL,
143 	    "1980/2/1 0:0:0 UTC"));
144 
145 	archive_entry_copy_pathname(ae, "file1");
146 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
147 	archive_entry_set_mtime(ae, t, 0);
148 	archive_entry_set_ctime(ae, t, 0);
149 	failure("Both Its mtime and ctime should not be excluded");
150 	assertEqualInt(0, archive_match_time_excluded(m, ae));
151 	assertEqualInt(0, archive_match_excluded(m, ae));
152 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
153 	archive_entry_set_mtime(ae, t, 0);
154 	archive_entry_set_ctime(ae, t, 0);
155 	failure("Both Its mtime and ctime should be excluded");
156 	assertEqualInt(1, archive_match_time_excluded(m, ae));
157 	assertEqualInt(1, archive_match_excluded(m, ae));
158 
159 	t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
160 	archive_entry_set_mtime(ae, t, 0);
161 	archive_entry_set_ctime(ae, t, 0);
162 	failure("Both Its mtime and ctime should not be excluded");
163 	assertEqualInt(0, archive_match_time_excluded(m, ae));
164 	assertEqualInt(0, archive_match_excluded(m, ae));
165 
166 	/* Clean up. */
167 	archive_entry_free(ae);
168 	archive_match_free(m);
169 }
170 
171 static void
172 test_newer_time_str_w(void)
173 {
174 	struct archive_entry *ae;
175 	struct archive *m;
176 	time_t now, t;
177 
178 	if (!assert((m = archive_match_new()) != NULL))
179 		return;
180 	if (!assert((ae = archive_entry_new()) != NULL)) {
181 		archive_match_free(m);
182 		return;
183 	}
184 
185 	time(&now);
186 
187 	assertEqualIntA(m, 0, archive_match_include_date_w(m,
188 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
189 	    ARCHIVE_MATCH_NEWER, L"1980/2/1 0:0:0 UTC"));
190 
191 	/* Test1: Allow newer time. */
192 	archive_entry_copy_pathname(ae, "file1");
193 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
194 	archive_entry_set_mtime(ae, t, 0);
195 	archive_entry_set_ctime(ae, t, 0);
196 	failure("Both Its mtime and ctime should be excluded");
197 	assertEqualInt(1, archive_match_time_excluded(m, ae));
198 	assertEqualInt(1, archive_match_excluded(m, ae));
199 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
200 	archive_entry_set_mtime(ae, t, 0);
201 	archive_entry_set_ctime(ae, t, 0);
202 	failure("Both Its mtime and ctime should be excluded");
203 	assertEqualInt(1, archive_match_time_excluded(m, ae));
204 	assertEqualInt(1, archive_match_excluded(m, ae));
205 
206 	t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
207 	archive_entry_set_mtime(ae, t, 0);
208 	archive_entry_set_ctime(ae, t, 0);
209 	failure("Both Its mtime and ctime should not be excluded");
210 	assertEqualInt(0, archive_match_time_excluded(m, ae));
211 	assertEqualInt(0, archive_match_excluded(m, ae));
212 
213 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
214 	archive_entry_set_mtime(ae, t, 1);
215 	archive_entry_set_ctime(ae, t, 0);
216 	failure("Its mtime should be excluded");
217 	assertEqualInt(1, archive_match_time_excluded(m, ae));
218 	assertEqualInt(1, archive_match_excluded(m, ae));
219 
220 	archive_entry_set_mtime(ae, t, 0);
221 	archive_entry_set_ctime(ae, t, 1);
222 	failure("Its ctime should be excluded");
223 	assertEqualInt(1, archive_match_time_excluded(m, ae));
224 	assertEqualInt(1, archive_match_excluded(m, ae));
225 
226 
227 	/* Test2: Allow equal or newer time. */
228 	assertEqualIntA(m, 0, archive_match_include_date_w(m,
229 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
230 	    ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL,
231 	    L"1980/2/1 0:0:0 UTC"));
232 
233 	archive_entry_copy_pathname(ae, "file1");
234 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
235 	archive_entry_set_mtime(ae, t, 0);
236 	archive_entry_set_ctime(ae, t, 0);
237 	failure("Both Its mtime and ctime should not be excluded");
238 	assertEqualInt(0, archive_match_time_excluded(m, ae));
239 	assertEqualInt(0, archive_match_excluded(m, ae));
240 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
241 	archive_entry_set_mtime(ae, t, 0);
242 	archive_entry_set_ctime(ae, t, 0);
243 	failure("Both Its mtime and ctime should be excluded");
244 	assertEqualInt(1, archive_match_time_excluded(m, ae));
245 	assertEqualInt(1, archive_match_excluded(m, ae));
246 
247 	t = __archive_get_date(now, "1980/2/1 0:0:1 UTC");
248 	archive_entry_set_mtime(ae, t, 0);
249 	archive_entry_set_ctime(ae, t, 0);
250 	failure("Both Its mtime and ctime should not be excluded");
251 	assertEqualInt(0, archive_match_time_excluded(m, ae));
252 	assertEqualInt(0, archive_match_excluded(m, ae));
253 
254 	/* Clean up. */
255 	archive_entry_free(ae);
256 	archive_match_free(m);
257 }
258 
259 static void
260 test_newer_mtime_than_file_mbs(void)
261 {
262 	struct archive *a;
263 	struct archive_entry *ae;
264 	struct archive *m;
265 
266 	if (!assert((m = archive_match_new()) != NULL))
267 		return;
268 	if (!assert((ae = archive_entry_new()) != NULL)) {
269 		archive_match_free(m);
270 		return;
271 	}
272 	if (!assert((a = archive_read_disk_new()) != NULL)) {
273 		archive_match_free(m);
274 		archive_entry_free(ae);
275 		return;
276 	}
277 
278 	/*
279 	 * Test: newer mtime than a file specified in MBS file name.
280 	 */
281 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
282 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "mid_mtime"));
283 
284 	/* Verify 'old_mtime' file. */
285 	archive_entry_copy_pathname(ae, "old_mtime");
286 	assertEqualIntA(a, ARCHIVE_OK,
287 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
288 	failure("old_mtime should be excluded");
289 	assertEqualInt(1, archive_match_time_excluded(m, ae));
290 	assertEqualInt(1, archive_match_excluded(m, ae));
291 
292 	/* Verify 'mid_mtime' file. */
293 	archive_entry_clear(ae);
294 	archive_entry_copy_pathname(ae, "mid_mtime");
295 	assertEqualIntA(a, ARCHIVE_OK,
296 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
297 	failure("mid_mtime should be excluded");
298 	assertEqualInt(1, archive_match_time_excluded(m, ae));
299 	assertEqualInt(1, archive_match_excluded(m, ae));
300 
301 	/* Verify 'new_mtime' file. */
302 	archive_entry_clear(ae);
303 	archive_entry_copy_pathname(ae, "new_mtime");
304 	assertEqualIntA(a, ARCHIVE_OK,
305 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
306 	failure("new_mtime should not be excluded");
307 	assertEqualInt(0, archive_match_time_excluded(m, ae));
308 	assertEqualInt(0, archive_match_excluded(m, ae));
309 
310 	/* Clean up. */
311 	archive_read_free(a);
312 	archive_entry_free(ae);
313 	archive_match_free(m);
314 }
315 
316 static void
317 test_newer_ctime_than_file_mbs(void)
318 {
319 	struct archive *a;
320 	struct archive_entry *ae;
321 	struct archive *m;
322 
323 #if defined(_WIN32) && !defined(__CYGWIN__)
324         skipping("Can't set ctime on Windows");
325         return;
326 #endif
327 
328 	if (!assert((m = archive_match_new()) != NULL))
329 		return;
330 	if (!assert((ae = archive_entry_new()) != NULL)) {
331 		archive_match_free(m);
332 		return;
333 	}
334 	if (!assert((a = archive_read_disk_new()) != NULL)) {
335 		archive_match_free(m);
336 		archive_entry_free(ae);
337 		return;
338 	}
339 
340 	/*
341 	 * Test: newer ctime than a file specified in MBS file name.
342 	 */
343 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
344 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "mid_ctime"));
345 
346 	/* Verify 'old_ctime' file. */
347 	archive_entry_copy_pathname(ae, "old_ctime");
348 	assertEqualIntA(a, ARCHIVE_OK,
349 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
350 	failure("old_ctime should be excluded");
351 	assertEqualInt(1, archive_match_time_excluded(m, ae));
352 	assertEqualInt(1, archive_match_excluded(m, ae));
353 
354 	/* Verify 'mid_ctime' file. */
355 	archive_entry_clear(ae);
356 	archive_entry_copy_pathname(ae, "mid_ctime");
357 	assertEqualIntA(a, ARCHIVE_OK,
358 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
359 	failure("mid_ctime should be excluded");
360 	assertEqualInt(1, archive_match_time_excluded(m, ae));
361 	assertEqualInt(1, archive_match_excluded(m, ae));
362 
363 	/* Verify 'new_ctime' file. */
364 	archive_entry_clear(ae);
365 	archive_entry_copy_pathname(ae, "new_ctime");
366 	assertEqualIntA(a, ARCHIVE_OK,
367 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
368 	failure("new_ctime should not be excluded");
369 	assertEqualInt(0, archive_match_time_excluded(m, ae));
370 	assertEqualInt(0, archive_match_excluded(m, ae));
371 
372 	/* Clean up. */
373 	archive_read_free(a);
374 	archive_entry_free(ae);
375 	archive_match_free(m);
376 }
377 
378 static void
379 test_newer_mtime_than_file_wcs(void)
380 {
381 	struct archive *a;
382 	struct archive_entry *ae;
383 	struct archive *m;
384 
385 	if (!assert((m = archive_match_new()) != NULL))
386 		return;
387 	if (!assert((ae = archive_entry_new()) != NULL)) {
388 		archive_match_free(m);
389 		return;
390 	}
391 	if (!assert((a = archive_read_disk_new()) != NULL)) {
392 		archive_match_free(m);
393 		archive_entry_free(ae);
394 		return;
395 	}
396 
397 	/*
398 	 * Test: newer mtime than a file specified in WCS file name.
399 	 */
400 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
401 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"mid_mtime"));
402 
403 	/* Verify 'old_mtime' file. */
404 	archive_entry_copy_pathname(ae, "old_mtime");
405 	assertEqualIntA(a, ARCHIVE_OK,
406 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
407 	failure("old_mtime should be excluded");
408 	assertEqualInt(1, archive_match_time_excluded(m, ae));
409 	assertEqualInt(1, archive_match_excluded(m, ae));
410 
411 	/* Verify 'mid_mtime' file. */
412 	archive_entry_clear(ae);
413 	archive_entry_copy_pathname(ae, "mid_mtime");
414 	assertEqualIntA(a, ARCHIVE_OK,
415 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
416 	failure("mid_mtime should be excluded");
417 	assertEqualInt(1, archive_match_time_excluded(m, ae));
418 	assertEqualInt(1, archive_match_excluded(m, ae));
419 
420 	/* Verify 'new_mtime' file. */
421 	archive_entry_clear(ae);
422 	archive_entry_copy_pathname(ae, "new_mtime");
423 	assertEqualIntA(a, ARCHIVE_OK,
424 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
425 	failure("new_mtime should not be excluded");
426 	assertEqualInt(0, archive_match_time_excluded(m, ae));
427 	assertEqualInt(0, archive_match_excluded(m, ae));
428 
429 	/* Clean up. */
430 	archive_read_free(a);
431 	archive_entry_free(ae);
432 	archive_match_free(m);
433 }
434 
435 static void
436 test_newer_ctime_than_file_wcs(void)
437 {
438 	struct archive *a;
439 	struct archive_entry *ae;
440 	struct archive *m;
441 
442 #if defined(_WIN32) && !defined(__CYGWIN__)
443         skipping("Can't set ctime on Windows");
444         return;
445 #endif
446 
447 	if (!assert((m = archive_match_new()) != NULL))
448 		return;
449 	if (!assert((ae = archive_entry_new()) != NULL)) {
450 		archive_match_free(m);
451 		return;
452 	}
453 	if (!assert((a = archive_read_disk_new()) != NULL)) {
454 		archive_match_free(m);
455 		archive_entry_free(ae);
456 		return;
457 	}
458 
459 	/*
460 	 * Test: newer ctime than a file specified in WCS file name.
461 	 */
462 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
463 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"mid_ctime"));
464 
465 	/* Verify 'old_ctime' file. */
466 	archive_entry_clear(ae);
467 	archive_entry_copy_pathname(ae, "old_ctime");
468 	assertEqualIntA(a, ARCHIVE_OK,
469 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
470 	failure("old_ctime should be excluded");
471 	assertEqualInt(1, archive_match_time_excluded(m, ae));
472 	assertEqualInt(1, archive_match_excluded(m, ae));
473 
474 	/* Verify 'mid_ctime' file. */
475 	archive_entry_clear(ae);
476 	archive_entry_copy_pathname(ae, "mid_ctime");
477 	assertEqualIntA(a, ARCHIVE_OK,
478 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
479 	failure("mid_ctime should be excluded");
480 	assertEqualInt(1, archive_match_time_excluded(m, ae));
481 	assertEqualInt(1, archive_match_excluded(m, ae));
482 
483 	/* Verify 'new_ctime' file. */
484 	archive_entry_clear(ae);
485 	archive_entry_copy_pathname(ae, "new_ctime");
486 	assertEqualIntA(a, ARCHIVE_OK,
487 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
488 	failure("new_ctime should not be excluded");
489 	assertEqualInt(0, archive_match_time_excluded(m, ae));
490 	assertEqualInt(0, archive_match_excluded(m, ae));
491 
492 	/* Clean up. */
493 	archive_read_free(a);
494 	archive_entry_free(ae);
495 	archive_match_free(m);
496 }
497 
498 static void
499 test_older_time(void)
500 {
501 	struct archive_entry *ae;
502 	struct archive *m;
503 
504 	if (!assert((m = archive_match_new()) != NULL))
505 		return;
506 	if (!assert((ae = archive_entry_new()) != NULL)) {
507 		archive_match_free(m);
508 		return;
509 	}
510 
511 	assertEqualIntA(m, 0, archive_match_include_time(m,
512 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
513 	    ARCHIVE_MATCH_OLDER, 7880, 0));
514 
515 	archive_entry_copy_pathname(ae, "file1");
516 	archive_entry_set_mtime(ae, 7880, 0);
517 	archive_entry_set_ctime(ae, 7880, 0);
518 	failure("Both Its mtime and ctime should be excluded");
519 	assertEqualInt(1, archive_match_time_excluded(m, ae));
520 	assertEqualInt(1, archive_match_excluded(m, ae));
521 	archive_entry_set_mtime(ae, 7879, 999);
522 	archive_entry_set_ctime(ae, 7879, 999);
523 	failure("Both Its mtime and ctime should not be excluded");
524 	assertEqualInt(0, archive_match_time_excluded(m, ae));
525 	assertEqualInt(0, archive_match_excluded(m, ae));
526 
527 	archive_entry_set_mtime(ae, 7881, 0);
528 	archive_entry_set_ctime(ae, 7881, 0);
529 	failure("Both Its mtime and ctime should be excluded");
530 	assertEqualInt(1, archive_match_time_excluded(m, ae));
531 	assertEqualInt(1, archive_match_excluded(m, ae));
532 
533 	archive_entry_set_mtime(ae, 7880, 1);
534 	archive_entry_set_ctime(ae, 7879, 0);
535 	failure("Its mtime should be excluded");
536 	assertEqualInt(1, archive_match_time_excluded(m, ae));
537 	assertEqualInt(1, archive_match_excluded(m, ae));
538 
539 	archive_entry_set_mtime(ae, 7879, 0);
540 	archive_entry_set_ctime(ae, 7880, 1);
541 	failure("Its ctime should be excluded");
542 	assertEqualInt(1, archive_match_time_excluded(m, ae));
543 	assertEqualInt(1, archive_match_excluded(m, ae));
544 
545 	/* Clean up. */
546 	archive_entry_free(ae);
547 	archive_match_free(m);
548 }
549 
550 static void
551 test_older_time_str(void)
552 {
553 	struct archive_entry *ae;
554 	struct archive *m;
555 	time_t now, t;
556 
557 	if (!assert((m = archive_match_new()) != NULL))
558 		return;
559 	if (!assert((ae = archive_entry_new()) != NULL)) {
560 		archive_match_free(m);
561 		return;
562 	}
563 
564 	time(&now);
565 
566 	/* Test1: Allow newer time. */
567 	assertEqualIntA(m, 0, archive_match_include_date(m,
568 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
569 	    ARCHIVE_MATCH_OLDER, "1980/2/1 0:0:0 UTC"));
570 
571 	archive_entry_copy_pathname(ae, "file1");
572 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
573 	archive_entry_set_mtime(ae, t, 0);
574 	archive_entry_set_ctime(ae, t, 0);
575 	failure("Both Its mtime and ctime should be excluded");
576 	assertEqualInt(1, archive_match_time_excluded(m, ae));
577 	assertEqualInt(1, archive_match_excluded(m, ae));
578 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
579 	archive_entry_set_mtime(ae, t, 0);
580 	archive_entry_set_ctime(ae, t, 0);
581 	failure("Both Its mtime and ctime should not be excluded");
582 	assertEqualInt(0, archive_match_time_excluded(m, ae));
583 	assertEqualInt(0, archive_match_excluded(m, ae));
584 
585 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
586 	archive_entry_set_mtime(ae, t, 0);
587 	archive_entry_set_ctime(ae, t, 0);
588 	failure("Both Its mtime and ctime should be excluded");
589 	assertEqualInt(1, archive_match_time_excluded(m, ae));
590 	assertEqualInt(1, archive_match_excluded(m, ae));
591 
592 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
593 	archive_entry_set_mtime(ae, t, 0);
594 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
595 	archive_entry_set_ctime(ae, t, 0);
596 	failure("Its mtime should be excluded");
597 	assertEqualInt(1, archive_match_time_excluded(m, ae));
598 	assertEqualInt(1, archive_match_excluded(m, ae));
599 
600 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
601 	archive_entry_set_mtime(ae, t, 0);
602 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
603 	archive_entry_set_ctime(ae, t, 0);
604 	failure("Its ctime should be excluded");
605 	assertEqualInt(1, archive_match_time_excluded(m, ae));
606 	assertEqualInt(1, archive_match_excluded(m, ae));
607 
608 	/* Test2: Allow equal or newer time. */
609 	assertEqualIntA(m, 0, archive_match_include_date(m,
610 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
611 	    ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL,
612 	    "1980/2/1 0:0:0 UTC"));
613 
614 	archive_entry_copy_pathname(ae, "file1");
615 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
616 	archive_entry_set_mtime(ae, t, 0);
617 	archive_entry_set_ctime(ae, t, 0);
618 	failure("Both Its mtime and ctime should not be excluded");
619 	assertEqualInt(0, archive_match_time_excluded(m, ae));
620 	assertEqualInt(0, archive_match_excluded(m, ae));
621 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
622 	archive_entry_set_mtime(ae, t, 0);
623 	archive_entry_set_ctime(ae, t, 0);
624 	failure("Both Its mtime and ctime should not be excluded");
625 	assertEqualInt(0, archive_match_time_excluded(m, ae));
626 	assertEqualInt(0, archive_match_excluded(m, ae));
627 
628 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
629 	archive_entry_set_mtime(ae, t, 0);
630 	archive_entry_set_ctime(ae, t, 0);
631 	failure("Both Its mtime and ctime should be excluded");
632 	assertEqualInt(1, archive_match_time_excluded(m, ae));
633 	assertEqualInt(1, archive_match_excluded(m, ae));
634 
635 	/* Clean up. */
636 	archive_entry_free(ae);
637 	archive_match_free(m);
638 }
639 
640 static void
641 test_older_time_str_w(void)
642 {
643 	struct archive_entry *ae;
644 	struct archive *m;
645 	time_t now, t;
646 
647 	if (!assert((m = archive_match_new()) != NULL))
648 		return;
649 	if (!assert((ae = archive_entry_new()) != NULL)) {
650 		archive_match_free(m);
651 		return;
652 	}
653 
654 	time(&now);
655 
656 	/* Test1: Allow newer time. */
657 	assertEqualIntA(m, 0, archive_match_include_date_w(m,
658 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
659 	    ARCHIVE_MATCH_OLDER, L"1980/2/1 0:0:0 UTC"));
660 
661 	archive_entry_copy_pathname(ae, "file1");
662 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
663 	archive_entry_set_mtime(ae, t, 0);
664 	archive_entry_set_ctime(ae, t, 0);
665 	failure("Both Its mtime and ctime should be excluded");
666 	assertEqualInt(1, archive_match_time_excluded(m, ae));
667 	assertEqualInt(1, archive_match_excluded(m, ae));
668 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
669 	archive_entry_set_mtime(ae, t, 0);
670 	archive_entry_set_ctime(ae, t, 0);
671 	failure("Both Its mtime and ctime should not be excluded");
672 	assertEqualInt(0, archive_match_time_excluded(m, ae));
673 	assertEqualInt(0, archive_match_excluded(m, ae));
674 
675 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
676 	archive_entry_set_mtime(ae, t, 0);
677 	archive_entry_set_ctime(ae, t, 0);
678 	failure("Both Its mtime and ctime should be excluded");
679 	assertEqualInt(1, archive_match_time_excluded(m, ae));
680 	assertEqualInt(1, archive_match_excluded(m, ae));
681 
682 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
683 	archive_entry_set_mtime(ae, t, 0);
684 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
685 	archive_entry_set_ctime(ae, t, 0);
686 	failure("Its mtime should be excluded");
687 	assertEqualInt(1, archive_match_time_excluded(m, ae));
688 	assertEqualInt(1, archive_match_excluded(m, ae));
689 
690 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
691 	archive_entry_set_mtime(ae, t, 0);
692 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
693 	archive_entry_set_ctime(ae, t, 0);
694 	failure("Its ctime should be excluded");
695 	assertEqualInt(1, archive_match_time_excluded(m, ae));
696 	assertEqualInt(1, archive_match_excluded(m, ae));
697 
698 	/* Test2: Allow equal or newer time. */
699 	assertEqualIntA(m, 0, archive_match_include_date_w(m,
700 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME |
701 	    ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL,
702 	    L"1980/2/1 0:0:0 UTC"));
703 
704 	archive_entry_copy_pathname(ae, "file1");
705 	t = __archive_get_date(now, "1980/2/1 0:0:0 UTC");
706 	archive_entry_set_mtime(ae, t, 0);
707 	archive_entry_set_ctime(ae, t, 0);
708 	failure("Both Its mtime and ctime should not be excluded");
709 	assertEqualInt(0, archive_match_time_excluded(m, ae));
710 	assertEqualInt(0, archive_match_excluded(m, ae));
711 	t = __archive_get_date(now, "1980/1/1 0:0:0 UTC");
712 	archive_entry_set_mtime(ae, t, 0);
713 	archive_entry_set_ctime(ae, t, 0);
714 	failure("Both Its mtime and ctime should not be excluded");
715 	assertEqualInt(0, archive_match_time_excluded(m, ae));
716 	assertEqualInt(0, archive_match_excluded(m, ae));
717 
718 	t = __archive_get_date(now, "1980/3/1 0:0:0 UTC");
719 	archive_entry_set_mtime(ae, t, 0);
720 	archive_entry_set_ctime(ae, t, 0);
721 	failure("Both Its mtime and ctime should be excluded");
722 	assertEqualInt(1, archive_match_time_excluded(m, ae));
723 	assertEqualInt(1, archive_match_excluded(m, ae));
724 
725 	/* Clean up. */
726 	archive_entry_free(ae);
727 	archive_match_free(m);
728 }
729 
730 static void
731 test_older_mtime_than_file_mbs(void)
732 {
733 	struct archive *a;
734 	struct archive_entry *ae;
735 	struct archive *m;
736 
737 	if (!assert((m = archive_match_new()) != NULL))
738 		return;
739 	if (!assert((ae = archive_entry_new()) != NULL)) {
740 		archive_match_free(m);
741 		return;
742 	}
743 	if (!assert((a = archive_read_disk_new()) != NULL)) {
744 		archive_match_free(m);
745 		archive_entry_free(ae);
746 		return;
747 	}
748 
749 	/*
750 	 * Test: older mtime than a file specified in MBS file name.
751 	 */
752 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
753 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "mid_mtime"));
754 
755 	/* Verify 'old_mtime' file. */
756 	archive_entry_copy_pathname(ae, "old_mtime");
757 	assertEqualIntA(a, ARCHIVE_OK,
758 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
759 	failure("old_mtime should not be excluded");
760 	assertEqualInt(0, archive_match_time_excluded(m, ae));
761 	assertEqualInt(0, archive_match_excluded(m, ae));
762 
763 	/* Verify 'mid_mtime' file. */
764 	archive_entry_clear(ae);
765 	archive_entry_copy_pathname(ae, "mid_mtime");
766 	assertEqualIntA(a, ARCHIVE_OK,
767 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
768 	failure("mid_mtime should be excluded");
769 	assertEqualInt(1, archive_match_time_excluded(m, ae));
770 	assertEqualInt(1, archive_match_excluded(m, ae));
771 
772 	/* Verify 'new_mtime' file. */
773 	archive_entry_clear(ae);
774 	archive_entry_copy_pathname(ae, "new_mtime");
775 	assertEqualIntA(a, ARCHIVE_OK,
776 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
777 	failure("new_mtime should be excluded");
778 	assertEqualInt(1, archive_match_time_excluded(m, ae));
779 	assertEqualInt(1, archive_match_excluded(m, ae));
780 
781 	/* Clean up. */
782 	archive_read_free(a);
783 	archive_entry_free(ae);
784 	archive_match_free(m);
785 }
786 
787 static void
788 test_older_ctime_than_file_mbs(void)
789 {
790 	struct archive *a;
791 	struct archive_entry *ae;
792 	struct archive *m;
793 
794 #if defined(_WIN32) && !defined(__CYGWIN__)
795         skipping("Can't set ctime on Windows");
796         return;
797 #endif
798 
799 	if (!assert((m = archive_match_new()) != NULL))
800 		return;
801 	if (!assert((ae = archive_entry_new()) != NULL)) {
802 		archive_match_free(m);
803 		return;
804 	}
805 	if (!assert((a = archive_read_disk_new()) != NULL)) {
806 		archive_match_free(m);
807 		archive_entry_free(ae);
808 		return;
809 	}
810 
811 	/*
812 	 * Test: older ctime than a file specified in MBS file name.
813 	 */
814 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
815 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "mid_ctime"));
816 
817 	/* Verify 'old_ctime' file. */
818 	archive_entry_clear(ae);
819 	archive_entry_copy_pathname(ae, "old_ctime");
820 	assertEqualIntA(a, ARCHIVE_OK,
821 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
822 	failure("old_ctime should not be excluded");
823 	assertEqualInt(0, archive_match_time_excluded(m, ae));
824 	assertEqualInt(0, archive_match_excluded(m, ae));
825 
826 	/* Verify 'mid_ctime' file. */
827 	archive_entry_clear(ae);
828 	archive_entry_copy_pathname(ae, "mid_ctime");
829 	assertEqualIntA(a, ARCHIVE_OK,
830 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
831 	failure("mid_ctime should be excluded");
832 	assertEqualInt(1, archive_match_time_excluded(m, ae));
833 	assertEqualInt(1, archive_match_excluded(m, ae));
834 
835 	/* Verify 'new_ctime' file. */
836 	archive_entry_clear(ae);
837 	archive_entry_copy_pathname(ae, "new_ctime");
838 	assertEqualIntA(a, ARCHIVE_OK,
839 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
840 	failure("new_ctime should be excluded");
841 	assertEqualInt(1, archive_match_time_excluded(m, ae));
842 	assertEqualInt(1, archive_match_excluded(m, ae));
843 
844 	/* Clean up. */
845 	archive_read_free(a);
846 	archive_entry_free(ae);
847 	archive_match_free(m);
848 }
849 
850 static void
851 test_older_mtime_than_file_wcs(void)
852 {
853 	struct archive *a;
854 	struct archive_entry *ae;
855 	struct archive *m;
856 
857 	if (!assert((m = archive_match_new()) != NULL))
858 		return;
859 	if (!assert((ae = archive_entry_new()) != NULL)) {
860 		archive_match_free(m);
861 		return;
862 	}
863 	if (!assert((a = archive_read_disk_new()) != NULL)) {
864 		archive_match_free(m);
865 		archive_entry_free(ae);
866 		return;
867 	}
868 
869 	/*
870 	 * Test: older mtime than a file specified in WCS file name.
871 	 */
872 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
873 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"mid_mtime"));
874 
875 	/* Verify 'old_mtime' file. */
876 	archive_entry_copy_pathname(ae, "old_mtime");
877 	assertEqualIntA(a, ARCHIVE_OK,
878 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
879 	failure("old_mtime should not be excluded");
880 	assertEqualInt(0, archive_match_time_excluded(m, ae));
881 	assertEqualInt(0, archive_match_excluded(m, ae));
882 
883 	/* Verify 'mid_mtime' file. */
884 	archive_entry_clear(ae);
885 	archive_entry_copy_pathname(ae, "mid_mtime");
886 	assertEqualIntA(a, ARCHIVE_OK,
887 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
888 	failure("mid_mtime should be excluded");
889 	assertEqualInt(1, archive_match_time_excluded(m, ae));
890 	assertEqualInt(1, archive_match_excluded(m, ae));
891 
892 	/* Verify 'new_mtime' file. */
893 	archive_entry_clear(ae);
894 	archive_entry_copy_pathname(ae, "new_mtime");
895 	assertEqualIntA(a, ARCHIVE_OK,
896 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
897 	failure("new_mtime should be excluded");
898 	assertEqualInt(1, archive_match_time_excluded(m, ae));
899 	assertEqualInt(1, archive_match_excluded(m, ae));
900 
901 	/* Clean up. */
902 	archive_read_free(a);
903 	archive_entry_free(ae);
904 	archive_match_free(m);
905 }
906 
907 static void
908 test_older_ctime_than_file_wcs(void)
909 {
910 	struct archive *a;
911 	struct archive_entry *ae;
912 	struct archive *m;
913 
914 #if defined(_WIN32) && !defined(__CYGWIN__)
915         skipping("Can't set ctime on Windows");
916         return;
917 #endif
918 
919 	if (!assert((m = archive_match_new()) != NULL))
920 		return;
921 	if (!assert((ae = archive_entry_new()) != NULL)) {
922 		archive_match_free(m);
923 		return;
924 	}
925 	if (!assert((a = archive_read_disk_new()) != NULL)) {
926 		archive_match_free(m);
927 		archive_entry_free(ae);
928 		return;
929 	}
930 
931 	/*
932 	 * Test: older ctime than a file specified in WCS file name.
933 	 */
934 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
935 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"mid_ctime"));
936 
937 	/* Verify 'old_ctime' file. */
938 	archive_entry_clear(ae);
939 	archive_entry_copy_pathname(ae, "old_ctime");
940 	assertEqualIntA(a, ARCHIVE_OK,
941 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
942 	failure("old_ctime should not be excluded");
943 	assertEqualInt(0, archive_match_time_excluded(m, ae));
944 	assertEqualInt(0, archive_match_excluded(m, ae));
945 
946 	/* Verify 'mid_ctime' file. */
947 	archive_entry_clear(ae);
948 	archive_entry_copy_pathname(ae, "mid_ctime");
949 	assertEqualIntA(a, ARCHIVE_OK,
950 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
951 	failure("mid_ctime should be excluded");
952 	assertEqualInt(1, archive_match_time_excluded(m, ae));
953 	assertEqualInt(1, archive_match_excluded(m, ae));
954 
955 	/* Verify 'new_ctime' file. */
956 	archive_entry_clear(ae);
957 	archive_entry_copy_pathname(ae, "new_ctime");
958 	assertEqualIntA(a, ARCHIVE_OK,
959 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
960 	failure("new_ctime should be excluded");
961 	assertEqualInt(1, archive_match_time_excluded(m, ae));
962 	assertEqualInt(1, archive_match_excluded(m, ae));
963 
964 	/* Clean up. */
965 	archive_read_free(a);
966 	archive_entry_free(ae);
967 	archive_match_free(m);
968 }
969 
970 static void
971 test_mtime_between_files_mbs(void)
972 {
973 	struct archive *a;
974 	struct archive_entry *ae;
975 	struct archive *m;
976 
977 	if (!assert((m = archive_match_new()) != NULL))
978 		return;
979 	if (!assert((ae = archive_entry_new()) != NULL)) {
980 		archive_match_free(m);
981 		return;
982 	}
983 	if (!assert((a = archive_read_disk_new()) != NULL)) {
984 		archive_match_free(m);
985 		archive_entry_free(ae);
986 		return;
987 	}
988 
989 	/*
990 	 * Test: mtime between  file specified in MBS file name.
991 	 */
992 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
993 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "old_mtime"));
994 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
995 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "new_mtime"));
996 
997 	/* Verify 'old_mtime' file. */
998 	archive_entry_copy_pathname(ae, "old_mtime");
999 	assertEqualIntA(a, ARCHIVE_OK,
1000 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1001 	failure("old_mtime should be excluded");
1002 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1003 	assertEqualInt(1, archive_match_excluded(m, ae));
1004 
1005 	/* Verify 'mid_mtime' file. */
1006 	archive_entry_clear(ae);
1007 	archive_entry_copy_pathname(ae, "mid_mtime");
1008 	assertEqualIntA(a, ARCHIVE_OK,
1009 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1010 	failure("mid_mtime should not be excluded");
1011 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1012 	assertEqualInt(0, archive_match_excluded(m, ae));
1013 
1014 	/* Verify 'new_mtime' file. */
1015 	archive_entry_clear(ae);
1016 	archive_entry_copy_pathname(ae, "new_mtime");
1017 	assertEqualIntA(a, ARCHIVE_OK,
1018 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1019 	failure("new_mtime should be excluded");
1020 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1021 	assertEqualInt(1, archive_match_excluded(m, ae));
1022 
1023 	/* Clean up. */
1024 	archive_read_free(a);
1025 	archive_entry_free(ae);
1026 	archive_match_free(m);
1027 }
1028 
1029 static void
1030 test_mtime_between_files_wcs(void)
1031 {
1032 	struct archive *a;
1033 	struct archive_entry *ae;
1034 	struct archive *m;
1035 
1036 	if (!assert((m = archive_match_new()) != NULL))
1037 		return;
1038 	if (!assert((ae = archive_entry_new()) != NULL)) {
1039 		archive_match_free(m);
1040 		return;
1041 	}
1042 	if (!assert((a = archive_read_disk_new()) != NULL)) {
1043 		archive_match_free(m);
1044 		archive_entry_free(ae);
1045 		return;
1046 	}
1047 
1048 	/*
1049 	 * Test: mtime between  file specified in WCS file name.
1050 	 */
1051 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
1052 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"old_mtime"));
1053 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
1054 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"new_mtime"));
1055 
1056 	/* Verify 'old_mtime' file. */
1057 	archive_entry_copy_pathname(ae, "old_mtime");
1058 	assertEqualIntA(a, ARCHIVE_OK,
1059 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1060 	failure("old_mtime should be excluded");
1061 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1062 	assertEqualInt(1, archive_match_excluded(m, ae));
1063 
1064 	/* Verify 'mid_mtime' file. */
1065 	archive_entry_clear(ae);
1066 	archive_entry_copy_pathname(ae, "mid_mtime");
1067 	assertEqualIntA(a, ARCHIVE_OK,
1068 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1069 	failure("mid_mtime should not be excluded");
1070 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1071 	assertEqualInt(0, archive_match_excluded(m, ae));
1072 
1073 	/* Verify 'new_mtime' file. */
1074 	archive_entry_clear(ae);
1075 	archive_entry_copy_pathname(ae, "new_mtime");
1076 	assertEqualIntA(a, ARCHIVE_OK,
1077 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1078 	failure("new_mtime should be excluded");
1079 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1080 	assertEqualInt(1, archive_match_excluded(m, ae));
1081 
1082 	/* Clean up. */
1083 	archive_read_free(a);
1084 	archive_entry_free(ae);
1085 	archive_match_free(m);
1086 }
1087 
1088 static void
1089 test_ctime_between_files_mbs(void)
1090 {
1091 	struct archive *a;
1092 	struct archive_entry *ae;
1093 	struct archive *m;
1094 
1095 #if defined(_WIN32) && !defined(__CYGWIN__)
1096         skipping("Can't set ctime on Windows");
1097         return;
1098 #endif
1099 
1100 	if (!assert((m = archive_match_new()) != NULL))
1101 		return;
1102 	if (!assert((ae = archive_entry_new()) != NULL)) {
1103 		archive_match_free(m);
1104 		return;
1105 	}
1106 	if (!assert((a = archive_read_disk_new()) != NULL)) {
1107 		archive_match_free(m);
1108 		archive_entry_free(ae);
1109 		return;
1110 	}
1111 
1112 	/*
1113 	 * Test: ctime between files specified in MBS file name.
1114 	 */
1115 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
1116 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "old_ctime"));
1117 	assertEqualIntA(m, 0, archive_match_include_file_time(m,
1118 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "new_ctime"));
1119 
1120 	/* Verify 'old_ctime' file. */
1121 	archive_entry_copy_pathname(ae, "old_ctime");
1122 	assertEqualIntA(a, ARCHIVE_OK,
1123 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1124 	failure("old_ctime should be excluded");
1125 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1126 	assertEqualInt(1, archive_match_excluded(m, ae));
1127 
1128 	/* Verify 'mid_ctime' file. */
1129 	archive_entry_clear(ae);
1130 	archive_entry_copy_pathname(ae, "mid_ctime");
1131 	assertEqualIntA(a, ARCHIVE_OK,
1132 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1133 	failure("mid_ctime should not be excluded");
1134 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1135 	assertEqualInt(0, archive_match_excluded(m, ae));
1136 
1137 	/* Verify 'new_ctime' file. */
1138 	archive_entry_clear(ae);
1139 	archive_entry_copy_pathname(ae, "new_ctime");
1140 	assertEqualIntA(a, ARCHIVE_OK,
1141 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1142 	failure("new_ctime should be excluded");
1143 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1144 	assertEqualInt(1, archive_match_excluded(m, ae));
1145 
1146 	/* Clean up. */
1147 	archive_read_free(a);
1148 	archive_entry_free(ae);
1149 	archive_match_free(m);
1150 }
1151 
1152 static void
1153 test_ctime_between_files_wcs(void)
1154 {
1155 	struct archive *a;
1156 	struct archive_entry *ae;
1157 	struct archive *m;
1158 
1159 #if defined(_WIN32) && !defined(__CYGWIN__)
1160         skipping("Can't set ctime on Windows");
1161         return;
1162 #endif
1163 
1164 	if (!assert((m = archive_match_new()) != NULL))
1165 		return;
1166 	if (!assert((ae = archive_entry_new()) != NULL)) {
1167 		archive_match_free(m);
1168 		return;
1169 	}
1170 	if (!assert((a = archive_read_disk_new()) != NULL)) {
1171 		archive_match_free(m);
1172 		archive_entry_free(ae);
1173 		return;
1174 	}
1175 
1176 	/*
1177 	 * Test: ctime between files specified in WCS file name.
1178 	 */
1179 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
1180 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"old_ctime"));
1181 	assertEqualIntA(m, 0, archive_match_include_file_time_w(m,
1182 	    ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"new_ctime"));
1183 
1184 	/* Verify 'old_ctime' file. */
1185 	archive_entry_copy_pathname(ae, "old_ctime");
1186 	assertEqualIntA(a, ARCHIVE_OK,
1187 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1188 	failure("old_ctime should be excluded");
1189 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1190 	assertEqualInt(1, archive_match_excluded(m, ae));
1191 
1192 	/* Verify 'mid_ctime' file. */
1193 	archive_entry_clear(ae);
1194 	archive_entry_copy_pathname(ae, "mid_ctime");
1195 	assertEqualIntA(a, ARCHIVE_OK,
1196 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1197 	failure("mid_ctime should not be excluded");
1198 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1199 	assertEqualInt(0, archive_match_excluded(m, ae));
1200 
1201 	/* Verify 'new_ctime' file. */
1202 	archive_entry_clear(ae);
1203 	archive_entry_copy_pathname(ae, "new_ctime");
1204 	assertEqualIntA(a, ARCHIVE_OK,
1205 	    archive_read_disk_entry_from_file(a, ae, -1, NULL));
1206 	failure("new_ctime should be excluded");
1207 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1208 	assertEqualInt(1, archive_match_excluded(m, ae));
1209 
1210 	/* Clean up. */
1211 	archive_read_free(a);
1212 	archive_entry_free(ae);
1213 	archive_match_free(m);
1214 }
1215 
1216 static void
1217 excluded(struct archive *m)
1218 {
1219 	struct archive_entry *ae;
1220 
1221 	if (!assert((ae = archive_entry_new()) != NULL))
1222 		return;
1223 
1224 	archive_entry_copy_pathname(ae, "file1");
1225 	archive_entry_set_mtime(ae, 7879, 999);
1226 	failure("It should be excluded");
1227 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1228 	assertEqualInt(1, archive_match_excluded(m, ae));
1229 	archive_entry_set_mtime(ae, 7880, 0);
1230 	failure("It should be excluded");
1231 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1232 	assertEqualInt(1, archive_match_excluded(m, ae));
1233 	archive_entry_set_mtime(ae, 7880, 1);
1234 	failure("It should not be excluded");
1235 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1236 	assertEqualInt(0, archive_match_excluded(m, ae));
1237 
1238 	archive_entry_copy_pathname(ae, "file2");
1239 	archive_entry_set_mtime(ae, 7879, 999);
1240 	failure("It should not be excluded");
1241 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1242 	assertEqualInt(0, archive_match_excluded(m, ae));
1243 	archive_entry_set_mtime(ae, 7880, 0);
1244 	failure("It should not be excluded");
1245 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1246 	assertEqualInt(0, archive_match_excluded(m, ae));
1247 	archive_entry_set_mtime(ae, 7880, 1);
1248 	failure("It should not be excluded");
1249 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1250 	assertEqualInt(0, archive_match_excluded(m, ae));
1251 
1252 	archive_entry_copy_pathname(ae, "file3");
1253 	archive_entry_set_mtime(ae, 7879, 999);
1254 	failure("It should be excluded");
1255 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1256 	assertEqualInt(1, archive_match_excluded(m, ae));
1257 	archive_entry_set_mtime(ae, 7880, 0);
1258 	failure("It should be excluded");
1259 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1260 	assertEqualInt(1, archive_match_excluded(m, ae));
1261 	archive_entry_set_mtime(ae, 7880, 1);
1262 	failure("It should be excluded");
1263 	assertEqualInt(1, archive_match_time_excluded(m, ae));
1264 	assertEqualInt(1, archive_match_excluded(m, ae));
1265 
1266 	/*
1267 	 * "file4" is not registered, that sort of a file should not be
1268 	 * excluded with any mtime.
1269 	 */
1270 	archive_entry_copy_pathname(ae, "file4");
1271 	archive_entry_set_mtime(ae, 7879, 999);
1272 	failure("It should not be excluded");
1273 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1274 	assertEqualInt(0, archive_match_excluded(m, ae));
1275 	archive_entry_set_mtime(ae, 7880, 0);
1276 	failure("It should not be excluded");
1277 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1278 	assertEqualInt(0, archive_match_excluded(m, ae));
1279 	archive_entry_set_mtime(ae, 7880, 1);
1280 	failure("It should not be excluded");
1281 	assertEqualInt(0, archive_match_time_excluded(m, ae));
1282 	assertEqualInt(0, archive_match_excluded(m, ae));
1283 
1284 
1285 	/* Clean up. */
1286 	archive_entry_free(ae);
1287 }
1288 
1289 static void
1290 test_pathname_newer_mtime(void)
1291 {
1292 	struct archive_entry *ae;
1293 	struct archive *m;
1294 
1295 	if (!assert((m = archive_match_new()) != NULL))
1296 		return;
1297 	if (!assert((ae = archive_entry_new()) != NULL)) {
1298 		archive_match_free(m);
1299 		return;
1300 	}
1301 
1302 	archive_entry_copy_pathname(ae, "file1");
1303 	archive_entry_set_mtime(ae, 7880, 0);
1304 	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
1305 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
1306 	    ARCHIVE_MATCH_EQUAL, ae));
1307 	archive_entry_copy_pathname(ae, "file2");
1308 	archive_entry_set_mtime(ae, 1, 0);
1309 	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
1310 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
1311 	    ARCHIVE_MATCH_EQUAL, ae));
1312 	archive_entry_copy_pathname(ae, "file3");
1313 	archive_entry_set_mtime(ae, 99999, 0);
1314 	assertEqualIntA(m, 0, archive_match_exclude_entry(m,
1315 	    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
1316 	    ARCHIVE_MATCH_EQUAL, ae));
1317 
1318 	excluded(m);
1319 
1320 	/* Clean up. */
1321 	archive_entry_free(ae);
1322 	archive_match_free(m);
1323 }
1324 
1325 DEFINE_TEST(test_archive_match_time)
1326 {
1327 	struct stat st;
1328 
1329 	/* Test: matching newer times. */
1330 	test_newer_time();
1331 	test_newer_time_str();
1332 	test_newer_time_str_w();
1333 	/* Test: matching older times. */
1334 	test_older_time();
1335 	test_older_time_str();
1336 	test_older_time_str_w();
1337 
1338 	/*
1339 	 * Create sample files for tests matching mtime.
1340 	 * ctimes of those files may be all the same or the ctime of
1341 	 * new_mtime may be older than old_mtime.
1342 	 */
1343 	assertMakeFile("new_mtime", 0666, "new");
1344 	assertUtimes("new_mtime", 10002, 0, 10002, 0);
1345 	assertMakeFile("mid_mtime", 0666, "mid");
1346 	assertUtimes("mid_mtime", 10001, 0, 10001, 0);
1347 	assertMakeFile("old_mtime", 0666, "old");
1348 	assertUtimes("old_mtime", 10000, 0, 10000, 0);
1349 
1350 	/*
1351 	 * Create sample files for tests matching ctime.
1352 	 * the mtime of mid_ctime is older than old_ctime and also the mtime
1353 	 * of new_ctime is older than both mid_ctime and old_ctime.
1354 	 */
1355 	assertMakeFile("old_ctime", 0666, "old");
1356 	assertUtimes("old_ctime", 10002, 0, 10002, 0);
1357 	assertEqualInt(0, stat("old_ctime", &st));
1358 	sleepUntilAfter(st.st_ctime);
1359 	assertMakeFile("mid_ctime", 0666, "mid");
1360 	assertUtimes("mid_ctime", 10001, 0, 10001, 0);
1361 	assertEqualInt(0, stat("mid_ctime", &st));
1362 	sleepUntilAfter(st.st_ctime);
1363 	assertMakeFile("new_ctime", 0666, "new");
1364 	assertUtimes("new_ctime", 10000, 0, 10000, 0);
1365 
1366 	/*
1367 	 * Test: matching mtime which indicated by files on the disk.
1368 	 */
1369 	test_newer_mtime_than_file_mbs();
1370 	test_newer_mtime_than_file_wcs();
1371 	test_older_mtime_than_file_mbs();
1372 	test_older_mtime_than_file_wcs();
1373 	test_mtime_between_files_mbs();
1374 	test_mtime_between_files_wcs();
1375 
1376 	/*
1377 	 * Test: matching ctime which indicated by files on the disk.
1378 	 */
1379 	test_newer_ctime_than_file_mbs();
1380 	test_newer_ctime_than_file_wcs();
1381 	test_older_ctime_than_file_mbs();
1382 	test_older_ctime_than_file_wcs();
1383 	test_ctime_between_files_mbs();
1384 	test_ctime_between_files_wcs();
1385 
1386 	/* Test: matching both pathname and mtime. */
1387 	test_pathname_newer_mtime();
1388 }
1389