Skip to content

Commit 05f44e8

Browse files
committed
Add efi variable list command logic
1 parent f4dc59c commit 05f44e8

File tree

9 files changed

+161
-2
lines changed

9 files changed

+161
-2
lines changed

meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ lib_refivar = static_library(
5757
lib_refivar_efi_guids_list_path_rs
5858
],
5959
{
60+
'efivarfs': [
61+
'src/lib/efivar/efivarfs/efi_variables.rs',
62+
'src/lib/efivar/efivarfs/mod.rs',
63+
],
64+
'efivar': [
65+
'src/lib/efivar/efivar/efi_variables.rs',
66+
'src/lib/efivar/efivar/mod.rs',
67+
],
6068
'print_mode': [
6169
'src/lib/efivar/print_mode/decimal.rs',
6270
'src/lib/efivar/print_mode/mod.rs',

src/bin/efivar.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ fn create_parser() -> clap::Command {
110110
}
111111

112112
fn list_variables(parser_args: clap::ArgMatches) -> ExitCode {
113+
let mut efi_variables: efivar::efivarfs::EfiVariables = Default::default();
114+
115+
for v in efi_variables.list() {
116+
println!("{}", v);
117+
}
113118
return std::process::ExitCode::from(0);
114119
}
115120

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::efivarfs;
2+
use std::path::PathBuf;
3+
4+
const EFIVARS_PATH: &'static str = "/sys/firmware/efi/vars";
5+
6+
pub struct EfiVariables {
7+
path: PathBuf,
8+
}
9+
10+
impl Default for EfiVariables {
11+
fn default() -> Self {
12+
return EfiVariables {
13+
path: EFIVARS_PATH.into(),
14+
};
15+
}
16+
}
17+
18+
impl EfiVariables {
19+
pub fn set_path(&mut self, path: PathBuf) -> &EfiVariables {
20+
self.path = path;
21+
return self;
22+
}
23+
24+
pub fn list(&self) -> efivarfs::EfiVariablesNameIter {
25+
let mut e: efivarfs::EfiVariables = Default::default();
26+
e.set_path(self.path.clone());
27+
return e.list();
28+
}
29+
}

src/lib/efivar/efivar/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* DEPRECTATED
3+
*
4+
* This module relies on a Linux kernel interface that was removed in 6.0. The interface was
5+
* deprecated with the 5.10 release of the Linux kernel.
6+
*
7+
* This module is included for support for kernels < 5.10. It should not be used for current or
8+
* future Linux kernels.
9+
*/
10+
mod efi_variables;
11+
12+
pub use efi_variables::EfiVariables;
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use crate::types::EfiGuid;
2+
use std::fs::{self, ReadDir};
3+
use std::path::PathBuf;
4+
5+
const EFIVARFS_PATH: &'static str = "/sys/firmware/efi/efivars";
6+
7+
// variable file names have 1 or more characters, a dash, then a UUID (36 characters)
8+
const MIN_VAR_FILE_NAME_LEN: usize = 38;
9+
10+
pub struct EfiVariables {
11+
path: PathBuf,
12+
}
13+
14+
pub struct EfiVariablesNameIter {
15+
dir_entry_iter: Option<ReadDir>,
16+
}
17+
18+
fn convert_name(name: Option<&str>) -> Result<String, String> {
19+
return match name {
20+
Some(n) => {
21+
if n.len() < MIN_VAR_FILE_NAME_LEN {
22+
return Err(format!(
23+
"file name {n} does not represent an EFI variable name"
24+
));
25+
}
26+
if n.bytes().nth(n.len() - MIN_VAR_FILE_NAME_LEN + 1).unwrap() != b'-' {
27+
return Err(format!(
28+
"file name {n} does not represent an EFI variable name"
29+
));
30+
}
31+
let guid_bytes = &n[n.len() - MIN_VAR_FILE_NAME_LEN + 2..n.len()];
32+
let guid: Option<EfiGuid> = match guid_bytes.try_into() {
33+
Ok(g) => Some(g),
34+
Err(_) => None,
35+
};
36+
if guid.is_none() {
37+
return Err(format!(
38+
"file name {n} does not represent an EFI variable name"
39+
));
40+
}
41+
let suffix = &n[0..n.len() - MIN_VAR_FILE_NAME_LEN + 1];
42+
43+
return Ok(String::new() + guid_bytes + &"-" + suffix);
44+
}
45+
None => Err("no name provided".to_string()),
46+
};
47+
}
48+
49+
impl Iterator for EfiVariablesNameIter {
50+
type Item = String;
51+
52+
fn next(&mut self) -> Option<Self::Item> {
53+
return match &mut self.dir_entry_iter {
54+
Some(iter) => {
55+
for entry in iter {
56+
let converted_name = match entry {
57+
Ok(entry) => convert_name(entry.file_name().to_str()),
58+
Err(e) => Err(e.to_string()),
59+
};
60+
if converted_name.is_ok() {
61+
return converted_name.ok();
62+
}
63+
}
64+
return None;
65+
}
66+
None => None,
67+
};
68+
}
69+
}
70+
71+
impl Default for EfiVariables {
72+
fn default() -> Self {
73+
return EfiVariables {
74+
path: EFIVARFS_PATH.into(),
75+
};
76+
}
77+
}
78+
79+
impl EfiVariables {
80+
pub fn set_path(&mut self, path: PathBuf) -> &EfiVariables {
81+
self.path = path;
82+
return self;
83+
}
84+
85+
pub fn list(&mut self) -> EfiVariablesNameIter {
86+
if self.path.is_dir() {
87+
let iter = fs::read_dir(&self.path);
88+
return EfiVariablesNameIter {
89+
dir_entry_iter: match iter {
90+
Ok(i) => Some(i),
91+
Err(_) => None,
92+
},
93+
};
94+
}
95+
return EfiVariablesNameIter {
96+
dir_entry_iter: None,
97+
};
98+
}
99+
}

src/lib/efivar/efivarfs/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mod efi_variables;
2+
3+
pub use crate::efivarfs::efi_variables::EfiVariables;
4+
pub use crate::efivarfs::efi_variables::EfiVariablesNameIter;

src/lib/efivar/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
pub mod efi_guids;
2+
pub mod efivar;
23
pub mod efivar_display;
4+
pub mod efivarfs;
35
pub mod print_mode;
46
pub mod types;
57

src/lib/efivar/types/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ mod print_mode;
88
pub use self::efi_guid::EfiGuid;
99
pub use self::efi_guid_error::EfiGuidError;
1010
pub use self::efi_guid_list_entry::EfiGuidListEntry;
11-
pub use self::efi_variable_attribute::EfiVariableAttribute;
1211
pub use self::efi_variable::EfiVariable;
12+
pub use self::efi_variable_attribute::EfiVariableAttribute;
1313
pub use self::print_mode::PrintMode;

src/lib/efivar/types/print_mode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pub enum PrintMode {
22
VERBOSE,
3-
DECIMAL
3+
DECIMAL,
44
}

0 commit comments

Comments
 (0)