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