use std::{ fs::{read_dir, read_link, read_to_string, DirEntry}, path::{Path, PathBuf}, }; use crate::{fs::resolve_link, Session, User}; #[derive(Debug)] struct PasswdUser { name: String, uid: u32, gid: u32, gecos: String, home: String, shell: String, } pub fn gather_users() -> Vec { 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 { 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"), generation: user.shell.to_str().unwrap().to_owned(), env: vec![], }], } } fn gather_hm_sessions(path: &PathBuf) -> Vec { let generation = resolve_link(path); let mut sessions = vec![gather_session_data(&generation, &generation)]; sessions.append(&mut gather_specialisations(&generation)); sessions } fn gather_specialisations(path: &PathBuf) -> Vec { let specialisation_path = path.join("specialisation"); if !specialisation_path.exists() { return vec![]; } read_dir(specialisation_path) .unwrap() .flatten() .map(|entry| { let link_path = resolve_link(&entry.path()); // let name = entry // .path() // .file_name() // .unwrap() // .to_str() // .unwrap() // .to_owned(); // Session { name, path } gather_session_data(&link_path, path) }) .collect() } fn gather_session_data(path: &PathBuf, reset_path: &PathBuf) -> Session { let session_path = path.join("session"); let env_file = read_to_string(session_path.join("env")).unwrap(); let name = read_to_string(session_path.join("name")).unwrap(); let generation = path.to_str().unwrap().to_owned(); let env = env_file.lines().map(String::from).collect(); Session { name, generation, env, } }