feat(system): add package manager detection
Swadhin Biswas committed 7 months ago
aab76c1
1 parent 2a5e415
commit aab76c1
1 file changed
+80 -0
Showing 1 changed file+80-0
▼src/system/mod.rs
+80-0
| @@ -228,3 +228,83 @@ fn get_os() -> String { | ||
228 | 228 | return uname; |
229 | 229 | } |
230 | 230 | |
231 | + "Unknown".to_string() | |
232 | +} | |
233 | + | |
234 | +fn get_host() -> String { | |
235 | + // DMI: product_name + product_version | |
236 | + let name = read_first_line("/sys/class/dmi/id/product_name"); | |
237 | + let version = read_first_line("/sys/class/dmi/id/product_version"); | |
238 | + | |
239 | + if !name.is_empty() { | |
240 | + let name = filter_oem(&name); | |
241 | + if name.is_empty() { | |
242 | + return "Unknown".to_string(); | |
243 | + } | |
244 | + let version = filter_oem(&version); | |
245 | + if !version.is_empty() { | |
246 | + return format!("{} {}", name, version); | |
247 | + } | |
248 | + return name; | |
249 | + } | |
250 | + | |
251 | + // dmidecode fallback | |
252 | + let dmi = run_cmd("dmidecode", &["-s", "system-product-name"]); | |
253 | + let dmi = filter_oem(&dmi); | |
254 | + if !dmi.is_empty() { | |
255 | + return dmi; | |
256 | + } | |
257 | + | |
258 | + "Unknown".to_string() | |
259 | +} | |
260 | + | |
261 | +fn filter_oem(s: &str) -> String { | |
262 | + let s = s.trim(); | |
263 | + let lc = s.to_lowercase(); | |
264 | + if lc.is_empty() | |
265 | + || lc == "to be filled by o.e.m." | |
266 | + || lc == "not applicable" | |
267 | + || lc == "system product name" | |
268 | + || lc == "type1productconfigid" | |
269 | + || lc == "default string" | |
270 | + || lc == "undefined" | |
271 | + || lc == "not specified" | |
272 | + || lc == "none" | |
273 | + { | |
274 | + return String::new(); | |
275 | + } | |
276 | + s.to_string() | |
277 | +} | |
278 | + | |
279 | +fn get_kernel() -> String { | |
280 | + let k = run_cmd("uname", &["-r"]); | |
281 | + if k.is_empty() { | |
282 | + "Unknown".to_string() | |
283 | + } else { | |
284 | + k | |
285 | + } | |
286 | +} | |
287 | + | |
288 | +fn get_uptime() -> String { | |
289 | + // /proc/uptime: "seconds.frac idle_seconds.frac" | |
290 | + let content = read_file("/proc/uptime"); | |
291 | + if let Some(secs_str) = content.split_whitespace().next() { | |
292 | + if let Ok(secs_f) = secs_str.parse::<f64>() { | |
293 | + let secs = secs_f as u64; | |
294 | + return format_uptime(secs); | |
295 | + } | |
296 | + } | |
297 | + // Fallback | |
298 | + let up = run_cmd("uptime", &["-p"]); | |
299 | + if !up.is_empty() { | |
300 | + return up.trim_start_matches("up ").to_string(); | |
301 | + } | |
302 | + "Unknown".to_string() | |
303 | +} | |
304 | + | |
305 | +fn format_uptime(total_secs: u64) -> String { | |
306 | + let days = total_secs / 86400; | |
307 | + let hours = (total_secs % 86400) / 3600; | |
308 | + let mins = (total_secs % 3600) / 60; | |
309 | + | |
310 | + let mut parts = Vec::new(); | |
231 | 311 | |