test_write_format_iso9660_zisofs.c revision 313571
1/*-
2 * Copyright (c) 2009-2011 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/*
28 * Check that a "zisofs" ISO 9660 image is correctly created.
29 */
30
31static const unsigned char primary_id[] = {
32    0x01, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
33};
34static const unsigned char volumesize[] = {
35    0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23
36};
37static const unsigned char volumesize2[] = {
38    0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36
39};
40static const unsigned char volumesize3[] = {
41    0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28
42};
43static const unsigned char volumeidu16[] = {
44    0x00, 0x43, 0x00, 0x44, 0x00, 0x52, 0x00, 0x4f,
45    0x00, 0x4d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
46    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
47    0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20
48};
49static const unsigned char supplementary_id[] = {
50    0x02, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
51};
52static const unsigned char terminator_id[] = {
53    0xff, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x00
54};
55
56static const unsigned char zisofs_magic[8] = {
57    0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
58};
59
60static const unsigned char zisofs_data[24] = {
61    0x37, 0xe4, 0x53, 0x96, 0xc9, 0xdb, 0xd6, 0x07,
62    0x00, 0x80, 0x00, 0x00, 0x04, 0x0f, 0x00, 0x00,
63    0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00
64};
65
66static const unsigned char boot_id[] = {
67    0x00, 0x43, 0x44, 0x30, 0x30, 0x31, 0x01, 0x45,
68    0x4c, 0x20, 0x54, 0x4f, 0x52, 0x49, 0x54, 0x4f,
69    0x20, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49,
70    0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x00,
71    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72};
73
74static const unsigned char boot_catalog[] = {
75    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78    0x00, 0x00, 0x00, 0x00, 0xaa, 0x55, 0x55, 0xaa,
79    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
80    0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
83};
84
85static const unsigned char el_torito_signature[] = {
86    "ER\355\001\012T\207\001RRIP_1991ATHE ROCK RIDGE "
87    "INTERCHANGE PROTOCOL PROVIDES SUPPORT FOR POSIX "
88    "FILE SYSTEM SEMANTICSPLEASE CONTACT DISC PUBLISHER "
89    "FOR SPECIFICATION SOURCE.  SEE PUBLISHER IDENTIFIER "
90    "IN PRIMARY VOLUME DESCRIPTOR FOR CONTACT INFORMATION."
91};
92
93static void
94test_write_format_iso9660_zisofs_1(void)
95{
96	unsigned char buff2[1024];
97	unsigned char nullb[1024];
98	struct archive *a;
99	struct archive_entry *ae;
100	unsigned char *buff;
101	size_t buffsize = 36 * 2048;
102	size_t used;
103	unsigned int i;
104	int r;
105
106	memset(nullb, 0, sizeof(nullb));
107	buff = malloc(buffsize);
108	assert(buff != NULL);
109	if (buff == NULL)
110		return;
111
112	/* ISO9660 format: Create a new archive in memory. */
113	assert((a = archive_write_new()) != NULL);
114	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
115	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
116	r = archive_write_set_option(a, NULL, "zisofs", "1");
117	if (r == ARCHIVE_FATAL) {
118		skipping("zisofs option not supported on this platform");
119		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
120		free(buff);
121		return;
122	}
123	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
124	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
125
126	/*
127	 * "file1" has a bunch of attributes and 256K bytes of null data.
128	 */
129	assert((ae = archive_entry_new()) != NULL);
130	archive_entry_set_atime(ae, 2, 20);
131	archive_entry_set_birthtime(ae, 3, 30);
132	archive_entry_set_ctime(ae, 4, 40);
133	archive_entry_set_mtime(ae, 5, 50);
134	archive_entry_copy_pathname(ae, "file1");
135	archive_entry_set_mode(ae, S_IFREG | 0755);
136	archive_entry_set_size(ae, 256*1024);
137	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
138	archive_entry_free(ae);
139	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
140
141	/*
142	 * "file2" has a bunch of attributes and 2048 bytes of null data.
143	 */
144	assert((ae = archive_entry_new()) != NULL);
145	archive_entry_set_atime(ae, 2, 20);
146	archive_entry_set_birthtime(ae, 3, 30);
147	archive_entry_set_ctime(ae, 4, 40);
148	archive_entry_set_mtime(ae, 5, 50);
149	archive_entry_copy_pathname(ae, "file2");
150	archive_entry_set_mode(ae, S_IFREG | 0755);
151	archive_entry_set_size(ae, 2048);
152	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
153	archive_entry_free(ae);
154	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
155
156	/*
157	 * "file3" has a bunch of attributes and 2049 bytes of null data.
158	 */
159	assert((ae = archive_entry_new()) != NULL);
160	archive_entry_set_atime(ae, 2, 20);
161	archive_entry_set_birthtime(ae, 3, 30);
162	archive_entry_set_ctime(ae, 4, 40);
163	archive_entry_set_mtime(ae, 5, 50);
164	archive_entry_copy_pathname(ae, "file3");
165	archive_entry_set_mode(ae, S_IFREG | 0755);
166	archive_entry_set_size(ae, 2049);
167	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
168	archive_entry_free(ae);
169	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
170
171	/*
172	 * "file4" has a bunch of attributes and 24 bytes of zisofs data
173	 * which is compressed from 32K bytes null data.
174	 */
175	assert((ae = archive_entry_new()) != NULL);
176	archive_entry_set_atime(ae, 2, 20);
177	archive_entry_set_birthtime(ae, 3, 30);
178	archive_entry_set_ctime(ae, 4, 40);
179	archive_entry_set_mtime(ae, 5, 50);
180	archive_entry_copy_pathname(ae, "file4");
181	archive_entry_set_mode(ae, S_IFREG | 0755);
182	archive_entry_set_size(ae, 24);
183	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
184	archive_entry_free(ae);
185	assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
186
187	/* Close out the archive. */
188	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
189	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
190
191	failure("The ISO image size should be 71680 bytes.");
192	assertEqualInt(used, 2048 * 35);
193
194	/* Check System Area. */
195	for (i = 0; i < 2048 * 16; i++) {
196		failure("System Area should be all nulls.");
197		assertEqualInt(buff[i], 0);
198	}
199
200	/* Primary Volume. */
201	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
202	assertEqualMem(buff+2048*16, primary_id, 8);
203	assertEqualMem(buff+2048*16+0x28,
204	    "CDROM                           ", 32);
205	assertEqualMem(buff+2048*16+0x50, volumesize, 8);
206
207	/* Supplementary Volume. */
208	failure("Supplementary Volume(Joliet) Descriptor "
209	    "should be in 17 Logical Sector.");
210	assertEqualMem(buff+2048*17, supplementary_id, 8);
211	assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
212	assertEqualMem(buff+2048*17+0x50, volumesize, 8);
213	failure("Date and Time of Primary Volume and "
214	    "Date and Time of Supplementary Volume "
215	    "must be the same.");
216	assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
217
218	/* Terminator. */
219	failure("Volume Descriptor Set Terminator "
220	    "should be in 18 Logical Sector.");
221	assertEqualMem(buff+2048*18, terminator_id, 8);
222	for (i = 8; i < 2048; i++) {
223		failure("Body of Volume Descriptor Set Terminator "
224		    "should be all nulls.");
225		assertEqualInt(buff[2048*18+i], 0);
226	}
227
228	/* "file1"  Contents is zisofs data. */
229	failure("file1 image should be zisofs'ed.");
230	assertEqualMem(buff+2048*31, zisofs_magic, 8);
231	/* "file2"  Contents is not zisofs data. */
232	failure("file2 image should not be zisofs'ed.");
233	assertEqualMem(buff+2048*32, nullb, 8);
234	/* "file3"  Contents is zisofs data. */
235	failure("file3 image should be zisofs'ed.");
236	assertEqualMem(buff+2048*33, zisofs_magic, 8);
237	/* "file4"  Contents is zisofs data. */
238	failure("file4 image should be zisofs'ed.");
239	assertEqualMem(buff+2048*34, zisofs_magic, 8);
240
241	/*
242	 * Read ISO image.
243	 */
244	assert((a = archive_read_new()) != NULL);
245	assertEqualIntA(a, 0, archive_read_support_format_all(a));
246	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
247	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
248
249	/*
250	 * Read Root Directory
251	 * Root Directory entry must be in ISO image.
252	 */
253	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
254	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
255	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
256	assertEqualString(".", archive_entry_pathname(ae));
257	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
258	assertEqualInt(2048, archive_entry_size(ae));
259
260	/*
261	 * Read "file1" which has 256K bytes null data.
262	 */
263	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
264	assertEqualInt(2, archive_entry_atime(ae));
265	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
266	assertEqualInt(4, archive_entry_ctime(ae));
267	assertEqualInt(5, archive_entry_mtime(ae));
268	assertEqualString("file1", archive_entry_pathname(ae));
269	assert((S_IFREG | 0555) == archive_entry_mode(ae));
270	assertEqualInt(256*1024, archive_entry_size(ae));
271	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
272	assertEqualMem(buff2, nullb, 1024);
273
274	/*
275	 * Read "file2" which has 2048 bytes null data.
276	 */
277	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
278	assertEqualInt(2, archive_entry_atime(ae));
279	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
280	assertEqualInt(4, archive_entry_ctime(ae));
281	assertEqualInt(5, archive_entry_mtime(ae));
282	assertEqualString("file2", archive_entry_pathname(ae));
283	assert((S_IFREG | 0555) == archive_entry_mode(ae));
284	assertEqualInt(2048, archive_entry_size(ae));
285	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
286	assertEqualMem(buff2, nullb, 1024);
287
288	/*
289	 * Read "file3" which has 2049 bytes null data.
290	 */
291	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
292	assertEqualInt(2, archive_entry_atime(ae));
293	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
294	assertEqualInt(4, archive_entry_ctime(ae));
295	assertEqualInt(5, archive_entry_mtime(ae));
296	assertEqualString("file3", archive_entry_pathname(ae));
297	assert((S_IFREG | 0555) == archive_entry_mode(ae));
298	assertEqualInt(2049, archive_entry_size(ae));
299	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
300	assertEqualMem(buff2, nullb, 1024);
301
302	/*
303	 * Read "file4" which has 32K bytes null data.
304	 */
305	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
306	assertEqualInt(2, archive_entry_atime(ae));
307	/* assertEqualInt(3, archive_entry_birthtime(ae)); */
308	assertEqualInt(4, archive_entry_ctime(ae));
309	assertEqualInt(5, archive_entry_mtime(ae));
310	assertEqualString("file4", archive_entry_pathname(ae));
311	assert((S_IFREG | 0555) == archive_entry_mode(ae));
312	assertEqualInt(32768, archive_entry_size(ae));
313	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
314	assertEqualMem(buff2, nullb, 1024);
315
316	/*
317	 * Verify the end of the archive.
318	 */
319	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
320	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
321	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
322
323	free(buff);
324}
325
326static void
327test_write_format_iso9660_zisofs_2(void)
328{
329	unsigned char buff2[1024];
330	unsigned char data[1024];
331	struct archive *a;
332	struct archive_entry *ae;
333	unsigned char *buff;
334	size_t buffsize = 60 * 2048;
335	size_t used;
336	unsigned int i;
337	int r;
338
339	buff = malloc(buffsize);
340	assert(buff != NULL);
341	if (buff == NULL)
342		return;
343
344	/* ISO9660 format: Create a new archive in memory. */
345	assert((a = archive_write_new()) != NULL);
346	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
347	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
348	r = archive_write_set_option(a, NULL, "zisofs", "1");
349	if (r == ARCHIVE_FATAL) {
350		skipping("zisofs option not supported on this platform");
351		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
352		free(buff);
353		return;
354	}
355	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
356	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
357
358	/*
359	 * "file1" has a bunch of attributes and 256K bytes of random data.
360	 */
361	assert((ae = archive_entry_new()) != NULL);
362	archive_entry_set_atime(ae, 2, 20);
363	archive_entry_set_birthtime(ae, 3, 30);
364	archive_entry_set_ctime(ae, 4, 40);
365	archive_entry_set_mtime(ae, 5, 50);
366	archive_entry_copy_pathname(ae, "file1");
367	archive_entry_set_mode(ae, S_IFREG | 0755);
368	archive_entry_set_size(ae, 256*1024);
369	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
370	archive_entry_free(ae);
371	for (i = 0; i < 256; i++) {
372		int j;
373		if (i == 0) {
374			for (j = 0; j < (int)sizeof(data); j++)
375				data[j] = (i^j) & 0xff;
376		} else {
377			for (j = 0; j < (int)sizeof(data); j++)
378				data[j] ^= i+j;
379		}
380		assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
381	}
382
383	/*
384	 * "file2" has a bunch of attributes and 2048 bytes data.
385	 */
386	assert((ae = archive_entry_new()) != NULL);
387	archive_entry_set_atime(ae, 2, 20);
388	archive_entry_set_birthtime(ae, 3, 30);
389	archive_entry_set_ctime(ae, 4, 40);
390	archive_entry_set_mtime(ae, 5, 50);
391	archive_entry_copy_pathname(ae, "file2");
392	archive_entry_set_mode(ae, S_IFREG | 0755);
393	archive_entry_set_size(ae, 2048);
394	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
395	archive_entry_free(ae);
396	memset(data, 'a', sizeof(data));
397	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
398	memset(data, 'b', sizeof(data));
399	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
400
401	/*
402	 * "file3" has a bunch of attributes and 1024 bytes of 'Z'
403	 *  + 1025 bytes of null data.
404	 */
405	assert((ae = archive_entry_new()) != NULL);
406	archive_entry_set_atime(ae, 2, 20);
407	archive_entry_set_birthtime(ae, 3, 30);
408	archive_entry_set_ctime(ae, 4, 40);
409	archive_entry_set_mtime(ae, 5, 50);
410	archive_entry_copy_pathname(ae, "file3");
411	archive_entry_set_mode(ae, S_IFREG | 0755);
412	archive_entry_set_size(ae, 2049);
413	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
414	archive_entry_free(ae);
415	memset(data, 'Z', sizeof(data));
416	assertEqualIntA(a, 1024, archive_write_data(a, data, 1024));
417
418	/*
419	 * "file4" has a bunch of attributes and 24 bytes of zisofs data
420	 * which is compressed from 32K bytes null data.
421	 */
422	assert((ae = archive_entry_new()) != NULL);
423	archive_entry_set_atime(ae, 2, 20);
424	archive_entry_set_birthtime(ae, 3, 30);
425	archive_entry_set_ctime(ae, 4, 40);
426	archive_entry_set_mtime(ae, 5, 50);
427	archive_entry_copy_pathname(ae, "file4");
428	archive_entry_set_mode(ae, S_IFREG | 0755);
429	archive_entry_set_size(ae, 24);
430	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
431	archive_entry_free(ae);
432	assertEqualIntA(a, 24, archive_write_data(a, zisofs_data, 24));
433
434	/* Close out the archive. */
435	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
436	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
437
438	failure("The ISO image size should be 110592 bytes.");
439	assertEqualInt(used, 2048 * 54);
440
441	/* Check System Area. */
442	for (i = 0; i < 2048 * 16; i++) {
443		failure("System Area should be all nulls.");
444		assertEqualInt(buff[i], 0);
445	}
446
447	/* Primary Volume. */
448	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
449	assertEqualMem(buff+2048*16, primary_id, 8);
450	assertEqualMem(buff+2048*16+0x28,
451	    "CDROM                           ", 32);
452	assertEqualMem(buff+2048*16+0x50, volumesize2, 8);
453
454	/* Supplementary Volume. */
455	failure("Supplementary Volume(Joliet) Descriptor "
456	    "should be in 17 Logical Sector.");
457	assertEqualMem(buff+2048*17, supplementary_id, 8);
458	assertEqualMem(buff+2048*17+0x28, volumeidu16, 32);
459	assertEqualMem(buff+2048*17+0x50, volumesize2, 8);
460	failure("Date and Time of Primary Volume and "
461	    "Date and Time of Supplementary Volume "
462	    "must be the same.");
463	assertEqualMem(buff+2048*16+0x32d, buff+2048*17+0x32d, 0x44);
464
465	/* Terminator. */
466	failure("Volume Descriptor Set Terminator "
467	    "should be in 18 Logical Sector.");
468	assertEqualMem(buff+2048*18, terminator_id, 8);
469	for (i = 8; i < 2048; i++) {
470		failure("Body of Volume Descriptor Set Terminator "
471		    "should be all nulls.");
472		assertEqualInt(buff[2048*18+i], 0);
473	}
474
475	/* "file1"  Contents is zisofs data. */
476	failure("file1 image should be zisofs'ed.");
477	assertEqualMem(buff+2048*31, zisofs_magic, 8);
478	/* "file2"  Contents is not zisofs data. */
479	memset(data, 'a', sizeof(data));
480	failure("file2 image should not be zisofs'ed.");
481	assertEqualMem(buff+2048*51, data, 1024);
482	memset(data, 'b', sizeof(data));
483	failure("file2 image should not be zisofs'ed.");
484	assertEqualMem(buff+2048*51+1024, data, 1024);
485	/* "file3"  Contents is zisofs data. */
486	failure("file3 image should be zisofs'ed.");
487	assertEqualMem(buff+2048*52, zisofs_magic, 8);
488	/* "file4"  Contents is zisofs data. */
489	failure("file4 image should be zisofs'ed.");
490	assertEqualMem(buff+2048*53, zisofs_magic, 8);
491
492	/*
493	 * Read ISO image.
494	 */
495	assert((a = archive_read_new()) != NULL);
496	assertEqualIntA(a, 0, archive_read_support_format_all(a));
497	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
498	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
499
500	/*
501	 * Read Root Directory
502	 * Root Directory entry must be in ISO image.
503	 */
504	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
505	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
506	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
507	assertEqualString(".", archive_entry_pathname(ae));
508	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
509	assertEqualInt(2048, archive_entry_size(ae));
510
511	/*
512	 * Read "file1" which has 256K bytes random data.
513	 */
514	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
515	assertEqualInt(2, archive_entry_atime(ae));
516	assertEqualInt(4, archive_entry_ctime(ae));
517	assertEqualInt(5, archive_entry_mtime(ae));
518	assertEqualString("file1", archive_entry_pathname(ae));
519	assert((S_IFREG | 0555) == archive_entry_mode(ae));
520	assertEqualInt(256*1024, archive_entry_size(ae));
521	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
522
523	/*
524	 * Read "file2" which has 2048 bytes data.
525	 */
526	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
527	assertEqualInt(2, archive_entry_atime(ae));
528	assertEqualInt(4, archive_entry_ctime(ae));
529	assertEqualInt(5, archive_entry_mtime(ae));
530	assertEqualString("file2", archive_entry_pathname(ae));
531	assert((S_IFREG | 0555) == archive_entry_mode(ae));
532	assertEqualInt(2048, archive_entry_size(ae));
533	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
534	memset(data, 'a', sizeof(data));
535	assertEqualMem(buff2, data, 1024);
536
537	/*
538	 * Read "file3" which has 2049 bytes data.
539	 */
540	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
541	assertEqualInt(2, archive_entry_atime(ae));
542	assertEqualInt(4, archive_entry_ctime(ae));
543	assertEqualInt(5, archive_entry_mtime(ae));
544	assertEqualString("file3", archive_entry_pathname(ae));
545	assert((S_IFREG | 0555) == archive_entry_mode(ae));
546	assertEqualInt(2049, archive_entry_size(ae));
547	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
548	memset(data, 'Z', sizeof(data));
549	assertEqualMem(buff2, data, 1024);
550
551	/*
552	 * Read "file4" which has 32K bytes null data.
553	 */
554	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
555	assertEqualInt(2, archive_entry_atime(ae));
556	assertEqualInt(4, archive_entry_ctime(ae));
557	assertEqualInt(5, archive_entry_mtime(ae));
558	assertEqualString("file4", archive_entry_pathname(ae));
559	assert((S_IFREG | 0555) == archive_entry_mode(ae));
560	assertEqualInt(32768, archive_entry_size(ae));
561	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
562	memset(data, 0, sizeof(data));
563	assertEqualMem(buff2, data, 1024);
564
565	/*
566	 * Verify the end of the archive.
567	 */
568	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
569	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
570	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
571
572	free(buff);
573}
574
575/*
576 * Make a bootable ISO image with "zisofs" option.
577 */
578static void
579test_write_format_iso9660_zisofs_3(void)
580{
581	unsigned char buff2[1024];
582	unsigned char nullb[2048];
583	struct archive *a;
584	struct archive_entry *ae;
585	unsigned char *buff;
586	size_t buffsize = 50 * 2048;
587	size_t used;
588	unsigned int i;
589	int r;
590
591	memset(nullb, 0, sizeof(nullb));
592	buff = malloc(buffsize);
593	assert(buff != NULL);
594	if (buff == NULL)
595		return;
596
597	/* ISO9660 format: Create a new archive in memory. */
598	assert((a = archive_write_new()) != NULL);
599	assertEqualIntA(a, 0, archive_write_set_format_iso9660(a));
600	assertEqualIntA(a, 0, archive_write_add_filter_none(a));
601	r = archive_write_set_option(a, NULL, "zisofs", "1");
602	if (r == ARCHIVE_FATAL) {
603		skipping("zisofs option not supported on this platform");
604		assertEqualInt(ARCHIVE_OK, archive_write_free(a));
605		free(buff);
606		return;
607	}
608	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "boot", "boot.img"));
609	assertEqualIntA(a, 0, archive_write_set_option(a, NULL, "pad", NULL));
610	assertEqualIntA(a, 0, archive_write_open_memory(a, buff, buffsize, &used));
611
612	/*
613	 * "file1" has a bunch of attributes and 256K bytes of null data.
614	 */
615	assert((ae = archive_entry_new()) != NULL);
616	archive_entry_set_atime(ae, 2, 20);
617	archive_entry_set_birthtime(ae, 3, 30);
618	archive_entry_set_ctime(ae, 4, 40);
619	archive_entry_set_mtime(ae, 5, 50);
620	archive_entry_copy_pathname(ae, "boot.img");
621	archive_entry_set_mode(ae, S_IFREG | 0755);
622	archive_entry_set_size(ae, 10*1024);
623	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
624	archive_entry_free(ae);
625	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
626
627	/*
628	 * "file2" has a bunch of attributes and 2048 bytes of null data.
629	 */
630	assert((ae = archive_entry_new()) != NULL);
631	archive_entry_set_atime(ae, 2, 20);
632	archive_entry_set_birthtime(ae, 3, 30);
633	archive_entry_set_ctime(ae, 4, 40);
634	archive_entry_set_mtime(ae, 5, 50);
635	archive_entry_copy_pathname(ae, "file2");
636	archive_entry_set_mode(ae, S_IFREG | 0755);
637	archive_entry_set_size(ae, 2048);
638	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
639	archive_entry_free(ae);
640	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
641
642	/*
643	 * "file3" has a bunch of attributes and 2049 bytes of null data.
644	 */
645	assert((ae = archive_entry_new()) != NULL);
646	archive_entry_set_atime(ae, 2, 20);
647	archive_entry_set_birthtime(ae, 3, 30);
648	archive_entry_set_ctime(ae, 4, 40);
649	archive_entry_set_mtime(ae, 5, 50);
650	archive_entry_copy_pathname(ae, "file3");
651	archive_entry_set_mode(ae, S_IFREG | 0755);
652	archive_entry_set_size(ae, 2049);
653	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
654	archive_entry_free(ae);
655	assertEqualIntA(a, 1024, archive_write_data(a, nullb, 1024));
656
657	/* Close out the archive. */
658	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
659	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
660
661	failure("The ISO image size should be 81920 bytes.");
662	assertEqualInt(used, 2048 * 40);
663
664	/* Check System Area. */
665	for (i = 0; i < 2048 * 16; i++) {
666		failure("System Area should be all nulls.");
667		assertEqualInt(buff[i], 0);
668	}
669
670	/* Primary Volume. */
671	failure("Primary Volume Descriptor should be in 16 Logical Sector.");
672	assertEqualMem(buff+2048*16, primary_id, 8);
673	assertEqualMem(buff+2048*16+0x28,
674	    "CDROM                           ", 32);
675	assertEqualMem(buff+2048*16+0x50, volumesize3, 8);
676
677	/* Boot Volume. */
678	failure("Boot Volume Descriptor should be in 17 Logical Sector.");
679	assertEqualMem(buff+2048*17, boot_id, sizeof(boot_id));
680	for (i = 0x27; i <= 0x46; i++) {
681		failure("Unused area must be all nulls.");
682		assert(buff[2048*17+i] == 0);
683	}
684	/* First sector of Boot Catalog. */
685	assert(buff[2048*17+0x47] == 0x20);
686	assert(buff[2048*17+0x48] == 0x00);
687	assert(buff[2048*17+0x49] == 0x00);
688	assert(buff[2048*17+0x4a] == 0x00);
689	for (i = 0x4a; i <= 0x7ff; i++) {
690		failure("Unused area must be all nulls.");
691		assert(buff[2048*17+i] == 0);
692	}
693
694	/* Supplementary Volume. */
695	failure("Supplementary Volume(Joliet) Descriptor "
696	    "should be in 18 Logical Sector.");
697	assertEqualMem(buff+2048*18, supplementary_id, 8);
698	assertEqualMem(buff+2048*18+0x28, volumeidu16, 32);
699	assertEqualMem(buff+2048*18+0x50, volumesize3, 8);
700	failure("Date and Time of Primary Volume and "
701	    "Date and Time of Supplementary Volume "
702	    "must be the same.");
703	assertEqualMem(buff+2048*16+0x32d, buff+2048*18+0x32d, 0x44);
704
705	/* Terminator. */
706	failure("Volume Descriptor Set Terminator "
707	    "should be in 19 Logical Sector.");
708	assertEqualMem(buff+2048*19, terminator_id, 8);
709	for (i = 8; i < 2048; i++) {
710		failure("Body of Volume Descriptor Set Terminator "
711		    "should be all nulls.");
712		assertEqualInt(buff[2048*19+i], 0);
713	}
714
715	/* Check signature of El-Torito. */
716	assertEqualMem(buff+2048*31, el_torito_signature, 237);
717	assertEqualMem(buff+2048*31+237, nullb, 2048-237);
718
719	/* Check contents of "boot.catalog". */
720	assertEqualMem(buff+2048*32, boot_catalog, 64);
721	assertEqualMem(buff+2048*32+64, nullb, 2048-64);
722
723	/* Check contents of "boot.img". */
724	failure("boot.img image should not be zisofs'ed.");
725	assertEqualMem(buff+2048*33, nullb, 2048);
726	for (i = 2048*34; i < 2048*38; i += 2048) {
727		assertEqualMem(buff+i, nullb, 2048);
728	}
729
730	/* "file2"  Contents is not zisofs data. */
731	failure("file2 image should not be zisofs'ed.");
732	assertEqualMem(buff+2048*38, nullb, 8);
733	/* "file3"  Contents is zisofs data. */
734	failure("file3 image should be zisofs'ed.");
735	assertEqualMem(buff+2048*39, zisofs_magic, 8);
736
737	/*
738	 * Read ISO image.
739	 */
740	assert((a = archive_read_new()) != NULL);
741	assertEqualIntA(a, 0, archive_read_support_format_all(a));
742	assertEqualIntA(a, 0, archive_read_support_filter_all(a));
743	assertEqualIntA(a, 0, archive_read_open_memory(a, buff, used));
744
745	/*
746	 * Read Root Directory
747	 * Root Directory entry must be in ISO image.
748	 */
749	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
750	assertEqualInt(archive_entry_atime(ae), archive_entry_ctime(ae));
751	assertEqualInt(archive_entry_atime(ae), archive_entry_mtime(ae));
752	assertEqualString(".", archive_entry_pathname(ae));
753	assert((S_IFDIR | 0555) == archive_entry_mode(ae));
754	assertEqualInt(2048, archive_entry_size(ae));
755
756	/*
757	 * Read "boot.catalog".
758	 */
759	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
760	assertEqualString("boot.catalog", archive_entry_pathname(ae));
761#if !defined(_WIN32) && !defined(__CYGWIN__)
762	assert((S_IFREG | 0444) == archive_entry_mode(ae));
763#else
764	/* On Windows and CYGWIN, always set all exec bit ON by default. */
765	assert((S_IFREG | 0555) == archive_entry_mode(ae));
766#endif
767	assertEqualInt(1, archive_entry_nlink(ae));
768	assertEqualInt(2*1024, archive_entry_size(ae));
769	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
770	assertEqualMem(buff2, boot_catalog, 64);
771
772	/*
773	 * Read "boot.img".
774	 */
775	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
776	assertEqualInt(2, archive_entry_atime(ae));
777	assertEqualInt(3, archive_entry_birthtime(ae));
778	assertEqualInt(4, archive_entry_ctime(ae));
779	assertEqualInt(5, archive_entry_mtime(ae));
780	assertEqualString("boot.img", archive_entry_pathname(ae));
781	assert((S_IFREG | 0555) == archive_entry_mode(ae));
782	assertEqualInt(1, archive_entry_nlink(ae));
783	assertEqualInt(10*1024, archive_entry_size(ae));
784	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
785	assertEqualMem(buff2, nullb, 1024);
786
787	/*
788	 * Read "file2" which has 2048 bytes null data.
789	 */
790	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
791	assertEqualInt(2, archive_entry_atime(ae));
792	assertEqualInt(4, archive_entry_ctime(ae));
793	assertEqualInt(5, archive_entry_mtime(ae));
794	assertEqualString("file2", archive_entry_pathname(ae));
795	assert((S_IFREG | 0555) == archive_entry_mode(ae));
796	assertEqualInt(2048, archive_entry_size(ae));
797	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
798	assertEqualMem(buff2, nullb, 1024);
799
800	/*
801	 * Read "file3" which has 2049 bytes null data.
802	 */
803	assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
804	assertEqualInt(2, archive_entry_atime(ae));
805	assertEqualInt(4, archive_entry_ctime(ae));
806	assertEqualInt(5, archive_entry_mtime(ae));
807	assertEqualString("file3", archive_entry_pathname(ae));
808	assert((S_IFREG | 0555) == archive_entry_mode(ae));
809	assertEqualInt(2049, archive_entry_size(ae));
810	assertEqualIntA(a, 1024, archive_read_data(a, buff2, 1024));
811	assertEqualMem(buff2, nullb, 1024);
812
813	/*
814	 * Verify the end of the archive.
815	 */
816	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
817	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
818	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
819
820	free(buff);
821}
822
823DEFINE_TEST(test_write_format_iso9660_zisofs)
824{
825	test_write_format_iso9660_zisofs_1();
826	test_write_format_iso9660_zisofs_2();
827	test_write_format_iso9660_zisofs_3();
828}
829