mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
105 lines
3.2 KiB
Rust
105 lines
3.2 KiB
Rust
// Copyright: Ankitects Pty Ltd and contributors
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
use std::process::Command;
|
|
|
|
use anyhow::Context;
|
|
use anyhow::Result;
|
|
|
|
pub fn relaunch_in_terminal() -> Result<()> {
|
|
let current_exe = std::env::current_exe().context("Failed to get current executable path")?;
|
|
|
|
// Try terminals in roughly most specific to least specific.
|
|
// First, try commonly used terminals for riced systems.
|
|
// Second, try common defaults.
|
|
// Finally, try x11 compatibility terminals.
|
|
let terminals = [
|
|
// commonly used for riced systems
|
|
("alacritty", vec!["-e"]),
|
|
("kitty", vec![]),
|
|
("foot", vec![]),
|
|
// the user's default terminal in Debian/Ubuntu
|
|
("x-terminal-emulator", vec!["-e"]),
|
|
// default installs for the most common distros
|
|
("xfce4-terminal", vec!["-e"]),
|
|
("gnome-terminal", vec!["-e"]),
|
|
("konsole", vec!["-e"]),
|
|
// x11-compatibility terminals
|
|
("urxvt", vec!["-e"]),
|
|
("xterm", vec!["-e"]),
|
|
];
|
|
|
|
for (terminal_cmd, args) in &terminals {
|
|
// Check if terminal exists
|
|
if Command::new("which")
|
|
.arg(terminal_cmd)
|
|
.output()
|
|
.map(|o| o.status.success())
|
|
.unwrap_or(false)
|
|
{
|
|
// Try to launch the terminal
|
|
let mut cmd = Command::new(terminal_cmd);
|
|
if args.is_empty() {
|
|
cmd.arg(¤t_exe);
|
|
} else {
|
|
cmd.args(args).arg(¤t_exe);
|
|
}
|
|
|
|
if cmd.spawn().is_ok() {
|
|
std::process::exit(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
// If no terminal worked, continue without relaunching
|
|
Ok(())
|
|
}
|
|
|
|
pub fn finalize_uninstall() {
|
|
use std::io::stdin;
|
|
use std::io::stdout;
|
|
use std::io::Write;
|
|
|
|
let uninstall_script = std::path::Path::new("/usr/local/share/anki/uninstall.sh");
|
|
|
|
if uninstall_script.exists() {
|
|
println!("To finish uninstalling, run 'sudo /usr/local/share/anki/uninstall.sh'");
|
|
} else {
|
|
println!("Anki has been uninstalled.");
|
|
}
|
|
println!("Press enter to quit.");
|
|
let _ = stdout().flush();
|
|
let mut input = String::new();
|
|
let _ = stdin().read_line(&mut input);
|
|
}
|
|
|
|
pub fn ensure_glibc_supported() -> Result<()> {
|
|
use std::ffi::CStr;
|
|
let get_glibc_version = || -> Option<(u32, u32)> {
|
|
let version_ptr = unsafe { libc::gnu_get_libc_version() };
|
|
if version_ptr.is_null() {
|
|
return None;
|
|
}
|
|
|
|
let version_cstr = unsafe { CStr::from_ptr(version_ptr) };
|
|
let version_str = version_cstr.to_str().ok()?;
|
|
|
|
// Parse version string (format: "2.36" or "2.36.1")
|
|
let version_parts: Vec<&str> = version_str.split('.').collect();
|
|
if version_parts.len() < 2 {
|
|
return None;
|
|
}
|
|
|
|
let major: u32 = version_parts[0].parse().ok()?;
|
|
let minor: u32 = version_parts[1].parse().ok()?;
|
|
|
|
Some((major, minor))
|
|
};
|
|
|
|
let (major, minor) = get_glibc_version().unwrap_or_default();
|
|
if major < 2 || (major == 2 && minor < 36) {
|
|
anyhow::bail!("Anki requires a modern Linux distro with glibc 2.36 or later.");
|
|
}
|
|
|
|
Ok(())
|
|
}
|