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 | |
21 | class KConfigGroup; |
22 | class KRemoteEncoding; |
23 | class QUrl; |
24 | |
25 | namespace KIO |
26 | { |
27 | class Connection; |
28 | class 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 | */ |
55 | class SlaveBase |
56 | { |
57 | public: |
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 | |
933 | protected: |
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 | |
949 | private: |
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 | |
977 | namespace 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 | */ |
987 | KIOCORE_EXPORT QString unsupportedActionErrorString(const QString &protocol, int cmd); |
988 | } |
989 | |
990 | #endif |
991 | |