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