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