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 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "test.h"
28
29 static char buff[4096];
30 static struct {
31 const char *path;
32 mode_t mode;
33 time_t mtime;
34 uid_t uid;
35 gid_t gid;
36 } entries[] = {
37 { "./COPYING", S_IFREG | 0644, 1231975636, 1001, 1001 },
38 { "./Makefile", S_IFREG | 0644, 1233041050, 1001, 1001 },
39 { "./NEWS", S_IFREG | 0644, 1231975636, 1001, 1001 },
40 { "./PROJECTS", S_IFREG | 0644, 1231975636, 1001, 1001 },
41 { "./README", S_IFREG | 0644, 1231975636, 1001, 1001 },
42 { "./subdir", S_IFDIR | 0755, 1233504586, 1001, 1001 },
43 { "./subdir/README", S_IFREG | 0664, 1231975636, 1002, 1001 },
44 { "./subdir/config", S_IFREG | 0664, 1232266273, 1003, 1003 },
45 { "./subdir2", S_IFDIR | 0755, 1233504586, 1001, 1001 },
46 { "./subdir3", S_IFDIR | 0755, 1233504586, 1001, 1001 },
47 { "./subdir3/mtree", S_IFREG | 0664, 1232266273, 1003, 1003 },
48 { NULL, 0, 0, 0, 0 }
49 };
50 static struct {
51 const char *path;
52 mode_t mode;
53 time_t mtime;
54 uid_t uid;
55 gid_t gid;
56 } entries2[] = {
57 { "COPYING", S_IFREG | 0644, 1231975636, 1001, 1001 },
58 { "Makefile", S_IFREG | 0644, 1233041050, 1001, 1001 },
59 { "NEWS", S_IFREG | 0644, 1231975636, 1001, 1001 },
60 { "PROJECTS", S_IFREG | 0644, 1231975636, 1001, 1001 },
61 { "README", S_IFREG | 0644, 1231975636, 1001, 1001 },
62 { "subdir", S_IFDIR | 0755, 1233504586, 1001, 1001 },
63 { "subdir/README", S_IFREG | 0664, 1231975636, 1002, 1001 },
64 { "subdir/config", S_IFREG | 0664, 1232266273, 1003, 1003 },
65 { "subdir2", S_IFDIR | 0755, 1233504586, 1001, 1001 },
66 { "subdir3", S_IFDIR | 0755, 1233504586, 1001, 1001 },
67 { "subdir3/mtree", S_IFREG | 0664, 1232266273, 1003, 1003 },
68 { NULL, 0, 0, 0, 0 }
69 };
70
71 static void
test_write_format_mtree_sub(int use_set,int dironly)72 test_write_format_mtree_sub(int use_set, int dironly)
73 {
74 struct archive_entry *ae;
75 struct archive* a;
76 size_t used;
77 int i;
78
79 /* Create a mtree format archive. */
80 assert((a = archive_write_new()) != NULL);
81 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a));
82 if (use_set)
83 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "use-set", "1"));
84 if (dironly)
85 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "dironly", "1"));
86 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff)-1, &used));
87
88 /* Write entries */
89 for (i = 0; entries[i].path != NULL; i++) {
90 assert((ae = archive_entry_new()) != NULL);
91 archive_entry_set_mtime(ae, entries[i].mtime, 0);
92 assert(entries[i].mtime == archive_entry_mtime(ae));
93 archive_entry_set_mode(ae, entries[i].mode);
94 assert(entries[i].mode == archive_entry_mode(ae));
95 archive_entry_set_uid(ae, entries[i].uid);
96 assert(entries[i].uid == archive_entry_uid(ae));
97 archive_entry_set_gid(ae, entries[i].gid);
98 assert(entries[i].gid == archive_entry_gid(ae));
99 archive_entry_copy_pathname(ae, entries[i].path);
100 if ((entries[i].mode & AE_IFMT) != S_IFDIR)
101 archive_entry_set_size(ae, 8);
102 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
103 if ((entries[i].mode & AE_IFMT) != S_IFDIR)
104 assertEqualIntA(a, 8,
105 archive_write_data(a, "Hello012", 15));
106 archive_entry_free(ae);
107 }
108 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
109 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
110
111 if (use_set) {
112 const char *p;
113
114 buff[used] = '\0';
115 assert(NULL != (p = strstr(buff, "\n/set ")));
116 if (p != NULL) {
117 char *r;
118 const char *o;
119 p++;
120 r = strchr(p, '\n');
121 if (r != NULL)
122 *r = '\0';
123 if (dironly)
124 o = "/set type=dir uid=1001 gid=1001 mode=755";
125 else
126 o = "/set type=file uid=1001 gid=1001 mode=644";
127 assertEqualString(o, p);
128 if (r != NULL)
129 *r = '\n';
130 }
131 }
132
133 /*
134 * Read the data and check it.
135 */
136 assert((a = archive_read_new()) != NULL);
137 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
138 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
139 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
140
141 /* Read entries */
142 for (i = 0; entries[i].path != NULL; i++) {
143 if (dironly && (entries[i].mode & AE_IFMT) != S_IFDIR)
144 continue;
145 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
146 assertEqualInt(entries[i].mtime, archive_entry_mtime(ae));
147 assertEqualInt(entries[i].mode, archive_entry_mode(ae));
148 assertEqualInt(entries[i].uid, archive_entry_uid(ae));
149 assertEqualInt(entries[i].gid, archive_entry_gid(ae));
150 assertEqualString(entries[i].path, archive_entry_pathname(ae));
151 if ((entries[i].mode & AE_IFMT) != S_IFDIR)
152 assertEqualInt(8, archive_entry_size(ae));
153 }
154 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
155 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
156 }
157
158 static void
test_write_format_mtree_sub2(int use_set,int dironly)159 test_write_format_mtree_sub2(int use_set, int dironly)
160 {
161 struct archive_entry *ae;
162 struct archive* a;
163 size_t used;
164 int i;
165 char str[32];
166
167 /* Create a mtree format archive. */
168 assert((a = archive_write_new()) != NULL);
169 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a));
170 if (use_set)
171 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "use-set", "1"));
172 if (dironly)
173 assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_option(a, NULL, "dironly", "1"));
174 assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff)-1, &used));
175
176 /* Write entries2 */
177 for (i = 0; entries2[i].path != NULL; i++) {
178 assert((ae = archive_entry_new()) != NULL);
179 archive_entry_set_mtime(ae, entries2[i].mtime, 0);
180 assert(entries2[i].mtime == archive_entry_mtime(ae));
181 archive_entry_set_mode(ae, entries2[i].mode);
182 assert(entries2[i].mode == archive_entry_mode(ae));
183 archive_entry_set_uid(ae, entries2[i].uid);
184 assert(entries2[i].uid == archive_entry_uid(ae));
185 archive_entry_set_gid(ae, entries2[i].gid);
186 assert(entries2[i].gid == archive_entry_gid(ae));
187 archive_entry_copy_pathname(ae, entries2[i].path);
188 if ((entries2[i].mode & AE_IFMT) != S_IFDIR)
189 archive_entry_set_size(ae, 8);
190 assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
191 if ((entries2[i].mode & AE_IFMT) != S_IFDIR)
192 assertEqualIntA(a, 8,
193 archive_write_data(a, "Hello012", 15));
194 archive_entry_free(ae);
195 }
196 assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
197 assertEqualInt(ARCHIVE_OK, archive_write_free(a));
198
199 if (use_set) {
200 const char *p;
201
202 buff[used] = '\0';
203 assert(NULL != (p = strstr(buff, "\n/set ")));
204 if (p != NULL) {
205 char *r;
206 const char *o;
207 p++;
208 r = strchr(p, '\n');
209 if (r != NULL)
210 *r = '\0';
211 if (dironly)
212 o = "/set type=dir uid=1001 gid=1001 mode=755";
213 else
214 o = "/set type=file uid=1001 gid=1001 mode=644";
215 assertEqualString(o, p);
216 if (r != NULL)
217 *r = '\n';
218 }
219 }
220
221 /*
222 * Read the data and check it.
223 */
224 assert((a = archive_read_new()) != NULL);
225 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
226 assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
227 assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
228
229 /* Read entries2 */
230 memset(str, 0, sizeof(str));
231 strcpy(str, "./");
232 for (i = 0; entries2[i].path != NULL; i++) {
233 if (dironly && (entries2[i].mode & AE_IFMT) != S_IFDIR)
234 continue;
235 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
236 assertEqualInt(entries2[i].mtime, archive_entry_mtime(ae));
237 assertEqualInt(entries2[i].mode, archive_entry_mode(ae));
238 assertEqualInt(entries2[i].uid, archive_entry_uid(ae));
239 assertEqualInt(entries2[i].gid, archive_entry_gid(ae));
240 strcpy(str + 2, entries2[i].path);
241 assertEqualString(str, archive_entry_pathname(ae));
242 if ((entries2[i].mode & AE_IFMT) != S_IFDIR)
243 assertEqualInt(8, archive_entry_size(ae));
244 }
245 assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
246 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
247 }
248
DEFINE_TEST(test_write_format_mtree)249 DEFINE_TEST(test_write_format_mtree)
250 {
251 /* Default setting */
252 test_write_format_mtree_sub(0, 0);
253 /* Directory only */
254 test_write_format_mtree_sub(0, 1);
255 /* Use /set keyword */
256 test_write_format_mtree_sub(1, 0);
257 /* Use /set keyword with directory only */
258 test_write_format_mtree_sub(1, 1);
259 }
260
DEFINE_TEST(test_write_format_mtree_no_leading_dotslash)261 DEFINE_TEST(test_write_format_mtree_no_leading_dotslash)
262 {
263 /* Default setting */
264 test_write_format_mtree_sub2(0, 0);
265 /* Directory only */
266 test_write_format_mtree_sub2(0, 1);
267 /* Use /set keyword */
268 test_write_format_mtree_sub2(1, 0);
269 /* Use /set keyword with directory only */
270 test_write_format_mtree_sub2(1, 1);
271 }
272