From cb707c3ce431891e189a7ebd071cc8d7ead450e5 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 6 Oct 2024 13:02:16 +0200 Subject: [PATCH] Update edition and rustfmt. --- Cargo.toml | 1 + src/bin/installer_tui.rs | 225 +++++++++++++++----------- src/config/file.rs | 18 +-- src/config/general.rs | 2 +- src/config/package.rs | 2 +- src/disk_wrapper.rs | 36 ++--- src/lib.rs | 337 +++++++++++++++++++++++---------------- 7 files changed, 360 insertions(+), 261 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8f7f9c4b02..00f8749401 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ license = "MIT" authors = ["Jeremy Soller "] repository = "https://gitlab.redox-os.org/redox-os/installer" default-run = "redox_installer" +edition = "2018" [[bin]] name = "redox_installer" diff --git a/src/bin/installer_tui.rs b/src/bin/installer_tui.rs index 99efbad390..4976003867 100644 --- a/src/bin/installer_tui.rs +++ b/src/bin/installer_tui.rs @@ -1,5 +1,6 @@ extern crate arg_parser; -#[macro_use] extern crate failure; +#[macro_use] +extern crate failure; extern crate pkgar; extern crate pkgar_core; extern crate pkgar_keys; @@ -8,17 +9,17 @@ extern crate serde; extern crate termion; extern crate toml; -use pkgar::{PackageHead, ext::EntryExt}; +use pkgar::{ext::EntryExt, PackageHead}; use pkgar_core::PackageSrc; use pkgar_keys::PublicKeyFile; -use redox_installer::{Config, with_whole_disk, DiskOption}; +use redox_installer::{with_whole_disk, Config, DiskOption}; use std::{ ffi::OsStr, fs, io::{self, Read, Write}, - os::unix::fs::{MetadataExt, OpenOptionsExt, symlink}, + os::unix::fs::{symlink, MetadataExt, OpenOptionsExt}, path::Path, - process + process, }; use termion::input::TermRead; @@ -29,52 +30,54 @@ fn disk_paths(_paths: &mut Vec<(String, u64)>) {} fn disk_paths(paths: &mut Vec<(String, u64)>) { let mut schemes = Vec::new(); match fs::read_dir("/scheme") { - Ok(entries) => for entry_res in entries { - if let Ok(entry) = entry_res { - let path = entry.path(); - if let Ok(path_str) = path.into_os_string().into_string() { - let scheme = path_str.trim_start_matches(':').trim_matches('/'); - if scheme.starts_with("disk") { - if scheme == "disk/live" { - // Skip live disks - continue; - } + Ok(entries) => { + for entry_res in entries { + if let Ok(entry) = entry_res { + let path = entry.path(); + if let Ok(path_str) = path.into_os_string().into_string() { + let scheme = path_str.trim_start_matches(':').trim_matches('/'); + if scheme.starts_with("disk") { + if scheme == "disk/live" { + // Skip live disks + continue; + } - schemes.push(format!("{}:", scheme)); + schemes.push(format!("{}:", scheme)); + } } } } - }, + } Err(err) => { eprintln!("installer_tui: failed to list schemes: {}", err); } } for scheme in schemes { - let is_dir = fs::metadata(&scheme) - .map(|x| x.is_dir()) - .unwrap_or(false); + let is_dir = fs::metadata(&scheme).map(|x| x.is_dir()).unwrap_or(false); if is_dir { match fs::read_dir(&scheme) { - Ok(entries) => for entry_res in entries { - if let Ok(entry) = entry_res { - if let Ok(file_name) = entry.file_name().into_string() { - if file_name.contains('p') { - // Skip partitions - continue; - } + Ok(entries) => { + for entry_res in entries { + if let Ok(entry) = entry_res { + if let Ok(file_name) = entry.file_name().into_string() { + if file_name.contains('p') { + // Skip partitions + continue; + } - if let Ok(path) = entry.path().into_os_string().into_string() { - if let Ok(metadata) = entry.metadata() { - let size = metadata.len(); - if size > 0 { - paths.push((path, size)); + if let Ok(path) = entry.path().into_os_string().into_string() { + if let Ok(metadata) = entry.metadata() { + let size = metadata.len(); + if size > 0 { + paths.push((path, size)); + } } } } } } - }, + } Err(err) => { eprintln!("installer_tui: failed to list '{}': {}", scheme, err); } @@ -105,11 +108,15 @@ fn format_size(size: u64) -> String { fn copy_file(src: &Path, dest: &Path, buf: &mut [u8]) -> Result<(), failure::Error> { if let Some(parent) = dest.parent() { // Parent may be a symlink - if ! parent.is_symlink() { + if !parent.is_symlink() { match fs::create_dir_all(&parent) { Ok(()) => (), Err(err) => { - return Err(format_err!("failed to create directory {}: {}", parent.display(), err)); + return Err(format_err!( + "failed to create directory {}: {}", + parent.display(), + err + )); } } } @@ -118,36 +125,63 @@ fn copy_file(src: &Path, dest: &Path, buf: &mut [u8]) -> Result<(), failure::Err let metadata = match fs::symlink_metadata(&src) { Ok(ok) => ok, Err(err) => { - return Err(format_err!("failed to read metadata of {}: {}", src.display(), err)); - }, + return Err(format_err!( + "failed to read metadata of {}: {}", + src.display(), + err + )); + } }; if metadata.file_type().is_symlink() { let real_src = match fs::read_link(&src) { Ok(ok) => ok, Err(err) => { - return Err(format_err!("failed to read link {}: {}", src.display(), err)); + return Err(format_err!( + "failed to read link {}: {}", + src.display(), + err + )); } }; match symlink(&real_src, &dest) { Ok(()) => (), Err(err) => { - return Err(format_err!("failed to copy link {} ({}) to {}: {}", src.display(), real_src.display(), dest.display(), err)); - }, + return Err(format_err!( + "failed to copy link {} ({}) to {}: {}", + src.display(), + real_src.display(), + dest.display(), + err + )); + } } } else { let mut src_file = match fs::File::open(&src) { Ok(ok) => ok, Err(err) => { - return Err(format_err!("failed to open file {}: {}", src.display(), err)); + return Err(format_err!( + "failed to open file {}: {}", + src.display(), + err + )); } }; - let mut dest_file = match fs::OpenOptions::new().write(true).create_new(true).mode(metadata.mode()).open(&dest) { + let mut dest_file = match fs::OpenOptions::new() + .write(true) + .create_new(true) + .mode(metadata.mode()) + .open(&dest) + { Ok(ok) => ok, Err(err) => { - return Err(format_err!("failed to create file {}: {}", dest.display(), err)); + return Err(format_err!( + "failed to create file {}: {}", + dest.display(), + err + )); } }; @@ -155,7 +189,11 @@ fn copy_file(src: &Path, dest: &Path, buf: &mut [u8]) -> Result<(), failure::Err let count = match src_file.read(buf) { Ok(ok) => ok, Err(err) => { - return Err(format_err!("failed to read file {}: {}", src.display(), err)); + return Err(format_err!( + "failed to read file {}: {}", + src.display(), + err + )); } }; @@ -166,7 +204,11 @@ fn copy_file(src: &Path, dest: &Path, buf: &mut [u8]) -> Result<(), failure::Err match dest_file.write_all(&buf[..count]) { Ok(()) => (), Err(err) => { - return Err(format_err!("failed to write file {}: {}", dest.display(), err)); + return Err(format_err!( + "failed to write file {}: {}", + dest.display(), + err + )); } } } @@ -175,7 +217,11 @@ fn copy_file(src: &Path, dest: &Path, buf: &mut [u8]) -> Result<(), failure::Err Ok(()) } -fn package_files(root_path: &Path, config: &mut Config, files: &mut Vec) -> Result<(), pkgar::Error> { +fn package_files( + root_path: &Path, + config: &mut Config, + files: &mut Vec, +) -> Result<(), pkgar::Error> { //TODO: Remove packages from config where all files are located (and have valid shasum?) config.packages.clear(); @@ -189,18 +235,15 @@ fn package_files(root_path: &Path, config: &mut Config, files: &mut Vec) if pkg_path.extension() == Some(OsStr::new("pkgar_head")) { let mut pkg = PackageHead::new(&pkg_path, &root_path, &pkey)?; for entry in pkg.read_entries()? { - files.push( - entry - .check_path()? - .to_str().unwrap() - .to_string() - ); + files.push(entry.check_path()?.to_str().unwrap().to_string()); } files.push( pkg_path - .strip_prefix(root_path).unwrap() - .to_str().unwrap() - .to_string() + .strip_prefix(root_path) + .unwrap() + .to_str() + .unwrap() + .to_string(), ); } } @@ -227,7 +270,7 @@ fn choose_disk() -> String { Ok(0) => { eprintln!("installer_tui: failed to read line: end of input"); process::exit(1); - }, + } Ok(_) => (), Err(err) => { eprintln!("installer_tui: failed to read line: {}", err); @@ -242,7 +285,7 @@ fn choose_disk() -> String { } else { eprintln!("{} not from 1 to {}", i, paths.len()); } - }, + } Err(err) => { eprintln!("invalid input: {}", err); } @@ -262,7 +305,7 @@ fn choose_password() -> Option { eprintln!(); if password.is_empty() { - return None; + return None; } Some(password) @@ -311,53 +354,51 @@ fn main() { password_opt: password_opt.as_ref().map(|x| x.as_bytes()), efi_partition_size: None, }; - let res = with_whole_disk(&disk_path, &disk_option, |mount_path| -> Result<(), failure::Error> { - let mut config: Config = Config::from_file(&root_path.join("filesystem.toml"))?; + let res = with_whole_disk( + &disk_path, + &disk_option, + |mount_path| -> Result<(), failure::Error> { + let mut config: Config = Config::from_file(&root_path.join("filesystem.toml"))?; - // Copy filesystem.toml, which is not packaged - let mut files = vec![ - "filesystem.toml".to_string(), - ]; + // Copy filesystem.toml, which is not packaged + let mut files = vec!["filesystem.toml".to_string()]; - // Copy files from locally installed packages - if let Err(err) = package_files(&root_path, &mut config, &mut files) { - return Err(format_err!("failed to read package files: {}", err)); - } + // Copy files from locally installed packages + if let Err(err) = package_files(&root_path, &mut config, &mut files) { + return Err(format_err!("failed to read package files: {}", err)); + } - // Perform config install (after packages have been converted to files) - eprintln!("configuring system"); - let cookbook: Option<&'static str> = None; - redox_installer::install_dir(config, mount_path, cookbook).map_err(|err| { - io::Error::new( - io::ErrorKind::Other, - err - ) - })?; + // Perform config install (after packages have been converted to files) + eprintln!("configuring system"); + let cookbook: Option<&'static str> = None; + redox_installer::install_dir(config, mount_path, cookbook) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; - // Sort and remove duplicates - files.sort(); - files.dedup(); + // Sort and remove duplicates + files.sort(); + files.dedup(); - // Install files - let mut buf = vec![0; 4 * MIB as usize]; - for (i, name) in files.iter().enumerate() { - eprintln!("copy {} [{}/{}]", name, i, files.len()); + // Install files + let mut buf = vec![0; 4 * MIB as usize]; + for (i, name) in files.iter().enumerate() { + eprintln!("copy {} [{}/{}]", name, i, files.len()); - let src = root_path.join(name); - let dest = mount_path.join(name); - copy_file(&src, &dest, &mut buf)?; - } + let src = root_path.join(name); + let dest = mount_path.join(name); + copy_file(&src, &dest, &mut buf)?; + } - eprintln!("finished installing, unmounting filesystem"); + eprintln!("finished installing, unmounting filesystem"); - Ok(()) - }); + Ok(()) + }, + ); match res { Ok(()) => { eprintln!("installer_tui: installed successfully"); process::exit(0); - }, + } Err(err) => { eprintln!("installer_tui: failed to install: {}", err); process::exit(1); diff --git a/src/config/file.rs b/src/config/file.rs index 7672f908d5..d56758bcba 100644 --- a/src/config/file.rs +++ b/src/config/file.rs @@ -1,12 +1,11 @@ - -use Result; +use crate::Result; use libc::{gid_t, uid_t}; -use std::io::{Error, Write}; use std::ffi::{CString, OsStr}; use std::fs::{self, File}; +use std::io::{Error, Write}; use std::os::unix::ffi::OsStrExt; -use std::os::unix::fs::{PermissionsExt, symlink}; +use std::os::unix::fs::{symlink, PermissionsExt}; use std::path::Path; //type Result = std::result::Result; @@ -48,8 +47,7 @@ pub struct FileConfig { impl FileConfig { pub(crate) fn create>(&self, prefix: P) -> Result<()> { let path = self.path.trim_start_matches('/'); - let target_file = prefix.as_ref() - .join(path); + let target_file = prefix.as_ref().join(path); if self.directory { println!("Create directory {}", target_file.display()); @@ -76,11 +74,9 @@ impl FileConfig { fn apply_perms>(&self, target: P) -> Result<()> { let path = target.as_ref(); - let mode = self.mode.unwrap_or_else(|| if self.directory { - 0o0755 - } else { - 0o0644 - }); + let mode = self + .mode + .unwrap_or_else(|| if self.directory { 0o0755 } else { 0o0644 }); let uid = self.uid.unwrap_or(!0); let gid = self.gid.unwrap_or(!0); diff --git a/src/config/general.rs b/src/config/general.rs index 3e26d3772e..c50d48fadb 100644 --- a/src/config/general.rs +++ b/src/config/general.rs @@ -3,7 +3,7 @@ pub struct GeneralConfig { pub prompt: Option, // Allow config to specify cookbook recipe or binary package as default pub repo_binary: Option, - pub filesystem_size: Option, //MiB + pub filesystem_size: Option, //MiB pub efi_partition_size: Option, //MiB } diff --git a/src/config/package.rs b/src/config/package.rs index 5f37196fe5..bbbfdc57ce 100644 --- a/src/config/package.rs +++ b/src/config/package.rs @@ -7,7 +7,7 @@ pub enum PackageConfig { version: Option, git: Option, path: Option, - } + }, } impl Default for PackageConfig { diff --git a/src/disk_wrapper.rs b/src/disk_wrapper.rs index 5697e07a0c..dd5a70b826 100644 --- a/src/disk_wrapper.rs +++ b/src/disk_wrapper.rs @@ -21,10 +21,7 @@ enum Buffer<'a> { impl DiskWrapper { pub fn open>(path: P) -> Result { - let disk = OpenOptions::new() - .read(true) - .write(true) - .open(path)?; + let disk = OpenOptions::new().read(true).write(true).open(path)?; let metadata = disk.metadata()?; let size = metadata.len(); // TODO: get real block size: disk_metadata.blksize() works on disks but not image files @@ -71,24 +68,27 @@ impl DiskWrapper { let remaining = buf_len.checked_sub(i).unwrap(); let len = cmp::min( remaining, - self.block.len().checked_sub(offset.try_into().unwrap()).unwrap() + self.block + .len() + .checked_sub(offset.try_into().unwrap()) + .unwrap(), ); - self.disk.seek(SeekFrom::Start(block.checked_mul(block_len).unwrap()))?; + self.disk + .seek(SeekFrom::Start(block.checked_mul(block_len).unwrap()))?; self.disk.read_exact(&mut self.block)?; match buf { Buffer::Read(read) => { - read[i..i.checked_add(len).unwrap()].copy_from_slice( - &self.block[offset..offset.checked_add(len).unwrap()] - ); - }, + read[i..i.checked_add(len).unwrap()] + .copy_from_slice(&self.block[offset..offset.checked_add(len).unwrap()]); + } Buffer::Write(write) => { - self.block[offset..offset.checked_add(len).unwrap()].copy_from_slice( - &write[i..i.checked_add(len).unwrap()] - ); + self.block[offset..offset.checked_add(len).unwrap()] + .copy_from_slice(&write[i..i.checked_add(len).unwrap()]); - self.disk.seek(SeekFrom::Start(block.checked_mul(block_len).unwrap()))?; + self.disk + .seek(SeekFrom::Start(block.checked_mul(block_len).unwrap()))?; self.disk.write_all(&mut self.block)?; } } @@ -112,12 +112,8 @@ impl Seek for DiskWrapper { let current: i64 = self.seek.try_into().unwrap(); let end: i64 = self.size.try_into().unwrap(); self.seek = match pos { - SeekFrom::Start(offset) => { - cmp::min(self.size, offset) - }, - SeekFrom::End(offset) => { - cmp::max(0, cmp::min(end, end.wrapping_add(offset))) as u64 - }, + SeekFrom::Start(offset) => cmp::min(self.size, offset), + SeekFrom::End(offset) => cmp::max(0, cmp::min(end, end.wrapping_add(offset))) as u64, SeekFrom::Current(offset) => { cmp::max(0, cmp::min(end, current.wrapping_add(offset))) as u64 } diff --git a/src/lib.rs b/src/lib.rs index 86f730405c..161c750431 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,27 +14,26 @@ extern crate termion; mod config; mod disk_wrapper; -pub use config::Config; -pub use config::file::FileConfig; -pub use config::package::PackageConfig; -use disk_wrapper::DiskWrapper; +pub use crate::config::file::FileConfig; +pub use crate::config::package::PackageConfig; +pub use crate::config::Config; +use crate::disk_wrapper::DiskWrapper; -use failure::{Error, err_msg}; -use rand::{RngCore, rngs::OsRng}; +use failure::{err_msg, Error}; +use pkgutils::{Package, Repo}; +use rand::{rngs::OsRng, RngCore}; use redoxfs::{unmount_path, Disk, DiskIo, FileSystem}; use termion::input::TermRead; -use pkgutils::{Repo, Package}; use std::{ collections::BTreeMap, - env, - fs, + env, fs, io::{self, Seek, SeekFrom, Write}, path::Path, process, sync::mpsc::channel, - time::{SystemTime, UNIX_EPOCH}, thread, + time::{SystemTime, UNIX_EPOCH}, }; pub(crate) type Result = std::result::Result; @@ -50,10 +49,7 @@ const REMOTE: &'static str = "https://static.redox-os.org/pkg"; fn get_target() -> String { env::var("TARGET").unwrap_or( - option_env!("TARGET").map_or( - "x86_64-unknown-redox".to_string(), - |x| x.to_string() - ) + option_env!("TARGET").map_or("x86_64-unknown-redox".to_string(), |x| x.to_string()), ) } @@ -104,37 +100,54 @@ fn install_packages>(config: &Config, dest: &str, cookbook: Option if let Some(cookbook) = cookbook { let dest_pkg = format!("{}/pkg", dest); - if ! Path::new(&dest_pkg).exists() { + if !Path::new(&dest_pkg).exists() { fs::create_dir(&dest_pkg).unwrap(); } for (packagename, package) in &config.packages { - let pkgar_path = format!("{}/{}/repo/{}/{}.pkgar", - env::current_dir().unwrap().to_string_lossy(), - cookbook.as_ref(), target, packagename); + let pkgar_path = format!( + "{}/{}/repo/{}/{}.pkgar", + env::current_dir().unwrap().to_string_lossy(), + cookbook.as_ref(), + target, + packagename + ); let from_remote = match (config.general.repo_binary, package) { (Some(true), PackageConfig::Empty) => true, - (Some(true), PackageConfig::Spec { version: None, git: None, path: None }) => true, + ( + Some(true), + PackageConfig::Spec { + version: None, + git: None, + path: None, + }, + ) => true, (_, PackageConfig::Build(rule)) if rule == "binary" => true, - _ => false + _ => false, }; if from_remote { println!("Installing package from remote: {}", packagename); repo.fetch(&packagename).unwrap().install(dest).unwrap(); } else if Path::new(&pkgar_path).exists() { println!("Installing package from local repo: {}", packagename); - let public_path = format!("{}/{}/build/id_ed25519.pub.toml", - env::current_dir().unwrap().to_string_lossy(), - cookbook.as_ref()); + let public_path = format!( + "{}/{}/build/id_ed25519.pub.toml", + env::current_dir().unwrap().to_string_lossy(), + cookbook.as_ref() + ); pkgar::extract(&public_path, &pkgar_path, dest).unwrap(); let head_path = format!("{}/{}.pkgar_head", dest_pkg, packagename); pkgar::split(&public_path, &pkgar_path, &head_path, Option::<&str>::None).unwrap(); } else { println!("Installing package tar.gz from local repo: {}", packagename); - let path = format!("{}/{}/repo/{}/{}.tar.gz", - env::current_dir().unwrap().to_string_lossy(), - cookbook.as_ref(), target, packagename); + let path = format!( + "{}/{}/repo/{}/{}.tar.gz", + env::current_dir().unwrap().to_string_lossy(), + cookbook.as_ref(), + target, + packagename + ); Package::from_path(&path).unwrap().install(dest).unwrap(); } } @@ -146,26 +159,32 @@ fn install_packages>(config: &Config, dest: &str, cookbook: Option } } -pub fn install_dir, S: AsRef>(config: Config, output_dir: P, cookbook: Option) -> Result<()> { +pub fn install_dir, S: AsRef>( + config: Config, + output_dir: P, + cookbook: Option, +) -> Result<()> { //let mut context = liner::Context::new(); macro_rules! prompt { - ($dst:expr, $def:expr, $($arg:tt)*) => (if config.general.prompt.unwrap_or(true) { - Err(io::Error::new( - io::ErrorKind::Other, - "prompt not currently supported" - )) - // match unwrap_or_prompt($dst, &mut context, &format!($($arg)*)) { - // Ok(res) => if res.is_empty() { - // Ok($def) - // } else { - // Ok(res) - // }, - // Err(err) => Err(err) - // } - } else { - Ok($dst.unwrap_or($def)) - }) + ($dst:expr, $def:expr, $($arg:tt)*) => { + if config.general.prompt.unwrap_or(true) { + Err(io::Error::new( + io::ErrorKind::Other, + "prompt not currently supported", + )) + // match unwrap_or_prompt($dst, &mut context, &format!($($arg)*)) { + // Ok(res) => if res.is_empty() { + // Ok($def) + // } else { + // Ok(res) + // }, + // Err(err) => Err(err) + // } + } else { + Ok($dst.unwrap_or($def)) + } + }; } let output_dir = output_dir.as_ref(); @@ -192,7 +211,8 @@ pub fn install_dir, S: AsRef>(config: Config, output_dir: P, } else if config.general.prompt.unwrap_or(true) { prompt_password( &format!("{}: enter password: ", username), - &format!("{}: confirm password: ", username))? + &format!("{}: confirm password: ", username), + )? } else { String::new() }; @@ -209,9 +229,26 @@ pub fn install_dir, S: AsRef>(config: Config, output_dir: P, next_gid = gid + 1; } - let name = prompt!(user.name, username.clone(), "{}: name (GECOS) [{}]: ", username, username)?; - let home = prompt!(user.home, format!("/home/{}", username), "{}: home [/home/{}]: ", username, username)?; - let shell = prompt!(user.shell, "/bin/ion".to_string(), "{}: shell [/bin/ion]: ", username)?; + let name = prompt!( + user.name, + username.clone(), + "{}: name (GECOS) [{}]: ", + username, + username + )?; + let home = prompt!( + user.home, + format!("/home/{}", username), + "{}: home [/home/{}]: ", + username, + username + )?; + let shell = prompt!( + user.shell, + "/bin/ion".to_string(), + "{}: shell [/bin/ion]: ", + username + )?; println!("Adding user {}:", username); println!("\tPassword: {}", password); @@ -230,7 +267,8 @@ pub fn install_dir, S: AsRef>(config: Config, output_dir: P, uid: Some(uid), gid: Some(gid), recursive_chown: true, - }.create(&output_dir)?; + } + .create(&output_dir)?; if uid >= 1000 { // Create XDG user dirs @@ -259,7 +297,8 @@ pub fn install_dir, S: AsRef>(config: Config, output_dir: P, uid: Some(uid), gid: Some(gid), recursive_chown: false, - }.create(&output_dir)?; + } + .create(&output_dir)?; } FileConfig { path: format!("{}/.config/user-dirs.dirs", home), @@ -272,19 +311,24 @@ XDG_PICTURES_DIR="$HOME/Pictures" XDG_PUBLICSHARE_DIR="$HOME/Public" XDG_TEMPLATES_DIR="$HOME/Templates" XDG_VIDEOS_DIR="$HOME/Videos" -"#.to_string(), +"# + .to_string(), symlink: false, directory: false, mode: Some(0o0600), uid: Some(uid), gid: Some(gid), recursive_chown: false, - }.create(&output_dir)?; + } + .create(&output_dir)?; } let password = hash_password(&password)?; - passwd.push_str(&format!("{};{};{};{};{};{}\n", username, uid, gid, name, home, shell)); + passwd.push_str(&format!( + "{};{};{};{};{};{}\n", + username, uid, gid, name, home, shell + )); shadow.push_str(&format!("{};{}\n", username, password)); groups.push((username.clone(), gid, vec![username])); } @@ -312,7 +356,8 @@ XDG_VIDEOS_DIR="$HOME/Videos" uid: None, gid: None, recursive_chown: false, - }.create(&output_dir)?; + } + .create(&output_dir)?; } if !shadow.is_empty() { @@ -325,7 +370,8 @@ XDG_VIDEOS_DIR="$HOME/Videos" uid: Some(0), gid: Some(0), recursive_chown: false, - }.create(&output_dir)?; + } + .create(&output_dir)?; } if !groups.is_empty() { @@ -350,16 +396,17 @@ XDG_VIDEOS_DIR="$HOME/Videos" uid: None, gid: None, recursive_chown: false, - }.create(&output_dir)?; + } + .create(&output_dir)?; } Ok(()) } -pub fn with_redoxfs(disk: D, password_opt: Option<&[u8]>, callback: F) - -> Result where - D: Disk + Send + 'static, - F: FnOnce(&Path) -> Result +pub fn with_redoxfs(disk: D, password_opt: Option<&[u8]>, callback: F) -> Result +where + D: Disk + Send + 'static, + F: FnOnce(&Path) -> Result, { let mount_path = if cfg!(target_os = "redox") { format!("file.redox_installer_{}", process::id()) @@ -368,35 +415,27 @@ pub fn with_redoxfs(disk: D, password_opt: Option<&[u8]>, callback: F) }; if cfg!(not(target_os = "redox")) { - if ! Path::new(&mount_path).exists() { + if !Path::new(&mount_path).exists() { fs::create_dir(&mount_path)?; } } let ctime = SystemTime::now().duration_since(UNIX_EPOCH)?; - let fs = FileSystem::create( - disk, - password_opt, - ctime.as_secs(), - ctime.subsec_nanos() - ).map_err(syscall_error)?; + let fs = FileSystem::create(disk, password_opt, ctime.as_secs(), ctime.subsec_nanos()) + .map_err(syscall_error)?; let (tx, rx) = channel(); let join_handle = { let mount_path = mount_path.clone(); thread::spawn(move || { - let res = redoxfs::mount( - fs, - &mount_path, - |real_path| { - tx.send(Ok(real_path.to_owned())).unwrap(); - } - ); + let res = redoxfs::mount(fs, &mount_path, |real_path| { + tx.send(Ok(real_path.to_owned())).unwrap(); + }); match res { Ok(()) => (), Err(err) => { tx.send(Err(err)).unwrap(); - }, + } }; }) }; @@ -406,10 +445,13 @@ pub fn with_redoxfs(disk: D, password_opt: Option<&[u8]>, callback: F) Ok(real_path) => callback(&real_path), Err(err) => return Err(err.into()), }, - Err(_) => return Err(io::Error::new( - io::ErrorKind::NotConnected, - "redoxfs thread did not send a result" - ).into()), + Err(_) => { + return Err(io::Error::new( + io::ErrorKind::NotConnected, + "redoxfs thread did not send a result", + ) + .into()) + } }; unmount_path(&mount_path)?; @@ -423,7 +465,11 @@ pub fn with_redoxfs(disk: D, password_opt: Option<&[u8]>, callback: F) res } -pub fn fetch_bootloaders>(config: &Config, cookbook: Option, live: bool) -> Result<(Vec, Vec)> { +pub fn fetch_bootloaders>( + config: &Config, + cookbook: Option, + live: bool, +) -> Result<(Vec, Vec)> { let bootloader_dir = format!("/tmp/redox_installer_bootloader_{}", process::id()); if Path::new(&bootloader_dir).exists() { @@ -434,7 +480,9 @@ pub fn fetch_bootloaders>(config: &Config, cookbook: Option, li let mut bootloader_config = Config::default(); bootloader_config.general = config.general.clone(); - bootloader_config.packages.insert("bootloader".to_string(), PackageConfig::default()); + bootloader_config + .packages + .insert("bootloader".to_string(), PackageConfig::default()); install_packages(&bootloader_config, &bootloader_dir, cookbook.as_ref()); let boot_dir = Path::new(&bootloader_dir).join("boot"); @@ -466,10 +514,10 @@ pub fn fetch_bootloaders>(config: &Config, cookbook: Option, li } //TODO: make bootloaders use Option, dynamically create BIOS and EFI partitions -pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback: F) - -> Result where - P: AsRef, - F: FnOnce(&Path) -> Result +pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback: F) -> Result +where + P: AsRef, + F: FnOnce(&Path) -> Result, { let target = get_target(); @@ -495,7 +543,6 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback } }; - // Calculate partition offsets let gpt_reserved = 34 * 512; // GPT always reserves 34 512-byte sectors let mibi = 1024 * 1024; @@ -506,7 +553,11 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback // Second megabyte of the disk is reserved for EFI partition let efi_start = bios_end + 1; - let efi_size = if let Some(size) = disk_option.efi_partition_size { size as u64 } else { 1 }; + let efi_size = if let Some(size) = disk_option.efi_partition_size { + size as u64 + } else { + 1 + }; let efi_end = efi_start + (efi_size * mibi / block_size) - 1; // The rest of the disk is RedoxFS, reserving the GPT table mirror at the end of disk @@ -516,7 +567,10 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback // Format and install BIOS partition { // Write BIOS bootloader to disk - eprintln!("Write bootloader with size {:#x}", disk_option.bootloader_bios.len()); + eprintln!( + "Write bootloader with size {:#x}", + disk_option.bootloader_bios.len() + ); disk_file.seek(SeekFrom::Start(0))?; disk_file.write_all(&disk_option.bootloader_bios)?; @@ -536,37 +590,46 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback // Add BIOS boot partition let mut partitions = BTreeMap::new(); let mut partition_id = 1; - partitions.insert(partition_id, gpt::partition::Partition { - part_type_guid: gpt::partition_types::BIOS, - part_guid: uuid::Uuid::new_v4(), - first_lba: bios_start, - last_lba: bios_end, - flags: 0, // TODO - name: "BIOS".to_string(), - }); + partitions.insert( + partition_id, + gpt::partition::Partition { + part_type_guid: gpt::partition_types::BIOS, + part_guid: uuid::Uuid::new_v4(), + first_lba: bios_start, + last_lba: bios_end, + flags: 0, // TODO + name: "BIOS".to_string(), + }, + ); partition_id += 1; // Add EFI boot partition - partitions.insert(partition_id, gpt::partition::Partition { - part_type_guid: gpt::partition_types::EFI, - part_guid: uuid::Uuid::new_v4(), - first_lba: efi_start, - last_lba: efi_end, - flags: 0, // TODO - name: "EFI".to_string(), - }); + partitions.insert( + partition_id, + gpt::partition::Partition { + part_type_guid: gpt::partition_types::EFI, + part_guid: uuid::Uuid::new_v4(), + first_lba: efi_start, + last_lba: efi_end, + flags: 0, // TODO + name: "EFI".to_string(), + }, + ); partition_id += 1; // Add RedoxFS partition - partitions.insert(partition_id, gpt::partition::Partition { - //TODO: Use REDOX_REDOXFS type (needs GPT crate changes) - part_type_guid: gpt::partition_types::LINUX_FS, - part_guid: uuid::Uuid::new_v4(), - first_lba: redoxfs_start, - last_lba: redoxfs_end, - flags: 0, - name: "REDOX".to_string(), - }); + partitions.insert( + partition_id, + gpt::partition::Partition { + //TODO: Use REDOX_REDOXFS type (needs GPT crate changes) + part_type_guid: gpt::partition_types::LINUX_FS, + part_guid: uuid::Uuid::new_v4(), + first_lba: redoxfs_start, + last_lba: redoxfs_end, + flags: 0, + name: "REDOX".to_string(), + }, + ); eprintln!("Writing GPT tables: {:#?}", partitions); @@ -581,13 +644,13 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback { let disk_efi_start = efi_start * block_size; let disk_efi_end = (efi_end + 1) * block_size; - let mut disk_efi = fscommon::StreamSlice::new( - &mut disk_file, - disk_efi_start, - disk_efi_end, - )?; + let mut disk_efi = + fscommon::StreamSlice::new(&mut disk_file, disk_efi_start, disk_efi_end)?; - eprintln!("Formatting EFI partition with size {:#x}", disk_efi_end - disk_efi_start); + eprintln!( + "Formatting EFI partition with size {:#x}", + disk_efi_end - disk_efi_start + ); fatfs::format_volume(&mut disk_efi, fatfs::FormatVolumeOptions::new())?; eprintln!("Opening EFI partition"); @@ -601,7 +664,11 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback let efi_dir = root_dir.open_dir("EFI")?; efi_dir.create_dir("BOOT")?; - eprintln!("Writing EFI/BOOT/{} file with size {:#x}", bootloader_efi_name, disk_option.bootloader_efi.len()); + eprintln!( + "Writing EFI/BOOT/{} file with size {:#x}", + bootloader_efi_name, + disk_option.bootloader_efi.len() + ); let boot_dir = efi_dir.open_dir("BOOT")?; let mut file = boot_dir.create_file(bootloader_efi_name)?; file.truncate()?; @@ -609,40 +676,38 @@ pub fn with_whole_disk(disk_path: P, disk_option: &DiskOption, callback } // Format and install RedoxFS partition - eprintln!("Installing to RedoxFS partition with size {:#x}", (redoxfs_end - redoxfs_start) * block_size); + eprintln!( + "Installing to RedoxFS partition with size {:#x}", + (redoxfs_end - redoxfs_start) * block_size + ); let disk_redoxfs = DiskIo(fscommon::StreamSlice::new( disk_file, redoxfs_start * block_size, - (redoxfs_end + 1) * block_size + (redoxfs_end + 1) * block_size, )?); - with_redoxfs( - disk_redoxfs, - disk_option.password_opt, - callback - ) + with_redoxfs(disk_redoxfs, disk_option.password_opt, callback) } -pub fn install(config: Config, output: P, cookbook: Option, live: bool) - -> Result<()> where - P: AsRef, - S: AsRef, +pub fn install(config: Config, output: P, cookbook: Option, live: bool) -> Result<()> +where + P: AsRef, + S: AsRef, { println!("Install {:#?} to {}", config, output.as_ref().display()); if output.as_ref().is_dir() { install_dir(config, output, cookbook) } else { - let (bootloader_bios, bootloader_efi) = fetch_bootloaders(&config, cookbook.as_ref(), live)?; + let (bootloader_bios, bootloader_efi) = + fetch_bootloaders(&config, cookbook.as_ref(), live)?; let disk_option = DiskOption { bootloader_bios: &bootloader_bios, bootloader_efi: &bootloader_efi, password_opt: None, efi_partition_size: config.general.efi_partition_size, }; - with_whole_disk(output, &disk_option, - move |mount_path| { - install_dir(config, mount_path, cookbook) - } - ) + with_whole_disk(output, &disk_option, move |mount_path| { + install_dir(config, mount_path, cookbook) + }) } }