2025-02-21 17:34:31 +00:00
|
|
|
use std::{
|
2025-02-21 19:24:49 +00:00
|
|
|
fs::{read_dir, read_link, read_to_string, DirEntry},
|
2025-02-21 17:34:31 +00:00
|
|
|
path::{Path, PathBuf},
|
|
|
|
};
|
|
|
|
|
2025-02-22 00:30:17 +00:00
|
|
|
use crate::{fs::resolve_link, Session, User};
|
2025-02-21 17:34:31 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct PasswdUser {
|
|
|
|
name: String,
|
|
|
|
uid: u32,
|
|
|
|
gid: u32,
|
|
|
|
gecos: String,
|
|
|
|
home: String,
|
|
|
|
shell: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn gather_users() -> Vec<User> {
|
|
|
|
let passwd = std::fs::read_to_string("/etc/passwd").unwrap();
|
|
|
|
passwd
|
|
|
|
.lines()
|
|
|
|
.map(|line| {
|
|
|
|
let fields: Vec<&str> = line.split(":").collect();
|
|
|
|
let name = fields[0].to_owned();
|
|
|
|
let uid = fields[2].parse().unwrap();
|
|
|
|
let gid = fields[3].parse().unwrap();
|
|
|
|
let gecos = fields[4].to_owned();
|
|
|
|
let home = fields[5].to_owned();
|
|
|
|
let shell = fields[6].to_owned();
|
|
|
|
|
|
|
|
PasswdUser {
|
|
|
|
name,
|
|
|
|
uid,
|
|
|
|
gid,
|
|
|
|
gecos,
|
|
|
|
home,
|
|
|
|
shell,
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.filter(|user| !user.shell.ends_with("nologin"))
|
|
|
|
.map(|user| User {
|
|
|
|
name: user.name,
|
|
|
|
home: user.home.into(),
|
|
|
|
shell: user.shell.into(),
|
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn gather_sessions(user: &User) -> Vec<Session> {
|
|
|
|
let hm_profile = user.home.join(".local/state/nix/profiles/home-manager");
|
|
|
|
match hm_profile.exists() {
|
|
|
|
true => gather_hm_sessions(&hm_profile),
|
|
|
|
false => vec![Session {
|
|
|
|
name: String::from("Shell"),
|
2025-02-22 00:30:17 +00:00
|
|
|
generation: user.shell.to_str().unwrap().to_owned(),
|
2025-02-21 17:34:31 +00:00
|
|
|
}],
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn gather_hm_sessions(path: &PathBuf) -> Vec<Session> {
|
|
|
|
let generation = resolve_link(path);
|
2025-02-21 20:21:25 +00:00
|
|
|
let mut sessions = vec![gather_session_data(&generation, &generation)];
|
2025-02-21 17:34:31 +00:00
|
|
|
|
2025-02-21 19:24:49 +00:00
|
|
|
sessions.append(&mut gather_specialisations(&generation));
|
2025-02-21 17:34:31 +00:00
|
|
|
|
|
|
|
sessions
|
|
|
|
}
|
|
|
|
|
2025-02-21 19:24:49 +00:00
|
|
|
fn gather_specialisations(path: &PathBuf) -> Vec<Session> {
|
|
|
|
let specialisation_path = path.join("specialisation");
|
2025-02-21 17:34:31 +00:00
|
|
|
if !specialisation_path.exists() {
|
|
|
|
return vec![];
|
|
|
|
}
|
|
|
|
|
|
|
|
read_dir(specialisation_path)
|
|
|
|
.unwrap()
|
|
|
|
.flatten()
|
|
|
|
.map(|entry| {
|
2025-02-21 20:21:25 +00:00
|
|
|
let link_path = resolve_link(&entry.path());
|
2025-02-21 19:24:49 +00:00
|
|
|
// let name = entry
|
|
|
|
// .path()
|
|
|
|
// .file_name()
|
|
|
|
// .unwrap()
|
|
|
|
// .to_str()
|
|
|
|
// .unwrap()
|
|
|
|
// .to_owned();
|
|
|
|
// Session { name, path }
|
2025-02-21 20:21:25 +00:00
|
|
|
gather_session_data(&link_path, path)
|
2025-02-21 17:34:31 +00:00
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
2025-02-21 19:24:49 +00:00
|
|
|
|
2025-02-21 20:21:25 +00:00
|
|
|
fn gather_session_data(path: &PathBuf, reset_path: &PathBuf) -> Session {
|
2025-02-21 19:24:49 +00:00
|
|
|
let session_path = path.join("session");
|
|
|
|
|
|
|
|
let name = read_to_string(session_path.join("name")).unwrap();
|
2025-02-22 00:30:17 +00:00
|
|
|
// let init = format!(
|
|
|
|
// "sh -c \"{} && {} && {}\"",
|
|
|
|
// path.join("activate").display(),
|
|
|
|
// session_path.join("init").display(),
|
|
|
|
// reset_path.join("activate").display()
|
|
|
|
// );
|
|
|
|
let generation = path.to_str().unwrap().to_owned();
|
2025-02-21 19:24:49 +00:00
|
|
|
|
2025-02-22 00:30:17 +00:00
|
|
|
Session { name, generation }
|
2025-02-21 19:24:49 +00:00
|
|
|
}
|