~akopytov/percona-xtrabackup/bug1166888-2.0

« back to all changes in this revision

Viewing changes to src/libarchive/libarchive/archive_read_support_format_iso9660.c

  • Committer: Alexey Kopytov
  • Date: 2012-02-10 20:05:56 UTC
  • mto: This revision was merged to the branch mainline in revision 390.
  • Revision ID: akopytov@gmail.com-20120210200556-6kx41z8wwrqfucro
Rebase of the parallel compression patch on new trunk + post-review
fixes.

Implementation of parallel compression and streaming for XtraBackup.

This revision implements the following changes:

* InnoDB files are now streamed by the xtrabackup binary rather than
innobackupex. As a result, integrity is now verified by xtrabackup and
thus tar4ibd is no longer needed, so it was removed.

* xtrabackup binary now accepts the new '--stream' option which has
exactly the same semantics as the '--stream' option in
innobackupex: it tells xtrabackup to stream all files to the standard
output in the specified format rather than storing them locally.

* The xtrabackup binary can now do parallel compression using the
quicklz library. Two new options were added to xtrabackup to support
this feature:

- '--compress' tells xtrabackup to compress all output data, including
the transaction log file and meta data files, using the specified
compression algorithm. The only currently supported algorithm is
'quicklz'. The resulting files have the qpress archive format,
i.e. every *.qp file produced by xtrabackup is essentially a one-file
qpress archive and can be extracted and uncompressed by the qpress
file archiver (http://www.quicklz.com/).

- '--compress-threads' specifies the number of worker threads used by
xtrabackup for parallel data compression. This option defaults to 1.

Parallel compression ('--compress-threads') can be used together with
parallel file copying ('--parallel'). For example, '--parallel=4
--compress --compress-threads=2' will create 4 IO threads that will
read the data and pipe it to 2 compression threads.

* To support simultaneous compression and streaming, a new custom
streaming format called 'xbstream' was introduced to XtraBackup in
addition to the 'tar' format. That was required to overcome some
limitations of traditional archive formats such as 'tar', 'cpio' and
others that do not allow streaming dynamically generated files, for
example dynamically compressed files.  Other advantages of xbstream over
traditional streaming/archive formats include ability to stream multiple
files concurrently (so it is possible to use streaming in the xbstream
format together with the --parallel option) and more compact data
storage.

* To allow streaming and extracting files to/from the xbstream format
produced by xtrabackup, a new utility aptly called 'xbstream' was
added to the XtraBackup distribution. This utility has a tar-like
interface:

- with the '-x' option it extracts files from the stream read from its
standard input to the current directory unless specified otherwise
with the '-C' option.

- with the '-c' option it streams files specified on the command line
to its standard output.

The utility also tries to minimize its impact on the OS page cache by
using the appropriate posix_fadvise() calls when available.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2003-2007 Tim Kientzle
 
3
 * Copyright (c) 2009 Andreas Henriksson <andreas@fatal.se>
 
4
 * Copyright (c) 2009 Michihiro NAKAJIMA
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions
 
9
 * are met:
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
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 "archive_platform.h"
 
29
__FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_iso9660.c 201246 2009-12-30 05:30:35Z kientzle $");
 
30
 
 
31
#ifdef HAVE_ERRNO_H
 
32
#include <errno.h>
 
33
#endif
 
34
/* #include <stdint.h> */ /* See archive_platform.h */
 
35
#include <stdio.h>
 
36
#ifdef HAVE_STDLIB_H
 
37
#include <stdlib.h>
 
38
#endif
 
39
#ifdef HAVE_STRING_H
 
40
#include <string.h>
 
41
#endif
 
42
#include <time.h>
 
43
#ifdef HAVE_ZLIB_H
 
44
#include <zlib.h>
 
45
#endif
 
46
 
 
47
#include "archive.h"
 
48
#include "archive_endian.h"
 
49
#include "archive_entry.h"
 
50
#include "archive_private.h"
 
51
#include "archive_read_private.h"
 
52
#include "archive_string.h"
 
53
 
 
54
/*
 
55
 * An overview of ISO 9660 format:
 
56
 *
 
57
 * Each disk is laid out as follows:
 
58
 *   * 32k reserved for private use
 
59
 *   * Volume descriptor table.  Each volume descriptor
 
60
 *     is 2k and specifies basic format information.
 
61
 *     The "Primary Volume Descriptor" (PVD) is defined by the
 
62
 *     standard and should always be present; other volume
 
63
 *     descriptors include various vendor-specific extensions.
 
64
 *   * Files and directories.  Each file/dir is specified by
 
65
 *     an "extent" (starting sector and length in bytes).
 
66
 *     Dirs are just files with directory records packed one
 
67
 *     after another.  The PVD contains a single dir entry
 
68
 *     specifying the location of the root directory.  Everything
 
69
 *     else follows from there.
 
70
 *
 
71
 * This module works by first reading the volume descriptors, then
 
72
 * building a list of directory entries, sorted by starting
 
73
 * sector.  At each step, I look for the earliest dir entry that
 
74
 * hasn't yet been read, seek forward to that location and read
 
75
 * that entry.  If it's a dir, I slurp in the new dir entries and
 
76
 * add them to the heap; if it's a regular file, I return the
 
77
 * corresponding archive_entry and wait for the client to request
 
78
 * the file body.  This strategy allows us to read most compliant
 
79
 * CDs with a single pass through the data, as required by libarchive.
 
80
 */
 
81
#define LOGICAL_BLOCK_SIZE      2048
 
82
#define SYSTEM_AREA_BLOCK       16
 
83
 
 
84
/* Structure of on-disk primary volume descriptor. */
 
85
#define PVD_type_offset 0
 
86
#define PVD_type_size 1
 
87
#define PVD_id_offset (PVD_type_offset + PVD_type_size)
 
88
#define PVD_id_size 5
 
89
#define PVD_version_offset (PVD_id_offset + PVD_id_size)
 
90
#define PVD_version_size 1
 
91
#define PVD_reserved1_offset (PVD_version_offset + PVD_version_size)
 
92
#define PVD_reserved1_size 1
 
93
#define PVD_system_id_offset (PVD_reserved1_offset + PVD_reserved1_size)
 
94
#define PVD_system_id_size 32
 
95
#define PVD_volume_id_offset (PVD_system_id_offset + PVD_system_id_size)
 
96
#define PVD_volume_id_size 32
 
97
#define PVD_reserved2_offset (PVD_volume_id_offset + PVD_volume_id_size)
 
98
#define PVD_reserved2_size 8
 
99
#define PVD_volume_space_size_offset (PVD_reserved2_offset + PVD_reserved2_size)
 
100
#define PVD_volume_space_size_size 8
 
101
#define PVD_reserved3_offset (PVD_volume_space_size_offset + PVD_volume_space_size_size)
 
102
#define PVD_reserved3_size 32
 
103
#define PVD_volume_set_size_offset (PVD_reserved3_offset + PVD_reserved3_size)
 
104
#define PVD_volume_set_size_size 4
 
105
#define PVD_volume_sequence_number_offset (PVD_volume_set_size_offset + PVD_volume_set_size_size)
 
106
#define PVD_volume_sequence_number_size 4
 
107
#define PVD_logical_block_size_offset (PVD_volume_sequence_number_offset + PVD_volume_sequence_number_size)
 
108
#define PVD_logical_block_size_size 4
 
109
#define PVD_path_table_size_offset (PVD_logical_block_size_offset + PVD_logical_block_size_size)
 
110
#define PVD_path_table_size_size 8
 
111
#define PVD_type_1_path_table_offset (PVD_path_table_size_offset + PVD_path_table_size_size)
 
112
#define PVD_type_1_path_table_size 4
 
113
#define PVD_opt_type_1_path_table_offset (PVD_type_1_path_table_offset + PVD_type_1_path_table_size)
 
114
#define PVD_opt_type_1_path_table_size 4
 
115
#define PVD_type_m_path_table_offset (PVD_opt_type_1_path_table_offset + PVD_opt_type_1_path_table_size)
 
116
#define PVD_type_m_path_table_size 4
 
117
#define PVD_opt_type_m_path_table_offset (PVD_type_m_path_table_offset + PVD_type_m_path_table_size)
 
118
#define PVD_opt_type_m_path_table_size 4
 
119
#define PVD_root_directory_record_offset (PVD_opt_type_m_path_table_offset + PVD_opt_type_m_path_table_size)
 
120
#define PVD_root_directory_record_size 34
 
121
#define PVD_volume_set_id_offset (PVD_root_directory_record_offset + PVD_root_directory_record_size)
 
122
#define PVD_volume_set_id_size 128
 
123
#define PVD_publisher_id_offset (PVD_volume_set_id_offset + PVD_volume_set_id_size)
 
124
#define PVD_publisher_id_size 128
 
125
#define PVD_preparer_id_offset (PVD_publisher_id_offset + PVD_publisher_id_size)
 
126
#define PVD_preparer_id_size 128
 
127
#define PVD_application_id_offset (PVD_preparer_id_offset + PVD_preparer_id_size)
 
128
#define PVD_application_id_size 128
 
129
#define PVD_copyright_file_id_offset (PVD_application_id_offset + PVD_application_id_size)
 
130
#define PVD_copyright_file_id_size 37
 
131
#define PVD_abstract_file_id_offset (PVD_copyright_file_id_offset + PVD_copyright_file_id_size)
 
132
#define PVD_abstract_file_id_size 37
 
133
#define PVD_bibliographic_file_id_offset (PVD_abstract_file_id_offset + PVD_abstract_file_id_size)
 
134
#define PVD_bibliographic_file_id_size 37
 
135
#define PVD_creation_date_offset (PVD_bibliographic_file_id_offset + PVD_bibliographic_file_id_size)
 
136
#define PVD_creation_date_size 17
 
137
#define PVD_modification_date_offset (PVD_creation_date_offset + PVD_creation_date_size)
 
138
#define PVD_modification_date_size 17
 
139
#define PVD_expiration_date_offset (PVD_modification_date_offset + PVD_modification_date_size)
 
140
#define PVD_expiration_date_size 17
 
141
#define PVD_effective_date_offset (PVD_expiration_date_offset + PVD_expiration_date_size)
 
142
#define PVD_effective_date_size 17
 
143
#define PVD_file_structure_version_offset (PVD_effective_date_offset + PVD_effective_date_size)
 
144
#define PVD_file_structure_version_size 1
 
145
#define PVD_reserved4_offset (PVD_file_structure_version_offset + PVD_file_structure_version_size)
 
146
#define PVD_reserved4_size 1
 
147
#define PVD_application_data_offset (PVD_reserved4_offset + PVD_reserved4_size)
 
148
#define PVD_application_data_size 512
 
149
#define PVD_reserved5_offset (PVD_application_data_offset + PVD_application_data_size)
 
150
#define PVD_reserved5_size (2048 - PVD_reserved5_offset)
 
151
 
 
152
/* TODO: It would make future maintenance easier to just hardcode the
 
153
 * above values.  In particular, ECMA119 states the offsets as part of
 
154
 * the standard.  That would eliminate the need for the following check.*/
 
155
#if PVD_reserved5_offset != 1395
 
156
#error PVD offset and size definitions are wrong.
 
157
#endif
 
158
 
 
159
 
 
160
/* Structure of optional on-disk supplementary volume descriptor. */
 
161
#define SVD_type_offset 0
 
162
#define SVD_type_size 1
 
163
#define SVD_id_offset (SVD_type_offset + SVD_type_size)
 
164
#define SVD_id_size 5
 
165
#define SVD_version_offset (SVD_id_offset + SVD_id_size)
 
166
#define SVD_version_size 1
 
167
/* ... */
 
168
#define SVD_reserved1_offset    72
 
169
#define SVD_reserved1_size      8
 
170
#define SVD_volume_space_size_offset 80
 
171
#define SVD_volume_space_size_size 8
 
172
#define SVD_escape_sequences_offset (SVD_volume_space_size_offset + SVD_volume_space_size_size)
 
173
#define SVD_escape_sequences_size 32
 
174
/* ... */
 
175
#define SVD_logical_block_size_offset 128
 
176
#define SVD_logical_block_size_size 4
 
177
#define SVD_type_L_path_table_offset 140
 
178
#define SVD_type_M_path_table_offset 148
 
179
/* ... */
 
180
#define SVD_root_directory_record_offset 156
 
181
#define SVD_root_directory_record_size 34
 
182
#define SVD_file_structure_version_offset 881
 
183
#define SVD_reserved2_offset    882
 
184
#define SVD_reserved2_size      1
 
185
#define SVD_reserved3_offset    1395
 
186
#define SVD_reserved3_size      653
 
187
/* ... */
 
188
/* FIXME: validate correctness of last SVD entry offset. */
 
189
 
 
190
/* Structure of an on-disk directory record. */
 
191
/* Note:  ISO9660 stores each multi-byte integer twice, once in
 
192
 * each byte order.  The sizes here are the size of just one
 
193
 * of the two integers.  (This is why the offset of a field isn't
 
194
 * the same as the offset+size of the previous field.) */
 
195
#define DR_length_offset 0
 
196
#define DR_length_size 1
 
197
#define DR_ext_attr_length_offset 1
 
198
#define DR_ext_attr_length_size 1
 
199
#define DR_extent_offset 2
 
200
#define DR_extent_size 4
 
201
#define DR_size_offset 10
 
202
#define DR_size_size 4
 
203
#define DR_date_offset 18
 
204
#define DR_date_size 7
 
205
#define DR_flags_offset 25
 
206
#define DR_flags_size 1
 
207
#define DR_file_unit_size_offset 26
 
208
#define DR_file_unit_size_size 1
 
209
#define DR_interleave_offset 27
 
210
#define DR_interleave_size 1
 
211
#define DR_volume_sequence_number_offset 28
 
212
#define DR_volume_sequence_number_size 2
 
213
#define DR_name_len_offset 32
 
214
#define DR_name_len_size 1
 
215
#define DR_name_offset 33
 
216
 
 
217
#ifdef HAVE_ZLIB_H
 
218
static const unsigned char zisofs_magic[8] = {
 
219
        0x37, 0xE4, 0x53, 0x96, 0xC9, 0xDB, 0xD6, 0x07
 
220
};
 
221
 
 
222
struct zisofs {
 
223
        /* Set 1 if this file compressed by paged zlib */
 
224
        int              pz;
 
225
        int              pz_log2_bs; /* Log2 of block size */
 
226
        uint64_t         pz_uncompressed_size;
 
227
 
 
228
        int              initialized;
 
229
        unsigned char   *uncompressed_buffer;
 
230
        size_t           uncompressed_buffer_size;
 
231
 
 
232
        uint32_t         pz_offset;
 
233
        unsigned char    header[16];
 
234
        size_t           header_avail;
 
235
        int              header_passed;
 
236
        unsigned char   *block_pointers;
 
237
        size_t           block_pointers_alloc;
 
238
        size_t           block_pointers_size;
 
239
        size_t           block_pointers_avail;
 
240
        size_t           block_off;
 
241
        uint32_t         block_avail;
 
242
 
 
243
        z_stream         stream;
 
244
        int              stream_valid;
 
245
};
 
246
#else
 
247
struct zisofs {
 
248
        /* Set 1 if this file compressed by paged zlib */
 
249
        int              pz;
 
250
};
 
251
#endif
 
252
 
 
253
struct content {
 
254
        uint64_t         offset;/* Offset on disk.              */
 
255
        uint64_t         size;  /* File size in bytes.          */
 
256
        struct content  *next;
 
257
};
 
258
 
 
259
/* In-memory storage for a directory record. */
 
260
struct file_info {
 
261
        struct file_info        *use_next;
 
262
        struct file_info        *parent;
 
263
        struct file_info        *next;
 
264
        int              subdirs;
 
265
        uint64_t         key;           /* Heap Key.                    */
 
266
        uint64_t         offset;        /* Offset on disk.              */
 
267
        uint64_t         size;          /* File size in bytes.          */
 
268
        uint32_t         ce_offset;     /* Offset of CE.                */
 
269
        uint32_t         ce_size;       /* Size of CE.                  */
 
270
        char             re;            /* Having RRIP "RE" extension.  */
 
271
        uint64_t         cl_offset;     /* Having RRIP "CL" extension.  */
 
272
        int              birthtime_is_set;
 
273
        time_t           birthtime;     /* File created time.           */
 
274
        time_t           mtime;         /* File last modified time.     */
 
275
        time_t           atime;         /* File last accessed time.     */
 
276
        time_t           ctime;         /* File attribute change time.  */
 
277
        uint64_t         rdev;          /* Device number.               */
 
278
        mode_t           mode;
 
279
        uid_t            uid;
 
280
        gid_t            gid;
 
281
        int64_t          number;
 
282
        int              nlinks;
 
283
        struct archive_string name; /* Pathname */
 
284
        char             name_continues; /* Non-zero if name continues */
 
285
        struct archive_string symlink;
 
286
        char             symlink_continues; /* Non-zero if link continues */
 
287
        /* Set 1 if this file compressed by paged zlib(zisofs) */
 
288
        int              pz;
 
289
        int              pz_log2_bs; /* Log2 of block size */
 
290
        uint64_t         pz_uncompressed_size;
 
291
        /* Set 1 if this file is multi extent. */
 
292
        int              multi_extent;
 
293
        struct {
 
294
                struct content  *first;
 
295
                struct content  **last;
 
296
        } contents;
 
297
        char             exposed;
 
298
};
 
299
 
 
300
struct heap_queue {
 
301
        struct file_info **files;
 
302
        int              allocated;
 
303
        int              used;
 
304
};
 
305
 
 
306
struct iso9660 {
 
307
        int     magic;
 
308
#define ISO9660_MAGIC   0x96609660
 
309
 
 
310
        int opt_support_joliet;
 
311
        int opt_support_rockridge;
 
312
 
 
313
        struct archive_string pathname;
 
314
        char    seenRockridge;  /* Set true if RR extensions are used. */
 
315
        char    seenSUSP;       /* Set true if SUSP is beging used. */
 
316
        char    seenJoliet;
 
317
 
 
318
        unsigned char   suspOffset;
 
319
        struct file_info *rr_moved;
 
320
        struct heap_queue                re_dirs;
 
321
        struct heap_queue                cl_files;
 
322
        struct read_ce_queue {
 
323
                struct read_ce_req {
 
324
                        uint64_t         offset;/* Offset of CE on disk. */
 
325
                        struct file_info *file;
 
326
                }               *reqs;
 
327
                int              cnt;
 
328
                int              allocated;
 
329
        }       read_ce_req;
 
330
 
 
331
        int64_t         previous_number;
 
332
        struct archive_string previous_pathname;
 
333
 
 
334
        struct file_info                *use_files;
 
335
        struct heap_queue                pending_files;
 
336
        struct {
 
337
                struct file_info        *first;
 
338
                struct file_info        **last;
 
339
        }       cache_files;
 
340
 
 
341
        uint64_t current_position;
 
342
        ssize_t logical_block_size;
 
343
        uint64_t volume_size; /* Total size of volume in bytes. */
 
344
        int32_t  volume_block;/* Total size of volume in logical blocks. */
 
345
 
 
346
        struct vd {
 
347
                int             location;       /* Location of Extent.  */
 
348
                uint32_t        size;
 
349
        } primary, joliet;
 
350
 
 
351
        off_t   entry_sparse_offset;
 
352
        int64_t entry_bytes_remaining;
 
353
        struct zisofs    entry_zisofs;
 
354
        struct content  *entry_content;
 
355
};
 
356
 
 
357
static int      archive_read_format_iso9660_bid(struct archive_read *);
 
358
static int      archive_read_format_iso9660_options(struct archive_read *,
 
359
                    const char *, const char *);
 
360
static int      archive_read_format_iso9660_cleanup(struct archive_read *);
 
361
static int      archive_read_format_iso9660_read_data(struct archive_read *,
 
362
                    const void **, size_t *, off_t *);
 
363
static int      archive_read_format_iso9660_read_data_skip(struct archive_read *);
 
364
static int      archive_read_format_iso9660_read_header(struct archive_read *,
 
365
                    struct archive_entry *);
 
366
static const char *build_pathname(struct archive_string *, struct file_info *);
 
367
#if DEBUG
 
368
static void     dump_isodirrec(FILE *, const unsigned char *isodirrec);
 
369
#endif
 
370
static time_t   time_from_tm(struct tm *);
 
371
static time_t   isodate17(const unsigned char *);
 
372
static time_t   isodate7(const unsigned char *);
 
373
static int      isBootRecord(struct iso9660 *, const unsigned char *);
 
374
static int      isVolumePartition(struct iso9660 *, const unsigned char *);
 
375
static int      isVDSetTerminator(struct iso9660 *, const unsigned char *);
 
376
static int      isJolietSVD(struct iso9660 *, const unsigned char *);
 
377
static int      isSVD(struct iso9660 *, const unsigned char *);
 
378
static int      isEVD(struct iso9660 *, const unsigned char *);
 
379
static int      isPVD(struct iso9660 *, const unsigned char *);
 
380
static struct file_info *next_cache_entry(struct iso9660 *iso9660);
 
381
static int      next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
 
382
                    struct file_info **pfile);
 
