Guest User

Untitled

a guest
Jan 16th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.45 KB | None | 0 0
  1. use clap::{App, Arg, ArgMatches};
  2. use std::path::{Path, PathBuf};
  3. use std::process;
  4. use std::fs;
  5. use std::ffi::OsString;
  6. use std::io;
  7. use std::os::unix::fs::MetadataExt;
  8.  
  9. const PROC_PATH: &str = "/proc";
  10. const FD_FOLDER: &str = "fd";
  11. const EXE_SYMLINK: &str = "exe";
  12.  
  13. fn get_filename_from_matches<'a>(matches: &'a ArgMatches) -> &'a str {
  14. matches.value_of("file").unwrap()
  15. }
  16.  
  17. fn get_current_directory() -> PathBuf {
  18. std::env::current_dir().unwrap()
  19. }
  20.  
  21. fn get_path_from_match(matches: &ArgMatches) -> PathBuf {
  22. PathBuf::from(get_filename_from_matches(&matches))
  23. }
  24.  
  25. fn get_only_process_pid(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
  26. dir_result.as_ref().unwrap()
  27. .file_name().to_str().unwrap()
  28. .chars().all(char::is_numeric)
  29. }
  30.  
  31. fn get_only_process_directory(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
  32. dir_result.as_ref().unwrap()
  33. .path().is_dir()
  34. }
  35.  
  36. fn map_to_process_struct<'a>(dir_result: Result<std::fs::DirEntry, std::io::Error>) -> Process {
  37. let pid = dir_result.unwrap()
  38. .path().into_os_string();
  39.  
  40. Process::new(pid)
  41. }
  42.  
  43. fn get_reachable_launched_programs(dir_result: &Result<std::fs::DirEntry, std::io::Error>) -> bool {
  44. let pid = dir_result.as_ref().unwrap().file_name();
  45. get_running_program_name(pid.to_str().unwrap()).is_ok()
  46. }
  47.  
  48. fn get_running_program_name(pid: &str) -> io::Result<PathBuf> {
  49. Path::new(PROC_PATH)
  50. .join(pid)
  51. .join(EXE_SYMLINK)
  52. .read_link()
  53. }
  54.  
  55. fn process_using_file(process: &Process, inode: &u64) -> bool {
  56. fs::read_dir(process.get_fd_directory()).unwrap()
  57. .filter(|file| fs::metadata(file.as_ref().unwrap().path()).unwrap().ino() == *inode )
  58. .count() > 0
  59. }
  60.  
  61. #[derive(Debug)]
  62. struct Process {
  63. pid: OsString,
  64. running_program_name: String
  65. }
  66.  
  67. impl Process {
  68. fn new(pid: OsString) -> Process {
  69. let running_program_name = get_running_program_name(pid.to_str().unwrap())
  70. .unwrap().to_str().unwrap().to_owned();
  71. Process{ pid, running_program_name }
  72. }
  73.  
  74. fn get_fd_directory(&self) -> PathBuf {
  75. let pid_path = Path::new(self.pid.to_str().unwrap());
  76. pid_path.join(FD_FOLDER)
  77. }
  78. }
  79.  
  80. fn main() -> io::Result<()> {
  81. let matches = App::new("FOWP")
  82. .version("1.0")
  83. .author("XXX <xxx@gmail.com>")
  84. .about("Tell which process has opened a given file")
  85. .arg(Arg::with_name("file")
  86. .short("f")
  87. .long("file")
  88. .value_name("FILE")
  89. .required(true)
  90. .help("Path to the file"))
  91. .get_matches();
  92.  
  93. let full_path = get_path_from_match(&matches);
  94. let inode = fs::metadata(&full_path)?.ino();
  95.  
  96. println!("Running program that using the file {:?} are : ", full_path);
  97.  
  98. if !full_path.exists(){
  99. eprintln!("The file {} does not exists", full_path.to_str().unwrap());
  100. process::exit(1);
  101. }
  102.  
  103.  
  104. fs::read_dir(PROC_PATH).unwrap()
  105. .filter(get_only_process_pid)
  106. .filter(get_only_process_directory)
  107. .filter(get_reachable_launched_programs)
  108. .map(map_to_process_struct)
  109. .filter(|process| process_using_file(process, &inode))
  110. .for_each(|process| println!("Running process is {:?}", process) );
  111.  
  112. Ok(())
  113. }
Add Comment
Please, Sign In to add comment