1caf54c4fSMartin Matuska /*-
2*bd66c1b4SMartin Matuska * SPDX-License-Identifier: BSD-2-Clause
3*bd66c1b4SMartin Matuska *
4caf54c4fSMartin Matuska * Copyright (c) 2003-2007 Tim Kientzle
5caf54c4fSMartin Matuska * All rights reserved.
6caf54c4fSMartin Matuska */
7caf54c4fSMartin Matuska #include "test.h"
8caf54c4fSMartin Matuska
9caf54c4fSMartin Matuska #if defined(__CYGWIN__)
10caf54c4fSMartin Matuska # include <limits.h>
11caf54c4fSMartin Matuska # include <sys/cygwin.h>
12caf54c4fSMartin Matuska #endif
13acc60b03SMartin Matuska #if defined(_WIN32) && !defined(__CYGWIN__)
14acc60b03SMartin Matuska # include <direct.h>
15acc60b03SMartin Matuska #endif
16caf54c4fSMartin Matuska
17caf54c4fSMartin Matuska /*
18caf54c4fSMartin Matuska * Try to figure out how deep we can go in our tests. Assumes that
19caf54c4fSMartin Matuska * the first call to this function has the longest starting cwd (which
20caf54c4fSMartin Matuska * is currently "<testdir>/original"). This is mostly to work around
21caf54c4fSMartin Matuska * limits in our Win32 support.
22caf54c4fSMartin Matuska *
23caf54c4fSMartin Matuska * Background: On Posix systems, PATH_MAX is merely a limit on the
24caf54c4fSMartin Matuska * length of the string passed into a system call. By repeatedly
25caf54c4fSMartin Matuska * calling chdir(), you can work with arbitrarily long paths on such
26caf54c4fSMartin Matuska * systems. In contrast, Win32 APIs apply PATH_MAX limits to the full
27caf54c4fSMartin Matuska * absolute path, so the permissible length of a system call argument
28caf54c4fSMartin Matuska * varies with the cwd. Some APIs actually enforce limits
29caf54c4fSMartin Matuska * significantly less than PATH_MAX to ensure that you can create
30caf54c4fSMartin Matuska * files within the current working directory. The Win32 limits also
31caf54c4fSMartin Matuska * apply to Cygwin before 1.7.
32caf54c4fSMartin Matuska *
33caf54c4fSMartin Matuska * Someday, I want to convert the Win32 support to use newer
34caf54c4fSMartin Matuska * wide-character paths with '\\?\' prefix, which has a 32k PATH_MAX
35caf54c4fSMartin Matuska * instead of the rather anemic 260 character limit of the older
36caf54c4fSMartin Matuska * system calls. Then we can drop this mess (unless we want to
37caf54c4fSMartin Matuska * continue to special-case Cygwin 1.5 and earlier).
38caf54c4fSMartin Matuska */
39caf54c4fSMartin Matuska static int
compute_loop_max(void)40caf54c4fSMartin Matuska compute_loop_max(void)
41caf54c4fSMartin Matuska {
42caf54c4fSMartin Matuska #if defined(_WIN32) && !defined(__CYGWIN__)
43caf54c4fSMartin Matuska static int LOOP_MAX = 0;
44caf54c4fSMartin Matuska char buf[MAX_PATH];
45caf54c4fSMartin Matuska size_t cwdlen;
46caf54c4fSMartin Matuska
47caf54c4fSMartin Matuska if (LOOP_MAX == 0) {
48caf54c4fSMartin Matuska assert(_getcwd(buf, MAX_PATH) != NULL);
49caf54c4fSMartin Matuska cwdlen = strlen(buf);
50caf54c4fSMartin Matuska /* 12 characters = length of 8.3 filename */
51caf54c4fSMartin Matuska /* 4 characters = length of "/../" used in symlink tests */
52caf54c4fSMartin Matuska /* 1 character = length of extra "/" separator */
53caf54c4fSMartin Matuska LOOP_MAX = MAX_PATH - (int)cwdlen - 12 - 4 - 1;
54caf54c4fSMartin Matuska }
55caf54c4fSMartin Matuska return LOOP_MAX;
56caf54c4fSMartin Matuska #elif defined(__CYGWIN__) && !defined(HAVE_CYGWIN_CONV_PATH)
57caf54c4fSMartin Matuska static int LOOP_MAX = 0;
58caf54c4fSMartin Matuska if (LOOP_MAX == 0) {
59caf54c4fSMartin Matuska char wbuf[PATH_MAX];
60caf54c4fSMartin Matuska char pbuf[PATH_MAX];
61caf54c4fSMartin Matuska size_t wcwdlen;
62caf54c4fSMartin Matuska size_t pcwdlen;
63caf54c4fSMartin Matuska size_t cwdlen;
64caf54c4fSMartin Matuska assert(getcwd(pbuf, PATH_MAX) != NULL);
65caf54c4fSMartin Matuska pcwdlen = strlen(pbuf);
66caf54c4fSMartin Matuska cygwin_conv_to_full_win32_path(pbuf, wbuf);
67caf54c4fSMartin Matuska wcwdlen = strlen(wbuf);
68caf54c4fSMartin Matuska cwdlen = ((wcwdlen > pcwdlen) ? wcwdlen : pcwdlen);
69caf54c4fSMartin Matuska /* Cygwin helper needs an extra few characters. */
70caf54c4fSMartin Matuska LOOP_MAX = PATH_MAX - (int)cwdlen - 12 - 4 - 4;
71caf54c4fSMartin Matuska }
72caf54c4fSMartin Matuska return LOOP_MAX;
73caf54c4fSMartin Matuska #else
74caf54c4fSMartin Matuska /* cygwin-1.7 ends up here, along with "normal" unix */
75caf54c4fSMartin Matuska return 200; /* restore pre-r278 depth */
76caf54c4fSMartin Matuska #endif
77caf54c4fSMartin Matuska }
78caf54c4fSMartin Matuska
79caf54c4fSMartin Matuska /* filenames[i] is a distinctive filename of length i. */
80caf54c4fSMartin Matuska /* To simplify interpreting failures, each filename ends with a
81caf54c4fSMartin Matuska * decimal integer which is the length of the filename. E.g., A
82caf54c4fSMartin Matuska * filename ending in "_92" is 92 characters long. To detect errors
83caf54c4fSMartin Matuska * which drop or misplace characters, the filenames use a repeating
84caf54c4fSMartin Matuska * "abcdefghijklmnopqrstuvwxyz..." pattern. */
85caf54c4fSMartin Matuska static char *filenames[201];
86caf54c4fSMartin Matuska
87caf54c4fSMartin Matuska static void
compute_filenames(void)88caf54c4fSMartin Matuska compute_filenames(void)
89caf54c4fSMartin Matuska {
90caf54c4fSMartin Matuska char buff[250];
91caf54c4fSMartin Matuska size_t i,j;
92caf54c4fSMartin Matuska
93caf54c4fSMartin Matuska filenames[0] = strdup("");
94caf54c4fSMartin Matuska filenames[1] = strdup("1");
95caf54c4fSMartin Matuska filenames[2] = strdup("a2");
96caf54c4fSMartin Matuska for (i = 3; i < sizeof(filenames)/sizeof(filenames[0]); ++i) {
97caf54c4fSMartin Matuska /* Fill with "abcdefghij..." */
98caf54c4fSMartin Matuska for (j = 0; j < i; ++j)
99caf54c4fSMartin Matuska buff[j] = 'a' + (j % 26);
100caf54c4fSMartin Matuska buff[j--] = '\0';
101caf54c4fSMartin Matuska /* Work from the end to fill in the number portion. */
102caf54c4fSMartin Matuska buff[j--] = '0' + (i % 10);
103caf54c4fSMartin Matuska if (i > 9) {
104caf54c4fSMartin Matuska buff[j--] = '0' + ((i / 10) % 10);
105caf54c4fSMartin Matuska if (i > 99)
106acc60b03SMartin Matuska buff[j--] = '0' + (char)(i / 100);
107caf54c4fSMartin Matuska }
108caf54c4fSMartin Matuska buff[j] = '_';
109caf54c4fSMartin Matuska /* Guard against obvious screwups in the above code. */
110caf54c4fSMartin Matuska assertEqualInt(strlen(buff), i);
111caf54c4fSMartin Matuska filenames[i] = strdup(buff);
112caf54c4fSMartin Matuska }
113caf54c4fSMartin Matuska }
114caf54c4fSMartin Matuska
115caf54c4fSMartin Matuska static void
create_tree(void)116caf54c4fSMartin Matuska create_tree(void)
117caf54c4fSMartin Matuska {
118caf54c4fSMartin Matuska char buff[260];
119caf54c4fSMartin Matuska char buff2[260];
120caf54c4fSMartin Matuska int i;
121caf54c4fSMartin Matuska int LOOP_MAX;
122caf54c4fSMartin Matuska
123caf54c4fSMartin Matuska compute_filenames();
124caf54c4fSMartin Matuska
125caf54c4fSMartin Matuska /* Log that we'll be omitting some checks. */
126caf54c4fSMartin Matuska if (!canSymlink()) {
127caf54c4fSMartin Matuska skipping("Symlink checks");
128caf54c4fSMartin Matuska }
129caf54c4fSMartin Matuska
130caf54c4fSMartin Matuska assertMakeDir("original", 0775);
131caf54c4fSMartin Matuska assertEqualInt(0, chdir("original"));
132caf54c4fSMartin Matuska LOOP_MAX = compute_loop_max();
133caf54c4fSMartin Matuska
134caf54c4fSMartin Matuska assertMakeDir("f", 0775);
135caf54c4fSMartin Matuska assertMakeDir("l", 0775);
136caf54c4fSMartin Matuska assertMakeDir("m", 0775);
137caf54c4fSMartin Matuska assertMakeDir("s", 0775);
138caf54c4fSMartin Matuska assertMakeDir("d", 0775);
139caf54c4fSMartin Matuska
140caf54c4fSMartin Matuska for (i = 1; i < LOOP_MAX; i++) {
141caf54c4fSMartin Matuska failure("Internal sanity check failed: i = %d", i);
142caf54c4fSMartin Matuska assert(filenames[i] != NULL);
143caf54c4fSMartin Matuska
144bd5e624aSMartin Matuska snprintf(buff, sizeof(buff), "f/%s", filenames[i]);
145caf54c4fSMartin Matuska assertMakeFile(buff, 0777, buff);
146caf54c4fSMartin Matuska
147caf54c4fSMartin Matuska /* Create a link named "l/abcdef..." to the above. */
148bd5e624aSMartin Matuska snprintf(buff2, sizeof(buff2), "l/%s", filenames[i]);
149caf54c4fSMartin Matuska assertMakeHardlink(buff2, buff);
150caf54c4fSMartin Matuska
151caf54c4fSMartin Matuska /* Create a link named "m/abcdef..." to the above. */
152bd5e624aSMartin Matuska snprintf(buff2, sizeof(buff2), "m/%s", filenames[i]);
153caf54c4fSMartin Matuska assertMakeHardlink(buff2, buff);
154caf54c4fSMartin Matuska
155caf54c4fSMartin Matuska if (canSymlink()) {
156caf54c4fSMartin Matuska /* Create a symlink named "s/abcdef..." to the above. */
157bd5e624aSMartin Matuska snprintf(buff, sizeof(buff), "s/%s", filenames[i]);
158bd5e624aSMartin Matuska snprintf(buff2, sizeof(buff2), "../f/%s", filenames[i]);
159caf54c4fSMartin Matuska failure("buff=\"%s\" buff2=\"%s\"", buff, buff2);
16052c2bb75SMartin Matuska assertMakeSymlink(buff, buff2, 0);
161caf54c4fSMartin Matuska }
162caf54c4fSMartin Matuska /* Create a dir named "d/abcdef...". */
163caf54c4fSMartin Matuska buff[0] = 'd';
164caf54c4fSMartin Matuska failure("buff=\"%s\"", buff);
165caf54c4fSMartin Matuska assertMakeDir(buff, 0775);
166caf54c4fSMartin Matuska }
167caf54c4fSMartin Matuska
168caf54c4fSMartin Matuska assertEqualInt(0, chdir(".."));
169caf54c4fSMartin Matuska }
170caf54c4fSMartin Matuska
171caf54c4fSMartin Matuska #define LIMIT_NONE 200
172caf54c4fSMartin Matuska #define LIMIT_USTAR 100
173caf54c4fSMartin Matuska
174caf54c4fSMartin Matuska static void
verify_tree(size_t limit,const char * format)175*bd66c1b4SMartin Matuska verify_tree(size_t limit, const char *format)
176caf54c4fSMartin Matuska {
177caf54c4fSMartin Matuska char name1[260];
178caf54c4fSMartin Matuska char name2[260];
179caf54c4fSMartin Matuska size_t i, LOOP_MAX;
180caf54c4fSMartin Matuska
181caf54c4fSMartin Matuska LOOP_MAX = compute_loop_max();
182caf54c4fSMartin Matuska
183caf54c4fSMartin Matuska /* Generate the names we know should be there and verify them. */
184caf54c4fSMartin Matuska for (i = 1; i < LOOP_MAX; i++) {
185caf54c4fSMartin Matuska /* Verify a file named "f/abcdef..." */
186bd5e624aSMartin Matuska snprintf(name1, sizeof(name1), "f/%s", filenames[i]);
187caf54c4fSMartin Matuska if (i <= limit) {
188*bd66c1b4SMartin Matuska failure("Verifying %s", format);
189caf54c4fSMartin Matuska assertFileExists(name1);
190acc60b03SMartin Matuska assertFileContents(name1, (int)strlen(name1), name1);
191caf54c4fSMartin Matuska }
192caf54c4fSMartin Matuska
193bd5e624aSMartin Matuska snprintf(name2, sizeof(name2), "l/%s", filenames[i]);
194caf54c4fSMartin Matuska if (i + 2 <= limit) {
195caf54c4fSMartin Matuska /* Verify hardlink "l/abcdef..." */
196*bd66c1b4SMartin Matuska failure("Verifying %s", format);
197caf54c4fSMartin Matuska assertIsHardlink(name1, name2);
198caf54c4fSMartin Matuska /* Verify hardlink "m/abcdef..." */
199caf54c4fSMartin Matuska name2[0] = 'm';
200caf54c4fSMartin Matuska assertIsHardlink(name1, name2);
201caf54c4fSMartin Matuska }
202caf54c4fSMartin Matuska
203caf54c4fSMartin Matuska if (canSymlink()) {
204caf54c4fSMartin Matuska /* Verify symlink "s/abcdef..." */
205bd5e624aSMartin Matuska snprintf(name1, sizeof(name1), "s/%s", filenames[i]);
206bd5e624aSMartin Matuska snprintf(name2, sizeof(name2), "../f/%s", filenames[i]);
207*bd66c1b4SMartin Matuska if (strlen(name2) <= limit) {
208*bd66c1b4SMartin Matuska failure("Verifying %s", format);
20952c2bb75SMartin Matuska assertIsSymlink(name1, name2, 0);
210caf54c4fSMartin Matuska }
211*bd66c1b4SMartin Matuska }
212caf54c4fSMartin Matuska
213caf54c4fSMartin Matuska /* Verify dir "d/abcdef...". */
214bd5e624aSMartin Matuska snprintf(name1, sizeof(name1), "d/%s", filenames[i]);
215caf54c4fSMartin Matuska if (i + 1 <= limit) { /* +1 for trailing slash */
216*bd66c1b4SMartin Matuska failure("Verifying %s", format);
217caf54c4fSMartin Matuska if (assertIsDir(name1, -1)) {
218caf54c4fSMartin Matuska /* TODO: opendir/readdir this
219caf54c4fSMartin Matuska * directory and make sure
220caf54c4fSMartin Matuska * it's empty.
221caf54c4fSMartin Matuska */
222caf54c4fSMartin Matuska }
223caf54c4fSMartin Matuska }
224caf54c4fSMartin Matuska }
225caf54c4fSMartin Matuska
226caf54c4fSMartin Matuska #if !defined(_WIN32) || defined(__CYGWIN__)
227caf54c4fSMartin Matuska {
228caf54c4fSMartin Matuska const char *dp;
229caf54c4fSMartin Matuska /* Now make sure nothing is there that shouldn't be. */
230caf54c4fSMartin Matuska for (dp = "dflms"; *dp != '\0'; ++dp) {
231caf54c4fSMartin Matuska DIR *d;
232caf54c4fSMartin Matuska struct dirent *de;
233caf54c4fSMartin Matuska char dir[2];
234caf54c4fSMartin Matuska dir[0] = *dp; dir[1] = '\0';
235caf54c4fSMartin Matuska d = opendir(dir);
236*bd66c1b4SMartin Matuska failure("Unable to open dir '%s' for testing %s", dir, format);
237caf54c4fSMartin Matuska if (!assert(d != NULL))
238caf54c4fSMartin Matuska continue;
239caf54c4fSMartin Matuska while ((de = readdir(d)) != NULL) {
240caf54c4fSMartin Matuska char *p = de->d_name;
241caf54c4fSMartin Matuska if (p[0] == '.')
242caf54c4fSMartin Matuska continue;
243caf54c4fSMartin Matuska switch(dp[0]) {
244caf54c4fSMartin Matuska case 'l': case 'm': case 'd':
245f9762417SMartin Matuska failure("strlen(p)=%zu", strlen(p));
246caf54c4fSMartin Matuska assert(strlen(p) < limit);
247caf54c4fSMartin Matuska assertEqualString(p,
248caf54c4fSMartin Matuska filenames[strlen(p)]);
249caf54c4fSMartin Matuska break;
250caf54c4fSMartin Matuska case 'f': case 's':
251f9762417SMartin Matuska failure("strlen(p)=%zu", strlen(p));
252caf54c4fSMartin Matuska assert(strlen(p) < limit + 1);
253caf54c4fSMartin Matuska assertEqualString(p,
254caf54c4fSMartin Matuska filenames[strlen(p)]);
255caf54c4fSMartin Matuska break;
256caf54c4fSMartin Matuska default:
257caf54c4fSMartin Matuska failure("File %s shouldn't be here", p);
258caf54c4fSMartin Matuska assert(0);
259caf54c4fSMartin Matuska }
260caf54c4fSMartin Matuska }
261caf54c4fSMartin Matuska closedir(d);
262caf54c4fSMartin Matuska }
263caf54c4fSMartin Matuska }
264caf54c4fSMartin Matuska #endif
265caf54c4fSMartin Matuska }
266caf54c4fSMartin Matuska
267caf54c4fSMartin Matuska static void
copy_basic(const char * extra_args,const char * name)268*bd66c1b4SMartin Matuska copy_basic(const char *extra_args, const char *name)
269caf54c4fSMartin Matuska {
270caf54c4fSMartin Matuska int r;
271caf54c4fSMartin Matuska
272caf54c4fSMartin Matuska /* NOTE: for proper operation on cygwin-1.5 and windows, the
273*bd66c1b4SMartin Matuska * length of the name of the directory below must be
274007dbc1fSMartin Matuska * less than or equal to the length of the name of the original
275caf54c4fSMartin Matuska * directory, "original" This restriction derives from the
276caf54c4fSMartin Matuska * extremely limited pathname lengths on those platforms.
277caf54c4fSMartin Matuska */
278*bd66c1b4SMartin Matuska assertMakeDir(name, 0775);
279*bd66c1b4SMartin Matuska assertEqualInt(0, chdir(name));
280caf54c4fSMartin Matuska
281caf54c4fSMartin Matuska /*
282caf54c4fSMartin Matuska * Use the tar program to create an archive.
283caf54c4fSMartin Matuska */
284*bd66c1b4SMartin Matuska r = systemf("%s cf archive %s -C ../original f d l m s >pack.out 2>pack.err",
285*bd66c1b4SMartin Matuska testprog, extra_args);
286*bd66c1b4SMartin Matuska failure("Error invoking \"%s cf archive %s\"", testprog, extra_args);
287caf54c4fSMartin Matuska assertEqualInt(r, 0);
288caf54c4fSMartin Matuska
289caf54c4fSMartin Matuska /* Verify that nothing went to stdout or stderr. */
290caf54c4fSMartin Matuska assertEmptyFile("pack.err");
291caf54c4fSMartin Matuska assertEmptyFile("pack.out");
292caf54c4fSMartin Matuska
293caf54c4fSMartin Matuska /*
294caf54c4fSMartin Matuska * Use tar to unpack the archive into another directory.
295caf54c4fSMartin Matuska */
296caf54c4fSMartin Matuska r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
297caf54c4fSMartin Matuska failure("Error invoking %s xf archive", testprog);
298caf54c4fSMartin Matuska assertEqualInt(r, 0);
299caf54c4fSMartin Matuska
300caf54c4fSMartin Matuska /* Verify that nothing went to stdout or stderr. */
301caf54c4fSMartin Matuska assertEmptyFile("unpack.err");
302caf54c4fSMartin Matuska assertEmptyFile("unpack.out");
303caf54c4fSMartin Matuska
304*bd66c1b4SMartin Matuska verify_tree(LIMIT_NONE, name);
305caf54c4fSMartin Matuska assertEqualInt(0, chdir(".."));
306caf54c4fSMartin Matuska }
307caf54c4fSMartin Matuska
308caf54c4fSMartin Matuska static void
copy_ustar(void)309caf54c4fSMartin Matuska copy_ustar(void)
310caf54c4fSMartin Matuska {
311caf54c4fSMartin Matuska const char *target = "ustar";
312caf54c4fSMartin Matuska int r;
313caf54c4fSMartin Matuska
314caf54c4fSMartin Matuska /* NOTE: for proper operation on cygwin-1.5 and windows, the
315caf54c4fSMartin Matuska * length of the name of the directory below, "ustar", must be
316007dbc1fSMartin Matuska * less than or equal to the length of the name of the original
317caf54c4fSMartin Matuska * directory, "original" This restriction derives from the
318caf54c4fSMartin Matuska * extremely limited pathname lengths on those platforms.
319caf54c4fSMartin Matuska */
320caf54c4fSMartin Matuska assertMakeDir(target, 0775);
321caf54c4fSMartin Matuska assertEqualInt(0, chdir(target));
322caf54c4fSMartin Matuska
323caf54c4fSMartin Matuska /*
324caf54c4fSMartin Matuska * Use the tar program to create an archive.
325caf54c4fSMartin Matuska */
326caf54c4fSMartin Matuska r = systemf("%s cf archive --format=ustar -C ../original f d l m s >pack.out 2>pack.err",
327caf54c4fSMartin Matuska testprog);
328caf54c4fSMartin Matuska failure("Error invoking \"%s cf archive --format=ustar\"", testprog);
329caf54c4fSMartin Matuska assertEqualInt(r, 0);
330caf54c4fSMartin Matuska
331caf54c4fSMartin Matuska /* Verify that nothing went to stdout. */
332caf54c4fSMartin Matuska assertEmptyFile("pack.out");
333caf54c4fSMartin Matuska /* Stderr is non-empty, since there are a bunch of files
334caf54c4fSMartin Matuska * with filenames too long to archive. */
335caf54c4fSMartin Matuska
336caf54c4fSMartin Matuska /*
337caf54c4fSMartin Matuska * Use tar to unpack the archive into another directory.
338caf54c4fSMartin Matuska */
339caf54c4fSMartin Matuska r = systemf("%s xf archive >unpack.out 2>unpack.err", testprog);
340caf54c4fSMartin Matuska failure("Error invoking %s xf archive", testprog);
341caf54c4fSMartin Matuska assertEqualInt(r, 0);
342caf54c4fSMartin Matuska
343caf54c4fSMartin Matuska /* Verify that nothing went to stdout or stderr. */
344caf54c4fSMartin Matuska assertEmptyFile("unpack.err");
345caf54c4fSMartin Matuska assertEmptyFile("unpack.out");
346caf54c4fSMartin Matuska
347*bd66c1b4SMartin Matuska verify_tree(LIMIT_USTAR, "ustar");
348*bd66c1b4SMartin Matuska assertEqualInt(0, chdir(".."));
349caf54c4fSMartin Matuska }
350caf54c4fSMartin Matuska
DEFINE_TEST(test_copy)351caf54c4fSMartin Matuska DEFINE_TEST(test_copy)
352caf54c4fSMartin Matuska {
353caf54c4fSMartin Matuska assertUmask(0);
354caf54c4fSMartin Matuska create_tree(); /* Create sample files in "original" dir. */
355caf54c4fSMartin Matuska
356caf54c4fSMartin Matuska /* Test simple "tar -c | tar -x" pipeline copy. */
357*bd66c1b4SMartin Matuska copy_basic("", "default");
358caf54c4fSMartin Matuska
359caf54c4fSMartin Matuska /* Same, but constrain to ustar format. */
360caf54c4fSMartin Matuska copy_ustar();
361*bd66c1b4SMartin Matuska
362*bd66c1b4SMartin Matuska /* Same, but with pax format. */
363*bd66c1b4SMartin Matuska copy_basic(" --format pax", "pax");
364caf54c4fSMartin Matuska }
365