383
static struct file_info *
 
384
                parse_file_info(struct archive_read *a,
 
385
                    struct file_info *parent, const unsigned char *isodirrec);
 
386
static int      parse_rockridge(struct archive_read *a,
 
387
                    struct file_info *file, const unsigned char *start,
 
388
                    const unsigned char *end);
 
389
static int      register_CE(struct archive_read *a, int32_t location,
 
390
                    struct file_info *file);
 
391
static int      read_CE(struct archive_read *a, struct iso9660 *iso9660);
 
392
static void     parse_rockridge_NM1(struct file_info *,
 
393
                    const unsigned char *, int);
 
394
static void     parse_rockridge_SL1(struct file_info *,
 
395
                    const unsigned char *, int);
 
396
static void     parse_rockridge_TF1(struct file_info *,
 
397
                    const unsigned char *, int);
 
398
static void     parse_rockridge_ZF1(struct file_info *,
 
399
                    const unsigned char *, int);
 
400
static void     register_file(struct iso9660 *, struct file_info *);
 
401
static void     release_files(struct iso9660 *);
 
402
static unsigned toi(const void *p, int n);
 
403
static inline void cache_add_entry(struct iso9660 *iso9660,
 
404
                    struct file_info *file);
 
405
static inline void cache_add_to_next_of_parent(struct iso9660 *iso9660,
 
406
                    struct file_info *file);
 
407
static inline struct file_info *cache_get_entry(struct iso9660 *iso9660);
 
408
static void     heap_add_entry(struct heap_queue *heap,
 
409
                    struct file_info *file, uint64_t key);
 
410
static struct file_info *heap_get_entry(struct heap_queue *heap);
 
411
 
 
412
#define add_entry(iso9660, file)        \
 
413
        heap_add_entry(&((iso9660)->pending_files), file, file->offset)
 
414
#define next_entry(iso9660)             \
 
415
        heap_get_entry(&((iso9660)->pending_files))
 
416
 
 
417
int
 
418
archive_read_support_format_iso9660(struct archive *_a)
 
419
{
 
420
        struct archive_read *a = (struct archive_read *)_a;
 
421
        struct iso9660 *iso9660;
 
422
        int r;
 
423
 
 
424
        iso9660 = (struct iso9660 *)malloc(sizeof(*iso9660));
 
425
        if (iso9660 == NULL) {
 
426
                archive_set_error(&a->archive, ENOMEM, "Can't allocate iso9660 data");
 
427
                return (ARCHIVE_FATAL);
 
428
        }
 
429
        memset(iso9660, 0, sizeof(*iso9660));
 
430
        iso9660->magic = ISO9660_MAGIC;
 
431
        iso9660->cache_files.first = NULL;
 
432
        iso9660->cache_files.last = &(iso9660->cache_files.first);
 
433
        /* Enable to support Joliet extensions by default.      */
 
434
        iso9660->opt_support_joliet = 1;
 
435
        /* Enable to support Rock Ridge extensions by default.  */
 
436
        iso9660->opt_support_rockridge = 1;
 
437
 
 
438
        r = __archive_read_register_format(a,
 
439
            iso9660,
 
440
            "iso9660",
 
441
            archive_read_format_iso9660_bid,
 
442
            archive_read_format_iso9660_options,
 
443
            archive_read_format_iso9660_read_header,
 
444
            archive_read_format_iso9660_read_data,
 
445
            archive_read_format_iso9660_read_data_skip,
 
446
            archive_read_format_iso9660_cleanup);
 
447
 
 
448
        if (r != ARCHIVE_OK) {
 
449
                free(iso9660);
 
450
                return (r);
 
451
        }
 
452
        return (ARCHIVE_OK);
 
453
}
 
454
 
 
455
 
 
456
static int
 
457
archive_read_format_iso9660_bid(struct archive_read *a)
 
458
{
 
459
        struct iso9660 *iso9660;
 
460
        ssize_t bytes_read;
 
461
        const void *h;
 
462
        const unsigned char *p;
 
463
        int seenTerminator;
 
464
 
 
465
        iso9660 = (struct iso9660 *)(a->format->data);
 
466
 
 
467
        /*
 
468
         * Skip the first 32k (reserved area) and get the first
 
469
         * 8 sectors of the volume descriptor table.  Of course,
 
470
         * if the I/O layer gives us more, we'll take it.
 
471
         */
 
472
#define RESERVED_AREA   (SYSTEM_AREA_BLOCK * LOGICAL_BLOCK_SIZE)
 
473
        h = __archive_read_ahead(a,
 
474
            RESERVED_AREA + 8 * LOGICAL_BLOCK_SIZE,
 
475
            &bytes_read);
 
476
        if (h == NULL)
 
477
            return (-1);
 
478
        p = (const unsigned char *)h;
 
479
 
 
480
        /* Skip the reserved area. */
 
481
        bytes_read -= RESERVED_AREA;
 
482
        p += RESERVED_AREA;
 
483
 
 
484
        /* Check each volume descriptor. */
 
485
        seenTerminator = 0;
 
486
        for (; bytes_read > LOGICAL_BLOCK_SIZE;
 
487
            bytes_read -= LOGICAL_BLOCK_SIZE, p += LOGICAL_BLOCK_SIZE) {
 
488
                /* Do not handle undefined Volume Descriptor Type. */
 
489
                if (p[0] >= 4 && p[0] <= 254)
 
490
                        return (0);
 
491
                /* Standard Identifier must be "CD001" */
 
492
                if (memcmp(p + 1, "CD001", 5) != 0)
 
493
                        return (0);
 
494
                if (!iso9660->primary.location) {
 
495
                        if (isPVD(iso9660, p))
 
496
                                continue;
 
497
                }
 
498
                if (!iso9660->joliet.location) {
 
499
                        if (isJolietSVD(iso9660, p))
 
500
                                continue;
 
501
                }
 
502
                if (isBootRecord(iso9660, p))
 
503
                        continue;
 
504
                if (isEVD(iso9660, p))
 
505
                        continue;
 
506
                if (isSVD(iso9660, p))
 
507
                        continue;
 
508
                if (isVolumePartition(iso9660, p))
 
509
                        continue;
 
510
                if (isVDSetTerminator(iso9660, p)) {
 
511
                        seenTerminator = 1;
 
512
                        break;
 
513
                }
 
514
                return (0);
 
515
        }
 
516
        /*
 
517
         * ISO 9660 format must have Primary Volume Descriptor and
 
518
         * Volume Descriptor Set Terminator.
 
519
         */
 
520
        if (seenTerminator && iso9660->primary.location > 16)
 
521
                return (48);
 
522
 
 
523
        /* We didn't find a valid PVD; return a bid of zero. */
 
524
        return (0);
 
525
}
 
526
 
 
527
static int
 
528
archive_read_format_iso9660_options(struct archive_read *a,
 
529
                const char *key, const char *val)
 
530
{
 
531
        struct iso9660 *iso9660;
 
532
 
 
533
        iso9660 = (struct iso9660 *)(a->format->data);
 
534
 
 
535
        if (strcmp(key, "joliet") == 0) {
 
536
                if (val == NULL || strcmp(val, "off") == 0 ||
 
537
                                strcmp(val, "ignore") == 0 ||
 
538
                                strcmp(val, "disable") == 0 ||
 
539
                                strcmp(val, "0") == 0)
 
540
                        iso9660->opt_support_joliet = 0;
 
541
                else
 
542
                        iso9660->opt_support_joliet = 1;
 
543
                return (ARCHIVE_OK);
 
544
        }
 
545
        if (strcmp(key, "rockridge") == 0 ||
 
546
            strcmp(key, "Rockridge") == 0) {
 
547
                iso9660->opt_support_rockridge = val != NULL;
 
548
                return (ARCHIVE_OK);
 
549
        }
 
550
 
 
551
        /* Note: The "warn" return is just to inform the options
 
552
         * supervisor that we didn't handle it.  It will generate
 
553
         * a suitable error if noone used this option. */
 
554
        return (ARCHIVE_WARN);
 
555
}
 
556
 
 
557
static int
 
558
isBootRecord(struct iso9660 *iso9660, const unsigned char *h)
 
559
{
 
560
        (void)iso9660; /* UNUSED */
 
561
 
 
562
        /* Type of the Volume Descriptor Boot Record must be 0. */
 
563
        if (h[0] != 0)
 
564
                return (0);
 
565
 
 
566
        /* Volume Descriptor Version must be 1. */
 
567
        if (h[6] != 1)
 
568
                return (0);
 
569
 
 
570
        return (1);
 
571
}
 
572
 
 
573
static int
 
574
isVolumePartition(struct iso9660 *iso9660, const unsigned char *h)
 
575
{
 
576
        int32_t location;
 
577
 
 
578
        /* Type of the Volume Partition Descriptor must be 3. */
 
579
        if (h[0] != 3)
 
580
                return (0);
 
581
 
 
582
        /* Volume Descriptor Version must be 1. */
 
583
        if (h[6] != 1)
 
584
                return (0);
 
585
        /* Unused Field */
 
586
        if (h[7] != 0)
 
587
                return (0);
 
588
 
 
589
        location = archive_le32dec(h + 72);
 
590
        if (location <= SYSTEM_AREA_BLOCK ||
 
591
            location >= iso9660->volume_block)
 
592
                return (0);
 
593
        if ((uint32_t)location != archive_be32dec(h + 76))
 
594
                return (0);
 
595
 
 
596
        return (1);
 
597
}
 
598
 
 
599
static int
 
600
isVDSetTerminator(struct iso9660 *iso9660, const unsigned char *h)
 
601
{
 
602
        int i;
 
603
 
 
604
        (void)iso9660; /* UNUSED */
 
605
 
 
606
        /* Type of the Volume Descriptor Set Terminator must be 255. */
 
607
        if (h[0] != 255)
 
608
                return (0);
 
609
 
 
610
        /* Volume Descriptor Version must be 1. */
 
611
        if (h[6] != 1)
 
612
                return (0);
 
613
 
 
614
        /* Reserved field must be 0. */
 
615
        for (i = 7; i < 2048; ++i)
 
616
                if (h[i] != 0)
 
617
                        return (0);
 
618
 
 
619
        return (1);
 
620
}
 
621
 
 
622
static int
 
623
isJolietSVD(struct iso9660 *iso9660, const unsigned char *h)
 
