moros/src/usr/install.rs

148 lines
5.7 KiB
Rust

use crate::{api, sys, usr};
use crate::api::console::Style;
use crate::api::fs;
use crate::api::fs::DeviceType;
use crate::api::io;
use crate::api::syscall;
use alloc::string::String;
pub fn copy_files(verbose: bool) {
create_dir("/bin", verbose); // Binaries
create_dir("/dev", verbose); // Devices
create_dir("/ini", verbose); // Initializers
create_dir("/lib", verbose); // Libraries
create_dir("/net", verbose); // Network
create_dir("/src", verbose); // Sources
create_dir("/tmp", verbose); // Temporaries
create_dir("/usr", verbose); // User directories
create_dir("/var", verbose); // Variables
copy_file("/bin/clear", include_bytes!("../../dsk/bin/clear"), verbose);
copy_file("/bin/halt", include_bytes!("../../dsk/bin/halt"), verbose);
copy_file("/bin/hello", include_bytes!("../../dsk/bin/hello"), verbose);
copy_file("/bin/print", include_bytes!("../../dsk/bin/print"), verbose);
copy_file("/bin/reboot", include_bytes!("../../dsk/bin/reboot"), verbose);
copy_file("/bin/sleep", include_bytes!("../../dsk/bin/sleep"), verbose);
create_dir("/dev/clk", verbose); // Clocks
create_dev("/dev/clk/uptime", DeviceType::Uptime, verbose);
create_dev("/dev/clk/realtime", DeviceType::Realtime, verbose);
create_dev("/dev/rtc", DeviceType::File, verbose); // TODO
create_dev("/dev/null", DeviceType::Null, verbose);
create_dev("/dev/random", DeviceType::Random, verbose);
create_dev("/dev/console", DeviceType::Console, verbose);
copy_file("/ini/boot.sh", include_bytes!("../../dsk/ini/boot.sh"), verbose);
copy_file("/ini/banner.txt", include_bytes!("../../dsk/ini/banner.txt"), verbose);
copy_file("/ini/version.txt", include_bytes!("../../dsk/ini/version.txt"), verbose);
copy_file("/ini/palette.csv", include_bytes!("../../dsk/ini/palette.csv"), verbose);
create_dir("/ini/lisp", verbose);
copy_file("/ini/lisp/core.lsp", include_bytes!("../../dsk/ini/lisp/core.lsp"), verbose);
create_dir("/ini/fonts", verbose);
copy_file("/ini/fonts/lat15-terminus-8x16.psf", include_bytes!("../../dsk/ini/fonts/lat15-terminus-8x16.psf"), verbose);
copy_file("/ini/fonts/zap-light-8x16.psf", include_bytes!("../../dsk/ini/fonts/zap-light-8x16.psf"), verbose);
copy_file("/ini/fonts/zap-vga-8x16.psf", include_bytes!("../../dsk/ini/fonts/zap-vga-8x16.psf"), verbose);
copy_file("/tmp/alice.txt", include_bytes!("../../dsk/tmp/alice.txt"), verbose);
create_dir("/tmp/lisp", verbose);
copy_file("/tmp/lisp/factorial.lsp", include_bytes!("../../dsk/tmp/lisp/factorial.lsp"), verbose);
copy_file("/tmp/lisp/fibonacci.lsp", include_bytes!("../../dsk/tmp/lisp/fibonacci.lsp"), verbose);
create_dir("/tmp/beep", verbose);
copy_file("/tmp/beep/tetris.sh", include_bytes!("../../dsk/tmp/beep/tetris.sh"), verbose);
copy_file("/tmp/beep/starwars.sh", include_bytes!("../../dsk/tmp/beep/starwars.sh"), verbose);
copy_file("/tmp/beep/mario.sh", include_bytes!("../../dsk/tmp/beep/mario.sh"), verbose);
}
pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
let csi_color = Style::color("Yellow");
let csi_reset = Style::reset();
println!("{}Welcome to MOROS v{} installation program!{}", csi_color, env!("CARGO_PKG_VERSION"), csi_reset);
println!();
print!("Proceed? [y/N] ");
if io::stdin().read_line().trim() == "y" {
println!();
if !sys::fs::is_mounted() {
println!("{}Listing disks ...{}", csi_color, csi_reset);
usr::disk::main(&["disk", "list"]);
println!();
println!("{}Formatting disk ...{}", csi_color, csi_reset);
print!("Enter path of disk to format: ");
let pathname = io::stdin().read_line();
let res = usr::disk::main(&["disk", "format", pathname.trim_end()]);
if res == usr::shell::ExitCode::CommandError {
return res;
}
println!();
}
println!("{}Populating filesystem...{}", csi_color, csi_reset);
let verbose = true;
copy_files(verbose);
if sys::process::user().is_none() {
println!();
println!("{}Creating user...{}", csi_color, csi_reset);
let res = usr::user::main(&["user", "create"]);
if res == usr::shell::ExitCode::CommandError {
return res;
}
}
println!();
println!("{}Installation successful!{}", csi_color, csi_reset);
println!();
println!("Exit console or reboot to apply changes");
}
usr::shell::ExitCode::CommandSuccessful
}
fn create_dir(pathname: &str, verbose: bool) {
if syscall::info(pathname).is_none() {
if let Some(handle) = api::fs::create_dir(pathname) {
syscall::close(handle);
if verbose {
println!("Created '{}'", pathname);
}
}
}
}
fn create_dev(pathname: &str, dev: DeviceType, verbose: bool) {
if syscall::info(pathname).is_none() {
if let Some(handle) = fs::create_device(pathname, dev) {
syscall::close(handle);
if verbose {
println!("Created '{}'", pathname);
}
}
}
}
fn copy_file(pathname: &str, buf: &[u8], verbose: bool) {
if fs::exists(pathname) {
return;
}
if pathname.ends_with(".txt") {
if let Ok(text) = String::from_utf8(buf.to_vec()) {
let text = text.replace("{x.x.x}", env!("CARGO_PKG_VERSION"));
fs::write(pathname, text.as_bytes()).ok();
} else {
fs::write(pathname, buf).ok();
}
} else {
fs::write(pathname, buf).ok();
}
// TODO: add File::write_all to split buf if needed
if verbose {
println!("Copied '{}'", pathname);
}
}