You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
CleanFlashInstaller/rust/crates/clean_flash_installer/src/installer_linux.rs

107 lines
3.6 KiB
Rust

use crate::install_flags::{self, InstallFlags};
use clean_flash_common::{native_host, InstallError, ProgressCallback};
use std::fs;
use std::io::{self, Cursor};
/// Extract native-host and pp64 entries from the embedded 7z archive,
/// placing them next to each other in the native host install directory.
fn install_from_archive(
archive_bytes: &[u8],
form: &dyn ProgressCallback,
) -> Result<(), InstallError> {
let native_host_dir = native_host::get_native_host_install_dir();
let _ = fs::create_dir_all(&native_host_dir);
form.update_progress_label("Extracting native messaging host files...", true);
sevenz_rust2::decompress_with_extract_fn(
Cursor::new(archive_bytes),
".",
|entry, reader, _dest| {
if entry.is_directory() {
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
return Ok(true);
}
let entry_name = entry.name().to_string();
let parts: Vec<&str> = entry_name.split('/').collect();
if parts.is_empty() {
return Ok(true);
}
let dirname = parts[0];
let install_key = dirname.split('-').next().unwrap_or(dirname);
// Only extract native-host-64, pp64, and uninstaller entries.
let dominated = dirname == "native-host-64"
|| install_key == "pp64"
|| install_key == "uninstaller";
if !dominated {
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
return Ok(true);
}
// Skip debug variants of pp64.
if install_key == "pp64" && dirname.contains("-debug") {
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
return Ok(true);
}
if dirname == "native-host-64" {
form.update_progress_label("Installing native messaging host...", true);
} else if install_key == "pp64" {
form.update_progress_label("Installing Pepper plugin files...", true);
} else if install_key == "uninstaller" {
form.update_progress_label("Extracting uninstaller...", true);
}
let out_name = parts.last().unwrap_or(&dirname);
let out_path = native_host_dir.join(out_name);
let mut buf = Vec::new();
reader
.read_to_end(&mut buf)
.map_err(sevenz_rust2::Error::from)?;
fs::write(&out_path, &buf).map_err(sevenz_rust2::Error::from)?;
// Make binaries executable.
#[cfg(unix)]
if dirname == "native-host-64" || install_key == "uninstaller" {
use std::os::unix::fs::PermissionsExt;
let _ = fs::set_permissions(&out_path, fs::Permissions::from_mode(0o755));
}
Ok(true)
},
)
.map_err(|e| InstallError::new(format!("Failed to extract archive: {}", e)))?;
Ok(())
}
/// Main install entry point for Linux.
pub fn install(
form: &dyn ProgressCallback,
flags: &mut InstallFlags,
) -> Result<(), InstallError> {
if flags.is_none_set() {
return Ok(());
}
#[cfg(target_os = "linux")]
let archive_bytes: &[u8] = include_bytes!("../cleanflash-linux.7z");
#[cfg(target_os = "macos")]
let archive_bytes: &[u8] = include_bytes!("../cleanflash-macos.7z");
if archive_bytes.is_empty() {
return Ok(());
}
if flags.is_set(install_flags::NATIVE_HOST) {
install_from_archive(archive_bytes, form)?;
native_host::install_native_host(form)?;
}
Ok(())
}