xref: /freebsd/contrib/libarchive/tar/test/test_option_s.c (revision 2e113ef82465598b8c26e0ca415fbe90677fbd47)
1caf54c4fSMartin Matuska /*-
2bd66c1b4SMartin Matuska  * SPDX-License-Identifier: BSD-2-Clause
3bd66c1b4SMartin Matuska  *
4caf54c4fSMartin Matuska  * Copyright (c) 2003-2008 Tim Kientzle
5caf54c4fSMartin Matuska  * All rights reserved.
6caf54c4fSMartin Matuska  */
7caf54c4fSMartin Matuska #include "test.h"
8caf54c4fSMartin Matuska 
DEFINE_TEST(test_option_s)9caf54c4fSMartin Matuska DEFINE_TEST(test_option_s)
10caf54c4fSMartin Matuska {
11caf54c4fSMartin Matuska 	struct stat st;
12caf54c4fSMartin Matuska 
13c5d360f8SMartin Matuska 	/* Create a sample file hierarchy. */
14caf54c4fSMartin Matuska 	assertMakeDir("in", 0755);
15caf54c4fSMartin Matuska 	assertMakeDir("in/d1", 0755);
166c95142eSMartin Matuska 	assertMakeFile("in/d1/foo", 0644, "foo");
176c95142eSMartin Matuska 	assertMakeFile("in/d1/bar", 0644, "bar");
186c95142eSMartin Matuska 	if (canSymlink()) {
196c95142eSMartin Matuska 		assertMakeFile("in/d1/realfile", 0644, "realfile");
2052c2bb75SMartin Matuska 		assertMakeSymlink("in/d1/symlink", "realfile", 0);
216c95142eSMartin Matuska 	}
226c95142eSMartin Matuska 	assertMakeFile("in/d1/hardlink1", 0644, "hardlinkedfile");
236c95142eSMartin Matuska 	assertMakeHardlink("in/d1/hardlink2", "in/d1/hardlink1");
24caf54c4fSMartin Matuska 
256c95142eSMartin Matuska 	/* Does tar support -s option ? */
26caf54c4fSMartin Matuska 	systemf("%s -cf - -s /foo/bar/ in/d1/foo > NUL 2> check.err",
27caf54c4fSMartin Matuska 	    testprog);
28caf54c4fSMartin Matuska 	assertEqualInt(0, stat("check.err", &st));
29caf54c4fSMartin Matuska 	if (st.st_size != 0) {
30caf54c4fSMartin Matuska 		skipping("%s does not support -s option on this platform",
31caf54c4fSMartin Matuska 			testprog);
32caf54c4fSMartin Matuska 		return;
33caf54c4fSMartin Matuska 	}
34caf54c4fSMartin Matuska 
35caf54c4fSMartin Matuska 	/*
36caf54c4fSMartin Matuska 	 * Test 1: Filename substitution when creating archives.
37caf54c4fSMartin Matuska 	 */
38caf54c4fSMartin Matuska 	assertMakeDir("test1", 0755);
396c95142eSMartin Matuska 	systemf("%s -cf test1_1.tar -s /foo/bar/ in/d1/foo", testprog);
406c95142eSMartin Matuska 	systemf("%s -xf test1_1.tar -C test1", testprog);
41caf54c4fSMartin Matuska 	assertFileContents("foo", 3, "test1/in/d1/bar");
426c95142eSMartin Matuska 	systemf("%s -cf test1_2.tar -s /d1/d2/ in/d1/foo", testprog);
436c95142eSMartin Matuska 	systemf("%s -xf test1_2.tar -C test1", testprog);
44caf54c4fSMartin Matuska 	assertFileContents("foo", 3, "test1/in/d2/foo");
45caf54c4fSMartin Matuska 
46caf54c4fSMartin Matuska 	/*
47caf54c4fSMartin Matuska 	 * Test 2: Basic substitution when extracting archive.
48caf54c4fSMartin Matuska 	 */
49caf54c4fSMartin Matuska 	assertMakeDir("test2", 0755);
506c95142eSMartin Matuska 	systemf("%s -cf test2.tar in/d1/foo", testprog);
516c95142eSMartin Matuska 	systemf("%s -xf test2.tar -s /foo/bar/ -C test2", testprog);
52caf54c4fSMartin Matuska 	assertFileContents("foo", 3, "test2/in/d1/bar");
53caf54c4fSMartin Matuska 
54caf54c4fSMartin Matuska 	/*
55caf54c4fSMartin Matuska 	 * Test 3: Files with empty names shouldn't be archived.
56caf54c4fSMartin Matuska 	 */
576c95142eSMartin Matuska 	systemf("%s -cf test3.tar -s ,in/d1/foo,, in/d1/foo", testprog);
586c95142eSMartin Matuska 	systemf("%s -tvf test3.tar > in.lst", testprog);
59caf54c4fSMartin Matuska 	assertEmptyFile("in.lst");
60caf54c4fSMartin Matuska 
61caf54c4fSMartin Matuska 	/*
62caf54c4fSMartin Matuska 	 * Test 4: Multiple substitutions when extracting archive.
63caf54c4fSMartin Matuska 	 */
64caf54c4fSMartin Matuska 	assertMakeDir("test4", 0755);
656c95142eSMartin Matuska 	systemf("%s -cf test4.tar in/d1/foo in/d1/bar",
66cdf63a70SMartin Matuska 	    testprog);
676c95142eSMartin Matuska 	systemf("%s -xf test4.tar -s /foo/bar/ -s }bar}baz} -C test4",
68cdf63a70SMartin Matuska 	    testprog);
69caf54c4fSMartin Matuska 	assertFileContents("foo", 3, "test4/in/d1/bar");
70caf54c4fSMartin Matuska 	assertFileContents("bar", 3, "test4/in/d1/baz");
71caf54c4fSMartin Matuska 
72caf54c4fSMartin Matuska 	/*
73*2e113ef8SMartin Matuska 	 * Test 4b: Multiple substitutions behavior with option b.
74b9128a37SMartin Matuska 	 */
75b9128a37SMartin Matuska 	assertMakeDir("test4b", 0755);
76b9128a37SMartin Matuska 	systemf("%s -cf test4b.tar in/d1/foo in/d1/bar",
77b9128a37SMartin Matuska 	    testprog);
78b9128a37SMartin Matuska 	systemf("%s -xf test4b.tar -s /oo/ar/ -s }ar}az}b -C test4b",
79b9128a37SMartin Matuska 	    testprog);
80b9128a37SMartin Matuska 	assertFileContents("foo", 3, "test4b/in/d1/faz");
81b9128a37SMartin Matuska 	assertFileContents("bar", 3, "test4b/in/d1/baz");
82b9128a37SMartin Matuska 
83b9128a37SMartin Matuska 	/*
84*2e113ef8SMartin Matuska 	 * Test 4bb: Multiple substitutions with option b
85*2e113ef8SMartin Matuska 	 * (libarchive/libarchive#2414 GitHub issue regression test).
86*2e113ef8SMartin Matuska 	 */
87*2e113ef8SMartin Matuska 	assertMakeDir("test4bb", 0755);
88*2e113ef8SMartin Matuska 	systemf("%s -cf test4bb.tar in/d1/foo in/d1/bar",
89*2e113ef8SMartin Matuska 	    testprog);
90*2e113ef8SMartin Matuska 	systemf("%s -xf test4bb.tar -s /oo/ar/ -s }ar}az}b -s :az:end:b -C test4bb",
91*2e113ef8SMartin Matuska 	    testprog);
92*2e113ef8SMartin Matuska 	assertFileContents("foo", 3, "test4bb/in/d1/fend");
93*2e113ef8SMartin Matuska 	assertFileContents("bar", 3, "test4bb/in/d1/bend");
94*2e113ef8SMartin Matuska 
95*2e113ef8SMartin Matuska 	/*
96caf54c4fSMartin Matuska 	 * Test 5: Name-switching substitutions when extracting archive.
97caf54c4fSMartin Matuska 	 */
98caf54c4fSMartin Matuska 	assertMakeDir("test5", 0755);
99f9762417SMartin Matuska 	systemf("%s -cf test5.tar in/d1/foo in/d1/bar", testprog);
100f9762417SMartin Matuska 	systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5", testprog);
101caf54c4fSMartin Matuska 	assertFileContents("foo", 3, "test5/in/d1/bar");
102caf54c4fSMartin Matuska 	assertFileContents("bar", 3, "test5/in/d1/foo");
1036c95142eSMartin Matuska 
1046c95142eSMartin Matuska 	/*
1056c95142eSMartin Matuska 	 * Test 6: symlinks get renamed by default
1066c95142eSMartin Matuska 	 */
1076c95142eSMartin Matuska 	if (canSymlink()) {
1086c95142eSMartin Matuska 		/* At extraction time. */
1096c95142eSMartin Matuska 		assertMakeDir("test6a", 0755);
1106c95142eSMartin Matuska 		systemf("%s -cf - in/d1 | %s -xf - -s /d1/d2/ -C test6a",
1116c95142eSMartin Matuska 		    testprog, testprog);
1126c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test6a/in/d2/realfile");
1136c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test6a/in/d2/symlink");
11452c2bb75SMartin Matuska 		assertIsSymlink("test6a/in/d2/symlink", "realfile", 0);
1156c95142eSMartin Matuska 		/* At creation time. */
1166c95142eSMartin Matuska 		assertMakeDir("test6b", 0755);
1176c95142eSMartin Matuska 		systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test6b",
1186c95142eSMartin Matuska 		    testprog, testprog);
1196c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test6b/in/d2/realfile");
1206c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test6b/in/d2/symlink");
12152c2bb75SMartin Matuska 		assertIsSymlink("test6b/in/d2/symlink", "realfile", 0);
1226c95142eSMartin Matuska 	}
1236c95142eSMartin Matuska 
1246c95142eSMartin Matuska 	/*
1256c95142eSMartin Matuska 	 * Test 7: selective renaming of symlink target
1266c95142eSMartin Matuska 	 */
1276c95142eSMartin Matuska 	if (canSymlink()) {
1286c95142eSMartin Matuska 		/* At extraction. */
1296c95142eSMartin Matuska 		assertMakeDir("test7a", 0755);
1306c95142eSMartin Matuska 		systemf("%s -cf - in/d1 | %s -xf - -s /realfile/realfile-renamed/ -C test7a",
1316c95142eSMartin Matuska 		    testprog, testprog);
1326c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test7a/in/d1/realfile-renamed");
1336c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test7a/in/d1/symlink");
13452c2bb75SMartin Matuska 		assertIsSymlink("test7a/in/d1/symlink", "realfile-renamed", 0);
1356c95142eSMartin Matuska 		/* At creation. */
1366c95142eSMartin Matuska 		assertMakeDir("test7b", 0755);
1376c95142eSMartin Matuska 		systemf("%s -cf - -s /realfile/realfile-renamed/ in/d1 | %s -xf - -C test7b",
1386c95142eSMartin Matuska 		    testprog, testprog);
1396c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test7b/in/d1/realfile-renamed");
1406c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test7b/in/d1/symlink");
14152c2bb75SMartin Matuska 		assertIsSymlink("test7b/in/d1/symlink", "realfile-renamed", 0);
1426c95142eSMartin Matuska 	}
1436c95142eSMartin Matuska 
1446c95142eSMartin Matuska 	/*
1456c95142eSMartin Matuska 	 * Test 8: hardlinks get renamed by default
1466c95142eSMartin Matuska 	 */
1476c95142eSMartin Matuska 	/* At extraction time. */
1486c95142eSMartin Matuska 	assertMakeDir("test8a", 0755);
1496c95142eSMartin Matuska 	systemf("%s -cf test8a.tar in/d1", testprog);
1506c95142eSMartin Matuska 	systemf("%s -xf test8a.tar -s /d1/d2/ -C test8a", testprog);
1516c95142eSMartin Matuska 	assertIsHardlink("test8a/in/d2/hardlink1", "test8a/in/d2/hardlink2");
1526c95142eSMartin Matuska 	/* At creation time. */
1536c95142eSMartin Matuska 	assertMakeDir("test8b", 0755);
1546c95142eSMartin Matuska 	systemf("%s -cf test8b.tar -s /d1/d2/ in/d1", testprog);
1556c95142eSMartin Matuska 	systemf("%s -xf test8b.tar -C test8b", testprog);
1566c95142eSMartin Matuska 	assertIsHardlink("test8b/in/d2/hardlink1", "test8b/in/d2/hardlink2");
1576c95142eSMartin Matuska 
1586c95142eSMartin Matuska 	/*
1596c95142eSMartin Matuska 	 * Test 9: selective renaming of hardlink target
1606c95142eSMartin Matuska 	 */
1616c95142eSMartin Matuska 	/* At extraction. (assuming hardlink2 is the hardlink entry) */
1626c95142eSMartin Matuska 	assertMakeDir("test9a", 0755);
1636c95142eSMartin Matuska 	systemf("%s -cf test9a.tar in/d1", testprog);
1646c95142eSMartin Matuska 	systemf("%s -xf test9a.tar -s /hardlink1/hardlink1-renamed/ -C test9a",
1656c95142eSMartin Matuska 	    testprog);
1666c95142eSMartin Matuska 	assertIsHardlink("test9a/in/d1/hardlink1-renamed", "test9a/in/d1/hardlink2");
1676c95142eSMartin Matuska 	/* At extraction. (assuming hardlink1 is the hardlink entry) */
1686c95142eSMartin Matuska 	assertMakeDir("test9b", 0755);
1696c95142eSMartin Matuska 	systemf("%s -cf test9b.tar in/d1", testprog);
1706c95142eSMartin Matuska 	systemf("%s -xf test9b.tar -s /hardlink2/hardlink2-renamed/ -C test9b",
1716c95142eSMartin Matuska 	    testprog);
1726c95142eSMartin Matuska 	assertIsHardlink("test9b/in/d1/hardlink1", "test9b/in/d1/hardlink2-renamed");
1736c95142eSMartin Matuska 	/* At creation. (assuming hardlink2 is the hardlink entry) */
1746c95142eSMartin Matuska 	assertMakeDir("test9c", 0755);
1756c95142eSMartin Matuska 	systemf("%s -cf test9c.tar -s /hardlink1/hardlink1-renamed/ in/d1",
1766c95142eSMartin Matuska 	    testprog);
1776c95142eSMartin Matuska 	systemf("%s -xf test9c.tar -C test9c", testprog);
1786c95142eSMartin Matuska 	assertIsHardlink("test9c/in/d1/hardlink1-renamed", "test9c/in/d1/hardlink2");
1796c95142eSMartin Matuska 	/* At creation. (assuming hardlink1 is the hardlink entry) */
1806c95142eSMartin Matuska 	assertMakeDir("test9d", 0755);
1816c95142eSMartin Matuska 	systemf("%s -cf test9d.tar -s /hardlink2/hardlink2-renamed/ in/d1",
1826c95142eSMartin Matuska 	    testprog);
1836c95142eSMartin Matuska 	systemf("%s -xf test9d.tar -C test9d", testprog);
1846c95142eSMartin Matuska 	assertIsHardlink("test9d/in/d1/hardlink1", "test9d/in/d1/hardlink2-renamed");
1856c95142eSMartin Matuska 
1866c95142eSMartin Matuska 	/*
1876c95142eSMartin Matuska 	 * Test 10: renaming symlink target without repointing symlink
1886c95142eSMartin Matuska 	 */
1896c95142eSMartin Matuska 	if (canSymlink()) {
1906c95142eSMartin Matuska 		/* At extraction. */
1916c95142eSMartin Matuska 		assertMakeDir("test10a", 0755);
1926c95142eSMartin Matuska 		systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/S -s /foo/realfile/ -C test10a",
1936c95142eSMartin Matuska 		    testprog, testprog);
1946c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test10a/in/d1/foo");
1956c95142eSMartin Matuska 		assertFileContents("foo", 3, "test10a/in/d1/realfile");
1966c95142eSMartin Matuska 		assertFileContents("foo", 3, "test10a/in/d1/symlink");
19752c2bb75SMartin Matuska 		assertIsSymlink("test10a/in/d1/symlink", "realfile", 0);
1986c95142eSMartin Matuska 		/* At creation. */
1996c95142eSMartin Matuska 		assertMakeDir("test10b", 0755);
2006c95142eSMartin Matuska 		systemf("%s -cf - -s /realfile/foo/S -s /foo/realfile/ in/d1 | %s -xf - -C test10b",
2016c95142eSMartin Matuska 		    testprog, testprog);
2026c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test10b/in/d1/foo");
2036c95142eSMartin Matuska 		assertFileContents("foo", 3, "test10b/in/d1/realfile");
2046c95142eSMartin Matuska 		assertFileContents("foo", 3, "test10b/in/d1/symlink");
20552c2bb75SMartin Matuska 		assertIsSymlink("test10b/in/d1/symlink", "realfile", 0);
2066c95142eSMartin Matuska 	}
2076c95142eSMartin Matuska 
2086c95142eSMartin Matuska 	/*
2096c95142eSMartin Matuska 	 * Test 11: repointing symlink without renaming file
2106c95142eSMartin Matuska 	 */
2116c95142eSMartin Matuska 	if (canSymlink()) {
2126c95142eSMartin Matuska 		/* At extraction. */
2136c95142eSMartin Matuska 		assertMakeDir("test11a", 0755);
2146c95142eSMartin Matuska 		systemf("%s -cf - in/d1 | %s -xf - -s /realfile/foo/sR -C test11a",
2156c95142eSMartin Matuska 		    testprog, testprog);
2166c95142eSMartin Matuska 		assertFileContents("foo", 3, "test11a/in/d1/foo");
2176c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test11a/in/d1/realfile");
2186c95142eSMartin Matuska 		assertFileContents("foo", 3, "test11a/in/d1/symlink");
21952c2bb75SMartin Matuska 		assertIsSymlink("test11a/in/d1/symlink", "foo", 0);
2206c95142eSMartin Matuska 		/* At creation. */
2216c95142eSMartin Matuska 		assertMakeDir("test11b", 0755);
2226c95142eSMartin Matuska 		systemf("%s -cf - -s /realfile/foo/R in/d1 | %s -xf - -C test11b",
2236c95142eSMartin Matuska 		    testprog, testprog);
2246c95142eSMartin Matuska 		assertFileContents("foo", 3, "test11b/in/d1/foo");
2256c95142eSMartin Matuska 		assertFileContents("realfile", 8, "test11b/in/d1/realfile");
2266c95142eSMartin Matuska 		assertFileContents("foo", 3, "test11b/in/d1/symlink");
22752c2bb75SMartin Matuska 		assertIsSymlink("test11b/in/d1/symlink", "foo", 0);
2286c95142eSMartin Matuska 	}
2296c95142eSMartin Matuska 
2306c95142eSMartin Matuska 	/*
2316c95142eSMartin Matuska 	 * Test 12: renaming hardlink target without changing hardlink.
2326c95142eSMartin Matuska 	 * (Requires a pre-built archive, since we otherwise can't know
2336c95142eSMartin Matuska 	 * which element will be stored as the hardlink.)
2346c95142eSMartin Matuska 	 */
2356c95142eSMartin Matuska 	extract_reference_file("test_option_s.tar.Z");
2366c95142eSMartin Matuska 	assertMakeDir("test12a", 0755);
2376c95142eSMartin Matuska 	systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/H -s /foo/hardlink1/ %s -C test12a",
2386c95142eSMartin Matuska 	    testprog, canSymlink()?"":"--exclude in/d1/symlink");
2396c95142eSMartin Matuska 	assertFileContents("foo", 3, "test12a/in/d1/hardlink1");
2406c95142eSMartin Matuska 	assertFileContents("hardlinkedfile", 14, "test12a/in/d1/foo");
2416c95142eSMartin Matuska 	assertFileContents("foo", 3, "test12a/in/d1/hardlink2");
2426c95142eSMartin Matuska 	assertIsHardlink("test12a/in/d1/hardlink1", "test12a/in/d1/hardlink2");
2436c95142eSMartin Matuska 	/* TODO: Expand this test to verify creation as well.
2446c95142eSMartin Matuska 	 * Since either hardlink1 or hardlink2 might get stored as a hardlink,
2456c95142eSMartin Matuska 	 * this will either requiring testing both cases and accepting either
2466c95142eSMartin Matuska 	 * pass, or some very creative renames that can be tested regardless.
2476c95142eSMartin Matuska 	 */
2486c95142eSMartin Matuska 
2496c95142eSMartin Matuska 	/*
2506c95142eSMartin Matuska 	 * Test 13: repoint hardlink without changing files
2516c95142eSMartin Matuska 	 * (Requires a pre-built archive, since we otherwise can't know
2526c95142eSMartin Matuska 	 * which element will be stored as the hardlink.)
2536c95142eSMartin Matuska 	 */
2546c95142eSMartin Matuska 	extract_reference_file("test_option_s.tar.Z");
2556c95142eSMartin Matuska 	assertMakeDir("test13a", 0755);
2566c95142eSMartin Matuska 	systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/Rh -s /foo/hardlink1/Rh %s -C test13a",
2576c95142eSMartin Matuska 	    testprog, canSymlink()?"":"--exclude in/d1/symlink");
2586c95142eSMartin Matuska 	assertFileContents("foo", 3, "test13a/in/d1/foo");
2596c95142eSMartin Matuska 	assertFileContents("hardlinkedfile", 14, "test13a/in/d1/hardlink1");
2606c95142eSMartin Matuska 	assertFileContents("foo", 3, "test13a/in/d1/hardlink2");
2616c95142eSMartin Matuska 	assertIsHardlink("test13a/in/d1/foo", "test13a/in/d1/hardlink2");
2626c95142eSMartin Matuska 	/* TODO: See above; expand this test to verify renames at creation. */
263cdf63a70SMartin Matuska 
264cdf63a70SMartin Matuska 	/*
265cdf63a70SMartin Matuska 	 * Test 14: Global substitutions when extracting archive.
266cdf63a70SMartin Matuska 	 */
267cdf63a70SMartin Matuska     /* Global substitution. */
268cdf63a70SMartin Matuska 	assertMakeDir("test14", 0755);
269cdf63a70SMartin Matuska 	systemf("%s -cf test14.tar in/d1/foo in/d1/bar",
270cdf63a70SMartin Matuska 	    testprog);
271cdf63a70SMartin Matuska 	systemf("%s -xf test14.tar -s /o/z/g -s /bar/baz/ -C test14",
272cdf63a70SMartin Matuska 	    testprog);
273cdf63a70SMartin Matuska 	assertFileContents("foo", 3, "test14/in/d1/fzz");
274cdf63a70SMartin Matuska 	assertFileContents("bar", 3, "test14/in/d1/baz");
275cdf63a70SMartin Matuska     /* Singular substitution. */
276cdf63a70SMartin Matuska 	systemf("%s -cf test14.tar in/d1/foo in/d1/bar",
277cdf63a70SMartin Matuska 	    testprog);
278cdf63a70SMartin Matuska 	systemf("%s -xf test14.tar -s /o/z/ -s /bar/baz/ -C test14",
279cdf63a70SMartin Matuska 	    testprog);
280cdf63a70SMartin Matuska 	assertFileContents("foo", 3, "test14/in/d1/fzo");
281cdf63a70SMartin Matuska 	assertFileContents("bar", 3, "test14/in/d1/baz");
282caf54c4fSMartin Matuska }
283