~ubuntu-branches/ubuntu/quantal/libarchive/quantal

« back to all changes in this revision

Viewing changes to .pc/0004-Patch-from-upstream-rev-2520.patch/libarchive/archive_read_support_format_iso9660.c

  • Committer: Package Import Robot
  • Author(s): Andres Mejia
  • Date: 2012-02-23 19:29:24 UTC
  • mfrom: (8.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120223192924-73n4iedok5fwgsyr
Tags: 3.0.3-5
* Detect if locales or locales-all is installed for use with test suite.
* Bump Standards-Version to 3.9.3.

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