libarchive-static 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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