-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'improve-documentation'
- Loading branch information
Showing
9 changed files
with
168 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters