]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libarchive/libarchive/test/test_read_format_mtree.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libarchive / libarchive / test / test_read_format_mtree.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * Copyright (c) 2011-2012 Michihiro NAKAJIMA
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "test.h"
27 __FBSDID("$FreeBSD$");
28
29 static void
30 test_read_format_mtree1(void)
31 {
32         const char reffile[] = "test_read_format_mtree.mtree";
33         char buff[16];
34         struct archive_entry *ae;
35         struct archive *a;
36         FILE *f;
37         /* Compute max 64-bit signed twos-complement value
38          * without relying on overflow.  This assumes that long long
39          * is at least 64 bits. */
40         static const long long max_int64 = ((((long long)1) << 62) - 1) + (((long long)1) << 62);
41         time_t min_time;
42         volatile time_t t;
43
44         extract_reference_file(reffile);
45
46         /*
47          * An access error occurred on some platform when mtree
48          * format handling open a directory. It is for through
49          * the routine which open a directory that we create
50          * "dir" and "dir2" directories.
51          */
52         assertMakeDir("dir", 0775);
53         assertMakeDir("dir2", 0775);
54
55         assert((a = archive_read_new()) != NULL);
56         assertEqualIntA(a, ARCHIVE_OK,
57             archive_read_support_filter_all(a));
58         assertEqualIntA(a, ARCHIVE_OK,
59             archive_read_support_format_all(a));
60         assertEqualIntA(a, ARCHIVE_OK,
61             archive_read_open_filename(a, reffile, 11));
62
63         /*
64          * Read "file", whose data is available on disk.
65          */
66         f = fopen("file", "wb");
67         assert(f != NULL);
68         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
69         fclose(f);
70         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
71         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
72         assertEqualString(archive_entry_pathname(ae), "file");
73         assertEqualInt(archive_entry_uid(ae), 18);
74         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
75         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
76         assertEqualInt(archive_entry_size(ae), 3);
77         assertEqualInt(3, archive_read_data(a, buff, 3));
78         assertEqualMem(buff, "hi\n", 3);
79
80         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
81         assertEqualString(archive_entry_pathname(ae), "dir");
82         assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
83
84         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
85         assertEqualString(archive_entry_pathname(ae), "dir/file with space");
86
87         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
88         assertEqualString(archive_entry_pathname(ae), "file with space");
89
90         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
91         assertEqualString(archive_entry_pathname(ae), "dir2");
92
93         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
94         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
95
96         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
97         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
98
99         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
100         assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
101         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
102
103         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
104         assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
105
106         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
107         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
108
109         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
110         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
111
112         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
113         assertEqualString(archive_entry_pathname(ae), "notindir");
114
115         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
116         assertEqualString(archive_entry_pathname(ae), "dir2/emptyfile");
117         assertEqualInt(archive_entry_size(ae), 0);
118
119         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
120         assertEqualString(archive_entry_pathname(ae), "dir2/smallfile");
121         assertEqualInt(archive_entry_size(ae), 1);
122
123         /* TODO: Mtree reader should probably return ARCHIVE_WARN for this. */
124         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
125         assertEqualString(archive_entry_pathname(ae), "dir2/toosmallfile");
126         assertEqualInt(archive_entry_size(ae), -1);
127
128         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
129         assertEqualString(archive_entry_pathname(ae), "dir2/bigfile");
130         assertEqualInt(archive_entry_size(ae), max_int64);
131
132         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
133         assertEqualString(archive_entry_pathname(ae), "dir2/toobigfile");
134         /* Size in mtree is max_int64 + 1; should return max_int64. */
135         assertEqualInt(archive_entry_size(ae), max_int64);
136
137         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
138         assertEqualString(archive_entry_pathname(ae), "dir2/veryoldfile");
139         /* The value in the file is MIN_INT64_T, but time_t may be narrower. */
140         /* Verify min_time is the smallest possible time_t. */
141         min_time = archive_entry_mtime(ae);
142         assert(min_time <= 0);
143         /* Simply asserting min_time - 1 > 0 breaks with some compiler optimizations. */
144         t = min_time - 1;
145         assert(t > 0);
146
147         /* toooldfile is 1 sec older, which should overflow and get returned
148          * with the same value. */
149         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
150         assertEqualString(archive_entry_pathname(ae), "dir2/toooldfile");
151         assertEqualInt(archive_entry_mtime(ae), min_time);
152
153         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
154         assertEqualInt(19, archive_file_count(a));
155         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
156         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
157 }
158
159 static void
160 test_read_format_mtree2(void)
161 {
162         static char archive[] =
163             "#mtree\n"
164             "d type=dir content=.\n";
165         struct archive_entry *ae;
166         struct archive *a;
167
168         assert((a = archive_read_new()) != NULL);
169         assertEqualIntA(a, ARCHIVE_OK,
170             archive_read_support_filter_all(a));
171         assertEqualIntA(a, ARCHIVE_OK,
172             archive_read_support_format_all(a));
173         assertEqualIntA(a, ARCHIVE_OK,
174             archive_read_open_memory(a, archive, sizeof(archive)));
175         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
176         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
177         assertEqualString(archive_entry_pathname(ae), "d");
178         assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
179         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
180         assertEqualInt(1, archive_file_count(a));
181         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
182         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
183 }
184
185 /*
186  * Reported to libarchive.googlecode.com as Issue 121.
187  */
188 static void
189 test_read_format_mtree3(void)
190 {
191         static char archive[] =
192             "#mtree\n"
193             "a type=file contents=file\n"
194             "b type=link link=a\n"
195             "c type=file contents=file\n";
196         struct archive_entry *ae;
197         struct archive *a;
198
199         assertMakeDir("mtree3", 0777);
200         assertChdir("mtree3");
201         assertMakeFile("file", 0644, "file contents");
202
203         assert((a = archive_read_new()) != NULL);
204         assertEqualIntA(a, ARCHIVE_OK,
205             archive_read_support_filter_all(a));
206         assertEqualIntA(a, ARCHIVE_OK,
207             archive_read_support_format_all(a));
208         assertEqualIntA(a, ARCHIVE_OK,
209             archive_read_open_memory(a, archive, sizeof(archive)));
210         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
211         assertEqualString(archive_entry_pathname(ae), "a");
212         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
213         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
214         assertEqualString(archive_entry_pathname(ae), "b");
215         assertEqualInt(archive_entry_filetype(ae), AE_IFLNK);
216         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
217         assertEqualString(archive_entry_pathname(ae), "c");
218         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
219
220         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
221         assertEqualInt(3, archive_file_count(a));
222         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
223         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
224
225         assertChdir("..");
226 }
227
228 DEFINE_TEST(test_read_format_mtree)
229 {
230         test_read_format_mtree1();
231         test_read_format_mtree2();
232         test_read_format_mtree3();
233 }
234
235 DEFINE_TEST(test_read_format_mtree_filenames_only)
236 {
237         static char archive[] =
238             "/set type=file mode=0644\n"
239             "./a\n"
240             "./b\n"
241             "./c\n"
242             "./d\n"
243             "./e\n"
244             "./f mode=0444\n";
245         struct archive_entry *ae;
246         struct archive *a;
247
248         assertMakeFile("file", 0644, "file contents");
249
250         assert((a = archive_read_new()) != NULL);
251         assertEqualIntA(a, ARCHIVE_OK,
252             archive_read_support_filter_all(a));
253         assertEqualIntA(a, ARCHIVE_OK,
254             archive_read_support_format_all(a));
255         assertEqualIntA(a, ARCHIVE_OK,
256             archive_read_open_memory(a, archive, sizeof(archive)));
257         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
258         assertEqualString(archive_entry_pathname(ae), "./a");
259         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
260         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
261         assertEqualString(archive_entry_pathname(ae), "./b");
262         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
263         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
264         assertEqualString(archive_entry_pathname(ae), "./c");
265         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
266         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
267         assertEqualString(archive_entry_pathname(ae), "./d");
268         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
269         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
270         assertEqualString(archive_entry_pathname(ae), "./e");
271         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
272         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
273         assertEqualString(archive_entry_pathname(ae), "./f");
274         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444);
275
276         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
277         assertEqualInt(6, archive_file_count(a));
278         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
279         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
280 }
281
282 DEFINE_TEST(test_read_format_mtree_nochange)
283 {
284         static char archive[] =
285             "#mtree\n"
286             "./a type=file mode=0644 time=123\n"
287             "./b type=file mode=0644 time=234\n"
288             "./c type=file mode=0644 time=345\n";
289         static char archive2[] =
290             "#mtree\n"
291             "./a type=file mode=0644 time=123 nochange\n"
292             "./b type=file mode=0644 time=234\n"
293             "./c type=file mode=0644 time=345 nochange\n";
294         struct archive_entry *ae;
295         struct archive *a;
296
297         assertMakeFile("a", 0640, "12345");
298         assertMakeFile("b", 0664, "123456");
299         assertMakeFile("c", 0755, "1234567");
300
301         /*
302          * Test 1. Read a mtree archive without `nochange' keyword.
303          */
304         assert((a = archive_read_new()) != NULL);
305         assertEqualIntA(a, ARCHIVE_OK,
306             archive_read_support_filter_all(a));
307         assertEqualIntA(a, ARCHIVE_OK,
308             archive_read_support_format_all(a));
309         assertEqualIntA(a, ARCHIVE_OK,
310             archive_read_open_memory(a, archive, sizeof(archive)));
311         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
312         assertEqualString(archive_entry_pathname(ae), "./a");
313         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
314         assertEqualInt(archive_entry_mtime(ae), 123);
315         assertEqualInt(archive_entry_size(ae), 5);
316         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
317         assertEqualString(archive_entry_pathname(ae), "./b");
318         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
319         assertEqualInt(archive_entry_mtime(ae), 234);
320         assertEqualInt(archive_entry_size(ae), 6);
321         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
322         assertEqualString(archive_entry_pathname(ae), "./c");
323         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
324         assertEqualInt(archive_entry_mtime(ae), 345);
325         assertEqualInt(archive_entry_size(ae), 7);
326
327         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
328         assertEqualInt(3, archive_file_count(a));
329         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
330         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
331
332         /*
333          * Test 2. Read a mtree archive with `nochange' keyword.
334          */
335         assert((a = archive_read_new()) != NULL);
336         assertEqualIntA(a, ARCHIVE_OK,
337             archive_read_support_filter_all(a));
338         assertEqualIntA(a, ARCHIVE_OK,
339             archive_read_support_format_all(a));
340         assertEqualIntA(a, ARCHIVE_OK,
341             archive_read_open_memory(a, archive2, sizeof(archive2)));
342         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
343         assertEqualString(archive_entry_pathname(ae), "./a");
344 #if !defined(_WIN32) || defined(__CYGWIN__)
345         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0640);
346 #endif
347         assert(archive_entry_mtime(ae) != 123);
348         assertEqualInt(archive_entry_size(ae), 5);
349         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
350         assertEqualString(archive_entry_pathname(ae), "./b");
351         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
352         assertEqualInt(archive_entry_mtime(ae), 234);
353         assertEqualInt(archive_entry_size(ae), 6);
354         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
355         assertEqualString(archive_entry_pathname(ae), "./c");
356 #if !defined(_WIN32) || defined(__CYGWIN__)
357         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0755);
358 #endif
359         assert(archive_entry_mtime(ae) != 345);
360         assertEqualInt(archive_entry_size(ae), 7);
361
362         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
363         assertEqualInt(3, archive_file_count(a));
364         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
365         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
366 }
367
368 DEFINE_TEST(test_read_format_mtree_nomagic_v1_form)
369 {
370         const char reffile[] = "test_read_format_mtree_nomagic.mtree";
371         char buff[16];
372         struct archive_entry *ae;
373         struct archive *a;
374         FILE *f;
375
376         extract_reference_file(reffile);
377
378         assert((a = archive_read_new()) != NULL);
379         assertEqualIntA(a, ARCHIVE_OK,
380             archive_read_support_filter_all(a));
381         assertEqualIntA(a, ARCHIVE_OK,
382             archive_read_support_format_all(a));
383         assertEqualIntA(a, ARCHIVE_OK,
384             archive_read_open_filename(a, reffile, 11));
385
386         /*
387          * Read "file", whose data is available on disk.
388          */
389         f = fopen("file", "wb");
390         assert(f != NULL);
391         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
392         fclose(f);
393         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
394         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
395         assertEqualString(archive_entry_pathname(ae), "file");
396         assertEqualInt(archive_entry_uid(ae), 18);
397         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
398         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
399         assertEqualInt(archive_entry_size(ae), 3);
400         assertEqualInt(3, archive_read_data(a, buff, 3));
401         assertEqualMem(buff, "hi\n", 3);
402
403         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
404         assertEqualString(archive_entry_pathname(ae), "dir");
405         assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));
406
407         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
408         assertEqualString(archive_entry_pathname(ae), "dir/file with space");
409
410         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
411         assertEqualString(archive_entry_pathname(ae), "file with space");
412
413         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
414         assertEqualString(archive_entry_pathname(ae), "dir2");
415
416         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
417         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");
418
419         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
420         assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");
421
422         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
423         assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
424         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
425
426         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
427         assertEqualString(archive_entry_pathname(ae), "dir2/indir2");
428
429         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
430         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");
431
432         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
433         assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");
434
435         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
436         assertEqualString(archive_entry_pathname(ae), "notindir");
437
438         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
439         assertEqualInt(12, archive_file_count(a));
440         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
441         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
442 }
443
444 /*
445  * Test for a format that NetBSD mtree -C generates.
446  */
447 DEFINE_TEST(test_read_format_mtree_nomagic_v2_form)
448 {
449         const char reffile[] = "test_read_format_mtree_nomagic2.mtree";
450         char buff[16];
451         struct archive_entry *ae;
452         struct archive *a;
453         FILE *f;
454
455         extract_reference_file(reffile);
456
457         assert((a = archive_read_new()) != NULL);
458         assertEqualIntA(a, ARCHIVE_OK,
459             archive_read_support_filter_all(a));
460         assertEqualIntA(a, ARCHIVE_OK,
461             archive_read_support_format_all(a));
462         assertEqualIntA(a, ARCHIVE_OK,
463             archive_read_open_filename(a, reffile, 11));
464
465         /*
466          * Read "file", whose data is available on disk.
467          */
468         f = fopen("file", "wb");
469         assert(f != NULL);
470         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
471         fclose(f);
472         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
473         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
474         assertEqualString(archive_entry_pathname(ae), "./file");
475         assertEqualInt(archive_entry_uid(ae), 18);
476         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
477         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
478         assertEqualInt(archive_entry_size(ae), 3);
479         assertEqualInt(3, archive_read_data(a, buff, 3));
480         assertEqualMem(buff, "hi\n", 3);
481
482         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
483         assertEqualString(archive_entry_pathname(ae), "./dir");
484         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
485
486         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
487         assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
488         assertEqualInt(archive_entry_uid(ae), 18);
489         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
490
491         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
492         assertEqualString(archive_entry_pathname(ae), "./file with space");
493         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
494
495         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
496         assertEqualString(archive_entry_pathname(ae), "./dir2");
497         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
498
499         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
500         assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
501         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
502
503         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
504         assertEqualInt(6, archive_file_count(a));
505         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
506         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
507 }
508
509 /*
510  * Test for a format that NetBSD mtree -D generates.
511  */
512 DEFINE_TEST(test_read_format_mtree_nomagic_v2_netbsd_form)
513 {
514         const char reffile[] = "test_read_format_mtree_nomagic3.mtree";
515         char buff[16];
516         struct archive_entry *ae;
517         struct archive *a;
518         FILE *f;
519
520         extract_reference_file(reffile);
521
522         assert((a = archive_read_new()) != NULL);
523         assertEqualIntA(a, ARCHIVE_OK,
524             archive_read_support_filter_all(a));
525         assertEqualIntA(a, ARCHIVE_OK,
526             archive_read_support_format_all(a));
527         assertEqualIntA(a, ARCHIVE_OK,
528             archive_read_open_filename(a, reffile, 11));
529
530         /*
531          * Read "file", whose data is available on disk.
532          */
533         f = fopen("file", "wb");
534         assert(f != NULL);
535         assertEqualInt(3, fwrite("hi\n", 1, 3, f));
536         fclose(f);
537         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
538         assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
539         assertEqualString(archive_entry_pathname(ae), "./file");
540         assertEqualInt(archive_entry_uid(ae), 18);
541         assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
542         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
543         assertEqualInt(archive_entry_size(ae), 3);
544         assertEqualInt(3, archive_read_data(a, buff, 3));
545         assertEqualMem(buff, "hi\n", 3);
546
547         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
548         assertEqualString(archive_entry_pathname(ae), "./dir");
549         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
550
551         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
552         assertEqualString(archive_entry_pathname(ae), "./dir/file with space");
553         assertEqualInt(archive_entry_uid(ae), 18);
554         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
555
556         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
557         assertEqualString(archive_entry_pathname(ae), "./file with space");
558         assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);
559
560         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
561         assertEqualString(archive_entry_pathname(ae), "./dir2");
562         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
563
564         assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
565         assertEqualString(archive_entry_pathname(ae), "./dir2/dir3a");
566         assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755);
567
568         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
569         assertEqualInt(6, archive_file_count(a));
570         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
571         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
572 }
573
574 /*
575  * We should get a warning if the contents file doesn't exist.
576  */
577 DEFINE_TEST(test_read_format_mtree_nonexistent_contents_file)
578 {
579         static char archive[] =
580             "#mtree\n"
581             "a type=file contents=nonexistent_file\n";
582         struct archive_entry *ae;
583         struct archive *a;
584
585         assert((a = archive_read_new()) != NULL);
586         assertEqualIntA(a, ARCHIVE_OK,
587             archive_read_support_filter_all(a));
588         assertEqualIntA(a, ARCHIVE_OK,
589             archive_read_support_format_all(a));
590         assertEqualIntA(a, ARCHIVE_OK,
591             archive_read_open_memory(a, archive, sizeof(archive)));
592         assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
593         assert(strlen(archive_error_string(a)) > 0);
594         assertEqualString(archive_entry_pathname(ae), "a");
595         assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
596
597         assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
598         assertEqualInt(1, archive_file_count(a));
599         assertEqualInt(ARCHIVE_OK, archive_read_close(a));
600         assertEqualInt(ARCHIVE_OK, archive_read_free(a));
601 }
602