xref: /netbsd-src/external/bsd/libarchive/dist/tar/test/test_windows.c (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009 Michihiro NAKAJIMA
5  * All rights reserved.
6  */
7 #include "test.h"
8 
9 #if defined(_WIN32) && !defined(__CYGWIN__)
10 #include <direct.h>
11 #include <windows.h>
12 
13 static void
14 mkfile(const char *name)
15 {
16 	FILE *f;
17 
18 	f = fopen(name, "wb");
19 	assert(f != NULL);
20 	assertEqualInt(5, fwrite("01234", 1, 5, f));
21 	fclose(f);
22 }
23 
24 static void
25 mkfullpath(char **path1, char **path2, const char *tpath, int type)
26 {
27 	char *fp1 = NULL, *fp2 = NULL, *p1 = NULL, *p2 = NULL;
28 	size_t l;
29 
30 	/*
31 	 * Get full path name of "tpath"
32 	 */
33 	l = GetFullPathNameA(tpath, 0, NULL, NULL);
34 	assert(0 != l);
35 	fp1 = malloc(l);
36 	assert(NULL != fp1);
37 	fp2 = malloc(l*2);
38 	assert(NULL != fp2);
39 	l = GetFullPathNameA(tpath, (DWORD)l, fp1, NULL);
40 	if ((type & 0x01) == 0) {
41 		for (p1 = fp1; *p1 != '\0'; p1++)
42 			if (*p1 == '\\')
43 				*p1 = '/';
44 	}
45 
46 	switch(type) {
47 	case 0: /* start with "/" */
48 	case 1: /* start with "\" */
49 		/* strip "c:" */
50 		memmove(fp1, fp1 + 2, l - 2);
51 		fp1[l -2] = '\0';
52 		p1 = fp1 + 1;
53 		break;
54 	case 2: /* start with "c:/" */
55 	case 3: /* start with "c:\" */
56 		p1 = fp1 + 3;
57 		break;
58 	case 4: /* start with "//./c:/" */
59 	case 5: /* start with "\\.\c:\" */
60 	case 6: /* start with "//?/c:/" */
61 	case 7: /* start with "\\?\c:\" */
62 		p1 = malloc(l + 4 + 1);
63 		assert(NULL != p1);
64 		if (type & 0x1)
65 			memcpy(p1, "\\\\.\\", 4);
66 		else
67 			memcpy(p1, "//./", 4);
68 		if (type == 6 || type == 7)
69 			p1[2] = '?';
70 		memcpy(p1 + 4, fp1, l);
71 		p1[l + 4] = '\0';
72 		free(fp1);
73 		fp1 = p1;
74 		p1 = fp1 + 7;
75 		break;
76 	}
77 
78 	/*
79 	 * Strip leading drive names and converting "\" to "\\"
80 	 */
81 	p2 = fp2;
82 	while (*p1 != '\0') {
83 		if (*p1 == '\\')
84 			*p2 = '/';
85 		else
86 			*p2 = *p1;
87 		++p1;
88 		++p2;
89 	}
90 	*p2++ = '\r';
91 	*p2++ = '\n';
92 	*p2 = '\0';
93 
94 	*path1 = fp1;
95 	*path2 = fp2;
96 }
97 
98 static const char *list1[] = {"aaa/", "aaa/file1", "aaa/xxa/", "aaa/xxb/",
99 	"aaa/zzc/", "aaa/zzc/file1", "aaa/xxb/file1", "aaa/xxa/file1",
100 	"aab/", "aac/", "abb/", "abc/", "abd/", NULL};
101 static const char *list2[] = {"bbb/", "bbb/file1", "bbb/xxa/", "bbb/xxb/",
102 	"bbb/zzc/", "bbb/zzc/file1", "bbb/xxb/file1", "bbb/xxa/file1", "bbc/",
103 	"bbd/", "bcc/", "bcd/", "bce/", NULL};
104 static const char *list3[] = {"aac/", "abc/", "bbc/", "bcc/", "ccc/", NULL};
105 static const char *list4[] = {"fff/abca", "fff/acca", NULL};
106 static const char *list5[] = {"aaa/file1", "aaa/xxa/", "aaa/xxa/file1",
107 	"aaa/xxb/", "aaa/xxb/file1", "aaa/zzc/", "aaa/zzc/file1", NULL};
108 static const char *list6[] = {"fff/abca", "fff/acca", "aaa/xxa/",
109 	"aaa/xxa/file1", "aaa/xxb/", "aaa/xxb/file1", NULL};
110 #endif /* _WIN32 && !__CYGWIN__ */
111 
112 DEFINE_TEST(test_windows)
113 {
114 #if defined(_WIN32) && !defined(__CYGWIN__)
115 	char *fp1, *fp2;
116 
117 	/*
118 	 * Prepare tests.
119 	 * Create directories and files.
120 	 */
121 	assertMakeDir("tmp", 0775);
122 	assertChdir("tmp");
123 
124 	assertMakeDir("aaa", 0775);
125 	assertMakeDir("aaa/xxa", 0775);
126 	assertMakeDir("aaa/xxb", 0775);
127 	assertMakeDir("aaa/zzc", 0775);
128 	mkfile("aaa/file1");
129 	mkfile("aaa/xxa/file1");
130 	mkfile("aaa/xxb/file1");
131 	mkfile("aaa/zzc/file1");
132 	assertMakeDir("aab", 0775);
133 	assertMakeDir("aac", 0775);
134 	assertMakeDir("abb", 0775);
135 	assertMakeDir("abc", 0775);
136 	assertMakeDir("abd", 0775);
137 	assertMakeDir("bbb", 0775);
138 	assertMakeDir("bbb/xxa", 0775);
139 	assertMakeDir("bbb/xxb", 0775);
140 	assertMakeDir("bbb/zzc", 0775);
141 	mkfile("bbb/file1");
142 	mkfile("bbb/xxa/file1");
143 	mkfile("bbb/xxb/file1");
144 	mkfile("bbb/zzc/file1");
145 	assertMakeDir("bbc", 0775);
146 	assertMakeDir("bbd", 0775);
147 	assertMakeDir("bcc", 0775);
148 	assertMakeDir("bcd", 0775);
149 	assertEqualInt(0, _mkdir("bce"));
150 	assertEqualInt(0, _mkdir("ccc"));
151 	assertEqualInt(0, _mkdir("fff"));
152 	mkfile("fff/aaaa");
153 	mkfile("fff/abba");
154 	mkfile("fff/abca");
155 	mkfile("fff/acba");
156 	mkfile("fff/acca");
157 
158 	/*
159 	 * Test1: Command line pattern matching.
160 	 */
161 	assertEqualInt(0,
162 	    systemf("%s -cf ../archive1.tar a*", testprog));
163 	assertEqualInt(0,
164 	    systemf("%s -tf ../archive1.tar > ../list1", testprog));
165 	assertFileContainsLinesAnyOrder("../list1", list1);
166 
167 	assertEqualInt(0,
168 	    systemf("%s -cf ../archive2.tar b*", testprog));
169 	assertEqualInt(0,
170 	    systemf("%s -tf ../archive2.tar > ../list2", testprog));
171 	assertFileContainsLinesAnyOrder("../list2", list2);
172 
173 	assertEqualInt(0,
174 	    systemf("%s -cf ../archive3.tar ??c", testprog));
175 	assertEqualInt(0,
176 	    systemf("%s -tf ../archive3.tar > ../list3", testprog));
177 	assertFileContainsLinesAnyOrder("../list3", list3);
178 
179 	assertEqualInt(0,
180 	    systemf("%s -cf ../archive3b.tar *c", testprog));
181 	assertEqualInt(0,
182 	    systemf("%s -tf ../archive3b.tar > ../list3b", testprog));
183 	assertFileContainsLinesAnyOrder("../list3b", list3);
184 
185 	assertEqualInt(0,
186 	    systemf("%s -cf ../archive4.tar fff/a?ca", testprog));
187 	assertEqualInt(0,
188 	    systemf("%s -tf ../archive4.tar > ../list4", testprog));
189 	assertFileContainsLinesAnyOrder("../list4", list4);
190 
191 	assertEqualInt(0,
192 	    systemf("%s -cf ../archive5.tar aaa\\*", testprog));
193 	assertEqualInt(0,
194 	    systemf("%s -tf ../archive5.tar > ../list5", testprog));
195 	assertFileContainsLinesAnyOrder("../list5", list5);
196 
197 	assertEqualInt(0,
198 	    systemf("%s -cf ../archive6.tar fff\\a?ca aaa\\xx*", testprog));
199 	assertEqualInt(0,
200 	    systemf("%s -tf ../archive6.tar > ../list6", testprog));
201 	assertFileContainsLinesAnyOrder("../list6", list6);
202 
203 	/*
204 	 * Test2: Archive the file start with drive letters.
205 	 */
206 	/* Test2a: start with "/" */
207 	mkfullpath(&fp1, &fp2, "aaa/file1", 0);
208 	assertEqualInt(0,
209 	    systemf("%s -cf ../archive10.tar %s > ../out10 2> ../err10",
210 	        testprog, fp1));
211 	assertEqualInt(0,
212 	    systemf("%s -tf ../archive10.tar > ../list10", testprog));
213 	/* Check drive letters have been stripped. */
214 	assertFileContents(fp2, (int)strlen(fp2), "../list10");
215 	free(fp1);
216 	free(fp2);
217 
218 	/* Test2b: start with "\" */
219 	mkfullpath(&fp1, &fp2, "aaa/file1", 1);
220 	assertEqualInt(0,
221 	    systemf("%s -cf ../archive11.tar %s > ../out11 2> ../err11",
222 	        testprog, fp1));
223 	assertEqualInt(0,
224 	    systemf("%s -tf ../archive11.tar > ../list11", testprog));
225 	/* Check drive letters have been stripped. */
226 	assertFileContents(fp2, (int)strlen(fp2), "../list11");
227 	free(fp1);
228 	free(fp2);
229 
230 	/* Test2c: start with "c:/" */
231 	mkfullpath(&fp1, &fp2, "aaa/file1", 2);
232 	assertEqualInt(0,
233 	    systemf("%s -cf ../archive12.tar %s > ../out12 2> ../err12",
234 	        testprog, fp1));
235 	assertEqualInt(0,
236 	    systemf("%s -tf ../archive12.tar > ../list12", testprog));
237 	/* Check drive letters have been stripped. */
238 	assertFileContents(fp2, (int)strlen(fp2), "../list12");
239 	free(fp1);
240 	free(fp2);
241 
242 	/* Test2d: start with "c:\" */
243 	mkfullpath(&fp1, &fp2, "aaa/file1", 3);
244 	assertEqualInt(0,
245 	    systemf("%s -cf ../archive13.tar %s > ../out13 2> ../err13",
246 	        testprog, fp1));
247 	assertEqualInt(0,
248 	    systemf("%s -tf ../archive13.tar > ../list13", testprog));
249 	/* Check drive letters have been stripped. */
250 	assertFileContents(fp2, (int)strlen(fp2), "../list13");
251 	free(fp1);
252 	free(fp2);
253 
254 	/* Test2e: start with "//./c:/" */
255 	mkfullpath(&fp1, &fp2, "aaa/file1", 4);
256 	assertEqualInt(0,
257 	    systemf("%s -cf ../archive14.tar %s > ../out14 2> ../err14",
258 	        testprog, fp1));
259 	assertEqualInt(0,
260 	    systemf("%s -tf ../archive14.tar > ../list14", testprog));
261 	/* Check drive letters have been stripped. */
262 	assertFileContents(fp2, (int)strlen(fp2), "../list14");
263 	free(fp1);
264 	free(fp2);
265 
266 	/* Test2f: start with "\\.\c:\" */
267 	mkfullpath(&fp1, &fp2, "aaa/file1", 5);
268 	assertEqualInt(0,
269 	    systemf("%s -cf ../archive15.tar %s > ../out15 2> ../err15",
270 	        testprog, fp1));
271 	assertEqualInt(0,
272 	    systemf("%s -tf ../archive15.tar > ../list15", testprog));
273 	/* Check drive letters have been stripped. */
274 	assertFileContents(fp2, (int)strlen(fp2), "../list15");
275 	free(fp1);
276 	free(fp2);
277 
278 	/* Test2g: start with "//?/c:/" */
279 	mkfullpath(&fp1, &fp2, "aaa/file1", 6);
280 	failure("fp1=%s, fp2=%s", fp1, fp2);
281 	assertEqualInt(0,
282 	    systemf("%s -cf ../archive16.tar %s > ../out16 2> ../err16",
283 	        testprog, fp1));
284 	assertEqualInt(0,
285 	    systemf("%s -tf ../archive16.tar > ../list16", testprog));
286 	/* Check drive letters have been stripped. */
287 	assertFileContents(fp2, (int)strlen(fp2), "../list16");
288 	free(fp1);
289 	free(fp2);
290 
291 	/* Test2h: start with "\\?\c:\" */
292 	mkfullpath(&fp1, &fp2, "aaa/file1", 7);
293 	failure("fp1=%s, fp2=%s", fp1, fp2);
294 	assertEqualInt(0,
295 	    systemf("%s -cf ../archive17.tar %s > ../out17 2> ../err17",
296 	        testprog, fp1));
297 	assertEqualInt(0,
298 	    systemf("%s -tf ../archive17.tar > ../list17", testprog));
299 	/* Check drive letters have been stripped. */
300 	assertFileContents(fp2, (int)strlen(fp2), "../list17");
301 	free(fp1);
302 	free(fp2);
303 #else
304 	skipping("Windows specific test");
305 #endif /* _WIN32 && !__CYGWIN__ */
306 }
307