1231200Smm/*- 2231200Smm * Copyright (c) 2003-2010 Tim Kientzle 3231200Smm * Copyright (c) 2012 Michihiro NAKAJIMA 4231200Smm * All rights reserved. 5231200Smm * 6231200Smm * Redistribution and use in source and binary forms, with or without 7231200Smm * modification, are permitted provided that the following conditions 8231200Smm * are met: 9231200Smm * 1. Redistributions of source code must retain the above copyright 10231200Smm * notice, this list of conditions and the following disclaimer. 11231200Smm * 2. Redistributions in binary form must reproduce the above copyright 12231200Smm * notice, this list of conditions and the following disclaimer in the 13231200Smm * documentation and/or other materials provided with the distribution. 14231200Smm * 15231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25231200Smm */ 26231200Smm#include "test.h" 27231200Smm__FBSDID("$FreeBSD$"); 28231200Smm 29231200Smmchar buff[1000000]; 30231200Smm 31231200Smmstatic void 32231200Smmtest_1(void) 33231200Smm{ 34231200Smm struct archive_entry *ae; 35231200Smm struct archive *a; 36231200Smm size_t used; 37231200Smm size_t blocksize; 38231200Smm int64_t offset, length; 39231200Smm char *buff2; 40231200Smm size_t buff2_size = 0x13000; 41231200Smm char buff3[1024]; 42231200Smm long i; 43231200Smm 44231200Smm assert((buff2 = malloc(buff2_size)) != NULL); 45231200Smm /* Repeat the following for a variety of odd blocksizes. */ 46231200Smm for (blocksize = 1; blocksize < 100000; blocksize += blocksize + 3) { 47231200Smm /* Create a new archive in memory. */ 48231200Smm assert((a = archive_write_new()) != NULL); 49231200Smm assertEqualIntA(a, ARCHIVE_OK, 50231200Smm archive_write_set_format_pax(a)); 51231200Smm assertEqualIntA(a, ARCHIVE_OK, 52248616Smm archive_write_add_filter_none(a)); 53231200Smm assertEqualIntA(a, ARCHIVE_OK, 54231200Smm archive_write_set_bytes_per_block(a, (int)blocksize)); 55231200Smm assertEqualIntA(a, ARCHIVE_OK, 56231200Smm archive_write_set_bytes_in_last_block(a, (int)blocksize)); 57231200Smm assertEqualInt(blocksize, 58231200Smm archive_write_get_bytes_in_last_block(a)); 59231200Smm assertEqualIntA(a, ARCHIVE_OK, 60231200Smm archive_write_open_memory(a, buff, sizeof(buff), &used)); 61231200Smm assertEqualInt(blocksize, 62231200Smm archive_write_get_bytes_in_last_block(a)); 63231200Smm 64231200Smm /* 65231200Smm * Write a file to it. 66231200Smm */ 67231200Smm assert((ae = archive_entry_new()) != NULL); 68231200Smm archive_entry_set_mtime(ae, 1, 10); 69231200Smm assertEqualInt(1, archive_entry_mtime(ae)); 70231200Smm assertEqualInt(10, archive_entry_mtime_nsec(ae)); 71231200Smm archive_entry_copy_pathname(ae, "file"); 72231200Smm assertEqualString("file", archive_entry_pathname(ae)); 73231200Smm archive_entry_set_mode(ae, S_IFREG | 0755); 74231200Smm assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); 75231200Smm archive_entry_set_size(ae, 0x81000); 76231200Smm archive_entry_sparse_add_entry(ae, 0x10000, 0x1000); 77231200Smm archive_entry_sparse_add_entry(ae, 0x80000, 0x1000); 78231200Smm 79231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 80231200Smm archive_entry_free(ae); 81231200Smm memset(buff2, 'a', buff2_size); 82231200Smm for (i = 0; i < 0x81000;) { 83231200Smm size_t ws = buff2_size; 84231200Smm if (i + ws > 0x81000) 85231200Smm ws = 0x81000 - i; 86231200Smm assertEqualInt(ws, 87231200Smm archive_write_data(a, buff2, ws)); 88248616Smm i += (long)ws; 89231200Smm } 90231200Smm 91231200Smm /* Close out the archive. */ 92231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 93231200Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 94231200Smm 95231200Smm /* This calculation gives "the smallest multiple of 96231200Smm * the block size that is at least 11264 bytes". */ 97231200Smm failure("blocksize=%d", blocksize); 98231200Smm assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); 99231200Smm 100231200Smm /* 101231200Smm * Now, read the data back. 102231200Smm */ 103231200Smm assert((a = archive_read_new()) != NULL); 104231200Smm assertEqualIntA(a, ARCHIVE_OK, 105231200Smm archive_read_support_format_all(a)); 106231200Smm assertEqualIntA(a, ARCHIVE_OK, 107231200Smm archive_read_support_filter_all(a)); 108231200Smm assertEqualIntA(a, ARCHIVE_OK, 109231200Smm archive_read_open_memory(a, buff, used)); 110231200Smm 111231200Smm assertEqualIntA(a, ARCHIVE_OK, 112231200Smm archive_read_next_header(a, &ae)); 113231200Smm 114231200Smm assertEqualInt(1, archive_entry_mtime(ae)); 115231200Smm assertEqualInt(10, archive_entry_mtime_nsec(ae)); 116231200Smm assertEqualInt(0, archive_entry_atime(ae)); 117231200Smm assertEqualInt(0, archive_entry_ctime(ae)); 118231200Smm assertEqualString("file", archive_entry_pathname(ae)); 119231200Smm assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 120231200Smm assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 121231200Smm assertEqualInt(0x81000, archive_entry_size(ae)); 122231200Smm /* Verify sparse information. */ 123231200Smm assertEqualInt(2, archive_entry_sparse_reset(ae)); 124231200Smm assertEqualInt(0, 125231200Smm archive_entry_sparse_next(ae, &offset, &length)); 126231200Smm assertEqualInt(0x10000, offset); 127231200Smm assertEqualInt(0x1000, length); 128231200Smm assertEqualInt(0, 129231200Smm archive_entry_sparse_next(ae, &offset, &length)); 130231200Smm assertEqualInt(0x80000, offset); 131231200Smm assertEqualInt(0x1000, length); 132231200Smm /* Verify file contents. */ 133231200Smm memset(buff3, 0, sizeof(buff3)); 134231200Smm for (i = 0; i < 0x10000; i += 1024) { 135231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 136231200Smm failure("Read data(0x%lx - 0x%lx) should be all zero", 137231200Smm i, i + 1024); 138231200Smm assertEqualMem(buff2, buff3, 1024); 139231200Smm } 140231200Smm memset(buff3, 'a', sizeof(buff3)); 141231200Smm for (i = 0x10000; i < 0x11000; i += 1024) { 142231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 143231200Smm failure("Read data(0x%lx - 0x%lx) should be all 'a'", 144231200Smm i, i + 1024); 145231200Smm assertEqualMem(buff2, buff3, 1024); 146231200Smm } 147231200Smm memset(buff3, 0, sizeof(buff3)); 148231200Smm for (i = 0x11000; i < 0x80000; i += 1024) { 149231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 150231200Smm failure("Read data(0x%lx - 0x%lx) should be all zero", 151231200Smm i, i + 1024); 152231200Smm assertEqualMem(buff2, buff3, 1024); 153231200Smm } 154231200Smm memset(buff3, 'a', sizeof(buff3)); 155231200Smm for (i = 0x80000; i < 0x81000; i += 1024) { 156231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 157231200Smm failure("Read data(0x%lx - 0x%lx) should be all 'a'", 158231200Smm i, i + 1024); 159231200Smm assertEqualMem(buff2, buff3, 1024); 160231200Smm } 161231200Smm 162231200Smm /* Verify the end of the archive. */ 163231200Smm assertEqualIntA(a, ARCHIVE_EOF, 164231200Smm archive_read_next_header(a, &ae)); 165231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 166231200Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 167231200Smm } 168231200Smm free(buff2); 169231200Smm} 170231200Smm 171231200Smm/* 172231200Smm * Test for the case the full bytes of sparse file data is not written. 173231200Smm */ 174231200Smmstatic void 175231200Smmtest_2(void) 176231200Smm{ 177231200Smm struct archive_entry *ae; 178231200Smm struct archive *a; 179231200Smm size_t used; 180231200Smm size_t blocksize = 20 * 512; 181231200Smm int64_t offset, length; 182231200Smm char *buff2; 183231200Smm size_t buff2_size = 0x11000; 184231200Smm char buff3[1024]; 185231200Smm long i; 186231200Smm 187231200Smm assert((buff2 = malloc(buff2_size)) != NULL); 188231200Smm /* Create a new archive in memory. */ 189231200Smm assert((a = archive_write_new()) != NULL); 190231200Smm assertEqualIntA(a, ARCHIVE_OK, 191231200Smm archive_write_set_format_pax(a)); 192231200Smm assertEqualIntA(a, ARCHIVE_OK, 193248616Smm archive_write_add_filter_none(a)); 194231200Smm assertEqualIntA(a, ARCHIVE_OK, 195231200Smm archive_write_set_bytes_per_block(a, (int)blocksize)); 196231200Smm assertEqualIntA(a, ARCHIVE_OK, 197231200Smm archive_write_set_bytes_in_last_block(a, (int)blocksize)); 198231200Smm assertEqualInt(blocksize, 199231200Smm archive_write_get_bytes_in_last_block(a)); 200231200Smm assertEqualIntA(a, ARCHIVE_OK, 201231200Smm archive_write_open_memory(a, buff, sizeof(buff), &used)); 202231200Smm assertEqualInt(blocksize, 203231200Smm archive_write_get_bytes_in_last_block(a)); 204231200Smm 205231200Smm /* 206231200Smm * Write a file to it. 207231200Smm */ 208231200Smm assert((ae = archive_entry_new()) != NULL); 209231200Smm archive_entry_set_mtime(ae, 1, 10); 210231200Smm assertEqualInt(1, archive_entry_mtime(ae)); 211231200Smm assertEqualInt(10, archive_entry_mtime_nsec(ae)); 212231200Smm archive_entry_copy_pathname(ae, "file"); 213231200Smm assertEqualString("file", archive_entry_pathname(ae)); 214231200Smm archive_entry_set_mode(ae, S_IFREG | 0755); 215231200Smm assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae)); 216231200Smm archive_entry_set_size(ae, 0x81000); 217231200Smm archive_entry_sparse_add_entry(ae, 0x10000, 0x1000); 218231200Smm archive_entry_sparse_add_entry(ae, 0x80000, 0x1000); 219231200Smm 220231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); 221231200Smm archive_entry_free(ae); 222231200Smm memset(buff2, 'a', buff2_size); 223231200Smm /* Write bytes less than it should be. */ 224231200Smm assertEqualInt(buff2_size, archive_write_data(a, buff2, buff2_size)); 225231200Smm 226231200Smm /* Close out the archive. */ 227231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); 228231200Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 229231200Smm 230231200Smm /* This calculation gives "the smallest multiple of 231231200Smm * the block size that is at least 11264 bytes". */ 232231200Smm failure("blocksize=%d", blocksize); 233231200Smm assertEqualInt(((11264 - 1)/blocksize+1)*blocksize, used); 234231200Smm 235231200Smm /* 236231200Smm * Now, read the data back. 237231200Smm */ 238231200Smm assert((a = archive_read_new()) != NULL); 239231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); 240231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); 241231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); 242231200Smm 243231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); 244231200Smm 245231200Smm assertEqualInt(1, archive_entry_mtime(ae)); 246231200Smm assertEqualInt(10, archive_entry_mtime_nsec(ae)); 247231200Smm assertEqualInt(0, archive_entry_atime(ae)); 248231200Smm assertEqualInt(0, archive_entry_ctime(ae)); 249231200Smm assertEqualString("file", archive_entry_pathname(ae)); 250231200Smm assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); 251231200Smm assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae)); 252231200Smm assertEqualInt(0x81000, archive_entry_size(ae)); 253231200Smm /* Verify sparse information. */ 254231200Smm assertEqualInt(2, archive_entry_sparse_reset(ae)); 255231200Smm assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length)); 256231200Smm assertEqualInt(0x10000, offset); 257231200Smm assertEqualInt(0x1000, length); 258231200Smm assertEqualInt(0, archive_entry_sparse_next(ae, &offset, &length)); 259231200Smm assertEqualInt(0x80000, offset); 260231200Smm assertEqualInt(0x1000, length); 261231200Smm /* Verify file contents. */ 262231200Smm memset(buff3, 0, sizeof(buff3)); 263231200Smm for (i = 0; i < 0x10000; i += 1024) { 264231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 265231200Smm failure("Read data(0x%lx - 0x%lx) should be all zero", 266231200Smm i, i + 1024); 267231200Smm assertEqualMem(buff2, buff3, 1024); 268231200Smm } 269231200Smm memset(buff3, 'a', sizeof(buff3)); 270231200Smm for (i = 0x10000; i < 0x11000; i += 1024) { 271231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 272231200Smm failure("Read data(0x%lx - 0x%lx) should be all 'a'", 273231200Smm i, i + 1024); 274231200Smm assertEqualMem(buff2, buff3, 1024); 275231200Smm } 276231200Smm memset(buff3, 0, sizeof(buff3)); 277231200Smm for (i = 0x11000; i < 0x80000; i += 1024) { 278231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 279231200Smm failure("Read data(0x%lx - 0x%lx) should be all zero", 280231200Smm i, i + 1024); 281231200Smm assertEqualMem(buff2, buff3, 1024); 282231200Smm } 283231200Smm memset(buff3, 0, sizeof(buff3)); 284231200Smm for (i = 0x80000; i < 0x81000; i += 1024) { 285231200Smm assertEqualInt(1024, archive_read_data(a, buff2, 1024)); 286231200Smm failure("Read data(0x%lx - 0x%lx) should be all 'a'", 287231200Smm i, i + 1024); 288231200Smm assertEqualMem(buff2, buff3, 1024); 289231200Smm } 290231200Smm 291231200Smm /* Verify the end of the archive. */ 292231200Smm assertEqualIntA(a, ARCHIVE_EOF, 293231200Smm archive_read_next_header(a, &ae)); 294231200Smm assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); 295231200Smm assertEqualInt(ARCHIVE_OK, archive_read_free(a)); 296231200Smm free(buff2); 297231200Smm} 298231200Smm 299231200SmmDEFINE_TEST(test_write_format_tar_sparse) 300231200Smm{ 301231200Smm /* Test1: archiving sparse files. */ 302231200Smm test_1(); 303231200Smm /* Test2: incompletely archiving sparse files. */ 304231200Smm test_2(); 305231200Smm} 306