Skip to content

Commit eb2edac

Browse files
author
luozijun
committed
Update
1 parent 51f5dbb commit eb2edac

File tree

4 files changed

+95
-44
lines changed

4 files changed

+95
-44
lines changed

system-configuration/examples/set_dns.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1+
extern crate core_foundation;
12
extern crate system_configuration;
23

4+
use core_foundation::base::kCFAllocatorDefault;
5+
6+
37
use system_configuration::dynamic_store::SCDynamicStoreBuilder;
48
use system_configuration::network_configuration::SCNetworkService;
9+
use system_configuration::preferences::SCPreferences;
10+
511

612
use std::net::{IpAddr, Ipv4Addr};
713

14+
815
// This example will change the DNS settings on the primary
916
// network interface to 8.8.8.8 and 8.8.4.4
1017

@@ -19,9 +26,12 @@ fn main() {
1926
IpAddr::V4(Ipv4Addr::new(8, 8, 4, 4)),
2027
];
2128

22-
let store = SCDynamicStoreBuilder::new("session_name").build();
29+
let session_name = "session_name";
30+
let store = SCDynamicStoreBuilder::new(session_name).build();
31+
let prefs = SCPreferences::new(unsafe { kCFAllocatorDefault }, session_name, None);
2332

24-
let global_service = SCNetworkService::global(&store).expect("No PrimaryService active");
33+
let global_service =
34+
SCNetworkService::global(&prefs, &store).expect("No PrimaryService active");
2535
let global_interface = global_service
2636
.interface()
2737
.expect("No PrimaryInterface active");
@@ -46,9 +56,7 @@ fn main() {
4656
);
4757

4858
// Check
49-
// networksetup -getdnsservers "Wi-Fi"
50-
// scutil --dns
51-
// dig
59+
// `networksetup -getdnsservers "Wi-Fi"` Or `scutil --dns` Or `dig`
5260
println!("{:?}", global_service.dns(&store));
5361

