1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-20 11:11:24 +00:00

Merge r558,567,569,571,581,582,583,598 from libarchive.googlecode.com:

Support Joliet extensions.  This currently ignores Rockridge extensions
if both exist on the same disk unless the '!joliet' option is provided.
e.g.: tar -xvf example.iso --options '!joliet'
Thanks to: Andreas Henriksson
This commit is contained in:
Tim Kientzle 2009-03-07 02:24:32 +00:00
parent 5e9641ba0a
commit cdad0e17a1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=189474
5 changed files with 460 additions and 31 deletions

View File

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -148,6 +149,28 @@ __FBSDID("$FreeBSD$");
#error PVD offset and size definitions are wrong.
#endif
/* Structure of optional on-disk supplementary volume descriptor. */
#define SVD_type_offset 0
#define SVD_type_size 1
#define SVD_id_offset (SVD_type_offset + SVD_type_size)
#define SVD_id_size 5
#define SVD_version_offset (SVD_id_offset + SVD_id_size)
#define SVD_version_size 1
/* ... */
#define SVD_volume_space_size_offset 80
#define SVD_volume_space_size_size 8
#define SVD_escape_sequences_offset (SVD_volume_space_size_offset + SVD_volume_space_size_size)
#define SVD_escape_sequences_size 32
/* ... */
#define SVD_logical_block_size_offset 128
#define SVD_logical_block_size_size 4
/* ... */
#define SVD_root_directory_record_offset 156
#define SVD_root_directory_record_size 34
/* ... */
/* FIXME: validate correctness of last SVD entry offset. */
/* Structure of an on-disk directory record. */
/* Note: ISO9660 stores each multi-byte integer twice, once in
* each byte order. The sizes here are the size of just one
@ -175,10 +198,6 @@ __FBSDID("$FreeBSD$");
#define DR_name_len_size 1
#define DR_name_offset 33
/*
* Our private data.
*/
/* In-memory storage for a directory record. */
struct file_info {
struct file_info *parent;
@ -207,9 +226,13 @@ struct file_info {
struct iso9660 {
int magic;
#define ISO9660_MAGIC 0x96609660
int option_ignore_joliet;
struct archive_string pathname;
char seenRockridge; /* Set true if RR extensions are used. */
unsigned char suspOffset;
char seenJoliet;
uint64_t previous_offset;
uint64_t previous_size;
@ -230,6 +253,8 @@ struct iso9660 {
static void add_entry(struct iso9660 *iso9660, struct file_info *file);
static int archive_read_format_iso9660_bid(struct archive_read *);
static int archive_read_format_iso9660_options(struct archive_read *,
const char *, const char *);
static int archive_read_format_iso9660_cleanup(struct archive_read *);
static int archive_read_format_iso9660_read_data(struct archive_read *,
const void **, size_t *, off_t *);
@ -243,6 +268,7 @@ static void dump_isodirrec(FILE *, const unsigned char *isodirrec);
static time_t time_from_tm(struct tm *);
static time_t isodate17(const unsigned char *);
static time_t isodate7(const unsigned char *);
static int isJolietSVD(struct iso9660 *, const unsigned char *);
static int isPVD(struct iso9660 *, const unsigned char *);
static struct file_info *next_entry(struct iso9660 *);
static int next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
@ -281,7 +307,7 @@ archive_read_support_format_iso9660(struct archive *_a)
iso9660,
"iso9660",
archive_read_format_iso9660_bid,
NULL,
archive_read_format_iso9660_options,
archive_read_format_iso9660_read_header,
archive_read_format_iso9660_read_data,
archive_read_format_iso9660_read_data_skip,
@ -299,9 +325,9 @@ static int
archive_read_format_iso9660_bid(struct archive_read *a)
{
struct iso9660 *iso9660;
ssize_t bytes_read;
ssize_t bytes_read, brsvd;
const void *h;
const unsigned char *p;
const unsigned char *p, *psvd;
int bid;
iso9660 = (struct iso9660 *)(a->format->data);
@ -320,6 +346,17 @@ archive_read_format_iso9660_bid(struct archive_read *a)
bytes_read -= 32768;
p += 32768;
/* Check each volume descriptor to locate possible SVD with Joliet. */
for (brsvd = bytes_read, psvd = p;
!iso9660->option_ignore_joliet && brsvd > 2048;
brsvd -= 2048, psvd += 2048) {
bid = isJolietSVD(iso9660, psvd);
if (bid > 0)
return (bid);
if (*p == '\177') /* End-of-volume-descriptor marker. */
break;
}
/* Check each volume descriptor to locate the PVD. */
for (; bytes_read > 2048; bytes_read -= 2048, p += 2048) {
bid = isPVD(iso9660, p);
@ -333,6 +370,88 @@ archive_read_format_iso9660_bid(struct archive_read *a)
return (0);
}
static int
archive_read_format_iso9660_options(struct archive_read *a,
const char *key, const char *val)
{
struct iso9660 *iso9660;
iso9660 = (struct iso9660 *)(a->format->data);
if (strcmp(key, "joliet") == 0) {
if (val == NULL || strcmp(val, "off") == 0 ||
strcmp(val, "ignore") == 0 ||
strcmp(val, "disable") == 0 ||
strcmp(val, "0") == 0)
iso9660->option_ignore_joliet = 1;
else
iso9660->option_ignore_joliet = 0;
return (ARCHIVE_OK);
}
/* Note: The "warn" return is just to inform the options
* supervisor that we didn't handle it. It will generate
* a suitable error if noone used this option. */
return (ARCHIVE_WARN);
}
static int
isJolietSVD(struct iso9660 *iso9660, const unsigned char *h)
{
struct file_info *file;
const unsigned char *p;
/* Type 2 means it's a SVD. */
if (h[SVD_type_offset] != 2)
return (0);
/* ID must be "CD001" */
if (memcmp(h + SVD_id_offset, "CD001", 5) != 0)
return (0);
/* FIXME: do more validations according to joliet spec. */
/* check if this SVD contains joliet extension! */
p = h + SVD_escape_sequences_offset;
/* N.B. Joliet spec says p[1] == '\\', but.... */
if (p[0] == '%' && p[1] == '/') {
int level = 0;
if (p[2] == '@')
level = 1;
else if (p[2] == 'C')
level = 2;
else if (p[2] == 'E')
level = 3;
else /* not joliet */
return (0);
iso9660->seenJoliet = level;
} else /* not joliet */
return (0);
iso9660->logical_block_size = toi(h + SVD_logical_block_size_offset, 2);
if (iso9660->logical_block_size <= 0)
return (0);
iso9660->volume_size = iso9660->logical_block_size
* (uint64_t)toi(h + SVD_volume_space_size_offset, 4);
#if DEBUG
fprintf(stderr, "Joliet UCS-2 level %d with "
"logical block size:%d, volume size:%d\n",
iso9660->seenJoliet,
iso9660->logical_block_size, iso9660->volume_size);
#endif
/* Store the root directory in the pending list. */
file = parse_file_info(iso9660, NULL, h + SVD_root_directory_record_offset);
add_entry(iso9660, file);
return (48);
}
static int
isPVD(struct iso9660 *iso9660, const unsigned char *h)
{
@ -507,6 +626,11 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
p += *p) {
struct file_info *child;
/* N.B.: these special directory identifiers
* are 8 bit "values" even on a
* Joliet CD with UCS-2 (16bit) encoding.
*/
/* Skip '.' entry. */
if (*(p + DR_name_len_offset) == 1
&& *(p + DR_name_offset) == '\0')
@ -601,7 +725,7 @@ parse_file_info(struct iso9660 *iso9660, struct file_info *parent,
struct file_info *file;
size_t name_len;
const unsigned char *rr_start, *rr_end;
const char *p;
const unsigned char *p;
int flags;
/* TODO: Sanity check that name_len doesn't exceed length, etc. */
@ -620,23 +744,68 @@ parse_file_info(struct iso9660 *iso9660, struct file_info *parent,
file->mtime = isodate7(isodirrec + DR_date_offset);
file->ctime = file->atime = file->mtime;
name_len = (size_t)*(const unsigned char *)(isodirrec + DR_name_len_offset);
name_len = (size_t)isodirrec[DR_name_len_offset];
p = isodirrec + DR_name_offset;
/* Rockridge extensions (if any) follow name. Compute this
* before fidgeting the name_len below. */
rr_start = p + name_len + (name_len & 1 ? 0 : 1) + iso9660->suspOffset;
rr_end = (const unsigned char *)isodirrec
+ *(isodirrec + DR_length_offset);
rr_end = isodirrec + isodirrec[DR_length_offset];
/* Chop off trailing ';1' from files. */
if (name_len > 2 && p[name_len - 1] == '1' && p[name_len - 2] == ';')
name_len -= 2;
/* Chop off trailing '.' from filenames. */
if (name_len > 1 && p[name_len - 1] == '.')
--name_len;
archive_strncpy(&file->name, p, name_len);
if (iso9660->seenJoliet) {
/* Joliet names are max 64 chars (128 bytes) according to spec,
* but genisoimage (and others?) will allow you to have more.
*/
wchar_t wbuff[64+1], *wp;
const unsigned char *c;
flags = *(isodirrec + DR_flags_offset);
/* TODO: warn when name_len > 128 ? */
/* convert BE UTF-16 to wchar_t */
for (c = p, wp = wbuff;
c < (p + name_len) &&
wp < (wbuff + sizeof(wbuff)/sizeof(*wbuff) - 1);
c += 2) {
*wp++ = (((255 & (int)c[0]) << 8) | (255 & (int)c[1]));
}
*wp = L'\0';
#if 0 /* untested code, is it at all useful on Joliet? */
/* trim trailing first version and dot from filename.
*
* Remember we where in UTF-16BE land!
* SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
* 16 bits big endian characters on Joliet.
*
* TODO: sanitize filename?
* Joliet allows any UCS-2 char except:
* *, /, :, ;, ? and \.
*/
/* Chop off trailing ';1' from files. */
if (*(wp-2) == ';' && *(wp-1) == '1') {
wp-=2;
*wp = L'\0';
}
/* Chop off trailing '.' from filenames. */
if (*(wp-1) == '.')
*(--wp) = L'\0';
#endif
/* store the result in the file name field. */
archive_strappend_w_utf8(&file->name, wbuff);
} else {
/* Chop off trailing ';1' from files. */
if (name_len > 2 && p[name_len - 2] == ';' &&
p[name_len - 1] == '1')
name_len -= 2;
/* Chop off trailing '.' from filenames. */
if (name_len > 1 && p[name_len - 1] == '.')
--name_len;
archive_strncpy(&file->name, (const char *)p, name_len);
}
flags = isodirrec[DR_flags_offset];
if (flags & 0x02)
file->mode = AE_IFDIR | 0700;
else
@ -884,8 +1053,8 @@ parse_rockridge(struct iso9660 *iso9660, struct file_info *file,
}
static void
parse_rockridge_NM1(struct file_info *file, const unsigned char *data,
int data_length)
parse_rockridge_NM1(struct file_info *file,
const unsigned char *data, int data_length)
{
if (!file->name_continues)
archive_string_empty(&file->name);
@ -906,12 +1075,12 @@ parse_rockridge_NM1(struct file_info *file, const unsigned char *data,
case 0:
if (data_length < 2)
return;
archive_strncat(&file->name, data + 1, data_length - 1);
archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
break;
case 1:
if (data_length < 2)
return;
archive_strncat(&file->name, data + 1, data_length - 1);
archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
file->name_continues = 1;
break;
case 2:

View File

@ -57,17 +57,20 @@ DEFINE_TEST(test_read_format_iso_gz)
struct archive_entry *ae;
struct archive *a;
assert((a = archive_read_new()) != NULL);
assert(0 == archive_read_support_compression_all(a));
assert(0 == archive_read_support_format_all(a));
assert(0 == archive_read_open_memory(a, archive, sizeof(archive)));
assert(0 == archive_read_next_header(a, &ae));
assert(archive_compression(a) == ARCHIVE_COMPRESSION_GZIP);
assert(archive_format(a) == ARCHIVE_FORMAT_ISO9660);
assert(0 == archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_compression_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_GZIP);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
#if ARCHIVE_VERSION_NUMBER < 2000000
archive_read_finish(a);
#else
assert(0 == archive_read_finish(a));
assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
#endif
#else
skipping("Need zlib");

View File

@ -0,0 +1,198 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Based on libarchive/test/test_read_format_isorr_bz2.c with
* bugs introduced by Andreas Henriksson <andreas@fatal.se> for
* testing ISO9660 image with Joliet extension.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
__FBSDID("$FreeBSD$");
/*
Execute the following to rebuild the data for this program:
tail -n +35 test_read_format_isojoliet_bz2.c | /bin/sh
rm -rf /tmp/iso
mkdir /tmp/iso
mkdir /tmp/iso/dir
echo "hello" >/tmp/iso/long-joliet-file-name.textfile
ln /tmp/iso/long-joliet-file-name.textfile /tmp/iso/hardlink
(cd /tmp/iso; ln -s long-joliet-file-name.textfile symlink)
if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h
TZ=utc touch -afm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir
TZ=utc touch -afm -t 197001030000.02 /tmp/iso/symlink
else
TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir
TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
fi
mkhybrid -J -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isojoliet_bz2.iso.bz2
F=test_read_format_isojoliet_bz2.iso.bz2
uuencode $F $F > $F.uu
exit 1
*/
static void
joliettest(int withrr)
{
const char *refname = "test_read_format_isojoliet_bz2.iso.bz2";
struct archive_entry *ae;
struct archive *a;
const void *p;
size_t size;
off_t offset;
int r;
if (withrr) {
refname = "test_read_format_isojolietrr_bz2.iso.bz2";
}
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualInt(0, archive_read_support_compression_bzip2(a));
assertEqualInt(0, archive_read_support_format_all(a));
r = archive_read_open_filename(a, refname, 10240);
if (r == ARCHIVE_FATAL) {
skipping("Bzip2 decompression unsupported on this platform");
archive_read_finish(a);
return;
}
assertEqualInt(0, r);
/* First entry is '.' root directory. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString(".", archive_entry_pathname(ae));
assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
assertEqualInt(2048, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(0, archive_entry_mtime_nsec(ae));
assertEqualInt(86401, archive_entry_ctime(ae));
assertEqualInt(0, archive_entry_stat(ae)->st_nlink);
assertEqualInt(0, archive_entry_uid(ae));
assertEqualIntA(a, ARCHIVE_EOF,
archive_read_data_block(a, &p, &size, &offset));
assertEqualInt((int)size, 0);
/* A directory. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("dir", archive_entry_pathname(ae));
assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
assertEqualInt(2048, archive_entry_size(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(86401, archive_entry_atime(ae));
if (withrr) {
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
}
/* A hardlink to the regular file. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("hardlink", archive_entry_pathname(ae));
assert(S_ISREG(archive_entry_stat(ae)->st_mode));
if (withrr) {
assertEqualString("long-joliet-file-name.textfile",
archive_entry_hardlink(ae));
}
assertEqualInt(6, archive_entry_size(ae));
assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
assertEqualInt(6, (int)size);
assertEqualInt(0, offset);
assertEqualInt(0, memcmp(p, "hello\n", 6));
if (withrr) {
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(86401, archive_entry_atime(ae));
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
}
/* A regular file. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("long-joliet-file-name.textfile", archive_entry_pathname(ae));
assert(S_ISREG(archive_entry_stat(ae)->st_mode));
assertEqualInt(6, archive_entry_size(ae));
if (withrr) {
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(86401, archive_entry_atime(ae));
assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
}
/* A symlink to the regular file. */
assertEqualInt(0, archive_read_next_header(a, &ae));
assertEqualString("symlink", archive_entry_pathname(ae));
if (withrr) {
assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
assertEqualString("long-joliet-file-name.textfile",
archive_entry_symlink(ae));
}
assertEqualInt(0, archive_entry_size(ae));
assertEqualInt(172802, archive_entry_mtime(ae));
assertEqualInt(172802, archive_entry_atime(ae));
if (withrr) {
assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
assertEqualInt(1, archive_entry_uid(ae));
assertEqualInt(2, archive_entry_gid(ae));
}
/* End of archive. */
assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
/* Verify archive format. */
assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2);
if (withrr) {
assertEqualInt(archive_format(a),
ARCHIVE_FORMAT_ISO9660_ROCKRIDGE);
}
/* Close the archive. */
assertEqualInt(0, archive_read_close(a));
#if ARCHIVE_VERSION_NUMBER < 2000000
archive_read_finish(a);
#else
assertEqualInt(0, archive_read_finish(a));
#endif
}
DEFINE_TEST(test_read_format_isojoliet_bz2)
{
joliettest(0);
}
DEFINE_TEST(test_read_format_isojolietrr_bz2)
{
/* XXXX This doesn't work today; can it be made to work? */
#if 0
joliettest(1);
#else
skipping("Mixed Joliet/RR not fully supported yet.");
#endif
}

View File

@ -0,0 +1,30 @@
$FreeBSD$
begin 644 test_read_format_isojoliet_bz2.iso.bz2
M0EIH.3%!62936??^FX(``/9_^__?1_?^8__L/__?8:?_W&8@Z@$`9``008"`
M``+)"-`$/@=NN!W8[`8#23*GY-3U$](,0:`:`&"`9``9``T-'J::>B/4``#0
MIM$9&IA-!-0'I`>HT`&1Z@``T`!H`:#0'H(,E-(-3-$-&AB-`8C0`R9#1A`#
M1A/1`&@,@!H'``#0`-`&@``-&(`!H`````&@`D1)H0B-1O)&4V2:9#"9/4/2
M`/4>H'J-#(83U/$R@WZJ#>J&CREP**.W2R[".$_:J#$"N5P7:?.#4-4/..?K
M!KG\G]P="PX^ADTP4^Y%[1+0V,;$*HTA<YH1X6CK3!F8"7`;A,@`EG8))`'G
MYLMPLN;1!"O8FP$A)&H":4#8(8(3:3:$-\J'`$#0D"2+KH"UH5!(:5K`4"&`
MBEED63`R)H"L->&\V'@+*$<.M-0L@CLZ\Z(B=]`3`4%B"00B`FF@!-]HK<2.
M)?&IAD^/KKM>TRY#@+H5W781AM)P\\-4$&88^S$WX"2$=(X7(?,=$?H.A')A
M`%2T4:GEQRL:WS4Q=4SU(F>*JM1UEK\V`5P$L[9[D*;FBNEC^GPMAH8T>K&>
MQ)_.TSB;5G`P>)20L5V6':NL^M38\&.')5)<VW?:?;C$"2$CCX^2_;^AMLCJ
M6D&YOR".&EDU$BT1!NXZY!E+8([6_XMK'6H)J`-@`)0+P,WDFWI5CYW!GY8'
M$>)BO/*5`\P%H!`D7B2](0T)?Y0"`M3A6)'=($UL$@I$0$RBA0F4.!DAM`/@
M!V,L#/`+FC!;C.K58BA"1P\H1LVXG\@^"8IJ@0*0>TP@8F#0R^(M($"`"#I"
M`.FD45RN3EH2^8X6C/LKMKA;@K,T&ZZ%&PIJW%:>FG[.F=KGJ_O.(K`+0#!@
MQK&-G6!">H`4_/.<\CK)K+S/I/"?`9JG,TS^C1FI[O3NN(`Q^:*`Z1WEO()6
MZ*!0@MSD*1?AE*V5[='!>>O%XL8LXIOQB\@CIBM%\0JD'+MAR$"@T'8M;JFM
MLHN7HG1S:F]+B'BZ)SJ(=0,6*Z791QW+3RNI(7!E!)'@.B$(934!)D0=U#%#
MV21)DA=@4;RM?@RLG1[`<V&84KLL$TD01>,A:"YQF2!`P`2B)#APE)`^\F8V
M5_U]0O,4AE6?->8U4$<2N%TC-HD%($@9'E1DCQZ&B:X4\IUV83HQ7)<P7!,P
MIR1^V$C4.C/RRDR4C#)9',&OL&&"151Q"I]]+-'$K@MUH=B,RO!U3D/(89G6
M&4#&KI;&J92*590`%I72,/2VN>A'8I511-P`;=!!).^8X*0NHMB+.&!W"009
M,<;0G^>BA6F[;A;X2B!%?BP&(G7&@(,*O-QP;;1*`*6"F:X8D"Y$/T,(1JM'
M$>\,IQ&V6;/)!\)0C$,[;`O,`9A-HRHQ8@^PLT.?=7RL[2789J_J86!HF0T"
M3%@,A$VPC(:A@3(\&9-TZP2>KA*D>D;<^L4(H=<F2>EUT419R5`$A(R(Y-^O
+_B[DBG"A(>_]-P0`
`
end

View File

@ -0,0 +1,29 @@
$FreeBSD$
begin 644 test_read_format_isojolietrr_bz2.iso.bz2
M0EIH.3%!6293695"/:0``/9_^__?1??^8_WL/__?8:?_W&8@Z@$`9``008"`
M``+)"-`$/@36`T;`8#*3*GY3U-$R`T::`&F@`!HQ`T9&FC0T!Z@8C0``-"-$
M9&IA-!3U`9`:-``]0``#0T!H`](`'J9!P`---``9```-```-```R``&AH`<`
M#330`&0``#0``#0``,@`!H:`"1$FIBFBGE/&H;4/5!H&GJ9,C(&3]4>H&T@!
MX4S4_23)^I!^J&,I:"BCP:NQU49CQU07@K5:%N+FASC:#&<_H!T3^C_8,EAR
M>AAY@*??BYHEH;&-B%4:0N<T(WVCIS!B8"7$?23(`):&"20!Z.+9M%LXM0$*
MYB;`2$D;0)I0-@A@A-I-H0WYT.`(&A($D6VP&!H5!(:6!@*!#`12RR+)@9$T
M!6&2&\6?>+*$9NC-0L@CJ9)U!$ST`F*D.$$@A"`320`3$S7*"&2:*6P36])5
M/UEPPP-G5GGH*!-7B20Y.4AU"9MM0?K(C+%&%#XTJC<J5*I1P#3EJUM70F:Y
MWDJD^MOH1-$5UZS[;H9\0LB)J'47HU7N:N70S>ZZ.GH)4JHJ2)5-QVD^9IA`
MJ%BPT5G;#K;5KM8^'@["26<S<ZYKN5WT0@DA(Y.3ENW-UMLCV,!!W.*01QTL
MFHD8!$'>TJX1E,$$=G]<V72K4$U`'6`"4"X&<23;UJQ]3@T:H'@.-BN/(5`\
M\%IA`D7"2]80T)?]0"`P)PK$C>($UUB04B("910H3*'`R0R@/,#L98&B`7-&
M"[C.G57E"$CP=BMVJ(CYQYJ5$37&!`J`\K""HB!0#0RZ(M($"`9Q##2WW*HJ
M);;2U[_KWUN>.EE\=W@T_FK1D:C59VF:FHGY.JASX+#OO(K0+@#!@Q]C&S&H
M`7LV-TZ>LFMC7W3@.V;-37Q'^&I-3X>E;:0!I<(H#U#>7?02J"@4(*Z"%P[!
M6EG=HX+CKQ:+0*\$Q3=05!208:0Y"@I%)<\JQ^N8_<1<O3,FOS.]+B'?DF6$
M<X08[QZI\B%:>47'#8&2%E+]X01#.8H+0J!NJ=8/99+F^C?B4L"NABYS:$@T
M'/CG%2[+1.R0(O$0N!93,D"!H`F$B'`C,2"&!,YML_<*Q@:I#GK1GP-<J"61
M7B^1FX,%0#`V7&DR7#I<)[Q43'9;C.G)>FSA<4[2H)(;4,<ATZ.68FS$8;,Q
M[1_=@PT,54>0KAA2WE9%>%ON#\AF6`/K>AZ1ANTM,HF-?E[&N9,4K"B`+BOD
M8@EUE%*/R3*BB??@W::!E$)SBI"^BVHM`:'\%!%LYRN"?R"*%<;]L%PA*8D6
M&308D=DJ0@QK`WG%UU,P`J:*I[QA@7209C/",;1QGP#*<9E+.QRP=LH1>,W6
M!<9P9GG`,J,5X?86:?0MKY&=E+J,Q^(SV!J&$TR2_.,A$X(1A-HSDR/.S#PG
ILA)[>>5(]8W)ZY0BAMDR3TMM%$6<M0!(2,*.7OU_\7<D4X4)"50CVD``
`
end