cyfs_util/util/
bdt_util.rs

1use crate::*;
2use cyfs_base::*;
3
4use std::path::Path;
5
6pub fn get_desc_from_file(
7    desc_path: &Path,
8    secret_path: &Path,
9) -> BuckyResult<(StandardObject, PrivateKey)> {
10    debug!("will open secret file: {}", secret_path.display());
11    let (secret, _) = PrivateKey::decode_from_file(secret_path, &mut vec![])?;
12    debug!("will open desc file: {}", desc_path.display());
13    let (desc, _) = StandardObject::decode_from_file(desc_path, &mut vec![])?;
14    Ok((desc, secret))
15}
16
17pub fn get_device_from_file(
18    desc_path: &Path,
19    secret_path: &Path,
20) -> BuckyResult<(Device, PrivateKey)> {
21    let (obj, sec) = get_desc_from_file(desc_path, secret_path)?;
22    if let StandardObject::Device(device) = obj {
23        Ok((device, sec))
24    } else {
25        Err(BuckyError::new(BuckyErrorCode::NotMatch, "not device desc"))
26    }
27}
28
29pub fn get_json_userdata_from_desc(desc: &Device) -> BuckyResult<(serde_json::Value, u64)> {
30    let (slice, create_time) = get_userdata_from_desc(desc)?;
31    Ok((serde_json::from_slice(slice)?, create_time))
32}
33
34pub fn get_userdata_from_desc(desc: &Device) -> BuckyResult<(&[u8], u64)> {
35    if let Some(userdata) = desc.body().as_ref().unwrap().user_data() {
36        Ok((
37            userdata.as_slice(),
38            desc.body().as_ref().unwrap().update_time(),
39        ))
40    } else {
41        return Err(BuckyError::from(BuckyErrorCode::NotFound));
42    }
43}
44
45pub(crate) fn load_device_objects_list(root: &Path) -> Vec<(DeviceId, Device)> {
46    if !root.is_dir() {
47        return vec![];
48    }
49
50    let mut loader = DirObjectsSyncLoader::new(root);
51    loader.load();
52
53    let objects = loader.into_objects();
54    let mut result = Vec::with_capacity(objects.len());
55    for (file_path, data) in objects {
56        match Device::clone_from_slice(&data) {
57            Ok(device) => {
58                let id = device.desc().device_id();
59                info!(
60                    "load local device object: file={}, id={}",
61                    file_path.display(),
62                    id
63                );
64                result.push((id, device));
65            }
66            Err(e) => {
67                error!(
68                    "invalid local device object: file={}, {}",
69                    file_path.display(),
70                    e
71                );
72            }
73        }
74    }
75
76    result
77}
78
79fn load_device_object(file: &Path) -> Vec<(DeviceId, Device)> {
80    match Device::decode_from_file(&file, &mut vec![]) {
81        Ok((device, _)) => {
82            let id = device.desc().device_id();
83            info!(
84                "load local device object: file={}, id={}",
85                file.display(),
86                id
87            );
88            vec![(id, device)]
89        }
90        Err(e) => {
91            error!(
92                "invalid local device object: file={}, {}",
93                file.display(),
94                e
95            );
96            vec![]
97        }
98    }
99}
100
101// 读取本地的pn配置,在{root}/etc/desc/pn.desc and {root}/etc/desc/pn
102fn load_local_pn_desc() -> Vec<(DeviceId, Device)> {
103    let mut default_pn_file = get_cyfs_root_path();
104    default_pn_file.push("etc");
105    default_pn_file.push("desc");
106
107    let dir = default_pn_file.join("pn");
108    if dir.is_dir() {
109        load_device_objects_list(&dir)
110    } else {
111        default_pn_file.push("pn.desc");
112        if default_pn_file.exists() {
113            load_device_object(&default_pn_file)
114        } else {
115            vec![]
116        }
117    }
118}
119
120fn load_local_sn_desc() -> Vec<(DeviceId, Device)> {
121    let mut default_sn_file = get_cyfs_root_path();
122    default_sn_file.push("etc");
123    default_sn_file.push("desc");
124
125    let dir = default_sn_file.join("sn");
126    if dir.is_dir() {
127        load_device_objects_list(&dir)
128    } else {
129        default_sn_file.push("sn.desc");
130        if default_sn_file.exists() {
131            load_device_object(&default_sn_file)
132        } else {
133            vec![]
134        }
135    }
136}
137
138fn load_default_sn_desc() -> Vec<(DeviceId, Device)> {
139    let sn_raw = match cyfs_base::get_channel() {
140        CyfsChannel::Nightly => env!("NIGHTLY_SN_RAW"),
141        CyfsChannel::Beta => env!("BETA_SN_RAW"),
142        CyfsChannel::Stable => {
143            unreachable!()
144        }
145    };
146
147    let object_raw = hex::decode(sn_raw).unwrap();
148    SNDirParser::parse(None, &object_raw).unwrap()
149}
150
151pub fn get_default_known_peers() -> Vec<Device> {
152    let mut ret = vec![];
153    let mut default_known_peer_dir = get_cyfs_root_path();
154    default_known_peer_dir.push("etc");
155    default_known_peer_dir.push("known_peers");
156    if default_known_peer_dir.exists() {
157        for desc_file in walkdir::WalkDir::new(&default_known_peer_dir)
158            .into_iter()
159            .filter_map(|e| e.ok())
160        {
161            if desc_file.path().extension().unwrap_or("".as_ref()) == "desc" {
162                match Device::decode_from_file(desc_file.path(), &mut vec![]) {
163                    Ok((p, _)) => {
164                        ret.push(p);
165                    }
166                    _ => {}
167                }
168            }
169        }
170    }
171
172    if ret.len() > 0 {
173        return ret;
174    }
175
176    ret
177}
178
179pub fn get_default_device_desc() -> BuckyResult<(Device, PrivateKey)> {
180    let mut desc_path = get_cyfs_root_path();
181    desc_path.push("etc");
182    desc_path.push("desc");
183    get_device_from_file(
184        &desc_path.join("device.desc"),
185        &desc_path.join("device.sec"),
186    )
187}
188
189pub fn get_device_desc(name: &str) -> BuckyResult<(Device, PrivateKey)> {
190    let mut desc_path = get_cyfs_root_path();
191    desc_path.push("etc");
192    desc_path.push("desc");
193    desc_path.push(name);
194    get_device_from_file(
195        &desc_path.with_extension("desc"),
196        &desc_path.with_extension("sec"),
197    )
198}
199
200lazy_static::lazy_static! {
201    pub static ref LOCAL_SN: Vec<(DeviceId, Device)> = load_local_sn_desc();
202    pub static ref LOCAL_PN: Vec<(DeviceId, Device)> = load_local_pn_desc();
203
204    pub static ref DEFAULT_SN: Vec<(DeviceId, Device)> = load_default_sn_desc();
205}
206
207// get configed pn
208pub fn get_local_pn_desc() -> &'static Vec<(DeviceId, Device)> {
209    &LOCAL_PN
210}
211
212pub fn get_local_pn_desc_id_list() -> Vec<DeviceId> {
213    LOCAL_PN.iter().map(|item| item.0.clone()).collect()
214}
215
216// configed sn
217pub fn get_local_sn_desc() -> &'static Vec<(DeviceId, Device)> {
218    &LOCAL_SN
219}
220
221pub fn get_local_sn_desc_id_list() -> Vec<DeviceId> {
222    LOCAL_SN.iter().map(|item| item.0.clone()).collect()
223}
224
225// builtin sn
226pub fn get_builtin_sn_desc() -> &'static Vec<(DeviceId, Device)> {
227    &DEFAULT_SN
228}
229
230pub fn get_builtin_sn_desc_id_list() -> Vec<DeviceId> {
231    DEFAULT_SN.iter().map(|item| item.0.clone()).collect()
232}
233
234// get local sn, if empty, get the buildin sn
235pub fn get_sn_desc() -> &'static Vec<(DeviceId, Device)> {
236    if LOCAL_SN.len() > 0 {
237        &LOCAL_SN
238    } else {
239        &DEFAULT_SN
240    }
241}