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