xref: /freebsd/contrib/libarchive/cpio/test/test_basic.c (revision bd66c1b43e33540205dbc1187c2f2a15c58b57ba)
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 static void
verify_files(const char * msg)10caf54c4fSMartin Matuska verify_files(const char *msg)
11caf54c4fSMartin Matuska {
12caf54c4fSMartin Matuska 	/*
13caf54c4fSMartin Matuska 	 * Verify unpacked files.
14caf54c4fSMartin Matuska 	 */
15caf54c4fSMartin Matuska 
16caf54c4fSMartin Matuska 	/* Regular file with 2 links. */
17f9762417SMartin Matuska 	failure("%s", msg);
18caf54c4fSMartin Matuska 	assertIsReg("file", 0644);
19f9762417SMartin Matuska 	failure("%s", msg);
20caf54c4fSMartin Matuska 	assertFileSize("file", 10);
21f9762417SMartin Matuska 	failure("%s", msg);
22caf54c4fSMartin Matuska 	assertFileNLinks("file", 2);
23caf54c4fSMartin Matuska 
24caf54c4fSMartin Matuska 	/* Another name for the same file. */
25f9762417SMartin Matuska 	failure("%s", msg);
26caf54c4fSMartin Matuska 	assertIsHardlink("linkfile", "file");
27caf54c4fSMartin Matuska 
28caf54c4fSMartin Matuska 	/* Symlink */
29caf54c4fSMartin Matuska 	if (canSymlink())
3052c2bb75SMartin Matuska 		assertIsSymlink("symlink", "file", 0);
31caf54c4fSMartin Matuska 
32caf54c4fSMartin Matuska 	/* Another file with 1 link and different permissions. */
33f9762417SMartin Matuska 	failure("%s", msg);
34caf54c4fSMartin Matuska 	assertIsReg("file2", 0777);
35f9762417SMartin Matuska 	failure("%s", msg);
36caf54c4fSMartin Matuska 	assertFileSize("file2", 10);
37f9762417SMartin Matuska 	failure("%s", msg);
38caf54c4fSMartin Matuska 	assertFileNLinks("file2", 1);
39caf54c4fSMartin Matuska 
40caf54c4fSMartin Matuska 	/* dir */
41caf54c4fSMartin Matuska 	assertIsDir("dir", 0775);
42caf54c4fSMartin Matuska }
43caf54c4fSMartin Matuska 
44caf54c4fSMartin Matuska static void
basic_cpio(const char * target,const char * pack_options,const char * unpack_options,const char * se,const char * se2)45caf54c4fSMartin Matuska basic_cpio(const char *target,
46caf54c4fSMartin Matuska     const char *pack_options,
47caf54c4fSMartin Matuska     const char *unpack_options,
486c95142eSMartin Matuska     const char *se, const char *se2)
49caf54c4fSMartin Matuska {
50caf54c4fSMartin Matuska 	int r;
51caf54c4fSMartin Matuska 
52caf54c4fSMartin Matuska 	if (!assertMakeDir(target, 0775))
53caf54c4fSMartin Matuska 	    return;
54caf54c4fSMartin Matuska 
55caf54c4fSMartin Matuska 	/* Use the cpio program to create an archive. */
56cdf63a70SMartin Matuska 	r = systemf("%s -R 1000:1000 -o %s < filelist >%s/archive 2>%s/pack.err",
57caf54c4fSMartin Matuska 	    testprog, pack_options, target, target);
58caf54c4fSMartin Matuska 	failure("Error invoking %s -o %s", testprog, pack_options);
59caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
60caf54c4fSMartin Matuska 
61caf54c4fSMartin Matuska 	assertChdir(target);
62caf54c4fSMartin Matuska 
63caf54c4fSMartin Matuska 	/* Verify stderr. */
64caf54c4fSMartin Matuska 	failure("Expected: %s, options=%s", se, pack_options);
65caf54c4fSMartin Matuska 	assertTextFileContents(se, "pack.err");
66caf54c4fSMartin Matuska 
67caf54c4fSMartin Matuska 	/*
68caf54c4fSMartin Matuska 	 * Use cpio to unpack the archive into another directory.
69caf54c4fSMartin Matuska 	 */
70caf54c4fSMartin Matuska 	r = systemf("%s -i %s< archive >unpack.out 2>unpack.err",
71caf54c4fSMartin Matuska 	    testprog, unpack_options);
72caf54c4fSMartin Matuska 	failure("Error invoking %s -i %s", testprog, unpack_options);
73caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
74caf54c4fSMartin Matuska 
75caf54c4fSMartin Matuska 	/* Verify stderr. */
76caf54c4fSMartin Matuska 	failure("Error invoking %s -i %s in dir %s", testprog, unpack_options, target);
776c95142eSMartin Matuska 	assertTextFileContents(se2, "unpack.err");
78caf54c4fSMartin Matuska 
79caf54c4fSMartin Matuska 	verify_files(pack_options);
80caf54c4fSMartin Matuska 
81caf54c4fSMartin Matuska 	assertChdir("..");
82caf54c4fSMartin Matuska }
83caf54c4fSMartin Matuska 
84caf54c4fSMartin Matuska static void
passthrough(const char * target)85caf54c4fSMartin Matuska passthrough(const char *target)
86caf54c4fSMartin Matuska {
87caf54c4fSMartin Matuska 	int r;
88caf54c4fSMartin Matuska 
89caf54c4fSMartin Matuska 	if (!assertMakeDir(target, 0775))
90caf54c4fSMartin Matuska 		return;
91caf54c4fSMartin Matuska 
92caf54c4fSMartin Matuska 	/*
93caf54c4fSMartin Matuska 	 * Use cpio passthrough mode to copy files to another directory.
94caf54c4fSMartin Matuska 	 */
95caf54c4fSMartin Matuska 	r = systemf("%s -p %s <filelist >%s/stdout 2>%s/stderr",
96caf54c4fSMartin Matuska 	    testprog, target, target, target);
97caf54c4fSMartin Matuska 	failure("Error invoking %s -p", testprog);
98caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
99caf54c4fSMartin Matuska 
100caf54c4fSMartin Matuska 	assertChdir(target);
101caf54c4fSMartin Matuska 
102caf54c4fSMartin Matuska 	/* Verify stderr. */
103caf54c4fSMartin Matuska 	failure("Error invoking %s -p in dir %s",
104caf54c4fSMartin Matuska 	    testprog, target);
105caf54c4fSMartin Matuska 	assertTextFileContents("1 block\n", "stderr");
106caf54c4fSMartin Matuska 
107caf54c4fSMartin Matuska 	verify_files("passthrough");
108caf54c4fSMartin Matuska 	assertChdir("..");
109caf54c4fSMartin Matuska }
110caf54c4fSMartin Matuska 
DEFINE_TEST(test_basic)111caf54c4fSMartin Matuska DEFINE_TEST(test_basic)
112caf54c4fSMartin Matuska {
113caf54c4fSMartin Matuska 	FILE *filelist;
114caf54c4fSMartin Matuska 	const char *msg;
1156c95142eSMartin Matuska 	char result[1024];
116caf54c4fSMartin Matuska 
117caf54c4fSMartin Matuska 	assertUmask(0);
118caf54c4fSMartin Matuska 
119caf54c4fSMartin Matuska 	/*
120caf54c4fSMartin Matuska 	 * Create an assortment of files on disk.
121caf54c4fSMartin Matuska 	 */
122caf54c4fSMartin Matuska 	filelist = fopen("filelist", "w");
1236c95142eSMartin Matuska 	memset(result, 0, sizeof(result));
124caf54c4fSMartin Matuska 
125caf54c4fSMartin Matuska 	/* File with 10 bytes content. */
126caf54c4fSMartin Matuska 	assertMakeFile("file", 0644, "1234567890");
127caf54c4fSMartin Matuska 	fprintf(filelist, "file\n");
128a7bc2822SMartin Matuska 	if (is_LargeInode("file")) {
1296c95142eSMartin Matuska 		strncat(result,
130a7bc2822SMartin Matuska 		    "bsdcpio: file: large inode number truncated: ",
131acc60b03SMartin Matuska 		    sizeof(result) - strlen(result) -1);
132a7bc2822SMartin Matuska 		strncat(result,
133a7bc2822SMartin Matuska 		    strerror(ERANGE),
134a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
135a7bc2822SMartin Matuska 		strncat(result,
136a7bc2822SMartin Matuska 		    "\n",
137a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
138a7bc2822SMartin Matuska 	}
139caf54c4fSMartin Matuska 
140caf54c4fSMartin Matuska 	/* hardlink to above file. */
141caf54c4fSMartin Matuska 	assertMakeHardlink("linkfile", "file");
142caf54c4fSMartin Matuska 	fprintf(filelist, "linkfile\n");
143a7bc2822SMartin Matuska 	if (is_LargeInode("linkfile")) {
1446c95142eSMartin Matuska 		strncat(result,
145a7bc2822SMartin Matuska 		    "bsdcpio: linkfile: large inode number truncated: ",
146acc60b03SMartin Matuska 		    sizeof(result) - strlen(result) -1);
147a7bc2822SMartin Matuska 		strncat(result,
148a7bc2822SMartin Matuska 		    strerror(ERANGE),
149a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
150a7bc2822SMartin Matuska 		strncat(result,
151a7bc2822SMartin Matuska 		    "\n",
152a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
153a7bc2822SMartin Matuska 	}
154caf54c4fSMartin Matuska 
155caf54c4fSMartin Matuska 	/* Symlink to above file. */
156caf54c4fSMartin Matuska 	if (canSymlink()) {
15752c2bb75SMartin Matuska 		assertMakeSymlink("symlink", "file", 0);
158caf54c4fSMartin Matuska 		fprintf(filelist, "symlink\n");
159a7bc2822SMartin Matuska 		if (is_LargeInode("symlink")) {
1606c95142eSMartin Matuska 			strncat(result,
161a7bc2822SMartin Matuska 			    "bsdcpio: symlink: large inode number truncated: ",
162acc60b03SMartin Matuska 			    sizeof(result) - strlen(result) -1);
163a7bc2822SMartin Matuska 			strncat(result,
164a7bc2822SMartin Matuska 			    strerror(ERANGE),
165a7bc2822SMartin Matuska 			    sizeof(result) - strlen(result) -1);
166a7bc2822SMartin Matuska 			strncat(result,
167a7bc2822SMartin Matuska 			    "\n",
168a7bc2822SMartin Matuska 			    sizeof(result) - strlen(result) -1);
169a7bc2822SMartin Matuska 		}
170caf54c4fSMartin Matuska 	}
171caf54c4fSMartin Matuska 
172caf54c4fSMartin Matuska 	/* Another file with different permissions. */
173caf54c4fSMartin Matuska 	assertMakeFile("file2", 0777, "1234567890");
174caf54c4fSMartin Matuska 	fprintf(filelist, "file2\n");
175a7bc2822SMartin Matuska 	if (is_LargeInode("file2")) {
1766c95142eSMartin Matuska 		strncat(result,
177a7bc2822SMartin Matuska 		    "bsdcpio: file2: large inode number truncated: ",
178acc60b03SMartin Matuska 		    sizeof(result) - strlen(result) -1);
179a7bc2822SMartin Matuska 		strncat(result,
180a7bc2822SMartin Matuska 		    strerror(ERANGE),
181a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
182a7bc2822SMartin Matuska 		strncat(result,
183a7bc2822SMartin Matuska 		    "\n",
184a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
185a7bc2822SMartin Matuska 	}
186caf54c4fSMartin Matuska 
187caf54c4fSMartin Matuska 	/* Directory. */
188caf54c4fSMartin Matuska 	assertMakeDir("dir", 0775);
189caf54c4fSMartin Matuska 	fprintf(filelist, "dir\n");
190a7bc2822SMartin Matuska 	if (is_LargeInode("dir")) {
1916c95142eSMartin Matuska 		strncat(result,
192a7bc2822SMartin Matuska 		    "bsdcpio: dir: large inode number truncated: ",
193acc60b03SMartin Matuska 		    sizeof(result) - strlen(result) -1);
194a7bc2822SMartin Matuska 		strncat(result,
195a7bc2822SMartin Matuska 		    strerror(ERANGE),
196a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
197a7bc2822SMartin Matuska 		strncat(result,
198a7bc2822SMartin Matuska 		    "\n",
199a7bc2822SMartin Matuska 		    sizeof(result) - strlen(result) -1);
200a7bc2822SMartin Matuska 	}
201acc60b03SMartin Matuska 	strncat(result, "2 blocks\n", sizeof(result) - strlen(result) -1);
2026c95142eSMartin Matuska 
203caf54c4fSMartin Matuska 	/* All done. */
204caf54c4fSMartin Matuska 	fclose(filelist);
205caf54c4fSMartin Matuska 
206caf54c4fSMartin Matuska 	assertUmask(022);
207caf54c4fSMartin Matuska 
208caf54c4fSMartin Matuska 	/* Archive/dearchive with a variety of options. */
209caf54c4fSMartin Matuska 	msg = canSymlink() ? "2 blocks\n" : "1 block\n";
2106c95142eSMartin Matuska 	basic_cpio("copy", "", "", msg, msg);
2116c95142eSMartin Matuska 	basic_cpio("copy_odc", "--format=odc", "", msg, msg);
2126c95142eSMartin Matuska 	basic_cpio("copy_newc", "-H newc", "", result, "2 blocks\n");
2136c95142eSMartin Matuska 	basic_cpio("copy_cpio", "-H odc", "", msg, msg);
214ddce862aSMartin Matuska 	msg = "1 block\n";
215ddce862aSMartin Matuska 	basic_cpio("copy_bin", "-H bin", "", msg, msg);
216caf54c4fSMartin Matuska 	msg = canSymlink() ? "9 blocks\n" : "8 blocks\n";
2176c95142eSMartin Matuska 	basic_cpio("copy_ustar", "-H ustar", "", msg, msg);
218caf54c4fSMartin Matuska 
219caf54c4fSMartin Matuska 	/* Copy in one step using -p */
220caf54c4fSMartin Matuska 	passthrough("passthrough");
221caf54c4fSMartin Matuska }
222