1caf54c4fSMartin Matuska /*- 2caf54c4fSMartin Matuska * Copyright (c) 2003-2007 Tim Kientzle 3caf54c4fSMartin Matuska * All rights reserved. 4caf54c4fSMartin Matuska * 5caf54c4fSMartin Matuska * Redistribution and use in source and binary forms, with or without 6caf54c4fSMartin Matuska * modification, are permitted provided that the following conditions 7caf54c4fSMartin Matuska * are met: 8caf54c4fSMartin Matuska * 1. Redistributions of source code must retain the above copyright 9caf54c4fSMartin Matuska * notice, this list of conditions and the following disclaimer. 10caf54c4fSMartin Matuska * 2. Redistributions in binary form must reproduce the above copyright 11caf54c4fSMartin Matuska * notice, this list of conditions and the following disclaimer in the 12caf54c4fSMartin Matuska * documentation and/or other materials provided with the distribution. 13caf54c4fSMartin Matuska * 14caf54c4fSMartin Matuska * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15caf54c4fSMartin Matuska * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16caf54c4fSMartin Matuska * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17caf54c4fSMartin Matuska * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18caf54c4fSMartin Matuska * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19caf54c4fSMartin Matuska * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20caf54c4fSMartin Matuska * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21caf54c4fSMartin Matuska * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22caf54c4fSMartin Matuska * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23caf54c4fSMartin Matuska * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24caf54c4fSMartin Matuska */ 25caf54c4fSMartin Matuska #include "test.h" 26caf54c4fSMartin Matuska __FBSDID("$FreeBSD$"); 27caf54c4fSMartin Matuska 28caf54c4fSMartin Matuska /* 29caf54c4fSMartin Matuska * Also see test_option_q for additional validation of -r support. 30caf54c4fSMartin Matuska */ 31caf54c4fSMartin Matuska DEFINE_TEST(test_option_r) 32caf54c4fSMartin Matuska { 33*6c95142eSMartin Matuska char *buff; 34caf54c4fSMartin Matuska char *p0, *p1; 35*6c95142eSMartin Matuska size_t buff_size = 35000; 36*6c95142eSMartin Matuska size_t s, buff_size_rounded; 37*6c95142eSMartin Matuska int r, i; 38caf54c4fSMartin Matuska 39*6c95142eSMartin Matuska /* Create an archive with one file. */ 40*6c95142eSMartin Matuska assertMakeFile("f1", 0644, "abc"); 41caf54c4fSMartin Matuska r = systemf("%s cf archive.tar --format=ustar f1 >step1.out 2>step1.err", testprog); 42caf54c4fSMartin Matuska failure("Error invoking %s cf archive.tar f1", testprog); 43caf54c4fSMartin Matuska assertEqualInt(r, 0); 44caf54c4fSMartin Matuska assertEmptyFile("step1.out"); 45caf54c4fSMartin Matuska assertEmptyFile("step1.err"); 46caf54c4fSMartin Matuska 47caf54c4fSMartin Matuska /* Do some basic validation of the constructed archive. */ 48caf54c4fSMartin Matuska p0 = slurpfile(&s, "archive.tar"); 49caf54c4fSMartin Matuska if (!assert(p0 != NULL)) 50caf54c4fSMartin Matuska return; 51caf54c4fSMartin Matuska if (!assert(s >= 2048)) { 52caf54c4fSMartin Matuska free(p0); 53caf54c4fSMartin Matuska return; 54caf54c4fSMartin Matuska } 55caf54c4fSMartin Matuska assertEqualMem(p0 + 0, "f1", 3); 56caf54c4fSMartin Matuska assertEqualMem(p0 + 512, "abc", 3); 57caf54c4fSMartin Matuska assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8); 58caf54c4fSMartin Matuska assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8); 59caf54c4fSMartin Matuska 60*6c95142eSMartin Matuska /* Edit that file with a lot more data and update the archive with a new copy. */ 61*6c95142eSMartin Matuska buff = malloc(buff_size); 62*6c95142eSMartin Matuska assert(buff != NULL); 63*6c95142eSMartin Matuska for (i = 0; i < (int)buff_size; ++i) 64*6c95142eSMartin Matuska buff[i] = "abcdefghijklmnopqrstuvwxyz"[rand() % 26]; 65*6c95142eSMartin Matuska buff[buff_size - 1] = '\0'; 66*6c95142eSMartin Matuska assertMakeFile("f1", 0644, buff); 67caf54c4fSMartin Matuska r = systemf("%s rf archive.tar --format=ustar f1 >step2.out 2>step2.err", testprog); 68caf54c4fSMartin Matuska failure("Error invoking %s rf archive.tar f1", testprog); 69caf54c4fSMartin Matuska assertEqualInt(r, 0); 70caf54c4fSMartin Matuska assertEmptyFile("step2.out"); 71caf54c4fSMartin Matuska assertEmptyFile("step2.err"); 72caf54c4fSMartin Matuska 73*6c95142eSMartin Matuska /* The constructed archive should just have the new entry appended. */ 74caf54c4fSMartin Matuska p1 = slurpfile(&s, "archive.tar"); 75caf54c4fSMartin Matuska if (!assert(p1 != NULL)) { 76caf54c4fSMartin Matuska free(p0); 77caf54c4fSMartin Matuska return; 78caf54c4fSMartin Matuska } 79*6c95142eSMartin Matuska buff_size_rounded = ((buff_size + 511) / 512) * 512; 80*6c95142eSMartin Matuska assert(s >= 2560 + buff_size_rounded); 81caf54c4fSMartin Matuska /* Verify first entry is unchanged. */ 82caf54c4fSMartin Matuska assertEqualMem(p0, p1, 1024); 83caf54c4fSMartin Matuska /* Verify that second entry is correct. */ 84caf54c4fSMartin Matuska assertEqualMem(p1 + 1024, "f1", 3); 85*6c95142eSMartin Matuska assertEqualMem(p1 + 1536, buff, buff_size); 86caf54c4fSMartin Matuska /* Verify end-of-archive marker. */ 87*6c95142eSMartin Matuska assertEqualMem(p1 + 1536 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 88*6c95142eSMartin Matuska assertEqualMem(p1 + 2048 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 89*6c95142eSMartin Matuska 90*6c95142eSMartin Matuska free(p0); 91*6c95142eSMartin Matuska p0 = p1; 92*6c95142eSMartin Matuska 93*6c95142eSMartin Matuska /* Update the archive by adding a different file. */ 94*6c95142eSMartin Matuska assertMakeFile("f2", 0644, "f2"); 95*6c95142eSMartin Matuska r = systemf("%s rf archive.tar --format=ustar f2 >step3.out 2>step3.err", testprog); 96*6c95142eSMartin Matuska failure("Error invoking %s rf archive.tar f2", testprog); 97*6c95142eSMartin Matuska assertEqualInt(r, 0); 98*6c95142eSMartin Matuska assertEmptyFile("step3.out"); 99*6c95142eSMartin Matuska assertEmptyFile("step3.err"); 100*6c95142eSMartin Matuska 101*6c95142eSMartin Matuska /* Validate the constructed archive. */ 102*6c95142eSMartin Matuska p1 = slurpfile(&s, "archive.tar"); 103*6c95142eSMartin Matuska if (!assert(p1 != NULL)) { 104*6c95142eSMartin Matuska free(p0); 105*6c95142eSMartin Matuska return; 106*6c95142eSMartin Matuska } 107*6c95142eSMartin Matuska assert(s >= 3584 + buff_size_rounded); 108*6c95142eSMartin Matuska /* Verify first two entries are unchanged. */ 109*6c95142eSMartin Matuska assertEqualMem(p0, p1, 1536 + buff_size_rounded); 110*6c95142eSMartin Matuska /* Verify that new entry is correct. */ 111*6c95142eSMartin Matuska assertEqualMem(p1 + 1536 + buff_size_rounded, "f2", 3); 112*6c95142eSMartin Matuska assertEqualMem(p1 + 2048 + buff_size_rounded, "f2", 3); 113*6c95142eSMartin Matuska /* Verify end-of-archive marker. */ 114*6c95142eSMartin Matuska assertEqualMem(p1 + 2560 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 115*6c95142eSMartin Matuska assertEqualMem(p1 + 3072 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 116caf54c4fSMartin Matuska free(p0); 117caf54c4fSMartin Matuska free(p1); 118caf54c4fSMartin Matuska 119*6c95142eSMartin Matuska /* Unpack everything */ 120*6c95142eSMartin Matuska assertMakeDir("extract", 0775); 121*6c95142eSMartin Matuska assertChdir("extract"); 122*6c95142eSMartin Matuska r = systemf("%s xf ../archive.tar >extract.out 2>extract.err", testprog); 123caf54c4fSMartin Matuska failure("Error invoking %s xf archive.tar", testprog); 124caf54c4fSMartin Matuska assertEqualInt(r, 0); 125*6c95142eSMartin Matuska assertEmptyFile("extract.out"); 126*6c95142eSMartin Matuska assertEmptyFile("extract.err"); 127caf54c4fSMartin Matuska 128*6c95142eSMartin Matuska /* Verify that the second copy of f1 overwrote the first. */ 129*6c95142eSMartin Matuska assertFileContents(buff, strlen(buff), "f1"); 130caf54c4fSMartin Matuska } 131