xref: /NovaShell/src/main.rs (revision 6f50094a7e1f5a323ffdd8ef4be4c22bba777501)
1*6f50094aSMemoryShore extern crate libc;
2*6f50094aSMemoryShore 
3*6f50094aSMemoryShore #[macro_use]
4*6f50094aSMemoryShore extern crate lazy_static;
5*6f50094aSMemoryShore 
6*6f50094aSMemoryShore use std::{
7*6f50094aSMemoryShore     collections::HashMap,
8*6f50094aSMemoryShore     fs::File,
9*6f50094aSMemoryShore     io::{Read, Write},
10*6f50094aSMemoryShore     path::Path,
11*6f50094aSMemoryShore     string::String,
12*6f50094aSMemoryShore     vec::Vec,
13*6f50094aSMemoryShore };
14*6f50094aSMemoryShore 
15*6f50094aSMemoryShore pub const ROOT_PATH: &str = "/";
16*6f50094aSMemoryShore 
17*6f50094aSMemoryShore mod shell;
18*6f50094aSMemoryShore 
19*6f50094aSMemoryShore pub mod special_keycode {
20*6f50094aSMemoryShore     pub const LF: u8 = b'\n';
21*6f50094aSMemoryShore     pub const CR: u8 = b'\r';
22*6f50094aSMemoryShore     pub const DL: u8 = b'\x7f';
23*6f50094aSMemoryShore     pub const BS: u8 = b'\x08';
24*6f50094aSMemoryShore     pub const SPACE: u8 = b' ';
25*6f50094aSMemoryShore     pub const TAB: u8 = b'\t';
26*6f50094aSMemoryShore 
27*6f50094aSMemoryShore     pub const UP: u8 = 72;
28*6f50094aSMemoryShore     pub const DOWN: u8 = 80;
29*6f50094aSMemoryShore     pub const LEFT: u8 = 75;
30*6f50094aSMemoryShore     pub const RIGHT: u8 = 77;
31*6f50094aSMemoryShore }
32*6f50094aSMemoryShore 
33*6f50094aSMemoryShore struct Env(std::collections::HashMap<String, String>);
34*6f50094aSMemoryShore 
35*6f50094aSMemoryShore lazy_static! {
36*6f50094aSMemoryShore     static ref ENV: std::sync::Mutex<Env> = std::sync::Mutex::new(Env(HashMap::new()));
37*6f50094aSMemoryShore }
38*6f50094aSMemoryShore 
39*6f50094aSMemoryShore impl Env {
40*6f50094aSMemoryShore     fn init_env() {
41*6f50094aSMemoryShore         let mut file = File::create("/etc/profile").unwrap();
42*6f50094aSMemoryShore         file.write_all("PATH=/bin:/usr/bin:/usr/local/bin\n".as_bytes())
43*6f50094aSMemoryShore             .unwrap();
44*6f50094aSMemoryShore         file.write_all("PWD=/\n".as_bytes()).unwrap();
45*6f50094aSMemoryShore     }
46*6f50094aSMemoryShore 
47*6f50094aSMemoryShore     fn read_env() {
48*6f50094aSMemoryShore         let env = &mut ENV.lock().unwrap().0;
49*6f50094aSMemoryShore         let mut file = File::open("/etc/profile").unwrap();
50*6f50094aSMemoryShore         let mut buf: Vec<u8> = Vec::new();
51*6f50094aSMemoryShore         file.read_to_end(&mut buf).unwrap();
52*6f50094aSMemoryShore         for (name, value) in String::from_utf8(buf)
53*6f50094aSMemoryShore             .unwrap()
54*6f50094aSMemoryShore             .split('\n')
55*6f50094aSMemoryShore             .filter_map(|str| {
56*6f50094aSMemoryShore                 let v = str.split('=').collect::<Vec<&str>>();
57*6f50094aSMemoryShore                 if v.len() == 2 && !v.contains(&"") {
58*6f50094aSMemoryShore                     Some((*v.get(0).unwrap(), *v.get(1).unwrap()))
59*6f50094aSMemoryShore                 } else {
60*6f50094aSMemoryShore                     None
61*6f50094aSMemoryShore                 }
62*6f50094aSMemoryShore             })
63*6f50094aSMemoryShore             .collect::<Vec<(&str, &str)>>()
64*6f50094aSMemoryShore         {
65*6f50094aSMemoryShore             env.insert(String::from(name), String::from(value));
66*6f50094aSMemoryShore         }
67*6f50094aSMemoryShore     }
68*6f50094aSMemoryShore 
69*6f50094aSMemoryShore     fn get(key: &String) -> Option<String> {
70*6f50094aSMemoryShore         let env = &mut ENV.lock().unwrap().0;
71*6f50094aSMemoryShore         env.get(key).map(|value| value.clone())
72*6f50094aSMemoryShore     }
73*6f50094aSMemoryShore 
74*6f50094aSMemoryShore     fn insert(key: String, value: String) {
75*6f50094aSMemoryShore         ENV.lock().unwrap().0.insert(key, value);
76*6f50094aSMemoryShore     }
77*6f50094aSMemoryShore 
78*6f50094aSMemoryShore     fn path() -> Vec<String> {
79*6f50094aSMemoryShore         let env = &ENV.lock().unwrap().0;
80*6f50094aSMemoryShore         let paths = env.get("PATH").unwrap();
81*6f50094aSMemoryShore         paths
82*6f50094aSMemoryShore             .split(':')
83*6f50094aSMemoryShore             .filter_map(|str| {
84*6f50094aSMemoryShore                 let path = String::from(str);
85*6f50094aSMemoryShore                 if Path::new(&path).is_dir() {
86*6f50094aSMemoryShore                     Some(path)
87*6f50094aSMemoryShore                 } else {
88*6f50094aSMemoryShore                     None
89*6f50094aSMemoryShore                 }
90*6f50094aSMemoryShore             })
91*6f50094aSMemoryShore             .collect::<Vec<String>>()
92*6f50094aSMemoryShore     }
93*6f50094aSMemoryShore }
94*6f50094aSMemoryShore 
95*6f50094aSMemoryShore fn main() {
96*6f50094aSMemoryShore     Env::init_env();
97*6f50094aSMemoryShore     Env::read_env();
98*6f50094aSMemoryShore     let mut shell = shell::Shell::new();
99*6f50094aSMemoryShore     shell.exec();
100*6f50094aSMemoryShore     return;
101*6f50094aSMemoryShore }
102