|
|
@@ -1,5 +1,6 @@
|
|
1
|
1
|
use std::ffi::{OsStr, OsString};
|
|
2
|
2
|
use std::fs::{self, create_dir_all, remove_file};
|
|
|
3
|
+use std::io::Write;
|
|
3
|
4
|
use std::sync::Arc;
|
|
4
|
5
|
|
|
5
|
6
|
use env_logger::Env;
|
|
|
@@ -22,6 +23,7 @@ struct SynchronizedDirectory {
|
|
22
|
23
|
client_side_sync: ClientSideSync,
|
|
23
|
24
|
file_system_watcher: FileSystemWatcher,
|
|
24
|
25
|
last_error: Option<Error>,
|
|
|
26
|
+ paused: bool,
|
|
25
|
27
|
}
|
|
26
|
28
|
|
|
27
|
29
|
impl SynchronizedDirectory {
|
|
|
@@ -38,17 +40,20 @@ impl SynchronizedDirectory {
|
|
38
|
40
|
client_side_sync,
|
|
39
|
41
|
file_system_watcher,
|
|
40
|
42
|
last_error: None,
|
|
|
43
|
+ paused: true,
|
|
41
|
44
|
})
|
|
42
|
45
|
}
|
|
43
|
46
|
|
|
44
|
47
|
async fn unpause(&mut self) {
|
|
45
|
48
|
self.client_side_sync.unpause().await;
|
|
46
|
49
|
self.file_system_watcher.unpause().await;
|
|
|
50
|
+ self.paused = false;
|
|
47
|
51
|
}
|
|
48
|
52
|
|
|
49
|
53
|
async fn pause(&mut self) {
|
|
50
|
54
|
self.client_side_sync.pause().await;
|
|
51
|
55
|
self.file_system_watcher.pause().await;
|
|
|
56
|
+ self.paused = true;
|
|
52
|
57
|
}
|
|
53
|
58
|
}
|
|
54
|
59
|
|
|
|
@@ -103,11 +108,17 @@ async fn main() {
|
|
103
|
108
|
match stream {
|
|
104
|
109
|
Some(Ok(stream)) => {
|
|
105
|
110
|
let mut stream = stream;
|
|
106
|
|
- match handle_cli_client(&mut stream, &mut directories, db.clone()).await {
|
|
107
|
|
- Ok(()) => {}
|
|
|
111
|
+ let mut output = Vec::new();
|
|
|
112
|
+ match handle_cli_client(&mut stream, &mut output, &mut directories, db.clone()).await {
|
|
|
113
|
+ Ok(()) => {
|
|
|
114
|
+ stream.write_all(&0i32.to_be_bytes()).await.ok();
|
|
|
115
|
+ stream.write_all(&output).await.ok();
|
|
|
116
|
+ }
|
|
108
|
117
|
Err(e) => {
|
|
109
|
118
|
// Log error and try to send it to the stream.
|
|
110
|
|
- // TODO: We want to send a return code as well.
|
|
|
119
|
+ error!("CLI command failed: {:?}", e);
|
|
|
120
|
+ stream.write_all(&(-1i32).to_be_bytes()).await.ok();
|
|
|
121
|
+ stream.write_all(&output).await.ok();
|
|
111
|
122
|
stream
|
|
112
|
123
|
.write_all(format!("Error: {:?}", e).as_bytes())
|
|
113
|
124
|
.await
|
|
|
@@ -153,17 +164,35 @@ async fn main() {
|
|
153
|
164
|
|
|
154
|
165
|
async fn handle_cli_client(
|
|
155
|
166
|
stream: &mut UnixStream,
|
|
|
167
|
+ output: &mut Vec<u8>,
|
|
156
|
168
|
directories: &mut Vec<SynchronizedDirectory>,
|
|
157
|
169
|
_db: Arc<Mutex<Database>>,
|
|
158
|
170
|
) -> Result<(), Error> {
|
|
159
|
171
|
let mut request = String::new();
|
|
160
|
172
|
stream.read_to_string(&mut request).await?;
|
|
|
173
|
+ // We must not write to the stream here, as we need to prepend the status code to any other
|
|
|
174
|
+ // output.
|
|
|
175
|
+ drop(stream);
|
|
161
|
176
|
|
|
162
|
177
|
let options: cli::Options = serde_json::from_str(&request)?;
|
|
163
|
178
|
let verbose = options.verbose;
|
|
164
|
179
|
match options.command {
|
|
165
|
180
|
_cmd @ cli::Command::ListDirectories { .. } => {
|
|
166
|
|
- // TODO
|
|
|
181
|
+ write!(output, "{} directories\n", directories.len()).ok();
|
|
|
182
|
+ for directory in directories.iter() {
|
|
|
183
|
+ write!(
|
|
|
184
|
+ output,
|
|
|
185
|
+ "\nDirectory: {}\nActive: {}\nLast error: {}\n",
|
|
|
186
|
+ directory.path.to_string_lossy(),
|
|
|
187
|
+ !directory.paused,
|
|
|
188
|
+ if directory.last_error.is_some() {
|
|
|
189
|
+ format!("{:?}", directory.last_error.as_ref().unwrap())
|
|
|
190
|
+ } else {
|
|
|
191
|
+ "None".to_owned()
|
|
|
192
|
+ }
|
|
|
193
|
+ )
|
|
|
194
|
+ .ok();
|
|
|
195
|
+ }
|
|
167
|
196
|
}
|
|
168
|
197
|
_cmd @ cli::Command::AddDirectory { .. } => {
|
|
169
|
198
|
// TODO
|
|
|
@@ -175,35 +204,19 @@ async fn handle_cli_client(
|
|
175
|
204
|
for directory in directories.iter_mut() {
|
|
176
|
205
|
directory.pause().await;
|
|
177
|
206
|
if verbose {
|
|
178
|
|
- stream
|
|
179
|
|
- .write_all(
|
|
180
|
|
- format!("Paused {}.\n", directory.path.to_string_lossy()).as_bytes(),
|
|
181
|
|
- )
|
|
182
|
|
- .await
|
|
183
|
|
- .ok();
|
|
|
207
|
+ write!(output, "Paused {}.\n", directory.path.to_string_lossy()).ok();
|
|
184
|
208
|
}
|
|
185
|
209
|
}
|
|
186
|
|
- stream
|
|
187
|
|
- .write_all("Synchronization paused.\n".as_bytes())
|
|
188
|
|
- .await
|
|
189
|
|
- .ok();
|
|
|
210
|
+ write!(output, "Synchronization paused.\n").ok();
|
|
190
|
211
|
}
|
|
191
|
212
|
cli::Command::Resume => {
|
|
192
|
213
|
for directory in directories.iter_mut() {
|
|
193
|
214
|
directory.unpause().await;
|
|
194
|
215
|
if verbose {
|
|
195
|
|
- stream
|
|
196
|
|
- .write_all(
|
|
197
|
|
- format!("Resumed {}.\n", directory.path.to_string_lossy()).as_bytes(),
|
|
198
|
|
- )
|
|
199
|
|
- .await
|
|
200
|
|
- .ok();
|
|
|
216
|
+ write!(output, "Resumed {}.\n", directory.path.to_string_lossy()).ok();
|
|
201
|
217
|
}
|
|
202
|
218
|
}
|
|
203
|
|
- stream
|
|
204
|
|
- .write_all("Synchronization resumed.\n".as_bytes())
|
|
205
|
|
- .await
|
|
206
|
|
- .ok();
|
|
|
219
|
+ write!(output, "Synchronization resumed.\n").ok();
|
|
207
|
220
|
}
|
|
208
|
221
|
}
|
|
209
|
222
|
|