unix.rs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use std::str::raw::from_c_str;
  2. use std::ptr::read;
  3. use std::collections::hashmap::HashMap;
  4. mod c {
  5. #![allow(non_camel_case_types)]
  6. extern crate libc;
  7. use self::libc::{
  8. c_char,
  9. c_int,
  10. uid_t,
  11. time_t
  12. };
  13. pub struct c_passwd {
  14. pub pw_name: *c_char, // login name
  15. pub pw_passwd: *c_char,
  16. pub pw_uid: c_int, // user ID
  17. pub pw_gid: c_int, // group ID
  18. pub pw_change: time_t,
  19. pub pw_class: *c_char,
  20. pub pw_gecos: *c_char, // full name
  21. pub pw_dir: *c_char, // login dir
  22. pub pw_shell: *c_char, // login shell
  23. pub pw_expire: time_t // password expiry time
  24. }
  25. pub struct c_group {
  26. pub gr_name: *c_char // group name
  27. }
  28. extern {
  29. pub fn getpwuid(uid: c_int) -> *c_passwd;
  30. pub fn getgrgid(gid: uid_t) -> *c_group;
  31. pub fn getuid() -> libc::c_int;
  32. }
  33. }
  34. pub struct Unix {
  35. user_names: HashMap<i32, Option<String>>,
  36. group_names: HashMap<u32, Option<String>>,
  37. }
  38. impl Unix {
  39. pub fn empty_cache() -> Unix {
  40. Unix {
  41. user_names: HashMap::new(),
  42. group_names: HashMap::new(),
  43. }
  44. }
  45. pub fn get_user_name<'a> (&'a mut self, uid: i32) -> Option<String> {
  46. self.user_names.find_or_insert_with(uid, |&u| {
  47. let pw = unsafe { c::getpwuid(u) };
  48. if pw.is_not_null() {
  49. return unsafe { Some(from_c_str(read(pw).pw_name)) };
  50. }
  51. else {
  52. return None;
  53. }
  54. }).clone()
  55. }
  56. pub fn get_group_name<'a>(&'a mut self, gid: u32) -> Option<String> {
  57. self.group_names.find_or_insert_with(gid, |&gid| {
  58. let gr = unsafe { c::getgrgid(gid) };
  59. if gr.is_not_null() {
  60. return unsafe { Some(from_c_str(read(gr).gr_name)) };
  61. }
  62. else {
  63. return None;
  64. }
  65. }).clone()
  66. }
  67. }
  68. pub fn get_current_user_id() -> u64 {
  69. unsafe { c::getuid() as u64 }
  70. }