624
{
 
625
        const unsigned char *p;
 
626
        ssize_t logical_block_size;
 
627
        int32_t volume_block;
 
628
 
 
629
        /* Check if current sector is a kind of Supplementary Volume
 
630
         * Descriptor. */
 
631
        if (!isSVD(iso9660, h))
 
632
                return (0);
 
633
 
 
634
        /* FIXME: do more validations according to joliet spec. */
 
635
 
 
636
        /* check if this SVD contains joliet extension! */
 
637
        p = h + SVD_escape_sequences_offset;
 
638
        /* N.B. Joliet spec says p[1] == '\\', but.... */
 
639
        if (p[0] == '%' && p[1] == '/') {
 
640
                int level = 0;
 
641
 
 
642
                if (p[2] == '@')
 
643
                        level = 1;
 
644
                else if (p[2] == 'C')
 
645
                        level = 2;
 
646
                else if (p[2] == 'E')
 
647
                        level = 3;
 
648
                else /* not joliet */
 
649
                        return (0);
 
650
 
 
651
                iso9660->seenJoliet = level;
 
652
 
 
653
        } else /* not joliet */
 
654
                return (0);
 
655
 
 
656
        logical_block_size =
 
657
            archive_le16dec(h + SVD_logical_block_size_offset);
 
658
        volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
 
659
 
 
660
        iso9660->logical_block_size = logical_block_size;
 
661
        iso9660->volume_block = volume_block;
 
662
        iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
 
663
        /* Read Root Directory Record in Volume Descriptor. */
 
664
        p = h + SVD_root_directory_record_offset;
 
665
        iso9660->joliet.location = archive_le32dec(p + DR_extent_offset);
 
666
        iso9660->joliet.size = archive_le32dec(p + DR_size_offset);
 
667
 
 
668
        return (48);
 
669
}
 
670
 
 
671
static int
 
672
isSVD(struct iso9660 *iso9660, const unsigned char *h)
 
673
{
 
674
        const unsigned char *p;
 
675
        ssize_t logical_block_size;
 
676
        int32_t volume_block;
 
677
        int32_t location;
 
678
        int i;
 
679
 
 
680
        (void)iso9660; /* UNUSED */
 
681
 
 
682
        /* Type 2 means it's a SVD. */
 
683
        if (h[SVD_type_offset] != 2)
 
684
                return (0);
 
685
 
 
686
        /* Reserved field must be 0. */
 
687
        for (i = 0; i < SVD_reserved1_size; ++i)
 
688
                if (h[SVD_reserved1_offset + i] != 0)
 
689
                        return (0);
 
690
        for (i = 0; i < SVD_reserved2_size; ++i)
 
691
                if (h[SVD_reserved2_offset + i] != 0)
 
692
                        return (0);
 
693
        for (i = 0; i < SVD_reserved3_size; ++i)
 
694
                if (h[SVD_reserved3_offset + i] != 0)
 
695
                        return (0);
 
696
 
 
697
        /* File structure version must be 1 for ISO9660/ECMA119. */
 
698
        if (h[SVD_file_structure_version_offset] != 1)
 
699
                return (0);
 
700
 
 
701
        logical_block_size =
 
702
            archive_le16dec(h + SVD_logical_block_size_offset);
 
703
        if (logical_block_size <= 0)
 
704
                return (0);
 
705
 
 
706
        volume_block = archive_le32dec(h + SVD_volume_space_size_offset);
 
707
        if (volume_block <= SYSTEM_AREA_BLOCK+4)
 
708
                return (0);
 
709
 
 
710
        /* Location of Occurrence of Type L Path Table must be
 
711
         * available location,
 
712
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
713
        location = archive_le32dec(h+SVD_type_L_path_table_offset);
 
714
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
715
                return (0);
 
716
 
 
717
        /* Location of Occurrence of Type M Path Table must be
 
718
         * available location,
 
719
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
720
        location = archive_be32dec(h+SVD_type_M_path_table_offset);
 
721
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
722
                return (0);
 
723
 
 
724
        /* Read Root Directory Record in Volume Descriptor. */
 
725
        p = h + SVD_root_directory_record_offset;
 
726
        if (p[DR_length_offset] != 34)
 
727
                return (0);
 
728
 
 
729
        return (48);
 
730
}
 
731
 
 
732
static int
 
733
isEVD(struct iso9660 *iso9660, const unsigned char *h)
 
734
{
 
735
        const unsigned char *p;
 
736
        ssize_t logical_block_size;
 
737
        int32_t volume_block;
 
738
        int32_t location;
 
739
        int i;
 
740
 
 
741
        (void)iso9660; /* UNUSED */
 
742
 
 
743
        /* Type of the Enhanced Volume Descriptor must be 2. */
 
744
        if (h[PVD_type_offset] != 2)
 
745
                return (0);
 
746
 
 
747
        /* EVD version must be 2. */
 
748
        if (h[PVD_version_offset] != 2)
 
749
                return (0);
 
750
 
 
751
        /* Reserved field must be 0. */
 
752
        if (h[PVD_reserved1_offset] != 0)
 
753
                return (0);
 
754
 
 
755
        /* Reserved field must be 0. */
 
756
        for (i = 0; i < PVD_reserved2_size; ++i)
 
757
                if (h[PVD_reserved2_offset + i] != 0)
 
758
                        return (0);
 
759
 
 
760
        /* Reserved field must be 0. */
 
761
        for (i = 0; i < PVD_reserved3_size; ++i)
 
762
                if (h[PVD_reserved3_offset + i] != 0)
 
763
                        return (0);
 
764
 
 
765
        /* Logical block size must be > 0. */
 
766
        /* I've looked at Ecma 119 and can't find any stronger
 
767
         * restriction on this field. */
 
768
        logical_block_size =
 
769
            archive_le16dec(h + PVD_logical_block_size_offset);
 
770
        if (logical_block_size <= 0)
 
771
                return (0);
 
772
 
 
773
        volume_block =
 
774
            archive_le32dec(h + PVD_volume_space_size_offset);
 
775
        if (volume_block <= SYSTEM_AREA_BLOCK+4)
 
776
                return (0);
 
777
 
 
778
        /* File structure version must be 2 for ISO9660:1999. */
 
779
        if (h[PVD_file_structure_version_offset] != 2)
 
780
                return (0);
 
781
 
 
782
        /* Location of Occurrence of Type L Path Table must be
 
783
         * available location,
 
784
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
785
        location = archive_le32dec(h+PVD_type_1_path_table_offset);
 
786
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
787
                return (0);
 
788
 
 
789
        /* Location of Occurrence of Type M Path Table must be
 
790
         * available location,
 
791
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
792
        location = archive_be32dec(h+PVD_type_m_path_table_offset);
 
793
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
794
                return (0);
 
795
 
 
796
        /* Reserved field must be 0. */
 
797
        for (i = 0; i < PVD_reserved4_size; ++i)
 
798
                if (h[PVD_reserved4_offset + i] != 0)
 
799
                        return (0);
 
800
 
 
801
        /* Reserved field must be 0. */
 
802
        for (i = 0; i < PVD_reserved5_size; ++i)
 
803
                if (h[PVD_reserved5_offset + i] != 0)
 
804
                        return (0);
 
805
 
 
806
        /* Read Root Directory Record in Volume Descriptor. */
 
807
        p = h + PVD_root_directory_record_offset;
 
808
        if (p[DR_length_offset] != 34)
 
809
                return (0);
 
810
 
 
811
        return (48);
 
812
}
 
813
 
 
814
static int
 
815
isPVD(struct iso9660 *iso9660, const unsigned char *h)
 
816
{
 
817
        const unsigned char *p;
 
818
        ssize_t logical_block_size;
 
819
        int32_t volume_block;
 
820
        int32_t location;
 
821
        int i;
 
822
 
 
823
        /* Type of the Primary Volume Descriptor must be 1. */
 
824
        if (h[PVD_type_offset] != 1)
 
825
                return (0);
 
826
 
 
827
        /* PVD version must be 1. */
 
828
        if (h[PVD_version_offset] != 1)
 
829
                return (0);
 
830
 
 
831
        /* Reserved field must be 0. */
 
832
        if (h[PVD_reserved1_offset] != 0)
 
833
                return (0);
 
834
 
 
835
        /* Reserved field must be 0. */
 
836
        for (i = 0; i < PVD_reserved2_size; ++i)
 
837
                if (h[PVD_reserved2_offset + i] != 0)
 
838
                        return (0);
 
839
 
 
840
        /* Reserved field must be 0. */
 
841
        for (i = 0; i < PVD_reserved3_size; ++i)
 
842
                if (h[PVD_reserved3_offset + i] != 0)
 
843
                        return (0);
 
844
 
 
845
        /* Logical block size must be > 0. */
 
846
        /* I've looked at Ecma 119 and can't find any stronger
 
847
         * restriction on this field. */
 
848
        logical_block_size =
 
849
            archive_le16dec(h + PVD_logical_block_size_offset);
 
850
        if (logical_block_size <= 0)
 
851
                return (0);
 
852
 
 
853
        volume_block = archive_le32dec(h + PVD_volume_space_size_offset);
 
854
        if (volume_block <= SYSTEM_AREA_BLOCK+4)
 
855
                return (0);
 
856
 
 
857
        /* File structure version must be 1 for ISO9660/ECMA119. */
 
858
        if (h[PVD_file_structure_version_offset] != 1)
 
859
                return (0);
 
860
 
 
861
        /* Location of Occurrence of Type L Path Table must be
 
862
         * available location,
 
863
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
864
        location = archive_le32dec(h+PVD_type_1_path_table_offset);
 
865
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
866
                return (0);
 
867
 
 
868
        /* Location of Occurrence of Type M Path Table must be
 
869
         * available location,
 
870
         * > SYSTEM_AREA_BLOCK(16) + 2 and < Volume Space Size. */
 
871
        location = archive_be32dec(h+PVD_type_m_path_table_offset);
 
872
        if (location <= SYSTEM_AREA_BLOCK+2 || location >= volume_block)
 
873
                return (0);
 
874
 
 
875
        /* Reserved field must be 0. */
 
876
        for (i = 0; i < PVD_reserved4_size; ++i)
 
877
                if (h[PVD_reserved4_offset + i] != 0)
 
878
                        return (0);
 
879
 
 
880
        /* Reserved field must be 0. */
 
881
        for (i = 0; i < PVD_reserved5_size; ++i)
 
882
                if (h[PVD_reserved5_offset + i] != 0)
 
883
                        return (0);
 
884
 
 
885
        /* XXX TODO: Check other values for sanity; reject more
 
886
         * malformed PVDs. XXX */
 
887
 
 
888
        /* Read Root Directory Record in Volume Descriptor. */
 
889
        p = h + PVD_root_directory_record_offset;
 
890
        if (p[DR_length_offset] != 34)
 
891
                return (0);
 
892
 
 
893
        iso9660->logical_block_size = logical_block_size;
 
894
        iso9660->volume_block = volume_block;
 
895
        iso9660->volume_size = logical_block_size * (uint64_t)volume_block;
 
896
        iso9660->primary.location = archive_le32dec(p + DR_extent_offset);
 
897
        iso9660->primary.size = archive_le32dec(p + DR_size_offset);
 
898
 
 
899
        return (48);
 
900
}
 
901
 
 
902
static int
 
903
read_children(struct archive_read *a, struct file_info *parent)
 
904
{
 
905
        struct iso9660 *iso9660;
 
906
        const unsigned char *b, *p;
 
907
        struct file_info *multi;
 
908
        size_t step;
 
909
 
 
910
        iso9660 = (struct iso9660 *)(a->format->data);
 
911
        if (iso9660->current_position > parent->offset) {
 
912
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
913
                    "Ignoring out-of-order directory (%s) %jd > %jd",
 
914
                    parent->name.s,
 
915
                    iso9660->current_position,
 
916
                    parent->offset);
 
917
                return (ARCHIVE_WARN);
 
918
        }
 
919
        if (parent->offset + parent->size > iso9660->volume_size) {
 
920
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
921
                    "Directory is beyond end-of-media: %s",
 
922
                    parent->name);
 
923
                return (ARCHIVE_WARN);
 
924
        }
 
925
        if (iso9660->current_position < parent->offset) {
 
926
                int64_t skipsize;
 
927
 
 
928
                skipsize = parent->offset - iso9660->current_position;
 
929
                skipsize = __archive_read_skip(a, skipsize);
 
930
                if (skipsize < 0)
 
931
                        return ((int)skipsize);
 
932
                iso9660->current_position = parent->offset;
 
933
        }
 
934
 
 
935
        step = ((parent->size + iso9660->logical_block_size -1) /
 
936
            iso9660->logical_block_size) * iso9660->logical_block_size;
 
937
        b = __archive_read_ahead(a, step, NULL);
 
938
        if (b == NULL) {
 
939
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
940
                    "Failed to read full block when scanning "
 
941
                    "ISO9660 directory list");
 
942
                return (ARCHIVE_FATAL);
 
943
        }
 
944
        __archive_read_consume(a, step);
 
945
        iso9660->current_position += step;
 
946
        multi = NULL;
 
947
        while (step) {
 
948
                p = b;
 
949
                b += iso9660->logical_block_size;
 
950
                step -= iso9660->logical_block_size;
 
951
                for (; *p != 0 && p < b && p + *p <= b; p += *p) {
 
952
                        struct file_info *child;
 
953
 
 
954
                        /* N.B.: these special directory identifiers
 
955
                         * are 8 bit "values" even on a
 
956
                         * Joliet CD with UCS-2 (16bit) encoding.
 
957
                         */
 
958
 
 
959
                        /* Skip '.' entry. */
 
960
                        if (*(p + DR_name_len_offset) == 1
 
961
                            && *(p + DR_name_offset) == '\0')
 
962
                                continue;
 
963
                        /* Skip '..' entry. */
 
964
                        if (*(p + DR_name_len_offset) == 1
 
965
                            && *(p + DR_name_offset) == '\001')
 
966
                                continue;
 
967
                        child = parse_file_info(a, parent, p);
 
968
                        if (child == NULL)
 
969
                                return (ARCHIVE_FATAL);
 
970
                        if (child->cl_offset)
 
971
                                heap_add_entry(&(iso9660->cl_files),
 
972
                                    child, child->cl_offset);
 
973
                        else {
 
974
                                if (child->multi_extent || multi != NULL) {
 
975
                                        struct content *con;
 
976
 
 
977
                                        if (multi == NULL) {
 
978
                                                multi = child;
 
979
                                                multi->contents.first = NULL;
 
980
                                                multi->contents.last =
 
981
                                                    &(multi->contents.first);
 
982
                                        }
 
983
                                        con = malloc(sizeof(struct content));
 
984
                                        if (con == NULL) {
 
985
                                                archive_set_error(
 
986
                                                    &a->archive, ENOMEM,
 
987
                                                    "No memory for "
 
988
                                                    "multi extent");
 
989
                                                return (ARCHIVE_FATAL);
 
990
                                        }
 
991
                                        con->offset = child->offset;
 
992
                                        con->size = child->size;
 
993
                                        con->next = NULL;
 
994
                                        *multi->contents.last = con;
 
995
                                        multi->contents.last = &(con->next);
 
996
                                        if (multi == child)
 
997
                                                add_entry(iso9660, child);
 
998
                                        else {
 
999
                                                multi->size += child->size;
 
1000
                                                if (!child->multi_extent)
 
1001
                                                        multi = NULL;
 
1002
                                        }
 
1003
                                } else
 
1004
                                        add_entry(iso9660, child);
 
1005
                        }
 
1006
                }
 
1007
        }
 
1008
 
 
1009
        /* Read data which recorded by RRIP "CE" extension. */
 
1010
        if (read_CE(a, iso9660) != ARCHIVE_OK)
 
1011
                return (ARCHIVE_FATAL);
 
1012
 
 
1013
        return (ARCHIVE_OK);
 
1014
}
 
1015
 
 
1016
static int
 
1017
relocate_dir(struct iso9660 *iso9660, struct file_info *file)
 
1018
{
 
1019
        struct file_info *re;
 
1020
 
 
1021
        re = heap_get_entry(&(iso9660->re_dirs));
 
1022
        while (re != NULL && re->offset < file->cl_offset) {
 
1023
                /* This case is wrong pattern.
 
1024
                 * But dont't reject this directory entry to be robust. */
 
1025
                cache_add_entry(iso9660, re);
 
1026
                re = heap_get_entry(&(iso9660->re_dirs));
 
1027
        }
 
1028
        if (re == NULL)
 
1029
                /* This case is wrong pattern. */
 
1030
                return (0);
 
1031
        if (re->offset == file->cl_offset) {
 
1032
                re->parent->subdirs--;
 
1033
                re->parent = file->parent;
 
1034
                re->parent->subdirs++;
 
1035
                cache_add_to_next_of_parent(iso9660, re);
 
1036
                return (1);
 
1037
        } else
 
1038
                /* This case is wrong pattern. */
 
1039
                heap_add_entry(&(iso9660->re_dirs), re, re->offset);
 
1040
        return (0);
 
1041
}
 
