diff --git a/src/bin/proxmox-backup-client.rs b/src/bin/proxmox-backup-client.rs index 1fd2c54a..66e6a3ba 100644 --- a/src/bin/proxmox-backup-client.rs +++ b/src/bin/proxmox-backup-client.rs @@ -485,22 +485,9 @@ fn dump_catalog( true, ).await?; - let tmpfile = std::fs::OpenOptions::new() - .write(true) - .read(true) - .custom_flags(libc::O_TMPFILE) - .open("/tmp")?; - let manifest = client.download_manifest().await?; - let tmpfile = client.download(CATALOG_NAME, tmpfile).await?; - - let index = DynamicIndexReader::new(tmpfile) - .map_err(|err| format_err!("unable to read catalog index - {}", err))?; - - // Note: do not use values stored in index (not trusted) - instead, computed them again - let (csum, size) = index.compute_csum(); - manifest.verify_file(CATALOG_NAME, &csum, size)?; + let index = client.download_dynamic_index(&manifest, CATALOG_NAME).await?; let most_used = index.find_most_used_chunks(8); @@ -1077,14 +1064,8 @@ async fn restore_do(param: Value) -> Result { } } else if server_archive_name.ends_with(".didx") { - let tmpfile = client.download(&server_archive_name, tmpfile).await?; - let index = DynamicIndexReader::new(tmpfile) - .map_err(|err| format_err!("unable to read dynamic index '{}' - {}", archive_name, err))?; - - // Note: do not use values stored in index (not trusted) - instead, computed them again - let (csum, size) = index.compute_csum(); - manifest.verify_file(&server_archive_name, &csum, size)?; + let index = client.download_dynamic_index(&manifest, &server_archive_name).await?; let most_used = index.find_most_used_chunks(8); @@ -1753,23 +1734,10 @@ async fn mount_do(param: Value, pipe: Option) -> Result { true, ).await?; - let tmpfile = std::fs::OpenOptions::new() - .write(true) - .read(true) - .custom_flags(libc::O_TMPFILE) - .open("/tmp")?; - let manifest = client.download_manifest().await?; if server_archive_name.ends_with(".didx") { - let tmpfile = client.download(&server_archive_name, tmpfile).await?; - let index = DynamicIndexReader::new(tmpfile) - .map_err(|err| format_err!("unable to read dynamic index '{}' - {}", archive_name, err))?; - - // Note: do not use values stored in index (not trusted) - instead, computed them again - let (csum, size) = index.compute_csum(); - manifest.verify_file(&server_archive_name, &csum, size)?; - + let index = client.download_dynamic_index(&manifest, &server_archive_name).await?; let most_used = index.find_most_used_chunks(8); let chunk_reader = RemoteChunkReader::new(client.clone(), crypt_config, most_used); let reader = BufferedDynamicReader::new(index, chunk_reader); diff --git a/src/client/backup_reader.rs b/src/client/backup_reader.rs index 3c30a2f9..01bba7f7 100644 --- a/src/client/backup_reader.rs +++ b/src/client/backup_reader.rs @@ -1,6 +1,7 @@ use failure::*; use std::io::Write; use std::sync::Arc; +use std::os::unix::fs::OpenOptionsExt; use chrono::{DateTime, Utc}; use serde_json::{json, Value}; @@ -133,4 +134,32 @@ impl BackupReader { BackupManifest::try_from(json) } + + /// Download dynamic index file + /// + /// This creates a temorary file in /tmp (using O_TMPFILE). The index is verified using + /// the provided manifest. + pub async fn download_dynamic_index( + &self, + manifest: &BackupManifest, + name: &str, + ) -> Result { + + let tmpfile = std::fs::OpenOptions::new() + .write(true) + .read(true) + .custom_flags(libc::O_TMPFILE) + .open("/tmp")?; + + let tmpfile = self.download(name, tmpfile).await?; + + let index = DynamicIndexReader::new(tmpfile) + .map_err(|err| format_err!("unable to read dynamic index '{}' - {}", name, err))?; + + // Note: do not use values stored in index (not trusted) - instead, computed them again + let (csum, size) = index.compute_csum(); + manifest.verify_file(name, &csum, size)?; + + Ok(index) + } }