diff --git a/Cargo.lock b/Cargo.lock
index 14aae8f..9210fa7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1158,8 +1158,6 @@ dependencies = [
[[package]]
name = "eframe"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0d49426c3e72a6728b0c790d22db8bf7bbcff10d83b8b6f3a01295be982302e"
dependencies = [
"bytemuck",
"egui",
@@ -1180,8 +1178,6 @@ dependencies = [
[[package]]
name = "egui"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc9fcd393c3daaaf5909008a1d948319d538b79c51871e4df0993260260a94e4"
dependencies = [
"ahash 0.8.0",
"epaint",
@@ -1192,8 +1188,6 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07ddc525334c416e11580123e147b970f738507f427c9fb1cd09ea2dd7416a3a"
dependencies = [
"arboard",
"egui",
@@ -1207,8 +1201,6 @@ dependencies = [
[[package]]
name = "egui_extras"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f698f685bb0ad39e87109e2f695ded0bccde77d5d40bbf7590cb5561c1e3039d"
dependencies = [
"egui",
"image",
@@ -1217,8 +1209,6 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad77d4a00402bae9658ee64be148f4b2a0b38e4fc7874970575ca01ed1c5b75d"
dependencies = [
"bytemuck",
"egui",
@@ -1238,8 +1228,6 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
[[package]]
name = "emath"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9542a40106fdba943a055f418d1746a050e1a903a049b030c2b097d4686a33cf"
dependencies = [
"bytemuck",
]
@@ -1296,8 +1284,6 @@ dependencies = [
[[package]]
name = "epaint"
version = "0.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ba04741be7f6602b1a1b28f1082cce45948a7032961c52814f8946b28493300"
dependencies = [
"ab_glyph",
"ahash 0.8.0",
@@ -1809,7 +1795,6 @@ dependencies = [
"reqwest",
"rusqlite",
"serde",
- "serde_derive",
"serde_json",
"sha2 0.10.6",
"tar",
diff --git a/Cargo.toml b/Cargo.toml
index a16b273..e5fa50a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,17 +10,17 @@ arti-hyper = "0.7.0"
bytes = "1.2.1"
chrono = "0.4.22"
dirs = "4.0.0"
-eframe = "0.19.0"
-egui = "0.19.0"
-egui_extras = { version = "0.19.0", features = ["image"] }
+#eframe = "0.19.0"
+#egui = "0.19.0"
+#egui_extras = { version = "0.19.0", features = ["image"] }
## [external/egui/crates/eframe/src/native/run.rs] line 41: [.with_srgb(true)]
## This line causes a [panic!] inside a Windows VM, from a Linux host.
## There are many issue threads and PRs to fix it but for now,
## this is here for convenience sake when I'm testing.
## The only change is [.with_srgb()] is set to [false].
-#eframe = { path = "external/egui/crates/eframe" }
-#egui = { path = "external/egui/crates/egui" }
-#egui_extras = { path = "external/egui/crates/egui_extras", features = ["image"] }
+eframe = { path = "external/egui/crates/eframe" }
+egui = { path = "external/egui/crates/egui" }
+egui_extras = { path = "external/egui/crates/egui_extras", features = ["image"] }
env_logger = "0.9.1"
figment = { version = "0.10.8", features = ["toml"] }
flate2 = "1.0"
@@ -37,24 +37,29 @@ rand = "0.8.5"
regex = "1.6.0"
reqwest = { version = "0.11.12", features = ["blocking", "json"] }
rusqlite = { version = "0.28.0", features = ["bundled"] }
-serde = "1.0.145"
-serde_derive = "1.0.145"
+serde = { version = "1.0.145", features = ["rc", "derive"] }
serde_json = "1.0"
sha2 = "0.10.6"
-tar = "0.4.38"
tls-api = "0.9.0"
tls-api-native-tls = "0.9.0"
tokio = { version = "1.21.2", features = ["full"] }
toml = "0.5.9"
tor-rtcompat = "0.7.0"
walkdir = "2.3.2"
+
+# Unix dependencies
+[target.'cfg(unix)'.dependencies]
+tar = "0.4.38"
+
+# Windows dependencies
+[target.'cfg(windows)'.dependencies]
zip = "0.6.3"
-# For Windows
+# For Windows build (icon)
[target.'cfg(windows)'.build-dependencies]
winres = "0.1.12"
-# For macOS (cargo-bundle)
+# For macOS build (cargo-bundle)
[package.metadata.bundle]
identifier = "io.github.hinto-janaiyo.gupax"
icon = ["images/png/icon@2x.png"]
diff --git a/src/gupax.rs b/src/gupax.rs
index a1cf49a..8c92d29 100644
--- a/src/gupax.rs
+++ b/src/gupax.rs
@@ -16,7 +16,7 @@
// along with this program. If not, see .
use std::path::Path;
-use crate::App;
+use crate::{App,State};
use egui::WidgetType::Button;
use crate::constants::*;
use crate::state::{Gupax,Version};
@@ -26,7 +26,7 @@ use std::sync::{Arc,Mutex};
use log::*;
impl Gupax {
- pub fn show(state: &mut Gupax, og: &Gupax, width: f32, height: f32, update: &mut Update, version: Version, ctx: &egui::Context, ui: &mut egui::Ui) {
+ pub fn show(state: &mut Gupax, og: &Arc>, state_ver: &Arc>, update: &Arc>, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
// Update button + Progress bar
ui.group(|ui| {
// These are in unnecessary [ui.vertical()]'s
@@ -35,30 +35,44 @@ impl Gupax {
// I have to pick one. This one seperates them though.
let height = height/6.0;
let width = width - SPACE;
- let updating = *update.updating.lock().unwrap();
+ let updating = *update.lock().unwrap().updating.lock().unwrap();
ui.vertical(|ui| {
ui.set_enabled(!updating);
if ui.add_sized([width, height], egui::Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
- update.path_p2pool = og.absolute_p2pool_path.display().to_string();
- update.path_xmrig = og.absolute_xmrig_path.display().to_string();
- update.tor = og.update_via_tor;
- let update = Arc::new(Mutex::new(update.clone()));
+ update.lock().unwrap().path_p2pool = og.lock().unwrap().gupax.absolute_p2pool_path.display().to_string();
+ update.lock().unwrap().path_xmrig = og.lock().unwrap().gupax.absolute_xmrig_path.display().to_string();
+ update.lock().unwrap().tor = og.lock().unwrap().gupax.update_via_tor;
+ let og = Arc::clone(&og);
+ let og_ver = Arc::clone(&og.lock().unwrap().version);
+ let state_ver = Arc::clone(&state_ver);
+ let update = Arc::clone(&update);
+ let update_thread = Arc::clone(&update);
thread::spawn(move|| {
info!("Spawning update thread...");
- match Update::start(update.clone(), version) {
+ match Update::start(update_thread, og_ver.clone(), state_ver.clone()) {
Err(e) => {
- info!("Update | {} ... FAIL", e);
+ info!("Update ... {} ... FAIL", e);
*update.lock().unwrap().msg.lock().unwrap() = format!("{} | {}", MSG_FAILED, e);
- *update.lock().unwrap().updating.lock().unwrap() = false;
},
- _ => (),
- }
+ _ => {
+ info!("Update | Saving state...");
+ match State::save(&mut og.lock().unwrap()) {
+ Ok(_) => info!("Update ... OK"),
+ Err(e) => {
+ warn!("Update | Saving state ... FAIL ... {}", e);
+ *update.lock().unwrap().msg.lock().unwrap() = format!("Saving new versions into state failed");
+ },
+ };
+ }
+ };
+ *update.lock().unwrap().updating.lock().unwrap() = false;
});
}
});
ui.vertical(|ui| {
ui.set_enabled(updating);
- let msg = format!("{}\n{}{}", *update.msg.lock().unwrap(), *update.prog.lock().unwrap(), "%");
+ let prog = *update.lock().unwrap().prog.lock().unwrap();
+ let msg = format!("{}\n{}{}", *update.lock().unwrap().msg.lock().unwrap(), prog, "%");
ui.add_sized([width, height*1.4], egui::Label::new(msg));
let height = height/2.0;
if updating {
@@ -66,7 +80,7 @@ impl Gupax {
} else {
ui.add_sized([width, height], egui::Label::new("..."));
}
- ui.add_sized([width, height], egui::ProgressBar::new((update.prog.lock().unwrap().round() / 100.0)));
+ ui.add_sized([width, height], egui::ProgressBar::new((update.lock().unwrap().prog.lock().unwrap().round() / 100.0)));
});
});
diff --git a/src/main.rs b/src/main.rs
index da8b77e..32832b7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -16,7 +16,7 @@
// along with this program. If not, see .
// Hide console in Windows
-#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+//#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
//---------------------------------------------------------------------------------------------------- Imports
// egui/eframe
@@ -70,10 +70,10 @@ pub struct App {
width: f32, // Top-level width
height: f32, // Top-level height
// State
- og: State, // og = Old state to compare against
+ og: Arc>, // og = Old state to compare against
state: State, // state = Working state (current settings)
- update: Update, // State for update data [update.rs]
- diff: bool, // Instead of comparing [og == state] every frame, this bool indicates changes
+ update: Arc>, // State for update data [update.rs]
+ diff: bool, // This bool indicates state changes
// Process/update state:
// Doesn't make sense to save this on disk
// so it's represented as a bool here.
@@ -113,9 +113,9 @@ impl App {
width: 1280.0,
height: 720.0,
node: Arc::new(Mutex::new(NodeStruct::default())),
- og: State::default(),
+ og: Arc::new(Mutex::new(State::default())),
state: State::default(),
- update: Update::new(PathBuf::new(), PathBuf::new(), true),
+ update: Arc::new(Mutex::new(Update::new(PathBuf::new(), PathBuf::new(), true))),
diff: false,
p2pool: false,
xmrig: false,
@@ -141,16 +141,23 @@ impl App {
// Read disk state if no [--reset] arg
if app.reset == false {
app.og = match State::get() {
- Ok(toml) => toml,
+ Ok(toml) => Arc::new(Mutex::new(toml)),
Err(err) => { panic_main(err.to_string()); exit(1); },
};
}
- app.state = app.og.clone();
+ app.state = app.og.lock().unwrap().clone();
// Handle max threads
- app.og.xmrig.max_threads = num_cpus::get();
- if app.og.xmrig.current_threads > app.og.xmrig.max_threads { app.og.xmrig.current_threads = app.og.xmrig.max_threads; }
+ app.og.lock().unwrap().xmrig.max_threads = num_cpus::get();
+ let current = app.og.lock().unwrap().xmrig.current_threads;
+ let max = app.og.lock().unwrap().xmrig.max_threads;
+ if current > max {
+ app.og.lock().unwrap().xmrig.current_threads = max;
+ }
// Apply TOML values to [Update]
- app.update = Update::new(app.og.gupax.absolute_p2pool_path.clone(), app.og.gupax.absolute_xmrig_path.clone(), app.og.gupax.update_via_tor);
+ let p2pool_path = app.og.lock().unwrap().gupax.absolute_p2pool_path.clone();
+ let xmrig_path = app.og.lock().unwrap().gupax.absolute_xmrig_path.clone();
+ let tor = app.og.lock().unwrap().gupax.update_via_tor;
+ app.update = Arc::new(Mutex::new(Update::new(p2pool_path, xmrig_path, tor)));
app
}
}
@@ -304,6 +311,22 @@ pub fn get_rand_tmp(path: &String) -> String {
path
}
+// Clean any [gupax_tmp.*] directories
+pub fn clean_dir() -> Result<(), anyhow::Error> {
+ for entry in std::fs::read_dir(get_exe_dir()?)? {
+ let entry = entry?;
+ entry.path().is_dir() && continue;
+ if entry.file_name().to_str().ok_or(anyhow::Error::msg("Basename failed"))?.starts_with("gupax_tmp_") {
+ let path = entry.path();
+ match std::fs::remove_dir_all(&path) {
+ Ok(_) => info!("Remove [{}] ... OK", path.display()),
+ Err(e) => warn!("Remove [{}] ... FAIL ... {}", path.display(), e),
+ }
+ }
+ }
+ Ok(())
+}
+
//---------------------------------------------------------------------------------------------------- [App] frame for [Panic] situations
fn panic_main(error: String) {
error!("{}", error);
@@ -358,6 +381,10 @@ impl eframe::App for Panic {
fn main() {
init_logger();
let options = init_options();
+ match clean_dir() {
+ Ok(_) => info!("Temporary folder cleanup ... OK"),
+ Err(e) => warn!("Could not cleanup [gupax_tmp] folders: {}", e),
+ }
let app = App::new();
let name = app.name_version.clone();
eframe::run_native(&name, options, Box::new(|cc| Box::new(App::cc(cc, app))),);
@@ -366,7 +393,7 @@ fn main() {
impl eframe::App for App {
fn on_close_event(&mut self) -> bool {
self.quit = true;
- if self.og.gupax.ask_before_quit {
+ if self.og.lock().unwrap().gupax.ask_before_quit {
self.quit_confirm
} else {
true
@@ -390,6 +417,17 @@ impl eframe::App for App {
frame.set_fullscreen(!info.window_info.fullscreen);
}
+ // If no state diff (og == state), compare and enable if found.
+ // The struct fields are compared directly because [Version]
+ // contains Arc's that cannot be compared easily.
+ // They don't need to be compared anyway.
+ let og = self.og.lock().unwrap().clone();
+ if og.gupax != self.state.gupax || og.p2pool != self.state.p2pool || og.xmrig != self.state.xmrig {
+ self.diff = true;
+ } else {
+ self.diff = false;
+ }
+
// Close confirmation.
if self.quit {
// If [ask_before_quit == true]
@@ -521,12 +559,21 @@ impl eframe::App for App {
ui.with_layout(egui::Layout::right_to_left(egui::Align::RIGHT), |ui| {
ui.group(|ui| {
- if self.state == self.og {
+ if self.diff == false {
ui.set_enabled(false)
}
let width = width / 2.0;
- if ui.add_sized([width, height], egui::Button::new("Save")).on_hover_text("Save changes").clicked() { self.og = self.state.clone(); self.state.save(); }
- if ui.add_sized([width, height], egui::Button::new("Reset")).on_hover_text("Reset changes").clicked() { self.state = self.og.clone(); }
+ if ui.add_sized([width, height], egui::Button::new("Save")).on_hover_text("Save changes").clicked() {
+ self.og.lock().unwrap().gupax = self.state.gupax.clone();
+ self.og.lock().unwrap().p2pool = self.state.p2pool.clone();
+ self.og.lock().unwrap().xmrig = self.state.xmrig.clone();
+ self.og.lock().unwrap().save();
+ }
+ if ui.add_sized([width, height], egui::Button::new("Reset")).on_hover_text("Reset changes").clicked() {
+ self.state.gupax = self.og.lock().unwrap().gupax.clone();
+ self.state.p2pool = self.og.lock().unwrap().p2pool.clone();
+ self.state.xmrig = self.og.lock().unwrap().xmrig.clone();
+ }
});
let width = (ui.available_width() / 3.0) - 6.2;
@@ -615,7 +662,7 @@ impl eframe::App for App {
Status::show(self, self.width, self.height, ctx, ui);
}
Tab::Gupax => {
- Gupax::show(&mut self.state.gupax, &self.og.gupax, self.width, self.height, &mut self.update, self.og.version.clone(), ctx, ui);
+ Gupax::show(&mut self.state.gupax, &self.og, &self.state.version, &self.update, self.width, self.height, ctx, ui);
}
Tab::P2pool => {
P2pool::show(&mut self.state.p2pool, self.width, self.height, ctx, ui);
diff --git a/src/node.rs b/src/node.rs
index 007cbe9..bbfdbd5 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-use serde_derive::{Serialize,Deserialize};
+use serde::{Serialize,Deserialize};
use std::time::{Instant,Duration};
use std::collections::HashMap;
use std::error::Error;
diff --git a/src/state.rs b/src/state.rs
index 8e71d9a..9cae04d 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -32,7 +32,8 @@ use std::{fs,env};
use std::fmt::Display;
use std::path::{Path,PathBuf};
use std::result::Result;
-use serde_derive::{Serialize,Deserialize};
+use std::sync::{Arc,Mutex};
+use serde::{Serialize,Deserialize};
use figment::Figment;
use figment::providers::{Format,Toml};
use crate::constants::HORIZONTAL;
@@ -81,10 +82,10 @@ impl State {
pool: "localhost:3333".to_string(),
address: "".to_string(),
},
- version: Version {
- p2pool: P2POOL_VERSION.to_string(),
- xmrig: XMRIG_VERSION.to_string(),
- },
+ version: Arc::new(Mutex::new(Version {
+ p2pool: Arc::new(Mutex::new(P2POOL_VERSION.to_string())),
+ xmrig: Arc::new(Mutex::new(XMRIG_VERSION.to_string())),
+ })),
}
}
@@ -267,13 +268,13 @@ const DIRECTORY: &'static str = "gupax";
#[cfg(target_os = "windows")]
pub const DEFAULT_P2POOL_PATH: &'static str = r"P2Pool\p2pool.exe";
#[cfg(target_os = "macos")]
-pub const DEFAULT_P2POOL_PATH: &'static str = "P2Pool/p2pool";
+pub const DEFAULT_P2POOL_PATH: &'static str = "P2Pool/P2Pool";
#[cfg(target_os = "linux")]
pub const DEFAULT_P2POOL_PATH: &'static str = "p2pool/p2pool";
#[cfg(target_os = "windows")]
pub const DEFAULT_XMRIG_PATH: &'static str = r"XMRig\xmrig.exe";
#[cfg(target_os = "macos")]
-pub const DEFAULT_XMRIG_PATH: &'static str = "XMRig/xmrig";
+pub const DEFAULT_XMRIG_PATH: &'static str = "XMRig/XMRig";
#[cfg(target_os = "linux")]
pub const DEFAULT_XMRIG_PATH: &'static str = "xmrig/xmrig";
@@ -288,12 +289,12 @@ pub enum TomlError {
}
//---------------------------------------------------------------------------------------------------- Structs
-#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
+#[derive(Clone,Debug,Deserialize,Serialize)]
pub struct State {
pub gupax: Gupax,
pub p2pool: P2pool,
pub xmrig: Xmrig,
- pub version: Version,
+ pub version: Arc>,
}
#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
@@ -341,8 +342,8 @@ pub struct Xmrig {
// pub args: String,
}
-#[derive(Clone,Eq,PartialEq,Debug,Deserialize,Serialize)]
+#[derive(Clone,Debug,Deserialize,Serialize)]
pub struct Version {
- pub p2pool: String,
- pub xmrig: String,
+ pub p2pool: Arc>,
+ pub xmrig: Arc>,
}
diff --git a/src/update.rs b/src/update.rs
index e16c144..8a0f085 100644
--- a/src/update.rs
+++ b/src/update.rs
@@ -38,7 +38,7 @@ use hyper_tls::HttpsConnector;
use log::*;
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng};
-use serde_derive::{Serialize,Deserialize};
+use serde::{Serialize,Deserialize};
use std::io::{Read,Write};
use std::path::PathBuf;
use std::sync::{Arc,Mutex};
@@ -47,7 +47,11 @@ use tls_api::{TlsConnector, TlsConnectorBuilder};
use tokio::io::{AsyncReadExt,AsyncWriteExt};
use tokio::task::JoinHandle;
use walkdir::WalkDir;
+
+#[cfg(target_os = "windows")]
use zip::ZipArchive;
+#[cfg(target_family = "unix")]
+use std::os::unix::fs::OpenOptionsExt;
//---------------------------------------------------------------------------------------------------- Constants
// Package naming schemes:
@@ -81,26 +85,47 @@ const P2POOL_HASH: &'static str = "sha256sums.txt.asc";
const XMRIG_HASH: &'static str = "SHA256SUMS";
#[cfg(target_os = "windows")]
-const GUPAX_EXTENSION: &'static str = "-windows-standalone-x64.exe";
+const GUPAX_EXTENSION: &'static str = "-windows-x64-standalone.exe";
#[cfg(target_os = "windows")]
const P2POOL_EXTENSION: &'static str = "-windows-x64.zip";
#[cfg(target_os = "windows")]
const XMRIG_EXTENSION: &'static str = "-msvc-win64.zip";
#[cfg(target_os = "macos")]
-const GUPAX_EXTENSION: &'static str = "-macos-standalone-x64";
+const GUPAX_EXTENSION: &'static str = "-macos-x64-standalone";
#[cfg(target_os = "macos")]
const P2POOL_EXTENSION: &'static str = "-macos-x64.tar.gz";
#[cfg(target_os = "macos")]
const XMRIG_EXTENSION: &'static str = "-macos-x64.tar.gz";
#[cfg(target_os = "linux")]
-const GUPAX_EXTENSION: &'static str = "-linux-standalone-x64";
+const GUPAX_EXTENSION: &'static str = "-linux-x64-standalone";
#[cfg(target_os = "linux")]
const P2POOL_EXTENSION: &'static str = "-linux-x64.tar.gz";
#[cfg(target_os = "linux")]
const XMRIG_EXTENSION: &'static str = "-linux-static-x64.tar.gz";
+#[cfg(target_os = "windows")]
+const GUPAX_BINARY: &'static str = "gupax.exe";
+#[cfg(target_os = "macos")]
+const GUPAX_BINARY: &'static str = "Gupax";
+#[cfg(target_os = "linux")]
+const GUPAX_BINARY: &'static str = "gupax";
+
+#[cfg(target_os = "windows")]
+const P2POOL_BINARY: &'static str = "p2pool.exe";
+#[cfg(target_os = "macos")]
+const P2POOL_BINARY: &'static str = "P2Pool";
+#[cfg(target_os = "linux")]
+const P2POOL_BINARY: &'static str = "p2pool";
+
+#[cfg(target_os = "windows")]
+const XMRIG_BINARY: &'static str = "xmrig.exe";
+#[cfg(target_os = "macos")]
+const XMRIG_BINARY: &'static str = "XMRig";
+#[cfg(target_os = "linux")]
+const XMRIG_BINARY: &'static str = "xmrig";
+
// Some fake Curl/Wget user-agents because GitHub API requires one and a Tor browser
// user-agent might be fingerprintable without all the associated headers.
const FAKE_USER_AGENT: [&'static str; 50] = [
@@ -226,7 +251,7 @@ impl Update {
// Get a temporary random folder for package download contents
// This used to use [std::env::temp_dir()] but there were issues
// using [std::fs::rename()] on tmpfs -> disk (Invalid cross-device link (os error 18)).
- // So, uses the [Gupax] binary directory as a base, something like [/home/hinto/gupax/gupax_SG4xsDdVmr]
+ // So, uses the [Gupax] binary directory as a base, something like [/home/hinto/gupax/gupax_tmp_SG4xsDdVmr]
pub fn get_tmp_dir() -> Result {
let rand_string: String = thread_rng()
.sample_iter(&Alphanumeric)
@@ -235,9 +260,9 @@ impl Update {
.collect();
let base = crate::get_exe_dir()?;
#[cfg(target_os = "windows")]
- let tmp_dir = format!("{}{}{}{}", base, r"\gupax_", rand_string, r"\");
+ let tmp_dir = format!("{}{}{}{}", base, r"\gupax_tmp_", rand_string, r"\");
#[cfg(target_family = "unix")]
- let tmp_dir = format!("{}{}{}{}", base, "/gupax_", rand_string, "/");
+ let tmp_dir = format!("{}{}{}{}", base, "/gupax_tmp_", rand_string, "/");
info!("Update | Temporary directory ... {}", tmp_dir);
Ok(tmp_dir)
}
@@ -281,7 +306,7 @@ impl Update {
// 5. extract, upgrade
#[tokio::main]
- pub async fn start(update: Arc>, mut version: Version) -> Result<(), anyhow::Error> {
+ pub async fn start(update: Arc>, og_ver: Arc>, state_ver: Arc>) -> Result<(), anyhow::Error> {
//---------------------------------------------------------------------------------------------------- Init
*update.lock().unwrap().updating.lock().unwrap() = true;
// Set timer
@@ -408,28 +433,30 @@ impl Update {
match pkg.name {
Gupax => {
if new_ver == GUPAX_VERSION {
- info!("Update | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), GUPAX_VERSION);
+ info!("Update | {} {} == {} ... SKIPPING", pkg.name, GUPAX_VERSION, new_ver);
} else {
- info!("Update | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), GUPAX_VERSION);
- new_pkgs.push(format!("\nGupax {} ➡ {}", GUPAX_VERSION, pkg.new_ver.lock().unwrap()));
+ info!("Update | {} {} != {} ... ADDING", pkg.name, GUPAX_VERSION, new_ver);
+ new_pkgs.push(format!("\nGupax {} ➡ {}", GUPAX_VERSION, new_ver));
vec3.push(pkg);
}
}
P2pool => {
- if new_ver == version.p2pool {
- info!("Update | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), version.p2pool);
+ let old_ver = og_ver.lock().unwrap().p2pool.lock().unwrap().to_owned();
+ if old_ver == new_ver {
+ info!("Update | {} {} == {} ... SKIPPING", pkg.name, old_ver, new_ver);
} else {
- info!("Update | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), version.p2pool);
- new_pkgs.push(format!("\nP2Pool {} ➡ {}", version.p2pool, pkg.new_ver.lock().unwrap()));
+ info!("Update | {} {} != {} ... ADDING", pkg.name, old_ver, new_ver);
+ new_pkgs.push(format!("\nP2Pool {} ➡ {}", old_ver, new_ver));
vec3.push(pkg);
}
}
Xmrig => {
- if new_ver == GUPAX_VERSION {
- info!("Update | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), version.xmrig);
+ let old_ver = og_ver.lock().unwrap().xmrig.lock().unwrap().to_owned();
+ if old_ver == new_ver {
+ info!("Update | {} {} == {} ... SKIPPING", pkg.name, old_ver, new_ver);
} else {
- info!("Update | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), version.xmrig);
- new_pkgs.push(format!("\nXMRig {} ➡ {}", version.xmrig, pkg.new_ver.lock().unwrap()));
+ info!("Update | {} {} != {} ... ADDING", pkg.name, old_ver, new_ver);
+ new_pkgs.push(format!("\nXMRig {} ➡ {}", old_ver, new_ver));
vec3.push(pkg);
}
}
@@ -522,14 +549,13 @@ impl Update {
*update.lock().unwrap().msg.lock().unwrap() = format!("{}{}", MSG_EXTRACT, new_pkgs);
info!("Update | {}", EXTRACT);
for pkg in vec4.iter() {
- let tmp = tmp_dir.to_owned() + &pkg.name.to_string();
if pkg.name == Name::Gupax {
+ let tmp = tmp_dir.to_owned() + GUPAX_BINARY;
#[cfg(target_family = "unix")]
- use std::os::unix::fs::OpenOptionsExt;
- #[cfg(target_family = "unix")]
- std::fs::OpenOptions::new().create(true).write(true).mode(0o770).open(&tmp)?;
+ std::fs::OpenOptions::new().create(true).write(true).mode(0o750).open(&tmp)?;
std::fs::write(tmp, pkg.bytes.lock().unwrap().as_ref())?;
} else {
+ let tmp = tmp_dir.to_owned() + &pkg.name.to_string();
#[cfg(target_os = "windows")]
ZipArchive::extract(&mut ZipArchive::new(std::io::Cursor::new(pkg.bytes.lock().unwrap().as_ref()))?, tmp)?;
#[cfg(target_family = "unix")]
@@ -553,46 +579,55 @@ impl Update {
let entry = entry?.clone();
let basename = entry.file_name().to_str().ok_or(anyhow::Error::msg("WalkDir basename failed"))?;
match basename {
- "Gupax" => {
+ GUPAX_BINARY => {
let path = update.lock().unwrap().path_gupax.clone();
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path);
+ // Unix can replace running binaries no problem (they're loading into memory)
+ // Windows locks binaries in place, so we must move (rename) current binary
+ // into the temp folder, then move the new binary into the old ones spot.
+ // Clearing the temp folder is now moved at startup instead at the end
+ // of this function due to this behavior, thanks Windows.
+ #[cfg(target_os = "windows")]
+ std::fs::rename(&path, tmp_dir.clone() + "gupax_old.exe")?;
std::fs::rename(entry.path(), path)?;
*update.lock().unwrap().prog.lock().unwrap() += (5.0 / pkg_amount).round();
},
- "p2pool" => {
+ P2POOL_BINARY => {
let path = update.lock().unwrap().path_p2pool.clone();
let path = std::path::Path::new(&path);
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path.display());
std::fs::create_dir_all(path.parent().ok_or(anyhow::Error::msg("P2Pool path failed"))?)?;
std::fs::rename(entry.path(), path)?;
- version.p2pool = Pkg::get_new_pkg_version(P2pool, &vec4)?;
+ *og_ver.lock().unwrap().p2pool.lock().unwrap() = Pkg::get_new_pkg_version(P2pool, &vec4)?;
*update.lock().unwrap().prog.lock().unwrap() += (5.0 / pkg_amount).round();
},
- "xmrig" => {
+ XMRIG_BINARY => {
let path = update.lock().unwrap().path_xmrig.clone();
let path = std::path::Path::new(&path);
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path.display());
std::fs::create_dir_all(path.parent().ok_or(anyhow::Error::msg("XMRig path failed"))?)?;
std::fs::rename(entry.path(), path)?;
- version.xmrig = Pkg::get_new_pkg_version(Xmrig, &vec4)?;
+ *og_ver.lock().unwrap().xmrig.lock().unwrap() = Pkg::get_new_pkg_version(Xmrig, &vec4)?;
*update.lock().unwrap().prog.lock().unwrap() += (5.0 / pkg_amount).round();
},
_ => (),
}
}
+ // Remove tmp dir (on Unix)
+ #[cfg(target_family = "unix")]
info!("Update | Removing temporary directory ... {}", tmp_dir);
+ #[cfg(target_family = "unix")]
std::fs::remove_dir_all(&tmp_dir)?;
+
let seconds = now.elapsed().as_secs();
- info!("Update ... Seconds elapsed: [{}s]", seconds);
- info!("Update ... OK ... 100%");
+ info!("Update | Seconds elapsed ... [{}s]", seconds);
match seconds {
0 => *update.lock().unwrap().msg.lock().unwrap() = format!("{}! Took 0 seconds... Do you have 10Gbit internet or something...?!{}", MSG_SUCCESS, new_pkgs),
1 => *update.lock().unwrap().msg.lock().unwrap() = format!("{}! Took 1 second... Wow!{}", MSG_SUCCESS, new_pkgs),
_ => *update.lock().unwrap().msg.lock().unwrap() = format!("{}! Took {} seconds.{}", MSG_SUCCESS, seconds, new_pkgs),
}
*update.lock().unwrap().prog.lock().unwrap() = 100.0;
- *update.lock().unwrap().updating.lock().unwrap() = false;
Ok(())
}
}