File indexing completed on 2024-05-05 12:18:22

0001 /*
0002     SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef SLAVEBASE_H
0008 #define SLAVEBASE_H
0009 
0010 #include "job_base.h" // for KIO::JobFlags
0011 #include <kio/authinfo.h>
0012 #include <kio/global.h>
0013 #include <kio/udsentry.h>
0014 
0015 #include <QByteArray>
0016 #include <QHostInfo>
0017 
0018 #include <memory>
0019 
0020 class KConfigGroup;
0021 class KRemoteEncoding;
0022 class QUrl;
0023 
0024 namespace KIO
0025 {
0026 class Connection;
0027 class SlaveBasePrivate;
0028 
0029 // TODO: Enable once file KIO worker is ported away and add endif, similar in the cpp file
0030 // #if KIOCORE_ENABLE_DEPRECATED_SINCE(version where file:/ KIO worker was ported)
0031 
0032 /**
0033  * @class KIO::SlaveBase slavebase.h <KIO/SlaveBase>
0034  *
0035  * There are two classes that specifies the protocol between application (job)
0036  * and kioslave. SlaveInterface is the class to use on the application end,
0037  * SlaveBase is the one to use on the slave end.
0038  *
0039  * Slave implementations should simply inherit SlaveBase
0040  *
0041  * A call to foo() results in a call to slotFoo() on the other end.
0042  *
0043  * Note that a kioslave doesn't have a Qt event loop. When idle, it's waiting for a command
0044  * on the socket that connects it to the application. So don't expect a kioslave to react
0045  * to D-Bus signals for instance. KIOSlaves are short-lived anyway, so any kind of watching
0046  * or listening for notifications should be done elsewhere, for instance in a kded module
0047  * (see kio_desktop's desktopnotifier.cpp for an example).
0048  *
0049  * If a kioslave needs a Qt event loop within the implementation of one method, e.g. to
0050  * wait for an asynchronous operation to finish, that is possible, using QEventLoop.
0051  *
0052  * @deprecated Since 5.96, use WorkerBase.
0053  */
0054 class KIOCORE_EXPORT SlaveBase
0055 {
0056 public:
0057     KIOCORE_DEPRECATED_VERSION_BELATED(5, 101, 5, 96, "Use WorkerBase")
0058     SlaveBase(const QByteArray &protocol, const QByteArray &pool_socket, const QByteArray &app_socket);
0059     virtual ~SlaveBase();
0060 
0061     /**
0062      * @internal
0063      * Terminate the slave by calling the destructor and then ::exit()
0064      */
0065     void exit();
0066 
0067     /**
0068      * @internal
0069      */
0070     void dispatchLoop();
0071 
0072     ///////////
0073     // Message Signals to send to the job
0074     ///////////
0075 
0076     /**
0077      * Sends data in the slave to the job (i.e.\ in get).
0078      *
0079      * To signal end of data, simply send an empty
0080      * QByteArray().
0081      *
0082      * @param data the data read by the slave
0083      */
0084     void data(const QByteArray &data);
0085 
0086     /**
0087      * Asks for data from the job.
0088      * @see readData
0089      */
0090     void dataReq();
0091 
0092     /**
0093      * open succeeds
0094      * @see open()
0095      */
0096     void opened();
0097 
0098     /**
0099      * Call to signal an error.
0100      * This also finishes the job, so you must not call
0101      * finished() after calling this.
0102      *
0103      * If the error code is KIO::ERR_SLAVE_DEFINED then the
0104      * _text should contain the complete translated text of
0105      * of the error message.
0106      *
0107      * For all other error codes, _text should match the corresponding
0108      * error code. Usually, _text is a file or host name, or the error which
0109      * was passed from the server.<br>
0110      * For example, for KIO::ERR_DOES_NOT_EXIST, _text may only
0111      * be the file or folder which does not exist, nothing else. Otherwise,
0112      * this would break error strings generated by KIO::buildErrorString().<br>
0113      * If you have to add more details than what the standard error codes
0114      * provide, you'll need to use KIO::ERR_SLAVE_DEFINED.
0115      * For a complete list of what _text should contain for each error code,
0116      * look at the source of KIO::buildErrorString().
0117      *
0118      * You can add rich text markup to the message, the places where the
0119      * error message will be displayed are rich text aware.
0120      *
0121      * @see KIO::Error
0122      * @see KIO::buildErrorString
0123      * @param _errid the error code from KIO::Error
0124      * @param _text the rich text error message
0125      */
0126     void error(int _errid, const QString &_text);
0127 
0128     /**
0129      * Call in openConnection, if you reimplement it, when you're done.
0130      */
0131     void connected();
0132 
0133     /**
0134      * Call to signal successful completion of any command
0135      * besides openConnection and closeConnection. Do not
0136      * call this after calling error().
0137      */
0138     void finished();
0139 
0140     /**
0141      * Call to signal that data from the sub-URL is needed
0142      */
0143     void needSubUrlData();
0144 
0145     /**
0146      * Used to report the status of the slave.
0147      * @param host the slave is currently connected to. (Should be
0148      *        empty if not connected)
0149      * @param connected Whether an actual network connection exists.
0150      **/
0151     void slaveStatus(const QString &host, bool connected);
0152 
0153     /**
0154      * Call this from stat() to express details about an object, the
0155      * UDSEntry customarily contains the atoms describing file name, size,
0156      * MIME type, etc.
0157      * @param _entry The UDSEntry containing all of the object attributes.
0158      */
0159     void statEntry(const UDSEntry &_entry);
0160 
0161     /**
0162      * Call this in listDir, each time you have a bunch of entries
0163      * to report.
0164      * @param _entry The UDSEntry containing all of the object attributes.
0165      */
0166     void listEntries(const UDSEntryList &_entry);
0167 
0168     /**
0169      * Call this at the beginning of put(), to give the size of the existing
0170      * partial file, if there is one. The @p offset argument notifies the
0171      * other job (the one that gets the data) about the offset to use.
0172      * In this case, the boolean returns whether we can indeed resume or not
0173      * (we can't if the protocol doing the get() doesn't support setting an offset)
0174      */
0175     bool canResume(KIO::filesize_t offset);
0176 
0177     /**
0178      * Call this at the beginning of get(), if the "range-start" metadata was set
0179      * and returning byte ranges is implemented by this protocol.
0180      */
0181     void canResume();
0182 
0183     ///////////
0184     // Info Signals to send to the job
0185     ///////////
0186 
0187     /**
0188      * Call this in get and copy, to give the total size
0189      * of the file.
0190      */
0191     void totalSize(KIO::filesize_t _bytes);
0192     /**
0193      * Call this during get and copy, once in a while,
0194      * to give some info about the current state.
0195      * Don't emit it in listDir, listEntries speaks for itself.
0196      */
0197     void processedSize(KIO::filesize_t _bytes);
0198 
0199     void position(KIO::filesize_t _pos);
0200 
0201     void written(KIO::filesize_t _bytes);
0202 
0203     /**
0204      * @since 5.66
0205      */
0206     void truncated(KIO::filesize_t _length);
0207 
0208     /**
0209      * Only use this if you can't know in advance the size of the
0210      * copied data. For example, if you're doing variable bitrate
0211      * compression of the source.
0212      *
0213      * STUB ! Currently unimplemented. Here now for binary compatibility.
0214      *
0215      * Call this during get and copy, once in a while,
0216      * to give some info about the current state.
0217      * Don't emit it in listDir, listEntries speaks for itself.
0218      */
0219     void processedPercent(float percent); // KF6 TODO REMOVE
0220 
0221     /**
0222      * Call this in get and copy, to give the current transfer
0223      * speed, but only if it can't be calculated out of the size you
0224      * passed to processedSize (in most cases you don't want to call it)
0225      */
0226     void speed(unsigned long _bytes_per_second);
0227 
0228     /**
0229      * Call this to signal a redirection.
0230      * The job will take care of going to that url.
0231      */
0232     void redirection(const QUrl &_url);
0233 
0234     /**
0235      * Tell that we will only get an error page here.
0236      * This means: the data you'll get isn't the data you requested,
0237      * but an error page (usually HTML) that describes an error.
0238      */
0239     void errorPage();
0240 
0241     /**
0242      * Call this in mimetype() and in get(), when you know the MIME type.
0243      * See mimetype() about other ways to implement it.
0244      */
0245     void mimeType(const QString &_type);
0246 
0247     /**
0248      * Call to signal a warning, to be displayed in a dialog box.
0249      */
0250     void warning(const QString &msg);
0251 
0252     /**
0253      * Call to signal a message, to be displayed if the application wants to,
0254      * for instance in a status bar. Usual examples are "connecting to host xyz", etc.
0255      */
0256     void infoMessage(const QString &msg);
0257 
0258     /**
0259      * Type of message box. Should be kept in sync with KMessageBox::DialogType.
0260      */
0261     enum MessageBoxType {
0262         QuestionTwoActions = 1, ///< @since 5.100
0263         WarningTwoActions = 2, ///< @since 5.100
0264         WarningContinueCancel = 3,
0265         WarningTwoActionsCancel = 4, ///< @since 5.100
0266         Information = 5,
0267         SSLMessageBox = 6,
0268         // In KMessageBox::DialogType; Sorry = 7, Error = 8, QuestionTwoActionsCancel = 9
0269         WarningContinueCancelDetailed = 10,
0270 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 100)
0271         QuestionYesNo ///< @deprecated Since 5.100, use QuestionTwoActions.
0272             KIOCORE_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use QuestionTwoActions.") = QuestionTwoActions,
0273         WarningYesNo ///< @deprecated Since 5.100, use WarningTwoActions.
0274             KIOCORE_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use WarningTwoActions.") = WarningTwoActions,
0275         WarningYesNoCancel ///< @deprecated Since 5.100, use WarningTwoActionsCancel.
0276             KIOCORE_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use WarningTwoActionsCancel.") = WarningTwoActionsCancel,
0277 #endif
0278     };
0279 
0280     /**
0281      * Button codes. Should be kept in sync with KMessageBox::ButtonCode
0282      */
0283     enum ButtonCode {
0284         Ok = 1,
0285         Cancel = 2,
0286         PrimaryAction = 3, ///< @since 5.100
0287         SecondaryAction = 4, ///< @since 5.100
0288         Continue = 5,
0289 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 100)
0290         Yes ///< @deprecated Since 5.100, use PrimaryAction.
0291             KIOCORE_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use PrimaryAction.") = PrimaryAction,
0292         No ///< @deprecated Since 5.100, use SecondaryAction.
0293             KIOCORE_ENUMERATOR_DEPRECATED_VERSION(5, 100, "Use SecondaryAction.") = SecondaryAction,
0294 #endif
0295     };
0296 
0297     /**
0298      * Call this to show a message box from the slave
0299      * @param type type of message box: QuestionTwoActions, WarningTwoActions, WarningContinueCancel...
0300      * @param text Message string. May contain newlines.
0301      * @param title Message box title.
0302      * @param primaryActionText the text for the first button.
0303      *                          Ignored for @p type Information & SSLMessageBox.
0304      *                          The (deprecated since 5.100) default is i18n("&Yes").
0305      * @param secondaryActionText the text for the second button.
0306      *                            Ignored for @p type WarningContinueCancel, WarningContinueCancelDetailed,
0307      *                            Information & SSLMessageBox.
0308      *                            The (deprecated since 5.100) default is i18n("&No").
0309      * @return a button code, as defined in ButtonCode, or 0 on communication error.
0310      */
0311     int messageBox(MessageBoxType type,
0312                    const QString &text,
0313                    const QString &title = QString(),
0314                    const QString &primaryActionText = QString(),
0315                    const QString &secondaryActionText = QString());
0316 
0317     /**
0318      * Call this to show a message box from the slave
0319      * @param text Message string. May contain newlines.
0320      * @param type type of message box: QuestionTwoActions, WarningTwoActions, WarningContinueCancel...
0321      * @param title Message box title.
0322      * @param primaryActionText the text for the first button.
0323      *                          Ignored for @p type Information & SSLMessageBox.
0324      *                          The (deprecated since 5.100) default is i18n("&Yes").
0325      * @param secondaryActionText the text for the second button.
0326      *                            Ignored for @p type WarningContinueCancel, WarningContinueCancelDetailed,
0327      *                            Information & SSLMessageBox.
0328      *                            The (deprecated since 5.100) default is i18n("&No").
0329      * @param dontAskAgainName the name used to store result from 'Do not ask again' checkbox.
0330      * @return a button code, as defined in ButtonCode, or 0 on communication error.
0331      */
0332     int messageBox(const QString &text,
0333                    MessageBoxType type,
0334                    const QString &title = QString(),
0335                    const QString &primaryActionText = QString(),
0336                    const QString &secondaryActionText = QString(),
0337                    const QString &dontAskAgainName = QString());
0338 
0339     /**
0340      * Sets meta-data to be send to the application before the first
0341      * data() or finished() signal.
0342      */
0343     void setMetaData(const QString &key, const QString &value);
0344 
0345     /**
0346      * Queries for the existence of a certain config/meta-data entry
0347      * send by the application to the slave.
0348      */
0349     bool hasMetaData(const QString &key) const;
0350 
0351     /**
0352      * Queries for config/meta-data send by the application to the slave.
0353      */
0354     QString metaData(const QString &key) const;
0355 
0356     /**
0357      * @internal for ForwardingSlaveBase
0358      * Contains all metadata (but no config) sent by the application to the slave.
0359      */
0360     MetaData allMetaData() const;
0361 
0362     /**
0363      * Returns a map to query config/meta-data information from.
0364      *
0365      * The application provides the slave with all configuration information
0366      * relevant for the current protocol and host.
0367      *
0368      * Use configValue() as shortcut.
0369      * @since 5.64
0370      */
0371     QMap<QString, QVariant> mapConfig() const;
0372 
0373     /**
0374      * Returns a bool from the config/meta-data information.
0375      * @since 5.64
0376      */
0377     bool configValue(const QString &key, bool defaultValue) const;
0378 
0379     /**
0380      * Returns an int from the config/meta-data information.
0381      * @since 5.64
0382      */
0383     int configValue(const QString &key, int defaultValue) const;
0384 
0385     /**
0386      * Returns a QString from the config/meta-data information.
0387      * @since 5.64
0388      */
0389     QString configValue(const QString &key, const QString &defaultValue = QString()) const;
0390 
0391     /**
0392      * Returns a configuration object to query config/meta-data information
0393      * from.
0394      *
0395      * The application provides the slave with all configuration information
0396      * relevant for the current protocol and host.
0397      *
0398      * @note Since 5.64 prefer to use mapConfig() or one of the configValue(...) overloads.
0399      * @todo Find replacements for the other current usages of this method.
0400      */
0401     KConfigGroup *config();
0402     // KF6: perhaps rename mapConfig() to config() when removing this
0403 
0404     /**
0405      * Returns an object that can translate remote filenames into proper
0406      * Unicode forms. This encoding can be set by the user.
0407      */
0408     KRemoteEncoding *remoteEncoding();
0409 
0410     ///////////
0411     // Commands sent by the job, the slave has to
0412     // override what it wants to implement
0413     ///////////
0414 
0415     /**
0416      * Set the host
0417      *
0418      * Called directly by createSlave, this is why there is no equivalent in
0419      * SlaveInterface, unlike the other methods.
0420      *
0421      * This method is called whenever a change in host, port or user occurs.
0422      */
0423     virtual void setHost(const QString &host, quint16 port, const QString &user, const QString &pass);
0424 
0425     /**
0426      * Prepare slave for streaming operation
0427      */
0428     virtual void setSubUrl(const QUrl &url); // TODO KF6 remove
0429 
0430     /**
0431      * Opens the connection (forced).
0432      *
0433      * When this function gets called the slave is operating in
0434      * connection-oriented mode.
0435      * When a connection gets lost while the slave operates in
0436      * connection oriented mode, the slave should report
0437      * ERR_CONNECTION_BROKEN instead of reconnecting. The user is
0438      * expected to disconnect the slave in the error handler.
0439      */
0440     virtual void openConnection();
0441 
0442     /**
0443      * Closes the connection (forced).
0444      *
0445      * Called when the application disconnects the slave to close
0446      * any open network connections.
0447      *
0448      * When the slave was operating in connection-oriented mode,
0449      * it should reset itself to connectionless (default) mode.
0450      */
0451     virtual void closeConnection();
0452 
0453     /**
0454      * get, aka read.
0455      * @param url the full url for this request. Host, port and user of the URL
0456      *        can be assumed to be the same as in the last setHost() call.
0457      *
0458      * The slave should first "emit" the MIME type by calling mimeType(),
0459      * and then "emit" the data using the data() method.
0460      *
0461      * The reason why we need get() to emit the MIME type is:
0462      * when pasting a URL in krunner, or konqueror's location bar,
0463      * we have to find out what is the MIME type of that URL.
0464      * Rather than doing it with a call to mimetype(), then the app or part
0465      * would have to do a second request to the same server, this is done
0466      * like this: get() is called, and when it emits the MIME type, the job
0467      * is put on hold and the right app or part is launched. When that app
0468      * or part calls get(), the slave is magically reused, and the download
0469      * can now happen. All with a single call to get() in the slave.
0470      * This mechanism is also described in KIO::get().
0471      */
0472     virtual void get(const QUrl &url);
0473 
0474     /**
0475      * open.
0476      * @param url the full url for this request. Host, port and user of the URL
0477      *        can be assumed to be the same as in the last setHost() call.
0478      * @param mode see \ref QIODevice::OpenMode
0479      */
0480     virtual void open(const QUrl &url, QIODevice::OpenMode mode);
0481 
0482     /**
0483      * read.
0484      * @param size the requested amount of data to read
0485      * @see KIO::FileJob::read()
0486      */
0487     virtual void read(KIO::filesize_t size);
0488     /**
0489      * write.
0490      * @param data the data to write
0491      * @see KIO::FileJob::write()
0492      */
0493     virtual void write(const QByteArray &data);
0494     /**
0495      * seek.
0496      * @param offset the requested amount of data to read
0497      * @see KIO::FileJob::read()
0498      */
0499     virtual void seek(KIO::filesize_t offset);
0500     /**
0501      * close.
0502      * @see KIO::FileJob::close()
0503      */
0504     virtual void close();
0505 
0506     /**
0507      * put, i.e.\ write data into a file.
0508      *
0509      * @param url where to write the file
0510      * @param permissions may be -1. In this case no special permission mode is set.
0511      * @param flags We support Overwrite here. Hopefully, we're going to
0512      * support Resume in the future, too.
0513      * If the file indeed already exists, the slave should NOT apply the
0514      * permissions change to it.
0515      * The support for resuming using .part files is done by calling canResume().
0516      *
0517      * IMPORTANT: Use the "modified" metadata in order to set the modification time of the file.
0518      *
0519      * @see canResume()
0520      */
0521     virtual void put(const QUrl &url, int permissions, JobFlags flags);
0522 
0523     /**
0524      * Finds all details for one file or directory.
0525      * The information returned is the same as what listDir returns,
0526      * but only for one file or directory.
0527      * Call statEntry() after creating the appropriate UDSEntry for this
0528      * url.
0529      *
0530      * You can use the "details" metadata to optimize this method to only
0531      * do as much work as needed by the application.
0532      * By default details is 2 (all details wanted, including modification time, size, etc.),
0533      * details==1 is used when deleting: we don't need all the information if it takes
0534      * too much time, no need to follow symlinks etc.
0535      * details==0 is used for very simple probing: we'll only get the answer
0536      * "it's a file or a directory (or a symlink), or it doesn't exist".
0537      */
0538     virtual void stat(const QUrl &url);
0539 
0540     /**
0541      * Finds MIME type for one file or directory.
0542      *
0543      * This method should either emit 'mimeType' or it
0544      * should send a block of data big enough to be able
0545      * to determine the MIME type.
0546      *
0547      * If the slave doesn't reimplement it, a get will
0548      * be issued, i.e. the whole file will be downloaded before
0549      * determining the MIME type on it - this is obviously not a
0550      * good thing in most cases.
0551      */
0552     virtual void mimetype(const QUrl &url);
0553 
0554     /**
0555      * Lists the contents of @p url.
0556      * The slave should emit ERR_CANNOT_ENTER_DIRECTORY if it doesn't exist,
0557      * if we don't have enough permissions.
0558      * You should not list files if the path in @p url is empty, but redirect
0559      * to a non-empty path instead.
0560      */
0561     virtual void listDir(const QUrl &url);
0562 
0563     /**
0564      * Create a directory
0565      * @param url path to the directory to create
0566      * @param permissions the permissions to set after creating the directory
0567      * (-1 if no permissions to be set)
0568      * The slave emits ERR_CANNOT_MKDIR if failure.
0569      */
0570     virtual void mkdir(const QUrl &url, int permissions);
0571 
0572     /**
0573      * Rename @p oldname into @p newname.
0574      * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will
0575      * ask for copy + del instead.
0576      *
0577      * Important: the slave must implement the logic "if the destination already
0578      * exists, error ERR_DIR_ALREADY_EXIST or ERR_FILE_ALREADY_EXIST".
0579      * For performance reasons no stat is done in the destination before hand,
0580      * the slave must do it.
0581      *
0582      * By default, rename() is only called when renaming (moving) from
0583      * yourproto://host/path to yourproto://host/otherpath.
0584      *
0585      * If you set renameFromFile=true then rename() will also be called when
0586      * moving a file from file:///path to yourproto://host/otherpath.
0587      * Otherwise such a move would have to be done the slow way (copy+delete).
0588      * See KProtocolManager::canRenameFromFile() for more details.
0589      *
0590      * If you set renameToFile=true then rename() will also be called when
0591      * moving a file from yourproto: to file:.
0592      * See KProtocolManager::canRenameToFile() for more details.
0593      *
0594      * @param src where to move the file from
0595      * @param dest where to move the file to
0596      * @param flags We support Overwrite here
0597      */
0598     virtual void rename(const QUrl &src, const QUrl &dest, JobFlags flags);
0599 
0600     /**
0601      * Creates a symbolic link named @p dest, pointing to @p target, which
0602      * may be a relative or an absolute path.
0603      * @param target The string that will become the "target" of the link (can be relative)
0604      * @param dest The symlink to create.
0605      * @param flags We support Overwrite here
0606      */
0607     virtual void symlink(const QString &target, const QUrl &dest, JobFlags flags);
0608 
0609     /**
0610      * Change permissions on @p url.
0611      *
0612      * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_CHMOD
0613      */
0614     virtual void chmod(const QUrl &url, int permissions);
0615 
0616     /**
0617      * Change ownership of @p url.
0618      *
0619      * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_CHOWN
0620      */
0621     virtual void chown(const QUrl &url, const QString &owner, const QString &group);
0622 
0623     /**
0624      * Sets the modification time for @p url.
0625      *
0626      * For instance this is what CopyJob uses to set mtime on dirs at the end of a copy.
0627      * It could also be used to set the mtime on any file, in theory.
0628      * The usual implementation on unix is to call utime(path, &myutimbuf).
0629      * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_SETTIME
0630      */
0631     virtual void setModificationTime(const QUrl &url, const QDateTime &mtime);
0632 
0633     /**
0634      * Copy @p src into @p dest.
0635      *
0636      * By default, copy() is only called when copying a file from
0637      * yourproto://host/path to yourproto://host/otherpath.
0638      *
0639      * If you set copyFromFile=true then copy() will also be called when
0640      * moving a file from file:///path to yourproto://host/otherpath.
0641      * Otherwise such a copy would have to be done the slow way (get+put).
0642      * See also KProtocolManager::canCopyFromFile().
0643      *
0644      * If you set copyToFile=true then copy() will also be called when
0645      * moving a file from yourproto: to file:.
0646      * See also KProtocolManager::canCopyToFile().
0647      *
0648      * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will
0649      * ask for get + put instead.
0650      *
0651      * If the slave returns an error ERR_FILE_ALREADY_EXIST, the job will
0652      * ask for a different destination filename.
0653      *
0654      * @param src where to copy the file from (decoded)
0655      * @param dest where to copy the file to (decoded)
0656      * @param permissions may be -1. In this case no special permission mode is set,
0657      *        and the owner and group permissions are not preserved.
0658      * @param flags We support Overwrite here
0659      *
0660      * Don't forget to set the modification time of @p dest to be the modification time of @p src.
0661      */
0662     virtual void copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags);
0663 
0664     /**
0665      * Delete a file or directory.
0666      * @param url file/directory to delete
0667      * @param isfile if true, a file should be deleted.
0668      *               if false, a directory should be deleted.
0669      *
0670      * By default, del() on a directory should FAIL if the directory is not empty.
0671      * However, if metadata("recurse") == "true", then the slave can do a recursive deletion.
0672      * This behavior is only invoked if the slave specifies deleteRecursive=true in its protocol file.
0673      */
0674     virtual void del(const QUrl &url, bool isfile);
0675 
0676     /**
0677      * Change the destination of a symlink
0678      * @param url the url of the symlink to modify
0679      * @param target the new destination (target) of the symlink
0680      */
0681     virtual void setLinkDest(const QUrl &url, const QString &target);
0682 
0683     /**
0684      * Used for any command that is specific to this slave (protocol).
0685      *
0686      * Examples are : HTTP POST, mount and unmount (kio_file)
0687      *
0688      * @param data packed data; the meaning is completely dependent on the
0689      *        slave, but usually starts with an int for the command number.
0690      * Document your slave's commands, at least in its header file.
0691      */
0692     virtual void special(const QByteArray &data);
0693 
0694     /**
0695      * Used for multiple get. Currently only used for HTTP pipelining
0696      * support.
0697      *
0698      * @param data packed data; Contains number of URLs to fetch, and for
0699      * each URL the URL itself and its associated MetaData.
0700      */
0701     virtual void multiGet(const QByteArray &data);
0702 
0703     /**
0704      * Called to get the status of the slave. Slave should respond
0705      * by calling slaveStatus(...)
0706      */
0707     virtual void slave_status();
0708 
0709     /**
0710      * Called by the scheduler to tell the slave that the configuration
0711      * changed (i.e.\ proxy settings).
0712      */
0713     virtual void reparseConfiguration();
0714 
0715     /**
0716      * @return timeout value for connecting to remote host.
0717      */
0718     int connectTimeout();
0719 
0720     /**
0721      * @return timeout value for connecting to proxy in secs.
0722      */
0723     int proxyConnectTimeout();
0724 
0725     /**
0726      * @return timeout value for read from first data from
0727      * remote host in seconds.
0728      */
0729     int responseTimeout();
0730 
0731     /**
0732      * @return timeout value for read from subsequent data from
0733      * remote host in secs.
0734      */
0735     int readTimeout();
0736 
0737     /**
0738      * This function sets a timeout of @p timeout seconds and calls
0739      * special(data) when the timeout occurs as if it was called by the
0740      * application.
0741      *
0742      * A timeout can only occur when the slave is waiting for a command
0743      * from the application.
0744      *
0745      * Specifying a negative timeout cancels a pending timeout.
0746      *
0747      * Only one timeout at a time is supported, setting a timeout
0748      * cancels any pending timeout.
0749      */
0750     void setTimeoutSpecialCommand(int timeout, const QByteArray &data = QByteArray());
0751 
0752     /////////////////
0753     // Dispatching (internal)
0754     ////////////////
0755 
0756     /**
0757      * @internal
0758      */
0759     virtual void dispatch(int command, const QByteArray &data);
0760 
0761     /**
0762      * @internal
0763      */
0764     virtual void dispatchOpenCommand(int command, const QByteArray &data);
0765 
0766     /**
0767      * Read data sent by the job, after a dataReq
0768      *
0769      * @param buffer buffer where data is stored
0770      * @return 0 on end of data,
0771      *         > 0 bytes read
0772      *         < 0 error
0773      **/
0774     int readData(QByteArray &buffer);
0775 
0776 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 0)
0777     /**
0778      * It collects entries and emits them via listEntries
0779      * when enough of them are there or a certain time
0780      * frame exceeded (to make sure the app gets some
0781      * items in time but not too many items one by one
0782      * as this will cause a drastic performance penalty).
0783      * @param _entry The UDSEntry containing all of the object attributes.
0784      * @param ready set to true after emitting all items. @p _entry is not
0785      *        used in this case
0786      * @deprecated since 5.0. the listEntry(entry, true) indicated
0787      * that the entry listing was completed. However, each slave should
0788      * already call finished() to also tell us that we're done listing.
0789      * You should make sure that finished() is called when the entry
0790      * listing is completed and simply remove the call to listEntry(entry, true).
0791      */
0792     KIOCORE_DEPRECATED_VERSION(5, 0, "See API docs")
0793     void listEntry(const UDSEntry &_entry, bool ready);
0794 #endif
0795 
0796     /**
0797      * It collects entries and emits them via listEntries
0798      * when enough of them are there or a certain time
0799      * frame exceeded (to make sure the app gets some
0800      * items in time but not too many items one by one
0801      * as this will cause a drastic performance penalty).
0802      * @param entry The UDSEntry containing all of the object attributes.
0803      * @since 5.0
0804      */
0805     void listEntry(const UDSEntry &entry);
0806 
0807     /**
0808      * internal function to connect a slave to/ disconnect from
0809      * either the slave pool or the application
0810      */
0811     void connectSlave(const QString &path);
0812     void disconnectSlave();
0813 
0814     /**
0815      * Prompt the user for Authorization info (login & password).
0816      *
0817      * Use this function to request authorization information from
0818      * the end user. You can also pass an error message which explains
0819      * why a previous authorization attempt failed. Here is a very
0820      * simple example:
0821      *
0822      * \code
0823      * KIO::AuthInfo authInfo;
0824      * int errorCode = openPasswordDialogV2(authInfo);
0825      * if (!errorCode) {
0826      *    qDebug() << QLatin1String("User: ") << authInfo.username;
0827      *    qDebug() << QLatin1String("Password: not displayed here!");
0828      * } else {
0829      *    error(errorCode, QString());
0830      * }
0831      * \endcode
0832      *
0833      * You can also preset some values like the username, caption or
0834      * comment as follows:
0835      *
0836      * \code
0837      * KIO::AuthInfo authInfo;
0838      * authInfo.caption = i18n("Acme Password Dialog");
0839      * authInfo.username = "Wile E. Coyote";
0840      * QString errorMsg = i18n("You entered an incorrect password.");
0841      * int errorCode = openPasswordDialogV2(authInfo, errorMsg);
0842      * [...]
0843      * \endcode
0844      *
0845      * \note You should consider using checkCachedAuthentication() to
0846      * see if the password is available in kpasswdserver before calling
0847      * this function.
0848      *
0849      * \note A call to this function can fail and return @p false,
0850      * if the password server could not be started for whatever reason.
0851      *
0852      * \note This function does not store the password information
0853      * automatically (and has not since kdelibs 4.7). If you want to
0854      * store the password information in a persistent storage like
0855      * KWallet, then you MUST call @ref cacheAuthentication.
0856      *
0857      * @see checkCachedAuthentication
0858      * @param info  See AuthInfo.
0859      * @param errorMsg Error message to show
0860      * @return a KIO error code: NoError (0), KIO::USER_CANCELED, or other error codes.
0861      */
0862     int openPasswordDialogV2(KIO::AuthInfo &info, const QString &errorMsg = QString());
0863 
0864 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 24)
0865     /**
0866      * @deprecated since KF 5.24, use openPasswordDialogV2.
0867      * The return value works differently:
0868      *  instead of
0869      *        if (!openPasswordDialog()) { error(USER_CANCELED); }
0870      *  store and pass the return value to error(), when NOT zero,
0871      *  as shown documentation for openPasswordDialogV2().
0872      */
0873     KIOCORE_DEPRECATED_VERSION(5, 24, "Use SlaveBase::openPasswordDialogV2(...)")
0874     bool openPasswordDialog(KIO::AuthInfo &info, const QString &errorMsg = QString());
0875 #endif
0876 
0877     /**
0878      * Checks for cached authentication based on parameters
0879      * given by @p info.
0880      *
0881      * Use this function to check if any cached password exists
0882      * for the URL given by @p info.  If @p AuthInfo::realmValue
0883      * and/or @p AuthInfo::verifyPath flag is specified, then
0884      * they will also be factored in determining the presence
0885      * of a cached password.  Note that @p Auth::url is a required
0886      * parameter when attempting to check for cached authorization
0887      * info. Here is a simple example:
0888      *
0889      * \code
0890      * AuthInfo info;
0891      * info.url = QUrl("https://www.foobar.org/foo/bar");
0892      * info.username = "somename";
0893      * info.verifyPath = true;
0894      * if ( !checkCachedAuthentication( info ) )
0895      * {
0896      *    int errorCode = openPasswordDialogV2(info);
0897      *     ....
0898      * }
0899      * \endcode
0900      *
0901      * @param       info See AuthInfo.
0902      * @return      @p true if cached Authorization is found, false otherwise.
0903      */
0904     bool checkCachedAuthentication(AuthInfo &info);
0905 
0906     /**
0907      * Caches @p info in a persistent storage like KWallet.
0908      *
0909      * Note that calling openPasswordDialogV2 does not store passwords
0910      * automatically for you (and has not since kdelibs 4.7).
0911      *
0912      * Here is a simple example of how to use cacheAuthentication:
0913      *
0914      * \code
0915      * AuthInfo info;
0916      * info.url = QUrl("https://www.foobar.org/foo/bar");
0917      * info.username = "somename";
0918      * info.verifyPath = true;
0919      * if ( !checkCachedAuthentication( info ) ) {
0920      *    int errorCode = openPasswordDialogV2(info);
0921      *    if (!errorCode) {
0922      *        if (info.keepPassword)  {  // user asked password be save/remembered
0923      *             cacheAuthentication(info);
0924      *        }
0925      *    }
0926      * }
0927      * \endcode
0928      *
0929      * @param info See AuthInfo.
0930      * @return @p true if @p info was successfully cached.
0931      */
0932     bool cacheAuthentication(const AuthInfo &info);
0933 
0934 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 0)
0935     /**
0936      * Used by the slave to check if it can connect
0937      * to a given host. This should be called where the slave is ready
0938      * to do a ::connect() on a socket. For each call to
0939      * requestNetwork must exist a matching call to
0940      * dropNetwork, or the system will stay online until
0941      * KNetMgr gets closed (or the SlaveBase gets destructed)!
0942      *
0943      * If KNetMgr is not running, then this is a no-op and returns true
0944      *
0945      * @param host tells the netmgr the host the slave wants to connect
0946      *             to. As this could also be a proxy, we can't just take
0947      *             the host currently connected to (but that's the default
0948      *             value)
0949      *
0950      * @return true in theory, the host is reachable
0951      *         false the system is offline and the host is in a remote network.
0952      *
0953      * @deprecated Since 5.0, for a very very long time, not implemented anymore
0954      * Probably dates back to model dialup times.
0955      */
0956     KIOCORE_DEPRECATED_VERSION(5, 0, "Not implemented & used")
0957     bool requestNetwork(const QString &host = QString());
0958 #endif
0959 
0960 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 0)
0961     /**
0962      *
0963      * Used by the slave to withdraw a connection requested by
0964      * requestNetwork. This function cancels the last call to
0965      * requestNetwork. If a client uses more than one internet
0966      * connection, it must use dropNetwork(host) to
0967      * stop each request.
0968      *
0969      * If KNetMgr is not running, then this is a no-op.
0970      *
0971      * @param host the host passed to requestNetwork
0972      *
0973      * A slave should call this function every time it disconnect from a host.
0974      *
0975      * @deprecated Since 5.0, for a very very long time, not implemented anymore
0976      * Probably dates back to model dialup times.
0977      */
0978     KIOCORE_DEPRECATED_VERSION(5, 0, "Not implemented & used")
0979     void dropNetwork(const QString &host = QString());
0980 #endif
0981 
0982     /**
0983      * Wait for an answer to our request, until we get @p expected1 or @p expected2
0984      * @return the result from readData, as well as the cmd in *pCmd if set, and the data in @p data
0985      */
0986     int waitForAnswer(int expected1, int expected2, QByteArray &data, int *pCmd = nullptr);
0987 
0988     /**
0989      * Internal function to transmit meta data to the application.
0990      * m_outgoingMetaData will be cleared; this means that if the slave is for
0991      * example put on hold and picked up by a different KIO::Job later the new
0992      * job will not see the metadata sent before.
0993      * See kio/DESIGN.krun for an overview of the state
0994      * progression of a job/slave.
0995      * @warning calling this method may seriously interfere with the operation
0996      * of KIO which relies on the presence of some metadata at some points in time.
0997      * You should not use it if you are not familiar with KIO and not before
0998      * the slave is connected to the last job before returning to idle state.
0999      */
1000     void sendMetaData();
1001 
1002     /**
1003      * Internal function to transmit meta data to the application.
1004      * Like sendMetaData() but m_outgoingMetaData will not be cleared.
1005      * This method is mainly useful in code that runs before the slave is connected
1006      * to its final job.
1007      */
1008     void sendAndKeepMetaData();
1009 
1010     /** If your ioslave was killed by a signal, wasKilled() returns true.
1011      Check it regularly in lengthy functions (e.g. in get();) and return
1012      as fast as possible from this function if wasKilled() returns true.
1013      This will ensure that your slave destructor will be called correctly.
1014      */
1015     bool wasKilled() const;
1016 
1017     /** Internally used.
1018      * @internal
1019      */
1020     void setKillFlag();
1021 
1022     /** Internally used
1023      * @internal
1024      */
1025     void lookupHost(const QString &host);
1026 
1027     /** Internally used
1028      * @internal
1029      */
1030     int waitForHostInfo(QHostInfo &info);
1031 
1032     /**
1033      * Checks with job if privilege operation is allowed.
1034      * @return privilege operation status.
1035      * @see PrivilegeOperationStatus
1036      * @since 5.66
1037      */
1038     PrivilegeOperationStatus requestPrivilegeOperation(const QString &operationDetails);
1039 
1040     /**
1041      * Adds @p action to the list of PolicyKit actions which the
1042      * slave is authorized to perform.
1043      *
1044      * @param action the PolicyKit action
1045      * @since 5.45
1046      */
1047     void addTemporaryAuthorization(const QString &action);
1048 
1049 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 66)
1050     /**
1051      * @deprecated since 5.66, use requestPrivilegeOperation(QString)
1052      */
1053     KIOCORE_DEPRECATED_VERSION(5, 66, "Pass QString action to requestPrivilegeOperation")
1054     PrivilegeOperationStatus requestPrivilegeOperation();
1055 #endif
1056 
1057 protected:
1058     /**
1059      * Name of the protocol supported by this slave
1060      */
1061     QByteArray mProtocol;
1062     // Often used by TcpSlaveBase and unlikely to change
1063     MetaData mOutgoingMetaData;
1064     MetaData mIncomingMetaData;
1065 
1066     enum VirtualFunctionId {
1067         AppConnectionMade = 0,
1068         GetFileSystemFreeSpace = 1, // KF6 TODO: Turn into a virtual method
1069         Truncate = 2, // KF6 TODO: Turn into a virtual method
1070     };
1071     virtual void virtual_hook(int id, void *data);
1072 
1073 private:
1074     // Convenience function converting mProtocol to QString as unsupportedActionErrorString(), which
1075     // is used in many places in the code, takes a QString parameter
1076     inline const QString protocolName() const
1077     {
1078         return QString::fromLatin1(mProtocol);
1079     }
1080 
1081     void setRunInThread(bool b);
1082 
1083     // This helps catching missing tr()/i18n() calls in error().
1084     void error(int _errid, const QByteArray &_text);
1085     void send(int cmd, const QByteArray &arr = QByteArray());
1086 
1087     std::unique_ptr<SlaveBasePrivate> const d;
1088     friend class SlaveBasePrivate;
1089     friend class WorkerThread;
1090     friend class WorkerBasePrivate;
1091     friend class WorkerSlaveBaseBridge;
1092 };
1093 
1094 /**
1095  * Returns an appropriate error message if the given command @p cmd
1096  * is an unsupported action (ERR_UNSUPPORTED_ACTION).
1097  * @param protocol name of the protocol
1098  * @param cmd given command
1099  * @see enum Command
1100  */
1101 KIOCORE_EXPORT QString unsupportedActionErrorString(const QString &protocol, int cmd);
1102 }
1103 
1104 #endif