1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm#include "test.h" 26228763Smm__FBSDID("$FreeBSD$"); 27228753Smm 28228753Smmstatic int 29228753Smmis_null(const char *p, size_t l) 30228753Smm{ 31228753Smm while (l > 0) { 32228753Smm if (*p != '\0') 33228753Smm return (0); 34228753Smm --l; 35228753Smm ++p; 36228753Smm } 37228753Smm return (1); 38228753Smm} 39228753Smm 40228753Smm/* Verify the contents, then erase them to NUL bytes. */ 41228753Smm/* Tar requires all "unused" bytes be set to NUL; this allows us 42228753Smm * to easily verify that by invoking is_null() over the entire header 43228753Smm * after verifying each field. */ 44228753Smm#define myAssertEqualMem(a,b,s) assertEqualMem(a, b, s); memset(a, 0, s) 45228753Smm 46228753Smm/* 47228753Smm * Detailed verification that 'ustar' archives are written with 48228753Smm * the correct format. 49228753Smm */ 50228753SmmDEFINE_TEST(test_write_format_tar_ustar) 51228753Smm{ 52228753Smm struct archive *a; 53228753Smm struct archive_entry *entry; 54228753Smm char *buff, *e; 55228753Smm size_t buffsize = 100000; 56228753Smm size_t used; 57228753Smm int i; 58228753Smm char f99[100]; 59228753Smm char f100[101]; 60228753Smm char f256[257]; 61228753Smm 62228753Smm for (i = 0; i < 99; ++i) 63228753Smm f99[i] = 'a' + i % 26; 64228753Smm f99[99] = '\0'; 65228753Smm 66228753Smm for (i = 0; i < 100; ++i) 67228753Smm f100[i] = 'A' + i % 26; 68228753Smm f100[100] = '\0'; 69228753Smm 70228753Smm for (i = 0; i < 256; ++i) 71228753Smm f256[i] = 'A' + i % 26; 72228753Smm f256[155] = '/'; 73228753Smm f256[256] = '\0'; 74228753Smm 75228753Smm buff = malloc(buffsize); 76228753Smm 77228753Smm /* Create a new archive in memory. */ 78228753Smm assert((a = archive_write_new()) != NULL); 79232153Smm assertEqualIntA(a, ARCHIVE_OK, 80232153Smm archive_write_set_format_ustar(a)); 81232153Smm assertEqualIntA(a, ARCHIVE_OK, 82248616Smm archive_write_add_filter_none(a)); 83232153Smm assertEqualIntA(a, ARCHIVE_OK, 84232153Smm archive_write_open_memory(a, buff, buffsize, &used)); 85228753Smm 86228753Smm /* 87228753Smm * Add various files to it. 88228753Smm * TODO: Extend this to cover more filetypes. 89228753Smm */ 90228753Smm 91228753Smm /* "file" with 10 bytes of content */ 92228753Smm assert((entry = archive_entry_new()) != NULL); 93228753Smm archive_entry_set_mtime(entry, 1, 10); 94228753Smm archive_entry_set_pathname(entry, "file"); 95228753Smm archive_entry_set_mode(entry, S_IFREG | 0664); 96228753Smm archive_entry_set_size(entry, 10); 97228753Smm archive_entry_set_uid(entry, 80); 98228753Smm archive_entry_set_gid(entry, 90); 99228753Smm archive_entry_set_dev(entry, 12); 100228753Smm archive_entry_set_ino(entry, 89); 101228753Smm archive_entry_set_nlink(entry, 2); 102232153Smm assertEqualIntA(a, ARCHIVE_OK, 103232153Smm archive_write_header(a, entry)); 104228753Smm archive_entry_free(entry); 105228753Smm assertEqualIntA(a, 10, archive_write_data(a, "1234567890", 10)); 106228753Smm 107228753Smm /* Hardlink to "file" with 10 bytes of content */ 108228753Smm assert((entry = archive_entry_new()) != NULL); 109228753Smm archive_entry_set_mtime(entry, 1, 10); 110228753Smm archive_entry_set_pathname(entry, "linkfile"); 111228753Smm archive_entry_set_mode(entry, S_IFREG | 0664); 112228753Smm /* TODO: Put this back and fix the bug. */ 113228753Smm /* archive_entry_set_size(entry, 10); */ 114228753Smm archive_entry_set_uid(entry, 80); 115228753Smm archive_entry_set_gid(entry, 90); 116228753Smm archive_entry_set_dev(entry, 12); 117228753Smm archive_entry_set_ino(entry, 89); 118228753Smm archive_entry_set_nlink(entry, 2); 119232153Smm assertEqualIntA(a, ARCHIVE_OK, 120232153Smm archive_write_header(a, entry)); 121228753Smm archive_entry_free(entry); 122228753Smm /* Write of data to dir should fail == zero bytes get written. */ 123228753Smm assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); 124228753Smm 125228753Smm /* "dir" */ 126228753Smm assert((entry = archive_entry_new()) != NULL); 127228753Smm archive_entry_set_mtime(entry, 2, 20); 128228753Smm archive_entry_set_pathname(entry, "dir"); 129228753Smm archive_entry_set_mode(entry, S_IFDIR | 0775); 130228753Smm archive_entry_set_size(entry, 10); 131228753Smm archive_entry_set_nlink(entry, 2); 132232153Smm assertEqualIntA(a, ARCHIVE_OK, 133232153Smm archive_write_header(a, entry)); 134228753Smm archive_entry_free(entry); 135228753Smm /* Write of data to dir should fail == zero bytes get written. */ 136228753Smm assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); 137228753Smm 138228753Smm /* "symlink" pointing to "file" */ 139228753Smm assert((entry = archive_entry_new()) != NULL); 140228753Smm archive_entry_set_mtime(entry, 3, 30); 141228753Smm archive_entry_set_pathname(entry, "symlink"); 142228753Smm archive_entry_set_mode(entry, 0664); 143228753Smm archive_entry_set_filetype(entry, AE_IFLNK); 144228753Smm archive_entry_set_symlink(entry,"file"); 145228753Smm archive_entry_set_size(entry, 0); 146228753Smm archive_entry_set_uid(entry, 88); 147228753Smm archive_entry_set_gid(entry, 98); 148228753Smm archive_entry_set_dev(entry, 12); 149228753Smm archive_entry_set_ino(entry, 90); 150228753Smm archive_entry_set_nlink(entry, 1); 151232153Smm assertEqualIntA(a, ARCHIVE_OK, 152232153Smm archive_write_header(a, entry)); 153228753Smm archive_entry_free(entry); 154228753Smm /* Write of data to symlink should fail == zero bytes get written. */ 155228753Smm assertEqualIntA(a, 0, archive_write_data(a, "1234567890", 10)); 156228753Smm 157228753Smm /* file with 99-char filename. */ 158228753Smm assert((entry = archive_entry_new()) != NULL); 159228753Smm archive_entry_set_mtime(entry, 1, 10); 160228753Smm archive_entry_set_pathname(entry, f99); 161228753Smm archive_entry_set_mode(entry, S_IFREG | 0664); 162228753Smm archive_entry_set_size(entry, 0); 163228753Smm archive_entry_set_uid(entry, 82); 164228753Smm archive_entry_set_gid(entry, 93); 165228753Smm archive_entry_set_dev(entry, 102); 166228753Smm archive_entry_set_ino(entry, 7); 167228753Smm archive_entry_set_nlink(entry, 1); 168232153Smm assertEqualIntA(a, ARCHIVE_OK, 169232153Smm archive_write_header(a, entry)); 170228753Smm archive_entry_free(entry); 171228753Smm 172228753Smm /* file with 100-char filename. */ 173228753Smm assert((entry = archive_entry_new()) != NULL); 174228753Smm archive_entry_set_mtime(entry, 1, 10); 175228753Smm archive_entry_set_pathname(entry, f100); 176228753Smm archive_entry_set_mode(entry, S_IFREG | 0664); 177228753Smm archive_entry_set_size(entry, 0); 178228753Smm archive_entry_set_uid(entry, 82); 179228753Smm archive_entry_set_gid(entry, 93); 180228753Smm archive_entry_set_dev(entry, 102); 181228753Smm archive_entry_set_ino(entry, 7); 182228753Smm archive_entry_set_nlink(entry, 1); 183232153Smm assertEqualIntA(a, ARCHIVE_OK, 184232153Smm archive_write_header(a, entry)); 185228753Smm archive_entry_free(entry); 186228753Smm 187228753Smm /* file with 256-char filename. */ 188228753Smm assert((entry = archive_entry_new()) != NULL); 189228753Smm archive_entry_set_mtime(entry, 1, 10); 190228753Smm archive_entry_set_pathname(entry, f256); 191228753Smm archive_entry_set_mode(entry, S_IFREG | 0664); 192228753Smm archive_entry_set_size(entry, 0); 193228753Smm archive_entry_set_uid(entry, 82); 194228753Smm archive_entry_set_gid(entry, 93); 195228753Smm archive_entry_set_dev(entry, 102); 196228753Smm archive_entry_set_ino(entry, 7); 197228753Smm archive_entry_set_nlink(entry, 1); 198232153Smm assertEqualIntA(a, ARCHIVE_OK, 199232153Smm archive_write_header(a, entry)); 200228753Smm archive_entry_free(entry); 201228753Smm 202232153Smm /* Close out the archive. */ 203232153Smm assertEqualInt(ARCHIVE_OK, archive_write_free(a)); 204228753Smm 205228753Smm /* 206228753Smm * Verify the archive format. 207228753Smm */ 208228753Smm e = buff; 209228753Smm 210228753Smm /* "file" */ 211228753Smm myAssertEqualMem(e + 0, "file", 5); /* Filename */ 212228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 213228753Smm myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ 214228753Smm myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ 215228753Smm myAssertEqualMem(e + 124, "00000000012 ", 12); /* size */ 216228753Smm myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ 217228753Smm myAssertEqualMem(e + 148, "010034\0 ", 8); /* checksum */ 218228753Smm myAssertEqualMem(e + 156, "0", 1); /* linkflag */ 219228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 220228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 221228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 222228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 223228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 224228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 225228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 226228753Smm assert(is_null(e + 0, 512)); 227228753Smm myAssertEqualMem(e + 512, "1234567890", 10); 228228753Smm assert(is_null(e + 512, 512)); 229228753Smm e += 1024; 230228753Smm 231228753Smm /* hardlink to "file" */ 232228753Smm myAssertEqualMem(e + 0, "linkfile", 9); /* Filename */ 233228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 234228753Smm myAssertEqualMem(e + 108, "000120 ", 8); /* uid */ 235228753Smm myAssertEqualMem(e + 116, "000132 ", 8); /* gid */ 236228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 237228753Smm myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ 238228753Smm myAssertEqualMem(e + 148, "010707\0 ", 8); /* checksum */ 239228753Smm myAssertEqualMem(e + 156, "0", 1); /* linkflag */ 240228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 241228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 242228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 243228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 244228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 245228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 246228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 247228753Smm assert(is_null(e + 0, 512)); 248228753Smm e += 512; 249228753Smm 250228753Smm /* "dir" */ 251228753Smm myAssertEqualMem(e + 0, "dir/", 4); /* Filename */ 252228753Smm myAssertEqualMem(e + 100, "000775 ", 8); /* mode */ 253228753Smm myAssertEqualMem(e + 108, "000000 ", 8); /* uid */ 254228753Smm myAssertEqualMem(e + 116, "000000 ", 8); /* gid */ 255228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 256228753Smm myAssertEqualMem(e + 136, "00000000002 ", 12); /* mtime */ 257228753Smm myAssertEqualMem(e + 148, "007747\0 ", 8); /* checksum */ 258228753Smm myAssertEqualMem(e + 156, "5", 1); /* typeflag */ 259228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 260228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 261228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 262228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 263228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 264228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 265228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 266228753Smm assert(is_null(e + 0, 512)); 267228753Smm e += 512; 268228753Smm 269228753Smm /* "symlink" pointing to "file" */ 270228753Smm myAssertEqualMem(e + 0, "symlink", 8); /* Filename */ 271228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 272228753Smm myAssertEqualMem(e + 108, "000130 ", 8); /* uid */ 273228753Smm myAssertEqualMem(e + 116, "000142 ", 8); /* gid */ 274228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 275228753Smm myAssertEqualMem(e + 136, "00000000003 ", 12); /* mtime */ 276228753Smm myAssertEqualMem(e + 148, "011446\0 ", 8); /* checksum */ 277228753Smm myAssertEqualMem(e + 156, "2", 1); /* linkflag */ 278228753Smm myAssertEqualMem(e + 157, "file", 5); /* linkname */ 279228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 280228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 281228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 282228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 283228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 284228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 285228753Smm assert(is_null(e + 0, 512)); 286228753Smm e += 512; 287228753Smm 288228753Smm /* File with 99-char filename */ 289228753Smm myAssertEqualMem(e + 0, f99, 100); /* Filename */ 290228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 291228753Smm myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ 292228753Smm myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ 293228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 294228753Smm myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ 295228753Smm myAssertEqualMem(e + 148, "034242\0 ", 8); /* checksum */ 296228753Smm myAssertEqualMem(e + 156, "0", 1); /* linkflag */ 297228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 298228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 299228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 300228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 301228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 302228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 303228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 304228753Smm assert(is_null(e + 0, 512)); 305228753Smm e += 512; 306228753Smm 307228753Smm /* File with 100-char filename */ 308228753Smm myAssertEqualMem(e + 0, f100, 100); /* Filename */ 309228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 310228753Smm myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ 311228753Smm myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ 312228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 313228753Smm myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ 314228753Smm myAssertEqualMem(e + 148, "026230\0 ", 8); /* checksum */ 315228753Smm myAssertEqualMem(e + 156, "0", 1); /* linkflag */ 316228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 317228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 318228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 319228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 320228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 321228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 322228753Smm myAssertEqualMem(e + 345, "", 1); /* prefix */ 323228753Smm assert(is_null(e + 0, 512)); 324228753Smm e += 512; 325228753Smm 326228753Smm /* File with 256-char filename */ 327228753Smm myAssertEqualMem(e + 0, f256 + 156, 100); /* Filename */ 328228753Smm myAssertEqualMem(e + 100, "000664 ", 8); /* mode */ 329228753Smm myAssertEqualMem(e + 108, "000122 ", 8); /* uid */ 330228753Smm myAssertEqualMem(e + 116, "000135 ", 8); /* gid */ 331228753Smm myAssertEqualMem(e + 124, "00000000000 ", 12); /* size */ 332228753Smm myAssertEqualMem(e + 136, "00000000001 ", 12); /* mtime */ 333228753Smm myAssertEqualMem(e + 148, "055570\0 ", 8); /* checksum */ 334228753Smm myAssertEqualMem(e + 156, "0", 1); /* linkflag */ 335228753Smm myAssertEqualMem(e + 157, "", 1); /* linkname */ 336228753Smm myAssertEqualMem(e + 257, "ustar\000000", 8); /* signature/version */ 337228753Smm myAssertEqualMem(e + 265, "", 1); /* uname */ 338228753Smm myAssertEqualMem(e + 297, "", 1); /* gname */ 339228753Smm myAssertEqualMem(e + 329, "000000 ", 8); /* devmajor */ 340228753Smm myAssertEqualMem(e + 337, "000000 ", 8); /* devminor */ 341228753Smm myAssertEqualMem(e + 345, f256, 155); /* prefix */ 342228753Smm assert(is_null(e + 0, 512)); 343228753Smm e += 512; 344228753Smm 345228753Smm /* TODO: Verify other types of entries. */ 346228753Smm 347228753Smm /* Last entry is end-of-archive marker. */ 348228753Smm assert(is_null(e, 1024)); 349228753Smm e += 1024; 350228753Smm 351228753Smm assertEqualInt((int)used, e - buff); 352228753Smm 353228753Smm free(buff); 354228753Smm} 355