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