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