libarchive-static 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. checksums.yaml +5 -5
  2. data/ext/extconf.rb +2 -9
  3. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +6 -6
  4. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.o +0 -0
  5. data/ext/libarchive-0.1.1/ext/archive_read_support_format.o +0 -0
  6. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +1 -1
  7. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.o +0 -0
  8. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +5 -5
  9. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.o +0 -0
  10. data/ext/libarchive-0.1.1/ext/config.h +23 -0
  11. data/ext/libarchive-0.1.1/ext/config.log +230 -0
  12. data/ext/libarchive-0.1.1/ext/config.status +671 -0
  13. data/ext/libarchive-0.1.1/ext/libarchive.c +1 -1
  14. data/ext/libarchive-0.1.1/ext/libarchive.o +0 -0
  15. data/ext/libarchive-0.1.1/ext/libarchive_archive.c +7 -7
  16. data/ext/libarchive-0.1.1/ext/libarchive_archive.o +0 -0
  17. data/ext/libarchive-0.1.1/ext/libarchive_entry.c +6 -0
  18. data/ext/libarchive-0.1.1/ext/libarchive_entry.o +0 -0
  19. data/ext/libarchive-0.1.1/ext/libarchive_internal.h +0 -1
  20. data/ext/libarchive-0.1.1/ext/libarchive_reader.c +6 -4
  21. data/ext/libarchive-0.1.1/ext/libarchive_reader.o +0 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_ruby.so +0 -0
  23. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +1 -1
  24. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +2 -2
  25. data/ext/libarchive-0.1.1/ext/libarchive_writer.o +0 -0
  26. data/ext/libarchive-3.6.2/Makefile.in +16892 -0
  27. data/ext/libarchive-3.6.2/build/autoconf/ax_append_compile_flags.m4 +67 -0
  28. data/ext/libarchive-3.6.2/build/autoconf/ax_append_flag.m4 +71 -0
  29. data/ext/libarchive-3.6.2/build/autoconf/ax_check_compile_flag.m4 +74 -0
  30. data/ext/libarchive-3.6.2/build/autoconf/ax_require_defined.m4 +37 -0
  31. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/check_stdcall_func.m4 +0 -0
  32. data/ext/libarchive-3.6.2/build/autoconf/compile +348 -0
  33. data/ext/libarchive-3.6.2/build/autoconf/config.guess +1754 -0
  34. data/ext/libarchive-3.6.2/build/autoconf/config.rpath +696 -0
  35. data/ext/libarchive-3.6.2/build/autoconf/config.sub +1890 -0
  36. data/ext/libarchive-3.6.2/build/autoconf/depcomp +791 -0
  37. data/ext/libarchive-3.6.2/build/autoconf/iconv.m4 +271 -0
  38. data/ext/libarchive-3.6.2/build/autoconf/install-sh +541 -0
  39. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/la_uid_t.m4 +0 -0
  40. data/ext/libarchive-3.6.2/build/autoconf/lib-ld.m4 +109 -0
  41. data/ext/libarchive-3.6.2/build/autoconf/lib-link.m4 +777 -0
  42. data/ext/libarchive-3.6.2/build/autoconf/lib-prefix.m4 +224 -0
  43. data/ext/libarchive-3.6.2/build/autoconf/ltmain.sh +11251 -0
  44. data/ext/libarchive-3.6.2/build/autoconf/m4_ax_compile_check_sizeof.m4 +115 -0
  45. data/ext/libarchive-3.6.2/build/autoconf/missing +215 -0
  46. data/ext/libarchive-3.6.2/build/autoconf/test-driver +153 -0
  47. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/pkgconfig/libarchive.pc.in +4 -1
  48. data/ext/libarchive-3.6.2/config.h.in +1504 -0
  49. data/ext/libarchive-3.6.2/configure +25558 -0
  50. data/ext/libarchive-3.6.2/libarchive/archive.h +1212 -0
  51. data/ext/libarchive-3.6.2/libarchive/archive_acl.c +2097 -0
  52. data/ext/libarchive-3.6.2/libarchive/archive_acl_private.h +83 -0
  53. data/ext/libarchive-3.6.2/libarchive/archive_blake2.h +197 -0
  54. data/ext/libarchive-3.6.2/libarchive/archive_blake2_impl.h +161 -0
  55. data/ext/libarchive-3.6.2/libarchive/archive_blake2s_ref.c +369 -0
  56. data/ext/libarchive-3.6.2/libarchive/archive_blake2sp_ref.c +361 -0
  57. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_check_magic.c +63 -22
  58. data/ext/libarchive-3.6.2/libarchive/archive_cmdline.c +227 -0
  59. data/ext/libarchive-3.6.2/libarchive/archive_cmdline_private.h +47 -0
  60. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_crc32.h +17 -0
  61. data/ext/libarchive-3.6.2/libarchive/archive_cryptor.c +534 -0
  62. data/ext/libarchive-3.6.2/libarchive/archive_cryptor_private.h +188 -0
  63. data/ext/libarchive-3.6.2/libarchive/archive_digest.c +1505 -0
  64. data/ext/libarchive-3.6.2/libarchive/archive_digest_private.h +416 -0
  65. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_darwin.c +559 -0
  66. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_freebsd.c +712 -0
  67. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_linux.c +760 -0
  68. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_sunos.c +824 -0
  69. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_endian.h +48 -15
  70. data/ext/libarchive-3.6.2/libarchive/archive_entry.c +2149 -0
  71. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry.h +305 -106
  72. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_bhfi.c +5 -4
  73. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_stat.c +9 -3
  74. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_link_resolver.c +104 -62
  75. data/ext/libarchive-3.6.2/libarchive/archive_entry_locale.h +92 -0
  76. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_private.h +65 -49
  77. data/ext/libarchive-3.6.2/libarchive/archive_entry_sparse.c +156 -0
  78. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_stat.c +6 -6
  79. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_strmode.c +1 -1
  80. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_xattr.c +4 -6
  81. data/ext/libarchive-3.6.2/libarchive/archive_getdate.c +1165 -0
  82. data/ext/libarchive-3.6.2/libarchive/archive_getdate.h +39 -0
  83. data/ext/libarchive-3.6.2/libarchive/archive_hmac.c +334 -0
  84. data/ext/libarchive-3.6.2/libarchive/archive_hmac_private.h +117 -0
  85. data/ext/libarchive-3.6.2/libarchive/archive_match.c +1875 -0
  86. data/ext/libarchive-3.6.2/libarchive/archive_openssl_evp_private.h +53 -0
  87. data/ext/libarchive-3.6.2/libarchive/archive_openssl_hmac_private.h +54 -0
  88. data/ext/libarchive-3.6.2/libarchive/archive_options.c +218 -0
  89. data/ext/libarchive-3.6.2/libarchive/archive_options_private.h +51 -0
  90. data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.c +337 -0
  91. data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.h +49 -0
  92. data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.c +463 -0
  93. data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.h +52 -0
  94. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_platform.h +77 -9
  95. data/ext/libarchive-3.6.2/libarchive/archive_platform_acl.h +55 -0
  96. data/ext/libarchive-3.6.2/libarchive/archive_platform_xattr.h +47 -0
  97. data/ext/libarchive-3.6.2/libarchive/archive_ppmd7.c +1168 -0
  98. data/ext/libarchive-3.6.2/libarchive/archive_ppmd7_private.h +119 -0
  99. data/ext/libarchive-3.6.2/libarchive/archive_ppmd8.c +1287 -0
  100. data/ext/libarchive-3.6.2/libarchive/archive_ppmd8_private.h +148 -0
  101. data/ext/libarchive-3.6.2/libarchive/archive_ppmd_private.h +151 -0
  102. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_private.h +74 -18
  103. data/ext/libarchive-3.6.2/libarchive/archive_random.c +272 -0
  104. data/ext/libarchive-3.6.2/libarchive/archive_random_private.h +36 -0
  105. data/ext/libarchive-3.6.2/libarchive/archive_rb.c +709 -0
  106. data/ext/libarchive-3.6.2/libarchive/archive_rb.h +113 -0
  107. data/ext/libarchive-3.6.2/libarchive/archive_read.c +1756 -0
  108. data/ext/libarchive-3.6.2/libarchive/archive_read_add_passphrase.c +190 -0
  109. data/ext/libarchive-3.6.2/libarchive/archive_read_append_filter.c +204 -0
  110. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_data_into_fd.c +64 -18
  111. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_entry_from_file.c +1086 -0
  112. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_posix.c +2732 -0
  113. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_private.h +40 -4
  114. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_set_standard_lookup.c +21 -11
  115. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_windows.c +2479 -0
  116. data/ext/libarchive-3.6.2/libarchive/archive_read_extract.c +60 -0
  117. data/ext/{libarchive-2.8.4/libarchive/archive_read_extract.c → libarchive-3.6.2/libarchive/archive_read_extract2.c} +34 -61
  118. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_fd.c +70 -49
  119. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_file.c +38 -23
  120. data/ext/libarchive-3.6.2/libarchive/archive_read_open_filename.c +586 -0
  121. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_memory.c +58 -28
  122. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_private.h +127 -59
  123. data/ext/libarchive-3.6.2/libarchive/archive_read_set_format.c +117 -0
  124. data/ext/libarchive-3.6.2/libarchive/archive_read_set_options.c +133 -0
  125. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_all.c → libarchive-3.6.2/libarchive/archive_read_support_filter_all.c} +35 -10
  126. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_by_code.c +83 -0
  127. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c → libarchive-3.6.2/libarchive/archive_read_support_filter_bzip2.c} +38 -26
  128. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c → libarchive-3.6.2/libarchive/archive_read_support_filter_compress.c} +52 -44
  129. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_grzip.c +112 -0
  130. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c → libarchive-3.6.2/libarchive/archive_read_support_filter_gzip.c} +108 -37
  131. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lrzip.c +122 -0
  132. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lz4.c +742 -0
  133. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lzop.c +499 -0
  134. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_none.c → libarchive-3.6.2/libarchive/archive_read_support_filter_none.c} +15 -3
  135. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_program.c → libarchive-3.6.2/libarchive/archive_read_support_filter_program.c} +114 -77
  136. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c → libarchive-3.6.2/libarchive/archive_read_support_filter_rpm.c} +31 -31
  137. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c → libarchive-3.6.2/libarchive/archive_read_support_filter_uu.c} +141 -85
  138. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c → libarchive-3.6.2/libarchive/archive_read_support_filter_xz.c} +369 -284
  139. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_zstd.c +297 -0
  140. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_7zip.c +3900 -0
  141. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_all.c +89 -0
  142. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_ar.c +126 -72
  143. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_by_code.c +92 -0
  144. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cab.c +3228 -0
  145. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cpio.c +1104 -0
  146. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_empty.c +14 -11
  147. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_iso9660.c +990 -541
  148. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_lha.c +2916 -0
  149. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_mtree.c +2150 -0
  150. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar.c +3797 -0
  151. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar5.c +4251 -0
  152. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_raw.c +38 -31
  153. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_tar.c +1157 -629
  154. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_warc.c +848 -0
  155. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_xar.c +439 -258
  156. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_zip.c +4270 -0
  157. data/ext/libarchive-3.6.2/libarchive/archive_string.c +4240 -0
  158. data/ext/libarchive-3.6.2/libarchive/archive_string.h +243 -0
  159. data/ext/libarchive-3.6.2/libarchive/archive_string_composition.h +2292 -0
  160. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_string_sprintf.c +44 -16
  161. data/ext/libarchive-3.6.2/libarchive/archive_util.c +655 -0
  162. data/ext/libarchive-3.6.2/libarchive/archive_version_details.c +151 -0
  163. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_virtual.c +85 -16
  164. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.c +214 -541
  165. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.h +74 -106
  166. data/ext/libarchive-3.6.2/libarchive/archive_write.c +828 -0
  167. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter.c +72 -0
  168. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_b64encode.c +304 -0
  169. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_by_name.c +77 -0
  170. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_bzip2.c +401 -0
  171. data/ext/{libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c → libarchive-3.6.2/libarchive/archive_write_add_filter_compress.c} +86 -131
  172. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_grzip.c +135 -0
  173. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_gzip.c +442 -0
  174. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lrzip.c +197 -0
  175. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lz4.c +700 -0
  176. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lzop.c +478 -0
  177. data/ext/{libarchive-2.8.4/libarchive/archive_read_support_format_all.c → libarchive-3.6.2/libarchive/archive_write_add_filter_none.c} +11 -11
  178. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_program.c +391 -0
  179. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_uuencode.c +295 -0
  180. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_xz.c +545 -0
  181. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_zstd.c +418 -0
  182. data/ext/libarchive-3.6.2/libarchive/archive_write_disk_posix.c +4711 -0
  183. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_private.h +9 -2
  184. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_set_standard_lookup.c +30 -29
  185. data/ext/libarchive-3.6.2/libarchive/archive_write_disk_windows.c +2842 -0
  186. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_fd.c +15 -10
  187. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_file.c +15 -9
  188. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_filename.c +128 -20
  189. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_memory.c +7 -18
  190. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_private.h +72 -29
  191. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format.c +56 -3
  192. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_7zip.c +2322 -0
  193. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ar.c +54 -34
  194. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_by_name.c +20 -2
  195. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio.c +11 -0
  196. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_binary.c +610 -0
  197. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_newc.c +457 -0
  198. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_odc.c +500 -0
  199. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_filter_by_ext.c +142 -0
  200. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_gnutar.c +755 -0
  201. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_iso9660.c +8165 -0
  202. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_mtree.c +2217 -0
  203. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_pax.c +1049 -387
  204. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_private.h +42 -0
  205. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_raw.c +125 -0
  206. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_shar.c +62 -47
  207. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ustar.c +279 -108
  208. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_v7tar.c +638 -0
  209. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_warc.c +453 -0
  210. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_xar.c +3259 -0
  211. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_zip.c +1704 -0
  212. data/ext/libarchive-3.6.2/libarchive/archive_write_set_options.c +130 -0
  213. data/ext/libarchive-3.6.2/libarchive/archive_write_set_passphrase.c +95 -0
  214. data/ext/libarchive-3.6.2/libarchive/archive_xxhash.h +48 -0
  215. data/ext/libarchive-3.6.2/libarchive/config_freebsd.h +271 -0
  216. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/filter_fork.h +10 -5
  217. data/ext/{libarchive-2.8.4/libarchive/filter_fork.c → libarchive-3.6.2/libarchive/filter_fork_posix.c} +98 -19
  218. data/ext/libarchive-3.6.2/libarchive/filter_fork_windows.c +236 -0
  219. data/ext/libarchive-3.6.2/libarchive/xxhash.c +525 -0
  220. data/ext/libarchive-static-makefile +144 -80
  221. data/ext/libarchive-static-wrapper-makefile +1 -1
  222. data/ext/zlib-1.2.13/Makefile.in +404 -0
  223. data/ext/{zlib-1.2.5 → zlib-1.2.13}/adler32.c +51 -34
  224. data/ext/{zlib-1.2.5 → zlib-1.2.13}/compress.c +27 -21
  225. data/ext/zlib-1.2.13/configure +922 -0
  226. data/ext/zlib-1.2.13/crc32.c +1125 -0
  227. data/ext/zlib-1.2.13/crc32.h +9446 -0
  228. data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.c +842 -459
  229. data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.h +37 -33
  230. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzclose.c +0 -0
  231. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzguts.h +103 -16
  232. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzlib.c +155 -53
  233. data/ext/zlib-1.2.13/gzread.c +650 -0
  234. data/ext/zlib-1.2.13/gzwrite.c +677 -0
  235. data/ext/{zlib-1.2.5 → zlib-1.2.13}/infback.c +24 -12
  236. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.c +49 -66
  237. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.h +0 -0
  238. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffixed.h +3 -3
  239. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.c +209 -94
  240. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.h +9 -5
  241. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.c +24 -50
  242. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.h +1 -1
  243. data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.c +135 -198
  244. data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.h +0 -0
  245. data/ext/zlib-1.2.13/uncompr.c +93 -0
  246. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zconf.h +182 -63
  247. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zlib.h +617 -295
  248. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.c +50 -41
  249. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.h +83 -82
  250. metadata +244 -137
  251. data/ext/libarchive-0.1.1/libarchive.c +0 -1762
  252. data/ext/libarchive-2.8.4/Makefile.in +0 -7076
  253. data/ext/libarchive-2.8.4/build/autoconf/compile +0 -143
  254. data/ext/libarchive-2.8.4/build/autoconf/config.guess +0 -1502
  255. data/ext/libarchive-2.8.4/build/autoconf/config.sub +0 -1708
  256. data/ext/libarchive-2.8.4/build/autoconf/depcomp +0 -630
  257. data/ext/libarchive-2.8.4/build/autoconf/install-sh +0 -291
  258. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +0 -8406
  259. data/ext/libarchive-2.8.4/build/autoconf/missing +0 -376
  260. data/ext/libarchive-2.8.4/config.h.in +0 -772
  261. data/ext/libarchive-2.8.4/configure +0 -17916
  262. data/ext/libarchive-2.8.4/libarchive/archive.h +0 -741
  263. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +0 -2202
  264. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +0 -281
  265. data/ext/libarchive-2.8.4/libarchive/archive_read.c +0 -1249
  266. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +0 -198
  267. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +0 -570
  268. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +0 -272
  269. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +0 -777
  270. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +0 -1304
  271. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +0 -903
  272. data/ext/libarchive-2.8.4/libarchive/archive_string.c +0 -453
  273. data/ext/libarchive-2.8.4/libarchive/archive_string.h +0 -148
  274. data/ext/libarchive-2.8.4/libarchive/archive_util.c +0 -391
  275. data/ext/libarchive-2.8.4/libarchive/archive_write.c +0 -466
  276. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +0 -2628
  277. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +0 -408
  278. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +0 -477
  279. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +0 -257
  280. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +0 -347
  281. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +0 -438
  282. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +0 -344
  283. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +0 -295
  284. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +0 -1050
  285. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +0 -667
  286. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +0 -154
  287. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +0 -113
  288. data/ext/zlib-1.2.5/Makefile.in +0 -257
  289. data/ext/zlib-1.2.5/configure +0 -596
  290. data/ext/zlib-1.2.5/crc32.c +0 -442
  291. data/ext/zlib-1.2.5/crc32.h +0 -441
  292. data/ext/zlib-1.2.5/example.c +0 -565
  293. data/ext/zlib-1.2.5/gzread.c +0 -653
  294. data/ext/zlib-1.2.5/gzwrite.c +0 -531
  295. data/ext/zlib-1.2.5/minigzip.c +0 -440
  296. data/ext/zlib-1.2.5/uncompr.c +0 -59
