1 extern crate libc; 2 3 #[macro_use] 4 extern crate lazy_static; 5 6 #[macro_use] 7 extern crate num_derive; 8 9 use std::{ 10 collections::HashMap, 11 fs::File, 12 io::{Read, Write}, 13 path::Path, 14 string::String, 15 vec::Vec, 16 }; 17 18 use num_enum::TryFromPrimitive; 19 20 pub const ROOT_PATH: &str = "/"; 21 22 mod shell; 23 24 #[repr(u8)] 25 #[derive(Debug, FromPrimitive, TryFromPrimitive, ToPrimitive, PartialEq, Eq, Clone)] 26 #[allow(dead_code)] 27 pub enum SpecialKeycode { 28 LF = b'\n', 29 CR = b'\r', 30 Delete = b'\x7f', 31 BackSpace = b'\x08', 32 Tab = b'\t', 33 34 FunctionKey = 0xE0, 35 PauseBreak = 0xE1, 36 37 Up = 0x48, 38 Down = 0x50, 39 Left = 0x4B, 40 Right = 0x4D, 41 42 Home = 0x47, 43 End = 0x4F, 44 } 45 46 impl Into<u8> for SpecialKeycode { 47 fn into(self) -> u8 { 48 self as u8 49 } 50 } 51 52 struct Env(std::collections::HashMap<String, String>); 53 54 lazy_static! { 55 static ref ENV: std::sync::Mutex<Env> = std::sync::Mutex::new(Env(HashMap::new())); 56 } 57 58 impl Env { 59 fn init_env() { 60 let mut file = File::create("/etc/profile").unwrap(); 61 file.write_all("PATH=/bin:/usr/bin:/usr/local/bin\n".as_bytes()) 62 .unwrap(); 63 file.write_all("PWD=/\n".as_bytes()).unwrap(); 64 } 65 66 fn read_env() { 67 let mut env = ENV.lock().unwrap(); 68 let mut file = File::open("/etc/profile").unwrap(); 69 let mut buf: Vec<u8> = Vec::new(); 70 file.read_to_end(&mut buf).unwrap(); 71 for (name, value) in String::from_utf8(buf) 72 .unwrap() 73 .split('\n') 74 .filter_map(|str| { 75 let v = str.split('=').collect::<Vec<&str>>(); 76 if v.len() == 2 && !v.contains(&"") { 77 Some((*v.get(0).unwrap(), *v.get(1).unwrap())) 78 } else { 79 None 80 } 81 }) 82 .collect::<Vec<(&str, &str)>>() 83 { 84 env.0.insert(String::from(name), String::from(value)); 85 } 86 } 87 88 fn get(key: &String) -> Option<String> { 89 let env = &mut ENV.lock().unwrap().0; 90 env.get(key).map(|value| value.clone()) 91 } 92 93 fn insert(key: String, value: String) { 94 ENV.lock().unwrap().0.insert(key, value); 95 } 96 97 fn path() -> Vec<String> { 98 let env = &ENV.lock().unwrap().0; 99 let paths = env.get("PATH").unwrap(); 100 paths 101 .split(':') 102 .filter_map(|str| { 103 let path = String::from(str); 104 if Path::new(&path).is_dir() { 105 Some(path) 106 } else { 107 None 108 } 109 }) 110 .collect::<Vec<String>>() 111 } 112 } 113 114 fn main() { 115 Env::init_env(); 116 Env::read_env(); 117 let mut shell = shell::Shell::new(); 118 shell.exec(); 119 return; 120 } 121