Home | History | Annotate | Line # | Download | only in test
      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 /*
     10  * tar -x -P should follow existing symlinks for dirs, but not other
     11  * content.  Plain tar -x should remove symlinks when they're in the
     12  * way of a dir extraction.
     13  */
     14 
     15 DEFINE_TEST(test_symlink_dir)
     16 {
     17 	assertUmask(0);
     18 
     19 	assertMakeDir("source", 0755);
     20 	assertMakeFile("source/file", 0755, "a");
     21 	assertMakeFile("source/file2", 0755, "ab");
     22 	assertMakeDir("source/dir", 0755);
     23 	assertMakeDir("source/dir/d", 0755);
     24 	assertMakeFile("source/dir/f", 0755, "abc");
     25 	assertMakeDir("source/dir2", 0755);
     26 	assertMakeDir("source/dir2/d2", 0755);
     27 	assertMakeFile("source/dir2/f2", 0755, "abcd");
     28 	assertMakeDir("source/dir3", 0755);
     29 	assertMakeDir("source/dir3/d3", 0755);
     30 	assertMakeFile("source/dir3/f3", 0755, "abcde");
     31 	assertMakeDir("source/dir4", 0755);
     32 	assertMakeFile("source/dir4/file3", 0755, "abcdef");
     33 	assertMakeHardlink("source/dir4/file4", "source/dir4/file3");
     34 
     35 	assertEqualInt(0,
     36 	    systemf("%s -cf test.tar -C source dir dir2 dir3 file file2",
     37 		testprog));
     38 
     39 	/* Second archive with hardlinks */
     40 	assertEqualInt(0,
     41 	    systemf("%s -cf test2.tar -C source dir4", testprog));
     42 
     43 	/*
     44 	 * Extract with -x and without -P.
     45 	 */
     46 	assertMakeDir("dest1", 0755);
     47 	/* "dir" is a symlink to an existing "dest1/real_dir" */
     48 	assertMakeDir("dest1/real_dir", 0755);
     49 	if (canSymlink()) {
     50 		assertMakeSymlink("dest1/dir", "real_dir", 1);
     51 		/* "dir2" is a symlink to a non-existing "real_dir2" */
     52 		assertMakeSymlink("dest1/dir2", "real_dir2", 1);
     53 	} else {
     54 		skipping("Symlinks are not supported on this platform");
     55 	}
     56 	/* "dir3" is a symlink to an existing "non_dir3" */
     57 	assertMakeFile("dest1/non_dir3", 0755, "abcdef");
     58 	if (canSymlink())
     59 		assertMakeSymlink("dest1/dir3", "non_dir3", 1);
     60 	/* "file" is a symlink to existing "real_file" */
     61 	assertMakeFile("dest1/real_file", 0755, "abcdefg");
     62 	if (canSymlink()) {
     63 		assertMakeSymlink("dest1/file", "real_file", 0);
     64 		/* "file2" is a symlink to non-existing "real_file2" */
     65 		assertMakeSymlink("dest1/file2", "real_file2", 0);
     66 	}
     67 	assertEqualInt(0, systemf("%s -xUf test.tar -C dest1", testprog));
     68 
     69 	/* dest1/dir symlink should be replaced */
     70 	failure("symlink to dir was followed when it shouldn't be");
     71 	assertIsDir("dest1/dir", -1);
     72 	/* dest1/dir2 symlink should be replaced */
     73 	failure("Broken symlink wasn't replaced with dir");
     74 	assertIsDir("dest1/dir2", -1);
     75 	/* dest1/dir3 symlink should be replaced */
     76 	failure("Symlink to non-dir wasn't replaced with dir");
     77 	assertIsDir("dest1/dir3", -1);
     78 	/* dest1/file symlink should be replaced */
     79 	failure("Symlink to existing file should be replaced");
     80 	assertIsReg("dest1/file", -1);
     81 	/* dest1/file2 symlink should be replaced */
     82 	failure("Symlink to non-existing file should be replaced");
     83 	assertIsReg("dest1/file2", -1);
     84 
     85 	/*
     86 	 * Extract with both -x and -P
     87 	 */
     88 	assertMakeDir("dest2", 0755);
     89 	/* "dir" is a symlink to existing "real_dir" */
     90 	assertMakeDir("dest2/real_dir", 0755);
     91 	if (canSymlink())
     92 		assertMakeSymlink("dest2/dir", "real_dir", 1);
     93 	/* "dir2" is a symlink to a non-existing "real_dir2" */
     94 	if (canSymlink())
     95 		assertMakeSymlink("dest2/dir2", "real_dir2", 1);
     96 	/* "dir3" is a symlink to an existing "non_dir3" */
     97 	assertMakeFile("dest2/non_dir3", 0755, "abcdefgh");
     98 	if (canSymlink())
     99 		assertMakeSymlink("dest2/dir3", "non_dir3", 1);
    100 	/* "file" is a symlink to existing "real_file" */
    101 	assertMakeFile("dest2/real_file", 0755, "abcdefghi");
    102 	if (canSymlink())
    103 		assertMakeSymlink("dest2/file", "real_file", 0);
    104 	/* "file2" is a symlink to non-existing "real_file2" */
    105 	if (canSymlink())
    106 		assertMakeSymlink("dest2/file2", "real_file2", 0);
    107 	assertEqualInt(0, systemf("%s -xPf test.tar -C dest2", testprog));
    108 
    109 	/* "dir4" is a symlink to existing "real_dir" */
    110 	if (canSymlink())
    111 		assertMakeSymlink("dest2/dir4", "real_dir", 1);
    112 	assertEqualInt(0, systemf("%s -xPf test2.tar -C dest2", testprog));
    113 
    114 	/* dest2/dir and dest2/dir4 symlinks should be followed */
    115 	if (canSymlink()) {
    116 		assertIsSymlink("dest2/dir", "real_dir", 1);
    117 		assertIsSymlink("dest2/dir4", "real_dir", 1);
    118 		assertIsDir("dest2/real_dir", -1);
    119 	}
    120 
    121 	/* Contents of 'dir' should be restored */
    122 	assertIsDir("dest2/dir/d", -1);
    123 	assertIsReg("dest2/dir/f", -1);
    124 	assertFileSize("dest2/dir/f", 3);
    125 	/* dest2/dir2 symlink should be removed */
    126 	failure("Broken symlink wasn't replaced with dir");
    127 	assertIsDir("dest2/dir2", -1);
    128 	/* dest2/dir3 symlink should be removed */
    129 	failure("Symlink to non-dir wasn't replaced with dir");
    130 	assertIsDir("dest2/dir3", -1);
    131 	/* dest2/file symlink should be removed;
    132 	 * even -P shouldn't follow symlinks for files */
    133 	failure("Symlink to existing file should be removed");
    134 	assertIsReg("dest2/file", -1);
    135 	/* dest2/file2 symlink should be removed */
    136 	failure("Symlink to non-existing file should be removed");
    137 	assertIsReg("dest2/file2", -1);
    138 
    139 	/* dest2/dir4/file3 and dest2/dir4/file4 should be hard links */
    140 	assertIsHardlink("dest2/dir4/file3", "dest2/dir4/file4");
    141 }
    142