Blame libarchive/test/test_write_disk_hfs_compression.c

Packit Service 1d0348
/*-
Packit Service 1d0348
 * Copyright (c) 2003-2007 Tim Kientzle
Packit Service 1d0348
 * Copyright (c) 2012 Michihiro NAKAJIMA
Packit Service 1d0348
 * All rights reserved.
Packit Service 1d0348
 *
Packit Service 1d0348
 * Redistribution and use in source and binary forms, with or without
Packit Service 1d0348
 * modification, are permitted provided that the following conditions
Packit Service 1d0348
 * are met:
Packit Service 1d0348
 * 1. Redistributions of source code must retain the above copyright
Packit Service 1d0348
 *    notice, this list of conditions and the following disclaimer.
Packit Service 1d0348
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 1d0348
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 1d0348
 *    documentation and/or other materials provided with the distribution.
Packit Service 1d0348
 *
Packit Service 1d0348
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
Packit Service 1d0348
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Packit Service 1d0348
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
Packit Service 1d0348
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
Packit Service 1d0348
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
Packit Service 1d0348
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit Service 1d0348
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit Service 1d0348
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit Service 1d0348
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
Packit Service 1d0348
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit Service 1d0348
 */
Packit Service 1d0348
#include "test.h"
Packit Service 1d0348
__FBSDID("$FreeBSD$");
Packit Service 1d0348
Packit Service 1d0348
#ifdef HAVE_SYS_XATTR_H
Packit Service 1d0348
#include <sys/xattr.h>
Packit Service 1d0348
#endif
Packit Service 1d0348
Packit Service 1d0348
#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\
Packit Service 1d0348
	&& defined(HAVE_ZLIB_H)
Packit Service 1d0348
static int
Packit Service 1d0348
has_xattr(const char *filename, const char *xattrname)
Packit Service 1d0348
{
Packit Service 1d0348
	char *nl, *nlp;
Packit Service 1d0348
	ssize_t r;
Packit Service 1d0348
	int exisiting;
Packit Service 1d0348
Packit Service 1d0348
	r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION);
Packit Service 1d0348
	if (r < 0)
Packit Service 1d0348
		return (0);
Packit Service 1d0348
	if (r == 0)
Packit Service 1d0348
		return (0);
Packit Service 1d0348
Packit Service 1d0348
	assert((nl = malloc(r)) != NULL);
Packit Service 1d0348
	if (nl == NULL)
Packit Service 1d0348
		return (0);
Packit Service 1d0348
Packit Service 1d0348
	r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION);
Packit Service 1d0348
	if (r < 0) {
Packit Service 1d0348
		free(nl);
Packit Service 1d0348
		return (0);
Packit Service 1d0348
	}
Packit Service 1d0348
Packit Service 1d0348
	exisiting = 0;
Packit Service 1d0348
	for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) {
Packit Service 1d0348
		if (strcmp(nlp, xattrname) == 0) {
Packit Service 1d0348
			exisiting = 1;
Packit Service 1d0348
			break;
Packit Service 1d0348
		}
Packit Service 1d0348
	}
Packit Service 1d0348
	free(nl);
Packit Service 1d0348
	return (exisiting);
Packit Service 1d0348
}
Packit Service 1d0348
static int
Packit Service 1d0348
get_rsrc_footer(const char *filename, char *buff, size_t s)
Packit Service 1d0348
{
Packit Service 1d0348
	ssize_t r;
Packit Service 1d0348
Packit Service 1d0348
	r = getxattr(filename, "com.apple.ResourceFork", NULL, 0, 0,
Packit Service 1d0348
	    XATTR_SHOWCOMPRESSION);
Packit Service 1d0348
	if (r < (ssize_t)s)
Packit Service 1d0348
		return (-1);
Packit Service 1d0348
	r = getxattr(filename, "com.apple.ResourceFork", buff, s,
Packit Service 1d0348
	    r - s, XATTR_SHOWCOMPRESSION);
Packit Service 1d0348
	if (r < (ssize_t)s)
Packit Service 1d0348
		return (-1);
Packit Service 1d0348
	return (0);
Packit Service 1d0348
}
Packit Service 1d0348
Packit Service 1d0348
#endif
Packit Service 1d0348
Packit Service 1d0348
/*
Packit Service 1d0348
 * Exercise HFS+ Compression.
Packit Service 1d0348
 */
