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