libarchive-static 1.0.6 → 1.1.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 (295) hide show
  1. checksums.yaml +4 -4
  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_reader.c +6 -4
  20. data/ext/libarchive-0.1.1/ext/libarchive_reader.o +0 -0
  21. data/ext/libarchive-0.1.1/ext/libarchive_ruby.so +0 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +1 -1
  23. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +2 -2
  24. data/ext/libarchive-0.1.1/ext/libarchive_writer.o +0 -0
  25. data/ext/libarchive-3.6.2/Makefile.in +16892 -0
  26. data/ext/libarchive-3.6.2/build/autoconf/ax_append_compile_flags.m4 +67 -0
  27. data/ext/libarchive-3.6.2/build/autoconf/ax_append_flag.m4 +71 -0
  28. data/ext/libarchive-3.6.2/build/autoconf/ax_check_compile_flag.m4 +74 -0
  29. data/ext/libarchive-3.6.2/build/autoconf/ax_require_defined.m4 +37 -0
  30. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/check_stdcall_func.m4 +0 -0
  31. data/ext/libarchive-3.6.2/build/autoconf/compile +348 -0
  32. data/ext/libarchive-3.6.2/build/autoconf/config.guess +1754 -0
  33. data/ext/libarchive-3.6.2/build/autoconf/config.rpath +696 -0
  34. data/ext/libarchive-3.6.2/build/autoconf/config.sub +1890 -0
  35. data/ext/libarchive-3.6.2/build/autoconf/depcomp +791 -0
  36. data/ext/libarchive-3.6.2/build/autoconf/iconv.m4 +271 -0
  37. data/ext/libarchive-3.6.2/build/autoconf/install-sh +541 -0
  38. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/autoconf/la_uid_t.m4 +0 -0
  39. data/ext/libarchive-3.6.2/build/autoconf/lib-ld.m4 +109 -0
  40. data/ext/libarchive-3.6.2/build/autoconf/lib-link.m4 +777 -0
  41. data/ext/libarchive-3.6.2/build/autoconf/lib-prefix.m4 +224 -0
  42. data/ext/libarchive-3.6.2/build/autoconf/ltmain.sh +11251 -0
  43. data/ext/libarchive-3.6.2/build/autoconf/m4_ax_compile_check_sizeof.m4 +115 -0
  44. data/ext/libarchive-3.6.2/build/autoconf/missing +215 -0
  45. data/ext/libarchive-3.6.2/build/autoconf/test-driver +153 -0
  46. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/build/pkgconfig/libarchive.pc.in +4 -1
  47. data/ext/libarchive-3.6.2/config.h.in +1504 -0
  48. data/ext/libarchive-3.6.2/configure +25558 -0
  49. data/ext/libarchive-3.6.2/libarchive/archive.h +1212 -0
  50. data/ext/libarchive-3.6.2/libarchive/archive_acl.c +2097 -0
  51. data/ext/libarchive-3.6.2/libarchive/archive_acl_private.h +83 -0
  52. data/ext/libarchive-3.6.2/libarchive/archive_blake2.h +197 -0
  53. data/ext/libarchive-3.6.2/libarchive/archive_blake2_impl.h +161 -0
  54. data/ext/libarchive-3.6.2/libarchive/archive_blake2s_ref.c +369 -0
  55. data/ext/libarchive-3.6.2/libarchive/archive_blake2sp_ref.c +361 -0
  56. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_check_magic.c +63 -22
  57. data/ext/libarchive-3.6.2/libarchive/archive_cmdline.c +227 -0
  58. data/ext/libarchive-3.6.2/libarchive/archive_cmdline_private.h +47 -0
  59. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_crc32.h +17 -0
  60. data/ext/libarchive-3.6.2/libarchive/archive_cryptor.c +534 -0
  61. data/ext/libarchive-3.6.2/libarchive/archive_cryptor_private.h +188 -0
  62. data/ext/libarchive-3.6.2/libarchive/archive_digest.c +1505 -0
  63. data/ext/libarchive-3.6.2/libarchive/archive_digest_private.h +416 -0
  64. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_darwin.c +559 -0
  65. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_freebsd.c +712 -0
  66. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_linux.c +760 -0
  67. data/ext/libarchive-3.6.2/libarchive/archive_disk_acl_sunos.c +824 -0
  68. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_endian.h +48 -15
  69. data/ext/libarchive-3.6.2/libarchive/archive_entry.c +2149 -0
  70. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry.h +305 -106
  71. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_bhfi.c +5 -4
  72. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_copy_stat.c +9 -3
  73. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_link_resolver.c +104 -62
  74. data/ext/libarchive-3.6.2/libarchive/archive_entry_locale.h +92 -0
  75. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_private.h +65 -49
  76. data/ext/libarchive-3.6.2/libarchive/archive_entry_sparse.c +156 -0
  77. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_stat.c +6 -6
  78. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_strmode.c +1 -1
  79. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_entry_xattr.c +4 -6
  80. data/ext/libarchive-3.6.2/libarchive/archive_getdate.c +1165 -0
  81. data/ext/libarchive-3.6.2/libarchive/archive_getdate.h +39 -0
  82. data/ext/libarchive-3.6.2/libarchive/archive_hmac.c +334 -0
  83. data/ext/libarchive-3.6.2/libarchive/archive_hmac_private.h +117 -0
  84. data/ext/libarchive-3.6.2/libarchive/archive_match.c +1875 -0
  85. data/ext/libarchive-3.6.2/libarchive/archive_openssl_evp_private.h +53 -0
  86. data/ext/libarchive-3.6.2/libarchive/archive_openssl_hmac_private.h +54 -0
  87. data/ext/libarchive-3.6.2/libarchive/archive_options.c +218 -0
  88. data/ext/libarchive-3.6.2/libarchive/archive_options_private.h +51 -0
  89. data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.c +337 -0
  90. data/ext/libarchive-3.6.2/libarchive/archive_pack_dev.h +49 -0
  91. data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.c +463 -0
  92. data/ext/libarchive-3.6.2/libarchive/archive_pathmatch.h +52 -0
  93. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_platform.h +77 -9
  94. data/ext/libarchive-3.6.2/libarchive/archive_platform_acl.h +55 -0
  95. data/ext/libarchive-3.6.2/libarchive/archive_platform_xattr.h +47 -0
  96. data/ext/libarchive-3.6.2/libarchive/archive_ppmd7.c +1168 -0
  97. data/ext/libarchive-3.6.2/libarchive/archive_ppmd7_private.h +119 -0
  98. data/ext/libarchive-3.6.2/libarchive/archive_ppmd8.c +1287 -0
  99. data/ext/libarchive-3.6.2/libarchive/archive_ppmd8_private.h +148 -0
  100. data/ext/libarchive-3.6.2/libarchive/archive_ppmd_private.h +151 -0
  101. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_private.h +74 -18
  102. data/ext/libarchive-3.6.2/libarchive/archive_random.c +272 -0
  103. data/ext/libarchive-3.6.2/libarchive/archive_random_private.h +36 -0
  104. data/ext/libarchive-3.6.2/libarchive/archive_rb.c +709 -0
  105. data/ext/libarchive-3.6.2/libarchive/archive_rb.h +113 -0
  106. data/ext/libarchive-3.6.2/libarchive/archive_read.c +1756 -0
  107. data/ext/libarchive-3.6.2/libarchive/archive_read_add_passphrase.c +190 -0
  108. data/ext/libarchive-3.6.2/libarchive/archive_read_append_filter.c +204 -0
  109. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_data_into_fd.c +64 -18
  110. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_entry_from_file.c +1086 -0
  111. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_posix.c +2732 -0
  112. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_private.h +40 -4
  113. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_disk_set_standard_lookup.c +21 -11
  114. data/ext/libarchive-3.6.2/libarchive/archive_read_disk_windows.c +2479 -0
  115. data/ext/libarchive-3.6.2/libarchive/archive_read_extract.c +60 -0
  116. data/ext/{libarchive-2.8.4/libarchive/archive_read_extract.c → libarchive-3.6.2/libarchive/archive_read_extract2.c} +34 -61
  117. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_fd.c +70 -49
  118. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_file.c +38 -23
  119. data/ext/libarchive-3.6.2/libarchive/archive_read_open_filename.c +586 -0
  120. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_open_memory.c +58 -28
  121. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_private.h +127 -59
  122. data/ext/libarchive-3.6.2/libarchive/archive_read_set_format.c +117 -0
  123. data/ext/libarchive-3.6.2/libarchive/archive_read_set_options.c +133 -0
  124. 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
  125. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_by_code.c +83 -0
  126. 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
  127. 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
  128. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_grzip.c +112 -0
  129. 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
  130. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lrzip.c +122 -0
  131. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lz4.c +742 -0
  132. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_lzop.c +499 -0
  133. 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
  134. 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
  135. 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
  136. 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
  137. 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
  138. data/ext/libarchive-3.6.2/libarchive/archive_read_support_filter_zstd.c +297 -0
  139. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_7zip.c +3900 -0
  140. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_all.c +89 -0
  141. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_ar.c +126 -72
  142. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_by_code.c +92 -0
  143. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cab.c +3228 -0
  144. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_cpio.c +1104 -0
  145. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_empty.c +14 -11
  146. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_iso9660.c +990 -541
  147. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_lha.c +2916 -0
  148. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_mtree.c +2150 -0
  149. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar.c +3797 -0
  150. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_rar5.c +4251 -0
  151. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_raw.c +38 -31
  152. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_tar.c +1157 -629
  153. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_warc.c +848 -0
  154. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_read_support_format_xar.c +439 -258
  155. data/ext/libarchive-3.6.2/libarchive/archive_read_support_format_zip.c +4270 -0
  156. data/ext/libarchive-3.6.2/libarchive/archive_string.c +4240 -0
  157. data/ext/libarchive-3.6.2/libarchive/archive_string.h +243 -0
  158. data/ext/libarchive-3.6.2/libarchive/archive_string_composition.h +2292 -0
  159. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_string_sprintf.c +44 -16
  160. data/ext/libarchive-3.6.2/libarchive/archive_util.c +655 -0
  161. data/ext/libarchive-3.6.2/libarchive/archive_version_details.c +151 -0
  162. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_virtual.c +85 -16
  163. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.c +214 -541
  164. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_windows.h +74 -106
  165. data/ext/libarchive-3.6.2/libarchive/archive_write.c +828 -0
  166. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter.c +72 -0
  167. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_b64encode.c +304 -0
  168. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_by_name.c +77 -0
  169. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_bzip2.c +401 -0
  170. 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
  171. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_grzip.c +135 -0
  172. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_gzip.c +442 -0
  173. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lrzip.c +197 -0
  174. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lz4.c +700 -0
  175. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_lzop.c +478 -0
  176. 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
  177. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_program.c +391 -0
  178. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_uuencode.c +295 -0
  179. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_xz.c +545 -0
  180. data/ext/libarchive-3.6.2/libarchive/archive_write_add_filter_zstd.c +418 -0
  181. data/ext/libarchive-3.6.2/libarchive/archive_write_disk_posix.c +4711 -0
  182. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_private.h +9 -2
  183. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_disk_set_standard_lookup.c +30 -29
  184. data/ext/libarchive-3.6.2/libarchive/archive_write_disk_windows.c +2842 -0
  185. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_fd.c +15 -10
  186. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_file.c +15 -9
  187. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_filename.c +128 -20
  188. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_open_memory.c +7 -18
  189. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_private.h +72 -29
  190. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format.c +56 -3
  191. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_7zip.c +2322 -0
  192. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ar.c +54 -34
  193. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_by_name.c +20 -2
  194. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio.c +11 -0
  195. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_binary.c +610 -0
  196. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_newc.c +457 -0
  197. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_cpio_odc.c +500 -0
  198. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_filter_by_ext.c +142 -0
  199. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_gnutar.c +755 -0
  200. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_iso9660.c +8165 -0
  201. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_mtree.c +2217 -0
  202. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_pax.c +1049 -387
  203. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_private.h +42 -0
  204. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_raw.c +125 -0
  205. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_shar.c +62 -47
  206. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/archive_write_set_format_ustar.c +279 -108
  207. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_v7tar.c +638 -0
  208. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_warc.c +453 -0
  209. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_xar.c +3259 -0
  210. data/ext/libarchive-3.6.2/libarchive/archive_write_set_format_zip.c +1704 -0
  211. data/ext/libarchive-3.6.2/libarchive/archive_write_set_options.c +130 -0
  212. data/ext/libarchive-3.6.2/libarchive/archive_write_set_passphrase.c +95 -0
  213. data/ext/libarchive-3.6.2/libarchive/archive_xxhash.h +48 -0
  214. data/ext/libarchive-3.6.2/libarchive/config_freebsd.h +271 -0
  215. data/ext/{libarchive-2.8.4 → libarchive-3.6.2}/libarchive/filter_fork.h +10 -5
  216. data/ext/{libarchive-2.8.4/libarchive/filter_fork.c → libarchive-3.6.2/libarchive/filter_fork_posix.c} +98 -19
  217. data/ext/libarchive-3.6.2/libarchive/filter_fork_windows.c +236 -0
  218. data/ext/libarchive-3.6.2/libarchive/xxhash.c +525 -0
  219. data/ext/libarchive-static-makefile +144 -80
  220. data/ext/libarchive-static-wrapper-makefile +1 -1
  221. data/ext/zlib-1.2.13/Makefile.in +404 -0
  222. data/ext/{zlib-1.2.5 → zlib-1.2.13}/adler32.c +51 -34
  223. data/ext/{zlib-1.2.5 → zlib-1.2.13}/compress.c +27 -21
  224. data/ext/zlib-1.2.13/configure +922 -0
  225. data/ext/zlib-1.2.13/crc32.c +1125 -0
  226. data/ext/zlib-1.2.13/crc32.h +9446 -0
  227. data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.c +842 -459
  228. data/ext/{zlib-1.2.5 → zlib-1.2.13}/deflate.h +37 -33
  229. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzclose.c +0 -0
  230. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzguts.h +103 -16
  231. data/ext/{zlib-1.2.5 → zlib-1.2.13}/gzlib.c +155 -53
  232. data/ext/zlib-1.2.13/gzread.c +650 -0
  233. data/ext/zlib-1.2.13/gzwrite.c +677 -0
  234. data/ext/{zlib-1.2.5 → zlib-1.2.13}/infback.c +24 -12
  235. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.c +49 -66
  236. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffast.h +0 -0
  237. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inffixed.h +3 -3
  238. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.c +209 -94
  239. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inflate.h +9 -5
  240. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.c +24 -50
  241. data/ext/{zlib-1.2.5 → zlib-1.2.13}/inftrees.h +1 -1
  242. data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.c +135 -198
  243. data/ext/{zlib-1.2.5 → zlib-1.2.13}/trees.h +0 -0
  244. data/ext/zlib-1.2.13/uncompr.c +93 -0
  245. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zconf.h +182 -63
  246. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zlib.h +617 -295
  247. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.c +50 -41
  248. data/ext/{zlib-1.2.5 → zlib-1.2.13}/zutil.h +83 -82
  249. metadata +241 -133
  250. data/ext/libarchive-0.1.1/libarchive.c +0 -1762
  251. data/ext/libarchive-2.8.4/Makefile.in +0 -7076
  252. data/ext/libarchive-2.8.4/build/autoconf/compile +0 -143
  253. data/ext/libarchive-2.8.4/build/autoconf/config.guess +0 -1502
  254. data/ext/libarchive-2.8.4/build/autoconf/config.sub +0 -1708
  255. data/ext/libarchive-2.8.4/build/autoconf/depcomp +0 -630
  256. data/ext/libarchive-2.8.4/build/autoconf/install-sh +0 -291
  257. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +0 -8406
  258. data/ext/libarchive-2.8.4/build/autoconf/missing +0 -376
  259. data/ext/libarchive-2.8.4/config.h.in +0 -772
  260. data/ext/libarchive-2.8.4/configure +0 -17916
  261. data/ext/libarchive-2.8.4/libarchive/archive.h +0 -741
  262. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +0 -2202
  263. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +0 -281
  264. data/ext/libarchive-2.8.4/libarchive/archive_read.c +0 -1249
  265. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +0 -198
  266. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +0 -570
  267. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +0 -272
  268. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +0 -777
  269. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +0 -1304
  270. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +0 -903
  271. data/ext/libarchive-2.8.4/libarchive/archive_string.c +0 -453
  272. data/ext/libarchive-2.8.4/libarchive/archive_string.h +0 -148
  273. data/ext/libarchive-2.8.4/libarchive/archive_util.c +0 -391
  274. data/ext/libarchive-2.8.4/libarchive/archive_write.c +0 -466
  275. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +0 -2628
  276. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +0 -408
  277. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +0 -477
  278. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +0 -257
  279. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +0 -347
  280. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +0 -438
  281. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +0 -344
  282. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +0 -295
  283. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +0 -1050
  284. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +0 -667
  285. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +0 -154
  286. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +0 -113
  287. data/ext/zlib-1.2.5/Makefile.in +0 -257
  288. data/ext/zlib-1.2.5/configure +0 -596
  289. data/ext/zlib-1.2.5/crc32.c +0 -442
  290. data/ext/zlib-1.2.5/crc32.h +0 -441
  291. data/ext/zlib-1.2.5/example.c +0 -565
  292. data/ext/zlib-1.2.5/gzread.c +0 -653
  293. data/ext/zlib-1.2.5/gzwrite.c +0 -531
  294. data/ext/zlib-1.2.5/minigzip.c +0 -440
  295. data/ext/zlib-1.2.5/uncompr.c +0 -59
