• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KIO

  • kio
  • kio
job.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2 Copyright (C) 2000 Stephan Kulow <coolo@kde.org>
3 2000-2009 David Faure <faure@kde.org>
4 Waldo Bastian <bastian@kde.org>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/
21
22#include "job.h"
23#include "job_p.h"
24#include "clipboardupdater_p.h"
25
26#include <config.h>
27
28#include <sys/types.h>
29#include <sys/wait.h>
30#include <sys/stat.h>
31
32#include <signal.h>
33#include <stdlib.h>
34#include <stdio.h>
35#include <time.h>
36#include <unistd.h>
37extern "C" {
38#include <pwd.h>
39#include <grp.h>
40}
41#include <QtCore/QTimer>
42#include <QtCore/QFile>
43
44#include <kauthorized.h>
45#include <klocale.h>
46#include <kconfig.h>
47#include <kdebug.h>
48#include <kde_file.h>
49
50#include <errno.h>
51
52#include "jobuidelegate.h"
53#include "kmimetype.h"
54#include "slave.h"
55#include "scheduler.h"
56#include "kdirwatch.h"
57#include "kprotocolinfo.h"
58#include "kprotocolmanager.h"
59#include "filejob.h"
60
61#include <kdirnotify.h>
62#include <ktemporaryfile.h>
63
64using namespace KIO;
65
66#define MAX_READ_BUF_SIZE (64 * 1024) // 64 KB at a time seems reasonable...
67
68static inline Slave *jobSlave(SimpleJob *job)
69{
70 return SimpleJobPrivate::get(job)->m_slave;
71}
72
73//this will update the report dialog with 5 Hz, I think this is fast enough, aleXXX
74#define REPORT_TIMEOUT 200
75
76Job::Job() : KCompositeJob(*new JobPrivate, 0)
77{
78 setCapabilities( KJob::Killable | KJob::Suspendable );
79}
80
81Job::Job(JobPrivate &dd) : KCompositeJob(dd, 0)
82{
83 setCapabilities( KJob::Killable | KJob::Suspendable );
84}
85
86Job::~Job()
87{
88}
89
90JobUiDelegate *Job::ui() const
91{
92 return static_cast<JobUiDelegate*>( uiDelegate() );
93}
94
95bool Job::addSubjob(KJob *jobBase)
96{
97 //kDebug(7007) << "addSubjob(" << jobBase << ") this=" << this;
98
99 bool ok = KCompositeJob::addSubjob( jobBase );
100 KIO::Job *job = dynamic_cast<KIO::Job*>( jobBase );
101 if (ok && job) {
102 // Copy metadata into subjob (e.g. window-id, user-timestamp etc.)
103 Q_D(Job);
104 job->mergeMetaData(d->m_outgoingMetaData);
105
106 // Forward information from that subjob.
107 connect(job, SIGNAL(speed(KJob*,ulong)),
108 SLOT(slotSpeed(KJob*,ulong)));
109
110 if (ui() && job->ui()) {
111 job->ui()->setWindow( ui()->window() );
112 job->ui()->updateUserTimestamp( ui()->userTimestamp() );
113 }
114 }
115 return ok;
116}
117
118bool Job::removeSubjob( KJob *jobBase )
119{
120 //kDebug(7007) << "removeSubjob(" << jobBase << ") this=" << this << "subjobs=" << subjobs().count();
121 return KCompositeJob::removeSubjob( jobBase );
122}
123
124void JobPrivate::emitMoving(KIO::Job * job, const KUrl &src, const KUrl &dest)
125{
126 emit job->description(job, i18nc("@title job","Moving"),
127 qMakePair(i18nc("The source of a file operation", "Source"), src.pathOrUrl()),
128 qMakePair(i18nc("The destination of a file operation", "Destination"), dest.pathOrUrl()));
129}
130
131void JobPrivate::emitCopying(KIO::Job * job, const KUrl &src, const KUrl &dest)
132{
133 emit job->description(job, i18nc("@title job","Copying"),
134 qMakePair(i18nc("The source of a file operation", "Source"), src.pathOrUrl()),
135 qMakePair(i18nc("The destination of a file operation", "Destination"), dest.pathOrUrl()));
136}
137
138void JobPrivate::emitCreatingDir(KIO::Job * job, const KUrl &dir)
139{
140 emit job->description(job, i18nc("@title job","Creating directory"),
141 qMakePair(i18n("Directory"), dir.pathOrUrl()));
142}
143
144void JobPrivate::emitDeleting(KIO::Job *job, const KUrl &url)
145{
146 emit job->description(job, i18nc("@title job","Deleting"),
147 qMakePair(i18n("File"), url.pathOrUrl()));
148}
149
150void JobPrivate::emitStating(KIO::Job *job, const KUrl &url)
151{
152 emit job->description(job, i18nc("@title job","Examining"),
153 qMakePair(i18n("File"), url.pathOrUrl()));
154}
155
156void JobPrivate::emitTransferring(KIO::Job *job, const KUrl &url)
157{
158 emit job->description(job, i18nc("@title job","Transferring"),
159 qMakePair(i18nc("The source of a file operation", "Source"), url.pathOrUrl()));
160}
161
162void JobPrivate::emitMounting(KIO::Job * job, const QString &dev, const QString &point)
163{
164 emit job->description(job, i18nc("@title job","Mounting"),
165 qMakePair(i18n("Device"), dev),
166 qMakePair(i18n("Mountpoint"), point));
167}
168
169void JobPrivate::emitUnmounting(KIO::Job * job, const QString &point)
170{
171 emit job->description(job, i18nc("@title job","Unmounting"),
172 qMakePair(i18n("Mountpoint"), point));
173}
174
175bool Job::doKill()
176{
177 // kill all subjobs, without triggering their result slot
178 Q_FOREACH( KJob* it, subjobs()) {
179 it->kill( KJob::Quietly );
180 }
181 clearSubjobs();
182
183 return true;
184}
185
186bool Job::doSuspend()
187{
188 Q_FOREACH(KJob* it, subjobs()) {
189 if (!it->suspend())
190 return false;
191 }
192
193 return true;
194}
195
196bool Job::doResume()
197{
198 Q_FOREACH ( KJob* it, subjobs() )
199 {
200 if (!it->resume())
201 return false;
202 }
203
204 return true;
205}
206
207void JobPrivate::slotSpeed( KJob*, unsigned long speed )
208{
209 //kDebug(7007) << speed;
210 q_func()->emitSpeed( speed );
211}
212
213//Job::errorString is implemented in global.cpp
214
215#ifndef KDE_NO_DEPRECATED
216void Job::showErrorDialog( QWidget *parent )
217{
218 if ( ui() )
219 {
220 ui()->setWindow( parent );
221 ui()->showErrorMessage();
222 }
223 else
224 {
225 kError() << errorString();
226 }
227}
228#endif
229
230bool Job::isInteractive() const
231{
232 return uiDelegate() != 0;
233}
234
235void Job::setParentJob(Job* job)
236{
237 Q_D(Job);
238 Q_ASSERT(d->m_parentJob == 0L);
239 Q_ASSERT(job);
240 d->m_parentJob = job;
241}
242
243Job* Job::parentJob() const
244{
245 return d_func()->m_parentJob;
246}
247
248MetaData Job::metaData() const
249{
250 return d_func()->m_incomingMetaData;
251}
252
253QString Job::queryMetaData(const QString &key)
254{
255 return d_func()->m_incomingMetaData.value(key, QString());
256}
257
258void Job::setMetaData( const KIO::MetaData &_metaData)
259{
260 Q_D(Job);
261 d->m_outgoingMetaData = _metaData;
262}
263
264void Job::addMetaData( const QString &key, const QString &value)
265{
266 d_func()->m_outgoingMetaData.insert(key, value);
267}
268
269void Job::addMetaData( const QMap<QString,QString> &values)
270{
271 Q_D(Job);
272 QMap<QString,QString>::const_iterator it = values.begin();
273 for(;it != values.end(); ++it)
274 d->m_outgoingMetaData.insert(it.key(), it.value());
275}
276
277void Job::mergeMetaData( const QMap<QString,QString> &values)
278{
279 Q_D(Job);
280 QMap<QString,QString>::const_iterator it = values.begin();
281 for(;it != values.end(); ++it)
282 // there's probably a faster way
283 if ( !d->m_outgoingMetaData.contains( it.key() ) )
284 d->m_outgoingMetaData.insert( it.key(), it.value() );
285}
286
287MetaData Job::outgoingMetaData() const
288{
289 return d_func()->m_outgoingMetaData;
290}
291
292SimpleJob::SimpleJob(SimpleJobPrivate &dd)
293 : Job(dd)
294{
295 d_func()->simpleJobInit();
296}
297
298void SimpleJobPrivate::simpleJobInit()
299{
300 Q_Q(SimpleJob);
301 if (!m_url.isValid())
302 {
303 q->setError( ERR_MALFORMED_URL );
304 q->setErrorText( m_url.url() );
305 QTimer::singleShot(0, q, SLOT(slotFinished()) );
306 return;
307 }
308
309 Scheduler::doJob(q);
310}
311
312
313bool SimpleJob::doKill()
314{
315 Q_D(SimpleJob);
316 if ((d->m_extraFlags & JobPrivate::EF_KillCalled) == 0) {
317 d->m_extraFlags |= JobPrivate::EF_KillCalled;
318 Scheduler::cancelJob(this); // deletes the slave if not 0
319 } else {
320 kWarning(7007) << this << "This is overkill.";
321 }
322 return Job::doKill();
323}
324
325bool SimpleJob::doSuspend()
326{
327 Q_D(SimpleJob);
328 if ( d->m_slave )
329 d->m_slave->suspend();
330 return Job::doSuspend();
331}
332
333bool SimpleJob::doResume()
334{
335 Q_D(SimpleJob);
336 if ( d->m_slave )
337 d->m_slave->resume();
338 return Job::doResume();
339}
340
341const KUrl& SimpleJob::url() const
342{
343 return d_func()->m_url;
344}
345
346void SimpleJob::putOnHold()
347{
348 Q_D(SimpleJob);
349 Q_ASSERT( d->m_slave );
350 if ( d->m_slave )
351 {
352 Scheduler::putSlaveOnHold(this, d->m_url);
353 }
354 // we should now be disassociated from the slave
355 Q_ASSERT(!d->m_slave);
356 kill( Quietly );
357}
358
359void SimpleJob::removeOnHold()
360{
361 Scheduler::removeSlaveOnHold();
362}
363
364bool SimpleJob::isRedirectionHandlingEnabled() const
365{
366 return d_func()->m_redirectionHandlingEnabled;
367}
368
369void SimpleJob::setRedirectionHandlingEnabled(bool handle)
370{
371 Q_D(SimpleJob);
372 d->m_redirectionHandlingEnabled = handle;
373}
374
375SimpleJob::~SimpleJob()
376{
377 Q_D(SimpleJob);
378 // last chance to remove this job from the scheduler!
379 if (d->m_schedSerial) {
380 kDebug(7007) << "Killing job" << this << "in destructor!" << kBacktrace();
381 Scheduler::cancelJob(this);
382 }
383}
384
385void SimpleJobPrivate::start(Slave *slave)
386{
387 Q_Q(SimpleJob);
388 m_slave = slave;
389
390 // Slave::setJob can send us SSL metadata if there is a persistent connection
391 q->connect( slave, SIGNAL(metaData(KIO::MetaData)),
392 SLOT(slotMetaData(KIO::MetaData)) );
393
394 slave->setJob(q);
395
396 q->connect( slave, SIGNAL(error(int,QString)),
397 SLOT(slotError(int,QString)) );
398
399 q->connect( slave, SIGNAL(warning(QString)),
400 SLOT(slotWarning(QString)) );
401
402 q->connect( slave, SIGNAL(infoMessage(QString)),
403 SLOT(_k_slotSlaveInfoMessage(QString)) );
404
405 q->connect( slave, SIGNAL(connected()),
406 SLOT(slotConnected()));
407
408 q->connect( slave, SIGNAL(finished()),
409 SLOT(slotFinished()) );
410
411 if ((m_extraFlags & EF_TransferJobDataSent) == 0) // this is a "get" job
412 {
413 q->connect( slave, SIGNAL(totalSize(KIO::filesize_t)),
414 SLOT(slotTotalSize(KIO::filesize_t)) );
415
416 q->connect( slave, SIGNAL(processedSize(KIO::filesize_t)),
417 SLOT(slotProcessedSize(KIO::filesize_t)) );
418
419 q->connect( slave, SIGNAL(speed(ulong)),
420 SLOT(slotSpeed(ulong)) );
421 }
422
423 if (ui() && ui()->window())
424 {
425 m_outgoingMetaData.insert("window-id", QString::number((qptrdiff)ui()->window()->winId()));
426 }
427
428 if (ui() && ui()->userTimestamp())
429 {
430 m_outgoingMetaData.insert("user-timestamp", QString::number(ui()->userTimestamp()));
431 }
432
433 if (ui() == 0) // not interactive
434 {
435 m_outgoingMetaData.insert("no-auth-prompt", "true");
436 }
437
438 if (!m_outgoingMetaData.isEmpty())
439 {
440 KIO_ARGS << m_outgoingMetaData;
441 slave->send( CMD_META_DATA, packedArgs );
442 }
443
444 if (!m_subUrl.isEmpty())
445 {
446 KIO_ARGS << m_subUrl;
447 slave->send( CMD_SUBURL, packedArgs );
448 }
449
450 slave->send( m_command, m_packedArgs );
451}
452
453void SimpleJobPrivate::slaveDone()
454{
455 Q_Q(SimpleJob);
456 if (m_slave) {
457 if (m_command == CMD_OPEN) {
458 m_slave->send(CMD_CLOSE);
459 }
460 q->disconnect(m_slave); // Remove all signals between slave and job
461 }
462 // only finish a job once; Scheduler::jobFinished() resets schedSerial to zero.
463 if (m_schedSerial) {
464 Scheduler::jobFinished(q, m_slave);
465 }
466}
467
468void SimpleJob::slotFinished( )
469{
470 Q_D(SimpleJob);
471 // Return slave to the scheduler
472 d->slaveDone();
473
474 if (!hasSubjobs())
475 {
476 if ( !error() && (d->m_command == CMD_MKDIR || d->m_command == CMD_RENAME ) )
477 {
478 if ( d->m_command == CMD_MKDIR )
479 {
480 KUrl urlDir( url() );
481 urlDir.setPath( urlDir.directory() );
482 org::kde::KDirNotify::emitFilesAdded( urlDir.url() );
483 }
484 else /*if ( m_command == CMD_RENAME )*/
485 {
486 KUrl src, dst;
487 QDataStream str( d->m_packedArgs );
488 str >> src >> dst;
489 if( src.directory() == dst.directory() ) // For the user, moving isn't renaming. Only renaming is.
490 org::kde::KDirNotify::emitFileRenamed( src.url(), dst.url() );
491
492 org::kde::KDirNotify::emitFileMoved( src.url(), dst.url() );
493 ClipboardUpdater::update(src, dst);
494 }
495 }
496 emitResult();
497 }
498}
499
500void SimpleJob::slotError( int err, const QString & errorText )
501{
502 Q_D(SimpleJob);
503 setError( err );
504 setErrorText( errorText );
505 if ((error() == ERR_UNKNOWN_HOST) && d->m_url.host().isEmpty())
506 setErrorText( QString() );
507 // error terminates the job
508 slotFinished();
509}
510
511void SimpleJob::slotWarning( const QString & errorText )
512{
513 emit warning( this, errorText );
514}
515
516void SimpleJobPrivate::_k_slotSlaveInfoMessage( const QString & msg )
517{
518 emit q_func()->infoMessage( q_func(), msg );
519}
520
521void SimpleJobPrivate::slotConnected()
522{
523 emit q_func()->connected( q_func() );
524}
525
526void SimpleJobPrivate::slotTotalSize( KIO::filesize_t size )
527{
528 Q_Q(SimpleJob);
529 if (size != q->totalAmount(KJob::Bytes))
530 {
531 q->setTotalAmount(KJob::Bytes, size);
532 }
533}
534
535void SimpleJobPrivate::slotProcessedSize( KIO::filesize_t size )
536{
537 Q_Q(SimpleJob);
538 //kDebug(7007) << KIO::number(size);
539 q->setProcessedAmount(KJob::Bytes, size);
540}
541
542void SimpleJobPrivate::slotSpeed( unsigned long speed )
543{
544 //kDebug(7007) << speed;
545 q_func()->emitSpeed( speed );
546}
547
548void SimpleJobPrivate::restartAfterRedirection(KUrl *redirectionUrl)
549{
550 Q_Q(SimpleJob);
551 // Return slave to the scheduler while we still have the old URL in place; the scheduler
552 // requires a job URL to stay invariant while the job is running.
553 slaveDone();
554
555 m_url = *redirectionUrl;
556 redirectionUrl->clear();
557 if ((m_extraFlags & EF_KillCalled) == 0) {
558 Scheduler::doJob(q);
559 }
560}
561
562int SimpleJobPrivate::requestMessageBox(int _type, const QString& text, const QString& caption,
563 const QString& buttonYes, const QString& buttonNo,
564 const QString& iconYes, const QString& iconNo,
565 const QString& dontAskAgainName,
566 const KIO::MetaData& sslMetaData)
567{
568 JobUiDelegate* delegate = ui();
569 if (delegate) {
570 const JobUiDelegate::MessageBoxType type = static_cast<JobUiDelegate::MessageBoxType>(_type);
571 return delegate->requestMessageBox(type, text, caption, buttonYes, buttonNo,
572 iconYes, iconNo, dontAskAgainName, sslMetaData);
573 }
574 kWarning(7007) << "JobUiDelegate not set! Returing -1";
575 return -1;
576}
577
578void SimpleJob::slotMetaData( const KIO::MetaData &_metaData )
579{
580 Q_D(SimpleJob);
581 QMapIterator<QString,QString> it (_metaData);
582 while (it.hasNext()) {
583 it.next();
584 if (it.key().startsWith(QLatin1String("{internal~"), Qt::CaseInsensitive))
585 d->m_internalMetaData.insert(it.key(), it.value());
586 else
587 d->m_incomingMetaData.insert(it.key(), it.value());
588 }
589
590 // Update the internal meta-data values as soon as possible. Waiting until
591 // the ioslave is finished has unintended consequences if the client starts
592 // a new connection without waiting for the ioslave to finish.
593 if (!d->m_internalMetaData.isEmpty()) {
594 Scheduler::updateInternalMetaData(this);
595 }
596}
597
598void SimpleJob::storeSSLSessionFromJob(const KUrl &redirectionURL)
599{
600 Q_UNUSED(redirectionURL);
601}
602
603
605class KIO::MkdirJobPrivate: public SimpleJobPrivate
606{
607public:
608 MkdirJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
609 : SimpleJobPrivate(url, command, packedArgs)
610 { }
611 KUrl m_redirectionURL;
612 void slotRedirection(const KUrl &url);
613
620 virtual void start( Slave *slave );
621
622 Q_DECLARE_PUBLIC(MkdirJob)
623
624 static inline MkdirJob *newJob(const KUrl& url, int command, const QByteArray &packedArgs)
625 {
626 MkdirJob *job = new MkdirJob(*new MkdirJobPrivate(url, command, packedArgs));
627 job->setUiDelegate(new JobUiDelegate);
628 return job;
629 }
630};
631
632MkdirJob::MkdirJob(MkdirJobPrivate &dd)
633 : SimpleJob(dd)
634{
635}
636
637MkdirJob::~MkdirJob()
638{
639}
640
641void MkdirJobPrivate::start(Slave *slave)
642{
643 Q_Q(MkdirJob);
644 q->connect( slave, SIGNAL(redirection(KUrl)),
645 SLOT(slotRedirection(KUrl)) );
646
647 SimpleJobPrivate::start(slave);
648}
649
650// Slave got a redirection request
651void MkdirJobPrivate::slotRedirection( const KUrl &url)
652{
653 Q_Q(MkdirJob);
654 kDebug(7007) << url;
655 if (!KAuthorized::authorizeUrlAction("redirect", m_url, url))
656 {
657 kWarning(7007) << "Redirection from" << m_url << "to" << url << "REJECTED!";
658 q->setError( ERR_ACCESS_DENIED );
659 q->setErrorText( url.pathOrUrl() );
660 return;
661 }
662 m_redirectionURL = url; // We'll remember that when the job finishes
663 // Tell the user that we haven't finished yet
664 emit q->redirection(q, m_redirectionURL);
665}
666
667void MkdirJob::slotFinished()
668{
669 Q_D(MkdirJob);
670
671 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() )
672 {
673 //kDebug(7007) << "MkdirJob: Redirection to " << m_redirectionURL;
674 if (queryMetaData("permanent-redirect")=="true")
675 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
676
677 if ( d->m_redirectionHandlingEnabled )
678 {
679 KUrl dummyUrl;
680 int permissions;
681 QDataStream istream( d->m_packedArgs );
682 istream >> dummyUrl >> permissions;
683
684 d->m_packedArgs.truncate(0);
685 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
686 stream << d->m_redirectionURL << permissions;
687
688 d->restartAfterRedirection(&d->m_redirectionURL);
689 return;
690 }
691 }
692
693 // Return slave to the scheduler
694 SimpleJob::slotFinished();
695}
696
697SimpleJob *KIO::mkdir( const KUrl& url, int permissions )
698{
699 //kDebug(7007) << "mkdir " << url;
700 KIO_ARGS << url << permissions;
701 return MkdirJobPrivate::newJob(url, CMD_MKDIR, packedArgs);
702}
703
704SimpleJob *KIO::rmdir( const KUrl& url )
705{
706 //kDebug(7007) << "rmdir " << url;
707 KIO_ARGS << url << qint8(false); // isFile is false
708 return SimpleJobPrivate::newJob(url, CMD_DEL, packedArgs);
709}
710
711SimpleJob *KIO::chmod( const KUrl& url, int permissions )
712{
713 //kDebug(7007) << "chmod " << url;
714 KIO_ARGS << url << permissions;
715 return SimpleJobPrivate::newJob(url, CMD_CHMOD, packedArgs);
716}
717
718SimpleJob *KIO::chown( const KUrl& url, const QString& owner, const QString& group )
719{
720 KIO_ARGS << url << owner << group;
721 return SimpleJobPrivate::newJob(url, CMD_CHOWN, packedArgs);
722}
723
724SimpleJob *KIO::setModificationTime( const KUrl& url, const QDateTime& mtime )
725{
726 //kDebug(7007) << "setModificationTime " << url << " " << mtime;
727 KIO_ARGS << url << mtime;
728 return SimpleJobPrivate::newJobNoUi(url, CMD_SETMODIFICATIONTIME, packedArgs);
729}
730
731SimpleJob *KIO::rename( const KUrl& src, const KUrl & dest, JobFlags flags )
732{
733 //kDebug(7007) << "rename " << src << " " << dest;
734 KIO_ARGS << src << dest << (qint8) (flags & Overwrite);
735 return SimpleJobPrivate::newJob(src, CMD_RENAME, packedArgs);
736}
737
738SimpleJob *KIO::symlink( const QString& target, const KUrl & dest, JobFlags flags )
739{
740 //kDebug(7007) << "symlink target=" << target << " " << dest;
741 KIO_ARGS << target << dest << (qint8) (flags & Overwrite);
742 return SimpleJobPrivate::newJob(dest, CMD_SYMLINK, packedArgs, flags);
743}
744
745SimpleJob *KIO::special(const KUrl& url, const QByteArray & data, JobFlags flags)
746{
747 //kDebug(7007) << "special " << url;
748 return SimpleJobPrivate::newJob(url, CMD_SPECIAL, data, flags);
749}
750
751SimpleJob *KIO::mount( bool ro, const QByteArray& fstype, const QString& dev, const QString& point, JobFlags flags )
752{
753 KIO_ARGS << int(1) << qint8( ro ? 1 : 0 )
754 << QString::fromLatin1(fstype) << dev << point;
755 SimpleJob *job = special( KUrl("file:/"), packedArgs, flags );
756 if (!(flags & HideProgressInfo)) {
757 KIO::JobPrivate::emitMounting(job, dev, point);
758 }
759 return job;
760}
761
762SimpleJob *KIO::unmount( const QString& point, JobFlags flags )
763{
764 KIO_ARGS << int(2) << point;
765 SimpleJob *job = special( KUrl("file:/"), packedArgs, flags );
766 if (!(flags & HideProgressInfo)) {
767 KIO::JobPrivate::emitUnmounting(job, point);
768 }
769 return job;
770}
771
772
773
775
776class KIO::StatJobPrivate: public SimpleJobPrivate
777{
778public:
779 inline StatJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
780 : SimpleJobPrivate(url, command, packedArgs), m_bSource(true), m_details(2)
781 {}
782
783 UDSEntry m_statResult;
784 KUrl m_redirectionURL;
785 bool m_bSource;
786 short int m_details;
787 void slotStatEntry( const KIO::UDSEntry & entry );
788 void slotRedirection( const KUrl &url);
789
796 virtual void start( Slave *slave );
797
798 Q_DECLARE_PUBLIC(StatJob)
799
800 static inline StatJob *newJob(const KUrl& url, int command, const QByteArray &packedArgs,
801 JobFlags flags )
802 {
803 StatJob *job = new StatJob(*new StatJobPrivate(url, command, packedArgs));
804 job->setUiDelegate(new JobUiDelegate);
805 if (!(flags & HideProgressInfo)) {
806 KIO::getJobTracker()->registerJob(job);
807 emitStating(job, url);
808 }
809 return job;
810 }
811};
812
813StatJob::StatJob(StatJobPrivate &dd)
814 : SimpleJob(dd)
815{
816}
817
818StatJob::~StatJob()
819{
820}
821
822#ifndef KDE_NO_DEPRECATED
823void StatJob::setSide( bool source )
824{
825 d_func()->m_bSource = source;
826}
827#endif
828
829void StatJob::setSide( StatSide side )
830{
831 d_func()->m_bSource = side == SourceSide;
832}
833
834void StatJob::setDetails( short int details )
835{
836 d_func()->m_details = details;
837}
838
839const UDSEntry & StatJob::statResult() const
840{
841 return d_func()->m_statResult;
842}
843
844KUrl StatJob::mostLocalUrl() const
845{
846 if (!url().isLocalFile()) {
847 const UDSEntry& udsEntry = d_func()->m_statResult;
848 const QString path = udsEntry.stringValue( KIO::UDSEntry::UDS_LOCAL_PATH );
849 if (!path.isEmpty())
850 return KUrl(path);
851 }
852 return url();
853}
854
855void StatJobPrivate::start(Slave *slave)
856{
857 Q_Q(StatJob);
858 m_outgoingMetaData.insert( "statSide", m_bSource ? "source" : "dest" );
859 m_outgoingMetaData.insert( "details", QString::number(m_details) );
860
861 q->connect( slave, SIGNAL(statEntry(KIO::UDSEntry)),
862 SLOT(slotStatEntry(KIO::UDSEntry)) );
863 q->connect( slave, SIGNAL(redirection(KUrl)),
864 SLOT(slotRedirection(KUrl)) );
865
866 SimpleJobPrivate::start(slave);
867}
868
869void StatJobPrivate::slotStatEntry( const KIO::UDSEntry & entry )
870{
871 //kDebug(7007);
872 m_statResult = entry;
873}
874
875// Slave got a redirection request
876void StatJobPrivate::slotRedirection( const KUrl &url)
877{
878 Q_Q(StatJob);
879 kDebug(7007) << m_url << "->" << url;
880 if (!KAuthorized::authorizeUrlAction("redirect", m_url, url))
881 {
882 kWarning(7007) << "Redirection from " << m_url << " to " << url << " REJECTED!";
883 q->setError( ERR_ACCESS_DENIED );
884 q->setErrorText( url.pathOrUrl() );
885 return;
886 }
887 m_redirectionURL = url; // We'll remember that when the job finishes
888 // Tell the user that we haven't finished yet
889 emit q->redirection(q, m_redirectionURL);
890}
891
892void StatJob::slotFinished()
893{
894 Q_D(StatJob);
895
896 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() )
897 {
898 //kDebug(7007) << "StatJob: Redirection to " << m_redirectionURL;
899 if (queryMetaData("permanent-redirect")=="true")
900 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
901
902 if ( d->m_redirectionHandlingEnabled )
903 {
904 d->m_packedArgs.truncate(0);
905 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
906 stream << d->m_redirectionURL;
907
908 d->restartAfterRedirection(&d->m_redirectionURL);
909 return;
910 }
911 }
912
913 // Return slave to the scheduler
914 SimpleJob::slotFinished();
915}
916
917void StatJob::slotMetaData( const KIO::MetaData &_metaData)
918{
919 Q_D(StatJob);
920 SimpleJob::slotMetaData(_metaData);
921 storeSSLSessionFromJob(d->m_redirectionURL);
922}
923
924StatJob *KIO::stat(const KUrl& url, JobFlags flags)
925{
926 // Assume sideIsSource. Gets are more common than puts.
927 return stat( url, StatJob::SourceSide, 2, flags );
928}
929
930StatJob *KIO::mostLocalUrl(const KUrl& url, JobFlags flags)
931{
932 StatJob* job = stat( url, StatJob::SourceSide, 2, flags );
933 if (url.isLocalFile()) {
934 QTimer::singleShot(0, job, SLOT(slotFinished()));
935 Scheduler::cancelJob(job); // deletes the slave if not 0
936 }
937 return job;
938}
939
940#ifndef KDE_NO_DEPRECATED
941StatJob *KIO::stat(const KUrl& url, bool sideIsSource, short int details, JobFlags flags )
942{
943 //kDebug(7007) << "stat" << url;
944 KIO_ARGS << url;
945 StatJob * job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
946 job->setSide( sideIsSource ? StatJob::SourceSide : StatJob::DestinationSide );
947 job->setDetails( details );
948 return job;
949}
950#endif
951
952StatJob *KIO::stat(const KUrl& url, KIO::StatJob::StatSide side, short int details, JobFlags flags )
953{
954 //kDebug(7007) << "stat" << url;
955 KIO_ARGS << url;
956 StatJob * job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
957 job->setSide( side );
958 job->setDetails( details );
959 return job;
960}
961
962SimpleJob *KIO::http_update_cache( const KUrl& url, bool no_cache, time_t expireDate)
963{
964 Q_ASSERT(url.protocol() == "http" || url.protocol() == "https");
965 // Send http update_cache command (2)
966 KIO_ARGS << (int)2 << url << no_cache << qlonglong(expireDate);
967 SimpleJob * job = SimpleJobPrivate::newJob(url, CMD_SPECIAL, packedArgs);
968 Scheduler::setJobPriority(job, 1);
969 return job;
970}
971
973
974TransferJob::TransferJob(TransferJobPrivate &dd)
975 : SimpleJob(dd)
976{
977 Q_D(TransferJob);
978 if (d->m_command == CMD_PUT) {
979 d->m_extraFlags |= JobPrivate::EF_TransferJobDataSent;
980 }
981}
982
983TransferJob::~TransferJob()
984{
985}
986
987// Slave sends data
988void TransferJob::slotData( const QByteArray &_data)
989{
990 Q_D(TransferJob);
991 if (d->m_command == CMD_GET && !d->m_isMimetypeEmitted) {
992 kWarning(7007) << "mimeType() not emitted when sending first data!; job URL ="
993 << d->m_url << "data size =" << _data.size();
994 }
995 // shut up the warning, HACK: downside is that it changes the meaning of the variable
996 d->m_isMimetypeEmitted = true;
997
998 if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error()) {
999 emit data(this, _data);
1000 }
1001}
1002
1003void KIO::TransferJob::setTotalSize(KIO::filesize_t bytes)
1004{
1005 setTotalAmount(KJob::Bytes, bytes);
1006}
1007
1008// Slave got a redirection request
1009void TransferJob::slotRedirection( const KUrl &url)
1010{
1011 Q_D(TransferJob);
1012 kDebug(7007) << url;
1013 if (!KAuthorized::authorizeUrlAction("redirect", d->m_url, url))
1014 {
1015 kWarning(7007) << "Redirection from " << d->m_url << " to " << url << " REJECTED!";
1016 return;
1017 }
1018
1019 // Some websites keep redirecting to themselves where each redirection
1020 // acts as the stage in a state-machine. We define "endless redirections"
1021 // as 5 redirections to the same URL.
1022 if (d->m_redirectionList.count(url) > 5)
1023 {
1024 kDebug(7007) << "CYCLIC REDIRECTION!";
1025 setError( ERR_CYCLIC_LINK );
1026 setErrorText( d->m_url.pathOrUrl() );
1027 }
1028 else
1029 {
1030 d->m_redirectionURL = url; // We'll remember that when the job finishes
1031 d->m_redirectionList.append(url);
1032 QString sslInUse = queryMetaData(QLatin1String("ssl_in_use"));
1033 if (!sslInUse.isNull()) { // the key is present
1034 addMetaData(QLatin1String("ssl_was_in_use"), sslInUse);
1035 } else {
1036 addMetaData(QLatin1String("ssl_was_in_use"), QLatin1String("FALSE"));
1037 }
1038 // Tell the user that we haven't finished yet
1039 emit redirection(this, d->m_redirectionURL);
1040 }
1041}
1042
1043void TransferJob::slotFinished()
1044{
1045 Q_D(TransferJob);
1046
1047 kDebug(7007) << d->m_url;
1048 if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid()) {
1049
1050 //kDebug(7007) << "Redirection to" << m_redirectionURL;
1051 if (queryMetaData("permanent-redirect")=="true")
1052 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
1053
1054 if (d->m_redirectionHandlingEnabled) {
1055 // Honour the redirection
1056 // We take the approach of "redirecting this same job"
1057 // Another solution would be to create a subjob, but the same problem
1058 // happens (unpacking+repacking)
1059 const QString redirectToGet = queryMetaData(QLatin1String("redirect-to-get"));
1060 if (redirectToGet == QLatin1String("true")) {
1061 d->m_command = CMD_GET;
1062 d->m_outgoingMetaData.remove(QLatin1String("CustomHTTPMethod"));
1063 d->m_outgoingMetaData.remove(QLatin1String("content-type"));
1064 }
1065 d->staticData.truncate(0);
1066 d->m_incomingMetaData.clear();
1067 if (queryMetaData("cache") != "reload")
1068 addMetaData("cache","refresh");
1069 d->m_internalSuspended = false;
1070 // The very tricky part is the packed arguments business
1071 switch( d->m_command ) {
1072 case CMD_GET:
1073 case CMD_STAT:
1074 case CMD_DEL: {
1075 d->m_packedArgs.truncate(0);
1076 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1077 stream << d->m_redirectionURL;
1078 break;
1079 }
1080 case CMD_PUT: {
1081 int permissions;
1082 qint8 iOverwrite, iResume;
1083 KUrl dummyUrl;
1084 QDataStream istream( d->m_packedArgs );
1085 istream >> dummyUrl >> iOverwrite >> iResume >> permissions;
1086 d->m_packedArgs.truncate(0);
1087 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1088 stream << d->m_redirectionURL << iOverwrite << iResume << permissions;
1089 break;
1090 }
1091 case CMD_SPECIAL: {
1092 int specialcmd;
1093 QDataStream istream( d->m_packedArgs );
1094 istream >> specialcmd;
1095 if (specialcmd == 1) { // HTTP POST
1096 d->m_packedArgs.truncate(0);
1097 QDataStream stream(&d->m_packedArgs, QIODevice::WriteOnly);
1098 Q_ASSERT(d->m_outgoingDataSource);
1099 d->m_outgoingDataSource->reset();
1100 stream << specialcmd << d->m_redirectionURL << d->m_outgoingDataSource->size();
1101 }
1102 break;
1103 }
1104 }
1105 d->restartAfterRedirection(&d->m_redirectionURL);
1106 return;
1107 }
1108 }
1109
1110 SimpleJob::slotFinished();
1111}
1112
1113void TransferJob::setAsyncDataEnabled(bool enabled)
1114{
1115 Q_D(TransferJob);
1116 if (enabled)
1117 d->m_extraFlags |= JobPrivate::EF_TransferJobAsync;
1118 else
1119 d->m_extraFlags &= ~JobPrivate::EF_TransferJobAsync;
1120}
1121
1122void TransferJob::sendAsyncData(const QByteArray &dataForSlave)
1123{
1124 Q_D(TransferJob);
1125 if (d->m_extraFlags & JobPrivate::EF_TransferJobNeedData)
1126 {
1127 d->m_slave->send( MSG_DATA, dataForSlave );
1128 if (d->m_extraFlags & JobPrivate::EF_TransferJobDataSent) // put job -> emit progress
1129 {
1130 KIO::filesize_t size = processedAmount(KJob::Bytes)+dataForSlave.size();
1131 setProcessedAmount(KJob::Bytes, size);
1132 }
1133 }
1134
1135 d->m_extraFlags &= ~JobPrivate::EF_TransferJobNeedData;
1136}
1137
1138#ifndef KDE_NO_DEPRECATED
1139void TransferJob::setReportDataSent(bool enabled)
1140{
1141 Q_D(TransferJob);
1142 if (enabled)
1143 d->m_extraFlags |= JobPrivate::EF_TransferJobDataSent;
1144 else
1145 d->m_extraFlags &= ~JobPrivate::EF_TransferJobDataSent;
1146}
1147#endif
1148
1149#ifndef KDE_NO_DEPRECATED
1150bool TransferJob::reportDataSent() const
1151{
1152 return (d_func()->m_extraFlags & JobPrivate::EF_TransferJobDataSent);
1153}
1154#endif
1155
1156QString TransferJob::mimetype() const
1157{
1158 return d_func()->m_mimetype;
1159}
1160
1161// Slave requests data
1162void TransferJob::slotDataReq()
1163{
1164 Q_D(TransferJob);
1165 QByteArray dataForSlave;
1166
1167 d->m_extraFlags |= JobPrivate::EF_TransferJobNeedData;
1168
1169 if (!d->staticData.isEmpty())
1170 {
1171 dataForSlave = d->staticData;
1172 d->staticData.clear();
1173 }
1174 else
1175 {
1176 emit dataReq( this, dataForSlave);
1177
1178 if (d->m_extraFlags & JobPrivate::EF_TransferJobAsync)
1179 return;
1180 }
1181
1182 static const int max_size = 14 * 1024 * 1024;
1183 if (dataForSlave.size() > max_size)
1184 {
1185 kDebug(7007) << "send " << dataForSlave.size() / 1024 / 1024 << "MB of data in TransferJob::dataReq. This needs to be splitted, which requires a copy. Fix the application.\n";
1186 d->staticData = QByteArray(dataForSlave.data() + max_size , dataForSlave.size() - max_size);
1187 dataForSlave.truncate(max_size);
1188 }
1189
1190 sendAsyncData(dataForSlave);
1191
1192 if (d->m_subJob)
1193 {
1194 // Bitburger protocol in action
1195 d->internalSuspend(); // Wait for more data from subJob.
1196 d->m_subJob->d_func()->internalResume(); // Ask for more!
1197 }
1198}
1199
1200void TransferJob::slotMimetype( const QString& type )
1201{
1202 Q_D(TransferJob);
1203 d->m_mimetype = type;
1204 if (d->m_command == CMD_GET && d->m_isMimetypeEmitted) {
1205 kWarning(7007) << "mimetype() emitted again, or after sending first data!; job URL ="
1206 << d->m_url;
1207 }
1208 d->m_isMimetypeEmitted = true;
1209 emit mimetype( this, type );
1210}
1211
1212
1213void TransferJobPrivate::internalSuspend()
1214{
1215 m_internalSuspended = true;
1216 if (m_slave)
1217 m_slave->suspend();
1218}
1219
1220void TransferJobPrivate::internalResume()
1221{
1222 m_internalSuspended = false;
1223 if ( m_slave && !suspended )
1224 m_slave->resume();
1225}
1226
1227bool TransferJob::doResume()
1228{
1229 Q_D(TransferJob);
1230 if ( !SimpleJob::doResume() )
1231 return false;
1232 if ( d->m_internalSuspended )
1233 d->internalSuspend();
1234 return true;
1235}
1236
1237bool TransferJob::isErrorPage() const
1238{
1239 return d_func()->m_errorPage;
1240}
1241
1242void TransferJobPrivate::start(Slave *slave)
1243{
1244 Q_Q(TransferJob);
1245 Q_ASSERT(slave);
1246 JobPrivate::emitTransferring(q, m_url);
1247 q->connect( slave, SIGNAL(data(QByteArray)),
1248 SLOT(slotData(QByteArray)) );
1249
1250 if (m_outgoingDataSource)
1251 q->connect( slave, SIGNAL(dataReq()),
1252 SLOT(slotDataReqFromDevice()) );
1253 else
1254 q->connect( slave, SIGNAL(dataReq()),
1255 SLOT(slotDataReq()) );
1256
1257 q->connect( slave, SIGNAL(redirection(KUrl)),
1258 SLOT(slotRedirection(KUrl)) );
1259
1260 q->connect( slave, SIGNAL(mimeType(QString)),
1261 SLOT(slotMimetype(QString)) );
1262
1263 q->connect( slave, SIGNAL(errorPage()),
1264 SLOT(slotErrorPage()) );
1265
1266 q->connect( slave, SIGNAL(needSubUrlData()),
1267 SLOT(slotNeedSubUrlData()) );
1268
1269 q->connect( slave, SIGNAL(canResume(KIO::filesize_t)),
1270 SLOT(slotCanResume(KIO::filesize_t)) );
1271
1272 if (slave->suspended())
1273 {
1274 m_mimetype = "unknown";
1275 // WABA: The slave was put on hold. Resume operation.
1276 slave->resume();
1277 }
1278
1279 SimpleJobPrivate::start(slave);
1280 if (m_internalSuspended)
1281 slave->suspend();
1282}
1283
1284void TransferJobPrivate::slotNeedSubUrlData()
1285{
1286 Q_Q(TransferJob);
1287 // Job needs data from subURL.
1288 m_subJob = KIO::get( m_subUrl, NoReload, HideProgressInfo);
1289 internalSuspend(); // Put job on hold until we have some data.
1290 q->connect(m_subJob, SIGNAL(data(KIO::Job*,QByteArray)),
1291 SLOT(slotSubUrlData(KIO::Job*,QByteArray)));
1292 q->addSubjob(m_subJob);
1293}
1294
1295void TransferJobPrivate::slotSubUrlData(KIO::Job*, const QByteArray &data)
1296{
1297 // The Alternating Bitburg protocol in action again.
1298 staticData = data;
1299 m_subJob->d_func()->internalSuspend(); // Put job on hold until we have delivered the data.
1300 internalResume(); // Activate ourselves again.
1301}
1302
1303void TransferJob::slotMetaData( const KIO::MetaData &_metaData)
1304{
1305 Q_D(TransferJob);
1306 SimpleJob::slotMetaData(_metaData);
1307 storeSSLSessionFromJob(d->m_redirectionURL);
1308}
1309
1310void TransferJobPrivate::slotErrorPage()
1311{
1312 m_errorPage = true;
1313}
1314
1315void TransferJobPrivate::slotCanResume( KIO::filesize_t offset )
1316{
1317 Q_Q(TransferJob);
1318 emit q->canResume(q, offset);
1319}
1320
1321void TransferJobPrivate::slotDataReqFromDevice()
1322{
1323 Q_Q(TransferJob);
1324
1325 QByteArray dataForSlave;
1326
1327 m_extraFlags |= JobPrivate::EF_TransferJobNeedData;
1328
1329 if (m_outgoingDataSource)
1330 dataForSlave = m_outgoingDataSource->read(MAX_READ_BUF_SIZE);
1331
1332 if (dataForSlave.isEmpty())
1333 {
1334 emit q->dataReq(q, dataForSlave);
1335 if (m_extraFlags & JobPrivate::EF_TransferJobAsync)
1336 return;
1337 }
1338
1339 q->sendAsyncData(dataForSlave);
1340
1341 if (m_subJob)
1342 {
1343 // Bitburger protocol in action
1344 internalSuspend(); // Wait for more data from subJob.
1345 m_subJob->d_func()->internalResume(); // Ask for more!
1346 }
1347}
1348
1349void TransferJob::slotResult( KJob *job)
1350{
1351 Q_D(TransferJob);
1352 // This can only be our suburl.
1353 Q_ASSERT(job == d->m_subJob);
1354
1355 SimpleJob::slotResult( job );
1356
1357 if (!error() && job == d->m_subJob)
1358 {
1359 d->m_subJob = 0; // No action required
1360 d->internalResume(); // Make sure we get the remaining data.
1361 }
1362}
1363
1364void TransferJob::setModificationTime( const QDateTime& mtime )
1365{
1366 addMetaData( "modified", mtime.toString( Qt::ISODate ) );
1367}
1368
1369TransferJob *KIO::get( const KUrl& url, LoadType reload, JobFlags flags )
1370{
1371 // Send decoded path and encoded query
1372 KIO_ARGS << url;
1373 TransferJob * job = TransferJobPrivate::newJob(url, CMD_GET, packedArgs,
1374 QByteArray(), flags);
1375 if (reload == Reload)
1376 job->addMetaData("cache", "reload");
1377 return job;
1378}
1379
1380class KIO::StoredTransferJobPrivate: public TransferJobPrivate
1381{
1382public:
1383 StoredTransferJobPrivate(const KUrl& url, int command,
1384 const QByteArray &packedArgs,
1385 const QByteArray &_staticData)
1386 : TransferJobPrivate(url, command, packedArgs, _staticData),
1387 m_uploadOffset( 0 )
1388 {}
1389 StoredTransferJobPrivate(const KUrl& url, int command,
1390 const QByteArray &packedArgs,
1391 QIODevice* ioDevice)
1392 : TransferJobPrivate(url, command, packedArgs, ioDevice),
1393 m_uploadOffset( 0 )
1394 {}
1395
1396 QByteArray m_data;
1397 int m_uploadOffset;
1398
1399 void slotStoredData( KIO::Job *job, const QByteArray &data );
1400 void slotStoredDataReq( KIO::Job *job, QByteArray &data );
1401
1402 Q_DECLARE_PUBLIC(StoredTransferJob)
1403
1404 static inline StoredTransferJob *newJob(const KUrl &url, int command,
1405 const QByteArray &packedArgs,
1406 const QByteArray &staticData, JobFlags flags)
1407 {
1408 StoredTransferJob *job = new StoredTransferJob(
1409 *new StoredTransferJobPrivate(url, command, packedArgs, staticData));
1410 job->setUiDelegate(new JobUiDelegate);
1411 if (!(flags & HideProgressInfo))
1412 KIO::getJobTracker()->registerJob(job);
1413 return job;
1414 }
1415
1416 static inline StoredTransferJob *newJob(const KUrl &url, int command,
1417 const QByteArray &packedArgs,
1418 QIODevice* ioDevice, JobFlags flags)
1419 {
1420 StoredTransferJob *job = new StoredTransferJob(
1421 *new StoredTransferJobPrivate(url, command, packedArgs, ioDevice));
1422 job->setUiDelegate(new JobUiDelegate);
1423 if (!(flags & HideProgressInfo))
1424 KIO::getJobTracker()->registerJob(job);
1425 return job;
1426 }
1427};
1428
1429namespace KIO {
1430 class PostErrorJob : public StoredTransferJob
1431 {
1432 public:
1433
1434 PostErrorJob(int _error, const QString& url, const QByteArray &packedArgs, const QByteArray &postData)
1435 : StoredTransferJob(*new StoredTransferJobPrivate(KUrl(), CMD_SPECIAL, packedArgs, postData))
1436 {
1437 setError( _error );
1438 setErrorText( url );
1439 }
1440
1441 PostErrorJob(int _error, const QString& url, const QByteArray &packedArgs, QIODevice* ioDevice)
1442 : StoredTransferJob(*new StoredTransferJobPrivate(KUrl(), CMD_SPECIAL, packedArgs, ioDevice))
1443 {
1444 setError( _error );
1445 setErrorText( url );
1446 }
1447 };
1448}
1449
1450static int isUrlPortBad(const KUrl& url)
1451{
1452 int _error = 0;
1453
1454 // filter out some malicious ports
1455 static const int bad_ports[] = {
1456 1, // tcpmux
1457 7, // echo
1458 9, // discard
1459 11, // systat
1460 13, // daytime
1461 15, // netstat
1462 17, // qotd
1463 19, // chargen
1464 20, // ftp-data
1465 21, // ftp-cntl
1466 22, // ssh
1467 23, // telnet
1468 25, // smtp
1469 37, // time
1470 42, // name
1471 43, // nicname
1472 53, // domain
1473 77, // priv-rjs
1474 79, // finger
1475 87, // ttylink
1476 95, // supdup
1477 101, // hostriame
1478 102, // iso-tsap
1479 103, // gppitnp
1480 104, // acr-nema
1481 109, // pop2
1482 110, // pop3
1483 111, // sunrpc
1484 113, // auth
1485 115, // sftp
1486 117, // uucp-path
1487 119, // nntp
1488 123, // NTP
1489 135, // loc-srv / epmap
1490 139, // netbios
1491 143, // imap2
1492 179, // BGP
1493 389, // ldap
1494 512, // print / exec
1495 513, // login
1496 514, // shell
1497 515, // printer
1498 526, // tempo
1499 530, // courier
1500 531, // Chat
1501 532, // netnews
1502 540, // uucp
1503 556, // remotefs
1504 587, // sendmail
1505 601, //
1506 989, // ftps data
1507 990, // ftps
1508 992, // telnets
1509 993, // imap/SSL
1510 995, // pop3/SSL
1511 1080, // SOCKS
1512 2049, // nfs
1513 4045, // lockd
1514 6000, // x11
1515 6667, // irc
1516 0};
1517 if (url.port() != 80)
1518 {
1519 const int port = url.port();
1520 for (int cnt=0; bad_ports[cnt] && bad_ports[cnt] <= port; ++cnt)
1521 if (port == bad_ports[cnt])
1522 {
1523 _error = KIO::ERR_POST_DENIED;
1524 break;
1525 }
1526 }
1527
1528 if ( _error )
1529 {
1530 static bool override_loaded = false;
1531 static QList< int >* overriden_ports = NULL;
1532 if( !override_loaded ) {
1533 KConfig cfg( "kio_httprc" );
1534 overriden_ports = new QList< int >;
1535 *overriden_ports = cfg.group(QString()).readEntry( "OverriddenPorts", QList<int>() );
1536 override_loaded = true;
1537 }
1538 for( QList< int >::ConstIterator it = overriden_ports->constBegin();
1539 it != overriden_ports->constEnd();
1540 ++it ) {
1541 if( overriden_ports->contains( url.port())) {
1542 _error = 0;
1543 }
1544 }
1545 }
1546
1547 // filter out non https? protocols
1548 if ((url.protocol() != "http") && (url.protocol() != "https" ))
1549 _error = KIO::ERR_POST_DENIED;
1550
1551 if (!_error && !KAuthorized::authorizeUrlAction("open", KUrl(), url))
1552 _error = KIO::ERR_ACCESS_DENIED;
1553
1554 return _error;
1555}
1556
1557static KIO::PostErrorJob* precheckHttpPost( const KUrl& url, QIODevice* ioDevice, JobFlags flags )
1558{
1559 // if request is not valid, return an invalid transfer job
1560 const int _error = isUrlPortBad(url);
1561
1562 if (_error)
1563 {
1564 KIO_ARGS << (int)1 << url;
1565 PostErrorJob * job = new PostErrorJob(_error, url.pathOrUrl(), packedArgs, ioDevice);
1566 job->setUiDelegate(new JobUiDelegate());
1567 if (!(flags & HideProgressInfo)) {
1568 KIO::getJobTracker()->registerJob(job);
1569 }
1570 return job;
1571 }
1572
1573 // all is ok, return 0
1574 return 0;
1575}
1576
1577static KIO::PostErrorJob* precheckHttpPost( const KUrl& url, const QByteArray& postData, JobFlags flags )
1578{
1579 // if request is not valid, return an invalid transfer job
1580 const int _error = isUrlPortBad(url);
1581
1582 if (_error)
1583 {
1584 KIO_ARGS << (int)1 << url;
1585 PostErrorJob * job = new PostErrorJob(_error, url.pathOrUrl(), packedArgs, postData);
1586 job->setUiDelegate(new JobUiDelegate());
1587 if (!(flags & HideProgressInfo)) {
1588 KIO::getJobTracker()->registerJob(job);
1589 }
1590 return job;
1591 }
1592
1593 // all is ok, return 0
1594 return 0;
1595}
1596
1597TransferJob *KIO::http_post( const KUrl& url, const QByteArray &postData, JobFlags flags )
1598{
1599 QBuffer* device = new QBuffer;
1600 device->setData(postData);
1601 device->open(QIODevice::ReadOnly);
1602 TransferJob* job = http_post(url, device, device->size(), flags);
1603 device->setParent(job);
1604 return job;
1605}
1606
1607TransferJob *KIO::http_post( const KUrl& url, QIODevice* ioDevice, qint64 size, JobFlags flags )
1608{
1609 bool redirection = false;
1610 KUrl _url(url);
1611 if (_url.path().isEmpty())
1612 {
1613 redirection = true;
1614 _url.setPath("/");
1615 }
1616
1617 TransferJob* job = precheckHttpPost(_url, ioDevice, flags);
1618 if (job)
1619 return job;
1620
1621 // If no size is specified and the QIODevice is not a sequential one,
1622 // attempt to obtain the size information from it.
1623 Q_ASSERT(ioDevice);
1624 if (size < 0)
1625 size = ((ioDevice && !ioDevice->isSequential()) ? ioDevice->size() : -1);
1626
1627 // Send http post command (1), decoded path and encoded query
1628 KIO_ARGS << (int)1 << _url << size;
1629 job = TransferJobPrivate::newJob(_url, CMD_SPECIAL, packedArgs, ioDevice, flags);
1630
1631 if (redirection)
1632 QTimer::singleShot(0, job, SLOT(slotPostRedirection()));
1633
1634 return job;
1635}
1636
1637TransferJob* KIO::http_delete(const KUrl& url, JobFlags flags)
1638{
1639 // Send decoded path and encoded query
1640 KIO_ARGS << url;
1641 TransferJob * job = TransferJobPrivate::newJob(url, CMD_DEL, packedArgs,
1642 QByteArray(), flags);
1643 return job;
1644}
1645
1646StoredTransferJob *KIO::storedHttpPost( const QByteArray& postData, const KUrl& url, JobFlags flags )
1647{
1648 KUrl _url(url);
1649 if (_url.path().isEmpty())
1650 {
1651 _url.setPath("/");
1652 }
1653
1654 StoredTransferJob* job = precheckHttpPost(_url, postData, flags);
1655 if (job)
1656 return job;
1657
1658 // Send http post command (1), decoded path and encoded query
1659 KIO_ARGS << (int)1 << _url << static_cast<qint64>(postData.size());
1660 job = StoredTransferJobPrivate::newJob(_url, CMD_SPECIAL, packedArgs, postData, flags );
1661 return job;
1662}
1663
1664StoredTransferJob *KIO::storedHttpPost( QIODevice* ioDevice, const KUrl& url, qint64 size, JobFlags flags )
1665{
1666 KUrl _url(url);
1667 if (_url.path().isEmpty())
1668 {
1669 _url.setPath("/");
1670 }
1671
1672 StoredTransferJob* job = precheckHttpPost(_url, ioDevice, flags);
1673 if (job)
1674 return job;
1675
1676 // If no size is specified and the QIODevice is not a sequential one,
1677 // attempt to obtain the size information from it.
1678 Q_ASSERT(ioDevice);
1679 if (size < 0)
1680 size = ((ioDevice && !ioDevice->isSequential()) ? ioDevice->size() : -1);
1681
1682 // Send http post command (1), decoded path and encoded query
1683 KIO_ARGS << (int)1 << _url << size;
1684 job = StoredTransferJobPrivate::newJob(_url, CMD_SPECIAL, packedArgs, ioDevice, flags );
1685 return job;
1686}
1687
1688// http post got redirected from http://host to http://host/ by TransferJob
1689// We must do this redirection ourselves because redirections by the
1690// slave change post jobs into get jobs.
1691void TransferJobPrivate::slotPostRedirection()
1692{
1693 Q_Q(TransferJob);
1694 kDebug(7007) << "TransferJob::slotPostRedirection(" << m_url << ")";
1695 // Tell the user about the new url.
1696 emit q->redirection(q, m_url);
1697}
1698
1699
1700TransferJob *KIO::put( const KUrl& url, int permissions, JobFlags flags )
1701{
1702 KIO_ARGS << url << qint8( (flags & Overwrite) ? 1 : 0 ) << qint8( (flags & Resume) ? 1 : 0 ) << permissions;
1703 return TransferJobPrivate::newJob(url, CMD_PUT, packedArgs, QByteArray(), flags);
1704}
1705
1707
1708StoredTransferJob::StoredTransferJob(StoredTransferJobPrivate &dd)
1709 : TransferJob(dd)
1710{
1711 connect( this, SIGNAL(data(KIO::Job*,QByteArray)),
1712 SLOT(slotStoredData(KIO::Job*,QByteArray)) );
1713 connect( this, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
1714 SLOT(slotStoredDataReq(KIO::Job*,QByteArray&)) );
1715}
1716
1717StoredTransferJob::~StoredTransferJob()
1718{
1719}
1720
1721void StoredTransferJob::setData( const QByteArray& arr )
1722{
1723 Q_D(StoredTransferJob);
1724 Q_ASSERT( d->m_data.isNull() ); // check that we're only called once
1725 Q_ASSERT( d->m_uploadOffset == 0 ); // no upload started yet
1726 d->m_data = arr;
1727 setTotalSize( d->m_data.size() );
1728}
1729
1730QByteArray StoredTransferJob::data() const
1731{
1732 return d_func()->m_data;
1733}
1734
1735void StoredTransferJobPrivate::slotStoredData( KIO::Job *, const QByteArray &data )
1736{
1737 // check for end-of-data marker:
1738 if ( data.size() == 0 )
1739 return;
1740 unsigned int oldSize = m_data.size();
1741 m_data.resize( oldSize + data.size() );
1742 memcpy( m_data.data() + oldSize, data.data(), data.size() );
1743}
1744
1745void StoredTransferJobPrivate::slotStoredDataReq( KIO::Job *, QByteArray &data )
1746{
1747 // Inspired from kmail's KMKernel::byteArrayToRemoteFile
1748 // send the data in 64 KB chunks
1749 const int MAX_CHUNK_SIZE = 64*1024;
1750 int remainingBytes = m_data.size() - m_uploadOffset;
1751 if( remainingBytes > MAX_CHUNK_SIZE ) {
1752 // send MAX_CHUNK_SIZE bytes to the receiver (deep copy)
1753 data = QByteArray( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
1754 m_uploadOffset += MAX_CHUNK_SIZE;
1755 //kDebug() << "Sending " << MAX_CHUNK_SIZE << " bytes ("
1756 // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n";
1757 } else {
1758 // send the remaining bytes to the receiver (deep copy)
1759 data = QByteArray( m_data.data() + m_uploadOffset, remainingBytes );
1760 m_data = QByteArray();
1761 m_uploadOffset = 0;
1762 //kDebug() << "Sending " << remainingBytes << " bytes\n";
1763 }
1764}
1765
1766StoredTransferJob *KIO::storedGet( const KUrl& url, LoadType reload, JobFlags flags )
1767{
1768 // Send decoded path and encoded query
1769 KIO_ARGS << url;
1770 StoredTransferJob * job = StoredTransferJobPrivate::newJob(url, CMD_GET, packedArgs, QByteArray(), flags);
1771 if (reload == Reload)
1772 job->addMetaData("cache", "reload");
1773 return job;
1774}
1775
1776StoredTransferJob *KIO::storedPut( const QByteArray& arr, const KUrl& url, int permissions,
1777 JobFlags flags )
1778{
1779 KIO_ARGS << url << qint8( (flags & Overwrite) ? 1 : 0 ) << qint8( (flags & Resume) ? 1 : 0 ) << permissions;
1780 StoredTransferJob * job = StoredTransferJobPrivate::newJob(url, CMD_PUT, packedArgs, QByteArray(), flags );
1781 job->setData( arr );
1782 return job;
1783}
1784
1786
1787class KIO::MimetypeJobPrivate: public KIO::TransferJobPrivate
1788{
1789public:
1790 MimetypeJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
1791 : TransferJobPrivate(url, command, packedArgs, QByteArray())
1792 {}
1793
1794 Q_DECLARE_PUBLIC(MimetypeJob)
1795
1796 static inline MimetypeJob *newJob(const KUrl& url, int command, const QByteArray &packedArgs,
1797 JobFlags flags)
1798 {
1799 MimetypeJob *job = new MimetypeJob(*new MimetypeJobPrivate(url, command, packedArgs));
1800 job->setUiDelegate(new JobUiDelegate);
1801 if (!(flags & HideProgressInfo)) {
1802 KIO::getJobTracker()->registerJob(job);
1803 emitStating(job, url);
1804 }
1805 return job;
1806 }
1807};
1808
1809MimetypeJob::MimetypeJob(MimetypeJobPrivate &dd)
1810 : TransferJob(dd)
1811{
1812}
1813
1814MimetypeJob::~MimetypeJob()
1815{
1816}
1817
1818void MimetypeJob::slotFinished( )
1819{
1820 Q_D(MimetypeJob);
1821 //kDebug(7007);
1822 if ( error() == KIO::ERR_IS_DIRECTORY )
1823 {
1824 // It is in fact a directory. This happens when HTTP redirects to FTP.
1825 // Due to the "protocol doesn't support listing" code in KRun, we
1826 // assumed it was a file.
1827 kDebug(7007) << "It is in fact a directory!";
1828 d->m_mimetype = QString::fromLatin1("inode/directory");
1829 emit TransferJob::mimetype( this, d->m_mimetype );
1830 setError( 0 );
1831 }
1832
1833 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && !error() )
1834 {
1835 //kDebug(7007) << "Redirection to " << m_redirectionURL;
1836 if (queryMetaData("permanent-redirect")=="true")
1837 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
1838
1839 if (d->m_redirectionHandlingEnabled)
1840 {
1841 d->staticData.truncate(0);
1842 d->m_internalSuspended = false;
1843 d->m_packedArgs.truncate(0);
1844 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1845 stream << d->m_redirectionURL;
1846
1847 d->restartAfterRedirection(&d->m_redirectionURL);
1848 return;
1849 }
1850 }
1851
1852 // Return slave to the scheduler
1853 TransferJob::slotFinished();
1854}
1855
1856MimetypeJob *KIO::mimetype(const KUrl& url, JobFlags flags)
1857{
1858 KIO_ARGS << url;
1859 return MimetypeJobPrivate::newJob(url, CMD_MIMETYPE, packedArgs, flags);
1860}
1861
1863
1864class KIO::DirectCopyJobPrivate: public KIO::SimpleJobPrivate
1865{
1866public:
1867 DirectCopyJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
1868 : SimpleJobPrivate(url, command, packedArgs)
1869 {}
1870
1877 virtual void start(Slave *slave);
1878
1879 Q_DECLARE_PUBLIC(DirectCopyJob)
1880};
1881
1882DirectCopyJob::DirectCopyJob(const KUrl &url, const QByteArray &packedArgs)
1883 : SimpleJob(*new DirectCopyJobPrivate(url, CMD_COPY, packedArgs))
1884{
1885 setUiDelegate(new JobUiDelegate);
1886}
1887
1888DirectCopyJob::~DirectCopyJob()
1889{
1890}
1891
1892void DirectCopyJobPrivate::start( Slave* slave )
1893{
1894 Q_Q(DirectCopyJob);
1895 q->connect( slave, SIGNAL(canResume(KIO::filesize_t)),
1896 SLOT(slotCanResume(KIO::filesize_t)) );
1897 SimpleJobPrivate::start(slave);
1898}
1899
1900void DirectCopyJob::slotCanResume( KIO::filesize_t offset )
1901{
1902 emit canResume(this, offset);
1903}
1904
1906
1908class KIO::FileCopyJobPrivate: public KIO::JobPrivate
1909{
1910public:
1911 FileCopyJobPrivate(const KUrl& src, const KUrl& dest, int permissions,
1912 bool move, JobFlags flags)
1913 : m_sourceSize(filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(0), m_copyJob(0), m_delJob(0),
1914 m_chmodJob(0), m_getJob(0), m_putJob(0), m_permissions(permissions),
1915 m_move(move), m_mustChmod(0), m_flags(flags)
1916 {
1917 }
1918 KIO::filesize_t m_sourceSize;
1919 QDateTime m_modificationTime;
1920 KUrl m_src;
1921 KUrl m_dest;
1922 QByteArray m_buffer;
1923 SimpleJob *m_moveJob;
1924 SimpleJob *m_copyJob;
1925 SimpleJob *m_delJob;
1926 SimpleJob *m_chmodJob;
1927 TransferJob *m_getJob;
1928 TransferJob *m_putJob;
1929 int m_permissions;
1930 bool m_move:1;
1931 bool m_canResume:1;
1932 bool m_resumeAnswerSent:1;
1933 bool m_mustChmod:1;
1934 JobFlags m_flags;
1935
1936 void startBestCopyMethod();
1937 void startCopyJob();
1938 void startCopyJob(const KUrl &slave_url);
1939 void startRenameJob(const KUrl &slave_url);
1940 void startDataPump();
1941 void connectSubjob( SimpleJob * job );
1942
1943 void slotStart();
1944 void slotData( KIO::Job *, const QByteArray &data);
1945 void slotDataReq( KIO::Job *, QByteArray &data);
1946 void slotMimetype( KIO::Job*, const QString& type );
1952 void slotProcessedSize( KJob *job, qulonglong size );
1958 void slotTotalSize( KJob *job, qulonglong size );
1964 void slotPercent( KJob *job, unsigned long pct );
1970 void slotCanResume( KIO::Job *job, KIO::filesize_t offset );
1971
1972 Q_DECLARE_PUBLIC(FileCopyJob)
1973
1974 static inline FileCopyJob* newJob(const KUrl& src, const KUrl& dest, int permissions, bool move,
1975 JobFlags flags)
1976 {
1977 //kDebug(7007) << src << "->" << dest;
1978 FileCopyJob *job = new FileCopyJob(
1979 *new FileCopyJobPrivate(src, dest, permissions, move, flags));
1980 job->setProperty("destUrl", dest.url());
1981 job->setUiDelegate(new JobUiDelegate);
1982 if (!(flags & HideProgressInfo))
1983 KIO::getJobTracker()->registerJob(job);
1984 return job;
1985 }
1986};
1987
1988/*
1989 * The FileCopyJob works according to the famous Bavarian
1990 * 'Alternating Bitburger Protocol': we either drink a beer or we
1991 * we order a beer, but never both at the same time.
1992 * Translated to io-slaves: We alternate between receiving a block of data
1993 * and sending it away.
1994 */
1995FileCopyJob::FileCopyJob(FileCopyJobPrivate &dd)
1996 : Job(dd)
1997{
1998 //kDebug(7007);
1999 QTimer::singleShot(0, this, SLOT(slotStart()));
2000}
2001
2002void FileCopyJobPrivate::slotStart()
2003{
2004 Q_Q(FileCopyJob);
2005 if (!m_move)
2006 JobPrivate::emitCopying( q, m_src, m_dest );
2007 else
2008 JobPrivate::emitMoving( q, m_src, m_dest );
2009
2010 if ( m_move )
2011 {
2012 // The if() below must be the same as the one in startBestCopyMethod
2013 if ((m_src.protocol() == m_dest.protocol()) &&
2014 (m_src.host() == m_dest.host()) &&
2015 (m_src.port() == m_dest.port()) &&
2016 (m_src.user() == m_dest.user()) &&
2017 (m_src.pass() == m_dest.pass()) &&
2018 !m_src.hasSubUrl() && !m_dest.hasSubUrl())
2019 {
2020 startRenameJob(m_src);
2021 return;
2022 }
2023 else if (m_src.isLocalFile() && KProtocolManager::canRenameFromFile(m_dest))
2024 {
2025 startRenameJob(m_dest);
2026 return;
2027 }
2028 else if (m_dest.isLocalFile() && KProtocolManager::canRenameToFile(m_src))
2029 {
2030 startRenameJob(m_src);
2031 return;
2032 }
2033 // No fast-move available, use copy + del.
2034 }
2035 startBestCopyMethod();
2036}
2037
2038void FileCopyJobPrivate::startBestCopyMethod()
2039{
2040 if ((m_src.protocol() == m_dest.protocol()) &&
2041 (m_src.host() == m_dest.host()) &&
2042 (m_src.port() == m_dest.port()) &&
2043 (m_src.user() == m_dest.user()) &&
2044 (m_src.pass() == m_dest.pass()) &&
2045 !m_src.hasSubUrl() && !m_dest.hasSubUrl())
2046 {
2047 startCopyJob();
2048 }
2049 else if (m_src.isLocalFile() && KProtocolManager::canCopyFromFile(m_dest))
2050 {
2051 startCopyJob(m_dest);
2052 }
2053 else if (m_dest.isLocalFile() && KProtocolManager::canCopyToFile(m_src) &&
2054 !KIO::Scheduler::isSlaveOnHoldFor(m_src))
2055 {
2056 startCopyJob(m_src);
2057 }
2058 else
2059 {
2060 startDataPump();
2061 }
2062}
2063
2064FileCopyJob::~FileCopyJob()
2065{
2066}
2067
2068void FileCopyJob::setSourceSize( KIO::filesize_t size )
2069{
2070 Q_D(FileCopyJob);
2071 d->m_sourceSize = size;
2072 if (size != (KIO::filesize_t) -1)
2073 setTotalAmount(KJob::Bytes, size);
2074}
2075
2076void FileCopyJob::setModificationTime( const QDateTime& mtime )
2077{
2078 Q_D(FileCopyJob);
2079 d->m_modificationTime = mtime;
2080}
2081
2082KUrl FileCopyJob::srcUrl() const
2083{
2084 return d_func()->m_src;
2085}
2086
2087KUrl FileCopyJob::destUrl() const
2088{
2089 return d_func()->m_dest;
2090}
2091
2092void FileCopyJobPrivate::startCopyJob()
2093{
2094 startCopyJob(m_src);
2095}
2096
2097void FileCopyJobPrivate::startCopyJob(const KUrl &slave_url)
2098{
2099 Q_Q(FileCopyJob);
2100 //kDebug(7007);
2101 KIO_ARGS << m_src << m_dest << m_permissions << (qint8) (m_flags & Overwrite);
2102 m_copyJob = new DirectCopyJob(slave_url, packedArgs);
2103 if (m_modificationTime.isValid()) {
2104 m_copyJob->addMetaData( "modified", m_modificationTime.toString( Qt::ISODate ) ); // #55804
2105 }
2106 q->addSubjob( m_copyJob );
2107 connectSubjob( m_copyJob );
2108 q->connect( m_copyJob, SIGNAL(canResume(KIO::Job*,KIO::filesize_t)),
2109 SLOT(slotCanResume(KIO::Job*,KIO::filesize_t)));
2110}
2111
2112void FileCopyJobPrivate::startRenameJob(const KUrl &slave_url)
2113{
2114 Q_Q(FileCopyJob);
2115 m_mustChmod = true; // CMD_RENAME by itself doesn't change permissions
2116 KIO_ARGS << m_src << m_dest << (qint8) (m_flags & Overwrite);
2117 m_moveJob = SimpleJobPrivate::newJobNoUi(slave_url, CMD_RENAME, packedArgs);
2118 if (m_modificationTime.isValid()) {
2119 m_moveJob->addMetaData( "modified", m_modificationTime.toString( Qt::ISODate ) ); // #55804
2120 }
2121 q->addSubjob( m_moveJob );
2122 connectSubjob( m_moveJob );
2123}
2124
2125void FileCopyJobPrivate::connectSubjob( SimpleJob * job )
2126{
2127 Q_Q(FileCopyJob);
2128 q->connect( job, SIGNAL(totalSize(KJob*,qulonglong)),
2129 SLOT(slotTotalSize(KJob*,qulonglong)) );
2130
2131 q->connect( job, SIGNAL(processedSize(KJob*,qulonglong)),
2132 SLOT(slotProcessedSize(KJob*,qulonglong)) );
2133
2134 q->connect( job, SIGNAL(percent(KJob*,ulong)),
2135 SLOT(slotPercent(KJob*,ulong)) );
2136
2137}
2138
2139bool FileCopyJob::doSuspend()
2140{
2141 Q_D(FileCopyJob);
2142 if (d->m_moveJob)
2143 d->m_moveJob->suspend();
2144
2145 if (d->m_copyJob)
2146 d->m_copyJob->suspend();
2147
2148 if (d->m_getJob)
2149 d->m_getJob->suspend();
2150
2151 if (d->m_putJob)
2152 d->m_putJob->suspend();
2153
2154 Job::doSuspend();
2155 return true;
2156}
2157
2158bool FileCopyJob::doResume()
2159{
2160 Q_D(FileCopyJob);
2161 if (d->m_moveJob)
2162 d->m_moveJob->resume();
2163
2164 if (d->m_copyJob)
2165 d->m_copyJob->resume();
2166
2167 if (d->m_getJob)
2168 d->m_getJob->resume();
2169
2170 if (d->m_putJob)
2171 d->m_putJob->resume();
2172
2173 Job::doResume();
2174 return true;
2175}
2176
2177void FileCopyJobPrivate::slotProcessedSize( KJob *, qulonglong size )
2178{
2179 Q_Q(FileCopyJob);
2180 q->setProcessedAmount(KJob::Bytes, size);
2181}
2182
2183void FileCopyJobPrivate::slotTotalSize( KJob*, qulonglong size )
2184{
2185 Q_Q(FileCopyJob);
2186 if (size != q->totalAmount(KJob::Bytes))
2187 {
2188 q->setTotalAmount(KJob::Bytes, size);
2189 }
2190}
2191
2192void FileCopyJobPrivate::slotPercent( KJob*, unsigned long pct )
2193{
2194 Q_Q(FileCopyJob);
2195 if ( pct > q->percent() ) {
2196 q->setPercent( pct );
2197 }
2198}
2199
2200void FileCopyJobPrivate::startDataPump()
2201{
2202 Q_Q(FileCopyJob);
2203 //kDebug(7007);
2204
2205 m_canResume = false;
2206 m_resumeAnswerSent = false;
2207 m_getJob = 0L; // for now
2208 m_putJob = put( m_dest, m_permissions, (m_flags | HideProgressInfo) /* no GUI */);
2209 //kDebug(7007) << "m_putJob=" << m_putJob << "m_dest=" << m_dest;
2210 if ( m_modificationTime.isValid() ) {
2211 m_putJob->setModificationTime( m_modificationTime );
2212 }
2213
2214 // The first thing the put job will tell us is whether we can
2215 // resume or not (this is always emitted)
2216 q->connect( m_putJob, SIGNAL(canResume(KIO::Job*,KIO::filesize_t)),
2217 SLOT(slotCanResume(KIO::Job*,KIO::filesize_t)));
2218 q->connect( m_putJob, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
2219 SLOT(slotDataReq(KIO::Job*,QByteArray&)));
2220 q->addSubjob( m_putJob );
2221}
2222
2223void FileCopyJobPrivate::slotCanResume( KIO::Job* job, KIO::filesize_t offset )
2224{
2225 Q_Q(FileCopyJob);
2226 if ( job == m_putJob || job == m_copyJob )
2227 {
2228 //kDebug(7007) << "'can resume' from PUT job. offset=" << KIO::number(offset);
2229 if (offset)
2230 {
2231 RenameDialog_Result res = R_RESUME;
2232
2233 if (!KProtocolManager::autoResume() && !(m_flags & Overwrite))
2234 {
2235 QString newPath;
2236 KIO::Job* job = ( q->parentJob() ) ? q->parentJob() : q;
2237 // Ask confirmation about resuming previous transfer
2238 res = ui()->askFileRename(
2239 job, i18n("File Already Exists"),
2240 m_src.url(),
2241 m_dest.url(),
2242 (RenameDialog_Mode) (M_OVERWRITE | M_RESUME | M_NORENAME), newPath,
2243 m_sourceSize, offset );
2244 }
2245
2246 if ( res == R_OVERWRITE || (m_flags & Overwrite) )
2247 offset = 0;
2248 else if ( res == R_CANCEL )
2249 {
2250 if ( job == m_putJob ) {
2251 m_putJob->kill( FileCopyJob::Quietly );
2252 q->removeSubjob(m_putJob);
2253 m_putJob = 0;
2254 } else {
2255 m_copyJob->kill( FileCopyJob::Quietly );
2256 q->removeSubjob(m_copyJob);
2257 m_copyJob = 0;
2258 }
2259 q->setError( ERR_USER_CANCELED );
2260 q->emitResult();
2261 return;
2262 }
2263 }
2264 else
2265 m_resumeAnswerSent = true; // No need for an answer
2266
2267 if ( job == m_putJob )
2268 {
2269 m_getJob = KIO::get( m_src, NoReload, HideProgressInfo /* no GUI */ );
2270 //kDebug(7007) << "m_getJob=" << m_getJob << m_src;
2271 m_getJob->addMetaData( "errorPage", "false" );
2272 m_getJob->addMetaData( "AllowCompressedPage", "false" );
2273 // Set size in subjob. This helps if the slave doesn't emit totalSize.
2274 if ( m_sourceSize != (KIO::filesize_t)-1 )
2275 m_getJob->setTotalAmount(KJob::Bytes, m_sourceSize);
2276 if (offset)
2277 {
2278 //kDebug(7007) << "Setting metadata for resume to" << (unsigned long) offset;
2279 // TODO KDE4: rename to seek or offset and document it
2280 // This isn't used only for resuming, but potentially also for extracting (#72302).
2281 m_getJob->addMetaData( "resume", KIO::number(offset) );
2282
2283 // Might or might not get emitted
2284 q->connect( m_getJob, SIGNAL(canResume(KIO::Job*,KIO::filesize_t)),
2285 SLOT(slotCanResume(KIO::Job*,KIO::filesize_t)));
2286 }
2287 jobSlave(m_putJob)->setOffset( offset );
2288
2289 m_putJob->d_func()->internalSuspend();
2290 q->addSubjob( m_getJob );
2291 connectSubjob( m_getJob ); // Progress info depends on get
2292 m_getJob->d_func()->internalResume(); // Order a beer
2293
2294 q->connect( m_getJob, SIGNAL(data(KIO::Job*,QByteArray)),
2295 SLOT(slotData(KIO::Job*,QByteArray)) );
2296 q->connect( m_getJob, SIGNAL(mimetype(KIO::Job*,QString)),
2297 SLOT(slotMimetype(KIO::Job*,QString)) );
2298 }
2299 else // copyjob
2300 {
2301 jobSlave(m_copyJob)->sendResumeAnswer( offset != 0 );
2302 }
2303 }
2304 else if ( job == m_getJob )
2305 {
2306 // Cool, the get job said ok, we can resume
2307 m_canResume = true;
2308 //kDebug(7007) << "'can resume' from the GET job -> we can resume";
2309
2310 jobSlave(m_getJob)->setOffset( jobSlave(m_putJob)->offset() );
2311 }
2312 else
2313 kWarning(7007) << "unknown job=" << job
2314 << "m_getJob=" << m_getJob << "m_putJob=" << m_putJob;
2315}
2316
2317void FileCopyJobPrivate::slotData( KIO::Job * , const QByteArray &data)
2318{
2319 //kDebug(7007) << "data size:" << data.size();
2320 Q_ASSERT(m_putJob);
2321 if (!m_putJob) return; // Don't crash
2322 m_getJob->d_func()->internalSuspend();
2323 m_putJob->d_func()->internalResume(); // Drink the beer
2324 m_buffer += data;
2325
2326 // On the first set of data incoming, we tell the "put" slave about our
2327 // decision about resuming
2328 if (!m_resumeAnswerSent)
2329 {
2330 m_resumeAnswerSent = true;
2331 //kDebug(7007) << "(first time) -> send resume answer " << m_canResume;
2332 jobSlave(m_putJob)->sendResumeAnswer( m_canResume );
2333 }
2334}
2335
2336void FileCopyJobPrivate::slotDataReq( KIO::Job * , QByteArray &data)
2337{
2338 Q_Q(FileCopyJob);
2339 //kDebug(7007);
2340 if (!m_resumeAnswerSent && !m_getJob) {
2341 // This can't happen
2342 q->setError( ERR_INTERNAL );
2343 q->setErrorText( "'Put' job did not send canResume or 'Get' job did not send data!" );
2344 m_putJob->kill( FileCopyJob::Quietly );
2345 q->removeSubjob(m_putJob);
2346 m_putJob = 0;
2347 q->emitResult();
2348 return;
2349 }
2350 if (m_getJob)
2351 {
2352 m_getJob->d_func()->internalResume(); // Order more beer
2353 m_putJob->d_func()->internalSuspend();
2354 }
2355 data = m_buffer;
2356 m_buffer = QByteArray();
2357}
2358
2359void FileCopyJobPrivate::slotMimetype( KIO::Job*, const QString& type )
2360{
2361 Q_Q(FileCopyJob);
2362 emit q->mimetype( q, type );
2363}
2364
2365void FileCopyJob::slotResult( KJob *job)
2366{
2367 Q_D(FileCopyJob);
2368 //kDebug(7007) << "this=" << this << "job=" << job;
2369 removeSubjob(job);
2370 // Did job have an error ?
2371 if ( job->error() )
2372 {
2373 if ((job == d->m_moveJob) && (job->error() == ERR_UNSUPPORTED_ACTION))
2374 {
2375 d->m_moveJob = 0;
2376 d->startBestCopyMethod();
2377 return;
2378 }
2379 else if ((job == d->m_copyJob) && (job->error() == ERR_UNSUPPORTED_ACTION))
2380 {
2381 d->m_copyJob = 0;
2382 d->startDataPump();
2383 return;
2384 }
2385 else if (job == d->m_getJob)
2386 {
2387 d->m_getJob = 0L;
2388 if (d->m_putJob)
2389 {
2390 d->m_putJob->kill( Quietly );
2391 removeSubjob( d->m_putJob );
2392 }
2393 }
2394 else if (job == d->m_putJob)
2395 {
2396 d->m_putJob = 0L;
2397 if (d->m_getJob)
2398 {
2399 d->m_getJob->kill( Quietly );
2400 removeSubjob( d->m_getJob );
2401 }
2402 }
2403 setError( job->error() );
2404 setErrorText( job->errorText() );
2405 emitResult();
2406 return;
2407 }
2408
2409 if (d->m_mustChmod)
2410 {
2411 // If d->m_permissions == -1, keep the default permissions
2412 if (d->m_permissions != -1)
2413 {
2414 d->m_chmodJob = chmod(d->m_dest, d->m_permissions);
2415 }
2416 d->m_mustChmod = false;
2417 }
2418
2419 if (job == d->m_moveJob)
2420 {
2421 d->m_moveJob = 0; // Finished
2422 }
2423
2424 if (job == d->m_copyJob)
2425 {
2426 d->m_copyJob = 0;
2427 if (d->m_move)
2428 {
2429 d->m_delJob = file_delete( d->m_src, HideProgressInfo/*no GUI*/ ); // Delete source
2430 addSubjob(d->m_delJob);
2431 }
2432 }
2433
2434 if (job == d->m_getJob)
2435 {
2436 //kDebug(7007) << "m_getJob finished";
2437 d->m_getJob = 0; // No action required
2438 if (d->m_putJob)
2439 d->m_putJob->d_func()->internalResume();
2440 }
2441
2442 if (job == d->m_putJob)
2443 {
2444 //kDebug(7007) << "m_putJob finished";
2445 d->m_putJob = 0;
2446 if (d->m_getJob)
2447 {
2448 // The get job is still running, probably after emitting data(QByteArray())
2449 // and before we receive its finished().
2450 d->m_getJob->d_func()->internalResume();
2451 }
2452 if (d->m_move)
2453 {
2454 d->m_delJob = file_delete( d->m_src, HideProgressInfo/*no GUI*/ ); // Delete source
2455 addSubjob(d->m_delJob);
2456 }
2457 }
2458
2459 if (job == d->m_delJob)
2460 {
2461 d->m_delJob = 0; // Finished
2462 }
2463
2464 if (job == d->m_chmodJob)
2465 {
2466 d->m_chmodJob = 0; // Finished
2467 }
2468
2469 if ( !hasSubjobs() )
2470 emitResult();
2471}
2472
2473FileCopyJob *KIO::file_copy( const KUrl& src, const KUrl& dest, int permissions,
2474 JobFlags flags )
2475{
2476 return FileCopyJobPrivate::newJob(src, dest, permissions, false, flags);
2477}
2478
2479FileCopyJob *KIO::file_move( const KUrl& src, const KUrl& dest, int permissions,
2480 JobFlags flags )
2481{
2482 FileCopyJob* job = FileCopyJobPrivate::newJob(src, dest, permissions, true, flags);
2483 ClipboardUpdater::create(job, ClipboardUpdater::UpdateContent);
2484 return job;
2485}
2486
2487SimpleJob *KIO::file_delete( const KUrl& src, JobFlags flags )
2488{
2489 KIO_ARGS << src << qint8(true); // isFile
2490 SimpleJob* job = SimpleJobPrivate::newJob(src, CMD_DEL, packedArgs, flags);
2491 ClipboardUpdater::create(job, ClipboardUpdater::RemoveContent);
2492 return job;
2493}
2494
2496
2497class KIO::ListJobPrivate: public KIO::SimpleJobPrivate
2498{
2499public:
2500 ListJobPrivate(const KUrl& url, bool _recursive,
2501 const QString &prefix, const QString &displayPrefix,
2502 bool _includeHidden)
2503 : SimpleJobPrivate(url, CMD_LISTDIR, QByteArray()),
2504 recursive(_recursive), includeHidden(_includeHidden),
2505 m_prefix(prefix), m_displayPrefix(displayPrefix), m_processedEntries(0)
2506 {}
2507 bool recursive;
2508 bool includeHidden;
2509 QString m_prefix;
2510 QString m_displayPrefix;
2511 unsigned long m_processedEntries;
2512 KUrl m_redirectionURL;
2513
2520 virtual void start( Slave *slave );
2521
2522 void slotListEntries( const KIO::UDSEntryList& list );
2523 void slotRedirection( const KUrl &url );
2524 void gotEntries( KIO::Job * subjob, const KIO::UDSEntryList& list );
2525 void slotSubError( ListJob* job, ListJob* subJob);
2526
2527 Q_DECLARE_PUBLIC(ListJob)
2528
2529 static inline ListJob *newJob(const KUrl& u, bool _recursive,
2530 const QString &prefix, const QString &displayPrefix,
2531 bool _includeHidden, JobFlags flags = HideProgressInfo)
2532 {
2533 ListJob *job = new ListJob(*new ListJobPrivate(u, _recursive, prefix, displayPrefix, _includeHidden));
2534 job->setUiDelegate(new JobUiDelegate);
2535 if (!(flags & HideProgressInfo))
2536 KIO::getJobTracker()->registerJob(job);
2537 return job;
2538 }
2539 static inline ListJob *newJobNoUi(const KUrl& u, bool _recursive,
2540 const QString &prefix, const QString &displayPrefix,
2541 bool _includeHidden)
2542 {
2543 return new ListJob(*new ListJobPrivate(u, _recursive, prefix, displayPrefix, _includeHidden));
2544 }
2545};
2546
2547ListJob::ListJob(ListJobPrivate &dd)
2548 : SimpleJob(dd)
2549{
2550 Q_D(ListJob);
2551 // We couldn't set the args when calling the parent constructor,
2552 // so do it now.
2553 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
2554 stream << d->m_url;
2555}
2556
2557ListJob::~ListJob()
2558{
2559}
2560
2561void ListJobPrivate::slotListEntries( const KIO::UDSEntryList& list )
2562{
2563 Q_Q(ListJob);
2564 // Emit progress info (takes care of emit processedSize and percent)
2565 m_processedEntries += list.count();
2566 slotProcessedSize( m_processedEntries );
2567
2568 if (recursive) {
2569 UDSEntryList::ConstIterator it = list.begin();
2570 const UDSEntryList::ConstIterator end = list.end();
2571
2572 for (; it != end; ++it) {
2573
2574 const UDSEntry& entry = *it;
2575
2576 KUrl itemURL;
2577 // const UDSEntry::ConstIterator end2 = entry.end();
2578 // UDSEntry::ConstIterator it2 = entry.find( KIO::UDSEntry::UDS_URL );
2579 // if ( it2 != end2 )
2580 if (entry.contains(KIO::UDSEntry::UDS_URL))
2581 // itemURL = it2.value().toString();
2582 itemURL = entry.stringValue(KIO::UDSEntry::UDS_URL);
2583 else { // no URL, use the name
2584 itemURL = q->url();
2585 const QString fileName = entry.stringValue(KIO::UDSEntry::UDS_NAME);
2586 Q_ASSERT(!fileName.isEmpty()); // we'll recurse forever otherwise :)
2587 itemURL.addPath(fileName);
2588 }
2589
2590 if (entry.isDir() && !entry.isLink()) {
2591 const QString filename = itemURL.fileName();
2592 QString displayName = entry.stringValue(KIO::UDSEntry::UDS_DISPLAY_NAME);
2593 if (displayName.isEmpty())
2594 displayName = filename;
2595 // skip hidden dirs when listing if requested
2596 if (filename != ".." && filename != "." && (includeHidden || filename[0] != '.')) {
2597 ListJob *job = ListJobPrivate::newJobNoUi(itemURL,
2598 true /*recursive*/,
2599 m_prefix + filename + '/',
2600 m_displayPrefix + displayName + '/',
2601 includeHidden);
2602 Scheduler::setJobPriority(job, 1);
2603 q->connect(job, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
2604 SLOT(gotEntries(KIO::Job*,KIO::UDSEntryList)));
2605 q->connect(job, SIGNAL(subError(KIO::ListJob*,KIO::ListJob*)),
2606 SLOT(slotSubError(KIO::ListJob*,KIO::ListJob*)));
2607 q->addSubjob(job);
2608 }
2609 }
2610 }
2611 }
2612
2613 // Not recursive, or top-level of recursive listing : return now (send . and .. as well)
2614 // exclusion of hidden files also requires the full sweep, but the case for full-listing
2615 // a single dir is probably common enough to justify the shortcut
2616 if (m_prefix.isNull() && includeHidden) {
2617 emit q->entries(q, list);
2618 } else {
2619 // cull the unwanted hidden dirs and/or parent dir references from the listing, then emit that
2620 UDSEntryList newlist;
2621
2622 UDSEntryList::const_iterator it = list.begin();
2623 const UDSEntryList::const_iterator end = list.end();
2624 for (; it != end; ++it) {
2625
2626 // Modify the name in the UDSEntry
2627 UDSEntry newone = *it;
2628 const QString filename = newone.stringValue( KIO::UDSEntry::UDS_NAME );
2629 QString displayName = newone.stringValue(KIO::UDSEntry::UDS_DISPLAY_NAME);
2630 if (displayName.isEmpty())
2631 displayName = filename;
2632 // Avoid returning entries like subdir/. and subdir/.., but include . and .. for
2633 // the toplevel dir, and skip hidden files/dirs if that was requested
2634 if ( (m_prefix.isNull() || (filename != ".." && filename != ".") )
2635 && (includeHidden || (filename[0] != '.') ) )
2636 {
2637 // ## Didn't find a way to use the iterator instead of re-doing a key lookup
2638 newone.insert( KIO::UDSEntry::UDS_NAME, m_prefix + filename );
2639 newone.insert(KIO::UDSEntry::UDS_DISPLAY_NAME, m_displayPrefix + displayName);
2640 newlist.append(newone);
2641 }
2642 }
2643
2644 emit q->entries(q, newlist);
2645 }
2646}
2647
2648void ListJobPrivate::gotEntries(KIO::Job *, const KIO::UDSEntryList& list )
2649{
2650 // Forward entries received by subjob - faking we received them ourselves
2651 Q_Q(ListJob);
2652 emit q->entries(q, list);
2653}
2654
2655void ListJobPrivate::slotSubError(KIO::ListJob* /*job*/, KIO::ListJob* subJob)
2656{
2657 Q_Q(ListJob);
2658
2659 emit q->subError(q, subJob); /*Let the signal of subError go up */
2660}
2661
2662void ListJob::slotResult( KJob * job )
2663{
2664 Q_D(ListJob);
2665
2666 if (job->error()) {
2667 // If we can't list a subdir, the result is still ok
2668 // This is why we override KCompositeJob::slotResult - to not set
2669 // an error on parent job.
2670 // Let's emit a signal about this though
2671 emit subError(this, static_cast<KIO::ListJob*>(job));
2672 }
2673 removeSubjob(job);
2674 if (!hasSubjobs() && !d->m_slave) // if the main directory listing is still running, it will emit result in SimpleJob::slotFinished()
2675 emitResult();
2676}
2677
2678void ListJobPrivate::slotRedirection( const KUrl & url )
2679{
2680 Q_Q(ListJob);
2681 if (!KAuthorized::authorizeUrlAction("redirect", m_url, url))
2682 {
2683 kWarning(7007) << "ListJob: Redirection from " << m_url << " to " << url << " REJECTED!";
2684 return;
2685 }
2686 m_redirectionURL = url; // We'll remember that when the job finishes
2687 emit q->redirection( q, m_redirectionURL );
2688}
2689
2690void ListJob::slotFinished()
2691{
2692 Q_D(ListJob);
2693
2694 // Support for listing archives as directories
2695 if ( error() == KIO::ERR_IS_FILE && d->m_url.isLocalFile() ) {
2696 KMimeType::Ptr ptr = KMimeType::findByUrl( d->m_url, 0, true, true );
2697 if ( ptr ) {
2698 QString proto = ptr->property("X-KDE-LocalProtocol").toString();
2699 if ( !proto.isEmpty() && KProtocolInfo::isKnownProtocol( proto) ) {
2700 d->m_redirectionURL = d->m_url;
2701 d->m_redirectionURL.setProtocol( proto );
2702 setError( 0 );
2703 emit redirection(this,d->m_redirectionURL);
2704 }
2705 }
2706 }
2707
2708 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && !error() ) {
2709
2710 //kDebug(7007) << "Redirection to " << d->m_redirectionURL;
2711 if (queryMetaData("permanent-redirect")=="true")
2712 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
2713
2714 if ( d->m_redirectionHandlingEnabled ) {
2715 d->m_packedArgs.truncate(0);
2716 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
2717 stream << d->m_redirectionURL;
2718
2719 d->restartAfterRedirection(&d->m_redirectionURL);
2720 return;
2721 }
2722 }
2723
2724 // Return slave to the scheduler
2725 SimpleJob::slotFinished();
2726}
2727
2728void ListJob::slotMetaData( const KIO::MetaData &_metaData)
2729{
2730 Q_D(ListJob);
2731 SimpleJob::slotMetaData(_metaData);
2732 storeSSLSessionFromJob(d->m_redirectionURL);
2733}
2734
2735ListJob *KIO::listDir( const KUrl& url, JobFlags flags, bool includeHidden )
2736{
2737 return ListJobPrivate::newJob(url, false, QString(), QString(), includeHidden, flags);
2738}
2739
2740ListJob *KIO::listRecursive( const KUrl& url, JobFlags flags, bool includeHidden )
2741{
2742 return ListJobPrivate::newJob(url, true, QString(), QString(), includeHidden, flags);
2743}
2744
2745void ListJob::setUnrestricted(bool unrestricted)
2746{
2747 Q_D(ListJob);
2748 if (unrestricted)
2749 d->m_extraFlags |= JobPrivate::EF_ListJobUnrestricted;
2750 else
2751 d->m_extraFlags &= ~JobPrivate::EF_ListJobUnrestricted;
2752}
2753
2754void ListJobPrivate::start(Slave *slave)
2755{
2756 Q_Q(ListJob);
2757 if (!KAuthorized::authorizeUrlAction("list", m_url, m_url) &&
2758 !(m_extraFlags & EF_ListJobUnrestricted))
2759 {
2760 q->setError( ERR_ACCESS_DENIED );
2761 q->setErrorText( m_url.url() );
2762 QTimer::singleShot(0, q, SLOT(slotFinished()) );
2763 return;
2764 }
2765 q->connect( slave, SIGNAL(listEntries(KIO::UDSEntryList)),
2766 SLOT(slotListEntries(KIO::UDSEntryList)));
2767 q->connect( slave, SIGNAL(totalSize(KIO::filesize_t)),
2768 SLOT(slotTotalSize(KIO::filesize_t)) );
2769 q->connect( slave, SIGNAL(redirection(KUrl)),
2770 SLOT(slotRedirection(KUrl)) );
2771
2772 SimpleJobPrivate::start(slave);
2773}
2774
2775const KUrl& ListJob::redirectionUrl() const
2776{
2777 return d_func()->m_redirectionURL;
2778}
2779
2781
2782class KIO::MultiGetJobPrivate: public KIO::TransferJobPrivate
2783{
2784public:
2785 MultiGetJobPrivate(const KUrl& url)
2786 : TransferJobPrivate(url, 0, QByteArray(), QByteArray()),
2787 m_currentEntry( 0, KUrl(), MetaData() )
2788 {}
2789 struct GetRequest {
2790 GetRequest(long _id, const KUrl &_url, const MetaData &_metaData)
2791 : id(_id), url(_url), metaData(_metaData) { }
2792 long id;
2793 KUrl url;
2794 MetaData metaData;
2795
2796 inline bool operator==( const GetRequest& req ) const
2797 { return req.id == id; }
2798 };
2799 typedef QLinkedList<GetRequest> RequestQueue;
2800
2801 RequestQueue m_waitQueue;
2802 RequestQueue m_activeQueue;
2803 GetRequest m_currentEntry;
2804 bool b_multiGetActive;
2805
2812 virtual void start(Slave *slave);
2813
2814 bool findCurrentEntry();
2815 void flushQueue(QLinkedList<GetRequest> &queue);
2816
2817 Q_DECLARE_PUBLIC(MultiGetJob)
2818
2819 static inline MultiGetJob *newJob(const KUrl &url)
2820 {
2821 MultiGetJob *job = new MultiGetJob(*new MultiGetJobPrivate(url));
2822 job->setUiDelegate(new JobUiDelegate);
2823 return job;
2824 }
2825};
2826
2827MultiGetJob::MultiGetJob(MultiGetJobPrivate &dd)
2828 : TransferJob(dd)
2829{
2830}
2831
2832MultiGetJob::~MultiGetJob()
2833{
2834}
2835
2836void MultiGetJob::get(long id, const KUrl &url, const MetaData &metaData)
2837{
2838 Q_D(MultiGetJob);
2839 MultiGetJobPrivate::GetRequest entry(id, url, metaData);
2840 entry.metaData["request-id"] = QString::number(id);
2841 d->m_waitQueue.append(entry);
2842}
2843
2844void MultiGetJobPrivate::flushQueue(RequestQueue &queue)
2845{
2846 // Use multi-get
2847 // Scan all jobs in m_waitQueue
2848 RequestQueue::iterator wqit = m_waitQueue.begin();
2849 const RequestQueue::iterator wqend = m_waitQueue.end();
2850 while ( wqit != wqend )
2851 {
2852 const GetRequest& entry = *wqit;
2853 if ((m_url.protocol() == entry.url.protocol()) &&
2854 (m_url.host() == entry.url.host()) &&
2855 (m_url.port() == entry.url.port()) &&
2856 (m_url.user() == entry.url.user()))
2857 {
2858 queue.append( entry );
2859 wqit = m_waitQueue.erase( wqit );
2860 }
2861 else
2862 {
2863 ++wqit;
2864 }
2865 }
2866 // Send number of URLs, (URL, metadata)*
2867 KIO_ARGS << (qint32) queue.count();
2868 RequestQueue::const_iterator qit = queue.begin();
2869 const RequestQueue::const_iterator qend = queue.end();
2870 for( ; qit != qend; ++qit )
2871 {
2872 stream << (*qit).url << (*qit).metaData;
2873 }
2874 m_packedArgs = packedArgs;
2875 m_command = CMD_MULTI_GET;
2876 m_outgoingMetaData.clear();
2877}
2878
2879void MultiGetJobPrivate::start(Slave *slave)
2880{
2881 // Add first job from m_waitQueue and add it to m_activeQueue
2882 GetRequest entry = m_waitQueue.takeFirst();
2883 m_activeQueue.append(entry);
2884
2885 m_url = entry.url;
2886
2887 if (!entry.url.protocol().startsWith(QLatin1String("http")))
2888 {
2889 // Use normal get
2890 KIO_ARGS << entry.url;
2891 m_packedArgs = packedArgs;
2892 m_outgoingMetaData = entry.metaData;
2893 m_command = CMD_GET;
2894 b_multiGetActive = false;
2895 }
2896 else
2897 {
2898 flushQueue(m_activeQueue);
2899 b_multiGetActive = true;
2900 }
2901
2902 TransferJobPrivate::start(slave); // Anything else to do??
2903}
2904
2905bool MultiGetJobPrivate::findCurrentEntry()
2906{
2907 if (b_multiGetActive)
2908 {
2909 long id = m_incomingMetaData["request-id"].toLong();
2910 RequestQueue::const_iterator qit = m_activeQueue.begin();
2911 const RequestQueue::const_iterator qend = m_activeQueue.end();
2912 for( ; qit != qend; ++qit )
2913 {
2914 if ((*qit).id == id)
2915 {
2916 m_currentEntry = *qit;
2917 return true;
2918 }
2919 }
2920 m_currentEntry.id = 0;
2921 return false;
2922 }
2923 else
2924 {
2925 if ( m_activeQueue.isEmpty() )
2926 return false;
2927 m_currentEntry = m_activeQueue.first();
2928 return true;
2929 }
2930}
2931
2932void MultiGetJob::slotRedirection( const KUrl &url)
2933{
2934 Q_D(MultiGetJob);
2935 if (!d->findCurrentEntry()) return; // Error
2936 if (!KAuthorized::authorizeUrlAction("redirect", d->m_url, url))
2937 {
2938 kWarning(7007) << "MultiGetJob: Redirection from " << d->m_currentEntry.url << " to " << url << " REJECTED!";
2939 return;
2940 }
2941 d->m_redirectionURL = url;
2942 get(d->m_currentEntry.id, d->m_redirectionURL, d->m_currentEntry.metaData); // Try again
2943}
2944
2945
2946void MultiGetJob::slotFinished()
2947{
2948 Q_D(MultiGetJob);
2949 if (!d->findCurrentEntry()) return;
2950 if (d->m_redirectionURL.isEmpty())
2951 {
2952 // No redirection, tell the world that we are finished.
2953 emit result(d->m_currentEntry.id);
2954 }
2955 d->m_redirectionURL = KUrl();
2956 setError( 0 );
2957 d->m_incomingMetaData.clear();
2958 d->m_activeQueue.removeAll(d->m_currentEntry);
2959 if (d->m_activeQueue.count() == 0)
2960 {
2961 if (d->m_waitQueue.count() == 0)
2962 {
2963 // All done
2964 TransferJob::slotFinished();
2965 }
2966 else
2967 {
2968 // return slave to pool
2969 // fetch new slave for first entry in d->m_waitQueue and call start
2970 // again.
2971 d->slaveDone();
2972
2973 d->m_url = d->m_waitQueue.first().url;
2974 if ((d->m_extraFlags & JobPrivate::EF_KillCalled) == 0) {
2975 Scheduler::doJob(this);
2976 }
2977 }
2978 }
2979}
2980
2981void MultiGetJob::slotData( const QByteArray &_data)
2982{
2983 Q_D(MultiGetJob);
2984 if(d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() || error())
2985 emit data(d->m_currentEntry.id, _data);
2986}
2987
2988void MultiGetJob::slotMimetype( const QString &_mimetype )
2989{
2990 Q_D(MultiGetJob);
2991 if (d->b_multiGetActive)
2992 {
2993 MultiGetJobPrivate::RequestQueue newQueue;
2994 d->flushQueue(newQueue);
2995 if (!newQueue.isEmpty())
2996 {
2997 d->m_activeQueue += newQueue;
2998 d->m_slave->send( d->m_command, d->m_packedArgs );
2999 }
3000 }
3001 if (!d->findCurrentEntry()) return; // Error, unknown request!
3002 emit mimetype(d->m_currentEntry.id, _mimetype);
3003}
3004
3005MultiGetJob *KIO::multi_get(long id, const KUrl &url, const MetaData &metaData)
3006{
3007 MultiGetJob * job = MultiGetJobPrivate::newJob(url);
3008 job->get(id, url, metaData);
3009 return job;
3010}
3011
3012class KIO::SpecialJobPrivate: public TransferJobPrivate
3013{
3014 SpecialJobPrivate(const KUrl& url, int command,
3015 const QByteArray &packedArgs,
3016 const QByteArray &_staticData)
3017 : TransferJobPrivate(url, command, packedArgs, _staticData)
3018 {}
3019};
3020
3021SpecialJob::SpecialJob(const KUrl &url, const QByteArray &packedArgs)
3022 : TransferJob(*new TransferJobPrivate(url, CMD_SPECIAL, packedArgs, QByteArray()))
3023{
3024}
3025
3026SpecialJob::~SpecialJob()
3027{
3028}
3029
3030void SpecialJob::setArguments(const QByteArray &data)
3031{
3032 Q_D(SpecialJob);
3033 d->m_packedArgs = data;
3034}
3035
3036QByteArray SpecialJob::arguments() const
3037{
3038 return d_func()->m_packedArgs;
3039}
3040
3041// Never defined, never used - what's this code about?
3042#ifdef CACHE_INFO
3043CacheInfo::CacheInfo(const KUrl &url)
3044{
3045 m_url = url;
3046}
3047
3048QString CacheInfo::cachedFileName()
3049{
3050 const QChar separator = '_';
3051
3052 QString CEF = m_url.path();
3053
3054 int p = CEF.find('/');
3055
3056 while(p != -1)
3057 {
3058 CEF[p] = separator;
3059 p = CEF.find('/', p);
3060 }
3061
3062 QString host = m_url.host().toLower();
3063 CEF = host + CEF + '_';
3064
3065 QString dir = KProtocolManager::cacheDir();
3066 if (dir[dir.length()-1] != '/')
3067 dir += '/';
3068
3069 int l = m_url.host().length();
3070 for(int i = 0; i < l; i++)
3071 {
3072 if (host[i].isLetter() && (host[i] != 'w'))
3073 {
3074 dir += host[i];
3075 break;
3076 }
3077 }
3078 if (dir[dir.length()-1] == '/')
3079 dir += '0';
3080
3081 unsigned long hash = 0x00000000;
3082 QString u = m_url.url().toLatin1();
3083 for(int i = u.length(); i--;)
3084 {
3085 hash = (hash * 12211 + u[i]) % 2147483563;
3086 }
3087
3088 QString hashString;
3089 hashString.sprintf("%08lx", hash);
3090
3091 CEF = CEF + hashString;
3092
3093 CEF = dir + '/' + CEF;
3094
3095 return CEF;
3096}
3097
3098QFile *CacheInfo::cachedFile()
3099{
3100#ifdef Q_WS_WIN
3101 const char *mode = (readWrite ? "rb+" : "rb");
3102#else
3103 const char *mode = (readWrite ? "r+" : "r");
3104#endif
3105
3106 FILE *fs = KDE::fopen(CEF, mode); // Open for reading and writing
3107 if (!fs)
3108 return 0;
3109
3110 char buffer[401];
3111 bool ok = true;
3112
3113 // CacheRevision
3114 if (ok && (!fgets(buffer, 400, fs)))
3115 ok = false;
3116 if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
3117 ok = false;
3118
3119 time_t date;
3120 time_t currentDate = time(0);
3121
3122 // URL
3123 if (ok && (!fgets(buffer, 400, fs)))
3124 ok = false;
3125 if (ok)
3126 {
3127 int l = strlen(buffer);
3128 if (l>0)
3129 buffer[l-1] = 0; // Strip newline
3130 if (m_.url.url() != buffer)
3131 {
3132 ok = false; // Hash collision
3133 }
3134 }
3135
3136 // Creation Date
3137 if (ok && (!fgets(buffer, 400, fs)))
3138 ok = false;
3139 if (ok)
3140 {
3141 date = (time_t) strtoul(buffer, 0, 10);
3142 if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge))
3143 {
3144 m_bMustRevalidate = true;
3145 m_expireDate = currentDate;
3146 }
3147 }
3148
3149 // Expiration Date
3150 m_cacheExpireDateOffset = KDE_ftell(fs);
3151 if (ok && (!fgets(buffer, 400, fs)))
3152 ok = false;
3153 if (ok)
3154 {
3155 if (m_request.cache == CC_Verify)
3156 {
3157 date = (time_t) strtoul(buffer, 0, 10);
3158 // After the expire date we need to revalidate.
3159 if (!date || difftime(currentDate, date) >= 0)
3160 m_bMustRevalidate = true;
3161 m_expireDate = date;
3162 }
3163 }
3164
3165 // ETag
3166 if (ok && (!fgets(buffer, 400, fs)))
3167 ok = false;
3168 if (ok)
3169 {
3170 m_etag = QString(buffer).trimmed();
3171 }
3172
3173 // Last-Modified
3174 if (ok && (!fgets(buffer, 400, fs)))
3175 ok = false;
3176 if (ok)
3177 {
3178 m_lastModified = QString(buffer).trimmed();
3179 }
3180
3181 fclose(fs);
3182
3183 if (ok)
3184 return fs;
3185
3186 unlink( QFile::encodeName(CEF) );
3187 return 0;
3188
3189}
3190
3191void CacheInfo::flush()
3192{
3193 cachedFile().remove();
3194}
3195
3196void CacheInfo::touch()
3197{
3198
3199}
3200void CacheInfo::setExpireDate(int);
3201void CacheInfo::setExpireTimeout(int);
3202
3203
3204int CacheInfo::creationDate();
3205int CacheInfo::expireDate();
3206int CacheInfo::expireTimeout();
3207#endif
3208
3209#include "jobclasses.moc"
3210#include "job_p.moc"
KCompositeJob
KCompositeJob::addSubjob
virtual bool addSubjob(KJob *job)
KCompositeJob::subjobs
const QList< KJob * > & subjobs() const
KCompositeJob::removeSubjob
virtual bool removeSubjob(KJob *job)
KCompositeJob::slotResult
virtual void slotResult(KJob *job)
KCompositeJob::clearSubjobs
void clearSubjobs()
KCompositeJob::hasSubjobs
bool hasSubjobs()
KConfigBase::group
KConfigGroup group(const char *group)
KConfigGroup::readEntry
QString readEntry(const char *key, const char *aDefault=0) const
KConfig
KDialogJobUiDelegate::showErrorMessage
virtual void showErrorMessage()
KDialogJobUiDelegate::updateUserTimestamp
void updateUserTimestamp(unsigned long time)
KIO::ClipboardUpdater::RemoveContent
@ RemoveContent
Definition: clipboardupdater_p.h:57
KIO::ClipboardUpdater::UpdateContent
@ UpdateContent
Definition: clipboardupdater_p.h:55
KIO::ClipboardUpdater::create
static ClipboardUpdater * create(Job *job, Mode mode)
Returns an instance of clipboard updater if QApplication::type() does not return a tty.
Definition: clipboardupdater.cpp:162
KIO::ClipboardUpdater::update
static void update(const KUrl &srcUrl, const KUrl &destUrl)
Convenience function that allows renaming of a single url in the clipboard.
Definition: clipboardupdater.cpp:171
KIO::DirectCopyJob
Definition: job_p.h:348
KIO::DirectCopyJob::~DirectCopyJob
~DirectCopyJob()
Definition: job.cpp:1888
KIO::DirectCopyJob::DirectCopyJob
DirectCopyJob(const KUrl &url, const QByteArray &packedArgs)
Definition: job.cpp:1882
KIO::DirectCopyJob::canResume
void canResume(KIO::Job *job, KIO::filesize_t offset)
KIO::DirectCopyJob::slotCanResume
void slotCanResume(KIO::filesize_t offset)
Definition: job.cpp:1900
KIO::FileCopyJob
The FileCopyJob copies data from one place to another.
Definition: jobclasses.h:856
KIO::FileCopyJob::slotResult
virtual void slotResult(KJob *job)
Called whenever a subjob finishes.
Definition: job.cpp:2365
KIO::FileCopyJob::setModificationTime
void setModificationTime(const QDateTime &mtime)
Sets the modification time of the file.
Definition: job.cpp:2076
KIO::FileCopyJob::FileCopyJob
FileCopyJob(FileCopyJobPrivate &dd)
Definition: job.cpp:1995
KIO::FileCopyJob::doSuspend
bool doSuspend()
Suspend this job.
Definition: job.cpp:2139
KIO::FileCopyJob::~FileCopyJob
~FileCopyJob()
Definition: job.cpp:2064
KIO::FileCopyJob::destUrl
KUrl destUrl() const
Returns the destination URL.
Definition: job.cpp:2087
KIO::FileCopyJob::doResume
bool doResume()
Resume this job.
Definition: job.cpp:2158
KIO::FileCopyJob::setSourceSize
void setSourceSize(KIO::filesize_t size)
If you know the size of the source file, call this method to inform this job.
Definition: job.cpp:2068
KIO::FileCopyJob::srcUrl
KUrl srcUrl() const
Returns the source URL.
Definition: job.cpp:2082
KIO::JobPrivate
Definition: job_p.h:40
KIO::JobPrivate::emitUnmounting
static void emitUnmounting(KIO::Job *, const QString &point)
Definition: job.cpp:169
KIO::JobPrivate::emitTransferring
static void emitTransferring(KIO::Job *, const KUrl &url)
Definition: job.cpp:156
KIO::JobPrivate::EF_TransferJobDataSent
@ EF_TransferJobDataSent
Definition: job_p.h:52
KIO::JobPrivate::EF_KillCalled
@ EF_KillCalled
Definition: job_p.h:54
KIO::JobPrivate::EF_TransferJobNeedData
@ EF_TransferJobNeedData
Definition: job_p.h:51
KIO::JobPrivate::EF_TransferJobAsync
@ EF_TransferJobAsync
Definition: job_p.h:50
KIO::JobPrivate::EF_ListJobUnrestricted
@ EF_ListJobUnrestricted
Definition: job_p.h:53
KIO::JobPrivate::ui
KIO::JobUiDelegate * ui() const
Definition: job_p.h:64
KIO::JobPrivate::emitMoving
static void emitMoving(KIO::Job *, const KUrl &src, const KUrl &dest)
Definition: job.cpp:124
KIO::JobPrivate::emitDeleting
static void emitDeleting(KIO::Job *, const KUrl &url)
Definition: job.cpp:144
KIO::JobPrivate::slotSpeed
void slotSpeed(KJob *job, unsigned long speed)
Definition: job.cpp:207
KIO::JobPrivate::m_extraFlags
int m_extraFlags
Definition: job_p.h:59
KIO::JobPrivate::emitCreatingDir
static void emitCreatingDir(KIO::Job *, const KUrl &dir)
Definition: job.cpp:138
KIO::JobPrivate::emitCopying
static void emitCopying(KIO::Job *, const KUrl &src, const KUrl &dest)
Definition: job.cpp:131
KIO::JobPrivate::m_outgoingMetaData
MetaData m_outgoingMetaData
Definition: job_p.h:62
KIO::JobPrivate::emitStating
static void emitStating(KIO::Job *, const KUrl &url)
Definition: job.cpp:150
KIO::JobPrivate::emitMounting
static void emitMounting(KIO::Job *, const QString &dev, const QString &point)
Definition: job.cpp:162
KIO::JobUiDelegate
A UI delegate tuned to be used with KIO Jobs.
Definition: jobuidelegate.h:40
KIO::JobUiDelegate::setWindow
virtual void setWindow(QWidget *window)
Associate this job with a window given by window.
Definition: jobuidelegate.cpp:58
KIO::JobUiDelegate::requestMessageBox
int requestMessageBox(MessageBoxType type, const QString &text, const QString &caption, const QString &buttonYes, const QString &buttonNo, const QString &iconYes=QString(), const QString &iconNo=QString(), const QString &dontAskAgainName=QString(), const KIO::MetaData &sslMetaData=KIO::MetaData())
This function allows for the delegation user prompts from the ioslaves.
Definition: jobuidelegate.cpp:200
KIO::JobUiDelegate::MessageBoxType
MessageBoxType
Message box types.
Definition: jobuidelegate.h:141
KIO::Job
The base class for all jobs.
Definition: jobclasses.h:94
KIO::Job::setMetaData
void setMetaData(const KIO::MetaData &metaData)
Set meta data to be sent to the slave, replacing existing meta data.
Definition: job.cpp:258
KIO::Job::~Job
virtual ~Job()
Definition: job.cpp:86
KIO::Job::setParentJob
void setParentJob(Job *parentJob)
Set the parent Job.
Definition: job.cpp:235
KIO::Job::errorString
QString errorString() const
Converts an error code and a non-i18n error message into an error message in the current language.
Definition: global.cpp:159
KIO::Job::doKill
virtual bool doKill()
Abort this job.
Definition: job.cpp:175
KIO::Job::parentJob
Job * parentJob() const
Returns the parent job, if there is one.
Definition: job.cpp:243
KIO::Job::showErrorDialog
void showErrorDialog(QWidget *parent=0)
Display a dialog box to inform the user of the error given by this job.
Definition: job.cpp:216
KIO::Job::Job
Job()
Definition: job.cpp:76
KIO::Job::mergeMetaData
void mergeMetaData(const QMap< QString, QString > &values)
Add key/value pairs to the meta data that is sent to the slave.
Definition: job.cpp:277
KIO::Job::doSuspend
virtual bool doSuspend()
Suspend this job.
Definition: job.cpp:186
KIO::Job::removeSubjob
virtual bool removeSubjob(KJob *job)
Mark a sub job as being done.
Definition: job.cpp:118
KIO::Job::outgoingMetaData
MetaData outgoingMetaData() const
Definition: job.cpp:287
KIO::Job::isInteractive
bool isInteractive() const
Returns whether the user should be asked about things when the job is unsure, like whether to overwri...
Definition: job.cpp:230
KIO::Job::queryMetaData
QString queryMetaData(const QString &key)
Query meta data received from the slave.
Definition: job.cpp:253
KIO::Job::ui
JobUiDelegate * ui() const
Retrieves the UI delegate of this job.
Definition: job.cpp:90
KIO::Job::metaData
MetaData metaData() const
Get meta data received from the slave.
Definition: job.cpp:248
KIO::Job::addSubjob
virtual bool addSubjob(KJob *job)
Add a job that has to be finished before a result is emitted.
Definition: job.cpp:95
KIO::Job::addMetaData
void addMetaData(const QString &key, const QString &value)
Add key/value pair to the meta data that is sent to the slave.
Definition: job.cpp:264
KIO::Job::doResume
virtual bool doResume()
Resume this job.
Definition: job.cpp:196
KIO::ListJob
A ListJob is allows you to get the get the content of a directory.
Definition: jobclasses.h:936
KIO::ListJob::~ListJob
~ListJob()
Definition: job.cpp:2557
KIO::ListJob::slotResult
virtual void slotResult(KJob *job)
Definition: job.cpp:2662
KIO::ListJob::redirection
void redirection(KIO::Job *job, const KUrl &url)
Signals a redirection.
KIO::ListJob::ListJob
ListJob(ListJobPrivate &dd)
Definition: job.cpp:2547
KIO::ListJob::subError
void subError(KIO::ListJob *job, KIO::ListJob *subJob)
This signal is emitted when a sub-directory could not be listed.
KIO::ListJob::setUnrestricted
void setUnrestricted(bool unrestricted)
Do not apply any KIOSK restrictions to this job.
Definition: job.cpp:2745
KIO::ListJob::slotMetaData
virtual void slotMetaData(const KIO::MetaData &_metaData)
Definition: job.cpp:2728
KIO::ListJob::permanentRedirection
void permanentRedirection(KIO::Job *job, const KUrl &fromUrl, const KUrl &toUrl)
Signals a permanent redirection.
KIO::ListJob::redirectionUrl
const KUrl & redirectionUrl() const
Returns the ListJob's redirection URL.
Definition: job.cpp:2775
KIO::ListJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:2690
KIO::MetaData
MetaData is a simple map of key/value strings.
Definition: global.h:397
KIO::MimetypeJob
A MimetypeJob is a TransferJob that allows you to get the mime type of an URL.
Definition: jobclasses.h:837
KIO::MimetypeJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:1818
KIO::MimetypeJob::MimetypeJob
MimetypeJob(MimetypeJobPrivate &dd)
Definition: job.cpp:1809
KIO::MimetypeJob::~MimetypeJob
~MimetypeJob()
Definition: job.cpp:1814
KIO::MkdirJob
A KIO job that creates a directory.
Definition: job_p.h:222
KIO::MkdirJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:667
KIO::MkdirJob::MkdirJob
MkdirJob(MkdirJobPrivate &dd)
Definition: job.cpp:632
KIO::MkdirJob::~MkdirJob
~MkdirJob()
Definition: job.cpp:637
KIO::MkdirJob::permanentRedirection
void permanentRedirection(KIO::Job *job, const KUrl &fromUrl, const KUrl &toUrl)
Signals a permanent redirection.
KIO::MultiGetJob
The MultiGetJob is a TransferJob that allows you to get several files from a single server.
Definition: jobclasses.h:778
KIO::MultiGetJob::slotRedirection
virtual void slotRedirection(const KUrl &url)
Definition: job.cpp:2932
KIO::MultiGetJob::slotData
virtual void slotData(const QByteArray &data)
Definition: job.cpp:2981
KIO::MultiGetJob::slotMimetype
virtual void slotMimetype(const QString &mimetype)
Definition: job.cpp:2988
KIO::MultiGetJob::~MultiGetJob
virtual ~MultiGetJob()
Definition: job.cpp:2832
KIO::MultiGetJob::result
void result(long id)
File transfer completed.
KIO::MultiGetJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:2946
KIO::MultiGetJob::MultiGetJob
MultiGetJob(MultiGetJobPrivate &dd)
Definition: job.cpp:2827
KIO::MultiGetJob::mimetype
void mimetype(long id, const QString &type)
Mimetype determined.
KIO::MultiGetJob::data
void data(long id, const QByteArray &data)
Data from the slave has arrived.
KIO::MultiGetJob::get
void get(long id, const KUrl &url, const MetaData &metaData)
Get an additional file.
Definition: job.cpp:2836
KIO::Scheduler::putSlaveOnHold
static void putSlaveOnHold(KIO::SimpleJob *job, const KUrl &url)
Puts a slave on notice.
Definition: scheduler.cpp:820
KIO::Scheduler::setJobPriority
static void setJobPriority(SimpleJob *job, int priority)
Changes the priority of job; jobs of the same priority run in the order in which they were created.
Definition: scheduler.cpp:805
KIO::Scheduler::isSlaveOnHoldFor
static bool isSlaveOnHoldFor(const KUrl &url)
Returns true if there is a slave on hold for url.
Definition: scheduler.cpp:835
KIO::Scheduler::removeSlaveOnHold
static void removeSlaveOnHold()
Removes any slave that might have been put on hold.
Definition: scheduler.cpp:825
KIO::Scheduler::doJob
static void doJob(SimpleJob *job)
Register job with the scheduler.
Definition: scheduler.cpp:793
KIO::Scheduler::jobFinished
static void jobFinished(KIO::SimpleJob *job, KIO::Slave *slave)
Called when a job is done.
Definition: scheduler.cpp:815
KIO::Scheduler::cancelJob
static void cancelJob(SimpleJob *job)
Stop the execution of a job.
Definition: scheduler.cpp:810
KIO::Scheduler::updateInternalMetaData
static void updateInternalMetaData(SimpleJob *job)
Updates the internal metadata from job.
Definition: scheduler.cpp:840
KIO::SimpleJobPrivate
Definition: job_p.h:82
KIO::SimpleJobPrivate::_k_slotSlaveInfoMessage
void _k_slotSlaveInfoMessage(const QString &s)
Called on a slave's info message.
Definition: job.cpp:516
KIO::SimpleJobPrivate::m_slave
Slave * m_slave
Definition: job_p.h:104
KIO::SimpleJobPrivate::get
static SimpleJobPrivate * get(KIO::SimpleJob *job)
Definition: job_p.h:199
KIO::SimpleJobPrivate::requestMessageBox
int requestMessageBox(int type, const QString &text, const QString &caption, const QString &buttonYes, const QString &buttonNo, const QString &iconYes=QString(), const QString &iconNo=QString(), const QString &dontAskAgainName=QString(), const KIO::MetaData &sslMetaData=KIO::MetaData())
Request the ui delegate to show a message box.
Definition: job.cpp:562
KIO::SimpleJobPrivate::restartAfterRedirection
void restartAfterRedirection(KUrl *redirectionUrl)
Called by subclasses to restart the job after a redirection was signalled.
Definition: job.cpp:548
KIO::SimpleJobPrivate::simpleJobInit
void simpleJobInit()
Definition: job.cpp:298
KIO::SimpleJobPrivate::m_url
KUrl m_url
Definition: job_p.h:106
KIO::SimpleJobPrivate::m_command
int m_command
Definition: job_p.h:108
KIO::SimpleJobPrivate::slotConnected
void slotConnected()
Called on a slave's connected signal.
Definition: job.cpp:521
KIO::SimpleJobPrivate::slotSpeed
void slotSpeed(unsigned long speed)
Forward signal from the slave.
Definition: job.cpp:542
KIO::SimpleJobPrivate::slaveDone
void slaveDone()
Definition: job.cpp:453
KIO::SimpleJobPrivate::m_packedArgs
QByteArray m_packedArgs
Definition: job_p.h:105
KIO::SimpleJobPrivate::slotProcessedSize
void slotProcessedSize(KIO::filesize_t data_size)
Forward signal from the slave.
Definition: job.cpp:535
KIO::SimpleJobPrivate::newJobNoUi
static SimpleJob * newJobNoUi(const KUrl &url, int command, const QByteArray &packedArgs)
Definition: job_p.h:201
KIO::SimpleJobPrivate::start
virtual void start(KIO::Slave *slave)
Definition: job.cpp:385
KIO::SimpleJobPrivate::newJob
static SimpleJob * newJob(const KUrl &url, int command, const QByteArray &packedArgs, JobFlags flags=HideProgressInfo)
Definition: job_p.h:206
KIO::SimpleJobPrivate::m_subUrl
KUrl m_subUrl
Definition: job_p.h:107
KIO::SimpleJobPrivate::m_schedSerial
int m_schedSerial
Definition: job_p.h:128
KIO::SimpleJobPrivate::slotTotalSize
void slotTotalSize(KIO::filesize_t data_size)
Forward signal from the slave Can also be called by the parent job, when it knows the size.
Definition: job.cpp:526
KIO::SimpleJob
A simple job (one url and one command).
Definition: jobclasses.h:322
KIO::SimpleJob::slotError
void slotError(int, const QString &)
Definition: job.cpp:500
KIO::SimpleJob::removeOnHold
static void removeOnHold()
Discard suspended slave.
Definition: job.cpp:359
KIO::SimpleJob::~SimpleJob
~SimpleJob()
Definition: job.cpp:375
KIO::SimpleJob::setRedirectionHandlingEnabled
void setRedirectionHandlingEnabled(bool handle)
Set handle to false to prevent the internal handling of redirections.
Definition: job.cpp:369
KIO::SimpleJob::putOnHold
virtual void putOnHold()
Abort job.
Definition: job.cpp:346
KIO::SimpleJob::slotWarning
virtual void slotWarning(const QString &)
Definition: job.cpp:511
KIO::SimpleJob::storeSSLSessionFromJob
void storeSSLSessionFromJob(const KUrl &m_redirectionURL)
Definition: job.cpp:598
KIO::SimpleJob::doKill
virtual bool doKill()
Abort job.
Definition: job.cpp:313
KIO::SimpleJob::slotFinished
virtual void slotFinished()
Called when the slave marks the job as finished.
Definition: job.cpp:468
KIO::SimpleJob::SimpleJob
SimpleJob(SimpleJobPrivate &dd)
Creates a new simple job.
Definition: job.cpp:292
KIO::SimpleJob::isRedirectionHandlingEnabled
bool isRedirectionHandlingEnabled() const
Returns true when redirections are handled internally, the default.
Definition: job.cpp:364
KIO::SimpleJob::slotMetaData
virtual void slotMetaData(const KIO::MetaData &_metaData)
MetaData from the slave is received.
Definition: job.cpp:578
KIO::SimpleJob::url
const KUrl & url() const
Returns the SimpleJob's URL.
Definition: job.cpp:341
KIO::SimpleJob::doSuspend
virtual bool doSuspend()
Suspend this job.
Definition: job.cpp:325
KIO::SimpleJob::doResume
virtual bool doResume()
Resume this job.
Definition: job.cpp:333
KIO::SlaveInterface::sendResumeAnswer
void sendResumeAnswer(bool resume)
Definition: slaveinterface.cpp:374
KIO::SlaveInterface::setOffset
void setOffset(KIO::filesize_t offset)
Definition: slaveinterface.cpp:347
KIO::Slave
Definition: slave.h:49
KIO::Slave::suspended
virtual bool suspended()
Tells whether the kioslave is suspended.
Definition: slave.cpp:326
KIO::Slave::send
virtual void send(int cmd, const QByteArray &arr=QByteArray())
Sends the given command to the kioslave.
Definition: slave.cpp:332
KIO::Slave::setJob
void setJob(KIO::SimpleJob *job)
Definition: slave.cpp:273
KIO::Slave::suspend
virtual void suspend()
Suspends the operation of the attached kioslave.
Definition: slave.cpp:314
KIO::Slave::resume
virtual void resume()
Resumes the operation of the attached kioslave.
Definition: slave.cpp:320
KIO::SpecialJob
A class that sends a special command to an ioslave.
Definition: jobclasses.h:1023
KIO::SpecialJob::arguments
QByteArray arguments() const
Returns the QByteArray data that will be sent (or has been sent) to the ioslave.
Definition: job.cpp:3036
KIO::SpecialJob::setArguments
void setArguments(const QByteArray &data)
Sets the QByteArray that is passed to SlaveBase::special() on the ioslave.
Definition: job.cpp:3030
KIO::SpecialJob::SpecialJob
SpecialJob(const KUrl &url, const QByteArray &data=QByteArray())
Creates a KIO::SpecialJob.
Definition: job.cpp:3021
KIO::SpecialJob::~SpecialJob
~SpecialJob()
Definition: job.cpp:3026
KIO::StatJob
A KIO job that retrieves information about a file or directory.
Definition: jobclasses.h:440
KIO::StatJob::permanentRedirection
void permanentRedirection(KIO::Job *job, const KUrl &fromUrl, const KUrl &toUrl)
Signals a permanent redirection.
KIO::StatJob::setDetails
void setDetails(short int details)
Selects the level of details we want.
Definition: job.cpp:834
KIO::StatJob::mostLocalUrl
KUrl mostLocalUrl() const
most local URL Call this in the slot connected to result, and only after making sure no error happene...
Definition: job.cpp:844
KIO::StatJob::StatSide
StatSide
Definition: jobclasses.h:445
KIO::StatJob::DestinationSide
@ DestinationSide
Definition: jobclasses.h:447
KIO::StatJob::SourceSide
@ SourceSide
Definition: jobclasses.h:446
KIO::StatJob::statResult
const UDSEntry & statResult() const
Result of the stat operation.
Definition: job.cpp:839
KIO::StatJob::setSide
void setSide(StatSide side)
A stat() can have two meanings.
Definition: job.cpp:829
KIO::StatJob::~StatJob
~StatJob()
Definition: job.cpp:818
KIO::StatJob::StatJob
StatJob(StatJobPrivate &dd)
Definition: job.cpp:813
KIO::StatJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:892
KIO::StatJob::slotMetaData
virtual void slotMetaData(const KIO::MetaData &_metaData)
Definition: job.cpp:917
KIO::StoredTransferJob
StoredTransferJob is a TransferJob (for downloading or uploading data) that also stores a QByteArray ...
Definition: jobclasses.h:743
KIO::StoredTransferJob::data
QByteArray data() const
Get hold of the downloaded data.
Definition: job.cpp:1730
KIO::StoredTransferJob::~StoredTransferJob
~StoredTransferJob()
Definition: job.cpp:1717
KIO::StoredTransferJob::setData
void setData(const QByteArray &arr)
Set data to be uploaded.
Definition: job.cpp:1721
KIO::StoredTransferJob::StoredTransferJob
StoredTransferJob(StoredTransferJobPrivate &dd)
Definition: job.cpp:1708
KIO::TransferJobPrivate
Definition: job_p.h:260
KIO::TransferJobPrivate::slotSubUrlData
void slotSubUrlData(KIO::Job *, const QByteArray &)
Definition: job.cpp:1295
KIO::TransferJobPrivate::slotErrorPage
void slotErrorPage()
Definition: job.cpp:1310
KIO::TransferJobPrivate::internalResume
void internalResume()
Flow control.
Definition: job.cpp:1220
KIO::TransferJobPrivate::staticData
QByteArray staticData
Definition: job_p.h:279
KIO::TransferJobPrivate::m_internalSuspended
bool m_internalSuspended
Definition: job_p.h:277
KIO::TransferJobPrivate::slotCanResume
void slotCanResume(KIO::filesize_t offset)
Definition: job.cpp:1315
KIO::TransferJobPrivate::newJob
static TransferJob * newJob(const KUrl &url, int command, const QByteArray &packedArgs, const QByteArray &_staticData, JobFlags flags)
Definition: job_p.h:317
KIO::TransferJobPrivate::slotDataReqFromDevice
virtual void slotDataReqFromDevice()
Definition: job.cpp:1321
KIO::TransferJobPrivate::m_subJob
TransferJob * m_subJob
Definition: job_p.h:284
KIO::TransferJobPrivate::slotPostRedirection
void slotPostRedirection()
Definition: job.cpp:1691
KIO::TransferJobPrivate::internalSuspend
void internalSuspend()
Flow control.
Definition: job.cpp:1213
KIO::TransferJobPrivate::start
virtual void start(KIO::Slave *slave)
Definition: job.cpp:1242
KIO::TransferJobPrivate::m_outgoingDataSource
QPointer< QIODevice > m_outgoingDataSource
Definition: job_p.h:285
KIO::TransferJobPrivate::slotNeedSubUrlData
void slotNeedSubUrlData()
Definition: job.cpp:1284
KIO::TransferJobPrivate::m_mimetype
QString m_mimetype
Definition: job_p.h:282
KIO::TransferJobPrivate::m_errorPage
bool m_errorPage
Definition: job_p.h:278
KIO::TransferJob
The transfer job pumps data into and/or out of a Slave.
Definition: jobclasses.h:555
KIO::TransferJob::dataReq
void dataReq(KIO::Job *job, QByteArray &data)
Request for data.
KIO::TransferJob::doResume
virtual bool doResume()
Reimplemented for internal reasons.
Definition: job.cpp:1227
KIO::TransferJob::TransferJob
TransferJob(TransferJobPrivate &dd)
Definition: job.cpp:974
KIO::TransferJob::sendAsyncData
void sendAsyncData(const QByteArray &data)
Provide data to the job when async data is enabled.
Definition: job.cpp:1122
KIO::TransferJob::redirection
void redirection(KIO::Job *job, const KUrl &url)
Signals a redirection.
KIO::TransferJob::slotMimetype
virtual void slotMimetype(const QString &mimetype)
Definition: job.cpp:1200
KIO::TransferJob::slotMetaData
virtual void slotMetaData(const KIO::MetaData &_metaData)
Definition: job.cpp:1303
KIO::TransferJob::~TransferJob
~TransferJob()
Definition: job.cpp:983
KIO::TransferJob::mimetype
QString mimetype() const
Call this in the slot connected to result, and only after making sure no error happened.
Definition: job.cpp:1156
KIO::TransferJob::slotRedirection
virtual void slotRedirection(const KUrl &url)
Definition: job.cpp:1009
KIO::TransferJob::slotDataReq
virtual void slotDataReq()
Definition: job.cpp:1162
KIO::TransferJob::data
void data(KIO::Job *job, const QByteArray &data)
Data from the slave has arrived.
KIO::TransferJob::isErrorPage
bool isErrorPage() const
Checks whether we got an error page.
Definition: job.cpp:1237
KIO::TransferJob::reportDataSent
bool reportDataSent() const
Returns whether the job reports the amount of data that has been sent (true), or whether the job repo...
Definition: job.cpp:1150
KIO::TransferJob::setModificationTime
void setModificationTime(const QDateTime &mtime)
Sets the modification time of the file to be created (by KIO::put) Note that some kioslaves might ign...
Definition: job.cpp:1364
KIO::TransferJob::slotData
virtual void slotData(const QByteArray &data)
Definition: job.cpp:988
KIO::TransferJob::slotFinished
virtual void slotFinished()
Definition: job.cpp:1043
KIO::TransferJob::setTotalSize
void setTotalSize(KIO::filesize_t bytes)
Set the total size of data that we are going to send in a put job.
Definition: job.cpp:1003
KIO::TransferJob::permanentRedirection
void permanentRedirection(KIO::Job *job, const KUrl &fromUrl, const KUrl &toUrl)
Signals a permanent redirection.
KIO::TransferJob::setReportDataSent
void setReportDataSent(bool enabled)
When enabled, the job reports the amount of data that has been sent, instead of the amount of data th...
Definition: job.cpp:1139
KIO::TransferJob::setAsyncDataEnabled
void setAsyncDataEnabled(bool enabled)
Enable the async data mode.
Definition: job.cpp:1113
KIO::UDSEntry
Universal Directory Service.
Definition: udsentry.h:59
KIO::UDSEntry::stringValue
QString stringValue(uint field) const
Definition: udsentry.cpp:73
KIO::UDSEntry::isLink
bool isLink() const
Definition: udsentry.cpp:89
KIO::UDSEntry::UDS_URL
@ UDS_URL
An alternative URL (If different from the caption).
Definition: udsentry.h:190
KIO::UDSEntry::UDS_LOCAL_PATH
@ UDS_LOCAL_PATH
A local file path if the ioslave display files sitting on the local filesystem (but in another hierar...
Definition: udsentry.h:166
KIO::UDSEntry::UDS_DISPLAY_NAME
@ UDS_DISPLAY_NAME
If set, contains the label to display instead of the 'real name' in UDS_NAME.
Definition: udsentry.h:211
KIO::UDSEntry::UDS_NAME
@ UDS_NAME
Filename - as displayed in directory listings etc.
Definition: udsentry.h:163
KIO::UDSEntry::contains
bool contains(uint field) const
check existence of a field
Definition: udsentry.cpp:118
KIO::UDSEntry::insert
void insert(uint field, const QString &value)
insert field with numeric value
Definition: udsentry.cpp:94
KIO::UDSEntry::isDir
bool isDir() const
Definition: udsentry.cpp:84
KJobPrivate::suspended
bool suspended
KJobPrivate::error
int error
KJobTrackerInterface::registerJob
virtual void registerJob(KJob *job)
KJob
KJob::setErrorText
void setErrorText(const QString &errorText)
KJob::Bytes
Bytes
KJob::resume
bool resume()
KJob::suspend
bool suspend()
KJob::setTotalAmount
void setTotalAmount(Unit unit, qulonglong amount)
KJob::emitResult
void emitResult()
KJob::Quietly
Quietly
KJob::error
int error() const
KJob::description
void description(KJob *job, const QString &title, const QPair< QString, QString > &field1=qMakePair(QString(), QString()), const QPair< QString, QString > &field2=qMakePair(QString(), QString()))
KJob::kill
bool kill(KillVerbosity verbosity=Quietly)
KJob::setError
void setError(int errorCode)
KJob::uiDelegate
KJobUiDelegate * uiDelegate() const
KJob::warning
void warning(KJob *job, const QString &plain, const QString &rich=QString())
KJob::processedAmount
void processedAmount(KJob *job, KJob::Unit unit, qulonglong amount)
KJob::setCapabilities
void setCapabilities(Capabilities capabilities)
KJob::Suspendable
Suspendable
KJob::Killable
Killable
KJob::errorText
QString errorText() const
KJob::setProcessedAmount
void setProcessedAmount(Unit unit, qulonglong amount)
KJob::setUiDelegate
void setUiDelegate(KJobUiDelegate *delegate)
KJob::speed
void speed(KJob *job, unsigned long speed)
KMimeType::findByUrl
static Ptr findByUrl(const KUrl &url, mode_t mode=0, bool is_local_file=false, bool fast_mode=false, int *accuracy=0)
KProtocolManager::canCopyFromFile
static bool canCopyFromFile(const KUrl &url)
Returns whether the protocol can copy files/objects directly from the filesystem itself.
Definition: kprotocolmanager.cpp:1114
KProtocolManager::canRenameToFile
static bool canRenameToFile(const KUrl &url)
Returns whether the protocol can rename (i.e.
Definition: kprotocolmanager.cpp:1143
KProtocolManager::cacheDir
static QString cacheDir()
The directory which contains the cache files.
Definition: kprotocolmanager.cpp:339
KProtocolManager::canCopyToFile
static bool canCopyToFile(const KUrl &url)
Returns whether the protocol can copy files/objects directly to the filesystem itself.
Definition: kprotocolmanager.cpp:1124
KProtocolManager::canRenameFromFile
static bool canRenameFromFile(const KUrl &url)
Returns whether the protocol can rename (i.e.
Definition: kprotocolmanager.cpp:1133
KProtocolManager::autoResume
static bool autoResume()
Returns true if partial downloads should be automatically resumed.
Definition: kprotocolmanager.cpp:969
KSharedPtr< KMimeType >
KUrl
KUrl::pathOrUrl
QString pathOrUrl() const
KUrl::url
QString url(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::path
QString path(AdjustPathOption trailing=LeaveTrailingSlash) const
KUrl::directory
QString directory(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUrl::isLocalFile
bool isLocalFile() const
KUrl::pass
QString pass() const
KUrl::user
QString user() const
KUrl::setPath
void setPath(const QString &path)
KUrl::fileName
QString fileName(const DirectoryOptions &options=IgnoreTrailingSlash) const
KUrl::protocol
QString protocol() const
KUrl::hasSubUrl
bool hasSubUrl() const
KUrl::addPath
void addPath(const QString &txt)
OrgKdeKDirNotifyInterface::emitFileRenamed
static void emitFileRenamed(const QString &src, const QString &dst)
Definition: kdirnotify.cpp:37
OrgKdeKDirNotifyInterface::emitFilesAdded
static void emitFilesAdded(const QString &directory)
Definition: kdirnotify.cpp:47
OrgKdeKDirNotifyInterface::emitFileMoved
static void emitFileMoved(const QString &src, const QString &dst)
Definition: kdirnotify.cpp:42
QIODevice
QList< int >
QMap
QWidget
clipboardupdater_p.h
filejob.h
kDebug
#define kDebug
kWarning
#define kWarning
CACHE_REVISION
#define CACHE_REVISION
Definition: http_slave_defaults.h:31
MAX_READ_BUF_SIZE
#define MAX_READ_BUF_SIZE
Definition: job.cpp:66
jobSlave
static Slave * jobSlave(SimpleJob *job)
Definition: job.cpp:68
precheckHttpPost
static KIO::PostErrorJob * precheckHttpPost(const KUrl &url, QIODevice *ioDevice, JobFlags flags)
Definition: job.cpp:1557
isUrlPortBad
static int isUrlPortBad(const KUrl &url)
Definition: job.cpp:1450
job.h
job_p.h
KIO_ARGS
#define KIO_ARGS
Definition: job_p.h:34
jobuidelegate.h
kauthorized.h
kconfig.h
operator==
bool operator==(const KEntry &k1, const KEntry &k2)
kdebug.h
kdirnotify.h
kdirwatch.h
klocale.h
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
kmimetype.h
kprotocolinfo.h
kprotocolmanager.h
prefix
QString prefix()
ktemporaryfile.h
KAuthorized::authorizeUrlAction
bool authorizeUrlAction(const QString &action, const KUrl &baseUrl, const KUrl &destUrl)
KDE::fopen
FILE * fopen(const QString &pathname, const char *mode)
caption
QString caption()
KIO
A namespace for KIO globals.
Definition: kbookmarkmenu.h:55
KIO::mostLocalUrl
StatJob * mostLocalUrl(const KUrl &url, JobFlags flags=DefaultFlags)
Tries to map a local URL for the given URL, using a KIO job.
Definition: job.cpp:930
KIO::chmod
ChmodJob * chmod(const KFileItemList &lstItems, int permissions, int mask, const QString &newOwner, const QString &newGroup, bool recursive, JobFlags flags=DefaultFlags)
Creates a job that changes permissions/ownership on several files or directories, optionally recursiv...
Definition: chmodjob.cpp:268
KIO::http_post
TransferJob * http_post(const KUrl &url, const QByteArray &postData, JobFlags flags=DefaultFlags)
HTTP POST (for form data).
Definition: job.cpp:1597
KIO::storedPut
StoredTransferJob * storedPut(const QByteArray &arr, const KUrl &url, int permissions, JobFlags flags=DefaultFlags)
Put (a.k.a.
Definition: job.cpp:1776
KIO::move
CopyJob * move(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Moves a file or directory src to the given destination dest.
Definition: copyjob.cpp:2186
KIO::mount
SimpleJob * mount(bool ro, const QByteArray &fstype, const QString &dev, const QString &point, JobFlags flags=DefaultFlags)
Mount filesystem.
Definition: job.cpp:751
KIO::chown
SimpleJob * chown(const KUrl &url, const QString &owner, const QString &group)
Changes ownership and group of a file or directory.
Definition: job.cpp:718
KIO::setModificationTime
SimpleJob * setModificationTime(const KUrl &url, const QDateTime &mtime)
Changes the modification time on a file or directory.
Definition: job.cpp:724
KIO::rmdir
SimpleJob * rmdir(const KUrl &url)
Removes a single directory.
Definition: job.cpp:704
KIO::listRecursive
ListJob * listRecursive(const KUrl &url, JobFlags flags=DefaultFlags, bool includeHidden=true)
The same as the previous method, but recurses subdirectories.
Definition: job.cpp:2740
KIO::CMD_SUBURL
@ CMD_SUBURL
Definition: global.h:174
KIO::CMD_LISTDIR
@ CMD_LISTDIR
Definition: global.h:163
KIO::CMD_COPY
@ CMD_COPY
Definition: global.h:166
KIO::CMD_DEL
@ CMD_DEL
Definition: global.h:167
KIO::CMD_MULTI_GET
@ CMD_MULTI_GET
Definition: global.h:178
KIO::CMD_CHMOD
@ CMD_CHMOD
Definition: global.h:168
KIO::CMD_META_DATA
@ CMD_META_DATA
Definition: global.h:172
KIO::CMD_PUT
@ CMD_PUT
Definition: global.h:160
KIO::CMD_OPEN
@ CMD_OPEN
Definition: global.h:180
KIO::CMD_SYMLINK
@ CMD_SYMLINK
Definition: global.h:173
KIO::CMD_MKDIR
@ CMD_MKDIR
Definition: global.h:164
KIO::CMD_CHOWN
@ CMD_CHOWN
Definition: global.h:181
KIO::CMD_GET
@ CMD_GET
Definition: global.h:159
KIO::CMD_STAT
@ CMD_STAT
Definition: global.h:161
KIO::CMD_SPECIAL
@ CMD_SPECIAL
Definition: global.h:169
KIO::CMD_CLOSE
@ CMD_CLOSE
Definition: global.h:185
KIO::CMD_MIMETYPE
@ CMD_MIMETYPE
Definition: global.h:162
KIO::CMD_RENAME
@ CMD_RENAME
Definition: global.h:165
KIO::CMD_SETMODIFICATIONTIME
@ CMD_SETMODIFICATIONTIME
Definition: global.h:170
KIO::storedGet
StoredTransferJob * storedGet(const KUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
Get (a.k.a.
Definition: job.cpp:1766
KIO::stat
StatJob * stat(const KUrl &url, JobFlags flags=DefaultFlags)
Find all details for one file or directory.
Definition: job.cpp:924
KIO::put
TransferJob * put(const KUrl &url, int permissions, JobFlags flags=DefaultFlags)
Put (a.k.a.
Definition: job.cpp:1700
KIO::listDir
ListJob * listDir(const KUrl &url, JobFlags flags=DefaultFlags, bool includeHidden=true)
List the contents of url, which is assumed to be a directory.
Definition: job.cpp:2735
KIO::file_copy
FileCopyJob * file_copy(const KUrl &src, const KUrl &dest, int permissions=-1, JobFlags flags=DefaultFlags)
Copy a single file.
Definition: job.cpp:2473
KIO::get
TransferJob * get(const KUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
Get (a.k.a.
Definition: job.cpp:1369
KIO::file_move
FileCopyJob * file_move(const KUrl &src, const KUrl &dest, int permissions=-1, JobFlags flags=DefaultFlags)
Move a single file.
Definition: job.cpp:2479
KIO::MSG_DATA
@ MSG_DATA
Definition: slaveinterface.h:68
KIO::special
SimpleJob * special(const KUrl &url, const QByteArray &data, JobFlags flags=DefaultFlags)
Execute any command that is specific to one slave (protocol).
Definition: job.cpp:745
KIO::mkdir
SimpleJob * mkdir(const KUrl &url, int permissions=-1)
Creates a single directory.
Definition: job.cpp:697
KIO::LoadType
LoadType
Definition: job.h:29
KIO::NoReload
@ NoReload
Definition: job.h:29
KIO::Reload
@ Reload
Definition: job.h:29
KIO::RenameDialog_Result
RenameDialog_Result
The result of open_RenameDialog().
Definition: renamedialog.h:61
KIO::R_OVERWRITE
@ R_OVERWRITE
Definition: renamedialog.h:61
KIO::R_RESUME
@ R_RESUME
Definition: renamedialog.h:61
KIO::R_CANCEL
@ R_CANCEL
Definition: renamedialog.h:61
KIO::mimetype
MimetypeJob * mimetype(const KUrl &url, JobFlags flags=DefaultFlags)
Find mimetype for one file or directory.
Definition: job.cpp:1856
KIO::unmount
SimpleJob * unmount(const QString &point, JobFlags flags=DefaultFlags)
Unmount filesystem.
Definition: job.cpp:762
KIO::CC_Verify
@ CC_Verify
Validate cached entry with remote site if expired.
Definition: global.h:334
KIO::RenameDialog_Mode
RenameDialog_Mode
M_OVERWRITE: We have an existing dest, show details about it and offer to overwrite it.
Definition: renamedialog.h:56
KIO::M_RESUME
@ M_RESUME
Definition: renamedialog.h:56
KIO::M_NORENAME
@ M_NORENAME
Definition: renamedialog.h:56
KIO::M_OVERWRITE
@ M_OVERWRITE
Definition: renamedialog.h:56
KIO::storedHttpPost
StoredTransferJob * storedHttpPost(const QByteArray &arr, const KUrl &url, JobFlags flags=DefaultFlags)
HTTP POST (a.k.a.
Definition: job.cpp:1646
KIO::rename
SimpleJob * rename(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
Rename a file or directory.
Definition: job.cpp:731
KIO::file_delete
SimpleJob * file_delete(const KUrl &src, JobFlags flags=DefaultFlags)
Delete a single file.
Definition: job.cpp:2487
KIO::Resume
@ Resume
When set, automatically append to the destination file if it exists already.
Definition: jobclasses.h:60
KIO::HideProgressInfo
@ HideProgressInfo
Hide progress information dialog, i.e.
Definition: jobclasses.h:51
KIO::Overwrite
@ Overwrite
When set, automatically overwrite the destination if it exists already.
Definition: jobclasses.h:67
KIO::multi_get
MultiGetJob * multi_get(long id, const KUrl &url, const MetaData &metaData)
Creates a new multiple get job.
Definition: job.cpp:3005
KIO::filesize_t
qulonglong filesize_t
64-bit file size
Definition: global.h:57
KIO::ERR_INTERNAL
@ ERR_INTERNAL
Definition: global.h:198
KIO::ERR_POST_DENIED
@ ERR_POST_DENIED
Definition: global.h:267
KIO::ERR_ACCESS_DENIED
@ ERR_ACCESS_DENIED
Definition: global.h:209
KIO::ERR_MALFORMED_URL
@ ERR_MALFORMED_URL
Definition: global.h:199
KIO::ERR_CYCLIC_LINK
@ ERR_CYCLIC_LINK
Definition: global.h:213
KIO::ERR_IS_FILE
@ ERR_IS_FILE
Definition: global.h:204
KIO::ERR_IS_DIRECTORY
@ ERR_IS_DIRECTORY
Definition: global.h:203
KIO::ERR_UNSUPPORTED_ACTION
@ ERR_UNSUPPORTED_ACTION
Definition: global.h:202
KIO::ERR_USER_CANCELED
@ ERR_USER_CANCELED
Definition: global.h:214
KIO::ERR_UNKNOWN_HOST
@ ERR_UNKNOWN_HOST
Definition: global.h:208
KIO::http_delete
TransferJob * http_delete(const KUrl &url, JobFlags flags=DefaultFlags)
HTTP DELETE.
Definition: job.cpp:1637
KIO::getJobTracker
KJobTrackerInterface * getJobTracker()
Definition: global.cpp:1246
KIO::symlink
SimpleJob * symlink(const QString &target, const KUrl &dest, JobFlags flags=DefaultFlags)
Create or move a symlink.
Definition: job.cpp:738
KIO::number
QString number(KIO::filesize_t size)
Converts a size to a string representation Not unlike QString::number(...)
Definition: global.cpp:63
KIO::http_update_cache
SimpleJob * http_update_cache(const KUrl &url, bool no_cache, time_t expireDate)
HTTP cache update.
Definition: job.cpp:962
group
group
KRecentDirs::dir
QString dir(const QString &fileClass)
Returns the most recently used directory accociated with this file-class.
Definition: krecentdirs.cpp:68
KRecentDirs::list
QStringList list(const QString &fileClass)
Returns a list of directories associated with this file-class.
Definition: krecentdirs.cpp:60
ok
KGuiItem ok()
end
const KShortcut & end()
reload
const KShortcut & reload()
scheduler.h
slave.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal