1
0
Fork 0
forked from AbleOS/ableos
ableos-idl/ableos/src/rhai_shell/mod.rs

224 lines
5.8 KiB
Rust
Raw Normal View History

2022-04-12 17:50:01 -05:00
use crate::arch::drivers::sysinfo::master;
2022-04-11 17:23:11 -05:00
use crate::filesystem::FILE_SYSTEM;
use crate::time::fetch_time;
use crate::wasm_jumploader::interp;
use crate::{
arch::{shutdown, sloop},
systeminfo::{KERNEL_VERSION, RELEASE_TYPE},
KERNEL_STATE,
};
use genfs::{Fs, OpenOptions};
2022-05-07 07:08:34 -05:00
use kernel::allocator::ALLOCATOR;
2022-04-11 17:23:11 -05:00
use rhai::Engine;
use spin::Lazy;
2022-04-11 17:23:11 -05:00
use x86_64::instructions::interrupts::{disable, enable};
2022-04-25 04:56:01 -05:00
pub const RHAISHELL_VERSION: &str = "0.1.0";
2022-04-11 17:23:11 -05:00
pub static KEYBUFF: spin::Mutex<Vec<char>> = spin::Mutex::new(Vec::new());
pub static CURRENT_DIR: Lazy<spin::Mutex<String>> = Lazy::new(|| spin::Mutex::new("/".to_string()));
2022-03-11 17:13:41 -06:00
#[cfg(target_arch = "riscv64")]
pub fn shell() {}
#[cfg(target_arch = "x86_64")]
pub fn shell() {
let _current_dir = "/".to_string();
2022-02-19 09:07:33 -06:00
let engine = engine_construction();
2022-02-19 08:46:11 -06:00
let mut scope = rhai::Scope::new();
2022-04-25 04:56:01 -05:00
println!("Rhaishell v{}", RHAISHELL_VERSION);
2022-02-19 08:46:11 -06:00
let mut buf = String::new();
print!("> ");
loop {
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
Some('\n') => {
2022-04-25 04:56:01 -05:00
if buf == "quit" {
println!("Bye!");
break;
}
2022-02-19 08:46:11 -06:00
match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
Ok(o) => println!("{o}"),
2022-04-09 17:26:43 -05:00
2022-02-19 08:46:11 -06:00
Err(e) => println!("Eval error: {e}"),
};
buf.clear();
print!("> ");
}
Some('\u{0008}') => {
buf.pop();
}
2022-03-26 06:35:33 -05:00
Some('\u{0009}') => {
buf.push(' ');
buf.push(' ');
buf.push(' ');
buf.push(' ');
}
2022-02-19 08:46:11 -06:00
Some(chr) => buf.push(chr),
None => (),
}
}
}
2022-02-19 08:46:11 -06:00
pub fn afetch() {
let kstate = KERNEL_STATE.lock();
2022-03-11 17:13:41 -06:00
let tick_time = fetch_time();
2022-02-19 08:46:11 -06:00
disable();
let allocator = ALLOCATOR.lock();
let size = allocator.size();
let used = allocator.used();
enable();
2022-02-23 10:06:27 -06:00
println!(
include_str!("balloon.txt"),
kstate.hostname,
RELEASE_TYPE,
KERNEL_VERSION,
tick_time,
master().unwrap().brand_string().unwrap(),
2022-04-12 13:46:50 -05:00
// "",
// mem
used,
size
2022-02-23 10:06:27 -06:00
);
2022-02-19 08:46:11 -06:00
drop(kstate);
}
2022-04-11 17:23:11 -05:00
2022-02-19 08:46:11 -06:00
pub fn set_hostname(name: String) {
let mut kstate = KERNEL_STATE.lock();
kstate.hostname = name;
}
2022-02-19 09:07:33 -06:00
2022-02-23 10:06:27 -06:00
/// Examine a memory pointer
2022-04-12 08:35:09 -05:00
pub fn peek_memory(ptr: i64) -> i64 {
unsafe { *(ptr as *const u8) as _ }
2022-02-23 10:06:27 -06:00
}
2022-04-12 08:35:09 -05:00
pub fn poke_memory(ptr: i64, val: i64) {
match val.try_into() {
Ok(val) => unsafe { *(ptr as *mut u8) = val },
Err(_) => error!("{val} cannot be converted into u8"),
2022-04-12 08:35:09 -05:00
}
2022-02-23 10:06:27 -06:00
}
2022-04-09 17:26:43 -05:00
pub fn ls() {
let current_dir = CURRENT_DIR.lock();
2022-04-09 17:26:43 -05:00
let fs = &*FILE_SYSTEM.lock();
let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap();
let mut files = file.directory().unwrap();
println!("current dir: {}", *current_dir);
while let Some(Ok(entry)) = files.next() {
let inode_name = entry.name;
let s = String::from_utf8_lossy(&inode_name);
println!("{}", s);
}
}
pub fn log_dump() {
use crate::network::socket::SimpleSock;
use crate::relib::network::socket::Socket;
let log_socket_id = SimpleSock::grab_socket("Logger".to_string());
match log_socket_id {
Some(mut log_socket_id) => {
let log = log_socket_id.peek();
match log {
crate::network::socket::SocketReturns::ReadOk(ok) => {
for x in ok.iter() {
print!("{}", *x as char);
}
}
crate::network::socket::SocketReturns::ReadIndexOutOfBounds => todo!(),
crate::network::socket::SocketReturns::WriteOk => todo!(),
}
}
None => warn!("No socket found for Logger"),
}
}
2022-04-09 17:26:43 -05:00
pub fn echo_file(path: String) {
let mut current_dir = CURRENT_DIR.lock();
let fs = &*FILE_SYSTEM.lock();
current_dir.push_str(&path);
let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap();
if file.is_dir() {
println!("{} is a directory", path);
} else {
let mut file_contents = Vec::new();
let _ret = file.read_to_end(&mut file_contents).unwrap();
2022-04-09 17:26:43 -05:00
let file_contents_str = String::from_utf8_lossy(&file_contents);
println!("{}", file_contents_str);
}
}
pub fn change_directory(path: String) {
let mut current_dir = CURRENT_DIR.lock();
let _fs = &*FILE_SYSTEM.lock();
2022-04-09 17:26:43 -05:00
if path == "." || path == ".." {
let mut split_dir = current_dir.split('/').collect::<Vec<&str>>();
2022-04-09 17:26:43 -05:00
let mut new_dir = String::new();
split_dir.remove(split_dir.len() - 1);
println!("{:?}", split_dir);
if split_dir.is_empty() {
2022-04-09 17:26:43 -05:00
new_dir = "/".to_string();
} else {
for x in split_dir {
new_dir.push_str(x);
new_dir.push('/');
}
}
*current_dir = new_dir;
} else {
if !current_dir.ends_with('/') {
current_dir.push('/');
2022-04-09 17:26:43 -05:00
}
current_dir.push_str(&path);
}
}
2022-04-11 17:23:11 -05:00
fn engine_construction() -> Engine {
let mut engine = rhai::Engine::new();
engine.on_print(|x| println!("{}", x));
engine.on_debug(|x, src, pos| {
let src = src.unwrap_or("unknown");
println!("DEBUG: {} at {:?}: {}", src, pos, x);
debug!("{} at {:?}: {}", src, pos, x);
});
engine.register_fn("afetch", afetch);
engine.register_fn("set_hostname", set_hostname);
engine.register_fn("shutdown", shutdown);
engine.register_fn("peek", peek_memory);
engine.register_fn("poke", poke_memory);
engine.register_fn("sloop", sloop);
engine.register_fn("log_dump", log_dump);
2022-07-28 20:15:02 -05:00
// engine.register_fn("ls", ls);
2022-04-11 17:23:11 -05:00
engine
}