libarchive-static 1.0.0

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