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: releng/11.0/contrib/libarchive/tar/test/test_symlink_dir.c 232153 2012-02-25 10:58:02Z mm $"); 27228753Smm 28228753Smm/* 29228753Smm * tar -x -P should follow existing symlinks for dirs, but not other 30228753Smm * content. Plain tar -x should remove symlinks when they're in the 31228753Smm * way of a dir extraction. 32228753Smm */ 33228753Smm 34228753SmmDEFINE_TEST(test_symlink_dir) 35228753Smm{ 36228753Smm assertUmask(0); 37228753Smm 38228753Smm assertMakeDir("source", 0755); 39232153Smm assertMakeFile("source/file", 0755, "a"); 40232153Smm assertMakeFile("source/file2", 0755, "ab"); 41228753Smm assertMakeDir("source/dir", 0755); 42228753Smm assertMakeDir("source/dir/d", 0755); 43232153Smm assertMakeFile("source/dir/f", 0755, "abc"); 44228753Smm assertMakeDir("source/dir2", 0755); 45228753Smm assertMakeDir("source/dir2/d2", 0755); 46232153Smm assertMakeFile("source/dir2/f2", 0755, "abcd"); 47228753Smm assertMakeDir("source/dir3", 0755); 48228753Smm assertMakeDir("source/dir3/d3", 0755); 49232153Smm assertMakeFile("source/dir3/f3", 0755, "abcde"); 50228753Smm 51228753Smm assertEqualInt(0, 52228753Smm systemf("%s -cf test.tar -C source dir dir2 dir3 file file2", 53228753Smm testprog)); 54228753Smm 55228753Smm /* 56228753Smm * Extract with -x and without -P. 57228753Smm */ 58228753Smm assertMakeDir("dest1", 0755); 59228753Smm /* "dir" is a symlink to an existing "dest1/real_dir" */ 60228753Smm assertMakeDir("dest1/real_dir", 0755); 61228753Smm if (canSymlink()) { 62228753Smm assertMakeSymlink("dest1/dir", "real_dir"); 63228753Smm /* "dir2" is a symlink to a non-existing "real_dir2" */ 64228753Smm assertMakeSymlink("dest1/dir2", "real_dir2"); 65228753Smm } else { 66228753Smm skipping("some symlink checks"); 67228753Smm } 68228753Smm /* "dir3" is a symlink to an existing "non_dir3" */ 69232153Smm assertMakeFile("dest1/non_dir3", 0755, "abcdef"); 70228753Smm if (canSymlink()) 71228753Smm assertMakeSymlink("dest1/dir3", "non_dir3"); 72228753Smm /* "file" is a symlink to existing "real_file" */ 73232153Smm assertMakeFile("dest1/real_file", 0755, "abcdefg"); 74228753Smm if (canSymlink()) { 75228753Smm assertMakeSymlink("dest1/file", "real_file"); 76228753Smm /* "file2" is a symlink to non-existing "real_file2" */ 77228753Smm assertMakeSymlink("dest1/file2", "real_file2"); 78228753Smm } 79228753Smm assertEqualInt(0, systemf("%s -xf test.tar -C dest1", testprog)); 80228753Smm 81228753Smm /* dest1/dir symlink should be replaced */ 82228753Smm failure("symlink to dir was followed when it shouldn't be"); 83228753Smm assertIsDir("dest1/dir", -1); 84228753Smm /* dest1/dir2 symlink should be replaced */ 85228753Smm failure("Broken symlink wasn't replaced with dir"); 86228753Smm assertIsDir("dest1/dir2", -1); 87228753Smm /* dest1/dir3 symlink should be replaced */ 88228753Smm failure("Symlink to non-dir wasn't replaced with dir"); 89228753Smm assertIsDir("dest1/dir3", -1); 90228753Smm /* dest1/file symlink should be replaced */ 91228753Smm failure("Symlink to existing file should be replaced"); 92228753Smm assertIsReg("dest1/file", -1); 93228753Smm /* dest1/file2 symlink should be replaced */ 94228753Smm failure("Symlink to non-existing file should be replaced"); 95228753Smm assertIsReg("dest1/file2", -1); 96228753Smm 97228753Smm /* 98228753Smm * Extract with both -x and -P 99228753Smm */ 100228753Smm assertMakeDir("dest2", 0755); 101228753Smm /* "dir" is a symlink to existing "real_dir" */ 102228753Smm assertMakeDir("dest2/real_dir", 0755); 103228753Smm if (canSymlink()) 104228753Smm assertMakeSymlink("dest2/dir", "real_dir"); 105228753Smm /* "dir2" is a symlink to a non-existing "real_dir2" */ 106228753Smm if (canSymlink()) 107228753Smm assertMakeSymlink("dest2/dir2", "real_dir2"); 108228753Smm /* "dir3" is a symlink to an existing "non_dir3" */ 109232153Smm assertMakeFile("dest2/non_dir3", 0755, "abcdefgh"); 110228753Smm if (canSymlink()) 111228753Smm assertMakeSymlink("dest2/dir3", "non_dir3"); 112228753Smm /* "file" is a symlink to existing "real_file" */ 113232153Smm assertMakeFile("dest2/real_file", 0755, "abcdefghi"); 114228753Smm if (canSymlink()) 115228753Smm assertMakeSymlink("dest2/file", "real_file"); 116228753Smm /* "file2" is a symlink to non-existing "real_file2" */ 117228753Smm if (canSymlink()) 118228753Smm assertMakeSymlink("dest2/file2", "real_file2"); 119228753Smm assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog)); 120228753Smm 121228753Smm /* dest2/dir symlink should be followed */ 122228753Smm if (canSymlink()) { 123228753Smm assertIsSymlink("dest2/dir", "real_dir"); 124228753Smm assertIsDir("dest2/real_dir", -1); 125228753Smm } 126228753Smm 127228753Smm /* Contents of 'dir' should be restored */ 128228753Smm assertIsDir("dest2/dir/d", -1); 129228753Smm assertIsReg("dest2/dir/f", -1); 130228753Smm assertFileSize("dest2/dir/f", 3); 131228753Smm /* dest2/dir2 symlink should be removed */ 132228753Smm failure("Broken symlink wasn't replaced with dir"); 133228753Smm assertIsDir("dest2/dir2", -1); 134228753Smm /* dest2/dir3 symlink should be removed */ 135228753Smm failure("Symlink to non-dir wasn't replaced with dir"); 136228753Smm assertIsDir("dest2/dir3", -1); 137228753Smm /* dest2/file symlink should be removed; 138228753Smm * even -P shouldn't follow symlinks for files */ 139228753Smm failure("Symlink to existing file should be removed"); 140228753Smm assertIsReg("dest2/file", -1); 141228753Smm /* dest2/file2 symlink should be removed */ 142228753Smm failure("Symlink to non-existing file should be removed"); 143228753Smm assertIsReg("dest2/file2", -1); 144228753Smm} 145