1231200Smm/*-
2231200Smm * Copyright (c) 2010 Tim Kientzle
3231200Smm * All rights reserved.
4231200Smm *
5231200Smm * Redistribution and use in source and binary forms, with or without
6231200Smm * modification, are permitted provided that the following conditions
7231200Smm * are met:
8231200Smm * 1. Redistributions of source code must retain the above copyright
9231200Smm *    notice, this list of conditions and the following disclaimer.
10231200Smm * 2. Redistributions in binary form must reproduce the above copyright
11231200Smm *    notice, this list of conditions and the following disclaimer in the
12231200Smm *    documentation and/or other materials provided with the distribution.
13231200Smm *
14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24231200Smm */
25231200Smm#include "test.h"
26231200Smm__FBSDID("$FreeBSD$");
27231200Smm
28231200Smmchar buff2[64];
29231200Smm
30231200Smm/* Some names 1026 characters long */
31231200Smmstatic const char *longfilename = "abcdefghijklmnopqrstuvwxyz"
32231200Smm    "12345678901234567890123456789012345678901234567890"
33231200Smm    "12345678901234567890123456789012345678901234567890"
34231200Smm    "12345678901234567890123456789012345678901234567890"
35231200Smm    "12345678901234567890123456789012345678901234567890"
36231200Smm    "12345678901234567890123456789012345678901234567890"
37231200Smm    "12345678901234567890123456789012345678901234567890"
38231200Smm    "12345678901234567890123456789012345678901234567890"
39231200Smm    "12345678901234567890123456789012345678901234567890"
40231200Smm    "12345678901234567890123456789012345678901234567890"
41231200Smm    "12345678901234567890123456789012345678901234567890"
42231200Smm    "12345678901234567890123456789012345678901234567890"
43231200Smm    "12345678901234567890123456789012345678901234567890"
44231200Smm    "12345678901234567890123456789012345678901234567890"
45231200Smm    "12345678901234567890123456789012345678901234567890"
46231200Smm    "12345678901234567890123456789012345678901234567890"
47231200Smm    "12345678901234567890123456789012345678901234567890"
48231200Smm    "12345678901234567890123456789012345678901234567890"
49231200Smm    "12345678901234567890123456789012345678901234567890"
50231200Smm    "12345678901234567890123456789012345678901234567890"
51231200Smm    "12345678901234567890123456789012345678901234567890";
52231200Smm
53231200Smmstatic const char *longlinkname = "Xabcdefghijklmnopqrstuvwxyz"
54231200Smm    "12345678901234567890123456789012345678901234567890"
55231200Smm    "12345678901234567890123456789012345678901234567890"
56231200Smm    "12345678901234567890123456789012345678901234567890"
57231200Smm    "12345678901234567890123456789012345678901234567890"
58231200Smm    "12345678901234567890123456789012345678901234567890"
59231200Smm    "12345678901234567890123456789012345678901234567890"
60231200Smm    "12345678901234567890123456789012345678901234567890"
61231200Smm    "12345678901234567890123456789012345678901234567890"
62231200Smm    "12345678901234567890123456789012345678901234567890"
63231200Smm    "12345678901234567890123456789012345678901234567890"
64231200Smm    "12345678901234567890123456789012345678901234567890"
65231200Smm    "12345678901234567890123456789012345678901234567890"
66231200Smm    "12345678901234567890123456789012345678901234567890"
67231200Smm    "12345678901234567890123456789012345678901234567890"
68231200Smm    "12345678901234567890123456789012345678901234567890"
69231200Smm    "12345678901234567890123456789012345678901234567890"
70231200Smm    "12345678901234567890123456789012345678901234567890"
71231200Smm    "12345678901234567890123456789012345678901234567890"
72231200Smm    "12345678901234567890123456789012345678901234567890"
73231200Smm    "12345678901234567890123456789012345678901234567890";
74231200Smm
75231200Smmstatic const char *longhardlinkname = "Yabcdefghijklmnopqrstuvwxyz"
76231200Smm    "12345678901234567890123456789012345678901234567890"
77231200Smm    "12345678901234567890123456789012345678901234567890"
78231200Smm    "12345678901234567890123456789012345678901234567890"
79231200Smm    "12345678901234567890123456789012345678901234567890"
80231200Smm    "12345678901234567890123456789012345678901234567890"
81231200Smm    "12345678901234567890123456789012345678901234567890"
82231200Smm    "12345678901234567890123456789012345678901234567890"
83231200Smm    "12345678901234567890123456789012345678901234567890"
84231200Smm    "12345678901234567890123456789012345678901234567890"
85231200Smm    "12345678901234567890123456789012345678901234567890"
86231200Smm    "12345678901234567890123456789012345678901234567890"
87231200Smm    "12345678901234567890123456789012345678901234567890"
88231200Smm    "12345678901234567890123456789012345678901234567890"
89231200Smm    "12345678901234567890123456789012345678901234567890"
90231200Smm    "12345678901234567890123456789012345678901234567890"
91231200Smm    "12345678901234567890123456789012345678901234567890"
92231200Smm    "12345678901234567890123456789012345678901234567890"
93231200Smm    "12345678901234567890123456789012345678901234567890"
94231200Smm    "12345678901234567890123456789012345678901234567890"
95231200Smm    "12345678901234567890123456789012345678901234567890";
96231200Smm
97231200Smm
98231200SmmDEFINE_TEST(test_write_format_gnutar)
99231200Smm{
100231200Smm	size_t buffsize = 1000000;
101231200Smm	char *buff;
102231200Smm	struct archive_entry *ae;
103231200Smm	struct archive *a;
104231200Smm	size_t used;
105231200Smm
106231200Smm	buff = malloc(buffsize); /* million bytes of work area */
107231200Smm	assert(buff != NULL);
108231200Smm
109231200Smm	/* Create a new archive in memory. */
110231200Smm	assert((a = archive_write_new()) != NULL);
111231200Smm	assertA(0 == archive_write_set_format_gnutar(a));
112248616Smm	assertA(0 == archive_write_add_filter_none(a));
113231200Smm	assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));
114231200Smm
115231200Smm	/*
116231200Smm	 * "file" has a bunch of attributes and 8 bytes of data.
117231200Smm	 */
118231200Smm	assert((ae = archive_entry_new()) != NULL);
119231200Smm	archive_entry_set_atime(ae, 2, 20);
120231200Smm	archive_entry_set_birthtime(ae, 3, 30);
121231200Smm	archive_entry_set_ctime(ae, 4, 40);
122231200Smm	archive_entry_set_mtime(ae, 5, 50);
123231200Smm	archive_entry_copy_pathname(ae, "file");
124231200Smm	archive_entry_set_mode(ae, S_IFREG | 0755);
125231200Smm	archive_entry_set_size(ae, 8);
126231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
127231200Smm	archive_entry_free(ae);
128231200Smm	assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
129231200Smm
130231200Smm	/*
131231200Smm	 * A file with a very long name
132231200Smm	 */
133231200Smm	assert((ae = archive_entry_new()) != NULL);
134231200Smm	archive_entry_copy_pathname(ae, longfilename);
135231200Smm	archive_entry_set_mode(ae, S_IFREG | 0755);
136231200Smm	archive_entry_set_size(ae, 8);
137231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
138231200Smm	archive_entry_free(ae);
139231200Smm	assertEqualIntA(a, 8, archive_write_data(a, "abcdefgh", 9));
140231200Smm
141231200Smm	/*
142231200Smm	 * A hardlink to the above file.
143231200Smm	 */
144231200Smm	assert((ae = archive_entry_new()) != NULL);
145231200Smm	archive_entry_copy_pathname(ae, longhardlinkname);
146231200Smm	archive_entry_copy_hardlink(ae, longfilename);
147231200Smm	archive_entry_set_mode(ae, S_IFREG | 0755);
148231200Smm	archive_entry_set_size(ae, 8);
149231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
150231200Smm	archive_entry_free(ae);
151231200Smm
152231200Smm	/*
153231200Smm	 * A symlink to the above file.
154231200Smm	 */
155231200Smm	assert((ae = archive_entry_new()) != NULL);
156231200Smm	archive_entry_copy_pathname(ae, longlinkname);
157231200Smm	archive_entry_copy_symlink(ae, longfilename);
158231200Smm	archive_entry_set_mode(ae, AE_IFLNK | 0755);
159231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
160231200Smm	archive_entry_free(ae);
161231200Smm
162231200Smm	/* TODO: support GNU tar sparse format and test it here. */
163231200Smm	/* See test_write_format_pax for an example of testing sparse files. */
164231200Smm
165231200Smm	/* Close out the archive. */
166231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
167231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
168231200Smm
169231200Smm	/*
170231200Smm	 * Some basic verification of the low-level format.
171231200Smm	 */
172231200Smm
173231200Smm	/* Verify GNU tar magic/version fields */
174231200Smm	assertEqualMem(buff + 257, "ustar  \0", 8);
175231200Smm
176231200Smm	assertEqualInt(14336, used);
177231200Smm
178231200Smm	/*
179231200Smm	 *
180231200Smm	 * Now, read the data back.
181231200Smm	 *
182231200Smm	 */
183231200Smm	assert((a = archive_read_new()) != NULL);
184231200Smm	assertEqualIntA(a, 0, archive_read_support_format_all(a));
185231200Smm	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
186231200Smm	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
187231200Smm
188231200Smm	/*
189231200Smm	 * Read "file"
190231200Smm	 */
191231200Smm	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
192231200Smm	assert(!archive_entry_atime_is_set(ae));
193231200Smm	assert(!archive_entry_birthtime_is_set(ae));
194231200Smm	assert(!archive_entry_ctime_is_set(ae));
195231200Smm	assertEqualInt(5, archive_entry_mtime(ae));
196231200Smm	assertEqualInt(0, archive_entry_mtime_nsec(ae));
197231200Smm	assertEqualString("file", archive_entry_pathname(ae));
198231200Smm	assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
199231200Smm	assertEqualInt(8, archive_entry_size(ae));
200231200Smm	assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
201231200Smm	assertEqualMem(buff2, "12345678", 8);
202231200Smm
203231200Smm	/*
204231200Smm	 * Read file with very long name.
205231200Smm	 */
206231200Smm	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
207231200Smm	assertEqualString(longfilename, archive_entry_pathname(ae));
208231200Smm	assertEqualInt(S_IFREG | 0755, archive_entry_mode(ae));
209231200Smm	assertEqualInt(8, archive_entry_size(ae));
210231200Smm	assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
211231200Smm	assertEqualMem(buff2, "abcdefgh", 8);
212231200Smm
213231200Smm	/*
214231200Smm	 * Read hardlink.
215231200Smm	 */
216231200Smm	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
217231200Smm	assertEqualString(longhardlinkname, archive_entry_pathname(ae));
218231200Smm	assertEqualString(longfilename, archive_entry_hardlink(ae));
219231200Smm
220231200Smm	/*
221231200Smm	 * Read symlink.
222231200Smm	 */
223231200Smm	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
224231200Smm	assertEqualString(longlinkname, archive_entry_pathname(ae));
225231200Smm	assertEqualString(longfilename, archive_entry_symlink(ae));
226231200Smm	assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
227231200Smm
228231200Smm	/*
229231200Smm	 * Verify the end of the archive.
230231200Smm	 */
231231200Smm	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
232231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
233231200Smm	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
234231200Smm
235231200Smm	free(buff);
236231200Smm}
237