@@ -0,0 +1,2150 @@
1
+ /*-
2
+ * Copyright (c) 2003-2007 Tim Kientzle
3
+ * Copyright (c) 2008 Joerg Sonnenberger
4
+ * Copyright (c) 2011-2012 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_mtree.c 201165 2009-12-29 05:52:13Z kientzle $");
30
+
31
+ #ifdef HAVE_SYS_STAT_H
32
+ #include <sys/stat.h>
33
+ #endif
34
+ #ifdef HAVE_ERRNO_H
35
+ #include <errno.h>
36
+ #endif
37
+ #ifdef HAVE_FCNTL_H
38
+ #include <fcntl.h>
39
+ #endif
40
+ #include <stddef.h>
41
+ /* #include <stdint.h> */ /* See archive_platform.h */
42
+ #ifdef HAVE_STDLIB_H
43
+ #include <stdlib.h>
44
+ #endif
45
+ #ifdef HAVE_STRING_H
46
+ #include <string.h>
47
+ #endif
48
+ #ifdef HAVE_CTYPE_H
49
+ #include <ctype.h>
50
+ #endif
51
+
52
+ #include "archive.h"
53
+ #include "archive_entry.h"
54
+ #include "archive_entry_private.h"
55
+ #include "archive_private.h"
56
+ #include "archive_rb.h"
57
+ #include "archive_read_private.h"
58
+ #include "archive_string.h"
59
+ #include "archive_pack_dev.h"
60
+
61
+ #ifndef O_BINARY
62
+ #define O_BINARY 0
63
+ #endif
64
+ #ifndef O_CLOEXEC
65
+ #define O_CLOEXEC 0
66
+ #endif
67
+
68
+ #define MTREE_HAS_DEVICE 0x0001
69
+ #define MTREE_HAS_FFLAGS 0x0002
70
+ #define MTREE_HAS_GID 0x0004
71
+ #define MTREE_HAS_GNAME 0x0008
72
+ #define MTREE_HAS_MTIME 0x0010
73
+ #define MTREE_HAS_NLINK 0x0020
74
+ #define MTREE_HAS_PERM 0x0040
75
+ #define MTREE_HAS_SIZE 0x0080
76
+ #define MTREE_HAS_TYPE 0x0100
77
+ #define MTREE_HAS_UID 0x0200
78
+ #define MTREE_HAS_UNAME 0x0400
79
+
80
+ #define MTREE_HAS_OPTIONAL 0x0800
81
+ #define MTREE_HAS_NOCHANGE 0x1000 /* FreeBSD specific */
82
+
83
+ #define MAX_LINE_LEN (1024 * 1024)
84
+
85
+ struct mtree_option {
86
+ struct mtree_option *next;
87
+ char *value;
88
+ };
89
+
90
+ struct mtree_entry {
91
+ struct archive_rb_node rbnode;
92
+ struct mtree_entry *next_dup;
93
+ struct mtree_entry *next;
94
+ struct mtree_option *options;
95
+ char *name;
96
+ char full;
97
+ char used;
98
+ };
99
+
100
+ struct mtree {
101
+ struct archive_string line;
102
+ size_t buffsize;
103
+ char *buff;
104
+ int64_t offset;
105
+ int fd;
106
+ int archive_format;
107
+ const char *archive_format_name;
108
+ struct mtree_entry *entries;
109
+ struct mtree_entry *this_entry;
110
+ struct archive_rb_tree entry_rbtree;
111
+ struct archive_string current_dir;
112
+ struct archive_string contents_name;
113
+
114
+ struct archive_entry_linkresolver *resolver;
115
+ struct archive_rb_tree rbtree;
116
+
117
+ int64_t cur_size;
118
+ char checkfs;
119
+ };
120
+
121
+ static int bid_keycmp(const char *, const char *, ssize_t);
122
+ static int cleanup(struct archive_read *);
123
+ static int detect_form(struct archive_read *, int *);
124
+ static int mtree_bid(struct archive_read *, int);
125
+ static int parse_file(struct archive_read *, struct archive_entry *,
126
+ struct mtree *, struct mtree_entry *, int *);
127
+ static void parse_escapes(char *, struct mtree_entry *);
128
+ static int parse_line(struct archive_read *, struct archive_entry *,
129
+ struct mtree *, struct mtree_entry *, int *);
130
+ static int parse_keyword(struct archive_read *, struct mtree *,
131
+ struct archive_entry *, struct mtree_option *, int *);
132
+ static int read_data(struct archive_read *a,
133
+ const void **buff, size_t *size, int64_t *offset);
134
+ static ssize_t readline(struct archive_read *, struct mtree *, char **, ssize_t);
135
+ static int skip(struct archive_read *a);
136
+ static int read_header(struct archive_read *,
137
+ struct archive_entry *);
138
+ static int64_t mtree_atol(char **, int base);
139
+ #ifndef HAVE_STRNLEN
140
+ static size_t mtree_strnlen(const char *, size_t);
141
+ #endif
142
+
143
+ /*
144
+ * There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
145
+ * here. TODO: Move this to configure time, but be careful
146
+ * about cross-compile environments.
147
+ */
148
+ static int64_t
149
+ get_time_t_max(void)
150
+ {
151
+ #if defined(TIME_T_MAX)
152
+ return TIME_T_MAX;
153
+ #else
154
+ /* ISO C allows time_t to be a floating-point type,
155
+ but POSIX requires an integer type. The following
156
+ should work on any system that follows the POSIX
157
+ conventions. */
158
+ if (((time_t)0) < ((time_t)-1)) {
159
+ /* Time_t is unsigned */
160
+ return (~(time_t)0);
161
+ } else {
162
+ /* Time_t is signed. */
163
+ /* Assume it's the same as int64_t or int32_t */
164
+ if (sizeof(time_t) == sizeof(int64_t)) {
165
+ return (time_t)INT64_MAX;
166
+ } else {
167
+ return (time_t)INT32_MAX;
168
+ }
169
+ }
170
+ #endif
171
+ }
172
+
173
+ static int64_t
174
+ get_time_t_min(void)
175
+ {
176
+ #if defined(TIME_T_MIN)
177
+ return TIME_T_MIN;
178
+ #else
179
+ if (((time_t)0) < ((time_t)-1)) {
180
+ /* Time_t is unsigned */
181
+ return (time_t)0;
182
+ } else {
183
+ /* Time_t is signed. */
184
+ if (sizeof(time_t) == sizeof(int64_t)) {
185
+ return (time_t)INT64_MIN;
186
+ } else {
187
+ return (time_t)INT32_MIN;
188
+ }
189
+ }
190
+ #endif
191
+ }
192
+
193
+ #ifdef HAVE_STRNLEN
194
+ #define mtree_strnlen(a,b) strnlen(a,b)
195
+ #else
196
+ static size_t
197
+ mtree_strnlen(const char *p, size_t maxlen)
198
+ {
199
+ size_t i;
200
+
201
+ for (i = 0; i <= maxlen; i++) {
202
+ if (p[i] == 0)
203
+ break;
204
+ }
205
+ if (i > maxlen)
206
+ return (-1);/* invalid */
207
+ return (i);
208
+ }
209
+ #endif
210
+
211
+ static int
212
+ archive_read_format_mtree_options(struct archive_read *a,
213
+ const char *key, const char *val)
214
+ {
215
+ struct mtree *mtree;
216
+
217
+ mtree = (struct mtree *)(a->format->data);
218
+ if (strcmp(key, "checkfs") == 0) {
219
+ /* Allows to read information missing from the mtree from the file system */
220
+ if (val == NULL || val[0] == 0) {
221
+ mtree->checkfs = 0;
222
+ } else {
223
+ mtree->checkfs = 1;
224
+ }
225
+ return (ARCHIVE_OK);
226
+ }
227
+
228
+ /* Note: The "warn" return is just to inform the options
229
+ * supervisor that we didn't handle it. It will generate
230
+ * a suitable error if no one used this option. */
231
+ return (ARCHIVE_WARN);
232
+ }
233
+
234
+ static void
235
+ free_options(struct mtree_option *head)
236
+ {
237
+ struct mtree_option *next;
238
+
239
+ for (; head != NULL; head = next) {
240
+ next = head->next;
241
+ free(head->value);
242
+ free(head);
243
+ }
244
+ }
245
+
246
+ static int
247
+ mtree_cmp_node(const struct archive_rb_node *n1,
248
+ const struct archive_rb_node *n2)
249
+ {
250
+ const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
251
+ const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
252
+
253
+ return (strcmp(e1->name, e2->name));
254
+ }
255
+
256
+ static int
257
+ mtree_cmp_key(const struct archive_rb_node *n, const void *key)
258
+ {
259
+ const struct mtree_entry *e = (const struct mtree_entry *)n;
260
+
261
+ return (strcmp(e->name, key));
262
+ }
263
+
264
+ int
265
+ archive_read_support_format_mtree(struct archive *_a)
266
+ {
267
+ static const struct archive_rb_tree_ops rb_ops = {
268
+ mtree_cmp_node, mtree_cmp_key,
269
+ };
270
+ struct archive_read *a = (struct archive_read *)_a;
271
+ struct mtree *mtree;
272
+ int r;
273
+
274
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
275
+ ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
276
+
277
+ mtree = (struct mtree *)calloc(1, sizeof(*mtree));
278
+ if (mtree == NULL) {
279
+ archive_set_error(&a->archive, ENOMEM,
280
+ "Can't allocate mtree data");
281
+ return (ARCHIVE_FATAL);
282
+ }
283
+ mtree->checkfs = 0;
284
+ mtree->fd = -1;
285
+
286
+ __archive_rb_tree_init(&mtree->rbtree, &rb_ops);
287
+
288
+ r = __archive_read_register_format(a, mtree, "mtree",
289
+ mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup, NULL, NULL);
290
+
291
+ if (r != ARCHIVE_OK)
292
+ free(mtree);
293
+ return (ARCHIVE_OK);
294
+ }
295
+
296
+ static int
297
+ cleanup(struct archive_read *a)
298
+ {
299
+ struct mtree *mtree;
300
+ struct mtree_entry *p, *q;
301
+
302
+ mtree = (struct mtree *)(a->format->data);
303
+
304
+ p = mtree->entries;
305
+ while (p != NULL) {
306
+ q = p->next;
307
+ free(p->name);
308
+ free_options(p->options);
309
+ free(p);
310
+ p = q;
311
+ }
312
+ archive_string_free(&mtree->line);
313
+ archive_string_free(&mtree->current_dir);
314
+ archive_string_free(&mtree->contents_name);
315
+ archive_entry_linkresolver_free(mtree->resolver);
316
+
317
+ free(mtree->buff);
318
+ free(mtree);
319
+ (a->format->data) = NULL;
320
+ return (ARCHIVE_OK);
321
+ }
322
+
323
+ static ssize_t
324
+ get_line_size(const char *b, ssize_t avail, ssize_t *nlsize)
325
+ {
326
+ ssize_t len;
327
+
328
+ len = 0;
329
+ while (len < avail) {
330
+ switch (*b) {
331
+ case '\0':/* Non-ascii character or control character. */
332
+ if (nlsize != NULL)
333
+ *nlsize = 0;
334
+ return (-1);
335
+ case '\r':
336
+ if (avail-len > 1 && b[1] == '\n') {
337
+ if (nlsize != NULL)
338
+ *nlsize = 2;
339
+ return (len+2);
340
+ }
341
+ /* FALL THROUGH */
342
+ case '\n':
343
+ if (nlsize != NULL)
344
+ *nlsize = 1;
345
+ return (len+1);
346
+ default:
347
+ b++;
348
+ len++;
349
+ break;
350
+ }
351
+ }
352
+ if (nlsize != NULL)
353
+ *nlsize = 0;
354
+ return (avail);
355
+ }
356
+
357
+ /*
358
+ * <---------------- ravail --------------------->
359
+ * <-- diff ------> <--- avail ----------------->
360
+ * <---- len ----------->
361
+ * | Previous lines | line being parsed nl extra |
362
+ * ^
363
+ * b
364
+ *
365
+ */
366
+ static ssize_t
367
+ next_line(struct archive_read *a,
368
+ const char **b, ssize_t *avail, ssize_t *ravail, ssize_t *nl)
369
+ {
370
+ ssize_t len;
371
+ int quit;
372
+
373
+ quit = 0;
374
+ if (*avail == 0) {
375
+ *nl = 0;
376
+ len = 0;
377
+ } else
378
+ len = get_line_size(*b, *avail, nl);
379
+ /*
380
+ * Read bytes more while it does not reach the end of line.
381
+ */
382
+ while (*nl == 0 && len == *avail && !quit) {
383
+ ssize_t diff = *ravail - *avail;
384
+ size_t nbytes_req = (*ravail+1023) & ~1023U;
385
+ ssize_t tested;
386
+
387
+ /*
388
+ * Place an arbitrary limit on the line length.
389
+ * mtree is almost free-form input and without line length limits,
390
+ * it can consume a lot of memory.
391
+ */
392
+ if (len >= MAX_LINE_LEN)
393
+ return (-1);
394
+
395
+ /* Increase reading bytes if it is not enough to at least
396
+ * new two lines. */
397
+ if (nbytes_req < (size_t)*ravail + 160)
398
+ nbytes_req <<= 1;
399
+
400
+ *b = __archive_read_ahead(a, nbytes_req, avail);
401
+ if (*b == NULL) {
402
+ if (*ravail >= *avail)
403
+ return (0);
404
+ /* Reading bytes reaches the end of file. */
405
+ *b = __archive_read_ahead(a, *avail, avail);
406
+ quit = 1;
407
+ }
408
+ *ravail = *avail;
409
+ *b += diff;
410
+ *avail -= diff;
411
+ tested = len;/* Skip some bytes we already determined. */
412
+ len = get_line_size(*b + len, *avail - len, nl);
413
+ if (len >= 0)
414
+ len += tested;
415
+ }
416
+ return (len);
417
+ }
418
+
419
+ /*
420
+ * Compare characters with a mtree keyword.
421
+ * Returns the length of a mtree keyword if matched.
422
+ * Returns 0 if not matched.
423
+ */
424
+ static int
425
+ bid_keycmp(const char *p, const char *key, ssize_t len)
426
+ {
427
+ int match_len = 0;
428
+
429
+ while (len > 0 && *p && *key) {
430
+ if (*p == *key) {
431
+ --len;
432
+ ++p;
433
+ ++key;
434
+ ++match_len;
435
+ continue;
436
+ }
437
+ return (0);/* Not match */
438
+ }
439
+ if (*key != '\0')
440
+ return (0);/* Not match */
441
+
442
+ /* A following character should be specified characters */
443
+ if (p[0] == '=' || p[0] == ' ' || p[0] == '\t' ||
444
+ p[0] == '\n' || p[0] == '\r' ||
445
+ (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r')))
446
+ return (match_len);
447
+ return (0);/* Not match */
448
+ }
449
+
450
+ /*
451
+ * Test whether the characters 'p' has is mtree keyword.
452
+ * Returns the length of a detected keyword.
453
+ * Returns 0 if any keywords were not found.
454
+ */
455
+ static int
456
+ bid_keyword(const char *p, ssize_t len)
457
+ {
458
+ static const char * const keys_c[] = {
459
+ "content", "contents", "cksum", NULL
460
+ };
461
+ static const char * const keys_df[] = {
462
+ "device", "flags", NULL
463
+ };
464
+ static const char * const keys_g[] = {
465
+ "gid", "gname", NULL
466
+ };
467
+ static const char * const keys_il[] = {
468
+ "ignore", "inode", "link", NULL
469
+ };
470
+ static const char * const keys_m[] = {
471
+ "md5", "md5digest", "mode", NULL
472
+ };
473
+ static const char * const keys_no[] = {
474
+ "nlink", "nochange", "optional", NULL
475
+ };
476
+ static const char * const keys_r[] = {
477
+ "resdevice", "rmd160", "rmd160digest", NULL
478
+ };
479
+ static const char * const keys_s[] = {
480
+ "sha1", "sha1digest",
481
+ "sha256", "sha256digest",
482
+ "sha384", "sha384digest",
483
+ "sha512", "sha512digest",
484
+ "size", NULL
485
+ };
486
+ static const char * const keys_t[] = {
487
+ "tags", "time", "type", NULL
488
+ };
489
+ static const char * const keys_u[] = {
490
+ "uid", "uname", NULL
491
+ };
492
+ const char * const *keys;
493
+ int i;
494
+
495
+ switch (*p) {
496
+ case 'c': keys = keys_c; break;
497
+ case 'd': case 'f': keys = keys_df; break;
498
+ case 'g': keys = keys_g; break;
499
+ case 'i': case 'l': keys = keys_il; break;
500
+ case 'm': keys = keys_m; break;
501
+ case 'n': case 'o': keys = keys_no; break;
502
+ case 'r': keys = keys_r; break;
503
+ case 's': keys = keys_s; break;
504
+ case 't': keys = keys_t; break;
505
+ case 'u': keys = keys_u; break;
506
+ default: return (0);/* Unknown key */
507
+ }
508
+
509
+ for (i = 0; keys[i] != NULL; i++) {
510
+ int l = bid_keycmp(p, keys[i], len);
511
+ if (l > 0)
512
+ return (l);
513
+ }
514
+ return (0);/* Unknown key */
515
+ }
516
+
517
+ /*
518
+ * Test whether there is a set of mtree keywords.
519
+ * Returns the number of keyword.
520
+ * Returns -1 if we got incorrect sequence.
521
+ * This function expects a set of "<space characters>keyword=value".
522
+ * When "unset" is specified, expects a set of "<space characters>keyword".
523
+ */
524
+ static int
525
+ bid_keyword_list(const char *p, ssize_t len, int unset, int last_is_path)
526
+ {
527
+ int l;
528
+ int keycnt = 0;
529
+
530
+ while (len > 0 && *p) {
531
+ int blank = 0;
532
+
533
+ /* Test whether there are blank characters in the line. */
534
+ while (len >0 && (*p == ' ' || *p == '\t')) {
535
+ ++p;
536
+ --len;
537
+ blank = 1;
538
+ }
539
+ if (*p == '\n' || *p == '\r')
540
+ break;
541
+ if (p[0] == '\\' && (p[1] == '\n' || p[1] == '\r'))
542
+ break;
543
+ if (!blank && !last_is_path) /* No blank character. */
544
+ return (-1);
545
+ if (last_is_path && len == 0)
546
+ return (keycnt);
547
+
548
+ if (unset) {
549
+ l = bid_keycmp(p, "all", len);
550
+ if (l > 0)
551
+ return (1);
552
+ }
553
+ /* Test whether there is a correct key in the line. */
554
+ l = bid_keyword(p, len);
555
+ if (l == 0)
556
+ return (-1);/* Unknown keyword was found. */
557
+ p += l;
558
+ len -= l;
559
+ keycnt++;
560
+
561
+ /* Skip value */
562
+ if (*p == '=') {
563
+ int value = 0;
564
+ ++p;
565
+ --len;
566
+ while (len > 0 && *p != ' ' && *p != '\t') {
567
+ ++p;
568
+ --len;
569
+ value = 1;
570
+ }
571
+ /* A keyword should have a its value unless
572
+ * "/unset" operation. */
573
+ if (!unset && value == 0)
574
+ return (-1);
575
+ }
576
+ }
577
+ return (keycnt);
578
+ }
579
+
580
+ static int
581
+ bid_entry(const char *p, ssize_t len, ssize_t nl, int *last_is_path)
582
+ {
583
+ int f = 0;
584
+ static const unsigned char safe_char[256] = {
585
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
586
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
587
+ /* !"$%&'()*+,-./ EXCLUSION:( )(#) */
588
+ 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
589
+ /* 0123456789:;<>? EXCLUSION:(=) */
590
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
591
+ /* @ABCDEFGHIJKLMNO */
592
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
593
+ /* PQRSTUVWXYZ[\]^_ */
594
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 - 5F */
595
+ /* `abcdefghijklmno */
596
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
597
+ /* pqrstuvwxyz{|}~ */
598
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
599
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
600
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
601
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
602
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
603
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
604
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
605
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
606
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
607
+ };
608
+ ssize_t ll;
609
+ const char *pp = p;
610
+ const char * const pp_end = pp + len;
611
+
612
+ *last_is_path = 0;
613
+ /*
614
+ * Skip the path-name which is quoted.
615
+ */
616
+ for (;pp < pp_end; ++pp) {
617
+ if (!safe_char[*(const unsigned char *)pp]) {
618
+ if (*pp != ' ' && *pp != '\t' && *pp != '\r'
619
+ && *pp != '\n')
620
+ f = 0;
621
+ break;
622
+ }
623
+ f = 1;
624
+ }
625
+ ll = pp_end - pp;
626
+
627
+ /* If a path-name was not found at the first, try to check
628
+ * a mtree format(a.k.a form D) ``NetBSD's mtree -D'' creates,
629
+ * which places the path-name at the last. */
630
+ if (f == 0) {
631
+ const char *pb = p + len - nl;
632
+ int name_len = 0;
633
+ int slash;
634
+
635
+ /* The form D accepts only a single line for an entry. */
636
+ if (pb-2 >= p &&
637
+ pb[-1] == '\\' && (pb[-2] == ' ' || pb[-2] == '\t'))
638
+ return (-1);
639
+ if (pb-1 >= p && pb[-1] == '\\')
640
+ return (-1);
641
+
642
+ slash = 0;
643
+ while (p <= --pb && *pb != ' ' && *pb != '\t') {
644
+ if (!safe_char[*(const unsigned char *)pb])
645
+ return (-1);
646
+ name_len++;
647
+ /* The pathname should have a slash in this
648
+ * format. */
649
+ if (*pb == '/')
650
+ slash = 1;
651
+ }
652
+ if (name_len == 0 || slash == 0)
653
+ return (-1);
654
+ /* If '/' is placed at the first in this field, this is not
655
+ * a valid filename. */
656
+ if (pb[1] == '/')
657
+ return (-1);
658
+ ll = len - nl - name_len;
659
+ pp = p;
660
+ *last_is_path = 1;
661
+ }
662
+
663
+ return (bid_keyword_list(pp, ll, 0, *last_is_path));
664
+ }
665
+
666
+ #define MAX_BID_ENTRY 3
667
+
668
+ static int
669
+ mtree_bid(struct archive_read *a, int best_bid)
670
+ {
671
+ const char *signature = "#mtree";
672
+ const char *p;
673
+
674
+ (void)best_bid; /* UNUSED */
675
+
676
+ /* Now let's look at the actual header and see if it matches. */
677
+ p = __archive_read_ahead(a, strlen(signature), NULL);
678
+ if (p == NULL)
679
+ return (-1);
680
+
681
+ if (memcmp(p, signature, strlen(signature)) == 0)
682
+ return (8 * (int)strlen(signature));
683
+
684
+ /*
685
+ * There is not a mtree signature. Let's try to detect mtree format.
686
+ */
687
+ return (detect_form(a, NULL));
688
+ }
689
+
690
+ static int
691
+ detect_form(struct archive_read *a, int *is_form_d)
692
+ {
693
+ const char *p;
694
+ ssize_t avail, ravail;
695
+ ssize_t len, nl;
696
+ int entry_cnt = 0, multiline = 0;
697
+ int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
698
+ * (In this source we call it `form D') . */
699
+
700
+ if (is_form_d != NULL)
701
+ *is_form_d = 0;
702
+ p = __archive_read_ahead(a, 1, &avail);
703
+ if (p == NULL)
704
+ return (-1);
705
+ ravail = avail;
706
+ for (;;) {
707
+ len = next_line(a, &p, &avail, &ravail, &nl);
708
+ /* The terminal character of the line should be
709
+ * a new line character, '\r\n' or '\n'. */
710
+ if (len <= 0 || nl == 0)
711
+ break;
712
+ if (!multiline) {
713
+ /* Leading whitespace is never significant,
714
+ * ignore it. */
715
+ while (len > 0 && (*p == ' ' || *p == '\t')) {
716
+ ++p;
717
+ --avail;
718
+ --len;
719
+ }
720
+ /* Skip comment or empty line. */
721
+ if (p[0] == '#' || p[0] == '\n' || p[0] == '\r') {
722
+ p += len;
723
+ avail -= len;
724
+ continue;
725
+ }
726
+ } else {
727
+ /* A continuance line; the terminal
728
+ * character of previous line was '\' character. */
729
+ if (bid_keyword_list(p, len, 0, 0) <= 0)
730
+ break;
731
+ if (p[len-nl-1] != '\\') {
732
+ if (multiline == 1 &&
733
+ ++entry_cnt >= MAX_BID_ENTRY)
734
+ break;
735
+ multiline = 0;
736
+ }
737
+ p += len;
738
+ avail -= len;
739
+ continue;
740
+ }
741
+ if (p[0] != '/') {
742
+ int last_is_path, keywords;
743
+
744
+ keywords = bid_entry(p, len, nl, &last_is_path);
745
+ if (keywords >= 0) {
746
+ if (form_D == 0) {
747
+ if (last_is_path)
748
+ form_D = 1;
749
+ else if (keywords > 0)
750
+ /* This line is not `form D'. */
751
+ form_D = -1;
752
+ } else if (form_D == 1) {
753
+ if (!last_is_path && keywords > 0)
754
+ /* This this is not `form D'
755
+ * and We cannot accept mixed
756
+ * format. */
757
+ break;
758
+ }
759
+ if (!last_is_path && p[len-nl-1] == '\\')
760
+ /* This line continues. */
761
+ multiline = 1;
762
+ else {
763
+ /* We've got plenty of correct lines
764
+ * to assume that this file is a mtree
765
+ * format. */
766
+ if (++entry_cnt >= MAX_BID_ENTRY)
767
+ break;
768
+ }
769
+ } else
770
+ break;
771
+ } else if (len > 4 && strncmp(p, "/set", 4) == 0) {
772
+ if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
773
+ break;
774
+ /* This line continues. */
775
+ if (p[len-nl-1] == '\\')
776
+ multiline = 2;
777
+ } else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
778
+ if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
779
+ break;
780
+ /* This line continues. */
781
+ if (p[len-nl-1] == '\\')
782
+ multiline = 2;
783
+ } else
784
+ break;
785
+
786
+ /* Test next line. */
787
+ p += len;
788
+ avail -= len;
789
+ }
790
+ if (entry_cnt >= MAX_BID_ENTRY || (entry_cnt > 0 && len == 0)) {
791
+ if (is_form_d != NULL) {
792
+ if (form_D == 1)
793
+ *is_form_d = 1;
794
+ }
795
+ return (32);
796
+ }
797
+
798
+ return (0);
799
+ }
800
+
801
+ /*
802
+ * The extended mtree format permits multiple lines specifying
803
+ * attributes for each file. For those entries, only the last line
804
+ * is actually used. Practically speaking, that means we have
805
+ * to read the entire mtree file into memory up front.
806
+ *
807
+ * The parsing is done in two steps. First, it is decided if a line
808
+ * changes the global defaults and if it is, processed accordingly.
809
+ * Otherwise, the options of the line are merged with the current
810
+ * global options.
811
+ */
812
+ static int
813
+ add_option(struct archive_read *a, struct mtree_option **global,
814
+ const char *value, size_t len)
815
+ {
816
+ struct mtree_option *opt;
817
+
818
+ if ((opt = malloc(sizeof(*opt))) == NULL) {
819
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
820
+ return (ARCHIVE_FATAL);
821
+ }
822
+ if ((opt->value = malloc(len + 1)) == NULL) {
823
+ free(opt);
824
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
825
+ return (ARCHIVE_FATAL);
826
+ }
827
+ memcpy(opt->value, value, len);
828
+ opt->value[len] = '\0';
829
+ opt->next = *global;
830
+ *global = opt;
831
+ return (ARCHIVE_OK);
832
+ }
833
+
834
+ static void
835
+ remove_option(struct mtree_option **global, const char *value, size_t len)
836
+ {
837
+ struct mtree_option *iter, *last;
838
+
839
+ last = NULL;
840
+ for (iter = *global; iter != NULL; last = iter, iter = iter->next) {
841
+ if (strncmp(iter->value, value, len) == 0 &&
842
+ (iter->value[len] == '\0' ||
843
+ iter->value[len] == '='))
844
+ break;
845
+ }
846
+ if (iter == NULL)
847
+ return;
848
+ if (last == NULL)
849
+ *global = iter->next;
850
+ else
851
+ last->next = iter->next;
852
+
853
+ free(iter->value);
854
+ free(iter);
855
+ }
856
+
857
+ static int
858
+ process_global_set(struct archive_read *a,
859
+ struct mtree_option **global, const char *line)
860
+ {
861
+ const char *next, *eq;
862
+ size_t len;
863
+ int r;
864
+
865
+ line += 4;
866
+ for (;;) {
867
+ next = line + strspn(line, " \t\r\n");
868
+ if (*next == '\0')
869
+ return (ARCHIVE_OK);
870
+ line = next;
871
+ next = line + strcspn(line, " \t\r\n");
872
+ eq = strchr(line, '=');
873
+ if (eq > next)
874
+ len = next - line;
875
+ else
876
+ len = eq - line;
877
+
878
+ remove_option(global, line, len);
879
+ r = add_option(a, global, line, next - line);
880
+ if (r != ARCHIVE_OK)
881
+ return (r);
882
+ line = next;
883
+ }
884
+ }
885
+
886
+ static int
887
+ process_global_unset(struct archive_read *a,
888
+ struct mtree_option **global, const char *line)
889
+ {
890
+ const char *next;
891
+ size_t len;
892
+
893
+ line += 6;
894
+ if (strchr(line, '=') != NULL) {
895
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
896
+ "/unset shall not contain `='");
897
+ return ARCHIVE_FATAL;
898
+ }
899
+
900
+ for (;;) {
901
+ next = line + strspn(line, " \t\r\n");
902
+ if (*next == '\0')
903
+ return (ARCHIVE_OK);
904
+ line = next;
905
+ len = strcspn(line, " \t\r\n");
906
+
907
+ if (len == 3 && strncmp(line, "all", 3) == 0) {
908
+ free_options(*global);
909
+ *global = NULL;
910
+ } else {
911
+ remove_option(global, line, len);
912
+ }
913
+
914
+ line += len;
915
+ }
916
+ }
917
+
918
+ static int
919
+ process_add_entry(struct archive_read *a, struct mtree *mtree,
920
+ struct mtree_option **global, const char *line, ssize_t line_len,
921
+ struct mtree_entry **last_entry, int is_form_d)
922
+ {
923
+ struct mtree_entry *entry;
924
+ struct mtree_option *iter;
925
+ const char *next, *eq, *name, *end;
926
+ size_t name_len, len;
927
+ int r, i;
928
+
929
+ if ((entry = malloc(sizeof(*entry))) == NULL) {
930
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
931
+ return (ARCHIVE_FATAL);
932
+ }
933
+ entry->next = NULL;
934
+ entry->options = NULL;
935
+ entry->name = NULL;
936
+ entry->used = 0;
937
+ entry->full = 0;
938
+
939
+ /* Add this entry to list. */
940
+ if (*last_entry == NULL)
941
+ mtree->entries = entry;
942
+ else
943
+ (*last_entry)->next = entry;
944
+ *last_entry = entry;
945
+
946
+ if (is_form_d) {
947
+ /* Filename is last item on line. */
948
+ /* Adjust line_len to trim trailing whitespace */
949
+ while (line_len > 0) {
950
+ char last_character = line[line_len - 1];
951
+ if (last_character == '\r'
952
+ || last_character == '\n'
953
+ || last_character == '\t'
954
+ || last_character == ' ') {
955
+ line_len--;
956
+ } else {
957
+ break;
958
+ }
959
+ }
960
+ /* Name starts after the last whitespace separator */
961
+ name = line;
962
+ for (i = 0; i < line_len; i++) {
963
+ if (line[i] == '\r'
964
+ || line[i] == '\n'
965
+ || line[i] == '\t'
966
+ || line[i] == ' ') {
967
+ name = line + i + 1;
968
+ }
969
+ }
970
+ name_len = line + line_len - name;
971
+ end = name;
972
+ } else {
973
+ /* Filename is first item on line */
974
+ name_len = strcspn(line, " \t\r\n");
975
+ name = line;
976
+ line += name_len;
977
+ end = line + line_len;
978
+ }
979
+ /* name/name_len is the name within the line. */
980
+ /* line..end brackets the entire line except the name */
981
+
982
+ if ((entry->name = malloc(name_len + 1)) == NULL) {
983
+ archive_set_error(&a->archive, errno, "Can't allocate memory");
984
+ return (ARCHIVE_FATAL);
985
+ }
986
+
987
+ memcpy(entry->name, name, name_len);
988
+ entry->name[name_len] = '\0';
989
+ parse_escapes(entry->name, entry);
990
+
991
+ entry->next_dup = NULL;
992
+ if (entry->full) {
993
+ if (!__archive_rb_tree_insert_node(&mtree->rbtree, &entry->rbnode)) {
994
+ struct mtree_entry *alt;
995
+ alt = (struct mtree_entry *)__archive_rb_tree_find_node(
996
+ &mtree->rbtree, entry->name);
997
+ if (alt != NULL) {
998
+ while (alt->next_dup)
999
+ alt = alt->next_dup;
1000
+ alt->next_dup = entry;
1001
+ }
1002
+ }
1003
+ }
1004
+
1005
+ for (iter = *global; iter != NULL; iter = iter->next) {
1006
+ r = add_option(a, &entry->options, iter->value,
1007
+ strlen(iter->value));
1008
+ if (r != ARCHIVE_OK)
1009
+ return (r);
1010
+ }
1011
+
1012
+ for (;;) {
1013
+ next = line + strspn(line, " \t\r\n");
1014
+ if (*next == '\0')
1015
+ return (ARCHIVE_OK);
1016
+ if (next >= end)
1017
+ return (ARCHIVE_OK);
1018
+ line = next;
1019
+ next = line + strcspn(line, " \t\r\n");
1020
+ eq = strchr(line, '=');
1021
+ if (eq == NULL || eq > next)
1022
+ len = next - line;
1023
+ else
1024
+ len = eq - line;
1025
+
1026
+ remove_option(&entry->options, line, len);
1027
+ r = add_option(a, &entry->options, line, next - line);
1028
+ if (r != ARCHIVE_OK)
1029
+ return (r);
1030
+ line = next;
1031
+ }
1032
+ }
1033
+
1034
+ static int
1035
+ read_mtree(struct archive_read *a, struct mtree *mtree)
1036
+ {
1037
+ ssize_t len;
1038
+ uintmax_t counter;
1039
+ char *p, *s;
1040
+ struct mtree_option *global;
1041
+ struct mtree_entry *last_entry;
1042
+ int r, is_form_d;
1043
+
1044
+ mtree->archive_format = ARCHIVE_FORMAT_MTREE;
1045
+ mtree->archive_format_name = "mtree";
1046
+
1047
+ global = NULL;
1048
+ last_entry = NULL;
1049
+
1050
+ (void)detect_form(a, &is_form_d);
1051
+
1052
+ for (counter = 1; ; ++counter) {
1053
+ r = ARCHIVE_OK;
1054
+ len = readline(a, mtree, &p, 65536);
1055
+ if (len == 0) {
1056
+ mtree->this_entry = mtree->entries;
1057
+ free_options(global);
1058
+ return (ARCHIVE_OK);
1059
+ }
1060
+ if (len < 0) {
1061
+ free_options(global);
1062
+ return ((int)len);
1063
+ }
1064
+ /* Leading whitespace is never significant, ignore it. */
1065
+ while (*p == ' ' || *p == '\t') {
1066
+ ++p;
1067
+ --len;
1068
+ }
1069
+ /* Skip content lines and blank lines. */
1070
+ if (*p == '#')
1071
+ continue;
1072
+ if (*p == '\r' || *p == '\n' || *p == '\0')
1073
+ continue;
1074
+ /* Non-printable characters are not allowed */
1075
+ for (s = p;s < p + len - 1; s++) {
1076
+ if (!isprint((unsigned char)*s) && *s != '\t') {
1077
+ r = ARCHIVE_FATAL;
1078
+ break;
1079
+ }
1080
+ }
1081
+ if (r != ARCHIVE_OK)
1082
+ break;
1083
+ if (*p != '/') {
1084
+ r = process_add_entry(a, mtree, &global, p, len,
1085
+ &last_entry, is_form_d);
1086
+ } else if (len > 4 && strncmp(p, "/set", 4) == 0) {
1087
+ if (p[4] != ' ' && p[4] != '\t')
1088
+ break;
1089
+ r = process_global_set(a, &global, p);
1090
+ } else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
1091
+ if (p[6] != ' ' && p[6] != '\t')
1092
+ break;
1093
+ r = process_global_unset(a, &global, p);
1094
+ } else
1095
+ break;
1096
+
1097
+ if (r != ARCHIVE_OK) {
1098
+ free_options(global);
1099
+ return r;
1100
+ }
1101
+ }
1102
+
1103
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1104
+ "Can't parse line %ju", counter);
1105
+ free_options(global);
1106
+ return (ARCHIVE_FATAL);
1107
+ }
1108
+
1109
+ /*
1110
+ * Read in the entire mtree file into memory on the first request.
1111
+ * Then use the next unused file to satisfy each header request.
1112
+ */
1113
+ static int
1114
+ read_header(struct archive_read *a, struct archive_entry *entry)
1115
+ {
1116
+ struct mtree *mtree;
1117
+ char *p;
1118
+ int r, use_next;
1119
+
1120
+ mtree = (struct mtree *)(a->format->data);
1121
+
1122
+ if (mtree->fd >= 0) {
1123
+ close(mtree->fd);
1124
+ mtree->fd = -1;
1125
+ }
1126
+
1127
+ if (mtree->entries == NULL) {
1128
+ mtree->resolver = archive_entry_linkresolver_new();
1129
+ if (mtree->resolver == NULL)
1130
+ return ARCHIVE_FATAL;
1131
+ archive_entry_linkresolver_set_strategy(mtree->resolver,
1132
+ ARCHIVE_FORMAT_MTREE);
1133
+ r = read_mtree(a, mtree);
1134
+ if (r != ARCHIVE_OK)
1135
+ return (r);
1136
+ }
1137
+
1138
+ a->archive.archive_format = mtree->archive_format;
1139
+ a->archive.archive_format_name = mtree->archive_format_name;
1140
+
1141
+ for (;;) {
1142
+ if (mtree->this_entry == NULL)
1143
+ return (ARCHIVE_EOF);
1144
+ if (strcmp(mtree->this_entry->name, "..") == 0) {
1145
+ mtree->this_entry->used = 1;
1146
+ if (archive_strlen(&mtree->current_dir) > 0) {
1147
+ /* Roll back current path. */
1148
+ p = mtree->current_dir.s
1149
+ + mtree->current_dir.length - 1;
1150
+ while (p >= mtree->current_dir.s && *p != '/')
1151
+ --p;
1152
+ if (p >= mtree->current_dir.s)
1153
+ --p;
1154
+ mtree->current_dir.length
1155
+ = p - mtree->current_dir.s + 1;
1156
+ }
1157
+ }
1158
+ if (!mtree->this_entry->used) {
1159
+ use_next = 0;
1160
+ r = parse_file(a, entry, mtree, mtree->this_entry,
1161
+ &use_next);
1162
+ if (use_next == 0)
1163
+ return (r);
1164
+ }
1165
+ mtree->this_entry = mtree->this_entry->next;
1166
+ }
1167
+ }
1168
+
1169
+ /*
1170
+ * A single file can have multiple lines contribute specifications.
1171
+ * Parse as many lines as necessary, then pull additional information
1172
+ * from a backing file on disk as necessary.
1173
+ */
1174
+ static int
1175
+ parse_file(struct archive_read *a, struct archive_entry *entry,
1176
+ struct mtree *mtree, struct mtree_entry *mentry, int *use_next)
1177
+ {
1178
+ const char *path;
1179
+ struct stat st_storage, *st;
1180
+ struct mtree_entry *mp;
1181
+ struct archive_entry *sparse_entry;
1182
+ int r = ARCHIVE_OK, r1, parsed_kws;
1183
+
1184
+ mentry->used = 1;
1185
+
1186
+ /* Initialize reasonable defaults. */
1187
+ archive_entry_set_filetype(entry, AE_IFREG);
1188
+ archive_entry_set_size(entry, 0);
1189
+ archive_string_empty(&mtree->contents_name);
1190
+
1191
+ /* Parse options from this line. */
1192
+ parsed_kws = 0;
1193
+ r = parse_line(a, entry, mtree, mentry, &parsed_kws);
1194
+
1195
+ if (mentry->full) {
1196
+ archive_entry_copy_pathname(entry, mentry->name);
1197
+ /*
1198
+ * "Full" entries are allowed to have multiple lines
1199
+ * and those lines aren't required to be adjacent. We
1200
+ * don't support multiple lines for "relative" entries
1201
+ * nor do we make any attempt to merge data from
1202
+ * separate "relative" and "full" entries. (Merging
1203
+ * "relative" and "full" entries would require dealing
1204
+ * with pathname canonicalization, which is a very
1205
+ * tricky subject.)
1206
+ */
1207
+ mp = (struct mtree_entry *)__archive_rb_tree_find_node(
1208
+ &mtree->rbtree, mentry->name);
1209
+ for (; mp; mp = mp->next_dup) {
1210
+ if (mp->full && !mp->used) {
1211
+ /* Later lines override earlier ones. */
1212
+ mp->used = 1;
1213
+ r1 = parse_line(a, entry, mtree, mp, &parsed_kws);
1214
+ if (r1 < r)
1215
+ r = r1;
1216
+ }
1217
+ }
1218
+ } else {
1219
+ /*
1220
+ * Relative entries require us to construct
1221
+ * the full path and possibly update the
1222
+ * current directory.
1223
+ */
1224
+ size_t n = archive_strlen(&mtree->current_dir);
1225
+ if (n > 0)
1226
+ archive_strcat(&mtree->current_dir, "/");
1227
+ archive_strcat(&mtree->current_dir, mentry->name);
1228
+ archive_entry_copy_pathname(entry, mtree->current_dir.s);
1229
+ if (archive_entry_filetype(entry) != AE_IFDIR)
1230
+ mtree->current_dir.length = n;
1231
+ }
1232
+
1233
+ if (mtree->checkfs) {
1234
+ /*
1235
+ * Try to open and stat the file to get the real size
1236
+ * and other file info. It would be nice to avoid
1237
+ * this here so that getting a listing of an mtree
1238
+ * wouldn't require opening every referenced contents
1239
+ * file. But then we wouldn't know the actual
1240
+ * contents size, so I don't see a really viable way
1241
+ * around this. (Also, we may want to someday pull
1242
+ * other unspecified info from the contents file on
1243
+ * disk.)
1244
+ */
1245
+ mtree->fd = -1;
1246
+ if (archive_strlen(&mtree->contents_name) > 0)
1247
+ path = mtree->contents_name.s;
1248
+ else
1249
+ path = archive_entry_pathname(entry);
1250
+
1251
+ if (archive_entry_filetype(entry) == AE_IFREG ||
1252
+ archive_entry_filetype(entry) == AE_IFDIR) {
1253
+ mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
1254
+ __archive_ensure_cloexec_flag(mtree->fd);
1255
+ if (mtree->fd == -1 && (
1256
+ #if defined(_WIN32) && !defined(__CYGWIN__)
1257
+ /*
1258
+ * On Windows, attempting to open a file with an
1259
+ * invalid name result in EINVAL (Error 22)
1260
+ */
1261
+ (errno != ENOENT && errno != EINVAL)
1262
+ #else
1263
+ errno != ENOENT
1264
+ #endif
1265
+ || archive_strlen(&mtree->contents_name) > 0)) {
1266
+ archive_set_error(&a->archive, errno,
1267
+ "Can't open %s", path);
1268
+ r = ARCHIVE_WARN;
1269
+ }
1270
+ }
1271
+
1272
+ st = &st_storage;
1273
+ if (mtree->fd >= 0) {
1274
+ if (fstat(mtree->fd, st) == -1) {
1275
+ archive_set_error(&a->archive, errno,
1276
+ "Could not fstat %s", path);
1277
+ r = ARCHIVE_WARN;
1278
+ /* If we can't stat it, don't keep it open. */
1279
+ close(mtree->fd);
1280
+ mtree->fd = -1;
1281
+ st = NULL;
1282
+ }
1283
+ } else if (lstat(path, st) == -1) {
1284
+ st = NULL;
1285
+ }
1286
+
1287
+ /*
1288
+ * Check for a mismatch between the type in the specification
1289
+ * and the type of the contents object on disk.
1290
+ */
1291
+ if (st != NULL) {
1292
+ if (((st->st_mode & S_IFMT) == S_IFREG &&
1293
+ archive_entry_filetype(entry) == AE_IFREG)
1294
+ #ifdef S_IFLNK
1295
+ ||((st->st_mode & S_IFMT) == S_IFLNK &&
1296
+ archive_entry_filetype(entry) == AE_IFLNK)
1297
+ #endif
1298
+ #ifdef S_IFSOCK
1299
+ ||((st->st_mode & S_IFSOCK) == S_IFSOCK &&
1300
+ archive_entry_filetype(entry) == AE_IFSOCK)
1301
+ #endif
1302
+ #ifdef S_IFCHR
1303
+ ||((st->st_mode & S_IFMT) == S_IFCHR &&
1304
+ archive_entry_filetype(entry) == AE_IFCHR)
1305
+ #endif
1306
+ #ifdef S_IFBLK
1307
+ ||((st->st_mode & S_IFMT) == S_IFBLK &&
1308
+ archive_entry_filetype(entry) == AE_IFBLK)
1309
+ #endif
1310
+ ||((st->st_mode & S_IFMT) == S_IFDIR &&
1311
+ archive_entry_filetype(entry) == AE_IFDIR)
1312
+ #ifdef S_IFIFO
1313
+ ||((st->st_mode & S_IFMT) == S_IFIFO &&
1314
+ archive_entry_filetype(entry) == AE_IFIFO)
1315
+ #endif
1316
+ ) {
1317
+ /* Types match. */
1318
+ } else {
1319
+ /* Types don't match; bail out gracefully. */
1320
+ if (mtree->fd >= 0)
1321
+ close(mtree->fd);
1322
+ mtree->fd = -1;
1323
+ if (parsed_kws & MTREE_HAS_OPTIONAL) {
1324
+ /* It's not an error for an optional
1325
+ * entry to not match disk. */
1326
+ *use_next = 1;
1327
+ } else if (r == ARCHIVE_OK) {
1328
+ archive_set_error(&a->archive,
1329
+ ARCHIVE_ERRNO_MISC,
1330
+ "mtree specification has different"
1331
+ " type for %s",
1332
+ archive_entry_pathname(entry));
1333
+ r = ARCHIVE_WARN;
1334
+ }
1335
+ return (r);
1336
+ }
1337
+ }
1338
+
1339
+ /*
1340
+ * If there is a contents file on disk, pick some of the
1341
+ * metadata from that file. For most of these, we only
1342
+ * set it from the contents if it wasn't already parsed
1343
+ * from the specification.
1344
+ */
1345
+ if (st != NULL) {
1346
+ if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
1347
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
1348
+ (archive_entry_filetype(entry) == AE_IFCHR ||
1349
+ archive_entry_filetype(entry) == AE_IFBLK))
1350
+ archive_entry_set_rdev(entry, st->st_rdev);
1351
+ if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME))
1352
+ == 0 ||
1353
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1354
+ archive_entry_set_gid(entry, st->st_gid);
1355
+ if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME))
1356
+ == 0 ||
1357
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1358
+ archive_entry_set_uid(entry, st->st_uid);
1359
+ if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
1360
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
1361
+ #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
1362
+ archive_entry_set_mtime(entry, st->st_mtime,
1363
+ st->st_mtimespec.tv_nsec);
1364
+ #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
1365
+ archive_entry_set_mtime(entry, st->st_mtime,
1366
+ st->st_mtim.tv_nsec);
1367
+ #elif HAVE_STRUCT_STAT_ST_MTIME_N
1368
+ archive_entry_set_mtime(entry, st->st_mtime,
1369
+ st->st_mtime_n);
1370
+ #elif HAVE_STRUCT_STAT_ST_UMTIME
1371
+ archive_entry_set_mtime(entry, st->st_mtime,
1372
+ st->st_umtime*1000);
1373
+ #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
1374
+ archive_entry_set_mtime(entry, st->st_mtime,
1375
+ st->st_mtime_usec*1000);
1376
+ #else
1377
+ archive_entry_set_mtime(entry, st->st_mtime, 0);
1378
+ #endif
1379
+ }
1380
+ if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
1381
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1382
+ archive_entry_set_nlink(entry, st->st_nlink);
1383
+ if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
1384
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1385
+ archive_entry_set_perm(entry, st->st_mode);
1386
+ if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
1387
+ (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
1388
+ archive_entry_set_size(entry, st->st_size);
1389
+ archive_entry_set_ino(entry, st->st_ino);
1390
+ archive_entry_set_dev(entry, st->st_dev);
1391
+
1392
+ archive_entry_linkify(mtree->resolver, &entry,
1393
+ &sparse_entry);
1394
+ } else if (parsed_kws & MTREE_HAS_OPTIONAL) {
1395
+ /*
1396
+ * Couldn't open the entry, stat it or the on-disk type
1397
+ * didn't match. If this entry is optional, just
1398
+ * ignore it and read the next header entry.
1399
+ */
1400
+ *use_next = 1;
1401
+ return ARCHIVE_OK;
1402
+ }
1403
+ }
1404
+
1405
+ mtree->cur_size = archive_entry_size(entry);
1406
+ mtree->offset = 0;
1407
+
1408
+ return r;
1409
+ }
1410
+
1411
+ /*
1412
+ * Each line contains a sequence of keywords.
1413
+ */
1414
+ static int
1415
+ parse_line(struct archive_read *a, struct archive_entry *entry,
1416
+ struct mtree *mtree, struct mtree_entry *mp, int *parsed_kws)
1417
+ {
1418
+ struct mtree_option *iter;
1419
+ int r = ARCHIVE_OK, r1;
1420
+
1421
+ for (iter = mp->options; iter != NULL; iter = iter->next) {
1422
+ r1 = parse_keyword(a, mtree, entry, iter, parsed_kws);
1423
+ if (r1 < r)
1424
+ r = r1;
1425
+ }
1426
+ if (r == ARCHIVE_OK && (*parsed_kws & MTREE_HAS_TYPE) == 0) {
1427
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1428
+ "Missing type keyword in mtree specification");
1429
+ return (ARCHIVE_WARN);
1430
+ }
1431
+ return (r);
1432
+ }
1433
+
1434
+ /*
1435
+ * Device entries have one of the following forms:
1436
+ * - raw dev_t
1437
+ * - format,major,minor[,subdevice]
1438
+ * When parsing succeeded, `pdev' will contain the appropriate dev_t value.
1439
+ */
1440
+
1441
+ /* strsep() is not in C90, but strcspn() is. */
1442
+ /* Taken from http://unixpapa.com/incnote/string.html */
1443
+ static char *
1444
+ la_strsep(char **sp, const char *sep)
1445
+ {
1446
+ char *p, *s;
1447
+ if (sp == NULL || *sp == NULL || **sp == '\0')
1448
+ return(NULL);
1449
+ s = *sp;
1450
+ p = s + strcspn(s, sep);
1451
+ if (*p != '\0')
1452
+ *p++ = '\0';
1453
+ *sp = p;
1454
+ return(s);
1455
+ }
1456
+
1457
+ static int
1458
+ parse_device(dev_t *pdev, struct archive *a, char *val)
1459
+ {
1460
+ #define MAX_PACK_ARGS 3
1461
+ unsigned long numbers[MAX_PACK_ARGS];
1462
+ char *p, *dev;
1463
+ int argc;
1464
+ pack_t *pack;
1465
+ dev_t result;
1466
+ const char *error = NULL;
1467
+
1468
+ memset(pdev, 0, sizeof(*pdev));
1469
+ if ((dev = strchr(val, ',')) != NULL) {
1470
+ /*
1471
+ * Device's major/minor are given in a specified format.
1472
+ * Decode and pack it accordingly.
1473
+ */
1474
+ *dev++ = '\0';
1475
+ if ((pack = pack_find(val)) == NULL) {
1476
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1477
+ "Unknown format `%s'", val);
1478
+ return ARCHIVE_WARN;
1479
+ }
1480
+ argc = 0;
1481
+ while ((p = la_strsep(&dev, ",")) != NULL) {
1482
+ if (*p == '\0') {
1483
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1484
+ "Missing number");
1485
+ return ARCHIVE_WARN;
1486
+ }
1487
+ if (argc >= MAX_PACK_ARGS) {
1488
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1489
+ "Too many arguments");
1490
+ return ARCHIVE_WARN;
1491
+ }
1492
+ numbers[argc++] = (unsigned long)mtree_atol(&p, 0);
1493
+ }
1494
+ if (argc < 2) {
1495
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1496
+ "Not enough arguments");
1497
+ return ARCHIVE_WARN;
1498
+ }
1499
+ result = (*pack)(argc, numbers, &error);
1500
+ if (error != NULL) {
1501
+ archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
1502
+ "%s", error);
1503
+ return ARCHIVE_WARN;
1504
+ }
1505
+ } else {
1506
+ /* file system raw value. */
1507
+ result = (dev_t)mtree_atol(&val, 0);
1508
+ }
1509
+ *pdev = result;
1510
+ return ARCHIVE_OK;
1511
+ #undef MAX_PACK_ARGS
1512
+ }
1513
+
1514
+ static int
1515
+ parse_hex_nibble(char c)
1516
+ {
1517
+ if (c >= '0' && c <= '9')
1518
+ return c - '0';
1519
+ if (c >= 'a' && c <= 'f')
1520
+ return 10 + c - 'a';
1521
+ #if 0
1522
+ /* XXX: Is uppercase something we should support? */
1523
+ if (c >= 'A' && c <= 'F')
1524
+ return 10 + c - 'A';
1525
+ #endif
1526
+
1527
+ return -1;
1528
+ }
1529
+
1530
+ static int
1531
+ parse_digest(struct archive_read *a, struct archive_entry *entry,
1532
+ const char *digest, int type)
1533
+ {
1534
+ unsigned char digest_buf[64];
1535
+ int high, low;
1536
+ size_t i, j, len;
1537
+
1538
+ switch (type) {
1539
+ case ARCHIVE_ENTRY_DIGEST_MD5:
1540
+ len = sizeof(entry->digest.md5);
1541
+ break;
1542
+ case ARCHIVE_ENTRY_DIGEST_RMD160:
1543
+ len = sizeof(entry->digest.rmd160);
1544
+ break;
1545
+ case ARCHIVE_ENTRY_DIGEST_SHA1:
1546
+ len = sizeof(entry->digest.sha1);
1547
+ break;
1548
+ case ARCHIVE_ENTRY_DIGEST_SHA256:
1549
+ len = sizeof(entry->digest.sha256);
1550
+ break;
1551
+ case ARCHIVE_ENTRY_DIGEST_SHA384:
1552
+ len = sizeof(entry->digest.sha384);
1553
+ break;
1554
+ case ARCHIVE_ENTRY_DIGEST_SHA512:
1555
+ len = sizeof(entry->digest.sha512);
1556
+ break;
1557
+ default:
1558
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
1559
+ "Internal error: Unknown digest type");
1560
+ return ARCHIVE_FATAL;
1561
+ }
1562
+
1563
+ if (len > sizeof(digest_buf)) {
1564
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
1565
+ "Internal error: Digest storage too large");
1566
+ return ARCHIVE_FATAL;
1567
+ }
1568
+
1569
+ len *= 2;
1570
+
1571
+ if (mtree_strnlen(digest, len+1) != len) {
1572
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1573
+ "incorrect digest length, ignoring");
1574
+ return ARCHIVE_WARN;
1575
+ }
1576
+
1577
+ for (i = 0, j = 0; i < len; i += 2, j++) {
1578
+ high = parse_hex_nibble(digest[i]);
1579
+ low = parse_hex_nibble(digest[i+1]);
1580
+ if (high == -1 || low == -1) {
1581
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1582
+ "invalid digest data, ignoring");
1583
+ return ARCHIVE_WARN;
1584
+ }
1585
+
1586
+ digest_buf[j] = high << 4 | low;
1587
+ }
1588
+
1589
+ return archive_entry_set_digest(entry, type, digest_buf);
1590
+ }
1591
+
1592
+ /*
1593
+ * Parse a single keyword and its value.
1594
+ */
1595
+ static int
1596
+ parse_keyword(struct archive_read *a, struct mtree *mtree,
1597
+ struct archive_entry *entry, struct mtree_option *opt, int *parsed_kws)
1598
+ {
1599
+ char *val, *key;
1600
+
1601
+ key = opt->value;
1602
+
1603
+ if (*key == '\0')
1604
+ return (ARCHIVE_OK);
1605
+
1606
+ if (strcmp(key, "nochange") == 0) {
1607
+ *parsed_kws |= MTREE_HAS_NOCHANGE;
1608
+ return (ARCHIVE_OK);
1609
+ }
1610
+ if (strcmp(key, "optional") == 0) {
1611
+ *parsed_kws |= MTREE_HAS_OPTIONAL;
1612
+ return (ARCHIVE_OK);
1613
+ }
1614
+ if (strcmp(key, "ignore") == 0) {
1615
+ /*
1616
+ * The mtree processing is not recursive, so
1617
+ * recursion will only happen for explicitly listed
1618
+ * entries.
1619
+ */
1620
+ return (ARCHIVE_OK);
1621
+ }
1622
+
1623
+ val = strchr(key, '=');
1624
+ if (val == NULL) {
1625
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1626
+ "Malformed attribute \"%s\" (%d)", key, key[0]);
1627
+ return (ARCHIVE_WARN);
1628
+ }
1629
+
1630
+ *val = '\0';
1631
+ ++val;
1632
+
1633
+ switch (key[0]) {
1634
+ case 'c':
1635
+ if (strcmp(key, "content") == 0
1636
+ || strcmp(key, "contents") == 0) {
1637
+ parse_escapes(val, NULL);
1638
+ archive_strcpy(&mtree->contents_name, val);
1639
+ return (ARCHIVE_OK);
1640
+ }
1641
+ if (strcmp(key, "cksum") == 0)
1642
+ return (ARCHIVE_OK);
1643
+ break;
1644
+ case 'd':
1645
+ if (strcmp(key, "device") == 0) {
1646
+ /* stat(2) st_rdev field, e.g. the major/minor IDs
1647
+ * of a char/block special file */
1648
+ int r;
1649
+ dev_t dev;
1650
+
1651
+ *parsed_kws |= MTREE_HAS_DEVICE;
1652
+ r = parse_device(&dev, &a->archive, val);
1653
+ if (r == ARCHIVE_OK)
1654
+ archive_entry_set_rdev(entry, dev);
1655
+ return r;
1656
+ }
1657
+ break;
1658
+ case 'f':
1659
+ if (strcmp(key, "flags") == 0) {
1660
+ *parsed_kws |= MTREE_HAS_FFLAGS;
1661
+ archive_entry_copy_fflags_text(entry, val);
1662
+ return (ARCHIVE_OK);
1663
+ }
1664
+ break;
1665
+ case 'g':
1666
+ if (strcmp(key, "gid") == 0) {
1667
+ *parsed_kws |= MTREE_HAS_GID;
1668
+ archive_entry_set_gid(entry, mtree_atol(&val, 10));
1669
+ return (ARCHIVE_OK);
1670
+ }
1671
+ if (strcmp(key, "gname") == 0) {
1672
+ *parsed_kws |= MTREE_HAS_GNAME;
1673
+ archive_entry_copy_gname(entry, val);
1674
+ return (ARCHIVE_OK);
1675
+ }
1676
+ break;
1677
+ case 'i':
1678
+ if (strcmp(key, "inode") == 0) {
1679
+ archive_entry_set_ino(entry, mtree_atol(&val, 10));
1680
+ return (ARCHIVE_OK);
1681
+ }
1682
+ break;
1683
+ case 'l':
1684
+ if (strcmp(key, "link") == 0) {
1685
+ parse_escapes(val, NULL);
1686
+ archive_entry_copy_symlink(entry, val);
1687
+ return (ARCHIVE_OK);
1688
+ }
1689
+ break;
1690
+ case 'm':
1691
+ if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
1692
+ return parse_digest(a, entry, val,
1693
+ ARCHIVE_ENTRY_DIGEST_MD5);
1694
+ }
1695
+ if (strcmp(key, "mode") == 0) {
1696
+ if (val[0] < '0' || val[0] > '7') {
1697
+ archive_set_error(&a->archive,
1698
+ ARCHIVE_ERRNO_FILE_FORMAT,
1699
+ "Symbolic or non-octal mode \"%s\" unsupported", val);
1700
+ return (ARCHIVE_WARN);
1701
+ }
1702
+ *parsed_kws |= MTREE_HAS_PERM;
1703
+ archive_entry_set_perm(entry, (mode_t)mtree_atol(&val, 8));
1704
+ return (ARCHIVE_OK);
1705
+ }
1706
+ break;
1707
+ case 'n':
1708
+ if (strcmp(key, "nlink") == 0) {
1709
+ *parsed_kws |= MTREE_HAS_NLINK;
1710
+ archive_entry_set_nlink(entry,
1711
+ (unsigned int)mtree_atol(&val, 10));
1712
+ return (ARCHIVE_OK);
1713
+ }
1714
+ break;
1715
+ case 'r':
1716
+ if (strcmp(key, "resdevice") == 0) {
1717
+ /* stat(2) st_dev field, e.g. the device ID where the
1718
+ * inode resides */
1719
+ int r;
1720
+ dev_t dev;
1721
+
1722
+ r = parse_device(&dev, &a->archive, val);
1723
+ if (r == ARCHIVE_OK)
1724
+ archive_entry_set_dev(entry, dev);
1725
+ return r;
1726
+ }
1727
+ if (strcmp(key, "rmd160") == 0 ||
1728
+ strcmp(key, "rmd160digest") == 0) {
1729
+ return parse_digest(a, entry, val,
1730
+ ARCHIVE_ENTRY_DIGEST_RMD160);
1731
+ }
1732
+ break;
1733
+ case 's':
1734
+ if (strcmp(key, "sha1") == 0 ||
1735
+ strcmp(key, "sha1digest") == 0) {
1736
+ return parse_digest(a, entry, val,
1737
+ ARCHIVE_ENTRY_DIGEST_SHA1);
1738
+ }
1739
+ if (strcmp(key, "sha256") == 0 ||
1740
+ strcmp(key, "sha256digest") == 0) {
1741
+ return parse_digest(a, entry, val,
1742
+ ARCHIVE_ENTRY_DIGEST_SHA256);
1743
+ }
1744
+ if (strcmp(key, "sha384") == 0 ||
1745
+ strcmp(key, "sha384digest") == 0) {
1746
+ return parse_digest(a, entry, val,
1747
+ ARCHIVE_ENTRY_DIGEST_SHA384);
1748
+ }
1749
+ if (strcmp(key, "sha512") == 0 ||
1750
+ strcmp(key, "sha512digest") == 0) {
1751
+ return parse_digest(a, entry, val,
1752
+ ARCHIVE_ENTRY_DIGEST_SHA512);
1753
+ }
1754
+ if (strcmp(key, "size") == 0) {
1755
+ archive_entry_set_size(entry, mtree_atol(&val, 10));
1756
+ return (ARCHIVE_OK);
1757
+ }
1758
+ break;
1759
+ case 't':
1760
+ if (strcmp(key, "tags") == 0) {
1761
+ /*
1762
+ * Comma delimited list of tags.
1763
+ * Ignore the tags for now, but the interface
1764
+ * should be extended to allow inclusion/exclusion.
1765
+ */
1766
+ return (ARCHIVE_OK);
1767
+ }
1768
+ if (strcmp(key, "time") == 0) {
1769
+ int64_t m;
1770
+ int64_t my_time_t_max = get_time_t_max();
1771
+ int64_t my_time_t_min = get_time_t_min();
1772
+ long ns = 0;
1773
+
1774
+ *parsed_kws |= MTREE_HAS_MTIME;
1775
+ m = mtree_atol(&val, 10);
1776
+ /* Replicate an old mtree bug:
1777
+ * 123456789.1 represents 123456789
1778
+ * seconds and 1 nanosecond. */
1779
+ if (*val == '.') {
1780
+ ++val;
1781
+ ns = (long)mtree_atol(&val, 10);
1782
+ if (ns < 0)
1783
+ ns = 0;
1784
+ else if (ns > 999999999)
1785
+ ns = 999999999;
1786
+ }
1787
+ if (m > my_time_t_max)
1788
+ m = my_time_t_max;
1789
+ else if (m < my_time_t_min)
1790
+ m = my_time_t_min;
1791
+ archive_entry_set_mtime(entry, (time_t)m, ns);
1792
+ return (ARCHIVE_OK);
1793
+ }
1794
+ if (strcmp(key, "type") == 0) {
1795
+ switch (val[0]) {
1796
+ case 'b':
1797
+ if (strcmp(val, "block") == 0) {
1798
+ *parsed_kws |= MTREE_HAS_TYPE;
1799
+ archive_entry_set_filetype(entry,
1800
+ AE_IFBLK);
1801
+ return (ARCHIVE_OK);
1802
+ }
1803
+ break;
1804
+ case 'c':
1805
+ if (strcmp(val, "char") == 0) {
1806
+ *parsed_kws |= MTREE_HAS_TYPE;
1807
+ archive_entry_set_filetype(entry,
1808
+ AE_IFCHR);
1809
+ return (ARCHIVE_OK);
1810
+ }
1811
+ break;
1812
+ case 'd':
1813
+ if (strcmp(val, "dir") == 0) {
1814
+ *parsed_kws |= MTREE_HAS_TYPE;
1815
+ archive_entry_set_filetype(entry,
1816
+ AE_IFDIR);
1817
+ return (ARCHIVE_OK);
1818
+ }
1819
+ break;
1820
+ case 'f':
1821
+ if (strcmp(val, "fifo") == 0) {
1822
+ *parsed_kws |= MTREE_HAS_TYPE;
1823
+ archive_entry_set_filetype(entry,
1824
+ AE_IFIFO);
1825
+ return (ARCHIVE_OK);
1826
+ }
1827
+ if (strcmp(val, "file") == 0) {
1828
+ *parsed_kws |= MTREE_HAS_TYPE;
1829
+ archive_entry_set_filetype(entry,
1830
+ AE_IFREG);
1831
+ return (ARCHIVE_OK);
1832
+ }
1833
+ break;
1834
+ case 'l':
1835
+ if (strcmp(val, "link") == 0) {
1836
+ *parsed_kws |= MTREE_HAS_TYPE;
1837
+ archive_entry_set_filetype(entry,
1838
+ AE_IFLNK);
1839
+ return (ARCHIVE_OK);
1840
+ }
1841
+ break;
1842
+ default:
1843
+ break;
1844
+ }
1845
+ archive_set_error(&a->archive,
1846
+ ARCHIVE_ERRNO_FILE_FORMAT,
1847
+ "Unrecognized file type \"%s\"; "
1848
+ "assuming \"file\"", val);
1849
+ archive_entry_set_filetype(entry, AE_IFREG);
1850
+ return (ARCHIVE_WARN);
1851
+ }
1852
+ break;
1853
+ case 'u':
1854
+ if (strcmp(key, "uid") == 0) {
1855
+ *parsed_kws |= MTREE_HAS_UID;
1856
+ archive_entry_set_uid(entry, mtree_atol(&val, 10));
1857
+ return (ARCHIVE_OK);
1858
+ }
1859
+ if (strcmp(key, "uname") == 0) {
1860
+ *parsed_kws |= MTREE_HAS_UNAME;
1861
+ archive_entry_copy_uname(entry, val);
1862
+ return (ARCHIVE_OK);
1863
+ }
1864
+ break;
1865
+ default:
1866
+ break;
1867
+ }
1868
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
1869
+ "Unrecognized key %s=%s", key, val);
1870
+ return (ARCHIVE_WARN);
1871
+ }
1872
+
1873
+ static int
1874
+ read_data(struct archive_read *a, const void **buff, size_t *size,
1875
+ int64_t *offset)
1876
+ {
1877
+ size_t bytes_to_read;
1878
+ ssize_t bytes_read;
1879
+ struct mtree *mtree;
1880
+
1881
+ mtree = (struct mtree *)(a->format->data);
1882
+ if (mtree->fd < 0) {
1883
+ *buff = NULL;
1884
+ *offset = 0;
1885
+ *size = 0;
1886
+ return (ARCHIVE_EOF);
1887
+ }
1888
+ if (mtree->buff == NULL) {
1889
+ mtree->buffsize = 64 * 1024;
1890
+ mtree->buff = malloc(mtree->buffsize);
1891
+ if (mtree->buff == NULL) {
1892
+ archive_set_error(&a->archive, ENOMEM,
1893
+ "Can't allocate memory");
1894
+ return (ARCHIVE_FATAL);
1895
+ }
1896
+ }
1897
+
1898
+ *buff = mtree->buff;
1899
+ *offset = mtree->offset;
1900
+ if ((int64_t)mtree->buffsize > mtree->cur_size - mtree->offset)
1901
+ bytes_to_read = (size_t)(mtree->cur_size - mtree->offset);
1902
+ else
1903
+ bytes_to_read = mtree->buffsize;
1904
+ bytes_read = read(mtree->fd, mtree->buff, bytes_to_read);
1905
+ if (bytes_read < 0) {
1906
+ archive_set_error(&a->archive, errno, "Can't read");
1907
+ return (ARCHIVE_WARN);
1908
+ }
1909
+ if (bytes_read == 0) {
1910
+ *size = 0;
1911
+ return (ARCHIVE_EOF);
1912
+ }
1913
+ mtree->offset += bytes_read;
1914
+ *size = bytes_read;
1915
+ return (ARCHIVE_OK);
1916
+ }
1917
+
1918
+ /* Skip does nothing except possibly close the contents file. */
1919
+ static int
1920
+ skip(struct archive_read *a)
1921
+ {
1922
+ struct mtree *mtree;
1923
+
1924
+ mtree = (struct mtree *)(a->format->data);
1925
+ if (mtree->fd >= 0) {
1926
+ close(mtree->fd);
1927
+ mtree->fd = -1;
1928
+ }
1929
+ return (ARCHIVE_OK);
1930
+ }
1931
+
1932
+ /*
1933
+ * Since parsing backslash sequences always makes strings shorter,
1934
+ * we can always do this conversion in-place.
1935
+ */
1936
+ static void
1937
+ parse_escapes(char *src, struct mtree_entry *mentry)
1938
+ {
1939
+ char *dest = src;
1940
+ char c;
1941
+
1942
+ if (mentry != NULL && strcmp(src, ".") == 0)
1943
+ mentry->full = 1;
1944
+
1945
+ while (*src != '\0') {
1946
+ c = *src++;
1947
+ if (c == '/' && mentry != NULL)
1948
+ mentry->full = 1;
1949
+ if (c == '\\') {
1950
+ switch (src[0]) {
1951
+ case '0':
1952
+ if (src[1] < '0' || src[1] > '7') {
1953
+ c = 0;
1954
+ ++src;
1955
+ break;
1956
+ }
1957
+ /* FALLTHROUGH */
1958
+ case '1':
1959
+ case '2':
1960
+ case '3':
1961
+ if (src[1] >= '0' && src[1] <= '7' &&
1962
+ src[2] >= '0' && src[2] <= '7') {
1963
+ c = (src[0] - '0') << 6;
1964
+ c |= (src[1] - '0') << 3;
1965
+ c |= (src[2] - '0');
1966
+ src += 3;
1967
+ }
1968
+ break;
1969
+ case 'a':
1970
+ c = '\a';
1971
+ ++src;
1972
+ break;
1973
+ case 'b':
1974
+ c = '\b';
1975
+ ++src;
1976
+ break;
1977
+ case 'f':
1978
+ c = '\f';
1979
+ ++src;
1980
+ break;
1981
+ case 'n':
1982
+ c = '\n';
1983
+ ++src;
1984
+ break;
1985
+ case 'r':
1986
+ c = '\r';
1987
+ ++src;
1988
+ break;
1989
+ case 's':
1990
+ c = ' ';
1991
+ ++src;
1992
+ break;
1993
+ case 't':
1994
+ c = '\t';
1995
+ ++src;
1996
+ break;
1997
+ case 'v':
1998
+ c = '\v';
1999
+ ++src;
2000
+ break;
2001
+ case '\\':
2002
+ c = '\\';
2003
+ ++src;
2004
+ break;
2005
+ }
2006
+ }
2007
+ *dest++ = c;
2008
+ }
2009
+ *dest = '\0';
2010
+ }
2011
+
2012
+ /* Parse a hex digit. */
2013
+ static int
2014
+ parsedigit(char c)
2015
+ {
2016
+ if (c >= '0' && c <= '9')
2017
+ return c - '0';
2018
+ else if (c >= 'a' && c <= 'f')
2019
+ return c - 'a';
2020
+ else if (c >= 'A' && c <= 'F')
2021
+ return c - 'A';
2022
+ else
2023
+ return -1;
2024
+ }
2025
+
2026
+ /*
2027
+ * Note that this implementation does not (and should not!) obey
2028
+ * locale settings; you cannot simply substitute strtol here, since
2029
+ * it does obey locale.
2030
+ */
2031
+ static int64_t
2032
+ mtree_atol(char **p, int base)
2033
+ {
2034
+ int64_t l, limit;
2035
+ int digit, last_digit_limit;
2036
+
2037
+ if (base == 0) {
2038
+ if (**p != '0')
2039
+ base = 10;
2040
+ else if ((*p)[1] == 'x' || (*p)[1] == 'X') {
2041
+ *p += 2;
2042
+ base = 16;
2043
+ } else {
2044
+ base = 8;
2045
+ }
2046
+ }
2047
+
2048
+ if (**p == '-') {
2049
+ limit = INT64_MIN / base;
2050
+ last_digit_limit = -(INT64_MIN % base);
2051
+ ++(*p);
2052
+
2053
+ l = 0;
2054
+ digit = parsedigit(**p);
2055
+ while (digit >= 0 && digit < base) {
2056
+ if (l < limit || (l == limit && digit >= last_digit_limit))
2057
+ return INT64_MIN;
2058
+ l = (l * base) - digit;
2059
+ digit = parsedigit(*++(*p));
2060
+ }
2061
+ return l;
2062
+ } else {
2063
+ limit = INT64_MAX / base;
2064
+ last_digit_limit = INT64_MAX % base;
2065
+
2066
+ l = 0;
2067
+ digit = parsedigit(**p);
2068
+ while (digit >= 0 && digit < base) {
2069
+ if (l > limit || (l == limit && digit > last_digit_limit))
2070
+ return INT64_MAX;
2071
+ l = (l * base) + digit;
2072
+ digit = parsedigit(*++(*p));
2073
+ }
2074
+ return l;
2075
+ }
2076
+ }
2077
+
2078
+ /*
2079
+ * Returns length of line (including trailing newline)
2080
+ * or negative on error. 'start' argument is updated to
2081
+ * point to first character of line.
2082
+ */
2083
+ static ssize_t
2084
+ readline(struct archive_read *a, struct mtree *mtree, char **start,
2085
+ ssize_t limit)
2086
+ {
2087
+ ssize_t bytes_read;
2088
+ ssize_t total_size = 0;
2089
+ ssize_t find_off = 0;
2090
+ const void *t;
2091
+ void *nl;
2092
+ char *u;
2093
+
2094
+ /* Accumulate line in a line buffer. */
2095
+ for (;;) {
2096
+ /* Read some more. */
2097
+ t = __archive_read_ahead(a, 1, &bytes_read);
2098
+ if (t == NULL)
2099
+ return (0);
2100
+ if (bytes_read < 0)
2101
+ return (ARCHIVE_FATAL);
2102
+ nl = memchr(t, '\n', bytes_read);
2103
+ /* If we found '\n', trim the read to end exactly there. */
2104
+ if (nl != NULL) {
2105
+ bytes_read = ((const char *)nl) - ((const char *)t) + 1;
2106
+ }
2107
+ if (total_size + bytes_read + 1 > limit) {
2108
+ archive_set_error(&a->archive,
2109
+ ARCHIVE_ERRNO_FILE_FORMAT,
2110
+ "Line too long");
2111
+ return (ARCHIVE_FATAL);
2112
+ }
2113
+ if (archive_string_ensure(&mtree->line,
2114
+ total_size + bytes_read + 1) == NULL) {
2115
+ archive_set_error(&a->archive, ENOMEM,
2116
+ "Can't allocate working buffer");
2117
+ return (ARCHIVE_FATAL);
2118
+ }
2119
+ /* Append new bytes to string. */
2120
+ memcpy(mtree->line.s + total_size, t, bytes_read);
2121
+ __archive_read_consume(a, bytes_read);
2122
+ total_size += bytes_read;
2123
+ mtree->line.s[total_size] = '\0';
2124
+
2125
+ for (u = mtree->line.s + find_off; *u; ++u) {
2126
+ if (u[0] == '\n') {
2127
+ /* Ends with unescaped newline. */
2128
+ *start = mtree->line.s;
2129
+ return total_size;
2130
+ } else if (u[0] == '#') {
2131
+ /* Ends with comment sequence #...\n */
2132
+ if (nl == NULL) {
2133
+ /* But we've not found the \n yet */
2134
+ break;
2135
+ }
2136
+ } else if (u[0] == '\\') {
2137
+ if (u[1] == '\n') {
2138
+ /* Trim escaped newline. */
2139
+ total_size -= 2;
2140
+ mtree->line.s[total_size] = '\0';
2141
+ break;
2142
+ } else if (u[1] != '\0') {
2143
+ /* Skip the two-char escape sequence */
2144
+ ++u;
2145
+ }
2146
+ }
2147
+ }
2148
+ find_off = u - mtree->line.s;
2149
+ }
2150
+ }