File indexing completed on 2024-04-21 04:57:37

0001 /*  This file is part of the KDE project
0002     SPDX-FileCopyrightText: 2000 Alexander Neundorf <neundorf@kde.org>
0003     SPDX-FileCopyrightText: 2014 Mathias Tillman <master.homer@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #ifndef KIO_NFS_H
0009 #define KIO_NFS_H
0010 
0011 #include <KConfigGroup>
0012 #include <KIO/Global>
0013 #include <KIO/SlaveBase>
0014 
0015 #include <QHash>
0016 #include <QMap>
0017 #include <QString>
0018 #include <QStringList>
0019 
0020 #include "rpc_nfs2_prot.h"
0021 #include "rpc_nfs3_prot.h"
0022 
0023 class NFSProtocol;
0024 
0025 class NFSSlave : public QObject, public KIO::SlaveBase
0026 {
0027     Q_OBJECT
0028 
0029 public:
0030     NFSSlave(const QByteArray &pool, const QByteArray &app);
0031     ~NFSSlave() override;
0032 
0033     void openConnection() override;
0034     void closeConnection() override;
0035 
0036     void setHost(const QString &host, quint16 port, const QString &user, const QString &pass) override;
0037 
0038     void put(const QUrl &url, int _mode, KIO::JobFlags _flags) override;
0039     void get(const QUrl &url) override;
0040     void listDir(const QUrl &url) override;
0041     void symlink(const QString &target, const QUrl &dest, KIO::JobFlags) override;
0042     void stat(const QUrl &url) override;
0043     void mkdir(const QUrl &url, int permissions) override;
0044     void del(const QUrl &url, bool isfile) override;
0045     void chmod(const QUrl &url, int permissions) override;
0046     void rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) override;
0047     void copy(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags) override;
0048 
0049     void setError(KIO::Error errid, const QString &text);
0050     // NFSProtocol should not call these.  See setError() and finishOperation().
0051     void finished() = delete;
0052     void error(int errid, const QString &text) = delete;
0053 
0054     bool usedirplus3() const
0055     {
0056         return (m_usedirplus3);
0057     }
0058 
0059 protected:
0060     // Verifies the URL, current protocol and connection state, returns true if valid.
0061     bool verifyProtocol(const QUrl &url);
0062     void finishOperation();
0063 
0064 private:
0065     NFSProtocol *m_protocol;
0066 
0067     // We need to cache these because the @openConnection call is responsible
0068     // for creating the protocol, and the @setHost call might happen before that.
0069     QString m_host;
0070     QString m_user;
0071 
0072     bool m_usedirplus3;
0073 
0074     KIO::Error m_errorId;
0075     QString m_errorText;
0076 };
0077 
0078 class NFSFileHandle
0079 {
0080 public:
0081     NFSFileHandle();
0082     NFSFileHandle(const NFSFileHandle &handle);
0083     NFSFileHandle(const fhandle3 &src);
0084     NFSFileHandle(const fhandle &src);
0085     NFSFileHandle(const nfs_fh3 &src);
0086     NFSFileHandle(const nfs_fh &src);
0087     ~NFSFileHandle();
0088 
0089     // Copies the handle data to an nfs file handle
0090     void toFH(nfs_fh3 &fh) const;
0091     void toFH(nfs_fh &fh) const;
0092 
0093     // Copies the source link handle data to an nfs file handle
0094     void toFHLink(nfs_fh3 &fh) const;
0095     void toFHLink(nfs_fh &fh) const;
0096 
0097     NFSFileHandle &operator=(const NFSFileHandle &src);
0098     NFSFileHandle &operator=(const fhandle3 &src);
0099     NFSFileHandle &operator=(const fhandle &src);
0100     NFSFileHandle &operator=(const nfs_fh3 &src);
0101     NFSFileHandle &operator=(const nfs_fh &src);
0102 
0103     bool isInvalid() const
0104     {
0105         return m_size == 0 && m_linkSize == 0;
0106     }
0107     bool isLink() const
0108     {
0109         return m_isLink;
0110     }
0111     bool isBadLink() const
0112     {
0113         return (m_isLink && m_linkSize == 0);
0114     }
0115 
0116     void setLinkSource(const nfs_fh3 &src);
0117     void setLinkSource(const nfs_fh &src);
0118     void setBadLink()
0119     {
0120         m_isLink = true;
0121         m_linkSize = 0;
0122     }
0123 
0124 protected:
0125     char *m_handle;
0126     unsigned int m_size;
0127 
0128     // Set to the link source's handle.
0129     char *m_linkHandle;
0130     unsigned int m_linkSize;
0131     bool m_isLink;
0132 };
0133 
0134 typedef QMap<QString, NFSFileHandle> NFSFileHandleMap;
0135 
0136 class NFSProtocol
0137 {
0138 public:
0139     explicit NFSProtocol(NFSSlave *slave);
0140     virtual ~NFSProtocol()
0141     {
0142     }
0143 
0144     virtual bool isCompatible(bool &connectionError) = 0;
0145     virtual bool isConnected() const = 0;
0146 
0147     virtual void openConnection() = 0;
0148     virtual void closeConnection() = 0;
0149 
0150     virtual void setHost(const QString &host, const QString &user = QString());
0151 
0152     virtual void put(const QUrl &url, int _mode, KIO::JobFlags _flags) = 0;
0153     virtual void get(const QUrl &url) = 0;
0154     virtual void listDir(const QUrl &url) = 0;
0155     virtual void symlink(const QString &target, const QUrl &dest, KIO::JobFlags) = 0;
0156     virtual void stat(const QUrl &url) = 0;
0157     virtual void mkdir(const QUrl &url, int permissions) = 0;
0158     virtual void del(const QUrl &url, bool isfile) = 0;
0159     virtual void chmod(const QUrl &url, int permissions) = 0;
0160     virtual void rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) = 0;
0161 
0162     void copy(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags);
0163 
0164 protected:
0165     // Copy from NFS to NFS
0166     virtual void copySame(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags) = 0;
0167     // Copy from NFS to local
0168     virtual void copyFrom(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags) = 0;
0169     // Copy from local to NFS
0170     virtual void copyTo(const QUrl &src, const QUrl &dest, int mode, KIO::JobFlags flags) = 0;
0171 
0172     // Look up a file handle
0173     virtual NFSFileHandle lookupFileHandle(const QString &path) = 0;
0174 
0175     // Modify the exported dirs.
0176     void addExportedDir(const QString &path);
0177     const QStringList &getExportedDirs();
0178     bool isExportedDir(const QString &path);
0179     void removeExportedDir(const QString &path);
0180 
0181     // File handle cache functions.
0182     void addFileHandle(const QString &path, NFSFileHandle fh);
0183     NFSFileHandle getFileHandle(const QString &path);
0184     void removeFileHandle(const QString &path);
0185 
0186     // Make sure that the path is actually a part of an nfs share.
0187     bool isValidPath(const QString &path);
0188     bool isValidLink(const QString &parentDir, const QString &linkDest);
0189 
0190     KIO::Error openConnection(const QString &host, int prog, int vers, CLIENT *&client, int &sock);
0191 
0192     bool checkForError(int clientStat, int nfsStat, const QString &text);
0193 
0194     void createVirtualDirEntry(KIO::UDSEntry &entry);
0195 
0196     QString listDirInternal(const QUrl &url);
0197     QString statInternal(const QUrl &url);
0198     void completeUDSEntry(KIO::UDSEntry &entry, uid_t uid, gid_t gid);
0199     void completeInvalidUDSEntry(KIO::UDSEntry &entry);
0200 
0201     QString currentHost() const
0202     {
0203         return (m_currentHost);
0204     }
0205     NFSSlave *slave() const
0206     {
0207         return (m_slave);
0208     }
0209     void setError(KIO::Error errid, const QString &text)
0210     {
0211         m_slave->setError(errid, text);
0212     }
0213 
0214 private:
0215     NFSSlave *m_slave;
0216     QString m_currentHost;
0217     QString m_currentUser;
0218 
0219     NFSFileHandleMap m_handleCache;
0220     QStringList m_exportedDirs;
0221 
0222     QHash<uid_t, QString> m_usercache;
0223     QHash<gid_t, QString> m_groupcache;
0224 };
0225 
0226 #endif