aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/builtins.rs8
-rw-r--r--src/main.rs21
-rw-r--r--src/prompt.rs54
3 files changed, 52 insertions, 31 deletions
diff --git a/src/builtins.rs b/src/builtins.rs
index 4ef2416..b81c4ba 100644
--- a/src/builtins.rs
+++ b/src/builtins.rs
@@ -2,9 +2,15 @@ use std::path::Path;
pub fn cd(args: std::str::SplitWhitespace) -> std::path::PathBuf {
let new_dir = args.peekable().peek().map_or("/", |x| *x);
- let root = Path::new(new_dir);
+
+ let root = match std::fs::canonicalize(Path::new(new_dir)) {
+ Ok(p) => p,
+ Err(_) => Path::new("/").to_path_buf(),
+ };
+
if let Err(e) = std::env::set_current_dir(&root) {
eprintln!("{}", e);
}
+
root.to_path_buf()
}
diff --git a/src/main.rs b/src/main.rs
index a4f3c25..0581b13 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,12 +5,19 @@ mod builtins;
mod prompt;
fn main() {
- println!("rshell motd");
+ match std::fs::read_to_string("/etc/motd") {
+ Ok(motd) => println!("{}", motd),
+ Err(_) => {},
+ }
- let mut prompt = prompt::Prompt::new();
+ let prompt = prompt::Prompt::new();
+ let mut cwd = match std::env::current_dir() {
+ Ok(p) => p,
+ Err(e) => panic!(e),
+ };
loop {
- prompt.print();
+ prompt.print(&cwd);
let mut input = String::new();
match std::io::stdin().read_line(&mut input) {
@@ -36,7 +43,7 @@ fn main() {
match command {
"cd" => {
- prompt.pwd = builtins::cd(args);
+ cwd = builtins::cd(args);
previous_command = None;
}
"exit" => return,
@@ -70,7 +77,11 @@ fn main() {
if let Some(mut final_command) = previous_command {
match final_command.wait() {
Ok(ret) => match ret.code() {
- Some(code) => println!("exit code [{}]", code),
+ Some(code) => {
+ if cfg!(debug_assertions) {
+ println!("exit code [{}]", code);
+ }
+ },
None => println!("Process termed by signal"),
},
Err(e) => eprintln!("error waiting on final command: {}", e),
diff --git a/src/prompt.rs b/src/prompt.rs
index fd9c872..e6600b7 100644
--- a/src/prompt.rs
+++ b/src/prompt.rs
@@ -1,22 +1,12 @@
use std::io::Write;
pub struct Prompt {
- home: std::path::PathBuf,
- pub pwd: std::path::PathBuf,
- username: std::string::String,
- hostname: std::string::String,
+ ps1: std::string::String,
+ pub home: std::path::PathBuf,
}
impl Prompt {
pub fn new() -> Prompt {
- let home = match std::env::home_dir() {
- Some(p) => p,
- None => std::path::Path::new("/").to_path_buf(),
- };
- let pwd = match std::env::current_dir() {
- Ok(p) => p,
- Err(e) => panic!(e),
- };
let username = match std::process::Command::new("whoami").output() {
Ok(s) => {
let output = std::string::String::from_utf8(s.stdout).unwrap();
@@ -31,24 +21,38 @@ impl Prompt {
}
Err(e) => panic!(e),
};
- Prompt {
- home,
- pwd,
- username,
- hostname,
- }
+ let ready = if username == "root" {
+ "#"
+ } else {
+ "$"
+ }.to_owned();
+
+ let ps1 = String::from(" {USER}@{HOST} [{PWD}]\n\\$ ")
+ .replace("{USER}", &username)
+ .replace("{HOST}", &hostname)
+ .replace("\\$", &ready);
+ let home = match std::env::home_dir() {
+ Some(p) => p,
+ None => std::path::Path::new("/").to_path_buf(),
+ };
+
+ Prompt { ps1, home }
}
- pub fn print(&self) {
- let path = if self.pwd == self.home {
- self.pwd.display()
- } else if self.pwd.starts_with(&self.home) {
- self.pwd.strip_prefix(&self.home).unwrap().display()
+ pub fn print(&self, pwd: &std::path::PathBuf) {
+ if cfg!(debug_assertions) {
+ println!("pwd={}", pwd.display());
+ }
+
+ let path = if pwd.starts_with(&self.home) {
+ "~".to_owned() + &pwd.strip_prefix(&self.home).unwrap().display().to_string()
} else {
- self.pwd.display()
+ pwd.display().to_string()
};
- print!(" {USER}@{HOST} [{PWD}]\n$ ", USER=self.username, HOST=self.hostname, PWD=path);
+ let ps1 = self.ps1.replace("{PWD}", &path);
+
+ print!("{}", ps1);
match std::io::stdout().flush() {
Ok(_) => {}
Err(_) => println!(""),