109ade360Sjoerg /*-
209ade360Sjoerg  * Copyright (c) 2003-2007 Tim Kientzle
309ade360Sjoerg  * All rights reserved.
409ade360Sjoerg  *
509ade360Sjoerg  * Redistribution and use in source and binary forms, with or without
609ade360Sjoerg  * modification, are permitted provided that the following conditions
709ade360Sjoerg  * are met:
809ade360Sjoerg  * 1. Redistributions of source code must retain the above copyright
909ade360Sjoerg  *    notice, this list of conditions and the following disclaimer.
1009ade360Sjoerg  * 2. Redistributions in binary form must reproduce the above copyright
1109ade360Sjoerg  *    notice, this list of conditions and the following disclaimer in the
1209ade360Sjoerg  *    documentation and/or other materials provided with the distribution.
1309ade360Sjoerg  *
1409ade360Sjoerg  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
1509ade360Sjoerg  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1609ade360Sjoerg  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1709ade360Sjoerg  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
1809ade360Sjoerg  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1909ade360Sjoerg  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2009ade360Sjoerg  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2109ade360Sjoerg  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2209ade360Sjoerg  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2309ade360Sjoerg  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2409ade360Sjoerg  */
2509ade360Sjoerg #include "test.h"
269fde5391Sjoerg __FBSDID("$FreeBSD: src/usr.bin/tar/test/test_copy.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
279fde5391Sjoerg 
289fde5391Sjoerg #if defined(__CYGWIN__)
299fde5391Sjoerg # include <limits.h>
309fde5391Sjoerg # include <sys/cygwin.h>
319fde5391Sjoerg #endif
32d05f0226Sjoerg #if defined(_WIN32) && !defined(__CYGWIN__)
33d05f0226Sjoerg # include <direct.h>
34d05f0226Sjoerg #endif
359fde5391Sjoerg 
369fde5391Sjoerg /*
379fde5391Sjoerg  * Try to figure out how deep we can go in our tests.  Assumes that
389fde5391Sjoerg  * the first call to this function has the longest starting cwd (which
399fde5391Sjoerg  * is currently "<testdir>/original").  This is mostly to work around
409fde5391Sjoerg  * limits in our Win32 support.
419fde5391Sjoerg  *
429fde5391Sjoerg  * Background: On Posix systems, PATH_MAX is merely a limit on the
439fde5391Sjoerg  * length of the string passed into a system call.  By repeatedly
449fde5391Sjoerg  * calling chdir(), you can work with arbitrarily long paths on such
459fde5391Sjoerg  * systems.  In contrast, Win32 APIs apply PATH_MAX limits to the full
469fde5391Sjoerg  * absolute path, so the permissible length of a system call argument
479fde5391Sjoerg  * varies with the cwd. Some APIs actually enforce limits
489fde5391Sjoerg  * significantly less than PATH_MAX to ensure that you can create
499fde5391Sjoerg  * files within the current working directory.  The Win32 limits also
509fde5391Sjoerg  * apply to Cygwin before 1.7.
519fde5391Sjoerg  *
529fde5391Sjoerg  * Someday, I want to convert the Win32 support to use newer
539fde5391Sjoerg  * wide-character paths with '\\?\' prefix, which has a 32k PATH_MAX
549fde5391Sjoerg  * instead of the rather anemic 260 character limit of the older
559fde5391Sjoerg  * system calls.  Then we can drop this mess (unless we want to
569fde5391Sjoerg  * continue to special-case Cygwin 1.5 and earlier).
579fde5391Sjoerg  */
589fde5391Sjoerg static int
compute_loop_max(void)599fde5391Sjoerg compute_loop_max(void)
609fde5391Sjoerg {
619fde5391Sjoerg #if defined(_WIN32) && !defined(__CYGWIN__)
629fde5391Sjoerg 	static int LOOP_MAX = 0;
639fde5391Sjoerg 	char buf[MAX_PATH];
649fde5391Sjoerg 	size_t cwdlen;
659fde5391Sjoerg 
669fde5391Sjoerg 	if (LOOP_MAX == 0) {
679fde5391Sjoerg 		assert(_getcwd(buf, MAX_PATH) != NULL);
689fde5391Sjoerg 		cwdlen = strlen(buf);
699fde5391Sjoerg 		/* 12 characters = length of 8.3 filename */
709fde5391Sjoerg 		/* 4 characters = length of "/../" used in symlink tests */
719fde5391Sjoerg 		/* 1 character = length of extra "/" separator */
729fde5391Sjoerg 		LOOP_MAX = MAX_PATH - (int)cwdlen - 12 - 4 - 1;
739fde5391Sjoerg 	}
749fde5391Sjoerg 	return LOOP_MAX;
759fde5391Sjoerg #elif defined(__CYGWIN__) && !defined(HAVE_CYGWIN_CONV_PATH)
769fde5391Sjoerg 	static int LOOP_MAX = 0;
779fde5391Sjoerg 	if (LOOP_MAX == 0) {
789fde5391Sjoerg 		char wbuf[PATH_MAX];
799fde5391Sjoerg 		char pbuf[PATH_MAX];
809fde5391Sjoerg 		size_t wcwdlen;
819fde5391Sjoerg 		size_t pcwdlen;
829fde5391Sjoerg 	        size_t cwdlen;
839fde5391Sjoerg 		assert(getcwd(pbuf, PATH_MAX) != NULL);
849fde5391Sjoerg 		pcwdlen = strlen(pbuf);
859fde5391Sjoerg 		cygwin_conv_to_full_win32_path(pbuf, wbuf);
869fde5391Sjoerg 		wcwdlen = strlen(wbuf);
879fde5391Sjoerg 		cwdlen = ((wcwdlen > pcwdlen) ? wcwdlen : pcwdlen);
889fde5391Sjoerg 		/* Cygwin helper needs an extra few characters. */
899fde5391Sjoerg 		LOOP_MAX = PATH_MAX - (int)cwdlen - 12 - 4 - 4;
909fde5391Sjoerg 	}
919fde5391Sjoerg 	return LOOP_MAX;
929fde5391Sjoerg #else
939fde5391Sjoerg 	/* cygwin-1.7 ends up here, along with "normal" unix */
949fde5391Sjoerg 	return 200; /* restore pre-r278 depth */
959fde5391Sjoerg #endif
969fde5391Sjoerg }
979fde5391Sjoerg 
989fde5391Sjoerg /* filenames[i] is a distinctive filename of length i. */
999fde5391Sjoerg /* To simplify interpreting failures, each filename ends with a
1009fde5391Sjoerg  * decimal integer which is the length of the filename.  E.g., A
1019fde5391Sjoerg  * filename ending in "_92" is 92 characters long.  To detect errors
1029fde5391Sjoerg  * which drop or misplace characters, the filenames use a repeating
1039fde5391Sjoerg  * "abcdefghijklmnopqrstuvwxyz..." pattern. */
1049fde5391Sjoerg static char *filenames[201];
1059fde5391Sjoerg 
1069fde5391Sjoerg static void
compute_filenames(void)1079fde5391Sjoerg compute_filenames(void)
1089fde5391Sjoerg {
1099fde5391Sjoerg 	char buff[250];
1109fde5391Sjoerg 	size_t i,j;
1119fde5391Sjoerg 
1129fde5391Sjoerg 	filenames[0] = strdup("");
1139fde5391Sjoerg 	filenames[1] = strdup("1");
1149fde5391Sjoerg 	filenames[2] = strdup("a2");
1159fde5391Sjoerg 	for (i = 3; i < sizeof(filenames)/sizeof(filenames[0]); ++i) {
1169fde5391Sjoerg 		/* Fill with "abcdefghij..." */
1179fde5391Sjoerg 		for (j = 0; j < i; ++j)
1189fde5391Sjoerg 			buff[j] = 'a' + (j % 26);
1199fde5391Sjoerg 		buff[j--] = '\0';
1209fde5391Sjoerg 		/* Work from the end to fill in the number portion. */
1219fde5391Sjoerg 		buff[j--] = '0' + (i % 10);
1229fde5391Sjoerg 		if (i > 9) {
1239fde5391Sjoerg 			buff[j--] = '0' + ((i / 10) % 10);
1249fde5391Sjoerg 			if (i > 99)
125d05f0226Sjoerg 				buff[j--] = '0' + (char)(i / 100);
1269fde5391Sjoerg 		}
1279fde5391Sjoerg 		buff[j] = '_';
1289fde5391Sjoerg 		/* Guard against obvious screwups in the above code. */
1299fde5391Sjoerg 		assertEqualInt(strlen(buff), i);
1309fde5391Sjoerg 		filenames[i] = strdup(buff);
1319fde5391Sjoerg 	}
1329fde5391Sjoerg }
13309ade360Sjoerg 
13409ade360Sjoerg static void
create_tree(void)13509ade360Sjoerg create_tree(void)
13609ade360Sjoerg {
13709ade360Sjoerg 	char buff[260];
13809ade360Sjoerg 	char buff2[260];
13909ade360Sjoerg 	int i;
1409fde5391Sjoerg 	int LOOP_MAX;
14109ade360Sjoerg 
1429fde5391Sjoerg 	compute_filenames();
14309ade360Sjoerg 
1449fde5391Sjoerg 	/* Log that we'll be omitting some checks. */
1459fde5391Sjoerg 	if (!canSymlink()) {
1469fde5391Sjoerg 		skipping("Symlink checks");
1479fde5391Sjoerg 	}
1489fde5391Sjoerg 
1499fde5391Sjoerg 	assertMakeDir("original", 0775);
1509fde5391Sjoerg 	assertEqualInt(0, chdir("original"));
1519fde5391Sjoerg 	LOOP_MAX = compute_loop_max();
1529fde5391Sjoerg 
1539fde5391Sjoerg 	assertMakeDir("f", 0775);
1549fde5391Sjoerg 	assertMakeDir("l", 0775);
1559fde5391Sjoerg 	assertMakeDir("m", 0775);
1569fde5391Sjoerg 	assertMakeDir("s", 0775);
1579fde5391Sjoerg 	assertMakeDir("d", 0775);
1589fde5391Sjoerg 
1599fde5391Sjoerg 	for (i = 1; i < LOOP_MAX; i++) {
1609fde5391Sjoerg 		failure("Internal sanity check failed: i = %d", i);
1619fde5391Sjoerg 		assert(filenames[i] != NULL);
1629fde5391Sjoerg 
1639fde5391Sjoerg 		sprintf(buff, "f/%s", filenames[i]);
1649fde5391Sjoerg 		assertMakeFile(buff, 0777, buff);
16509ade360Sjoerg 
16609ade360Sjoerg 		/* Create a link named "l/abcdef..." to the above. */
1679fde5391Sjoerg 		sprintf(buff2, "l/%s", filenames[i]);
1689fde5391Sjoerg 		assertMakeHardlink(buff2, buff);
16909ade360Sjoerg 
17009ade360Sjoerg 		/* Create a link named "m/abcdef..." to the above. */
1719fde5391Sjoerg 		sprintf(buff2, "m/%s", filenames[i]);
1729fde5391Sjoerg 		assertMakeHardlink(buff2, buff);
17309ade360Sjoerg 
1749fde5391Sjoerg 		if (canSymlink()) {
17509ade360Sjoerg 			/* Create a symlink named "s/abcdef..." to the above. */
1769fde5391Sjoerg 			sprintf(buff, "s/%s", filenames[i]);
1779fde5391Sjoerg 			sprintf(buff2, "../f/%s", filenames[i]);
1789fde5391Sjoerg 			failure("buff=\"%s\" buff2=\"%s\"", buff, buff2);
179efdd4e46Sjoerg 			assertMakeSymlink(buff, buff2, 0);
1809fde5391Sjoerg 		}
18109ade360Sjoerg 		/* Create a dir named "d/abcdef...". */
18209ade360Sjoerg 		buff[0] = 'd';
1839fde5391Sjoerg 		failure("buff=\"%s\"", buff);
1849fde5391Sjoerg 		assertMakeDir(buff, 0775);
18509ade360Sjoerg 	}
18609ade360Sjoerg 
1879fde5391Sjoerg 	assertEqualInt(0, chdir(".."));
18809ade360Sjoerg }
18909ade360Sjoerg 
1909fde5391Sjoerg #define LIMIT_NONE 200
1919fde5391Sjoerg #define LIMIT_USTAR 100
19209ade360Sjoerg 
19309ade360Sjoerg static void
verify_tree(size_t limit)1949fde5391Sjoerg verify_tree(size_t limit)
19509ade360Sjoerg {
19609ade360Sjoerg 	char name1[260];
19709ade360Sjoerg 	char name2[260];
1989fde5391Sjoerg 	size_t i, LOOP_MAX;
1999fde5391Sjoerg 
2009fde5391Sjoerg 	LOOP_MAX = compute_loop_max();
20109ade360Sjoerg 
20209ade360Sjoerg 	/* Generate the names we know should be there and verify them. */
2039fde5391Sjoerg 	for (i = 1; i < LOOP_MAX; i++) {
20409ade360Sjoerg 		/* Verify a file named "f/abcdef..." */
2059fde5391Sjoerg 		sprintf(name1, "f/%s", filenames[i]);
2069fde5391Sjoerg 		if (i <= limit) {
2079fde5391Sjoerg 			assertFileExists(name1);
208d05f0226Sjoerg 			assertFileContents(name1, (int)strlen(name1), name1);
20909ade360Sjoerg 		}
21009ade360Sjoerg 
2119fde5391Sjoerg 		sprintf(name2, "l/%s", filenames[i]);
2129fde5391Sjoerg 		if (i + 2 <= limit) {
21309ade360Sjoerg 			/* Verify hardlink "l/abcdef..." */
2149fde5391Sjoerg 			assertIsHardlink(name1, name2);
2159fde5391Sjoerg 			/* Verify hardlink "m/abcdef..." */
21609ade360Sjoerg 			name2[0] = 'm';
2179fde5391Sjoerg 			assertIsHardlink(name1, name2);
21809ade360Sjoerg 		}
21909ade360Sjoerg 
2209fde5391Sjoerg 		if (canSymlink()) {
22109ade360Sjoerg 			/* Verify symlink "s/abcdef..." */
2229fde5391Sjoerg 			sprintf(name1, "s/%s", filenames[i]);
2239fde5391Sjoerg 			sprintf(name2, "../f/%s", filenames[i]);
2249fde5391Sjoerg 			if (strlen(name2) <= limit)
225efdd4e46Sjoerg 				assertIsSymlink(name1, name2, 0);
22609ade360Sjoerg 		}
22709ade360Sjoerg 
22809ade360Sjoerg 		/* Verify dir "d/abcdef...". */
2299fde5391Sjoerg 		sprintf(name1, "d/%s", filenames[i]);
2309fde5391Sjoerg 		if (i + 1 <= limit) { /* +1 for trailing slash */
2319fde5391Sjoerg 			if (assertIsDir(name1, -1)) {
23209ade360Sjoerg 				/* TODO: opendir/readdir this
23309ade360Sjoerg 				 * directory and make sure
23409ade360Sjoerg 				 * it's empty.
23509ade360Sjoerg 				 */
23609ade360Sjoerg 			}
23709ade360Sjoerg 		}
23809ade360Sjoerg 	}
23909ade360Sjoerg 
2409fde5391Sjoerg #if !defined(_WIN32) || defined(__CYGWIN__)
2419fde5391Sjoerg 	{
2429fde5391Sjoerg 		const char *dp;
24309ade360Sjoerg 		/* Now make sure nothing is there that shouldn't be. */
24409ade360Sjoerg 		for (dp = "dflms"; *dp != '\0'; ++dp) {
2459fde5391Sjoerg 			DIR *d;
2469fde5391Sjoerg 			struct dirent *de;
24709ade360Sjoerg 			char dir[2];
24809ade360Sjoerg 			dir[0] = *dp; dir[1] = '\0';
24909ade360Sjoerg 			d = opendir(dir);
2509fde5391Sjoerg 			failure("Unable to open dir '%s'", dir);
2519fde5391Sjoerg 			if (!assert(d != NULL))
2529fde5391Sjoerg 				continue;
25309ade360Sjoerg 			while ((de = readdir(d)) != NULL) {
2549fde5391Sjoerg 				char *p = de->d_name;
2559fde5391Sjoerg 				if (p[0] == '.')
2569fde5391Sjoerg 					continue;
25709ade360Sjoerg 				switch(dp[0]) {
2589fde5391Sjoerg 				case 'l': case 'm': case 'd':
259*1a7b189bSchristos 					failure("strlen(p)=%zu", strlen(p));
2609fde5391Sjoerg 					assert(strlen(p) < limit);
2619fde5391Sjoerg 					assertEqualString(p,
2629fde5391Sjoerg 					    filenames[strlen(p)]);
26309ade360Sjoerg 					break;
2649fde5391Sjoerg 				case 'f': case 's':
265*1a7b189bSchristos 					failure("strlen(p)=%zu", strlen(p));
2669fde5391Sjoerg 					assert(strlen(p) < limit + 1);
2679fde5391Sjoerg 					assertEqualString(p,
2689fde5391Sjoerg 					    filenames[strlen(p)]);
26909ade360Sjoerg 					break;
27009ade360Sjoerg 				default:
27109ade360Sjoerg 					failure("File %s shouldn't be here", p);
27209ade360Sjoerg 					assert(0);
27309ade360Sjoerg 				}
27409ade360Sjoerg 			}
27509ade360Sjoerg 			closedir(d);
27609ade360Sjoerg 		}
27709ade360Sjoerg 	}
2789fde5391Sjoerg #endif
2799fde5391Sjoerg }
28009ade360Sjoerg 
28109ade360Sjoerg static void
copy_basic(void)28209ade360Sjoerg copy_basic(void)
28309ade360Sjoerg {
28409ade360Sjoerg 	int r;
28509ade360Sjoerg 
2869fde5391Sjoerg 	/* NOTE: for proper operation on cygwin-1.5 and windows, the
2879fde5391Sjoerg 	 * length of the name of the directory below, "plain", must be
288d05f0226Sjoerg 	 * less than or equal to the length of the name of the original
2899fde5391Sjoerg 	 * directory, "original"  This restriction derives from the
2909fde5391Sjoerg 	 * extremely limited pathname lengths on those platforms.
2919fde5391Sjoerg 	 */
2929fde5391Sjoerg 	assertMakeDir("plain", 0775);
29309ade360Sjoerg 	assertEqualInt(0, chdir("plain"));
29409ade360Sjoerg 
29509ade360Sjoerg 	/*
29609ade360Sjoerg 	 * Use the tar program to create an archive.
29709ade360Sjoerg 	 */
29809ade360Sjoerg 	r = systemf("%s cf archive -C ../original f d l m s >pack.out 2>pack.err",
29909ade360Sjoerg 	    testprog);
30009ade360Sjoerg 	failure("Error invoking \"%s cf\"", testprog);
30109ade360Sjoerg 	assertEqualInt(r, 0);
30209ade360Sjoerg 
30309ade360Sjoerg 	/* Verify that nothing went to stdout or stderr. */
30409ade360Sjoerg 	assertEmptyFile("pack.err");
30509ade360Sjoerg 	assertEmptyFile("pack.out");
30609ade360Sjoerg 
30709ade360Sjoerg 	/*
30809ade360Sjoerg 	 * Use tar to unpack the archive into another directory.
30909ade360Sjoerg 	 */
31009ade360Sjoerg 	r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
31109ade360Sjoerg 	failure("Error invoking %s xf archive", testprog);
31209ade360Sjoerg 	assertEqualInt(r, 0);
31309ade360Sjoerg 
31409ade360Sjoerg 	/* Verify that nothing went to stdout or stderr. */
31509ade360Sjoerg 	assertEmptyFile("unpack.err");
31609ade360Sjoerg 	assertEmptyFile("unpack.out");
31709ade360Sjoerg 
31809ade360Sjoerg 	verify_tree(LIMIT_NONE);
3190c8b3e90Schristos 
3200c8b3e90Schristos 	/*
3210c8b3e90Schristos 	 * Unpack a second time to make sure that things are still ok
3220c8b3e90Schristos 	 */
3230c8b3e90Schristos 	r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
3240c8b3e90Schristos 	failure("Error invoking %s xf archive", testprog);
3250c8b3e90Schristos 	assertEqualInt(r, 0);
3260c8b3e90Schristos 
3270c8b3e90Schristos 	/* Verify that nothing went to stdout or stderr. */
3280c8b3e90Schristos 	assertEmptyFile("unpack.err");
3290c8b3e90Schristos 	assertEmptyFile("unpack.out");
3300c8b3e90Schristos 
3310c8b3e90Schristos 	verify_tree(LIMIT_NONE);
33209ade360Sjoerg 	assertEqualInt(0, chdir(".."));
33309ade360Sjoerg }
33409ade360Sjoerg 
33509ade360Sjoerg static void
copy_ustar(void)33609ade360Sjoerg copy_ustar(void)
33709ade360Sjoerg {
33809ade360Sjoerg 	const char *target = "ustar";
33909ade360Sjoerg 	int r;
34009ade360Sjoerg 
3419fde5391Sjoerg 	/* NOTE: for proper operation on cygwin-1.5 and windows, the
3429fde5391Sjoerg 	 * length of the name of the directory below, "ustar", must be
343d05f0226Sjoerg 	 * less than or equal to the length of the name of the original
3449fde5391Sjoerg 	 * directory, "original"  This restriction derives from the
3459fde5391Sjoerg 	 * extremely limited pathname lengths on those platforms.
3469fde5391Sjoerg 	 */
3479fde5391Sjoerg 	assertMakeDir(target, 0775);
34809ade360Sjoerg 	assertEqualInt(0, chdir(target));
34909ade360Sjoerg 
35009ade360Sjoerg 	/*
35109ade360Sjoerg 	 * Use the tar program to create an archive.
35209ade360Sjoerg 	 */
35309ade360Sjoerg 	r = systemf("%s cf archive --format=ustar -C ../original f d l m s >pack.out 2>pack.err",
35409ade360Sjoerg 	    testprog);
35509ade360Sjoerg 	failure("Error invoking \"%s cf archive --format=ustar\"", testprog);
35609ade360Sjoerg 	assertEqualInt(r, 0);
35709ade360Sjoerg 
35809ade360Sjoerg 	/* Verify that nothing went to stdout. */
35909ade360Sjoerg 	assertEmptyFile("pack.out");
36009ade360Sjoerg 	/* Stderr is non-empty, since there are a bunch of files
36109ade360Sjoerg 	 * with filenames too long to archive. */
36209ade360Sjoerg 
36309ade360Sjoerg 	/*
36409ade360Sjoerg 	 * Use tar to unpack the archive into another directory.
36509ade360Sjoerg 	 */
36609ade360Sjoerg 	r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
36709ade360Sjoerg 	failure("Error invoking %s xf archive", testprog);
36809ade360Sjoerg 	assertEqualInt(r, 0);
36909ade360Sjoerg 
37009ade360Sjoerg 	/* Verify that nothing went to stdout or stderr. */
37109ade360Sjoerg 	assertEmptyFile("unpack.err");
37209ade360Sjoerg 	assertEmptyFile("unpack.out");
37309ade360Sjoerg 
37409ade360Sjoerg 	verify_tree(LIMIT_USTAR);
3759fde5391Sjoerg 	assertEqualInt(0, chdir("../.."));
37609ade360Sjoerg }
37709ade360Sjoerg 
DEFINE_TEST(test_copy)37809ade360Sjoerg DEFINE_TEST(test_copy)
37909ade360Sjoerg {
3809fde5391Sjoerg 	assertUmask(0);
38109ade360Sjoerg 	create_tree(); /* Create sample files in "original" dir. */
38209ade360Sjoerg 
38309ade360Sjoerg 	/* Test simple "tar -c | tar -x" pipeline copy. */
38409ade360Sjoerg 	copy_basic();
38509ade360Sjoerg 
38609ade360Sjoerg 	/* Same, but constrain to ustar format. */
38709ade360Sjoerg 	copy_ustar();
38809ade360Sjoerg }
389