]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c
MFC r299529,r299540,r299576,r299896:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / test / test_read_disk_directory_traversals.c
1 /*-
2  * Copyright (c) 2010-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 #include "test.h"
26 __FBSDID("$FreeBSD$");
27
28 #include <limits.h>
29 #if defined(_WIN32) && !defined(__CYGWIN__)
30 # if !defined(__BORLANDC__)
31 #  define getcwd _getcwd
32 # endif
33 #endif
34
35 /*
36  * Test if the current filesytem is mounted with noatime option.
37  */
38 static int
39 atimeIsUpdated(void)
40 {
41         const char *fn = "fs_noatime";
42         struct stat st;
43
44         if (!assertMakeFile(fn, 0666, "a"))
45                 return (0);
46         if (!assertUtimes(fn, 1, 0, 1, 0))
47                 return (0);
48         /* Test the file contents in order to update its atime. */
49         if (!assertTextFileContents("a", fn))
50                 return (0);
51         if (stat(fn, &st) != 0)
52                 return (0);
53         /* Is atime updated? */
54         if (st.st_atime > 1)
55                 return (1);
56         return (0);
57 }
58
59 static void
60 test_basic(void)
61 {
62         struct archive *a;
63         struct archive_entry *ae;
64         const void *p;
65         char *initial_cwd, *cwd;
66         size_t size;
67         int64_t offset;
68         int file_count;
69 #if defined(_WIN32) && !defined(__CYGWIN__)
70         wchar_t *wcwd, *wp, *fullpath;
71 #endif
72
73         assertMakeDir("dir1", 0755);
74         assertMakeFile("dir1/file1", 0644, "0123456789");
75         assertMakeFile("dir1/file2", 0644, "hello world");
76         assertMakeDir("dir1/sub1", 0755);
77         assertMakeFile("dir1/sub1/file1", 0644, "0123456789");
78         assertMakeDir("dir1/sub2", 0755);
79         assertMakeFile("dir1/sub2/file1", 0644, "0123456789");
80         assertMakeFile("dir1/sub2/file2", 0644, "0123456789");
81         assertMakeDir("dir1/sub2/sub1", 0755);
82         assertMakeDir("dir1/sub2/sub2", 0755);
83         assertMakeDir("dir1/sub2/sub3", 0755);
84         assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz");
85         file_count = 12;
86
87         assert((ae = archive_entry_new()) != NULL);
88         assert((a = archive_read_disk_new()) != NULL);
89         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1"));
90
91         while (file_count--) {
92                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
93                 if (strcmp(archive_entry_pathname(ae), "dir1") == 0) {
94                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
95                         assertEqualInt(1, archive_read_disk_can_descend(a));
96                 } else if (strcmp(archive_entry_pathname(ae),
97                     "dir1/file1") == 0) {
98                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
99                         assertEqualInt(archive_entry_size(ae), 10);
100                         assertEqualIntA(a, ARCHIVE_OK,
101                             archive_read_data_block(a, &p, &size, &offset));
102                         assertEqualInt((int)size, 10);
103                         assertEqualInt((int)offset, 0);
104                         assertEqualMem(p, "0123456789", 10);
105                         assertEqualInt(ARCHIVE_EOF,
106                             archive_read_data_block(a, &p, &size, &offset));
107                         assertEqualInt((int)size, 0);
108                         assertEqualInt((int)offset, 10);
109                         assertEqualInt(0, archive_read_disk_can_descend(a));
110                 } else if (strcmp(archive_entry_pathname(ae),
111                     "dir1/file2") == 0) {
112                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
113                         assertEqualInt(archive_entry_size(ae), 11);
114                         assertEqualIntA(a, ARCHIVE_OK,
115                             archive_read_data_block(a, &p, &size, &offset));
116                         assertEqualInt((int)size, 11);
117                         assertEqualInt((int)offset, 0);
118                         assertEqualMem(p, "hello world", 11);
119                         assertEqualInt(ARCHIVE_EOF,
120                             archive_read_data_block(a, &p, &size, &offset));
121                         assertEqualInt((int)size, 0);
122                         assertEqualInt((int)offset, 11);
123                         assertEqualInt(0, archive_read_disk_can_descend(a));
124                 } else if (strcmp(archive_entry_pathname(ae),
125                     "dir1/sub1") == 0) {
126                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
127                         assertEqualInt(1, archive_read_disk_can_descend(a));
128                 } else if (strcmp(archive_entry_pathname(ae),
129                     "dir1/sub1/file1") == 0) {
130                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
131                         assertEqualInt(archive_entry_size(ae), 10);
132                         assertEqualIntA(a, ARCHIVE_OK,
133                             archive_read_data_block(a, &p, &size, &offset));
134                         assertEqualInt((int)size, 10);
135                         assertEqualInt((int)offset, 0);
136                         assertEqualMem(p, "0123456789", 10);
137                         assertEqualInt(ARCHIVE_EOF,
138                             archive_read_data_block(a, &p, &size, &offset));
139                         assertEqualInt((int)size, 0);
140                         assertEqualInt((int)offset, 10);
141                         assertEqualInt(0, archive_read_disk_can_descend(a));
142                 } else if (strcmp(archive_entry_pathname(ae),
143                     "dir1/sub2") == 0) {
144                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
145                         assertEqualInt(1, archive_read_disk_can_descend(a));
146                 } else if (strcmp(archive_entry_pathname(ae),
147                     "dir1/sub2/file1") == 0) {
148                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
149                         assertEqualInt(archive_entry_size(ae), 10);
150                         assertEqualIntA(a, ARCHIVE_OK,
151                             archive_read_data_block(a, &p, &size, &offset));
152                         assertEqualInt((int)size, 10);
153                         assertEqualInt((int)offset, 0);
154                         assertEqualMem(p, "0123456789", 10);
155                         assertEqualInt(ARCHIVE_EOF,
156                             archive_read_data_block(a, &p, &size, &offset));
157                         assertEqualInt((int)size, 0);
158                         assertEqualInt((int)offset, 10);
159                         assertEqualInt(0, archive_read_disk_can_descend(a));
160                 } else if (strcmp(archive_entry_pathname(ae),
161                     "dir1/sub2/file2") == 0) {
162                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
163                         assertEqualInt(archive_entry_size(ae), 10);
164                         assertEqualIntA(a, ARCHIVE_OK,
165                             archive_read_data_block(a, &p, &size, &offset));
166                         assertEqualInt((int)size, 10);
167                         assertEqualInt((int)offset, 0);
168                         assertEqualMem(p, "0123456789", 10);
169                         assertEqualInt(ARCHIVE_EOF,
170                             archive_read_data_block(a, &p, &size, &offset));
171                         assertEqualInt((int)size, 0);
172                         assertEqualInt((int)offset, 10);
173                         assertEqualInt(0, archive_read_disk_can_descend(a));
174                 } else if (strcmp(archive_entry_pathname(ae),
175                     "dir1/sub2/sub1") == 0) {
176                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
177                         assertEqualInt(1, archive_read_disk_can_descend(a));
178                 } else if (strcmp(archive_entry_pathname(ae),
179                     "dir1/sub2/sub2") == 0) {
180                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
181                         assertEqualInt(1, archive_read_disk_can_descend(a));
182                 } else if (strcmp(archive_entry_pathname(ae),
183                     "dir1/sub2/sub3") == 0) {
184                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
185                         assertEqualInt(1, archive_read_disk_can_descend(a));
186                 } else if (strcmp(archive_entry_pathname(ae),
187                     "dir1/sub2/sub3/file") == 0) {
188                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
189                         assertEqualInt(archive_entry_size(ae), 3);
190                         assertEqualIntA(a, ARCHIVE_OK,
191                             archive_read_data_block(a, &p, &size, &offset));
192                         assertEqualInt((int)size, 3);
193                         assertEqualInt((int)offset, 0);
194                         assertEqualMem(p, "xyz", 3);
195                         assertEqualInt(ARCHIVE_EOF,
196                             archive_read_data_block(a, &p, &size, &offset));
197                         assertEqualInt((int)size, 0);
198                         assertEqualInt((int)offset, 3);
199                         assertEqualInt(0, archive_read_disk_can_descend(a));
200                 }
201                 if (archive_entry_filetype(ae) == AE_IFDIR) {
202                         /* Descend into the current object */
203                         assertEqualIntA(a, ARCHIVE_OK,
204                             archive_read_disk_descend(a));
205                 }
206         }
207         /* There is no entry. */
208         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
209
210         /* Close the disk object. */
211         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
212
213         /*
214          * Test that call archive_read_disk_open_w, wchar_t version.
215          */
216         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1"));
217
218         file_count = 12;
219         while (file_count--) {
220                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
221                 if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) {
222                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
223                         assertEqualInt(1, archive_read_disk_can_descend(a));
224                 } else if (wcscmp(archive_entry_pathname_w(ae),
225                     L"dir1/file1") == 0) {
226                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
227                         assertEqualInt(archive_entry_size(ae), 10);
228                         assertEqualIntA(a, ARCHIVE_OK,
229                             archive_read_data_block(a, &p, &size, &offset));
230                         assertEqualInt((int)size, 10);
231                         assertEqualInt((int)offset, 0);
232                         assertEqualMem(p, "0123456789", 10);
233                         assertEqualInt(ARCHIVE_EOF,
234                             archive_read_data_block(a, &p, &size, &offset));
235                         assertEqualInt((int)size, 0);
236                         assertEqualInt((int)offset, 10);
237                         assertEqualInt(0, archive_read_disk_can_descend(a));
238                 } else if (wcscmp(archive_entry_pathname_w(ae),
239                     L"dir1/file2") == 0) {
240                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
241                         assertEqualInt(archive_entry_size(ae), 11);
242                         assertEqualIntA(a, ARCHIVE_OK,
243                             archive_read_data_block(a, &p, &size, &offset));
244                         assertEqualInt((int)size, 11);
245                         assertEqualInt((int)offset, 0);
246                         assertEqualMem(p, "hello world", 11);
247                         assertEqualInt(ARCHIVE_EOF,
248                             archive_read_data_block(a, &p, &size, &offset));
249                         assertEqualInt((int)size, 0);
250                         assertEqualInt((int)offset, 11);
251                         assertEqualInt(0, archive_read_disk_can_descend(a));
252                 } else if (wcscmp(archive_entry_pathname_w(ae),
253                     L"dir1/sub1") == 0) {
254                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
255                         assertEqualInt(1, archive_read_disk_can_descend(a));
256                 } else if (wcscmp(archive_entry_pathname_w(ae),
257                     L"dir1/sub1/file1") == 0) {
258                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
259                         assertEqualInt(archive_entry_size(ae), 10);
260                         assertEqualIntA(a, ARCHIVE_OK,
261                             archive_read_data_block(a, &p, &size, &offset));
262                         assertEqualInt((int)size, 10);
263                         assertEqualInt((int)offset, 0);
264                         assertEqualMem(p, "0123456789", 10);
265                         assertEqualInt(ARCHIVE_EOF,
266                             archive_read_data_block(a, &p, &size, &offset));
267                         assertEqualInt((int)size, 0);
268                         assertEqualInt((int)offset, 10);
269                         assertEqualInt(0, archive_read_disk_can_descend(a));
270                 } else if (wcscmp(archive_entry_pathname_w(ae),
271                     L"dir1/sub2") == 0) {
272                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
273                         assertEqualInt(1, archive_read_disk_can_descend(a));
274                 } else if (wcscmp(archive_entry_pathname_w(ae),
275                     L"dir1/sub2/file1") == 0) {
276                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
277                         assertEqualInt(archive_entry_size(ae), 10);
278                         assertEqualIntA(a, ARCHIVE_OK,
279                             archive_read_data_block(a, &p, &size, &offset));
280                         assertEqualInt((int)size, 10);
281                         assertEqualInt((int)offset, 0);
282                         assertEqualMem(p, "0123456789", 10);
283                         assertEqualInt(ARCHIVE_EOF,
284                             archive_read_data_block(a, &p, &size, &offset));
285                         assertEqualInt((int)size, 0);
286                         assertEqualInt((int)offset, 10);
287                         assertEqualInt(0, archive_read_disk_can_descend(a));
288                 } else if (wcscmp(archive_entry_pathname_w(ae),
289                     L"dir1/sub2/file2") == 0) {
290                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
291                         assertEqualInt(archive_entry_size(ae), 10);
292                         assertEqualIntA(a, ARCHIVE_OK,
293                             archive_read_data_block(a, &p, &size, &offset));
294                         assertEqualInt((int)size, 10);
295                         assertEqualInt((int)offset, 0);
296                         assertEqualMem(p, "0123456789", 10);
297                         assertEqualInt(ARCHIVE_EOF,
298                             archive_read_data_block(a, &p, &size, &offset));
299                         assertEqualInt((int)size, 0);
300                         assertEqualInt((int)offset, 10);
301                         assertEqualInt(0, archive_read_disk_can_descend(a));
302                 } else if (wcscmp(archive_entry_pathname_w(ae),
303                     L"dir1/sub2/sub1") == 0) {
304                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
305                         assertEqualInt(1, archive_read_disk_can_descend(a));
306                 } else if (wcscmp(archive_entry_pathname_w(ae),
307                     L"dir1/sub2/sub2") == 0) {
308                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
309                         assertEqualInt(1, archive_read_disk_can_descend(a));
310                 } else if (wcscmp(archive_entry_pathname_w(ae),
311                     L"dir1/sub2/sub3") == 0) {
312                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
313                         assertEqualInt(1, archive_read_disk_can_descend(a));
314                 } else if (wcscmp(archive_entry_pathname_w(ae),
315                     L"dir1/sub2/sub3/file") == 0) {
316                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
317                         assertEqualInt(archive_entry_size(ae), 3);
318                         assertEqualIntA(a, ARCHIVE_OK,
319                             archive_read_data_block(a, &p, &size, &offset));
320                         assertEqualInt((int)size, 3);
321                         assertEqualInt((int)offset, 0);
322                         assertEqualMem(p, "xyz", 3);
323                         assertEqualInt(ARCHIVE_EOF,
324                             archive_read_data_block(a, &p, &size, &offset));
325                         assertEqualInt((int)size, 0);
326                         assertEqualInt((int)offset, 3);
327                         assertEqualInt(0, archive_read_disk_can_descend(a));
328                 }
329                 if (archive_entry_filetype(ae) == AE_IFDIR) {
330                         /* Descend into the current object */
331                         assertEqualIntA(a, ARCHIVE_OK,
332                             archive_read_disk_descend(a));
333                 }
334         }
335         /* There is no entry. */
336         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
337
338         /* Close the disk object. */
339         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
340
341         /*
342          * Test that call archive_read_disk_open with a regular file.
343          */
344         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1"));
345
346         /* dir1/file1 */
347         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
348         assertEqualInt(0, archive_read_disk_can_descend(a));
349         assertEqualString(archive_entry_pathname(ae), "dir1/file1");
350         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
351         assertEqualInt(archive_entry_size(ae), 10);
352         assertEqualIntA(a, ARCHIVE_OK,
353             archive_read_data_block(a, &p, &size, &offset));
354         assertEqualInt((int)size, 10);
355         assertEqualInt((int)offset, 0);
356         assertEqualMem(p, "0123456789", 10);
357
358         /* There is no entry. */
359         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
360
361         /* Close the disk object. */
362         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
363
364
365 #if defined(_WIN32) && !defined(__CYGWIN__)
366         /*
367          * Test for wildcard '*' or '?'
368          */
369         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1"));
370
371         /* dir1/file1 */
372         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
373         assertEqualInt(0, archive_read_disk_can_descend(a));
374         assertEqualString(archive_entry_pathname(ae), "dir1/file1");
375         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
376         assertEqualInt(archive_entry_size(ae), 10);
377         assertEqualIntA(a, ARCHIVE_OK,
378             archive_read_data_block(a, &p, &size, &offset));
379         assertEqualInt((int)size, 10);
380         assertEqualInt((int)offset, 0);
381         assertEqualMem(p, "0123456789", 10);
382
383         /* dir1/sub1 */
384         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
385         assertEqualInt(1, archive_read_disk_can_descend(a));
386         assertEqualString(archive_entry_pathname(ae), "dir1/sub1");
387         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
388
389         /* Descend into the current object */
390         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
391
392         /* dir1/sub1/file1 */
393         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
394         assertEqualInt(0, archive_read_disk_can_descend(a));
395         assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1");
396         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
397         assertEqualInt(archive_entry_size(ae), 10);
398         assertEqualIntA(a, ARCHIVE_OK,
399             archive_read_data_block(a, &p, &size, &offset));
400         assertEqualInt((int)size, 10);
401         assertEqualInt((int)offset, 0);
402         assertEqualMem(p, "0123456789", 10);
403
404         /* There is no entry. */
405         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
406
407         /* Close the disk object. */
408         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
409
410         /*
411          * Test for a full-path beginning with "//?/"
412          */
413         wcwd = _wgetcwd(NULL, 0);
414         fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
415         wcscpy(fullpath, L"//?/");
416         wcscat(fullpath, wcwd);
417         wcscat(fullpath, L"/dir1/file1");
418         free(wcwd);
419         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
420         while ((wcwd = wcschr(fullpath, L'\\')) != NULL)
421                 *wcwd = L'/';
422
423         /* dir1/file1 */
424         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
425         assertEqualInt(0, archive_read_disk_can_descend(a));
426         assertEqualWString(archive_entry_pathname_w(ae), fullpath);
427         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
428         assertEqualInt(archive_entry_size(ae), 10);
429         assertEqualIntA(a, ARCHIVE_OK,
430             archive_read_data_block(a, &p, &size, &offset));
431         assertEqualInt((int)size, 10);
432         assertEqualInt((int)offset, 0);
433         assertEqualMem(p, "0123456789", 10);
434
435         /* There is no entry. */
436         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
437
438         /* Close the disk object. */
439         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
440         free(fullpath);
441
442         /*
443          * Test for wild card '*' or '?' with "//?/" prefix.
444          */
445         wcwd = _wgetcwd(NULL, 0);
446         fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32));
447         wcscpy(fullpath, L"//?/");
448         wcscat(fullpath, wcwd);
449         wcscat(fullpath, L"/dir1/*1");
450         free(wcwd);
451         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath));
452         while ((wcwd = wcschr(fullpath, L'\\')) != NULL)
453                 *wcwd = L'/';
454
455         /* dir1/file1 */
456         wp = wcsrchr(fullpath, L'/');
457         wcscpy(wp+1, L"file1");
458         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
459         assertEqualInt(0, archive_read_disk_can_descend(a));
460         assertEqualWString(archive_entry_pathname_w(ae), fullpath);
461         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
462         assertEqualInt(archive_entry_size(ae), 10);
463         assertEqualIntA(a, ARCHIVE_OK,
464             archive_read_data_block(a, &p, &size, &offset));
465         assertEqualInt((int)size, 10);
466         assertEqualInt((int)offset, 0);
467         assertEqualMem(p, "0123456789", 10);
468
469         /* dir1/sub1 */
470         wcscpy(wp+1, L"sub1");
471         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
472         assertEqualInt(1, archive_read_disk_can_descend(a));
473         assertEqualWString(archive_entry_pathname_w(ae), fullpath);
474         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
475
476         /* Descend into the current object */
477         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
478
479         /* dir1/sub1/file1 */
480         wcscpy(wp+1, L"sub1/file1");
481         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
482         assertEqualInt(0, archive_read_disk_can_descend(a));
483         assertEqualWString(archive_entry_pathname_w(ae), fullpath);
484         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
485         assertEqualInt(archive_entry_size(ae), 10);
486         assertEqualIntA(a, ARCHIVE_OK,
487             archive_read_data_block(a, &p, &size, &offset));
488         assertEqualInt((int)size, 10);
489         assertEqualInt((int)offset, 0);
490         assertEqualMem(p, "0123456789", 10);
491
492         /* There is no entry. */
493         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
494
495         /* Close the disk object. */
496         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
497         free(fullpath);
498
499 #endif
500
501         /*
502          * We should be on the initial directory where we performed
503          * archive_read_disk_new() after we perfome archive_read_free()
504          *  even if we broke off the directory traversals.
505          */
506
507         /* Save current working directory. */
508 #ifdef PATH_MAX
509         initial_cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
510 #else
511         initial_cwd = getcwd(NULL, 0);
512 #endif
513
514         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1"));
515
516         /* Step in a deep directory. */
517         file_count = 12;
518         while (file_count--) {
519                 assertEqualIntA(a, ARCHIVE_OK,
520                     archive_read_next_header2(a, ae));
521                 if (strcmp(archive_entry_pathname(ae),
522                     "dir1/sub1/file1") == 0)
523                         /*
524                          * We are on an another directory at this time.
525                          */
526                         break;
527                 if (archive_entry_filetype(ae) == AE_IFDIR) {
528                         /* Descend into the current object */
529                         assertEqualIntA(a, ARCHIVE_OK,
530                             archive_read_disk_descend(a));
531                 }
532         }
533         /* Destroy the disk object. */
534         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
535
536         /* We should be on the initial working directory. */
537         failure(
538             "Current working directory does not return to the initial"
539             "directory");
540 #ifdef PATH_MAX
541         cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */
542 #else
543         cwd = getcwd(NULL, 0);
544 #endif
545         assertEqualString(initial_cwd, cwd);
546         free(initial_cwd);
547         free(cwd);
548
549         archive_entry_free(ae);
550 }
551
552 static void
553 test_symlink_hybrid(void)
554 {
555         struct archive *a;
556         struct archive_entry *ae;
557         const void *p;
558         size_t size;
559         int64_t offset;
560         int file_count;
561
562         if (!canSymlink()) {
563                 skipping("Can't test symlinks on this filesystem");
564                 return;
565         }
566
567         /*
568          * Create a sample archive.
569          */
570         assertMakeDir("h", 0755);
571         assertChdir("h");
572         assertMakeDir("d1", 0755);
573         assertMakeSymlink("ld1", "d1");
574         assertMakeFile("d1/file1", 0644, "d1/file1");
575         assertMakeFile("d1/file2", 0644, "d1/file2");
576         assertMakeSymlink("d1/link1", "file1");
577         assertMakeSymlink("d1/linkX", "fileX");
578         assertMakeSymlink("link2", "d1/file2");
579         assertMakeSymlink("linkY", "d1/fileY");
580         assertChdir("..");
581
582         assert((ae = archive_entry_new()) != NULL);
583         assert((a = archive_read_disk_new()) != NULL);
584         assertEqualIntA(a, ARCHIVE_OK,
585             archive_read_disk_set_symlink_hybrid(a));
586
587         /*
588          * Specified file is a symbolic link file.
589          */
590         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h/ld1"));
591         file_count = 5;
592
593         while (file_count--) {
594                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
595                 if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) {
596                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
597                 } else if (strcmp(archive_entry_pathname(ae),
598                     "h/ld1/file1") == 0) {
599                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
600                         assertEqualInt(archive_entry_size(ae), 8);
601                         assertEqualIntA(a, ARCHIVE_OK,
602                             archive_read_data_block(a, &p, &size, &offset));
603                         assertEqualInt((int)size, 8);
604                         assertEqualInt((int)offset, 0);
605                         assertEqualMem(p, "d1/file1", 8);
606                         assertEqualInt(ARCHIVE_EOF,
607                             archive_read_data_block(a, &p, &size, &offset));
608                         assertEqualInt((int)size, 0);
609                         assertEqualInt((int)offset, 8);
610                 } else if (strcmp(archive_entry_pathname(ae),
611                     "h/ld1/file2") == 0) {
612                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
613                         assertEqualInt(archive_entry_size(ae), 8);
614                         assertEqualIntA(a, ARCHIVE_OK,
615                             archive_read_data_block(a, &p, &size, &offset));
616                         assertEqualInt((int)size, 8);
617                         assertEqualInt((int)offset, 0);
618                         assertEqualMem(p, "d1/file2", 8);
619                         assertEqualInt(ARCHIVE_EOF,
620                             archive_read_data_block(a, &p, &size, &offset));
621                         assertEqualInt((int)size, 0);
622                         assertEqualInt((int)offset, 8);
623                 } else if (strcmp(archive_entry_pathname(ae),
624                     "h/ld1/link1") == 0) {
625                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
626                 } else if (strcmp(archive_entry_pathname(ae),
627                     "h/ld1/linkX") == 0) {
628                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
629                 }
630                 if (archive_entry_filetype(ae) == AE_IFDIR) {
631                         /* Descend into the current object */
632                         assertEqualIntA(a, ARCHIVE_OK,
633                             archive_read_disk_descend(a));
634                 }
635         }
636         /* There is no entry. */
637         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
638         /* Close the disk object. */
639         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
640
641         /*
642          * Specified file is a directory and it has symbolic files.
643          */
644         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h"));
645         file_count = 9;
646
647         while (file_count--) {
648                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
649                 if (strcmp(archive_entry_pathname(ae), "h") == 0) {
650                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
651                 } else if (strcmp(archive_entry_pathname(ae), "h/d1") == 0) {
652                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
653                 } else if (strcmp(archive_entry_pathname(ae),
654                     "h/d1/file1") == 0) {
655                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
656                         assertEqualInt(archive_entry_size(ae), 8);
657                         assertEqualIntA(a, ARCHIVE_OK,
658                             archive_read_data_block(a, &p, &size, &offset));
659                         assertEqualInt((int)size, 8);
660                         assertEqualInt((int)offset, 0);
661                         assertEqualMem(p, "d1/file1", 8);
662                         assertEqualInt(ARCHIVE_EOF,
663                             archive_read_data_block(a, &p, &size, &offset));
664                         assertEqualInt((int)size, 0);
665                         assertEqualInt((int)offset, 8);
666                 } else if (strcmp(archive_entry_pathname(ae),
667                     "h/d1/file2") == 0) {
668                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
669                         assertEqualInt(archive_entry_size(ae), 8);
670                         assertEqualIntA(a, ARCHIVE_OK,
671                             archive_read_data_block(a, &p, &size, &offset));
672                         assertEqualInt((int)size, 8);
673                         assertEqualInt((int)offset, 0);
674                         assertEqualMem(p, "d1/file2", 8);
675                         assertEqualInt(ARCHIVE_EOF,
676                             archive_read_data_block(a, &p, &size, &offset));
677                         assertEqualInt((int)size, 0);
678                         assertEqualInt((int)offset, 8);
679                 } else if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) {
680                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
681                 } else if (strcmp(archive_entry_pathname(ae),
682                     "h/d1/link1") == 0) {
683                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
684                 } else if (strcmp(archive_entry_pathname(ae),
685                     "h/d1/linkX") == 0) {
686                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
687                 } else if (strcmp(archive_entry_pathname(ae),
688                     "h/link2") == 0) {
689                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
690                 } else if (strcmp(archive_entry_pathname(ae),
691                     "h/linkY") == 0) {
692                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
693                 }
694                 if (archive_entry_filetype(ae) == AE_IFDIR) {
695                         /* Descend into the current object */
696                         assertEqualIntA(a, ARCHIVE_OK,
697                             archive_read_disk_descend(a));
698                 }
699         }
700         /* There is no entry. */
701         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
702         /* Close the disk object. */
703         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
704         /* Destroy the disk object. */
705         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
706         archive_entry_free(ae);
707 }
708
709 static void
710 test_symlink_logical(void)
711 {
712         struct archive *a;
713         struct archive_entry *ae;
714         const void *p;
715         size_t size;
716         int64_t offset;
717         int file_count;
718
719         if (!canSymlink()) {
720                 skipping("Can't test symlinks on this filesystem");
721                 return;
722         }
723
724         /*
725          * Create a sample archive.
726          */
727         assertMakeDir("l", 0755);
728         assertChdir("l");
729         assertMakeDir("d1", 0755);
730         assertMakeSymlink("ld1", "d1");
731         assertMakeFile("d1/file1", 0644, "d1/file1");
732         assertMakeFile("d1/file2", 0644, "d1/file2");
733         assertMakeSymlink("d1/link1", "file1");
734         assertMakeSymlink("d1/linkX", "fileX");
735         assertMakeSymlink("link2", "d1/file2");
736         assertMakeSymlink("linkY", "d1/fileY");
737         assertChdir("..");
738
739         /* Note: this test uses archive_read_next_header()
740            instead of archive_read_next_header2() */
741         assert((a = archive_read_disk_new()) != NULL);
742         assertEqualIntA(a, ARCHIVE_OK,
743             archive_read_disk_set_symlink_logical(a));
744
745         /*
746          * Specified file is a symbolic link file.
747          */
748         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l/ld1"));
749         file_count = 5;
750
751         while (file_count--) {
752                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
753                 if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) {
754                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
755                 } else if (strcmp(archive_entry_pathname(ae),
756                     "l/ld1/file1") == 0) {
757                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
758                         assertEqualInt(archive_entry_size(ae), 8);
759                         assertEqualIntA(a, ARCHIVE_OK,
760                             archive_read_data_block(a, &p, &size, &offset));
761                         assertEqualInt((int)size, 8);
762                         assertEqualInt((int)offset, 0);
763                         assertEqualMem(p, "d1/file1", 8);
764                         assertEqualInt(ARCHIVE_EOF,
765                             archive_read_data_block(a, &p, &size, &offset));
766                         assertEqualInt((int)size, 0);
767                         assertEqualInt((int)offset, 8);
768                 } else if (strcmp(archive_entry_pathname(ae),
769                     "l/ld1/file2") == 0) {
770                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
771                         assertEqualInt(archive_entry_size(ae), 8);
772                         assertEqualIntA(a, ARCHIVE_OK,
773                             archive_read_data_block(a, &p, &size, &offset));
774                         assertEqualInt((int)size, 8);
775                         assertEqualInt((int)offset, 0);
776                         assertEqualMem(p, "d1/file2", 8);
777                         assertEqualInt(ARCHIVE_EOF,
778                             archive_read_data_block(a, &p, &size, &offset));
779                         assertEqualInt((int)size, 0);
780                         assertEqualInt((int)offset, 8);
781                 } else if (strcmp(archive_entry_pathname(ae),
782                     "l/ld1/link1") == 0) {
783                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
784                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
785                         assertEqualInt(archive_entry_size(ae), 8);
786                         assertEqualIntA(a, ARCHIVE_OK,
787                             archive_read_data_block(a, &p, &size, &offset));
788                         assertEqualInt((int)size, 8);
789                         assertEqualInt((int)offset, 0);
790                         assertEqualMem(p, "d1/file1", 8);
791                         assertEqualInt(ARCHIVE_EOF,
792                             archive_read_data_block(a, &p, &size, &offset));
793                         assertEqualInt((int)size, 0);
794                         assertEqualInt((int)offset, 8);
795                 } else if (strcmp(archive_entry_pathname(ae),
796                     "l/ld1/linkX") == 0) {
797                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
798                 }
799                 if (archive_entry_filetype(ae) == AE_IFDIR) {
800                         /* Descend into the current object */
801                         assertEqualIntA(a, ARCHIVE_OK,
802                             archive_read_disk_descend(a));
803                 }
804         }
805         /* There is no entry. */
806         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
807         /* Close the disk object. */
808         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
809
810         /*
811          * Specified file is a directory and it has symbolic files.
812          */
813         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l"));
814         file_count = 13;
815
816         while (file_count--) {
817                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
818                 if (strcmp(archive_entry_pathname(ae), "l") == 0) {
819                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
820                 } else if (strcmp(archive_entry_pathname(ae), "l/d1") == 0) {
821                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
822                 } else if (strcmp(archive_entry_pathname(ae),
823                     "l/d1/file1") == 0) {
824                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
825                         assertEqualInt(archive_entry_size(ae), 8);
826                         assertEqualIntA(a, ARCHIVE_OK,
827                             archive_read_data_block(a, &p, &size, &offset));
828                         assertEqualInt((int)size, 8);
829                         assertEqualInt((int)offset, 0);
830                         assertEqualMem(p, "d1/file1", 8);
831                         assertEqualInt(ARCHIVE_EOF,
832                             archive_read_data_block(a, &p, &size, &offset));
833                         assertEqualInt((int)size, 0);
834                         assertEqualInt((int)offset, 8);
835                 } else if (strcmp(archive_entry_pathname(ae),
836                     "l/d1/file2") == 0) {
837                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
838                         assertEqualInt(archive_entry_size(ae), 8);
839                         assertEqualIntA(a, ARCHIVE_OK,
840                             archive_read_data_block(a, &p, &size, &offset));
841                         assertEqualInt((int)size, 8);
842                         assertEqualInt((int)offset, 0);
843                         assertEqualMem(p, "d1/file2", 8);
844                         assertEqualInt(ARCHIVE_EOF,
845                             archive_read_data_block(a, &p, &size, &offset));
846                         assertEqualInt((int)size, 0);
847                         assertEqualInt((int)offset, 8);
848                 } else if (strcmp(archive_entry_pathname(ae),
849                     "l/d1/link1") == 0) {
850                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
851                         assertEqualInt(archive_entry_size(ae), 8);
852                         assertEqualIntA(a, ARCHIVE_OK,
853                             archive_read_data_block(a, &p, &size, &offset));
854                         assertEqualInt((int)size, 8);
855                         assertEqualInt((int)offset, 0);
856                         assertEqualMem(p, "d1/file1", 8);
857                         assertEqualInt(ARCHIVE_EOF,
858                             archive_read_data_block(a, &p, &size, &offset));
859                         assertEqualInt((int)size, 0);
860                         assertEqualInt((int)offset, 8);
861                 } else if (strcmp(archive_entry_pathname(ae),
862                     "l/d1/linkX") == 0) {
863                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
864                 } else if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) {
865                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
866                 } else if (strcmp(archive_entry_pathname(ae),
867                     "l/ld1/file1") == 0) {
868                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
869                         assertEqualInt(archive_entry_size(ae), 8);
870                         assertEqualIntA(a, ARCHIVE_OK,
871                             archive_read_data_block(a, &p, &size, &offset));
872                         assertEqualInt((int)size, 8);
873                         assertEqualInt((int)offset, 0);
874                         assertEqualMem(p, "d1/file1", 8);
875                         assertEqualInt(ARCHIVE_EOF,
876                             archive_read_data_block(a, &p, &size, &offset));
877                         assertEqualInt((int)size, 0);
878                         assertEqualInt((int)offset, 8);
879                 } else if (strcmp(archive_entry_pathname(ae),
880                     "l/ld1/file2") == 0) {
881                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
882                         assertEqualInt(archive_entry_size(ae), 8);
883                         assertEqualIntA(a, ARCHIVE_OK,
884                             archive_read_data_block(a, &p, &size, &offset));
885                         assertEqualInt((int)size, 8);
886                         assertEqualInt((int)offset, 0);
887                         assertEqualMem(p, "d1/file2", 8);
888                         assertEqualInt(ARCHIVE_EOF,
889                             archive_read_data_block(a, &p, &size, &offset));
890                         assertEqualInt((int)size, 0);
891                         assertEqualInt((int)offset, 8);
892                 } else if (strcmp(archive_entry_pathname(ae),
893                     "l/ld1/link1") == 0) {
894                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
895                         assertEqualInt(archive_entry_size(ae), 8);
896                         assertEqualIntA(a, ARCHIVE_OK,
897                             archive_read_data_block(a, &p, &size, &offset));
898                         assertEqualInt((int)size, 8);
899                         assertEqualInt((int)offset, 0);
900                         assertEqualMem(p, "d1/file1", 8);
901                         assertEqualInt(ARCHIVE_EOF,
902                             archive_read_data_block(a, &p, &size, &offset));
903                         assertEqualInt((int)size, 0);
904                         assertEqualInt((int)offset, 8);
905                 } else if (strcmp(archive_entry_pathname(ae),
906                     "l/ld1/linkX") == 0) {
907                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
908                 } else if (strcmp(archive_entry_pathname(ae),
909                     "l/link2") == 0) {
910                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
911                         assertEqualInt(archive_entry_size(ae), 8);
912                         assertEqualIntA(a, ARCHIVE_OK,
913                             archive_read_data_block(a, &p, &size, &offset));
914                         assertEqualInt((int)size, 8);
915                         assertEqualInt((int)offset, 0);
916                         assertEqualMem(p, "d1/file2", 8);
917                         assertEqualInt(ARCHIVE_EOF,
918                             archive_read_data_block(a, &p, &size, &offset));
919                         assertEqualInt((int)size, 0);
920                         assertEqualInt((int)offset, 8);
921                 } else if (strcmp(archive_entry_pathname(ae),
922                     "l/linkY") == 0) {
923                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
924                 }
925                 if (archive_entry_filetype(ae) == AE_IFDIR) {
926                         /* Descend into the current object */
927                         assertEqualIntA(a, ARCHIVE_OK,
928                             archive_read_disk_descend(a));
929                 }
930         }
931         /* There is no entry. */
932         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
933         /* Close the disk object. */
934         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
935         /* Destroy the disk object. */
936         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
937 }
938
939 static void
940 test_symlink_logical_loop(void)
941 {
942         struct archive *a;
943         struct archive_entry *ae;
944         const void *p;
945         size_t size;
946         int64_t offset;
947         int file_count;
948
949         if (!canSymlink()) {
950                 skipping("Can't test symlinks on this filesystem");
951                 return;
952         }
953
954         /*
955          * Create a sample archive.
956          */
957         assertMakeDir("l2", 0755);
958         assertChdir("l2");
959         assertMakeDir("d1", 0755);
960         assertMakeDir("d1/d2", 0755);
961         assertMakeDir("d1/d2/d3", 0755);
962         assertMakeDir("d2", 0755);
963         assertMakeFile("d2/file1", 0644, "d2/file1");
964         assertMakeSymlink("d1/d2/ld1", "../../d1");
965         assertMakeSymlink("d1/d2/ld2", "../../d2");
966         assertChdir("..");
967
968         assert((ae = archive_entry_new()) != NULL);
969         assert((a = archive_read_disk_new()) != NULL);
970         assertEqualIntA(a, ARCHIVE_OK,
971             archive_read_disk_set_symlink_logical(a));
972
973         /*
974          * Specified file is a symbolic link file.
975          */
976         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l2/d1"));
977         file_count = 6;
978
979         while (file_count--) {
980                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
981                 if (strcmp(archive_entry_pathname(ae), "l2/d1") == 0) {
982                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
983                 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2") == 0) {
984                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
985                 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/d3") == 0) {
986                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
987                 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld1") == 0) {
988                         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
989                 } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2") == 0) {
990                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
991                 } else if (strcmp(archive_entry_pathname(ae),
992                     "l2/d1/d2/ld2/file1") == 0) {
993                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
994                         assertEqualInt(archive_entry_size(ae), 8);
995                         assertEqualIntA(a, ARCHIVE_OK,
996                             archive_read_data_block(a, &p, &size, &offset));
997                         assertEqualInt((int)size, 8);
998                         assertEqualInt((int)offset, 0);
999                         assertEqualMem(p, "d2/file1", 8);
1000                         assertEqualInt(ARCHIVE_EOF,
1001                             archive_read_data_block(a, &p, &size, &offset));
1002                         assertEqualInt((int)size, 0);
1003                         assertEqualInt((int)offset, 8);
1004                 }
1005                 if (archive_entry_filetype(ae) == AE_IFDIR) {
1006                         /* Descend into the current object */
1007                         assertEqualIntA(a, ARCHIVE_OK,
1008                             archive_read_disk_descend(a));
1009                 }
1010         }
1011         /* There is no entry. */
1012         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1013         /* Destroy the disk object. */
1014         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1015         archive_entry_free(ae);
1016 }
1017
1018 static void
1019 test_restore_atime(void)
1020 {
1021         struct archive *a;
1022         struct archive_entry *ae;
1023         const void *p;
1024         size_t size;
1025         int64_t offset;
1026         int file_count;
1027
1028         if (!atimeIsUpdated()) {
1029                 skipping("Can't test restoring atime on this filesystem");
1030                 return;
1031         }
1032
1033         assertMakeDir("at", 0755);
1034         assertMakeFile("at/f1", 0644, "0123456789");
1035         assertMakeFile("at/f2", 0644, "hello world");
1036         assertMakeFile("at/fe", 0644, NULL);
1037         assertUtimes("at/f1", 886600, 0, 886600, 0);
1038         assertUtimes("at/f2", 886611, 0, 886611, 0);
1039         assertUtimes("at/fe", 886611, 0, 886611, 0);
1040         assertUtimes("at", 886622, 0, 886622, 0);
1041         file_count = 4;
1042
1043         assert((ae = archive_entry_new()) != NULL);
1044         assert((a = archive_read_disk_new()) != NULL);
1045
1046         /*
1047          * Test1: Traversals without archive_read_disk_set_atime_restored().
1048          */
1049         failure("Directory traversals should work as well");
1050         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
1051         while (file_count--) {
1052                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1053                 if (strcmp(archive_entry_pathname(ae), "at") == 0) {
1054                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1055                 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) {
1056                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1057                         assertEqualInt(archive_entry_size(ae), 10);
1058                         assertEqualIntA(a, ARCHIVE_OK,
1059                             archive_read_data_block(a, &p, &size, &offset));
1060                         assertEqualInt((int)size, 10);
1061                         assertEqualInt((int)offset, 0);
1062                         assertEqualMem(p, "0123456789", 10);
1063                         assertEqualInt(ARCHIVE_EOF,
1064                             archive_read_data_block(a, &p, &size, &offset));
1065                         assertEqualInt((int)size, 0);
1066                         assertEqualInt((int)offset, 10);
1067                 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) {
1068                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1069                         assertEqualInt(archive_entry_size(ae), 11);
1070                         assertEqualIntA(a, ARCHIVE_OK,
1071                             archive_read_data_block(a, &p, &size, &offset));
1072                         assertEqualInt((int)size, 11);
1073                         assertEqualInt((int)offset, 0);
1074                         assertEqualMem(p, "hello world", 11);
1075                         assertEqualInt(ARCHIVE_EOF,
1076                             archive_read_data_block(a, &p, &size, &offset));
1077                         assertEqualInt((int)size, 0);
1078                         assertEqualInt((int)offset, 11);
1079                 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
1080                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1081                         assertEqualInt(archive_entry_size(ae), 0);
1082                 }
1083                 if (archive_entry_filetype(ae) == AE_IFDIR) {
1084                         /* Descend into the current object */
1085                         assertEqualIntA(a, ARCHIVE_OK,
1086                             archive_read_disk_descend(a));
1087                 }
1088         }
1089         /* There is no entry. */
1090         failure("There must be no entry");
1091         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1092
1093         /* On FreeBSD (and likely other systems), atime on
1094            dirs does not change when it is read. */
1095         /* failure("Atime should be restored"); */
1096         /* assertFileAtimeRecent("at"); */
1097         failure("Atime should be restored");
1098         assertFileAtimeRecent("at/f1");
1099         failure("Atime should be restored");
1100         assertFileAtimeRecent("at/f2");
1101         failure("The atime of a empty file should not be changed");
1102         assertFileAtime("at/fe", 886611, 0);
1103
1104         /* Close the disk object. */
1105         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1106
1107         /*
1108          * Test2: Traversals with archive_read_disk_set_atime_restored().
1109          */
1110         assertUtimes("at/f1", 886600, 0, 886600, 0);
1111         assertUtimes("at/f2", 886611, 0, 886611, 0);
1112         assertUtimes("at/fe", 886611, 0, 886611, 0);
1113         assertUtimes("at", 886622, 0, 886622, 0);
1114         file_count = 4;
1115         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a));
1116         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
1117
1118         failure("Directory traversals should work as well");
1119         while (file_count--) {
1120                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1121                 if (strcmp(archive_entry_pathname(ae), "at") == 0) {
1122                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1123                 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) {
1124                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1125                         assertEqualInt(archive_entry_size(ae), 10);
1126                         assertEqualIntA(a, ARCHIVE_OK,
1127                             archive_read_data_block(a, &p, &size, &offset));
1128                         assertEqualInt((int)size, 10);
1129                         assertEqualInt((int)offset, 0);
1130                         assertEqualMem(p, "0123456789", 10);
1131                         assertEqualInt(ARCHIVE_EOF,
1132                             archive_read_data_block(a, &p, &size, &offset));
1133                         assertEqualInt((int)size, 0);
1134                         assertEqualInt((int)offset, 10);
1135                 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) {
1136                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1137                         assertEqualInt(archive_entry_size(ae), 11);
1138                         assertEqualIntA(a, ARCHIVE_OK,
1139                             archive_read_data_block(a, &p, &size, &offset));
1140                         assertEqualInt((int)size, 11);
1141                         assertEqualInt((int)offset, 0);
1142                         assertEqualMem(p, "hello world", 11);
1143                         assertEqualInt(ARCHIVE_EOF,
1144                             archive_read_data_block(a, &p, &size, &offset));
1145                         assertEqualInt((int)size, 0);
1146                         assertEqualInt((int)offset, 11);
1147                 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
1148                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1149                         assertEqualInt(archive_entry_size(ae), 0);
1150                 }
1151                 if (archive_entry_filetype(ae) == AE_IFDIR) {
1152                         /* Descend into the current object */
1153                         assertEqualIntA(a, ARCHIVE_OK,
1154                             archive_read_disk_descend(a));
1155                 }
1156         }
1157         /* There is no entry. */
1158         failure("There must be no entry");
1159         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1160
1161         failure("Atime should be restored");
1162         assertFileAtime("at", 886622, 0);
1163         failure("Atime should be restored");
1164         assertFileAtime("at/f1", 886600, 0);
1165         failure("Atime should be restored");
1166         assertFileAtime("at/f2", 886611, 0);
1167         failure("The atime of a empty file should not be changed");
1168         assertFileAtime("at/fe", 886611, 0);
1169
1170         /* Close the disk object. */
1171         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1172
1173         /*
1174          * Test3: Traversals with archive_read_disk_set_atime_restored() but
1175          * no data read as a listing.
1176          */
1177         assertUtimes("at/f1", 886600, 0, 886600, 0);
1178         assertUtimes("at/f2", 886611, 0, 886611, 0);
1179         assertUtimes("at/fe", 886611, 0, 886611, 0);
1180         assertUtimes("at", 886622, 0, 886622, 0);
1181         file_count = 4;
1182         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a));
1183         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
1184
1185         failure("Directory traversals should work as well");
1186         while (file_count--) {
1187                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1188                 if (strcmp(archive_entry_pathname(ae), "at") == 0) {
1189                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1190                 } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) {
1191                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1192                         assertEqualInt(archive_entry_size(ae), 10);
1193                 } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) {
1194                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1195                         assertEqualInt(archive_entry_size(ae), 11);
1196                 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
1197                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1198                         assertEqualInt(archive_entry_size(ae), 0);
1199                 }
1200                 if (archive_entry_filetype(ae) == AE_IFDIR) {
1201                         /* Descend into the current object */
1202                         assertEqualIntA(a, ARCHIVE_OK,
1203                             archive_read_disk_descend(a));
1204                 }
1205         }
1206         /* There is no entry. */
1207         failure("There must be no entry");
1208         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1209
1210         failure("Atime should be restored");
1211         assertFileAtime("at", 886622, 0);
1212         failure("Atime should be restored");
1213         assertFileAtime("at/f1", 886600, 0);
1214         failure("Atime should be restored");
1215         assertFileAtime("at/f2", 886611, 0);
1216         failure("The atime of a empty file should not be changed");
1217         assertFileAtime("at/fe", 886611, 0);
1218
1219         if (!canNodump()) {
1220                 /* Destroy the disk object. */
1221                 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1222                 archive_entry_free(ae);
1223                 skipping("Can't test atime with nodump on this filesystem");
1224                 return;
1225         }
1226
1227         /* Close the disk object. */
1228         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1229
1230         /*
1231          * Test4: Traversals with archive_read_disk_set_atime_restored() and
1232          * archive_read_disk_honor_nodump().
1233          */
1234         assertNodump("at/f1");
1235         assertNodump("at/f2");
1236         assertUtimes("at/f1", 886600, 0, 886600, 0);
1237         assertUtimes("at/f2", 886611, 0, 886611, 0);
1238         assertUtimes("at/fe", 886611, 0, 886611, 0);
1239         assertUtimes("at", 886622, 0, 886622, 0);
1240         file_count = 2;
1241         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a,
1242                 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP));
1243         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at"));
1244
1245         failure("Directory traversals should work as well");
1246         while (file_count--) {
1247                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1248                 if (strcmp(archive_entry_pathname(ae), "at") == 0) {
1249                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1250                 } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) {
1251                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1252                         assertEqualInt(archive_entry_size(ae), 0);
1253                 }
1254                 if (archive_entry_filetype(ae) == AE_IFDIR) {
1255                         /* Descend into the current object */
1256                         assertEqualIntA(a, ARCHIVE_OK,
1257                             archive_read_disk_descend(a));
1258                 }
1259         }
1260         /* There is no entry. */
1261         failure("There must be no entry");
1262         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1263
1264         failure("Atime should be restored");
1265         assertFileAtime("at", 886622, 0);
1266         failure("Atime should be restored");
1267         assertFileAtime("at/f1", 886600, 0);
1268         failure("Atime should be restored");
1269         assertFileAtime("at/f2", 886611, 0);
1270         failure("The atime of a empty file should not be changed");
1271         assertFileAtime("at/fe", 886611, 0);
1272
1273         /* Destroy the disk object. */
1274         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1275         archive_entry_free(ae);
1276 }
1277
1278 static int
1279 metadata_filter(struct archive *a, void *data, struct archive_entry *ae)
1280 {
1281         (void)data; /* UNUSED */
1282
1283         failure("CTime should be set");
1284         assertEqualInt(8, archive_entry_ctime_is_set(ae));
1285         failure("MTime should be set");
1286         assertEqualInt(16, archive_entry_mtime_is_set(ae));
1287
1288         if (archive_entry_mtime(ae) < 886611)
1289                 return (0);
1290         if (archive_read_disk_can_descend(a)) {
1291                 /* Descend into the current object */
1292                 failure("archive_read_disk_can_descend should work"
1293                         " in metadata filter");
1294                 assertEqualIntA(a, 1, archive_read_disk_can_descend(a));
1295                 failure("archive_read_disk_descend should work"
1296                         " in metadata filter");
1297                 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a));
1298         }
1299         return (1);
1300 }
1301
1302 static void
1303 test_callbacks(void)
1304 {
1305         struct archive *a;
1306         struct archive *m;
1307         struct archive_entry *ae;
1308         const void *p;
1309         size_t size;
1310         int64_t offset;
1311         int file_count;
1312
1313         assertMakeDir("cb", 0755);
1314         assertMakeFile("cb/f1", 0644, "0123456789");
1315         assertMakeFile("cb/f2", 0644, "hello world");
1316         assertMakeFile("cb/fe", 0644, NULL);
1317         assertUtimes("cb/f1", 886600, 0, 886600, 0);
1318         assertUtimes("cb/f2", 886611, 0, 886611, 0);
1319         assertUtimes("cb/fe", 886611, 0, 886611, 0);
1320         assertUtimes("cb", 886622, 0, 886622, 0);
1321
1322         assert((ae = archive_entry_new()) != NULL);
1323         if (assert((a = archive_read_disk_new()) != NULL)) {
1324                 archive_entry_free(ae);
1325                 return;
1326         }
1327         if (assert((m = archive_match_new()) != NULL)) {
1328                 archive_entry_free(ae);
1329                 archive_read_free(a);
1330                 return;
1331         }
1332
1333         /*
1334          * Test1: Traversals with a name filter.
1335          */
1336         file_count = 3;
1337         assertEqualIntA(m, ARCHIVE_OK,
1338             archive_match_exclude_pattern(m, "cb/f2"));
1339         assertEqualIntA(a, ARCHIVE_OK,
1340             archive_read_disk_set_matching(a, m, NULL, NULL));
1341         failure("Directory traversals should work as well");
1342         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb"));
1343         while (file_count--) {
1344                 archive_entry_clear(ae);
1345                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1346                 failure("File 'cb/f2' should be exclueded");
1347                 assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0);
1348                 if (strcmp(archive_entry_pathname(ae), "cb") == 0) {
1349                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1350                 } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) {
1351                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1352                         assertEqualInt(archive_entry_size(ae), 10);
1353                         assertEqualIntA(a, ARCHIVE_OK,
1354                             archive_read_data_block(a, &p, &size, &offset));
1355                         assertEqualInt((int)size, 10);
1356                         assertEqualInt((int)offset, 0);
1357                         assertEqualMem(p, "0123456789", 10);
1358                         assertEqualInt(ARCHIVE_EOF,
1359                             archive_read_data_block(a, &p, &size, &offset));
1360                         assertEqualInt((int)size, 0);
1361                         assertEqualInt((int)offset, 10);
1362                 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) {
1363                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1364                         assertEqualInt(archive_entry_size(ae), 0);
1365                 }
1366                 if (archive_read_disk_can_descend(a)) {
1367                         /* Descend into the current object */
1368                         assertEqualIntA(a, ARCHIVE_OK,
1369                             archive_read_disk_descend(a));
1370                 }
1371         }
1372         /* There is no entry. */
1373         failure("There should be no entry");
1374         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1375
1376         /* Close the disk object. */
1377         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1378
1379         /*
1380          * Test2: Traversals with a metadata filter.
1381          */
1382         assertUtimes("cb/f1", 886600, 0, 886600, 0);
1383         assertUtimes("cb/f2", 886611, 0, 886611, 0);
1384         assertUtimes("cb/fe", 886611, 0, 886611, 0);
1385         assertUtimes("cb", 886622, 0, 886622, 0);
1386         file_count = 3;
1387         assertEqualIntA(a, ARCHIVE_OK,
1388             archive_read_disk_set_metadata_filter_callback(a, metadata_filter,
1389                     NULL));
1390         failure("Directory traversals should work as well");
1391         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb"));
1392
1393         while (file_count--) {
1394                 archive_entry_clear(ae);
1395                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1396                 failure("File 'cb/f1' should be exclueded");
1397                 assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0);
1398                 if (strcmp(archive_entry_pathname(ae), "cb") == 0) {
1399                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1400                 } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) {
1401                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1402                         assertEqualInt(archive_entry_size(ae), 11);
1403                         assertEqualIntA(a, ARCHIVE_OK,
1404                             archive_read_data_block(a, &p, &size, &offset));
1405                         assertEqualInt((int)size, 11);
1406                         assertEqualInt((int)offset, 0);
1407                         assertEqualMem(p, "hello world", 11);
1408                         assertEqualInt(ARCHIVE_EOF,
1409                             archive_read_data_block(a, &p, &size, &offset));
1410                         assertEqualInt((int)size, 0);
1411                         assertEqualInt((int)offset, 11);
1412                 } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) {
1413                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1414                         assertEqualInt(archive_entry_size(ae), 0);
1415                 }
1416         }
1417         /* There is no entry. */
1418         failure("There should be no entry");
1419         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1420
1421         /* Destroy the disk object. */
1422         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1423         assertEqualInt(ARCHIVE_OK, archive_match_free(m));
1424         archive_entry_free(ae);
1425 }
1426
1427 static void
1428 test_nodump(void)
1429 {
1430         struct archive *a;
1431         struct archive_entry *ae;
1432         const void *p;
1433         size_t size;
1434         int64_t offset;
1435         int file_count;
1436
1437         if (!canNodump()) {
1438                 skipping("Can't test nodump on this filesystem");
1439                 return;
1440         }
1441
1442         assertMakeDir("nd", 0755);
1443         assertMakeFile("nd/f1", 0644, "0123456789");
1444         assertMakeFile("nd/f2", 0644, "hello world");
1445         assertMakeFile("nd/fe", 0644, NULL);
1446         assertNodump("nd/f2");
1447         assertUtimes("nd/f1", 886600, 0, 886600, 0);
1448         assertUtimes("nd/f2", 886611, 0, 886611, 0);
1449         assertUtimes("nd/fe", 886611, 0, 886611, 0);
1450         assertUtimes("nd", 886622, 0, 886622, 0);
1451
1452         assert((ae = archive_entry_new()) != NULL);
1453         assert((a = archive_read_disk_new()) != NULL);
1454
1455         /*
1456          * Test1: Traversals without archive_read_disk_honor_nodump().
1457          */
1458         failure("Directory traversals should work as well");
1459         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd"));
1460
1461         file_count = 4;
1462         while (file_count--) {
1463                 archive_entry_clear(ae);
1464                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1465                 if (strcmp(archive_entry_pathname(ae), "nd") == 0) {
1466                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1467                 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) {
1468                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1469                         assertEqualInt(archive_entry_size(ae), 10);
1470                         assertEqualIntA(a, ARCHIVE_OK,
1471                             archive_read_data_block(a, &p, &size, &offset));
1472                         assertEqualInt((int)size, 10);
1473                         assertEqualInt((int)offset, 0);
1474                         assertEqualMem(p, "0123456789", 10);
1475                         assertEqualInt(ARCHIVE_EOF,
1476                             archive_read_data_block(a, &p, &size, &offset));
1477                         assertEqualInt((int)size, 0);
1478                         assertEqualInt((int)offset, 10);
1479                 } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) {
1480                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1481                         assertEqualInt(archive_entry_size(ae), 11);
1482                         assertEqualIntA(a, ARCHIVE_OK,
1483                             archive_read_data_block(a, &p, &size, &offset));
1484                         assertEqualInt((int)size, 11);
1485                         assertEqualInt((int)offset, 0);
1486                         assertEqualMem(p, "hello world", 11);
1487                         assertEqualInt(ARCHIVE_EOF,
1488                             archive_read_data_block(a, &p, &size, &offset));
1489                         assertEqualInt((int)size, 0);
1490                         assertEqualInt((int)offset, 11);
1491                 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) {
1492                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1493                         assertEqualInt(archive_entry_size(ae), 0);
1494                 }
1495                 if (archive_read_disk_can_descend(a)) {
1496                         /* Descend into the current object */
1497                         assertEqualIntA(a, ARCHIVE_OK,
1498                             archive_read_disk_descend(a));
1499                 }
1500         }
1501         /* There is no entry. */
1502         failure("There should be no entry");
1503         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1504
1505         /* Close the disk object. */
1506         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1507
1508         /*
1509          * Test2: Traversals with archive_read_disk_honor_nodump().
1510          */
1511         assertUtimes("nd/f1", 886600, 0, 886600, 0);
1512         assertUtimes("nd/f2", 886611, 0, 886611, 0);
1513         assertUtimes("nd/fe", 886611, 0, 886611, 0);
1514         assertUtimes("nd", 886622, 0, 886622, 0);
1515
1516         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a,
1517                 ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP));
1518         failure("Directory traversals should work as well");
1519         assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd"));
1520
1521         file_count = 3;
1522         while (file_count--) {
1523                 archive_entry_clear(ae);
1524                 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1525                 failure("File 'nd/f2' should be exclueded");
1526                 assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0);
1527                 if (strcmp(archive_entry_pathname(ae), "nd") == 0) {
1528                         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1529                 } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) {
1530                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1531                         assertEqualInt(archive_entry_size(ae), 10);
1532                         assertEqualIntA(a, ARCHIVE_OK,
1533                             archive_read_data_block(a, &p, &size, &offset));
1534                         assertEqualInt((int)size, 10);
1535                         assertEqualInt((int)offset, 0);
1536                         assertEqualMem(p, "0123456789", 10);
1537                         assertEqualInt(ARCHIVE_EOF,
1538                             archive_read_data_block(a, &p, &size, &offset));
1539                         assertEqualInt((int)size, 0);
1540                         assertEqualInt((int)offset, 10);
1541                 } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) {
1542                         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1543                         assertEqualInt(archive_entry_size(ae), 0);
1544                 }
1545                 if (archive_read_disk_can_descend(a)) {
1546                         /* Descend into the current object */
1547                         assertEqualIntA(a, ARCHIVE_OK,
1548                             archive_read_disk_descend(a));
1549                 }
1550         }
1551         /* There is no entry. */
1552         failure("There should be no entry");
1553         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1554
1555         failure("Atime should be restored");
1556         assertFileAtime("nd/f2", 886611, 0);
1557
1558         /* Destroy the disk object. */
1559         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1560         archive_entry_free(ae);
1561 }
1562
1563 DEFINE_TEST(test_read_disk_directory_traversals)
1564 {
1565         /* Basic test. */
1566         test_basic();
1567         /* Test hybird mode; follow symlink initially, then not. */
1568         test_symlink_hybrid();
1569         /* Test logcal mode; follow all symlinks. */
1570         test_symlink_logical();
1571         /* Test logcal mode; prevent loop in symlinks. */ 
1572         test_symlink_logical_loop();
1573         /* Test to restore atime. */
1574         test_restore_atime();
1575         /* Test callbacks. */
1576         test_callbacks();
1577         /* Test nodump. */
1578         test_nodump();
1579 }