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