two-way file system sync
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

client.rs 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. use std::fs::create_dir_all;
  2. use std::io::{self, Read, Write};
  3. use std::os::unix::net::{UnixListener, UnixStream};
  4. use std::sync::{Arc, Mutex};
  5. use std::thread;
  6. use twfss::{Database, SynchronizedDirectory};
  7. mod cli;
  8. fn config_dir() -> String {
  9. format!(
  10. "{}/.config/twfss",
  11. dirs::home_dir().unwrap().to_str().unwrap().to_owned()
  12. )
  13. }
  14. fn data_dir() -> String {
  15. format!(
  16. "{}/.local/share/twfss-client",
  17. dirs::home_dir().unwrap().to_str().unwrap().to_owned()
  18. )
  19. }
  20. fn db_path() -> String {
  21. format!("{}/client.db", data_dir())
  22. }
  23. fn main() {
  24. // Create the data directories if necessary.
  25. create_dir_all(config_dir()).unwrap();
  26. create_dir_all(data_dir()).unwrap();
  27. // Check whether the client is already running, and exit if it is.
  28. // TODO
  29. // TODO: Register signal handler for graceful shutdown.
  30. // Initialize the existing synchronized directories.
  31. let mut directories = Vec::new();
  32. let db = Arc::new(Mutex::new(Database::create_or_open(&db_path()).unwrap()));
  33. for directory in db.lock().unwrap().synchronized_directories() {
  34. // TODO: Error handling. If the directory was removed, remove it from the
  35. // list of synchronized directories.
  36. directories.push(SynchronizedDirectory::open(db.clone(), &directory, false).unwrap());
  37. }
  38. // Listen for CLI commands.
  39. // TODO: Graceful shutdown on errors.
  40. let listener = UnixListener::bind(cli::socket_path()).unwrap();
  41. for stream in listener.incoming() {
  42. match stream {
  43. Ok(stream) => {
  44. thread::spawn(move || {
  45. let mut stream = stream;
  46. match handle_cli_client(&mut stream) {
  47. Ok(()) => {}
  48. Err(e) => {
  49. // Log error and try to send it to the stream.
  50. // TODO
  51. write!(stream, "Error: {:?}", e).ok();
  52. }
  53. };
  54. });
  55. }
  56. Err(err) => {
  57. eprintln!("Error while listening on the local unix socket: {:?}", err);
  58. break;
  59. }
  60. }
  61. }
  62. }
  63. fn handle_cli_client(stream: &mut UnixStream) -> Result<(), Error> {
  64. let mut request = String::new();
  65. stream.read_to_string(&mut request)?;
  66. let options: cli::Options = serde_json::from_str(&request)?;
  67. let _verbose = options.verbose;
  68. match options.command {
  69. _cmd @ cli::Command::ListDirectories { .. } => {
  70. // TODO
  71. }
  72. _cmd @ cli::Command::AddDirectory { .. } => {
  73. // TODO
  74. }
  75. _cmd @ cli::Command::RemoveDirectory { .. } => {
  76. // TODO
  77. }
  78. }
  79. // TODO
  80. Ok(())
  81. }
  82. #[derive(Debug)]
  83. enum Error {
  84. Json(serde_json::error::Error),
  85. Io(std::io::Error),
  86. }
  87. impl From<serde_json::error::Error> for Error {
  88. fn from(e: serde_json::error::Error) -> Error {
  89. Error::Json(e)
  90. }
  91. }
  92. impl From<io::Error> for Error {
  93. fn from(e: io::Error) -> Error {
  94. Error::Io(e)
  95. }
  96. }