File indexing completed on 2024-05-12 03:56:43

0001 /*
0002     SPDX-FileCopyrightText: 2000-2002 Stephan Kulow <coolo@kde.org>
0003     SPDX-FileCopyrightText: 2000-2002 David Faure <faure@kde.org>
0004     SPDX-FileCopyrightText: 2000-2002 Waldo Bastian <bastian@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #ifndef __file_h__
0010 #define __file_h__
0011 
0012 #include <kio/global.h>
0013 #include <kio/workerbase.h>
0014 
0015 #include <KUser>
0016 #include <QFile>
0017 #include <QHash>
0018 #include <QObject>
0019 
0020 #include <config-kioworker-file.h>
0021 #include <qplatformdefs.h> // mode_t
0022 
0023 #if HAVE_SYS_ACL_H
0024 #include <sys/acl.h>
0025 #endif
0026 #if HAVE_ACL_LIBACL_H
0027 #include <acl/libacl.h>
0028 #endif
0029 
0030 #include "file_p.h"
0031 
0032 #include <QLoggingCategory>
0033 Q_DECLARE_LOGGING_CATEGORY(KIO_FILE)
0034 
0035 class FileProtocol : public QObject, public KIO::WorkerBase
0036 {
0037     Q_OBJECT
0038 public:
0039     FileProtocol(const QByteArray &pool, const QByteArray &app);
0040     ~FileProtocol() override;
0041 
0042     KIO::WorkerResult get(const QUrl &url) override;
0043     virtual KIO::WorkerResult put(const QUrl &url, int _mode, KIO::JobFlags _flags) override;
0044     virtual KIO::WorkerResult copy(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags) override;
0045     virtual KIO::WorkerResult rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) override;
0046     virtual KIO::WorkerResult symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags) override;
0047 
0048     KIO::WorkerResult stat(const QUrl &url) override;
0049     KIO::WorkerResult listDir(const QUrl &url) override;
0050     KIO::WorkerResult mkdir(const QUrl &url, int permissions) override;
0051     KIO::WorkerResult chmod(const QUrl &url, int permissions) override;
0052     KIO::WorkerResult chown(const QUrl &url, const QString &owner, const QString &group) override;
0053     KIO::WorkerResult setModificationTime(const QUrl &url, const QDateTime &mtime) override;
0054     KIO::WorkerResult del(const QUrl &url, bool isfile) override;
0055     KIO::WorkerResult open(const QUrl &url, QIODevice::OpenMode mode) override;
0056     KIO::WorkerResult read(KIO::filesize_t size) override;
0057     KIO::WorkerResult write(const QByteArray &data) override;
0058     KIO::WorkerResult seek(KIO::filesize_t offset) override;
0059     KIO::WorkerResult truncate(KIO::filesize_t length) override;
0060     bool copyXattrs(const int src_fd, const int dest_fd);
0061     KIO::WorkerResult close() override;
0062 
0063     KIO::WorkerResult fileSystemFreeSpace(const QUrl &url) override;
0064 
0065     /**
0066      * Special commands supported by this worker:
0067      * 1 - mount
0068      * 2 - unmount
0069      */
0070     KIO::WorkerResult special(const QByteArray &data) override;
0071     KIO::WorkerResult unmount(const QString &point);
0072     KIO::WorkerResult mount(bool _ro, const char *_fstype, const QString &dev, const QString &point);
0073 
0074 #if HAVE_POSIX_ACL
0075     static bool isExtendedACL(acl_t acl);
0076 #endif
0077 
0078 private:
0079     int setACL(const char *path, mode_t perm, bool _directoryDefault);
0080     QString getUserName(KUserId uid) const;
0081     QString getGroupName(KGroupId gid) const;
0082     KIO::WorkerResult deleteRecursive(const QString &path);
0083 
0084     bool privilegeOperationUnitTestMode();
0085     KIO::WorkerResult execWithElevatedPrivilege(ActionType action, const QVariantList &args, int errcode);
0086     KIO::WorkerResult tryOpen(QFile &f, const QByteArray &path, int flags, int mode, int errcode);
0087 
0088     // We want to execute chmod/chown/utime with elevated privileges (in copy & put)
0089     // only during the brief period privileges are elevated. If it's not the case show
0090     // a warning and continue.
0091     KIO::WorkerResult tryChangeFileAttr(ActionType action, const QVariantList &args, int errcode);
0092 
0093     KIO::WorkerResult redirect(const QUrl &url);
0094 
0095     // Close without calling finish(). Use this to close after error.
0096     void closeWithoutFinish();
0097 
0098 private:
0099     QFile *mFile;
0100 
0101     bool resultWasCancelled(KIO::WorkerResult result);
0102 
0103     bool testMode = false;
0104     KIO::StatDetails getStatDetails();
0105 };
0106 
0107 #endif