util.rs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use std::ffi::CStr;
  2. use std::os::raw::{c_char};
  3. use std::io::Write;
  4. #[derive(Debug)]
  5. enum Error {
  6. IOError { error: std::io::Error },
  7. StringError { error: std::str::Utf8Error },
  8. PopenError { error: subprocess::PopenError },
  9. Other { message: String },
  10. }
  11. impl From<std::str::Utf8Error> for Error {
  12. fn from(err: std::str::Utf8Error) -> Error {
  13. Error::StringError { error: err }
  14. }
  15. }
  16. impl From<std::io::Error> for Error {
  17. fn from(err: std::io::Error) -> Error {
  18. Error::IOError { error: err }
  19. }
  20. }
  21. impl From<subprocess::PopenError> for Error {
  22. fn from(err: subprocess::PopenError) -> Error {
  23. Error::PopenError { error: err }
  24. }
  25. }
  26. #[no_mangle]
  27. pub extern "C" fn rs_add_mcookie(
  28. cookie: *const c_char,
  29. display: *const c_char,
  30. xauth_cmd: *const c_char,
  31. authfile: *const c_char,
  32. ) -> c_char {
  33. let result = unsafe { add_mcookie(
  34. CStr::from_ptr(cookie),
  35. CStr::from_ptr(display),
  36. CStr::from_ptr(xauth_cmd),
  37. CStr::from_ptr(authfile),
  38. ) };
  39. match result {
  40. Ok(()) => 1,
  41. Err(err) => {
  42. eprintln!("{:?}", err);
  43. 0
  44. }
  45. }
  46. }
  47. fn add_mcookie(cookie: &CStr, display: &CStr, xauth_cmd: &CStr,authfile: &CStr) -> Result<(), Error> {
  48. let cmd = format!("{} -f {} -q", xauth_cmd.to_str()?, authfile.to_str()?);
  49. let mut p = subprocess::Popen::create(&[cmd], subprocess::PopenConfig {
  50. stdin: subprocess::Redirection::Pipe, ..Default::default()
  51. })?;
  52. if let Some(stdin) = &mut p.stdin {
  53. stdin.write(format!("remove {}\n", display.to_str()?).as_bytes())?;
  54. stdin.write(format!("add {} . {}\n", display.to_str()?, cookie.to_str()?).as_bytes())?;
  55. stdin.write("exit\n".as_bytes())?;
  56. } else {
  57. return Err(Error::Other { message: format!("unable to get pipe for writing") });
  58. }
  59. Ok(())
  60. }