test_entry.c revision 348608
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: stable/10/contrib/libarchive/libarchive/test/test_entry.c 348608 2019-06-04 10:36:26Z mm $");
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
35static 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
55DEFINE_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}
892