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,2217 @@
1
+ /*-
2
+ * Copyright (c) 2008 Joerg Sonnenberger
3
+ * Copyright (c) 2009-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
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ */
26
+
27
+ #include "archive_platform.h"
28
+ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
29
+
30
+ #ifdef HAVE_SYS_TYPES_H
31
+ #include <sys/types.h>
32
+ #endif
33
+ #include <errno.h>
34
+ #include <stdlib.h>
35
+ #include <string.h>
36
+
37
+ #include "archive.h"
38
+ #include "archive_digest_private.h"
39
+ #include "archive_entry.h"
40
+ #include "archive_entry_private.h"
41
+ #include "archive_private.h"
42
+ #include "archive_rb.h"
43
+ #include "archive_string.h"
44
+ #include "archive_write_private.h"
45
+
46
+ #define INDENTNAMELEN 15
47
+ #define MAXLINELEN 80
48
+ #define SET_KEYS \
49
+ (F_FLAGS | F_GID | F_GNAME | F_MODE | F_TYPE | F_UID | F_UNAME)
50
+
51
+ struct attr_counter {
52
+ struct attr_counter *prev;
53
+ struct attr_counter *next;
54
+ struct mtree_entry *m_entry;
55
+ int count;
56
+ };
57
+
58
+ struct att_counter_set {
59
+ struct attr_counter *uid_list;
60
+ struct attr_counter *gid_list;
61
+ struct attr_counter *mode_list;
62
+ struct attr_counter *flags_list;
63
+ };
64
+
65
+ struct mtree_chain {
66
+ struct mtree_entry *first;
67
+ struct mtree_entry **last;
68
+ };
69
+
70
+ /*
71
+ * The Data only for a directory file.
72
+ */
73
+ struct dir_info {
74
+ struct archive_rb_tree rbtree;
75
+ struct mtree_chain children;
76
+ struct mtree_entry *chnext;
77
+ int virtual;
78
+ };
79
+
80
+ /*
81
+ * The Data only for a regular file.
82
+ */
83
+ struct reg_info {
84
+ int compute_sum;
85
+ uint32_t crc;
86
+ struct ae_digest digest;
87
+ };
88
+
89
+ struct mtree_entry {
90
+ struct archive_rb_node rbnode;
91
+ struct mtree_entry *next;
92
+ struct mtree_entry *parent;
93
+ struct dir_info *dir_info;
94
+ struct reg_info *reg_info;
95
+
96
+ struct archive_string parentdir;
97
+ struct archive_string basename;
98
+ struct archive_string pathname;
99
+ struct archive_string symlink;
100
+ struct archive_string uname;
101
+ struct archive_string gname;
102
+ struct archive_string fflags_text;
103
+ unsigned int nlink;
104
+ mode_t filetype;
105
+ mode_t mode;
106
+ int64_t size;
107
+ int64_t uid;
108
+ int64_t gid;
109
+ time_t mtime;
110
+ long mtime_nsec;
111
+ unsigned long fflags_set;
112
+ unsigned long fflags_clear;
113
+ dev_t rdevmajor;
114
+ dev_t rdevminor;
115
+ dev_t devmajor;
116
+ dev_t devminor;
117
+ int64_t ino;
118
+ };
119
+
120
+ struct mtree_writer {
121
+ struct mtree_entry *mtree_entry;
122
+ struct mtree_entry *root;
123
+ struct mtree_entry *cur_dirent;
124
+ struct archive_string cur_dirstr;
125
+ struct mtree_chain file_list;
126
+
127
+ struct archive_string ebuf;
128
+ struct archive_string buf;
129
+ int first;
130
+ uint64_t entry_bytes_remaining;
131
+
132
+ /*
133
+ * Set global value.
134
+ */
135
+ struct {
136
+ int processing;
137
+ mode_t type;
138
+ int keys;
139
+ int64_t uid;
140
+ int64_t gid;
141
+ mode_t mode;
142
+ unsigned long fflags_set;
143
+ unsigned long fflags_clear;
144
+ } set;
145
+ struct att_counter_set acs;
146
+ int classic;
147
+ int depth;
148
+
149
+ /* check sum */
150
+ int compute_sum;
151
+ uint32_t crc;
152
+ uint64_t crc_len;
153
+ #ifdef ARCHIVE_HAS_MD5
154
+ archive_md5_ctx md5ctx;
155
+ #endif
156
+ #ifdef ARCHIVE_HAS_RMD160
157
+ archive_rmd160_ctx rmd160ctx;
158
+ #endif
159
+ #ifdef ARCHIVE_HAS_SHA1
160
+ archive_sha1_ctx sha1ctx;
161
+ #endif
162
+ #ifdef ARCHIVE_HAS_SHA256
163
+ archive_sha256_ctx sha256ctx;
164
+ #endif
165
+ #ifdef ARCHIVE_HAS_SHA384
166
+ archive_sha384_ctx sha384ctx;
167
+ #endif
168
+ #ifdef ARCHIVE_HAS_SHA512
169
+ archive_sha512_ctx sha512ctx;
170
+ #endif
171
+ /* Keyword options */
172
+ int keys;
173
+ #define F_CKSUM 0x00000001 /* checksum */
174
+ #define F_DEV 0x00000002 /* device type */
175
+ #define F_DONE 0x00000004 /* directory done */
176
+ #define F_FLAGS 0x00000008 /* file flags */
177
+ #define F_GID 0x00000010 /* gid */
178
+ #define F_GNAME 0x00000020 /* group name */
179
+ #define F_IGN 0x00000040 /* ignore */
180
+ #define F_MAGIC 0x00000080 /* name has magic chars */
181
+ #define F_MD5 0x00000100 /* MD5 digest */
182
+ #define F_MODE 0x00000200 /* mode */
183
+ #define F_NLINK 0x00000400 /* number of links */
184
+ #define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do
185
+ * not change */
186
+ #define F_OPT 0x00001000 /* existence optional */
187
+ #define F_RMD160 0x00002000 /* RIPEMD160 digest */
188
+ #define F_SHA1 0x00004000 /* SHA-1 digest */
189
+ #define F_SIZE 0x00008000 /* size */
190
+ #define F_SLINK 0x00010000 /* symbolic link */
191
+ #define F_TAGS 0x00020000 /* tags */
192
+ #define F_TIME 0x00040000 /* modification time */
193
+ #define F_TYPE 0x00080000 /* file type */
194
+ #define F_UID 0x00100000 /* uid */
195
+ #define F_UNAME 0x00200000 /* user name */
196
+ #define F_VISIT 0x00400000 /* file visited */
197
+ #define F_SHA256 0x00800000 /* SHA-256 digest */
198
+ #define F_SHA384 0x01000000 /* SHA-384 digest */
199
+ #define F_SHA512 0x02000000 /* SHA-512 digest */
200
+ #define F_INO 0x04000000 /* inode number */
201
+ #define F_RESDEV 0x08000000 /* device ID on which the
202
+ * entry resides */
203
+
204
+ /* Options */
205
+ int dironly; /* If it is set, ignore all files except
206
+ * directory files, like mtree(8) -d option. */
207
+ int indent; /* If it is set, indent output data. */
208
+ int output_global_set; /* If it is set, use /set keyword to set
209
+ * global values. When generating mtree
210
+ * classic format, it is set by default. */
211
+ };
212
+
213
+ #define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
214
+ | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
215
+ | F_UNAME)
216
+ #define attr_counter_set_reset attr_counter_set_free
217
+
218
+ static void attr_counter_free(struct attr_counter **);
219
+ static int attr_counter_inc(struct attr_counter **, struct attr_counter *,
220
+ struct attr_counter *, struct mtree_entry *);
221
+ static struct attr_counter * attr_counter_new(struct mtree_entry *,
222
+ struct attr_counter *);
223
+ static int attr_counter_set_collect(struct mtree_writer *,
224
+ struct mtree_entry *);
225
+ static void attr_counter_set_free(struct mtree_writer *);
226
+ static int get_global_set_keys(struct mtree_writer *, struct mtree_entry *);
227
+ static int mtree_entry_add_child_tail(struct mtree_entry *,
228
+ struct mtree_entry *);
229
+ static int mtree_entry_create_virtual_dir(struct archive_write *, const char *,
230
+ struct mtree_entry **);
231
+ static int mtree_entry_cmp_node(const struct archive_rb_node *,
232
+ const struct archive_rb_node *);
233
+ static int mtree_entry_cmp_key(const struct archive_rb_node *, const void *);
234
+ static int mtree_entry_exchange_same_entry(struct archive_write *,
235
+ struct mtree_entry *, struct mtree_entry *);
236
+ static void mtree_entry_free(struct mtree_entry *);
237
+ static int mtree_entry_new(struct archive_write *, struct archive_entry *,
238
+ struct mtree_entry **);
239
+ static void mtree_entry_register_free(struct mtree_writer *);
240
+ static void mtree_entry_register_init(struct mtree_writer *);
241
+ static int mtree_entry_setup_filenames(struct archive_write *,
242
+ struct mtree_entry *, struct archive_entry *);
243
+ static int mtree_entry_tree_add(struct archive_write *, struct mtree_entry **);
244
+ static void sum_init(struct mtree_writer *);
245
+ static void sum_update(struct mtree_writer *, const void *, size_t);
246
+ static void sum_final(struct mtree_writer *, struct reg_info *);
247
+ static void sum_write(struct archive_string *, struct reg_info *);
248
+ static int write_mtree_entry(struct archive_write *, struct mtree_entry *);
249
+ static int write_dot_dot_entry(struct archive_write *, struct mtree_entry *);
250
+
251
+ #define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
252
+ static const uint32_t crctab[] = {
253
+ 0x0,
254
+ 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
255
+ 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
256
+ 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
257
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
258
+ 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
259
+ 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
260
+ 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
261
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
262
+ 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
263
+ 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
264
+ 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
265
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
266
+ 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
267
+ 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
268
+ 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
269
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
270
+ 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
271
+ 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
272
+ 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
273
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
274
+ 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
275
+ 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
276
+ 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
277
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
278
+ 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
279
+ 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
280
+ 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
281
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
282
+ 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
283
+ 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
284
+ 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
285
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
286
+ 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
287
+ 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
288
+ 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
289
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
290
+ 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
291
+ 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
292
+ 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
293
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
294
+ 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
295
+ 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
296
+ 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
297
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
298
+ 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
299
+ 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
300
+ 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
301
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
302
+ 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
303
+ 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
304
+ 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
305
+ };
306
+
307
+ static const unsigned char safe_char[256] = {
308
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 0F */
309
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1F */
310
+ /* !"$%&'()*+,-./ EXCLUSION:0x20( ) 0x23(#) */
311
+ 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 - 2F */
312
+ /* 0123456789:;<>? EXCLUSION:0x3d(=) */
313
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, /* 30 - 3F */
314
+ /* @ABCDEFGHIJKLMNO */
315
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 - 4F */
316
+ /* PQRSTUVWXYZ[]^_ EXCLUSION:0x5c(\) */
317
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, /* 50 - 5F */
318
+ /* `abcdefghijklmno */
319
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 - 6F */
320
+ /* pqrstuvwxyz{|}~ */
321
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* 70 - 7F */
322
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8F */
323
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9F */
324
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* A0 - AF */
325
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* B0 - BF */
326
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* C0 - CF */
327
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* D0 - DF */
328
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* E0 - EF */
329
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F0 - FF */
330
+ };
331
+
332
+ static void
333
+ mtree_quote(struct archive_string *s, const char *str)
334
+ {
335
+ const char *start;
336
+ char buf[4];
337
+ unsigned char c;
338
+
339
+ for (start = str; *str != '\0'; ++str) {
340
+ if (safe_char[*(const unsigned char *)str])
341
+ continue;
342
+ if (start != str)
343
+ archive_strncat(s, start, str - start);
344
+ c = (unsigned char)*str;
345
+ buf[0] = '\\';
346
+ buf[1] = (c / 64) + '0';
347
+ buf[2] = (c / 8 % 8) + '0';
348
+ buf[3] = (c % 8) + '0';
349
+ archive_strncat(s, buf, 4);
350
+ start = str + 1;
351
+ }
352
+
353
+ if (start != str)
354
+ archive_strncat(s, start, str - start);
355
+ }
356
+
357
+ /*
358
+ * Indent a line as the mtree utility does so it is readable for people.
359
+ */
360
+ static void
361
+ mtree_indent(struct mtree_writer *mtree)
362
+ {
363
+ int i, fn, nd, pd;
364
+ const char *r, *s, *x;
365
+
366
+ if (mtree->classic) {
367
+ if (mtree->indent) {
368
+ nd = 0;
369
+ pd = mtree->depth * 4;
370
+ } else {
371
+ nd = mtree->depth?4:0;
372
+ pd = 0;
373
+ }
374
+ } else
375
+ nd = pd = 0;
376
+ fn = 1;
377
+ s = r = mtree->ebuf.s;
378
+ x = NULL;
379
+ while (*r == ' ')
380
+ r++;
381
+ while ((r = strchr(r, ' ')) != NULL) {
382
+ if (fn) {
383
+ fn = 0;
384
+ for (i = 0; i < nd + pd; i++)
385
+ archive_strappend_char(&mtree->buf, ' ');
386
+ archive_strncat(&mtree->buf, s, r - s);
387
+ if (nd + (r -s) > INDENTNAMELEN) {
388
+ archive_strncat(&mtree->buf, " \\\n", 3);
389
+ for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
390
+ archive_strappend_char(&mtree->buf, ' ');
391
+ } else {
392
+ for (i = (int)(r -s + nd);
393
+ i < (INDENTNAMELEN + 1); i++)
394
+ archive_strappend_char(&mtree->buf, ' ');
395
+ }
396
+ s = ++r;
397
+ x = NULL;
398
+ continue;
399
+ }
400
+ if (pd + (r - s) <= MAXLINELEN - 3 - INDENTNAMELEN)
401
+ x = r++;
402
+ else {
403
+ if (x == NULL)
404
+ x = r;
405
+ archive_strncat(&mtree->buf, s, x - s);
406
+ archive_strncat(&mtree->buf, " \\\n", 3);
407
+ for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
408
+ archive_strappend_char(&mtree->buf, ' ');
409
+ s = r = ++x;
410
+ x = NULL;
411
+ }
412
+ }
413
+ if (fn) {
414
+ for (i = 0; i < nd + pd; i++)
415
+ archive_strappend_char(&mtree->buf, ' ');
416
+ archive_strcat(&mtree->buf, s);
417
+ s += strlen(s);
418
+ }
419
+ if (x != NULL && pd + strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
420
+ /* Last keyword is longer. */
421
+ archive_strncat(&mtree->buf, s, x - s);
422
+ archive_strncat(&mtree->buf, " \\\n", 3);
423
+ for (i = 0; i < (INDENTNAMELEN + 1 + pd); i++)
424
+ archive_strappend_char(&mtree->buf, ' ');
425
+ s = ++x;
426
+ }
427
+ archive_strcat(&mtree->buf, s);
428
+ archive_string_empty(&mtree->ebuf);
429
+ }
430
+
431
+ /*
432
+ * Write /set keyword.
433
+ * Set the most used value of uid, gid, mode and fflags, which are
434
+ * collected by the attr_counter_set_collect() function.
435
+ */
436
+ static void
437
+ write_global(struct mtree_writer *mtree)
438
+ {
439
+ struct archive_string setstr;
440
+ struct archive_string unsetstr;
441
+ struct att_counter_set *acs;
442
+ int keys, oldkeys, effkeys;
443
+
444
+ archive_string_init(&setstr);
445
+ archive_string_init(&unsetstr);
446
+ keys = mtree->keys & SET_KEYS;
447
+ oldkeys = mtree->set.keys;
448
+ effkeys = keys;
449
+ acs = &mtree->acs;
450
+ if (mtree->set.processing) {
451
+ /*
452
+ * Check if the global data needs updating.
453
+ */
454
+ effkeys &= ~F_TYPE;
455
+ if (acs->uid_list == NULL)
456
+ effkeys &= ~(F_UNAME | F_UID);
457
+ else if (oldkeys & (F_UNAME | F_UID)) {
458
+ if (acs->uid_list->count < 2 ||
459
+ mtree->set.uid == acs->uid_list->m_entry->uid)
460
+ effkeys &= ~(F_UNAME | F_UID);
461
+ }
462
+ if (acs->gid_list == NULL)
463
+ effkeys &= ~(F_GNAME | F_GID);
464
+ else if (oldkeys & (F_GNAME | F_GID)) {
465
+ if (acs->gid_list->count < 2 ||
466
+ mtree->set.gid == acs->gid_list->m_entry->gid)
467
+ effkeys &= ~(F_GNAME | F_GID);
468
+ }
469
+ if (acs->mode_list == NULL)
470
+ effkeys &= ~F_MODE;
471
+ else if (oldkeys & F_MODE) {
472
+ if (acs->mode_list->count < 2 ||
473
+ mtree->set.mode == acs->mode_list->m_entry->mode)
474
+ effkeys &= ~F_MODE;
475
+ }
476
+ if (acs->flags_list == NULL)
477
+ effkeys &= ~F_FLAGS;
478
+ else if ((oldkeys & F_FLAGS) != 0) {
479
+ if (acs->flags_list->count < 2 ||
480
+ (acs->flags_list->m_entry->fflags_set ==
481
+ mtree->set.fflags_set &&
482
+ acs->flags_list->m_entry->fflags_clear ==
483
+ mtree->set.fflags_clear))
484
+ effkeys &= ~F_FLAGS;
485
+ }
486
+ } else {
487
+ if (acs->uid_list == NULL)
488
+ keys &= ~(F_UNAME | F_UID);
489
+ if (acs->gid_list == NULL)
490
+ keys &= ~(F_GNAME | F_GID);
491
+ if (acs->mode_list == NULL)
492
+ keys &= ~F_MODE;
493
+ if (acs->flags_list == NULL)
494
+ keys &= ~F_FLAGS;
495
+ }
496
+ if ((keys & effkeys & F_TYPE) != 0) {
497
+ if (mtree->dironly) {
498
+ archive_strcat(&setstr, " type=dir");
499
+ mtree->set.type = AE_IFDIR;
500
+ } else {
501
+ archive_strcat(&setstr, " type=file");
502
+ mtree->set.type = AE_IFREG;
503
+ }
504
+ }
505
+ if ((keys & effkeys & F_UNAME) != 0) {
506
+ if (archive_strlen(&(acs->uid_list->m_entry->uname)) > 0) {
507
+ archive_strcat(&setstr, " uname=");
508
+ mtree_quote(&setstr, acs->uid_list->m_entry->uname.s);
509
+ } else {
510
+ keys &= ~F_UNAME;
511
+ if ((oldkeys & F_UNAME) != 0)
512
+ archive_strcat(&unsetstr, " uname");
513
+ }
514
+ }
515
+ if ((keys & effkeys & F_UID) != 0) {
516
+ mtree->set.uid = acs->uid_list->m_entry->uid;
517
+ archive_string_sprintf(&setstr, " uid=%jd",
518
+ (intmax_t)mtree->set.uid);
519
+ }
520
+ if ((keys & effkeys & F_GNAME) != 0) {
521
+ if (archive_strlen(&(acs->gid_list->m_entry->gname)) > 0) {
522
+ archive_strcat(&setstr, " gname=");
523
+ mtree_quote(&setstr, acs->gid_list->m_entry->gname.s);
524
+ } else {
525
+ keys &= ~F_GNAME;
526
+ if ((oldkeys & F_GNAME) != 0)
527
+ archive_strcat(&unsetstr, " gname");
528
+ }
529
+ }
530
+ if ((keys & effkeys & F_GID) != 0) {
531
+ mtree->set.gid = acs->gid_list->m_entry->gid;
532
+ archive_string_sprintf(&setstr, " gid=%jd",
533
+ (intmax_t)mtree->set.gid);
534
+ }
535
+ if ((keys & effkeys & F_MODE) != 0) {
536
+ mtree->set.mode = acs->mode_list->m_entry->mode;
537
+ archive_string_sprintf(&setstr, " mode=%o",
538
+ (unsigned int)mtree->set.mode);
539
+ }
540
+ if ((keys & effkeys & F_FLAGS) != 0) {
541
+ if (archive_strlen(
542
+ &(acs->flags_list->m_entry->fflags_text)) > 0) {
543
+ archive_strcat(&setstr, " flags=");
544
+ mtree_quote(&setstr,
545
+ acs->flags_list->m_entry->fflags_text.s);
546
+ mtree->set.fflags_set =
547
+ acs->flags_list->m_entry->fflags_set;
548
+ mtree->set.fflags_clear =
549
+ acs->flags_list->m_entry->fflags_clear;
550
+ } else {
551
+ keys &= ~F_FLAGS;
552
+ if ((oldkeys & F_FLAGS) != 0)
553
+ archive_strcat(&unsetstr, " flags");
554
+ }
555
+ }
556
+ if (unsetstr.length > 0)
557
+ archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
558
+ archive_string_free(&unsetstr);
559
+ if (setstr.length > 0)
560
+ archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
561
+ archive_string_free(&setstr);
562
+ mtree->set.keys = keys;
563
+ mtree->set.processing = 1;
564
+ }
565
+
566
+ static struct attr_counter *
567
+ attr_counter_new(struct mtree_entry *me, struct attr_counter *prev)
568
+ {
569
+ struct attr_counter *ac;
570
+
571
+ ac = malloc(sizeof(*ac));
572
+ if (ac != NULL) {
573
+ ac->prev = prev;
574
+ ac->next = NULL;
575
+ ac->count = 1;
576
+ ac->m_entry = me;
577
+ }
578
+ return (ac);
579
+ }
580
+
581
+ static void
582
+ attr_counter_free(struct attr_counter **top)
583
+ {
584
+ struct attr_counter *ac, *tac;
585
+
586
+ if (*top == NULL)
587
+ return;
588
+ ac = *top;
589
+ while (ac != NULL) {
590
+ tac = ac->next;
591
+ free(ac);
592
+ ac = tac;
593
+ }
594
+ *top = NULL;
595
+ }
596
+
597
+ static int
598
+ attr_counter_inc(struct attr_counter **top, struct attr_counter *ac,
599
+ struct attr_counter *last, struct mtree_entry *me)
600
+ {
601
+ struct attr_counter *pac;
602
+
603
+ if (ac != NULL) {
604
+ ac->count++;
605
+ if (*top == ac || ac->prev->count >= ac->count)
606
+ return (0);
607
+ for (pac = ac->prev; pac; pac = pac->prev) {
608
+ if (pac->count >= ac->count)
609
+ break;
610
+ }
611
+ ac->prev->next = ac->next;
612
+ if (ac->next != NULL)
613
+ ac->next->prev = ac->prev;
614
+ if (pac != NULL) {
615
+ ac->prev = pac;
616
+ ac->next = pac->next;
617
+ pac->next = ac;
618
+ if (ac->next != NULL)
619
+ ac->next->prev = ac;
620
+ } else {
621
+ ac->prev = NULL;
622
+ ac->next = *top;
623
+ *top = ac;
624
+ ac->next->prev = ac;
625
+ }
626
+ } else if (last != NULL) {
627
+ ac = attr_counter_new(me, last);
628
+ if (ac == NULL)
629
+ return (-1);
630
+ last->next = ac;
631
+ }
632
+ return (0);
633
+ }
634
+
635
+ /*
636
+ * Tabulate uid, gid, mode and fflags of a entry in order to be used for /set.
637
+ */
638
+ static int
639
+ attr_counter_set_collect(struct mtree_writer *mtree, struct mtree_entry *me)
640
+ {
641
+ struct attr_counter *ac, *last;
642
+ struct att_counter_set *acs = &mtree->acs;
643
+ int keys = mtree->keys;
644
+
645
+ if (keys & (F_UNAME | F_UID)) {
646
+ if (acs->uid_list == NULL) {
647
+ acs->uid_list = attr_counter_new(me, NULL);
648
+ if (acs->uid_list == NULL)
649
+ return (-1);
650
+ } else {
651
+ last = NULL;
652
+ for (ac = acs->uid_list; ac; ac = ac->next) {
653
+ if (ac->m_entry->uid == me->uid)
654
+ break;
655
+ last = ac;
656
+ }
657
+ if (attr_counter_inc(&acs->uid_list, ac, last, me) < 0)
658
+ return (-1);
659
+ }
660
+ }
661
+ if (keys & (F_GNAME | F_GID)) {
662
+ if (acs->gid_list == NULL) {
663
+ acs->gid_list = attr_counter_new(me, NULL);
664
+ if (acs->gid_list == NULL)
665
+ return (-1);
666
+ } else {
667
+ last = NULL;
668
+ for (ac = acs->gid_list; ac; ac = ac->next) {
669
+ if (ac->m_entry->gid == me->gid)
670
+ break;
671
+ last = ac;
672
+ }
673
+ if (attr_counter_inc(&acs->gid_list, ac, last, me) < 0)
674
+ return (-1);
675
+ }
676
+ }
677
+ if (keys & F_MODE) {
678
+ if (acs->mode_list == NULL) {
679
+ acs->mode_list = attr_counter_new(me, NULL);
680
+ if (acs->mode_list == NULL)
681
+ return (-1);
682
+ } else {
683
+ last = NULL;
684
+ for (ac = acs->mode_list; ac; ac = ac->next) {
685
+ if (ac->m_entry->mode == me->mode)
686
+ break;
687
+ last = ac;
688
+ }
689
+ if (attr_counter_inc(&acs->mode_list, ac, last, me) < 0)
690
+ return (-1);
691
+ }
692
+ }
693
+ if (keys & F_FLAGS) {
694
+ if (acs->flags_list == NULL) {
695
+ acs->flags_list = attr_counter_new(me, NULL);
696
+ if (acs->flags_list == NULL)
697
+ return (-1);
698
+ } else {
699
+ last = NULL;
700
+ for (ac = acs->flags_list; ac; ac = ac->next) {
701
+ if (ac->m_entry->fflags_set == me->fflags_set &&
702
+ ac->m_entry->fflags_clear ==
703
+ me->fflags_clear)
704
+ break;
705
+ last = ac;
706
+ }
707
+ if (attr_counter_inc(&acs->flags_list, ac, last, me) < 0)
708
+ return (-1);
709
+ }
710
+ }
711
+
712
+ return (0);
713
+ }
714
+
715
+ static void
716
+ attr_counter_set_free(struct mtree_writer *mtree)
717
+ {
718
+ struct att_counter_set *acs = &mtree->acs;
719
+
720
+ attr_counter_free(&acs->uid_list);
721
+ attr_counter_free(&acs->gid_list);
722
+ attr_counter_free(&acs->mode_list);
723
+ attr_counter_free(&acs->flags_list);
724
+ }
725
+
726
+ static int
727
+ get_global_set_keys(struct mtree_writer *mtree, struct mtree_entry *me)
728
+ {
729
+ int keys;
730
+
731
+ keys = mtree->keys;
732
+
733
+ /*
734
+ * If a keyword has been set by /set, we do not need to
735
+ * output it.
736
+ */
737
+ if (mtree->set.keys == 0)
738
+ return (keys);/* /set is not used. */
739
+
740
+ if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
741
+ mtree->set.gid == me->gid)
742
+ keys &= ~(F_GNAME | F_GID);
743
+ if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
744
+ mtree->set.uid == me->uid)
745
+ keys &= ~(F_UNAME | F_UID);
746
+ if (mtree->set.keys & F_FLAGS) {
747
+ if (mtree->set.fflags_set == me->fflags_set &&
748
+ mtree->set.fflags_clear == me->fflags_clear)
749
+ keys &= ~F_FLAGS;
750
+ }
751
+ if ((mtree->set.keys & F_MODE) != 0 && mtree->set.mode == me->mode)
752
+ keys &= ~F_MODE;
753
+
754
+ switch (me->filetype) {
755
+ case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
756
+ case AE_IFBLK: case AE_IFIFO:
757
+ break;
758
+ case AE_IFDIR:
759
+ if ((mtree->set.keys & F_TYPE) != 0 &&
760
+ mtree->set.type == AE_IFDIR)
761
+ keys &= ~F_TYPE;
762
+ break;
763
+ case AE_IFREG:
764
+ default: /* Handle unknown file types as regular files. */
765
+ if ((mtree->set.keys & F_TYPE) != 0 &&
766
+ mtree->set.type == AE_IFREG)
767
+ keys &= ~F_TYPE;
768
+ break;
769
+ }
770
+
771
+ return (keys);
772
+ }
773
+
774
+ static int
775
+ mtree_entry_new(struct archive_write *a, struct archive_entry *entry,
776
+ struct mtree_entry **m_entry)
777
+ {
778
+ struct mtree_entry *me;
779
+ const char *s;
780
+ int r;
781
+ static const struct archive_rb_tree_ops rb_ops = {
782
+ mtree_entry_cmp_node, mtree_entry_cmp_key
783
+ };
784
+
785
+ me = calloc(1, sizeof(*me));
786
+ if (me == NULL) {
787
+ archive_set_error(&a->archive, ENOMEM,
788
+ "Can't allocate memory for a mtree entry");
789
+ *m_entry = NULL;
790
+ return (ARCHIVE_FATAL);
791
+ }
792
+
793
+ r = mtree_entry_setup_filenames(a, me, entry);
794
+ if (r < ARCHIVE_WARN) {
795
+ mtree_entry_free(me);
796
+ *m_entry = NULL;
797
+ return (r);
798
+ }
799
+
800
+ if ((s = archive_entry_symlink(entry)) != NULL)
801
+ archive_strcpy(&me->symlink, s);
802
+ me->nlink = archive_entry_nlink(entry);
803
+ me->filetype = archive_entry_filetype(entry);
804
+ me->mode = archive_entry_mode(entry) & 07777;
805
+ me->uid = archive_entry_uid(entry);
806
+ me->gid = archive_entry_gid(entry);
807
+ if ((s = archive_entry_uname(entry)) != NULL)
808
+ archive_strcpy(&me->uname, s);
809
+ if ((s = archive_entry_gname(entry)) != NULL)
810
+ archive_strcpy(&me->gname, s);
811
+ if ((s = archive_entry_fflags_text(entry)) != NULL)
812
+ archive_strcpy(&me->fflags_text, s);
813
+ archive_entry_fflags(entry, &me->fflags_set, &me->fflags_clear);
814
+ me->mtime = archive_entry_mtime(entry);
815
+ me->mtime_nsec = archive_entry_mtime_nsec(entry);
816
+ me->rdevmajor = archive_entry_rdevmajor(entry);
817
+ me->rdevminor = archive_entry_rdevminor(entry);
818
+ me->devmajor = archive_entry_devmajor(entry);
819
+ me->devminor = archive_entry_devminor(entry);
820
+ me->ino = archive_entry_ino(entry);
821
+ me->size = archive_entry_size(entry);
822
+ if (me->filetype == AE_IFDIR) {
823
+ me->dir_info = calloc(1, sizeof(*me->dir_info));
824
+ if (me->dir_info == NULL) {
825
+ mtree_entry_free(me);
826
+ archive_set_error(&a->archive, ENOMEM,
827
+ "Can't allocate memory for a mtree entry");
828
+ *m_entry = NULL;
829
+ return (ARCHIVE_FATAL);
830
+ }
831
+ __archive_rb_tree_init(&me->dir_info->rbtree, &rb_ops);
832
+ me->dir_info->children.first = NULL;
833
+ me->dir_info->children.last = &(me->dir_info->children.first);
834
+ me->dir_info->chnext = NULL;
835
+ } else if (me->filetype == AE_IFREG) {
836
+ me->reg_info = calloc(1, sizeof(*me->reg_info));
837
+ if (me->reg_info == NULL) {
838
+ mtree_entry_free(me);
839
+ archive_set_error(&a->archive, ENOMEM,
840
+ "Can't allocate memory for a mtree entry");
841
+ *m_entry = NULL;
842
+ return (ARCHIVE_FATAL);
843
+ }
844
+ me->reg_info->compute_sum = 0;
845
+ }
846
+
847
+ *m_entry = me;
848
+ return (ARCHIVE_OK);
849
+ }
850
+
851
+ static void
852
+ mtree_entry_free(struct mtree_entry *me)
853
+ {
854
+ archive_string_free(&me->parentdir);
855
+ archive_string_free(&me->basename);
856
+ archive_string_free(&me->pathname);
857
+ archive_string_free(&me->symlink);
858
+ archive_string_free(&me->uname);
859
+ archive_string_free(&me->gname);
860
+ archive_string_free(&me->fflags_text);
861
+ free(me->dir_info);
862
+ free(me->reg_info);
863
+ free(me);
864
+ }
865
+
866
+ static int
867
+ archive_write_mtree_header(struct archive_write *a,
868
+ struct archive_entry *entry)
869
+ {
870
+ struct mtree_writer *mtree= a->format_data;
871
+ struct mtree_entry *mtree_entry;
872
+ int r, r2;
873
+
874
+ if (mtree->first) {
875
+ mtree->first = 0;
876
+ archive_strcat(&mtree->buf, "#mtree\n");
877
+ if ((mtree->keys & SET_KEYS) == 0)
878
+ mtree->output_global_set = 0;/* Disabled. */
879
+ }
880
+
881
+ mtree->entry_bytes_remaining = archive_entry_size(entry);
882
+
883
+ /* While directory only mode, we do not handle non directory files. */
884
+ if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR)
885
+ return (ARCHIVE_OK);
886
+
887
+ r2 = mtree_entry_new(a, entry, &mtree_entry);
888
+ if (r2 < ARCHIVE_WARN)
889
+ return (r2);
890
+ r = mtree_entry_tree_add(a, &mtree_entry);
891
+ if (r < ARCHIVE_WARN) {
892
+ mtree_entry_free(mtree_entry);
893
+ return (r);
894
+ }
895
+ mtree->mtree_entry = mtree_entry;
896
+
897
+ /* If the current file is a regular file, we have to
898
+ * compute the sum of its content.
899
+ * Initialize a bunch of checksum context. */
900
+ if (mtree_entry->reg_info)
901
+ sum_init(mtree);
902
+
903
+ return (r2);
904
+ }
905
+
906
+ static int
907
+ write_mtree_entry(struct archive_write *a, struct mtree_entry *me)
908
+ {
909
+ struct mtree_writer *mtree = a->format_data;
910
+ struct archive_string *str;
911
+ int keys, ret;
912
+
913
+ if (me->dir_info) {
914
+ if (mtree->classic) {
915
+ /*
916
+ * Output a comment line to describe the full
917
+ * pathname of the entry as mtree utility does
918
+ * while generating classic format.
919
+ */
920
+ if (!mtree->dironly)
921
+ archive_strappend_char(&mtree->buf, '\n');
922
+ if (me->parentdir.s)
923
+ archive_string_sprintf(&mtree->buf,
924
+ "# %s/%s\n",
925
+ me->parentdir.s, me->basename.s);
926
+ else
927
+ archive_string_sprintf(&mtree->buf,
928
+ "# %s\n",
929
+ me->basename.s);
930
+ }
931
+ if (mtree->output_global_set)
932
+ write_global(mtree);
933
+ }
934
+ archive_string_empty(&mtree->ebuf);
935
+ str = (mtree->indent || mtree->classic)? &mtree->ebuf : &mtree->buf;
936
+
937
+ if (!mtree->classic && me->parentdir.s) {
938
+ /*
939
+ * If generating format is not classic one(v1), output
940
+ * a full pathname.
941
+ */
942
+ mtree_quote(str, me->parentdir.s);
943
+ archive_strappend_char(str, '/');
944
+ }
945
+ mtree_quote(str, me->basename.s);
946
+
947
+ keys = get_global_set_keys(mtree, me);
948
+ if ((keys & F_NLINK) != 0 &&
949
+ me->nlink != 1 && me->filetype != AE_IFDIR)
950
+ archive_string_sprintf(str, " nlink=%u", me->nlink);
951
+
952
+ if ((keys & F_GNAME) != 0 && archive_strlen(&me->gname) > 0) {
953
+ archive_strcat(str, " gname=");
954
+ mtree_quote(str, me->gname.s);
955
+ }
956
+ if ((keys & F_UNAME) != 0 && archive_strlen(&me->uname) > 0) {
957
+ archive_strcat(str, " uname=");
958
+ mtree_quote(str, me->uname.s);
959
+ }
960
+ if ((keys & F_FLAGS) != 0) {
961
+ if (archive_strlen(&me->fflags_text) > 0) {
962
+ archive_strcat(str, " flags=");
963
+ mtree_quote(str, me->fflags_text.s);
964
+ } else if (mtree->set.processing &&
965
+ (mtree->set.keys & F_FLAGS) != 0)
966
+ /* Overwrite the global parameter. */
967
+ archive_strcat(str, " flags=none");
968
+ }
969
+ if ((keys & F_TIME) != 0)
970
+ archive_string_sprintf(str, " time=%jd.%jd",
971
+ (intmax_t)me->mtime, (intmax_t)me->mtime_nsec);
972
+ if ((keys & F_MODE) != 0)
973
+ archive_string_sprintf(str, " mode=%o", (unsigned int)me->mode);
974
+ if ((keys & F_GID) != 0)
975
+ archive_string_sprintf(str, " gid=%jd", (intmax_t)me->gid);
976
+ if ((keys & F_UID) != 0)
977
+ archive_string_sprintf(str, " uid=%jd", (intmax_t)me->uid);
978
+
979
+ if ((keys & F_INO) != 0)
980
+ archive_string_sprintf(str, " inode=%jd", (intmax_t)me->ino);
981
+ if ((keys & F_RESDEV) != 0) {
982
+ archive_string_sprintf(str,
983
+ " resdevice=native,%ju,%ju",
984
+ (uintmax_t)me->devmajor,
985
+ (uintmax_t)me->devminor);
986
+ }
987
+
988
+ switch (me->filetype) {
989
+ case AE_IFLNK:
990
+ if ((keys & F_TYPE) != 0)
991
+ archive_strcat(str, " type=link");
992
+ if ((keys & F_SLINK) != 0) {
993
+ archive_strcat(str, " link=");
994
+ mtree_quote(str, me->symlink.s);
995
+ }
996
+ break;
997
+ case AE_IFSOCK:
998
+ if ((keys & F_TYPE) != 0)
999
+ archive_strcat(str, " type=socket");
1000
+ break;
1001
+ case AE_IFCHR:
1002
+ if ((keys & F_TYPE) != 0)
1003
+ archive_strcat(str, " type=char");
1004
+ if ((keys & F_DEV) != 0) {
1005
+ archive_string_sprintf(str,
1006
+ " device=native,%ju,%ju",
1007
+ (uintmax_t)me->rdevmajor,
1008
+ (uintmax_t)me->rdevminor);
1009
+ }
1010
+ break;
1011
+ case AE_IFBLK:
1012
+ if ((keys & F_TYPE) != 0)
1013
+ archive_strcat(str, " type=block");
1014
+ if ((keys & F_DEV) != 0) {
1015
+ archive_string_sprintf(str,
1016
+ " device=native,%ju,%ju",
1017
+ (uintmax_t)me->rdevmajor,
1018
+ (uintmax_t)me->rdevminor);
1019
+ }
1020
+ break;
1021
+ case AE_IFDIR:
1022
+ if ((keys & F_TYPE) != 0)
1023
+ archive_strcat(str, " type=dir");
1024
+ break;
1025
+ case AE_IFIFO:
1026
+ if ((keys & F_TYPE) != 0)
1027
+ archive_strcat(str, " type=fifo");
1028
+ break;
1029
+ case AE_IFREG:
1030
+ default: /* Handle unknown file types as regular files. */
1031
+ if ((keys & F_TYPE) != 0)
1032
+ archive_strcat(str, " type=file");
1033
+ if ((keys & F_SIZE) != 0)
1034
+ archive_string_sprintf(str, " size=%jd",
1035
+ (intmax_t)me->size);
1036
+ break;
1037
+ }
1038
+
1039
+ /* Write a bunch of sum. */
1040
+ if (me->reg_info)
1041
+ sum_write(str, me->reg_info);
1042
+
1043
+ archive_strappend_char(str, '\n');
1044
+ if (mtree->indent || mtree->classic)
1045
+ mtree_indent(mtree);
1046
+
1047
+ if (mtree->buf.length > 32768) {
1048
+ ret = __archive_write_output(
1049
+ a, mtree->buf.s, mtree->buf.length);
1050
+ archive_string_empty(&mtree->buf);
1051
+ } else
1052
+ ret = ARCHIVE_OK;
1053
+ return (ret);
1054
+ }
1055
+
1056
+ static int
1057
+ write_dot_dot_entry(struct archive_write *a, struct mtree_entry *n)
1058
+ {
1059
+ struct mtree_writer *mtree = a->format_data;
1060
+ int ret;
1061
+
1062
+ if (n->parentdir.s) {
1063
+ if (mtree->indent) {
1064
+ int i, pd = mtree->depth * 4;
1065
+ for (i = 0; i < pd; i++)
1066
+ archive_strappend_char(&mtree->buf, ' ');
1067
+ }
1068
+ archive_string_sprintf(&mtree->buf, "# %s/%s\n",
1069
+ n->parentdir.s, n->basename.s);
1070
+ }
1071
+
1072
+ if (mtree->indent) {
1073
+ archive_string_empty(&mtree->ebuf);
1074
+ archive_strncat(&mtree->ebuf, "..\n\n", (mtree->dironly)?3:4);
1075
+ mtree_indent(mtree);
1076
+ } else
1077
+ archive_strncat(&mtree->buf, "..\n\n", (mtree->dironly)?3:4);
1078
+
1079
+ if (mtree->buf.length > 32768) {
1080
+ ret = __archive_write_output(
1081
+ a, mtree->buf.s, mtree->buf.length);
1082
+ archive_string_empty(&mtree->buf);
1083
+ } else
1084
+ ret = ARCHIVE_OK;
1085
+ return (ret);
1086
+ }
1087
+
1088
+ /*
1089
+ * Write mtree entries saved at attr_counter_set_collect() function.
1090
+ */
1091
+ static int
1092
+ write_mtree_entry_tree(struct archive_write *a)
1093
+ {
1094
+ struct mtree_writer *mtree = a->format_data;
1095
+ struct mtree_entry *np = mtree->root;
1096
+ struct archive_rb_node *n;
1097
+ int ret;
1098
+
1099
+ do {
1100
+ if (mtree->output_global_set) {
1101
+ /*
1102
+ * Collect attribute information to know which value
1103
+ * is frequently used among the children.
1104
+ */
1105
+ attr_counter_set_reset(mtree);
1106
+ ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
1107
+ struct mtree_entry *e = (struct mtree_entry *)n;
1108
+ if (attr_counter_set_collect(mtree, e) < 0) {
1109
+ archive_set_error(&a->archive, ENOMEM,
1110
+ "Can't allocate memory");
1111
+ return (ARCHIVE_FATAL);
1112
+ }
1113
+ }
1114
+ }
1115
+ if (!np->dir_info->virtual || mtree->classic) {
1116
+ ret = write_mtree_entry(a, np);
1117
+ if (ret != ARCHIVE_OK)
1118
+ return (ARCHIVE_FATAL);
1119
+ } else {
1120
+ /* Whenever output_global_set is enabled
1121
+ * output global value(/set keywords)
1122
+ * even if the directory entry is not allowed
1123
+ * to be written because the global values
1124
+ * can be used for the children. */
1125
+ if (mtree->output_global_set)
1126
+ write_global(mtree);
1127
+ }
1128
+ /*
1129
+ * Output the attribute of all files except directory files.
1130
+ */
1131
+ mtree->depth++;
1132
+ ARCHIVE_RB_TREE_FOREACH(n, &(np->dir_info->rbtree)) {
1133
+ struct mtree_entry *e = (struct mtree_entry *)n;
1134
+
1135
+ if (e->dir_info)
1136
+ mtree_entry_add_child_tail(np, e);
1137
+ else {
1138
+ ret = write_mtree_entry(a, e);
1139
+ if (ret != ARCHIVE_OK)
1140
+ return (ARCHIVE_FATAL);
1141
+ }
1142
+ }
1143
+ mtree->depth--;
1144
+
1145
+ if (np->dir_info->children.first != NULL) {
1146
+ /*
1147
+ * Descend the tree.
1148
+ */
1149
+ np = np->dir_info->children.first;
1150
+ if (mtree->indent)
1151
+ mtree->depth++;
1152
+ continue;
1153
+ } else if (mtree->classic) {
1154
+ /*
1155
+ * While printing mtree classic, if there are not
1156
+ * any directory files(except "." and "..") in the
1157
+ * directory, output two dots ".." as returning
1158
+ * the parent directory.
1159
+ */
1160
+ ret = write_dot_dot_entry(a, np);
1161
+ if (ret != ARCHIVE_OK)
1162
+ return (ARCHIVE_FATAL);
1163
+ }
1164
+
1165
+ while (np != np->parent) {
1166
+ if (np->dir_info->chnext == NULL) {
1167
+ /*
1168
+ * Ascend the tree; go back to the parent.
1169
+ */
1170
+ if (mtree->indent)
1171
+ mtree->depth--;
1172
+ if (mtree->classic) {
1173
+ ret = write_dot_dot_entry(a,
1174
+ np->parent);
1175
+ if (ret != ARCHIVE_OK)
1176
+ return (ARCHIVE_FATAL);
1177
+ }
1178
+ np = np->parent;
1179
+ } else {
1180
+ /*
1181
+ * Switch to next mtree entry in the directory.
1182
+ */
1183
+ np = np->dir_info->chnext;
1184
+ break;
1185
+ }
1186
+ }
1187
+ } while (np != np->parent);
1188
+
1189
+ return (ARCHIVE_OK);
1190
+ }
1191
+
1192
+ static int
1193
+ archive_write_mtree_finish_entry(struct archive_write *a)
1194
+ {
1195
+ struct mtree_writer *mtree = a->format_data;
1196
+ struct mtree_entry *me;
1197
+
1198
+ if ((me = mtree->mtree_entry) == NULL)
1199
+ return (ARCHIVE_OK);
1200
+ mtree->mtree_entry = NULL;
1201
+
1202
+ if (me->reg_info)
1203
+ sum_final(mtree, me->reg_info);
1204
+
1205
+ return (ARCHIVE_OK);
1206
+ }
1207
+
1208
+ static int
1209
+ archive_write_mtree_close(struct archive_write *a)
1210
+ {
1211
+ struct mtree_writer *mtree= a->format_data;
1212
+ int ret;
1213
+
1214
+ if (mtree->root != NULL) {
1215
+ ret = write_mtree_entry_tree(a);
1216
+ if (ret != ARCHIVE_OK)
1217
+ return (ARCHIVE_FATAL);
1218
+ }
1219
+
1220
+ archive_write_set_bytes_in_last_block(&a->archive, 1);
1221
+
1222
+ return __archive_write_output(a, mtree->buf.s, mtree->buf.length);
1223
+ }
1224
+
1225
+ static ssize_t
1226
+ archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
1227
+ {
1228
+ struct mtree_writer *mtree= a->format_data;
1229
+
1230
+ if (n > mtree->entry_bytes_remaining)
1231
+ n = (size_t)mtree->entry_bytes_remaining;
1232
+ mtree->entry_bytes_remaining -= n;
1233
+
1234
+ /* We don't need to compute a regular file sum */
1235
+ if (mtree->mtree_entry == NULL)
1236
+ return (n);
1237
+
1238
+ if (mtree->mtree_entry->filetype == AE_IFREG)
1239
+ sum_update(mtree, buff, n);
1240
+
1241
+ return (n);
1242
+ }
1243
+
1244
+ static int
1245
+ archive_write_mtree_free(struct archive_write *a)
1246
+ {
1247
+ struct mtree_writer *mtree= a->format_data;
1248
+
1249
+ if (mtree == NULL)
1250
+ return (ARCHIVE_OK);
1251
+
1252
+ /* Make sure we do not leave any entries. */
1253
+ mtree_entry_register_free(mtree);
1254
+ archive_string_free(&mtree->cur_dirstr);
1255
+ archive_string_free(&mtree->ebuf);
1256
+ archive_string_free(&mtree->buf);
1257
+ attr_counter_set_free(mtree);
1258
+ free(mtree);
1259
+ a->format_data = NULL;
1260
+ return (ARCHIVE_OK);
1261
+ }
1262
+
1263
+ static int
1264
+ archive_write_mtree_options(struct archive_write *a, const char *key,
1265
+ const char *value)
1266
+ {
1267
+ struct mtree_writer *mtree= a->format_data;
1268
+ int keybit = 0;
1269
+
1270
+ switch (key[0]) {
1271
+ case 'a':
1272
+ if (strcmp(key, "all") == 0)
1273
+ keybit = ~0;
1274
+ break;
1275
+ case 'c':
1276
+ if (strcmp(key, "cksum") == 0)
1277
+ keybit = F_CKSUM;
1278
+ break;
1279
+ case 'd':
1280
+ if (strcmp(key, "device") == 0)
1281
+ keybit = F_DEV;
1282
+ else if (strcmp(key, "dironly") == 0) {
1283
+ mtree->dironly = (value != NULL)? 1: 0;
1284
+ return (ARCHIVE_OK);
1285
+ }
1286
+ break;
1287
+ case 'f':
1288
+ if (strcmp(key, "flags") == 0)
1289
+ keybit = F_FLAGS;
1290
+ break;
1291
+ case 'g':
1292
+ if (strcmp(key, "gid") == 0)
1293
+ keybit = F_GID;
1294
+ else if (strcmp(key, "gname") == 0)
1295
+ keybit = F_GNAME;
1296
+ break;
1297
+ case 'i':
1298
+ if (strcmp(key, "indent") == 0) {
1299
+ mtree->indent = (value != NULL)? 1: 0;
1300
+ return (ARCHIVE_OK);
1301
+ } else if (strcmp(key, "inode") == 0) {
1302
+ keybit = F_INO;
1303
+ }
1304
+ break;
1305
+ case 'l':
1306
+ if (strcmp(key, "link") == 0)
1307
+ keybit = F_SLINK;
1308
+ break;
1309
+ case 'm':
1310
+ if (strcmp(key, "md5") == 0 ||
1311
+ strcmp(key, "md5digest") == 0)
1312
+ keybit = F_MD5;
1313
+ if (strcmp(key, "mode") == 0)
1314
+ keybit = F_MODE;
1315
+ break;
1316
+ case 'n':
1317
+ if (strcmp(key, "nlink") == 0)
1318
+ keybit = F_NLINK;
1319
+ break;
1320
+ case 'r':
1321
+ if (strcmp(key, "resdevice") == 0) {
1322
+ keybit = F_RESDEV;
1323
+ } else if (strcmp(key, "ripemd160digest") == 0 ||
1324
+ strcmp(key, "rmd160") == 0 ||
1325
+ strcmp(key, "rmd160digest") == 0)
1326
+ keybit = F_RMD160;
1327
+ break;
1328
+ case 's':
1329
+ if (strcmp(key, "sha1") == 0 ||
1330
+ strcmp(key, "sha1digest") == 0)
1331
+ keybit = F_SHA1;
1332
+ if (strcmp(key, "sha256") == 0 ||
1333
+ strcmp(key, "sha256digest") == 0)
1334
+ keybit = F_SHA256;
1335
+ if (strcmp(key, "sha384") == 0 ||
1336
+ strcmp(key, "sha384digest") == 0)
1337
+ keybit = F_SHA384;
1338
+ if (strcmp(key, "sha512") == 0 ||
1339
+ strcmp(key, "sha512digest") == 0)
1340
+ keybit = F_SHA512;
1341
+ if (strcmp(key, "size") == 0)
1342
+ keybit = F_SIZE;
1343
+ break;
1344
+ case 't':
1345
+ if (strcmp(key, "time") == 0)
1346
+ keybit = F_TIME;
1347
+ else if (strcmp(key, "type") == 0)
1348
+ keybit = F_TYPE;
1349
+ break;
1350
+ case 'u':
1351
+ if (strcmp(key, "uid") == 0)
1352
+ keybit = F_UID;
1353
+ else if (strcmp(key, "uname") == 0)
1354
+ keybit = F_UNAME;
1355
+ else if (strcmp(key, "use-set") == 0) {
1356
+ mtree->output_global_set = (value != NULL)? 1: 0;
1357
+ return (ARCHIVE_OK);
1358
+ }
1359
+ break;
1360
+ }
1361
+ if (keybit != 0) {
1362
+ if (value != NULL)
1363
+ mtree->keys |= keybit;
1364
+ else
1365
+ mtree->keys &= ~keybit;
1366
+ return (ARCHIVE_OK);
1367
+ }
1368
+
1369
+ /* Note: The "warn" return is just to inform the options
1370
+ * supervisor that we didn't handle it. It will generate
1371
+ * a suitable error if no one used this option. */
1372
+ return (ARCHIVE_WARN);
1373
+ }
1374
+
1375
+ static int
1376
+ archive_write_set_format_mtree_default(struct archive *_a, const char *fn)
1377
+ {
1378
+ struct archive_write *a = (struct archive_write *)_a;
1379
+ struct mtree_writer *mtree;
1380
+
1381
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_NEW, fn);
1382
+
1383
+ if (a->format_free != NULL)
1384
+ (a->format_free)(a);
1385
+
1386
+ if ((mtree = calloc(1, sizeof(*mtree))) == NULL) {
1387
+ archive_set_error(&a->archive, ENOMEM,
1388
+ "Can't allocate mtree data");
1389
+ return (ARCHIVE_FATAL);
1390
+ }
1391
+
1392
+ mtree->mtree_entry = NULL;
1393
+ mtree->first = 1;
1394
+ memset(&(mtree->set), 0, sizeof(mtree->set));
1395
+ mtree->keys = DEFAULT_KEYS;
1396
+ mtree->dironly = 0;
1397
+ mtree->indent = 0;
1398
+ archive_string_init(&mtree->ebuf);
1399
+ archive_string_init(&mtree->buf);
1400
+ mtree_entry_register_init(mtree);
1401
+ a->format_data = mtree;
1402
+ a->format_free = archive_write_mtree_free;
1403
+ a->format_name = "mtree";
1404
+ a->format_options = archive_write_mtree_options;
1405
+ a->format_write_header = archive_write_mtree_header;
1406
+ a->format_close = archive_write_mtree_close;
1407
+ a->format_write_data = archive_write_mtree_data;
1408
+ a->format_finish_entry = archive_write_mtree_finish_entry;
1409
+ a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
1410
+ a->archive.archive_format_name = "mtree";
1411
+
1412
+ return (ARCHIVE_OK);
1413
+ }
1414
+
1415
+ int
1416
+ archive_write_set_format_mtree(struct archive *_a)
1417
+ {
1418
+ return archive_write_set_format_mtree_default(_a,
1419
+ "archive_write_set_format_mtree");
1420
+ }
1421
+
1422
+ int
1423
+ archive_write_set_format_mtree_classic(struct archive *_a)
1424
+ {
1425
+ int r;
1426
+
1427
+ r = archive_write_set_format_mtree_default(_a,
1428
+ "archive_write_set_format_mtree_classic");
1429
+ if (r == ARCHIVE_OK) {
1430
+ struct archive_write *a = (struct archive_write *)_a;
1431
+ struct mtree_writer *mtree;
1432
+
1433
+ mtree = (struct mtree_writer *)a->format_data;
1434
+
1435
+ /* Set to output a mtree archive in classic format. */
1436
+ mtree->classic = 1;
1437
+ /* Basically, mtree classic format uses '/set' global
1438
+ * value. */
1439
+ mtree->output_global_set = 1;
1440
+ }
1441
+ return (r);
1442
+ }
1443
+
1444
+ static void
1445
+ sum_init(struct mtree_writer *mtree)
1446
+ {
1447
+
1448
+ mtree->compute_sum = 0;
1449
+
1450
+ if (mtree->keys & F_CKSUM) {
1451
+ mtree->compute_sum |= F_CKSUM;
1452
+ mtree->crc = 0;
1453
+ mtree->crc_len = 0;
1454
+ }
1455
+ #ifdef ARCHIVE_HAS_MD5
1456
+ if (mtree->keys & F_MD5) {
1457
+ if (archive_md5_init(&mtree->md5ctx) == ARCHIVE_OK)
1458
+ mtree->compute_sum |= F_MD5;
1459
+ else
1460
+ mtree->keys &= ~F_MD5;/* Not supported. */
1461
+ }
1462
+ #endif
1463
+ #ifdef ARCHIVE_HAS_RMD160
1464
+ if (mtree->keys & F_RMD160) {
1465
+ if (archive_rmd160_init(&mtree->rmd160ctx) == ARCHIVE_OK)
1466
+ mtree->compute_sum |= F_RMD160;
1467
+ else
1468
+ mtree->keys &= ~F_RMD160;/* Not supported. */
1469
+ }
1470
+ #endif
1471
+ #ifdef ARCHIVE_HAS_SHA1
1472
+ if (mtree->keys & F_SHA1) {
1473
+ if (archive_sha1_init(&mtree->sha1ctx) == ARCHIVE_OK)
1474
+ mtree->compute_sum |= F_SHA1;
1475
+ else
1476
+ mtree->keys &= ~F_SHA1;/* Not supported. */
1477
+ }
1478
+ #endif
1479
+ #ifdef ARCHIVE_HAS_SHA256
1480
+ if (mtree->keys & F_SHA256) {
1481
+ if (archive_sha256_init(&mtree->sha256ctx) == ARCHIVE_OK)
1482
+ mtree->compute_sum |= F_SHA256;
1483
+ else
1484
+ mtree->keys &= ~F_SHA256;/* Not supported. */
1485
+ }
1486
+ #endif
1487
+ #ifdef ARCHIVE_HAS_SHA384
1488
+ if (mtree->keys & F_SHA384) {
1489
+ if (archive_sha384_init(&mtree->sha384ctx) == ARCHIVE_OK)
1490
+ mtree->compute_sum |= F_SHA384;
1491
+ else
1492
+ mtree->keys &= ~F_SHA384;/* Not supported. */
1493
+ }
1494
+ #endif
1495
+ #ifdef ARCHIVE_HAS_SHA512
1496
+ if (mtree->keys & F_SHA512) {
1497
+ if (archive_sha512_init(&mtree->sha512ctx) == ARCHIVE_OK)
1498
+ mtree->compute_sum |= F_SHA512;
1499
+ else
1500
+ mtree->keys &= ~F_SHA512;/* Not supported. */
1501
+ }
1502
+ #endif
1503
+ }
1504
+
1505
+ static void
1506
+ sum_update(struct mtree_writer *mtree, const void *buff, size_t n)
1507
+ {
1508
+ if (mtree->compute_sum & F_CKSUM) {
1509
+ /*
1510
+ * Compute a POSIX 1003.2 checksum
1511
+ */
1512
+ const unsigned char *p;
1513
+ size_t nn;
1514
+
1515
+ for (nn = n, p = buff; nn--; ++p)
1516
+ COMPUTE_CRC(mtree->crc, *p);
1517
+ mtree->crc_len += n;
1518
+ }
1519
+ #ifdef ARCHIVE_HAS_MD5
1520
+ if (mtree->compute_sum & F_MD5)
1521
+ archive_md5_update(&mtree->md5ctx, buff, n);
1522
+ #endif
1523
+ #ifdef ARCHIVE_HAS_RMD160
1524
+ if (mtree->compute_sum & F_RMD160)
1525
+ archive_rmd160_update(&mtree->rmd160ctx, buff, n);
1526
+ #endif
1527
+ #ifdef ARCHIVE_HAS_SHA1
1528
+ if (mtree->compute_sum & F_SHA1)
1529
+ archive_sha1_update(&mtree->sha1ctx, buff, n);
1530
+ #endif
1531
+ #ifdef ARCHIVE_HAS_SHA256
1532
+ if (mtree->compute_sum & F_SHA256)
1533
+ archive_sha256_update(&mtree->sha256ctx, buff, n);
1534
+ #endif
1535
+ #ifdef ARCHIVE_HAS_SHA384
1536
+ if (mtree->compute_sum & F_SHA384)
1537
+ archive_sha384_update(&mtree->sha384ctx, buff, n);
1538
+ #endif
1539
+ #ifdef ARCHIVE_HAS_SHA512
1540
+ if (mtree->compute_sum & F_SHA512)
1541
+ archive_sha512_update(&mtree->sha512ctx, buff, n);
1542
+ #endif
1543
+ }
1544
+
1545
+ static void
1546
+ sum_final(struct mtree_writer *mtree, struct reg_info *reg)
1547
+ {
1548
+
1549
+ if (mtree->compute_sum & F_CKSUM) {
1550
+ uint64_t len;
1551
+ /* Include the length of the file. */
1552
+ for (len = mtree->crc_len; len != 0; len >>= 8)
1553
+ COMPUTE_CRC(mtree->crc, len & 0xff);
1554
+ reg->crc = ~mtree->crc;
1555
+ }
1556
+ #ifdef ARCHIVE_HAS_MD5
1557
+ if (mtree->compute_sum & F_MD5)
1558
+ archive_md5_final(&mtree->md5ctx, reg->digest.md5);
1559
+ #endif
1560
+ #ifdef ARCHIVE_HAS_RMD160
1561
+ if (mtree->compute_sum & F_RMD160)
1562
+ archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
1563
+ #endif
1564
+ #ifdef ARCHIVE_HAS_SHA1
1565
+ if (mtree->compute_sum & F_SHA1)
1566
+ archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
1567
+ #endif
1568
+ #ifdef ARCHIVE_HAS_SHA256
1569
+ if (mtree->compute_sum & F_SHA256)
1570
+ archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
1571
+ #endif
1572
+ #ifdef ARCHIVE_HAS_SHA384
1573
+ if (mtree->compute_sum & F_SHA384)
1574
+ archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
1575
+ #endif
1576
+ #ifdef ARCHIVE_HAS_SHA512
1577
+ if (mtree->compute_sum & F_SHA512)
1578
+ archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
1579
+ #endif
1580
+ /* Save what types of sum are computed. */
1581
+ reg->compute_sum = mtree->compute_sum;
1582
+ }
1583
+
1584
+ #if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
1585
+ defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
1586
+ defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
1587
+ static void
1588
+ strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
1589
+ {
1590
+ static const char hex[] = "0123456789abcdef";
1591
+ int i;
1592
+
1593
+ for (i = 0; i < n; i++) {
1594
+ archive_strappend_char(s, hex[bin[i] >> 4]);
1595
+ archive_strappend_char(s, hex[bin[i] & 0x0f]);
1596
+ }
1597
+ }
1598
+ #endif
1599
+
1600
+ static void
1601
+ sum_write(struct archive_string *str, struct reg_info *reg)
1602
+ {
1603
+
1604
+ if (reg->compute_sum & F_CKSUM) {
1605
+ archive_string_sprintf(str, " cksum=%ju",
1606
+ (uintmax_t)reg->crc);
1607
+ }
1608
+
1609
+ #define append_digest(_s, _r, _t) \
1610
+ strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
1611
+
1612
+ #ifdef ARCHIVE_HAS_MD5
1613
+ if (reg->compute_sum & F_MD5) {
1614
+ archive_strcat(str, " md5digest=");
1615
+ append_digest(str, reg, md5);
1616
+ }
1617
+ #endif
1618
+ #ifdef ARCHIVE_HAS_RMD160
1619
+ if (reg->compute_sum & F_RMD160) {
1620
+ archive_strcat(str, " rmd160digest=");
1621
+ append_digest(str, reg, rmd160);
1622
+ }
1623
+ #endif
1624
+ #ifdef ARCHIVE_HAS_SHA1
1625
+ if (reg->compute_sum & F_SHA1) {
1626
+ archive_strcat(str, " sha1digest=");
1627
+ append_digest(str, reg, sha1);
1628
+ }
1629
+ #endif
1630
+ #ifdef ARCHIVE_HAS_SHA256
1631
+ if (reg->compute_sum & F_SHA256) {
1632
+ archive_strcat(str, " sha256digest=");
1633
+ append_digest(str, reg, sha256);
1634
+ }
1635
+ #endif
1636
+ #ifdef ARCHIVE_HAS_SHA384
1637
+ if (reg->compute_sum & F_SHA384) {
1638
+ archive_strcat(str, " sha384digest=");
1639
+ append_digest(str, reg, sha384);
1640
+ }
1641
+ #endif
1642
+ #ifdef ARCHIVE_HAS_SHA512
1643
+ if (reg->compute_sum & F_SHA512) {
1644
+ archive_strcat(str, " sha512digest=");
1645
+ append_digest(str, reg, sha512);
1646
+ }
1647
+ #endif
1648
+ #undef append_digest
1649
+ }
1650
+
1651
+ static int
1652
+ mtree_entry_cmp_node(const struct archive_rb_node *n1,
1653
+ const struct archive_rb_node *n2)
1654
+ {
1655
+ const struct mtree_entry *e1 = (const struct mtree_entry *)n1;
1656
+ const struct mtree_entry *e2 = (const struct mtree_entry *)n2;
1657
+
1658
+ return (strcmp(e2->basename.s, e1->basename.s));
1659
+ }
1660
+
1661
+ static int
1662
+ mtree_entry_cmp_key(const struct archive_rb_node *n, const void *key)
1663
+ {
1664
+ const struct mtree_entry *e = (const struct mtree_entry *)n;
1665
+
1666
+ return (strcmp((const char *)key, e->basename.s));
1667
+ }
1668
+
1669
+ #if defined(_WIN32) || defined(__CYGWIN__)
1670
+ static int
1671
+ cleanup_backslash_1(char *p)
1672
+ {
1673
+ int mb, dos;
1674
+
1675
+ mb = dos = 0;
1676
+ while (*p) {
1677
+ if (*(unsigned char *)p > 127)
1678
+ mb = 1;
1679
+ if (*p == '\\') {
1680
+ /* If we have not met any multi-byte characters,
1681
+ * we can replace '\' with '/'. */
1682
+ if (!mb)
1683
+ *p = '/';
1684
+ dos = 1;
1685
+ }
1686
+ p++;
1687
+ }
1688
+ if (!mb || !dos)
1689
+ return (0);
1690
+ return (-1);
1691
+ }
1692
+
1693
+ static void
1694
+ cleanup_backslash_2(wchar_t *p)
1695
+ {
1696
+
1697
+ /* Convert a path-separator from '\' to '/' */
1698
+ while (*p != L'\0') {
1699
+ if (*p == L'\\')
1700
+ *p = L'/';
1701
+ p++;
1702
+ }
1703
+ }
1704
+ #endif
1705
+
1706
+ /*
1707
+ * Generate a parent directory name and a base name from a pathname.
1708
+ */
1709
+ static int
1710
+ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
1711
+ struct archive_entry *entry)
1712
+ {
1713
+ const char *pathname;
1714
+ char *p, *dirname, *slash;
1715
+ size_t len;
1716
+ int ret = ARCHIVE_OK;
1717
+
1718
+ archive_strcpy(&file->pathname, archive_entry_pathname(entry));
1719
+ #if defined(_WIN32) || defined(__CYGWIN__)
1720
+ /*
1721
+ * Convert a path-separator from '\' to '/'
1722
+ */
1723
+ if (cleanup_backslash_1(file->pathname.s) != 0) {
1724
+ const wchar_t *wp = archive_entry_pathname_w(entry);
1725
+ struct archive_wstring ws;
1726
+
1727
+ if (wp != NULL) {
1728
+ int r;
1729
+ archive_string_init(&ws);
1730
+ archive_wstrcpy(&ws, wp);
1731
+ cleanup_backslash_2(ws.s);
1732
+ archive_string_empty(&(file->pathname));
1733
+ r = archive_string_append_from_wcs(&(file->pathname),
1734
+ ws.s, ws.length);
1735
+ archive_wstring_free(&ws);
1736
+ if (r < 0 && errno == ENOMEM) {
1737
+ archive_set_error(&a->archive, ENOMEM,
1738
+ "Can't allocate memory");
1739
+ return (ARCHIVE_FATAL);
1740
+ }
1741
+ }
1742
+ }
1743
+ #else
1744
+ (void)a; /* UNUSED */
1745
+ #endif
1746
+ pathname = file->pathname.s;
1747
+ if (strcmp(pathname, ".") == 0) {
1748
+ archive_strcpy(&file->basename, ".");
1749
+ return (ARCHIVE_OK);
1750
+ }
1751
+
1752
+ archive_strcpy(&(file->parentdir), pathname);
1753
+
1754
+ len = file->parentdir.length;
1755
+ p = dirname = file->parentdir.s;
1756
+
1757
+ /*
1758
+ * Remove leading '/' and '../' elements
1759
+ */
1760
+ while (*p) {
1761
+ if (p[0] == '/') {
1762
+ p++;
1763
+ len--;
1764
+ } else if (p[0] != '.')
1765
+ break;
1766
+ else if (p[1] == '.' && p[2] == '/') {
1767
+ p += 3;
1768
+ len -= 3;
1769
+ } else
1770
+ break;
1771
+ }
1772
+ if (p != dirname) {
1773
+ memmove(dirname, p, len+1);
1774
+ p = dirname;
1775
+ }
1776
+ /*
1777
+ * Remove "/","/." and "/.." elements from tail.
1778
+ */
1779
+ while (len > 0) {
1780
+ size_t ll = len;
1781
+
1782
+ if (len > 0 && p[len-1] == '/') {
1783
+ p[len-1] = '\0';
1784
+ len--;
1785
+ }
1786
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
1787
+ p[len-2] = '\0';
1788
+ len -= 2;
1789
+ }
1790
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
1791
+ p[len-1] == '.') {
1792
+ p[len-3] = '\0';
1793
+ len -= 3;
1794
+ }
1795
+ if (ll == len)
1796
+ break;
1797
+ }
1798
+ while (*p) {
1799
+ if (p[0] == '/') {
1800
+ if (p[1] == '/')
1801
+ /* Convert '//' --> '/' */
1802
+ memmove(p, p+1, strlen(p+1) + 1);
1803
+ else if (p[1] == '.' && p[2] == '/')
1804
+ /* Convert '/./' --> '/' */
1805
+ memmove(p, p+2, strlen(p+2) + 1);
1806
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
1807
+ /* Convert 'dir/dir1/../dir2/'
1808
+ * --> 'dir/dir2/'
1809
+ */
1810
+ char *rp = p -1;
1811
+ while (rp >= dirname) {
1812
+ if (*rp == '/')
1813
+ break;
1814
+ --rp;
1815
+ }
1816
+ if (rp > dirname) {
1817
+ strcpy(rp, p+3);
1818
+ p = rp;
1819
+ } else {
1820
+ strcpy(dirname, p+4);
1821
+ p = dirname;
1822
+ }
1823
+ } else
1824
+ p++;
1825
+ } else
1826
+ p++;
1827
+ }
1828
+ p = dirname;
1829
+ len = strlen(p);
1830
+
1831
+ /*
1832
+ * Add "./" prefix.
1833
+ * NOTE: If the pathname does not have a path separator, we have
1834
+ * to add "./" to the head of the pathname because mtree reader
1835
+ * will suppose that it is v1(a.k.a classic) mtree format and
1836
+ * change the directory unexpectedly and so it will make a wrong
1837
+ * path.
1838
+ */
1839
+ if (strcmp(p, ".") != 0 && strncmp(p, "./", 2) != 0) {
1840
+ struct archive_string as;
1841
+ archive_string_init(&as);
1842
+ archive_strcpy(&as, "./");
1843
+ archive_strncat(&as, p, len);
1844
+ archive_string_empty(&file->parentdir);
1845
+ archive_string_concat(&file->parentdir, &as);
1846
+ archive_string_free(&as);
1847
+ p = file->parentdir.s;
1848
+ len = archive_strlen(&file->parentdir);
1849
+ }
1850
+
1851
+ /*
1852
+ * Find out the position which points the last position of
1853
+ * path separator('/').
1854
+ */
1855
+ slash = NULL;
1856
+ for (; *p != '\0'; p++) {
1857
+ if (*p == '/')
1858
+ slash = p;
1859
+ }
1860
+ if (slash == NULL) {
1861
+ /* The pathname doesn't have a parent directory. */
1862
+ file->parentdir.length = len;
1863
+ archive_string_copy(&(file->basename), &(file->parentdir));
1864
+ archive_string_empty(&(file->parentdir));
1865
+ *file->parentdir.s = '\0';
1866
+ return (ret);
1867
+ }
1868
+
1869
+ /* Make a basename from file->parentdir.s and slash */
1870
+ *slash = '\0';
1871
+ file->parentdir.length = slash - file->parentdir.s;
1872
+ archive_strcpy(&(file->basename), slash + 1);
1873
+ return (ret);
1874
+ }
1875
+
1876
+ static int
1877
+ mtree_entry_create_virtual_dir(struct archive_write *a, const char *pathname,
1878
+ struct mtree_entry **m_entry)
1879
+ {
1880
+ struct archive_entry *entry;
1881
+ struct mtree_entry *file;
1882
+ int r;
1883
+
1884
+ entry = archive_entry_new();
1885
+ if (entry == NULL) {
1886
+ *m_entry = NULL;
1887
+ archive_set_error(&a->archive, ENOMEM,
1888
+ "Can't allocate memory");
1889
+ return (ARCHIVE_FATAL);
1890
+ }
1891
+ archive_entry_copy_pathname(entry, pathname);
1892
+ archive_entry_set_mode(entry, AE_IFDIR | 0755);
1893
+ archive_entry_set_mtime(entry, time(NULL), 0);
1894
+
1895
+ r = mtree_entry_new(a, entry, &file);
1896
+ archive_entry_free(entry);
1897
+ if (r < ARCHIVE_WARN) {
1898
+ *m_entry = NULL;
1899
+ archive_set_error(&a->archive, ENOMEM,
1900
+ "Can't allocate memory");
1901
+ return (ARCHIVE_FATAL);
1902
+ }
1903
+
1904
+ file->dir_info->virtual = 1;
1905
+
1906
+ *m_entry = file;
1907
+ return (ARCHIVE_OK);
1908
+ }
1909
+
1910
+ static void
1911
+ mtree_entry_register_add(struct mtree_writer *mtree, struct mtree_entry *file)
1912
+ {
1913
+ file->next = NULL;
1914
+ *mtree->file_list.last = file;
1915
+ mtree->file_list.last = &(file->next);
1916
+ }
1917
+
1918
+ static void
1919
+ mtree_entry_register_init(struct mtree_writer *mtree)
1920
+ {
1921
+ mtree->file_list.first = NULL;
1922
+ mtree->file_list.last = &(mtree->file_list.first);
1923
+ }
1924
+
1925
+ static void
1926
+ mtree_entry_register_free(struct mtree_writer *mtree)
1927
+ {
1928
+ struct mtree_entry *file, *file_next;
1929
+
1930
+ file = mtree->file_list.first;
1931
+ while (file != NULL) {
1932
+ file_next = file->next;
1933
+ mtree_entry_free(file);
1934
+ file = file_next;
1935
+ }
1936
+ }
1937
+
1938
+ static int
1939
+ mtree_entry_add_child_tail(struct mtree_entry *parent,
1940
+ struct mtree_entry *child)
1941
+ {
1942
+ child->dir_info->chnext = NULL;
1943
+ *parent->dir_info->children.last = child;
1944
+ parent->dir_info->children.last = &(child->dir_info->chnext);
1945
+ return (1);
1946
+ }
1947
+
1948
+ /*
1949
+ * Find a entry from a parent entry with the name.
1950
+ */
1951
+ static struct mtree_entry *
1952
+ mtree_entry_find_child(struct mtree_entry *parent, const char *child_name)
1953
+ {
1954
+ struct mtree_entry *np;
1955
+
1956
+ if (parent == NULL)
1957
+ return (NULL);
1958
+ np = (struct mtree_entry *)__archive_rb_tree_find_node(
1959
+ &(parent->dir_info->rbtree), child_name);
1960
+ return (np);
1961
+ }
1962
+
1963
+ static int
1964
+ get_path_component(char *name, size_t n, const char *fn)
1965
+ {
1966
+ char *p;
1967
+ size_t l;
1968
+
1969
+ p = strchr(fn, '/');
1970
+ if (p == NULL) {
1971
+ if ((l = strlen(fn)) == 0)
1972
+ return (0);
1973
+ } else
1974
+ l = p - fn;
1975
+ if (l > n -1)
1976
+ return (-1);
1977
+ memcpy(name, fn, l);
1978
+ name[l] = '\0';
1979
+
1980
+ return ((int)l);
1981
+ }
1982
+
1983
+ /*
1984
+ * Add a new entry into the tree.
1985
+ */
1986
+ static int
1987
+ mtree_entry_tree_add(struct archive_write *a, struct mtree_entry **filep)
1988
+ {
1989
+ #if defined(_WIN32) && !defined(__CYGWIN__)
1990
+ char name[_MAX_FNAME];/* Included null terminator size. */
1991
+ #elif defined(NAME_MAX) && NAME_MAX >= 255
1992
+ char name[NAME_MAX+1];
1993
+ #else
1994
+ char name[256];
1995
+ #endif
1996
+ struct mtree_writer *mtree = (struct mtree_writer *)a->format_data;
1997
+ struct mtree_entry *dent, *file, *np;
1998
+ const char *fn, *p;
1999
+ int l, r;
2000
+
2001
+ file = *filep;
2002
+ if (file->parentdir.length == 0 && file->basename.length == 1 &&
2003
+ file->basename.s[0] == '.') {
2004
+ file->parent = file;
2005
+ if (mtree->root != NULL) {
2006
+ np = mtree->root;
2007
+ goto same_entry;
2008
+ }
2009
+ mtree->root = file;
2010
+ mtree_entry_register_add(mtree, file);
2011
+ return (ARCHIVE_OK);
2012
+ }
2013
+
2014
+ if (file->parentdir.length == 0) {
2015
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2016
+ "Internal programming error "
2017
+ "in generating canonical name for %s",
2018
+ file->pathname.s);
2019
+ return (ARCHIVE_FAILED);
2020
+ }
2021
+
2022
+ fn = p = file->parentdir.s;
2023
+
2024
+ /*
2025
+ * If the path of the parent directory of `file' entry is
2026
+ * the same as the path of `cur_dirent', add `file' entry to
2027
+ * `cur_dirent'.
2028
+ */
2029
+ if (archive_strlen(&(mtree->cur_dirstr))
2030
+ == archive_strlen(&(file->parentdir)) &&
2031
+ strcmp(mtree->cur_dirstr.s, fn) == 0) {
2032
+ if (!__archive_rb_tree_insert_node(
2033
+ &(mtree->cur_dirent->dir_info->rbtree),
2034
+ (struct archive_rb_node *)file)) {
2035
+ /* There is the same name in the tree. */
2036
+ np = (struct mtree_entry *)__archive_rb_tree_find_node(
2037
+ &(mtree->cur_dirent->dir_info->rbtree),
2038
+ file->basename.s);
2039
+ goto same_entry;
2040
+ }
2041
+ file->parent = mtree->cur_dirent;
2042
+ mtree_entry_register_add(mtree, file);
2043
+ return (ARCHIVE_OK);
2044
+ }
2045
+
2046
+ dent = mtree->root;
2047
+ for (;;) {
2048
+ l = get_path_component(name, sizeof(name), fn);
2049
+ if (l == 0) {
2050
+ np = NULL;
2051
+ break;
2052
+ }
2053
+ if (l < 0) {
2054
+ archive_set_error(&a->archive,
2055
+ ARCHIVE_ERRNO_MISC,
2056
+ "A name buffer is too small");
2057
+ return (ARCHIVE_FATAL);
2058
+ }
2059
+ if (l == 1 && name[0] == '.' && dent != NULL &&
2060
+ dent == mtree->root) {
2061
+ fn += l;
2062
+ if (fn[0] == '/')
2063
+ fn++;
2064
+ continue;
2065
+ }
2066
+
2067
+ np = mtree_entry_find_child(dent, name);
2068
+ if (np == NULL || fn[0] == '\0')
2069
+ break;
2070
+
2071
+ /* Find next sub directory. */
2072
+ if (!np->dir_info) {
2073
+ /* NOT Directory! */
2074
+ archive_set_error(&a->archive,
2075
+ ARCHIVE_ERRNO_MISC,
2076
+ "`%s' is not directory, we cannot insert `%s' ",
2077
+ np->pathname.s, file->pathname.s);
2078
+ return (ARCHIVE_FAILED);
2079
+ }
2080
+ fn += l;
2081
+ if (fn[0] == '/')
2082
+ fn++;
2083
+ dent = np;
2084
+ }
2085
+ if (np == NULL) {
2086
+ /*
2087
+ * Create virtual parent directories.
2088
+ */
2089
+ while (fn[0] != '\0') {
2090
+ struct mtree_entry *vp;
2091
+ struct archive_string as;
2092
+
2093
+ archive_string_init(&as);
2094
+ archive_strncat(&as, p, fn - p + l);
2095
+ if (as.s[as.length-1] == '/') {
2096
+ as.s[as.length-1] = '\0';
2097
+ as.length--;
2098
+ }
2099
+ r = mtree_entry_create_virtual_dir(a, as.s, &vp);
2100
+ archive_string_free(&as);
2101
+ if (r < ARCHIVE_WARN)
2102
+ return (r);
2103
+
2104
+ if (strcmp(vp->pathname.s, ".") == 0) {
2105
+ vp->parent = vp;
2106
+ mtree->root = vp;
2107
+ } else {
2108
+ __archive_rb_tree_insert_node(
2109
+ &(dent->dir_info->rbtree),
2110
+ (struct archive_rb_node *)vp);
2111
+ vp->parent = dent;
2112
+ }
2113
+ mtree_entry_register_add(mtree, vp);
2114
+ np = vp;
2115
+
2116
+ fn += l;
2117
+ if (fn[0] == '/')
2118
+ fn++;
2119
+ l = get_path_component(name, sizeof(name), fn);
2120
+ if (l < 0) {
2121
+ archive_string_free(&as);
2122
+ archive_set_error(&a->archive,
2123
+ ARCHIVE_ERRNO_MISC,
2124
+ "A name buffer is too small");
2125
+ return (ARCHIVE_FATAL);
2126
+ }
2127
+ dent = np;
2128
+ }
2129
+
2130
+ /* Found out the parent directory where `file' can be
2131
+ * inserted. */
2132
+ mtree->cur_dirent = dent;
2133
+ archive_string_empty(&(mtree->cur_dirstr));
2134
+ archive_string_ensure(&(mtree->cur_dirstr),
2135
+ archive_strlen(&(dent->parentdir)) +
2136
+ archive_strlen(&(dent->basename)) + 2);
2137
+ if (archive_strlen(&(dent->parentdir)) +
2138
+ archive_strlen(&(dent->basename)) == 0)
2139
+ mtree->cur_dirstr.s[0] = 0;
2140
+ else {
2141
+ if (archive_strlen(&(dent->parentdir)) > 0) {
2142
+ archive_string_copy(&(mtree->cur_dirstr),
2143
+ &(dent->parentdir));
2144
+ archive_strappend_char(
2145
+ &(mtree->cur_dirstr), '/');
2146
+ }
2147
+ archive_string_concat(&(mtree->cur_dirstr),
2148
+ &(dent->basename));
2149
+ }
2150
+
2151
+ if (!__archive_rb_tree_insert_node(
2152
+ &(dent->dir_info->rbtree),
2153
+ (struct archive_rb_node *)file)) {
2154
+ np = (struct mtree_entry *)__archive_rb_tree_find_node(
2155
+ &(dent->dir_info->rbtree), file->basename.s);
2156
+ goto same_entry;
2157
+ }
2158
+ file->parent = dent;
2159
+ mtree_entry_register_add(mtree, file);
2160
+ return (ARCHIVE_OK);
2161
+ }
2162
+
2163
+ same_entry:
2164
+ /*
2165
+ * We have already has the entry the filename of which is
2166
+ * the same.
2167
+ */
2168
+ r = mtree_entry_exchange_same_entry(a, np, file);
2169
+ if (r < ARCHIVE_WARN)
2170
+ return (r);
2171
+ if (np->dir_info)
2172
+ np->dir_info->virtual = 0;
2173
+ *filep = np;
2174
+ mtree_entry_free(file);
2175
+ return (ARCHIVE_WARN);
2176
+ }
2177
+
2178
+ static int
2179
+ mtree_entry_exchange_same_entry(struct archive_write *a, struct mtree_entry *np,
2180
+ struct mtree_entry *file)
2181
+ {
2182
+
2183
+ if ((np->mode & AE_IFMT) != (file->mode & AE_IFMT)) {
2184
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2185
+ "Found duplicate entries `%s' and its file type is "
2186
+ "different",
2187
+ np->pathname.s);
2188
+ return (ARCHIVE_FAILED);
2189
+ }
2190
+
2191
+ /* Update the existent mtree entry's attributes by the new one's. */
2192
+ archive_string_empty(&np->symlink);
2193
+ archive_string_concat(&np->symlink, &file->symlink);
2194
+ archive_string_empty(&np->uname);
2195
+ archive_string_concat(&np->uname, &file->uname);
2196
+ archive_string_empty(&np->gname);
2197
+ archive_string_concat(&np->gname, &file->gname);
2198
+ archive_string_empty(&np->fflags_text);
2199
+ archive_string_concat(&np->fflags_text, &file->fflags_text);
2200
+ np->nlink = file->nlink;
2201
+ np->filetype = file->filetype;
2202
+ np->mode = file->mode;
2203
+ np->size = file->size;
2204
+ np->uid = file->uid;
2205
+ np->gid = file->gid;
2206
+ np->fflags_set = file->fflags_set;
2207
+ np->fflags_clear = file->fflags_clear;
2208
+ np->mtime = file->mtime;
2209
+ np->mtime_nsec = file->mtime_nsec;
2210
+ np->rdevmajor = file->rdevmajor;
2211
+ np->rdevminor = file->rdevminor;
2212
+ np->devmajor = file->devmajor;
2213
+ np->devminor = file->devminor;
2214
+ np->ino = file->ino;
2215
+
2216
+ return (ARCHIVE_WARN);
2217
+ }