KCoreAddons

kfilesystemtype.cpp
1/*
2 This file is part of the KDE libraries
3
4 SPDX-FileCopyrightText: 2011 David Faure <faure@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.1-only
7*/
8
9#include "kfilesystemtype.h"
10#include "knetworkmounts.h"
11
12#include <config-kfilesystemtype.h>
13#if HAVE_UDEV
14#include <libudev.h>
15#endif
16
17#include <QCoreApplication>
18#include <QFile>
19
20#include <array>
21
22struct FsInfo {
23 KFileSystemType::Type type = KFileSystemType::Unknown;
24 const char *name = nullptr;
25};
26
27#ifndef Q_OS_WIN
28// clang-format off
29static const std::array<FsInfo, 19> s_fsMap = {{
30 {KFileSystemType::Nfs, "nfs"},
31 {KFileSystemType::Nfs, "nfs4"},
32 {KFileSystemType::Smb, "smb"},
33 {KFileSystemType::Fat, "fat"},
34 {KFileSystemType::Ramfs, "ramfs"},
35 {KFileSystemType::Other, "other"},
36 {KFileSystemType::Ntfs, "ntfs"},
37 {KFileSystemType::Ntfs, "ntfs3"},
38 {KFileSystemType::Exfat, "exfat"},
39 {KFileSystemType::Unknown, "unknown"},
40 {KFileSystemType::Nfs, "autofs"},
41 {KFileSystemType::Nfs, "cachefs"},
42 {KFileSystemType::Nfs, "fuse.sshfs"},
43 {KFileSystemType::Nfs, "xtreemfs@"}, // #178678
44 {KFileSystemType::Smb, "smbfs"},
45 {KFileSystemType::Smb, "cifs"},
46 {KFileSystemType::Fat, "vfat"},
47 {KFileSystemType::Fat, "msdos"},
48 {KFileSystemType::Fuse, "fuseblk"},
49}};
50// clang-format on
51
52inline KFileSystemType::Type kde_typeFromName(const QLatin1String name)
53{
54 auto it = std::find_if(s_fsMap.cbegin(), s_fsMap.cend(), [name](const auto &fsInfo) {
55 return QLatin1String(fsInfo.name) == name;
56 });
57 return it != s_fsMap.cend() ? it->type : KFileSystemType::Other;
58}
59
60inline KFileSystemType::Type kde_typeFromName(const char *c)
61{
62 return kde_typeFromName(QLatin1String(c));
63}
64
65#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
66#include <sys/mount.h>
67#include <sys/param.h>
68
69KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
70{
71 struct statfs buf;
72 if (statfs(path.constData(), &buf) != 0) {
73 return KFileSystemType::Unknown;
74 }
75 return kde_typeFromName(buf.f_fstypename);
76}
77
78#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
79#include <sys/statfs.h>
80
81#ifdef Q_OS_LINUX
82#include <linux/magic.h> // A lot of the filesystem superblock MAGIC numbers
83#include <sys/stat.h>
84#endif
85
86// Add known missig magics
87// Can use https://github.com/systemd/systemd/blob/main/src/basic/missing_magic.h
88// as reference
89
90// From linux/fs/ntfs/ntfs.h
91#ifndef NTFS_SB_MAGIC
92#define NTFS_SB_MAGIC 0x5346544e
93#endif
94
95// From linux/fs/ntfs3/super.c
96#ifndef NTFS3_MAGIC
97#define NTFS3_MAGIC 0x7366746E
98#endif
99
100// From linux/fs/exfat/exfat_fs.h
101#ifndef EXFAT_SUPER_MAGIC
102#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
103#endif
104
105// From linux/fs/cifs/smb2glob.h
106#ifndef SMB2_MAGIC_NUMBER
107#define SMB2_MAGIC_NUMBER 0xFE534D42
108#endif
109
110// From linux/fs/cifs/cifsglob.h
111#ifndef CIFS_MAGIC_NUMBER
112#define CIFS_MAGIC_NUMBER 0xFF534D42
113#endif
114
115// From linux/fs/fuse/inode.c
116#ifndef FUSE_SUPER_MAGIC
117#define FUSE_SUPER_MAGIC 0x65735546
118#endif
119
120#ifndef AUTOFSNG_SUPER_MAGIC
121#define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0
122#endif
123
124#ifdef Q_OS_HURD
125#ifndef NFS_SUPER_MAGIC
126#define NFS_SUPER_MAGIC 0x00006969
127#endif
128#ifndef AUTOFS_SUPER_MAGIC
129#define AUTOFS_SUPER_MAGIC 0x00000187
130#endif
131#ifndef MSDOS_SUPER_MAGIC
132#define MSDOS_SUPER_MAGIC 0x00004d44
133#endif
134#ifndef SMB_SUPER_MAGIC
135#define SMB_SUPER_MAGIC 0x0000517B
136#endif
137#ifndef RAMFS_MAGIC
138#define RAMFS_MAGIC 0x858458F6
139#endif
140#endif
141
142KFileSystemType::Type probeFuseBlkType(const QByteArray &path)
143{
144 using namespace KFileSystemType;
145
146#if HAVE_UDEV
147 struct stat buf;
148 if (stat(path.constData(), &buf) != 0) {
149 return Fuse;
150 }
151
152 using UdevPtr = std::unique_ptr<struct udev, decltype(&udev_unref)>;
153 using UDevicePtr = std::unique_ptr<struct udev_device, decltype(&udev_device_unref)>;
154
155 // Code originally copied from util-linux/misc-utils/lsblk.c
156 auto udevP = UdevPtr(udev_new(), udev_unref);
157 if (!udevP) {
158 return Fuse;
159 }
160
161 // 'b' for block devices
162 auto devPtr = UDevicePtr(udev_device_new_from_devnum(udevP.get(), 'b', buf.st_dev), udev_device_unref);
163 if (!devPtr) {
164 // If is not block device, assume conservatively it is a remote FS under FUSE.
165 return Nfs;
166 }
167
168 const QLatin1String fsType(udev_device_get_property_value(devPtr.get(), "ID_FS_TYPE"));
169 return kde_typeFromName(fsType);
170#endif
171
172 return Fuse;
173}
174
175// Reverse-engineering without C++ code:
176// strace stat -f /mnt 2>&1|grep statfs|grep mnt, and look for f_type
177//
178// Also grep'ing in /usr/src/<kernel-version>/fs/
179
180static KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
181{
182 struct statfs buf;
183 if (statfs(path.constData(), &buf) != 0) {
184 return KFileSystemType::Unknown;
185 }
186
187 switch (static_cast<unsigned long>(buf.f_type)) {
188 case NFS_SUPER_MAGIC:
189 case AUTOFS_SUPER_MAGIC:
190 case AUTOFSNG_SUPER_MAGIC:
192 case FUSE_SUPER_MAGIC:
193 return probeFuseBlkType(path);
194 case SMB_SUPER_MAGIC:
195 case SMB2_MAGIC_NUMBER:
196 case CIFS_MAGIC_NUMBER:
198 case MSDOS_SUPER_MAGIC:
200 case NTFS_SB_MAGIC:
201 case NTFS3_MAGIC:
203 case EXFAT_SUPER_MAGIC:
205 case RAMFS_MAGIC:
207 default:
209 }
210}
211
212#elif defined(Q_OS_AIX) || defined(Q_OS_HPUX) || defined(Q_OS_QNX) || defined(Q_OS_SCO) || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT) \
213 || defined(Q_OS_NETBSD)
214#include <sys/statvfs.h>
215
216KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
217{
218 struct statvfs buf;
219 if (statvfs(path.constData(), &buf) != 0) {
220 return KFileSystemType::Unknown;
221 }
222#if defined(Q_OS_NETBSD)
223 return kde_typeFromName(buf.f_fstypename);
224#else
225 return kde_typeFromName(buf.f_basetype);
226#endif
227}
228#endif
229#else
230KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
231{
232 Q_UNUSED(path);
233 return KFileSystemType::Unknown;
234}
235#endif
236
238{
243 } else {
244 return determineFileSystemTypeImpl(QFile::encodeName(path));
245 }
246}
247
249{
250 switch (type) {
252 return QCoreApplication::translate("KFileSystemType", "NFS");
254 return QCoreApplication::translate("KFileSystemType", "SMB");
256 return QCoreApplication::translate("KFileSystemType", "FAT");
258 return QCoreApplication::translate("KFileSystemType", "RAMFS");
260 return QCoreApplication::translate("KFileSystemType", "Other");
262 return QCoreApplication::translate("KFileSystemType", "NTFS");
264 return QCoreApplication::translate("KFileSystemType", "ExFAT");
266 return QCoreApplication::translate("KFileSystemType", "FUSE");
267 case KFileSystemType::Unknown:
268 return QCoreApplication::translate("KFileSystemType", "Unknown");
269 }
270
271 Q_UNREACHABLE();
272 return {};
273}
static KNetworkMounts * self()
Returns (and creates if necessary) the singleton instance.
@ SmbPaths
SMB paths.
@ NfsPaths
NFS paths.
Provides utility functions for the type of file systems.
@ Other
Ext3, Ext4, ReiserFs, and so on. "Normal" local filesystems.
@ Exfat
ExFat filesystem.
@ Fuse
FUSE (Filesystem in USErspace), this is used for a variety of underlying filesystems.
@ Ramfs
RAMDISK mount.
@ Smb
SMB/CIFS mount (networked but with some FAT-like behavior)
@ Fat
FAT or similar (msdos, FAT, VFAT)
@ Ntfs
NTFS filesystem.
@ Nfs
NFS or other full-featured networked filesystems (autofs, subfs, cachefs, sshfs)
KCOREADDONS_EXPORT Type fileSystemType(const QString &path)
For a given path, returns the filesystem type, one of KFileSystemType::Type values.
KCOREADDONS_EXPORT QString fileSystemName(KFileSystemType::Type type)
Returns the possibly translated name of a filesystem corresponding to a value from KFileSystemType::T...
KIOCORE_EXPORT StatJob * stat(const QUrl &url, JobFlags flags=DefaultFlags)
QString path(const QString &relativePath)
Absolute libexec path resolved in relative relation to the current shared object.
Definition klibexec.h:48
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
QByteArray encodeName(const QString &fileName)
const QChar * constData() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Jun 7 2024 12:01:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.