1248590Smm/*- 2248590Smm * Copyright (c) 2003-2007 Tim Kientzle 3248590Smm * Copyright (c) 2012 Michihiro NAKAJIMA 4248590Smm * All rights reserved. 5248590Smm * 6248590Smm * Redistribution and use in source and binary forms, with or without 7248590Smm * modification, are permitted provided that the following conditions 8248590Smm * are met: 9248590Smm * 1. Redistributions of source code must retain the above copyright 10248590Smm * notice, this list of conditions and the following disclaimer. 11248590Smm * 2. Redistributions in binary form must reproduce the above copyright 12248590Smm * notice, this list of conditions and the following disclaimer in the 13248590Smm * documentation and/or other materials provided with the distribution. 14248590Smm * 15248590Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16248590Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17248590Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18248590Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19248590Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20248590Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21248590Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22248590Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23248590Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24248590Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25248590Smm */ 26248590Smm#include "test.h" 27248590Smm__FBSDID("$FreeBSD$"); 28248590Smm 29248590Smm#ifdef HAVE_SYS_ACL_H 30248590Smm#include <sys/acl.h> 31248590Smm#endif 32248590Smm#ifdef HAVE_SYS_XATTR_H 33248590Smm#include <sys/xattr.h> 34248590Smm#endif 35248590Smm 36248590Smm#if defined(__APPLE__) && defined(UF_COMPRESSED) && defined(HAVE_SYS_XATTR_H)\ 37248590Smm && defined(HAVE_ZLIB_H) 38299529Smm 39299529Smm// 40299529Smm// The test ACL used here is sometimes assigned to the 'Guest' user 41299529Smm// This changes the text and breaks the test. This function simply 42299529Smm// strips the 'Guest' information from the string to help ensure 43299529Smm// consistent results on different machines. 44299529Smm// 45299529Smmstatic char _acl_temp[256]; 46299529Smmstatic const char * 47299529Smmclean_acl(const char *acl) { 48299529Smm char *p, *q; 49299529Smm if (strlen(acl) >= sizeof(_acl_temp)) 50299529Smm return acl; 51299529Smm 52299529Smm strcpy(_acl_temp, acl); 53299529Smm p = strstr(_acl_temp, ":Guest:"); 54299529Smm if (p != NULL) { 55299529Smm fprintf(stderr, "Shortening: %s\n", p + 1); 56299529Smm memmove(p + 1, p + 6, strlen(p + 6) + 1); 57299529Smm q = strstr(p + 2, ":"); 58299529Smm fprintf(stderr, "Shortening: %s\n", q); 59299529Smm memmove(p + 2, q, strlen(q) + 1); 60299529Smm return _acl_temp; 61299529Smm } 62299529Smm return _acl_temp; 63299529Smm} 64299529Smm 65248590Smmstatic int 66248590Smmhas_xattr(const char *filename, const char *xattrname) 67248590Smm{ 68248590Smm char *nl, *nlp; 69248590Smm ssize_t r; 70370535Sgit2svn int existing; 71248590Smm 72248590Smm r = listxattr(filename, NULL, 0, XATTR_SHOWCOMPRESSION); 73248590Smm if (r < 0) 74248590Smm return (0); 75248590Smm if (r == 0) 76248590Smm return (0); 77248590Smm 78299529Smm assert((nl = malloc(r)) != NULL); 79299529Smm if (nl == NULL) 80248590Smm return (0); 81248590Smm 82248590Smm r = listxattr(filename, nl, r, XATTR_SHOWCOMPRESSION); 83248590Smm if (r < 0) { 84248590Smm free(nl); 85248590Smm return (0); 86248590Smm } 87248590Smm 88370535Sgit2svn existing = 0; 89248590Smm for (nlp = nl; nlp < nl + r; nlp += strlen(nlp) + 1) { 90248590Smm if (strcmp(nlp, xattrname) == 0) { 91370535Sgit2svn existing = 1; 92248590Smm break; 93248590Smm } 94248590Smm } 95248590Smm free(nl); 96370535Sgit2svn return (existing); 97248590Smm} 98248590Smm 99248590Smm#endif 100248590Smm 101248590Smm/* 102248590Smm * Exercise HFS+ Compression. 103248590Smm */ 104248590SmmDEFINE_TEST(test_write_disk_appledouble) 105248590Smm{ 106248590Smm#if !defined(__APPLE__) || !defined(UF_COMPRESSED) || !defined(HAVE_SYS_XATTR_H)\ 107248590Smm || !defined(HAVE_ZLIB_H) 108248590Smm skipping("MacOS-specific AppleDouble test"); 109248590Smm#else 110248590Smm const char *refname = "test_write_disk_appledouble.cpio.gz"; 111248590Smm struct archive *ad, *a; 112248590Smm struct archive_entry *ae; 113248590Smm struct stat st; 114248590Smm acl_t acl; 115248590Smm 116248590Smm extract_reference_file(refname); 117248590Smm 118248590Smm /* 119248590Smm * Extract an archive to disk with HFS+ Compression. 120248590Smm */ 121248590Smm assert((ad = archive_write_disk_new()) != NULL); 122248590Smm assertEqualIntA(ad, ARCHIVE_OK, 123248590Smm archive_write_disk_set_standard_lookup(ad)); 124248590Smm assertEqualIntA(ad, ARCHIVE_OK, 125248590Smm archive_write_disk_set_options(ad, 126248590Smm ARCHIVE_EXTRACT_TIME | 127248590Smm ARCHIVE_EXTRACT_SECURE_SYMLINKS | 128248590Smm ARCHIVE_EXTRACT_SECURE_NODOTDOT | 129248590Smm ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED)); 130248590Smm 131248590Smm assert((a = archive_read_new()) != NULL); 132248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 133248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 134248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, 135248590Smm refname, 512 * 20)); 136248590Smm 137248590Smm assertMakeDir("hfscmp", 0755); 138248590Smm assertChdir("hfscmp"); 139248590Smm 140248590Smm /* Skip "." */ 141248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 142248590Smm assertEqualString(".", archive_entry_pathname(ae)); 143248590Smm /* Extract file3. */ 144248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 145248590Smm assertEqualString("./file3", archive_entry_pathname(ae)); 146248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); 147311041Smm /* Extract ._file3 which will be merged into file3 as metadata. */ 148248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 149248590Smm assertEqualString("./._file3", archive_entry_pathname(ae)); 150248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); 151248590Smm 152248590Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 153248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 154248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 155248590Smm assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); 156248590Smm 157248590Smm /* Test file3. */ 158248590Smm assertEqualInt(0, stat("file3", &st)); 159248590Smm assertEqualInt(UF_COMPRESSED, st.st_flags & UF_COMPRESSED); 160248590Smm assertFileSize("file3", 8); 161248590Smm failure("'%s' should not have Resource Fork", "file3"); 162248590Smm assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); 163248590Smm failure("'%s' should have decompfs xattr", "file3"); 164248590Smm assertEqualInt(1, has_xattr("file3", "com.apple.decmpfs")); 165248590Smm assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); 166299529Smm assertEqualString(clean_acl(acl_to_text(acl, NULL)), 167248590Smm "!#acl 1\n" 168299529Smm "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" 169248590Smm "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" 170248590Smm ); 171248590Smm if (acl) acl_free(acl); 172248590Smm /* Test ._file3. */ 173248590Smm failure("'file3' should be merged and removed"); 174248590Smm assertFileNotExists("._file3"); 175248590Smm 176248590Smm assertChdir(".."); 177248590Smm 178248590Smm /* 179248590Smm * Extract an archive to disk without HFS+ Compression. 180248590Smm */ 181248590Smm assert((ad = archive_write_disk_new()) != NULL); 182248590Smm assertEqualIntA(ad, ARCHIVE_OK, 183248590Smm archive_write_disk_set_standard_lookup(ad)); 184248590Smm assertEqualIntA(ad, ARCHIVE_OK, 185248590Smm archive_write_disk_set_options(ad, 186248590Smm ARCHIVE_EXTRACT_TIME | 187248590Smm ARCHIVE_EXTRACT_SECURE_SYMLINKS | 188248590Smm ARCHIVE_EXTRACT_SECURE_NODOTDOT)); 189248590Smm 190248590Smm assert((a = archive_read_new()) != NULL); 191248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 192248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 193248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, 194248590Smm refname, 512 * 20)); 195248590Smm 196248590Smm assertMakeDir("nocmp", 0755); 197248590Smm assertChdir("nocmp"); 198248590Smm 199248590Smm /* Skip "." */ 200248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 201248590Smm assertEqualString(".", archive_entry_pathname(ae)); 202248590Smm /* Extract file3. */ 203248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 204248590Smm assertEqualString("./file3", archive_entry_pathname(ae)); 205248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); 206311041Smm /* Extract ._file3 which will be merged into file3 as metadata. */ 207248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 208248590Smm assertEqualString("./._file3", archive_entry_pathname(ae)); 209248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_extract2(a, ae, ad)); 210248590Smm 211248590Smm assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); 212248590Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 213248590Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 214248590Smm assertEqualIntA(ad, ARCHIVE_OK, archive_write_free(ad)); 215248590Smm 216248590Smm /* Test file3. */ 217248590Smm assertEqualInt(0, stat("file3", &st)); 218248590Smm assertEqualInt(0, st.st_flags & UF_COMPRESSED); 219248590Smm assertFileSize("file3", 8); 220248590Smm failure("'%s' should not have Resource Fork", "file3"); 221248590Smm assertEqualInt(0, has_xattr("file3", "com.apple.ResourceFork")); 222248590Smm failure("'%s' should not have decmpfs", "file3"); 223248590Smm assertEqualInt(0, has_xattr("file3", "com.apple.decmpfs")); 224248590Smm assert(NULL != (acl = acl_get_file("file3", ACL_TYPE_EXTENDED))); 225299529Smm assertEqualString(clean_acl(acl_to_text(acl, NULL)), 226248590Smm "!#acl 1\n" 227299529Smm "user:FFFFEEEE-DDDD-CCCC-BBBB-AAAA000000C9:::deny:read\n" 228248590Smm "group:ABCDEFAB-CDEF-ABCD-EFAB-CDEF00000050:admin:80:allow:write\n" 229248590Smm ); 230248590Smm if (acl) acl_free(acl); 231248590Smm /* Test ._file3. */ 232248590Smm failure("'file3' should be merged and removed"); 233248590Smm assertFileNotExists("._file3"); 234248590Smm 235248590Smm assertChdir(".."); 236248590Smm 237248590Smm assertEqualFile("hfscmp/file3", "nocmp/file3"); 238248590Smm#endif 239248590Smm} 240