summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock9
-rw-r--r--Cargo.toml1
-rw-r--r--mullvad-platform-metadata/Cargo.toml12
-rw-r--r--mullvad-platform-metadata/src/lib.rs151
-rw-r--r--mullvad-problem-report/Cargo.toml5
-rw-r--r--mullvad-problem-report/src/metadata.rs155
6 files changed, 176 insertions, 157 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b7c07e91e2..36841748bc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1322,6 +1322,13 @@ dependencies = [
]
[[package]]
+name = "mullvad-platform-metadata"
+version = "0.1.0"
+dependencies = [
+ "rs-release",
+]
+
+[[package]]
name = "mullvad-problem-report"
version = "2020.8.0-beta2"
dependencies = [
@@ -1332,9 +1339,9 @@ dependencies = [
"err-derive",
"lazy_static",
"mullvad-paths",
+ "mullvad-platform-metadata",
"mullvad-rpc",
"regex",
- "rs-release",
"talpid-types",
"tokio",
"uuid",
diff --git a/Cargo.toml b/Cargo.toml
index f87705cf22..4d155d203a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,7 @@ members = [
"mullvad-problem-report",
"mullvad-jni",
"mullvad-paths",
+ "mullvad-platform-metadata",
"mullvad-types",
"mullvad-rpc",
# "mullvad-tests",
diff --git a/mullvad-platform-metadata/Cargo.toml b/mullvad-platform-metadata/Cargo.toml
new file mode 100644
index 0000000000..d1ba2f6a14
--- /dev/null
+++ b/mullvad-platform-metadata/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "mullvad-platform-metadata"
+version = "0.1.0"
+authors = ["Mullvad VPN"]
+description = "Platform metadata detection functions"
+license = "GPL-3.0"
+edition = "2018"
+publish = false
+
+
+[target.'cfg(target_os = "linux")'.dependencies]
+rs-release = "0.1.7"
diff --git a/mullvad-platform-metadata/src/lib.rs b/mullvad-platform-metadata/src/lib.rs
new file mode 100644
index 0000000000..bcdc640ee6
--- /dev/null
+++ b/mullvad-platform-metadata/src/lib.rs
@@ -0,0 +1,151 @@
+use std::process::Command;
+
+#[cfg(target_os = "linux")]
+mod imp {
+ pub fn version() -> String {
+ // The OS version information is obtained first from the os-release file. If that
+ // information is incomplete or unavailable, an attempt is made to obtain the
+ // version information from the lsb_release command. If that fails, any partial
+ // information from os-release is used if available, or a fallback message if
+ // reading from the os-release file produced
+ // no version information.
+ let version = read_os_release_file().unwrap_or_else(|incomplete_info| {
+ parse_lsb_release().unwrap_or_else(|| {
+ incomplete_info.unwrap_or_else(|| String::from("[Failed to detect version]"))
+ })
+ });
+
+ format!("Linux {}", version)
+ }
+
+ fn read_os_release_file() -> Result<String, Option<String>> {
+ let mut os_release_info = rs_release::get_os_release().map_err(|_| None)?;
+ let os_name = os_release_info.remove("NAME");
+ let os_version = os_release_info.remove("VERSION");
+
+ if os_name.is_some() || os_version.is_some() {
+ let full_info_available = os_name.is_some() && os_version.is_some();
+
+ let gathered_info = format!(
+ "{} {}",
+ os_name.unwrap_or_else(|| "[unknown distribution]".to_owned()),
+ os_version.unwrap_or_else(|| "[unknown version]".to_owned())
+ );
+
+ if full_info_available {
+ Ok(gathered_info)
+ } else {
+ // Partial version information
+ Err(Some(gathered_info))
+ }
+ } else {
+ // No information was obtained
+ Err(None)
+ }
+ }
+
+ fn parse_lsb_release() -> Option<String> {
+ super::command_stdout_lossy("lsb_release", &["-ds"]).and_then(|output| {
+ if output.is_empty() {
+ None
+ } else {
+ Some(output)
+ }
+ })
+ }
+
+ pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
+ std::iter::empty()
+ }
+}
+
+#[cfg(target_os = "macos")]
+mod imp {
+ pub fn version() -> String {
+ format!(
+ "macOS {}",
+ super::command_stdout_lossy("sw_vers", &["-productVersion"])
+ .unwrap_or(String::from("[Failed to detect version]"))
+ )
+ }
+
+ pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
+ std::iter::empty()
+ }
+}
+
+#[cfg(windows)]
+mod imp {
+ pub fn version() -> String {
+ let system_info =
+ super::command_stdout_lossy("systeminfo", &["/FO", "LIST"]).unwrap_or_else(String::new);
+
+ let mut version = None;
+ let mut full_version = None;
+
+ for info_line in system_info.lines() {
+ let mut info_parts = info_line.split(":");
+
+ match info_parts.next() {
+ Some("OS Name") => {
+ version = info_parts
+ .next()
+ .map(|s| s.trim().trim_start_matches("Microsoft Windows "))
+ }
+ Some("OS Version") => full_version = info_parts.next().map(str::trim),
+ _ => {}
+ }
+ }
+
+ let version = version.unwrap_or("N/A");
+ let full_version = full_version.unwrap_or("N/A");
+ format!("Windows {} ({})", version, full_version)
+ }
+
+ pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
+ std::iter::empty()
+ }
+}
+
+#[cfg(target_os = "android")]
+mod imp {
+ use std::collections::HashMap;
+
+ pub fn version() -> String {
+ let version = get_prop("ro.build.version.release").unwrap_or_else(|| "N/A".to_owned());
+ let api_level = get_prop("ro.build.version.sdk").unwrap_or_else(|| "N/A".to_owned());
+
+ let manufacturer =
+ get_prop("ro.product.manufacturer").unwrap_or_else(|| "Unknown brand".to_owned());
+ let product = get_prop("ro.product.model").unwrap_or_else(|| "Unknown model".to_owned());
+
+ format!(
+ "Android {} (API: {}) - {} {}",
+ version, api_level, manufacturer, product
+ )
+ }
+
+ pub fn extra_metadata() -> HashMap<String, String> {
+ let mut metadata = HashMap::new();
+ metadata.insert(
+ "abi".to_owned(),
+ get_prop("ro.product.cpu.abilist").unwrap_or_else(|| "N/A".to_owned()),
+ );
+ metadata
+ }
+
+ fn get_prop(property: &str) -> Option<String> {
+ super::command_stdout_lossy("getprop", &[property])
+ }
+}
+
+/// Helper for getting stdout of some command as a String. Ignores the exit code of the command.
+fn command_stdout_lossy(cmd: &str, args: &[&str]) -> Option<String> {
+ Command::new(cmd)
+ .args(args)
+ .output()
+ .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_string())
+ .ok()
+}
+
+pub use imp::{extra_metadata, version};
diff --git a/mullvad-problem-report/Cargo.toml b/mullvad-problem-report/Cargo.toml
index 79ae9b757d..18a749650f 100644
--- a/mullvad-problem-report/Cargo.toml
+++ b/mullvad-problem-report/Cargo.toml
@@ -18,6 +18,7 @@ uuid = { version = "0.8", features = ["v4"] }
tokio = { version = "0.2", features = [ "rt-core" ] }
mullvad-paths = { path = "../mullvad-paths" }
+mullvad-platform-metadata = { path = "../mullvad-platform-metadata" }
mullvad-rpc = { path = "../mullvad-rpc" }
talpid-types = { path = "../talpid-types" }
@@ -26,10 +27,6 @@ talpid-types = { path = "../talpid-types" }
duct = "0.13"
-[target.'cfg(target_os = "linux")'.dependencies]
-rs-release = "0.1.7"
-
-
[target.'cfg(windows)'.build-dependencies]
winres = "0.1"
winapi = "0.3"
diff --git a/mullvad-problem-report/src/metadata.rs b/mullvad-problem-report/src/metadata.rs
index 1e4d6c864d..0d7eecfb47 100644
--- a/mullvad-problem-report/src/metadata.rs
+++ b/mullvad-problem-report/src/metadata.rs
@@ -1,5 +1,4 @@
-use std::{collections::BTreeMap, process::Command};
-
+use std::collections::BTreeMap;
pub const PRODUCT_VERSION: &str = include_str!(concat!(env!("OUT_DIR"), "/product-version.txt"));
@@ -10,155 +9,7 @@ pub fn collect() -> BTreeMap<String, String> {
"mullvad-product-version".to_owned(),
PRODUCT_VERSION.to_owned(),
);
- metadata.insert("os".to_owned(), os::version());
- metadata.extend(os::extra_metadata());
+ metadata.insert("os".to_owned(), mullvad_platform_metadata::version());
+ metadata.extend(mullvad_platform_metadata::extra_metadata());
metadata
}
-
-#[cfg(target_os = "linux")]
-mod os {
- pub fn version() -> String {
- // The OS version information is obtained first from the os-release file. If that
- // information is incomplete or unavailable, an attempt is made to obtain the
- // version information from the lsb_release command. If that fails, any partial
- // information from os-release is used if available, or a fallback message if
- // reading from the os-release file produced
- // no version information.
- let version = read_os_release_file().unwrap_or_else(|incomplete_info| {
- parse_lsb_release().unwrap_or_else(|| {
- incomplete_info.unwrap_or_else(|| String::from("[Failed to detect version]"))
- })
- });
-
- format!("Linux {}", version)
- }
-
- fn read_os_release_file() -> Result<String, Option<String>> {
- let mut os_release_info = rs_release::get_os_release().map_err(|_| None)?;
- let os_name = os_release_info.remove("NAME");
- let os_version = os_release_info.remove("VERSION");
-
- if os_name.is_some() || os_version.is_some() {
- let full_info_available = os_name.is_some() && os_version.is_some();
-
- let gathered_info = format!(
- "{} {}",
- os_name.unwrap_or_else(|| "[unknown distribution]".to_owned()),
- os_version.unwrap_or_else(|| "[unknown version]".to_owned())
- );
-
- if full_info_available {
- Ok(gathered_info)
- } else {
- // Partial version information
- Err(Some(gathered_info))
- }
- } else {
- // No information was obtained
- Err(None)
- }
- }
-
- fn parse_lsb_release() -> Option<String> {
- super::command_stdout_lossy("lsb_release", &["-ds"]).and_then(|output| {
- if output.is_empty() {
- None
- } else {
- Some(output)
- }
- })
- }
-
- pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
- std::iter::empty()
- }
-}
-
-#[cfg(target_os = "macos")]
-mod os {
- pub fn version() -> String {
- format!(
- "macOS {}",
- super::command_stdout_lossy("sw_vers", &["-productVersion"])
- .unwrap_or(String::from("[Failed to detect version]"))
- )
- }
-
- pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
- std::iter::empty()
- }
-}
-
-#[cfg(windows)]
-mod os {
- pub fn version() -> String {
- let system_info =
- super::command_stdout_lossy("systeminfo", &["/FO", "LIST"]).unwrap_or_else(String::new);
-
- let mut version = None;
- let mut full_version = None;
-
- for info_line in system_info.lines() {
- let mut info_parts = info_line.split(":");
-
- match info_parts.next() {
- Some("OS Name") => {
- version = info_parts
- .next()
- .map(|s| s.trim().trim_start_matches("Microsoft Windows "))
- }
- Some("OS Version") => full_version = info_parts.next().map(str::trim),
- _ => {}
- }
- }
-
- let version = version.unwrap_or("N/A");
- let full_version = full_version.unwrap_or("N/A");
- format!("Windows {} ({})", version, full_version)
- }
-
- pub fn extra_metadata() -> impl Iterator<Item = (String, String)> {
- std::iter::empty()
- }
-}
-
-#[cfg(target_os = "android")]
-mod os {
- use std::collections::HashMap;
-
- pub fn version() -> String {
- let version = get_prop("ro.build.version.release").unwrap_or_else(|| "N/A".to_owned());
- let api_level = get_prop("ro.build.version.sdk").unwrap_or_else(|| "N/A".to_owned());
-
- let manufacturer =
- get_prop("ro.product.manufacturer").unwrap_or_else(|| "Unknown brand".to_owned());
- let product = get_prop("ro.product.model").unwrap_or_else(|| "Unknown model".to_owned());
-
- format!(
- "Android {} (API: {}) - {} {}",
- version, api_level, manufacturer, product
- )
- }
-
- pub fn extra_metadata() -> HashMap<String, String> {
- let mut metadata = HashMap::new();
- metadata.insert(
- "abi".to_owned(),
- get_prop("ro.product.cpu.abilist").unwrap_or_else(|| "N/A".to_owned()),
- );
- metadata
- }
-
- fn get_prop(property: &str) -> Option<String> {
- super::command_stdout_lossy("getprop", &[property])
- }
-}
-
-/// Helper for getting stdout of some command as a String. Ignores the exit code of the command.
-fn command_stdout_lossy(cmd: &str, args: &[&str]) -> Option<String> {
- Command::new(cmd)
- .args(args)
- .output()
- .map(|output| String::from_utf8_lossy(&output.stdout).trim().to_string())
- .ok()
-}