Packit Service 1d0348
DEFINE_TEST(test_write_disk_hfs_compression)
Packit Service 1d0348
{
Packit Service 1d0348
#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\
Packit Service 1d0348
	|| !defined(HAVE_ZLIB_H)
Packit Service 1d0348
	skipping("MacOS-specific HFS+ Compression test");
Packit Service 1d0348
#else
Packit Service 1d0348
	const char *refname = "test_write_disk_hfs_compression.tgz";
Packit Service 1d0348
	struct archive *ad, *a;
Packit Service 1d0348
	struct archive_entry *ae;
Packit Service 1d0348
	struct stat st;
Packit Service 1d0348
	char rsrc[50];
Packit Service 1d0348
	static const char rsrc_footer[50] = {
Packit Service 1d0348
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 1d0348
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 1d0348
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 1d0348
		0x00, 0x1c, 0x00, 0x32, 0x00, 0x00, 'c',  'm',
Packit Service 1d0348
		'p', 'f',   0x00, 0x00, 0x00, 0x0a, 0x00, 0x01,
Packit Service 1d0348
		0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Packit Service 1d0348
		0x00, 0x00
Packit Service 1d0348
	};
Packit Service 1d0348
Packit Service 1d0348
	extract_reference_file(refname);
Packit Service 1d0348
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * Extract an archive to disk with HFS+ Compression.
Packit Service 1d0348
	 */
Packit Service 1d0348
	assert((ad = archive_write_disk_new()) != NULL);
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK,
Packit Service 1d0348
	    archive_write_disk_set_standard_lookup(ad));
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK,
Packit Service 1d0348
	    archive_write_disk_set_options(ad,
Packit Service 1d0348
		ARCHIVE_EXTRACT_TIME |
Packit Service 1d0348
		ARCHIVE_EXTRACT_SECURE_SYMLINKS |
Packit Service 1d0348
		ARCHIVE_EXTRACT_SECURE_NODOTDOT |
Packit Service 1d0348
		ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED));
Packit Service 1d0348
Packit Service 1d0348
	assert((a = archive_read_new()) != NULL);
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a,
Packit Service 1d0348
	    refname, 512 * 20));
Packit Service 1d0348
Packit Service 1d0348
	assertMakeDir("hfscmp", 0755);
Packit Service 1d0348
	assertChdir("hfscmp");
Packit Service 1d0348
Packit Service 1d0348
	/* Extract file1. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract README. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract NEWS. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract Makefile. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
Packit Service 1d0348
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad));
Packit Service 1d0348
Packit Service 1d0348
	/* Test file1. */
Packit Service 1d0348
	assertEqualInt(0, stat("file1", &st);;
Packit Service 1d0348
	assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("file1", 8);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "file1");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should have decompfs xattr", "file1");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("file1", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	/* Test README. */
Packit Service 1d0348
	assertEqualInt(0, stat("README", &st);;
Packit Service 1d0348
	assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("README", 6586);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "README");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should have decompfs xattr", "README");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("README", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	/* Test NEWS. */
Packit Service 1d0348
	assertEqualInt(0, stat("NEWS", &st);;
Packit Service 1d0348
	assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("NEWS", 28438);
Packit Service 1d0348
	failure("'%s' should have Resource Fork", "NEWS");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("NEWS", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should have decompfs xattr", "NEWS");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("NEWS", "com.apple.decmpfs"));
Packit Service 1d0348
	assertEqualInt(0, get_rsrc_footer("NEWS", rsrc, sizeof(rsrc)));
Packit Service 1d0348
	failure("Resource Fork should have consistent 50 bytes data");
Packit Service 1d0348
	assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc));
Packit Service 1d0348
Packit Service 1d0348
	/* Test Makefile. */
