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