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
28static const std::array<FsInfo, 19> s_fsMap = {{
29 {KFileSystemType::Nfs, "nfs"},
30 {KFileSystemType::Smb, "smb"},
31 {KFileSystemType::Fat, "fat"},
32 {KFileSystemType::Ramfs, "ramfs"},
33 {KFileSystemType::Other, "other"},
34 {KFileSystemType::Ntfs, "ntfs"},
35 {KFileSystemType::Ntfs, "ntfs3"},
36 {KFileSystemType::Exfat, "exfat"},
37 {KFileSystemType::Unknown, "unknown"},
38 {KFileSystemType::Nfs, "autofs"},
39 {KFileSystemType::Nfs, "cachefs"},
40 {KFileSystemType::Nfs, "fuse.sshfs"},
41 {KFileSystemType::Nfs, "xtreemfs@"}, // #178678
42 {KFileSystemType::Smb, "smbfs"},
43 {KFileSystemType::Smb, "cifs"},
44 {KFileSystemType::Fat, "vfat"},
45 {KFileSystemType::Fat, "msdos"},
46 {KFileSystemType::Fuse, "fuseblk"},
47}};
48
49inline KFileSystemType::Type kde_typeFromName(const QLatin1String name)
50{
51 auto it = std::find_if(s_fsMap.cbegin(), s_fsMap.cend(), [name](const auto &fsInfo) {
52 return QLatin1String(fsInfo.name) == name;
53 });
54 return it != s_fsMap.cend() ? it->type : KFileSystemType::Other;
55}
56
57inline KFileSystemType::Type kde_typeFromName(const char *c)
58{
59 return kde_typeFromName(QLatin1String(c));
60}
61
62#if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
63#include <sys/mount.h>
64#include <sys/param.h>
65
66KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
67{
68 struct statfs buf;
69 if (statfs(path.constData(), &buf) != 0) {
70 return KFileSystemType::Unknown;
71 }
72 return kde_typeFromName(buf.f_fstypename);
73}
74
75#elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
76#include <sys/statfs.h>
77
78#ifdef Q_OS_LINUX
79#include <linux/magic.h> // A lot of the filesystem superblock MAGIC numbers
80#include <sys/stat.h>
81#endif
82
83// Add known missig magics
84// Can use https://github.com/systemd/systemd/blob/main/src/basic/missing_magic.h
85// as reference
86
87// From linux/fs/ntfs/ntfs.h
88#ifndef NTFS_SB_MAGIC
89#define NTFS_SB_MAGIC 0x5346544e
90#endif
91
92// From linux/fs/ntfs3/super.c
93#ifndef NTFS3_MAGIC
94#define NTFS3_MAGIC 0x7366746E
95#endif
96
97// From linux/fs/exfat/exfat_fs.h
98#ifndef EXFAT_SUPER_MAGIC
99#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
100#endif
101
102// From linux/fs/cifs/smb2glob.h
103#ifndef SMB2_MAGIC_NUMBER
104#define SMB2_MAGIC_NUMBER 0xFE534D42
105#endif
106
107// From linux/fs/cifs/cifsglob.h
108#ifndef CIFS_MAGIC_NUMBER
109#define CIFS_MAGIC_NUMBER 0xFF534D42
110#endif
111
112// From linux/fs/fuse/inode.c
113#ifndef FUSE_SUPER_MAGIC
114#define FUSE_SUPER_MAGIC 0x65735546
115#endif
116
117#ifndef AUTOFSNG_SUPER_MAGIC
118#define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0
119#endif
120
121#ifdef Q_OS_HURD
122#ifndef NFS_SUPER_MAGIC
123#define NFS_SUPER_MAGIC 0x00006969
124#endif
125#ifndef AUTOFS_SUPER_MAGIC
126#define AUTOFS_SUPER_MAGIC 0x00000187
127#endif
128#ifndef MSDOS_SUPER_MAGIC
129#define MSDOS_SUPER_MAGIC 0x00004d44
130#endif
131#ifndef SMB_SUPER_MAGIC
132#define SMB_SUPER_MAGIC 0x0000517B
133#endif
134#ifndef RAMFS_MAGIC
135#define RAMFS_MAGIC 0x858458F6
136#endif
137#endif
138
139KFileSystemType::Type probeFuseBlkType(const QByteArray &path)
140{
141 using namespace KFileSystemType;
142
143#if HAVE_UDEV
144 struct stat buf;
145 if (stat(path.constData(), &buf) != 0) {
146 return Fuse;
147 }
148
149 using UdevPtr = std::unique_ptr<struct udev, decltype(&udev_unref)>;
150 using UDevicePtr = std::unique_ptr<struct udev_device, decltype(&udev_device_unref)>;
151
152 // Code originally copied from util-linux/misc-utils/lsblk.c
153 auto udevP = UdevPtr(udev_new(), udev_unref);
154 if (!udevP) {
155 return Fuse;
156 }
157
158 // 'b' for block devices
159 auto devPtr = UDevicePtr(udev_device_new_from_devnum(udevP.get(), 'b', buf.st_dev), udev_device_unref);
160 if (!devPtr) {
161 // If is not block device, assume conservatively it is a remote FS under FUSE.
162 return Nfs;
163 }
164
165 const QLatin1String fsType(udev_device_get_property_value(devPtr.get(), "ID_FS_TYPE"));
166 return kde_typeFromName(fsType);
167#endif
168
169 return Fuse;
170}
171
172// Reverse-engineering without C++ code:
173// strace stat -f /mnt 2>&1|grep statfs|grep mnt, and look for f_type
174//
175// Also grep'ing in /usr/src/<kernel-version>/fs/
176
177static KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
178{
179 struct statfs buf;
180 if (statfs(path.constData(), &buf) != 0) {
181 return KFileSystemType::Unknown;
182 }
183
184 switch (static_cast<unsigned long>(buf.f_type)) {
185 case NFS_SUPER_MAGIC:
186 case AUTOFS_SUPER_MAGIC:
187 case AUTOFSNG_SUPER_MAGIC:
189 case FUSE_SUPER_MAGIC:
190 return probeFuseBlkType(path);
191 case SMB_SUPER_MAGIC:
192 case SMB2_MAGIC_NUMBER:
193 case CIFS_MAGIC_NUMBER:
195 case MSDOS_SUPER_MAGIC:
197 case NTFS_SB_MAGIC:
198 case NTFS3_MAGIC:
200 case EXFAT_SUPER_MAGIC:
202 case RAMFS_MAGIC:
204 default:
206 }
207}
208
209#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) \
210 || defined(Q_OS_NETBSD)
211#include <sys/statvfs.h>
212
213KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
214{
215 struct statvfs buf;
216 if (statvfs(path.constData(), &buf) != 0) {
217 return KFileSystemType::Unknown;
218 }
219#if defined(Q_OS_NETBSD)
220 return kde_typeFromName(buf.f_fstypename);
221#else
222 return kde_typeFromName(buf.f_basetype);
223#endif
224}
225#endif
226#else
227KFileSystemType::Type determineFileSystemTypeImpl(const QByteArray &path)
228{
229 Q_UNUSED(path);
230 return KFileSystemType::Unknown;
231}
232#endif
233
235{
240 } else {
241 return determineFileSystemTypeImpl(QFile::encodeName(path));
242 }
243}
244
246{
247 switch (type) {
249 return QCoreApplication::translate("KFileSystemType", "NFS");
251 return QCoreApplication::translate("KFileSystemType", "SMB");
253 return QCoreApplication::translate("KFileSystemType", "FAT");
255 return QCoreApplication::translate("KFileSystemType", "RAMFS");
257 return QCoreApplication::translate("KFileSystemType", "Other");
259 return QCoreApplication::translate("KFileSystemType", "NTFS");
261 return QCoreApplication::translate("KFileSystemType", "ExFAT");
263 return QCoreApplication::translate("KFileSystemType", "FUSE");
264 case KFileSystemType::Unknown:
265 return QCoreApplication::translate("KFileSystemType", "Unknown");
266 }
267
268 Q_UNREACHABLE();
269 return {};
270}
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 Tue Mar 26 2024 11:13:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.