libblkid_rs/
partition.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use std::ffi::CStr;
6
7use uuid::Uuid;
8
9use crate::{
10    devno::BlkidDevno,
11    err::BlkidErr,
12    utils::{BlkidBytes, BlkidSectors},
13    Result,
14};
15
16/// A handle for working with partition tables.
17pub struct BlkidParttable(libblkid_rs_sys::blkid_parttable);
18
19impl BlkidParttable {
20    /// Get the type of the partition table.
21    pub fn get_type(&self) -> Result<String> {
22        Ok(unsafe {
23            CStr::from_ptr(errno_ptr!(libblkid_rs_sys::blkid_parttable_get_type(
24                self.0
25            ))?)
26        }
27        .to_str()?
28        .to_string())
29    }
30
31    /// Get the ID of the partition table. Given that this could be a UUID or some
32    /// other form of identifier, the return value is a `String` to cover all cases.
33    pub fn get_id(&self) -> Result<String> {
34        Ok(
35            unsafe { CStr::from_ptr(errno_ptr!(libblkid_rs_sys::blkid_parttable_get_id(self.0))?) }
36                .to_str()?
37                .to_string(),
38        )
39    }
40
41    /// Get the offset of the partition table in bytes.
42    pub fn get_offset(&self) -> Result<BlkidBytes> {
43        Ok(BlkidBytes::new(errno_with_ret!(unsafe {
44            libblkid_rs_sys::blkid_parttable_get_offset(self.0)
45        })?))
46    }
47
48    /// Get the parent partition in the case of nested partition tables.
49    pub fn get_parent(&self) -> Option<BlkidPartition> {
50        option_ptr!(unsafe { libblkid_rs_sys::blkid_parttable_get_parent(self.0) })
51            .map(BlkidPartition)
52    }
53}
54
55/// A handle for working with a probed partition.
56pub struct BlkidPartition(libblkid_rs_sys::blkid_partition);
57
58impl BlkidPartition {
59    /// Get the partition table for the given partition.
60    pub fn get_table(&self) -> Result<BlkidParttable> {
61        Ok(BlkidParttable(errno_ptr!(unsafe {
62            libblkid_rs_sys::blkid_partition_get_table(self.0)
63        })?))
64    }
65
66    /// Get the partition name or `None` if it can't be represented.
67    pub fn get_name(&self) -> Result<Option<String>> {
68        let char_ptr =
69            match option_ptr!(unsafe { libblkid_rs_sys::blkid_partition_get_name(self.0) }) {
70                Some(ptr) => ptr,
71                None => return Ok(None),
72            };
73        unsafe { CStr::from_ptr(char_ptr) }
74            .to_str()
75            .map(|s| Some(s.to_string()))
76            .map_err(BlkidErr::UTF8)
77    }
78
79    /// Get the partition UUID or `None` if the partition table doesn't support it.
80    pub fn get_uuid(&self) -> Result<Option<Uuid>> {
81        let char_ptr =
82            match option_ptr!(unsafe { libblkid_rs_sys::blkid_partition_get_uuid(self.0) }) {
83                Some(ptr) => ptr,
84                None => return Ok(None),
85            };
86        match unsafe { CStr::from_ptr(char_ptr) }.to_str() {
87            Ok(s) => Ok(Some(Uuid::parse_str(s).map_err(BlkidErr::Uuid)?)),
88            Err(e) => Err(BlkidErr::UTF8(e)),
89        }
90    }
91
92    /// Get the partition number.
93    pub fn get_partno(&self) -> Result<libc::c_uint> {
94        errno_with_ret!(unsafe { libblkid_rs_sys::blkid_partition_get_partno(self.0) })
95            .map(|i| i as libc::c_uint)
96    }
97
98    /// Get the start of the partition in units of sectors.
99    pub fn get_start(&self) -> BlkidSectors {
100        BlkidSectors::new(unsafe { libblkid_rs_sys::blkid_partition_get_start(self.0) })
101    }
102
103    /// Get the size of the partition in units of sectors.
104    pub fn get_size(&self) -> BlkidSectors {
105        BlkidSectors::new(unsafe { libblkid_rs_sys::blkid_partition_get_size(self.0) })
106    }
107
108    /// Get the numeric partition type. Use `get_type_string` for the `String`
109    /// representation.
110    pub fn get_type(&self) -> libc::c_int {
111        unsafe { libblkid_rs_sys::blkid_partition_get_type(self.0) }
112    }
113
114    /// Get the string representation of the partition type.
115    pub fn get_type_string(&self) -> Result<String> {
116        Ok(unsafe {
117            CStr::from_ptr(errno_ptr!(
118                libblkid_rs_sys::blkid_partition_get_type_string(self.0)
119            )?)
120        }
121        .to_str()?
122        .to_string())
123    }
124
125    /// Get the flags for the given partition.
126    ///
127    /// This method is not typed as the documentation does not specify which
128    /// constants are used as flags.
129    pub fn get_flags(&self) -> libc::c_ulonglong {
130        unsafe { libblkid_rs_sys::blkid_partition_get_flags(self.0) }
131    }
132
133    /// Check whether the given partition is logical.
134    pub fn is_logical(&self) -> bool {
135        (unsafe { libblkid_rs_sys::blkid_partition_is_logical(self.0) }) != 0
136    }
137
138    /// Check whether the given partition is an extended partition.
139    pub fn is_extended(&self) -> bool {
140        (unsafe { libblkid_rs_sys::blkid_partition_is_extended(self.0) }) != 0
141    }
142
143    /// Check whether the given partition is a primary partition.
144    pub fn is_primary(&self) -> bool {
145        (unsafe { libblkid_rs_sys::blkid_partition_is_primary(self.0) }) != 0
146    }
147}
148
149/// A handle for traversing a list of partitions.
150pub struct BlkidPartlist(libblkid_rs_sys::blkid_partlist);
151
152impl BlkidPartlist {
153    pub(crate) fn new(partlist: libblkid_rs_sys::blkid_partlist) -> BlkidPartlist {
154        BlkidPartlist(partlist)
155    }
156
157    /// Get the number of partitions in the list.
158    pub fn number_of_partitions(&mut self) -> Result<libc::c_int> {
159        errno_with_ret!(unsafe { libblkid_rs_sys::blkid_partlist_numof_partitions(self.0) })
160    }
161
162    /// Get the partition table for a list of partitions.
163    pub fn get_table(&mut self) -> Result<BlkidParttable> {
164        Ok(BlkidParttable(errno_ptr!(unsafe {
165            libblkid_rs_sys::blkid_partlist_get_table(self.0)
166        })?))
167    }
168
169    /// Get a partition at the given index of the list.
170    pub fn get_partition(&mut self, index: libc::c_int) -> Result<BlkidPartition> {
171        Ok(BlkidPartition(errno_ptr!(unsafe {
172            libblkid_rs_sys::blkid_partlist_get_partition(self.0, index)
173        })?))
174    }
175
176    /// Get a partition by the number listed in the partition table. Correctly
177    /// handles "out-of-order" partition tables.
178    pub fn get_partition_by_partno(&mut self, num: libc::c_int) -> Result<BlkidPartition> {
179        Ok(BlkidPartition(errno_ptr!(unsafe {
180            libblkid_rs_sys::blkid_partlist_get_partition_by_partno(self.0, num)
181        })?))
182    }
183
184    /// Get a partition using the device number of a partition.
185    pub fn get_partition_by_devno(&mut self, dev: &BlkidDevno) -> Result<BlkidPartition> {
186        Ok(BlkidPartition(errno_ptr!(unsafe {
187            libblkid_rs_sys::blkid_partlist_devno_to_partition(self.0, dev.as_dev_t())
188        })?))
189    }
190}