use std::fs::File; use std::path::Path; use std::result::Result; use std::process::Command; use reqwest::Client; use reqwest::header::ETAG; fn err_and_exit(msg: String, code: i32) { println!("ERROR!: {}", msg); std::process::exit(code); } fn main() -> Result<(), std::io::Error> { let client = Client::new(); let args: Vec<_> = std::env::args().collect(); if args.len() < 2 { println!("[PACK]: Please enter a package name..."); std::process::exit(1); } let split = args[1].as_str().split("::"); let vec: Vec<&str> = split.collect(); if vec.len() < 2 { err_and_exit("Please enter a repo to download from!".to_string(), 0); } println!("[PACK]: Downloading {}", vec[0]); if !Path::new(format!("/usr/pack/repo/{}", vec[1]).as_str()).exists() { err_and_exit(format!("Path /usr/pack/repo/{} does not exist. Please setup your environment.", vec[1]), 1); } let full_path: Vec<&str> = vec[0].split("/").collect(); let pkgname = full_path[full_path.len() - 1]; let repo = match vec[1] { "arch_core" => "http://mirrors.advancedhosters.com/archlinux/core/os/x86_64/", "arch_extra" => "http://mirrors.advancedhosters.com/archlinux/extra/os/x86_64/", _ => { println!("ERROR!: Repo {} is not supported...", vec[1]); std::process::exit(0); }, }; print!("[PACK]: Making request..."); let url = reqwest::Url::parse(&(repo.to_string() + pkgname)).expect("Failed to parse URL"); let mut resp = match client.get(url).send() { Ok(a) => a, Err(e) => { println!("ERROR!: Couldn't get package from url. Are you connected to the internet?\n\n{}", e); std::process::exit(0); }, }; if resp.status().is_success() { println!("OK"); if let Some(etag) = resp.headers().get(ETAG) { std::fs::write("etag", etag.as_bytes()).expect("Failed to write ETAG..."); } let mut file = match File::create(format!("/usr/pack/repo/{}/tarballs/{}", vec[1], pkgname)) { Ok(res) => res, Err(e) => { println!("Failed to create file...did you setup you environment? Do you have permission to create files?\n\n{}", e); std::process::exit(0); }, }; resp.copy_to(&mut file).expect("failed to write file"); } else { println!("FAIL!"); std::process::exit(1); } let spltdirname: Vec<&str> = pkgname.split(".").collect(); let dirname = spltdirname[0]; print!("[PACK]: Creating package dir..."); std::fs::create_dir(format!("/usr/pack/repo/{}/{}", vec[1], dirname)).expect("Failed to create directory"); println!("OK"); print!("[PACK]: Executing tar..."); Command::new("tar") .arg(format!("-C/usr/pack/repo/{}/{}", vec[1], dirname)) .arg("-xf") .arg(format!("/usr/pack/repo/{}/tarballs/{}", vec[1], pkgname)) .output() .expect("Failed to execute tar"); println!("OK"); let paths = std::fs::read_dir(format!("/usr/pack/repo/{}/{}/usr/bin/", vec[1], dirname)).expect("Failed to read dir..."); println!("[PACK]: Creating symlinks"); for file in paths { let pth = &file.expect("Failed to read file").path(); let strpth = pth.to_str().expect("Failed to convert to str..."); println!("\tAdding file {} to /usr/pack/bin/", strpth); let a: Vec<&str> = strpth.split("/").collect(); let name = a[a.len() - 1]; std::os::unix::fs::symlink(pth, format!("/usr/pack/bin/{}", name)).expect("Failed to symlink..."); } Ok(()) }