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_strip_components.c 232153 2012-02-25 10:58:02Z mm $");
27228753Smm
28228753SmmDEFINE_TEST(test_strip_components)
29228753Smm{
30228753Smm	assertMakeDir("d0", 0755);
31228753Smm	assertChdir("d0");
32228753Smm	assertMakeDir("d1", 0755);
33228753Smm	assertMakeDir("d1/d2", 0755);
34228753Smm	assertMakeDir("d1/d2/d3", 0755);
35232153Smm	assertMakeFile("d1/d2/f1", 0644, "");
36228753Smm	assertMakeHardlink("l1", "d1/d2/f1");
37228753Smm	assertMakeHardlink("d1/l2", "d1/d2/f1");
38228753Smm	if (canSymlink()) {
39228753Smm		assertMakeSymlink("s1", "d1/d2/f1");
40228753Smm		assertMakeSymlink("d1/s2", "d2/f1");
41228753Smm	}
42228753Smm	assertChdir("..");
43228753Smm
44232153Smm	/*
45232153Smm	 * Test 1: Strip components when extracting archives.
46232153Smm	 */
47232153Smm	if (canSymlink())
48232153Smm		assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/s1 d0/d1",
49232153Smm		    testprog));
50232153Smm	else
51232153Smm		assertEqualInt(0, systemf("%s -cf test.tar d0/l1 d0/d1",
52232153Smm		    testprog));
53228753Smm
54228753Smm	assertMakeDir("target", 0755);
55228753Smm	assertEqualInt(0, systemf("%s -x -C target --strip-components 2 "
56228753Smm	    "-f test.tar", testprog));
57228753Smm
58228753Smm	failure("d0/ is too short and should not get restored");
59228753Smm	assertFileNotExists("target/d0");
60228753Smm	failure("d0/d1/ is too short and should not get restored");
61228753Smm	assertFileNotExists("target/d1");
62232153Smm	failure("d0/s1 is too short and should not get restored");
63232153Smm	assertFileNotExists("target/s1");
64228753Smm	failure("d0/d1/s2 is a symlink to something that won't be extracted");
65228753Smm	/* If platform supports symlinks, target/s2 is a broken symlink. */
66228753Smm	/* If platform does not support symlink, target/s2 doesn't exist. */
67228753Smm	assertFileNotExists("target/s2");
68228753Smm	if (canSymlink())
69228753Smm		assertIsSymlink("target/s2", "d2/f1");
70228753Smm	failure("d0/d1/d2 should be extracted");
71228753Smm	assertIsDir("target/d2", -1);
72228753Smm
73228753Smm	/*
74232153Smm	 * Test 1b: Strip components extracting archives involving hardlinks.
75232153Smm	 *
76228753Smm	 * This next is a complicated case.  d0/l1, d0/d1/l2, and
77228753Smm	 * d0/d1/d2/f1 are all hardlinks to the same file; d0/l1 can't
78228753Smm	 * be extracted with --strip-components=2 and the other two
79228753Smm	 * can.  Remember that tar normally stores the first file with
80228753Smm	 * a body and the other as hardlink entries to the first
81228753Smm	 * appearance.  So the final result depends on the order in
82228753Smm	 * which these three names get archived.  If d0/l1 is first,
83228753Smm	 * none of the three can be restored.  If either of the longer
84228753Smm	 * names are first, then the two longer ones can both be
85232153Smm	 * restored.  Note that the "tar -cf" command above explicitly
86232153Smm	 * lists d0/l1 before d0/d1.
87228753Smm	 *
88232153Smm	 * It may be worth extending this test to exercise other
89232153Smm	 * archiving orders.
90228753Smm	 *
91228753Smm	 * Of course, this is all totally different for cpio and newc
92228753Smm	 * formats because the hardlink management is different.
93228753Smm	 * TODO: Rename this to test_strip_components_tar and create
94228753Smm	 * parallel tests for cpio and newc formats.
95228753Smm	 */
96228753Smm	failure("d0/l1 is too short and should not get restored");
97228753Smm	assertFileNotExists("target/l1");
98228753Smm	failure("d0/d1/l2 is a hardlink to file whose name was too short");
99228753Smm	assertFileNotExists("target/l2");
100228753Smm	failure("d0/d1/d2/f1 is a hardlink to file whose name was too short");
101228753Smm	assertFileNotExists("target/d2/f1");
102232153Smm
103232153Smm	/*
104232153Smm	 * Test 2: Strip components when creating archives.
105232153Smm	 */
106232153Smm	if (canSymlink())
107232153Smm		assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar "
108232153Smm					"d0/l1 d0/s1 d0/d1", testprog));
109232153Smm	else
110232153Smm		assertEqualInt(0, systemf("%s --strip-components 2 -cf test2.tar "
111232153Smm					"d0/l1 d0/d1", testprog));
112232153Smm
113232153Smm	assertMakeDir("target2", 0755);
114232153Smm	assertEqualInt(0, systemf("%s -x -C target2 -f test2.tar", testprog));
115232153Smm
116232153Smm	failure("d0/ is too short and should not have been archived");
117232153Smm	assertFileNotExists("target2/d0");
118232153Smm	failure("d0/d1/ is too short and should not have been archived");
119232153Smm	assertFileNotExists("target2/d1");
120232153Smm	failure("d0/s1 is too short and should not get restored");
121232153Smm	assertFileNotExists("target/s1");
122232153Smm	/* If platform supports symlinks, target/s2 is included. */
123232153Smm	if (canSymlink()) {
124232153Smm		failure("d0/d1/s2 is a symlink to something included in archive");
125232153Smm		assertIsSymlink("target2/s2", "d2/f1");
126232153Smm	}
127232153Smm	failure("d0/d1/d2 should be archived");
128232153Smm	assertIsDir("target2/d2", -1);
129232153Smm
130232153Smm	/*
131232153Smm	 * Test 2b: Strip components creating archives involving hardlinks.
132232153Smm	 */
133232153Smm	failure("d0/l1 is too short and should not have been archived");
134232153Smm	assertFileNotExists("target/l1");
135232153Smm	failure("d0/d1/l2 is a hardlink to file whose name was too short");
136232153Smm	assertFileNotExists("target/l2");
137232153Smm	failure("d0/d1/d2/f1 is a hardlink to file whose name was too short");
138232153Smm	assertFileNotExists("target/d2/f1");
139228753Smm}
140