87 lines
2.9 KiB
Rust
87 lines
2.9 KiB
Rust
use std::collections::BTreeMap;
|
|
|
|
use clap::crate_name;
|
|
|
|
use osquery_rust::plugin::{ColumnDef, ColumnType, Plugin, Table};
|
|
use osquery_rust::prelude::*;
|
|
|
|
#[osquery_rust::args]
|
|
fn main() -> std::io::Result<()> {
|
|
let args = Args::parse();
|
|
|
|
if !args.standalone {
|
|
let mut manager =
|
|
Server::new(Some(crate_name!()), args.socket().unwrap().as_str()).unwrap();
|
|
|
|
manager.register_plugin(Plugin::Table(Table::new(
|
|
"xbps_packages",
|
|
xbps_packages_columns(),
|
|
xbps_packages_generate,
|
|
)));
|
|
|
|
manager.run();
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn xbps_packages_columns() -> Vec<ColumnDef> {
|
|
vec![
|
|
ColumnDef::new("name", ColumnType::Text),
|
|
ColumnDef::new("version", ColumnType::Text),
|
|
ColumnDef::new("description", ColumnType::Text),
|
|
ColumnDef::new("homepage", ColumnType::Text),
|
|
ColumnDef::new("maintainer", ColumnType::Text),
|
|
ColumnDef::new("install_date", ColumnType::Text),
|
|
ColumnDef::new("license", ColumnType::Text),
|
|
ColumnDef::new("repository", ColumnType::Text),
|
|
]
|
|
}
|
|
|
|
fn xbps_packages_generate(_req: ExtensionPluginRequest) -> ExtensionResponse {
|
|
let mut resp = ExtensionPluginResponse::new();
|
|
|
|
let pkgdb: plist::Value =
|
|
plist::from_file("/var/db/xbps/pkgdb-0.38.plist").expect("failed to read pkgdb");
|
|
|
|
if let plist::Value::Dictionary(pkgdb) = pkgdb {
|
|
for (name, pkg) in pkgdb {
|
|
if let plist::Value::Dictionary(pkg) = pkg {
|
|
let pkgmap: Result<BTreeMap<String, String>, String> = vec![
|
|
("name", pkg.get("pkgname")),
|
|
("version", pkg.get("pkgver")),
|
|
("description", pkg.get("short_desc")),
|
|
("homepage", pkg.get("homepage")),
|
|
("maintainer", pkg.get("maintainer")),
|
|
("install_date", pkg.get("install-date")),
|
|
("license", pkg.get("license")),
|
|
("repository", pkg.get("repository")),
|
|
]
|
|
.into_iter()
|
|
.map(|(key, value)| {
|
|
match value {
|
|
Some(plist::Value::String(value)) => Ok((key.to_owned(), value.to_owned())),
|
|
None => Err(format!("{name} has no {key} field")),
|
|
Some(_) => Err(format!("{name} has an invalid type in {key}")),
|
|
}
|
|
.map(|(key, value)| {
|
|
if key == "version" {
|
|
let (_, value) = value.split_at(name.len() + 1);
|
|
(key, value.into())
|
|
} else {
|
|
(key, value)
|
|
}
|
|
})
|
|
})
|
|
.collect();
|
|
|
|
if let Ok(pkgmap) = pkgmap {
|
|
resp.push(pkgmap);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ExtensionResponse::new(ExtensionStatus::default(), resp)
|
|
}
|