1042
 
 
1043
static int
 
1044
read_entries(struct archive_read *a)
 
1045
{
 
1046
        struct iso9660 *iso9660;
 
1047
        struct file_info *file;
 
1048
        int r;
 
1049
 
 
1050
        iso9660 = (struct iso9660 *)(a->format->data);
 
1051
 
 
1052
        while ((file = next_entry(iso9660)) != NULL &&
 
1053
            (file->mode & AE_IFMT) == AE_IFDIR) {
 
1054
                r = read_children(a, file);
 
1055
                if (r != ARCHIVE_OK)
 
1056
                        return (r);
 
1057
 
 
1058
                if (iso9660->seenRockridge &&
 
1059
                    file->parent != NULL &&
 
1060
                    file->parent->parent == NULL &&
 
1061
                    iso9660->rr_moved == NULL &&
 
1062
                    (strcmp(file->name.s, "rr_moved") == 0 ||
 
1063
                     strcmp(file->name.s, ".rr_moved") == 0)) {
 
1064
                        iso9660->rr_moved = file;
 
1065
                } else if (file->re)
 
1066
                        heap_add_entry(&(iso9660->re_dirs), file,
 
1067
                            file->offset);
 
1068
                else
 
1069
                        cache_add_entry(iso9660, file);
 
1070
        }
 
1071
        if (file != NULL)
 
1072
                add_entry(iso9660, file);
 
1073
 
 
1074
        if (iso9660->rr_moved != NULL) {
 
1075
                /*
 
1076
                 * Relocate directory which rr_moved has.
 
1077
                 */
 
1078
                while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL)
 
1079
                        relocate_dir(iso9660, file);
 
1080
 
 
1081
                /* If rr_moved directory still has children,
 
1082
                 * Add rr_moved into pending_files to show
 
1083
                 */
 
1084
                if (iso9660->rr_moved->subdirs) {
 
1085
                        cache_add_entry(iso9660, iso9660->rr_moved);
 
1086
                        /* If entries which have "RE" extension are still
 
1087
                         * remaining(this case is unlikely except ISO image
 
1088
                         * is broken), the entries won't be exposed. */
 
1089
                        while ((file = heap_get_entry(&(iso9660->re_dirs))) != NULL)
 
1090
                                cache_add_entry(iso9660, file);
 
1091
                } else
 
1092
                        iso9660->rr_moved->parent->subdirs--;
 
1093
        } else {
 
1094
                /*
 
1095
                 * In case ISO image is broken. If the name of rr_moved
 
1096
                 * directory has been changed by damage, subdirectories
 
1097
                 * of rr_moved entry won't be exposed.
 
1098
                 */
 
1099
                while ((file = heap_get_entry(&(iso9660->re_dirs))) != NULL)
 
1100
                        cache_add_entry(iso9660, file);
 
1101
        }
 
1102
 
 
1103
        return (ARCHIVE_OK);
 
1104
}
 
1105
 
 
1106
static int
 
1107
archive_read_format_iso9660_read_header(struct archive_read *a,
 
1108
    struct archive_entry *entry)
 
1109
{
 
1110
        struct iso9660 *iso9660;
 
1111
        struct file_info *file;
 
1112
        int r, rd_r;
 
1113
 
 
1114
        iso9660 = (struct iso9660 *)(a->format->data);
 
1115
 
 
1116
        if (!a->archive.archive_format) {
 
1117
                a->archive.archive_format = ARCHIVE_FORMAT_ISO9660;
 
1118
                a->archive.archive_format_name = "ISO9660";
 
1119
        }
 
1120
 
 
1121
        if (iso9660->current_position == 0) {
 
1122
                int64_t skipsize;
 
1123
                struct vd *vd;
 
1124
                const void *block;
 
1125
                char seenJoliet;
 
1126
 
 
1127
                vd = &(iso9660->primary);
 
1128
                if (!iso9660->opt_support_joliet)
 
1129
                        iso9660->seenJoliet = 0;
 
1130
                if (iso9660->seenJoliet &&
 
1131
                        vd->location > iso9660->joliet.location)
 
1132
                        /* This condition is unlikely; by way of caution. */
 
1133
                        vd = &(iso9660->joliet);
 
1134
 
 
1135
                skipsize = LOGICAL_BLOCK_SIZE * vd->location;
 
1136
                skipsize = __archive_read_skip(a, skipsize);
 
1137
                if (skipsize < 0)
 
1138
                        return ((int)skipsize);
 
1139
                iso9660->current_position = skipsize;
 
1140
 
 
1141
                block = __archive_read_ahead(a, vd->size, NULL);
 
1142
                if (block == NULL) {
 
1143
                        archive_set_error(&a->archive,
 
1144
                            ARCHIVE_ERRNO_MISC,
 
1145
                            "Failed to read full block when scanning "
 
1146
                            "ISO9660 directory list");
 
1147
                        return (ARCHIVE_FATAL);
 
1148
                }
 
1149
 
 
1150
                /*
 
1151
                 * While reading Root Directory, flag seenJoliet
 
1152
                 * must be zero to avoid converting special name
 
1153
                 * 0x00(Current Directory) and next byte to UCS2.
 
1154
                 */
 
1155
                seenJoliet = iso9660->seenJoliet;/* Save flag. */
 
1156
                iso9660->seenJoliet = 0;
 
1157
                file = parse_file_info(a, NULL, block);
 
1158
                if (file == NULL)
 
1159
                        return (ARCHIVE_FATAL);
 
1160
                iso9660->seenJoliet = seenJoliet;
 
1161
                if (vd == &(iso9660->primary) && iso9660->seenRockridge
 
1162
                    && iso9660->seenJoliet)
 
1163
                        /*
 
1164
                         * If iso image has RockRidge and Joliet,
 
1165
                         * we use RockRidge Extensions.
 
1166
                         */
 
1167
                        iso9660->seenJoliet = 0;
 
1168
                if (vd == &(iso9660->primary) && !iso9660->seenRockridge
 
1169
                    && iso9660->seenJoliet) {
 
1170
                        /* Switch reading data from primary to joliet. */ 
 
1171
                        vd = &(iso9660->joliet);
 
1172
                        skipsize = LOGICAL_BLOCK_SIZE * vd->location;
 
1173
                        skipsize -= iso9660->current_position;
 
1174
                        skipsize = __archive_read_skip(a, skipsize);
 
1175
                        if (skipsize < 0)
 
1176
                                return ((int)skipsize);
 
1177
                        iso9660->current_position += skipsize;
 
1178
 
 
1179
                        block = __archive_read_ahead(a, vd->size, NULL);
 
1180
                        if (block == NULL) {
 
1181
                                archive_set_error(&a->archive,
 
1182
                                    ARCHIVE_ERRNO_MISC,
 
1183
                                    "Failed to read full block when scanning "
 
1184
                                    "ISO9660 directory list");
 
1185
                                return (ARCHIVE_FATAL);
 
1186
                        }
 
1187
                        seenJoliet = iso9660->seenJoliet;/* Save flag. */
 
1188
                        iso9660->seenJoliet = 0;
 
1189
                        file = parse_file_info(a, NULL, block);
 
1190
                        if (file == NULL)
 
1191
                                return (ARCHIVE_FATAL);
 
1192
                        iso9660->seenJoliet = seenJoliet;
 
1193
                }
 
1194
                /* Store the root directory in the pending list. */
 
1195
                add_entry(iso9660, file);
 
1196
                if (iso9660->seenRockridge) {
 
1197
                        a->archive.archive_format =
 
1198
                            ARCHIVE_FORMAT_ISO9660_ROCKRIDGE;
 
1199
                        a->archive.archive_format_name =
 
1200
                            "ISO9660 with Rockridge extensions";
 
1201
                }
 
1202
                rd_r = read_entries(a);
 
1203
                if (rd_r == ARCHIVE_FATAL)
 
1204
                        return (ARCHIVE_FATAL);
 
1205
        } else
 
1206
                rd_r = ARCHIVE_OK;
 
1207
 
 
1208
        /* Get the next entry that appears after the current offset. */
 
1209
        r = next_entry_seek(a, iso9660, &file);
 
1210
        if (r != ARCHIVE_OK)
 
1211
                return (r);
 
1212
 
 
1213
        iso9660->entry_bytes_remaining = file->size;
 
1214
        iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
 
1215
 
 
1216
        if (file->offset + file->size > iso9660->volume_size) {
 
1217
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1218
                    "File is beyond end-of-media: %s", file->name);
 
1219
                iso9660->entry_bytes_remaining = 0;
 
1220
                iso9660->entry_sparse_offset = 0;
 
1221
                return (ARCHIVE_WARN);
 
1222
        }
 
1223
 
 
1224
        /* Set up the entry structure with information about this entry. */
 
1225
        archive_entry_set_mode(entry, file->mode);
 
1226
        archive_entry_set_uid(entry, file->uid);
 
1227
        archive_entry_set_gid(entry, file->gid);
 
1228
        archive_entry_set_nlink(entry, file->nlinks);
 
1229
        if (file->birthtime_is_set)
 
1230
                archive_entry_set_birthtime(entry, file->birthtime, 0);
 
1231
        else
 
1232
                archive_entry_unset_birthtime(entry);
 
1233
        archive_entry_set_mtime(entry, file->mtime, 0);
 
1234
        archive_entry_set_ctime(entry, file->ctime, 0);
 
1235
        archive_entry_set_atime(entry, file->atime, 0);
 
1236
        /* N.B.: Rock Ridge supports 64-bit device numbers. */
 
1237
        archive_entry_set_rdev(entry, (dev_t)file->rdev);
 
1238
        archive_entry_set_size(entry, iso9660->entry_bytes_remaining);
 
1239
        archive_string_empty(&iso9660->pathname);
 
1240
        archive_entry_set_pathname(entry,
 
1241
            build_pathname(&iso9660->pathname, file));
 
1242
        if (file->symlink.s != NULL)
 
1243
                archive_entry_copy_symlink(entry, file->symlink.s);
 
1244
 
 
1245
        /* Note: If the input isn't seekable, we can't rewind to
 
1246
         * return the same body again, so if the next entry refers to
 
1247
         * the same data, we have to return it as a hardlink to the
 
1248
         * original entry. */
 
1249
        if (file->number != -1 &&
 
1250
            file->number == iso9660->previous_number) {
 
1251
                archive_entry_set_hardlink(entry,
 
1252
                    iso9660->previous_pathname.s);
 
1253
                archive_entry_unset_size(entry);
 
1254
                iso9660->entry_bytes_remaining = 0;
 
1255
                iso9660->entry_sparse_offset = 0;
 
1256
                return (ARCHIVE_OK);
 
1257
        }
 
1258
 
 
1259
        /* Except for the hardlink case above, if the offset of the
 
1260
         * next entry is before our current position, we can't seek
 
1261
         * backwards to extract it, so issue a warning.  Note that
 
1262
         * this can only happen if this entry was added to the heap
 
1263
         * after we passed this offset, that is, only if the directory
 
1264
         * mentioning this entry is later than the body of the entry.
 
1265
         * Such layouts are very unusual; most ISO9660 writers lay out
 
1266
         * and record all directory information first, then store
 
1267
         * all file bodies. */
 
1268
        /* TODO: Someday, libarchive's I/O core will support optional
 
1269
         * seeking.  When that day comes, this code should attempt to
 
1270
         * seek and only return the error if the seek fails.  That
 
1271
         * will give us support for whacky ISO images that require
 
1272
         * seeking while retaining the ability to read almost all ISO
 
1273
         * images in a streaming fashion. */
 
1274
        if ((file->mode & AE_IFMT) != AE_IFDIR &&
 
1275
            file->offset < iso9660->current_position) {
 
1276
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1277
                    "Ignoring out-of-order file @%x (%s) %jd < %jd",
 
1278
                    file,
 
1279
                    iso9660->pathname.s,
 
1280
                    file->offset, iso9660->current_position);
 
1281
                iso9660->entry_bytes_remaining = 0;
 
1282
                iso9660->entry_sparse_offset = 0;
 
1283
                return (ARCHIVE_WARN);
 
1284
        }
 
1285
 
 
1286
        /* Initialize zisofs variables. */
 
1287
        iso9660->entry_zisofs.pz = file->pz;
 
1288
        if (file->pz) {
 
1289
#ifdef HAVE_ZLIB_H
 
1290
                struct zisofs  *zisofs;
 
1291
 
 
1292
                zisofs = &iso9660->entry_zisofs;
 
1293
                zisofs->initialized = 0;
 
1294
                zisofs->pz_log2_bs = file->pz_log2_bs;
 
1295
                zisofs->pz_uncompressed_size = file->pz_uncompressed_size;
 
1296
                zisofs->pz_offset = 0;
 
1297
                zisofs->header_avail = 0;
 
1298
                zisofs->header_passed = 0;
 
1299
                zisofs->block_pointers_avail = 0;
 
1300
#endif
 
1301
                archive_entry_set_size(entry, file->pz_uncompressed_size);
 
1302
        }
 
1303
 
 
1304
        iso9660->previous_number = file->number;
 
1305
        archive_strcpy(&iso9660->previous_pathname, iso9660->pathname.s);
 
1306
 
 
1307
        /* Reset entry_bytes_remaining if the file is multi extent. */
 
1308
        iso9660->entry_content = file->contents.first;
 
1309
        if (iso9660->entry_content != NULL)
 
1310
                iso9660->entry_bytes_remaining = iso9660->entry_content->size;
 
1311
 
 
1312
        if (archive_entry_filetype(entry) == AE_IFDIR) {
 
1313
                /* Overwrite nlinks by proper link number which is
 
1314
                 * calculated from number of sub directories. */
 
1315
                archive_entry_set_nlink(entry, 2 + file->subdirs);
 
1316
                /* Directory data has been read completely. */
 
1317
                iso9660->entry_bytes_remaining = 0;
 
1318
                iso9660->entry_sparse_offset = 0;
 
1319
                file->exposed = 1;
 
1320
        }
 
1321
 
 
1322
        if (rd_r != ARCHIVE_OK)
 
1323
                return (rd_r);
 
1324
        return (ARCHIVE_OK);
 
1325
}
 
1326
 
 
1327
static int
 
1328
archive_read_format_iso9660_read_data_skip(struct archive_read *a)
 
1329
{
 
1330
        /* Because read_next_header always does an explicit skip
 
1331
         * to the next entry, we don't need to do anything here. */
 
1332
        (void)a; /* UNUSED */
 
1333
        return (ARCHIVE_OK);
 
1334
}
 
1335
 
 
1336
#ifdef HAVE_ZLIB_H
 
1337
 
 
1338
static int
 
1339
zisofs_read_data(struct archive_read *a,
 
1340
    const void **buff, size_t *size, off_t *offset)
 
1341
{
 
1342
        struct iso9660 *iso9660;
 
1343
        struct zisofs  *zisofs;
 
1344
        const unsigned char *p;
 
1345
        size_t avail;
 
1346
        ssize_t bytes_read;
 
1347
        size_t uncompressed_size;
 
1348
        int r;
 
1349
 
 
1350
        iso9660 = (struct iso9660 *)(a->format->data);
 
1351
        zisofs = &iso9660->entry_zisofs;
 
1352
 
 
1353
        p = __archive_read_ahead(a, 1, &bytes_read);
 
1354
        if (bytes_read <= 0) {
 
1355
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1356
                    "Truncated zisofs file body");
 
1357
                return (ARCHIVE_FATAL);
 
1358
        }
 
1359
        if (bytes_read > iso9660->entry_bytes_remaining)
 
1360
                bytes_read = iso9660->entry_bytes_remaining;
 
1361
        avail = bytes_read;
 
1362
        uncompressed_size = 0;
 
1363
 
 
1364
        if (!zisofs->initialized) {
 
1365
                size_t ceil, xsize;
 
1366
 
 
1367
                /* Allocate block pointers buffer. */
 
1368
                ceil = (zisofs->pz_uncompressed_size +
 
1369
                        (1LL << zisofs->pz_log2_bs) - 1)
 
1370
                        >> zisofs->pz_log2_bs;
 
1371
                xsize = (ceil + 1) * 4;
 
1372
                if (zisofs->block_pointers_alloc < xsize) {
 
1373
                        size_t alloc;
 
1374
 
 
1375
                        if (zisofs->block_pointers != NULL)
 
1376
                                free(zisofs->block_pointers);
 
1377
                        alloc = ((xsize >> 10) + 1) << 10;
 
1378
                        zisofs->block_pointers = malloc(alloc);
 
1379
                        if (zisofs->block_pointers == NULL) {
 
1380
                                archive_set_error(&a->archive, ENOMEM,
 
1381
                                    "No memory for zisofs decompression");
 
1382
                                return (ARCHIVE_FATAL);
 
1383
                        }
 
1384
                        zisofs->block_pointers_alloc = alloc;
 
1385
                }
 
1386
                zisofs->block_pointers_size = xsize;
 
1387
 
 
1388
                /* Allocate uncompressed data buffer. */
 
1389
                xsize = 1UL << zisofs->pz_log2_bs;
 
1390
                if (zisofs->uncompressed_buffer_size < xsize) {
 
1391
                        if (zisofs->uncompressed_buffer != NULL)
 
1392
                                free(zisofs->uncompressed_buffer);
 
1393
                        zisofs->uncompressed_buffer = malloc(xsize);
 
1394
                        if (zisofs->uncompressed_buffer == NULL) {
 
1395
                                archive_set_error(&a->archive, ENOMEM,
 
1396
                                    "No memory for zisofs decompression");
 
1397
                                return (ARCHIVE_FATAL);
 
1398
                        }
 
1399
                }
 
1400
                zisofs->uncompressed_buffer_size = xsize;
 
1401
 
 
1402
                /*
 
1403
                 * Read the file header, and check the magic code of zisofs.
 
1404
                 */
 
1405
                if (zisofs->header_avail < sizeof(zisofs->header)) {
 
1406
                        xsize = sizeof(zisofs->header) - zisofs->header_avail;
 
1407
                        if (avail < xsize)
 
1408
                                xsize = avail;
 
1409
                        memcpy(zisofs->header + zisofs->header_avail, p, xsize);
 
1410
                        zisofs->header_avail += xsize;
 
1411
                        avail -= xsize;
 
1412
                        p += xsize;
 
1413
                }
 
1414
                if (!zisofs->header_passed &&
 
1415
                    zisofs->header_avail == sizeof(zisofs->header)) {
 
1416
                        int err = 0;
 
1417
 
 
1418
                        if (memcmp(zisofs->header, zisofs_magic,
 
1419
                            sizeof(zisofs_magic)) != 0)
 
1420
                                err = 1;
 
1421
                        if (archive_le32dec(zisofs->header + 8)
 
1422
                            != zisofs->pz_uncompressed_size)
 
1423
                                err = 1;
 
1424
                        if (zisofs->header[12] != 4)
 
1425
                                err = 1;
 
1426
                        if (zisofs->header[13] != zisofs->pz_log2_bs)
 
1427
                                err = 1;
 
1428
                        if (err) {
 
1429
                                archive_set_error(&a->archive,
 
1430
                                    ARCHIVE_ERRNO_FILE_FORMAT,
 
1431
                                    "Illegal zisofs file body");
 
1432
                                return (ARCHIVE_FATAL);
 
1433
                        }
 
1434
                        zisofs->header_passed = 1;
 
1435
                }
 
1436
                /*
 
1437
                 * Read block pointers.
 
1438
                 */
 
1439
                if (zisofs->header_passed &&
 
1440
                    zisofs->block_pointers_avail < zisofs->block_pointers_size) {
 
1441
                        xsize = zisofs->block_pointers_size
 
1442
                            - zisofs->block_pointers_avail;
 
1443
                        if (avail < xsize)
 
1444
                                xsize = avail;
 
1445
                        memcpy(zisofs->block_pointers
 
1446
                            + zisofs->block_pointers_avail, p, xsize);
 
1447
                        zisofs->block_pointers_avail += xsize;
 
1448
                        avail -= xsize;
 
1449
                        p += xsize;
 
1450
                        if (zisofs->block_pointers_avail
 
1451
                            == zisofs->block_pointers_size) {
 
1452
                                /* We've got all block pointers and initialize
 
1453
                                 * related variables.   */
 
1454
                                zisofs->block_off = 0;
 
1455
                                zisofs->block_avail = 0;
 
1456
                                /* Complete a initialization */
 
1457
                                zisofs->initialized = 1;
 
1458
                        }
 
1459
                }
 
1460
 
 
1461
                if (!zisofs->initialized)
 
1462
                        goto next_data; /* We need more datas. */
 
1463
        }
 
1464
 
 
1465
        /*
 
1466
         * Get block offsets from block pointers.
 
1467
         */
 
1468
        if (zisofs->block_avail == 0) {
 
1469
                uint32_t bst, bed;
 
1470
 
 
1471
                if (zisofs->block_off + 4 >= zisofs->block_pointers_size) {
 
1472
                        /* There isn't a pair of offsets. */
 
1473
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1474
                            "Illegal zisofs block pointers");
 
1475
                        return (ARCHIVE_FATAL);
 
1476
                }
 
1477
                bst = archive_le32dec(zisofs->block_pointers + zisofs->block_off);
 
1478
                if (bst != zisofs->pz_offset + (bytes_read - avail)) {
 
1479
                        /* TODO: Should we seek offset of current file by bst ? */
 
1480
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1481
                            "Illegal zisofs block pointers(cannot seek)");
 
1482
                        return (ARCHIVE_FATAL);
 
1483
                }
 
1484
                bed = archive_le32dec(
 
1485
                    zisofs->block_pointers + zisofs->block_off + 4);
 
1486
                if (bed < bst) {
 
1487
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1488
                            "Illegal zisofs block pointers");
 
1489
                        return (ARCHIVE_FATAL);
 
1490
                }
 
1491
                zisofs->block_avail = bed - bst;
 
1492
                zisofs->block_off += 4;
 
1493
 
 
1494
                /* Initialize compression library for new block. */
 
1495
                if (zisofs->stream_valid)
 
1496
                        r = inflateReset(&zisofs->stream);
 
1497
                else
 
1498
                        r = inflateInit(&zisofs->stream);
 
1499
                if (r != Z_OK) {
 
1500
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1501
                            "Can't initialize zisofs decompression.");
 
1502
                        return (ARCHIVE_FATAL);
 
1503
                }
 
1504
                zisofs->stream_valid = 1;
 
1505
                zisofs->stream.total_in = 0;
 
1506
                zisofs->stream.total_out = 0;
 
1507
        }
 
1508
 
 
1509
        /*
 
1510
         * Make uncompressed datas.
 
1511
         */
 
1512
        if (zisofs->block_avail == 0) {
 
1513
                memset(zisofs->uncompressed_buffer, 0,
 
1514
                    zisofs->uncompressed_buffer_size);
 
1515
                uncompressed_size = zisofs->uncompressed_buffer_size;
 
1516
        } else {
 
1517
                zisofs->stream.next_in = (Bytef *)(uintptr_t)(const void *)p;
 
1518
                if (avail > zisofs->block_avail)
 
1519
                        zisofs->stream.avail_in = zisofs->block_avail;
 
1520
                else
 
1521
                        zisofs->stream.avail_in = avail;
 
1522
                zisofs->stream.next_out = zisofs->uncompressed_buffer;
 
1523
                zisofs->stream.avail_out = zisofs->uncompressed_buffer_size;
 
1524
 
 
1525
                r = inflate(&zisofs->stream, 0);
 
1526
                switch (r) {
 
1527
                case Z_OK: /* Decompressor made some progress.*/
 
1528
                case Z_STREAM_END: /* Found end of stream. */
 
1529
                        break;
 
1530
                default:
 
1531
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1532
                            "zisofs decompression failed (%d)", r);
 
1533
                        return (ARCHIVE_FATAL);
 
1534
                }
 
1535
                uncompressed_size =
 
1536
                    zisofs->uncompressed_buffer_size - zisofs->stream.avail_out;
 
1537
                avail -= zisofs->stream.next_in - p;
 
1538
                zisofs->block_avail -= zisofs->stream.next_in - p;
 
1539
        }
 
1540
next_data:
 
1541
        bytes_read -= avail;
 
1542
        *buff = zisofs->uncompressed_buffer;
 
1543
        *size = uncompressed_size;
 
1544
        *offset = iso9660->entry_sparse_offset;
 
1545
        iso9660->entry_sparse_offset += uncompressed_size;
 
1546
        iso9660->entry_bytes_remaining -= bytes_read;
 
1547
        iso9660->current_position += bytes_read;
 
1548
        zisofs->pz_offset += bytes_read;
 
1549
        __archive_read_consume(a, bytes_read);
 
1550
 
 
1551
        return (ARCHIVE_OK);
 
1552
}
 
1553
 
 
1554
#else /* HAVE_ZLIB_H */
 
1555
 
 
1556
static int
 
1557
zisofs_read_data(struct archive_read *a,
 
1558
    const void **buff, size_t *size, off_t *offset)
 
1559
{
 
1560
 
 
1561
        (void)buff;/* UNUSED */
 
1562
        (void)size;/* UNUSED */
 
1563
        (void)offset;/* UNUSED */
 
1564
        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
1565
            "zisofs is not supported on this platform.");
 
1566
        return (ARCHIVE_FAILED);
 
1567
}
 
1568
 
 
1569
#endif /* HAVE_ZLIB_H */
 
1570
 
 
1571
static int
 
1572
archive_read_format_iso9660_read_data(struct archive_read *a,
 
1573
    const void **buff, size_t *size, off_t *offset)
 
1574
{
 
1575
        ssize_t bytes_read;
 
1576
        struct iso9660 *iso9660;
 
1577
 
 
1578
        iso9660 = (struct iso9660 *)(a->format->data);
 
1579
        if (iso9660->entry_bytes_remaining <= 0) {
 
1580
                if (iso9660->entry_content != NULL)
 
1581
                        iso9660->entry_content = iso9660->entry_content->next;
 
1582
                if (iso9660->entry_content == NULL) {
 
1583
                        *buff = NULL;
 
1584
                        *size = 0;
 
1585
                        *offset = iso9660->entry_sparse_offset;
 
1586
                        return (ARCHIVE_EOF);
 
1587
                }
 
1588
                /* Seek forward to the start of the entry. */
 
1589
                if (iso9660->current_position < iso9660->entry_content->offset) {
 
1590
                        int64_t step;
 
1591
 
 
1592
                        step = iso9660->entry_content->offset -
 
1593
                            iso9660->current_position;
 
1594
                        step = __archive_read_skip(a, step);
 
1595
                        if (step < 0)
 
1596
                                return ((int)step);
 
1597
                        iso9660->current_position =
 
1598
                            iso9660->entry_content->offset;
 
1599
                }
 
1600
                if (iso9660->entry_content->offset < iso9660->current_position) {
 
1601
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1602
                            "Ignoring out-of-order file (%s) %jd < %jd",
 
1603
                            iso9660->pathname.s,
 
1604
                            iso9660->entry_content->offset,
 
1605
                            iso9660->current_position);
 
1606
                        *buff = NULL;
 
1607
                        *size = 0;
 
1608
                        *offset = iso9660->entry_sparse_offset;
 
1609
                        return (ARCHIVE_WARN);
 
1610
                }
 
1611
                iso9660->entry_bytes_remaining = iso9660->entry_content->size;
 
1612
        }
 
1613
        if (iso9660->entry_zisofs.pz)
 
1614
                return (zisofs_read_data(a, buff, size, offset));
 
1615
 
 
1616
        *buff = __archive_read_ahead(a, 1, &bytes_read);
 
1617
        if (bytes_read == 0)
 
1618
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1619
                    "Truncated input file");
 
1620
        if (*buff == NULL)
 
1621
                return (ARCHIVE_FATAL);
 
1622
        if (bytes_read > iso9660->entry_bytes_remaining)
 
1623
                bytes_read = iso9660->entry_bytes_remaining;
 
1624
        *size = bytes_read;
 
1625
        *offset = iso9660->entry_sparse_offset;
 
1626
        iso9660->entry_sparse_offset += bytes_read;
 
1627
        iso9660->entry_bytes_remaining -= bytes_read;
 
1628
        iso9660->current_position += bytes_read;
 
1629
        __archive_read_consume(a, bytes_read);
 
1630
        return (ARCHIVE_OK);
 
1631
}
 
1632
 
 
1633
static int
 
1634
archive_read_format_iso9660_cleanup(struct archive_read *a)
 
1635
{
 
1636
        struct iso9660 *iso9660;
 
1637
        int r = ARCHIVE_OK;
 
1638
 
 
1639
        iso9660 = (struct iso9660 *)(a->format->data);
 
1640
        release_files(iso9660);
 
1641
        free(iso9660->read_ce_req.reqs);
 
1642
        archive_string_free(&iso9660->pathname);
 
1643
        archive_string_free(&iso9660->previous_pathname);
 
1644
        if (iso9660->pending_files.files)
 
1645
                free(iso9660->pending_files.files);
 
1646
        if (iso9660->re_dirs.files)
 
1647
                free(iso9660->re_dirs.files);
 
1648
        if (iso9660->cl_files.files)
 
1649
                free(iso9660->cl_files.files);
 
1650
#ifdef HAVE_ZLIB_H
 
1651
        free(iso9660->entry_zisofs.uncompressed_buffer);
 
1652
        free(iso9660->entry_zisofs.block_pointers);
 
1653
        if (iso9660->entry_zisofs.stream_valid) {
 
1654
                if (inflateEnd(&iso9660->entry_zisofs.stream) != Z_OK) {
 
1655
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1656
                            "Failed to clean up zlib decompressor");
 
1657
                        r = ARCHIVE_FATAL;
 
1658
                }
 
1659
        }
 
1660
#endif
 
1661
        free(iso9660);
 
1662
        (a->format->data) = NULL;
 
1663
        return (r);
 
1664
}
 
1665
 
 
1666
/*
 
1667
 * This routine parses a single ISO directory record, makes sense
 
1668
 * of any extensions, and stores the result in memory.
 
1669
 */
 
1670
static struct file_info *
 
1671
parse_file_info(struct archive_read *a, struct file_info *parent,
 
1672
    const unsigned char *isodirrec)
 
1673
{
 
1674
        struct iso9660 *iso9660;
 
1675
        struct file_info *file;
 
1676
        size_t name_len;
 
1677
        const unsigned char *rr_start, *rr_end;
 
1678
        const unsigned char *p;
 
1679
        size_t dr_len;
 
1680
        int32_t location;
 
1681
        int flags;
 
1682
 
 
1683
        iso9660 = (struct iso9660 *)(a->format->data);
 
1684
 
 
1685
        dr_len = (size_t)isodirrec[DR_length_offset];
 
1686
        name_len = (size_t)isodirrec[DR_name_len_offset];
 
1687
        location = archive_le32dec(isodirrec + DR_extent_offset);
 
1688
        /* Sanity check that dr_len needs at least 34. */
 
1689
        if (dr_len < 34) {
 
1690
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1691
                    "Invalid length of directory record");
 
1692
                return (NULL);
 
1693
        }
 
1694
        /* Sanity check that name_len doesn't exceed dr_len. */
 
1695
        if (dr_len - 33 < name_len || name_len == 0) {
 
1696
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1697
                    "Invalid length of file identifier");
 
1698
                return (NULL);
 
1699
        }
 
1700
        /* Sanity check that location doesn't exceed volume block.
 
1701
         * Don't check lower limit of location; it's possibility
 
1702
         * the location has negative value when file type is symbolic
 
1703
         * link or file size is zero. As far as I know latest mkisofs
 
1704
         * do that.
 
1705
         */
 
