1use crate::entry::EntryMut;
4use crate::error::{Error, Result};
5use std::ops::{BitOr, BitOrAssign};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub struct ExtractFlags(i32);
10
11impl ExtractFlags {
12 pub const NONE: ExtractFlags = ExtractFlags(0);
14
15 pub const OWNER: ExtractFlags = ExtractFlags(0x0001);
17
18 pub const PERM: ExtractFlags = ExtractFlags(0x0002);
20
21 pub const TIME: ExtractFlags = ExtractFlags(0x0004);
23
24 pub const NO_OVERWRITE: ExtractFlags = ExtractFlags(0x0008);
26
27 pub const UNLINK: ExtractFlags = ExtractFlags(0x0010);
29
30 pub const ACL: ExtractFlags = ExtractFlags(0x0020);
32
33 pub const FFLAGS: ExtractFlags = ExtractFlags(0x0040);
35
36 pub const XATTR: ExtractFlags = ExtractFlags(0x0080);
38
39 pub const SECURE_SYMLINKS: ExtractFlags = ExtractFlags(0x0100);
41
42 pub const SECURE_NODOTDOT: ExtractFlags = ExtractFlags(0x0200);
44
45 pub const NO_AUTODIR: ExtractFlags = ExtractFlags(0x0400);
47
48 pub const NO_OVERWRITE_NEWER: ExtractFlags = ExtractFlags(0x0800);
50
51 pub const SPARSE: ExtractFlags = ExtractFlags(0x1000);
53
54 pub const MAC_METADATA: ExtractFlags = ExtractFlags(0x2000);
56
57 pub const NO_HFS_COMPRESSION: ExtractFlags = ExtractFlags(0x4000);
59
60 pub const HFS_COMPRESSION_FORCED: ExtractFlags = ExtractFlags(0x8000);
62
63 pub const SECURE_NOABSOLUTEPATHS: ExtractFlags = ExtractFlags(0x10000);
65
66 pub const CLEAR_NOCHANGE_FFLAGS: ExtractFlags = ExtractFlags(0x20000);
68
69 pub const SAFE_WRITES: ExtractFlags = ExtractFlags(0x40000);
71
72 pub fn bits(&self) -> i32 {
74 self.0
75 }
76}
77
78impl BitOr for ExtractFlags {
79 type Output = Self;
80
81 fn bitor(self, rhs: Self) -> Self::Output {
82 ExtractFlags(self.0 | rhs.0)
83 }
84}
85
86impl BitOrAssign for ExtractFlags {
87 fn bitor_assign(&mut self, rhs: Self) {
88 self.0 |= rhs.0;
89 }
90}
91
92pub struct WriteDisk {
102 archive: *mut libarchive2_sys::archive,
103}
104
105unsafe impl Send for WriteDisk {}
109
110impl WriteDisk {
114 pub fn new() -> Result<Self> {
116 unsafe {
117 let archive = libarchive2_sys::archive_write_disk_new();
118 if archive.is_null() {
119 return Err(Error::NullPointer);
120 }
121 Ok(WriteDisk { archive })
122 }
123 }
124
125 pub fn set_options(&mut self, flags: ExtractFlags) -> Result<()> {
127 unsafe {
128 Error::from_return_code(
129 libarchive2_sys::archive_write_disk_set_options(self.archive, flags.bits()),
130 self.archive,
131 )?;
132 }
133 Ok(())
134 }
135
136 pub fn set_standard_lookup(&mut self) -> Result<()> {
140 unsafe {
141 Error::from_return_code(
142 libarchive2_sys::archive_write_disk_set_standard_lookup(self.archive),
143 self.archive,
144 )?;
145 }
146 Ok(())
147 }
148
149 pub fn write_header(&mut self, entry: &EntryMut) -> Result<()> {
153 let _guard = crate::locale::WindowsUTF8LocaleGuard::new();
155
156 unsafe {
157 Error::from_return_code(
158 libarchive2_sys::archive_write_header(self.archive, entry.entry),
159 self.archive,
160 )?;
161 }
162 Ok(())
163 }
164
165 pub fn write_data(&mut self, data: &[u8]) -> Result<usize> {
167 unsafe {
168 let ret = libarchive2_sys::archive_write_data(
169 self.archive,
170 data.as_ptr() as *const std::os::raw::c_void,
171 data.len(),
172 );
173
174 if ret < 0 {
175 Err(Error::from_archive(self.archive))
176 } else {
177 Ok(ret as usize)
178 }
179 }
180 }
181
182 pub fn finish_entry(&mut self) -> Result<()> {
184 unsafe {
185 Error::from_return_code(
186 libarchive2_sys::archive_write_finish_entry(self.archive),
187 self.archive,
188 )?;
189 }
190 Ok(())
191 }
192
193 pub fn close(mut self) -> Result<()> {
195 unsafe {
196 if !self.archive.is_null() {
197 Error::from_return_code(
198 libarchive2_sys::archive_write_close(self.archive),
199 self.archive,
200 )?;
201 libarchive2_sys::archive_write_free(self.archive);
202 self.archive = std::ptr::null_mut();
203 }
204 }
205 Ok(())
206 }
207}
208
209impl Drop for WriteDisk {
210 fn drop(&mut self) {
211 unsafe {
212 if !self.archive.is_null() {
213 libarchive2_sys::archive_write_close(self.archive);
214 libarchive2_sys::archive_write_free(self.archive);
215 }
216 }
217 }
218}
219
220