Skip to content

Commit

Permalink
Add High-level API
Browse files Browse the repository at this point in the history
  • Loading branch information
luozijun committed Mar 13, 2018
1 parent 1356ce1 commit a75deee
Show file tree
Hide file tree
Showing 6 changed files with 590 additions and 43 deletions.
4 changes: 3 additions & 1 deletion system-configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@ readme = "../README.md"

[dependencies]
core-foundation = "0.5"

system-configuration-sys = { path = "../system-configuration-sys", version = "0.1" }

[features]
nightly = []
38 changes: 38 additions & 0 deletions system-configuration/examples/network_configuration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
extern crate core_foundation;
extern crate system_configuration;

use core_foundation::base::kCFAllocatorDefault;

use system_configuration::dynamic_store::SCDynamicStoreBuilder;
use system_configuration::network_configuration::{global_router, SCNetworkInterface,
SCNetworkService};
use system_configuration::preferences::SCPreferences;

// This example will output network-global-service, network-global-interface, network-global-router,
// network-service-order-list, network-services and network-interfaces to stdout.

fn main() {
let session_name = "session_name";
let prefs = SCPreferences::new(unsafe { kCFAllocatorDefault }, session_name, None);
let store = SCDynamicStoreBuilder::new(session_name).build();

let service = SCNetworkService::global(&prefs, &store).unwrap();
println!("Global Service:\n{:?}\n", service);
println!("Global Interface:\n{:?}\n", service.interface());
println!("Global Service Router:\n{:?}\n", global_router(&store));

println!("\n-listnetworkserviceorder:");
for service in SCNetworkService::list_order(&prefs) {
println!("{:?}", service);
}

println!("\n-listallnetworkservices:");
for service in SCNetworkService::list(&prefs) {
println!("{:?}", service);
}

println!("\n-listallnetworkinterface:");
for interface in SCNetworkInterface::list() {
println!("{:?}", interface);
}
}
95 changes: 54 additions & 41 deletions system-configuration/examples/set_dns.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,66 @@
extern crate core_foundation;
extern crate system_configuration;

extern crate core_foundation;
use core_foundation::base::kCFAllocatorDefault;


use system_configuration::dynamic_store::SCDynamicStoreBuilder;
use system_configuration::network_configuration::SCNetworkService;
use system_configuration::preferences::SCPreferences;

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};
use std::net::{IpAddr, Ipv4Addr};


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

// Usage:

// $ cargo build --example set_dns
// $ sudo ../target/debug/examples/set_dns

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);
}
let addrs = vec![
IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)),
IpAddr::V4(Ipv4Addr::new(8, 8, 4, 4)),
];

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
}
}
let session_name = "session_name";
let store = SCDynamicStoreBuilder::new(session_name).build();
let prefs = SCPreferences::new(unsafe { kCFAllocatorDefault }, session_name, None);

let global_service =
SCNetworkService::global(&prefs, &store).expect("No PrimaryService active");
let global_interface = global_service
.interface()
.expect("No PrimaryInterface active");

println!("Global Service:");
println!("\tid: {:?}", global_service.id());
println!("\tname: {:?}", global_service.name());
println!("\tenabled: {:?}", global_service.enabled());
println!("\tdns: {:?}", global_service.dns(&store));
println!("\tinterface: {:?}", global_interface.name().unwrap());

println!(
"Set dns to {:?} on {:?} service ...",
addrs,
global_service.name()
);


println!(
"Success: {:?}",
global_service.set_dns_server_addresses(&store, Some(addrs))
);

// Check
// `networksetup -getdnsservers "Wi-Fi"` Or `scutil --dns` Or `dig`
println!("{:?}", global_service.dns(&store));

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)])
println!(
"\n\nUse Command `networksetup -setdnsservers \"{}\" \"Empty\"` to restore DNS setting. ",
global_service.name()
);
}
6 changes: 5 additions & 1 deletion system-configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
//!
//! [SystemConfiguration]: https://developer.apple.com/documentation/systemconfiguration?language=objc
//! [`system-configuration-sys`]: https://crates.io/crates/system-configuration-sys
#![cfg_attr(all(feature = "nightly", test), feature(test))]
#![deny(missing_docs)]

#[macro_use]
extern crate core_foundation;
extern crate system_configuration_sys;
#[cfg(all(feature = "nightly", test))]
extern crate test;

pub mod dynamic_store;
pub mod preferences;
pub mod network_configuration;
Loading

0 comments on commit a75deee

Please sign in to comment.