1 /*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 #include "test.h" 26 __FBSDID("$FreeBSD$"); 27 28 DEFINE_TEST(test_strip_components) 29 { 30 assertMakeDir("d0", 0755); 31 assertChdir("d0"); 32 assertMakeDir("d1", 0755); 33 assertMakeDir("d1/d2", 0755); 34 assertMakeDir("d1/d2/d3", 0755); 35 assertMakeFile("d1/d2/f1", 0644, ""); 36 assertMakeHardlink("l1", "d1/d2/f1"); 37 assertMakeHardlink("d1/l2", "d1/d2/f1"); 38 if (canSymlink()) { 39 assertMakeSymlink("s1", "d1/d2/f1", 0); 40 assertMakeSymlink("d1/s2", "d2/f1", 0); 41 } 42 assertChdir(".."); 43 44 /* 45 * Test 1: Strip components when extracting archives. 46 */ 47 if (canSymlink()) 48 assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/s1 d0/d1", 49 testprog)); 50 else 51 assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/d1", 52 testprog)); 53 54 assertMakeDir("target", 0755); 55 assertEqualInt(0, systemf("%s -x -C target --strip-components 2 " 56 "-f test.tar", testprog)); 57 58 failure("d0/ is too short and should not get restored"); 59 assertFileNotExists("target/d0"); 60 failure("d0/d1/ is too short and should not get restored"); 61 assertFileNotExists("target/d1"); 62 failure("d0/s1 is too short and should not get restored"); 63 assertFileNotExists("target/s1"); 64 failure("d0/d1/s2 is a symlink to something that won't be extracted"); 65 /* If platform supports symlinks, target/s2 is a broken symlink. */ 66 /* If platform does not support symlink, target/s2 doesn't exist. */ 67 if (canSymlink()) 68 assertIsSymlink("target/s2", "d2/f1", 0); 69 else 70 assertFileNotExists("target/s2"); 71 failure("d0/d1/d2 should be extracted"); 72 assertIsDir("target/d2", -1); 73 74 /* 75 * Test 1b: Strip components extracting archives involving hardlinks. 76 * 77 * This next is a complicated case. d0/l1, d0/d1/l2, and 78 * d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't 79 * be extracted with --strip-components=2 and the other two 80 * can. Remember that tar normally stores the first file with 81 * a body and the other as hardlink entries to the first 82 * appearance. So the final result depends on the order in 83 * which these three names get archived. If d0/l1 is first, 84 * none of the three can be restored. If either of the longer 85 * names are first, then the two longer ones can both be 86 * restored. Note that the "tar -cf" command above explicitly 87 * lists d0/l1 before d0/d1. 88 * 89 * It may be worth extending this test to exercise other 90 * archiving orders. 91 * 92 * Of course, this is all totally different for cpio and newc 93 * formats because the hardlink management is different. 94 * TODO: Rename this to test_strip_components_tar and create 95 * parallel tests for cpio and newc formats. 96 */ 97 failure("d0/l1 is too short and should not get restored"); 98 assertFileNotExists("target/l1"); 99 failure("d0/d1/l2 is a hardlink to file whose name was too short"); 100 assertFileNotExists("target/l2"); 101 failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); 102 assertFileNotExists("target/d2/f1"); 103 104 /* 105 * Test 2: Strip components when creating archives. 106 */ 107 if (canSymlink()) 108 assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " 109 "d0/l1 d0/s1 d0/d1", testprog)); 110 else 111 assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " 112 "d0/l1 d0/d1", testprog)); 113 114 assertMakeDir("target2", 0755); 115 assertEqualInt(0, systemf("%s -x -C target2 -f test2.tar", testprog)); 116 117 failure("d0/ is too short and should not have been archived"); 118 assertFileNotExists("target2/d0"); 119 failure("d0/d1/ is too short and should not have been archived"); 120 assertFileNotExists("target2/d1"); 121 failure("d0/s1 is too short and should not get restored"); 122 assertFileNotExists("target/s1"); 123 /* If platform supports symlinks, target/s2 is included. */ 124 if (canSymlink()) { 125 failure("d0/d1/s2 is a symlink to something included in archive"); 126 assertIsSymlink("target2/s2", "d2/f1", 0); 127 } 128 failure("d0/d1/d2 should be archived"); 129 assertIsDir("target2/d2", -1); 130 131 /* 132 * Test 2b: Strip components creating archives involving hardlinks. 133 */ 134 failure("d0/l1 is too short and should not have been archived"); 135 assertFileNotExists("target/l1"); 136 failure("d0/d1/l2 is a hardlink to file whose name was too short"); 137 assertFileNotExists("target/l2"); 138 failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); 139 assertFileNotExists("target/d2/f1"); 140 } 141