fix(client): don't create local file if remote file doesn't exist

Previously, the get command would create/truncate the local file before
starting the download, then delete it on error. This could inadvertently
destroy an existing local file if the remote file didn't exist.

Now the download completes to memory first, and the local file is only
written after a successful transfer. This is safe for TFTP since files
are typically small (bootloaders, configs, etc.).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 13:41:49 +01:00
parent 35cc9ee036
commit 27d891111f

View File

@@ -248,30 +248,28 @@ fn main() -> ExitCode {
}
};
// Create output file
let mut file = match File::create(&local_file) {
Ok(f) => f,
// Download to memory first - only create local file on success
let data = match client.get(&remote_file, args.mode) {
Ok(data) => data,
Err(e) => {
eprintln!("Error creating file '{local_file}': {e}");
eprintln!("Error: {e}");
return ExitCode::FAILURE;
}
};
// Download
match client.get_to_writer(&remote_file, args.mode, &mut file) {
Ok(bytes) => {
if args.verbose {
eprintln!("Received {bytes} bytes");
}
println!("Downloaded '{remote_file}' -> '{local_file}' ({bytes} bytes)");
}
Err(e) => {
// Clean up partial file
let _ = std::fs::remove_file(&local_file);
eprintln!("Error: {e}");
// Write to local file
if let Err(e) = std::fs::write(&local_file, &data) {
eprintln!("Error writing file '{local_file}': {e}");
return ExitCode::FAILURE;
}
if args.verbose {
eprintln!("Received {} bytes", data.len());
}
println!(
"Downloaded '{remote_file}' -> '{local_file}' ({} bytes)",
data.len()
);
}
Command::Put {