1 /*-
2  * Copyright (c) 2007 Kai Wang
3  * Copyright (c) 2007 Tim Kientzle
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer
11  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "test.h"
29 __FBSDID("$FreeBSD: head/lib/libarchive/test/test_write_format_ar.c 189308 2009-03-03 17:02:51Z kientzle $");
30 
31 char buff[4096];
32 char buff2[64];
33 static char strtab[] = "abcdefghijklmn.o/\nggghhhjjjrrrttt.o/\niiijjjdddsssppp.o/\n";
34 
DEFINE_TEST(test_write_format_ar)35 DEFINE_TEST(test_write_format_ar)
36 {
37 #if ARCHIVE_VERSION_NUMBER < 1009000
38 	skipping("ar write support");
39 #else
40 	struct archive_entry *ae;
41 	struct archive* a;
42 	size_t used;
43 
44 	/*
45 	 * First we try to create a SVR4/GNU format archive.
46 	 */
47 	assert((a = archive_write_new()) != NULL);
48 	assertA(0 == archive_write_set_format_ar_svr4(a));
49 	assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));
50 
51 	/* write the filename table */
52 	assert((ae = archive_entry_new()) != NULL);
53 	archive_entry_copy_pathname(ae, "//");
54 	archive_entry_set_size(ae, strlen(strtab));
55 	assertA(0 == archive_write_header(a, ae));
56 	assertA(strlen(strtab) == (size_t)archive_write_data(a, strtab, strlen(strtab)));
57 	archive_entry_free(ae);
58 
59 	/* write entries */
60 	assert((ae = archive_entry_new()) != NULL);
61 	archive_entry_set_mtime(ae, 1, 0);
62 	assert(1 == archive_entry_mtime(ae));
63 	archive_entry_set_mode(ae, S_IFREG | 0755);
64 	assert((S_IFREG | 0755) == archive_entry_mode(ae));
65 	archive_entry_copy_pathname(ae, "abcdefghijklmn.o");
66 	archive_entry_set_size(ae, 8);
67 	assertA(0 == archive_write_header(a, ae));
68 	assertA(8 == archive_write_data(a, "87654321", 15));
69 	archive_entry_free(ae);
70 
71 	assert((ae = archive_entry_new()) != NULL);
72 	archive_entry_copy_pathname(ae, "ggghhhjjjrrrttt.o");
73 	archive_entry_set_filetype(ae, AE_IFREG);
74 	archive_entry_set_size(ae, 7);
75 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
76 	assertEqualIntA(a, 7, archive_write_data(a, "7777777", 7));
77 	archive_entry_free(ae);
78 
79 	/* test full pathname */
80 	assert((ae = archive_entry_new()) != NULL);
81 	archive_entry_copy_pathname(ae, "/usr/home/xx/iiijjjdddsssppp.o");
82 	archive_entry_set_mode(ae, S_IFREG | 0755);
83 	archive_entry_set_size(ae, 8);
84 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
85 	assertEqualIntA(a, 8, archive_write_data(a, "88877766", 8));
86 	archive_entry_free(ae);
87 
88 	/* trailing "/" should be rejected */
89 	assert((ae = archive_entry_new()) != NULL);
90 	archive_entry_copy_pathname(ae, "/usr/home/xx/iiijjj/");
91 	archive_entry_set_size(ae, 8);
92 	assertA(0 != archive_write_header(a, ae));
93 	archive_entry_free(ae);
94 
95 	/* Non regular file should be rejected */
96 	assert((ae = archive_entry_new()) != NULL);
97 	archive_entry_copy_pathname(ae, "gfgh.o");
98 	archive_entry_set_mode(ae, S_IFDIR | 0755);
99 	archive_entry_set_size(ae, 6);
100 	assertA(0 != archive_write_header(a, ae));
101 	archive_entry_free(ae);
102 
103 	archive_write_close(a);
104 #if ARCHIVE_VERSION_NUMBER < 2000000
105 	archive_write_finish(a);
106 #else
107 	assertEqualInt(0, archive_write_finish(a));
108 #endif
109 
110 	/*
111 	 * Now, read the data back.
112 	 */
113 	assert((a = archive_read_new()) != NULL);
114 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
115 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
116 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
117 
118 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
119 	assertEqualInt(0, archive_entry_mtime(ae));
120 	assertEqualString("//", archive_entry_pathname(ae));
121 	assertEqualInt(0, archive_entry_size(ae));
122 
123 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
124 	assertEqualInt(1, archive_entry_mtime(ae));
125 	assertEqualString("abcdefghijklmn.o", archive_entry_pathname(ae));
126 	assertEqualInt(8, archive_entry_size(ae));
127 	assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
128 	assertEqualMem(buff2, "87654321", 8);
129 
130 	assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae));
131 	assertEqualString("ggghhhjjjrrrttt.o", archive_entry_pathname(ae));
132 	assertEqualInt(7, archive_entry_size(ae));
133 	assertEqualIntA(a, 7, archive_read_data(a, buff2, 11));
134 	assertEqualMem(buff2, "7777777", 7);
135 
136 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
137 	assertEqualString("iiijjjdddsssppp.o", archive_entry_pathname(ae));
138 	assertEqualInt(8, archive_entry_size(ae));
139 	assertEqualIntA(a, 8, archive_read_data(a, buff2, 17));
140 	assertEqualMem(buff2, "88877766", 8);
141 
142 	assertEqualIntA(a, 0, archive_read_close(a));
143 #if ARCHIVE_VERSION_NUMBER < 2000000
144 	archive_read_finish(a);
145 #else
146 	assertEqualInt(0, archive_read_finish(a));
147 #endif
148 
149 	/*
150 	 * Then, we try to create a BSD format archive.
151 	 */
152 	memset(buff, 0, sizeof(buff));
153 	assert((a = archive_write_new()) != NULL);
154 	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ar_bsd(a));
155 	assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff), &used));
156 
157 	/* write a entry need long name extension */
158 	assert((ae = archive_entry_new()) != NULL);
159 	archive_entry_copy_pathname(ae, "ttttyyyyuuuuiiii.o");
160 	archive_entry_set_filetype(ae, AE_IFREG);
161 	archive_entry_set_size(ae, 5);
162 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
163 	assertEqualInt(5, archive_entry_size(ae));
164 	assertEqualIntA(a, 5, archive_write_data(a, "12345", 7));
165 	archive_entry_free(ae);
166 
167 	/* write a entry with a short name */
168 	assert((ae = archive_entry_new()) != NULL);
169 	archive_entry_copy_pathname(ae, "ttyy.o");
170 	archive_entry_set_filetype(ae, AE_IFREG);
171 	archive_entry_set_size(ae, 6);
172 	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
173 	assertEqualIntA(a, 6, archive_write_data(a, "555555", 7));
174 	archive_entry_free(ae);
175 	archive_write_close(a);
176 #if ARCHIVE_VERSION_NUMBER < 2000000
177 	archive_write_finish(a);
178 #else
179 	assertEqualInt(0, archive_write_finish(a));
180 #endif
181 
182 	/* Now, Read the data back */
183 	assert((a = archive_read_new()) != NULL);
184 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
185 	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
186 	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used));
187 
188 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
189 	assertEqualString("ttttyyyyuuuuiiii.o", archive_entry_pathname(ae));
190 	assertEqualInt(5, archive_entry_size(ae));
191 	assertEqualIntA(a, 5, archive_read_data(a, buff2, 10));
192 	assertEqualMem(buff2, "12345", 5);
193 
194 	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
195 	assertEqualString("ttyy.o", archive_entry_pathname(ae));
196 	assertEqualInt(6, archive_entry_size(ae));
197 	assertEqualIntA(a, 6, archive_read_data(a, buff2, 10));
198 	assertEqualMem(buff2, "555555", 6);
199 
200 	/* Test EOF */
201 	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
202 	assertEqualIntA(a, 0, archive_read_close(a));
203 #if ARCHIVE_VERSION_NUMBER < 2000000
204 	archive_read_finish(a);
205 #else
206 	assertEqualInt(0, archive_read_finish(a));
207 #endif
208 #endif
209 }
210