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