Skip to content

Commit

Permalink
Merge branch 'improve-documentation'
Browse files Browse the repository at this point in the history
  • Loading branch information
faern committed Feb 1, 2018
2 parents 122586c + 46f526a commit 290fc79
Show file tree
Hide file tree
Showing 9 changed files with 168 additions and 126 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## SystemConfiguration bindings

This crate is a high level binding to the Apple [SystemConfiguration] framework. For low level
FFI bindings, check out the [`system-configuration-sys`] crate.

This crate only implements a small part of the [SystemConfiguration] framework so far. If you
need a yet unimplemented part, feel free to submit a pull request!

[SystemConfiguration]: https://developer.apple.com/documentation/systemconfiguration?language=objc
[`system-configuration-sys`]: https://crates.io/crates/system-configuration-sys

License: MIT/Apache-2.0
6 changes: 6 additions & 0 deletions system-configuration-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Low level bindings to the Apple [SystemConfiguration] framework. Generated with bindgen.
//! For a safe, higher level, API, check out the [`system-configuration`] crate.
//!
//! [SystemConfiguration]: https://developer.apple.com/documentation/systemconfiguration?language=objc
//! [`system-configuration`]: https://crates.io/crates/system-configuration
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
Expand Down
1 change: 1 addition & 0 deletions system-configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ keywords = ["macos", "system", "configuration", "bindings"]
categories = ["api-bindings", "os::macos-apis"]
repository = "https://github.com/mullvad/system-configuration-rs"
license = "MIT/Apache-2.0"
readme = "../README.md"

[dependencies]
core-foundation = "0.5"
Expand Down
53 changes: 53 additions & 0 deletions system-configuration/examples/set_dns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
extern crate system_configuration;

extern crate core_foundation;

use core_foundation::array::CFArray;
use core_foundation::base::TCFType;
use core_foundation::dictionary::CFDictionary;
use core_foundation::propertylist::CFPropertyList;
use core_foundation::string::{CFString, CFStringRef};

use system_configuration::dynamic_store::{SCDynamicStore, SCDynamicStoreBuilder};

// This example will change the DNS settings on the primary
// network interface to 8.8.8.8 and 8.8.4.4

fn main() {
let store = SCDynamicStoreBuilder::new("my-test-dyn-store").build();
let primary_service_uuid = get_primary_service_uuid(&store).expect("No PrimaryService active");
println!("PrimaryService UUID: {}", primary_service_uuid);

let primary_service_path = CFString::new(&format!(
"State:/Network/Service/{}/DNS",
primary_service_uuid
));
println!("PrimaryService path: {}", primary_service_path);

let dns_dictionary = create_dns_dictionary(&[
CFString::from_static_string("8.8.8.8"),
CFString::from_static_string("8.8.4.4"),
]);

let success = store.set(primary_service_path, dns_dictionary);
println!("success? {}", success);
}

fn get_primary_service_uuid(store: &SCDynamicStore) -> Option<CFString> {
let dictionary = store
.get("State:/Network/Global/IPv4")
.and_then(CFPropertyList::downcast_into::<CFDictionary>);
if let Some(dictionary) = dictionary {
dictionary
.find2(&CFString::from_static_string("PrimaryService"))
.map(|ptr| unsafe { CFString::wrap_under_get_rule(ptr as CFStringRef) })
} else {
None
}
}

fn create_dns_dictionary(addresses: &[CFString]) -> CFDictionary {
let key = CFString::from_static_string("ServerAddresses");
let value = CFArray::from_CFTypes(addresses);
CFDictionary::from_CFType_pairs(&[(key, value)])
}
79 changes: 79 additions & 0 deletions system-configuration/examples/watch_dns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
extern crate system_configuration;

extern crate core_foundation;

use core_foundation::array::CFArray;
use core_foundation::base::{CFType, TCFType};
use core_foundation::dictionary::CFDictionary;
use core_foundation::propertylist::CFPropertyList;
use core_foundation::runloop::{CFRunLoop, kCFRunLoopCommonModes};
use core_foundation::string::CFString;

