File indexing completed on 2024-05-05 04:59:31

0001 /*
0002     fish.h  -  a FISH KIO worker
0003     SPDX-FileCopyrightText: 2001 Jörg Walter <trouble@garni.ch>
0004     SPDX-License-Identifier: GPL-2.0-only
0005 */
0006 
0007 #ifndef FISH_H
0008 #define FISH_H
0009 
0010 #include <KIO/AuthInfo>
0011 #include <KIO/Global>
0012 #include <KIO/WorkerBase>
0013 
0014 #define FISH_EXEC_CMD 'X'
0015 
0016 using Result = KIO::WorkerResult;
0017 
0018 struct ReceivedResult {
0019     KIO::fileoffset_t remainingBufferSize;
0020     KIO::WorkerResult result;
0021 };
0022 
0023 struct ConnectedResult {
0024     qsizetype remainingBufferSize;
0025     KIO::WorkerResult result;
0026 };
0027 
0028 class fishProtocol : public KIO::WorkerBase
0029 {
0030 public:
0031     fishProtocol(const QByteArray &pool_socket, const QByteArray &app_socket);
0032     ~fishProtocol() override;
0033 
0034     /**
0035     Connects to a server and logs us in via SSH. Then starts FISH protocol.
0036     @ref isConnected is set to true if logging on was successful.
0037     It is set to false if the connection becomes closed.
0038 
0039     */
0040     KIO::WorkerResult openConnection() override;
0041 
0042     /** sets connection information for subsequent commands */
0043     void setHost(const QString &host, quint16 port, const QString &user, const QString &pass) override;
0044     /** Forced close of the connection */
0045     void closeConnection() override;
0046     /** get a file */
0047     KIO::WorkerResult get(const QUrl &url) override;
0048     /** put a file */
0049     KIO::WorkerResult put(const QUrl &url, int permissions, KIO::JobFlags flags) override;
0050     /** stat a file */
0051     KIO::WorkerResult stat(const QUrl &url) override;
0052     /** find mimetype for a file */
0053     KIO::WorkerResult mimetype(const QUrl &url) override;
0054     /** list a directory */
0055     KIO::WorkerResult listDir(const QUrl &url) override;
0056     /** create a directory */
0057     KIO::WorkerResult mkdir(const QUrl &url, int permissions) override;
0058     /** rename a file */
0059     KIO::WorkerResult rename(const QUrl &src, const QUrl &dest, KIO::JobFlags flags) override;
0060     /** create a symlink */
0061     KIO::WorkerResult symlink(const QString &target, const QUrl &dest, KIO::JobFlags flags) override;
0062     /** change file permissions */
0063     KIO::WorkerResult chmod(const QUrl &url, int permissions) override;
0064     /** copies a file */
0065     KIO::WorkerResult copy(const QUrl &src, const QUrl &dest, int permissions, KIO::JobFlags flags) override;
0066     /** report status */
0067     void worker_status() override;
0068     /** removes a file or directory */
0069     KIO::WorkerResult del(const QUrl &u, bool isfile) override;
0070     /** special like background execute */
0071     KIO::WorkerResult special(const QByteArray &data) override;
0072 
0073 private: // Private methods
0074     /** Clean up connection */
0075     void shutdownConnection(bool forced = false);
0076     /** aborts command sequence and calls error() */
0077     Q_REQUIRED_RESULT KIO::WorkerResult error(int type, const QString &detail);
0078     /** executes next command in sequence or calls finished() if all is done */
0079     void finished();
0080 
0081 private: // Private attributes
0082     /** fd for reading and writing to the process */
0083     int childFd;
0084     /** buffer for data to be written */
0085     QByteArray outBuf;
0086     /** current write position in buffer */
0087     KIO::fileoffset_t outBufPos;
0088     /** use su if true else use ssh */
0089     bool local;
0090     /**  // FIXME: just a workaround for konq deficiencies */
0091     bool isStat;
0092     /**  // FIXME: just a workaround for konq deficiencies */
0093     QString redirectUser, redirectPass;
0094 
0095 protected: // Protected attributes
0096     /** for LIST/STAT */
0097     KIO::UDSEntry udsEntry;
0098     /** for LIST/STAT */
0099     KIO::UDSEntry udsStatEntry;
0100     /** for LIST/STAT */
0101     long long udsType;
0102     /** for LIST/STAT */
0103     QString udsMime;
0104     /** for LIST/STAT */
0105     QString thisFn;
0106     /** for STAT */
0107     QString wantedFn;
0108     QString statPath;
0109     /** url of current request */
0110     QUrl url;
0111     /** true if connection is logged in successfully */
0112     bool isLoggedIn;
0113     /** host name of current connection */
0114     QString connectionHost;
0115     /** user name of current connection */
0116     QString connectionUser;
0117     /** port of current connection */
0118     int connectionPort;
0119     /** password of current connection */
0120     QString connectionPassword;
0121     /** AuthInfo object used for logging in */
0122     KIO::AuthInfo connectionAuth;
0123     /** number of lines received, == 0 -> everything went ok */
0124     int errorCount;
0125     /** queue for lines to be sent */
0126     QList<QByteArray> qlist;
0127     /** queue for commands to be sent */
0128     QStringList commandList;
0129     /** queue for commands to be sent */
0130     QList<int> commandCodes;
0131     /** bytes still to be read in raw mode */
0132     KIO::fileoffset_t rawRead;
0133     /** bytes still to be written in raw mode */
0134     KIO::fileoffset_t rawWrite;
0135     /** data bytes to read in next read command */
0136     KIO::fileoffset_t recvLen;
0137     /** data bytes to write in next write command */
0138     KIO::fileoffset_t sendLen;
0139     /** true if the last write operation was finished */
0140     bool writeReady;
0141     /** true if a command stack is currently executing */
0142     bool isRunning;
0143     /** reason of LIST command */
0144     enum { CHECK, LIST } listReason;
0145     /** true if FISH server understands APPEND command */
0146     bool hasAppend;
0147     /** permission of created file */
0148     int putPerm;
0149     /** true if file may be overwritten */
0150     bool checkOverwrite;
0151     /** current position of write */
0152     KIO::fileoffset_t putPos;
0153     /** true if file already existed */
0154     bool checkExist;
0155     /** true if this is the first login attempt (== use cached password) */
0156     bool firstLogin;
0157     /** write buffer */
0158     QByteArray rawData;
0159     /** buffer for storing bytes used for MimeMagic */
0160     QByteArray mimeBuffer;
0161     /** whther the mimetype has been sent already */
0162     bool mimeTypeSent;
0163     /** number of bytes read so far */
0164     KIO::fileoffset_t dataRead;
0165     /** details about each fishCommand */
0166     static const struct fish_info {
0167         const char *command;
0168         int params;
0169         const char *alt;
0170         int lines;
0171     } fishInfo[];
0172     /** last FISH command sent to server */
0173     enum fish_command_type {
0174         FISH_FISH,
0175         FISH_VER,
0176         FISH_PWD,
0177         FISH_LIST,
0178         FISH_STAT,
0179         FISH_RETR,
0180         FISH_STOR,
0181         FISH_CWD,
0182         FISH_CHMOD,
0183         FISH_DELE,
0184         FISH_MKD,
0185         FISH_RMD,
0186         FISH_RENAME,
0187         FISH_LINK,
0188         FISH_SYMLINK,
0189         FISH_CHOWN,
0190         FISH_CHGRP,
0191         FISH_READ,
0192         FISH_WRITE,
0193         FISH_COPY,
0194         FISH_APPEND,
0195         FISH_EXEC
0196     } fishCommand;
0197     int fishCodeLen;
0198 
0199 protected: // Protected methods
0200     /** manages initial communication setup including password queries */
0201 #ifndef Q_OS_WIN
0202     ConnectedResult establishConnection(char *buffer, KIO::fileoffset_t buflen);
0203 #else
0204     ConnectedResult establishConnection(const QByteArray &buffer);
0205 #endif
0206     ReceivedResult received(const char *buffer, KIO::fileoffset_t buflen);
0207     void sent();
0208     /** builds each FISH request and sets the error counter */
0209     bool sendCommand(fish_command_type cmd, ...);
0210     /** checks response string for result code, converting 000 and 001 appropriately */
0211     int handleResponse(const QString &str);
0212     /** parses a ls -l time spec */
0213     int makeTimeFromLs(const QString &dayStr, const QString &monthStr, const QString &timeyearStr);
0214     /** executes a chain of commands */
0215     KIO::WorkerResult run();
0216     /** creates the subprocess */
0217     KIO::WorkerResult connectionStart();
0218     /** writes one chunk of data to stdin of child process */
0219 #ifndef Q_OS_WIN
0220     void writeChild(const char *buf, KIO::fileoffset_t len);
0221 #else
0222     void writeChild(const QByteArray &buf, KIO::fileoffset_t len);
0223 #endif
0224     /** parses response from server and acts accordingly */
0225     KIO::WorkerResult manageConnection(const QString &line);
0226     /** writes to process */
0227     void writeStdin(const QString &line);
0228     /** Verify port **/
0229     void setHostInternal(const QUrl &u);
0230 };
0231 
0232 #endif