You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.0 KiB

  1. use daemonize::Daemonize;
  2. use std::fs::File;
  3. use std::io::prelude::*;
  4. use std::{fs, process};
  5. pub mod crypto;
  6. pub mod error;
  7. pub mod logs;
  8. #[cfg(test)]
  9. mod tests;
  10. macro_rules! exit_match {
  11. ($e: expr) => {
  12. match $e {
  13. Ok(_) => {}
  14. Err(e) => {
  15. log::error!("error: {}", e);
  16. std::process::exit(3);
  17. }
  18. }
  19. };
  20. }
  21. pub fn to_idna(domain_name: &str) -> Result<String, error::Error> {
  22. let mut idna_parts = vec![];
  23. let parts: Vec<&str> = domain_name.split('.').collect();
  24. for name in parts.iter() {
  25. let raw_name = name.to_lowercase();
  26. let idna_name = if name.is_ascii() {
  27. raw_name
  28. } else {
  29. let idna_name = punycode::encode(&raw_name)
  30. .map_err(|_| error::Error::from("IDNA encoding failed."))?;
  31. format!("xn--{}", idna_name)
  32. };
  33. idna_parts.push(idna_name);
  34. }
  35. Ok(idna_parts.join("."))
  36. }
  37. pub fn b64_encode<T: ?Sized + AsRef<[u8]>>(input: &T) -> String {
  38. base64::encode_config(input, base64::URL_SAFE_NO_PAD)
  39. }
  40. pub fn b64_decode<T: ?Sized + AsRef<[u8]>>(input: &T) -> Result<Vec<u8>, error::Error> {
  41. let res = base64::decode_config(input, base64::URL_SAFE_NO_PAD)?;
  42. Ok(res)
  43. }
  44. pub fn init_server(foreground: bool, pid_file: Option<&str>, default_pid_file: &str) {
  45. if !foreground {
  46. let daemonize = Daemonize::new().pid_file(pid_file.unwrap_or(default_pid_file));
  47. exit_match!(daemonize.start());
  48. } else if let Some(f) = pid_file {
  49. exit_match!(write_pid_file(f).map_err(|e| e.prefix(f)));
  50. }
  51. }
  52. fn write_pid_file(pid_file: &str) -> Result<(), error::Error> {
  53. let data = format!("{}\n", process::id()).into_bytes();
  54. let mut file = File::create(pid_file)?;
  55. file.write_all(&data)?;
  56. file.sync_all()?;
  57. Ok(())
  58. }
  59. pub fn clean_pid_file(pid_file: Option<&str>) -> Result<(), error::Error> {
  60. if let Some(f) = pid_file {
  61. fs::remove_file(f)?;
  62. }
  63. Ok(())
  64. }