2 * Copyright (c) 2003-2007 Tim Kientzle
3 * Copyright (c) 2012 Michihiro NAKAJIMA
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 __FBSDID("$FreeBSD$");
29 #ifdef HAVE_SYS_XATTR_H
30 #include <sys/xattr.h>
33 #if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\
34 && defined(HAVE_ZLIB_H)
36 has_xattr(const char *filename, const char *xattrname)
42 r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION);
49 if (!assert(nl != NULL))
52 r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION);
59 for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) {
60 if (strcmp(nlp, xattrname) == 0) {
69 get_rsrc_footer(const char *filename, char *buff, size_t s)
73 r = getxattr(filename, "com.apple.ResourceFork", NULL, 0, 0,
74 XATTR_SHOWCOMPRESSION);
77 r = getxattr(filename, "com.apple.ResourceFork", buff, s,
78 r - s, XATTR_SHOWCOMPRESSION);
87 * Exercise HFS+ Compression.
89 DEFINE_TEST(test_write_disk_hfs_compression)
91 #if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\
92 || !defined(HAVE_ZLIB_H)
93 skipping("MacOS-specific HFS+ Compression test");
95 const char *refname = "test_write_disk_hfs_compression.tgz";
96 struct archive *ad, *a;
97 struct archive_entry *ae;
100 static const char rsrc_footer[50] = {
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x1c, 0x00, 0x32, 0x00, 0x00, 'c', 'm',
105 'p', 'f', 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01,
106 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 extract_reference_file(refname);
113 * Extract an archive to disk with HFS+ Compression.
115 assert((ad = archive_write_disk_new()) != NULL);
116 assertEqualIntA(ad, ARCHIVE_OK,
117 archive_write_disk_set_standard_lookup(ad));
118 assertEqualIntA(ad, ARCHIVE_OK,
119 archive_write_disk_set_options(ad,
120 ARCHIVE_EXTRACT_TIME |
121 ARCHIVE_EXTRACT_SECURE_SYMLINKS |
122 ARCHIVE_EXTRACT_SECURE_NODOTDOT |
123 ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED));
125 assert((a = archive_read_new()) != NULL);
126 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
127 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
128 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a,
131 assertMakeDir("hfscmp", 0755);
132 assertChdir("hfscmp");
135 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
136 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
137 /* Extract README. */
138 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
139 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
141 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
142 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
143 /* Extract Makefile. */
144 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
145 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
147 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
148 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
149 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
150 assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad));
153 assertEqualInt(0, stat("file1", &st));
154 assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
155 assertFileSize("file1", 8);
156 failure("'%s' should not have Resource Fork", "file1");
157 assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork"));
158 failure("'%s' should have decompfs xattr", "file1");
159 assertEqualInt(1, has_xattr("file1", "com.apple.decmpfs"));
162 assertEqualInt(0, stat("README", &st));
163 assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
164 assertFileSize("README", 6586);
165 failure("'%s' should not have Resource Fork", "README");
166 assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork"));
167 failure("'%s' should have decompfs xattr", "README");
168 assertEqualInt(1, has_xattr("README", "com.apple.decmpfs"));
171 assertEqualInt(0, stat("NEWS", &st));
172 assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
173 assertFileSize("NEWS", 28438);
174 failure("'%s' should have Resource Fork", "NEWS");
175 assertEqualInt(1, has_xattr("NEWS", "com.apple.ResourceFork"));
176 failure("'%s' should have decompfs xattr", "NEWS");
177 assertEqualInt(1, has_xattr("NEWS", "com.apple.decmpfs"));
178 assertEqualInt(0, get_rsrc_footer("NEWS", rsrc, sizeof(rsrc)));
179 failure("Resource Fork should have consistent 50 bytes data");
180 assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc));
183 assertEqualInt(0, stat("Makefile", &st));
184 assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
185 assertFileSize("Makefile", 1264000);
186 failure("'%s' should have Resource Fork", "Makefile");
187 assertEqualInt(1, has_xattr("Makefile", "com.apple.ResourceFork"));
188 failure("'%s' should have decompfs xattr", "Makefile");
189 assertEqualInt(1, has_xattr("Makefile", "com.apple.decmpfs"));
190 assertEqualInt(0, get_rsrc_footer("Makefile", rsrc, sizeof(rsrc)));
191 failure("Resource Fork should have consistent 50 bytes data");
192 assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc));
197 * Extract an archive to disk without HFS+ Compression.
199 assert((ad = archive_write_disk_new()) != NULL);
200 assertEqualIntA(ad, ARCHIVE_OK,
201 archive_write_disk_set_standard_lookup(ad));
202 assertEqualIntA(ad, ARCHIVE_OK,
203 archive_write_disk_set_options(ad,
204 ARCHIVE_EXTRACT_TIME |
205 ARCHIVE_EXTRACT_SECURE_SYMLINKS |
206 ARCHIVE_EXTRACT_SECURE_NODOTDOT));
208 assert((a = archive_read_new()) != NULL);
209 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
210 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
211 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a,
214 assertMakeDir("nocmp", 0755);
215 assertChdir("nocmp");
218 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
219 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
220 /* Extract README. */
221 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
222 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
224 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
225 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
226 /* Extract Makefile. */
227 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
228 assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
230 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
231 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
232 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
233 assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad));
236 assertEqualInt(0, stat("file1", &st));
237 assertEqualInt(0, st.st_flags & UF_COMPRESSED);
238 assertFileSize("file1", 8);
239 failure("'%s' should not have Resource Fork", "file1");
240 assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork"));
241 failure("'%s' should not have decmpfs", "file1");
242 assertEqualInt(0, has_xattr("file1", "com.apple.decmpfs"));
245 assertEqualInt(0, stat("README", &st));
246 assertEqualInt(0, st.st_flags & UF_COMPRESSED);
247 assertFileSize("README", 6586);
248 failure("'%s' should not have Resource Fork", "README");
249 assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork"));
250 failure("'%s' should not have decmpfs", "README");
251 assertEqualInt(0, has_xattr("README", "com.apple.decmpfs"));
254 assertEqualInt(0, stat("NEWS", &st));
255 assertEqualInt(0, st.st_flags & UF_COMPRESSED);
256 assertFileSize("NEWS", 28438);
257 failure("'%s' should not have Resource Fork", "NEWS");
258 assertEqualInt(0, has_xattr("NEWS", "com.apple.ResourceFork"));
259 failure("'%s' should not have decmpfs", "NEWS");
260 assertEqualInt(0, has_xattr("NEWS", "com.apple.decmpfs"));
263 assertEqualInt(0, stat("Makefile", &st));
264 assertEqualInt(0, st.st_flags & UF_COMPRESSED);
265 assertFileSize("Makefile", 1264000);
266 failure("'%s' should not have Resource Fork", "Makefile");
267 assertEqualInt(0, has_xattr("Makefile", "com.apple.ResourceFork"));
268 failure("'%s' should not have decmpfs", "Makefile");
269 assertEqualInt(0, has_xattr("Makefile", "com.apple.decmpfs"));
273 assertEqualFile("hfscmp/file1", "nocmp/file1");
274 assertEqualFile("hfscmp/README", "nocmp/README");
275 assertEqualFile("hfscmp/NEWS", "nocmp/NEWS");
276 assertEqualFile("hfscmp/Makefile", "nocmp/Makefile");