diff --git a/Cargo.toml b/Cargo.toml index 12a9c27e66..7e1e2ca24b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ liner = "0.1" rand = "0.3" serde = "0.8" serde_derive = "0.8" +tar = { git = "https://github.com/redox-os/tar-rs.git" } termion = "1.1" toml = { version = "0.2", default-features = false, features = ["serde"] } userutils = { git = "https://github.com/redox-os/userutils.git" } diff --git a/config/default.toml b/config/default.toml index 48b87a5362..36eac78273 100644 --- a/config/default.toml +++ b/config/default.toml @@ -8,13 +8,16 @@ prompt = false # Package settings [packages] acid = {} +binutils = {} coreutils = {} extrautils = {} games = {} ion = {} netutils = {} -pkgutils = {} +orbdata = {} +orbital = {} orbutils = {} +pkgutils = {} smith = {} userutils = {} diff --git a/config/example.toml b/config/example.toml index 007bad0c12..05babbf2d0 100644 --- a/config/example.toml +++ b/config/example.toml @@ -7,7 +7,19 @@ prompt = true # Package settings [packages] +acid = {} +binutils = {} +coreutils = {} +extrautils = {} +games = {} +ion = {} +netutils = {} +orbdata = {} +orbital = {} orbutils = {} +pkgutils = {} +smith = {} +userutils = {} # User settings [users.root] diff --git a/config/minimal.toml b/config/minimal.toml new file mode 100644 index 0000000000..dba20f5d48 --- /dev/null +++ b/config/minimal.toml @@ -0,0 +1,25 @@ +# This is the default configuration file + +# General settings +[general] +# Do not prompt if settings are not defined +prompt = false + +# Package settings +[packages] +binutils = {} +coreutils = {} +extrautils = {} +ion = {} +netutils = {} +pkgutils = {} +userutils = {} + +# User settings +[users.root] +# Password is set to "password" +password = "$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk" +uid = 0 +gid = 0 +name = "root" +home = "/root" diff --git a/src/config/mod.rs b/src/config/mod.rs index 8418384aed..5465d4f9f8 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -8,7 +8,7 @@ mod user; #[derive(Debug, Default, Deserialize)] pub struct Config { pub general: general::GeneralConfig, - pub files: Vec, pub packages: BTreeMap, + pub files: Vec, pub users: BTreeMap, } diff --git a/src/install/mod.rs b/src/install/mod.rs index d0af357c5a..0307d08610 100644 --- a/src/install/mod.rs +++ b/src/install/mod.rs @@ -1,13 +1,17 @@ extern crate liner; extern crate rand; +extern crate tar; extern crate termion; extern crate userutils; use self::rand::Rng; +use self::tar::{Archive, EntryType}; use self::termion::input::TermRead; use std::{env, fs}; -use std::io::{self, Write}; +use std::io::{self, Read, Write}; +use std::os::unix::fs::OpenOptionsExt; +use std::path::{Path, PathBuf}; use std::str::FromStr; use config::Config; @@ -58,6 +62,45 @@ fn prompt_password(prompt: &str, confirm_prompt: &str) -> Result } } +fn extract_inner(ar: &mut Archive, root: &Path) -> io::Result<()> { + for entry_result in try!(ar.entries()) { + let mut entry = try!(entry_result); + match entry.header().entry_type() { + EntryType::Regular => { + let mut file = { + let mut path = root.to_path_buf(); + path.push(try!(entry.path())); + println!("Extract file {}", path.display()); + if let Some(parent) = path.parent() { + try!(fs::create_dir_all(parent)); + } + try!( + fs::OpenOptions::new() + .read(true) + .write(true) + .truncate(true) + .create(true) + .mode(entry.header().mode().unwrap_or(644)) + .open(path) + ) + }; + try!(io::copy(&mut entry, &mut file)); + }, + EntryType::Directory => { + let mut path = root.to_path_buf(); + path.push(try!(entry.path())); + println!("Extract directory {}", path.display()); + try!(fs::create_dir_all(path)); + }, + other => { + panic!("Unsupported entry type {:?}", other); + } + } + } + + Ok(()) +} + pub fn install(config: Config) -> Result<(), String> { println!("Install {:#?}", config); @@ -90,7 +133,7 @@ pub fn install(config: Config) -> Result<(), String> { let mut path = sysroot.clone(); path.push($path); println!("Create directory {}", path.display()); - fs::create_dir(&path).map_err(|err| format!("failed to create {}: {}", path.display(), err))?; + fs::create_dir_all(&path).map_err(|err| format!("failed to create {}: {}", path.display(), err))?; }}; } @@ -104,10 +147,20 @@ pub fn install(config: Config) -> Result<(), String> { }}; } + macro_rules! pkg { + ($path:expr) => {{ + let path = PathBuf::from($path); + println!("Extract package {}", path.display()); + let file = fs::File::open(&path).map_err(|err| format!("failed to open {}: {}", path.display(), err))?; + extract_inner(&mut Archive::new(file), &sysroot).map_err(|err| format!("failed to extract {}: {}", path.display(), err))?; + }}; + } + dir!(""); - dir!("bin"); - dir!("etc"); - dir!("home"); + + for (packagename, _package) in config.packages { + pkg!(&format!("../cookbook/repo/x86_64-unknown-redox/{}.tar", packagename)); + } for file in config.files { file!(file.path.trim_matches('/'), file.data.as_bytes());