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