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,3259 @@
1
+ /*-
2
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
3
+ * All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ * 1. Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * 2. Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ *
14
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+ */
25
+
26
+ #include "archive_platform.h"
27
+ __FBSDID("$FreeBSD$");
28
+
29
+ #ifdef HAVE_ERRNO_H
30
+ #include <errno.h>
31
+ #endif
32
+ #ifdef HAVE_LIMITS_H
33
+ #include <limits.h>
34
+ #endif
35
+ #include <stdlib.h>
36
+ #if HAVE_LIBXML_XMLWRITER_H
37
+ #include <libxml/xmlwriter.h>
38
+ #endif
39
+ #ifdef HAVE_BZLIB_H
40
+ #include <bzlib.h>
41
+ #endif
42
+ #if HAVE_LZMA_H
43
+ #include <lzma.h>
44
+ #endif
45
+ #ifdef HAVE_ZLIB_H
46
+ #include <zlib.h>
47
+ #endif
48
+
49
+ #include "archive.h"
50
+ #include "archive_digest_private.h"
51
+ #include "archive_endian.h"
52
+ #include "archive_entry.h"
53
+ #include "archive_entry_locale.h"
54
+ #include "archive_private.h"
55
+ #include "archive_rb.h"
56
+ #include "archive_string.h"
57
+ #include "archive_write_private.h"
58
+
59
+ /*
60
+ * Differences to xar utility.
61
+ * - Subdocument is not supported yet.
62
+ * - ACL is not supported yet.
63
+ * - When writing an XML element <link type="<file-type>">, <file-type>
64
+ * which is a file type a symbolic link is referencing is always marked
65
+ * as "broken". Xar utility uses stat(2) to get the file type, but, in
66
+ * libarchive format writer, we should not use it; if it is needed, we
67
+ * should get about it at archive_read_disk.c.
68
+ * - It is possible to appear both <flags> and <ext2> elements.
69
+ * Xar utility generates <flags> on BSD platform and <ext2> on Linux
70
+ * platform.
71
+ *
72
+ */
73
+
74
+ #if !(defined(HAVE_LIBXML_XMLWRITER_H) && defined(LIBXML_VERSION) &&\
75
+ LIBXML_VERSION >= 20703) ||\
76
+ !defined(HAVE_ZLIB_H) || \
77
+ !defined(ARCHIVE_HAS_MD5) || !defined(ARCHIVE_HAS_SHA1)
78
+ /*
79
+ * xar needs several external libraries.
80
+ * o libxml2
81
+ * o openssl or MD5/SHA1 hash function
82
+ * o zlib
83
+ * o bzlib2 (option)
84
+ * o liblzma (option)
85
+ */
86
+ int
87
+ archive_write_set_format_xar(struct archive *_a)
88
+ {
89
+ struct archive_write *a = (struct archive_write *)_a;
90
+
91
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
92
+ "Xar not supported on this platform");
93
+ return (ARCHIVE_WARN);
94
+ }
95
+
96
+ #else /* Support xar format */
97
+
98
+ /*#define DEBUG_PRINT_TOC 1 */
99
+
100
+ #define BAD_CAST_CONST (const xmlChar *)
101
+
102
+ #define HEADER_MAGIC 0x78617221
103
+ #define HEADER_SIZE 28
104
+ #define HEADER_VERSION 1
105
+
106
+ enum sumalg {
107
+ CKSUM_NONE = 0,
108
+ CKSUM_SHA1 = 1,
109
+ CKSUM_MD5 = 2
110
+ };
111
+
112
+ #define MD5_SIZE 16
113
+ #define SHA1_SIZE 20
114
+ #define MAX_SUM_SIZE 20
115
+ #define MD5_NAME "md5"
116
+ #define SHA1_NAME "sha1"
117
+
118
+ enum enctype {
119
+ NONE,
120
+ GZIP,
121
+ BZIP2,
122
+ LZMA,
123
+ XZ,
124
+ };
125
+
126
+ struct chksumwork {
127
+ enum sumalg alg;
128
+ #ifdef ARCHIVE_HAS_MD5
129
+ archive_md5_ctx md5ctx;
130
+ #endif
131
+ #ifdef ARCHIVE_HAS_SHA1
132
+ archive_sha1_ctx sha1ctx;
133
+ #endif
134
+ };
135
+
136
+ enum la_zaction {
137
+ ARCHIVE_Z_FINISH,
138
+ ARCHIVE_Z_RUN
139
+ };
140
+
141
+ /*
142
+ * Universal zstream.
143
+ */
144
+ struct la_zstream {
145
+ const unsigned char *next_in;
146
+ size_t avail_in;
147
+ uint64_t total_in;
148
+
149
+ unsigned char *next_out;
150
+ size_t avail_out;
151
+ uint64_t total_out;
152
+
153
+ int valid;
154
+ void *real_stream;
155
+ int (*code) (struct archive *a,
156
+ struct la_zstream *lastrm,
157
+ enum la_zaction action);
158
+ int (*end)(struct archive *a,
159
+ struct la_zstream *lastrm);
160
+ };
161
+
162
+ struct chksumval {
163
+ enum sumalg alg;
164
+ size_t len;
165
+ unsigned char val[MAX_SUM_SIZE];
166
+ };
167
+
168
+ struct heap_data {
169
+ int id;
170
+ struct heap_data *next;
171
+ uint64_t temp_offset;
172
+ uint64_t length; /* archived size. */
173
+ uint64_t size; /* extracted size. */
174
+ enum enctype compression;
175
+ struct chksumval a_sum; /* archived checksum. */
176
+ struct chksumval e_sum; /* extracted checksum. */
177
+ };
178
+
179
+ struct file {
180
+ struct archive_rb_node rbnode;
181
+
182
+ int id;
183
+ struct archive_entry *entry;
184
+
185
+ struct archive_rb_tree rbtree;
186
+ struct file *next;
187
+ struct file *chnext;
188
+ struct file *hlnext;
189
+ /* For hardlinked files.
190
+ * Use only when archive_entry_nlink() > 1 */
191
+ struct file *hardlink_target;
192
+ struct file *parent; /* parent directory entry */
193
+ /*
194
+ * To manage sub directory files.
195
+ * We use 'chnext' (a member of struct file) to chain.
196
+ */
197
+ struct {
198
+ struct file *first;
199
+ struct file **last;
200
+ } children;
201
+
202
+ /* For making a directory tree. */
203
+ struct archive_string parentdir;
204
+ struct archive_string basename;
205
+ struct archive_string symlink;
206
+
207
+ int ea_idx;
208
+ struct {
209
+ struct heap_data *first;
210
+ struct heap_data **last;
211
+ } xattr;
212
+ struct heap_data data;
213
+ struct archive_string script;
214
+
215
+ signed int virtual:1;
216
+ signed int dir:1;
217
+ };
218
+
219
+ struct hardlink {
220
+ struct archive_rb_node rbnode;
221
+ int nlink;
222
+ struct {
223
+ struct file *first;
224
+ struct file **last;
225
+ } file_list;
226
+ };
227
+
228
+ struct xar {
229
+ int temp_fd;
230
+ uint64_t temp_offset;
231
+
232
+ int file_idx;
233
+ struct file *root;
234
+ struct file *cur_dirent;
235
+ struct archive_string cur_dirstr;
236
+ struct file *cur_file;
237
+ uint64_t bytes_remaining;
238
+ struct archive_string tstr;
239
+ struct archive_string vstr;
240
+
241
+ enum sumalg opt_toc_sumalg;
242
+ enum sumalg opt_sumalg;
243
+ enum enctype opt_compression;
244
+ int opt_compression_level;
245
+ uint32_t opt_threads;
246
+
247
+ struct chksumwork a_sumwrk; /* archived checksum. */
248
+ struct chksumwork e_sumwrk; /* extracted checksum. */
249
+ struct la_zstream stream;
250
+ struct archive_string_conv *sconv;
251
+ /*
252
+ * Compressed data buffer.
253
+ */
254
+ unsigned char wbuff[1024 * 64];
255
+ size_t wbuff_remaining;
256
+
257
+ struct heap_data toc;
258
+ /*
259
+ * The list of all file entries is used to manage struct file
260
+ * objects.
261
+ * We use 'next' (a member of struct file) to chain.
262
+ */
263
+ struct {
264
+ struct file *first;
265
+ struct file **last;
266
+ } file_list;
267
+ /*
268
+ * The list of hard-linked file entries.
269
+ * We use 'hlnext' (a member of struct file) to chain.
270
+ */
271
+ struct archive_rb_tree hardlink_rbtree;
272
+ };
273
+
274
+ static int xar_options(struct archive_write *,
275
+ const char *, const char *);
276
+ static int xar_write_header(struct archive_write *,
277
+ struct archive_entry *);
278
+ static ssize_t xar_write_data(struct archive_write *,
279
+ const void *, size_t);
280
+ static int xar_finish_entry(struct archive_write *);
281
+ static int xar_close(struct archive_write *);
282
+ static int xar_free(struct archive_write *);
283
+
284
+ static struct file *file_new(struct archive_write *a, struct archive_entry *);
285
+ static void file_free(struct file *);
286
+ static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
287
+ const char *);
288
+ static int file_add_child_tail(struct file *, struct file *);
289
+ static struct file *file_find_child(struct file *, const char *);
290
+ static int file_gen_utility_names(struct archive_write *,
291
+ struct file *);
292
+ static int get_path_component(char *, int, const char *);
293
+ static int file_tree(struct archive_write *, struct file **);
294
+ static void file_register(struct xar *, struct file *);
295
+ static void file_init_register(struct xar *);
296
+ static void file_free_register(struct xar *);
297
+ static int file_register_hardlink(struct archive_write *,
298
+ struct file *);
299
+ static void file_connect_hardlink_files(struct xar *);
300
+ static void file_init_hardlinks(struct xar *);
301
+ static void file_free_hardlinks(struct xar *);
302
+
303
+ static void checksum_init(struct chksumwork *, enum sumalg);
304
+ static void checksum_update(struct chksumwork *, const void *, size_t);
305
+ static void checksum_final(struct chksumwork *, struct chksumval *);
306
+ static int compression_init_encoder_gzip(struct archive *,
307
+ struct la_zstream *, int, int);
308
+ static int compression_code_gzip(struct archive *,
309
+ struct la_zstream *, enum la_zaction);
310
+ static int compression_end_gzip(struct archive *, struct la_zstream *);
311
+ static int compression_init_encoder_bzip2(struct archive *,
312
+ struct la_zstream *, int);
313
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
314
+ static int compression_code_bzip2(struct archive *,
315
+ struct la_zstream *, enum la_zaction);
316
+ static int compression_end_bzip2(struct archive *, struct la_zstream *);
317
+ #endif
318
+ static int compression_init_encoder_lzma(struct archive *,
319
+ struct la_zstream *, int);
320
+ static int compression_init_encoder_xz(struct archive *,
321
+ struct la_zstream *, int, int);
322
+ #if defined(HAVE_LZMA_H)
323
+ static int compression_code_lzma(struct archive *,
324
+ struct la_zstream *, enum la_zaction);
325
+ static int compression_end_lzma(struct archive *, struct la_zstream *);
326
+ #endif
327
+ static int xar_compression_init_encoder(struct archive_write *);
328
+ static int compression_code(struct archive *,
329
+ struct la_zstream *, enum la_zaction);
330
+ static int compression_end(struct archive *,
331
+ struct la_zstream *);
332
+ static int save_xattrs(struct archive_write *, struct file *);
333
+ static int getalgsize(enum sumalg);
334
+ static const char *getalgname(enum sumalg);
335
+
336
+ int
337
+ archive_write_set_format_xar(struct archive *_a)
338
+ {
339
+ struct archive_write *a = (struct archive_write *)_a;
340
+ struct xar *xar;
341
+
342
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
343
+ ARCHIVE_STATE_NEW, "archive_write_set_format_xar");
344
+
345
+ /* If another format was already registered, unregister it. */
346
+ if (a->format_free != NULL)
347
+ (a->format_free)(a);
348
+
349
+ xar = calloc(1, sizeof(*xar));
350
+ if (xar == NULL) {
351
+ archive_set_error(&a->archive, ENOMEM,
352
+ "Can't allocate xar data");
353
+ return (ARCHIVE_FATAL);
354
+ }
355
+ xar->temp_fd = -1;
356
+ file_init_register(xar);
357
+ file_init_hardlinks(xar);
358
+ archive_string_init(&(xar->tstr));
359
+ archive_string_init(&(xar->vstr));
360
+
361
+ /*
362
+ * Create the root directory.
363
+ */
364
+ xar->root = file_create_virtual_dir(a, xar, "");
365
+ if (xar->root == NULL) {
366
+ free(xar);
367
+ archive_set_error(&a->archive, ENOMEM,
368
+ "Can't allocate xar data");
369
+ return (ARCHIVE_FATAL);
370
+ }
371
+ xar->root->parent = xar->root;
372
+ file_register(xar, xar->root);
373
+ xar->cur_dirent = xar->root;
374
+ archive_string_init(&(xar->cur_dirstr));
375
+ archive_string_ensure(&(xar->cur_dirstr), 1);
376
+ xar->cur_dirstr.s[0] = 0;
377
+
378
+ /*
379
+ * Initialize option.
380
+ */
381
+ /* Set default checksum type. */
382
+ xar->opt_toc_sumalg = CKSUM_SHA1;
383
+ xar->opt_sumalg = CKSUM_SHA1;
384
+ /* Set default compression type, level, and number of threads. */
385
+ xar->opt_compression = GZIP;
386
+ xar->opt_compression_level = 6;
387
+ xar->opt_threads = 1;
388
+
389
+ a->format_data = xar;
390
+
391
+ a->format_name = "xar";
392
+ a->format_options = xar_options;
393
+ a->format_write_header = xar_write_header;
394
+ a->format_write_data = xar_write_data;
395
+ a->format_finish_entry = xar_finish_entry;
396
+ a->format_close = xar_close;
397
+ a->format_free = xar_free;
398
+ a->archive.archive_format = ARCHIVE_FORMAT_XAR;
399
+ a->archive.archive_format_name = "xar";
400
+
401
+ return (ARCHIVE_OK);
402
+ }
403
+
404
+ static int
405
+ xar_options(struct archive_write *a, const char *key, const char *value)
406
+ {
407
+ struct xar *xar;
408
+
409
+ xar = (struct xar *)a->format_data;
410
+
411
+ if (strcmp(key, "checksum") == 0) {
412
+ if (value == NULL)
413
+ xar->opt_sumalg = CKSUM_NONE;
414
+ else if (strcmp(value, "none") == 0)
415
+ xar->opt_sumalg = CKSUM_NONE;
416
+ else if (strcmp(value, "sha1") == 0)
417
+ xar->opt_sumalg = CKSUM_SHA1;
418
+ else if (strcmp(value, "md5") == 0)
419
+ xar->opt_sumalg = CKSUM_MD5;
420
+ else {
421
+ archive_set_error(&(a->archive),
422
+ ARCHIVE_ERRNO_MISC,
423
+ "Unknown checksum name: `%s'",
424
+ value);
425
+ return (ARCHIVE_FAILED);
426
+ }
427
+ return (ARCHIVE_OK);
428
+ }
429
+ if (strcmp(key, "compression") == 0) {
430
+ const char *name = NULL;
431
+
432
+ if (value == NULL)
433
+ xar->opt_compression = NONE;
434
+ else if (strcmp(value, "none") == 0)
435
+ xar->opt_compression = NONE;
436
+ else if (strcmp(value, "gzip") == 0)
437
+ xar->opt_compression = GZIP;
438
+ else if (strcmp(value, "bzip2") == 0)
439
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
440
+ xar->opt_compression = BZIP2;
441
+ #else
442
+ name = "bzip2";
443
+ #endif
444
+ else if (strcmp(value, "lzma") == 0)
445
+ #if HAVE_LZMA_H
446
+ xar->opt_compression = LZMA;
447
+ #else
448
+ name = "lzma";
449
+ #endif
450
+ else if (strcmp(value, "xz") == 0)
451
+ #if HAVE_LZMA_H
452
+ xar->opt_compression = XZ;
453
+ #else
454
+ name = "xz";
455
+ #endif
456
+ else {
457
+ archive_set_error(&(a->archive),
458
+ ARCHIVE_ERRNO_MISC,
459
+ "Unknown compression name: `%s'",
460
+ value);
461
+ return (ARCHIVE_FAILED);
462
+ }
463
+ if (name != NULL) {
464
+ archive_set_error(&(a->archive),
465
+ ARCHIVE_ERRNO_MISC,
466
+ "`%s' compression not supported "
467
+ "on this platform",
468
+ name);
469
+ return (ARCHIVE_FAILED);
470
+ }
471
+ return (ARCHIVE_OK);
472
+ }
473
+ if (strcmp(key, "compression-level") == 0) {
474
+ if (value == NULL ||
475
+ !(value[0] >= '0' && value[0] <= '9') ||
476
+ value[1] != '\0') {
477
+ archive_set_error(&(a->archive),
478
+ ARCHIVE_ERRNO_MISC,
479
+ "Illegal value `%s'",
480
+ value);
481
+ return (ARCHIVE_FAILED);
482
+ }
483
+ xar->opt_compression_level = value[0] - '0';
484
+ return (ARCHIVE_OK);
485
+ }
486
+ if (strcmp(key, "toc-checksum") == 0) {
487
+ if (value == NULL)
488
+ xar->opt_toc_sumalg = CKSUM_NONE;
489
+ else if (strcmp(value, "none") == 0)
490
+ xar->opt_toc_sumalg = CKSUM_NONE;
491
+ else if (strcmp(value, "sha1") == 0)
492
+ xar->opt_toc_sumalg = CKSUM_SHA1;
493
+ else if (strcmp(value, "md5") == 0)
494
+ xar->opt_toc_sumalg = CKSUM_MD5;
495
+ else {
496
+ archive_set_error(&(a->archive),
497
+ ARCHIVE_ERRNO_MISC,
498
+ "Unknown checksum name: `%s'",
499
+ value);
500
+ return (ARCHIVE_FAILED);
501
+ }
502
+ return (ARCHIVE_OK);
503
+ }
504
+ if (strcmp(key, "threads") == 0) {
505
+ char *endptr;
506
+
507
+ if (value == NULL)
508
+ return (ARCHIVE_FAILED);
509
+ errno = 0;
510
+ xar->opt_threads = (int)strtoul(value, &endptr, 10);
511
+ if (errno != 0 || *endptr != '\0') {
512
+ xar->opt_threads = 1;
513
+ archive_set_error(&(a->archive),
514
+ ARCHIVE_ERRNO_MISC,
515
+ "Illegal value `%s'",
516
+ value);
517
+ return (ARCHIVE_FAILED);
518
+ }
519
+ if (xar->opt_threads == 0) {
520
+ #ifdef HAVE_LZMA_STREAM_ENCODER_MT
521
+ xar->opt_threads = lzma_cputhreads();
522
+ #else
523
+ xar->opt_threads = 1;
524
+ #endif
525
+ }
526
+ }
527
+
528
+ /* Note: The "warn" return is just to inform the options
529
+ * supervisor that we didn't handle it. It will generate
530
+ * a suitable error if no one used this option. */
531
+ return (ARCHIVE_WARN);
532
+ }
533
+
534
+ static int
535
+ xar_write_header(struct archive_write *a, struct archive_entry *entry)
536
+ {
537
+ struct xar *xar;
538
+ struct file *file;
539
+ struct archive_entry *file_entry;
540
+ int r, r2;
541
+
542
+ xar = (struct xar *)a->format_data;
543
+ xar->cur_file = NULL;
544
+ xar->bytes_remaining = 0;
545
+
546
+ if (xar->sconv == NULL) {
547
+ xar->sconv = archive_string_conversion_to_charset(
548
+ &a->archive, "UTF-8", 1);
549
+ if (xar->sconv == NULL)
550
+ return (ARCHIVE_FATAL);
551
+ }
552
+
553
+ file = file_new(a, entry);
554
+ if (file == NULL) {
555
+ archive_set_error(&a->archive, ENOMEM,
556
+ "Can't allocate data");
557
+ return (ARCHIVE_FATAL);
558
+ }
559
+ r2 = file_gen_utility_names(a, file);
560
+ if (r2 < ARCHIVE_WARN)
561
+ return (r2);
562
+
563
+ /*
564
+ * Ignore a path which looks like the top of directory name
565
+ * since we have already made the root directory of an Xar archive.
566
+ */
567
+ if (archive_strlen(&(file->parentdir)) == 0 &&
568
+ archive_strlen(&(file->basename)) == 0) {
569
+ file_free(file);
570
+ return (r2);
571
+ }
572
+
573
+ /* Add entry into tree */
574
+ file_entry = file->entry;
575
+ r = file_tree(a, &file);
576
+ if (r != ARCHIVE_OK)
577
+ return (r);
578
+ /* There is the same file in tree and
579
+ * the current file is older than the file in tree.
580
+ * So we don't need the current file data anymore. */
581
+ if (file->entry != file_entry)
582
+ return (r2);
583
+ if (file->id == 0)
584
+ file_register(xar, file);
585
+
586
+ /* A virtual file, which is a directory, does not have
587
+ * any contents and we won't store it into a archive
588
+ * file other than its name. */
589
+ if (file->virtual)
590
+ return (r2);
591
+
592
+ /*
593
+ * Prepare to save the contents of the file.
594
+ */
595
+ if (xar->temp_fd == -1) {
596
+ int algsize;
597
+ xar->temp_offset = 0;
598
+ xar->temp_fd = __archive_mktemp(NULL);
599
+ if (xar->temp_fd < 0) {
600
+ archive_set_error(&a->archive, errno,
601
+ "Couldn't create temporary file");
602
+ return (ARCHIVE_FATAL);
603
+ }
604
+ algsize = getalgsize(xar->opt_toc_sumalg);
605
+ if (algsize > 0) {
606
+ if (lseek(xar->temp_fd, algsize, SEEK_SET) < 0) {
607
+ archive_set_error(&(a->archive), errno,
608
+ "lseek failed");
609
+ return (ARCHIVE_FATAL);
610
+ }
611
+ xar->temp_offset = algsize;
612
+ }
613
+ }
614
+
615
+ if (archive_entry_hardlink(file->entry) == NULL) {
616
+ r = save_xattrs(a, file);
617
+ if (r != ARCHIVE_OK)
618
+ return (ARCHIVE_FATAL);
619
+ }
620
+
621
+ /* Non regular files contents are unneeded to be saved to
622
+ * a temporary file. */
623
+ if (archive_entry_filetype(file->entry) != AE_IFREG)
624
+ return (r2);
625
+
626
+ /*
627
+ * Set the current file to cur_file to read its contents.
628
+ */
629
+ xar->cur_file = file;
630
+
631
+ if (archive_entry_nlink(file->entry) > 1) {
632
+ r = file_register_hardlink(a, file);
633
+ if (r != ARCHIVE_OK)
634
+ return (r);
635
+ if (archive_entry_hardlink(file->entry) != NULL) {
636
+ archive_entry_unset_size(file->entry);
637
+ return (r2);
638
+ }
639
+ }
640
+
641
+ /* Save a offset of current file in temporary file. */
642
+ file->data.temp_offset = xar->temp_offset;
643
+ file->data.size = archive_entry_size(file->entry);
644
+ file->data.compression = xar->opt_compression;
645
+ xar->bytes_remaining = archive_entry_size(file->entry);
646
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
647
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
648
+ r = xar_compression_init_encoder(a);
649
+
650
+ if (r != ARCHIVE_OK)
651
+ return (r);
652
+ else
653
+ return (r2);
654
+ }
655
+
656
+ static int
657
+ write_to_temp(struct archive_write *a, const void *buff, size_t s)
658
+ {
659
+ struct xar *xar;
660
+ const unsigned char *p;
661
+ ssize_t ws;
662
+
663
+ xar = (struct xar *)a->format_data;
664
+ p = (const unsigned char *)buff;
665
+ while (s) {
666
+ ws = write(xar->temp_fd, p, s);
667
+ if (ws < 0) {
668
+ archive_set_error(&(a->archive), errno,
669
+ "fwrite function failed");
670
+ return (ARCHIVE_FATAL);
671
+ }
672
+ s -= ws;
673
+ p += ws;
674
+ xar->temp_offset += ws;
675
+ }
676
+ return (ARCHIVE_OK);
677
+ }
678
+
679
+ static ssize_t
680
+ xar_write_data(struct archive_write *a, const void *buff, size_t s)
681
+ {
682
+ struct xar *xar;
683
+ enum la_zaction run;
684
+ size_t size = 0;
685
+ size_t rsize;
686
+ int r;
687
+
688
+ xar = (struct xar *)a->format_data;
689
+
690
+ if (s > xar->bytes_remaining)
691
+ s = (size_t)xar->bytes_remaining;
692
+ if (s == 0 || xar->cur_file == NULL)
693
+ return (0);
694
+ if (xar->cur_file->data.compression == NONE) {
695
+ checksum_update(&(xar->e_sumwrk), buff, s);
696
+ checksum_update(&(xar->a_sumwrk), buff, s);
697
+ size = rsize = s;
698
+ } else {
699
+ xar->stream.next_in = (const unsigned char *)buff;
700
+ xar->stream.avail_in = s;
701
+ if (xar->bytes_remaining > s)
702
+ run = ARCHIVE_Z_RUN;
703
+ else
704
+ run = ARCHIVE_Z_FINISH;
705
+ /* Compress file data. */
706
+ for (;;) {
707
+ r = compression_code(&(a->archive), &(xar->stream),
708
+ run);
709
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
710
+ return (ARCHIVE_FATAL);
711
+ if (xar->stream.avail_out == 0 ||
712
+ run == ARCHIVE_Z_FINISH) {
713
+ size = sizeof(xar->wbuff) -
714
+ xar->stream.avail_out;
715
+ checksum_update(&(xar->a_sumwrk), xar->wbuff,
716
+ size);
717
+ xar->cur_file->data.length += size;
718
+ if (write_to_temp(a, xar->wbuff,
719
+ size) != ARCHIVE_OK)
720
+ return (ARCHIVE_FATAL);
721
+ if (r == ARCHIVE_OK) {
722
+ /* Output buffer was full */
723
+ xar->stream.next_out = xar->wbuff;
724
+ xar->stream.avail_out =
725
+ sizeof(xar->wbuff);
726
+ } else {
727
+ /* ARCHIVE_EOF - We are done */
728
+ break;
729
+ }
730
+ } else {
731
+ /* Compressor wants more input */
732
+ break;
733
+ }
734
+ }
735
+ rsize = s - xar->stream.avail_in;
736
+ checksum_update(&(xar->e_sumwrk), buff, rsize);
737
+ }
738
+ #if !defined(_WIN32) || defined(__CYGWIN__)
739
+ if (xar->bytes_remaining ==
740
+ (uint64_t)archive_entry_size(xar->cur_file->entry)) {
741
+ /*
742
+ * Get the path of a shell script if so.
743
+ */
744
+ const unsigned char *b = (const unsigned char *)buff;
745
+
746
+ archive_string_empty(&(xar->cur_file->script));
747
+ if (rsize > 2 && b[0] == '#' && b[1] == '!') {
748
+ size_t i, end, off;
749
+
750
+ off = 2;
751
+ if (b[off] == ' ')
752
+ off++;
753
+ #ifdef PATH_MAX
754
+ if ((rsize - off) > PATH_MAX)
755
+ end = off + PATH_MAX;
756
+ else
757
+ #endif
758
+ end = rsize;
759
+ /* Find the end of a script path. */
760
+ for (i = off; i < end && b[i] != '\0' &&
761
+ b[i] != '\n' && b[i] != '\r' &&
762
+ b[i] != ' ' && b[i] != '\t'; i++)
763
+ ;
764
+ archive_strncpy(&(xar->cur_file->script), b + off,
765
+ i - off);
766
+ }
767
+ }
768
+ #endif
769
+
770
+ if (xar->cur_file->data.compression == NONE) {
771
+ if (write_to_temp(a, buff, size) != ARCHIVE_OK)
772
+ return (ARCHIVE_FATAL);
773
+ xar->cur_file->data.length += size;
774
+ }
775
+ xar->bytes_remaining -= rsize;
776
+
777
+ return (rsize);
778
+ }
779
+
780
+ static int
781
+ xar_finish_entry(struct archive_write *a)
782
+ {
783
+ struct xar *xar;
784
+ struct file *file;
785
+ size_t s;
786
+ ssize_t w;
787
+
788
+ xar = (struct xar *)a->format_data;
789
+ if (xar->cur_file == NULL)
790
+ return (ARCHIVE_OK);
791
+
792
+ while (xar->bytes_remaining > 0) {
793
+ s = (size_t)xar->bytes_remaining;
794
+ if (s > a->null_length)
795
+ s = a->null_length;
796
+ w = xar_write_data(a, a->nulls, s);
797
+ if (w > 0)
798
+ xar->bytes_remaining -= w;
799
+ else
800
+ return (w);
801
+ }
802
+ file = xar->cur_file;
803
+ checksum_final(&(xar->e_sumwrk), &(file->data.e_sum));
804
+ checksum_final(&(xar->a_sumwrk), &(file->data.a_sum));
805
+ xar->cur_file = NULL;
806
+
807
+ return (ARCHIVE_OK);
808
+ }
809
+
810
+ static int
811
+ xmlwrite_string_attr(struct archive_write *a, xmlTextWriterPtr writer,
812
+ const char *key, const char *value,
813
+ const char *attrkey, const char *attrvalue)
814
+ {
815
+ int r;
816
+
817
+ r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
818
+ if (r < 0) {
819
+ archive_set_error(&a->archive,
820
+ ARCHIVE_ERRNO_MISC,
821
+ "xmlTextWriterStartElement() failed: %d", r);
822
+ return (ARCHIVE_FATAL);
823
+ }
824
+ if (attrkey != NULL && attrvalue != NULL) {
825
+ r = xmlTextWriterWriteAttribute(writer,
826
+ BAD_CAST_CONST(attrkey), BAD_CAST_CONST(attrvalue));
827
+ if (r < 0) {
828
+ archive_set_error(&a->archive,
829
+ ARCHIVE_ERRNO_MISC,
830
+ "xmlTextWriterWriteAttribute() failed: %d", r);
831
+ return (ARCHIVE_FATAL);
832
+ }
833
+ }
834
+ if (value != NULL) {
835
+ r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
836
+ if (r < 0) {
837
+ archive_set_error(&a->archive,
838
+ ARCHIVE_ERRNO_MISC,
839
+ "xmlTextWriterWriteString() failed: %d", r);
840
+ return (ARCHIVE_FATAL);
841
+ }
842
+ }
843
+ r = xmlTextWriterEndElement(writer);
844
+ if (r < 0) {
845
+ archive_set_error(&a->archive,
846
+ ARCHIVE_ERRNO_MISC,
847
+ "xmlTextWriterEndElement() failed: %d", r);
848
+ return (ARCHIVE_FATAL);
849
+ }
850
+ return (ARCHIVE_OK);
851
+ }
852
+
853
+ static int
854
+ xmlwrite_string(struct archive_write *a, xmlTextWriterPtr writer,
855
+ const char *key, const char *value)
856
+ {
857
+ int r;
858
+
859
+ if (value == NULL)
860
+ return (ARCHIVE_OK);
861
+
862
+ r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(key));
863
+ if (r < 0) {
864
+ archive_set_error(&a->archive,
865
+ ARCHIVE_ERRNO_MISC,
866
+ "xmlTextWriterStartElement() failed: %d", r);
867
+ return (ARCHIVE_FATAL);
868
+ }
869
+ if (value != NULL) {
870
+ r = xmlTextWriterWriteString(writer, BAD_CAST_CONST(value));
871
+ if (r < 0) {
872
+ archive_set_error(&a->archive,
873
+ ARCHIVE_ERRNO_MISC,
874
+ "xmlTextWriterWriteString() failed: %d", r);
875
+ return (ARCHIVE_FATAL);
876
+ }
877
+ }
878
+ r = xmlTextWriterEndElement(writer);
879
+ if (r < 0) {
880
+ archive_set_error(&a->archive,
881
+ ARCHIVE_ERRNO_MISC,
882
+ "xmlTextWriterEndElement() failed: %d", r);
883
+ return (ARCHIVE_FATAL);
884
+ }
885
+ return (ARCHIVE_OK);
886
+ }
887
+
888
+ static int
889
+ xmlwrite_fstring(struct archive_write *a, xmlTextWriterPtr writer,
890
+ const char *key, const char *fmt, ...)
891
+ {
892
+ struct xar *xar;
893
+ va_list ap;
894
+
895
+ xar = (struct xar *)a->format_data;
896
+ va_start(ap, fmt);
897
+ archive_string_empty(&xar->vstr);
898
+ archive_string_vsprintf(&xar->vstr, fmt, ap);
899
+ va_end(ap);
900
+ return (xmlwrite_string(a, writer, key, xar->vstr.s));
901
+ }
902
+
903
+ static int
904
+ xmlwrite_time(struct archive_write *a, xmlTextWriterPtr writer,
905
+ const char *key, time_t t, int z)
906
+ {
907
+ char timestr[100];
908
+ struct tm tm;
909
+ #if defined(HAVE__GMTIME64_S)
910
+ __time64_t tmptime;
911
+ #endif
912
+
913
+ #if defined(HAVE_GMTIME_R)
914
+ gmtime_r(&t, &tm);
915
+ #elif defined(HAVE__GMTIME64_S)
916
+ tmptime = t;
917
+ _gmtime64_s(&tm, &tmptime);
918
+ #else
919
+ memcpy(&tm, gmtime(&t), sizeof(tm));
920
+ #endif
921
+ memset(&timestr, 0, sizeof(timestr));
922
+ /* Do not use %F and %T for portability. */
923
+ strftime(timestr, sizeof(timestr), "%Y-%m-%dT%H:%M:%S", &tm);
924
+ if (z)
925
+ strcat(timestr, "Z");
926
+ return (xmlwrite_string(a, writer, key, timestr));
927
+ }
928
+
929
+ static int
930
+ xmlwrite_mode(struct archive_write *a, xmlTextWriterPtr writer,
931
+ const char *key, mode_t mode)
932
+ {
933
+ char ms[5];
934
+
935
+ ms[0] = '0';
936
+ ms[1] = '0' + ((mode >> 6) & 07);
937
+ ms[2] = '0' + ((mode >> 3) & 07);
938
+ ms[3] = '0' + (mode & 07);
939
+ ms[4] = '\0';
940
+
941
+ return (xmlwrite_string(a, writer, key, ms));
942
+ }
943
+
944
+ static int
945
+ xmlwrite_sum(struct archive_write *a, xmlTextWriterPtr writer,
946
+ const char *key, struct chksumval *sum)
947
+ {
948
+ const char *algname;
949
+ int algsize;
950
+ char buff[MAX_SUM_SIZE*2 + 1];
951
+ char *p;
952
+ unsigned char *s;
953
+ int i, r;
954
+
955
+ if (sum->len > 0) {
956
+ algname = getalgname(sum->alg);
957
+ algsize = getalgsize(sum->alg);
958
+ if (algname != NULL) {
959
+ const char *hex = "0123456789abcdef";
960
+ p = buff;
961
+ s = sum->val;
962
+ for (i = 0; i < algsize; i++) {
963
+ *p++ = hex[(*s >> 4)];
964
+ *p++ = hex[(*s & 0x0f)];
965
+ s++;
966
+ }
967
+ *p = '\0';
968
+ r = xmlwrite_string_attr(a, writer,
969
+ key, buff,
970
+ "style", algname);
971
+ if (r < 0)
972
+ return (ARCHIVE_FATAL);
973
+ }
974
+ }
975
+ return (ARCHIVE_OK);
976
+ }
977
+
978
+ static int
979
+ xmlwrite_heap(struct archive_write *a, xmlTextWriterPtr writer,
980
+ struct heap_data *heap)
981
+ {
982
+ const char *encname;
983
+ int r;
984
+
985
+ r = xmlwrite_fstring(a, writer, "length", "%ju", heap->length);
986
+ if (r < 0)
987
+ return (ARCHIVE_FATAL);
988
+ r = xmlwrite_fstring(a, writer, "offset", "%ju", heap->temp_offset);
989
+ if (r < 0)
990
+ return (ARCHIVE_FATAL);
991
+ r = xmlwrite_fstring(a, writer, "size", "%ju", heap->size);
992
+ if (r < 0)
993
+ return (ARCHIVE_FATAL);
994
+ switch (heap->compression) {
995
+ case GZIP:
996
+ encname = "application/x-gzip"; break;
997
+ case BZIP2:
998
+ encname = "application/x-bzip2"; break;
999
+ case LZMA:
1000
+ encname = "application/x-lzma"; break;
1001
+ case XZ:
1002
+ encname = "application/x-xz"; break;
1003
+ default:
1004
+ encname = "application/octet-stream"; break;
1005
+ }
1006
+ r = xmlwrite_string_attr(a, writer, "encoding", NULL,
1007
+ "style", encname);
1008
+ if (r < 0)
1009
+ return (ARCHIVE_FATAL);
1010
+ r = xmlwrite_sum(a, writer, "archived-checksum", &(heap->a_sum));
1011
+ if (r < 0)
1012
+ return (ARCHIVE_FATAL);
1013
+ r = xmlwrite_sum(a, writer, "extracted-checksum", &(heap->e_sum));
1014
+ if (r < 0)
1015
+ return (ARCHIVE_FATAL);
1016
+ return (ARCHIVE_OK);
1017
+ }
1018
+
1019
+ /*
1020
+ * xar utility records fflags as following xml elements:
1021
+ * <flags>
1022
+ * <UserNoDump/>
1023
+ * .....
1024
+ * </flags>
1025
+ * or
1026
+ * <ext2>
1027
+ * <NoDump/>
1028
+ * .....
1029
+ * </ext2>
1030
+ * If xar is running on BSD platform, records <flags>..</flags>;
1031
+ * if xar is running on linux platform, records <ext2>..</ext2>;
1032
+ * otherwise does not record.
1033
+ *
1034
+ * Our implements records both <flags> and <ext2> if it's necessary.
1035
+ */
1036
+ static int
1037
+ make_fflags_entry(struct archive_write *a, xmlTextWriterPtr writer,
1038
+ const char *element, const char *fflags_text)
1039
+ {
1040
+ static const struct flagentry {
1041
+ const char *name;
1042
+ const char *xarname;
1043
+ }
1044
+ flagbsd[] = {
1045
+ { "sappnd", "SystemAppend"},
1046
+ { "sappend", "SystemAppend"},
1047
+ { "arch", "SystemArchived"},
1048
+ { "archived", "SystemArchived"},
1049
+ { "schg", "SystemImmutable"},
1050
+ { "schange", "SystemImmutable"},
1051
+ { "simmutable", "SystemImmutable"},
1052
+ { "nosunlnk", "SystemNoUnlink"},
1053
+ { "nosunlink", "SystemNoUnlink"},
1054
+ { "snapshot", "SystemSnapshot"},
1055
+ { "uappnd", "UserAppend"},
1056
+ { "uappend", "UserAppend"},
1057
+ { "uchg", "UserImmutable"},
1058
+ { "uchange", "UserImmutable"},
1059
+ { "uimmutable", "UserImmutable"},
1060
+ { "nodump", "UserNoDump"},
1061
+ { "noopaque", "UserOpaque"},
1062
+ { "nouunlnk", "UserNoUnlink"},
1063
+ { "nouunlink", "UserNoUnlink"},
1064
+ { NULL, NULL}
1065
+ },
1066
+ flagext2[] = {
1067
+ { "sappnd", "AppendOnly"},
1068
+ { "sappend", "AppendOnly"},
1069
+ { "schg", "Immutable"},
1070
+ { "schange", "Immutable"},
1071
+ { "simmutable", "Immutable"},
1072
+ { "nodump", "NoDump"},
1073
+ { "nouunlnk", "Undelete"},
1074
+ { "nouunlink", "Undelete"},
1075
+ { "btree", "BTree"},
1076
+ { "comperr", "CompError"},
1077
+ { "compress", "Compress"},
1078
+ { "noatime", "NoAtime"},
1079
+ { "compdirty", "CompDirty"},
1080
+ { "comprblk", "CompBlock"},
1081
+ { "dirsync", "DirSync"},
1082
+ { "hashidx", "HashIndexed"},
1083
+ { "imagic", "iMagic"},
1084
+ { "journal", "Journaled"},
1085
+ { "securedeletion", "SecureDeletion"},
1086
+ { "sync", "Synchronous"},
1087
+ { "notail", "NoTail"},
1088
+ { "topdir", "TopDir"},
1089
+ { "reserved", "Reserved"},
1090
+ { NULL, NULL}
1091
+ };
1092
+ const struct flagentry *fe, *flagentry;
1093
+ #define FLAGENTRY_MAXSIZE ((sizeof(flagbsd)+sizeof(flagext2))/sizeof(flagbsd))
1094
+ const struct flagentry *avail[FLAGENTRY_MAXSIZE];
1095
+ const char *p;
1096
+ int i, n, r;
1097
+
1098
+ if (strcmp(element, "ext2") == 0)
1099
+ flagentry = flagext2;
1100
+ else
1101
+ flagentry = flagbsd;
1102
+ n = 0;
1103
+ p = fflags_text;
1104
+ do {
1105
+ const char *cp;
1106
+
1107
+ cp = strchr(p, ',');
1108
+ if (cp == NULL)
1109
+ cp = p + strlen(p);
1110
+
1111
+ for (fe = flagentry; fe->name != NULL; fe++) {
1112
+ if (fe->name[cp - p] != '\0'
1113
+ || p[0] != fe->name[0])
1114
+ continue;
1115
+ if (strncmp(p, fe->name, cp - p) == 0) {
1116
+ avail[n++] = fe;
1117
+ break;
1118
+ }
1119
+ }
1120
+ if (*cp == ',')
1121
+ p = cp + 1;
1122
+ else
1123
+ p = NULL;
1124
+ } while (p != NULL);
1125
+
1126
+ if (n > 0) {
1127
+ r = xmlTextWriterStartElement(writer, BAD_CAST_CONST(element));
1128
+ if (r < 0) {
1129
+ archive_set_error(&a->archive,
1130
+ ARCHIVE_ERRNO_MISC,
1131
+ "xmlTextWriterStartElement() failed: %d", r);
1132
+ return (ARCHIVE_FATAL);
1133
+ }
1134
+ for (i = 0; i < n; i++) {
1135
+ r = xmlwrite_string(a, writer,
1136
+ avail[i]->xarname, NULL);
1137
+ if (r != ARCHIVE_OK)
1138
+ return (r);
1139
+ }
1140
+
1141
+ r = xmlTextWriterEndElement(writer);
1142
+ if (r < 0) {
1143
+ archive_set_error(&a->archive,
1144
+ ARCHIVE_ERRNO_MISC,
1145
+ "xmlTextWriterEndElement() failed: %d", r);
1146
+ return (ARCHIVE_FATAL);
1147
+ }
1148
+ }
1149
+ return (ARCHIVE_OK);
1150
+ }
1151
+
1152
+ static int
1153
+ make_file_entry(struct archive_write *a, xmlTextWriterPtr writer,
1154
+ struct file *file)
1155
+ {
1156
+ struct xar *xar;
1157
+ const char *filetype, *filelink, *fflags;
1158
+ struct archive_string linkto;
1159
+ struct heap_data *heap;
1160
+ unsigned char *tmp;
1161
+ const char *p;
1162
+ size_t len;
1163
+ int r, r2, l, ll;
1164
+
1165
+ xar = (struct xar *)a->format_data;
1166
+ r2 = ARCHIVE_OK;
1167
+
1168
+ /*
1169
+ * Make a file name entry, "<name>".
1170
+ */
1171
+ l = ll = archive_strlen(&(file->basename));
1172
+ tmp = malloc(l);
1173
+ if (tmp == NULL) {
1174
+ archive_set_error(&a->archive, ENOMEM,
1175
+ "Can't allocate memory");
1176
+ return (ARCHIVE_FATAL);
1177
+ }
1178
+ r = UTF8Toisolat1(tmp, &l, BAD_CAST(file->basename.s), &ll);
1179
+ free(tmp);
1180
+ if (r < 0) {
1181
+ r = xmlTextWriterStartElement(writer, BAD_CAST("name"));
1182
+ if (r < 0) {
1183
+ archive_set_error(&a->archive,
1184
+ ARCHIVE_ERRNO_MISC,
1185
+ "xmlTextWriterStartElement() failed: %d", r);
1186
+ return (ARCHIVE_FATAL);
1187
+ }
1188
+ r = xmlTextWriterWriteAttribute(writer,
1189
+ BAD_CAST("enctype"), BAD_CAST("base64"));
1190
+ if (r < 0) {
1191
+ archive_set_error(&a->archive,
1192
+ ARCHIVE_ERRNO_MISC,
1193
+ "xmlTextWriterWriteAttribute() failed: %d", r);
1194
+ return (ARCHIVE_FATAL);
1195
+ }
1196
+ r = xmlTextWriterWriteBase64(writer, file->basename.s,
1197
+ 0, archive_strlen(&(file->basename)));
1198
+ if (r < 0) {
1199
+ archive_set_error(&a->archive,
1200
+ ARCHIVE_ERRNO_MISC,
1201
+ "xmlTextWriterWriteBase64() failed: %d", r);
1202
+ return (ARCHIVE_FATAL);
1203
+ }
1204
+ r = xmlTextWriterEndElement(writer);
1205
+ if (r < 0) {
1206
+ archive_set_error(&a->archive,
1207
+ ARCHIVE_ERRNO_MISC,
1208
+ "xmlTextWriterEndElement() failed: %d", r);
1209
+ return (ARCHIVE_FATAL);
1210
+ }
1211
+ } else {
1212
+ r = xmlwrite_string(a, writer, "name", file->basename.s);
1213
+ if (r < 0)
1214
+ return (ARCHIVE_FATAL);
1215
+ }
1216
+
1217
+ /*
1218
+ * Make a file type entry, "<type>".
1219
+ */
1220
+ filelink = NULL;
1221
+ archive_string_init(&linkto);
1222
+ switch (archive_entry_filetype(file->entry)) {
1223
+ case AE_IFDIR:
1224
+ filetype = "directory"; break;
1225
+ case AE_IFLNK:
1226
+ filetype = "symlink"; break;
1227
+ case AE_IFCHR:
1228
+ filetype = "character special"; break;
1229
+ case AE_IFBLK:
1230
+ filetype = "block special"; break;
1231
+ case AE_IFSOCK:
1232
+ filetype = "socket"; break;
1233
+ case AE_IFIFO:
1234
+ filetype = "fifo"; break;
1235
+ case AE_IFREG:
1236
+ default:
1237
+ if (file->hardlink_target != NULL) {
1238
+ filetype = "hardlink";
1239
+ filelink = "link";
1240
+ if (file->hardlink_target == file)
1241
+ archive_strcpy(&linkto, "original");
1242
+ else
1243
+ archive_string_sprintf(&linkto, "%d",
1244
+ file->hardlink_target->id);
1245
+ } else
1246
+ filetype = "file";
1247
+ break;
1248
+ }
1249
+ r = xmlwrite_string_attr(a, writer, "type", filetype,
1250
+ filelink, linkto.s);
1251
+ archive_string_free(&linkto);
1252
+ if (r < 0)
1253
+ return (ARCHIVE_FATAL);
1254
+
1255
+ /*
1256
+ * On a virtual directory, we record "name" and "type" only.
1257
+ */
1258
+ if (file->virtual)
1259
+ return (ARCHIVE_OK);
1260
+
1261
+ switch (archive_entry_filetype(file->entry)) {
1262
+ case AE_IFLNK:
1263
+ /*
1264
+ * xar utility has checked a file type, which
1265
+ * a symbolic-link file has referenced.
1266
+ * For example:
1267
+ * <link type="directory">../ref/</link>
1268
+ * The symlink target file is "../ref/" and its
1269
+ * file type is a directory.
1270
+ *
1271
+ * <link type="file">../f</link>
1272
+ * The symlink target file is "../f" and its
1273
+ * file type is a regular file.
1274
+ *
1275
+ * But our implementation cannot do it, and then we
1276
+ * always record that a attribute "type" is "broken",
1277
+ * for example:
1278
+ * <link type="broken">foo/bar</link>
1279
+ * It means "foo/bar" is not reachable.
1280
+ */
1281
+ r = xmlwrite_string_attr(a, writer, "link",
1282
+ file->symlink.s,
1283
+ "type", "broken");
1284
+ if (r < 0)
1285
+ return (ARCHIVE_FATAL);
1286
+ break;
1287
+ case AE_IFCHR:
1288
+ case AE_IFBLK:
1289
+ r = xmlTextWriterStartElement(writer, BAD_CAST("device"));
1290
+ if (r < 0) {
1291
+ archive_set_error(&a->archive,
1292
+ ARCHIVE_ERRNO_MISC,
1293
+ "xmlTextWriterStartElement() failed: %d", r);
1294
+ return (ARCHIVE_FATAL);
1295
+ }
1296
+ r = xmlwrite_fstring(a, writer, "major",
1297
+ "%d", archive_entry_rdevmajor(file->entry));
1298
+ if (r < 0)
1299
+ return (ARCHIVE_FATAL);
1300
+ r = xmlwrite_fstring(a, writer, "minor",
1301
+ "%d", archive_entry_rdevminor(file->entry));
1302
+ if (r < 0)
1303
+ return (ARCHIVE_FATAL);
1304
+ r = xmlTextWriterEndElement(writer);
1305
+ if (r < 0) {
1306
+ archive_set_error(&a->archive,
1307
+ ARCHIVE_ERRNO_MISC,
1308
+ "xmlTextWriterEndElement() failed: %d", r);
1309
+ return (ARCHIVE_FATAL);
1310
+ }
1311
+ break;
1312
+ default:
1313
+ break;
1314
+ }
1315
+
1316
+ /*
1317
+ * Make a inode entry, "<inode>".
1318
+ */
1319
+ r = xmlwrite_fstring(a, writer, "inode",
1320
+ "%jd", archive_entry_ino64(file->entry));
1321
+ if (r < 0)
1322
+ return (ARCHIVE_FATAL);
1323
+ if (archive_entry_dev(file->entry) != 0) {
1324
+ r = xmlwrite_fstring(a, writer, "deviceno",
1325
+ "%d", archive_entry_dev(file->entry));
1326
+ if (r < 0)
1327
+ return (ARCHIVE_FATAL);
1328
+ }
1329
+
1330
+ /*
1331
+ * Make a file mode entry, "<mode>".
1332
+ */
1333
+ r = xmlwrite_mode(a, writer, "mode",
1334
+ archive_entry_mode(file->entry));
1335
+ if (r < 0)
1336
+ return (ARCHIVE_FATAL);
1337
+
1338
+ /*
1339
+ * Make a user entry, "<uid>" and "<user>.
1340
+ */
1341
+ r = xmlwrite_fstring(a, writer, "uid",
1342
+ "%d", archive_entry_uid(file->entry));
1343
+ if (r < 0)
1344
+ return (ARCHIVE_FATAL);
1345
+ r = archive_entry_uname_l(file->entry, &p, &len, xar->sconv);
1346
+ if (r != 0) {
1347
+ if (errno == ENOMEM) {
1348
+ archive_set_error(&a->archive, ENOMEM,
1349
+ "Can't allocate memory for Uname");
1350
+ return (ARCHIVE_FATAL);
1351
+ }
1352
+ archive_set_error(&a->archive,
1353
+ ARCHIVE_ERRNO_FILE_FORMAT,
1354
+ "Can't translate uname '%s' to UTF-8",
1355
+ archive_entry_uname(file->entry));
1356
+ r2 = ARCHIVE_WARN;
1357
+ }
1358
+ if (len > 0) {
1359
+ r = xmlwrite_string(a, writer, "user", p);
1360
+ if (r < 0)
1361
+ return (ARCHIVE_FATAL);
1362
+ }
1363
+
1364
+ /*
1365
+ * Make a group entry, "<gid>" and "<group>.
1366
+ */
1367
+ r = xmlwrite_fstring(a, writer, "gid",
1368
+ "%d", archive_entry_gid(file->entry));
1369
+ if (r < 0)
1370
+ return (ARCHIVE_FATAL);
1371
+ r = archive_entry_gname_l(file->entry, &p, &len, xar->sconv);
1372
+ if (r != 0) {
1373
+ if (errno == ENOMEM) {
1374
+ archive_set_error(&a->archive, ENOMEM,
1375
+ "Can't allocate memory for Gname");
1376
+ return (ARCHIVE_FATAL);
1377
+ }
1378
+ archive_set_error(&a->archive,
1379
+ ARCHIVE_ERRNO_FILE_FORMAT,
1380
+ "Can't translate gname '%s' to UTF-8",
1381
+ archive_entry_gname(file->entry));
1382
+ r2 = ARCHIVE_WARN;
1383
+ }
1384
+ if (len > 0) {
1385
+ r = xmlwrite_string(a, writer, "group", p);
1386
+ if (r < 0)
1387
+ return (ARCHIVE_FATAL);
1388
+ }
1389
+
1390
+ /*
1391
+ * Make a ctime entry, "<ctime>".
1392
+ */
1393
+ if (archive_entry_ctime_is_set(file->entry)) {
1394
+ r = xmlwrite_time(a, writer, "ctime",
1395
+ archive_entry_ctime(file->entry), 1);
1396
+ if (r < 0)
1397
+ return (ARCHIVE_FATAL);
1398
+ }
1399
+
1400
+ /*
1401
+ * Make a mtime entry, "<mtime>".
1402
+ */
1403
+ if (archive_entry_mtime_is_set(file->entry)) {
1404
+ r = xmlwrite_time(a, writer, "mtime",
1405
+ archive_entry_mtime(file->entry), 1);
1406
+ if (r < 0)
1407
+ return (ARCHIVE_FATAL);
1408
+ }
1409
+
1410
+ /*
1411
+ * Make a atime entry, "<atime>".
1412
+ */
1413
+ if (archive_entry_atime_is_set(file->entry)) {
1414
+ r = xmlwrite_time(a, writer, "atime",
1415
+ archive_entry_atime(file->entry), 1);
1416
+ if (r < 0)
1417
+ return (ARCHIVE_FATAL);
1418
+ }
1419
+
1420
+ /*
1421
+ * Make fflags entries, "<flags>" and "<ext2>".
1422
+ */
1423
+ fflags = archive_entry_fflags_text(file->entry);
1424
+ if (fflags != NULL) {
1425
+ r = make_fflags_entry(a, writer, "flags", fflags);
1426
+ if (r < 0)
1427
+ return (r);
1428
+ r = make_fflags_entry(a, writer, "ext2", fflags);
1429
+ if (r < 0)
1430
+ return (r);
1431
+ }
1432
+
1433
+ /*
1434
+ * Make extended attribute entries, "<ea>".
1435
+ */
1436
+ archive_entry_xattr_reset(file->entry);
1437
+ for (heap = file->xattr.first; heap != NULL; heap = heap->next) {
1438
+ const char *name;
1439
+ const void *value;
1440
+ size_t size;
1441
+
1442
+ archive_entry_xattr_next(file->entry,
1443
+ &name, &value, &size);
1444
+ r = xmlTextWriterStartElement(writer, BAD_CAST("ea"));
1445
+ if (r < 0) {
1446
+ archive_set_error(&a->archive,
1447
+ ARCHIVE_ERRNO_MISC,
1448
+ "xmlTextWriterStartElement() failed: %d", r);
1449
+ return (ARCHIVE_FATAL);
1450
+ }
1451
+ r = xmlTextWriterWriteFormatAttribute(writer,
1452
+ BAD_CAST("id"), "%d", heap->id);
1453
+ if (r < 0) {
1454
+ archive_set_error(&a->archive,
1455
+ ARCHIVE_ERRNO_MISC,
1456
+ "xmlTextWriterWriteAttribute() failed: %d", r);
1457
+ return (ARCHIVE_FATAL);
1458
+ }
1459
+ r = xmlwrite_heap(a, writer, heap);
1460
+ if (r < 0)
1461
+ return (ARCHIVE_FATAL);
1462
+ r = xmlwrite_string(a, writer, "name", name);
1463
+ if (r < 0)
1464
+ return (ARCHIVE_FATAL);
1465
+
1466
+ r = xmlTextWriterEndElement(writer);
1467
+ if (r < 0) {
1468
+ archive_set_error(&a->archive,
1469
+ ARCHIVE_ERRNO_MISC,
1470
+ "xmlTextWriterEndElement() failed: %d", r);
1471
+ return (ARCHIVE_FATAL);
1472
+ }
1473
+ }
1474
+
1475
+ /*
1476
+ * Make a file data entry, "<data>".
1477
+ */
1478
+ if (file->data.length > 0) {
1479
+ r = xmlTextWriterStartElement(writer, BAD_CAST("data"));
1480
+ if (r < 0) {
1481
+ archive_set_error(&a->archive,
1482
+ ARCHIVE_ERRNO_MISC,
1483
+ "xmlTextWriterStartElement() failed: %d", r);
1484
+ return (ARCHIVE_FATAL);
1485
+ }
1486
+
1487
+ r = xmlwrite_heap(a, writer, &(file->data));
1488
+ if (r < 0)
1489
+ return (ARCHIVE_FATAL);
1490
+
1491
+ r = xmlTextWriterEndElement(writer);
1492
+ if (r < 0) {
1493
+ archive_set_error(&a->archive,
1494
+ ARCHIVE_ERRNO_MISC,
1495
+ "xmlTextWriterEndElement() failed: %d", r);
1496
+ return (ARCHIVE_FATAL);
1497
+ }
1498
+ }
1499
+
1500
+ if (archive_strlen(&file->script) > 0) {
1501
+ r = xmlTextWriterStartElement(writer, BAD_CAST("content"));
1502
+ if (r < 0) {
1503
+ archive_set_error(&a->archive,
1504
+ ARCHIVE_ERRNO_MISC,
1505
+ "xmlTextWriterStartElement() failed: %d", r);
1506
+ return (ARCHIVE_FATAL);
1507
+ }
1508
+
1509
+ r = xmlwrite_string(a, writer,
1510
+ "interpreter", file->script.s);
1511
+ if (r < 0)
1512
+ return (ARCHIVE_FATAL);
1513
+
1514
+ r = xmlwrite_string(a, writer, "type", "script");
1515
+ if (r < 0)
1516
+ return (ARCHIVE_FATAL);
1517
+
1518
+ r = xmlTextWriterEndElement(writer);
1519
+ if (r < 0) {
1520
+ archive_set_error(&a->archive,
1521
+ ARCHIVE_ERRNO_MISC,
1522
+ "xmlTextWriterEndElement() failed: %d", r);
1523
+ return (ARCHIVE_FATAL);
1524
+ }
1525
+ }
1526
+
1527
+ return (r2);
1528
+ }
1529
+
1530
+ /*
1531
+ * Make the TOC
1532
+ */
1533
+ static int
1534
+ make_toc(struct archive_write *a)
1535
+ {
1536
+ struct xar *xar;
1537
+ struct file *np;
1538
+ xmlBufferPtr bp;
1539
+ xmlTextWriterPtr writer;
1540
+ int algsize;
1541
+ int r, ret;
1542
+
1543
+ xar = (struct xar *)a->format_data;
1544
+
1545
+ ret = ARCHIVE_FATAL;
1546
+
1547
+ /*
1548
+ * Initialize xml writer.
1549
+ */
1550
+ writer = NULL;
1551
+ bp = xmlBufferCreate();
1552
+ if (bp == NULL) {
1553
+ archive_set_error(&a->archive, ENOMEM,
1554
+ "xmlBufferCreate() "
1555
+ "couldn't create xml buffer");
1556
+ goto exit_toc;
1557
+ }
1558
+ writer = xmlNewTextWriterMemory(bp, 0);
1559
+ if (writer == NULL) {
1560
+ archive_set_error(&a->archive,
1561
+ ARCHIVE_ERRNO_MISC,
1562
+ "xmlNewTextWriterMemory() "
1563
+ "couldn't create xml writer");
1564
+ goto exit_toc;
1565
+ }
1566
+ r = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL);
1567
+ if (r < 0) {
1568
+ archive_set_error(&a->archive,
1569
+ ARCHIVE_ERRNO_MISC,
1570
+ "xmlTextWriterStartDocument() failed: %d", r);
1571
+ goto exit_toc;
1572
+ }
1573
+ r = xmlTextWriterSetIndent(writer, 4);
1574
+ if (r < 0) {
1575
+ archive_set_error(&a->archive,
1576
+ ARCHIVE_ERRNO_MISC,
1577
+ "xmlTextWriterSetIndent() failed: %d", r);
1578
+ goto exit_toc;
1579
+ }
1580
+
1581
+ /*
1582
+ * Start recording TOC
1583
+ */
1584
+ r = xmlTextWriterStartElement(writer, BAD_CAST("xar"));
1585
+ if (r < 0) {
1586
+ archive_set_error(&a->archive,
1587
+ ARCHIVE_ERRNO_MISC,
1588
+ "xmlTextWriterStartElement() failed: %d", r);
1589
+ goto exit_toc;
1590
+ }
1591
+ r = xmlTextWriterStartElement(writer, BAD_CAST("toc"));
1592
+ if (r < 0) {
1593
+ archive_set_error(&a->archive,
1594
+ ARCHIVE_ERRNO_MISC,
1595
+ "xmlTextWriterStartDocument() failed: %d", r);
1596
+ goto exit_toc;
1597
+ }
1598
+
1599
+ /*
1600
+ * Record the creation time of the archive file.
1601
+ */
1602
+ r = xmlwrite_time(a, writer, "creation-time", time(NULL), 0);
1603
+ if (r < 0)
1604
+ goto exit_toc;
1605
+
1606
+ /*
1607
+ * Record the checksum value of TOC
1608
+ */
1609
+ algsize = getalgsize(xar->opt_toc_sumalg);
1610
+ if (algsize) {
1611
+ /*
1612
+ * Record TOC checksum
1613
+ */
1614
+ r = xmlTextWriterStartElement(writer, BAD_CAST("checksum"));
1615
+ if (r < 0) {
1616
+ archive_set_error(&a->archive,
1617
+ ARCHIVE_ERRNO_MISC,
1618
+ "xmlTextWriterStartElement() failed: %d", r);
1619
+ goto exit_toc;
1620
+ }
1621
+ r = xmlTextWriterWriteAttribute(writer, BAD_CAST("style"),
1622
+ BAD_CAST_CONST(getalgname(xar->opt_toc_sumalg)));
1623
+ if (r < 0) {
1624
+ archive_set_error(&a->archive,
1625
+ ARCHIVE_ERRNO_MISC,
1626
+ "xmlTextWriterWriteAttribute() failed: %d", r);
1627
+ goto exit_toc;
1628
+ }
1629
+
1630
+ /*
1631
+ * Record the offset of the value of checksum of TOC
1632
+ */
1633
+ r = xmlwrite_string(a, writer, "offset", "0");
1634
+ if (r < 0)
1635
+ goto exit_toc;
1636
+
1637
+ /*
1638
+ * Record the size of the value of checksum of TOC
1639
+ */
1640
+ r = xmlwrite_fstring(a, writer, "size", "%d", algsize);
1641
+ if (r < 0)
1642
+ goto exit_toc;
1643
+
1644
+ r = xmlTextWriterEndElement(writer);
1645
+ if (r < 0) {
1646
+ archive_set_error(&a->archive,
1647
+ ARCHIVE_ERRNO_MISC,
1648
+ "xmlTextWriterEndElement() failed: %d", r);
1649
+ goto exit_toc;
1650
+ }
1651
+ }
1652
+
1653
+ np = xar->root;
1654
+ do {
1655
+ if (np != np->parent) {
1656
+ r = make_file_entry(a, writer, np);
1657
+ if (r != ARCHIVE_OK)
1658
+ goto exit_toc;
1659
+ }
1660
+
1661
+ if (np->dir && np->children.first != NULL) {
1662
+ /* Enter to sub directories. */
1663
+ np = np->children.first;
1664
+ r = xmlTextWriterStartElement(writer,
1665
+ BAD_CAST("file"));
1666
+ if (r < 0) {
1667
+ archive_set_error(&a->archive,
1668
+ ARCHIVE_ERRNO_MISC,
1669
+ "xmlTextWriterStartElement() "
1670
+ "failed: %d", r);
1671
+ goto exit_toc;
1672
+ }
1673
+ r = xmlTextWriterWriteFormatAttribute(
1674
+ writer, BAD_CAST("id"), "%d", np->id);
1675
+ if (r < 0) {
1676
+ archive_set_error(&a->archive,
1677
+ ARCHIVE_ERRNO_MISC,
1678
+ "xmlTextWriterWriteAttribute() "
1679
+ "failed: %d", r);
1680
+ goto exit_toc;
1681
+ }
1682
+ continue;
1683
+ }
1684
+ while (np != np->parent) {
1685
+ r = xmlTextWriterEndElement(writer);
1686
+ if (r < 0) {
1687
+ archive_set_error(&a->archive,
1688
+ ARCHIVE_ERRNO_MISC,
1689
+ "xmlTextWriterEndElement() "
1690
+ "failed: %d", r);
1691
+ goto exit_toc;
1692
+ }
1693
+ if (np->chnext == NULL) {
1694
+ /* Return to the parent directory. */
1695
+ np = np->parent;
1696
+ } else {
1697
+ np = np->chnext;
1698
+ r = xmlTextWriterStartElement(writer,
1699
+ BAD_CAST("file"));
1700
+ if (r < 0) {
1701
+ archive_set_error(&a->archive,
1702
+ ARCHIVE_ERRNO_MISC,
1703
+ "xmlTextWriterStartElement() "
1704
+ "failed: %d", r);
1705
+ goto exit_toc;
1706
+ }
1707
+ r = xmlTextWriterWriteFormatAttribute(
1708
+ writer, BAD_CAST("id"), "%d", np->id);
1709
+ if (r < 0) {
1710
+ archive_set_error(&a->archive,
1711
+ ARCHIVE_ERRNO_MISC,
1712
+ "xmlTextWriterWriteAttribute() "
1713
+ "failed: %d", r);
1714
+ goto exit_toc;
1715
+ }
1716
+ break;
1717
+ }
1718
+ }
1719
+ } while (np != np->parent);
1720
+
1721
+ r = xmlTextWriterEndDocument(writer);
1722
+ if (r < 0) {
1723
+ archive_set_error(&a->archive,
1724
+ ARCHIVE_ERRNO_MISC,
1725
+ "xmlTextWriterEndDocument() failed: %d", r);
1726
+ goto exit_toc;
1727
+ }
1728
+ #if DEBUG_PRINT_TOC
1729
+ fprintf(stderr, "\n---TOC-- %d bytes --\n%s\n",
1730
+ strlen((const char *)bp->content), bp->content);
1731
+ #endif
1732
+
1733
+ /*
1734
+ * Compress the TOC and calculate the sum of the TOC.
1735
+ */
1736
+ xar->toc.temp_offset = xar->temp_offset;
1737
+ xar->toc.size = bp->use;
1738
+ checksum_init(&(xar->a_sumwrk), xar->opt_toc_sumalg);
1739
+
1740
+ r = compression_init_encoder_gzip(&(a->archive),
1741
+ &(xar->stream), 6, 1);
1742
+ if (r != ARCHIVE_OK)
1743
+ goto exit_toc;
1744
+ xar->stream.next_in = bp->content;
1745
+ xar->stream.avail_in = bp->use;
1746
+ xar->stream.total_in = 0;
1747
+ xar->stream.next_out = xar->wbuff;
1748
+ xar->stream.avail_out = sizeof(xar->wbuff);
1749
+ xar->stream.total_out = 0;
1750
+ for (;;) {
1751
+ size_t size;
1752
+
1753
+ r = compression_code(&(a->archive),
1754
+ &(xar->stream), ARCHIVE_Z_FINISH);
1755
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF)
1756
+ goto exit_toc;
1757
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
1758
+ checksum_update(&(xar->a_sumwrk), xar->wbuff, size);
1759
+ if (write_to_temp(a, xar->wbuff, size) != ARCHIVE_OK)
1760
+ goto exit_toc;
1761
+ if (r == ARCHIVE_EOF)
1762
+ break;
1763
+ xar->stream.next_out = xar->wbuff;
1764
+ xar->stream.avail_out = sizeof(xar->wbuff);
1765
+ }
1766
+ r = compression_end(&(a->archive), &(xar->stream));
1767
+ if (r != ARCHIVE_OK)
1768
+ goto exit_toc;
1769
+ xar->toc.length = xar->stream.total_out;
1770
+ xar->toc.compression = GZIP;
1771
+ checksum_final(&(xar->a_sumwrk), &(xar->toc.a_sum));
1772
+
1773
+ ret = ARCHIVE_OK;
1774
+ exit_toc:
1775
+ if (writer)
1776
+ xmlFreeTextWriter(writer);
1777
+ if (bp)
1778
+ xmlBufferFree(bp);
1779
+
1780
+ return (ret);
1781
+ }
1782
+
1783
+ static int
1784
+ flush_wbuff(struct archive_write *a)
1785
+ {
1786
+ struct xar *xar;
1787
+ int r;
1788
+ size_t s;
1789
+
1790
+ xar = (struct xar *)a->format_data;
1791
+ s = sizeof(xar->wbuff) - xar->wbuff_remaining;
1792
+ r = __archive_write_output(a, xar->wbuff, s);
1793
+ if (r != ARCHIVE_OK)
1794
+ return (r);
1795
+ xar->wbuff_remaining = sizeof(xar->wbuff);
1796
+ return (r);
1797
+ }
1798
+
1799
+ static int
1800
+ copy_out(struct archive_write *a, uint64_t offset, uint64_t length)
1801
+ {
1802
+ struct xar *xar;
1803
+ int r;
1804
+
1805
+ xar = (struct xar *)a->format_data;
1806
+ if (lseek(xar->temp_fd, offset, SEEK_SET) < 0) {
1807
+ archive_set_error(&(a->archive), errno, "lseek failed");
1808
+ return (ARCHIVE_FATAL);
1809
+ }
1810
+ while (length) {
1811
+ size_t rsize;
1812
+ ssize_t rs;
1813
+ unsigned char *wb;
1814
+
1815
+ if (length > xar->wbuff_remaining)
1816
+ rsize = xar->wbuff_remaining;
1817
+ else
1818
+ rsize = (size_t)length;
1819
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1820
+ rs = read(xar->temp_fd, wb, rsize);
1821
+ if (rs < 0) {
1822
+ archive_set_error(&(a->archive), errno,
1823
+ "Can't read temporary file(%jd)",
1824
+ (intmax_t)rs);
1825
+ return (ARCHIVE_FATAL);
1826
+ }
1827
+ if (rs == 0) {
1828
+ archive_set_error(&(a->archive), 0,
1829
+ "Truncated xar archive");
1830
+ return (ARCHIVE_FATAL);
1831
+ }
1832
+ xar->wbuff_remaining -= rs;
1833
+ length -= rs;
1834
+ if (xar->wbuff_remaining == 0) {
1835
+ r = flush_wbuff(a);
1836
+ if (r != ARCHIVE_OK)
1837
+ return (r);
1838
+ }
1839
+ }
1840
+ return (ARCHIVE_OK);
1841
+ }
1842
+
1843
+ static int
1844
+ xar_close(struct archive_write *a)
1845
+ {
1846
+ struct xar *xar;
1847
+ unsigned char *wb;
1848
+ uint64_t length;
1849
+ int r;
1850
+
1851
+ xar = (struct xar *)a->format_data;
1852
+
1853
+ /* Empty! */
1854
+ if (xar->root->children.first == NULL)
1855
+ return (ARCHIVE_OK);
1856
+
1857
+ /* Save the length of all file extended attributes and contents. */
1858
+ length = xar->temp_offset;
1859
+
1860
+ /* Connect hardlinked files */
1861
+ file_connect_hardlink_files(xar);
1862
+
1863
+ /* Make the TOC */
1864
+ r = make_toc(a);
1865
+ if (r != ARCHIVE_OK)
1866
+ return (r);
1867
+ /*
1868
+ * Make the xar header on wbuff(write buffer).
1869
+ */
1870
+ wb = xar->wbuff;
1871
+ xar->wbuff_remaining = sizeof(xar->wbuff);
1872
+ archive_be32enc(&wb[0], HEADER_MAGIC);
1873
+ archive_be16enc(&wb[4], HEADER_SIZE);
1874
+ archive_be16enc(&wb[6], HEADER_VERSION);
1875
+ archive_be64enc(&wb[8], xar->toc.length);
1876
+ archive_be64enc(&wb[16], xar->toc.size);
1877
+ archive_be32enc(&wb[24], xar->toc.a_sum.alg);
1878
+ xar->wbuff_remaining -= HEADER_SIZE;
1879
+
1880
+ /*
1881
+ * Write the TOC
1882
+ */
1883
+ r = copy_out(a, xar->toc.temp_offset, xar->toc.length);
1884
+ if (r != ARCHIVE_OK)
1885
+ return (r);
1886
+
1887
+ /* Write the checksum value of the TOC. */
1888
+ if (xar->toc.a_sum.len) {
1889
+ if (xar->wbuff_remaining < xar->toc.a_sum.len) {
1890
+ r = flush_wbuff(a);
1891
+ if (r != ARCHIVE_OK)
1892
+ return (r);
1893
+ }
1894
+ wb = xar->wbuff + (sizeof(xar->wbuff) - xar->wbuff_remaining);
1895
+ memcpy(wb, xar->toc.a_sum.val, xar->toc.a_sum.len);
1896
+ xar->wbuff_remaining -= xar->toc.a_sum.len;
1897
+ }
1898
+
1899
+ /*
1900
+ * Write all file extended attributes and contents.
1901
+ */
1902
+ r = copy_out(a, xar->toc.a_sum.len, length);
1903
+ if (r != ARCHIVE_OK)
1904
+ return (r);
1905
+ r = flush_wbuff(a);
1906
+ return (r);
1907
+ }
1908
+
1909
+ static int
1910
+ xar_free(struct archive_write *a)
1911
+ {
1912
+ struct xar *xar;
1913
+
1914
+ xar = (struct xar *)a->format_data;
1915
+
1916
+ /* Close the temporary file. */
1917
+ if (xar->temp_fd >= 0)
1918
+ close(xar->temp_fd);
1919
+
1920
+ archive_string_free(&(xar->cur_dirstr));
1921
+ archive_string_free(&(xar->tstr));
1922
+ archive_string_free(&(xar->vstr));
1923
+ file_free_hardlinks(xar);
1924
+ file_free_register(xar);
1925
+ compression_end(&(a->archive), &(xar->stream));
1926
+ free(xar);
1927
+
1928
+ return (ARCHIVE_OK);
1929
+ }
1930
+
1931
+ static int
1932
+ file_cmp_node(const struct archive_rb_node *n1,
1933
+ const struct archive_rb_node *n2)
1934
+ {
1935
+ const struct file *f1 = (const struct file *)n1;
1936
+ const struct file *f2 = (const struct file *)n2;
1937
+
1938
+ return (strcmp(f1->basename.s, f2->basename.s));
1939
+ }
1940
+
1941
+ static int
1942
+ file_cmp_key(const struct archive_rb_node *n, const void *key)
1943
+ {
1944
+ const struct file *f = (const struct file *)n;
1945
+
1946
+ return (strcmp(f->basename.s, (const char *)key));
1947
+ }
1948
+
1949
+ static struct file *
1950
+ file_new(struct archive_write *a, struct archive_entry *entry)
1951
+ {
1952
+ struct file *file;
1953
+ static const struct archive_rb_tree_ops rb_ops = {
1954
+ file_cmp_node, file_cmp_key
1955
+ };
1956
+
1957
+ file = calloc(1, sizeof(*file));
1958
+ if (file == NULL)
1959
+ return (NULL);
1960
+
1961
+ if (entry != NULL)
1962
+ file->entry = archive_entry_clone(entry);
1963
+ else
1964
+ file->entry = archive_entry_new2(&a->archive);
1965
+ if (file->entry == NULL) {
1966
+ free(file);
1967
+ return (NULL);
1968
+ }
1969
+ __archive_rb_tree_init(&(file->rbtree), &rb_ops);
1970
+ file->children.first = NULL;
1971
+ file->children.last = &(file->children.first);
1972
+ file->xattr.first = NULL;
1973
+ file->xattr.last = &(file->xattr.first);
1974
+ archive_string_init(&(file->parentdir));
1975
+ archive_string_init(&(file->basename));
1976
+ archive_string_init(&(file->symlink));
1977
+ archive_string_init(&(file->script));
1978
+ if (entry != NULL && archive_entry_filetype(entry) == AE_IFDIR)
1979
+ file->dir = 1;
1980
+
1981
+ return (file);
1982
+ }
1983
+
1984
+ static void
1985
+ file_free(struct file *file)
1986
+ {
1987
+ struct heap_data *heap, *next_heap;
1988
+
1989
+ heap = file->xattr.first;
1990
+ while (heap != NULL) {
1991
+ next_heap = heap->next;
1992
+ free(heap);
1993
+ heap = next_heap;
1994
+ }
1995
+ archive_string_free(&(file->parentdir));
1996
+ archive_string_free(&(file->basename));
1997
+ archive_string_free(&(file->symlink));
1998
+ archive_string_free(&(file->script));
1999
+ archive_entry_free(file->entry);
2000
+ free(file);
2001
+ }
2002
+
2003
+ static struct file *
2004
+ file_create_virtual_dir(struct archive_write *a, struct xar *xar,
2005
+ const char *pathname)
2006
+ {
2007
+ struct file *file;
2008
+
2009
+ (void)xar; /* UNUSED */
2010
+
2011
+ file = file_new(a, NULL);
2012
+ if (file == NULL)
2013
+ return (NULL);
2014
+ archive_entry_set_pathname(file->entry, pathname);
2015
+ archive_entry_set_mode(file->entry, 0555 | AE_IFDIR);
2016
+
2017
+ file->dir = 1;
2018
+ file->virtual = 1;
2019
+
2020
+ return (file);
2021
+ }
2022
+
2023
+ static int
2024
+ file_add_child_tail(struct file *parent, struct file *child)
2025
+ {
2026
+ if (!__archive_rb_tree_insert_node(
2027
+ &(parent->rbtree), (struct archive_rb_node *)child))
2028
+ return (0);
2029
+ child->chnext = NULL;
2030
+ *parent->children.last = child;
2031
+ parent->children.last = &(child->chnext);
2032
+ child->parent = parent;
2033
+ return (1);
2034
+ }
2035
+
2036
+ /*
2037
+ * Find a entry from `parent'
2038
+ */
2039
+ static struct file *
2040
+ file_find_child(struct file *parent, const char *child_name)
2041
+ {
2042
+ struct file *np;
2043
+
2044
+ np = (struct file *)__archive_rb_tree_find_node(
2045
+ &(parent->rbtree), child_name);
2046
+ return (np);
2047
+ }
2048
+
2049
+ #if defined(_WIN32) || defined(__CYGWIN__)
2050
+ static void
2051
+ cleanup_backslash(char *utf8, size_t len)
2052
+ {
2053
+
2054
+ /* Convert a path-separator from '\' to '/' */
2055
+ while (*utf8 != '\0' && len) {
2056
+ if (*utf8 == '\\')
2057
+ *utf8 = '/';
2058
+ ++utf8;
2059
+ --len;
2060
+ }
2061
+ }
2062
+ #else
2063
+ #define cleanup_backslash(p, len) /* nop */
2064
+ #endif
2065
+
2066
+ /*
2067
+ * Generate a parent directory name and a base name from a pathname.
2068
+ */
2069
+ static int
2070
+ file_gen_utility_names(struct archive_write *a, struct file *file)
2071
+ {
2072
+ struct xar *xar;
2073
+ const char *pp;
2074
+ char *p, *dirname, *slash;
2075
+ size_t len;
2076
+ int r = ARCHIVE_OK;
2077
+
2078
+ xar = (struct xar *)a->format_data;
2079
+ archive_string_empty(&(file->parentdir));
2080
+ archive_string_empty(&(file->basename));
2081
+ archive_string_empty(&(file->symlink));
2082
+
2083
+ if (file->parent == file)/* virtual root */
2084
+ return (ARCHIVE_OK);
2085
+
2086
+ if (archive_entry_pathname_l(file->entry, &pp, &len, xar->sconv)
2087
+ != 0) {
2088
+ if (errno == ENOMEM) {
2089
+ archive_set_error(&a->archive, ENOMEM,
2090
+ "Can't allocate memory for Pathname");
2091
+ return (ARCHIVE_FATAL);
2092
+ }
2093
+ archive_set_error(&a->archive,
2094
+ ARCHIVE_ERRNO_FILE_FORMAT,
2095
+ "Can't translate pathname '%s' to UTF-8",
2096
+ archive_entry_pathname(file->entry));
2097
+ r = ARCHIVE_WARN;
2098
+ }
2099
+ archive_strncpy(&(file->parentdir), pp, len);
2100
+ len = file->parentdir.length;
2101
+ p = dirname = file->parentdir.s;
2102
+ /*
2103
+ * Convert a path-separator from '\' to '/'
2104
+ */
2105
+ cleanup_backslash(p, len);
2106
+
2107
+ /*
2108
+ * Remove leading '/', '../' and './' elements
2109
+ */
2110
+ while (*p) {
2111
+ if (p[0] == '/') {
2112
+ p++;
2113
+ len--;
2114
+ } else if (p[0] != '.')
2115
+ break;
2116
+ else if (p[1] == '.' && p[2] == '/') {
2117
+ p += 3;
2118
+ len -= 3;
2119
+ } else if (p[1] == '/' || (p[1] == '.' && p[2] == '\0')) {
2120
+ p += 2;
2121
+ len -= 2;
2122
+ } else if (p[1] == '\0') {
2123
+ p++;
2124
+ len--;
2125
+ } else
2126
+ break;
2127
+ }
2128
+ if (p != dirname) {
2129
+ memmove(dirname, p, len+1);
2130
+ p = dirname;
2131
+ }
2132
+ /*
2133
+ * Remove "/","/." and "/.." elements from tail.
2134
+ */
2135
+ while (len > 0) {
2136
+ size_t ll = len;
2137
+
2138
+ if (p[len-1] == '/') {
2139
+ p[len-1] = '\0';
2140
+ len--;
2141
+ }
2142
+ if (len > 1 && p[len-2] == '/' && p[len-1] == '.') {
2143
+ p[len-2] = '\0';
2144
+ len -= 2;
2145
+ }
2146
+ if (len > 2 && p[len-3] == '/' && p[len-2] == '.' &&
2147
+ p[len-1] == '.') {
2148
+ p[len-3] = '\0';
2149
+ len -= 3;
2150
+ }
2151
+ if (ll == len)
2152
+ break;
2153
+ }
2154
+ while (*p) {
2155
+ if (p[0] == '/') {
2156
+ if (p[1] == '/')
2157
+ /* Convert '//' --> '/' */
2158
+ memmove(p, p+1, strlen(p+1) + 1);
2159
+ else if (p[1] == '.' && p[2] == '/')
2160
+ /* Convert '/./' --> '/' */
2161
+ memmove(p, p+2, strlen(p+2) + 1);
2162
+ else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
2163
+ /* Convert 'dir/dir1/../dir2/'
2164
+ * --> 'dir/dir2/'
2165
+ */
2166
+ char *rp = p -1;
2167
+ while (rp >= dirname) {
2168
+ if (*rp == '/')
2169
+ break;
2170
+ --rp;
2171
+ }
2172
+ if (rp > dirname) {
2173
+ strcpy(rp, p+3);
2174
+ p = rp;
2175
+ } else {
2176
+ strcpy(dirname, p+4);
2177
+ p = dirname;
2178
+ }
2179
+ } else
2180
+ p++;
2181
+ } else
2182
+ p++;
2183
+ }
2184
+ p = dirname;
2185
+ len = strlen(p);
2186
+
2187
+ if (archive_entry_filetype(file->entry) == AE_IFLNK) {
2188
+ size_t len2;
2189
+ /* Convert symlink name too. */
2190
+ if (archive_entry_symlink_l(file->entry, &pp, &len2,
2191
+ xar->sconv) != 0) {
2192
+ if (errno == ENOMEM) {
2193
+ archive_set_error(&a->archive, ENOMEM,
2194
+ "Can't allocate memory for Linkname");
2195
+ return (ARCHIVE_FATAL);
2196
+ }
2197
+ archive_set_error(&a->archive,
2198
+ ARCHIVE_ERRNO_FILE_FORMAT,
2199
+ "Can't translate symlink '%s' to UTF-8",
2200
+ archive_entry_symlink(file->entry));
2201
+ r = ARCHIVE_WARN;
2202
+ }
2203
+ archive_strncpy(&(file->symlink), pp, len2);
2204
+ cleanup_backslash(file->symlink.s, file->symlink.length);
2205
+ }
2206
+ /*
2207
+ * - Count up directory elements.
2208
+ * - Find out the position which points the last position of
2209
+ * path separator('/').
2210
+ */
2211
+ slash = NULL;
2212
+ for (; *p != '\0'; p++)
2213
+ if (*p == '/')
2214
+ slash = p;
2215
+ if (slash == NULL) {
2216
+ /* The pathname doesn't have a parent directory. */
2217
+ file->parentdir.length = len;
2218
+ archive_string_copy(&(file->basename), &(file->parentdir));
2219
+ archive_string_empty(&(file->parentdir));
2220
+ *file->parentdir.s = '\0';
2221
+ return (r);
2222
+ }
2223
+
2224
+ /* Make a basename from dirname and slash */
2225
+ *slash = '\0';
2226
+ file->parentdir.length = slash - dirname;
2227
+ archive_strcpy(&(file->basename), slash + 1);
2228
+ return (r);
2229
+ }
2230
+
2231
+ static int
2232
+ get_path_component(char *name, int n, const char *fn)
2233
+ {
2234
+ char *p;
2235
+ int l;
2236
+
2237
+ p = strchr(fn, '/');
2238
+ if (p == NULL) {
2239
+ if ((l = strlen(fn)) == 0)
2240
+ return (0);
2241
+ } else
2242
+ l = p - fn;
2243
+ if (l > n -1)
2244
+ return (-1);
2245
+ memcpy(name, fn, l);
2246
+ name[l] = '\0';
2247
+
2248
+ return (l);
2249
+ }
2250
+
2251
+ /*
2252
+ * Add a new entry into the tree.
2253
+ */
2254
+ static int
2255
+ file_tree(struct archive_write *a, struct file **filepp)
2256
+ {
2257
+ #if defined(_WIN32) && !defined(__CYGWIN__)
2258
+ char name[_MAX_FNAME];/* Included null terminator size. */
2259
+ #elif defined(NAME_MAX) && NAME_MAX >= 255
2260
+ char name[NAME_MAX+1];
2261
+ #else
2262
+ char name[256];
2263
+ #endif
2264
+ struct xar *xar = (struct xar *)a->format_data;
2265
+ struct file *dent, *file, *np;
2266
+ struct archive_entry *ent;
2267
+ const char *fn, *p;
2268
+ int l;
2269
+
2270
+ file = *filepp;
2271
+ dent = xar->root;
2272
+ if (file->parentdir.length > 0)
2273
+ fn = p = file->parentdir.s;
2274
+ else
2275
+ fn = p = "";
2276
+
2277
+ /*
2278
+ * If the path of the parent directory of `file' entry is
2279
+ * the same as the path of `cur_dirent', add isoent to
2280
+ * `cur_dirent'.
2281
+ */
2282
+ if (archive_strlen(&(xar->cur_dirstr))
2283
+ == archive_strlen(&(file->parentdir)) &&
2284
+ strcmp(xar->cur_dirstr.s, fn) == 0) {
2285
+ if (!file_add_child_tail(xar->cur_dirent, file)) {
2286
+ np = (struct file *)__archive_rb_tree_find_node(
2287
+ &(xar->cur_dirent->rbtree),
2288
+ file->basename.s);
2289
+ goto same_entry;
2290
+ }
2291
+ return (ARCHIVE_OK);
2292
+ }
2293
+
2294
+ for (;;) {
2295
+ l = get_path_component(name, sizeof(name), fn);
2296
+ if (l == 0) {
2297
+ np = NULL;
2298
+ break;
2299
+ }
2300
+ if (l < 0) {
2301
+ archive_set_error(&a->archive,
2302
+ ARCHIVE_ERRNO_MISC,
2303
+ "A name buffer is too small");
2304
+ file_free(file);
2305
+ *filepp = NULL;
2306
+ return (ARCHIVE_FATAL);
2307
+ }
2308
+
2309
+ np = file_find_child(dent, name);
2310
+ if (np == NULL || fn[0] == '\0')
2311
+ break;
2312
+
2313
+ /* Find next subdirectory. */
2314
+ if (!np->dir) {
2315
+ /* NOT Directory! */
2316
+ archive_set_error(&a->archive,
2317
+ ARCHIVE_ERRNO_MISC,
2318
+ "`%s' is not directory, we cannot insert `%s' ",
2319
+ archive_entry_pathname(np->entry),
2320
+ archive_entry_pathname(file->entry));
2321
+ file_free(file);
2322
+ *filepp = NULL;
2323
+ return (ARCHIVE_FAILED);
2324
+ }
2325
+ fn += l;
2326
+ if (fn[0] == '/')
2327
+ fn++;
2328
+ dent = np;
2329
+ }
2330
+ if (np == NULL) {
2331
+ /*
2332
+ * Create virtual parent directories.
2333
+ */
2334
+ while (fn[0] != '\0') {
2335
+ struct file *vp;
2336
+ struct archive_string as;
2337
+
2338
+ archive_string_init(&as);
2339
+ archive_strncat(&as, p, fn - p + l);
2340
+ if (as.s[as.length-1] == '/') {
2341
+ as.s[as.length-1] = '\0';
2342
+ as.length--;
2343
+ }
2344
+ vp = file_create_virtual_dir(a, xar, as.s);
2345
+ if (vp == NULL) {
2346
+ archive_string_free(&as);
2347
+ archive_set_error(&a->archive, ENOMEM,
2348
+ "Can't allocate memory");
2349
+ file_free(file);
2350
+ *filepp = NULL;
2351
+ return (ARCHIVE_FATAL);
2352
+ }
2353
+ archive_string_free(&as);
2354
+ if (file_gen_utility_names(a, vp) <= ARCHIVE_FAILED)
2355
+ return (ARCHIVE_FATAL);
2356
+ file_add_child_tail(dent, vp);
2357
+ file_register(xar, vp);
2358
+ np = vp;
2359
+
2360
+ fn += l;
2361
+ if (fn[0] == '/')
2362
+ fn++;
2363
+ l = get_path_component(name, sizeof(name), fn);
2364
+ if (l < 0) {
2365
+ archive_string_free(&as);
2366
+ archive_set_error(&a->archive,
2367
+ ARCHIVE_ERRNO_MISC,
2368
+ "A name buffer is too small");
2369
+ file_free(file);
2370
+ *filepp = NULL;
2371
+ return (ARCHIVE_FATAL);
2372
+ }
2373
+ dent = np;
2374
+ }
2375
+
2376
+ /* Found out the parent directory where isoent can be
2377
+ * inserted. */
2378
+ xar->cur_dirent = dent;
2379
+ archive_string_empty(&(xar->cur_dirstr));
2380
+ archive_string_ensure(&(xar->cur_dirstr),
2381
+ archive_strlen(&(dent->parentdir)) +
2382
+ archive_strlen(&(dent->basename)) + 2);
2383
+ if (archive_strlen(&(dent->parentdir)) +
2384
+ archive_strlen(&(dent->basename)) == 0)
2385
+ xar->cur_dirstr.s[0] = 0;
2386
+ else {
2387
+ if (archive_strlen(&(dent->parentdir)) > 0) {
2388
+ archive_string_copy(&(xar->cur_dirstr),
2389
+ &(dent->parentdir));
2390
+ archive_strappend_char(&(xar->cur_dirstr), '/');
2391
+ }
2392
+ archive_string_concat(&(xar->cur_dirstr),
2393
+ &(dent->basename));
2394
+ }
2395
+
2396
+ if (!file_add_child_tail(dent, file)) {
2397
+ np = (struct file *)__archive_rb_tree_find_node(
2398
+ &(dent->rbtree), file->basename.s);
2399
+ goto same_entry;
2400
+ }
2401
+ return (ARCHIVE_OK);
2402
+ }
2403
+
2404
+ same_entry:
2405
+ /*
2406
+ * We have already has the entry the filename of which is
2407
+ * the same.
2408
+ */
2409
+ if (archive_entry_filetype(np->entry) !=
2410
+ archive_entry_filetype(file->entry)) {
2411
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
2412
+ "Found duplicate entries `%s' and its file type is "
2413
+ "different",
2414
+ archive_entry_pathname(np->entry));
2415
+ file_free(file);
2416
+ *filepp = NULL;
2417
+ return (ARCHIVE_FAILED);
2418
+ }
2419
+
2420
+ /* Swap files. */
2421
+ ent = np->entry;
2422
+ np->entry = file->entry;
2423
+ file->entry = ent;
2424
+ np->virtual = 0;
2425
+
2426
+ file_free(file);
2427
+ *filepp = np;
2428
+ return (ARCHIVE_OK);
2429
+ }
2430
+
2431
+ static void
2432
+ file_register(struct xar *xar, struct file *file)
2433
+ {
2434
+ file->id = xar->file_idx++;
2435
+ file->next = NULL;
2436
+ *xar->file_list.last = file;
2437
+ xar->file_list.last = &(file->next);
2438
+ }
2439
+
2440
+ static void
2441
+ file_init_register(struct xar *xar)
2442
+ {
2443
+ xar->file_list.first = NULL;
2444
+ xar->file_list.last = &(xar->file_list.first);
2445
+ }
2446
+
2447
+ static void
2448
+ file_free_register(struct xar *xar)
2449
+ {
2450
+ struct file *file, *file_next;
2451
+
2452
+ file = xar->file_list.first;
2453
+ while (file != NULL) {
2454
+ file_next = file->next;
2455
+ file_free(file);
2456
+ file = file_next;
2457
+ }
2458
+ }
2459
+
2460
+ /*
2461
+ * Register entry to get a hardlink target.
2462
+ */
2463
+ static int
2464
+ file_register_hardlink(struct archive_write *a, struct file *file)
2465
+ {
2466
+ struct xar *xar = (struct xar *)a->format_data;
2467
+ struct hardlink *hl;
2468
+ const char *pathname;
2469
+
2470
+ archive_entry_set_nlink(file->entry, 1);
2471
+ pathname = archive_entry_hardlink(file->entry);
2472
+ if (pathname == NULL) {
2473
+ /* This `file` is a hardlink target. */
2474
+ hl = malloc(sizeof(*hl));
2475
+ if (hl == NULL) {
2476
+ archive_set_error(&a->archive, ENOMEM,
2477
+ "Can't allocate memory");
2478
+ return (ARCHIVE_FATAL);
2479
+ }
2480
+ hl->nlink = 1;
2481
+ /* A hardlink target must be the first position. */
2482
+ file->hlnext = NULL;
2483
+ hl->file_list.first = file;
2484
+ hl->file_list.last = &(file->hlnext);
2485
+ __archive_rb_tree_insert_node(&(xar->hardlink_rbtree),
2486
+ (struct archive_rb_node *)hl);
2487
+ } else {
2488
+ hl = (struct hardlink *)__archive_rb_tree_find_node(
2489
+ &(xar->hardlink_rbtree), pathname);
2490
+ if (hl != NULL) {
2491
+ /* Insert `file` entry into the tail. */
2492
+ file->hlnext = NULL;
2493
+ *hl->file_list.last = file;
2494
+ hl->file_list.last = &(file->hlnext);
2495
+ hl->nlink++;
2496
+ }
2497
+ archive_entry_unset_size(file->entry);
2498
+ }
2499
+
2500
+ return (ARCHIVE_OK);
2501
+ }
2502
+
2503
+ /*
2504
+ * Hardlinked files have to have the same location of extent.
2505
+ * We have to find out hardlink target entries for entries which
2506
+ * have a hardlink target name.
2507
+ */
2508
+ static void
2509
+ file_connect_hardlink_files(struct xar *xar)
2510
+ {
2511
+ struct archive_rb_node *n;
2512
+ struct hardlink *hl;
2513
+ struct file *target, *nf;
2514
+
2515
+ ARCHIVE_RB_TREE_FOREACH(n, &(xar->hardlink_rbtree)) {
2516
+ hl = (struct hardlink *)n;
2517
+
2518
+ /* The first entry must be a hardlink target. */
2519
+ target = hl->file_list.first;
2520
+ archive_entry_set_nlink(target->entry, hl->nlink);
2521
+ if (hl->nlink > 1)
2522
+ /* It means this file is a hardlink
2523
+ * target itself. */
2524
+ target->hardlink_target = target;
2525
+ for (nf = target->hlnext;
2526
+ nf != NULL; nf = nf->hlnext) {
2527
+ nf->hardlink_target = target;
2528
+ archive_entry_set_nlink(nf->entry, hl->nlink);
2529
+ }
2530
+ }
2531
+ }
2532
+
2533
+ static int
2534
+ file_hd_cmp_node(const struct archive_rb_node *n1,
2535
+ const struct archive_rb_node *n2)
2536
+ {
2537
+ const struct hardlink *h1 = (const struct hardlink *)n1;
2538
+ const struct hardlink *h2 = (const struct hardlink *)n2;
2539
+
2540
+ return (strcmp(archive_entry_pathname(h1->file_list.first->entry),
2541
+ archive_entry_pathname(h2->file_list.first->entry)));
2542
+ }
2543
+
2544
+ static int
2545
+ file_hd_cmp_key(const struct archive_rb_node *n, const void *key)
2546
+ {
2547
+ const struct hardlink *h = (const struct hardlink *)n;
2548
+
2549
+ return (strcmp(archive_entry_pathname(h->file_list.first->entry),
2550
+ (const char *)key));
2551
+ }
2552
+
2553
+
2554
+ static void
2555
+ file_init_hardlinks(struct xar *xar)
2556
+ {
2557
+ static const struct archive_rb_tree_ops rb_ops = {
2558
+ file_hd_cmp_node, file_hd_cmp_key,
2559
+ };
2560
+
2561
+ __archive_rb_tree_init(&(xar->hardlink_rbtree), &rb_ops);
2562
+ }
2563
+
2564
+ static void
2565
+ file_free_hardlinks(struct xar *xar)
2566
+ {
2567
+ struct archive_rb_node *n, *tmp;
2568
+
2569
+ ARCHIVE_RB_TREE_FOREACH_SAFE(n, &(xar->hardlink_rbtree), tmp) {
2570
+ __archive_rb_tree_remove_node(&(xar->hardlink_rbtree), n);
2571
+ free(n);
2572
+ }
2573
+ }
2574
+
2575
+ static void
2576
+ checksum_init(struct chksumwork *sumwrk, enum sumalg sum_alg)
2577
+ {
2578
+ sumwrk->alg = sum_alg;
2579
+ switch (sum_alg) {
2580
+ case CKSUM_NONE:
2581
+ break;
2582
+ case CKSUM_SHA1:
2583
+ archive_sha1_init(&(sumwrk->sha1ctx));
2584
+ break;
2585
+ case CKSUM_MD5:
2586
+ archive_md5_init(&(sumwrk->md5ctx));
2587
+ break;
2588
+ }
2589
+ }
2590
+
2591
+ static void
2592
+ checksum_update(struct chksumwork *sumwrk, const void *buff, size_t size)
2593
+ {
2594
+
2595
+ switch (sumwrk->alg) {
2596
+ case CKSUM_NONE:
2597
+ break;
2598
+ case CKSUM_SHA1:
2599
+ archive_sha1_update(&(sumwrk->sha1ctx), buff, size);
2600
+ break;
2601
+ case CKSUM_MD5:
2602
+ archive_md5_update(&(sumwrk->md5ctx), buff, size);
2603
+ break;
2604
+ }
2605
+ }
2606
+
2607
+ static void
2608
+ checksum_final(struct chksumwork *sumwrk, struct chksumval *sumval)
2609
+ {
2610
+
2611
+ switch (sumwrk->alg) {
2612
+ case CKSUM_NONE:
2613
+ sumval->len = 0;
2614
+ break;
2615
+ case CKSUM_SHA1:
2616
+ archive_sha1_final(&(sumwrk->sha1ctx), sumval->val);
2617
+ sumval->len = SHA1_SIZE;
2618
+ break;
2619
+ case CKSUM_MD5:
2620
+ archive_md5_final(&(sumwrk->md5ctx), sumval->val);
2621
+ sumval->len = MD5_SIZE;
2622
+ break;
2623
+ }
2624
+ sumval->alg = sumwrk->alg;
2625
+ }
2626
+
2627
+ #if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
2628
+ static int
2629
+ compression_unsupported_encoder(struct archive *a,
2630
+ struct la_zstream *lastrm, const char *name)
2631
+ {
2632
+
2633
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2634
+ "%s compression not supported on this platform", name);
2635
+ lastrm->valid = 0;
2636
+ lastrm->real_stream = NULL;
2637
+ return (ARCHIVE_FAILED);
2638
+ }
2639
+ #endif
2640
+
2641
+ static int
2642
+ compression_init_encoder_gzip(struct archive *a,
2643
+ struct la_zstream *lastrm, int level, int withheader)
2644
+ {
2645
+ z_stream *strm;
2646
+
2647
+ if (lastrm->valid)
2648
+ compression_end(a, lastrm);
2649
+ strm = calloc(1, sizeof(*strm));
2650
+ if (strm == NULL) {
2651
+ archive_set_error(a, ENOMEM,
2652
+ "Can't allocate memory for gzip stream");
2653
+ return (ARCHIVE_FATAL);
2654
+ }
2655
+ /* zlib.h is not const-correct, so we need this one bit
2656
+ * of ugly hackery to convert a const * pointer to
2657
+ * a non-const pointer. */
2658
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2659
+ strm->avail_in = lastrm->avail_in;
2660
+ strm->total_in = (uLong)lastrm->total_in;
2661
+ strm->next_out = lastrm->next_out;
2662
+ strm->avail_out = lastrm->avail_out;
2663
+ strm->total_out = (uLong)lastrm->total_out;
2664
+ if (deflateInit2(strm, level, Z_DEFLATED,
2665
+ (withheader)?15:-15,
2666
+ 8, Z_DEFAULT_STRATEGY) != Z_OK) {
2667
+ free(strm);
2668
+ lastrm->real_stream = NULL;
2669
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2670
+ "Internal error initializing compression library");
2671
+ return (ARCHIVE_FATAL);
2672
+ }
2673
+ lastrm->real_stream = strm;
2674
+ lastrm->valid = 1;
2675
+ lastrm->code = compression_code_gzip;
2676
+ lastrm->end = compression_end_gzip;
2677
+ return (ARCHIVE_OK);
2678
+ }
2679
+
2680
+ static int
2681
+ compression_code_gzip(struct archive *a,
2682
+ struct la_zstream *lastrm, enum la_zaction action)
2683
+ {
2684
+ z_stream *strm;
2685
+ int r;
2686
+
2687
+ strm = (z_stream *)lastrm->real_stream;
2688
+ /* zlib.h is not const-correct, so we need this one bit
2689
+ * of ugly hackery to convert a const * pointer to
2690
+ * a non-const pointer. */
2691
+ strm->next_in = (Bytef *)(uintptr_t)(const void *)lastrm->next_in;
2692
+ strm->avail_in = lastrm->avail_in;
2693
+ strm->total_in = (uLong)lastrm->total_in;
2694
+ strm->next_out = lastrm->next_out;
2695
+ strm->avail_out = lastrm->avail_out;
2696
+ strm->total_out = (uLong)lastrm->total_out;
2697
+ r = deflate(strm,
2698
+ (action == ARCHIVE_Z_FINISH)? Z_FINISH: Z_NO_FLUSH);
2699
+ lastrm->next_in = strm->next_in;
2700
+ lastrm->avail_in = strm->avail_in;
2701
+ lastrm->total_in = strm->total_in;
2702
+ lastrm->next_out = strm->next_out;
2703
+ lastrm->avail_out = strm->avail_out;
2704
+ lastrm->total_out = strm->total_out;
2705
+ switch (r) {
2706
+ case Z_OK:
2707
+ return (ARCHIVE_OK);
2708
+ case Z_STREAM_END:
2709
+ return (ARCHIVE_EOF);
2710
+ default:
2711
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2712
+ "GZip compression failed:"
2713
+ " deflate() call returned status %d", r);
2714
+ return (ARCHIVE_FATAL);
2715
+ }
2716
+ }
2717
+
2718
+ static int
2719
+ compression_end_gzip(struct archive *a, struct la_zstream *lastrm)
2720
+ {
2721
+ z_stream *strm;
2722
+ int r;
2723
+
2724
+ strm = (z_stream *)lastrm->real_stream;
2725
+ r = deflateEnd(strm);
2726
+ free(strm);
2727
+ lastrm->real_stream = NULL;
2728
+ lastrm->valid = 0;
2729
+ if (r != Z_OK) {
2730
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2731
+ "Failed to clean up compressor");
2732
+ return (ARCHIVE_FATAL);
2733
+ }
2734
+ return (ARCHIVE_OK);
2735
+ }
2736
+
2737
+ #if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
2738
+ static int
2739
+ compression_init_encoder_bzip2(struct archive *a,
2740
+ struct la_zstream *lastrm, int level)
2741
+ {
2742
+ bz_stream *strm;
2743
+
2744
+ if (lastrm->valid)
2745
+ compression_end(a, lastrm);
2746
+ strm = calloc(1, sizeof(*strm));
2747
+ if (strm == NULL) {
2748
+ archive_set_error(a, ENOMEM,
2749
+ "Can't allocate memory for bzip2 stream");
2750
+ return (ARCHIVE_FATAL);
2751
+ }
2752
+ /* bzlib.h is not const-correct, so we need this one bit
2753
+ * of ugly hackery to convert a const * pointer to
2754
+ * a non-const pointer. */
2755
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2756
+ strm->avail_in = lastrm->avail_in;
2757
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2758
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2759
+ strm->next_out = (char *)lastrm->next_out;
2760
+ strm->avail_out = lastrm->avail_out;
2761
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2762
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2763
+ if (BZ2_bzCompressInit(strm, level, 0, 30) != BZ_OK) {
2764
+ free(strm);
2765
+ lastrm->real_stream = NULL;
2766
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2767
+ "Internal error initializing compression library");
2768
+ return (ARCHIVE_FATAL);
2769
+ }
2770
+ lastrm->real_stream = strm;
2771
+ lastrm->valid = 1;
2772
+ lastrm->code = compression_code_bzip2;
2773
+ lastrm->end = compression_end_bzip2;
2774
+ return (ARCHIVE_OK);
2775
+ }
2776
+
2777
+ static int
2778
+ compression_code_bzip2(struct archive *a,
2779
+ struct la_zstream *lastrm, enum la_zaction action)
2780
+ {
2781
+ bz_stream *strm;
2782
+ int r;
2783
+
2784
+ strm = (bz_stream *)lastrm->real_stream;
2785
+ /* bzlib.h is not const-correct, so we need this one bit
2786
+ * of ugly hackery to convert a const * pointer to
2787
+ * a non-const pointer. */
2788
+ strm->next_in = (char *)(uintptr_t)(const void *)lastrm->next_in;
2789
+ strm->avail_in = lastrm->avail_in;
2790
+ strm->total_in_lo32 = (uint32_t)(lastrm->total_in & 0xffffffff);
2791
+ strm->total_in_hi32 = (uint32_t)(lastrm->total_in >> 32);
2792
+ strm->next_out = (char *)lastrm->next_out;
2793
+ strm->avail_out = lastrm->avail_out;
2794
+ strm->total_out_lo32 = (uint32_t)(lastrm->total_out & 0xffffffff);
2795
+ strm->total_out_hi32 = (uint32_t)(lastrm->total_out >> 32);
2796
+ r = BZ2_bzCompress(strm,
2797
+ (action == ARCHIVE_Z_FINISH)? BZ_FINISH: BZ_RUN);
2798
+ lastrm->next_in = (const unsigned char *)strm->next_in;
2799
+ lastrm->avail_in = strm->avail_in;
2800
+ lastrm->total_in =
2801
+ (((uint64_t)(uint32_t)strm->total_in_hi32) << 32)
2802
+ + (uint64_t)(uint32_t)strm->total_in_lo32;
2803
+ lastrm->next_out = (unsigned char *)strm->next_out;
2804
+ lastrm->avail_out = strm->avail_out;
2805
+ lastrm->total_out =
2806
+ (((uint64_t)(uint32_t)strm->total_out_hi32) << 32)
2807
+ + (uint64_t)(uint32_t)strm->total_out_lo32;
2808
+ switch (r) {
2809
+ case BZ_RUN_OK: /* Non-finishing */
2810
+ case BZ_FINISH_OK: /* Finishing: There's more work to do */
2811
+ return (ARCHIVE_OK);
2812
+ case BZ_STREAM_END: /* Finishing: all done */
2813
+ /* Only occurs in finishing case */
2814
+ return (ARCHIVE_EOF);
2815
+ default:
2816
+ /* Any other return value indicates an error */
2817
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2818
+ "Bzip2 compression failed:"
2819
+ " BZ2_bzCompress() call returned status %d", r);
2820
+ return (ARCHIVE_FATAL);
2821
+ }
2822
+ }
2823
+
2824
+ static int
2825
+ compression_end_bzip2(struct archive *a, struct la_zstream *lastrm)
2826
+ {
2827
+ bz_stream *strm;
2828
+ int r;
2829
+
2830
+ strm = (bz_stream *)lastrm->real_stream;
2831
+ r = BZ2_bzCompressEnd(strm);
2832
+ free(strm);
2833
+ lastrm->real_stream = NULL;
2834
+ lastrm->valid = 0;
2835
+ if (r != BZ_OK) {
2836
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2837
+ "Failed to clean up compressor");
2838
+ return (ARCHIVE_FATAL);
2839
+ }
2840
+ return (ARCHIVE_OK);
2841
+ }
2842
+
2843
+ #else
2844
+ static int
2845
+ compression_init_encoder_bzip2(struct archive *a,
2846
+ struct la_zstream *lastrm, int level)
2847
+ {
2848
+
2849
+ (void) level; /* UNUSED */
2850
+ if (lastrm->valid)
2851
+ compression_end(a, lastrm);
2852
+ return (compression_unsupported_encoder(a, lastrm, "bzip2"));
2853
+ }
2854
+ #endif
2855
+
2856
+ #if defined(HAVE_LZMA_H)
2857
+ static int
2858
+ compression_init_encoder_lzma(struct archive *a,
2859
+ struct la_zstream *lastrm, int level)
2860
+ {
2861
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2862
+ lzma_stream *strm;
2863
+ lzma_options_lzma lzma_opt;
2864
+ int r;
2865
+
2866
+ if (lastrm->valid)
2867
+ compression_end(a, lastrm);
2868
+ if (lzma_lzma_preset(&lzma_opt, level)) {
2869
+ lastrm->real_stream = NULL;
2870
+ archive_set_error(a, ENOMEM,
2871
+ "Internal error initializing compression library");
2872
+ return (ARCHIVE_FATAL);
2873
+ }
2874
+ strm = calloc(1, sizeof(*strm));
2875
+ if (strm == NULL) {
2876
+ archive_set_error(a, ENOMEM,
2877
+ "Can't allocate memory for lzma stream");
2878
+ return (ARCHIVE_FATAL);
2879
+ }
2880
+ *strm = lzma_init_data;
2881
+ r = lzma_alone_encoder(strm, &lzma_opt);
2882
+ switch (r) {
2883
+ case LZMA_OK:
2884
+ lastrm->real_stream = strm;
2885
+ lastrm->valid = 1;
2886
+ lastrm->code = compression_code_lzma;
2887
+ lastrm->end = compression_end_lzma;
2888
+ r = ARCHIVE_OK;
2889
+ break;
2890
+ case LZMA_MEM_ERROR:
2891
+ free(strm);
2892
+ lastrm->real_stream = NULL;
2893
+ archive_set_error(a, ENOMEM,
2894
+ "Internal error initializing compression library: "
2895
+ "Cannot allocate memory");
2896
+ r = ARCHIVE_FATAL;
2897
+ break;
2898
+ default:
2899
+ free(strm);
2900
+ lastrm->real_stream = NULL;
2901
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2902
+ "Internal error initializing compression library: "
2903
+ "It's a bug in liblzma");
2904
+ r = ARCHIVE_FATAL;
2905
+ break;
2906
+ }
2907
+ return (r);
2908
+ }
2909
+
2910
+ static int
2911
+ compression_init_encoder_xz(struct archive *a,
2912
+ struct la_zstream *lastrm, int level, int threads)
2913
+ {
2914
+ static const lzma_stream lzma_init_data = LZMA_STREAM_INIT;
2915
+ lzma_stream *strm;
2916
+ lzma_filter *lzmafilters;
2917
+ lzma_options_lzma lzma_opt;
2918
+ int r;
2919
+ #ifdef HAVE_LZMA_STREAM_ENCODER_MT
2920
+ lzma_mt mt_options;
2921
+ #endif
2922
+
2923
+ (void)threads; /* UNUSED (if multi-threaded LZMA library not avail) */
2924
+
2925
+ if (lastrm->valid)
2926
+ compression_end(a, lastrm);
2927
+ strm = calloc(1, sizeof(*strm) + sizeof(*lzmafilters) * 2);
2928
+ if (strm == NULL) {
2929
+ archive_set_error(a, ENOMEM,
2930
+ "Can't allocate memory for xz stream");
2931
+ return (ARCHIVE_FATAL);
2932
+ }
2933
+ lzmafilters = (lzma_filter *)(strm+1);
2934
+ if (level > 9)
2935
+ level = 9;
2936
+ if (lzma_lzma_preset(&lzma_opt, level)) {
2937
+ free(strm);
2938
+ lastrm->real_stream = NULL;
2939
+ archive_set_error(a, ENOMEM,
2940
+ "Internal error initializing compression library");
2941
+ return (ARCHIVE_FATAL);
2942
+ }
2943
+ lzmafilters[0].id = LZMA_FILTER_LZMA2;
2944
+ lzmafilters[0].options = &lzma_opt;
2945
+ lzmafilters[1].id = LZMA_VLI_UNKNOWN;/* Terminate */
2946
+
2947
+ *strm = lzma_init_data;
2948
+ #ifdef HAVE_LZMA_STREAM_ENCODER_MT
2949
+ if (threads > 1) {
2950
+ memset(&mt_options, 0, sizeof(mt_options));
2951
+ mt_options.threads = threads;
2952
+ mt_options.timeout = 300;
2953
+ mt_options.filters = lzmafilters;
2954
+ mt_options.check = LZMA_CHECK_CRC64;
2955
+ r = lzma_stream_encoder_mt(strm, &mt_options);
2956
+ } else
2957
+ #endif
2958
+ r = lzma_stream_encoder(strm, lzmafilters, LZMA_CHECK_CRC64);
2959
+ switch (r) {
2960
+ case LZMA_OK:
2961
+ lastrm->real_stream = strm;
2962
+ lastrm->valid = 1;
2963
+ lastrm->code = compression_code_lzma;
2964
+ lastrm->end = compression_end_lzma;
2965
+ r = ARCHIVE_OK;
2966
+ break;
2967
+ case LZMA_MEM_ERROR:
2968
+ free(strm);
2969
+ lastrm->real_stream = NULL;
2970
+ archive_set_error(a, ENOMEM,
2971
+ "Internal error initializing compression library: "
2972
+ "Cannot allocate memory");
2973
+ r = ARCHIVE_FATAL;
2974
+ break;
2975
+ default:
2976
+ free(strm);
2977
+ lastrm->real_stream = NULL;
2978
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
2979
+ "Internal error initializing compression library: "
2980
+ "It's a bug in liblzma");
2981
+ r = ARCHIVE_FATAL;
2982
+ break;
2983
+ }
2984
+ return (r);
2985
+ }
2986
+
2987
+ static int
2988
+ compression_code_lzma(struct archive *a,
2989
+ struct la_zstream *lastrm, enum la_zaction action)
2990
+ {
2991
+ lzma_stream *strm;
2992
+ int r;
2993
+
2994
+ strm = (lzma_stream *)lastrm->real_stream;
2995
+ strm->next_in = lastrm->next_in;
2996
+ strm->avail_in = lastrm->avail_in;
2997
+ strm->total_in = lastrm->total_in;
2998
+ strm->next_out = lastrm->next_out;
2999
+ strm->avail_out = lastrm->avail_out;
3000
+ strm->total_out = lastrm->total_out;
3001
+ r = lzma_code(strm,
3002
+ (action == ARCHIVE_Z_FINISH)? LZMA_FINISH: LZMA_RUN);
3003
+ lastrm->next_in = strm->next_in;
3004
+ lastrm->avail_in = strm->avail_in;
3005
+ lastrm->total_in = strm->total_in;
3006
+ lastrm->next_out = strm->next_out;
3007
+ lastrm->avail_out = strm->avail_out;
3008
+ lastrm->total_out = strm->total_out;
3009
+ switch (r) {
3010
+ case LZMA_OK:
3011
+ /* Non-finishing case */
3012
+ return (ARCHIVE_OK);
3013
+ case LZMA_STREAM_END:
3014
+ /* This return can only occur in finishing case. */
3015
+ return (ARCHIVE_EOF);
3016
+ case LZMA_MEMLIMIT_ERROR:
3017
+ archive_set_error(a, ENOMEM,
3018
+ "lzma compression error:"
3019
+ " %ju MiB would have been needed",
3020
+ (uintmax_t)((lzma_memusage(strm) + 1024 * 1024 -1)
3021
+ / (1024 * 1024)));
3022
+ return (ARCHIVE_FATAL);
3023
+ default:
3024
+ /* Any other return value indicates an error */
3025
+ archive_set_error(a, ARCHIVE_ERRNO_MISC,
3026
+ "lzma compression failed:"
3027
+ " lzma_code() call returned status %d", r);
3028
+ return (ARCHIVE_FATAL);
3029
+ }
3030
+ }
3031
+
3032
+ static int
3033
+ compression_end_lzma(struct archive *a, struct la_zstream *lastrm)
3034
+ {
3035
+ lzma_stream *strm;
3036
+
3037
+ (void)a; /* UNUSED */
3038
+ strm = (lzma_stream *)lastrm->real_stream;
3039
+ lzma_end(strm);
3040
+ free(strm);
3041
+ lastrm->valid = 0;
3042
+ lastrm->real_stream = NULL;
3043
+ return (ARCHIVE_OK);
3044
+ }
3045
+ #else
3046
+ static int
3047
+ compression_init_encoder_lzma(struct archive *a,
3048
+ struct la_zstream *lastrm, int level)
3049
+ {
3050
+
3051
+ (void) level; /* UNUSED */
3052
+ if (lastrm->valid)
3053
+ compression_end(a, lastrm);
3054
+ return (compression_unsupported_encoder(a, lastrm, "lzma"));
3055
+ }
3056
+ static int
3057
+ compression_init_encoder_xz(struct archive *a,
3058
+ struct la_zstream *lastrm, int level, int threads)
3059
+ {
3060
+
3061
+ (void) level; /* UNUSED */
3062
+ (void) threads; /* UNUSED */
3063
+ if (lastrm->valid)
3064
+ compression_end(a, lastrm);
3065
+ return (compression_unsupported_encoder(a, lastrm, "xz"));
3066
+ }
3067
+ #endif
3068
+
3069
+ static int
3070
+ xar_compression_init_encoder(struct archive_write *a)
3071
+ {
3072
+ struct xar *xar;
3073
+ int r;
3074
+
3075
+ xar = (struct xar *)a->format_data;
3076
+ switch (xar->opt_compression) {
3077
+ case GZIP:
3078
+ r = compression_init_encoder_gzip(
3079
+ &(a->archive), &(xar->stream),
3080
+ xar->opt_compression_level, 1);
3081
+ break;
3082
+ case BZIP2:
3083
+ r = compression_init_encoder_bzip2(
3084
+ &(a->archive), &(xar->stream),
3085
+ xar->opt_compression_level);
3086
+ break;
3087
+ case LZMA:
3088
+ r = compression_init_encoder_lzma(
3089
+ &(a->archive), &(xar->stream),
3090
+ xar->opt_compression_level);
3091
+ break;
3092
+ case XZ:
3093
+ r = compression_init_encoder_xz(
3094
+ &(a->archive), &(xar->stream),
3095
+ xar->opt_compression_level, xar->opt_threads);
3096
+ break;
3097
+ default:
3098
+ r = ARCHIVE_OK;
3099
+ break;
3100
+ }
3101
+ if (r == ARCHIVE_OK) {
3102
+ xar->stream.total_in = 0;
3103
+ xar->stream.next_out = xar->wbuff;
3104
+ xar->stream.avail_out = sizeof(xar->wbuff);
3105
+ xar->stream.total_out = 0;
3106
+ }
3107
+
3108
+ return (r);
3109
+ }
3110
+
3111
+ static int
3112
+ compression_code(struct archive *a, struct la_zstream *lastrm,
3113
+ enum la_zaction action)
3114
+ {
3115
+ if (lastrm->valid)
3116
+ return (lastrm->code(a, lastrm, action));
3117
+ return (ARCHIVE_OK);
3118
+ }
3119
+
3120
+ static int
3121
+ compression_end(struct archive *a, struct la_zstream *lastrm)
3122
+ {
3123
+ if (lastrm->valid)
3124
+ return (lastrm->end(a, lastrm));
3125
+ return (ARCHIVE_OK);
3126
+ }
3127
+
3128
+
3129
+ static int
3130
+ save_xattrs(struct archive_write *a, struct file *file)
3131
+ {
3132
+ struct xar *xar;
3133
+ const char *name;
3134
+ const void *value;
3135
+ struct heap_data *heap;
3136
+ size_t size;
3137
+ int count, r;
3138
+
3139
+ xar = (struct xar *)a->format_data;
3140
+ count = archive_entry_xattr_reset(file->entry);
3141
+ if (count == 0)
3142
+ return (ARCHIVE_OK);
3143
+ while (count--) {
3144
+ archive_entry_xattr_next(file->entry,
3145
+ &name, &value, &size);
3146
+ checksum_init(&(xar->a_sumwrk), xar->opt_sumalg);
3147
+ checksum_init(&(xar->e_sumwrk), xar->opt_sumalg);
3148
+
3149
+ heap = calloc(1, sizeof(*heap));
3150
+ if (heap == NULL) {
3151
+ archive_set_error(&a->archive, ENOMEM,
3152
+ "Can't allocate memory for xattr");
3153
+ return (ARCHIVE_FATAL);
3154
+ }
3155
+ heap->id = file->ea_idx++;
3156
+ heap->temp_offset = xar->temp_offset;
3157
+ heap->size = size;/* save a extracted size */
3158
+ heap->compression = xar->opt_compression;
3159
+ /* Get a extracted sumcheck value. */
3160
+ checksum_update(&(xar->e_sumwrk), value, size);
3161
+ checksum_final(&(xar->e_sumwrk), &(heap->e_sum));
3162
+
3163
+ /*
3164
+ * Not compression to xattr is simple way.
3165
+ */
3166
+ if (heap->compression == NONE) {
3167
+ checksum_update(&(xar->a_sumwrk), value, size);
3168
+ checksum_final(&(xar->a_sumwrk), &(heap->a_sum));
3169
+ if (write_to_temp(a, value, size)
3170
+ != ARCHIVE_OK) {
3171
+ free(heap);
3172
+ return (ARCHIVE_FATAL);
3173
+ }
3174
+ heap->length = size;
3175
+ /* Add heap to the tail of file->xattr. */
3176
+ heap->next = NULL;
3177
+ *file->xattr.last = heap;
3178
+ file->xattr.last = &(heap->next);
3179
+ /* Next xattr */
3180
+ continue;
3181
+ }
3182
+
3183
+ /*
3184
+ * Init compression library.
3185
+ */
3186
+ r = xar_compression_init_encoder(a);
3187
+ if (r != ARCHIVE_OK) {
3188
+ free(heap);
3189
+ return (ARCHIVE_FATAL);
3190
+ }
3191
+
3192
+ xar->stream.next_in = (const unsigned char *)value;
3193
+ xar->stream.avail_in = size;
3194
+ for (;;) {
3195
+ r = compression_code(&(a->archive),
3196
+ &(xar->stream), ARCHIVE_Z_FINISH);
3197
+ if (r != ARCHIVE_OK && r != ARCHIVE_EOF) {
3198
+ free(heap);
3199
+ return (ARCHIVE_FATAL);
3200
+ }
3201
+ size = sizeof(xar->wbuff) - xar->stream.avail_out;
3202
+ checksum_update(&(xar->a_sumwrk),
3203
+ xar->wbuff, size);
3204
+ if (write_to_temp(a, xar->wbuff, size)
3205
+ != ARCHIVE_OK) {
3206
+ free(heap);
3207
+ return (ARCHIVE_FATAL);
3208
+ }
3209
+ if (r == ARCHIVE_OK) {
3210
+ xar->stream.next_out = xar->wbuff;
3211
+ xar->stream.avail_out = sizeof(xar->wbuff);
3212
+ } else {
3213
+ checksum_final(&(xar->a_sumwrk),
3214
+ &(heap->a_sum));
3215
+ heap->length = xar->stream.total_out;
3216
+ /* Add heap to the tail of file->xattr. */
3217
+ heap->next = NULL;
3218
+ *file->xattr.last = heap;
3219
+ file->xattr.last = &(heap->next);
3220
+ break;
3221
+ }
3222
+ }
3223
+ /* Clean up compression library. */
3224
+ r = compression_end(&(a->archive), &(xar->stream));
3225
+ if (r != ARCHIVE_OK)
3226
+ return (ARCHIVE_FATAL);
3227
+ }
3228
+ return (ARCHIVE_OK);
3229
+ }
3230
+
3231
+ static int
3232
+ getalgsize(enum sumalg sumalg)
3233
+ {
3234
+ switch (sumalg) {
3235
+ default:
3236
+ case CKSUM_NONE:
3237
+ return (0);
3238
+ case CKSUM_SHA1:
3239
+ return (SHA1_SIZE);
3240
+ case CKSUM_MD5:
3241
+ return (MD5_SIZE);
3242
+ }
3243
+ }
3244
+
3245
+ static const char *
3246
+ getalgname(enum sumalg sumalg)
3247
+ {
3248
+ switch (sumalg) {
3249
+ default:
3250
+ case CKSUM_NONE:
3251
+ return (NULL);
3252
+ case CKSUM_SHA1:
3253
+ return (SHA1_NAME);
3254
+ case CKSUM_MD5:
3255
+ return (MD5_NAME);
3256
+ }
3257
+ }
3258
+
3259
+ #endif /* Support xar format */