Skip to main content

09_aa_entry_blobs/
09_aa_entry_blobs.rs

1mod common;
2
3use common::{artifact_dir, path_string};
4use compression::{AceQualifierType, AccessControlEntry, ArchiveFlags, EntryAclBlob, EntryXatBlob};
5use std::env;
6use std::fs;
7use std::process::Command;
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    let artifact_dir = artifact_dir("aa-entry-blobs");
11    let dir = path_string(&artifact_dir);
12    let source_name = "source.txt";
13    let target_name = "target.txt";
14    let source_path = path_string(&artifact_dir.join(source_name));
15    let target_path = path_string(&artifact_dir.join(target_name));
16    fs::write(&source_path, b"blob source")?;
17    fs::write(&target_path, b"blob target")?;
18
19    Command::new("xattr")
20        .args(["-w", "com.example.compression-rs", "example", &source_path])
21        .status()?;
22
23    let acl_entry = AccessControlEntry {
24        tag: 1,
25        perms: 1 << 1,
26        flags: 0,
27        qualifier_type: AceQualifierType::User,
28        qualifier: env::var("USER")?.into_bytes(),
29    };
30    let mut acl = EntryAclBlob::new()?;
31    acl.append_entry(&acl_entry)?;
32    let xat = EntryXatBlob::from_path(&dir, source_name, ArchiveFlags::empty())?;
33    if !acl.is_empty() {
34        let encoded = acl.encoded_data()?;
35        let decoded = EntryAclBlob::from_encoded_data(&encoded)?;
36        decoded.apply_to_path(&dir, target_name, ArchiveFlags::REPLACE_ATTRIBUTES)?;
37    }
38    let encoded_xat = xat.encoded_data()?;
39    let decoded_xat = EntryXatBlob::from_encoded_data(&encoded_xat)?;
40    decoded_xat.apply_to_path(&dir, target_name, ArchiveFlags::REPLACE_ATTRIBUTES)?;
41
42    println!("acl_entries={} xattrs={}", acl.entry_count(), xat.entry_count());
43    println!("✅ AppleArchive ACL/XAT blob helpers OK");
44    Ok(())
45}