dia_files/
path_ext.rs

1/*
2==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--
3
4Dia-Files
5
6Copyright (C) 2019-2024  Anonymous
7
8There are several releases over multiple years,
9they are listed as ranges, such as: "2019-2024".
10
11This program is free software: you can redistribute it and/or modify
12it under the terms of the GNU Lesser General Public License as published by
13the Free Software Foundation, either version 3 of the License, or
14(at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU Lesser General Public License for more details.
20
21You should have received a copy of the GNU Lesser General Public License
22along with this program.  If not, see <https://www.gnu.org/licenses/>.
23
24::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
25*/
26
27//! # Extensions for `Path`
28
29use {
30    std::{
31        env,
32        path::{Path, PathBuf},
33    },
34    crate::Sealed,
35};
36
37#[cfg(unix)]
38#[cfg(feature="libc")]
39use {
40    core::{
41        ffi::CStr,
42        mem,
43    },
44    alloc::ffi::CString,
45    std::{
46        io::Error,
47        os::unix::prelude::OsStrExt,
48    },
49    crate::{FileSystem, Result},
50};
51
52/// # Extensions for `Path`
53///
54/// This (sealed) trait provides some extensions for [`Path`][struct:std/path/Path].
55///
56/// [struct:std/path/Path]: https://doc.rust-lang.org/std/path/struct.Path.html
57pub trait PathExt: Sealed {
58
59    /// # Shortens this path from a base
60    ///
61    /// If there's an error, the original path is returned.
62    fn shorten<P>(&self, base: P) -> &Path where P: AsRef<Path>;
63
64    /// # Shortens this path from current directory
65    ///
66    /// If there's an error, the original path is returned.
67    fn shorten_here(&self) -> &Path;
68
69    /// # Gets file system which this path resides on
70    #[cfg(all(feature="libc", unix))]
71    #[doc(cfg(all(feature="libc", unix)))]
72    fn file_system(&self) -> Result<FileSystem>;
73
74}
75
76macro_rules! impl_path_ext { ($($ty: ty),+$(,)?) => {
77    $(
78        impl Sealed for $ty {}
79
80        impl PathExt for $ty {
81
82            fn shorten<P>(&self, base: P) -> &Path where P: AsRef<Path> {
83                self.strip_prefix(base).unwrap_or(self)
84            }
85
86            fn shorten_here(&self) -> &Path {
87                env::current_dir().map(|d| self.shorten(d)).unwrap_or(self)
88            }
89
90            #[cfg(all(feature="libc", unix))]
91            #[doc(cfg(all(feature="libc", unix)))]
92            fn file_system(&self) -> Result<FileSystem> {
93                file_system(self)
94            }
95
96        }
97    )+
98}}
99
100impl_path_ext!(&Path, PathBuf);
101
102/// # Gets file system of a path
103#[cfg(all(feature="libc", unix))]
104#[doc(cfg(all(feature="libc", unix)))]
105fn file_system(path: &Path) -> Result<FileSystem> {
106    // Docs: statfs(2)
107    match unsafe {
108        let mut statfs = mem::zeroed::<libc::statfs>();
109        match libc::statfs(CString::new(path.as_os_str().as_bytes())?.as_ptr(), &mut statfs) {
110            0 => statfs.f_type,
111            _ => return Err(fmt_err_code("statfs")),
112        }
113    } {
114        libc::ADFS_SUPER_MAGIC => Ok(FileSystem::ADFSSuper),
115        libc::AFFS_SUPER_MAGIC => Ok(FileSystem::AFFSSuper),
116        libc::AFS_SUPER_MAGIC => Ok(FileSystem::AFSSuper),
117        libc::AUTOFS_SUPER_MAGIC => Ok(FileSystem::AutoFSSuper),
118        libc::BPF_FS_MAGIC => Ok(FileSystem::BpfFS),
119        libc::BTRFS_SUPER_MAGIC => Ok(FileSystem::BtrFSSuper),
120        libc::CGROUP_SUPER_MAGIC => Ok(FileSystem::CgroupSuper),
121        libc::CGROUP2_SUPER_MAGIC => Ok(FileSystem::Cgroup2Super),
122        libc::CODA_SUPER_MAGIC => Ok(FileSystem::CodaSuper),
123        libc::CRAMFS_MAGIC => Ok(FileSystem::CramFS),
124        libc::DEBUGFS_MAGIC => Ok(FileSystem::DebugFS),
125        libc::DEVPTS_SUPER_MAGIC => Ok(FileSystem::DevPtsSuper),
126        libc::ECRYPTFS_SUPER_MAGIC => Ok(FileSystem::EcryptFSSuper),
127        libc::EFS_SUPER_MAGIC => Ok(FileSystem::EFSSuper),
128        libc::EXT4_SUPER_MAGIC => Ok(FileSystem::Ext234Super),
129        libc::F2FS_SUPER_MAGIC => Ok(FileSystem::F2FSSuper),
130        libc::FUSE_SUPER_MAGIC => Ok(FileSystem::FuseSuper),
131        libc::FUTEXFS_SUPER_MAGIC => Ok(FileSystem::FutexFSSuper),
132        libc::HOSTFS_SUPER_MAGIC => Ok(FileSystem::HostFSSuper),
133        libc::HPFS_SUPER_MAGIC => Ok(FileSystem::HPFSSuper),
134        libc::HUGETLBFS_MAGIC => Ok(FileSystem::HugeTLBFS),
135        libc::ISOFS_SUPER_MAGIC => Ok(FileSystem::IsoFSSuper),
136        libc::JFFS2_SUPER_MAGIC => Ok(FileSystem::JFFS2Super),
137        libc::MINIX_SUPER_MAGIC => Ok(FileSystem::MINIXSuper),
138        libc::MINIX_SUPER_MAGIC2 => Ok(FileSystem::MINIXSuper2),
139        libc::MINIX2_SUPER_MAGIC => Ok(FileSystem::MINIX2Super),
140        libc::MINIX2_SUPER_MAGIC2 => Ok(FileSystem::MINIX2Super2),
141        libc::MINIX3_SUPER_MAGIC => Ok(FileSystem::MINIX3Super),
142        libc::MSDOS_SUPER_MAGIC => Ok(FileSystem::MSDOSSuper),
143        libc::NCP_SUPER_MAGIC => Ok(FileSystem::NCPSuper),
144        libc::NFS_SUPER_MAGIC => Ok(FileSystem::NFSSuper),
145        libc::NILFS_SUPER_MAGIC => Ok(FileSystem::NILFSSuper),
146        libc::NSFS_MAGIC => Ok(FileSystem::NSFS),
147        libc::OCFS2_SUPER_MAGIC => Ok(FileSystem::OCFS2Super),
148        libc::OPENPROM_SUPER_MAGIC => Ok(FileSystem::OpenPROMSuper),
149        libc::OVERLAYFS_SUPER_MAGIC => Ok(FileSystem::OverlayFSSuper),
150        libc::PROC_SUPER_MAGIC => Ok(FileSystem::ProcSuper),
151        libc::QNX4_SUPER_MAGIC => Ok(FileSystem::QNX4Super),
152        libc::QNX6_SUPER_MAGIC => Ok(FileSystem::QNX6Super),
153        libc::REISERFS_SUPER_MAGIC => Ok(FileSystem::ReiserFSSuper),
154        libc::SECURITYFS_MAGIC => Ok(FileSystem::SecurityFS),
155        libc::SELINUX_MAGIC => Ok(FileSystem::SELinux),
156        libc::SMACK_MAGIC => Ok(FileSystem::Smack),
157        libc::SMB_SUPER_MAGIC => Ok(FileSystem::SMBSuper),
158        libc::SYSFS_MAGIC => Ok(FileSystem::SysFS),
159        libc::TMPFS_MAGIC => Ok(FileSystem::TmpFS),
160        libc::TRACEFS_MAGIC => Ok(FileSystem::TraceFS),
161        libc::UDF_SUPER_MAGIC => Ok(FileSystem::UDFSuper),
162        libc::USBDEVICE_SUPER_MAGIC => Ok(FileSystem::USBDeviceSuper),
163        libc::XENFS_SUPER_MAGIC => Ok(FileSystem::XENFSSuper),
164        libc::XFS_SUPER_MAGIC => Ok(FileSystem::XFSSuper),
165        _ => Ok(FileSystem::Unknown),
166    }
167}
168
169#[cfg(feature="libc")]
170#[doc(cfg(feature="libc"))]
171fn fmt_err_code<S>(fn_name: S) -> Error where S: AsRef<str> {
172    let err_code = unsafe {
173        *libc::__errno_location()
174    };
175    err!(
176        "libc::{fn_name}() failed: {err_code}: {err:?}",
177        fn_name=fn_name.as_ref(),
178        err=unsafe { CStr::from_ptr(libc::strerror(err_code)) },
179    )
180}