use std::{ env, error::Error, fmt::format, fs::{self, File}, io::{Read, Write}, path, }; use toml::Table; use toml::{self, Value}; fn main() -> Result<(), Box> { let mut args: Vec = env::args().collect(); args.remove(0); let file_path = &args[0]; println!("{}", file_path); let mut file = File::open(file_path).expect("Unable to open the file"); let mut contents = String::new(); file.read_to_string(&mut contents) .expect("Unable to read the file"); let value = contents.parse::().unwrap(); fs::remove_dir_all("disk")?; fs::create_dir("disk")?; // HANDLE repolist { let repolist = value.get("repositories").unwrap(); let ret = make_repolist("repolist.toml".to_string(), repolist); println!("making repolist {:?}", ret); } // HANDLE boot { let boot = value.get("boot").unwrap(); let boot_table = boot.as_table().unwrap(); if boot_table.contains_key("limine") { let limine = boot_table.get("limine").unwrap(); let ret = make_limine_cfg(limine); println!("limine return {:?}", ret); } // println!("{:#?}", boot); } // HANDLE users { let mut passhash_list: Vec<(String, String)> = vec![]; let users = value.get("users").unwrap(); // println!("{:?}", users.as_table().unwrap().keys()); let users_table = users.as_table().unwrap(); for user in users_table.keys() { let ut = users_table.get(user).unwrap(); let home_path = ut.get("home").unwrap(); let pass_hash = ut.get("password_hash").unwrap(); passhash_list.push((user.to_string(), pass_hash.to_string())); let ret = make_user(home_path.to_string()); println!("making user return {:?}", ret); // Handle homepath generation of USER { let mut hp = home_path.clone().to_string(); hp.remove(0); hp.remove(0); hp.remove(hp.len() - 1); hp.remove(hp.len() - 1); for package in ut.get("packages").unwrap().as_table().unwrap().keys() { let pack_folder: String = format!("disk/{}/{}", hp, package); let pack_config: String = format!("disk/{}/{}/config.toml", hp, package); fs::create_dir(pack_folder)?; let mut file = File::create(pack_config)?; // repo_list_str.as_bytes() let abc = ut .get("packages") .unwrap() .get(package) .unwrap() .get("configuration") .unwrap(); let mut abc = abc.to_string(); if abc.len() > 2 { abc.remove(0); abc.remove(0); abc.remove(abc.len() - 1); abc.remove(abc.len() - 1); } if abc.len() == 2 { abc.remove(0); abc.remove(0); } file.write_all(abc.as_bytes())?; } } { let repolist = ut.get("repositories").unwrap(); let mut hp = home_path.clone().to_string(); hp.remove(0); hp.remove(0); hp.remove(hp.len() - 1); hp.remove(hp.len() - 1); let user_path_repolist = format!("{}/repolist.toml", hp.to_string()); println!("{}", user_path_repolist); let ret = make_repolist(user_path_repolist, repolist); println!("making repolist {:?}", ret); } } let ret = generate_password_hashlist(passhash_list); println!("making password hashlist {:?}", ret); } // let mut file = File::create("disk/foo.txt")?; // file.write_all(b"Hello, world!")?; Ok(()) } pub fn make_limine_cfg(limine: &Value) -> std::io::Result<()> { let mut limine_str = String::new(); // raw_limine { let mut lc = limine.clone(); let boot_entries = lc.as_table_mut().unwrap(); let default_entry = boot_entries.get("default_entry").unwrap(); let timeout = boot_entries.get("timeout").unwrap(); let interface_resolution = boot_entries.get("interface_resolution").unwrap(); let verbose = boot_entries.get("verbose").unwrap(); let term_wallpaper = boot_entries.get("term_wallpaper").unwrap(); let vb_post = match verbose.as_bool().unwrap() { true => "yes", false => "no", }; let term_background = boot_entries .get("term_backdrop") .unwrap_or(&Value::Integer(0)); let base = format!( "DEFAULT_ENTRY={} TIMEOUT={} VERBOSE={} INTERFACE_RESOLUTION={} # Terminal related settings TERM_WALLPAPER={} TERM_BACKDROP={} ", default_entry, timeout, vb_post, interface_resolution, term_wallpaper, term_background ); limine_str.push_str(&base); } // HANDLE boot_entries { let mut lc = limine.clone(); let boot_entries = lc.as_table_mut().unwrap(); let mut real_boot_entries = boot_entries.clone(); for (key, value) in boot_entries.into_iter() { if !value.is_table() { real_boot_entries.remove(key); } } for (name, value) in real_boot_entries { let comment = value.get("comment").unwrap(); let protocol = value.get("protocol").unwrap(); let resolution = value.get("resolution").unwrap(); let kernel_path = value.get("kernel_path").unwrap(); let kernel_cmdline = value.get("kernel_cmdline").unwrap(); let entry = format!( " :{} COMMENT={} PROTOCOL={} RESOLUTION={} KERNEL_PATH={} KERNEL_CMDLINE={} ", name, comment, protocol, resolution, kernel_path, kernel_cmdline, ); limine_str.push_str(&entry); } } let mut file = File::create("disk/limine.cfg")?; file.write_all(limine_str.as_bytes())?; Ok(()) } pub fn make_user(mut home_path: String) -> std::io::Result<()> { home_path.remove(0); home_path.remove(home_path.len() - 1); let path = format!("disk/{}", home_path); fs::create_dir_all(path)?; Ok(()) } pub fn make_repolist(path: String, repolist: &Value) -> std::io::Result<()> { let path = format!("disk/{}", path); let mut file = File::create(path)?; let mut repo_list_str = String::new(); for (repo_name, repo_url) in repolist.as_table().unwrap() { let entry = format!("{} = {}\n", repo_name, repo_url); repo_list_str.push_str(&entry); } file.write_all(repo_list_str.as_bytes())?; Ok(()) } pub fn generate_password_hashlist(passhash_list: Vec<(String, String)>) -> std::io::Result<()> { let mut file = File::create("disk/passwords.toml")?; let mut file_cont = String::new(); for (user, hash) in passhash_list { let ret = format!("{}={}\n", user, hash); file_cont.push_str(&ret); } file.write_all(file_cont.as_bytes())?; Ok(()) }