btrfs_cli/filesystem/
label.rs1use crate::{Format, Runnable};
2use anyhow::{Context, Result};
3use btrfs_uapi::filesystem::{label_get, label_set};
4use clap::Parser;
5use std::{
6 ffi::CString,
7 fs::File,
8 os::unix::{ffi::OsStrExt, io::AsFd},
9 path::PathBuf,
10};
11
12#[derive(Parser, Debug)]
14pub struct FilesystemLabelCommand {
15 pub path: PathBuf,
17
18 pub new_label: Option<std::ffi::OsString>,
20}
21
22impl Runnable for FilesystemLabelCommand {
23 fn run(&self, _format: Format, _dry_run: bool) -> Result<()> {
24 let file = File::open(&self.path).with_context(|| {
25 format!("failed to open '{}'", self.path.display())
26 })?;
27 match &self.new_label {
28 None => {
29 let label = label_get(file.as_fd()).with_context(|| {
30 format!("failed to get label for '{}'", self.path.display())
31 })?;
32 println!("{}", label.to_bytes().escape_ascii());
33 }
34 Some(new_label) => {
35 let cstring = CString::new(new_label.as_bytes())
36 .context("label must not contain null bytes")?;
37 label_set(file.as_fd(), &cstring).with_context(|| {
38 format!("failed to set label for '{}'", self.path.display())
39 })?;
40 }
41 }
42 Ok(())
43 }
44}