1 /*
2     This file is part of the KDE libraries
3     Copyright (C) 1997 Torben Weis (weis@kde.org)
4     Copyright (C) 1998 Matthias Ettrich (ettrich@kde.org)
5     Copyright (C) 1999-2004 David Faure (faure@kde.org)
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16 
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22 
23 #ifndef KO_NETACCESS_h
24 #define KO_NETACCESS_h
25 
26 #include <QtCore/QObject>
27 #include <QtCore/QString>
28 #include <kio/global.h>
29 #include <kio/udsentry.h>
30 #include <kio/jobclasses.h> // for KIO::JobFlags
31 
32 class QStringList;
33 class QWidget;
34 
35 #include <kostore_export.h>
36 
37 
38 template<typename T, typename K> class QMap;
39 
40 class KJob;
41 namespace KIO
42 {
43 
44 class Job;
45 
46 class NetAccessPrivate;
47 /**
48  * Net Transparency.
49  *
50  * NetAccess allows you to do simple file operation (load, save,
51  * copy, delete...) without working with KIO::Job directly.
52  * Whereas a KIO::Job is asynchronous, meaning that the
53  * developer has to connect slots for it, KIO::NetAccess provides
54  * synchronous downloads and uploads, as well as temporary file
55  * creation and removal. The functions appear to be blocking,
56  * but the Qt event loop continues running while the operations
57  * are handled. More precisely, the GUI will still repaint, but no user
58  * interaction will be possible. If you can, please use async KIO jobs instead!
59  * See the documentation of KJob::exec() for more about the dangers of NetAccess.
60  *
61  * This class isn't meant to be used as a class but only as a simple
62  * namespace for static functions, though an instance of the class
63  * is built for internal purposes. TODO KDE5: turn into namespace,
64  * and make the qobject class private.
65  *
66  * Port to kio done by David Faure, faure@kde.org
67  *
68  * @short Provides a blocking interface to KIO file operations.
69  */
70 class KOSTORE_EXPORT NetAccess : public QObject
71 {
72     Q_OBJECT
73 
74 public:
75     enum StatSide {
76         SourceSide,
77         DestinationSide
78     };
79 
80     /**
81      * Downloads a file from an arbitrary URL (@p src) to a
82      * temporary file on the local filesystem (@p target).
83      *
84      * If the argument
85      * for @p target is an empty string, download will generate a
86      * unique temporary filename in /tmp. Since @p target is a reference
87      * to QString you can access this filename easily. Download will
88      * return true if the download was successful, otherwise false.
89      *
90      * Special case:
91      * If the URL is of kind file:, then no downloading is
92      * processed but the full filename is returned in @p target.
93      * That means you @em have to take care about the @p target argument.
94      * (This is very easy to do, please see the example below.)
95      *
96      * Download is synchronous. That means you can use it like this:
97      * (assuming your application has a loadFile() function)
98      *
99      * \code
100      * QString tmpFile;
101      * if( KIO::NetAccess::download(url, tmpFile, window)) {
102      *     loadFile(tmpFile);
103      *     KIO::NetAccess::removeTempFile(tmpFile);
104      * } else {
105      *     KMessageBox::error(this, KIO::NetAccess::lastErrorString());
106      * }
107      * \endcode
108      *
109      * Of course, your user interface will still process exposure/repaint
110      * events during the download.
111      *
112      * If the download fails, lastError() and lastErrorString() will be set.
113      *
114      * If the url is always remote, then you could also just write the more usual way:
115      * \code
116      * QTemporaryFile tmpFile;
117      * if (tmpFile.open()) {
118      *     KIO::Job* getJob = KIO::file_copy(url, QUrl::fromLocalFile(tmpFile.fileName()), -1, KIO::Overwrite | KIO::HideProgressInfo);
119      *     getJob->ui()->setWindow(window);
120      *     if (KIO::NetAccess::synchronousRun(getJob, 0)) {
121      *         loadFile(tmpFile.fileName());
122      *     } else {
123      *         getJob->ui()->showErrorMessage();
124      *     }
125      * }
126      * \endcode
127      *
128      * @param src URL Reference to the file to download.
129      * @param target String containing the final local location of the
130      *               file.  If you insert an empty string, it will
131      *               return a location in a temporary spot. <B>Note:</B>
132      *               you are responsible for the removal of this file when
133      *               you are finished reading it using removeTempFile.
134      * @param window main window associated with this job. This is used to
135      *               automatically cache and discard authentication information
136      *               as needed. If NULL, authentication information will be
137      *               cached only for a short duration after which the user will
138      *               again be prompted for passwords as needed.
139      * @return true if successful, false for failure.  Use lastErrorString() to
140      *         get the reason it failed.
141      *
142      * @see lastErrorString()
143      * @deprecated since 5.0, use KIO::storedGet + KJobWidgets::setWindow + job->exec() instead
144      */
145     static bool download(const QUrl &src, QString &target, QWidget *window);
146 
147     /**
148      * Removes the specified file if and only if it was created
149      * by KIO::NetAccess as a temporary file for a former download.
150      *
151      * Note: This means that if you created your temporary with KTempFile,
152      * use KTempFile::unlink() or KTempFile::setAutoDelete() to have
153      * it removed.
154      *
155      * @param name Path to temporary file to remove.  May not be
156      *             empty.
157      */
158     static void removeTempFile(const QString &name);
159 
160     /**
161      * Uploads file @p src to URL @p target.
162      *
163      * Both must be specified, unlike download.
164      * Note that this is assumed to be used for saving a file over
165      * the network, so overwriting is set to true. This is not the
166      * case with copy.
167      *
168      * @param src URL Referencing the file to upload.
169      * @param target URL containing the final location of the file.
170      * @param window main window associated with this job. This is used to
171      *               automatically cache and discard authentication information
172      *               as needed. If NULL, authentication information will be cached
173      *               only for a short duration after which the user will again be
174      *               prompted for passwords as needed.
175      *
176      * @return true if successful, false for failure
177      * @deprecated since 5.0, use KIO::storedPut + KJobWidgets::setWindow + job->exec() instead
178      */
179     static bool upload(const QString &src, const QUrl &target, QWidget *window);
180 
181     /**
182      * Alternative to upload for copying over the network.
183      * Overwrite is false, so this will fail if @p target exists.
184      *
185      * This one takes two URLs and is a direct equivalent of KIO::file_copy.
186      *
187      * @param src URL Referencing the file to upload.
188      * @param target URL containing the final location of the file.
189      * @param window main window associated with this job. This is used to
190      *               automatically cache and discard authentication information
191      *               as needed. If NULL, authentication information will be cached
192      *               only for a short duration after which the user will again be
193      *               prompted for passwords as needed.
194      *
195      * @return true if successful, false for failure
196      * @deprecated since 5.0, use KIO::file_copy + job->ui()->setWindow() + job->exec() instead
197      */
198     static  bool file_copy(const QUrl &src, const QUrl &target, QWidget *window = 0);
199     static  bool copy(const QUrl &src, const QUrl &target,
200             QWidget *window = 0);
201 
202     /**
203      * Alternative method for copying over the network.
204      *
205      * This one takes two URLs and is a direct equivalent
206      * of KIO::copy!.
207      * This means that it can copy files and directories alike
208      * (it should have been named copy()).
209      *
210      * This method will bring up a dialog if the destination already exists.
211      *
212      * @param src URL Referencing the file to upload.
213      * @param target URL containing the final location of the
214      *               file.
215      * @param window main window associated with this job. This is used to
216      *               automatically cache and discard authentication information
217      *               as needed. If NULL, authentication information will be cached
218      *               only for a short duration after which the user will again be
219      *               prompted for passwords as needed.
220      * @return true if successful, false for failure
221      * @deprecated since 5.0, use KIO::copy + job->ui()->setWindow() + job->exec() instead
222      */
223     static  bool dircopy(const QUrl &src, const QUrl &target, QWidget *window);
224 
225     /**
226      * Overloaded method, which takes a list of source URLs
227      * @deprecated since 5.0, use KIO::copy + job->ui()->setWindow() + job->exec() instead
228      */
229     static   bool dircopy(const QList<QUrl> &src, const QUrl &target, QWidget *window = 0L);
230 
231     /**
232      * Full-fledged equivalent of KIO::move.
233      * Moves or renames one file or directory.
234      * @deprecated since 5.0, use KIO::move + job->ui()->setWindow() + job->exec() instead
235      */
236     static  bool move(const QUrl &src, const QUrl &target, QWidget *window = 0L);
237 
238     /**
239      * Full-fledged equivalent of KIO::move.
240      * Moves or renames a list of files or directories.
241      * @deprecated since 5.0, use KIO::move + job->ui()->setWindow() + job->exec() instead
242      */
243     static  bool move(const QList<QUrl> &src, const QUrl &target, QWidget *window = 0L);
244 
245     /**
246      * Tests whether a URL exists.
247      *
248      * @param url the URL we are testing
249      * @param source if true, we want to read from that URL.
250      *               If false, we want to write to it.
251      * IMPORTANT: see documentation for KIO::stat for more details about this.
252      * @param window main window associated with this job. This is used to
253      *               automatically cache and discard authentication information
254      *               as needed. If NULL, authentication information will be
255      *               cached only for a short duration after which the user will
256      *               again be prompted for passwords as needed.
257      * @return true if the URL exists and we can do the operation specified by
258      *              @p source, false otherwise
259      *
260      * @deprecated use the StatSide enum instead of the bool source
261      */
262     static  bool exists(const QUrl &url, bool source, QWidget *window);
263 
264     /**
265      * Tests whether a URL exists.
266      *
267      * @param url the URL we are testing
268      * @param statSide determines if we want to read or write.
269      * IMPORTANT: see documentation for KIO::stat for more details about this.
270      * @param window main window associated with this job. This is used to
271      *               automatically cache and discard authentication information
272      *               as needed. If NULL, authentication information will be
273      *               cached only for a short duration after which the user will
274      *               again be prompted for passwords as needed.
275      * @return true if the URL exists and we can do the operation specified by
276      *              @p source, false otherwise
277      * @deprecated since 5.0, use QFile::exists for local files and KIO::stat for transparency
278      */
279     static bool exists(const QUrl &url, StatSide statSide, QWidget *window);
280 
281     /**
282      * Tests whether a URL exists and return information on it.
283      *
284      * This is a convenience function for KIO::stat
285      * (it saves creating a slot and testing for the job result).
286      *
287      * @param url The URL we are testing.
288      * @param entry The result of the stat. Iterate over the list
289      * of atoms to get hold of name, type, size, etc., or use KFileItem.
290      * @param window main window associated with this job. This is used to
291      *               automatically cache and discard authentication information
292      *               as needed. If NULL, authentication information will be
293      *               cached only for a short duration after which the user will
294      *               again be prompted for passwords as needed.
295      * @return true if successful, false for failure
296      * @deprecated since 5.0, use KIO::stat + KJobWidgets::setWindow + job->exec() instead
297      */
298     static bool stat(const QUrl &url, KIO::UDSEntry &entry, QWidget *window);
299 
300     /**
301      * Tries to map a local URL for the given URL.
302      *
303      * This is a convenience function for KIO::stat + parsing the
304      * resulting UDSEntry.
305      *
306      * @param url The URL we are testing.
307      * @param window main window associated with this job. This is used to
308      *               automatically cache and discard authentication information
309      *               as needed. If NULL, authentication information will be
310      *               cached only for a short duration after which the user will
311      *               again be prompted for passwords as needed.
312      * @return a local URL corresponding to the same resource than the
313      *         original URL, or the original URL if no local URL can be mapped
314      * @deprecated since 5.0, use KIO::mostLocalUrl + KJobWidgets::setWindow + job->exec() instead
315      */
316     static QUrl mostLocalUrl(const QUrl &url, QWidget *window);
317 
318     /**
319      * Deletes a file or a directory in a synchronous way.
320      *
321      * This is a convenience function for KIO::del
322      * (it saves creating a slot and testing for the job result).
323      *
324      * @param url The file or directory to delete.
325      * @param window main window associated with this job. This is used to
326      *               automatically cache and discard authentication information
327      *               as needed. If NULL, authentication information will be
328      *               cached only for a short duration after which the user will
329      *               again be prompted for passwords as needed.
330      * @return true on success, false on failure.
331      * @deprecated since 5.0, use KIO::del + job->ui()->setWindow() + job->exec() instead
332      */
333     static  bool del(const QUrl &url, QWidget *window);
334 
335     /**
336      * Creates a directory in a synchronous way.
337      *
338      * This is a convenience function for @p KIO::mkdir
339      * (it saves creating a slot and testing for the job result).
340      *
341      * @param url The directory to create.
342      * @param window main window associated with this job. This is used to
343      *               automatically cache and discard authentication information
344      *               as needed. If NULL, authentication information will be
345      *               cached only for a short duration after which the user will
346      *               again be prompted for passwords as needed.
347      * @param permissions directory permissions.
348      * @return true on success, false on failure.
349      * @deprecated since 5.0, use KIO::mkdir + job->ui()->setWindow() + job->exec() instead
350      */
351     static  bool mkdir(const QUrl &url, QWidget *window, int permissions = -1);
352 
353     /**
354      * Executes a remote process via the fish ioslave in a synchronous way.
355      *
356      * @param url The remote machine where the command should be executed.
357      *            e.g. fish://someuser\@somehost:sshport/
358      *            some special cases exist.
359      *            fish://someuser\@localhost/
360      *            will use su instead of ssh to connect and execute the command.
361      *            fish://someuser\@localhost:port/
362      *            will use ssh to connect and execute the command.
363      * @param command The command to be executed.
364      * @param window main window associated with this job. This is used to
365      *               automatically cache and discard authentication information
366      *               as needed. If NULL, authentication information will be
367      *               cached only for a short duration after which the user will
368      *               again be prompted for passwords as needed.
369      * @return The resulting output of the @p command that is executed.
370      */
371     static QString fish_execute(const QUrl &url, const QString &command, QWidget *window);
372 
373     /**
374      * This function executes a job in a synchronous way.
375      * If a job fetches some data, pass a QByteArray pointer as data parameter to this function
376      * and after the function returns it will contain all the data fetched by this job.
377      *
378      * @code
379      * KIO::Job *job = KIO::get( url );
380      * QMap<QString, QString> metaData;
381      * metaData.insert( "PropagateHttpHeader", "true" );
382      * if ( NetAccess::synchronousRun( job, 0, &data, &url, &metaData ) ) {
383      *   QString responseHeaders = metaData[ "HTTP-Headers" ];
384      *   qDebug()<<"Response header = "<< responseHeaders;
385      * }
386      * @endcode
387      *
388      * @param job job which the function will run. Note that after this function
389      *            finishes running, job is deleted and you can't access it anymore!
390      * @param window main window associated with this job. This is used to
391      *               automatically cache and discard authentication information
392      *               as needed. If NULL, authentication information will be
393      *               cached only for a short duration after which the user will
394      *               again be prompted for passwords as needed.
395      * @param data if passed and relevant to this job then it will contain the data
396      *               that was fetched by the job
397      * @param finalURL if passed will contain the final url of this job (it might differ
398      *                 from the one it was created with if there was a redirection)
399      * @param metaData you can pass a pointer to the map with meta data you wish to
400      *                 set on the job. After the job finishes this map will hold all the
401      *                 meta data from the job.
402      *
403      * @return true on success, false on failure.
404      * @deprecated since 5.0, KJobWidgets::setWindow + job->exec() instead
405      */
406     static bool synchronousRun(Job *job, QWidget *window, QByteArray *data = 0,
407                                QUrl *finalURL = 0, QMap<QString, QString> *metaData = 0);
408 
409     /**
410      * Determines the mimetype of a given URL.
411      *
412      * This is a convenience function for KIO::mimetype.  You
413      * should call this only when really necessary.
414      * QMimeDatabase::mimeTypeForUrl can determine the mimetype a lot faster, but
415      * less reliably for remote files. When mimeTypeForUrl() returns
416      * unknown (application/octet-stream) for a remote file, then this one
417      * should be used.
418      *
419      * @param url The URL whose mimetype we are interested in.
420      * @param window main window associated with this job. This is used to
421      *               automatically cache and discard authentication information
422      *               as needed. If NULL, authentication information will be
423      *               cached only for a short duration after which the user will
424      *               again be prompted for passwords as needed.
425      * @return The mimetype name.
426      * @deprecated since 5.0, use KIO::mimetype + KJobWidgets::setWindow + job->exec() instead
427      */
428     static QString mimetype(const QUrl &url, QWidget *window);
429 
430     /**
431      * Returns the error string for the last job, in case it failed.
432      * Note that this is already translated.
433      * @return the last error string, or QString()
434      */
435     static QString lastErrorString();
436 
437     /**
438      * Returns the error code for the last job, in case it failed.
439      * @return the last error code
440      */
441     static int lastError();
442 
443 Q_SIGNALS:
444     void leaveModality();
445 private:
446     /**
447      * Private constructor
448      */
449     NetAccess();
450 
451     /**
452      * Private destructor
453      */
454     ~NetAccess() override;
455 
456     /**
457      * Internal methods
458      */
459     bool filecopyInternal(const QUrl &src, const QUrl &target, int permissions,
460                           KIO::JobFlags flags, QWidget *window, bool move);
461     bool dircopyInternal(const QList<QUrl> &src, const QUrl &target,
462                          QWidget *window, bool move);
463     bool statInternal(const QUrl &url, int details, StatSide side, QWidget *window = 0);
464 
465     bool delInternal(const QUrl &url, QWidget *window = 0);
466     bool mkdirInternal(const QUrl &url, int permissions, QWidget *window = 0);
467     QString fish_executeInternal(const QUrl &url, const QString &command, QWidget *window = 0);
468     bool synchronousRunInternal(Job *job, QWidget *window, QByteArray *data,
469                                 QUrl *finalURL, QMap<QString, QString> *metaData);
470 
471     QString mimetypeInternal(const QUrl &url, QWidget *window = 0);
472     void enter_loop();
473 
474     friend class I_like_this_class;
475 
476 private Q_SLOTS:
477     void slotResult(KJob *job);
478     void slotMimetype(KIO::Job *job, const QString &type);
479     void slotData(KIO::Job *, const QByteArray &);
480     void slotRedirection(KIO::Job *, const QUrl &);
481 
482 private:
483     NetAccessPrivate *const d;
484 };
485 
486 }
487 
488 #endif
489