ghidra-version-manager 0.7.2

Ghidra Version Manager
use crate::cache::CacheEntry;
use crate::prefs_backup::gvm_config::GvmConfig;
use anyhow::Context;
use std::io::{Cursor, Read};
use std::path::Path;
use tracing::info;
use zip::ZipArchive;

pub struct BackupRestorer {
    pub backup_data: Vec<u8>,
}

impl BackupRestorer {
    pub fn from_path(p: &Path) -> anyhow::Result<Self> {
        Ok(Self {
            backup_data: std::fs::read(p)?,
        })
    }
    pub fn restore_to_cached_version(&self, cache_entry: &CacheEntry) -> anyhow::Result<()> {
        let home = std::env::home_dir().context("Couldn't determine home directory")?;

        let name = cache_entry.path.file_name().unwrap();
        let pref_path = home
            .join("./.config/ghidra/")
            .join(name)
            .join("./preferences");

        let zip_data = Cursor::new(&self.backup_data);
        let mut zip = ZipArchive::new(zip_data)?;

        let mut prefs = zip.by_path("/prefs").context("Prefs not found")?;
        let mut prefs_data = Vec::new();
        prefs.read_to_end(&mut prefs_data)?;
        drop(prefs);

        let mut cfg = zip
            .by_path("/gvm_config.toml")
            .context("Config not found")?;
        let mut cfg_data = Vec::new();
        cfg.read_to_end(&mut cfg_data)?;
        let cfg = toml::from_slice::<GvmConfig>(&cfg_data)?;

        info!("Restoring backup version {} from {}", cfg.version, cfg.tag);

        std::fs::write(pref_path, prefs_data)?;

        Ok(())
    }
}