5462
println!(

system-configuration/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ extern crate core_foundation;
2424
extern crate system_configuration_sys;
2525

2626
pub mod dynamic_store;
27+
pub mod preferences;
2728
pub mod network_configuration;

system-configuration/src/network_configuration.rs

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@
1212
//!
1313
//! [`SCNetworkConfiguration`]: https://developer.apple.com/documentation/systemconfiguration/scnetworkconfiguration
1414
15+
1516
use core_foundation::array::CFArray;
1617
use core_foundation::base::{CFType, TCFType};
17-
use core_foundation::base::kCFAllocatorDefault;
1818
use core_foundation::dictionary::CFDictionary;
1919
use core_foundation::string::CFString;
2020

2121
use dynamic_store::SCDynamicStore;
22+
use preferences::SCPreferences;
23+
2224
pub use system_configuration_sys::network_configuration::*;
23-
use system_configuration_sys::preferences::SCPreferencesCreate;
2425

25-
use std::{fmt, ptr};
26+
use std::fmt;
2627
use std::net::IpAddr;
2728

2829
/// MTU
@@ -100,48 +101,45 @@ impl_TCFType!(
100101

101102
impl SCNetworkService {
102103
/// Returns primary network service
103-
pub fn global(store: &SCDynamicStore) -> Option<Self> {
104-
if let Some(service_id) = global_query(store, "PrimaryService") {
105-
for service in SCNetworkService::list() {
106-
if service.id() == service_id {
107-
return Some(service);
108-
}
109-
}
104+
pub fn global(prefs: &SCPreferences, store: &SCDynamicStore) -> Option<Self> {
105+
match global_query(store, "PrimaryService") {
106+
Some(service_id) => SCNetworkService::from_id(prefs, &service_id),
107+
None => None,
110108
}
111-
112-
return None;
113109
}
114110

115-
/// Returns all available network services for the specified preferences.
116-
pub fn list() -> Vec<SCNetworkService> {
117-
let prefs = unsafe {
118-
SCPreferencesCreate(
119-
kCFAllocatorDefault,
120-
CFString::from_static_string("ns_list").as_concrete_TypeRef(),
121-
ptr::null(),
111+
/// Returns network service for the specified preferences session and service ID.
112+
pub fn from_id(prefs: &SCPreferences, service_id: &str) -> Option<SCNetworkService> {
113+
let network_service_ref = unsafe {
114+
SCNetworkServiceCopy(
115+
prefs.as_concrete_TypeRef(),
116+
CFString::new(service_id).as_concrete_TypeRef(),
122117
)
123118
};
124119

125-
let array: CFArray<CFType> =
126-
unsafe { CFArray::wrap_under_get_rule(SCNetworkServiceCopyAll(prefs)) };
120+
if network_service_ref.is_null() {
121+
None
122+
} else {
123+
Some(unsafe { SCNetworkService::wrap_under_get_rule(network_service_ref) })
124+
}
125+
}
126+
127+
/// Returns all available network services for the specified preferences.
128+
pub fn list(prefs: &SCPreferences) -> Vec<SCNetworkService> {
129+
let array: CFArray<CFType> = unsafe {
130+
CFArray::wrap_under_get_rule(SCNetworkServiceCopyAll(prefs.as_concrete_TypeRef()))
131+
};
127132

128133
array
129134
.iter()
130135
.map(|item| item.downcast::<SCNetworkService>().unwrap())
131136
.collect::<Vec<SCNetworkService>>()
132137
}
133138

134-
/// Returns the user-specified ordering of network services within the specified set.
135-
pub fn list_order() -> Vec<SCNetworkService> {
136-
let prefs = unsafe {
137-
SCPreferencesCreate(
138-
kCFAllocatorDefault,
139-
CFString::from_static_string("ns_list_order").as_concrete_TypeRef(),
140-
ptr::null(),
141-
)
142-
};
143-
144-
let netset = unsafe { SCNetworkSetCopyCurrent(prefs) };
139+
/// Returns the user-specified ordering of network services within the specified
140+
/// preferences.
141+
pub fn list_order(prefs: &SCPreferences) -> Vec<SCNetworkService> {
142+
let netset = unsafe { SCNetworkSetCopyCurrent(prefs.as_concrete_TypeRef()) };
145143

146144
let array: CFArray<CFType> =
147145
unsafe { CFArray::wrap_under_get_rule(SCNetworkSetGetServiceOrder(netset)) };
@@ -150,13 +148,8 @@ impl SCNetworkService {
150148

151149
for item in array.iter() {
152150
if let Some(id) = item.downcast::<CFString>() {
153-
let service_ref = unsafe {
154-
CFType::wrap_under_get_rule(SCNetworkServiceCopy(
155-
prefs,
156-
id.as_concrete_TypeRef(),
157-
))
158-
};
159-
if let Some(serv) = service_ref.downcast::<SCNetworkService>() {
151+
println!("id: {:?}", id);
152+
if let Some(serv) = SCNetworkService::from_id(prefs, id.to_string().as_str()) {
160153
services.push(serv);
161154
}
162155
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2017 Amagicom AB.
2+
//
3+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. This file may not be copied, modified, or distributed
7+
// except according to those terms.
8+
9+
//! Bindings to [`SCPreferences`].
10+
//!
11+
//! See the examples directory for examples how to use this module.
12+
//!
13+
//! [`SCPreferences`]: https://developer.apple.com/documentation/systemconfiguration/scpreferences
14+
15+
16+
use core_foundation::base::CFAllocatorRef;
17+
use core_foundation::base::TCFType;
18+
use core_foundation::string::CFString;
19+
20+
pub use system_configuration_sys::preferences::*;
21+
22+
use std::ptr;
23+
24+
25+
declare_TCFType!{
26+
/// The handle to an open preferences session for accessing system configuration preferences.
27+
SCPreferences, SCPreferencesRef
28+
}
29+
30+
impl_TCFType!(SCPreferences, SCPreferencesRef, SCPreferencesGetTypeID);
31+
32+
33+
impl SCPreferences {
34+
/// Initiates access to the per-system set of configuration preferences.
35+
pub fn new(allocator: CFAllocatorRef, name: &str, prefs_id: Option<&str>) -> Self {
36+
let prefs_id = match prefs_id {
37+
Some(prefs_id) => CFString::new(prefs_id).as_concrete_TypeRef(),
38+
None => ptr::null(),
39+
};
40+
41+
unsafe {
42+
SCPreferences::wrap_under_get_rule(SCPreferencesCreate(
43+
allocator,
44+
CFString::new(name).as_concrete_TypeRef(),
45+
prefs_id,
46+
))
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)