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 { 336c95142eSMartin Matuska char *buff; 34caf54c4fSMartin Matuska char *p0, *p1; 356c95142eSMartin Matuska size_t buff_size = 35000; 366c95142eSMartin Matuska size_t s, buff_size_rounded; 376c95142eSMartin Matuska int r, i; 38caf54c4fSMartin Matuska 39*63ecfce8SEnji Cooper buff = NULL; 40*63ecfce8SEnji Cooper p0 = NULL; 41*63ecfce8SEnji Cooper p1 = NULL; 42*63ecfce8SEnji Cooper 436c95142eSMartin Matuska /* Create an archive with one file. */ 446c95142eSMartin Matuska assertMakeFile("f1", 0644, "abc"); 45caf54c4fSMartin Matuska r = systemf("%s cf archive.tar --format=ustar f1 >step1.out 2>step1.err", testprog); 46caf54c4fSMartin Matuska failure("Error invoking %s cf archive.tar f1", testprog); 47caf54c4fSMartin Matuska assertEqualInt(r, 0); 48caf54c4fSMartin Matuska assertEmptyFile("step1.out"); 49caf54c4fSMartin Matuska assertEmptyFile("step1.err"); 50caf54c4fSMartin Matuska 51caf54c4fSMartin Matuska /* Do some basic validation of the constructed archive. */ 52caf54c4fSMartin Matuska p0 = slurpfile(&s, "archive.tar"); 53caf54c4fSMartin Matuska if (!assert(p0 != NULL)) 54*63ecfce8SEnji Cooper goto done; 55*63ecfce8SEnji Cooper if (!assert(s >= 2048)) 56*63ecfce8SEnji Cooper goto done; 57caf54c4fSMartin Matuska assertEqualMem(p0 + 0, "f1", 3); 58caf54c4fSMartin Matuska assertEqualMem(p0 + 512, "abc", 3); 59caf54c4fSMartin Matuska assertEqualMem(p0 + 1024, "\0\0\0\0\0\0\0\0", 8); 60caf54c4fSMartin Matuska assertEqualMem(p0 + 1536, "\0\0\0\0\0\0\0\0", 8); 61caf54c4fSMartin Matuska 626c95142eSMartin Matuska /* Edit that file with a lot more data and update the archive with a new copy. */ 636c95142eSMartin Matuska buff = malloc(buff_size); 646c95142eSMartin Matuska assert(buff != NULL); 65*63ecfce8SEnji Cooper if (buff == NULL) 66*63ecfce8SEnji Cooper goto done; 67acc60b03SMartin Matuska 686c95142eSMartin Matuska for (i = 0; i < (int)buff_size; ++i) 696c95142eSMartin Matuska buff[i] = "abcdefghijklmnopqrstuvwxyz"[rand() % 26]; 706c95142eSMartin Matuska buff[buff_size - 1] = '\0'; 716c95142eSMartin Matuska assertMakeFile("f1", 0644, buff); 72caf54c4fSMartin Matuska r = systemf("%s rf archive.tar --format=ustar f1 >step2.out 2>step2.err", testprog); 73caf54c4fSMartin Matuska failure("Error invoking %s rf archive.tar f1", testprog); 74caf54c4fSMartin Matuska assertEqualInt(r, 0); 75caf54c4fSMartin Matuska assertEmptyFile("step2.out"); 76caf54c4fSMartin Matuska assertEmptyFile("step2.err"); 77caf54c4fSMartin Matuska 786c95142eSMartin Matuska /* The constructed archive should just have the new entry appended. */ 79caf54c4fSMartin Matuska p1 = slurpfile(&s, "archive.tar"); 80*63ecfce8SEnji Cooper if (!assert(p1 != NULL)) 81*63ecfce8SEnji Cooper goto done; 826c95142eSMartin Matuska buff_size_rounded = ((buff_size + 511) / 512) * 512; 836c95142eSMartin Matuska assert(s >= 2560 + buff_size_rounded); 84caf54c4fSMartin Matuska /* Verify first entry is unchanged. */ 85caf54c4fSMartin Matuska assertEqualMem(p0, p1, 1024); 86caf54c4fSMartin Matuska /* Verify that second entry is correct. */ 87caf54c4fSMartin Matuska assertEqualMem(p1 + 1024, "f1", 3); 886c95142eSMartin Matuska assertEqualMem(p1 + 1536, buff, buff_size); 89caf54c4fSMartin Matuska /* Verify end-of-archive marker. */ 906c95142eSMartin Matuska assertEqualMem(p1 + 1536 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 916c95142eSMartin Matuska assertEqualMem(p1 + 2048 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 926c95142eSMartin Matuska 936c95142eSMartin Matuska free(p0); 946c95142eSMartin Matuska p0 = p1; 956c95142eSMartin Matuska 966c95142eSMartin Matuska /* Update the archive by adding a different file. */ 976c95142eSMartin Matuska assertMakeFile("f2", 0644, "f2"); 986c95142eSMartin Matuska r = systemf("%s rf archive.tar --format=ustar f2 >step3.out 2>step3.err", testprog); 996c95142eSMartin Matuska failure("Error invoking %s rf archive.tar f2", testprog); 1006c95142eSMartin Matuska assertEqualInt(r, 0); 1016c95142eSMartin Matuska assertEmptyFile("step3.out"); 1026c95142eSMartin Matuska assertEmptyFile("step3.err"); 1036c95142eSMartin Matuska 1046c95142eSMartin Matuska /* Validate the constructed archive. */ 1056c95142eSMartin Matuska p1 = slurpfile(&s, "archive.tar"); 106*63ecfce8SEnji Cooper if (!assert(p1 != NULL)) 107*63ecfce8SEnji Cooper goto done; 1086c95142eSMartin Matuska assert(s >= 3584 + buff_size_rounded); 1096c95142eSMartin Matuska /* Verify first two entries are unchanged. */ 1106c95142eSMartin Matuska assertEqualMem(p0, p1, 1536 + buff_size_rounded); 1116c95142eSMartin Matuska /* Verify that new entry is correct. */ 1126c95142eSMartin Matuska assertEqualMem(p1 + 1536 + buff_size_rounded, "f2", 3); 1136c95142eSMartin Matuska assertEqualMem(p1 + 2048 + buff_size_rounded, "f2", 3); 1146c95142eSMartin Matuska /* Verify end-of-archive marker. */ 1156c95142eSMartin Matuska assertEqualMem(p1 + 2560 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 1166c95142eSMartin Matuska assertEqualMem(p1 + 3072 + buff_size_rounded, "\0\0\0\0\0\0\0\0", 8); 117caf54c4fSMartin Matuska free(p1); 118caf54c4fSMartin Matuska 1196c95142eSMartin Matuska /* Unpack everything */ 1206c95142eSMartin Matuska assertMakeDir("extract", 0775); 1216c95142eSMartin Matuska assertChdir("extract"); 1226c95142eSMartin 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); 1256c95142eSMartin Matuska assertEmptyFile("extract.out"); 1266c95142eSMartin Matuska assertEmptyFile("extract.err"); 127caf54c4fSMartin Matuska 1286c95142eSMartin Matuska /* Verify that the second copy of f1 overwrote the first. */ 129acc60b03SMartin Matuska assertFileContents(buff, (int)strlen(buff), "f1"); 130*63ecfce8SEnji Cooper done: 131*63ecfce8SEnji Cooper free(buff); 132*63ecfce8SEnji Cooper free(p0); 133caf54c4fSMartin Matuska } 134