#pragma once #include #include #include #ifdef _WIN32 #include #include #else #include #include #include #include #endif #include #include #include #include #ifndef LIBSSH2_S_ISDIR #define LIBSSH2_S_ISDIR(mode) (((mode) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) #endif #ifndef LIBSSH2_S_ISREG #define LIBSSH2_S_ISREG(mode) (((mode) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) #endif struct RemoteFileInfo { QString name; qint64 size; bool isDir; uint permissions; QDateTime lastModified; // 修改日期 uint uid; // 用户ID uint gid; // 组ID QString owner; // 用户名 QString group; // 组名 }; class ScpClient : public QObject { Q_OBJECT public: explicit ScpClient(QObject *parent = nullptr); ~ScpClient(); bool connectToHost(const QString &host, int port, const QString &user, const QString &password, int timeoutMs = 10000); void disconnectFromHost(); bool download(const QString &remotePath, const QString &localPath); bool upload(const QString &localPath, const QString &remotePath,const QString& fileName,int type = -1, int fileMode = 0644); void cancel(); void uploadFinish(); // ===== SFTP 相关 ===== bool listRemoteDir(const QString &path, QVector &outList); bool makeRemoteDir(const QString &path, int mode = 0755); bool removeRemoteFile(const QString &path); bool removeRemoteDir(const QString &path); bool renameRemote(const QString &oldPath, const QString &newPath); bool exec(const QString &cmd, QString &output); void waitSocket(int sock); bool goUp(QString& filePath, QVector &outList,QString& retPath); QString m_currentPath; signals: void progress(qint64 current, qint64 total); void error(const QString &msg); void finished(); private: int m_sock{-1}; LIBSSH2_SESSION *m_session{nullptr}; std::atomic_bool m_cancelled{false}; int m_Type; QString m_fileName; QString uidToName(uint uid); QString gidToName(uint gid); };