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