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