Skip to content

Commit

Permalink
Merge pull request #18 from mach-kernel/090622/update-deps-fix-arm
Browse files Browse the repository at this point in the history
Update to latest crates, add aarch to build targets, misc cleanups
  • Loading branch information
mach-kernel committed Aug 13, 2023
2 parents ef9b870 + 7ce1549 commit 0f6348e
Show file tree
Hide file tree
Showing 22 changed files with 1,193 additions and 793 deletions.
1,260 changes: 790 additions & 470 deletions Cargo.lock

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions launchk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "launchk"
version = "0.1.4"
version = "0.2.0"
authors = ["David Stancu <dstancu@nyu.edu>"]
edition = "2018"

Expand All @@ -9,11 +9,15 @@ edition = "2018"
[dependencies]
xpc-sys = { path= "../xpc-sys" }
lazy_static = "1.4.0"
cursive = { version = "0.15.0", features = ["toml"] }
tokio = { version = "1", features = ["full"] }
futures = "0.3"
plist = "1.1.0"
bitflags = "1.2.1"
notify = "4.0.16"
log = "0.4.14"
env_logger = "0.8.3"
cursive = { version = "0.20.0", features = ["toml"] }
tokio = { version = "1.31.0", features = ["full"] }
futures = "0.3.28"
plist = "1.5.0"
bitflags = "2.4.0"
notify = "6.0.1"
log = "0.4.20"
env_logger = "0.10.0"
notify-debouncer-mini = { version = "*", default-features = false }
sudo = "0.6.0"
clearscreen = "2.0.1"
git-version = "0.3.5"
2 changes: 1 addition & 1 deletion launchk/src/launchd/entry_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lazy_static! {
Mutex::new(HashMap::new());
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct LaunchdEntryStatus {
pub plist: Option<LaunchdPlist>,
pub limit_load_to_session_type: SessionType,
Expand Down
16 changes: 15 additions & 1 deletion launchk/src/launchd/job_type_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::fmt;
use std::fmt::Formatter;

bitflags! {
#[derive(Default)]
#[derive(Clone, Copy, Default, Eq, PartialEq, Hash)]
/// Bitmask for filtering on the job type, which is a mix
/// of scope (where it's located), and kind (agent v. daemon)
pub struct JobTypeFilter: u32 {
Expand Down Expand Up @@ -56,3 +56,17 @@ impl fmt::Display for JobTypeFilter {
write!(f, "{}", display)
}
}

impl fmt::Debug for JobTypeFilter {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match *self {
JobTypeFilter::SYSTEM => write!(f, "SYSTEM"),
JobTypeFilter::GLOBAL => write!(f, "GLOBAL"),
JobTypeFilter::USER => write!(f, "USER"),
JobTypeFilter::AGENT => write!(f, "AGENT"),
JobTypeFilter::DAEMON => write!(f, "DAEMON"),
JobTypeFilter::LOADED => write!(f, "LOADED"),
_ => Ok(()),
}
}
}
2 changes: 1 addition & 1 deletion launchk/src/launchd/message.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use xpc_sys::traits::query_builder::QueryBuilder;
use xpc_sys::objects::xpc_dictionary::XPCDictionary;
use xpc_sys::traits::query_builder::QueryBuilder;

// A bunch of XPCDictionary 'protos' that can be extended to make XPC queries

Expand Down
123 changes: 54 additions & 69 deletions launchk/src/launchd/plist.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use std::borrow::Borrow;
use std::collections::HashMap;
use std::env;
use std::fmt;
use std::fs;
use std::path::Path;
use std::path::{Path, PathBuf};
use std::sync::{Once, RwLock};

use crate::launchd::job_type_filter::JobTypeFilter;
use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use std::fs::{DirEntry, File, ReadDir};
use notify_debouncer_mini::{new_debouncer, notify::RecursiveMode, DebounceEventResult};
use std::fs::File;
use std::io::Read;
use std::iter::FilterMap;
use std::process::Command;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
Expand All @@ -34,7 +32,7 @@ od -xc binary.plist
*/
static PLIST_MAGIC: &str = "bplist00";

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum LaunchdEntryType {
/// Runs on behalf of currently logged in user
Agent,
Expand All @@ -48,12 +46,13 @@ impl fmt::Display for LaunchdEntryType {
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum LaunchdEntryLocation {
/// macOS system provided agent or daemon
System,
/// "Administrator provided" agent or daemon
/// TODO: is 'global' appropriate?
/// Admin provided agent or daemon in /Library,
/// would name it admin...but the [sguadl] filter
/// needs uniques
Global,
/// User provided agent
User,
Expand All @@ -65,7 +64,7 @@ impl fmt::Display for LaunchdEntryLocation {
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct LaunchdPlist {
pub entry_type: LaunchdEntryType,
pub entry_location: LaunchdEntryLocation,
Expand Down Expand Up @@ -97,65 +96,57 @@ impl LaunchdPlist {
}
}

pub const GLOBAL_LAUNCH_AGENTS: &str = "/Library/LaunchAgents";
pub const ADMIN_LAUNCH_AGENTS: &str = "/Library/LaunchAgents";
pub const SYSTEM_LAUNCH_AGENTS: &str = "/System/Library/LaunchAgents";

pub const ADMIN_LAUNCH_DAEMONS: &str = "/Library/LaunchDaemons";
pub const GLOBAL_LAUNCH_DAEMONS: &str = "/System/Library/LaunchDaemons";
pub const SYSTEM_LAUNCH_DAEMONS: &str = "/System/Library/LaunchDaemons";

async fn fsnotify_subscriber() {
let (tx, rx): (Sender<DebouncedEvent>, Receiver<DebouncedEvent>) = channel();
let mut watcher = watcher(tx, Duration::from_secs(5)).expect("Must make fsnotify watcher");
let (tx, rx): (Sender<DebounceEventResult>, Receiver<DebounceEventResult>) = channel();
let mut debouncer = new_debouncer(Duration::from_secs(5), None, tx).unwrap();
let watcher = debouncer.watcher();

// Register plist paths
let watchers = [
watcher.watch(Path::new(&*USER_LAUNCH_AGENTS), RecursiveMode::Recursive),
watcher.watch(Path::new(GLOBAL_LAUNCH_AGENTS), RecursiveMode::Recursive),
watcher.watch(Path::new(ADMIN_LAUNCH_AGENTS), RecursiveMode::Recursive),
watcher.watch(Path::new(SYSTEM_LAUNCH_AGENTS), RecursiveMode::Recursive),
watcher.watch(Path::new(ADMIN_LAUNCH_DAEMONS), RecursiveMode::Recursive),
watcher.watch(Path::new(GLOBAL_LAUNCH_DAEMONS), RecursiveMode::Recursive),
watcher.watch(Path::new(SYSTEM_LAUNCH_DAEMONS), RecursiveMode::Recursive),
];

for sub in watchers.iter() {
sub.as_ref().expect("Must subscribe to fs events");
}

loop {
let event = rx.recv();
if event.is_err() {
continue;
}

let event = event.unwrap();

let reload_plists = match event {
DebouncedEvent::Create(pb) => fs::read_dir(pb),
DebouncedEvent::Write(pb) => fs::read_dir(pb),
DebouncedEvent::Remove(pb) => fs::read_dir(pb),
DebouncedEvent::Rename(_, new) => fs::read_dir(new),
_ => continue,
};

if reload_plists.is_err() {
continue;
}

insert_plists(readdir_filter_plists(reload_plists.unwrap()));
let events = rx
.recv()
.map(|dbr| dbr.ok())
.ok()
.flatten()
.unwrap_or(vec![]);

let paths: Vec<PathBuf> = events
.iter()
.filter_map(|e| path_if_plist(&e.path))
.collect();

insert_plists(paths.into_iter());
}
}

fn build_label_map_entry(plist_path: DirEntry) -> Option<(String, LaunchdPlist)> {
let path = plist_path.path();
let path_string = path.to_string_lossy().to_string();

let label = plist::Value::from_file(path.clone()).ok()?;
fn build_label_map_entry(plist_path: PathBuf) -> Option<(String, LaunchdPlist)> {
let path_string = plist_path.to_string_lossy().to_string();
let label = plist::Value::from_file(&path_string).ok()?;
let label = label
.as_dictionary()
.and_then(|d| d.get("Label"))
.and_then(|v| v.as_string());

let entry_type = if path_string.starts_with(ADMIN_LAUNCH_DAEMONS)
|| path_string.starts_with(GLOBAL_LAUNCH_DAEMONS)
|| path_string.starts_with(SYSTEM_LAUNCH_DAEMONS)
{
LaunchdEntryType::Daemon
} else {
Expand All @@ -164,7 +155,7 @@ fn build_label_map_entry(plist_path: DirEntry) -> Option<(String, LaunchdPlist)>

let entry_location = if path_string.starts_with(&*USER_LAUNCH_AGENTS) {
LaunchdEntryLocation::User
} else if path_string.starts_with(GLOBAL_LAUNCH_AGENTS)
} else if path_string.starts_with(ADMIN_LAUNCH_AGENTS)
|| path_string.starts_with(ADMIN_LAUNCH_DAEMONS)
{
LaunchdEntryLocation::Global
Expand All @@ -178,41 +169,33 @@ fn build_label_map_entry(plist_path: DirEntry) -> Option<(String, LaunchdPlist)>
entry_location,
entry_type,
plist_path: path_string,
readonly: path
readonly: plist_path
.metadata()
.map(|m| m.permissions().readonly())
.unwrap_or(true),
},
))
}

fn readdir_filter_plists(
rd: ReadDir,
) -> FilterMap<ReadDir, fn(futures::io::Result<DirEntry>) -> Option<DirEntry>> {
rd.filter_map(|e| {
if e.is_err() {
return None;
}

let path = e.borrow().as_ref().unwrap().path();

if path.is_dir()
|| path
.extension()
.map(|ex| ex.to_string_lossy().ne("plist"))
.unwrap_or(true)
{
None
} else {
Some(e.unwrap())
}
})
fn path_if_plist(path: &PathBuf) -> Option<PathBuf> {
if path.is_dir()
|| path
.extension()
.map(|ex| ex.to_string_lossy().ne("plist"))
.unwrap_or(true)
{
None
} else {
Some(path.clone())
}
}

fn insert_plists(plists: impl Iterator<Item = DirEntry>) {
fn insert_plists(plists: impl Iterator<Item = PathBuf>) {
let mut label_map = LABEL_TO_ENTRY_CONFIG.write().expect("Must update");

for plist_path in plists {
log::info!("Loading plist {:?}", plist_path);

let entry = build_label_map_entry(plist_path);
if entry.is_none() {
continue;
Expand All @@ -228,17 +211,19 @@ fn insert_plists(plists: impl Iterator<Item = DirEntry>) {
pub fn init_plist_map(runtime_handle: &Handle) {
let dirs = [
&USER_LAUNCH_AGENTS,
GLOBAL_LAUNCH_AGENTS,
ADMIN_LAUNCH_AGENTS,
SYSTEM_LAUNCH_AGENTS,
ADMIN_LAUNCH_DAEMONS,
GLOBAL_LAUNCH_DAEMONS,
SYSTEM_LAUNCH_DAEMONS,
];

// Get all the plists from everywhere into one stream
let plists = dirs
.iter()
.filter_map(|&dirname| fs::read_dir(Path::new(dirname)).ok())
.flat_map(readdir_filter_plists);
.flat_map(|rd| rd.map(|e| e.ok()))
.flatten()
.filter_map(|d| path_if_plist(&d.path()));

insert_plists(plists);

Expand Down
Loading

0 comments on commit 0f6348e

Please sign in to comment.