@@ -0,0 +1,2732 @@
1
+ /*-
2
+ * Copyright (c) 2003-2009 Tim Kientzle
3
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer
11
+ * in this position and unchanged.
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
+ /* This is the tree-walking code for POSIX systems. */
29
+ #if !defined(_WIN32) || defined(__CYGWIN__)
30
+
31
+ #include "archive_platform.h"
32
+ __FBSDID("$FreeBSD$");
33
+
34
+ #ifdef HAVE_SYS_PARAM_H
35
+ #include <sys/param.h>
36
+ #endif
37
+ #ifdef HAVE_SYS_STAT_H
38
+ #include <sys/stat.h>
39
+ #endif
40
+ #ifdef HAVE_SYS_STATFS_H
41
+ #include <sys/statfs.h>
42
+ #endif
43
+ #ifdef HAVE_SYS_STATVFS_H
44
+ #include <sys/statvfs.h>
45
+ #endif
46
+ #ifdef HAVE_SYS_TIME_H
47
+ #include <sys/time.h>
48
+ #endif
49
+ #ifdef HAVE_LINUX_MAGIC_H
50
+ #include <linux/magic.h>
51
+ #endif
52
+ #ifdef HAVE_LINUX_FS_H
53
+ #include <linux/fs.h>
54
+ #elif HAVE_SYS_MOUNT_H
55
+ #include <sys/mount.h>
56
+ #endif
57
+ /*
58
+ * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
59
+ * As the include guards don't agree, the order of include is important.
60
+ */
61
+ #ifdef HAVE_LINUX_EXT2_FS_H
62
+ #include <linux/ext2_fs.h> /* for Linux file flags */
63
+ #endif
64
+ #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
65
+ #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */
66
+ #endif
67
+ #ifdef HAVE_DIRECT_H
68
+ #include <direct.h>
69
+ #endif
70
+ #ifdef HAVE_DIRENT_H
71
+ #include <dirent.h>
72
+ #endif
73
+ #ifdef HAVE_ERRNO_H
74
+ #include <errno.h>
75
+ #endif
76
+ #ifdef HAVE_FCNTL_H
77
+ #include <fcntl.h>
78
+ #endif
79
+ #ifdef HAVE_LIMITS_H
80
+ #include <limits.h>
81
+ #endif
82
+ #ifdef HAVE_STDLIB_H
83
+ #include <stdlib.h>
84
+ #endif
85
+ #ifdef HAVE_STRING_H
86
+ #include <string.h>
87
+ #endif
88
+ #ifdef HAVE_UNISTD_H
89
+ #include <unistd.h>
90
+ #endif
91
+ #ifdef HAVE_SYS_IOCTL_H
92
+ #include <sys/ioctl.h>
93
+ #endif
94
+
95
+ #include "archive.h"
96
+ #include "archive_string.h"
97
+ #include "archive_entry.h"
98
+ #include "archive_private.h"
99
+ #include "archive_read_disk_private.h"
100
+
101
+ #ifndef HAVE_FCHDIR
102
+ #error fchdir function required.
103
+ #endif
104
+ #ifndef O_BINARY
105
+ #define O_BINARY 0
106
+ #endif
107
+ #ifndef O_CLOEXEC
108
+ #define O_CLOEXEC 0
109
+ #endif
110
+
111
+ #if defined(__hpux) && !defined(HAVE_DIRFD)
112
+ #define dirfd(x) ((x)->__dd_fd)
113
+ #define HAVE_DIRFD
114
+ #endif
115
+
116
+ /*-
117
+ * This is a new directory-walking system that addresses a number
118
+ * of problems I've had with fts(3). In particular, it has no
119
+ * pathname-length limits (other than the size of 'int'), handles
120
+ * deep logical traversals, uses considerably less memory, and has
121
+ * an opaque interface (easier to modify in the future).
122
+ *
123
+ * Internally, it keeps a single list of "tree_entry" items that
124
+ * represent filesystem objects that require further attention.
125
+ * Non-directories are not kept in memory: they are pulled from
126
+ * readdir(), returned to the client, then freed as soon as possible.
127
+ * Any directory entry to be traversed gets pushed onto the stack.
128
+ *
129
+ * There is surprisingly little information that needs to be kept for
130
+ * each item on the stack. Just the name, depth (represented here as the
131
+ * string length of the parent directory's pathname), and some markers
132
+ * indicating how to get back to the parent (via chdir("..") for a
133
+ * regular dir or via fchdir(2) for a symlink).
134
+ */
135
+ /*
136
+ * TODO:
137
+ * 1) Loop checking.
138
+ * 3) Arbitrary logical traversals by closing/reopening intermediate fds.
139
+ */
140
+
141
+ struct restore_time {
142
+ const char *name;
143
+ time_t mtime;
144
+ long mtime_nsec;
145
+ time_t atime;
146
+ long atime_nsec;
147
+ mode_t filetype;
148
+ int noatime;
149
+ };
150
+
151
+ struct tree_entry {
152
+ int depth;
153
+ struct tree_entry *next;
154
+ struct tree_entry *parent;
155
+ struct archive_string name;
156
+ size_t dirname_length;
157
+ int64_t dev;
158
+ int64_t ino;
159
+ int flags;
160
+ int filesystem_id;
161
+ /* How to return back to the parent of a symlink. */
162
+ int symlink_parent_fd;
163
+ /* How to restore time of a directory. */
164
+ struct restore_time restore_time;
165
+ };
166
+
167
+ struct filesystem {
168
+ int64_t dev;
169
+ int synthetic;
170
+ int remote;
171
+ int noatime;
172
+ #if defined(USE_READDIR_R)
173
+ size_t name_max;
174
+ #endif
175
+ long incr_xfer_size;
176
+ long max_xfer_size;
177
+ long min_xfer_size;
178
+ long xfer_align;
179
+
180
+ /*
181
+ * Buffer used for reading file contents.
182
+ */
183
+ /* Exactly allocated memory pointer. */
184
+ unsigned char *allocation_ptr;
185
+ /* Pointer adjusted to the filesystem alignment . */
186
+ unsigned char *buff;
187
+ size_t buff_size;
188
+ };
189
+
190
+ /* Definitions for tree_entry.flags bitmap. */
191
+ #define isDir 1 /* This entry is a regular directory. */
192
+ #define isDirLink 2 /* This entry is a symbolic link to a directory. */
193
+ #define needsFirstVisit 4 /* This is an initial entry. */
194
+ #define needsDescent 8 /* This entry needs to be previsited. */
195
+ #define needsOpen 16 /* This is a directory that needs to be opened. */
196
+ #define needsAscent 32 /* This entry needs to be postvisited. */
197
+
198
+ /*
199
+ * Local data for this package.
200
+ */
201
+ struct tree {
202
+ struct tree_entry *stack;
203
+ struct tree_entry *current;
204
+ DIR *d;
205
+ #define INVALID_DIR_HANDLE NULL
206
+ struct dirent *de;
207
+ #if defined(USE_READDIR_R)
208
+ struct dirent *dirent;
209
+ size_t dirent_allocated;
210
+ #endif
211
+ int flags;
212
+ int visit_type;
213
+ /* Error code from last failed operation. */
214
+ int tree_errno;
215
+
216
+ /* Dynamically-sized buffer for holding path */
217
+ struct archive_string path;
218
+
219
+ /* Last path element */
220
+ const char *basename;
221
+ /* Leading dir length */
222
+ size_t dirname_length;
223
+
224
+ int depth;
225
+ int openCount;
226
+ int maxOpenCount;
227
+ int initial_dir_fd;
228
+ int working_dir_fd;
229
+
230
+ struct stat lst;
231
+ struct stat st;
232
+ int descend;
233
+ int nlink;
234
+ /* How to restore time of a file. */
235
+ struct restore_time restore_time;
236
+
237
+ struct entry_sparse {
238
+ int64_t length;
239
+ int64_t offset;
240
+ } *sparse_list, *current_sparse;
241
+ int sparse_count;
242
+ int sparse_list_size;
243
+
244
+ char initial_symlink_mode;
245
+ char symlink_mode;
246
+ struct filesystem *current_filesystem;
247
+ struct filesystem *filesystem_table;
248
+ int initial_filesystem_id;
249
+ int current_filesystem_id;
250
+ int max_filesystem_id;
251
+ int allocated_filesystem;
252
+
253
+ int entry_fd;
254
+ int entry_eof;
255
+ int64_t entry_remaining_bytes;
256
+ int64_t entry_total;
257
+ unsigned char *entry_buff;
258
+ size_t entry_buff_size;
259
+ };
260
+
261
+ /* Definitions for tree.flags bitmap. */
262
+ #define hasStat 16 /* The st entry is valid. */
263
+ #define hasLstat 32 /* The lst entry is valid. */
264
+ #define onWorkingDir 64 /* We are on the working dir where we are
265
+ * reading directory entry at this time. */
266
+ #define needsRestoreTimes 128
267
+ #define onInitialDir 256 /* We are on the initial dir. */
268
+
269
+ static int
270
+ tree_dir_next_posix(struct tree *t);
271
+
272
+ #ifdef HAVE_DIRENT_D_NAMLEN
273
+ /* BSD extension; avoids need for a strlen() call. */
274
+ #define D_NAMELEN(dp) (dp)->d_namlen
275
+ #else
276
+ #define D_NAMELEN(dp) (strlen((dp)->d_name))
277
+ #endif
278
+
279
+ /* Initiate/terminate a tree traversal. */
280
+ static struct tree *tree_open(const char *, int, int);
281
+ static struct tree *tree_reopen(struct tree *, const char *, int);
282
+ static void tree_close(struct tree *);
283
+ static void tree_free(struct tree *);
284
+ static void tree_push(struct tree *, const char *, int, int64_t, int64_t,
285
+ struct restore_time *);
286
+ static int tree_enter_initial_dir(struct tree *);
287
+ static int tree_enter_working_dir(struct tree *);
288
+ static int tree_current_dir_fd(struct tree *);
289
+
290
+ /*
291
+ * tree_next() returns Zero if there is no next entry, non-zero if
292
+ * there is. Note that directories are visited three times.
293
+ * Directories are always visited first as part of enumerating their
294
+ * parent; that is a "regular" visit. If tree_descend() is invoked at
295
+ * that time, the directory is added to a work list and will
296
+ * subsequently be visited two more times: once just after descending
297
+ * into the directory ("postdescent") and again just after ascending
298
+ * back to the parent ("postascent").
299
+ *
300
+ * TREE_ERROR_DIR is returned if the descent failed (because the
301
+ * directory couldn't be opened, for instance). This is returned
302
+ * instead of TREE_POSTDESCENT/TREE_POSTASCENT. TREE_ERROR_DIR is not a
303
+ * fatal error, but it does imply that the relevant subtree won't be
304
+ * visited. TREE_ERROR_FATAL is returned for an error that left the
305
+ * traversal completely hosed. Right now, this is only returned for
306
+ * chdir() failures during ascent.
307
+ */
308
+ #define TREE_REGULAR 1
309
+ #define TREE_POSTDESCENT 2
310
+ #define TREE_POSTASCENT 3
311
+ #define TREE_ERROR_DIR -1
312
+ #define TREE_ERROR_FATAL -2
313
+
314
+ static int tree_next(struct tree *);
315
+
316
+ /*
317
+ * Return information about the current entry.
318
+ */
319
+
320
+ /*
321
+ * The current full pathname, length of the full pathname, and a name
322
+ * that can be used to access the file. Because tree does use chdir
323
+ * extensively, the access path is almost never the same as the full
324
+ * current path.
325
+ *
326
+ * TODO: On platforms that support it, use openat()-style operations
327
+ * to eliminate the chdir() operations entirely while still supporting
328
+ * arbitrarily deep traversals. This makes access_path troublesome to
329
+ * support, of course, which means we'll need a rich enough interface
330
+ * that clients can function without it. (In particular, we'll need
331
+ * tree_current_open() that returns an open file descriptor.)
332
+ *
333
+ */
334
+ static const char *tree_current_path(struct tree *);
335
+ static const char *tree_current_access_path(struct tree *);
336
+
337
+ /*
338
+ * Request the lstat() or stat() data for the current path. Since the
339
+ * tree package needs to do some of this anyway, and caches the
340
+ * results, you should take advantage of it here if you need it rather
341
+ * than make a redundant stat() or lstat() call of your own.
342
+ */
343
+ static const struct stat *tree_current_stat(struct tree *);
344
+ static const struct stat *tree_current_lstat(struct tree *);
345
+ static int tree_current_is_symblic_link_target(struct tree *);
346
+
347
+ /* The following functions use tricks to avoid a certain number of
348
+ * stat()/lstat() calls. */
349
+ /* "is_physical_dir" is equivalent to S_ISDIR(tree_current_lstat()->st_mode) */
350
+ static int tree_current_is_physical_dir(struct tree *);
351
+ /* "is_dir" is equivalent to S_ISDIR(tree_current_stat()->st_mode) */
352
+ static int tree_current_is_dir(struct tree *);
353
+ static int update_current_filesystem(struct archive_read_disk *a,
354
+ int64_t dev);
355
+ static int setup_current_filesystem(struct archive_read_disk *);
356
+ static int tree_target_is_same_as_parent(struct tree *, const struct stat *);
357
+
358
+ static int _archive_read_disk_open(struct archive *, const char *);
359
+ static int _archive_read_free(struct archive *);
360
+ static int _archive_read_close(struct archive *);
361
+ static int _archive_read_data_block(struct archive *,
362
+ const void **, size_t *, int64_t *);
363
+ static int _archive_read_next_header(struct archive *,
364
+ struct archive_entry **);
365
+ static int _archive_read_next_header2(struct archive *,
366
+ struct archive_entry *);
367
+ static const char *trivial_lookup_gname(void *, int64_t gid);
368
+ static const char *trivial_lookup_uname(void *, int64_t uid);
369
+ static int setup_sparse(struct archive_read_disk *, struct archive_entry *);
370
+ static int close_and_restore_time(int fd, struct tree *,
371
+ struct restore_time *);
372
+ static int open_on_current_dir(struct tree *, const char *, int);
373
+ static int tree_dup(int);
374
+
375
+
376
+ static const struct archive_vtable
377
+ archive_read_disk_vtable = {
378
+ .archive_free = _archive_read_free,
379
+ .archive_close = _archive_read_close,
380
+ .archive_read_data_block = _archive_read_data_block,
381
+ .archive_read_next_header = _archive_read_next_header,
382
+ .archive_read_next_header2 = _archive_read_next_header2,
383
+ };
384
+
385
+ const char *
386
+ archive_read_disk_gname(struct archive *_a, la_int64_t gid)
387
+ {
388
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
389
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
390
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
391
+ return (NULL);
392
+ if (a->lookup_gname == NULL)
393
+ return (NULL);
394
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
395
+ }
396
+
397
+ const char *
398
+ archive_read_disk_uname(struct archive *_a, la_int64_t uid)
399
+ {
400
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
401
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
402
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
403
+ return (NULL);
404
+ if (a->lookup_uname == NULL)
405
+ return (NULL);
406
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
407
+ }
408
+
409
+ int
410
+ archive_read_disk_set_gname_lookup(struct archive *_a,
411
+ void *private_data,
412
+ const char * (*lookup_gname)(void *private, la_int64_t gid),
413
+ void (*cleanup_gname)(void *private))
414
+ {
415
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
416
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
417
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
418
+
419
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
420
+ (a->cleanup_gname)(a->lookup_gname_data);
421
+
422
+ a->lookup_gname = lookup_gname;
423
+ a->cleanup_gname = cleanup_gname;
424
+ a->lookup_gname_data = private_data;
425
+ return (ARCHIVE_OK);
426
+ }
427
+
428
+ int
429
+ archive_read_disk_set_uname_lookup(struct archive *_a,
430
+ void *private_data,
431
+ const char * (*lookup_uname)(void *private, la_int64_t uid),
432
+ void (*cleanup_uname)(void *private))
433
+ {
434
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
435
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
436
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
437
+
438
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
439
+ (a->cleanup_uname)(a->lookup_uname_data);
440
+
441
+ a->lookup_uname = lookup_uname;
442
+ a->cleanup_uname = cleanup_uname;
443
+ a->lookup_uname_data = private_data;
444
+ return (ARCHIVE_OK);
445
+ }
446
+
447
+ /*
448
+ * Create a new archive_read_disk object and initialize it with global state.
449
+ */
450
+ struct archive *
451
+ archive_read_disk_new(void)
452
+ {
453
+ struct archive_read_disk *a;
454
+
455
+ a = (struct archive_read_disk *)calloc(1, sizeof(*a));
456
+ if (a == NULL)
457
+ return (NULL);
458
+ a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
459
+ a->archive.state = ARCHIVE_STATE_NEW;
460
+ a->archive.vtable = &archive_read_disk_vtable;
461
+ a->entry = archive_entry_new2(&a->archive);
462
+ a->lookup_uname = trivial_lookup_uname;
463
+ a->lookup_gname = trivial_lookup_gname;
464
+ a->flags = ARCHIVE_READDISK_MAC_COPYFILE;
465
+ a->open_on_current_dir = open_on_current_dir;
466
+ a->tree_current_dir_fd = tree_current_dir_fd;
467
+ a->tree_enter_working_dir = tree_enter_working_dir;
468
+ return (&a->archive);
469
+ }
470
+
471
+ static int
472
+ _archive_read_free(struct archive *_a)
473
+ {
474
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
475
+ int r;
476
+
477
+ if (_a == NULL)
478
+ return (ARCHIVE_OK);
479
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
480
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
481
+
482
+ if (a->archive.state != ARCHIVE_STATE_CLOSED)
483
+ r = _archive_read_close(&a->archive);
484
+ else
485
+ r = ARCHIVE_OK;
486
+
487
+ tree_free(a->tree);
488
+ if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
489
+ (a->cleanup_gname)(a->lookup_gname_data);
490
+ if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
491
+ (a->cleanup_uname)(a->lookup_uname_data);
492
+ archive_string_free(&a->archive.error_string);
493
+ archive_entry_free(a->entry);
494
+ a->archive.magic = 0;
495
+ __archive_clean(&a->archive);
496
+ free(a);
497
+ return (r);
498
+ }
499
+
500
+ static int
501
+ _archive_read_close(struct archive *_a)
502
+ {
503
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
504
+
505
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
506
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
507
+
508
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
509
+ a->archive.state = ARCHIVE_STATE_CLOSED;
510
+
511
+ tree_close(a->tree);
512
+
513
+ return (ARCHIVE_OK);
514
+ }
515
+
516
+ static void
517
+ setup_symlink_mode(struct archive_read_disk *a, char symlink_mode,
518
+ int follow_symlinks)
519
+ {
520
+ a->symlink_mode = symlink_mode;
521
+ a->follow_symlinks = follow_symlinks;
522
+ if (a->tree != NULL) {
523
+ a->tree->initial_symlink_mode = a->symlink_mode;
524
+ a->tree->symlink_mode = a->symlink_mode;
525
+ }
526
+ }
527
+
528
+ int
529
+ archive_read_disk_set_symlink_logical(struct archive *_a)
530
+ {
531
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
532
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
533
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
534
+ setup_symlink_mode(a, 'L', 1);
535
+ return (ARCHIVE_OK);
536
+ }
537
+
538
+ int
539
+ archive_read_disk_set_symlink_physical(struct archive *_a)
540
+ {
541
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
542
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
543
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
544
+ setup_symlink_mode(a, 'P', 0);
545
+ return (ARCHIVE_OK);
546
+ }
547
+
548
+ int
549
+ archive_read_disk_set_symlink_hybrid(struct archive *_a)
550
+ {
551
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
552
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
553
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
554
+ setup_symlink_mode(a, 'H', 1);/* Follow symlinks initially. */
555
+ return (ARCHIVE_OK);
556
+ }
557
+
558
+ int
559
+ archive_read_disk_set_atime_restored(struct archive *_a)
560
+ {
561
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
562
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
563
+ ARCHIVE_STATE_ANY, "archive_read_disk_restore_atime");
564
+ #ifdef HAVE_UTIMES
565
+ a->flags |= ARCHIVE_READDISK_RESTORE_ATIME;
566
+ if (a->tree != NULL)
567
+ a->tree->flags |= needsRestoreTimes;
568
+ return (ARCHIVE_OK);
569
+ #else
570
+ /* Display warning and unset flag */
571
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
572
+ "Cannot restore access time on this system");
573
+ a->flags &= ~ARCHIVE_READDISK_RESTORE_ATIME;
574
+ return (ARCHIVE_WARN);
575
+ #endif
576
+ }
577
+
578
+ int
579
+ archive_read_disk_set_behavior(struct archive *_a, int flags)
580
+ {
581
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
582
+ int r = ARCHIVE_OK;
583
+
584
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
585
+ ARCHIVE_STATE_ANY, "archive_read_disk_honor_nodump");
586
+
587
+ a->flags = flags;
588
+
589
+ if (flags & ARCHIVE_READDISK_RESTORE_ATIME)
590
+ r = archive_read_disk_set_atime_restored(_a);
591
+ else {
592
+ if (a->tree != NULL)
593
+ a->tree->flags &= ~needsRestoreTimes;
594
+ }
595
+ return (r);
596
+ }
597
+
598
+ /*
599
+ * Trivial implementations of gname/uname lookup functions.
600
+ * These are normally overridden by the client, but these stub
601
+ * versions ensure that we always have something that works.
602
+ */
603
+ static const char *
604
+ trivial_lookup_gname(void *private_data, int64_t gid)
605
+ {
606
+ (void)private_data; /* UNUSED */
607
+ (void)gid; /* UNUSED */
608
+ return (NULL);
609
+ }
610
+
611
+ static const char *
612
+ trivial_lookup_uname(void *private_data, int64_t uid)
613
+ {
614
+ (void)private_data; /* UNUSED */
615
+ (void)uid; /* UNUSED */
616
+ return (NULL);
617
+ }
618
+
619
+ /*
620
+ * Allocate memory for the reading buffer adjusted to the filesystem
621
+ * alignment.
622
+ */
623
+ static int
624
+ setup_suitable_read_buffer(struct archive_read_disk *a)
625
+ {
626
+ struct tree *t = a->tree;
627
+ struct filesystem *cf = t->current_filesystem;
628
+ size_t asize;
629
+ size_t s;
630
+
631
+ if (cf->allocation_ptr == NULL) {
632
+ /* If we couldn't get a filesystem alignment,
633
+ * we use 4096 as default value but we won't use
634
+ * O_DIRECT to open() and openat() operations. */
635
+ long xfer_align = (cf->xfer_align == -1)?4096:cf->xfer_align;
636
+
637
+ if (cf->max_xfer_size != -1)
638
+ asize = cf->max_xfer_size + xfer_align;
639
+ else {
640
+ long incr = cf->incr_xfer_size;
641
+ /* Some platform does not set a proper value to
642
+ * incr_xfer_size.*/
643
+ if (incr < 0)
644
+ incr = cf->min_xfer_size;
645
+ if (cf->min_xfer_size < 0) {
646
+ incr = xfer_align;
647
+ asize = xfer_align;
648
+ } else
649
+ asize = cf->min_xfer_size;
650
+
651
+ /* Increase a buffer size up to 64K bytes in
652
+ * a proper increment size. */
653
+ while (asize < 1024*64)
654
+ asize += incr;
655
+ /* Take a margin to adjust to the filesystem
656
+ * alignment. */
657
+ asize += xfer_align;
658
+ }
659
+ cf->allocation_ptr = malloc(asize);
660
+ if (cf->allocation_ptr == NULL) {
661
+ archive_set_error(&a->archive, ENOMEM,
662
+ "Couldn't allocate memory");
663
+ a->archive.state = ARCHIVE_STATE_FATAL;
664
+ return (ARCHIVE_FATAL);
665
+ }
666
+
667
+ /*
668
+ * Calculate proper address for the filesystem.
669
+ */
670
+ s = (uintptr_t)cf->allocation_ptr;
671
+ s %= xfer_align;
672
+ if (s > 0)
673
+ s = xfer_align - s;
674
+
675
+ /*
676
+ * Set a read buffer pointer in the proper alignment of
677
+ * the current filesystem.
678
+ */
679
+ cf->buff = cf->allocation_ptr + s;
680
+ cf->buff_size = asize - xfer_align;
681
+ }
682
+ return (ARCHIVE_OK);
683
+ }
684
+
685
+ static int
686
+ _archive_read_data_block(struct archive *_a, const void **buff,
687
+ size_t *size, int64_t *offset)
688
+ {
689
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
690
+ struct tree *t = a->tree;
691
+ int r;
692
+ ssize_t bytes;
693
+ int64_t sparse_bytes;
694
+ size_t buffbytes;
695
+ int empty_sparse_region = 0;
696
+
697
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
698
+ "archive_read_data_block");
699
+
700
+ if (t->entry_eof || t->entry_remaining_bytes <= 0) {
701
+ r = ARCHIVE_EOF;
702
+ goto abort_read_data;
703
+ }
704
+
705
+ /*
706
+ * Open the current file.
707
+ */
708
+ if (t->entry_fd < 0) {
709
+ int flags = O_RDONLY | O_BINARY | O_CLOEXEC;
710
+
711
+ /*
712
+ * Eliminate or reduce cache effects if we can.
713
+ *
714
+ * Carefully consider this to be enabled.
715
+ */
716
+ #if defined(O_DIRECT) && 0/* Disabled for now */
717
+ if (t->current_filesystem->xfer_align != -1 &&
718
+ t->nlink == 1)
719
+ flags |= O_DIRECT;
720
+ #endif
721
+ #if defined(O_NOATIME)
722
+ /*
723
+ * Linux has O_NOATIME flag; use it if we need.
724
+ */
725
+ if ((t->flags & needsRestoreTimes) != 0 &&
726
+ t->restore_time.noatime == 0)
727
+ flags |= O_NOATIME;
728
+ #endif
729
+ t->entry_fd = open_on_current_dir(t,
730
+ tree_current_access_path(t), flags);
731
+ __archive_ensure_cloexec_flag(t->entry_fd);
732
+ #if defined(O_NOATIME)
733
+ /*
734
+ * When we did open the file with O_NOATIME flag,
735
+ * if successful, set 1 to t->restore_time.noatime
736
+ * not to restore an atime of the file later.
737
+ * if failed by EPERM, retry it without O_NOATIME flag.
738
+ */
739
+ if (flags & O_NOATIME) {
740
+ if (t->entry_fd >= 0)
741
+ t->restore_time.noatime = 1;
742
+ else if (errno == EPERM)
743
+ flags &= ~O_NOATIME;
744
+ }
745
+ #endif
746
+ if (t->entry_fd < 0) {
747
+ archive_set_error(&a->archive, errno,
748
+ "Couldn't open %s", tree_current_path(t));
749
+ r = ARCHIVE_FAILED;
750
+ tree_enter_initial_dir(t);
751
+ goto abort_read_data;
752
+ }
753
+ tree_enter_initial_dir(t);
754
+ }
755
+
756
+ /*
757
+ * Allocate read buffer if not allocated.
758
+ */
759
+ if (t->current_filesystem->allocation_ptr == NULL) {
760
+ r = setup_suitable_read_buffer(a);
761
+ if (r != ARCHIVE_OK) {
762
+ a->archive.state = ARCHIVE_STATE_FATAL;
763
+ goto abort_read_data;
764
+ }
765
+ }
766
+ t->entry_buff = t->current_filesystem->buff;
767
+ t->entry_buff_size = t->current_filesystem->buff_size;
768
+
769
+ buffbytes = t->entry_buff_size;
770
+ if ((int64_t)buffbytes > t->current_sparse->length)
771
+ buffbytes = t->current_sparse->length;
772
+
773
+ if (t->current_sparse->length == 0)
774
+ empty_sparse_region = 1;
775
+
776
+ /*
777
+ * Skip hole.
778
+ * TODO: Should we consider t->current_filesystem->xfer_align?
779
+ */
780
+ if (t->current_sparse->offset > t->entry_total) {
781
+ if (lseek(t->entry_fd,
782
+ (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
783
+ archive_set_error(&a->archive, errno, "Seek error");
784
+ r = ARCHIVE_FATAL;
785
+ a->archive.state = ARCHIVE_STATE_FATAL;
786
+ goto abort_read_data;
787
+ }
788
+ sparse_bytes = t->current_sparse->offset - t->entry_total;
789
+ t->entry_remaining_bytes -= sparse_bytes;
790
+ t->entry_total += sparse_bytes;
791
+ }
792
+
793
+ /*
794
+ * Read file contents.
795
+ */
796
+ if (buffbytes > 0) {
797
+ bytes = read(t->entry_fd, t->entry_buff, buffbytes);
798
+ if (bytes < 0) {
799
+ archive_set_error(&a->archive, errno, "Read error");
800
+ r = ARCHIVE_FATAL;
801
+ a->archive.state = ARCHIVE_STATE_FATAL;
802
+ goto abort_read_data;
803
+ }
804
+ } else
805
+ bytes = 0;
806
+ /*
807
+ * Return an EOF unless we've read a leading empty sparse region, which
808
+ * is used to represent fully-sparse files.
809
+ */
810
+ if (bytes == 0 && !empty_sparse_region) {
811
+ /* Get EOF */
812
+ t->entry_eof = 1;
813
+ r = ARCHIVE_EOF;
814
+ goto abort_read_data;
815
+ }
816
+ *buff = t->entry_buff;
817
+ *size = bytes;
818
+ *offset = t->entry_total;
819
+ t->entry_total += bytes;
820
+ t->entry_remaining_bytes -= bytes;
821
+ if (t->entry_remaining_bytes == 0) {
822
+ /* Close the current file descriptor */
823
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
824
+ t->entry_fd = -1;
825
+ t->entry_eof = 1;
826
+ }
827
+ t->current_sparse->offset += bytes;
828
+ t->current_sparse->length -= bytes;
829
+ if (t->current_sparse->length == 0 && !t->entry_eof)
830
+ t->current_sparse++;
831
+ return (ARCHIVE_OK);
832
+
833
+ abort_read_data:
834
+ *buff = NULL;
835
+ *size = 0;
836
+ *offset = t->entry_total;
837
+ if (t->entry_fd >= 0) {
838
+ /* Close the current file descriptor */
839
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
840
+ t->entry_fd = -1;
841
+ }
842
+ return (r);
843
+ }
844
+
845
+ static int
846
+ next_entry(struct archive_read_disk *a, struct tree *t,
847
+ struct archive_entry *entry)
848
+ {
849
+ const struct stat *st; /* info to use for this entry */
850
+ const struct stat *lst;/* lstat() information */
851
+ const char *name;
852
+ int delayed, delayed_errno, descend, r;
853
+ struct archive_string delayed_str;
854
+
855
+ delayed = ARCHIVE_OK;
856
+ delayed_errno = 0;
857
+ archive_string_init(&delayed_str);
858
+
859
+ st = NULL;
860
+ lst = NULL;
861
+ t->descend = 0;
862
+ do {
863
+ switch (tree_next(t)) {
864
+ case TREE_ERROR_FATAL:
865
+ archive_set_error(&a->archive, t->tree_errno,
866
+ "%s: Unable to continue traversing directory tree",
867
+ tree_current_path(t));
868
+ a->archive.state = ARCHIVE_STATE_FATAL;
869
+ tree_enter_initial_dir(t);
870
+ return (ARCHIVE_FATAL);
871
+ case TREE_ERROR_DIR:
872
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
873
+ "%s: Couldn't visit directory",
874
+ tree_current_path(t));
875
+ tree_enter_initial_dir(t);
876
+ return (ARCHIVE_FAILED);
877
+ case 0:
878
+ tree_enter_initial_dir(t);
879
+ return (ARCHIVE_EOF);
880
+ case TREE_POSTDESCENT:
881
+ case TREE_POSTASCENT:
882
+ break;
883
+ case TREE_REGULAR:
884
+ lst = tree_current_lstat(t);
885
+ if (lst == NULL) {
886
+ if (errno == ENOENT && t->depth > 0) {
887
+ delayed = ARCHIVE_WARN;
888
+ delayed_errno = errno;
889
+ if (delayed_str.length == 0) {
890
+ archive_string_sprintf(&delayed_str,
891
+ "%s", tree_current_path(t));
892
+ } else {
893
+ archive_string_sprintf(&delayed_str,
894
+ " %s", tree_current_path(t));
895
+ }
896
+ } else {
897
+ archive_set_error(&a->archive, errno,
898
+ "%s: Cannot stat",
899
+ tree_current_path(t));
900
+ tree_enter_initial_dir(t);
901
+ return (ARCHIVE_FAILED);
902
+ }
903
+ }
904
+ break;
905
+ }
906
+ } while (lst == NULL);
907
+
908
+ #ifdef __APPLE__
909
+ if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) {
910
+ /* If we're using copyfile(), ignore "._XXX" files. */
911
+ const char *bname = strrchr(tree_current_path(t), '/');
912
+ if (bname == NULL)
913
+ bname = tree_current_path(t);
914
+ else
915
+ ++bname;
916
+ if (bname[0] == '.' && bname[1] == '_')
917
+ return (ARCHIVE_RETRY);
918
+ }
919
+ #endif
920
+
921
+ archive_entry_copy_pathname(entry, tree_current_path(t));
922
+ /*
923
+ * Perform path matching.
924
+ */
925
+ if (a->matching) {
926
+ r = archive_match_path_excluded(a->matching, entry);
927
+ if (r < 0) {
928
+ archive_set_error(&(a->archive), errno,
929
+ "Failed : %s", archive_error_string(a->matching));
930
+ return (r);
931
+ }
932
+ if (r) {
933
+ if (a->excluded_cb_func)
934
+ a->excluded_cb_func(&(a->archive),
935
+ a->excluded_cb_data, entry);
936
+ return (ARCHIVE_RETRY);
937
+ }
938
+ }
939
+
940
+ /*
941
+ * Distinguish 'L'/'P'/'H' symlink following.
942
+ */
943
+ switch(t->symlink_mode) {
944
+ case 'H':
945
+ /* 'H': After the first item, rest like 'P'. */
946
+ t->symlink_mode = 'P';
947
+ /* 'H': First item (from command line) like 'L'. */
948
+ /* FALLTHROUGH */
949
+ case 'L':
950
+ /* 'L': Do descend through a symlink to dir. */
951
+ descend = tree_current_is_dir(t);
952
+ /* 'L': Follow symlinks to files. */
953
+ a->symlink_mode = 'L';
954
+ a->follow_symlinks = 1;
955
+ /* 'L': Archive symlinks as targets, if we can. */
956
+ st = tree_current_stat(t);
957
+ if (st != NULL && !tree_target_is_same_as_parent(t, st))
958
+ break;
959
+ /* If stat fails, we have a broken symlink;
960
+ * in that case, don't follow the link. */
961
+ /* FALLTHROUGH */
962
+ default:
963
+ /* 'P': Don't descend through a symlink to dir. */
964
+ descend = tree_current_is_physical_dir(t);
965
+ /* 'P': Don't follow symlinks to files. */
966
+ a->symlink_mode = 'P';
967
+ a->follow_symlinks = 0;
968
+ /* 'P': Archive symlinks as symlinks. */
969
+ st = lst;
970
+ break;
971
+ }
972
+
973
+ if (update_current_filesystem(a, st->st_dev) != ARCHIVE_OK) {
974
+ a->archive.state = ARCHIVE_STATE_FATAL;
975
+ tree_enter_initial_dir(t);
976
+ return (ARCHIVE_FATAL);
977
+ }
978
+ if (t->initial_filesystem_id == -1)
979
+ t->initial_filesystem_id = t->current_filesystem_id;
980
+ if (a->flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) {
981
+ if (t->initial_filesystem_id != t->current_filesystem_id)
982
+ descend = 0;
983
+ }
984
+ t->descend = descend;
985
+
986
+ /*
987
+ * Honor nodump flag.
988
+ * If the file is marked with nodump flag, do not return this entry.
989
+ */
990
+ if (a->flags & ARCHIVE_READDISK_HONOR_NODUMP) {
991
+ #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP)
992
+ if (st->st_flags & UF_NODUMP)
993
+ return (ARCHIVE_RETRY);
994
+ #elif (defined(FS_IOC_GETFLAGS) && defined(FS_NODUMP_FL) && \
995
+ defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \
996
+ (defined(EXT2_IOC_GETFLAGS) && defined(EXT2_NODUMP_FL) && \
997
+ defined(HAVE_WORKING_EXT2_IOC_GETFLAGS))
998
+ if (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode)) {
999
+ int stflags;
1000
+
1001
+ t->entry_fd = open_on_current_dir(t,
1002
+ tree_current_access_path(t),
1003
+ O_RDONLY | O_NONBLOCK | O_CLOEXEC);
1004
+ __archive_ensure_cloexec_flag(t->entry_fd);
1005
+ if (t->entry_fd >= 0) {
1006
+ r = ioctl(t->entry_fd,
1007
+ #ifdef FS_IOC_GETFLAGS
1008
+ FS_IOC_GETFLAGS,
1009
+ #else
1010
+ EXT2_IOC_GETFLAGS,
1011
+ #endif
1012
+ &stflags);
1013
+ #ifdef FS_NODUMP_FL
1014
+ if (r == 0 && (stflags & FS_NODUMP_FL) != 0)
1015
+ #else
1016
+ if (r == 0 && (stflags & EXT2_NODUMP_FL) != 0)
1017
+ #endif
1018
+ return (ARCHIVE_RETRY);
1019
+ }
1020
+ }
1021
+ #endif
1022
+ }
1023
+
1024
+ archive_entry_copy_stat(entry, st);
1025
+
1026
+ /* Save the times to be restored. This must be in before
1027
+ * calling archive_read_disk_descend() or any chance of it,
1028
+ * especially, invoking a callback. */
1029
+ t->restore_time.mtime = archive_entry_mtime(entry);
1030
+ t->restore_time.mtime_nsec = archive_entry_mtime_nsec(entry);
1031
+ t->restore_time.atime = archive_entry_atime(entry);
1032
+ t->restore_time.atime_nsec = archive_entry_atime_nsec(entry);
1033
+ t->restore_time.filetype = archive_entry_filetype(entry);
1034
+ t->restore_time.noatime = t->current_filesystem->noatime;
1035
+
1036
+ /*
1037
+ * Perform time matching.
1038
+ */
1039
+ if (a->matching) {
1040
+ r = archive_match_time_excluded(a->matching, entry);
1041
+ if (r < 0) {
1042
+ archive_set_error(&(a->archive), errno,
1043
+ "Failed : %s", archive_error_string(a->matching));
1044
+ return (r);
1045
+ }
1046
+ if (r) {
1047
+ if (a->excluded_cb_func)
1048
+ a->excluded_cb_func(&(a->archive),
1049
+ a->excluded_cb_data, entry);
1050
+ return (ARCHIVE_RETRY);
1051
+ }
1052
+ }
1053
+
1054
+ /* Lookup uname/gname */
1055
+ name = archive_read_disk_uname(&(a->archive), archive_entry_uid(entry));
1056
+ if (name != NULL)
1057
+ archive_entry_copy_uname(entry, name);
1058
+ name = archive_read_disk_gname(&(a->archive), archive_entry_gid(entry));
1059
+ if (name != NULL)
1060
+ archive_entry_copy_gname(entry, name);
1061
+
1062
+ /*
1063
+ * Perform owner matching.
1064
+ */
1065
+ if (a->matching) {
1066
+ r = archive_match_owner_excluded(a->matching, entry);
1067
+ if (r < 0) {
1068
+ archive_set_error(&(a->archive), errno,
1069
+ "Failed : %s", archive_error_string(a->matching));
1070
+ return (r);
1071
+ }
1072
+ if (r) {
1073
+ if (a->excluded_cb_func)
1074
+ a->excluded_cb_func(&(a->archive),
1075
+ a->excluded_cb_data, entry);
1076
+ return (ARCHIVE_RETRY);
1077
+ }
1078
+ }
1079
+
1080
+ /*
1081
+ * Invoke a meta data filter callback.
1082
+ */
1083
+ if (a->metadata_filter_func) {
1084
+ if (!a->metadata_filter_func(&(a->archive),
1085
+ a->metadata_filter_data, entry))
1086
+ return (ARCHIVE_RETRY);
1087
+ }
1088
+
1089
+ /*
1090
+ * Populate the archive_entry with metadata from the disk.
1091
+ */
1092
+ archive_entry_copy_sourcepath(entry, tree_current_access_path(t));
1093
+ r = archive_read_disk_entry_from_file(&(a->archive), entry,
1094
+ t->entry_fd, st);
1095
+
1096
+ if (r == ARCHIVE_OK) {
1097
+ r = delayed;
1098
+ if (r != ARCHIVE_OK) {
1099
+ archive_string_sprintf(&delayed_str, ": %s",
1100
+ "File removed before we read it");
1101
+ archive_set_error(&(a->archive), delayed_errno,
1102
+ "%s", delayed_str.s);
1103
+ }
1104
+ }
1105
+ archive_string_free(&delayed_str);
1106
+
1107
+ return (r);
1108
+ }
1109
+
1110
+ static int
1111
+ _archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
1112
+ {
1113
+ int ret;
1114
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1115
+ *entryp = NULL;
1116
+ ret = _archive_read_next_header2(_a, a->entry);
1117
+ *entryp = a->entry;
1118
+ return ret;
1119
+ }
1120
+
1121
+ static int
1122
+ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
1123
+ {
1124
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1125
+ struct tree *t;
1126
+ int r;
1127
+
1128
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1129
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1130
+ "archive_read_next_header2");
1131
+
1132
+ t = a->tree;
1133
+ if (t->entry_fd >= 0) {
1134
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
1135
+ t->entry_fd = -1;
1136
+ }
1137
+
1138
+ archive_entry_clear(entry);
1139
+
1140
+ for (;;) {
1141
+ r = next_entry(a, t, entry);
1142
+ if (t->entry_fd >= 0) {
1143
+ close(t->entry_fd);
1144
+ t->entry_fd = -1;
1145
+ }
1146
+
1147
+ if (r == ARCHIVE_RETRY) {
1148
+ archive_entry_clear(entry);
1149
+ continue;
1150
+ }
1151
+ break;
1152
+ }
1153
+
1154
+ /* Return to the initial directory. */
1155
+ tree_enter_initial_dir(t);
1156
+
1157
+ /*
1158
+ * EOF and FATAL are persistent at this layer. By
1159
+ * modifying the state, we guarantee that future calls to
1160
+ * read a header or read data will fail.
1161
+ */
1162
+ switch (r) {
1163
+ case ARCHIVE_EOF:
1164
+ a->archive.state = ARCHIVE_STATE_EOF;
1165
+ break;
1166
+ case ARCHIVE_OK:
1167
+ case ARCHIVE_WARN:
1168
+ /* Overwrite the sourcepath based on the initial directory. */
1169
+ archive_entry_copy_sourcepath(entry, tree_current_path(t));
1170
+ t->entry_total = 0;
1171
+ if (archive_entry_filetype(entry) == AE_IFREG) {
1172
+ t->nlink = archive_entry_nlink(entry);
1173
+ t->entry_remaining_bytes = archive_entry_size(entry);
1174
+ t->entry_eof = (t->entry_remaining_bytes == 0)? 1: 0;
1175
+ if (!t->entry_eof &&
1176
+ setup_sparse(a, entry) != ARCHIVE_OK)
1177
+ return (ARCHIVE_FATAL);
1178
+ } else {
1179
+ t->entry_remaining_bytes = 0;
1180
+ t->entry_eof = 1;
1181
+ }
1182
+ a->archive.state = ARCHIVE_STATE_DATA;
1183
+ break;
1184
+ case ARCHIVE_RETRY:
1185
+ break;
1186
+ case ARCHIVE_FATAL:
1187
+ a->archive.state = ARCHIVE_STATE_FATAL;
1188
+ break;
1189
+ }
1190
+
1191
+ __archive_reset_read_data(&a->archive);
1192
+ return (r);
1193
+ }
1194
+
1195
+ static int
1196
+ setup_sparse(struct archive_read_disk *a, struct archive_entry *entry)
1197
+ {
1198
+ struct tree *t = a->tree;
1199
+ int64_t length, offset;
1200
+ int i;
1201
+
1202
+ t->sparse_count = archive_entry_sparse_reset(entry);
1203
+ if (t->sparse_count+1 > t->sparse_list_size) {
1204
+ free(t->sparse_list);
1205
+ t->sparse_list_size = t->sparse_count + 1;
1206
+ t->sparse_list = malloc(sizeof(t->sparse_list[0]) *
1207
+ t->sparse_list_size);
1208
+ if (t->sparse_list == NULL) {
1209
+ t->sparse_list_size = 0;
1210
+ archive_set_error(&a->archive, ENOMEM,
1211
+ "Can't allocate data");
1212
+ a->archive.state = ARCHIVE_STATE_FATAL;
1213
+ return (ARCHIVE_FATAL);
1214
+ }
1215
+ }
1216
+ for (i = 0; i < t->sparse_count; i++) {
1217
+ archive_entry_sparse_next(entry, &offset, &length);
1218
+ t->sparse_list[i].offset = offset;
1219
+ t->sparse_list[i].length = length;
1220
+ }
1221
+ if (i == 0) {
1222
+ t->sparse_list[i].offset = 0;
1223
+ t->sparse_list[i].length = archive_entry_size(entry);
1224
+ } else {
1225
+ t->sparse_list[i].offset = archive_entry_size(entry);
1226
+ t->sparse_list[i].length = 0;
1227
+ }
1228
+ t->current_sparse = t->sparse_list;
1229
+
1230
+ return (ARCHIVE_OK);
1231
+ }
1232
+
1233
+ int
1234
+ archive_read_disk_set_matching(struct archive *_a, struct archive *_ma,
1235
+ void (*_excluded_func)(struct archive *, void *, struct archive_entry *),
1236
+ void *_client_data)
1237
+ {
1238
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1239
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1240
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_matching");
1241
+ a->matching = _ma;
1242
+ a->excluded_cb_func = _excluded_func;
1243
+ a->excluded_cb_data = _client_data;
1244
+ return (ARCHIVE_OK);
1245
+ }
1246
+
1247
+ int
1248
+ archive_read_disk_set_metadata_filter_callback(struct archive *_a,
1249
+ int (*_metadata_filter_func)(struct archive *, void *,
1250
+ struct archive_entry *), void *_client_data)
1251
+ {
1252
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1253
+
1254
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY,
1255
+ "archive_read_disk_set_metadata_filter_callback");
1256
+
1257
+ a->metadata_filter_func = _metadata_filter_func;
1258
+ a->metadata_filter_data = _client_data;
1259
+ return (ARCHIVE_OK);
1260
+ }
1261
+
1262
+ int
1263
+ archive_read_disk_can_descend(struct archive *_a)
1264
+ {
1265
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1266
+ struct tree *t = a->tree;
1267
+
1268
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1269
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1270
+ "archive_read_disk_can_descend");
1271
+
1272
+ return (t->visit_type == TREE_REGULAR && t->descend);
1273
+ }
1274
+
1275
+ /*
1276
+ * Called by the client to mark the directory just returned from
1277
+ * tree_next() as needing to be visited.
1278
+ */
1279
+ int
1280
+ archive_read_disk_descend(struct archive *_a)
1281
+ {
1282
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1283
+ struct tree *t = a->tree;
1284
+
1285
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1286
+ ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1287
+ "archive_read_disk_descend");
1288
+
1289
+ if (!archive_read_disk_can_descend(_a))
1290
+ return (ARCHIVE_OK);
1291
+
1292
+ /*
1293
+ * We must not treat the initial specified path as a physical dir,
1294
+ * because if we do then we will try and ascend out of it by opening
1295
+ * ".." which is (a) wrong and (b) causes spurious permissions errors
1296
+ * if ".." is not readable by us. Instead, treat it as if it were a
1297
+ * symlink. (This uses an extra fd, but it can only happen once at the
1298
+ * top level of a traverse.) But we can't necessarily assume t->st is
1299
+ * valid here (though t->lst is), which complicates the logic a
1300
+ * little.
1301
+ */
1302
+ if (tree_current_is_physical_dir(t)) {
1303
+ tree_push(t, t->basename, t->current_filesystem_id,
1304
+ t->lst.st_dev, t->lst.st_ino, &t->restore_time);
1305
+ if (t->stack->parent->parent != NULL)
1306
+ t->stack->flags |= isDir;
1307
+ else
1308
+ t->stack->flags |= isDirLink;
1309
+ } else if (tree_current_is_dir(t)) {
1310
+ tree_push(t, t->basename, t->current_filesystem_id,
1311
+ t->st.st_dev, t->st.st_ino, &t->restore_time);
1312
+ t->stack->flags |= isDirLink;
1313
+ }
1314
+ t->descend = 0;
1315
+ return (ARCHIVE_OK);
1316
+ }
1317
+
1318
+ int
1319
+ archive_read_disk_open(struct archive *_a, const char *pathname)
1320
+ {
1321
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1322
+
1323
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1324
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1325
+ "archive_read_disk_open");
1326
+ archive_clear_error(&a->archive);
1327
+
1328
+ return (_archive_read_disk_open(_a, pathname));
1329
+ }
1330
+
1331
+ int
1332
+ archive_read_disk_open_w(struct archive *_a, const wchar_t *pathname)
1333
+ {
1334
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1335
+ struct archive_string path;
1336
+ int ret;
1337
+
1338
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
1339
+ ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED,
1340
+ "archive_read_disk_open_w");
1341
+ archive_clear_error(&a->archive);
1342
+
1343
+ /* Make a char string from a wchar_t string. */
1344
+ archive_string_init(&path);
1345
+ if (archive_string_append_from_wcs(&path, pathname,
1346
+ wcslen(pathname)) != 0) {
1347
+ if (errno == ENOMEM)
1348
+ archive_set_error(&a->archive, ENOMEM,
1349
+ "Can't allocate memory");
1350
+ else
1351
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1352
+ "Can't convert a path to a char string");
1353
+ a->archive.state = ARCHIVE_STATE_FATAL;
1354
+ ret = ARCHIVE_FATAL;
1355
+ } else
1356
+ ret = _archive_read_disk_open(_a, path.s);
1357
+
1358
+ archive_string_free(&path);
1359
+ return (ret);
1360
+ }
1361
+
1362
+ static int
1363
+ _archive_read_disk_open(struct archive *_a, const char *pathname)
1364
+ {
1365
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1366
+
1367
+ if (a->tree != NULL)
1368
+ a->tree = tree_reopen(a->tree, pathname,
1369
+ a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
1370
+ else
1371
+ a->tree = tree_open(pathname, a->symlink_mode,
1372
+ a->flags & ARCHIVE_READDISK_RESTORE_ATIME);
1373
+ if (a->tree == NULL) {
1374
+ archive_set_error(&a->archive, ENOMEM,
1375
+ "Can't allocate tar data");
1376
+ a->archive.state = ARCHIVE_STATE_FATAL;
1377
+ return (ARCHIVE_FATAL);
1378
+ }
1379
+ a->archive.state = ARCHIVE_STATE_HEADER;
1380
+
1381
+ return (ARCHIVE_OK);
1382
+ }
1383
+
1384
+ /*
1385
+ * Return a current filesystem ID which is index of the filesystem entry
1386
+ * you've visited through archive_read_disk.
1387
+ */
1388
+ int
1389
+ archive_read_disk_current_filesystem(struct archive *_a)
1390
+ {
1391
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1392
+
1393
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1394
+ "archive_read_disk_current_filesystem");
1395
+
1396
+ return (a->tree->current_filesystem_id);
1397
+ }
1398
+
1399
+ static int
1400
+ update_current_filesystem(struct archive_read_disk *a, int64_t dev)
1401
+ {
1402
+ struct tree *t = a->tree;
1403
+ int i, fid;
1404
+
1405
+ if (t->current_filesystem != NULL &&
1406
+ t->current_filesystem->dev == dev)
1407
+ return (ARCHIVE_OK);
1408
+
1409
+ for (i = 0; i < t->max_filesystem_id; i++) {
1410
+ if (t->filesystem_table[i].dev == dev) {
1411
+ /* There is the filesystem ID we've already generated. */
1412
+ t->current_filesystem_id = i;
1413
+ t->current_filesystem = &(t->filesystem_table[i]);
1414
+ return (ARCHIVE_OK);
1415
+ }
1416
+ }
1417
+
1418
+ /*
1419
+ * This is the new filesystem which we have to generate a new ID for.
1420
+ */
1421
+ fid = t->max_filesystem_id++;
1422
+ if (t->max_filesystem_id > t->allocated_filesystem) {
1423
+ size_t s;
1424
+ void *p;
1425
+
1426
+ s = t->max_filesystem_id * 2;
1427
+ p = realloc(t->filesystem_table,
1428
+ s * sizeof(*t->filesystem_table));
1429
+ if (p == NULL) {
1430
+ archive_set_error(&a->archive, ENOMEM,
1431
+ "Can't allocate tar data");
1432
+ return (ARCHIVE_FATAL);
1433
+ }
1434
+ t->filesystem_table = (struct filesystem *)p;
1435
+ t->allocated_filesystem = s;
1436
+ }
1437
+ t->current_filesystem_id = fid;
1438
+ t->current_filesystem = &(t->filesystem_table[fid]);
1439
+ t->current_filesystem->dev = dev;
1440
+ t->current_filesystem->allocation_ptr = NULL;
1441
+ t->current_filesystem->buff = NULL;
1442
+
1443
+ /* Setup the current filesystem properties which depend on
1444
+ * platform specific. */
1445
+ return (setup_current_filesystem(a));
1446
+ }
1447
+
1448
+ /*
1449
+ * Returns 1 if current filesystem is generated filesystem, 0 if it is not
1450
+ * or -1 if it is unknown.
1451
+ */
1452
+ int
1453
+ archive_read_disk_current_filesystem_is_synthetic(struct archive *_a)
1454
+ {
1455
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1456
+
1457
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1458
+ "archive_read_disk_current_filesystem");
1459
+
1460
+ return (a->tree->current_filesystem->synthetic);
1461
+ }
1462
+
1463
+ /*
1464
+ * Returns 1 if current filesystem is remote filesystem, 0 if it is not
1465
+ * or -1 if it is unknown.
1466
+ */
1467
+ int
1468
+ archive_read_disk_current_filesystem_is_remote(struct archive *_a)
1469
+ {
1470
+ struct archive_read_disk *a = (struct archive_read_disk *)_a;
1471
+
1472
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_DATA,
1473
+ "archive_read_disk_current_filesystem");
1474
+
1475
+ return (a->tree->current_filesystem->remote);
1476
+ }
1477
+
1478
+ #if defined(_PC_REC_INCR_XFER_SIZE) && defined(_PC_REC_MAX_XFER_SIZE) &&\
1479
+ defined(_PC_REC_MIN_XFER_SIZE) && defined(_PC_REC_XFER_ALIGN)
1480
+ static int
1481
+ get_xfer_size(struct tree *t, int fd, const char *path)
1482
+ {
1483
+ t->current_filesystem->xfer_align = -1;
1484
+ errno = 0;
1485
+ if (fd >= 0) {
1486
+ t->current_filesystem->incr_xfer_size =
1487
+ fpathconf(fd, _PC_REC_INCR_XFER_SIZE);
1488
+ t->current_filesystem->max_xfer_size =
1489
+ fpathconf(fd, _PC_REC_MAX_XFER_SIZE);
1490
+ t->current_filesystem->min_xfer_size =
1491
+ fpathconf(fd, _PC_REC_MIN_XFER_SIZE);
1492
+ t->current_filesystem->xfer_align =
1493
+ fpathconf(fd, _PC_REC_XFER_ALIGN);
1494
+ } else if (path != NULL) {
1495
+ t->current_filesystem->incr_xfer_size =
1496
+ pathconf(path, _PC_REC_INCR_XFER_SIZE);
1497
+ t->current_filesystem->max_xfer_size =
1498
+ pathconf(path, _PC_REC_MAX_XFER_SIZE);
1499
+ t->current_filesystem->min_xfer_size =
1500
+ pathconf(path, _PC_REC_MIN_XFER_SIZE);
1501
+ t->current_filesystem->xfer_align =
1502
+ pathconf(path, _PC_REC_XFER_ALIGN);
1503
+ }
1504
+ /* At least we need an alignment size. */
1505
+ if (t->current_filesystem->xfer_align == -1)
1506
+ return ((errno == EINVAL)?1:-1);
1507
+ else
1508
+ return (0);
1509
+ }
1510
+ #else
1511
+ static int
1512
+ get_xfer_size(struct tree *t, int fd, const char *path)
1513
+ {
1514
+ (void)t; /* UNUSED */
1515
+ (void)fd; /* UNUSED */
1516
+ (void)path; /* UNUSED */
1517
+ return (1);/* Not supported */
1518
+ }
1519
+ #endif
1520
+
1521
+ #if defined(HAVE_STATVFS)
1522
+ static inline __LA_UNUSED void
1523
+ set_statvfs_transfer_size(struct filesystem *fs, const struct statvfs *sfs)
1524
+ {
1525
+ fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1;
1526
+ fs->max_xfer_size = -1;
1527
+ #if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
1528
+ fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
1529
+ fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
1530
+ #else
1531
+ fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
1532
+ fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
1533
+ #endif
1534
+ }
1535
+ #endif
1536
+
1537
+ #if defined(HAVE_STRUCT_STATFS)
1538
+ static inline __LA_UNUSED void
1539
+ set_statfs_transfer_size(struct filesystem *fs, const struct statfs *sfs)
1540
+ {
1541
+ fs->xfer_align = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
1542
+ fs->max_xfer_size = -1;
1543
+ #if defined(HAVE_STRUCT_STATFS_F_IOSIZE)
1544
+ fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
1545
+ fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
1546
+ #else
1547
+ fs->min_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
1548
+ fs->incr_xfer_size = sfs->f_bsize > 0 ? (long)sfs->f_bsize : -1;
1549
+ #endif
1550
+ }
1551
+ #endif
1552
+
1553
+ #if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS) && \
1554
+ defined(HAVE_FSTATFS) && defined(MNT_LOCAL) && !defined(ST_LOCAL)
1555
+
1556
+ /*
1557
+ * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
1558
+ */
1559
+ static int
1560
+ setup_current_filesystem(struct archive_read_disk *a)
1561
+ {
1562
+ struct tree *t = a->tree;
1563
+ struct statfs sfs;
1564
+ #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
1565
+ /* TODO: configure should set GETVFSBYNAME_ARG_TYPE to make
1566
+ * this accurate; some platforms have both and we need the one that's
1567
+ * used by getvfsbyname()
1568
+ *
1569
+ * Then the following would become:
1570
+ * #if defined(GETVFSBYNAME_ARG_TYPE)
1571
+ * GETVFSBYNAME_ARG_TYPE vfc;
1572
+ * #endif
1573
+ */
1574
+ # if defined(HAVE_STRUCT_XVFSCONF)
1575
+ struct xvfsconf vfc;
1576
+ # else
1577
+ struct vfsconf vfc;
1578
+ # endif
1579
+ #endif
1580
+ int r, xr = 0;
1581
+ #if !defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
1582
+ long nm;
1583
+ #endif
1584
+
1585
+ t->current_filesystem->synthetic = -1;
1586
+ t->current_filesystem->remote = -1;
1587
+ if (tree_current_is_symblic_link_target(t)) {
1588
+ #if defined(HAVE_OPENAT)
1589
+ /*
1590
+ * Get file system statistics on any directory
1591
+ * where current is.
1592
+ */
1593
+ int fd = openat(tree_current_dir_fd(t),
1594
+ tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
1595
+ __archive_ensure_cloexec_flag(fd);
1596
+ if (fd < 0) {
1597
+ archive_set_error(&a->archive, errno,
1598
+ "openat failed");
1599
+ return (ARCHIVE_FAILED);
1600
+ }
1601
+ r = fstatfs(fd, &sfs);
1602
+ if (r == 0)
1603
+ xr = get_xfer_size(t, fd, NULL);
1604
+ close(fd);
1605
+ #else
1606
+ if (tree_enter_working_dir(t) != 0) {
1607
+ archive_set_error(&a->archive, errno, "fchdir failed");
1608
+ return (ARCHIVE_FAILED);
1609
+ }
1610
+ r = statfs(tree_current_access_path(t), &sfs);
1611
+ if (r == 0)
1612
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
1613
+ #endif
1614
+ } else {
1615
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
1616
+ if (r == 0)
1617
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1618
+ }
1619
+ if (r == -1 || xr == -1) {
1620
+ archive_set_error(&a->archive, errno, "statfs failed");
1621
+ return (ARCHIVE_FAILED);
1622
+ } else if (xr == 1) {
1623
+ /* pathconf(_PC_REX_*) operations are not supported. */
1624
+ set_statfs_transfer_size(t->current_filesystem, &sfs);
1625
+ }
1626
+ if (sfs.f_flags & MNT_LOCAL)
1627
+ t->current_filesystem->remote = 0;
1628
+ else
1629
+ t->current_filesystem->remote = 1;
1630
+
1631
+ #if defined(HAVE_GETVFSBYNAME) && defined(VFCF_SYNTHETIC)
1632
+ r = getvfsbyname(sfs.f_fstypename, &vfc);
1633
+ if (r == -1) {
1634
+ archive_set_error(&a->archive, errno, "getvfsbyname failed");
1635
+ return (ARCHIVE_FAILED);
1636
+ }
1637
+ if (vfc.vfc_flags & VFCF_SYNTHETIC)
1638
+ t->current_filesystem->synthetic = 1;
1639
+ else
1640
+ t->current_filesystem->synthetic = 0;
1641
+ #endif
1642
+
1643
+ #if defined(MNT_NOATIME)
1644
+ if (sfs.f_flags & MNT_NOATIME)
1645
+ t->current_filesystem->noatime = 1;
1646
+ else
1647
+ #endif
1648
+ t->current_filesystem->noatime = 0;
1649
+
1650
+ #if defined(USE_READDIR_R)
1651
+ /* Set maximum filename length. */
1652
+ #if defined(HAVE_STRUCT_STATFS_F_NAMEMAX)
1653
+ t->current_filesystem->name_max = sfs.f_namemax;
1654
+ #else
1655
+ # if defined(_PC_NAME_MAX)
1656
+ /* Mac OS X does not have f_namemax in struct statfs. */
1657
+ if (tree_current_is_symblic_link_target(t)) {
1658
+ if (tree_enter_working_dir(t) != 0) {
1659
+ archive_set_error(&a->archive, errno, "fchdir failed");
1660
+ return (ARCHIVE_FAILED);
1661
+ }
1662
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
1663
+ } else
1664
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
1665
+ # else
1666
+ nm = -1;
1667
+ # endif
1668
+ if (nm == -1)
1669
+ t->current_filesystem->name_max = NAME_MAX;
1670
+ else
1671
+ t->current_filesystem->name_max = nm;
1672
+ #endif
1673
+ #endif /* USE_READDIR_R */
1674
+ return (ARCHIVE_OK);
1675
+ }
1676
+
1677
+ #elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
1678
+
1679
+ /*
1680
+ * Gather current filesystem properties on NetBSD
1681
+ */
1682
+ static int
1683
+ setup_current_filesystem(struct archive_read_disk *a)
1684
+ {
1685
+ struct tree *t = a->tree;
1686
+ struct statvfs svfs;
1687
+ int r, xr = 0;
1688
+
1689
+ t->current_filesystem->synthetic = -1;
1690
+ if (tree_enter_working_dir(t) != 0) {
1691
+ archive_set_error(&a->archive, errno, "fchdir failed");
1692
+ return (ARCHIVE_FAILED);
1693
+ }
1694
+ if (tree_current_is_symblic_link_target(t)) {
1695
+ r = statvfs(tree_current_access_path(t), &svfs);
1696
+ if (r == 0)
1697
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
1698
+ } else {
1699
+ #ifdef HAVE_FSTATVFS
1700
+ r = fstatvfs(tree_current_dir_fd(t), &svfs);
1701
+ if (r == 0)
1702
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1703
+ #else
1704
+ r = statvfs(".", &svfs);
1705
+ if (r == 0)
1706
+ xr = get_xfer_size(t, -1, ".");
1707
+ #endif
1708
+ }
1709
+ if (r == -1 || xr == -1) {
1710
+ t->current_filesystem->remote = -1;
1711
+ archive_set_error(&a->archive, errno, "statvfs failed");
1712
+ return (ARCHIVE_FAILED);
1713
+ } else if (xr == 1) {
1714
+ /* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
1715
+ * for pathconf() function. */
1716
+ set_statvfs_transfer_size(t->current_filesystem, &svfs);
1717
+ }
1718
+ if (svfs.f_flag & ST_LOCAL)
1719
+ t->current_filesystem->remote = 0;
1720
+ else
1721
+ t->current_filesystem->remote = 1;
1722
+
1723
+ #if defined(ST_NOATIME)
1724
+ if (svfs.f_flag & ST_NOATIME)
1725
+ t->current_filesystem->noatime = 1;
1726
+ else
1727
+ #endif
1728
+ t->current_filesystem->noatime = 0;
1729
+
1730
+ /* Set maximum filename length. */
1731
+ t->current_filesystem->name_max = svfs.f_namemax;
1732
+ return (ARCHIVE_OK);
1733
+ }
1734
+
1735
+ #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_LINUX_MAGIC_H) &&\
1736
+ defined(HAVE_STATFS) && defined(HAVE_FSTATFS)
1737
+ /*
1738
+ * Note: statfs is deprecated since LSB 3.2
1739
+ */
1740
+
1741
+ #ifndef CIFS_SUPER_MAGIC
1742
+ #define CIFS_SUPER_MAGIC 0xFF534D42
1743
+ #endif
1744
+ #ifndef DEVFS_SUPER_MAGIC
1745
+ #define DEVFS_SUPER_MAGIC 0x1373
1746
+ #endif
1747
+
1748
+ /*
1749
+ * Gather current filesystem properties on Linux
1750
+ */
1751
+ static int
1752
+ setup_current_filesystem(struct archive_read_disk *a)
1753
+ {
1754
+ struct tree *t = a->tree;
1755
+ struct statfs sfs;
1756
+ #if defined(HAVE_STATVFS)
1757
+ struct statvfs svfs;
1758
+ #endif
1759
+ int r, vr = 0, xr = 0;
1760
+
1761
+ if (tree_current_is_symblic_link_target(t)) {
1762
+ #if defined(HAVE_OPENAT)
1763
+ /*
1764
+ * Get file system statistics on any directory
1765
+ * where current is.
1766
+ */
1767
+ int fd = openat(tree_current_dir_fd(t),
1768
+ tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
1769
+ __archive_ensure_cloexec_flag(fd);
1770
+ if (fd < 0) {
1771
+ archive_set_error(&a->archive, errno,
1772
+ "openat failed");
1773
+ return (ARCHIVE_FAILED);
1774
+ }
1775
+ #if defined(HAVE_FSTATVFS)
1776
+ vr = fstatvfs(fd, &svfs);/* for f_flag, mount flags */
1777
+ #endif
1778
+ r = fstatfs(fd, &sfs);
1779
+ if (r == 0)
1780
+ xr = get_xfer_size(t, fd, NULL);
1781
+ close(fd);
1782
+ #else
1783
+ if (tree_enter_working_dir(t) != 0) {
1784
+ archive_set_error(&a->archive, errno, "fchdir failed");
1785
+ return (ARCHIVE_FAILED);
1786
+ }
1787
+ #if defined(HAVE_STATVFS)
1788
+ vr = statvfs(tree_current_access_path(t), &svfs);
1789
+ #endif
1790
+ r = statfs(tree_current_access_path(t), &sfs);
1791
+ if (r == 0)
1792
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
1793
+ #endif
1794
+ } else {
1795
+ #ifdef HAVE_FSTATFS
1796
+ #if defined(HAVE_FSTATVFS)
1797
+ vr = fstatvfs(tree_current_dir_fd(t), &svfs);
1798
+ #endif
1799
+ r = fstatfs(tree_current_dir_fd(t), &sfs);
1800
+ if (r == 0)
1801
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1802
+ #else
1803
+ if (tree_enter_working_dir(t) != 0) {
1804
+ archive_set_error(&a->archive, errno, "fchdir failed");
1805
+ return (ARCHIVE_FAILED);
1806
+ }
1807
+ #if defined(HAVE_STATVFS)
1808
+ vr = statvfs(".", &svfs);
1809
+ #endif
1810
+ r = statfs(".", &sfs);
1811
+ if (r == 0)
1812
+ xr = get_xfer_size(t, -1, ".");
1813
+ #endif
1814
+ }
1815
+ if (r == -1 || xr == -1 || vr == -1) {
1816
+ t->current_filesystem->synthetic = -1;
1817
+ t->current_filesystem->remote = -1;
1818
+ archive_set_error(&a->archive, errno, "statfs failed");
1819
+ return (ARCHIVE_FAILED);
1820
+ } else if (xr == 1) {
1821
+ /* pathconf(_PC_REX_*) operations are not supported. */
1822
+ #if defined(HAVE_STATVFS)
1823
+ set_statvfs_transfer_size(t->current_filesystem, &svfs);
1824
+ #else
1825
+ set_statfs_transfer_size(t->current_filesystem, &sfs);
1826
+ #endif
1827
+ }
1828
+ switch (sfs.f_type) {
1829
+ case AFS_SUPER_MAGIC:
1830
+ case CIFS_SUPER_MAGIC:
1831
+ case CODA_SUPER_MAGIC:
1832
+ case NCP_SUPER_MAGIC:/* NetWare */
1833
+ case NFS_SUPER_MAGIC:
1834
+ case SMB_SUPER_MAGIC:
1835
+ t->current_filesystem->remote = 1;
1836
+ t->current_filesystem->synthetic = 0;
1837
+ break;
1838
+ case DEVFS_SUPER_MAGIC:
1839
+ case PROC_SUPER_MAGIC:
1840
+ case USBDEVICE_SUPER_MAGIC:
1841
+ t->current_filesystem->remote = 0;
1842
+ t->current_filesystem->synthetic = 1;
1843
+ break;
1844
+ default:
1845
+ t->current_filesystem->remote = 0;
1846
+ t->current_filesystem->synthetic = 0;
1847
+ break;
1848
+ }
1849
+
1850
+ #if defined(ST_NOATIME)
1851
+ #if defined(HAVE_STATVFS)
1852
+ if (svfs.f_flag & ST_NOATIME)
1853
+ #else
1854
+ if (sfs.f_flags & ST_NOATIME)
1855
+ #endif
1856
+ t->current_filesystem->noatime = 1;
1857
+ else
1858
+ #endif
1859
+ t->current_filesystem->noatime = 0;
1860
+
1861
+ #if defined(USE_READDIR_R)
1862
+ /* Set maximum filename length. */
1863
+ t->current_filesystem->name_max = sfs.f_namelen;
1864
+ #endif
1865
+ return (ARCHIVE_OK);
1866
+ }
1867
+
1868
+ #elif defined(HAVE_SYS_STATVFS_H) &&\
1869
+ (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS))
1870
+
1871
+ /*
1872
+ * Gather current filesystem properties on other posix platform.
1873
+ */
1874
+ static int
1875
+ setup_current_filesystem(struct archive_read_disk *a)
1876
+ {
1877
+ struct tree *t = a->tree;
1878
+ struct statvfs svfs;
1879
+ int r, xr = 0;
1880
+
1881
+ t->current_filesystem->synthetic = -1;/* Not supported */
1882
+ t->current_filesystem->remote = -1;/* Not supported */
1883
+ if (tree_current_is_symblic_link_target(t)) {
1884
+ #if defined(HAVE_OPENAT)
1885
+ /*
1886
+ * Get file system statistics on any directory
1887
+ * where current is.
1888
+ */
1889
+ int fd = openat(tree_current_dir_fd(t),
1890
+ tree_current_access_path(t), O_RDONLY | O_CLOEXEC);
1891
+ __archive_ensure_cloexec_flag(fd);
1892
+ if (fd < 0) {
1893
+ archive_set_error(&a->archive, errno,
1894
+ "openat failed");
1895
+ return (ARCHIVE_FAILED);
1896
+ }
1897
+ r = fstatvfs(fd, &svfs);
1898
+ if (r == 0)
1899
+ xr = get_xfer_size(t, fd, NULL);
1900
+ close(fd);
1901
+ #else
1902
+ if (tree_enter_working_dir(t) != 0) {
1903
+ archive_set_error(&a->archive, errno, "fchdir failed");
1904
+ return (ARCHIVE_FAILED);
1905
+ }
1906
+ r = statvfs(tree_current_access_path(t), &svfs);
1907
+ if (r == 0)
1908
+ xr = get_xfer_size(t, -1, tree_current_access_path(t));
1909
+ #endif
1910
+ } else {
1911
+ #ifdef HAVE_FSTATVFS
1912
+ r = fstatvfs(tree_current_dir_fd(t), &svfs);
1913
+ if (r == 0)
1914
+ xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
1915
+ #else
1916
+ if (tree_enter_working_dir(t) != 0) {
1917
+ archive_set_error(&a->archive, errno, "fchdir failed");
1918
+ return (ARCHIVE_FAILED);
1919
+ }
1920
+ r = statvfs(".", &svfs);
1921
+ if (r == 0)
1922
+ xr = get_xfer_size(t, -1, ".");
1923
+ #endif
1924
+ }
1925
+ if (r == -1 || xr == -1) {
1926
+ t->current_filesystem->synthetic = -1;
1927
+ t->current_filesystem->remote = -1;
1928
+ archive_set_error(&a->archive, errno, "statvfs failed");
1929
+ return (ARCHIVE_FAILED);
1930
+ } else if (xr == 1) {
1931
+ /* pathconf(_PC_REX_*) operations are not supported. */
1932
+ set_statvfs_transfer_size(t->current_filesystem, &svfs);
1933
+ }
1934
+
1935
+ #if defined(ST_NOATIME)
1936
+ if (svfs.f_flag & ST_NOATIME)
1937
+ t->current_filesystem->noatime = 1;
1938
+ else
1939
+ #endif
1940
+ t->current_filesystem->noatime = 0;
1941
+
1942
+ #if defined(USE_READDIR_R)
1943
+ /* Set maximum filename length. */
1944
+ t->current_filesystem->name_max = svfs.f_namemax;
1945
+ #endif
1946
+ return (ARCHIVE_OK);
1947
+ }
1948
+
1949
+ #else
1950
+
1951
+ /*
1952
+ * Generic: Gather current filesystem properties.
1953
+ * TODO: Is this generic function really needed?
1954
+ */
1955
+ static int
1956
+ setup_current_filesystem(struct archive_read_disk *a)
1957
+ {
1958
+ struct tree *t = a->tree;
1959
+ #if defined(_PC_NAME_MAX) && defined(USE_READDIR_R)
1960
+ long nm;
1961
+ #endif
1962
+ t->current_filesystem->synthetic = -1;/* Not supported */
1963
+ t->current_filesystem->remote = -1;/* Not supported */
1964
+ t->current_filesystem->noatime = 0;
1965
+ (void)get_xfer_size(t, -1, ".");/* Dummy call to avoid build error. */
1966
+ t->current_filesystem->xfer_align = -1;/* Unknown */
1967
+ t->current_filesystem->max_xfer_size = -1;
1968
+ t->current_filesystem->min_xfer_size = -1;
1969
+ t->current_filesystem->incr_xfer_size = -1;
1970
+
1971
+ #if defined(USE_READDIR_R)
1972
+ /* Set maximum filename length. */
1973
+ # if defined(_PC_NAME_MAX)
1974
+ if (tree_current_is_symblic_link_target(t)) {
1975
+ if (tree_enter_working_dir(t) != 0) {
1976
+ archive_set_error(&a->archive, errno, "fchdir failed");
1977
+ return (ARCHIVE_FAILED);
1978
+ }
1979
+ nm = pathconf(tree_current_access_path(t), _PC_NAME_MAX);
1980
+ } else
1981
+ nm = fpathconf(tree_current_dir_fd(t), _PC_NAME_MAX);
1982
+ if (nm == -1)
1983
+ # endif /* _PC_NAME_MAX */
1984
+ /*
1985
+ * Some systems (HP-UX or others?) incorrectly defined
1986
+ * NAME_MAX macro to be a smaller value.
1987
+ */
1988
+ # if defined(NAME_MAX) && NAME_MAX >= 255
1989
+ t->current_filesystem->name_max = NAME_MAX;
1990
+ # else
1991
+ /* No way to get a trusted value of maximum filename
1992
+ * length. */
1993
+ t->current_filesystem->name_max = PATH_MAX;
1994
+ # endif /* NAME_MAX */
1995
+ # if defined(_PC_NAME_MAX)
1996
+ else
1997
+ t->current_filesystem->name_max = nm;
1998
+ # endif /* _PC_NAME_MAX */
1999
+ #endif /* USE_READDIR_R */
2000
+ return (ARCHIVE_OK);
2001
+ }
2002
+
2003
+ #endif
2004
+
2005
+ static int
2006
+ close_and_restore_time(int fd, struct tree *t, struct restore_time *rt)
2007
+ {
2008
+ #ifndef HAVE_UTIMES
2009
+ (void)t; /* UNUSED */
2010
+ (void)rt; /* UNUSED */
2011
+ return (close(fd));
2012
+ #else
2013
+ #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
2014
+ struct timespec timespecs[2];
2015
+ #endif
2016
+ struct timeval times[2];
2017
+
2018
+ if ((t->flags & needsRestoreTimes) == 0 || rt->noatime) {
2019
+ if (fd >= 0)
2020
+ return (close(fd));
2021
+ else
2022
+ return (0);
2023
+ }
2024
+
2025
+ #if defined(HAVE_FUTIMENS) && !defined(__CYGWIN__)
2026
+ timespecs[1].tv_sec = rt->mtime;
2027
+ timespecs[1].tv_nsec = rt->mtime_nsec;
2028
+
2029
+ timespecs[0].tv_sec = rt->atime;
2030
+ timespecs[0].tv_nsec = rt->atime_nsec;
2031
+ /* futimens() is defined in POSIX.1-2008. */
2032
+ if (futimens(fd, timespecs) == 0)
2033
+ return (close(fd));
2034
+ #endif
2035
+
2036
+ times[1].tv_sec = rt->mtime;
2037
+ times[1].tv_usec = rt->mtime_nsec / 1000;
2038
+
2039
+ times[0].tv_sec = rt->atime;
2040
+ times[0].tv_usec = rt->atime_nsec / 1000;
2041
+
2042
+ #if !defined(HAVE_FUTIMENS) && defined(HAVE_FUTIMES) && !defined(__CYGWIN__)
2043
+ if (futimes(fd, times) == 0)
2044
+ return (close(fd));
2045
+ #endif
2046
+ close(fd);
2047
+ #if defined(HAVE_FUTIMESAT)
2048
+ if (futimesat(tree_current_dir_fd(t), rt->name, times) == 0)
2049
+ return (0);
2050
+ #endif
2051
+ #ifdef HAVE_LUTIMES
2052
+ if (lutimes(rt->name, times) != 0)
2053
+ #else
2054
+ if (AE_IFLNK != rt->filetype && utimes(rt->name, times) != 0)
2055
+ #endif
2056
+ return (-1);
2057
+ #endif
2058
+ return (0);
2059
+ }
2060
+
2061
+ static int
2062
+ open_on_current_dir(struct tree *t, const char *path, int flags)
2063
+ {
2064
+ #ifdef HAVE_OPENAT
2065
+ return (openat(tree_current_dir_fd(t), path, flags));
2066
+ #else
2067
+ if (tree_enter_working_dir(t) != 0)
2068
+ return (-1);
2069
+ return (open(path, flags));
2070
+ #endif
2071
+ }
2072
+
2073
+ static int
2074
+ tree_dup(int fd)
2075
+ {
2076
+ int new_fd;
2077
+ #ifdef F_DUPFD_CLOEXEC
2078
+ static volatile int can_dupfd_cloexec = 1;
2079
+
2080
+ if (can_dupfd_cloexec) {
2081
+ new_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
2082
+ if (new_fd != -1)
2083
+ return (new_fd);
2084
+ /* Linux 2.6.18 - 2.6.23 declare F_DUPFD_CLOEXEC,
2085
+ * but it cannot be used. So we have to try dup(). */
2086
+ /* We won't try F_DUPFD_CLOEXEC. */
2087
+ can_dupfd_cloexec = 0;
2088
+ }
2089
+ #endif /* F_DUPFD_CLOEXEC */
2090
+ new_fd = dup(fd);
2091
+ __archive_ensure_cloexec_flag(new_fd);
2092
+ return (new_fd);
2093
+ }
2094
+
2095
+ /*
2096
+ * Add a directory path to the current stack.
2097
+ */
2098
+ static void
2099
+ tree_push(struct tree *t, const char *path, int filesystem_id,
2100
+ int64_t dev, int64_t ino, struct restore_time *rt)
2101
+ {
2102
+ struct tree_entry *te;
2103
+
2104
+ te = calloc(1, sizeof(*te));
2105
+ if (te == NULL)
2106
+ __archive_errx(1, "Out of memory");
2107
+ te->next = t->stack;
2108
+ te->parent = t->current;
2109
+ if (te->parent)
2110
+ te->depth = te->parent->depth + 1;
2111
+ t->stack = te;
2112
+ archive_string_init(&te->name);
2113
+ te->symlink_parent_fd = -1;
2114
+ archive_strcpy(&te->name, path);
2115
+ te->flags = needsDescent | needsOpen | needsAscent;
2116
+ te->filesystem_id = filesystem_id;
2117
+ te->dev = dev;
2118
+ te->ino = ino;
2119
+ te->dirname_length = t->dirname_length;
2120
+ te->restore_time.name = te->name.s;
2121
+ if (rt != NULL) {
2122
+ te->restore_time.mtime = rt->mtime;
2123
+ te->restore_time.mtime_nsec = rt->mtime_nsec;
2124
+ te->restore_time.atime = rt->atime;
2125
+ te->restore_time.atime_nsec = rt->atime_nsec;
2126
+ te->restore_time.filetype = rt->filetype;
2127
+ te->restore_time.noatime = rt->noatime;
2128
+ }
2129
+ }
2130
+
2131
+ /*
2132
+ * Append a name to the current dir path.
2133
+ */
2134
+ static void
2135
+ tree_append(struct tree *t, const char *name, size_t name_length)
2136
+ {
2137
+ size_t size_needed;
2138
+
2139
+ t->path.s[t->dirname_length] = '\0';
2140
+ t->path.length = t->dirname_length;
2141
+ /* Strip trailing '/' from name, unless entire name is "/". */
2142
+ while (name_length > 1 && name[name_length - 1] == '/')
2143
+ name_length--;
2144
+
2145
+ /* Resize pathname buffer as needed. */
2146
+ size_needed = name_length + t->dirname_length + 2;
2147
+ archive_string_ensure(&t->path, size_needed);
2148
+ /* Add a separating '/' if it's needed. */
2149
+ if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != '/')
2150
+ archive_strappend_char(&t->path, '/');
2151
+ t->basename = t->path.s + archive_strlen(&t->path);
2152
+ archive_strncat(&t->path, name, name_length);
2153
+ t->restore_time.name = t->basename;
2154
+ }
2155
+
2156
+ /*
2157
+ * Open a directory tree for traversal.
2158
+ */
2159
+ static struct tree *
2160
+ tree_open(const char *path, int symlink_mode, int restore_time)
2161
+ {
2162
+ struct tree *t;
2163
+
2164
+ if ((t = calloc(1, sizeof(*t))) == NULL)
2165
+ return (NULL);
2166
+ archive_string_init(&t->path);
2167
+ archive_string_ensure(&t->path, 31);
2168
+ t->initial_symlink_mode = symlink_mode;
2169
+ return (tree_reopen(t, path, restore_time));
2170
+ }
2171
+
2172
+ static struct tree *
2173
+ tree_reopen(struct tree *t, const char *path, int restore_time)
2174
+ {
2175
+ #if defined(O_PATH)
2176
+ /* Linux */
2177
+ const int o_flag = O_PATH;
2178
+ #elif defined(O_SEARCH)
2179
+ /* SunOS */
2180
+ const int o_flag = O_SEARCH;
2181
+ #elif defined(__FreeBSD__) && defined(O_EXEC)
2182
+ /* FreeBSD */
2183
+ const int o_flag = O_EXEC;
2184
+ #endif
2185
+
2186
+ t->flags = (restore_time != 0)?needsRestoreTimes:0;
2187
+ t->flags |= onInitialDir;
2188
+ t->visit_type = 0;
2189
+ t->tree_errno = 0;
2190
+ t->dirname_length = 0;
2191
+ t->depth = 0;
2192
+ t->descend = 0;
2193
+ t->current = NULL;
2194
+ t->d = INVALID_DIR_HANDLE;
2195
+ t->symlink_mode = t->initial_symlink_mode;
2196
+ archive_string_empty(&t->path);
2197
+ t->entry_fd = -1;
2198
+ t->entry_eof = 0;
2199
+ t->entry_remaining_bytes = 0;
2200
+ t->initial_filesystem_id = -1;
2201
+
2202
+ /* First item is set up a lot like a symlink traversal. */
2203
+ tree_push(t, path, 0, 0, 0, NULL);
2204
+ t->stack->flags = needsFirstVisit;
2205
+ t->maxOpenCount = t->openCount = 1;
2206
+ t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC);
2207
+ #if defined(O_PATH) || defined(O_SEARCH) || \
2208
+ (defined(__FreeBSD__) && defined(O_EXEC))
2209
+ /*
2210
+ * Most likely reason to fail opening "." is that it's not readable,
2211
+ * so try again for execute. The consequences of not opening this are
2212
+ * unhelpful and unnecessary errors later.
2213
+ */
2214
+ if (t->initial_dir_fd < 0)
2215
+ t->initial_dir_fd = open(".", o_flag | O_CLOEXEC);
2216
+ #endif
2217
+ __archive_ensure_cloexec_flag(t->initial_dir_fd);
2218
+ t->working_dir_fd = tree_dup(t->initial_dir_fd);
2219
+ return (t);
2220
+ }
2221
+
2222
+ static int
2223
+ tree_descent(struct tree *t)
2224
+ {
2225
+ int flag, new_fd, r = 0;
2226
+
2227
+ t->dirname_length = archive_strlen(&t->path);
2228
+ flag = O_RDONLY | O_CLOEXEC;
2229
+ #if defined(O_DIRECTORY)
2230
+ flag |= O_DIRECTORY;
2231
+ #endif
2232
+ new_fd = open_on_current_dir(t, t->stack->name.s, flag);
2233
+ __archive_ensure_cloexec_flag(new_fd);
2234
+ if (new_fd < 0) {
2235
+ t->tree_errno = errno;
2236
+ r = TREE_ERROR_DIR;
2237
+ } else {
2238
+ t->depth++;
2239
+ /* If it is a link, set up fd for the ascent. */
2240
+ if (t->stack->flags & isDirLink) {
2241
+ t->stack->symlink_parent_fd = t->working_dir_fd;
2242
+ t->openCount++;
2243
+ if (t->openCount > t->maxOpenCount)
2244
+ t->maxOpenCount = t->openCount;
2245
+ } else
2246
+ close(t->working_dir_fd);
2247
+ /* Renew the current working directory. */
2248
+ t->working_dir_fd = new_fd;
2249
+ t->flags &= ~onWorkingDir;
2250
+ }
2251
+ return (r);
2252
+ }
2253
+
2254
+ /*
2255
+ * We've finished a directory; ascend back to the parent.
2256
+ */
2257
+ static int
2258
+ tree_ascend(struct tree *t)
2259
+ {
2260
+ struct tree_entry *te;
2261
+ int new_fd, r = 0, prev_dir_fd;
2262
+
2263
+ te = t->stack;
2264
+ prev_dir_fd = t->working_dir_fd;
2265
+ if (te->flags & isDirLink)
2266
+ new_fd = te->symlink_parent_fd;
2267
+ else {
2268
+ new_fd = open_on_current_dir(t, "..", O_RDONLY | O_CLOEXEC);
2269
+ __archive_ensure_cloexec_flag(new_fd);
2270
+ }
2271
+ if (new_fd < 0) {
2272
+ t->tree_errno = errno;
2273
+ r = TREE_ERROR_FATAL;
2274
+ } else {
2275
+ /* Renew the current working directory. */
2276
+ t->working_dir_fd = new_fd;
2277
+ t->flags &= ~onWorkingDir;
2278
+ /* Current directory has been changed, we should
2279
+ * close an fd of previous working directory. */
2280
+ close_and_restore_time(prev_dir_fd, t, &te->restore_time);
2281
+ if (te->flags & isDirLink) {
2282
+ t->openCount--;
2283
+ te->symlink_parent_fd = -1;
2284
+ }
2285
+ t->depth--;
2286
+ }
2287
+ return (r);
2288
+ }
2289
+
2290
+ /*
2291
+ * Return to the initial directory where tree_open() was performed.
2292
+ */
2293
+ static int
2294
+ tree_enter_initial_dir(struct tree *t)
2295
+ {
2296
+ int r = 0;
2297
+
2298
+ if ((t->flags & onInitialDir) == 0) {
2299
+ r = fchdir(t->initial_dir_fd);
2300
+ if (r == 0) {
2301
+ t->flags &= ~onWorkingDir;
2302
+ t->flags |= onInitialDir;
2303
+ }
2304
+ }
2305
+ return (r);
2306
+ }
2307
+
2308
+ /*
2309
+ * Restore working directory of directory traversals.
2310
+ */
2311
+ static int
2312
+ tree_enter_working_dir(struct tree *t)
2313
+ {
2314
+ int r = 0;
2315
+
2316
+ /*
2317
+ * Change the current directory if really needed.
2318
+ * Sometimes this is unneeded when we did not do
2319
+ * descent.
2320
+ */
2321
+ if (t->depth > 0 && (t->flags & onWorkingDir) == 0) {
2322
+ r = fchdir(t->working_dir_fd);
2323
+ if (r == 0) {
2324
+ t->flags &= ~onInitialDir;
2325
+ t->flags |= onWorkingDir;
2326
+ }
2327
+ }
2328
+ return (r);
2329
+ }
2330
+
2331
+ static int
2332
+ tree_current_dir_fd(struct tree *t)
2333
+ {
2334
+ return (t->working_dir_fd);
2335
+ }
2336
+
2337
+ /*
2338
+ * Pop the working stack.
2339
+ */
2340
+ static void
2341
+ tree_pop(struct tree *t)
2342
+ {
2343
+ struct tree_entry *te;
2344
+
2345
+ t->path.s[t->dirname_length] = '\0';
2346
+ t->path.length = t->dirname_length;
2347
+ if (t->stack == t->current && t->current != NULL)
2348
+ t->current = t->current->parent;
2349
+ te = t->stack;
2350
+ t->stack = te->next;
2351
+ t->dirname_length = te->dirname_length;
2352
+ t->basename = t->path.s + t->dirname_length;
2353
+ while (t->basename[0] == '/')
2354
+ t->basename++;
2355
+ archive_string_free(&te->name);
2356
+ free(te);
2357
+ }
2358
+
2359
+ /*
2360
+ * Get the next item in the tree traversal.
2361
+ */
2362
+ static int
2363
+ tree_next(struct tree *t)
2364
+ {
2365
+ int r;
2366
+
2367
+ while (t->stack != NULL) {
2368
+ /* If there's an open dir, get the next entry from there. */
2369
+ if (t->d != INVALID_DIR_HANDLE) {
2370
+ r = tree_dir_next_posix(t);
2371
+ if (r == 0)
2372
+ continue;
2373
+ return (r);
2374
+ }
2375
+
2376
+ if (t->stack->flags & needsFirstVisit) {
2377
+ /* Top stack item needs a regular visit. */
2378
+ t->current = t->stack;
2379
+ tree_append(t, t->stack->name.s,
2380
+ archive_strlen(&(t->stack->name)));
2381
+ /* t->dirname_length = t->path_length; */
2382
+ /* tree_pop(t); */
2383
+ t->stack->flags &= ~needsFirstVisit;
2384
+ return (t->visit_type = TREE_REGULAR);
2385
+ } else if (t->stack->flags & needsDescent) {
2386
+ /* Top stack item is dir to descend into. */
2387
+ t->current = t->stack;
2388
+ tree_append(t, t->stack->name.s,
2389
+ archive_strlen(&(t->stack->name)));
2390
+ t->stack->flags &= ~needsDescent;
2391
+ r = tree_descent(t);
2392
+ if (r != 0) {
2393
+ tree_pop(t);
2394
+ t->visit_type = r;
2395
+ } else
2396
+ t->visit_type = TREE_POSTDESCENT;
2397
+ return (t->visit_type);
2398
+ } else if (t->stack->flags & needsOpen) {
2399
+ t->stack->flags &= ~needsOpen;
2400
+ r = tree_dir_next_posix(t);
2401
+ if (r == 0)
2402
+ continue;
2403
+ return (r);
2404
+ } else if (t->stack->flags & needsAscent) {
2405
+ /* Top stack item is dir and we're done with it. */
2406
+ r = tree_ascend(t);
2407
+ tree_pop(t);
2408
+ t->visit_type = r != 0 ? r : TREE_POSTASCENT;
2409
+ return (t->visit_type);
2410
+ } else {
2411
+ /* Top item on stack is dead. */
2412
+ tree_pop(t);
2413
+ t->flags &= ~hasLstat;
2414
+ t->flags &= ~hasStat;
2415
+ }
2416
+ }
2417
+ return (t->visit_type = 0);
2418
+ }
2419
+
2420
+ static int
2421
+ tree_dir_next_posix(struct tree *t)
2422
+ {
2423
+ int r;
2424
+ const char *name;
2425
+ size_t namelen;
2426
+
2427
+ if (t->d == NULL) {
2428
+ #if defined(USE_READDIR_R)
2429
+ size_t dirent_size;
2430
+ #endif
2431
+
2432
+ #if defined(HAVE_FDOPENDIR)
2433
+ t->d = fdopendir(tree_dup(t->working_dir_fd));
2434
+ #else /* HAVE_FDOPENDIR */
2435
+ if (tree_enter_working_dir(t) == 0) {
2436
+ t->d = opendir(".");
2437
+ #ifdef HAVE_DIRFD
2438
+ __archive_ensure_cloexec_flag(dirfd(t->d));
2439
+ #endif
2440
+ }
2441
+ #endif /* HAVE_FDOPENDIR */
2442
+ if (t->d == NULL) {
2443
+ r = tree_ascend(t); /* Undo "chdir" */
2444
+ tree_pop(t);
2445
+ t->tree_errno = errno;
2446
+ t->visit_type = r != 0 ? r : TREE_ERROR_DIR;
2447
+ return (t->visit_type);
2448
+ }
2449
+ #if defined(USE_READDIR_R)
2450
+ dirent_size = offsetof(struct dirent, d_name) +
2451
+ t->filesystem_table[t->current->filesystem_id].name_max + 1;
2452
+ if (t->dirent == NULL || t->dirent_allocated < dirent_size) {
2453
+ free(t->dirent);
2454
+ t->dirent = malloc(dirent_size);
2455
+ if (t->dirent == NULL) {
2456
+ closedir(t->d);
2457
+ t->d = INVALID_DIR_HANDLE;
2458
+ (void)tree_ascend(t);
2459
+ tree_pop(t);
2460
+ t->tree_errno = ENOMEM;
2461
+ t->visit_type = TREE_ERROR_DIR;
2462
+ return (t->visit_type);
2463
+ }
2464
+ t->dirent_allocated = dirent_size;
2465
+ }
2466
+ #endif /* USE_READDIR_R */
2467
+ }
2468
+ for (;;) {
2469
+ errno = 0;
2470
+ #if defined(USE_READDIR_R)
2471
+ r = readdir_r(t->d, t->dirent, &t->de);
2472
+ #ifdef _AIX
2473
+ /* Note: According to the man page, return value 9 indicates
2474
+ * that the readdir_r was not successful and the error code
2475
+ * is set to the global errno variable. And then if the end
2476
+ * of directory entries was reached, the return value is 9
2477
+ * and the third parameter is set to NULL and errno is
2478
+ * unchanged. */
2479
+ if (r == 9)
2480
+ r = errno;
2481
+ #endif /* _AIX */
2482
+ if (r != 0 || t->de == NULL) {
2483
+ #else
2484
+ t->de = readdir(t->d);
2485
+ if (t->de == NULL) {
2486
+ r = errno;
2487
+ #endif
2488
+ closedir(t->d);
2489
+ t->d = INVALID_DIR_HANDLE;
2490
+ if (r != 0) {
2491
+ t->tree_errno = r;
2492
+ t->visit_type = TREE_ERROR_DIR;
2493
+ return (t->visit_type);
2494
+ } else
2495
+ return (0);
2496
+ }
2497
+ name = t->de->d_name;
2498
+ namelen = D_NAMELEN(t->de);
2499
+ t->flags &= ~hasLstat;
2500
+ t->flags &= ~hasStat;
2501
+ if (name[0] == '.' && name[1] == '\0')
2502
+ continue;
2503
+ if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
2504
+ continue;
2505
+ tree_append(t, name, namelen);
2506
+ return (t->visit_type = TREE_REGULAR);
2507
+ }
2508
+ }
2509
+
2510
+
2511
+ /*
2512
+ * Get the stat() data for the entry just returned from tree_next().
2513
+ */
2514
+ static const struct stat *
2515
+ tree_current_stat(struct tree *t)
2516
+ {
2517
+ if (!(t->flags & hasStat)) {
2518
+ #ifdef HAVE_FSTATAT
2519
+ if (fstatat(tree_current_dir_fd(t),
2520
+ tree_current_access_path(t), &t->st, 0) != 0)
2521
+ #else
2522
+ if (tree_enter_working_dir(t) != 0)
2523
+ return NULL;
2524
+ if (la_stat(tree_current_access_path(t), &t->st) != 0)
2525
+ #endif
2526
+ return NULL;
2527
+ t->flags |= hasStat;
2528
+ }
2529
+ return (&t->st);
2530
+ }
2531
+
2532
+ /*
2533
+ * Get the lstat() data for the entry just returned from tree_next().
2534
+ */
2535
+ static const struct stat *
2536
+ tree_current_lstat(struct tree *t)
2537
+ {
2538
+ if (!(t->flags & hasLstat)) {
2539
+ #ifdef HAVE_FSTATAT
2540
+ if (fstatat(tree_current_dir_fd(t),
2541
+ tree_current_access_path(t), &t->lst,
2542
+ AT_SYMLINK_NOFOLLOW) != 0)
2543
+ #else
2544
+ if (tree_enter_working_dir(t) != 0)
2545
+ return NULL;
2546
+ if (lstat(tree_current_access_path(t), &t->lst) != 0)
2547
+ #endif
2548
+ return NULL;
2549
+ t->flags |= hasLstat;
2550
+ }
2551
+ return (&t->lst);
2552
+ }
2553
+
2554
+ /*
2555
+ * Test whether current entry is a dir or link to a dir.
2556
+ */
2557
+ static int
2558
+ tree_current_is_dir(struct tree *t)
2559
+ {
2560
+ const struct stat *st;
2561
+ /*
2562
+ * If we already have lstat() info, then try some
2563
+ * cheap tests to determine if this is a dir.
2564
+ */
2565
+ if (t->flags & hasLstat) {
2566
+ /* If lstat() says it's a dir, it must be a dir. */
2567
+ st = tree_current_lstat(t);
2568
+ if (st == NULL)
2569
+ return 0;
2570
+ if (S_ISDIR(st->st_mode))
2571
+ return 1;
2572
+ /* Not a dir; might be a link to a dir. */
2573
+ /* If it's not a link, then it's not a link to a dir. */
2574
+ if (!S_ISLNK(st->st_mode))
2575
+ return 0;
2576
+ /*
2577
+ * It's a link, but we don't know what it's a link to,
2578
+ * so we'll have to use stat().
2579
+ */
2580
+ }
2581
+
2582
+ st = tree_current_stat(t);
2583
+ /* If we can't stat it, it's not a dir. */
2584
+ if (st == NULL)
2585
+ return 0;
2586
+ /* Use the definitive test. Hopefully this is cached. */
2587
+ return (S_ISDIR(st->st_mode));
2588
+ }
2589
+
2590
+ /*
2591
+ * Test whether current entry is a physical directory. Usually, we
2592
+ * already have at least one of stat() or lstat() in memory, so we
2593
+ * use tricks to try to avoid an extra trip to the disk.
2594
+ */
2595
+ static int
2596
+ tree_current_is_physical_dir(struct tree *t)
2597
+ {
2598
+ const struct stat *st;
2599
+
2600
+ /*
2601
+ * If stat() says it isn't a dir, then it's not a dir.
2602
+ * If stat() data is cached, this check is free, so do it first.
2603
+ */
2604
+ if (t->flags & hasStat) {
2605
+ st = tree_current_stat(t);
2606
+ if (st == NULL)
2607
+ return (0);
2608
+ if (!S_ISDIR(st->st_mode))
2609
+ return (0);
2610
+ }
2611
+
2612
+ /*
2613
+ * Either stat() said it was a dir (in which case, we have
2614
+ * to determine whether it's really a link to a dir) or
2615
+ * stat() info wasn't available. So we use lstat(), which
2616
+ * hopefully is already cached.
2617
+ */
2618
+
2619
+ st = tree_current_lstat(t);
2620
+ /* If we can't stat it, it's not a dir. */
2621
+ if (st == NULL)
2622
+ return 0;
2623
+ /* Use the definitive test. Hopefully this is cached. */
2624
+ return (S_ISDIR(st->st_mode));
2625
+ }
2626
+
2627
+ /*
2628
+ * Test whether the same file has been in the tree as its parent.
2629
+ */
2630
+ static int
2631
+ tree_target_is_same_as_parent(struct tree *t, const struct stat *st)
2632
+ {
2633
+ struct tree_entry *te;
2634
+
2635
+ for (te = t->current->parent; te != NULL; te = te->parent) {
2636
+ if (te->dev == (int64_t)st->st_dev &&
2637
+ te->ino == (int64_t)st->st_ino)
2638
+ return (1);
2639
+ }
2640
+ return (0);
2641
+ }
2642
+
2643
+ /*
2644
+ * Test whether the current file is symbolic link target and
2645
+ * on the other filesystem.
2646
+ */
2647
+ static int
2648
+ tree_current_is_symblic_link_target(struct tree *t)
2649
+ {
2650
+ static const struct stat *lst, *st;
2651
+
2652
+ lst = tree_current_lstat(t);
2653
+ st = tree_current_stat(t);
2654
+ return (st != NULL && lst != NULL &&
2655
+ (int64_t)st->st_dev == t->current_filesystem->dev &&
2656
+ st->st_dev != lst->st_dev);
2657
+ }
2658
+
2659
+ /*
2660
+ * Return the access path for the entry just returned from tree_next().
2661
+ */
2662
+ static const char *
2663
+ tree_current_access_path(struct tree *t)
2664
+ {
2665
+ return (t->basename);
2666
+ }
2667
+
2668
+ /*
2669
+ * Return the full path for the entry just returned from tree_next().
2670
+ */
2671
+ static const char *
2672
+ tree_current_path(struct tree *t)
2673
+ {
2674
+ return (t->path.s);
2675
+ }
2676
+
2677
+ /*
2678
+ * Terminate the traversal.
2679
+ */
2680
+ static void
2681
+ tree_close(struct tree *t)
2682
+ {
2683
+
2684
+ if (t == NULL)
2685
+ return;
2686
+ if (t->entry_fd >= 0) {
2687
+ close_and_restore_time(t->entry_fd, t, &t->restore_time);
2688
+ t->entry_fd = -1;
2689
+ }
2690
+ /* Close the handle of readdir(). */
2691
+ if (t->d != INVALID_DIR_HANDLE) {
2692
+ closedir(t->d);
2693
+ t->d = INVALID_DIR_HANDLE;
2694
+ }
2695
+ /* Release anything remaining in the stack. */
2696
+ while (t->stack != NULL) {
2697
+ if (t->stack->flags & isDirLink)
2698
+ close(t->stack->symlink_parent_fd);
2699
+ tree_pop(t);
2700
+ }
2701
+ if (t->working_dir_fd >= 0) {
2702
+ close(t->working_dir_fd);
2703
+ t->working_dir_fd = -1;
2704
+ }
2705
+ if (t->initial_dir_fd >= 0) {
2706
+ close(t->initial_dir_fd);
2707
+ t->initial_dir_fd = -1;
2708
+ }
2709
+ }
2710
+
2711
+ /*
2712
+ * Release any resources.
2713
+ */
2714
+ static void
2715
+ tree_free(struct tree *t)
2716
+ {
2717
+ int i;
2718
+
2719
+ if (t == NULL)
2720
+ return;
2721
+ archive_string_free(&t->path);
2722
+ #if defined(USE_READDIR_R)
2723
+ free(t->dirent);
2724
+ #endif
2725
+ free(t->sparse_list);
2726
+ for (i = 0; i < t->max_filesystem_id; i++)
2727
+ free(t->filesystem_table[i].allocation_ptr);
2728
+ free(t->filesystem_table);
2729
+ free(t);
2730
+ }
2731
+
2732
+ #endif