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