1706
        if (location >= iso9660->volume_block) {
 
1707
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1708
                    "Invalid location of extent of file");
 
1709
                return (NULL);
 
1710
        }
 
1711
 
 
1712
        /* Create a new file entry and copy data from the ISO dir record. */
 
1713
        file = (struct file_info *)malloc(sizeof(*file));
 
1714
        if (file == NULL) {
 
1715
                archive_set_error(&a->archive, ENOMEM,
 
1716
                    "No memory for file entry");
 
1717
                return (NULL);
 
1718
        }
 
1719
        memset(file, 0, sizeof(*file));
 
1720
        file->parent = parent;
 
1721
        file->offset = iso9660->logical_block_size * (uint64_t)location;
 
1722
        file->size = toi(isodirrec + DR_size_offset, DR_size_size);
 
1723
        file->mtime = isodate7(isodirrec + DR_date_offset);
 
1724
        file->ctime = file->atime = file->mtime;
 
1725
 
 
1726
        p = isodirrec + DR_name_offset;
 
1727
        /* Rockridge extensions (if any) follow name.  Compute this
 
1728
         * before fidgeting the name_len below. */
 
1729
        rr_start = p + name_len + (name_len & 1 ? 0 : 1);
 
1730
        rr_end = isodirrec + dr_len;
 
1731
 
 
1732
        if (iso9660->seenJoliet) {
 
1733
                /* Joliet names are max 64 chars (128 bytes) according to spec,
 
1734
                 * but genisoimage/mkisofs allows recording longer Joliet
 
1735
                 * names which are 103 UCS2 characters(206 bytes) by their
 
1736
                 * option '-joliet-long'.
 
1737
                 */
 
1738
                wchar_t wbuff[103+1], *wp;
 
1739
                const unsigned char *c;
 
1740
 
 
1741
                if (name_len > 206)
 
1742
                        name_len = 206;
 
1743
                /* convert BE UTF-16 to wchar_t */
 
1744
                for (c = p, wp = wbuff;
 
1745
                                c < (p + name_len) &&
 
1746
                                wp < (wbuff + sizeof(wbuff)/sizeof(*wbuff) - 1);
 
1747
                                c += 2) {
 
1748
                        *wp++ = (((255 & (int)c[0]) << 8) | (255 & (int)c[1]));
 
1749
                }
 
1750
                *wp = L'\0';
 
1751
 
 
1752
#if 0 /* untested code, is it at all useful on Joliet? */
 
1753
                /* trim trailing first version and dot from filename.
 
1754
                 *
 
1755
                 * Remember we where in UTF-16BE land!
 
1756
                 * SEPARATOR 1 (.) and SEPARATOR 2 (;) are both
 
1757
                 * 16 bits big endian characters on Joliet.
 
1758
                 *
 
1759
                 * TODO: sanitize filename?
 
1760
                 *       Joliet allows any UCS-2 char except:
 
1761
                 *       *, /, :, ;, ? and \.
 
1762
                 */
 
1763
                /* Chop off trailing ';1' from files. */
 
1764
                if (*(wp-2) == ';' && *(wp-1) == '1') {
 
1765
                        wp-=2;
 
1766
                        *wp = L'\0';
 
1767
                }
 
1768
 
 
1769
                /* Chop off trailing '.' from filenames. */
 
1770
                if (*(wp-1) == '.')
 
1771
                        *(--wp) = L'\0';
 
1772
#endif
 
1773
 
 
1774
                /* store the result in the file name field. */
 
1775
                archive_strappend_w_utf8(&file->name, wbuff);
 
1776
        } else {
 
1777
                /* Chop off trailing ';1' from files. */
 
1778
                if (name_len > 2 && p[name_len - 2] == ';' &&
 
1779
                                p[name_len - 1] == '1')
 
1780
                        name_len -= 2;
 
1781
                /* Chop off trailing '.' from filenames. */
 
1782
                if (name_len > 1 && p[name_len - 1] == '.')
 
1783
                        --name_len;
 
1784
 
 
1785
                archive_strncpy(&file->name, (const char *)p, name_len);
 
1786
        }
 
1787
 
 
1788
        flags = isodirrec[DR_flags_offset];
 
1789
        if (flags & 0x02)
 
1790
                file->mode = AE_IFDIR | 0700;
 
1791
        else
 
1792
                file->mode = AE_IFREG | 0400;
 
1793
        if (flags & 0x80)
 
1794
                file->multi_extent = 1;
 
1795
        else
 
1796
                file->multi_extent = 0;
 
1797
        /*
 
1798
         * Use location for file number.
 
1799
         * File number is treated as inode number to find out harlink
 
1800
         * target. If Rockridge extensions is being used, file number
 
1801
         * will be overwritten by FILE SERIAL NUMBER of RRIP "PX"
 
1802
         * extension.
 
1803
         * NOTE: Old mkisofs did not record that FILE SERIAL NUMBER
 
1804
         * in ISO images.
 
1805
         */
 
1806
        if (file->size == 0 && location >= 0)
 
1807
                /* If file->size is zero, its location points wrong place.
 
1808
                 * Dot not use it for file number.
 
1809
                 * When location has negative value, it can be used
 
1810
                 * for file number.
 
1811
                 */
 
1812
                file->number = -1;
 
1813
        else
 
1814
                file->number = (int64_t)(uint32_t)location;
 
1815
 
 
1816
        /* Rockridge extensions overwrite information from above. */
 
1817
        if (iso9660->opt_support_rockridge) {
 
1818
                if (parent == NULL && rr_end - rr_start >= 7) {
 
1819
                        p = rr_start;
 
1820
                        if (p[0] == 'S' && p[1] == 'P'
 
1821
                            && p[2] == 7 && p[3] == 1
 
1822
                            && p[4] == 0xBE && p[5] == 0xEF) {
 
1823
                                /*
 
1824
                                 * SP extension stores the suspOffset
 
1825
                                 * (Number of bytes to skip between
 
1826
                                 * filename and SUSP records.)
 
1827
                                 * It is mandatory by the SUSP standard
 
1828
                                 * (IEEE 1281).
 
1829
                                 *
 
1830
                                 * It allows SUSP to coexist with
 
1831
                                 * non-SUSP uses of the System
 
1832
                                 * Use Area by placing non-SUSP data
 
1833
                                 * before SUSP data.
 
1834
                                 *
 
1835
                                 * SP extension must be in the root
 
1836
                                 * directory entry, disable all SUSP
 
1837
                                 * processing if not found.
 
1838
                                 */
 
1839
                                iso9660->suspOffset = p[6];
 
1840
                                iso9660->seenSUSP = 1;
 
1841
                                rr_start += 7;
 
1842
                        }
 
1843
                }
 
1844
                if (iso9660->seenSUSP) {
 
1845
                        int r;
 
1846
 
 
1847
                        file->name_continues = 0;
 
1848
                        file->symlink_continues = 0;
 
1849
                        rr_start += iso9660->suspOffset;
 
1850
                        r = parse_rockridge(a, file, rr_start, rr_end);
 
1851
                        if (r != ARCHIVE_OK) {
 
1852
                                free(file);
 
1853
                                return (NULL);
 
1854
                        }
 
1855
                } else
 
1856
                        /* If there isn't SUSP, disable parsing
 
1857
                         * rock ridge extensions. */
 
1858
                        iso9660->opt_support_rockridge = 0;
 
1859
        }
 
1860
 
 
1861
        file->nlinks = 1;/* Reset nlink. we'll calculate it later. */
 
1862
        /* Tell file's parent how many children that parent has. */
 
1863
        if (parent != NULL && (flags & 0x02) && file->cl_offset == 0)
 
1864
                parent->subdirs++;
 
1865
 
 
1866
#if DEBUG
 
1867
        /* DEBUGGING: Warn about attributes I don't yet fully support. */
 
1868
        if ((flags & ~0x02) != 0) {
 
1869
                fprintf(stderr, "\n ** Unrecognized flag: ");
 
1870
                dump_isodirrec(stderr, isodirrec);
 
1871
                fprintf(stderr, "\n");
 
1872
        } else if (toi(isodirrec + DR_volume_sequence_number_offset, 2) != 1) {
 
1873
                fprintf(stderr, "\n ** Unrecognized sequence number: ");
 
1874
                dump_isodirrec(stderr, isodirrec);
 
1875
                fprintf(stderr, "\n");
 
1876
        } else if (*(isodirrec + DR_file_unit_size_offset) != 0) {
 
1877
                fprintf(stderr, "\n ** Unexpected file unit size: ");
 
1878
                dump_isodirrec(stderr, isodirrec);
 
1879
                fprintf(stderr, "\n");
 
1880
        } else if (*(isodirrec + DR_interleave_offset) != 0) {
 
1881
                fprintf(stderr, "\n ** Unexpected interleave: ");
 
1882
                dump_isodirrec(stderr, isodirrec);
 
1883
                fprintf(stderr, "\n");
 
1884
        } else if (*(isodirrec + DR_ext_attr_length_offset) != 0) {
 
1885
                fprintf(stderr, "\n ** Unexpected extended attribute length: ");
 
1886
                dump_isodirrec(stderr, isodirrec);
 
1887
                fprintf(stderr, "\n");
 
1888
        }
 
1889
#endif
 
1890
        register_file(iso9660, file);
 
1891
        return (file);
 
1892
}
 
1893
 
 
1894
static int
 
1895
parse_rockridge(struct archive_read *a, struct file_info *file,
 
1896
    const unsigned char *p, const unsigned char *end)
 
1897
{
 
1898
        struct iso9660 *iso9660;
 
1899
 
 
1900
        iso9660 = (struct iso9660 *)(a->format->data);
 
1901
 
 
1902
        while (p + 4 <= end  /* Enough space for another entry. */
 
1903
            && p[0] >= 'A' && p[0] <= 'Z' /* Sanity-check 1st char of name. */
 
1904
            && p[1] >= 'A' && p[1] <= 'Z' /* Sanity-check 2nd char of name. */
 
1905
            && p[2] >= 4 /* Sanity-check length. */
 
1906
            && p + p[2] <= end) { /* Sanity-check length. */
 
1907
                const unsigned char *data = p + 4;
 
1908
                int data_length = p[2] - 4;
 
1909
                int version = p[3];
 
1910
 
 
1911
                /*
 
1912
                 * Yes, each 'if' here does test p[0] again.
 
1913
                 * Otherwise, the fall-through handling to catch
 
1914
                 * unsupported extensions doesn't work.
 
1915
                 */
 
1916
                switch(p[0]) {
 
1917
                case 'C':
 
1918
                        if (p[0] == 'C' && p[1] == 'E') {
 
1919
                                if (version == 1 && data_length == 24) {
 
1920
                                        /*
 
1921
                                         * CE extension comprises:
 
1922
                                         *   8 byte sector containing extension
 
1923
                                         *   8 byte offset w/in above sector
 
1924
                                         *   8 byte length of continuation
 
1925
                                         */
 
1926
                                        int32_t location =
 
1927
                                            archive_le32dec(data);
 
1928
                                        file->ce_offset =
 
1929
                                            archive_le32dec(data+8);
 
1930
                                        file->ce_size =
 
1931
                                            archive_le32dec(data+16);
 
1932
                                        if (register_CE(a, location, file)
 
1933
                                            != ARCHIVE_OK)
 
1934
                                                return (ARCHIVE_FATAL);
 
1935
                                }
 
1936
                                break;
 
1937
                        }
 
1938
                        if (p[0] == 'C' && p[1] == 'L') {
 
1939
                                if (version == 1 && data_length == 8) {
 
1940
                                        file->cl_offset = (uint64_t)
 
1941
                                            iso9660->logical_block_size *
 
1942
                                            (uint64_t)archive_le32dec(data);
 
1943
                                        iso9660->seenRockridge = 1;
 
1944
                                }
 
1945
                                break;
 
1946
                        }
 
1947
                        /* FALLTHROUGH */
 
1948
                case 'N':
 
1949
                        if (p[0] == 'N' && p[1] == 'M') {
 
1950
                                if (version == 1) {
 
1951
                                        parse_rockridge_NM1(file,
 
1952
                                            data, data_length);
 
1953
                                        iso9660->seenRockridge = 1;
 
1954
                                }
 
1955
                                break;
 
1956
                        }
 
1957
                        /* FALLTHROUGH */
 
1958
                case 'P':
 
1959
                        if (p[0] == 'P' && p[1] == 'D') {
 
1960
                                /*
 
1961
                                 * PD extension is padding;
 
1962
                                 * contents are always ignored.
 
1963
                                 */
 
1964
                                break;
 
1965
                        }
 
1966
                        if (p[0] == 'P' && p[1] == 'N') {
 
1967
                                if (version == 1 && data_length == 16) {
 
1968
                                        file->rdev = toi(data,4);
 
1969
                                        file->rdev <<= 32;
 
1970
                                        file->rdev |= toi(data + 8, 4);
 
1971
                                        iso9660->seenRockridge = 1;
 
1972
                                }
 
1973
                                break;
 
1974
                        }
 
1975
                        if (p[0] == 'P' && p[1] == 'X') {
 
1976
                                /*
 
1977
                                 * PX extension comprises:
 
1978
                                 *   8 bytes for mode,
 
1979
                                 *   8 bytes for nlinks,
 
1980
                                 *   8 bytes for uid,
 
1981
                                 *   8 bytes for gid,
 
1982
                                 *   8 bytes for inode.
 
1983
                                 */
 
1984
                                if (version == 1) {
 
1985
                                        if (data_length >= 8)
 
1986
                                                file->mode
 
1987
                                                    = toi(data, 4);
 
1988
                                        if (data_length >= 16)
 
1989
                                                file->nlinks
 
1990
                                                    = toi(data + 8, 4);
 
1991
                                        if (data_length >= 24)
 
1992
                                                file->uid
 
1993
                                                    = toi(data + 16, 4);
 
1994
                                        if (data_length >= 32)
 
1995
                                                file->gid
 
1996
                                                    = toi(data + 24, 4);
 
1997
                                        if (data_length >= 40)
 
1998
                                                file->number
 
1999
                                                    = toi(data + 32, 4);
 
2000
                                        iso9660->seenRockridge = 1;
 
2001
                                }
 
2002
                                break;
 
2003
                        }
 
2004
                        /* FALLTHROUGH */
 
2005
                case 'R':
 
2006
                        if (p[0] == 'R' && p[1] == 'E' && version == 1) {
 
2007
                                file->re = 1;
 
2008
                                iso9660->seenRockridge = 1;
 
2009
                                break;
 
2010
                        }
 
2011
                        if (p[0] == 'R' && p[1] == 'R' && version == 1) {
 
2012
                                /*
 
2013
                                 * RR extension comprises:
 
2014
                                 *    one byte flag value
 
2015
                                 * This extension is obsolete,
 
2016
                                 * so contents are always ignored.
 
2017
                                 */
 
2018
                                break;
 
2019
                        }
 
2020
                        /* FALLTHROUGH */
 
2021
                case 'S':
 
2022
                        if (p[0] == 'S' && p[1] == 'L') {
 
2023
                                if (version == 1) {
 
2024
                                        parse_rockridge_SL1(file,
 
2025
                                            data, data_length);
 
2026
                                        iso9660->seenRockridge = 1;
 
2027
                                }
 
2028
                                break;
 
2029
                        }
 
2030
                        if (p[0] == 'S' && p[1] == 'T'
 
2031
                            && data_length == 0 && version == 1) {
 
2032
                                /*
 
2033
                                 * ST extension marks end of this
 
2034
                                 * block of SUSP entries.
 
2035
                                 *
 
2036
                                 * It allows SUSP to coexist with
 
2037
                                 * non-SUSP uses of the System
 
2038
                                 * Use Area by placing non-SUSP data
 
2039
                                 * after SUSP data.
 
2040
                                 */
 
2041
                                iso9660->seenSUSP = 0;
 
2042
                                iso9660->seenRockridge = 0;
 
2043
                                return (ARCHIVE_OK);
 
2044
                        }
 
2045
                case 'T':
 
2046
                        if (p[0] == 'T' && p[1] == 'F') {
 
2047
                                if (version == 1) {
 
2048
                                        parse_rockridge_TF1(file,
 
2049
                                            data, data_length);
 
2050
                                        iso9660->seenRockridge = 1;
 
2051
                                }
 
2052
                                break;
 
2053
                        }
 
2054
                        /* FALLTHROUGH */
 
2055
                case 'Z':
 
2056
                        if (p[0] == 'Z' && p[1] == 'F') {
 
2057
                                if (version == 1)
 
2058
                                        parse_rockridge_ZF1(file,
 
2059
                                            data, data_length);
 
2060
                                break;
 
2061
                        }
 
2062
                        /* FALLTHROUGH */
 
2063
                default:
 
2064
                        /* The FALLTHROUGHs above leave us here for
 
2065
                         * any unsupported extension. */
 
2066
                        break;
 
2067
                }
 
2068
 
 
2069
 
 
2070
 
 
2071
                p += p[2];
 
2072
        }
 
2073
        return (ARCHIVE_OK);
 
2074
}
 
