]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libarchive/libarchive/test/test_entry.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libarchive / libarchive / test / test_entry.c
1 /*-
2  * Copyright (c) 2003-2007 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #include "test.h"
26 __FBSDID("$FreeBSD$");
27
28 #include <locale.h>
29
30 #ifndef HAVE_WCSCPY
31 static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2)
32 {
33         wchar_t *dest = s1;
34         while ((*s1 = *s2) != L'\0')
35                 ++s1, ++s2;
36         return dest;
37 }
38 #endif
39
40 /*
41  * Most of these tests are system-independent, though a few depend on
42  * features of the local system.  Such tests are conditionalized on
43  * the platform name.  On unsupported platforms, only the
44  * system-independent features will be tested.
45  *
46  * No, I don't want to use config.h in the test files because I want
47  * the tests to also serve as a check on the correctness of config.h.
48  * A mis-configured library build should cause tests to fail.
49  */
50
51 DEFINE_TEST(test_entry)
52 {
53         char buff[128];
54         wchar_t wbuff[128];
55         struct stat st;
56         struct archive_entry *e, *e2;
57         const struct stat *pst;
58         unsigned long set, clear; /* For fflag testing. */
59         int type, permset, tag, qual; /* For ACL testing. */
60         const char *name; /* For ACL testing. */
61         const char *xname; /* For xattr tests. */
62         const void *xval; /* For xattr tests. */
63         size_t xsize; /* For xattr tests. */
64         wchar_t wc;
65         long l;
66         int i;
67
68         assert((e = archive_entry_new()) != NULL);
69
70         /*
71          * Verify that the AE_IF* defines match S_IF* defines
72          * on this platform. See comments in archive_entry.h.
73          */
74 #ifdef S_IFREG
75         assertEqualInt(S_IFREG, AE_IFREG);
76 #endif
77 #ifdef S_IFLNK
78         assertEqualInt(S_IFLNK, AE_IFLNK);
79 #endif
80 #ifdef S_IFSOCK
81         assertEqualInt(S_IFSOCK, AE_IFSOCK);
82 #endif
83 #ifdef S_IFCHR
84         assertEqualInt(S_IFCHR, AE_IFCHR);
85 #endif
86 /* Work around MinGW, which defines S_IFBLK wrong. */
87 /* sourceforge.net/tracker/?func=detail&atid=102435&aid=1942809&group_id=2435 */
88 #if defined(S_IFBLK) && !defined(_WIN32)
89         assertEqualInt(S_IFBLK, AE_IFBLK);
90 #endif
91 #ifdef S_IFDIR
92         assertEqualInt(S_IFDIR, AE_IFDIR);
93 #endif
94 #ifdef S_IFIFO
95         assertEqualInt(S_IFIFO, AE_IFIFO);
96 #endif
97
98         /*
99          * Basic set/read tests for all fields.
100          * We should be able to set any field and read
101          * back the same value.
102          *
103          * For methods that "copy" a string, we should be able
104          * to overwrite the original passed-in string without
105          * changing the value in the entry.
106          *
107          * The following tests are ordered alphabetically by the
108          * name of the field.
109          */
110
111         /* atime */
112         archive_entry_set_atime(e, 13579, 24680);
113         assertEqualInt(archive_entry_atime(e), 13579);
114         assertEqualInt(archive_entry_atime_nsec(e), 24680);
115         archive_entry_set_atime(e, 13580, 1000000001L);
116         assertEqualInt(archive_entry_atime(e), 13581);
117         assertEqualInt(archive_entry_atime_nsec(e), 1);
118         archive_entry_set_atime(e, 13580, -7);
119         assertEqualInt(archive_entry_atime(e), 13579);
120         assertEqualInt(archive_entry_atime_nsec(e), 999999993);
121         archive_entry_unset_atime(e);
122         assertEqualInt(archive_entry_atime(e), 0);
123         assertEqualInt(archive_entry_atime_nsec(e), 0);
124         assert(!archive_entry_atime_is_set(e));
125
126         /* birthtime */
127         archive_entry_set_birthtime(e, 17579, 24990);
128         assertEqualInt(archive_entry_birthtime(e), 17579);
129         assertEqualInt(archive_entry_birthtime_nsec(e), 24990);
130         archive_entry_set_birthtime(e, 17580, 1234567890L);
131         assertEqualInt(archive_entry_birthtime(e), 17581);
132         assertEqualInt(archive_entry_birthtime_nsec(e), 234567890);
133         archive_entry_set_birthtime(e, 17581, -24990);
134         assertEqualInt(archive_entry_birthtime(e), 17580);
135         assertEqualInt(archive_entry_birthtime_nsec(e), 999975010);
136         archive_entry_unset_birthtime(e);
137         assertEqualInt(archive_entry_birthtime(e), 0);
138         assertEqualInt(archive_entry_birthtime_nsec(e), 0);
139         assert(!archive_entry_birthtime_is_set(e));
140
141         /* ctime */
142         archive_entry_set_ctime(e, 13580, 24681);
143         assertEqualInt(archive_entry_ctime(e), 13580);
144         assertEqualInt(archive_entry_ctime_nsec(e), 24681);
145         archive_entry_set_ctime(e, 13581, 2008182348L);
146         assertEqualInt(archive_entry_ctime(e), 13583);
147         assertEqualInt(archive_entry_ctime_nsec(e), 8182348);
148         archive_entry_set_ctime(e, 13582, -24681);
149         assertEqualInt(archive_entry_ctime(e), 13581);
150         assertEqualInt(archive_entry_ctime_nsec(e), 999975319);
151         archive_entry_unset_ctime(e);
152         assertEqualInt(archive_entry_ctime(e), 0);
153         assertEqualInt(archive_entry_ctime_nsec(e), 0);
154         assert(!archive_entry_ctime_is_set(e));
155
156         /* dev */
157         assert(!archive_entry_dev_is_set(e));
158         archive_entry_set_dev(e, 235);
159         assert(archive_entry_dev_is_set(e));
160         assertEqualInt(archive_entry_dev(e), 235);
161         /* devmajor/devminor are tested specially below. */
162
163         /* filetype */
164         archive_entry_set_filetype(e, AE_IFREG);
165         assertEqualInt(archive_entry_filetype(e), AE_IFREG);
166
167         /* fflags are tested specially below */
168
169         /* gid */
170         archive_entry_set_gid(e, 204);
171         assertEqualInt(archive_entry_gid(e), 204);
172
173         /* gname */
174         archive_entry_set_gname(e, "group");
175         assertEqualString(archive_entry_gname(e), "group");
176         wcscpy(wbuff, L"wgroup");
177         archive_entry_copy_gname_w(e, wbuff);
178         assertEqualWString(archive_entry_gname_w(e), L"wgroup");
179         memset(wbuff, 0, sizeof(wbuff));
180         assertEqualWString(archive_entry_gname_w(e), L"wgroup");
181
182         /* hardlink */
183         archive_entry_set_hardlink(e, "hardlinkname");
184         assertEqualString(archive_entry_hardlink(e), "hardlinkname");
185         strcpy(buff, "hardlinkname2");
186         archive_entry_copy_hardlink(e, buff);
187         assertEqualString(archive_entry_hardlink(e), "hardlinkname2");
188         memset(buff, 0, sizeof(buff));
189         assertEqualString(archive_entry_hardlink(e), "hardlinkname2");
190         archive_entry_copy_hardlink(e, NULL);
191         assertEqualString(archive_entry_hardlink(e), NULL);
192         assertEqualWString(archive_entry_hardlink_w(e), NULL);
193         wcscpy(wbuff, L"whardlink");
194         archive_entry_copy_hardlink_w(e, wbuff);
195         assertEqualWString(archive_entry_hardlink_w(e), L"whardlink");
196         memset(wbuff, 0, sizeof(wbuff));
197         assertEqualWString(archive_entry_hardlink_w(e), L"whardlink");
198         archive_entry_copy_hardlink_w(e, NULL);
199         assertEqualString(archive_entry_hardlink(e), NULL);
200         assertEqualWString(archive_entry_hardlink_w(e), NULL);
201
202         /* ino */
203         assert(!archive_entry_ino_is_set(e));
204         archive_entry_set_ino(e, 8593);
205         assert(archive_entry_ino_is_set(e));
206         assertEqualInt(archive_entry_ino(e), 8593);
207         assertEqualInt(archive_entry_ino64(e), 8593);
208         archive_entry_set_ino64(e, 8594);
209         assert(archive_entry_ino_is_set(e));
210         assertEqualInt(archive_entry_ino(e), 8594);
211         assertEqualInt(archive_entry_ino64(e), 8594);
212
213         /* link */
214         archive_entry_set_hardlink(e, "hardlinkname");
215         archive_entry_set_symlink(e, NULL);
216         archive_entry_set_link(e, "link");
217         assertEqualString(archive_entry_hardlink(e), "link");
218         assertEqualString(archive_entry_symlink(e), NULL);
219         archive_entry_copy_link(e, "link2");
220         assertEqualString(archive_entry_hardlink(e), "link2");
221         assertEqualString(archive_entry_symlink(e), NULL);
222         archive_entry_copy_link_w(e, L"link3");
223         assertEqualString(archive_entry_hardlink(e), "link3");
224         assertEqualString(archive_entry_symlink(e), NULL);
225         archive_entry_set_hardlink(e, NULL);
226         archive_entry_set_symlink(e, "symlink");
227         archive_entry_set_link(e, "link");
228         assertEqualString(archive_entry_hardlink(e), NULL);
229         assertEqualString(archive_entry_symlink(e), "link");
230         archive_entry_copy_link(e, "link2");
231         assertEqualString(archive_entry_hardlink(e), NULL);
232         assertEqualString(archive_entry_symlink(e), "link2");
233         archive_entry_copy_link_w(e, L"link3");
234         assertEqualString(archive_entry_hardlink(e), NULL);
235         assertEqualString(archive_entry_symlink(e), "link3");
236         /* Arbitrarily override symlink if both hardlink and symlink set. */
237         archive_entry_set_hardlink(e, "hardlink");
238         archive_entry_set_symlink(e, "symlink");
239         archive_entry_set_link(e, "link");
240         assertEqualString(archive_entry_hardlink(e), "hardlink");
241         assertEqualString(archive_entry_symlink(e), "link");
242
243         /* mode */
244         archive_entry_set_mode(e, 0123456);
245         assertEqualInt(archive_entry_mode(e), 0123456);
246
247         /* mtime */
248         archive_entry_set_mtime(e, 13581, 24682);
249         assertEqualInt(archive_entry_mtime(e), 13581);
250         assertEqualInt(archive_entry_mtime_nsec(e), 24682);
251         archive_entry_set_mtime(e, 13582, 1358297468);
252         assertEqualInt(archive_entry_mtime(e), 13583);
253         assertEqualInt(archive_entry_mtime_nsec(e), 358297468);
254         archive_entry_set_mtime(e, 13583, -24682);
255         assertEqualInt(archive_entry_mtime(e), 13582);
256         assertEqualInt(archive_entry_mtime_nsec(e), 999975318);
257         archive_entry_unset_mtime(e);
258         assertEqualInt(archive_entry_mtime(e), 0);
259         assertEqualInt(archive_entry_mtime_nsec(e), 0);
260         assert(!archive_entry_mtime_is_set(e));
261
262         /* nlink */
263         archive_entry_set_nlink(e, 736);
264         assertEqualInt(archive_entry_nlink(e), 736);
265
266         /* pathname */
267         archive_entry_set_pathname(e, "path");
268         assertEqualString(archive_entry_pathname(e), "path");
269         archive_entry_set_pathname(e, "path");
270         assertEqualString(archive_entry_pathname(e), "path");
271         strcpy(buff, "path2");
272         archive_entry_copy_pathname(e, buff);
273         assertEqualString(archive_entry_pathname(e), "path2");
274         memset(buff, 0, sizeof(buff));
275         assertEqualString(archive_entry_pathname(e), "path2");
276         wcscpy(wbuff, L"wpath");
277         archive_entry_copy_pathname_w(e, wbuff);
278         assertEqualWString(archive_entry_pathname_w(e), L"wpath");
279         memset(wbuff, 0, sizeof(wbuff));
280         assertEqualWString(archive_entry_pathname_w(e), L"wpath");
281
282         /* rdev */
283         archive_entry_set_rdev(e, 532);
284         assertEqualInt(archive_entry_rdev(e), 532);
285         /* rdevmajor/rdevminor are tested specially below. */
286
287         /* size */
288         archive_entry_set_size(e, 987654321);
289         assertEqualInt(archive_entry_size(e), 987654321);
290         archive_entry_unset_size(e);
291         assertEqualInt(archive_entry_size(e), 0);
292         assert(!archive_entry_size_is_set(e));
293
294         /* sourcepath */
295         archive_entry_copy_sourcepath(e, "path1");
296         assertEqualString(archive_entry_sourcepath(e), "path1");
297
298         /* symlink */
299         archive_entry_set_symlink(e, "symlinkname");
300         assertEqualString(archive_entry_symlink(e), "symlinkname");
301         strcpy(buff, "symlinkname2");
302         archive_entry_copy_symlink(e, buff);
303         assertEqualString(archive_entry_symlink(e), "symlinkname2");
304         memset(buff, 0, sizeof(buff));
305         assertEqualString(archive_entry_symlink(e), "symlinkname2");
306         archive_entry_copy_symlink_w(e, NULL);
307         assertEqualWString(archive_entry_symlink_w(e), NULL);
308         assertEqualString(archive_entry_symlink(e), NULL);
309         archive_entry_copy_symlink_w(e, L"wsymlink");
310         assertEqualWString(archive_entry_symlink_w(e), L"wsymlink");
311         archive_entry_copy_symlink(e, NULL);
312         assertEqualWString(archive_entry_symlink_w(e), NULL);
313         assertEqualString(archive_entry_symlink(e), NULL);
314
315         /* uid */
316         archive_entry_set_uid(e, 83);
317         assertEqualInt(archive_entry_uid(e), 83);
318
319         /* uname */
320         archive_entry_set_uname(e, "user");
321         assertEqualString(archive_entry_uname(e), "user");
322         wcscpy(wbuff, L"wuser");
323         archive_entry_copy_gname_w(e, wbuff);
324         assertEqualWString(archive_entry_gname_w(e), L"wuser");
325         memset(wbuff, 0, sizeof(wbuff));
326         assertEqualWString(archive_entry_gname_w(e), L"wuser");
327
328         /* Test fflags interface. */
329         archive_entry_set_fflags(e, 0x55, 0xAA);
330         archive_entry_fflags(e, &set, &clear);
331         failure("Testing set/get of fflags data.");
332         assertEqualInt(set, 0x55);
333         failure("Testing set/get of fflags data.");
334         assertEqualInt(clear, 0xAA);
335 #ifdef __FreeBSD__
336         /* Converting fflags bitmap to string is currently system-dependent. */
337         /* TODO: Make this system-independent. */
338         assertEqualString(archive_entry_fflags_text(e),
339             "uappnd,nouchg,nodump,noopaque,uunlnk");
340         /* Test archive_entry_copy_fflags_text_w() */
341         archive_entry_copy_fflags_text_w(e, L" ,nouappnd, nouchg, dump,uunlnk");
342         archive_entry_fflags(e, &set, &clear);
343         assertEqualInt(16, set);
344         assertEqualInt(7, clear);
345         /* Test archive_entry_copy_fflags_text() */
346         archive_entry_copy_fflags_text(e, " ,nouappnd, nouchg, dump,uunlnk");
347         archive_entry_fflags(e, &set, &clear);
348         assertEqualInt(16, set);
349         assertEqualInt(7, clear);
350 #endif
351
352         /* See test_acl_basic.c for tests of ACL set/get consistency. */
353
354         /* Test xattrs set/get consistency. */
355         archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue1", 12);
356         assertEqualInt(1, archive_entry_xattr_reset(e));
357         assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize));
358         assertEqualString(xname, "xattr1");
359         assertEqualString(xval, "xattrvalue1");
360         assertEqualInt((int)xsize, 12);
361         assertEqualInt(1, archive_entry_xattr_count(e));
362         assertEqualInt(ARCHIVE_WARN,
363             archive_entry_xattr_next(e, &xname, &xval, &xsize));
364         assertEqualString(xname, NULL);
365         assertEqualString(xval, NULL);
366         assertEqualInt((int)xsize, 0);
367         archive_entry_xattr_clear(e);
368         assertEqualInt(0, archive_entry_xattr_reset(e));
369         assertEqualInt(ARCHIVE_WARN,
370             archive_entry_xattr_next(e, &xname, &xval, &xsize));
371         assertEqualString(xname, NULL);
372         assertEqualString(xval, NULL);
373         assertEqualInt((int)xsize, 0);
374         archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue1", 12);
375         assertEqualInt(1, archive_entry_xattr_reset(e));
376         archive_entry_xattr_add_entry(e, "xattr2", "xattrvalue2", 12);
377         assertEqualInt(2, archive_entry_xattr_reset(e));
378         assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize));
379         assertEqualInt(0, archive_entry_xattr_next(e, &xname, &xval, &xsize));
380         assertEqualInt(ARCHIVE_WARN,
381             archive_entry_xattr_next(e, &xname, &xval, &xsize));
382         assertEqualString(xname, NULL);
383         assertEqualString(xval, NULL);
384         assertEqualInt((int)xsize, 0);
385
386
387         /*
388          * Test clone() implementation.
389          */
390
391         /* Set values in 'e' */
392         archive_entry_clear(e);
393         archive_entry_set_atime(e, 13579, 24680);
394         archive_entry_set_birthtime(e, 13779, 24990);
395         archive_entry_set_ctime(e, 13580, 24681);
396         archive_entry_set_dev(e, 235);
397         archive_entry_set_fflags(e, 0x55, 0xAA);
398         archive_entry_set_gid(e, 204);
399         archive_entry_set_gname(e, "group");
400         archive_entry_set_hardlink(e, "hardlinkname");
401         archive_entry_set_ino(e, 8593);
402         archive_entry_set_mode(e, 0123456);
403         archive_entry_set_mtime(e, 13581, 24682);
404         archive_entry_set_nlink(e, 736);
405         archive_entry_set_pathname(e, "path");
406         archive_entry_set_rdev(e, 532);
407         archive_entry_set_size(e, 987654321);
408         archive_entry_copy_sourcepath(e, "source");
409         archive_entry_set_symlink(e, "symlinkname");
410         archive_entry_set_uid(e, 83);
411         archive_entry_set_uname(e, "user");
412         /* Add an ACL entry. */
413         archive_entry_acl_add_entry(e, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
414             ARCHIVE_ENTRY_ACL_READ, ARCHIVE_ENTRY_ACL_USER, 77, "user77");
415         /* Add an extended attribute. */
416         archive_entry_xattr_add_entry(e, "xattr1", "xattrvalue", 11);
417
418         /* Make a clone. */
419         e2 = archive_entry_clone(e);
420
421         /* Clone should have same contents. */
422         assertEqualInt(archive_entry_atime(e2), 13579);
423         assertEqualInt(archive_entry_atime_nsec(e2), 24680);
424         assertEqualInt(archive_entry_birthtime(e2), 13779);
425         assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
426         assertEqualInt(archive_entry_ctime(e2), 13580);
427         assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
428         assertEqualInt(archive_entry_dev(e2), 235);
429         archive_entry_fflags(e, &set, &clear);
430         assertEqualInt(clear, 0xAA);
431         assertEqualInt(set, 0x55);
432         assertEqualInt(archive_entry_gid(e2), 204);
433         assertEqualString(archive_entry_gname(e2), "group");
434         assertEqualString(archive_entry_hardlink(e2), "hardlinkname");
435         assertEqualInt(archive_entry_ino(e2), 8593);
436         assertEqualInt(archive_entry_mode(e2), 0123456);
437         assertEqualInt(archive_entry_mtime(e2), 13581);
438         assertEqualInt(archive_entry_mtime_nsec(e2), 24682);
439         assertEqualInt(archive_entry_nlink(e2), 736);
440         assertEqualString(archive_entry_pathname(e2), "path");
441         assertEqualInt(archive_entry_rdev(e2), 532);
442         assertEqualInt(archive_entry_size(e2), 987654321);
443         assertEqualString(archive_entry_sourcepath(e2), "source");
444         assertEqualString(archive_entry_symlink(e2), "symlinkname");
445         assertEqualInt(archive_entry_uid(e2), 83);
446         assertEqualString(archive_entry_uname(e2), "user");
447
448         /* Verify ACL was copied. */
449         assertEqualInt(4, archive_entry_acl_reset(e2,
450                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
451         /* First three are standard permission bits. */
452         assertEqualInt(0, archive_entry_acl_next(e2,
453                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
454                            &type, &permset, &tag, &qual, &name));
455         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
456         assertEqualInt(permset, 4);
457         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER_OBJ);
458         assertEqualInt(qual, -1);
459         assertEqualString(name, NULL);
460         assertEqualInt(0, archive_entry_acl_next(e2,
461                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
462                            &type, &permset, &tag, &qual, &name));
463         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
464         assertEqualInt(permset, 5);
465         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_GROUP_OBJ);
466         assertEqualInt(qual, -1);
467         assertEqualString(name, NULL);
468         assertEqualInt(0, archive_entry_acl_next(e2,
469                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
470                            &type, &permset, &tag, &qual, &name));
471         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
472         assertEqualInt(permset, 6);
473         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_OTHER);
474         assertEqualInt(qual, -1);
475         assertEqualString(name, NULL);
476         /* Fourth is custom one. */
477         assertEqualInt(0, archive_entry_acl_next(e2,
478                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
479                            &type, &permset, &tag, &qual, &name));
480         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
481         assertEqualInt(permset, ARCHIVE_ENTRY_ACL_READ);
482         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER);
483         assertEqualInt(qual, 77);
484         assertEqualString(name, "user77");
485
486         /* Verify xattr was copied. */
487         assertEqualInt(1, archive_entry_xattr_reset(e2));
488         assertEqualInt(0, archive_entry_xattr_next(e2, &xname, &xval, &xsize));
489         assertEqualString(xname, "xattr1");
490         assertEqualString(xval, "xattrvalue");
491         assertEqualInt((int)xsize, 11);
492         assertEqualInt(ARCHIVE_WARN,
493             archive_entry_xattr_next(e2, &xname, &xval, &xsize));
494         assertEqualString(xname, NULL);
495         assertEqualString(xval, NULL);
496         assertEqualInt((int)xsize, 0);
497
498         /* Change the original */
499         archive_entry_set_atime(e, 13580, 24690);
500         archive_entry_set_birthtime(e, 13980, 24999);
501         archive_entry_set_ctime(e, 13590, 24691);
502         archive_entry_set_dev(e, 245);
503         archive_entry_set_fflags(e, 0x85, 0xDA);
504         archive_entry_set_filetype(e, AE_IFLNK);
505         archive_entry_set_gid(e, 214);
506         archive_entry_set_gname(e, "grouper");
507         archive_entry_set_hardlink(e, "hardlinkpath");
508         archive_entry_set_ino(e, 8763);
509         archive_entry_set_mode(e, 0123654);
510         archive_entry_set_mtime(e, 18351, 28642);
511         archive_entry_set_nlink(e, 73);
512         archive_entry_set_pathname(e, "pathest");
513         archive_entry_set_rdev(e, 132);
514         archive_entry_set_size(e, 987456321);
515         archive_entry_copy_sourcepath(e, "source2");
516         archive_entry_set_symlink(e, "symlinkpath");
517         archive_entry_set_uid(e, 93);
518         archive_entry_set_uname(e, "username");
519         archive_entry_acl_clear(e);
520         archive_entry_xattr_clear(e);
521
522         /* Clone should still have same contents. */
523         assertEqualInt(archive_entry_atime(e2), 13579);
524         assertEqualInt(archive_entry_atime_nsec(e2), 24680);
525         assertEqualInt(archive_entry_birthtime(e2), 13779);
526         assertEqualInt(archive_entry_birthtime_nsec(e2), 24990);
527         assertEqualInt(archive_entry_ctime(e2), 13580);
528         assertEqualInt(archive_entry_ctime_nsec(e2), 24681);
529         assertEqualInt(archive_entry_dev(e2), 235);
530         archive_entry_fflags(e2, &set, &clear);
531         assertEqualInt(clear, 0xAA);
532         assertEqualInt(set, 0x55);
533         assertEqualInt(archive_entry_gid(e2), 204);
534         assertEqualString(archive_entry_gname(e2), "group");
535         assertEqualString(archive_entry_hardlink(e2), "hardlinkname");
536         assertEqualInt(archive_entry_ino(e2), 8593);
537         assertEqualInt(archive_entry_mode(e2), 0123456);
538         assertEqualInt(archive_entry_mtime(e2), 13581);
539         assertEqualInt(archive_entry_mtime_nsec(e2), 24682);
540         assertEqualInt(archive_entry_nlink(e2), 736);
541         assertEqualString(archive_entry_pathname(e2), "path");
542         assertEqualInt(archive_entry_rdev(e2), 532);
543         assertEqualInt(archive_entry_size(e2), 987654321);
544         assertEqualString(archive_entry_sourcepath(e2), "source");
545         assertEqualString(archive_entry_symlink(e2), "symlinkname");
546         assertEqualInt(archive_entry_uid(e2), 83);
547         assertEqualString(archive_entry_uname(e2), "user");
548
549         /* Verify ACL was unchanged. */
550         assertEqualInt(4, archive_entry_acl_reset(e2,
551                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
552         /* First three are standard permission bits. */
553         assertEqualInt(0, archive_entry_acl_next(e2,
554                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
555                            &type, &permset, &tag, &qual, &name));
556         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
557         assertEqualInt(permset, 4);
558         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER_OBJ);
559         assertEqualInt(qual, -1);
560         assertEqualString(name, NULL);
561         assertEqualInt(0, archive_entry_acl_next(e2,
562                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
563                            &type, &permset, &tag, &qual, &name));
564         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
565         assertEqualInt(permset, 5);
566         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_GROUP_OBJ);
567         assertEqualInt(qual, -1);
568         assertEqualString(name, NULL);
569         assertEqualInt(0, archive_entry_acl_next(e2,
570                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
571                            &type, &permset, &tag, &qual, &name));
572         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
573         assertEqualInt(permset, 6);
574         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_OTHER);
575         assertEqualInt(qual, -1);
576         assertEqualString(name, NULL);
577         /* Fourth is custom one. */
578         assertEqualInt(0, archive_entry_acl_next(e2,
579                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
580                            &type, &permset, &tag, &qual, &name));
581         assertEqualInt(type, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
582         assertEqualInt(permset, ARCHIVE_ENTRY_ACL_READ);
583         assertEqualInt(tag, ARCHIVE_ENTRY_ACL_USER);
584         assertEqualInt(qual, 77);
585         assertEqualString(name, "user77");
586         assertEqualInt(1, archive_entry_acl_next(e2,
587                            ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
588                            &type, &permset, &tag, &qual, &name));
589         assertEqualInt(type, 0);
590         assertEqualInt(permset, 0);
591         assertEqualInt(tag, 0);
592         assertEqualInt(qual, -1);
593         assertEqualString(name, NULL);
594
595         /* Verify xattr was unchanged. */
596         assertEqualInt(1, archive_entry_xattr_reset(e2));
597
598         /* Release clone. */
599         archive_entry_free(e2);
600
601         /*
602          * Test clear() implementation.
603          */
604         archive_entry_clear(e);
605         assertEqualInt(archive_entry_atime(e), 0);
606         assertEqualInt(archive_entry_atime_nsec(e), 0);
607         assertEqualInt(archive_entry_birthtime(e), 0);
608         assertEqualInt(archive_entry_birthtime_nsec(e), 0);
609         assertEqualInt(archive_entry_ctime(e), 0);
610         assertEqualInt(archive_entry_ctime_nsec(e), 0);
611         assertEqualInt(archive_entry_dev(e), 0);
612         archive_entry_fflags(e, &set, &clear);
613         assertEqualInt(clear, 0);
614         assertEqualInt(set, 0);
615         assertEqualInt(archive_entry_filetype(e), 0);
616         assertEqualInt(archive_entry_gid(e), 0);
617         assertEqualString(archive_entry_gname(e), NULL);
618         assertEqualString(archive_entry_hardlink(e), NULL);
619         assertEqualInt(archive_entry_ino(e), 0);
620         assertEqualInt(archive_entry_mode(e), 0);
621         assertEqualInt(archive_entry_mtime(e), 0);
622         assertEqualInt(archive_entry_mtime_nsec(e), 0);
623         assertEqualInt(archive_entry_nlink(e), 0);
624         assertEqualString(archive_entry_pathname(e), NULL);
625         assertEqualInt(archive_entry_rdev(e), 0);
626         assertEqualInt(archive_entry_size(e), 0);
627         assertEqualString(archive_entry_symlink(e), NULL);
628         assertEqualInt(archive_entry_uid(e), 0);
629         assertEqualString(archive_entry_uname(e), NULL);
630         /* ACLs should be cleared. */
631         assertEqualInt(archive_entry_acl_count(e, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), 0);
632         assertEqualInt(archive_entry_acl_count(e, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT), 0);
633         /* Extended attributes should be cleared. */
634         assertEqualInt(archive_entry_xattr_count(e), 0);
635
636         /*
637          * Test archive_entry_copy_stat().
638          */
639         memset(&st, 0, sizeof(st));
640         /* Set all of the standard 'struct stat' fields. */
641         st.st_atime = 456789;
642         st.st_ctime = 345678;
643         st.st_dev = 123;
644         st.st_gid = 34;
645         st.st_ino = 234;
646         st.st_mode = 077777;
647         st.st_mtime = 234567;
648         st.st_nlink = 345;
649         st.st_size = 123456789;
650         st.st_uid = 23;
651 #ifdef __FreeBSD__
652         /* On FreeBSD, high-res timestamp data should come through. */
653         st.st_atimespec.tv_nsec = 6543210;
654         st.st_ctimespec.tv_nsec = 5432109;
655         st.st_mtimespec.tv_nsec = 3210987;
656         st.st_birthtimespec.tv_nsec = 7459386;
657 #endif
658         /* Copy them into the entry. */
659         archive_entry_copy_stat(e, &st);
660         /* Read each one back separately and compare. */
661         assertEqualInt(archive_entry_atime(e), 456789);
662         assertEqualInt(archive_entry_ctime(e), 345678);
663         assertEqualInt(archive_entry_dev(e), 123);
664         assertEqualInt(archive_entry_gid(e), 34);
665         assertEqualInt(archive_entry_ino(e), 234);
666         assertEqualInt(archive_entry_mode(e), 077777);
667         assertEqualInt(archive_entry_mtime(e), 234567);
668         assertEqualInt(archive_entry_nlink(e), 345);
669         assertEqualInt(archive_entry_size(e), 123456789);
670         assertEqualInt(archive_entry_uid(e), 23);
671 #if __FreeBSD__
672         /* On FreeBSD, high-res timestamp data should come through. */
673         assertEqualInt(archive_entry_atime_nsec(e), 6543210);
674         assertEqualInt(archive_entry_ctime_nsec(e), 5432109);
675         assertEqualInt(archive_entry_mtime_nsec(e), 3210987);
676         assertEqualInt(archive_entry_birthtime_nsec(e), 7459386);
677 #endif
678
679         /*
680          * Test archive_entry_stat().
681          */
682         /* First, clear out any existing stat data. */
683         memset(&st, 0, sizeof(st));
684         archive_entry_copy_stat(e, &st);
685         /* Set a bunch of fields individually. */
686         archive_entry_set_atime(e, 456789, 321);
687         archive_entry_set_ctime(e, 345678, 432);
688         archive_entry_set_dev(e, 123);
689         archive_entry_set_gid(e, 34);
690         archive_entry_set_ino(e, 234);
691         archive_entry_set_mode(e, 012345);
692         archive_entry_set_mode(e, 012345);
693         archive_entry_set_mtime(e, 234567, 543);
694         archive_entry_set_nlink(e, 345);
695         archive_entry_set_size(e, 123456789);
696         archive_entry_set_uid(e, 23);
697         /* Retrieve a stat structure. */
698         assert((pst = archive_entry_stat(e)) != NULL);
699         if (pst == NULL)
700                 return;
701         /* Check that the values match. */
702         assertEqualInt(pst->st_atime, 456789);
703         assertEqualInt(pst->st_ctime, 345678);
704         assertEqualInt(pst->st_dev, 123);
705         assertEqualInt(pst->st_gid, 34);
706         assertEqualInt(pst->st_ino, 234);
707         assertEqualInt(pst->st_mode, 012345);
708         assertEqualInt(pst->st_mtime, 234567);
709         assertEqualInt(pst->st_nlink, 345);
710         assertEqualInt(pst->st_size, 123456789);
711         assertEqualInt(pst->st_uid, 23);
712 #ifdef __FreeBSD__
713         /* On FreeBSD, high-res timestamp data should come through. */
714         assertEqualInt(pst->st_atimespec.tv_nsec, 321);
715         assertEqualInt(pst->st_ctimespec.tv_nsec, 432);
716         assertEqualInt(pst->st_mtimespec.tv_nsec, 543);
717 #endif
718
719         /* Changing any one value should update struct stat. */
720         archive_entry_set_atime(e, 456788, 0);
721         assert((pst = archive_entry_stat(e)) != NULL);
722         if (pst == NULL)
723                 return;
724         assertEqualInt(pst->st_atime, 456788);
725         archive_entry_set_ctime(e, 345677, 431);
726         assert((pst = archive_entry_stat(e)) != NULL);
727         if (pst == NULL)
728                 return;
729         assertEqualInt(pst->st_ctime, 345677);
730         archive_entry_set_dev(e, 122);
731         assert((pst = archive_entry_stat(e)) != NULL);
732         if (pst == NULL)
733                 return;
734         assertEqualInt(pst->st_dev, 122);
735         archive_entry_set_gid(e, 33);
736         assert((pst = archive_entry_stat(e)) != NULL);
737         if (pst == NULL)
738                 return;
739         assertEqualInt(pst->st_gid, 33);
740         archive_entry_set_ino(e, 233);
741         assert((pst = archive_entry_stat(e)) != NULL);
742         if (pst == NULL)
743                 return;
744         assertEqualInt(pst->st_ino, 233);
745         archive_entry_set_mode(e, 012344);
746         assert((pst = archive_entry_stat(e)) != NULL);
747         if (pst == NULL)
748                 return;
749         assertEqualInt(pst->st_mode, 012344);
750         archive_entry_set_mtime(e, 234566, 542);
751         assert((pst = archive_entry_stat(e)) != NULL);
752         if (pst == NULL)
753                 return;
754         assertEqualInt(pst->st_mtime, 234566);
755         archive_entry_set_nlink(e, 344);
756         assert((pst = archive_entry_stat(e)) != NULL);
757         if (pst == NULL)
758                 return;
759         assertEqualInt(pst->st_nlink, 344);
760         archive_entry_set_size(e, 123456788);
761         assert((pst = archive_entry_stat(e)) != NULL);
762         if (pst == NULL)
763                 return;
764         assertEqualInt(pst->st_size, 123456788);
765         archive_entry_set_uid(e, 22);
766         assert((pst = archive_entry_stat(e)) != NULL);
767         if (pst == NULL)
768                 return;
769         assertEqualInt(pst->st_uid, 22);
770         /* We don't need to check high-res fields here. */
771
772         /*
773          * Test dev/major/minor interfaces.  Setting 'dev' or 'rdev'
774          * should change the corresponding major/minor values, and
775          * vice versa.
776          *
777          * The test here is system-specific because it assumes that
778          * makedev(), major(), and minor() are defined in sys/stat.h.
779          * I'm not too worried about it, though, because the code is
780          * simple.  If it works on FreeBSD, it's unlikely to be broken
781          * anywhere else.  Note: The functionality is present on every
782          * platform even if these tests only run some places;
783          * libarchive's more extensive configuration logic should find
784          * the necessary definitions on every platform.
785          */
786 #if __FreeBSD__
787         archive_entry_set_dev(e, 0x12345678);
788         assertEqualInt(archive_entry_devmajor(e), major(0x12345678));
789         assertEqualInt(archive_entry_devminor(e), minor(0x12345678));
790         assertEqualInt(archive_entry_dev(e), 0x12345678);
791         archive_entry_set_devmajor(e, 0xfe);
792         archive_entry_set_devminor(e, 0xdcba98);
793         assertEqualInt(archive_entry_devmajor(e), 0xfe);
794         assertEqualInt(archive_entry_devminor(e), 0xdcba98);
795         assertEqualInt(archive_entry_dev(e), makedev(0xfe, 0xdcba98));
796         archive_entry_set_rdev(e, 0x12345678);
797         assertEqualInt(archive_entry_rdevmajor(e), major(0x12345678));
798         assertEqualInt(archive_entry_rdevminor(e), minor(0x12345678));
799         assertEqualInt(archive_entry_rdev(e), 0x12345678);
800         archive_entry_set_rdevmajor(e, 0xfe);
801         archive_entry_set_rdevminor(e, 0xdcba98);
802         assertEqualInt(archive_entry_rdevmajor(e), 0xfe);
803         assertEqualInt(archive_entry_rdevminor(e), 0xdcba98);
804         assertEqualInt(archive_entry_rdev(e), makedev(0xfe, 0xdcba98));
805 #endif
806
807         /*
808          * Exercise the character-conversion logic, if we can.
809          */
810         if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
811                 skipping("Can't exercise charset-conversion logic without"
812                         " a suitable locale.");
813         } else {
814                 /* A filename that cannot be converted to wide characters. */
815                 archive_entry_copy_pathname(e, "abc\314\214mno\374xyz");
816                 failure("Converting invalid chars to Unicode should fail.");
817                 assert(NULL == archive_entry_pathname_w(e));
818                 /*
819                   failure("Converting invalid chars to UTF-8 should fail.");
820                   assert(NULL == archive_entry_pathname_utf8(e));
821                 */
822
823                 /* A group name that cannot be converted. */
824                 archive_entry_copy_gname(e, "abc\314\214mno\374xyz");
825                 failure("Converting invalid chars to Unicode should fail.");
826                 assert(NULL == archive_entry_gname_w(e));
827
828                 /* A user name that cannot be converted. */
829                 archive_entry_copy_uname(e, "abc\314\214mno\374xyz");
830                 failure("Converting invalid chars to Unicode should fail.");
831                 assert(NULL == archive_entry_uname_w(e));
832
833                 /* A hardlink target that cannot be converted. */
834                 archive_entry_copy_hardlink(e, "abc\314\214mno\374xyz");
835                 failure("Converting invalid chars to Unicode should fail.");
836                 assert(NULL == archive_entry_hardlink_w(e));
837
838                 /* A symlink target that cannot be converted. */
839                 archive_entry_copy_symlink(e, "abc\314\214mno\374xyz");
840                 failure("Converting invalid chars to Unicode should fail.");
841                 assert(NULL == archive_entry_symlink_w(e));
842         }
843
844         l = 0x12345678L;
845         wc = (wchar_t)l; /* Wide character too big for UTF-8. */
846         if (NULL == setlocale(LC_ALL, "C") || (long)wc != l) {
847                 skipping("Testing charset conversion failure requires 32-bit wchar_t and support for \"C\" locale.");
848         } else {
849                 /*
850                  * Build the string L"xxx\U12345678yyy\u5678zzz" without
851                  * using wcscpy or C99 \u#### syntax.
852                  */
853                 name = "xxxAyyyBzzz";
854                 for (i = 0; i < (int)strlen(name); ++i)
855                         wbuff[i] = name[i];
856                 wbuff[3] = (wchar_t)0x12345678;
857                 wbuff[7] = (wchar_t)0x5678;
858                 /* A Unicode filename that cannot be converted to UTF-8. */
859                 archive_entry_copy_pathname_w(e, wbuff);
860                 failure("Converting wide characters from Unicode should fail.");
861                 assertEqualString(NULL, archive_entry_pathname(e));
862         }
863
864         /* Release the experimental entry. */
865         archive_entry_free(e);
866 }