mirror of
https://github.com/uutils/coreutils
synced 2024-11-15 01:17:09 +00:00
commit
0d8cfbbe45
7 changed files with 149 additions and 84 deletions
1
Makefile
1
Makefile
|
@ -36,6 +36,7 @@ UNIX_PROGS := \
|
||||||
users \
|
users \
|
||||||
whoami \
|
whoami \
|
||||||
tty \
|
tty \
|
||||||
|
groups \
|
||||||
id
|
id
|
||||||
|
|
||||||
ifneq ($(OS),Windows_NT)
|
ifneq ($(OS),Windows_NT)
|
||||||
|
|
|
@ -95,7 +95,7 @@ To do
|
||||||
- fold
|
- fold
|
||||||
- getlimits
|
- getlimits
|
||||||
- group-list
|
- group-list
|
||||||
- groups (in progress)
|
- groups
|
||||||
- hostid
|
- hostid
|
||||||
- install
|
- install
|
||||||
- join
|
- join
|
||||||
|
|
|
@ -1,11 +1,20 @@
|
||||||
#[allow(dead_code)];
|
#[allow(dead_code)];
|
||||||
|
|
||||||
|
extern crate getopts;
|
||||||
|
|
||||||
use std::libc::{
|
use std::libc::{
|
||||||
c_char,
|
c_char,
|
||||||
c_int,
|
c_int,
|
||||||
time_t
|
uid_t,
|
||||||
|
time_t,
|
||||||
|
getgroups
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use std::vec;
|
||||||
|
|
||||||
|
use std::ptr::read;
|
||||||
|
use std::str::raw::from_c_str;
|
||||||
|
|
||||||
pub struct c_passwd {
|
pub struct c_passwd {
|
||||||
pw_name: *c_char, /* user name */
|
pw_name: *c_char, /* user name */
|
||||||
pw_passwd: *c_char, /* user name */
|
pw_passwd: *c_char, /* user name */
|
||||||
|
@ -22,3 +31,85 @@ pub struct c_passwd {
|
||||||
pub struct c_group {
|
pub struct c_group {
|
||||||
gr_name: *c_char /* group name */
|
gr_name: *c_char /* group name */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern {
|
||||||
|
pub fn getpwuid(uid: c_int) -> *c_passwd;
|
||||||
|
pub fn getpwnam(login: *c_char) -> *c_passwd;
|
||||||
|
pub fn getgrouplist(name: *c_char,
|
||||||
|
basegid: c_int,
|
||||||
|
groups: *c_int,
|
||||||
|
ngroups: *mut c_int) -> c_int;
|
||||||
|
pub fn getgrgid(gid: uid_t) -> *c_group;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_pw_from_args(free: &~[~str]) -> Option<c_passwd> {
|
||||||
|
if free.len() == 1 {
|
||||||
|
let username = free[0].clone();
|
||||||
|
|
||||||
|
// Passed user as id
|
||||||
|
if username.chars().all(|c| c.is_digit()) {
|
||||||
|
let id = from_str::<i32>(username).unwrap();
|
||||||
|
let pw_pointer = unsafe { getpwuid(id) };
|
||||||
|
|
||||||
|
if pw_pointer.is_not_null() {
|
||||||
|
Some(unsafe { read(pw_pointer) })
|
||||||
|
} else {
|
||||||
|
crash!(1, "{:s}: no such user", username);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passed the username as a string
|
||||||
|
} else {
|
||||||
|
let pw_pointer = unsafe {
|
||||||
|
getpwnam(username.as_slice().as_ptr() as *i8)
|
||||||
|
};
|
||||||
|
if pw_pointer.is_not_null() {
|
||||||
|
Some(unsafe { read(pw_pointer) })
|
||||||
|
} else {
|
||||||
|
crash!(1, "{:s}: no such user", username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NGROUPS: i32 = 20;
|
||||||
|
|
||||||
|
pub fn group(possible_pw: Option<c_passwd>, nflag: bool) {
|
||||||
|
let mut groups = vec::with_capacity(NGROUPS as uint);
|
||||||
|
let mut ngroups;
|
||||||
|
|
||||||
|
if possible_pw.is_some() {
|
||||||
|
ngroups = NGROUPS;
|
||||||
|
unsafe {
|
||||||
|
getgrouplist(
|
||||||
|
possible_pw.unwrap().pw_name,
|
||||||
|
possible_pw.unwrap().pw_gid,
|
||||||
|
groups.as_ptr(),
|
||||||
|
&mut ngroups);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ngroups = unsafe {
|
||||||
|
getgroups(NGROUPS, groups.as_mut_ptr() as *mut u32)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsafe { groups.set_len(ngroups as uint) };
|
||||||
|
|
||||||
|
for &g in groups.iter() {
|
||||||
|
if nflag {
|
||||||
|
let group = unsafe { getgrgid(g as u32) };
|
||||||
|
if group.is_not_null() {
|
||||||
|
let name = unsafe {
|
||||||
|
from_c_str(read(group).gr_name)
|
||||||
|
};
|
||||||
|
print!("{:s} ", name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print!("{:d} ", g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
macro_rules! show_error(
|
macro_rules! show_error(
|
||||||
($exitcode:expr, $($args:expr),+) => ({
|
($exitcode:expr, $($args:expr),+) => ({
|
||||||
::std::os::set_exit_status($exitcode);
|
::std::os::set_exit_status($exitcode);
|
||||||
safe_write!(&mut ::std::io::stderr(), "{}: error: ", NAME);
|
safe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME);
|
||||||
safe_writeln!(&mut ::std::io::stderr(), $($args),+);
|
safe_writeln!(&mut ::std::io::stderr(), $($args),+);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
43
groups/groups.rs
Normal file
43
groups/groups.rs
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#[crate_id(name="groups", vers="1.0.0", author="Alan Andrade")];
|
||||||
|
/*
|
||||||
|
* This file is part of the uutils coreutils package.
|
||||||
|
*
|
||||||
|
* (c) Alan Andrade <alan.andradec@gmail.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#[feature(macro_rules)];
|
||||||
|
|
||||||
|
extern crate getopts;
|
||||||
|
|
||||||
|
use std::os;
|
||||||
|
use getopts::{
|
||||||
|
optflag,
|
||||||
|
getopts,
|
||||||
|
usage
|
||||||
|
};
|
||||||
|
use c_types::{get_pw_from_args, group};
|
||||||
|
|
||||||
|
#[path = "../common/util.rs"] mod util;
|
||||||
|
#[path = "../common/c_types.rs"] mod c_types;
|
||||||
|
|
||||||
|
static NAME: &'static str = "groups";
|
||||||
|
|
||||||
|
fn main () {
|
||||||
|
let args = os::args();
|
||||||
|
let options = [
|
||||||
|
optflag("h", "", "Help")
|
||||||
|
];
|
||||||
|
|
||||||
|
let matches = match getopts(args.tail(), options) {
|
||||||
|
Ok(m) => { m },
|
||||||
|
Err(_) => {
|
||||||
|
show_error!(1, "{}", usage(NAME, options));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
group(get_pw_from_args(&matches.free), true);
|
||||||
|
}
|
89
id/id.rs
89
id/id.rs
|
@ -32,7 +32,10 @@ use std::str::raw::from_c_str;
|
||||||
use getopts::{getopts, optflag, usage};
|
use getopts::{getopts, optflag, usage};
|
||||||
use c_types::{
|
use c_types::{
|
||||||
c_passwd,
|
c_passwd,
|
||||||
c_group
|
c_group,
|
||||||
|
get_pw_from_args,
|
||||||
|
getpwuid,
|
||||||
|
group
|
||||||
};
|
};
|
||||||
|
|
||||||
#[path = "../common/util.rs"] mod util;
|
#[path = "../common/util.rs"] mod util;
|
||||||
|
@ -75,9 +78,7 @@ mod audit {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
fn getpwuid(uid: uid_t) -> *c_passwd;
|
|
||||||
fn getgrgid(gid: uid_t) -> *c_group;
|
fn getgrgid(gid: uid_t) -> *c_group;
|
||||||
fn getpwnam(login: *c_char) -> *c_passwd;
|
|
||||||
fn getgrouplist(name: *c_char,
|
fn getgrouplist(name: *c_char,
|
||||||
basegid: c_int,
|
basegid: c_int,
|
||||||
groups: *c_int,
|
groups: *c_int,
|
||||||
|
@ -86,37 +87,6 @@ extern {
|
||||||
|
|
||||||
static NAME: &'static str = "id";
|
static NAME: &'static str = "id";
|
||||||
|
|
||||||
fn get_pw_from_args(matches: &getopts::Matches) -> Option<c_passwd> {
|
|
||||||
if matches.free.len() == 1 {
|
|
||||||
let username = matches.free[0].clone();
|
|
||||||
|
|
||||||
// Passed user as id
|
|
||||||
if username.chars().all(|c| c.is_digit()) {
|
|
||||||
let id = from_str::<u32>(username).unwrap();
|
|
||||||
let pw_pointer = unsafe { getpwuid(id) };
|
|
||||||
|
|
||||||
if pw_pointer.is_not_null() {
|
|
||||||
Some(unsafe { read(pw_pointer) })
|
|
||||||
} else {
|
|
||||||
crash!(1, "{:s}: no such user", username);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passed the username as a string
|
|
||||||
} else {
|
|
||||||
let pw_pointer = unsafe {
|
|
||||||
getpwnam(username.as_slice().as_ptr() as *i8)
|
|
||||||
};
|
|
||||||
if pw_pointer.is_not_null() {
|
|
||||||
Some(unsafe { read(pw_pointer) })
|
|
||||||
} else {
|
|
||||||
crash!(1, "{:s}: no such user", username);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main () {
|
fn main () {
|
||||||
let args = os::args();
|
let args = os::args();
|
||||||
let args_t = args.tail();
|
let args_t = args.tail();
|
||||||
|
@ -152,7 +122,7 @@ fn main () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let possible_pw = get_pw_from_args(&matches);
|
let possible_pw = get_pw_from_args(&matches.free);
|
||||||
|
|
||||||
let nflag = matches.opt_present("n");
|
let nflag = matches.opt_present("n");
|
||||||
let uflag = matches.opt_present("u");
|
let uflag = matches.opt_present("u");
|
||||||
|
@ -189,7 +159,7 @@ fn main () {
|
||||||
unsafe { getegid() as i32 }
|
unsafe { getegid() as i32 }
|
||||||
};
|
};
|
||||||
|
|
||||||
let pw = unsafe { getpwuid(id as u32) };
|
let pw = unsafe { getpwuid(id) };
|
||||||
if nflag && pw.is_not_null() {
|
if nflag && pw.is_not_null() {
|
||||||
let pw_name = unsafe {
|
let pw_name = unsafe {
|
||||||
from_c_str(read(pw).pw_name)
|
from_c_str(read(pw).pw_name)
|
||||||
|
@ -234,7 +204,7 @@ fn pretty(possible_pw: Option<c_passwd>) {
|
||||||
} else {
|
} else {
|
||||||
let login = unsafe { from_c_str(getlogin()) };
|
let login = unsafe { from_c_str(getlogin()) };
|
||||||
let rid = unsafe { getuid() };
|
let rid = unsafe { getuid() };
|
||||||
let pw = unsafe { getpwuid(rid) };
|
let pw = unsafe { getpwuid(rid as i32) };
|
||||||
|
|
||||||
let is_same_user = unsafe {
|
let is_same_user = unsafe {
|
||||||
from_c_str(read(pw).pw_name) == login
|
from_c_str(read(pw).pw_name) == login
|
||||||
|
@ -254,7 +224,7 @@ fn pretty(possible_pw: Option<c_passwd>) {
|
||||||
|
|
||||||
let eid = unsafe { getegid() };
|
let eid = unsafe { getegid() };
|
||||||
if eid == rid {
|
if eid == rid {
|
||||||
let pw = unsafe { getpwuid(eid) };
|
let pw = unsafe { getpwuid(eid as i32) };
|
||||||
if pw.is_not_null() {
|
if pw.is_not_null() {
|
||||||
println!(
|
println!(
|
||||||
"euid\t{:s}",
|
"euid\t{:s}",
|
||||||
|
@ -284,7 +254,7 @@ fn pretty(possible_pw: Option<c_passwd>) {
|
||||||
|
|
||||||
fn pline(possible_pw: Option<c_passwd>) {
|
fn pline(possible_pw: Option<c_passwd>) {
|
||||||
let pw = if possible_pw.is_none() {
|
let pw = if possible_pw.is_none() {
|
||||||
unsafe { read(getpwuid(getuid())) }
|
unsafe { read(getpwuid(getuid() as i32)) }
|
||||||
} else {
|
} else {
|
||||||
possible_pw.unwrap()
|
possible_pw.unwrap()
|
||||||
};
|
};
|
||||||
|
@ -312,45 +282,6 @@ fn pline(possible_pw: Option<c_passwd>) {
|
||||||
|
|
||||||
static NGROUPS: i32 = 20;
|
static NGROUPS: i32 = 20;
|
||||||
|
|
||||||
fn group(possible_pw: Option<c_passwd>, nflag: bool) {
|
|
||||||
let mut groups = vec::with_capacity(NGROUPS as uint);
|
|
||||||
let mut ngroups;
|
|
||||||
|
|
||||||
if possible_pw.is_some() {
|
|
||||||
ngroups = NGROUPS;
|
|
||||||
unsafe {
|
|
||||||
getgrouplist(
|
|
||||||
possible_pw.unwrap().pw_name,
|
|
||||||
possible_pw.unwrap().pw_gid,
|
|
||||||
groups.as_ptr(),
|
|
||||||
&mut ngroups);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ngroups = unsafe {
|
|
||||||
libc::getgroups(NGROUPS, groups.as_mut_ptr() as *mut u32)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsafe { groups.set_len(ngroups as uint) };
|
|
||||||
|
|
||||||
for &g in groups.iter() {
|
|
||||||
if nflag {
|
|
||||||
let group = unsafe { getgrgid(g as u32) };
|
|
||||||
if group.is_not_null() {
|
|
||||||
let name = unsafe {
|
|
||||||
from_c_str(read(group).gr_name)
|
|
||||||
};
|
|
||||||
print!("{:s} ", name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print!("{:d} ", g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn auditid() { }
|
fn auditid() { }
|
||||||
|
|
||||||
|
@ -420,7 +351,7 @@ fn id_print(possible_pw: Option<c_passwd>,
|
||||||
let euid = unsafe { libc::geteuid() };
|
let euid = unsafe { libc::geteuid() };
|
||||||
if p_euid && (euid != uid as u32) {
|
if p_euid && (euid != uid as u32) {
|
||||||
print!(" euid={:u}", euid);
|
print!(" euid={:u}", euid);
|
||||||
let pw = unsafe { getpwuid(euid) };
|
let pw = unsafe { getpwuid(euid as i32) };
|
||||||
if pw.is_not_null() {
|
if pw.is_not_null() {
|
||||||
print!(
|
print!(
|
||||||
"({:s})",
|
"({:s})",
|
||||||
|
|
|
@ -22,14 +22,13 @@ use std::io::print;
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
use c_types::c_passwd;
|
use c_types::{c_passwd, getpwuid};
|
||||||
|
|
||||||
#[path = "../common/util.rs"] mod util;
|
#[path = "../common/util.rs"] mod util;
|
||||||
#[path = "../common/c_types.rs"] mod c_types;
|
#[path = "../common/c_types.rs"] mod c_types;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn geteuid() -> libc::c_int;
|
pub fn geteuid() -> libc::c_int;
|
||||||
pub fn getpwuid(uid: libc::c_int) -> *c_passwd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn getusername() -> ~str {
|
unsafe fn getusername() -> ~str {
|
||||||
|
|
Loading…
Reference in a new issue