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