Packit Service 1d0348
	assertEqualInt(0, stat("Makefile", &st);;
Packit Service 1d0348
	assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("Makefile", 1264000);
Packit Service 1d0348
	failure("'%s' should have Resource Fork", "Makefile");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("Makefile", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should have decompfs xattr", "Makefile");
Packit Service 1d0348
	assertEqualInt(1, has_xattr("Makefile", "com.apple.decmpfs"));
Packit Service 1d0348
	assertEqualInt(0, get_rsrc_footer("Makefile", rsrc, sizeof(rsrc)));
Packit Service 1d0348
	failure("Resource Fork should have consistent 50 bytes data");
Packit Service 1d0348
	assertEqualMem(rsrc_footer, rsrc, sizeof(rsrc));
Packit Service 1d0348
Packit Service 1d0348
	assertChdir("..");
Packit Service 1d0348
Packit Service 1d0348
	/*
Packit Service 1d0348
	 * Extract an archive to disk without HFS+ Compression.
Packit Service 1d0348
	 */
Packit Service 1d0348
	assert((ad = archive_write_disk_new()) != NULL);
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK,
Packit Service 1d0348
	    archive_write_disk_set_standard_lookup(ad));
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK,
Packit Service 1d0348
	    archive_write_disk_set_options(ad,
Packit Service 1d0348
		ARCHIVE_EXTRACT_TIME |
Packit Service 1d0348
		ARCHIVE_EXTRACT_SECURE_SYMLINKS |
Packit Service 1d0348
		ARCHIVE_EXTRACT_SECURE_NODOTDOT));
Packit Service 1d0348
Packit Service 1d0348
	assert((a = archive_read_new()) != NULL);
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a,
Packit Service 1d0348
	    refname, 512 * 20));
Packit Service 1d0348
Packit Service 1d0348
	assertMakeDir("nocmp", 0755);
Packit Service 1d0348
	assertChdir("nocmp");
Packit Service 1d0348
Packit Service 1d0348
	/* Extract file1. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract README. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract NEWS. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
	/* Extract Makefile. */
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad));
Packit Service 1d0348
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae);;
Packit Service 1d0348
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
Packit Service 1d0348
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
Packit Service 1d0348
	assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad));
Packit Service 1d0348
Packit Service 1d0348
	/* Test file1. */
Packit Service 1d0348
	assertEqualInt(0, stat("file1", &st);;
Packit Service 1d0348
	assertEqualInt(0, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("file1", 8);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "file1");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("file1", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should not have decmpfs", "file1");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("file1", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	/* Test README. */
Packit Service 1d0348
	assertEqualInt(0, stat("README", &st);;
Packit Service 1d0348
	assertEqualInt(0, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("README", 6586);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "README");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("README", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should not have decmpfs", "README");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("README", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	/* Test NEWS. */
Packit Service 1d0348
	assertEqualInt(0, stat("NEWS", &st);;
Packit Service 1d0348
	assertEqualInt(0, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("NEWS", 28438);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "NEWS");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("NEWS", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should not have decmpfs", "NEWS");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("NEWS", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	/* Test Makefile. */
Packit Service 1d0348
	assertEqualInt(0, stat("Makefile", &st);;
Packit Service 1d0348
	assertEqualInt(0, st.st_flags & UF_COMPRESSED);
Packit Service 1d0348
	assertFileSize("Makefile", 1264000);
Packit Service 1d0348
	failure("'%s' should not have Resource Fork", "Makefile");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("Makefile", "com.apple.ResourceFork"));
Packit Service 1d0348
	failure("'%s' should not have decmpfs", "Makefile");
Packit Service 1d0348
	assertEqualInt(0, has_xattr("Makefile", "com.apple.decmpfs"));
Packit Service 1d0348
Packit Service 1d0348
	assertChdir("..");
Packit Service 1d0348
Packit Service 1d0348
	assertEqualFile("hfscmp/file1", "nocmp/file1");
Packit Service 1d0348
	assertEqualFile("hfscmp/README", "nocmp/README");
Packit Service 1d0348
	assertEqualFile("hfscmp/NEWS", "nocmp/NEWS");
Packit Service 1d0348
	assertEqualFile("hfscmp/Makefile", "nocmp/Makefile");
Packit Service 1d0348
#endif
Packit Service 1d0348
}