Implemented whoami on top of system calls.

Details

- The current implementataion the `whoami` utility relies
on a env var to determine the user. With this change we get
the effective user id of the context and lookup that id on
/etc/passwd.
- Added the Redox `libextra` dependency as it has some goodies
for error handling. This will allow to make this crate upto date
with `coreutils` practices.
- Added a new small `arg_parser` crate that was extracted from
`coreutils` as is now commen between `coreutils` and here.
This commit is contained in:
Jose Narvaez
2017-07-16 17:47:18 +01:00
parent 3ca18917f8
commit 3a06dbbc8e
2 changed files with 74 additions and 3 deletions
+2
View File
@@ -32,6 +32,8 @@ path = "src/bin/whoami.rs"
[dependencies]
argon2rs = { version = "0.2", default-features = false }
arg_parser = { path = "../arg_parser" }
extra = { git = "https://github.com/redox-os/libextra.git" }
liner = "0.1"
rand = "0.3"
redox_syscall = "0.1"
+72 -3
View File
@@ -1,5 +1,74 @@
use std::env;
#![deny(warnings)]
pub fn main() {
println!("{}", env::var("USER").unwrap_or(String::new()));
extern crate arg_parser;
extern crate extra;
extern crate syscall;
extern crate userutils;
use std::io::{self, Read, Write};
use std::process::exit;
use std::fs::File;
use std::env;
use arg_parser::ArgParser;
use extra::option::OptionalExt;
use userutils::Passwd;
const MAN_PAGE: &'static str = /* @MANSTART{whoami} */ r#"
NAME
whoami - display effective user id
SYNOPSIS
whoami [ -h | --help ]
DESCRIPTION
The whoami utility displays your effective user ID as a name.
OPTIONS
-h
--help
Display this help and exit.
EXIT STATUS
The whoami utility exits 0 on success, and >0 if an error occurs.
AUTHOR
Written by Jose Narvaez.
"#; /* @MANEND */
const PASSWD_FILE: &'static str = "/etc/passwd";
fn main() {
let stdout = io::stdout();
let mut stdout = stdout.lock();
let mut stderr = io::stderr();
let mut parser = ArgParser::new(1)
.add_flag(&["h", "help"]);
parser.parse(env::args());
if parser.found("help") {
stdout.write_all(MAN_PAGE.as_bytes()).try(&mut stderr);
stdout.flush().try(&mut stderr);
exit(0);
}
match syscall::geteuid() {
Ok(euid) => {
let mut passwd_string = String::new();
if let Ok(mut file) = File::open(PASSWD_FILE) {
let _ = file.read_to_string(&mut passwd_string);
}
for line in passwd_string.lines() {
if let Ok(passwd) = Passwd::parse(line) {
if euid == passwd.uid as usize {
stdout.write_all(format!("{}\n", passwd.name).as_bytes()).try(&mut stderr);
stdout.flush().try(&mut stderr);
exit(0);
}
}
}
},
Err(_) => exit(1)
};
}