1/*
2 SPDX-FileCopyrightText: 2000 David Faure <faure@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#ifndef SLAVEBASE_H
8#define SLAVEBASE_H
9
10#include "job_base.h" // for KIO::JobFlags
11#include <kio/authinfo.h>
12#include <kio/global.h>
13#include <kio/udsentry.h>
14
15#include <QByteArray>
16#include <QHostInfo>
17#include <QSsl>
18
19#include <memory>
20
21class KConfigGroup;
22class KRemoteEncoding;
23class QUrl;
24
25namespace KIO
26{
27class Connection;
28class SlaveBasePrivate;
29
30// TODO: Enable once file KIO worker is ported away and add endif, similar in the cpp file
31// #if KIOCORE_ENABLE_DEPRECATED_SINCE(version where file:/ KIO worker was ported)
32
33/**
34 * @class KIO::SlaveBase slavebase.h <KIO/SlaveBase>
35 *
36 * There are two classes that specifies the protocol between application (job)
37 * and kioslave. SlaveInterface is the class to use on the application end,
38 * SlaveBase is the one to use on the slave end.
39 *
40 * Slave implementations should simply inherit SlaveBase
41 *
42 * A call to foo() results in a call to slotFoo() on the other end.
43 *
44 * Note that a kioslave doesn't have a Qt event loop. When idle, it's waiting for a command
45 * on the socket that connects it to the application. So don't expect a kioslave to react
46 * to D-Bus signals for instance. KIOSlaves are short-lived anyway, so any kind of watching
47 * or listening for notifications should be done elsewhere, for instance in a kded module
48 * (see kio_desktop's desktopnotifier.cpp for an example).
49 *
50 * If a kioslave needs a Qt event loop within the implementation of one method, e.g. to
51 * wait for an asynchronous operation to finish, that is possible, using QEventLoop.
52 *
53 * @deprecated Since 5.96, use WorkerBase.
54 */
55class SlaveBase
56{
57public:
58 KIOCORE_DEPRECATED_VERSION_BELATED(5, 101, 5, 96, "Use WorkerBase")
59 SlaveBase(const QByteArray &protocol, const QByteArray &pool_socket, const QByteArray &app_socket);
60 virtual ~SlaveBase();
61
62 /**
63 * @internal
64 * Terminate the slave by calling the destructor and then ::exit()
65 */
66 void exit();
67
68 /**
69 * @internal
70 */
71 void dispatchLoop();
72
73 ///////////
74 // Message Signals to send to the job
75 ///////////
76
77 /**
78 * Sends data in the slave to the job (i.e.\ in get).
79 *
80 * To signal end of data, simply send an empty
81 * QByteArray().
82 *
83 * @param data the data read by the slave
84 */
85 void data(const QByteArray &data);
86
87 /**
88 * Asks for data from the job.
89 * @see readData
90 */
91 void dataReq();
92
93 /**
94 * open succeeds
95 * @see open()
96 */
97 void opened();
98
99 /**
100 * Call to signal an error.
101 * This also finishes the job, so you must not call
102 * finished() after calling this.
103 *
104 * If the error code is KIO::ERR_SLAVE_DEFINED then the
105 * _text should contain the complete translated text of
106 * of the error message.
107 *
108 * For all other error codes, _text should match the corresponding
109 * error code. Usually, _text is a file or host name, or the error which
110 * was passed from the server.<br>
111 * For example, for KIO::ERR_DOES_NOT_EXIST, _text may only
112 * be the file or folder which does not exist, nothing else. Otherwise,
113 * this would break error strings generated by KIO::buildErrorString().<br>
114 * If you have to add more details than what the standard error codes
115 * provide, you'll need to use KIO::ERR_SLAVE_DEFINED.
116 * For a complete list of what _text should contain for each error code,
117 * look at the source of KIO::buildErrorString().
118 *
119 * You can add rich text markup to the message, the places where the
120 * error message will be displayed are rich text aware.
121 *
122 * @see KIO::Error
123 * @see KIO::buildErrorString
124 * @param _errid the error code from KIO::Error
125 * @param _text the rich text error message
126 */
127 void error(int _errid, const QString &_text);
128
129 /**
130 * Call in openConnection, if you reimplement it, when you're done.
131 */
132 void connected();
133
134 /**
135 * Call to signal successful completion of any command
136 * besides openConnection and closeConnection. Do not
137 * call this after calling error().
138 */
139 void finished();
140
141 /**
142 * Used to report the status of the slave.
143 * @param host the slave is currently connected to. (Should be
144 * empty if not connected)
145 * @param connected Whether an actual network connection exists.
146 **/
147 void slaveStatus(const QString &host, bool connected);
148
149 /**
150 * Call this from stat() to express details about an object, the
151 * UDSEntry customarily contains the atoms describing file name, size,
152 * MIME type, etc.
153 * @param _entry The UDSEntry containing all of the object attributes.
154 */
155 void statEntry(const UDSEntry &_entry);
156
157 /**
158 * Call this in listDir, each time you have a bunch of entries
159 * to report.
160 * @param _entry The UDSEntry containing all of the object attributes.
161 */
162 void listEntries(const UDSEntryList &_entry);
163
164 /**
165 * Call this at the beginning of put(), to give the size of the existing
166 * partial file, if there is one. The @p offset argument notifies the
167 * other job (the one that gets the data) about the offset to use.
168 * In this case, the boolean returns whether we can indeed resume or not
169 * (we can't if the protocol doing the get() doesn't support setting an offset)
170 */
171 bool canResume(KIO::filesize_t offset);
172
173 /**
174 * Call this at the beginning of get(), if the "range-start" metadata was set
175 * and returning byte ranges is implemented by this protocol.
176 */
177 void canResume();
178
179 ///////////
180 // Info Signals to send to the job
181 ///////////
182
183 /**
184 * Call this in get and copy, to give the total size
185 * of the file.
186 */
187 void totalSize(KIO::filesize_t _bytes);
188 /**
189 * Call this during get and copy, once in a while,
190 * to give some info about the current state.
191 * Don't emit it in listDir, listEntries speaks for itself.
192 */
193 void processedSize(KIO::filesize_t _bytes);
194
195 void position(KIO::filesize_t _pos);
196
197 void written(KIO::filesize_t _bytes);
198
199 /**
200 * @since 5.66
201 */
202 void truncated(KIO::filesize_t _length);
203
204 /**
205 * Only use this if you can't know in advance the size of the
206 * copied data. For example, if you're doing variable bitrate
207 * compression of the source.
208 *
209 * STUB ! Currently unimplemented. Here now for binary compatibility.
210 *
211 * Call this during get and copy, once in a while,
212 * to give some info about the current state.
213 * Don't emit it in listDir, listEntries speaks for itself.
214 */
215 void processedPercent(float percent); // KF6 TODO REMOVE
216
217 /**
218 * Call this in get and copy, to give the current transfer
219 * speed, but only if it can't be calculated out of the size you
220 * passed to processedSize (in most cases you don't want to call it)
221 */
222 void speed(unsigned long _bytes_per_second);
223
224 /**
225 * Call this to signal a redirection.
226 * The job will take care of going to that url.
227 */
228 void redirection(const QUrl &_url);
229
230 /**
231 * Tell that we will only get an error page here.
232 * This means: the data you'll get isn't the data you requested,
233 * but an error page (usually HTML) that describes an error.
234 */
235 void errorPage();
236
237 /**
238 * Call this in mimetype() and in get(), when you know the MIME type.
239 * See mimetype() about other ways to implement it.
240 */
241 void mimeType(const QString &_type);
242
243 /**
244 * Call to signal a warning, to be displayed in a dialog box.
245 */
246 void warning(const QString &msg);
247
248 /**
249 * Call to signal a message, to be displayed if the application wants to,
250 * for instance in a status bar. Usual examples are "connecting to host xyz", etc.
251 */
252 void infoMessage(const QString &msg);
253
254 /**
255 * Type of message box. Should be kept in sync with KMessageBox::DialogType.
256 */
257 enum MessageBoxType {
258 QuestionTwoActions = 1, ///< @since 5.100
259 WarningTwoActions = 2, ///< @since 5.100
260 WarningContinueCancel = 3,
261 WarningTwoActionsCancel = 4, ///< @since 5.100
262 Information = 5,
263 // In KMessageBox::DialogType; <unused> = 7, Error = 8, QuestionTwoActionsCancel = 9
264 WarningContinueCancelDetailed = 10,
265 };
266
267 /**
268 * Button codes. Should be kept in sync with KMessageBox::ButtonCode
269 */
270 enum ButtonCode {
271 Ok = 1,
272 Cancel = 2,
273 PrimaryAction = 3, ///< @since 5.100
274 SecondaryAction = 4, ///< @since 5.100
275 Continue = 5,
276 };
277
278 /**
279 * Call this to show a message box from the slave
280 * @param type type of message box: QuestionTwoActions, WarningTwoActions, WarningContinueCancel...
281 * @param text Message string. May contain newlines.
282 * @param title Message box title.
283 * @param primaryActionText the text for the first button.
284 * Ignored for @p type Information & SSLMessageBox.
285 * @param secondaryActionText the text for the second button.
286 * Ignored for @p type WarningContinueCancel, WarningContinueCancelDetailed,
287 * Information & SSLMessageBox.
288 * @return a button code, as defined in ButtonCode, or 0 on communication error.
289 */
290 int messageBox(MessageBoxType type,
291 const QString &text,
292 const QString &title = QString(),
293 const QString &primaryActionText = QString(),
294 const QString &secondaryActionText = QString());
295
296 int sslError(const QVariantMap &sslData);
297
298 /**
299 * Call this to show a message box from the slave
300 * @param text Message string. May contain newlines.
301 * @param type type of message box: QuestionTwoActions, WarningTwoActions, WarningContinueCancel...
302 * @param title Message box title.
303 * @param primaryActionText the text for the first button.
304 * Ignored for @p type Information & SSLMessageBox.
305 * @param secondaryActionText the text for the second button.
306 * Ignored for @p type WarningContinueCancel, WarningContinueCancelDetailed,
307 * Information & SSLMessageBox.
308 * @param dontAskAgainName the name used to store result from 'Do not ask again' checkbox.
309 * @return a button code, as defined in ButtonCode, or 0 on communication error.
310 */
311 int messageBox(const QString &text,
312 MessageBoxType type,
313 const QString &title = QString(),
314 const QString &primaryActionText = QString(),
315 const QString &secondaryActionText = QString(),
316 const QString &dontAskAgainName = QString());
317
318 /**
319 * Sets meta-data to be send to the application before the first
320 * data() or finished() signal.
321 */
322 void setMetaData(const QString &key, const QString &value);
323
324 /**
325 * Queries for the existence of a certain config/meta-data entry
326 * send by the application to the slave.
327 */
328 bool hasMetaData(const QString &key) const;
329
330 /**
331 * Queries for config/meta-data send by the application to the slave.
332 */
333 QString metaData(const QString &key) const;
334
335 /**
336 * @internal for ForwardingSlaveBase
337 * Contains all metadata (but no config) sent by the application to the slave.
338 */
339 MetaData allMetaData() const;
340
341 /**
342 * Returns a map to query config/meta-data information from.
343 *
344 * The application provides the slave with all configuration information
345 * relevant for the current protocol and host.
346 *
347 * Use configValue() as shortcut.
348 * @since 5.64
349 */
350 QMap<QString, QVariant> mapConfig() const;
351
352 /**
353 * Returns a bool from the config/meta-data information.
354 * @since 5.64
355 */
356 bool configValue(const QString &key, bool defaultValue) const;
357
358 /**
359 * Returns an int from the config/meta-data information.
360 * @since 5.64
361 */
362 int configValue(const QString &key, int defaultValue) const;
363
364 /**
365 * Returns a QString from the config/meta-data information.
366 * @since 5.64
367 */
368 QString configValue(const QString &key, const QString &defaultValue = QString()) const;
369
370 /**
371 * Returns a configuration object to query config/meta-data information
372 * from.
373 *
374 * The application provides the slave with all configuration information
375 * relevant for the current protocol and host.
376 *
377 * @note Since 5.64 prefer to use mapConfig() or one of the configValue(...) overloads.
378 * @todo Find replacements for the other current usages of this method.
379 */
380 KConfigGroup *config();
381 // KF6: perhaps rename mapConfig() to config() when removing this
382
383 /**
384 * Returns an object that can translate remote filenames into proper
385 * Unicode forms. This encoding can be set by the user.
386 */
387 KRemoteEncoding *remoteEncoding();
388
389 ///////////
390 // Commands sent by the job, the slave has to
391 // override what it wants to implement
392 ///////////
393
394 /**
395 * Set the host
396 *
397 * Called directly by createWorker, this is why there is no equivalent in
398 * SlaveInterface, unlike the other methods.
399 *
400 * This method is called whenever a change in host, port or user occurs.
401 */
402 virtual void setHost(const QString &host, quint16 port, const QString &user, const QString &pass);
403
404 /**
405 * Opens the connection (forced).
406 *
407 * When this function gets called the slave is operating in
408 * connection-oriented mode.
409 * When a connection gets lost while the slave operates in
410 * connection oriented mode, the slave should report
411 * ERR_CONNECTION_BROKEN instead of reconnecting. The user is
412 * expected to disconnect the slave in the error handler.
413 */
414 virtual void openConnection();
415
416 /**
417 * Closes the connection (forced).
418 *
419 * Called when the application disconnects the slave to close
420 * any open network connections.
421 *
422 * When the slave was operating in connection-oriented mode,
423 * it should reset itself to connectionless (default) mode.
424 */
425 virtual void closeConnection();
426
427 /**
428 * get, aka read.
429 * @param url the full url for this request. Host, port and user of the URL
430 * can be assumed to be the same as in the last setHost() call.
431 *
432 * The slave should first "emit" the MIME type by calling mimeType(),
433 * and then "emit" the data using the data() method.
434 *
435 * The reason why we need get() to emit the MIME type is:
436 * when pasting a URL in krunner, or konqueror's location bar,
437 * we have to find out what is the MIME type of that URL.
438 * Rather than doing it with a call to mimetype(), then the app or part
439 * would have to do a second request to the same server, this is done
440 * like this: get() is called, and when it emits the MIME type, the job
441 * is put on hold and the right app or part is launched. When that app
442 * or part calls get(), the slave is magically reused, and the download
443 * can now happen. All with a single call to get() in the slave.
444 * This mechanism is also described in KIO::get().
445 */
446 virtual void get(const QUrl &url);
447
448 /**
449 * open.
450 * @param url the full url for this request. Host, port and user of the URL
451 * can be assumed to be the same as in the last setHost() call.
452 * @param mode see \ref QIODevice::OpenMode
453 */
454 virtual void open(const QUrl &url, QIODevice::OpenMode mode);
455
456 /**
457 * read.
458 * @param size the requested amount of data to read
459 * @see KIO::FileJob::read()
460 */
461 virtual void read(KIO::filesize_t size);
462 /**
463 * write.
464 * @param data the data to write
465 * @see KIO::FileJob::write()
466 */
467 virtual void write(const QByteArray &data);
468 /**
469 * seek.
470 * @param offset the requested amount of data to read
471 * @see KIO::FileJob::read()
472 */
473 virtual void seek(KIO::filesize_t offset);
474 /**
475 * close.
476 * @see KIO::FileJob::close()
477 */
478 virtual void close();
479
480 /**
481 * put, i.e.\ write data into a file.
482 *
483 * @param url where to write the file
484 * @param permissions may be -1. In this case no special permission mode is set.
485 * @param flags We support Overwrite here. Hopefully, we're going to
486 * support Resume in the future, too.
487 * If the file indeed already exists, the slave should NOT apply the
488 * permissions change to it.
489 * The support for resuming using .part files is done by calling canResume().
490 *
491 * IMPORTANT: Use the "modified" metadata in order to set the modification time of the file.
492 *
493 * @see canResume()
494 */
495 virtual void put(const QUrl &url, int permissions, JobFlags flags);
496
497 /**
498 * Finds all details for one file or directory.
499 * The information returned is the same as what listDir returns,
500 * but only for one file or directory.
501 * Call statEntry() after creating the appropriate UDSEntry for this
502 * url.
503 *
504 * You can use the "details" metadata to optimize this method to only
505 * do as much work as needed by the application.
506 * By default details is 2 (all details wanted, including modification time, size, etc.),
507 * details==1 is used when deleting: we don't need all the information if it takes
508 * too much time, no need to follow symlinks etc.
509 * details==0 is used for very simple probing: we'll only get the answer
510 * "it's a file or a directory (or a symlink), or it doesn't exist".
511 */
512 virtual void stat(const QUrl &url);
513
514 /**
515 * Finds MIME type for one file or directory.
516 *
517 * This method should either emit 'mimeType' or it
518 * should send a block of data big enough to be able
519 * to determine the MIME type.
520 *
521 * If the slave doesn't reimplement it, a get will
522 * be issued, i.e. the whole file will be downloaded before
523 * determining the MIME type on it - this is obviously not a
524 * good thing in most cases.
525 */
526 virtual void mimetype(const QUrl &url);
527
528 /**
529 * Lists the contents of @p url.
530 * The slave should emit ERR_CANNOT_ENTER_DIRECTORY if it doesn't exist,
531 * if we don't have enough permissions.
532 * You should not list files if the path in @p url is empty, but redirect
533 * to a non-empty path instead.
534 */
535 virtual void listDir(const QUrl &url);
536
537 /**
538 * Create a directory
539 * @param url path to the directory to create
540 * @param permissions the permissions to set after creating the directory
541 * (-1 if no permissions to be set)
542 * The slave emits ERR_CANNOT_MKDIR if failure.
543 */
544 virtual void mkdir(const QUrl &url, int permissions);
545
546 /**
547 * Rename @p oldname into @p newname.
548 * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will
549 * ask for copy + del instead.
550 *
551 * Important: the slave must implement the logic "if the destination already
552 * exists, error ERR_DIR_ALREADY_EXIST or ERR_FILE_ALREADY_EXIST".
553 * For performance reasons no stat is done in the destination before hand,
554 * the slave must do it.
555 *
556 * By default, rename() is only called when renaming (moving) from
557 * yourproto://host/path to yourproto://host/otherpath.
558 *
559 * If you set renameFromFile=true then rename() will also be called when
560 * moving a file from file:///path to yourproto://host/otherpath.
561 * Otherwise such a move would have to be done the slow way (copy+delete).
562 * See KProtocolManager::canRenameFromFile() for more details.
563 *
564 * If you set renameToFile=true then rename() will also be called when
565 * moving a file from yourproto: to file:.
566 * See KProtocolManager::canRenameToFile() for more details.
567 *
568 * @param src where to move the file from
569 * @param dest where to move the file to
570 * @param flags We support Overwrite here
571 */
572 virtual void rename(const QUrl &src, const QUrl &dest, JobFlags flags);
573
574 /**
575 * Creates a symbolic link named @p dest, pointing to @p target, which
576 * may be a relative or an absolute path.
577 * @param target The string that will become the "target" of the link (can be relative)
578 * @param dest The symlink to create.
579 * @param flags We support Overwrite here
580 */
581 virtual void symlink(const QString &target, const QUrl &dest, JobFlags flags);
582
583 /**
584 * Change permissions on @p url.
585 *
586 * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_CHMOD
587 */
588 virtual void chmod(const QUrl &url, int permissions);
589
590 /**
591 * Change ownership of @p url.
592 *
593 * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_CHOWN
594 */
595 virtual void chown(const QUrl &url, const QString &owner, const QString &group);
596
597 /**
598 * Sets the modification time for @p url.
599 *
600 * For instance this is what CopyJob uses to set mtime on dirs at the end of a copy.
601 * It could also be used to set the mtime on any file, in theory.
602 * The usual implementation on unix is to call utime(path, &myutimbuf).
603 * The slave emits ERR_DOES_NOT_EXIST or ERR_CANNOT_SETTIME
604 */
605 virtual void setModificationTime(const QUrl &url, const QDateTime &mtime);
606
607 /**
608 * Copy @p src into @p dest.
609 *
610 * By default, copy() is only called when copying a file from
611 * yourproto://host/path to yourproto://host/otherpath.
612 *
613 * If you set copyFromFile=true then copy() will also be called when
614 * moving a file from file:///path to yourproto://host/otherpath.
615 * Otherwise such a copy would have to be done the slow way (get+put).
616 * See also KProtocolManager::canCopyFromFile().
617 *
618 * If you set copyToFile=true then copy() will also be called when
619 * moving a file from yourproto: to file:.
620 * See also KProtocolManager::canCopyToFile().
621 *
622 * If the slave returns an error ERR_UNSUPPORTED_ACTION, the job will
623 * ask for get + put instead.
624 *
625 * If the slave returns an error ERR_FILE_ALREADY_EXIST, the job will
626 * ask for a different destination filename.
627 *
628 * @param src where to copy the file from (decoded)
629 * @param dest where to copy the file to (decoded)
630 * @param permissions may be -1. In this case no special permission mode is set,
631 * and the owner and group permissions are not preserved.
632 * @param flags We support Overwrite here
633 *
634 * Don't forget to set the modification time of @p dest to be the modification time of @p src.
635 */
636 virtual void copy(const QUrl &src, const QUrl &dest, int permissions, JobFlags flags);
637
638 /**
639 * Delete a file or directory.
640 * @param url file/directory to delete
641 * @param isfile if true, a file should be deleted.
642 * if false, a directory should be deleted.
643 *
644 * By default, del() on a directory should FAIL if the directory is not empty.
645 * However, if metadata("recurse") == "true", then the slave can do a recursive deletion.
646 * This behavior is only invoked if the slave specifies deleteRecursive=true in its protocol file.
647 */
648 virtual void del(const QUrl &url, bool isfile);
649
650 /**
651 * Change the destination of a symlink
652 * @param url the url of the symlink to modify
653 * @param target the new destination (target) of the symlink
654 */
655 virtual void setLinkDest(const QUrl &url, const QString &target);
656
657 /**
658 * Used for any command that is specific to this slave (protocol).
659 *
660 * Examples are : HTTP POST, mount and unmount (kio_file)
661 *
662 * @param data packed data; the meaning is completely dependent on the
663 * slave, but usually starts with an int for the command number.
664 * Document your slave's commands, at least in its header file.
665 */
666 virtual void special(const QByteArray &data);
667
668 /**
669 * Called to get the status of the slave. Slave should respond
670 * by calling slaveStatus(...)
671 */
672 virtual void slave_status();
673
674 /**
675 * Called by the scheduler to tell the slave that the configuration
676 * changed (i.e.\ proxy settings).
677 */
678 virtual void reparseConfiguration();
679
680 /**
681 * @return timeout value for connecting to remote host.
682 */
683 int connectTimeout();
684
685 /**
686 * @return timeout value for connecting to proxy in secs.
687 */
688 int proxyConnectTimeout();
689
690 /**
691 * @return timeout value for read from first data from
692 * remote host in seconds.
693 */
694 int responseTimeout();
695
696 /**
697 * @return timeout value for read from subsequent data from
698 * remote host in secs.
699 */
700 int readTimeout();
701
702 /**
703 * This function sets a timeout of @p timeout seconds and calls
704 * special(data) when the timeout occurs as if it was called by the
705 * application.
706 *
707 * A timeout can only occur when the slave is waiting for a command
708 * from the application.
709 *
710 * Specifying a negative timeout cancels a pending timeout.
711 *
712 * Only one timeout at a time is supported, setting a timeout
713 * cancels any pending timeout.
714 */
715 void setTimeoutSpecialCommand(int timeout, const QByteArray &data = QByteArray());
716
717 /////////////////
718 // Dispatching (internal)
719 ////////////////
720
721 /**
722 * @internal
723 */
724 virtual void dispatch(int command, const QByteArray &data);
725
726 /**
727 * @internal
728 */
729 virtual void dispatchOpenCommand(int command, const QByteArray &data);
730
731 /**
732 * Read data sent by the job, after a dataReq
733 *
734 * @param buffer buffer where data is stored
735 * @return 0 on end of data,
736 * > 0 bytes read
737 * < 0 error
738 **/
739 int readData(QByteArray &buffer);
740
741 /**
742 * It collects entries and emits them via listEntries
743 * when enough of them are there or a certain time
744 * frame exceeded (to make sure the app gets some
745 * items in time but not too many items one by one
746 * as this will cause a drastic performance penalty).
747 * @param entry The UDSEntry containing all of the object attributes.
748 * @since 5.0
749 */
750 void listEntry(const UDSEntry &entry);
751
752 /**
753 * internal function to connect a slave to/ disconnect from
754 * either the slave pool or the application
755 */
756 void connectSlave(const QString &path);
757 void disconnectSlave();
758
759 /**
760 * Prompt the user for Authorization info (login & password).
761 *
762 * Use this function to request authorization information from
763 * the end user. You can also pass an error message which explains
764 * why a previous authorization attempt failed. Here is a very
765 * simple example:
766 *
767 * \code
768 * KIO::AuthInfo authInfo;
769 * int errorCode = openPasswordDialogV2(authInfo);
770 * if (!errorCode) {
771 * qDebug() << QLatin1String("User: ") << authInfo.username;
772 * qDebug() << QLatin1String("Password: not displayed here!");
773 * } else {
774 * error(errorCode, QString());
775 * }
776 * \endcode
777 *
778 * You can also preset some values like the username, caption or
779 * comment as follows:
780 *
781 * \code
782 * KIO::AuthInfo authInfo;
783 * authInfo.caption = i18n("Acme Password Dialog");
784 * authInfo.username = "Wile E. Coyote";
785 * QString errorMsg = i18n("You entered an incorrect password.");
786 * int errorCode = openPasswordDialogV2(authInfo, errorMsg);
787 * [...]
788 * \endcode
789 *
790 * \note You should consider using checkCachedAuthentication() to
791 * see if the password is available in kpasswdserver before calling
792 * this function.
793 *
794 * \note A call to this function can fail and return @p false,
795 * if the password server could not be started for whatever reason.
796 *
797 * \note This function does not store the password information
798 * automatically (and has not since kdelibs 4.7). If you want to
799 * store the password information in a persistent storage like
800 * KWallet, then you MUST call @ref cacheAuthentication.
801 *
802 * @see checkCachedAuthentication
803 * @param info See AuthInfo.
804 * @param errorMsg Error message to show
805 * @return a KIO error code: NoError (0), KIO::USER_CANCELED, or other error codes.
806 */
807 int openPasswordDialogV2(KIO::AuthInfo &info, const QString &errorMsg = QString());
808
809 /**
810 * Checks for cached authentication based on parameters
811 * given by @p info.
812 *
813 * Use this function to check if any cached password exists
814 * for the URL given by @p info. If @p AuthInfo::realmValue
815 * and/or @p AuthInfo::verifyPath flag is specified, then
816 * they will also be factored in determining the presence
817 * of a cached password. Note that @p Auth::url is a required
818 * parameter when attempting to check for cached authorization
819 * info. Here is a simple example:
820 *
821 * \code
822 * AuthInfo info;
823 * info.url = QUrl("https://www.foobar.org/foo/bar");
824 * info.username = "somename";
825 * info.verifyPath = true;
826 * if ( !checkCachedAuthentication( info ) )
827 * {
828 * int errorCode = openPasswordDialogV2(info);
829 * ....
830 * }
831 * \endcode
832 *
833 * @param info See AuthInfo.
834 * @return @p true if cached Authorization is found, false otherwise.
835 */
836 bool checkCachedAuthentication(AuthInfo &info);
837
838 /**
839 * Caches @p info in a persistent storage like KWallet.
840 *
841 * Note that calling openPasswordDialogV2 does not store passwords
842 * automatically for you (and has not since kdelibs 4.7).
843 *
844 * Here is a simple example of how to use cacheAuthentication:
845 *
846 * \code
847 * AuthInfo info;
848 * info.url = QUrl("https://www.foobar.org/foo/bar");
849 * info.username = "somename";
850 * info.verifyPath = true;
851 * if ( !checkCachedAuthentication( info ) ) {
852 * int errorCode = openPasswordDialogV2(info);
853 * if (!errorCode) {
854 * if (info.keepPassword) { // user asked password be save/remembered
855 * cacheAuthentication(info);
856 * }
857 * }
858 * }
859 * \endcode
860 *
861 * @param info See AuthInfo.
862 * @return @p true if @p info was successfully cached.
863 */
864 bool cacheAuthentication(const AuthInfo &info);
865
866 /**
867 * Wait for an answer to our request, until we get @p expected1 or @p expected2
868 * @return the result from readData, as well as the cmd in *pCmd if set, and the data in @p data
869 */
870 int waitForAnswer(int expected1, int expected2, QByteArray &data, int *pCmd = nullptr);
871
872 /**
873 * Internal function to transmit meta data to the application.
874 * m_outgoingMetaData will be cleared; this means that if the slave is for
875 * example put on hold and picked up by a different KIO::Job later the new
876 * job will not see the metadata sent before.
877 * See kio/DESIGN.krun for an overview of the state
878 * progression of a job/slave.
879 * @warning calling this method may seriously interfere with the operation
880 * of KIO which relies on the presence of some metadata at some points in time.
881 * You should not use it if you are not familiar with KIO and not before
882 * the slave is connected to the last job before returning to idle state.
883 */
884 void sendMetaData();
885
886 /**
887 * Internal function to transmit meta data to the application.
888 * Like sendMetaData() but m_outgoingMetaData will not be cleared.
889 * This method is mainly useful in code that runs before the slave is connected
890 * to its final job.
891 */
892 void sendAndKeepMetaData();
893
894 /** If your ioslave was killed by a signal, wasKilled() returns true.
895 Check it regularly in lengthy functions (e.g. in get();) and return
896 as fast as possible from this function if wasKilled() returns true.
897 This will ensure that your slave destructor will be called correctly.
898 */
899 bool wasKilled() const;
900
901 /** Internally used.
902 * @internal
903 */
904 void setKillFlag();
905
906 /** Internally used
907 * @internal
908 */
909 void lookupHost(const QString &host);
910
911 /** Internally used
912 * @internal
913 */
914 int waitForHostInfo(QHostInfo &info);
915
916 /**
917 * Checks with job if privilege operation is allowed.
918 * @return privilege operation status.
919 * @see PrivilegeOperationStatus
920 * @since 5.66
921 */
922 PrivilegeOperationStatus requestPrivilegeOperation(const QString &operationDetails);
923
924 /**
925 * Adds @p action to the list of PolicyKit actions which the
926 * slave is authorized to perform.
927 *
928 * @param action the PolicyKit action
929 * @since 5.45
930 */
931 void addTemporaryAuthorization(const QString &action);
932
933protected:
934 /**
935 * Name of the protocol supported by this slave
936 */
937 QByteArray mProtocol;
938 // Often used by TcpSlaveBase and unlikely to change
939 MetaData mOutgoingMetaData;
940 MetaData mIncomingMetaData;
941
942 enum VirtualFunctionId {
943 AppConnectionMade = 0,
944 GetFileSystemFreeSpace = 1, // KF6 TODO: Turn into a virtual method
945 Truncate = 2, // KF6 TODO: Turn into a virtual method
946 };
947 virtual void virtual_hook(int id, void *data);
948
949private:
950 // Convenience function converting mProtocol to QString as unsupportedActionErrorString(), which
951 // is used in many places in the code, takes a QString parameter
952 inline const QString protocolName() const
953 {
954 return QString::fromLatin1(ba: mProtocol);
955 }
956
957 void setRunInThread(bool b);
958
959 // This helps catching missing tr()/i18n() calls in error().
960 void error(int _errid, const QByteArray &_text);
961 void send(int cmd, const QByteArray &arr = QByteArray());
962
963 std::unique_ptr<SlaveBasePrivate> const d;
964 friend class SlaveBasePrivate;
965 friend class WorkerThread;
966 friend class WorkerBasePrivate;
967 friend class WorkerSlaveBaseBridge;
968};
969}
970
971#endif
972
973// HACK see comments in workerbase.h for same include/declaration guard
974#ifndef KIO_UNSUPPORTEDACTIONERRORSTRING
975#define KIO_UNSUPPORTEDACTIONERRORSTRING
976
977namespace KIO
978{
979
980/**
981 * Returns an appropriate error message if the given command @p cmd
982 * is an unsupported action (ERR_UNSUPPORTED_ACTION).
983 * @param protocol name of the protocol
984 * @param cmd given command
985 * @see enum Command
986 */
987KIOCORE_EXPORT QString unsupportedActionErrorString(const QString &protocol, int cmd);
988}
989
990#endif
991

source code of kio/src/core/slavebase.h