2075
 
 
2076
static int
 
2077
register_CE(struct archive_read *a, int32_t location,
 
2078
    struct file_info *file)
 
2079
{
 
2080
        struct iso9660 *iso9660;
 
2081
        struct read_ce_queue *heap;
 
2082
        struct read_ce_req *p;
 
2083
        uint64_t offset, parent_offset;
 
2084
        int hole, parent;
 
2085
 
 
2086
        iso9660 = (struct iso9660 *)(a->format->data);
 
2087
        offset = ((uint64_t)location) * (uint64_t)iso9660->logical_block_size;
 
2088
        if (((file->mode & AE_IFMT) == AE_IFREG &&
 
2089
            offset >= file->offset) ||
 
2090
            offset < iso9660->current_position) {
 
2091
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
2092
                    "Invalid location in SUSP \"CE\" extension");
 
2093
                return (ARCHIVE_FATAL);
 
2094
        }
 
2095
 
 
2096
        /* Expand our CE list as necessary. */
 
2097
        heap = &(iso9660->read_ce_req);
 
2098
        if (heap->cnt >= heap->allocated) {
 
2099
                int new_size;
 
2100
 
 
2101
                if (heap->allocated < 16)
 
2102
                        new_size = 16;
 
2103
                else
 
2104
                        new_size = heap->allocated * 2;
 
2105
                /* Overflow might keep us from growing the list. */
 
2106
                if (new_size <= heap->allocated)
 
2107
                        __archive_errx(1, "Out of memory");
 
2108
                p = malloc(new_size * sizeof(p[0]));
 
2109
                if (p == NULL)
 
2110
                        __archive_errx(1, "Out of memory");
 
2111
                if (heap->reqs != NULL) {
 
2112
                        memcpy(p, heap->reqs, heap->cnt * sizeof(*p));
 
2113
                        free(heap->reqs);
 
2114
                }
 
2115
                heap->reqs = p;
 
2116
                heap->allocated = new_size;
 
2117
        }
 
2118
 
 
2119
        /*
 
2120
         * Start with hole at end, walk it up tree to find insertion point.
 
2121
         */
 
2122
        hole = heap->cnt++;
 
2123
        while (hole > 0) {
 
2124
                parent = (hole - 1)/2;
 
2125
                parent_offset = heap->reqs[parent].offset;
 
2126
                if (offset >= parent_offset) {
 
2127
                        heap->reqs[hole].offset = offset;
 
2128
                        heap->reqs[hole].file = file;
 
2129
                        return (ARCHIVE_OK);
 
2130
                }
 
2131
                // Move parent into hole <==> move hole up tree.
 
2132
                heap->reqs[hole] = heap->reqs[parent];
 
2133
                hole = parent;
 
2134
        }
 
2135
        heap->reqs[0].offset = offset;
 
2136
        heap->reqs[0].file = file;
 
2137
        return (ARCHIVE_OK);
 
2138
}
 
2139
 
 
2140
static void
 
2141
next_CE(struct read_ce_queue *heap)
 
2142
{
 
2143
        uint64_t a_offset, b_offset, c_offset;
 
2144
        int a, b, c;
 
2145
        struct read_ce_req tmp;
 
2146
 
 
2147
        if (heap->cnt < 1)
 
2148
                return;
 
2149
 
 
2150
        /*
 
2151
         * Move the last item in the heap to the root of the tree
 
2152
         */
 
2153
        heap->reqs[0] = heap->reqs[--(heap->cnt)];
 
2154
 
 
2155
        /*
 
2156
         * Rebalance the heap.
 
2157
         */
 
2158
        a = 0; // Starting element and its offset
 
2159
        a_offset = heap->reqs[a].offset;
 
2160
        for (;;) {
 
2161
                b = a + a + 1; // First child
 
2162
                if (b >= heap->cnt)
 
2163
                        return;
 
2164
                b_offset = heap->reqs[b].offset;
 
2165
                c = b + 1; // Use second child if it is smaller.
 
2166
                if (c < heap->cnt) {
 
2167
                        c_offset = heap->reqs[c].offset;
 
2168
                        if (c_offset < b_offset) {
 
2169
                                b = c;
 
2170
                                b_offset = c_offset;
 
2171
                        }
 
2172
                }
 
2173
                if (a_offset <= b_offset)
 
2174
                        return;
 
2175
                tmp = heap->reqs[a];
 
2176
                heap->reqs[a] = heap->reqs[b];
 
2177
                heap->reqs[b] = tmp;
 
2178
                a = b;
 
2179
        }
 
2180
}
 
2181
 
 
2182
 
 
2183
static int
 
2184
read_CE(struct archive_read *a, struct iso9660 *iso9660)
 
2185
{
 
2186
        struct read_ce_queue *heap;
 
2187
        const unsigned char *b, *p, *end;
 
2188
        struct file_info *file;
 
2189
        size_t step;
 
2190
        int r;
 
2191
 
 
2192
        /* Read data which RRIP "CE" extension points. */
 
2193
        heap = &(iso9660->read_ce_req);
 
2194
        step = iso9660->logical_block_size;
 
2195
        while (heap->cnt &&
 
2196
            heap->reqs[0].offset == iso9660->current_position) {
 
2197
                b = __archive_read_ahead(a, step, NULL);
 
2198
                if (b == NULL) {
 
2199
                        archive_set_error(&a->archive,
 
2200
                            ARCHIVE_ERRNO_MISC,
 
2201
                            "Failed to read full block when scanning "
 
2202
                            "ISO9660 directory list");
 
2203
                        return (ARCHIVE_FATAL);
 
2204
                }
 
2205
                do {
 
2206
                        file = heap->reqs[0].file;
 
2207
                        p = b + file->ce_offset;
 
2208
                        end = p + file->ce_size;
 
2209
                        next_CE(heap);
 
2210
                        r = parse_rockridge(a, file, p, end);
 
2211
                        if (r != ARCHIVE_OK)
 
2212
                                return (ARCHIVE_FATAL);
 
2213
                } while (heap->cnt &&
 
2214
                    heap->reqs[0].offset == iso9660->current_position);
 
2215
                /* NOTE: Do not move this consume's code to fron of
 
2216
                 * do-while loop. Registration of nested CE extension
 
2217
                 * might cause error because of current position. */
 
2218
                __archive_read_consume(a, step);
 
2219
                iso9660->current_position += step;
 
2220
        }
 
2221
        return (ARCHIVE_OK);
 
2222
}
 
2223
 
 
2224
static void
 
2225
parse_rockridge_NM1(struct file_info *file,
 
2226
                    const unsigned char *data, int data_length)
 
2227
{
 
2228
        if (!file->name_continues)
 
2229
                archive_string_empty(&file->name);
 
2230
        file->name_continues = 0;
 
2231
        if (data_length < 1)
 
2232
                return;
 
2233
        /*
 
2234
         * NM version 1 extension comprises:
 
2235
         *   1 byte flag, value is one of:
 
2236
         *     = 0: remainder is name
 
2237
         *     = 1: remainder is name, next NM entry continues name
 
2238
         *     = 2: "."
 
2239
         *     = 4: ".."
 
2240
         *     = 32: Implementation specific
 
2241
         *     All other values are reserved.
 
2242
         */
 
2243
        switch(data[0]) {
 
2244
        case 0:
 
2245
                if (data_length < 2)
 
2246
                        return;
 
2247
                archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
 
2248
                break;
 
2249
        case 1:
 
2250
                if (data_length < 2)
 
2251
                        return;
 
2252
                archive_strncat(&file->name, (const char *)data + 1, data_length - 1);
 
2253
                file->name_continues = 1;
 
2254
                break;
 
2255
        case 2:
 
2256
                archive_strcat(&file->name, ".");
 
2257
                break;
 
2258
        case 4:
 
2259
                archive_strcat(&file->name, "..");
 
2260
                break;
 
2261
        default:
 
2262
                return;
 
2263
        }
 
2264
 
 
2265
}
 
2266
 
 
2267
static void
 
2268
parse_rockridge_TF1(struct file_info *file, const unsigned char *data,
 
2269
    int data_length)
 
2270
{
 
2271
        char flag;
 
2272
        /*
 
2273
         * TF extension comprises:
 
2274
         *   one byte flag
 
2275
         *   create time (optional)
 
2276
         *   modify time (optional)
 
2277
         *   access time (optional)
 
2278
         *   attribute time (optional)
 
2279
         *  Time format and presence of fields
 
2280
         *  is controlled by flag bits.
 
2281
         */
 
2282
        if (data_length < 1)
 
2283
                return;
 
2284
        flag = data[0];
 
2285
        ++data;
 
2286
        --data_length;
 
2287
        if (flag & 0x80) {
 
2288
                /* Use 17-byte time format. */
 
2289
                if ((flag & 1) && data_length >= 17) {
 
2290
                        /* Create time. */
 
2291
                        file->birthtime_is_set = 1;
 
2292
                        file->birthtime = isodate17(data);
 
2293
                        data += 17;
 
2294
                        data_length -= 17;
 
2295
                }
 
2296
                if ((flag & 2) && data_length >= 17) {
 
2297
                        /* Modify time. */
 
2298
                        file->mtime = isodate17(data);
 
2299
                        data += 17;
 
2300
                        data_length -= 17;
 
2301
                }
 
2302
                if ((flag & 4) && data_length >= 17) {
 
2303
                        /* Access time. */
 
2304
                        file->atime = isodate17(data);
 
2305
                        data += 17;
 
2306
                        data_length -= 17;
 
2307
                }
 
2308
                if ((flag & 8) && data_length >= 17) {
 
2309
                        /* Attribute change time. */
 
2310
                        file->ctime = isodate17(data);
 
2311
                }
 
2312
        } else {
 
2313
                /* Use 7-byte time format. */
 
2314
                if ((flag & 1) && data_length >= 7) {
 
2315
                        /* Create time. */
 
2316
                        file->birthtime_is_set = 1;
 
2317
                        file->birthtime = isodate7(data);
 
2318
                        data += 7;
 
2319
                        data_length -= 7;
 
2320
                }
 
2321
                if ((flag & 2) && data_length >= 7) {
 
2322
                        /* Modify time. */
 
2323
                        file->mtime = isodate7(data);
 
2324
                        data += 7;
 
2325
                        data_length -= 7;
 
2326
                }
 
2327
                if ((flag & 4) && data_length >= 7) {
 
2328
                        /* Access time. */
 
2329
                        file->atime = isodate7(data);
 
2330
                        data += 7;
 
2331
                        data_length -= 7;
 
2332
                }
 
2333
                if ((flag & 8) && data_length >= 7) {
 
2334
                        /* Attribute change time. */
 
2335
                        file->ctime = isodate7(data);
 
2336
                }
 
2337
        }
 
2338
}
 
2339
 
 
2340
static void
 
2341
parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
 
2342
    int data_length)
 
2343
{
 
2344
        const char *separator = "";
 
2345
 
 
2346
        if (!file->symlink_continues || file->symlink.length < 1)
 
2347
                archive_string_empty(&file->symlink);
 
2348
        else if (!file->symlink_continues &&
 
2349
            file->symlink.s[file->symlink.length - 1] != '/')
 
2350
                separator = "/";
 
2351
        file->symlink_continues = 0;
 
2352
 
 
2353
        /*
 
2354
         * Defined flag values:
 
2355
         *  0: This is the last SL record for this symbolic link
 
2356
         *  1: this symbolic link field continues in next SL entry
 
2357
         *  All other values are reserved.
 
2358
         */
 
2359
        if (data_length < 1)
 
2360
                return;
 
2361
        switch(*data) {
 
2362
        case 0:
 
2363
                break;
 
2364
        case 1:
 
2365
                file->symlink_continues = 1;
 
2366
                break;
 
2367
        default:
 
2368
                return;
 
2369
        }
 
2370
        ++data;  /* Skip flag byte. */
 
2371
        --data_length;
 
2372
 
 
2373
        /*
 
2374
         * SL extension body stores "components".
 
2375
         * Basically, this is a complicated way of storing
 
2376
         * a POSIX path.  It also interferes with using
 
2377
         * symlinks for storing non-path data. <sigh>
 
2378
         *
 
2379
         * Each component is 2 bytes (flag and length)
 
2380
         * possibly followed by name data.
 
2381
         */
 
2382
        while (data_length >= 2) {
 
2383
                unsigned char flag = *data++;
 
2384
                unsigned char nlen = *data++;
 
2385
                data_length -= 2;
 
2386
 
 
2387
                archive_strcat(&file->symlink, separator);
 
2388
                separator = "/";
 
2389
 
 
2390
                switch(flag) {
 
2391
                case 0: /* Usual case, this is text. */
 
2392
                        if (data_length < nlen)
 
2393
                                return;
 
2394
                        archive_strncat(&file->symlink,
 
2395
                            (const char *)data, nlen);
 
2396
                        break;
 
2397
                case 0x01: /* Text continues in next component. */
 
2398
                        if (data_length < nlen)
 
2399
                                return;
 
2400
                        archive_strncat(&file->symlink,
 
2401
                            (const char *)data, nlen);
 
2402
                        separator = "";
 
2403
                        break;
 
2404
                case 0x02: /* Current dir. */
 
2405
                        archive_strcat(&file->symlink, ".");
 
2406
                        break;
 
2407
                case 0x04: /* Parent dir. */
 
2408
                        archive_strcat(&file->symlink, "..");
 
2409
                        break;
 
2410
                case 0x08: /* Root of filesystem. */
 
2411
                        archive_strcat(&file->symlink, "/");
 
2412
                        separator = "";
 
2413
                        break;
 
2414
                case 0x10: /* Undefined (historically "volume root" */
 
2415
                        archive_string_empty(&file->symlink);
 
2416
                        archive_strcat(&file->symlink, "ROOT");
 
2417
                        break;
 
2418
                case 0x20: /* Undefined (historically "hostname") */
 
2419
                        archive_strcat(&file->symlink, "hostname");
 
2420
                        break;
 
2421
                default:
 
2422
                        /* TODO: issue a warning ? */
 
2423
                        return;
 
2424
                }
 
2425
                data += nlen;
 
2426
                data_length -= nlen;
 
2427
        }
 
2428
}
 
2429
 
 
2430
static void
 
2431
parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
 
2432
    int data_length)
 
2433
{
 
2434
 
 
2435
        if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) {
 
2436
                /* paged zlib */
 
2437
                file->pz = 1;
 
2438
                file->pz_log2_bs = data[3];
 
2439
                file->pz_uncompressed_size = archive_le32dec(&data[4]);
 
2440
        }
 
2441
}
 
2442
 
 
2443
static void
 
2444
register_file(struct iso9660 *iso9660, struct file_info *file)
 
2445
{
 
2446
 
 
2447
        file->use_next = iso9660->use_files;
 
2448
        iso9660->use_files = file;
 
2449
}
 
2450
 
 
2451
static void
 
2452
release_files(struct iso9660 *iso9660)
 
