Skip to content

Commit 4dae19a

Browse files
authored
fix: label regex groups and add support for parsing ls output on systems that include SELinux labels, POSIX ACLs, and extended attributes (#9)
1 parent 763ee33 commit 4dae19a

File tree

1 file changed

+11
-22
lines changed

1 file changed

+11
-22
lines changed

src/ssh/scp.rs

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::utils::{fmt as fmt_utils, parser as parser_utils, path as path_utils}
2121

2222
/// NOTE: about this damn regex <https://stackoverflow.com/questions/32480890/is-there-a-regex-to-parse-the-values-from-an-ftp-directory-listing>
2323
static LS_RE: Lazy<Regex> = lazy_regex!(
24-
r#"^([\-ld])([\-rwxsStT]{9})\s+(\d+)\s+(.+)\s+(.+)\s+(\d+)\s+(\w{3}\s+\d{1,2}\s+(?:\d{1,2}:\d{1,2}|\d{4}))\s+(.+)$"#
24+
r#"^(?<sym_dir>[\-ld])(?<pex>[\-rwxsStT]{9})(?<sec_ctx>\.|\+|\@)?\s+(?<n_links>\d+)\s+(?<uid>.+)\s+(?<gid>.+)\s+(?<size>\d+)\s+(?<date_time>\w{3}\s+\d{1,2}\s+(?:\d{1,2}:\d{1,2}|\d{4}))\s+(?<name>.+)$"#
2525
);
2626

2727
/// SCP "filesystem" client
@@ -72,20 +72,21 @@ impl ScpFs {
7272
}
7373
// Collect metadata
7474
// Get if is directory and if is symlink
75-
let (is_dir, is_symlink): (bool, bool) = match metadata.get(1).unwrap().as_str() {
75+
76+
let (is_dir, is_symlink): (bool, bool) = match &metadata["sym_dir"] {
7677
"-" => (false, false),
7778
"l" => (false, true),
7879
"d" => (true, false),
7980
_ => return Err(()), // Ignore special files
8081
};
8182
// Check string length (unix pex)
82-
if metadata.get(2).unwrap().as_str().len() < 9 {
83+
if metadata["pex"].len() < 9 {
8384
return Err(());
8485
}
8586

8687
let pex = |range: Range<usize>| {
8788
let mut count: u8 = 0;
88-
for (i, c) in metadata.get(2).unwrap().as_str()[range].chars().enumerate() {
89+
for (i, c) in metadata["pex"][range].chars().enumerate() {
8990
match c {
9091
'-' => {}
9192
_ => {
@@ -110,34 +111,23 @@ impl ScpFs {
110111

111112
// Parse modified and convert to SystemTime
112113
let modified: SystemTime = match parser_utils::parse_lstime(
113-
metadata.get(7).unwrap().as_str(),
114+
&metadata["date_time"],
114115
"%b %d %Y",
115116
"%b %d %H:%M",
116117
) {
117118
Ok(t) => t,
118119
Err(_) => SystemTime::UNIX_EPOCH,
119120
};
120121
// Get uid
121-
let uid: Option<u32> = match metadata.get(4).unwrap().as_str().parse::<u32>() {
122-
Ok(uid) => Some(uid),
123-
Err(_) => None,
124-
};
122+
let uid: Option<u32> = metadata["uid"].parse::<u32>().ok();
125123
// Get gid
126-
let gid: Option<u32> = match metadata.get(5).unwrap().as_str().parse::<u32>() {
127-
Ok(gid) => Some(gid),
128-
Err(_) => None,
129-
};
124+
let gid: Option<u32> = metadata["gid"].parse::<u32>().ok();
130125
// Get filesize
131-
let size = metadata
132-
.get(6)
133-
.unwrap()
134-
.as_str()
135-
.parse::<u64>()
136-
.unwrap_or(0);
126+
let size = metadata["size"].parse::<u64>().unwrap_or(0);
137127
// Get link and name
138128
let (file_name, symlink): (String, Option<PathBuf>) = match is_symlink {
139-
true => self.get_name_and_link(metadata.get(8).unwrap().as_str()),
140-
false => (String::from(metadata.get(8).unwrap().as_str()), None),
129+
true => self.get_name_and_link(&metadata["name"]),
130+
false => (String::from(&metadata["name"]), None),
141131
};
142132
// Sanitize file name
143133
let file_name = PathBuf::from(&file_name)
@@ -146,7 +136,6 @@ impl ScpFs {
146136
.unwrap_or(file_name);
147137
// Check if file_name is '.' or '..'
148138
if file_name.as_str() == "." || file_name.as_str() == ".." {
149-
debug!("File name is {}; ignoring entry", file_name);
150139
return Err(());
151140
}
152141
// Re-check if is directory

0 commit comments

Comments
 (0)