1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2003-2007 Tim Kientzle 5 * All rights reserved. 6 */ 7 #include "test.h" 8 9 DEFINE_TEST(test_strip_components) 10 { 11 assertMakeDir("d0", 0755); 12 assertChdir("d0"); 13 assertMakeDir("d1", 0755); 14 assertMakeDir("d1/d2", 0755); 15 assertMakeDir("d1/d2/d3", 0755); 16 assertMakeFile("d1/d2/f1", 0644, ""); 17 assertMakeHardlink("l1", "d1/d2/f1"); 18 assertMakeHardlink("d1/l2", "d1/d2/f1"); 19 if (canSymlink()) { 20 assertMakeSymlink("s1", "d1/d2/f1", 0); 21 assertMakeSymlink("d1/s2", "d2/f1", 0); 22 } 23 assertChdir(".."); 24 25 /* 26 * Test 1: Strip components when extracting archives. 27 */ 28 if (canSymlink()) 29 assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/s1 d0/d1", 30 testprog)); 31 else 32 assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/d1", 33 testprog)); 34 35 assertMakeDir("target", 0755); 36 assertEqualInt(0, systemf("%s -x -C target --strip-components 2 " 37 "-f test.tar", testprog)); 38 39 failure("d0/ is too short and should not get restored"); 40 assertFileNotExists("target/d0"); 41 failure("d0/d1/ is too short and should not get restored"); 42 assertFileNotExists("target/d1"); 43 failure("d0/s1 is too short and should not get restored"); 44 assertFileNotExists("target/s1"); 45 failure("d0/d1/s2 is a symlink to something that won't be extracted"); 46 /* If platform supports symlinks, target/s2 is a broken symlink. */ 47 /* If platform does not support symlink, target/s2 doesn't exist. */ 48 if (canSymlink()) 49 assertIsSymlink("target/s2", "d2/f1", 0); 50 else 51 assertFileNotExists("target/s2"); 52 failure("d0/d1/d2 should be extracted"); 53 assertIsDir("target/d2", -1); 54 55 /* 56 * Test 1b: Strip components extracting archives involving hardlinks. 57 * 58 * This next is a complicated case. d0/l1, d0/d1/l2, and 59 * d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't 60 * be extracted with --strip-components=2 and the other two 61 * can. Remember that tar normally stores the first file with 62 * a body and the other as hardlink entries to the first 63 * appearance. So the final result depends on the order in 64 * which these three names get archived. If d0/l1 is first, 65 * none of the three can be restored. If either of the longer 66 * names are first, then the two longer ones can both be 67 * restored. Note that the "tar -cf" command above explicitly 68 * lists d0/l1 before d0/d1. 69 * 70 * It may be worth extending this test to exercise other 71 * archiving orders. 72 * 73 * Of course, this is all totally different for cpio and newc 74 * formats because the hardlink management is different. 75 * TODO: Rename this to test_strip_components_tar and create 76 * parallel tests for cpio and newc formats. 77 */ 78 failure("d0/l1 is too short and should not get restored"); 79 assertFileNotExists("target/l1"); 80 failure("d0/d1/l2 is a hardlink to file whose name was too short"); 81 assertFileNotExists("target/l2"); 82 failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); 83 assertFileNotExists("target/d2/f1"); 84 85 /* 86 * Test 2: Strip components when creating archives. 87 */ 88 if (canSymlink()) 89 assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " 90 "d0/l1 d0/s1 d0/d1", testprog)); 91 else 92 assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar " 93 "d0/l1 d0/d1", testprog)); 94 95 assertMakeDir("target2", 0755); 96 assertEqualInt(0, systemf("%s -x -C target2 -f test2.tar", testprog)); 97 98 failure("d0/ is too short and should not have been archived"); 99 assertFileNotExists("target2/d0"); 100 failure("d0/d1/ is too short and should not have been archived"); 101 assertFileNotExists("target2/d1"); 102 failure("d0/s1 is too short and should not get restored"); 103 assertFileNotExists("target/s1"); 104 /* If platform supports symlinks, target/s2 is included. */ 105 if (canSymlink()) { 106 failure("d0/d1/s2 is a symlink to something included in archive"); 107 assertIsSymlink("target2/s2", "d2/f1", 0); 108 } 109 failure("d0/d1/d2 should be archived"); 110 assertIsDir("target2/d2", -1); 111 112 /* 113 * Test 2b: Strip components creating archives involving hardlinks. 114 */ 115 failure("d0/l1 is too short and should not have been archived"); 116 assertFileNotExists("target/l1"); 117 failure("d0/d1/l2 is a hardlink to file whose name was too short"); 118 assertFileNotExists("target/l2"); 119 failure("d0/d1/d2/f1 is a hardlink to file whose name was too short"); 120 assertFileNotExists("target/d2/f1"); 121 } 122