2453
{
 
2454
        struct content *con, *connext;
 
2455
        struct file_info *file;
 
2456
 
 
2457
        file = iso9660->use_files;
 
2458
        while (file != NULL) {
 
2459
                struct file_info *next = file->use_next;
 
2460
 
 
2461
                archive_string_free(&file->name);
 
2462
                archive_string_free(&file->symlink);
 
2463
                con = file->contents.first;
 
2464
                while (con != NULL) {
 
2465
                        connext = con->next;
 
2466
                        free(con);
 
2467
                        con = connext;
 
2468
                }
 
2469
                free(file);
 
2470
                file = next;
 
2471
        }
 
2472
}
 
2473
 
 
2474
static int
 
2475
next_entry_seek(struct archive_read *a, struct iso9660 *iso9660,
 
2476
    struct file_info **pfile)
 
2477
{
 
2478
        struct file_info *file;
 
2479
 
 
2480
        *pfile = file = next_cache_entry(iso9660);
 
2481
        if (file == NULL)
 
2482
                return (ARCHIVE_EOF);
 
2483
 
 
2484
        /* Don't waste time seeking for zero-length bodies. */
 
2485
        if (file->size == 0)
 
2486
                file->offset = iso9660->current_position;
 
2487
 
 
2488
        /* Seek forward to the start of the entry. */
 
2489
        if (iso9660->current_position < file->offset) {
 
2490
                int64_t step;
 
2491
 
 
2492
                step = file->offset - iso9660->current_position;
 
2493
                step = __archive_read_skip(a, step);
 
2494
                if (step < 0)
 
2495
                        return ((int)step);
 
2496
                iso9660->current_position = file->offset;
 
2497
        }
 
2498
 
 
2499
        /* We found body of file; handle it now. */
 
2500
        return (ARCHIVE_OK);
 
2501
}
 
2502
 
 
2503
static struct file_info *
 
2504
next_cache_entry(struct iso9660 *iso9660)
 
2505
{
 
2506
        struct file_info *file;
 
2507
        struct {
 
2508
                struct file_info        *first;
 
2509
                struct file_info        **last;
 
2510
        }       empty_files;
 
2511
        int64_t number;
 
2512
        int count;
 
2513
 
 
2514
        file = cache_get_entry(iso9660);
 
2515
        if (file != NULL) {
 
2516
                while (file->parent != NULL && !file->parent->exposed) {
 
2517
                        /* If file's parent is not exposed, it's moved
 
2518
                         * to next entry of its parent. */
 
2519
                        cache_add_to_next_of_parent(iso9660, file);
 
2520
                        file = cache_get_entry(iso9660);
 
2521
                }
 
2522
                return (file);
 
2523
        }
 
2524
 
 
2525
        file = next_entry(iso9660);
 
2526
        if (file == NULL)
 
2527
                return (NULL);
 
2528
 
 
2529
        if ((file->mode & AE_IFMT) != AE_IFREG || file->number == -1)
 
2530
                return (file);
 
2531
 
 
2532
        count = 0;
 
2533
        number = file->number;
 
2534
        iso9660->cache_files.first = NULL;
 
2535
        iso9660->cache_files.last = &(iso9660->cache_files.first);
 
2536
        empty_files.first = NULL;
 
2537
        empty_files.last = &empty_files.first;
 
2538
        /* Collect files which has the same file serial number.
 
2539
         * Peek pending_files so that file which number is different
 
2540
         * is not put bak. */
 
2541
        while (iso9660->pending_files.used > 0 &&
 
2542
            (iso9660->pending_files.files[0]->number == -1 ||
 
2543
             iso9660->pending_files.files[0]->number == number)) {
 
2544
                if (file->number == -1) {
 
2545
                        /* This file has the same offset
 
2546
                         * but it's wrong offset which empty files
 
2547
                         * and symlink files have.
 
2548
                         * NOTE: This wrong offse was recorded by
 
2549
                         * old mkisofs utility. If ISO images is
 
2550
                         * created by latest mkisofs, this does not
 
2551
                         * happen.
 
2552
                         */
 
2553
                        file->next = NULL;
 
2554
                        *empty_files.last = file;
 
2555
                        empty_files.last = &(file->next);
 
2556
                } else {
 
2557
                        count++;
 
2558
                        cache_add_entry(iso9660, file);
 
2559
                }
 
2560
                file = next_entry(iso9660);
 
2561
        }
 
2562
 
 
2563
        if (count == 0)
 
2564
                return (file);
 
2565
        if (file->number == -1) {
 
2566
                file->next = NULL;
 
2567
                *empty_files.last = file;
 
2568
                empty_files.last = &(file->next);
 
2569
        } else {
 
2570
                count++;
 
2571
                cache_add_entry(iso9660, file);
 
2572
        }
 
2573
 
 
2574
        if (count > 1) {
 
2575
                /* The count is the same as number of hardlink,
 
2576
                 * so much so that each nlinks of files in cache_file
 
2577
                 * is overwritten by value of the count.
 
2578
                 */
 
2579
                for (file = iso9660->cache_files.first;
 
2580
                    file != NULL; file = file->next)
 
2581
                        file->nlinks = count;
 
2582
        }
 
2583
        /* If there are empty files, that files are added
 
2584
         * to the tail of the cache_files. */
 
2585
        if (empty_files.first != NULL) {
 
2586
                *iso9660->cache_files.last = empty_files.first;
 
2587
                iso9660->cache_files.last = empty_files.last;
 
2588
        }
 
2589
        return (cache_get_entry(iso9660));
 
2590
}
 
2591
 
 
2592
static inline void
 
2593
cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
 
2594
{
 
2595
        file->next = NULL;
 
2596
        *iso9660->cache_files.last = file;
 
2597
        iso9660->cache_files.last = &(file->next);
 
2598
}
 
2599
 
 
2600
static inline void
 
2601
cache_add_to_next_of_parent(struct iso9660 *iso9660, struct file_info *file)
 
2602
{
 
2603
        file->next = file->parent->next;
 
2604
        file->parent->next = file;
 
2605
        if (iso9660->cache_files.last == &(file->parent->next))
 
2606
                iso9660->cache_files.last = &(file->next);
 
2607
}
 
2608
 
 
2609
static inline struct file_info *
 
2610
cache_get_entry(struct iso9660 *iso9660)
 
2611
{
 
2612
        struct file_info *file;
 
2613
 
 
2614
        if ((file = iso9660->cache_files.first) != NULL) {
 
2615
                iso9660->cache_files.first = file->next;
 
2616
                if (iso9660->cache_files.first == NULL)
 
2617
                        iso9660->cache_files.last = &(iso9660->cache_files.first);
 
2618
        }
 
2619
        return (file);
 
2620
}
 
2621
 
 
2622
static void
 
2623
heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
 
2624
{
 
2625
        uint64_t file_key, parent_key;
 
2626
        int hole, parent;
 
2627
 
 
2628
        /* Expand our pending files list as necessary. */
 
2629
        if (heap->used >= heap->allocated) {
 
2630
                struct file_info **new_pending_files;
 
2631
                int new_size = heap->allocated * 2;
 
2632
 
 
2633
                if (heap->allocated < 1024)
 
2634
                        new_size = 1024;
 
2635
                /* Overflow might keep us from growing the list. */
 
2636
                if (new_size <= heap->allocated)
 
2637
                        __archive_errx(1, "Out of memory");
 
2638
                new_pending_files = (struct file_info **)
 
2639
                    malloc(new_size * sizeof(new_pending_files[0]));
 
2640
                if (new_pending_files == NULL)
 
2641
                        __archive_errx(1, "Out of memory");
 
2642
                memcpy(new_pending_files, heap->files,
 
2643
                    heap->allocated * sizeof(new_pending_files[0]));
 
2644
                if (heap->files != NULL)
 
2645
                        free(heap->files);
 
2646
                heap->files = new_pending_files;
 
2647
                heap->allocated = new_size;
 
2648
        }
 
2649
 
 
2650
        file_key = file->key = key;
 
2651
 
 
2652
        /*
 
2653
         * Start with hole at end, walk it up tree to find insertion point.
 
2654
         */
 
2655
        hole = heap->used++;
 
2656
        while (hole > 0) {
 
2657
                parent = (hole - 1)/2;
 
2658
                parent_key = heap->files[parent]->key;
 
2659
                if (file_key >= parent_key) {
 
2660
                        heap->files[hole] = file;
 
2661
                        return;
 
2662
                }
 
2663
                // Move parent into hole <==> move hole up tree.
 
2664
                heap->files[hole] = heap->files[parent];
 
2665
                hole = parent;
 
2666
        }
 
2667
        heap->files[0] = file;
 
2668
}
 
2669
 
 
2670
static struct file_info *
 
2671
heap_get_entry(struct heap_queue *heap)
 
2672
{
 
2673
        uint64_t a_key, b_key, c_key;
 
2674
        int a, b, c;
 
2675
        struct file_info *r, *tmp;
 
2676
 
 
2677
        if (heap->used < 1)
 
2678
                return (NULL);
 
2679
 
 
2680
        /*
 
2681
         * The first file in the list is the earliest; we'll return this.
 
2682
         */
 
2683
        r = heap->files[0];
 
2684
 
 
2685
        /*
 
2686
         * Move the last item in the heap to the root of the tree
 
2687
         */
 
2688
        heap->files[0] = heap->files[--(heap->used)];
 
2689
 
 
2690
        /*
 
2691
         * Rebalance the heap.
 
2692
         */
 
2693
        a = 0; // Starting element and its heap key
 
2694
        a_key = heap->files[a]->key;
 
2695
        for (;;) {
 
2696
                b = a + a + 1; // First child
 
2697
                if (b >= heap->used)
 
2698
                        return (r);
 
2699
                b_key = heap->files[b]->key;
 
2700
                c = b + 1; // Use second child if it is smaller.
 
2701
                if (c < heap->used) {
 
2702
                        c_key = heap->files[c]->key;
 
2703
                        if (c_key < b_key) {
 
2704
                                b = c;
 
2705
                                b_key = c_key;
 
2706
                        }
 
2707
                }
 
2708
                if (a_key <= b_key)
 
2709
                        return (r);
 
2710
                tmp = heap->files[a];
 
2711
                heap->files[a] = heap->files[b];
 
2712
                heap->files[b] = tmp;
 
2713
                a = b;
 
2714
        }
 
2715
}
 
2716
 
 
2717
static unsigned int
 
2718
toi(const void *p, int n)
 
2719
{
 
2720
        const unsigned char *v = (const unsigned char *)p;
 
2721
        if (n > 1)
 
2722
                return v[0] + 256 * toi(v + 1, n - 1);
 
2723
        if (n == 1)
 
2724
                return v[0];
 
2725
        return (0);
 
2726
}
 
2727
 
 
2728
static time_t
 
2729
isodate7(const unsigned char *v)
 
2730
{
 
2731
        struct tm tm;
 
2732
        int offset;
 
2733
        memset(&tm, 0, sizeof(tm));
 
2734
        tm.tm_year = v[0];
 
2735
        tm.tm_mon = v[1] - 1;
 
2736
        tm.tm_mday = v[2];
 
2737
        tm.tm_hour = v[3];
 
2738
        tm.tm_min = v[4];
 
2739
        tm.tm_sec = v[5];
 
2740
        /* v[6] is the signed timezone offset, in 1/4-hour increments. */
 
2741
        offset = ((const signed char *)v)[6];
 
2742
        if (offset > -48 && offset < 52) {
 
2743
                tm.tm_hour -= offset / 4;
 
2744
                tm.tm_min -= (offset % 4) * 15;
 
2745
        }
 
2746
        return (time_from_tm(&tm));
 
2747
}
 
2748
 
 
2749
static time_t
 
2750
isodate17(const unsigned char *v)
 
2751
{
 
2752
        struct tm tm;
 
2753
        int offset;
 
2754
        memset(&tm, 0, sizeof(tm));
 
2755
        tm.tm_year = (v[0] - '0') * 1000 + (v[1] - '0') * 100
 
2756
            + (v[2] - '0') * 10 + (v[3] - '0')
 
2757
            - 1900;
 
2758
        tm.tm_mon = (v[4] - '0') * 10 + (v[5] - '0');
 
2759
        tm.tm_mday = (v[6] - '0') * 10 + (v[7] - '0');
 
2760
        tm.tm_hour = (v[8] - '0') * 10 + (v[9] - '0');
 
2761
        tm.tm_min = (v[10] - '0') * 10 + (v[11] - '0');
 
2762
        tm.tm_sec = (v[12] - '0') * 10 + (v[13] - '0');
 
2763
        /* v[16] is the signed timezone offset, in 1/4-hour increments. */
 
2764
        offset = ((const signed char *)v)[16];
 
2765
        if (offset > -48 && offset < 52) {
 
2766
                tm.tm_hour -= offset / 4;
 
2767
                tm.tm_min -= (offset % 4) * 15;
 
2768
        }
 
2769
        return (time_from_tm(&tm));
 
2770
}
 
2771
 
 
2772
static time_t
 
2773
time_from_tm(struct tm *t)
 
2774
{
 
2775
#if HAVE_TIMEGM
 
2776
        /* Use platform timegm() if available. */
 
2777
        return (timegm(t));
 
2778
#else
 
2779
        /* Else use direct calculation using POSIX assumptions. */
 
2780
        /* First, fix up tm_yday based on the year/month/day. */
 
2781
        mktime(t);
 
2782
        /* Then we can compute timegm() from first principles. */
 
2783
        return (t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600
 
2784
            + t->tm_yday * 86400 + (t->tm_year - 70) * 31536000
 
2785
            + ((t->tm_year - 69) / 4) * 86400 -
 
2786
            ((t->tm_year - 1) / 100) * 86400
 
2787
            + ((t->tm_year + 299) / 400) * 86400);
 
2788
#endif
 
2789
}
 
2790
 
 
2791
static const char *
 
2792
build_pathname(struct archive_string *as, struct file_info *file)
 
2793
{
 
2794
        if (file->parent != NULL && archive_strlen(&file->parent->name) > 0) {
 
2795
                build_pathname(as, file->parent);
 
2796
                archive_strcat(as, "/");
 
2797
        }
 
2798
        if (archive_strlen(&file->name) == 0)
 
2799
                archive_strcat(as, ".");
 
2800
        else
 
2801
                archive_string_concat(as, &file->name);
 
2802
        return (as->s);
 
2803
}
 
2804
 
 
2805
#if DEBUG
 
2806
static void
 
2807
dump_isodirrec(FILE *out, const unsigned char *isodirrec)
 
2808
{
 
2809
        fprintf(out, " l %d,",
 
2810
            toi(isodirrec + DR_length_offset, DR_length_size));
 
2811
        fprintf(out, " a %d,",
 
2812
            toi(isodirrec + DR_ext_attr_length_offset, DR_ext_attr_length_size));
 
2813
        fprintf(out, " ext 0x%x,",
 
2814
            toi(isodirrec + DR_extent_offset, DR_extent_size));
 
2815
        fprintf(out, " s %d,",
 
2816
            toi(isodirrec + DR_size_offset, DR_extent_size));
 
2817
        fprintf(out, " f 0x%02x,",
 
2818
            toi(isodirrec + DR_flags_offset, DR_flags_size));
 
2819
        fprintf(out, " u %d,",
 
2820
            toi(isodirrec + DR_file_unit_size_offset, DR_file_unit_size_size));
 
2821
        fprintf(out, " ilv %d,",
 
2822
            toi(isodirrec + DR_interleave_offset, DR_interleave_size));
 
2823
        fprintf(out, " seq %d,",
 
2824
            toi(isodirrec + DR_volume_sequence_number_offset, DR_volume_sequence_number_size));
 
2825
        fprintf(out, " nl %d:",
 
2826
            toi(isodirrec + DR_name_len_offset, DR_name_len_size));
 
2827
        fprintf(out, " `%.*s'",
 
2828
            toi(isodirrec + DR_name_len_offset, DR_name_len_size), isodirrec + DR_name_offset);
 
2829
}
 
2830
#endif