use system_configuration::dynamic_store::{SCDynamicStore, SCDynamicStoreBuilder,
SCDynamicStoreCallBackContext};

// This example will watch the dynamic store for changes to any DNS setting. As soon as a change
// is detected, it will be printed to stdout.

fn main() {
let callback_context = SCDynamicStoreCallBackContext {
callout: my_callback,
info: Context { call_count: 0 },
};

let store = SCDynamicStoreBuilder::new("my-watch-dns-store")
.callback_context(callback_context)
.build();

let watch_keys: CFArray<CFString> = CFArray::from_CFTypes(&[]);
let watch_patterns =
CFArray::from_CFTypes(&[CFString::from("(State|Setup):/Network/Service/.*/DNS")]);

if store.set_notification_keys(&watch_keys, &watch_patterns) {
println!("Registered for notifications");
} else {
panic!("Unable to register notifications");
}

let run_loop_source = store.create_run_loop_source();
let run_loop = CFRunLoop::get_current();
run_loop.add_source(&run_loop_source, unsafe { kCFRunLoopCommonModes });

println!("Entering run loop");
CFRunLoop::run_current();
}

/// This struct acts as a user provided context/payload to each notification callback.
/// Here one can store any type of data or state needed in the callback function.
#[derive(Debug)]
struct Context {
call_count: u64,
}

fn my_callback(store: SCDynamicStore, changed_keys: CFArray<CFString>, context: &mut Context) {
context.call_count += 1;
println!("Callback call count: {}", context.call_count);

for key in changed_keys.iter() {
if let Some(addresses) = get_dns(&store, key.clone()) {
let addresses = addresses.iter().map(|s| s.to_string()).collect::<Vec<_>>();
println!("{} changed DNS to {:?}", *key, addresses);
} else {
println!("{} removed DNS", *key);
}
}
}

fn get_dns(store: &SCDynamicStore, path: CFString) -> Option<CFArray<CFString>> {
let dictionary = store
.get(path)
.and_then(CFPropertyList::downcast_into::<CFDictionary>);
if let Some(dictionary) = dictionary {
dictionary
.find2(&CFString::from_static_string("ServerAddresses"))
.map(|ptr| unsafe { CFType::wrap_under_get_rule(ptr) })
.and_then(CFType::downcast_into::<CFArray<CFString>>)
} else {
None
}
}
44 changes: 0 additions & 44 deletions system-configuration/src/bin/set_dns.rs

This file was deleted.

82 changes: 0 additions & 82 deletions system-configuration/src/bin/watch_dns.rs

This file was deleted.

6 changes: 6 additions & 0 deletions system-configuration/src/dynamic_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Bindings to [`SCDynamicStore`].
//!
//! See the examples directory for examples how to use this module.
//!
//! [`SCDynamicStore`]: https://developer.apple.com/documentation/systemconfiguration/scdynamicstore?language=objc
use core_foundation::array::{CFArray, CFArrayRef};
use core_foundation::base::{TCFType, kCFAllocatorDefault};
use core_foundation::boolean::CFBoolean;
Expand Down
11 changes: 11 additions & 0 deletions system-configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # SystemConfiguration bindings
//!
//! This crate is a high level binding to the Apple [SystemConfiguration] framework. For low level
//! FFI bindings, check out the [`system-configuration-sys`] crate.
//!
//! This crate only implements a small part of the [SystemConfiguration] framework so far. If you
//! need a yet unimplemented part, feel free to submit a pull request!
//!
//! [SystemConfiguration]: https://developer.apple.com/documentation/systemconfiguration?language=objc
//! [`system-configuration-sys`]: https://crates.io/crates/system-configuration-sys
#[macro_use]
extern crate core_foundation;
extern crate system_configuration_sys;
Expand Down

0 comments on commit 290fc79

Please sign in to comment.