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,2097 @@
1
+ /*-
2
+ * Copyright (c) 2003-2010 Tim Kientzle
3
+ * Copyright (c) 2016 Martin Matuska
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ */
26
+
27
+ #include "archive_platform.h"
28
+ __FBSDID("$FreeBSD$");
29
+
30
+ #ifdef HAVE_ERRNO_H
31
+ #include <errno.h>
32
+ #endif
33
+ #ifdef HAVE_LIMITS_H
34
+ #include <limits.h>
35
+ #endif
36
+ #ifdef HAVE_WCHAR_H
37
+ #include <wchar.h>
38
+ #endif
39
+
40
+ #include "archive_acl_private.h"
41
+ #include "archive_entry.h"
42
+ #include "archive_private.h"
43
+
44
+ #undef max
45
+ #define max(a, b) ((a)>(b)?(a):(b))
46
+
47
+ #ifndef HAVE_WMEMCMP
48
+ /* Good enough for simple equality testing, but not for sorting. */
49
+ #define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t))
50
+ #endif
51
+
52
+ static int acl_special(struct archive_acl *acl,
53
+ int type, int permset, int tag);
54
+ static struct archive_acl_entry *acl_new_entry(struct archive_acl *acl,
55
+ int type, int permset, int tag, int id);
56
+ static int archive_acl_add_entry_len_l(struct archive_acl *acl,
57
+ int type, int permset, int tag, int id, const char *name,
58
+ size_t len, struct archive_string_conv *sc);
59
+ static int archive_acl_text_want_type(struct archive_acl *acl, int flags);
60
+ static ssize_t archive_acl_text_len(struct archive_acl *acl, int want_type,
61
+ int flags, int wide, struct archive *a,
62
+ struct archive_string_conv *sc);
63
+ static int isint_w(const wchar_t *start, const wchar_t *end, int *result);
64
+ static int ismode_w(const wchar_t *start, const wchar_t *end, int *result);
65
+ static int is_nfs4_flags_w(const wchar_t *start, const wchar_t *end,
66
+ int *result);
67
+ static int is_nfs4_perms_w(const wchar_t *start, const wchar_t *end,
68
+ int *result);
69
+ static void next_field_w(const wchar_t **wp, const wchar_t **start,
70
+ const wchar_t **end, wchar_t *sep);
71
+ static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
72
+ int tag, int flags, const wchar_t *wname, int perm, int id);
73
+ static void append_id_w(wchar_t **wp, int id);
74
+ static int isint(const char *start, const char *end, int *result);
75
+ static int ismode(const char *start, const char *end, int *result);
76
+ static int is_nfs4_flags(const char *start, const char *end,
77
+ int *result);
78
+ static int is_nfs4_perms(const char *start, const char *end,
79
+ int *result);
80
+ static void next_field(const char **p, const char **start,
81
+ const char **end, char *sep);
82
+ static void append_entry(char **p, const char *prefix, int type,
83
+ int tag, int flags, const char *name, int perm, int id);
84
+ static void append_id(char **p, int id);
85
+
86
+ static const struct {
87
+ const int perm;
88
+ const char c;
89
+ const wchar_t wc;
90
+ } nfsv4_acl_perm_map[] = {
91
+ { ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, 'r',
92
+ L'r' },
93
+ { ARCHIVE_ENTRY_ACL_WRITE_DATA | ARCHIVE_ENTRY_ACL_ADD_FILE, 'w',
94
+ L'w' },
95
+ { ARCHIVE_ENTRY_ACL_EXECUTE, 'x', L'x' },
96
+ { ARCHIVE_ENTRY_ACL_APPEND_DATA | ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY,
97
+ 'p', L'p' },
98
+ { ARCHIVE_ENTRY_ACL_DELETE, 'd', L'd' },
99
+ { ARCHIVE_ENTRY_ACL_DELETE_CHILD, 'D', L'D' },
100
+ { ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, 'a', L'a' },
101
+ { ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, 'A', L'A' },
102
+ { ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, 'R', L'R' },
103
+ { ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, 'W', L'W' },
104
+ { ARCHIVE_ENTRY_ACL_READ_ACL, 'c', L'c' },
105
+ { ARCHIVE_ENTRY_ACL_WRITE_ACL, 'C', L'C' },
106
+ { ARCHIVE_ENTRY_ACL_WRITE_OWNER, 'o', L'o' },
107
+ { ARCHIVE_ENTRY_ACL_SYNCHRONIZE, 's', L's' }
108
+ };
109
+
110
+ static const int nfsv4_acl_perm_map_size = (int)(sizeof(nfsv4_acl_perm_map) /
111
+ sizeof(nfsv4_acl_perm_map[0]));
112
+
113
+ static const struct {
114
+ const int perm;
115
+ const char c;
116
+ const wchar_t wc;
117
+ } nfsv4_acl_flag_map[] = {
118
+ { ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, 'f', L'f' },
119
+ { ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, 'd', L'd' },
120
+ { ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, 'i', L'i' },
121
+ { ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, 'n', L'n' },
122
+ { ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, 'S', L'S' },
123
+ { ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, 'F', L'F' },
124
+ { ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, 'I', L'I' }
125
+ };
126
+
127
+ static const int nfsv4_acl_flag_map_size = (int)(sizeof(nfsv4_acl_flag_map) /
128
+ sizeof(nfsv4_acl_flag_map[0]));
129
+
130
+ void
131
+ archive_acl_clear(struct archive_acl *acl)
132
+ {
133
+ struct archive_acl_entry *ap;
134
+
135
+ while (acl->acl_head != NULL) {
136
+ ap = acl->acl_head->next;
137
+ archive_mstring_clean(&acl->acl_head->name);
138
+ free(acl->acl_head);
139
+ acl->acl_head = ap;
140
+ }
141
+ free(acl->acl_text_w);
142
+ acl->acl_text_w = NULL;
143
+ free(acl->acl_text);
144
+ acl->acl_text = NULL;
145
+ acl->acl_p = NULL;
146
+ acl->acl_types = 0;
147
+ acl->acl_state = 0; /* Not counting. */
148
+ }
149
+
150
+ void
151
+ archive_acl_copy(struct archive_acl *dest, struct archive_acl *src)
152
+ {
153
+ struct archive_acl_entry *ap, *ap2;
154
+
155
+ archive_acl_clear(dest);
156
+
157
+ dest->mode = src->mode;
158
+ ap = src->acl_head;
159
+ while (ap != NULL) {
160
+ ap2 = acl_new_entry(dest,
161
+ ap->type, ap->permset, ap->tag, ap->id);
162
+ if (ap2 != NULL)
163
+ archive_mstring_copy(&ap2->name, &ap->name);
164
+ ap = ap->next;
165
+ }
166
+ }
167
+
168
+ int
169
+ archive_acl_add_entry(struct archive_acl *acl,
170
+ int type, int permset, int tag, int id, const char *name)
171
+ {
172
+ struct archive_acl_entry *ap;
173
+
174
+ if (acl_special(acl, type, permset, tag) == 0)
175
+ return ARCHIVE_OK;
176
+ ap = acl_new_entry(acl, type, permset, tag, id);
177
+ if (ap == NULL) {
178
+ /* XXX Error XXX */
179
+ return ARCHIVE_FAILED;
180
+ }
181
+ if (name != NULL && *name != '\0')
182
+ archive_mstring_copy_mbs(&ap->name, name);
183
+ else
184
+ archive_mstring_clean(&ap->name);
185
+ return ARCHIVE_OK;
186
+ }
187
+
188
+ int
189
+ archive_acl_add_entry_w_len(struct archive_acl *acl,
190
+ int type, int permset, int tag, int id, const wchar_t *name, size_t len)
191
+ {
192
+ struct archive_acl_entry *ap;
193
+
194
+ if (acl_special(acl, type, permset, tag) == 0)
195
+ return ARCHIVE_OK;
196
+ ap = acl_new_entry(acl, type, permset, tag, id);
197
+ if (ap == NULL) {
198
+ /* XXX Error XXX */
199
+ return ARCHIVE_FAILED;
200
+ }
201
+ if (name != NULL && *name != L'\0' && len > 0)
202
+ archive_mstring_copy_wcs_len(&ap->name, name, len);
203
+ else
204
+ archive_mstring_clean(&ap->name);
205
+ return ARCHIVE_OK;
206
+ }
207
+
208
+ static int
209
+ archive_acl_add_entry_len_l(struct archive_acl *acl,
210
+ int type, int permset, int tag, int id, const char *name, size_t len,
211
+ struct archive_string_conv *sc)
212
+ {
213
+ struct archive_acl_entry *ap;
214
+ int r;
215
+
216
+ if (acl_special(acl, type, permset, tag) == 0)
217
+ return ARCHIVE_OK;
218
+ ap = acl_new_entry(acl, type, permset, tag, id);
219
+ if (ap == NULL) {
220
+ /* XXX Error XXX */
221
+ return ARCHIVE_FAILED;
222
+ }
223
+ if (name != NULL && *name != '\0' && len > 0) {
224
+ r = archive_mstring_copy_mbs_len_l(&ap->name, name, len, sc);
225
+ } else {
226
+ r = 0;
227
+ archive_mstring_clean(&ap->name);
228
+ }
229
+ if (r == 0)
230
+ return (ARCHIVE_OK);
231
+ else if (errno == ENOMEM)
232
+ return (ARCHIVE_FATAL);
233
+ else
234
+ return (ARCHIVE_WARN);
235
+ }
236
+
237
+ /*
238
+ * If this ACL entry is part of the standard POSIX permissions set,
239
+ * store the permissions in the stat structure and return zero.
240
+ */
241
+ static int
242
+ acl_special(struct archive_acl *acl, int type, int permset, int tag)
243
+ {
244
+ if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS
245
+ && ((permset & ~007) == 0)) {
246
+ switch (tag) {
247
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
248
+ acl->mode &= ~0700;
249
+ acl->mode |= (permset & 7) << 6;
250
+ return (0);
251
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
252
+ acl->mode &= ~0070;
253
+ acl->mode |= (permset & 7) << 3;
254
+ return (0);
255
+ case ARCHIVE_ENTRY_ACL_OTHER:
256
+ acl->mode &= ~0007;
257
+ acl->mode |= permset & 7;
258
+ return (0);
259
+ }
260
+ }
261
+ return (1);
262
+ }
263
+
264
+ /*
265
+ * Allocate and populate a new ACL entry with everything but the
266
+ * name.
267
+ */
268
+ static struct archive_acl_entry *
269
+ acl_new_entry(struct archive_acl *acl,
270
+ int type, int permset, int tag, int id)
271
+ {
272
+ struct archive_acl_entry *ap, *aq;
273
+
274
+ /* Type argument must be a valid NFS4 or POSIX.1e type.
275
+ * The type must agree with anything already set and
276
+ * the permset must be compatible. */
277
+ if (type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
278
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
279
+ return (NULL);
280
+ }
281
+ if (permset &
282
+ ~(ARCHIVE_ENTRY_ACL_PERMS_NFS4
283
+ | ARCHIVE_ENTRY_ACL_INHERITANCE_NFS4)) {
284
+ return (NULL);
285
+ }
286
+ } else if (type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
287
+ if (acl->acl_types & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
288
+ return (NULL);
289
+ }
290
+ if (permset & ~ARCHIVE_ENTRY_ACL_PERMS_POSIX1E) {
291
+ return (NULL);
292
+ }
293
+ } else {
294
+ return (NULL);
295
+ }
296
+
297
+ /* Verify the tag is valid and compatible with NFS4 or POSIX.1e. */
298
+ switch (tag) {
299
+ case ARCHIVE_ENTRY_ACL_USER:
300
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
301
+ case ARCHIVE_ENTRY_ACL_GROUP:
302
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
303
+ /* Tags valid in both NFS4 and POSIX.1e */
304
+ break;
305
+ case ARCHIVE_ENTRY_ACL_MASK:
306
+ case ARCHIVE_ENTRY_ACL_OTHER:
307
+ /* Tags valid only in POSIX.1e. */
308
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) {
309
+ return (NULL);
310
+ }
311
+ break;
312
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
313
+ /* Tags valid only in NFS4. */
314
+ if (type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
315
+ return (NULL);
316
+ }
317
+ break;
318
+ default:
319
+ /* No other values are valid. */
320
+ return (NULL);
321
+ }
322
+
323
+ free(acl->acl_text_w);
324
+ acl->acl_text_w = NULL;
325
+ free(acl->acl_text);
326
+ acl->acl_text = NULL;
327
+
328
+ /*
329
+ * If there's a matching entry already in the list, overwrite it.
330
+ * NFSv4 entries may be repeated and are not overwritten.
331
+ *
332
+ * TODO: compare names of no id is provided (needs more rework)
333
+ */
334
+ ap = acl->acl_head;
335
+ aq = NULL;
336
+ while (ap != NULL) {
337
+ if (((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0) &&
338
+ ap->type == type && ap->tag == tag && ap->id == id) {
339
+ if (id != -1 || (tag != ARCHIVE_ENTRY_ACL_USER &&
340
+ tag != ARCHIVE_ENTRY_ACL_GROUP)) {
341
+ ap->permset = permset;
342
+ return (ap);
343
+ }
344
+ }
345
+ aq = ap;
346
+ ap = ap->next;
347
+ }
348
+
349
+ /* Add a new entry to the end of the list. */
350
+ ap = (struct archive_acl_entry *)calloc(1, sizeof(*ap));
351
+ if (ap == NULL)
352
+ return (NULL);
353
+ if (aq == NULL)
354
+ acl->acl_head = ap;
355
+ else
356
+ aq->next = ap;
357
+ ap->type = type;
358
+ ap->tag = tag;
359
+ ap->id = id;
360
+ ap->permset = permset;
361
+ acl->acl_types |= type;
362
+ return (ap);
363
+ }
364
+
365
+ /*
366
+ * Return a count of entries matching "want_type".
367
+ */
368
+ int
369
+ archive_acl_count(struct archive_acl *acl, int want_type)
370
+ {
371
+ int count;
372
+ struct archive_acl_entry *ap;
373
+
374
+ count = 0;
375
+ ap = acl->acl_head;
376
+ while (ap != NULL) {
377
+ if ((ap->type & want_type) != 0)
378
+ count++;
379
+ ap = ap->next;
380
+ }
381
+
382
+ if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0))
383
+ count += 3;
384
+ return (count);
385
+ }
386
+
387
+ /*
388
+ * Return a bitmask of stored ACL types in an ACL list
389
+ */
390
+ int
391
+ archive_acl_types(struct archive_acl *acl)
392
+ {
393
+ return (acl->acl_types);
394
+ }
395
+
396
+ /*
397
+ * Prepare for reading entries from the ACL data. Returns a count
398
+ * of entries matching "want_type", or zero if there are no
399
+ * non-extended ACL entries of that type.
400
+ */
401
+ int
402
+ archive_acl_reset(struct archive_acl *acl, int want_type)
403
+ {
404
+ int count, cutoff;
405
+
406
+ count = archive_acl_count(acl, want_type);
407
+
408
+ /*
409
+ * If the only entries are the three standard ones,
410
+ * then don't return any ACL data. (In this case,
411
+ * client can just use chmod(2) to set permissions.)
412
+ */
413
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
414
+ cutoff = 3;
415
+ else
416
+ cutoff = 0;
417
+
418
+ if (count > cutoff)
419
+ acl->acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ;
420
+ else
421
+ acl->acl_state = 0;
422
+ acl->acl_p = acl->acl_head;
423
+ return (count);
424
+ }
425
+
426
+
427
+ /*
428
+ * Return the next ACL entry in the list. Fake entries for the
429
+ * standard permissions and include them in the returned list.
430
+ */
431
+ int
432
+ archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type,
433
+ int *type, int *permset, int *tag, int *id, const char **name)
434
+ {
435
+ *name = NULL;
436
+ *id = -1;
437
+
438
+ /*
439
+ * The acl_state is either zero (no entries available), -1
440
+ * (reading from list), or an entry type (retrieve that type
441
+ * from ae_stat.aest_mode).
442
+ */
443
+ if (acl->acl_state == 0)
444
+ return (ARCHIVE_WARN);
445
+
446
+ /* The first three access entries are special. */
447
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
448
+ switch (acl->acl_state) {
449
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
450
+ *permset = (acl->mode >> 6) & 7;
451
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
452
+ *tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
453
+ acl->acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
454
+ return (ARCHIVE_OK);
455
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
456
+ *permset = (acl->mode >> 3) & 7;
457
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
458
+ *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
459
+ acl->acl_state = ARCHIVE_ENTRY_ACL_OTHER;
460
+ return (ARCHIVE_OK);
461
+ case ARCHIVE_ENTRY_ACL_OTHER:
462
+ *permset = acl->mode & 7;
463
+ *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
464
+ *tag = ARCHIVE_ENTRY_ACL_OTHER;
465
+ acl->acl_state = -1;
466
+ acl->acl_p = acl->acl_head;
467
+ return (ARCHIVE_OK);
468
+ default:
469
+ break;
470
+ }
471
+ }
472
+
473
+ while (acl->acl_p != NULL && (acl->acl_p->type & want_type) == 0)
474
+ acl->acl_p = acl->acl_p->next;
475
+ if (acl->acl_p == NULL) {
476
+ acl->acl_state = 0;
477
+ *type = 0;
478
+ *permset = 0;
479
+ *tag = 0;
480
+ *id = -1;
481
+ *name = NULL;
482
+ return (ARCHIVE_EOF); /* End of ACL entries. */
483
+ }
484
+ *type = acl->acl_p->type;
485
+ *permset = acl->acl_p->permset;
486
+ *tag = acl->acl_p->tag;
487
+ *id = acl->acl_p->id;
488
+ if (archive_mstring_get_mbs(a, &acl->acl_p->name, name) != 0) {
489
+ if (errno == ENOMEM)
490
+ return (ARCHIVE_FATAL);
491
+ *name = NULL;
492
+ }
493
+ acl->acl_p = acl->acl_p->next;
494
+ return (ARCHIVE_OK);
495
+ }
496
+
497
+ /*
498
+ * Determine what type of ACL do we want
499
+ */
500
+ static int
501
+ archive_acl_text_want_type(struct archive_acl *acl, int flags)
502
+ {
503
+ int want_type;
504
+
505
+ /* Check if ACL is NFSv4 */
506
+ if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
507
+ /* NFSv4 should never mix with POSIX.1e */
508
+ if ((acl->acl_types & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
509
+ return (0);
510
+ else
511
+ return (ARCHIVE_ENTRY_ACL_TYPE_NFS4);
512
+ }
513
+
514
+ /* Now deal with POSIX.1e ACLs */
515
+
516
+ want_type = 0;
517
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)
518
+ want_type |= ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
519
+ if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
520
+ want_type |= ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
521
+
522
+ /* By default we want both access and default ACLs */
523
+ if (want_type == 0)
524
+ return (ARCHIVE_ENTRY_ACL_TYPE_POSIX1E);
525
+
526
+ return (want_type);
527
+ }
528
+
529
+ /*
530
+ * Calculate ACL text string length
531
+ */
532
+ static ssize_t
533
+ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
534
+ int wide, struct archive *a, struct archive_string_conv *sc) {
535
+ struct archive_acl_entry *ap;
536
+ const char *name;
537
+ const wchar_t *wname;
538
+ int count, idlen, tmp, r;
539
+ ssize_t length;
540
+ size_t len;
541
+
542
+ count = 0;
543
+ length = 0;
544
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
545
+ if ((ap->type & want_type) == 0)
546
+ continue;
547
+ /*
548
+ * Filemode-mapping ACL entries are stored exclusively in
549
+ * ap->mode so they should not be in the list
550
+ */
551
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
552
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
553
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
554
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
555
+ continue;
556
+ count++;
557
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0
558
+ && (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
559
+ length += 8; /* "default:" */
560
+ switch (ap->tag) {
561
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
562
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
563
+ length += 6; /* "owner@" */
564
+ break;
565
+ }
566
+ /* FALLTHROUGH */
567
+ case ARCHIVE_ENTRY_ACL_USER:
568
+ case ARCHIVE_ENTRY_ACL_MASK:
569
+ length += 4; /* "user", "mask" */
570
+ break;
571
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
572
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
573
+ length += 6; /* "group@" */
574
+ break;
575
+ }
576
+ /* FALLTHROUGH */
577
+ case ARCHIVE_ENTRY_ACL_GROUP:
578
+ case ARCHIVE_ENTRY_ACL_OTHER:
579
+ length += 5; /* "group", "other" */
580
+ break;
581
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
582
+ length += 9; /* "everyone@" */
583
+ break;
584
+ }
585
+ length += 1; /* colon after tag */
586
+ if (ap->tag == ARCHIVE_ENTRY_ACL_USER ||
587
+ ap->tag == ARCHIVE_ENTRY_ACL_GROUP) {
588
+ if (wide) {
589
+ r = archive_mstring_get_wcs(a, &ap->name,
590
+ &wname);
591
+ if (r == 0 && wname != NULL)
592
+ length += wcslen(wname);
593
+ else if (r < 0 && errno == ENOMEM)
594
+ return (0);
595
+ else
596
+ length += sizeof(uid_t) * 3 + 1;
597
+ } else {
598
+ r = archive_mstring_get_mbs_l(a, &ap->name, &name,
599
+ &len, sc);
600
+ if (r != 0)
601
+ return (0);
602
+ if (len > 0 && name != NULL)
603
+ length += len;
604
+ else
605
+ length += sizeof(uid_t) * 3 + 1;
606
+ }
607
+ length += 1; /* colon after user or group name */
608
+ } else if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4)
609
+ length += 1; /* 2nd colon empty user,group or other */
610
+
611
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0)
612
+ && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
613
+ && (ap->tag == ARCHIVE_ENTRY_ACL_OTHER
614
+ || ap->tag == ARCHIVE_ENTRY_ACL_MASK)) {
615
+ /* Solaris has no colon after other: and mask: */
616
+ length = length - 1;
617
+ }
618
+
619
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
620
+ /* rwxpdDaARWcCos:fdinSFI:deny */
621
+ length += 27;
622
+ if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) == 0)
623
+ length += 1; /* allow, alarm, audit */
624
+ } else
625
+ length += 3; /* rwx */
626
+
627
+ if ((ap->tag == ARCHIVE_ENTRY_ACL_USER ||
628
+ ap->tag == ARCHIVE_ENTRY_ACL_GROUP) &&
629
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) {
630
+ length += 1; /* colon */
631
+ /* ID digit count */
632
+ idlen = 1;
633
+ tmp = ap->id;
634
+ while (tmp > 9) {
635
+ tmp = tmp / 10;
636
+ idlen++;
637
+ }
638
+ length += idlen;
639
+ }
640
+ length ++; /* entry separator */
641
+ }
642
+
643
+ /* Add filemode-mapping access entries to the length */
644
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
645
+ if ((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) {
646
+ /* "user::rwx\ngroup::rwx\nother:rwx\n" */
647
+ length += 31;
648
+ } else {
649
+ /* "user::rwx\ngroup::rwx\nother::rwx\n" */
650
+ length += 32;
651
+ }
652
+ } else if (count == 0)
653
+ return (0);
654
+
655
+ /* The terminating character is included in count */
656
+ return (length);
657
+ }
658
+
659
+ /*
660
+ * Generate a wide text version of the ACL. The flags parameter controls
661
+ * the type and style of the generated ACL.
662
+ */
663
+ wchar_t *
664
+ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
665
+ struct archive *a)
666
+ {
667
+ int count;
668
+ ssize_t length;
669
+ size_t len;
670
+ const wchar_t *wname;
671
+ const wchar_t *prefix;
672
+ wchar_t separator;
673
+ struct archive_acl_entry *ap;
674
+ int id, r, want_type;
675
+ wchar_t *wp, *ws;
676
+
677
+ want_type = archive_acl_text_want_type(acl, flags);
678
+
679
+ /* Both NFSv4 and POSIX.1 types found */
680
+ if (want_type == 0)
681
+ return (NULL);
682
+
683
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
684
+ flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
685
+
686
+ length = archive_acl_text_len(acl, want_type, flags, 1, a, NULL);
687
+
688
+ if (length == 0)
689
+ return (NULL);
690
+
691
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
692
+ separator = L',';
693
+ else
694
+ separator = L'\n';
695
+
696
+ /* Now, allocate the string and actually populate it. */
697
+ wp = ws = (wchar_t *)malloc(length * sizeof(wchar_t));
698
+ if (wp == NULL) {
699
+ if (errno == ENOMEM)
700
+ __archive_errx(1, "No memory");
701
+ return (NULL);
702
+ }
703
+ count = 0;
704
+
705
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
706
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
707
+ ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
708
+ acl->mode & 0700, -1);
709
+ *wp++ = separator;
710
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
711
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
712
+ acl->mode & 0070, -1);
713
+ *wp++ = separator;
714
+ append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
715
+ ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
716
+ acl->mode & 0007, -1);
717
+ count += 3;
718
+ }
719
+
720
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
721
+ if ((ap->type & want_type) == 0)
722
+ continue;
723
+ /*
724
+ * Filemode-mapping ACL entries are stored exclusively in
725
+ * ap->mode so they should not be in the list
726
+ */
727
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
728
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
729
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
730
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
731
+ continue;
732
+ if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
733
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
734
+ prefix = L"default:";
735
+ else
736
+ prefix = NULL;
737
+ r = archive_mstring_get_wcs(a, &ap->name, &wname);
738
+ if (r == 0) {
739
+ if (count > 0)
740
+ *wp++ = separator;
741
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
742
+ id = ap->id;
743
+ else
744
+ id = -1;
745
+ append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
746
+ wname, ap->permset, id);
747
+ count++;
748
+ } else if (r < 0 && errno == ENOMEM) {
749
+ free(ws);
750
+ return (NULL);
751
+ }
752
+ }
753
+
754
+ /* Add terminating character */
755
+ *wp++ = L'\0';
756
+
757
+ len = wcslen(ws);
758
+
759
+ if ((ssize_t)len > (length - 1))
760
+ __archive_errx(1, "Buffer overrun");
761
+
762
+ if (text_len != NULL)
763
+ *text_len = len;
764
+
765
+ return (ws);
766
+ }
767
+
768
+ static void
769
+ append_id_w(wchar_t **wp, int id)
770
+ {
771
+ if (id < 0)
772
+ id = 0;
773
+ if (id > 9)
774
+ append_id_w(wp, id / 10);
775
+ *(*wp)++ = L"0123456789"[id % 10];
776
+ }
777
+
778
+ static void
779
+ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
780
+ int tag, int flags, const wchar_t *wname, int perm, int id)
781
+ {
782
+ int i;
783
+
784
+ if (prefix != NULL) {
785
+ wcscpy(*wp, prefix);
786
+ *wp += wcslen(*wp);
787
+ }
788
+ switch (tag) {
789
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
790
+ wname = NULL;
791
+ id = -1;
792
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
793
+ wcscpy(*wp, L"owner@");
794
+ break;
795
+ }
796
+ /* FALLTHROUGH */
797
+ case ARCHIVE_ENTRY_ACL_USER:
798
+ wcscpy(*wp, L"user");
799
+ break;
800
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
801
+ wname = NULL;
802
+ id = -1;
803
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
804
+ wcscpy(*wp, L"group@");
805
+ break;
806
+ }
807
+ /* FALLTHROUGH */
808
+ case ARCHIVE_ENTRY_ACL_GROUP:
809
+ wcscpy(*wp, L"group");
810
+ break;
811
+ case ARCHIVE_ENTRY_ACL_MASK:
812
+ wcscpy(*wp, L"mask");
813
+ wname = NULL;
814
+ id = -1;
815
+ break;
816
+ case ARCHIVE_ENTRY_ACL_OTHER:
817
+ wcscpy(*wp, L"other");
818
+ wname = NULL;
819
+ id = -1;
820
+ break;
821
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
822
+ wcscpy(*wp, L"everyone@");
823
+ wname = NULL;
824
+ id = -1;
825
+ break;
826
+ }
827
+ *wp += wcslen(*wp);
828
+ *(*wp)++ = L':';
829
+ if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
830
+ tag == ARCHIVE_ENTRY_ACL_USER ||
831
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
832
+ if (wname != NULL) {
833
+ wcscpy(*wp, wname);
834
+ *wp += wcslen(*wp);
835
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
836
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
837
+ append_id_w(wp, id);
838
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
839
+ id = -1;
840
+ }
841
+ /* Solaris style has no second colon after other and mask */
842
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
843
+ || (tag != ARCHIVE_ENTRY_ACL_OTHER
844
+ && tag != ARCHIVE_ENTRY_ACL_MASK))
845
+ *(*wp)++ = L':';
846
+ }
847
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
848
+ /* POSIX.1e ACL perms */
849
+ *(*wp)++ = (perm & 0444) ? L'r' : L'-';
850
+ *(*wp)++ = (perm & 0222) ? L'w' : L'-';
851
+ *(*wp)++ = (perm & 0111) ? L'x' : L'-';
852
+ } else {
853
+ /* NFSv4 ACL perms */
854
+ for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
855
+ if (perm & nfsv4_acl_perm_map[i].perm)
856
+ *(*wp)++ = nfsv4_acl_perm_map[i].wc;
857
+ else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
858
+ *(*wp)++ = L'-';
859
+ }
860
+ *(*wp)++ = L':';
861
+ for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
862
+ if (perm & nfsv4_acl_flag_map[i].perm)
863
+ *(*wp)++ = nfsv4_acl_flag_map[i].wc;
864
+ else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
865
+ *(*wp)++ = L'-';
866
+ }
867
+ *(*wp)++ = L':';
868
+ switch (type) {
869
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
870
+ wcscpy(*wp, L"allow");
871
+ break;
872
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
873
+ wcscpy(*wp, L"deny");
874
+ break;
875
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
876
+ wcscpy(*wp, L"audit");
877
+ break;
878
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
879
+ wcscpy(*wp, L"alarm");
880
+ break;
881
+ default:
882
+ break;
883
+ }
884
+ *wp += wcslen(*wp);
885
+ }
886
+ if (id != -1) {
887
+ *(*wp)++ = L':';
888
+ append_id_w(wp, id);
889
+ }
890
+ }
891
+
892
+ /*
893
+ * Generate a text version of the ACL. The flags parameter controls
894
+ * the type and style of the generated ACL.
895
+ */
896
+ char *
897
+ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
898
+ struct archive_string_conv *sc)
899
+ {
900
+ int count;
901
+ ssize_t length;
902
+ size_t len;
903
+ const char *name;
904
+ const char *prefix;
905
+ char separator;
906
+ struct archive_acl_entry *ap;
907
+ int id, r, want_type;
908
+ char *p, *s;
909
+
910
+ want_type = archive_acl_text_want_type(acl, flags);
911
+
912
+ /* Both NFSv4 and POSIX.1 types found */
913
+ if (want_type == 0)
914
+ return (NULL);
915
+
916
+ if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
917
+ flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
918
+
919
+ length = archive_acl_text_len(acl, want_type, flags, 0, NULL, sc);
920
+
921
+ if (length == 0)
922
+ return (NULL);
923
+
924
+ if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
925
+ separator = ',';
926
+ else
927
+ separator = '\n';
928
+
929
+ /* Now, allocate the string and actually populate it. */
930
+ p = s = (char *)malloc(length * sizeof(char));
931
+ if (p == NULL) {
932
+ if (errno == ENOMEM)
933
+ __archive_errx(1, "No memory");
934
+ return (NULL);
935
+ }
936
+ count = 0;
937
+
938
+ if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
939
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
940
+ ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
941
+ acl->mode & 0700, -1);
942
+ *p++ = separator;
943
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
944
+ ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
945
+ acl->mode & 0070, -1);
946
+ *p++ = separator;
947
+ append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
948
+ ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
949
+ acl->mode & 0007, -1);
950
+ count += 3;
951
+ }
952
+
953
+ for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
954
+ if ((ap->type & want_type) == 0)
955
+ continue;
956
+ /*
957
+ * Filemode-mapping ACL entries are stored exclusively in
958
+ * ap->mode so they should not be in the list
959
+ */
960
+ if ((ap->type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS)
961
+ && (ap->tag == ARCHIVE_ENTRY_ACL_USER_OBJ
962
+ || ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
963
+ || ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
964
+ continue;
965
+ if (ap->type == ARCHIVE_ENTRY_ACL_TYPE_DEFAULT &&
966
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0)
967
+ prefix = "default:";
968
+ else
969
+ prefix = NULL;
970
+ r = archive_mstring_get_mbs_l(
971
+ NULL, &ap->name, &name, &len, sc);
972
+ if (r != 0) {
973
+ free(s);
974
+ return (NULL);
975
+ }
976
+ if (count > 0)
977
+ *p++ = separator;
978
+ if (name == NULL ||
979
+ (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) {
980
+ id = ap->id;
981
+ } else {
982
+ id = -1;
983
+ }
984
+ append_entry(&p, prefix, ap->type, ap->tag, flags, name,
985
+ ap->permset, id);
986
+ count++;
987
+ }
988
+
989
+ /* Add terminating character */
990
+ *p++ = '\0';
991
+
992
+ len = strlen(s);
993
+
994
+ if ((ssize_t)len > (length - 1))
995
+ __archive_errx(1, "Buffer overrun");
996
+
997
+ if (text_len != NULL)
998
+ *text_len = len;
999
+
1000
+ return (s);
1001
+ }
1002
+
1003
+ static void
1004
+ append_id(char **p, int id)
1005
+ {
1006
+ if (id < 0)
1007
+ id = 0;
1008
+ if (id > 9)
1009
+ append_id(p, id / 10);
1010
+ *(*p)++ = "0123456789"[id % 10];
1011
+ }
1012
+
1013
+ static void
1014
+ append_entry(char **p, const char *prefix, int type,
1015
+ int tag, int flags, const char *name, int perm, int id)
1016
+ {
1017
+ int i;
1018
+
1019
+ if (prefix != NULL) {
1020
+ strcpy(*p, prefix);
1021
+ *p += strlen(*p);
1022
+ }
1023
+ switch (tag) {
1024
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
1025
+ name = NULL;
1026
+ id = -1;
1027
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
1028
+ strcpy(*p, "owner@");
1029
+ break;
1030
+ }
1031
+ /* FALLTHROUGH */
1032
+ case ARCHIVE_ENTRY_ACL_USER:
1033
+ strcpy(*p, "user");
1034
+ break;
1035
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
1036
+ name = NULL;
1037
+ id = -1;
1038
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
1039
+ strcpy(*p, "group@");
1040
+ break;
1041
+ }
1042
+ /* FALLTHROUGH */
1043
+ case ARCHIVE_ENTRY_ACL_GROUP:
1044
+ strcpy(*p, "group");
1045
+ break;
1046
+ case ARCHIVE_ENTRY_ACL_MASK:
1047
+ strcpy(*p, "mask");
1048
+ name = NULL;
1049
+ id = -1;
1050
+ break;
1051
+ case ARCHIVE_ENTRY_ACL_OTHER:
1052
+ strcpy(*p, "other");
1053
+ name = NULL;
1054
+ id = -1;
1055
+ break;
1056
+ case ARCHIVE_ENTRY_ACL_EVERYONE:
1057
+ strcpy(*p, "everyone@");
1058
+ name = NULL;
1059
+ id = -1;
1060
+ break;
1061
+ }
1062
+ *p += strlen(*p);
1063
+ *(*p)++ = ':';
1064
+ if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
1065
+ tag == ARCHIVE_ENTRY_ACL_USER ||
1066
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
1067
+ if (name != NULL) {
1068
+ strcpy(*p, name);
1069
+ *p += strlen(*p);
1070
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER
1071
+ || tag == ARCHIVE_ENTRY_ACL_GROUP) {
1072
+ append_id(p, id);
1073
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
1074
+ id = -1;
1075
+ }
1076
+ /* Solaris style has no second colon after other and mask */
1077
+ if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
1078
+ || (tag != ARCHIVE_ENTRY_ACL_OTHER
1079
+ && tag != ARCHIVE_ENTRY_ACL_MASK))
1080
+ *(*p)++ = ':';
1081
+ }
1082
+ if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
1083
+ /* POSIX.1e ACL perms */
1084
+ *(*p)++ = (perm & 0444) ? 'r' : '-';
1085
+ *(*p)++ = (perm & 0222) ? 'w' : '-';
1086
+ *(*p)++ = (perm & 0111) ? 'x' : '-';
1087
+ } else {
1088
+ /* NFSv4 ACL perms */
1089
+ for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
1090
+ if (perm & nfsv4_acl_perm_map[i].perm)
1091
+ *(*p)++ = nfsv4_acl_perm_map[i].c;
1092
+ else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
1093
+ *(*p)++ = '-';
1094
+ }
1095
+ *(*p)++ = ':';
1096
+ for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
1097
+ if (perm & nfsv4_acl_flag_map[i].perm)
1098
+ *(*p)++ = nfsv4_acl_flag_map[i].c;
1099
+ else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
1100
+ *(*p)++ = '-';
1101
+ }
1102
+ *(*p)++ = ':';
1103
+ switch (type) {
1104
+ case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
1105
+ strcpy(*p, "allow");
1106
+ break;
1107
+ case ARCHIVE_ENTRY_ACL_TYPE_DENY:
1108
+ strcpy(*p, "deny");
1109
+ break;
1110
+ case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
1111
+ strcpy(*p, "audit");
1112
+ break;
1113
+ case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
1114
+ strcpy(*p, "alarm");
1115
+ break;
1116
+ }
1117
+ *p += strlen(*p);
1118
+ }
1119
+ if (id != -1) {
1120
+ *(*p)++ = ':';
1121
+ append_id(p, id);
1122
+ }
1123
+ }
1124
+
1125
+ /*
1126
+ * Parse a wide ACL text string.
1127
+ *
1128
+ * The want_type argument may be one of the following:
1129
+ * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS
1130
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT
1131
+ * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL
1132
+ *
1133
+ * POSIX.1e ACL entries prefixed with "default:" are treated as
1134
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4
1135
+ */
1136
+ int
1137
+ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
1138
+ int want_type)
1139
+ {
1140
+ struct {
1141
+ const wchar_t *start;
1142
+ const wchar_t *end;
1143
+ } field[6], name;
1144
+
1145
+ const wchar_t *s, *st;
1146
+
1147
+ int numfields, fields, n, r, sol, ret;
1148
+ int type, types, tag, permset, id;
1149
+ size_t len;
1150
+ wchar_t sep;
1151
+
1152
+ ret = ARCHIVE_OK;
1153
+ types = 0;
1154
+
1155
+ switch (want_type) {
1156
+ case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
1157
+ want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
1158
+ __LA_FALLTHROUGH;
1159
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
1160
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
1161
+ numfields = 5;
1162
+ break;
1163
+ case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
1164
+ numfields = 6;
1165
+ break;
1166
+ default:
1167
+ return (ARCHIVE_FATAL);
1168
+ }
1169
+
1170
+ while (text != NULL && *text != L'\0') {
1171
+ /*
1172
+ * Parse the fields out of the next entry,
1173
+ * advance 'text' to start of next entry.
1174
+ */
1175
+ fields = 0;
1176
+ do {
1177
+ const wchar_t *start, *end;
1178
+ next_field_w(&text, &start, &end, &sep);
1179
+ if (fields < numfields) {
1180
+ field[fields].start = start;
1181
+ field[fields].end = end;
1182
+ }
1183
+ ++fields;
1184
+ } while (sep == L':');
1185
+
1186
+ /* Set remaining fields to blank. */
1187
+ for (n = fields; n < numfields; ++n)
1188
+ field[n].start = field[n].end = NULL;
1189
+
1190
+ if (field[0].start != NULL && *(field[0].start) == L'#') {
1191
+ /* Comment, skip entry */
1192
+ continue;
1193
+ }
1194
+
1195
+ n = 0;
1196
+ sol = 0;
1197
+ id = -1;
1198
+ permset = 0;
1199
+ name.start = name.end = NULL;
1200
+
1201
+ if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
1202
+ /* POSIX.1e ACLs */
1203
+ /*
1204
+ * Default keyword "default:user::rwx"
1205
+ * if found, we have one more field
1206
+ *
1207
+ * We also support old Solaris extension:
1208
+ * "defaultuser::rwx" is the default ACL corresponding
1209
+ * to "user::rwx", etc. valid only for first field
1210
+ */
1211
+ s = field[0].start;
1212
+ len = field[0].end - field[0].start;
1213
+ if (*s == L'd' && (len == 1 || (len >= 7
1214
+ && wmemcmp((s + 1), L"efault", 6) == 0))) {
1215
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
1216
+ if (len > 7)
1217
+ field[0].start += 7;
1218
+ else
1219
+ n = 1;
1220
+ } else
1221
+ type = want_type;
1222
+
1223
+ /* Check for a numeric ID in field n+1 or n+3. */
1224
+ isint_w(field[n + 1].start, field[n + 1].end, &id);
1225
+ /* Field n+3 is optional. */
1226
+ if (id == -1 && fields > n+3)
1227
+ isint_w(field[n + 3].start, field[n + 3].end,
1228
+ &id);
1229
+
1230
+ tag = 0;
1231
+ s = field[n].start;
1232
+ st = field[n].start + 1;
1233
+ len = field[n].end - field[n].start;
1234
+
1235
+ switch (*s) {
1236
+ case L'u':
1237
+ if (len == 1 || (len == 4
1238
+ && wmemcmp(st, L"ser", 3) == 0))
1239
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
1240
+ break;
1241
+ case L'g':
1242
+ if (len == 1 || (len == 5
1243
+ && wmemcmp(st, L"roup", 4) == 0))
1244
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
1245
+ break;
1246
+ case L'o':
1247
+ if (len == 1 || (len == 5
1248
+ && wmemcmp(st, L"ther", 4) == 0))
1249
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
1250
+ break;
1251
+ case L'm':
1252
+ if (len == 1 || (len == 4
1253
+ && wmemcmp(st, L"ask", 3) == 0))
1254
+ tag = ARCHIVE_ENTRY_ACL_MASK;
1255
+ break;
1256
+ default:
1257
+ break;
1258
+ }
1259
+
1260
+ switch (tag) {
1261
+ case ARCHIVE_ENTRY_ACL_OTHER:
1262
+ case ARCHIVE_ENTRY_ACL_MASK:
1263
+ if (fields == (n + 2)
1264
+ && field[n + 1].start < field[n + 1].end
1265
+ && ismode_w(field[n + 1].start,
1266
+ field[n + 1].end, &permset)) {
1267
+ /* This is Solaris-style "other:rwx" */
1268
+ sol = 1;
1269
+ } else if (fields == (n + 3) &&
1270
+ field[n + 1].start < field[n + 1].end) {
1271
+ /* Invalid mask or other field */
1272
+ ret = ARCHIVE_WARN;
1273
+ continue;
1274
+ }
1275
+ break;
1276
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
1277
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
1278
+ if (id != -1 ||
1279
+ field[n + 1].start < field[n + 1].end) {
1280
+ name = field[n + 1];
1281
+ if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
1282
+ tag = ARCHIVE_ENTRY_ACL_USER;
1283
+ else
1284
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
1285
+ }
1286
+ break;
1287
+ default:
1288
+ /* Invalid tag, skip entry */
1289
+ ret = ARCHIVE_WARN;
1290
+ continue;
1291
+ }
1292
+
1293
+ /*
1294
+ * Without "default:" we expect mode in field 2
1295
+ * Exception: Solaris other and mask fields
1296
+ */
1297
+ if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
1298
+ field[n + 2 - sol].end, &permset)) {
1299
+ /* Invalid mode, skip entry */
1300
+ ret = ARCHIVE_WARN;
1301
+ continue;
1302
+ }
1303
+ } else {
1304
+ /* NFS4 ACLs */
1305
+ s = field[0].start;
1306
+ len = field[0].end - field[0].start;
1307
+ tag = 0;
1308
+
1309
+ switch (len) {
1310
+ case 4:
1311
+ if (wmemcmp(s, L"user", 4) == 0)
1312
+ tag = ARCHIVE_ENTRY_ACL_USER;
1313
+ break;
1314
+ case 5:
1315
+ if (wmemcmp(s, L"group", 5) == 0)
1316
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
1317
+ break;
1318
+ case 6:
1319
+ if (wmemcmp(s, L"owner@", 6) == 0)
1320
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
1321
+ else if (wmemcmp(s, L"group@", len) == 0)
1322
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
1323
+ break;
1324
+ case 9:
1325
+ if (wmemcmp(s, L"everyone@", 9) == 0)
1326
+ tag = ARCHIVE_ENTRY_ACL_EVERYONE;
1327
+ default:
1328
+ break;
1329
+ }
1330
+
1331
+ if (tag == 0) {
1332
+ /* Invalid tag, skip entry */
1333
+ ret = ARCHIVE_WARN;
1334
+ continue;
1335
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER ||
1336
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
1337
+ n = 1;
1338
+ name = field[1];
1339
+ isint_w(name.start, name.end, &id);
1340
+ } else
1341
+ n = 0;
1342
+
1343
+ if (!is_nfs4_perms_w(field[1 + n].start,
1344
+ field[1 + n].end, &permset)) {
1345
+ /* Invalid NFSv4 perms, skip entry */
1346
+ ret = ARCHIVE_WARN;
1347
+ continue;
1348
+ }
1349
+ if (!is_nfs4_flags_w(field[2 + n].start,
1350
+ field[2 + n].end, &permset)) {
1351
+ /* Invalid NFSv4 flags, skip entry */
1352
+ ret = ARCHIVE_WARN;
1353
+ continue;
1354
+ }
1355
+ s = field[3 + n].start;
1356
+ len = field[3 + n].end - field[3 + n].start;
1357
+ type = 0;
1358
+ if (len == 4) {
1359
+ if (wmemcmp(s, L"deny", 4) == 0)
1360
+ type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
1361
+ } else if (len == 5) {
1362
+ if (wmemcmp(s, L"allow", 5) == 0)
1363
+ type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
1364
+ else if (wmemcmp(s, L"audit", 5) == 0)
1365
+ type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
1366
+ else if (wmemcmp(s, L"alarm", 5) == 0)
1367
+ type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
1368
+ }
1369
+ if (type == 0) {
1370
+ /* Invalid entry type, skip entry */
1371
+ ret = ARCHIVE_WARN;
1372
+ continue;
1373
+ }
1374
+ isint_w(field[4 + n].start, field[4 + n].end, &id);
1375
+ }
1376
+
1377
+ /* Add entry to the internal list. */
1378
+ r = archive_acl_add_entry_w_len(acl, type, permset,
1379
+ tag, id, name.start, name.end - name.start);
1380
+ if (r < ARCHIVE_WARN)
1381
+ return (r);
1382
+ if (r != ARCHIVE_OK)
1383
+ ret = ARCHIVE_WARN;
1384
+ types |= type;
1385
+ }
1386
+
1387
+ /* Reset ACL */
1388
+ archive_acl_reset(acl, types);
1389
+
1390
+ return (ret);
1391
+ }
1392
+
1393
+ /*
1394
+ * Parse a string to a positive decimal integer. Returns true if
1395
+ * the string is non-empty and consists only of decimal digits,
1396
+ * false otherwise.
1397
+ */
1398
+ static int
1399
+ isint_w(const wchar_t *start, const wchar_t *end, int *result)
1400
+ {
1401
+ int n = 0;
1402
+ if (start >= end)
1403
+ return (0);
1404
+ while (start < end) {
1405
+ if (*start < L'0' || *start > L'9')
1406
+ return (0);
1407
+ if (n > (INT_MAX / 10) ||
1408
+ (n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) {
1409
+ n = INT_MAX;
1410
+ } else {
1411
+ n *= 10;
1412
+ n += *start - L'0';
1413
+ }
1414
+ start++;
1415
+ }
1416
+ *result = n;
1417
+ return (1);
1418
+ }
1419
+
1420
+ /*
1421
+ * Parse a string as a mode field. Returns true if
1422
+ * the string is non-empty and consists only of mode characters,
1423
+ * false otherwise.
1424
+ */
1425
+ static int
1426
+ ismode_w(const wchar_t *start, const wchar_t *end, int *permset)
1427
+ {
1428
+ const wchar_t *p;
1429
+
1430
+ if (start >= end)
1431
+ return (0);
1432
+ p = start;
1433
+ *permset = 0;
1434
+ while (p < end) {
1435
+ switch (*p++) {
1436
+ case L'r': case L'R':
1437
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
1438
+ break;
1439
+ case L'w': case L'W':
1440
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
1441
+ break;
1442
+ case L'x': case L'X':
1443
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
1444
+ break;
1445
+ case L'-':
1446
+ break;
1447
+ default:
1448
+ return (0);
1449
+ }
1450
+ }
1451
+ return (1);
1452
+ }
1453
+
1454
+ /*
1455
+ * Parse a string as a NFS4 ACL permission field.
1456
+ * Returns true if the string is non-empty and consists only of NFS4 ACL
1457
+ * permission characters, false otherwise
1458
+ */
1459
+ static int
1460
+ is_nfs4_perms_w(const wchar_t *start, const wchar_t *end, int *permset)
1461
+ {
1462
+ const wchar_t *p = start;
1463
+
1464
+ while (p < end) {
1465
+ switch (*p++) {
1466
+ case L'r':
1467
+ *permset |= ARCHIVE_ENTRY_ACL_READ_DATA;
1468
+ break;
1469
+ case L'w':
1470
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA;
1471
+ break;
1472
+ case L'x':
1473
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
1474
+ break;
1475
+ case L'p':
1476
+ *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA;
1477
+ break;
1478
+ case L'D':
1479
+ *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD;
1480
+ break;
1481
+ case L'd':
1482
+ *permset |= ARCHIVE_ENTRY_ACL_DELETE;
1483
+ break;
1484
+ case L'a':
1485
+ *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES;
1486
+ break;
1487
+ case L'A':
1488
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES;
1489
+ break;
1490
+ case L'R':
1491
+ *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS;
1492
+ break;
1493
+ case L'W':
1494
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS;
1495
+ break;
1496
+ case L'c':
1497
+ *permset |= ARCHIVE_ENTRY_ACL_READ_ACL;
1498
+ break;
1499
+ case L'C':
1500
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL;
1501
+ break;
1502
+ case L'o':
1503
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER;
1504
+ break;
1505
+ case L's':
1506
+ *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
1507
+ break;
1508
+ case L'-':
1509
+ break;
1510
+ default:
1511
+ return(0);
1512
+ }
1513
+ }
1514
+ return (1);
1515
+ }
1516
+
1517
+ /*
1518
+ * Parse a string as a NFS4 ACL flags field.
1519
+ * Returns true if the string is non-empty and consists only of NFS4 ACL
1520
+ * flag characters, false otherwise
1521
+ */
1522
+ static int
1523
+ is_nfs4_flags_w(const wchar_t *start, const wchar_t *end, int *permset)
1524
+ {
1525
+ const wchar_t *p = start;
1526
+
1527
+ while (p < end) {
1528
+ switch(*p++) {
1529
+ case L'f':
1530
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT;
1531
+ break;
1532
+ case L'd':
1533
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT;
1534
+ break;
1535
+ case L'i':
1536
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY;
1537
+ break;
1538
+ case L'n':
1539
+ *permset |=
1540
+ ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT;
1541
+ break;
1542
+ case L'S':
1543
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS;
1544
+ break;
1545
+ case L'F':
1546
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS;
1547
+ break;
1548
+ case L'I':
1549
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED;
1550
+ break;
1551
+ case L'-':
1552
+ break;
1553
+ default:
1554
+ return (0);
1555
+ }
1556
+ }
1557
+ return (1);
1558
+ }
1559
+
1560
+ /*
1561
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
1562
+ * to point to just after the separator. *start points to the first
1563
+ * character of the matched text and *end just after the last
1564
+ * character of the matched identifier. In particular *end - *start
1565
+ * is the length of the field body, not including leading or trailing
1566
+ * whitespace.
1567
+ */
1568
+ static void
1569
+ next_field_w(const wchar_t **wp, const wchar_t **start,
1570
+ const wchar_t **end, wchar_t *sep)
1571
+ {
1572
+ /* Skip leading whitespace to find start of field. */
1573
+ while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') {
1574
+ (*wp)++;
1575
+ }
1576
+ *start = *wp;
1577
+
1578
+ /* Scan for the separator. */
1579
+ while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
1580
+ **wp != L'\n' && **wp != L'#') {
1581
+ (*wp)++;
1582
+ }
1583
+ *sep = **wp;
1584
+
1585
+ /* Locate end of field, trim trailing whitespace if necessary */
1586
+ if (*wp == *start) {
1587
+ *end = *wp;
1588
+ } else {
1589
+ *end = *wp - 1;
1590
+ while (**end == L' ' || **end == L'\t' || **end == L'\n') {
1591
+ (*end)--;
1592
+ }
1593
+ (*end)++;
1594
+ }
1595
+
1596
+ /* Handle in-field comments */
1597
+ if (*sep == L'#') {
1598
+ while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
1599
+ (*wp)++;
1600
+ }
1601
+ *sep = **wp;
1602
+ }
1603
+
1604
+ /* Adjust scanner location. */
1605
+ if (**wp != L'\0')
1606
+ (*wp)++;
1607
+ }
1608
+
1609
+ /*
1610
+ * Parse an ACL text string.
1611
+ *
1612
+ * The want_type argument may be one of the following:
1613
+ * ARCHIVE_ENTRY_ACL_TYPE_ACCESS - text is a POSIX.1e ACL of type ACCESS
1614
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT - text is a POSIX.1e ACL of type DEFAULT
1615
+ * ARCHIVE_ENTRY_ACL_TYPE_NFS4 - text is as a NFSv4 ACL
1616
+ *
1617
+ * POSIX.1e ACL entries prefixed with "default:" are treated as
1618
+ * ARCHIVE_ENTRY_ACL_TYPE_DEFAULT unless type is ARCHIVE_ENTRY_ACL_TYPE_NFS4
1619
+ */
1620
+ int
1621
+ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
1622
+ int want_type, struct archive_string_conv *sc)
1623
+ {
1624
+ struct {
1625
+ const char *start;
1626
+ const char *end;
1627
+ } field[6], name;
1628
+
1629
+ const char *s, *st;
1630
+ int numfields, fields, n, r, sol, ret;
1631
+ int type, types, tag, permset, id;
1632
+ size_t len;
1633
+ char sep;
1634
+
1635
+ switch (want_type) {
1636
+ case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
1637
+ want_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
1638
+ __LA_FALLTHROUGH;
1639
+ case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
1640
+ case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
1641
+ numfields = 5;
1642
+ break;
1643
+ case ARCHIVE_ENTRY_ACL_TYPE_NFS4:
1644
+ numfields = 6;
1645
+ break;
1646
+ default:
1647
+ return (ARCHIVE_FATAL);
1648
+ }
1649
+
1650
+ ret = ARCHIVE_OK;
1651
+ types = 0;
1652
+
1653
+ while (text != NULL && *text != '\0') {
1654
+ /*
1655
+ * Parse the fields out of the next entry,
1656
+ * advance 'text' to start of next entry.
1657
+ */
1658
+ fields = 0;
1659
+ do {
1660
+ const char *start, *end;
1661
+ next_field(&text, &start, &end, &sep);
1662
+ if (fields < numfields) {
1663
+ field[fields].start = start;
1664
+ field[fields].end = end;
1665
+ }
1666
+ ++fields;
1667
+ } while (sep == ':');
1668
+
1669
+ /* Set remaining fields to blank. */
1670
+ for (n = fields; n < numfields; ++n)
1671
+ field[n].start = field[n].end = NULL;
1672
+
1673
+ if (field[0].start != NULL && *(field[0].start) == '#') {
1674
+ /* Comment, skip entry */
1675
+ continue;
1676
+ }
1677
+
1678
+ n = 0;
1679
+ sol = 0;
1680
+ id = -1;
1681
+ permset = 0;
1682
+ name.start = name.end = NULL;
1683
+
1684
+ if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
1685
+ /* POSIX.1e ACLs */
1686
+ /*
1687
+ * Default keyword "default:user::rwx"
1688
+ * if found, we have one more field
1689
+ *
1690
+ * We also support old Solaris extension:
1691
+ * "defaultuser::rwx" is the default ACL corresponding
1692
+ * to "user::rwx", etc. valid only for first field
1693
+ */
1694
+ s = field[0].start;
1695
+ len = field[0].end - field[0].start;
1696
+ if (*s == 'd' && (len == 1 || (len >= 7
1697
+ && memcmp((s + 1), "efault", 6) == 0))) {
1698
+ type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
1699
+ if (len > 7)
1700
+ field[0].start += 7;
1701
+ else
1702
+ n = 1;
1703
+ } else
1704
+ type = want_type;
1705
+
1706
+ /* Check for a numeric ID in field n+1 or n+3. */
1707
+ isint(field[n + 1].start, field[n + 1].end, &id);
1708
+ /* Field n+3 is optional. */
1709
+ if (id == -1 && fields > (n + 3))
1710
+ isint(field[n + 3].start, field[n + 3].end,
1711
+ &id);
1712
+
1713
+ tag = 0;
1714
+ s = field[n].start;
1715
+ st = field[n].start + 1;
1716
+ len = field[n].end - field[n].start;
1717
+
1718
+ if (len == 0) {
1719
+ ret = ARCHIVE_WARN;
1720
+ continue;
1721
+ }
1722
+
1723
+ switch (*s) {
1724
+ case 'u':
1725
+ if (len == 1 || (len == 4
1726
+ && memcmp(st, "ser", 3) == 0))
1727
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
1728
+ break;
1729
+ case 'g':
1730
+ if (len == 1 || (len == 5
1731
+ && memcmp(st, "roup", 4) == 0))
1732
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
1733
+ break;
1734
+ case 'o':
1735
+ if (len == 1 || (len == 5
1736
+ && memcmp(st, "ther", 4) == 0))
1737
+ tag = ARCHIVE_ENTRY_ACL_OTHER;
1738
+ break;
1739
+ case 'm':
1740
+ if (len == 1 || (len == 4
1741
+ && memcmp(st, "ask", 3) == 0))
1742
+ tag = ARCHIVE_ENTRY_ACL_MASK;
1743
+ break;
1744
+ default:
1745
+ break;
1746
+ }
1747
+
1748
+ switch (tag) {
1749
+ case ARCHIVE_ENTRY_ACL_OTHER:
1750
+ case ARCHIVE_ENTRY_ACL_MASK:
1751
+ if (fields == (n + 2)
1752
+ && field[n + 1].start < field[n + 1].end
1753
+ && ismode(field[n + 1].start,
1754
+ field[n + 1].end, &permset)) {
1755
+ /* This is Solaris-style "other:rwx" */
1756
+ sol = 1;
1757
+ } else if (fields == (n + 3) &&
1758
+ field[n + 1].start < field[n + 1].end) {
1759
+ /* Invalid mask or other field */
1760
+ ret = ARCHIVE_WARN;
1761
+ continue;
1762
+ }
1763
+ break;
1764
+ case ARCHIVE_ENTRY_ACL_USER_OBJ:
1765
+ case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
1766
+ if (id != -1 ||
1767
+ field[n + 1].start < field[n + 1].end) {
1768
+ name = field[n + 1];
1769
+ if (tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
1770
+ tag = ARCHIVE_ENTRY_ACL_USER;
1771
+ else
1772
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
1773
+ }
1774
+ break;
1775
+ default:
1776
+ /* Invalid tag, skip entry */
1777
+ ret = ARCHIVE_WARN;
1778
+ continue;
1779
+ }
1780
+
1781
+ /*
1782
+ * Without "default:" we expect mode in field 3
1783
+ * Exception: Solaris other and mask fields
1784
+ */
1785
+ if (permset == 0 && !ismode(field[n + 2 - sol].start,
1786
+ field[n + 2 - sol].end, &permset)) {
1787
+ /* Invalid mode, skip entry */
1788
+ ret = ARCHIVE_WARN;
1789
+ continue;
1790
+ }
1791
+ } else {
1792
+ /* NFS4 ACLs */
1793
+ s = field[0].start;
1794
+ len = field[0].end - field[0].start;
1795
+ tag = 0;
1796
+
1797
+ switch (len) {
1798
+ case 4:
1799
+ if (memcmp(s, "user", 4) == 0)
1800
+ tag = ARCHIVE_ENTRY_ACL_USER;
1801
+ break;
1802
+ case 5:
1803
+ if (memcmp(s, "group", 5) == 0)
1804
+ tag = ARCHIVE_ENTRY_ACL_GROUP;
1805
+ break;
1806
+ case 6:
1807
+ if (memcmp(s, "owner@", 6) == 0)
1808
+ tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
1809
+ else if (memcmp(s, "group@", 6) == 0)
1810
+ tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
1811
+ break;
1812
+ case 9:
1813
+ if (memcmp(s, "everyone@", 9) == 0)
1814
+ tag = ARCHIVE_ENTRY_ACL_EVERYONE;
1815
+ break;
1816
+ default:
1817
+ break;
1818
+ }
1819
+
1820
+ if (tag == 0) {
1821
+ /* Invalid tag, skip entry */
1822
+ ret = ARCHIVE_WARN;
1823
+ continue;
1824
+ } else if (tag == ARCHIVE_ENTRY_ACL_USER ||
1825
+ tag == ARCHIVE_ENTRY_ACL_GROUP) {
1826
+ n = 1;
1827
+ name = field[1];
1828
+ isint(name.start, name.end, &id);
1829
+ } else
1830
+ n = 0;
1831
+
1832
+ if (!is_nfs4_perms(field[1 + n].start,
1833
+ field[1 + n].end, &permset)) {
1834
+ /* Invalid NFSv4 perms, skip entry */
1835
+ ret = ARCHIVE_WARN;
1836
+ continue;
1837
+ }
1838
+ if (!is_nfs4_flags(field[2 + n].start,
1839
+ field[2 + n].end, &permset)) {
1840
+ /* Invalid NFSv4 flags, skip entry */
1841
+ ret = ARCHIVE_WARN;
1842
+ continue;
1843
+ }
1844
+ s = field[3 + n].start;
1845
+ len = field[3 + n].end - field[3 + n].start;
1846
+ type = 0;
1847
+ if (len == 4) {
1848
+ if (memcmp(s, "deny", 4) == 0)
1849
+ type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
1850
+ } else if (len == 5) {
1851
+ if (memcmp(s, "allow", 5) == 0)
1852
+ type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
1853
+ else if (memcmp(s, "audit", 5) == 0)
1854
+ type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
1855
+ else if (memcmp(s, "alarm", 5) == 0)
1856
+ type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
1857
+ }
1858
+ if (type == 0) {
1859
+ /* Invalid entry type, skip entry */
1860
+ ret = ARCHIVE_WARN;
1861
+ continue;
1862
+ }
1863
+ isint(field[4 + n].start, field[4 + n].end,
1864
+ &id);
1865
+ }
1866
+
1867
+ /* Add entry to the internal list. */
1868
+ r = archive_acl_add_entry_len_l(acl, type, permset,
1869
+ tag, id, name.start, name.end - name.start, sc);
1870
+ if (r < ARCHIVE_WARN)
1871
+ return (r);
1872
+ if (r != ARCHIVE_OK)
1873
+ ret = ARCHIVE_WARN;
1874
+ types |= type;
1875
+ }
1876
+
1877
+ /* Reset ACL */
1878
+ archive_acl_reset(acl, types);
1879
+
1880
+ return (ret);
1881
+ }
1882
+
1883
+ /*
1884
+ * Parse a string to a positive decimal integer. Returns true if
1885
+ * the string is non-empty and consists only of decimal digits,
1886
+ * false otherwise.
1887
+ */
1888
+ static int
1889
+ isint(const char *start, const char *end, int *result)
1890
+ {
1891
+ int n = 0;
1892
+ if (start >= end)
1893
+ return (0);
1894
+ while (start < end) {
1895
+ if (*start < '0' || *start > '9')
1896
+ return (0);
1897
+ if (n > (INT_MAX / 10) ||
1898
+ (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
1899
+ n = INT_MAX;
1900
+ } else {
1901
+ n *= 10;
1902
+ n += *start - '0';
1903
+ }
1904
+ start++;
1905
+ }
1906
+ *result = n;
1907
+ return (1);
1908
+ }
1909
+
1910
+ /*
1911
+ * Parse a string as a mode field. Returns true if
1912
+ * the string is non-empty and consists only of mode characters,
1913
+ * false otherwise.
1914
+ */
1915
+ static int
1916
+ ismode(const char *start, const char *end, int *permset)
1917
+ {
1918
+ const char *p;
1919
+
1920
+ if (start >= end)
1921
+ return (0);
1922
+ p = start;
1923
+ *permset = 0;
1924
+ while (p < end) {
1925
+ switch (*p++) {
1926
+ case 'r': case 'R':
1927
+ *permset |= ARCHIVE_ENTRY_ACL_READ;
1928
+ break;
1929
+ case 'w': case 'W':
1930
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE;
1931
+ break;
1932
+ case 'x': case 'X':
1933
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
1934
+ break;
1935
+ case '-':
1936
+ break;
1937
+ default:
1938
+ return (0);
1939
+ }
1940
+ }
1941
+ return (1);
1942
+ }
1943
+
1944
+ /*
1945
+ * Parse a string as a NFS4 ACL permission field.
1946
+ * Returns true if the string is non-empty and consists only of NFS4 ACL
1947
+ * permission characters, false otherwise
1948
+ */
1949
+ static int
1950
+ is_nfs4_perms(const char *start, const char *end, int *permset)
1951
+ {
1952
+ const char *p = start;
1953
+
1954
+ while (p < end) {
1955
+ switch (*p++) {
1956
+ case 'r':
1957
+ *permset |= ARCHIVE_ENTRY_ACL_READ_DATA;
1958
+ break;
1959
+ case 'w':
1960
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_DATA;
1961
+ break;
1962
+ case 'x':
1963
+ *permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
1964
+ break;
1965
+ case 'p':
1966
+ *permset |= ARCHIVE_ENTRY_ACL_APPEND_DATA;
1967
+ break;
1968
+ case 'D':
1969
+ *permset |= ARCHIVE_ENTRY_ACL_DELETE_CHILD;
1970
+ break;
1971
+ case 'd':
1972
+ *permset |= ARCHIVE_ENTRY_ACL_DELETE;
1973
+ break;
1974
+ case 'a':
1975
+ *permset |= ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES;
1976
+ break;
1977
+ case 'A':
1978
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES;
1979
+ break;
1980
+ case 'R':
1981
+ *permset |= ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS;
1982
+ break;
1983
+ case 'W':
1984
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS;
1985
+ break;
1986
+ case 'c':
1987
+ *permset |= ARCHIVE_ENTRY_ACL_READ_ACL;
1988
+ break;
1989
+ case 'C':
1990
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_ACL;
1991
+ break;
1992
+ case 'o':
1993
+ *permset |= ARCHIVE_ENTRY_ACL_WRITE_OWNER;
1994
+ break;
1995
+ case 's':
1996
+ *permset |= ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
1997
+ break;
1998
+ case '-':
1999
+ break;
2000
+ default:
2001
+ return(0);
2002
+ }
2003
+ }
2004
+ return (1);
2005
+ }
2006
+
2007
+ /*
2008
+ * Parse a string as a NFS4 ACL flags field.
2009
+ * Returns true if the string is non-empty and consists only of NFS4 ACL
2010
+ * flag characters, false otherwise
2011
+ */
2012
+ static int
2013
+ is_nfs4_flags(const char *start, const char *end, int *permset)
2014
+ {
2015
+ const char *p = start;
2016
+
2017
+ while (p < end) {
2018
+ switch(*p++) {
2019
+ case 'f':
2020
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT;
2021
+ break;
2022
+ case 'd':
2023
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT;
2024
+ break;
2025
+ case 'i':
2026
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY;
2027
+ break;
2028
+ case 'n':
2029
+ *permset |=
2030
+ ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT;
2031
+ break;
2032
+ case 'S':
2033
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS;
2034
+ break;
2035
+ case 'F':
2036
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS;
2037
+ break;
2038
+ case 'I':
2039
+ *permset |= ARCHIVE_ENTRY_ACL_ENTRY_INHERITED;
2040
+ break;
2041
+ case '-':
2042
+ break;
2043
+ default:
2044
+ return (0);
2045
+ }
2046
+ }
2047
+ return (1);
2048
+ }
2049
+
2050
+ /*
2051
+ * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated
2052
+ * to point to just after the separator. *start points to the first
2053
+ * character of the matched text and *end just after the last
2054
+ * character of the matched identifier. In particular *end - *start
2055
+ * is the length of the field body, not including leading or trailing
2056
+ * whitespace.
2057
+ */
2058
+ static void
2059
+ next_field(const char **p, const char **start,
2060
+ const char **end, char *sep)
2061
+ {
2062
+ /* Skip leading whitespace to find start of field. */
2063
+ while (**p == ' ' || **p == '\t' || **p == '\n') {
2064
+ (*p)++;
2065
+ }
2066
+ *start = *p;
2067
+
2068
+ /* Scan for the separator. */
2069
+ while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
2070
+ **p != '#') {
2071
+ (*p)++;
2072
+ }
2073
+ *sep = **p;
2074
+
2075
+ /* Locate end of field, trim trailing whitespace if necessary */
2076
+ if (*p == *start) {
2077
+ *end = *p;
2078
+ } else {
2079
+ *end = *p - 1;
2080
+ while (**end == ' ' || **end == '\t' || **end == '\n') {
2081
+ (*end)--;
2082
+ }
2083
+ (*end)++;
2084
+ }
2085
+
2086
+ /* Handle in-field comments */
2087
+ if (*sep == '#') {
2088
+ while (**p != '\0' && **p != ',' && **p != '\n') {
2089
+ (*p)++;
2090
+ }
2091
+ *sep = **p;
2092
+ }
2093
+
2094
+ /* Adjust scanner location. */
2095
+ if (**p != '\0')
2096
+ (*p)++;
2097
+ }