xref: /NovaShell/src/main.rs (revision 81c61261198d944586ff01a3425de1c7761cc9cf)
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