use toml::{Value}; use std::{fs, env}; use std::io::Write; use std::process::Command; pub fn help() { println!("Usage: -h, help: Show this help message -v, version: Show version -i, init: Initialize the database -c, create-script: create the scripts for the warnings -w , warning : Show the warning for specified package manager "); } pub fn create_database() { let file = "/usr/share/pkg_warner/pkg_mngrs.db".to_string(); if !std::path::Path::new(&"/usr/share/pkg_warner/").is_dir() { let _cdar = fs::create_dir_all("/usr/share/pkg_warner/".to_string()); match _cdar { Ok(_) => { println!("Created path for database (previously missing)"); } Err(_) => { println!("Couldn't create path for database (/usr/share/pkg_warner)") } } } let connection = sqlite::open(file).unwrap(); let result = connection .execute( " CREATE TABLE pkg_mngrs (mngr TEXT, distro TEXT, UNIQUE (mngr)); ", ); match result { Ok(_) => { println!("Created database"); } Err(_) => { println!("Couldn't create database"); } } } pub fn add_mngrs(pkg_managers: Vec>, proper_manager: String) { let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db".to_string()).unwrap(); let result = connection.execute(format!( "INSERT INTO pkg_mngrs (mngr,distro) VALUES (\"{}\",\"{}\")", "proper_manager", proper_manager)); match result { Ok(_) => { println!("Added {} to database", proper_manager); } Err(_) => { println!("Couldn't add {} to database, maybe it already exists?", proper_manager); } } for entry in pkg_managers { println!("Don't use {}! {} is used on {}, here you use {}!", entry[0], entry[0], entry[1], proper_manager); let result = connection.execute(format!( " INSERT INTO pkg_mngrs (mngr, distro) VALUES (\"{}\", \"{}\"); ", entry[0], entry[1] )); match result { Ok(_) => { println!("Added {} to database", entry[0]); } Err(_) => { println!("Couldn't add {} to database, maybe it already exists?", entry[0]); } } } } pub fn create_script() { let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db").unwrap(); let path = std::path::Path::new("/usr/share/pkg_warner/backs/"); let result = connection.iterate( format!("SELECT mngr FROM pkg_mngrs WHERE mngr IS NOT \"proper_manager\";"), |pairs| { for &(_column, value) in pairs.iter() { if std::path::Path::new(&format!("/usr/bin/{}", value.unwrap())).exists() { if !path.is_dir() { let result = std::fs::create_dir_all("/usr/share/pkg_warner/backs/".to_string()); match result { Ok(_) => { println!("Created path for binary backups (previously missing)"); } Err(_) => { println!("Couldn't create path for binary backups (/usr/share/pkg_warner/backs)") } } } let result = std::fs::copy(&format!("/usr/bin/{}", value.unwrap()), &format!("/usr/share/pkg_warner/backs/{}", value.unwrap())); match result { Ok(_) => { } Err(_) => { println!("Couldn't back up {}", value.unwrap()); } } } writeln!(&mut fs::File::create(format!("/usr/bin/{}",value.unwrap())).unwrap(), "#!/usr/bin/env bash\n pkg-warner -w {}", value.unwrap()).unwrap(); Command::new("chmod") .arg("+x") .arg(format!("/usr/bin/{}", value.unwrap())) .status() .expect("Failed to chmod script"); } true }, ); match result { Ok(_) => {} Err(_) => println!("Couldn't get value from database"), } } pub fn dump_database() -> Vec { let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db").unwrap(); let mut dump = Vec::new(); let result = connection.iterate( format!("SELECT mngr FROM pkg_mngrs WHERE mngr IS NOT \"proper_manager\";"), |pairs| { for &(_column, value) in pairs.iter() { dump.push(value.unwrap().to_string()); } true }, ); match result { Ok(_) => {} Err(_) => println!("Couldn't get value from database"), } return dump; } pub fn rem_mngr(mngrs_to_remove: Vec) { let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db").unwrap(); for mngr in mngrs_to_remove { let result = fs::remove_file(format!("/usr/bin/{}", mngr)); match result { Ok(_) => { println!("Removed {}", mngr); } Err(_) => { println!("Couldn't remove {}", mngr); } } let result = connection.execute(format!( "DELETE FROM pkg_mngrs WHERE mngr = \"{}\"", mngr)); match result { Ok(_) => { println!("Removed {} from database", mngr); } Err(_) => { println!("Couldn't remove {} from database", mngr); } } } } pub fn warn(proper_manager: String, package_manager: String) { let connection = sqlite::open("/usr/share/pkg_warner/pkg_mngrs.db".to_string()).unwrap(); let mut warned = false; let result = connection.iterate( format!("SELECT distro FROM pkg_mngrs WHERE mngr = \"{}\";", package_manager), |pairs| { for &(_column, value) in pairs.iter() { if !warned { println!("{} is used on {}! Please use {} instead!", package_manager, value.unwrap(), proper_manager); warned = true; } } true }, ); match result { Ok(_) => {} Err(_) => println!("Couldn't get value from database"), } } pub fn res_bin() { for file in fs::read_dir("/usr/share/pkg_warner/backs/").unwrap() { let path = file.unwrap().path().display().to_string(); let result = std::fs::copy(&format!("{}", path), format!("/usr/bin/{}", path.to_string().replace("/usr/share/pkg_warner/backs/", ""))); match result { Ok(_) => { println!("Restored {}", path); } Err(_) => { println!("Couldn't restore {}", path); } } } } fn main() { let args: Vec = env::args().skip(1).collect(); if args.is_empty() { help(); return; } let oper = &args[0]; if !nix::unistd::Uid::effective().is_root() && oper != "-w" { println!("You need to be root to run this program"); return; } let file = "/usr/share/pkg_warner/pkg_mngrs.db".to_string(); if !std::path::Path::new(&file).exists() { create_database(); } let file = format!("/etc/package_managers.toml"); let database = fs::read_to_string(file).expect("Unable to read file"); let db_parsed = database.parse::().expect("Unable to parse database"); let mut pkg_managers: Vec> = Vec::new(); let proper_manager = db_parsed["proper_manager"].as_str().unwrap().to_string(); for entry in db_parsed.as_table() { for (key, value) in &*entry { let mut tempvec = Vec::new(); tempvec.push(key.to_string()); tempvec.push(value.to_string().replace("distro = ", "").replace("\n","").replace("\"","")); if !tempvec.contains(&proper_manager) { pkg_managers.push(tempvec); } } } let dat_mgrs = dump_database(); let mut pkgs_to_remove: Vec = Vec::new(); for i in dat_mgrs { let mut in_conf = false; for managers in &pkg_managers { if managers.contains(&&i) { in_conf = true; } } if !in_conf { pkgs_to_remove.push(i); } } match oper.as_str() { "-i" | "init" => { create_database(); add_mngrs(pkg_managers, proper_manager); create_script(); } "-a" | "add" => { add_mngrs(pkg_managers, proper_manager); } "-c" | "create-script" => { create_script(); } "-w" | "warning" => { warn(proper_manager, args[1].to_string()); } "-r" | "remove" => { if !pkgs_to_remove.is_empty() { println!("Removing {} from database", pkgs_to_remove.join(", ")); rem_mngr(pkgs_to_remove); } } "-res" | "restore" => { res_bin(); } _ => { help(); } } }