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