00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "job.h"
00023 #include "job_p.h"
00024
00025 #include <config.h>
00026
00027 #include <sys/types.h>
00028 #include <sys/wait.h>
00029 #include <sys/stat.h>
00030
00031 #include <assert.h>
00032
00033 #include <signal.h>
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <time.h>
00037 #include <unistd.h>
00038 extern "C" {
00039 #include <pwd.h>
00040 #include <grp.h>
00041 }
00042 #include <QtCore/QTimer>
00043 #include <QtCore/QFile>
00044
00045 #include <kapplication.h>
00046 #include <kauthorized.h>
00047 #include <kglobal.h>
00048 #include <klocale.h>
00049 #include <kconfig.h>
00050 #include <kdebug.h>
00051 #include <kde_file.h>
00052
00053 #include <errno.h>
00054
00055 #include "jobuidelegate.h"
00056 #include "kmimetype.h"
00057 #include "slave.h"
00058 #include "scheduler.h"
00059 #include "kdirwatch.h"
00060 #include "kprotocolinfo.h"
00061 #include "kprotocolmanager.h"
00062 #include "filejob.h"
00063
00064 #include "kssl/ksslcsessioncache.h"
00065
00066 #include <kdirnotify.h>
00067 #include <ktemporaryfile.h>
00068
00069 #ifdef Q_OS_UNIX
00070 #include <utime.h>
00071 #endif
00072
00073 using namespace KIO;
00074
00075 static inline Slave *jobSlave(SimpleJob *job)
00076 {
00077 return SimpleJobPrivate::get(job)->m_slave;
00078 }
00079
00080
00081 #define REPORT_TIMEOUT 200
00082
00083 #define KIO_ARGS QByteArray packedArgs; QDataStream stream( &packedArgs, QIODevice::WriteOnly ); stream
00084
00085 Job::Job() : KCompositeJob(*new JobPrivate, 0)
00086 {
00087 setCapabilities( KJob::Killable | KJob::Suspendable );
00088 }
00089
00090 Job::Job(JobPrivate &dd) : KCompositeJob(dd, 0)
00091 {
00092 setCapabilities( KJob::Killable | KJob::Suspendable );
00093 }
00094
00095 Job::~Job()
00096 {
00097 }
00098
00099 JobUiDelegate *Job::ui() const
00100 {
00101 return static_cast<JobUiDelegate*>( uiDelegate() );
00102 }
00103
00104 bool Job::addSubjob(KJob *jobBase)
00105 {
00106
00107
00108 bool ok = KCompositeJob::addSubjob( jobBase );
00109 KIO::Job *job = dynamic_cast<KIO::Job*>( jobBase );
00110 if (ok && job) {
00111
00112 Q_D(Job);
00113 job->mergeMetaData(d->m_outgoingMetaData);
00114
00115
00116 connect( job, SIGNAL(speed( KJob*, unsigned long )),
00117 SLOT(slotSpeed(KJob*, unsigned long)) );
00118
00119 if (ui() && job->ui()) {
00120 job->ui()->setWindow( ui()->window() );
00121 job->ui()->updateUserTimestamp( ui()->userTimestamp() );
00122 }
00123 }
00124 return ok;
00125 }
00126
00127 bool Job::removeSubjob( KJob *jobBase )
00128 {
00129
00130 return KCompositeJob::removeSubjob( jobBase );
00131 }
00132
00133 void JobPrivate::emitMoving(KIO::Job * job, const KUrl &src, const KUrl &dest)
00134 {
00135 emit job->description(job, i18nc("@title job","Moving"),
00136 qMakePair(i18n("Source"), src.prettyUrl()),
00137 qMakePair(i18n("Destination"), dest.prettyUrl()));
00138 }
00139
00140 void JobPrivate::emitCopying(KIO::Job * job, const KUrl &src, const KUrl &dest)
00141 {
00142 emit job->description(job, i18nc("@title job","Copying"),
00143 qMakePair(i18n("Source"), src.prettyUrl()),
00144 qMakePair(i18n("Destination"), dest.prettyUrl()));
00145 }
00146
00147 void JobPrivate::emitCreatingDir(KIO::Job * job, const KUrl &dir)
00148 {
00149 emit job->description(job, i18nc("@title job","Creating directory"),
00150 qMakePair(i18n("Directory"), dir.prettyUrl()));
00151 }
00152
00153 void JobPrivate::emitDeleting(KIO::Job *job, const KUrl &url)
00154 {
00155 emit job->description(job, i18nc("@title job","Deleting"),
00156 qMakePair(i18n("File"), url.prettyUrl()));
00157 }
00158
00159 void JobPrivate::emitStating(KIO::Job *job, const KUrl &url)
00160 {
00161 emit job->description(job, i18nc("@title job","Stating"),
00162 qMakePair(i18n("File"), url.prettyUrl()));
00163 }
00164
00165 void JobPrivate::emitTransferring(KIO::Job *job, const KUrl &url)
00166 {
00167 emit job->description(job, i18nc("@title job","Transferring"),
00168 qMakePair(i18n("Source"), url.prettyUrl()));
00169 }
00170
00171 void JobPrivate::emitMounting(KIO::Job * job, const QString &dev, const QString &point)
00172 {
00173 emit job->description(job, i18nc("@title job","Mounting"),
00174 qMakePair(i18n("Device"), dev),
00175 qMakePair(i18n("Mountpoint"), point));
00176 }
00177
00178 void JobPrivate::emitUnmounting(KIO::Job * job, const QString &point)
00179 {
00180 emit job->description(job, i18nc("@title job","Unmounting"),
00181 qMakePair(i18n("Mountpoint"), point));
00182 }
00183
00184 bool Job::doKill()
00185 {
00186
00187 Q_FOREACH( KJob* it, subjobs()) {
00188 it->kill( KJob::Quietly );
00189 }
00190 clearSubjobs();
00191
00192 return true;
00193 }
00194
00195 bool Job::doSuspend()
00196 {
00197 Q_FOREACH(KJob* it, subjobs()) {
00198 if (!it->suspend())
00199 return false;
00200 }
00201
00202 return true;
00203 }
00204
00205 bool Job::doResume()
00206 {
00207 Q_FOREACH ( KJob* it, subjobs() )
00208 {
00209 if (!it->resume())
00210 return false;
00211 }
00212
00213 return true;
00214 }
00215
00216 void JobPrivate::slotSpeed( KJob*, unsigned long speed )
00217 {
00218
00219 q_func()->emitSpeed( speed );
00220 }
00221
00222
00223
00224 void Job::showErrorDialog( QWidget *parent )
00225 {
00226 if ( ui() )
00227 {
00228 ui()->setWindow( parent );
00229 ui()->showErrorMessage();
00230 }
00231 else
00232 {
00233 kError() << errorString();
00234 }
00235 }
00236
00237 bool Job::isInteractive() const
00238 {
00239 return uiDelegate() != 0;
00240 }
00241
00242 void Job::setParentJob(Job* job)
00243 {
00244 Q_D(Job);
00245 Q_ASSERT(d->m_parentJob == 0L);
00246 Q_ASSERT(job);
00247 d->m_parentJob = job;
00248 }
00249
00250 Job* Job::parentJob() const
00251 {
00252 return d_func()->m_parentJob;
00253 }
00254
00255 MetaData Job::metaData() const
00256 {
00257 return d_func()->m_incomingMetaData;
00258 }
00259
00260 QString Job::queryMetaData(const QString &key)
00261 {
00262 return d_func()->m_incomingMetaData.value(key, QString());
00263 }
00264
00265 void Job::setMetaData( const KIO::MetaData &_metaData)
00266 {
00267 Q_D(Job);
00268 d->m_outgoingMetaData = _metaData;
00269 }
00270
00271 void Job::addMetaData( const QString &key, const QString &value)
00272 {
00273 d_func()->m_outgoingMetaData.insert(key, value);
00274 }
00275
00276 void Job::addMetaData( const QMap<QString,QString> &values)
00277 {
00278 Q_D(Job);
00279 QMap<QString,QString>::const_iterator it = values.begin();
00280 for(;it != values.end(); ++it)
00281 d->m_outgoingMetaData.insert(it.key(), it.value());
00282 }
00283
00284 void Job::mergeMetaData( const QMap<QString,QString> &values)
00285 {
00286 Q_D(Job);
00287 QMap<QString,QString>::const_iterator it = values.begin();
00288 for(;it != values.end(); ++it)
00289
00290 if ( !d->m_outgoingMetaData.contains( it.key() ) )
00291 d->m_outgoingMetaData.insert( it.key(), it.value() );
00292 }
00293
00294 MetaData Job::outgoingMetaData() const
00295 {
00296 return d_func()->m_outgoingMetaData;
00297 }
00298
00299 SimpleJob::SimpleJob(SimpleJobPrivate &dd)
00300 : Job(dd)
00301 {
00302 d_func()->simpleJobInit();
00303 }
00304
00305 void SimpleJobPrivate::simpleJobInit()
00306 {
00307 Q_Q(SimpleJob);
00308 if (!m_url.isValid())
00309 {
00310 q->setError( ERR_MALFORMED_URL );
00311 q->setErrorText( m_url.url() );
00312 QTimer::singleShot(0, q, SLOT(slotFinished()) );
00313 return;
00314 }
00315
00316 Scheduler::doJob(q);
00317 }
00318
00319
00320 bool SimpleJob::doKill()
00321 {
00322
00323 Q_D(SimpleJob);
00324 Scheduler::cancelJob( this );
00325 d->m_slave = 0;
00326 return Job::doKill();
00327 }
00328
00329 bool SimpleJob::doSuspend()
00330 {
00331 Q_D(SimpleJob);
00332 if ( d->m_slave )
00333 d->m_slave->suspend();
00334 return Job::doSuspend();
00335 }
00336
00337 bool SimpleJob::doResume()
00338 {
00339 Q_D(SimpleJob);
00340 if ( d->m_slave )
00341 d->m_slave->resume();
00342 return Job::doResume();
00343 }
00344
00345 const KUrl& SimpleJob::url() const
00346 {
00347 return d_func()->m_url;
00348 }
00349
00350 void SimpleJob::putOnHold()
00351 {
00352 Q_D(SimpleJob);
00353 Q_ASSERT( d->m_slave );
00354 if ( d->m_slave )
00355 {
00356 Scheduler::putSlaveOnHold(this, d->m_url);
00357 d->m_slave = 0;
00358 }
00359 kill( Quietly );
00360 }
00361
00362 void SimpleJob::removeOnHold()
00363 {
00364 Scheduler::removeSlaveOnHold();
00365 }
00366
00367 SimpleJob::~SimpleJob()
00368 {
00369 Q_D(SimpleJob);
00370 if (d->m_slave)
00371 {
00372 kDebug(7007) << "Killing running job in destructor!" << kBacktrace();
00373 #if 0
00374 d->m_slave->kill();
00375 Scheduler::jobFinished( this, d->m_slave );
00376 #endif
00377 Scheduler::cancelJob( this );
00378 d->m_slave = 0;
00379 }
00380 }
00381
00382 void SimpleJobPrivate::start(Slave *slave)
00383 {
00384 Q_Q(SimpleJob);
00385 m_slave = slave;
00386
00387 q->connect( slave, SIGNAL( error( int , const QString & ) ),
00388 SLOT( slotError( int , const QString & ) ) );
00389
00390 q->connect( slave, SIGNAL( warning( const QString & ) ),
00391 SLOT( slotWarning( const QString & ) ) );
00392
00393 q->connect( slave, SIGNAL( infoMessage( const QString & ) ),
00394 SLOT( _k_slotSlaveInfoMessage( const QString & ) ) );
00395
00396 q->connect( slave, SIGNAL( connected() ),
00397 SLOT( slotConnected() ) );
00398
00399 q->connect( slave, SIGNAL( finished() ),
00400 SLOT( slotFinished() ) );
00401
00402 if ((m_extraFlags & EF_TransferJobDataSent) == 0)
00403 {
00404 q->connect( slave, SIGNAL( totalSize( KIO::filesize_t ) ),
00405 SLOT( slotTotalSize( KIO::filesize_t ) ) );
00406
00407 q->connect( slave, SIGNAL( processedSize( KIO::filesize_t ) ),
00408 SLOT( slotProcessedSize( KIO::filesize_t ) ) );
00409
00410 q->connect( slave, SIGNAL( speed( unsigned long ) ),
00411 SLOT( slotSpeed( unsigned long ) ) );
00412 }
00413 q->connect( slave, SIGNAL(metaData( const KIO::MetaData& ) ),
00414 SLOT( slotMetaData( const KIO::MetaData& ) ) );
00415
00416 if (ui() && ui()->window())
00417 {
00418 m_outgoingMetaData.insert("window-id", QString::number((long)ui()->window()->winId()));
00419 }
00420
00421 if (ui() && ui()->userTimestamp())
00422 {
00423 m_outgoingMetaData.insert("user-timestamp", QString::number(ui()->userTimestamp()));
00424 }
00425
00426 QString sslSession = KSSLCSessionCache::getSessionForUrl(m_url);
00427 if ( !sslSession.isNull() )
00428 {
00429 m_outgoingMetaData.insert("ssl_session_id", sslSession);
00430 }
00431
00432 if (ui() == 0)
00433 {
00434 m_outgoingMetaData.insert("no-auth-prompt", "true");
00435 }
00436
00437 if (!m_outgoingMetaData.isEmpty())
00438 {
00439 KIO_ARGS << m_outgoingMetaData;
00440 slave->send( CMD_META_DATA, packedArgs );
00441 }
00442
00443 if (!m_subUrl.isEmpty())
00444 {
00445 KIO_ARGS << m_subUrl;
00446 slave->send( CMD_SUBURL, packedArgs );
00447 }
00448
00449 slave->send( m_command, m_packedArgs );
00450 }
00451
00452 void SimpleJobPrivate::slaveDone()
00453 {
00454 Q_Q(SimpleJob);
00455 if (!m_slave) return;
00456 if (m_command == CMD_OPEN) m_slave->send(CMD_CLOSE);
00457 q->disconnect(m_slave);
00458 Scheduler::jobFinished( q, m_slave );
00459 m_slave = 0;
00460 }
00461
00462 void SimpleJob::slotFinished( )
00463 {
00464 Q_D(SimpleJob);
00465
00466 d->slaveDone();
00467
00468 if (!hasSubjobs())
00469 {
00470 if ( !error() && (d->m_command == CMD_MKDIR || d->m_command == CMD_RENAME ) )
00471 {
00472 if ( d->m_command == CMD_MKDIR )
00473 {
00474 KUrl urlDir( url() );
00475 urlDir.setPath( urlDir.directory() );
00476 org::kde::KDirNotify::emitFilesAdded( urlDir.url() );
00477 }
00478 else
00479 {
00480 KUrl src, dst;
00481 QDataStream str( d->m_packedArgs );
00482 str >> src >> dst;
00483 if( src.directory() == dst.directory() )
00484 org::kde::KDirNotify::emitFileRenamed( src.url(), dst.url() );
00485
00486 org::kde::KDirNotify::emitFileMoved( src.url(), dst.url() );
00487 }
00488 }
00489 emitResult();
00490 }
00491 }
00492
00493 void SimpleJob::slotError( int err, const QString & errorText )
00494 {
00495 Q_D(SimpleJob);
00496 setError( err );
00497 setErrorText( errorText );
00498 if ((error() == ERR_UNKNOWN_HOST) && d->m_url.host().isEmpty())
00499 setErrorText( QString() );
00500
00501 slotFinished();
00502 }
00503
00504 void SimpleJob::slotWarning( const QString & errorText )
00505 {
00506 emit warning( this, errorText );
00507 }
00508
00509 void SimpleJobPrivate::_k_slotSlaveInfoMessage( const QString & msg )
00510 {
00511 emit q_func()->infoMessage( q_func(), msg );
00512 }
00513
00514 void SimpleJobPrivate::slotConnected()
00515 {
00516 emit q_func()->connected( q_func() );
00517 }
00518
00519 void SimpleJobPrivate::slotTotalSize( KIO::filesize_t size )
00520 {
00521 Q_Q(SimpleJob);
00522 if (size > q->totalAmount(KJob::Bytes))
00523 {
00524 q->setTotalAmount(KJob::Bytes, size);
00525 }
00526 }
00527
00528 void SimpleJobPrivate::slotProcessedSize( KIO::filesize_t size )
00529 {
00530 Q_Q(SimpleJob);
00531
00532 q->setProcessedAmount(KJob::Bytes, size);
00533 }
00534
00535 void SimpleJobPrivate::slotSpeed( unsigned long speed )
00536 {
00537
00538 q_func()->emitSpeed( speed );
00539 }
00540
00541 void SimpleJob::slotMetaData( const KIO::MetaData &_metaData )
00542 {
00543 Q_D(SimpleJob);
00544 d->m_incomingMetaData += _metaData;
00545 }
00546
00547 void SimpleJob::storeSSLSessionFromJob(const KUrl &redirectionURL)
00548 {
00549 Q_D(SimpleJob);
00550 QString sslSession = queryMetaData("ssl_session_id");
00551
00552 if ( !sslSession.isNull() ) {
00553 const KUrl &queryURL = redirectionURL.isEmpty() ? d->m_url : redirectionURL;
00554 KSSLCSessionCache::putSessionForUrl(queryURL, sslSession);
00555 }
00556 }
00557
00559 class KIO::MkdirJobPrivate: public SimpleJobPrivate
00560 {
00561 public:
00562 MkdirJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
00563 : SimpleJobPrivate(url, command, packedArgs)
00564 { }
00565 KUrl m_redirectionURL;
00566 void slotRedirection(const KUrl &url);
00567
00574 virtual void start( Slave *slave );
00575
00576 Q_DECLARE_PUBLIC(MkdirJob)
00577
00578 static inline MkdirJob *newJob(const KUrl& url, int command, const QByteArray &packedArgs)
00579 {
00580 MkdirJob *job = new MkdirJob(*new MkdirJobPrivate(url, command, packedArgs));
00581 job->setUiDelegate(new JobUiDelegate);
00582 return job;
00583 }
00584 };
00585
00586 MkdirJob::MkdirJob(MkdirJobPrivate &dd)
00587 : SimpleJob(dd)
00588 {
00589 }
00590
00591 MkdirJob::~MkdirJob()
00592 {
00593 }
00594
00595 void MkdirJobPrivate::start(Slave *slave)
00596 {
00597 Q_Q(MkdirJob);
00598 q->connect( slave, SIGNAL( redirection(const KUrl &) ),
00599 SLOT( slotRedirection(const KUrl &) ) );
00600
00601 SimpleJobPrivate::start(slave);
00602 }
00603
00604
00605 void MkdirJobPrivate::slotRedirection( const KUrl &url)
00606 {
00607 Q_Q(MkdirJob);
00608 kDebug(7007) << url;
00609 if (!KAuthorized::authorizeUrlAction("redirect", m_url, url))
00610 {
00611 kWarning(7007) << "Redirection from" << m_url << "to" << url << "REJECTED!";
00612 q->setError( ERR_ACCESS_DENIED );
00613 q->setErrorText( url.prettyUrl() );
00614 return;
00615 }
00616 m_redirectionURL = url;
00617 if (m_url.hasUser() && !url.hasUser() && (m_url.host().toLower() == url.host().toLower()))
00618 m_redirectionURL.setUser(m_url.user());
00619
00620 emit q->redirection(q, m_redirectionURL);
00621 }
00622
00623 void MkdirJob::slotFinished()
00624 {
00625 Q_D(MkdirJob);
00626 if ( d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid())
00627 {
00628
00629 SimpleJob::slotFinished();
00630 } else {
00631
00632 if (queryMetaData("permanent-redirect")=="true")
00633 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
00634 KUrl dummyUrl;
00635 int permissions;
00636 QDataStream istream( d->m_packedArgs );
00637 istream >> dummyUrl >> permissions;
00638
00639 d->m_url = d->m_redirectionURL;
00640 d->m_redirectionURL = KUrl();
00641 d->m_packedArgs.truncate(0);
00642 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
00643 stream << d->m_url << permissions;
00644
00645
00646 d->slaveDone();
00647 Scheduler::doJob(this);
00648 }
00649 }
00650
00651 SimpleJob *KIO::mkdir( const KUrl& url, int permissions )
00652 {
00653
00654 KIO_ARGS << url << permissions;
00655 return MkdirJobPrivate::newJob(url, CMD_MKDIR, packedArgs);
00656 }
00657
00658 SimpleJob *KIO::rmdir( const KUrl& url )
00659 {
00660
00661 KIO_ARGS << url << qint8(false);
00662 return SimpleJobPrivate::newJob(url, CMD_DEL, packedArgs);
00663 }
00664
00665 SimpleJob *KIO::chmod( const KUrl& url, int permissions )
00666 {
00667
00668 KIO_ARGS << url << permissions;
00669 return SimpleJobPrivate::newJob(url, CMD_CHMOD, packedArgs);
00670 }
00671
00672 SimpleJob *KIO::chown( const KUrl& url, const QString& owner, const QString& group )
00673 {
00674 KIO_ARGS << url << owner << group;
00675 return SimpleJobPrivate::newJob(url, CMD_CHOWN, packedArgs);
00676 }
00677
00678 SimpleJob *KIO::setModificationTime( const KUrl& url, const QDateTime& mtime )
00679 {
00680
00681 KIO_ARGS << url << mtime;
00682 return SimpleJobPrivate::newJobNoUi(url, CMD_SETMODIFICATIONTIME, packedArgs);
00683 }
00684
00685 SimpleJob *KIO::rename( const KUrl& src, const KUrl & dest, JobFlags flags )
00686 {
00687
00688 KIO_ARGS << src << dest << (qint8) (flags & Overwrite);
00689 return SimpleJobPrivate::newJob(src, CMD_RENAME, packedArgs);
00690 }
00691
00692 SimpleJob *KIO::symlink( const QString& target, const KUrl & dest, JobFlags flags )
00693 {
00694
00695 KIO_ARGS << target << dest << (qint8) (flags & Overwrite);
00696 return SimpleJobPrivate::newJob(dest, CMD_SYMLINK, packedArgs, flags);
00697 }
00698
00699 SimpleJob *KIO::special(const KUrl& url, const QByteArray & data, JobFlags flags)
00700 {
00701
00702 return SimpleJobPrivate::newJob(url, CMD_SPECIAL, data, flags);
00703 }
00704
00705 SimpleJob *KIO::mount( bool ro, const QByteArray& fstype, const QString& dev, const QString& point, JobFlags flags )
00706 {
00707 KIO_ARGS << int(1) << qint8( ro ? 1 : 0 )
00708 << QString::fromLatin1(fstype) << dev << point;
00709 SimpleJob *job = special( KUrl("file:/"), packedArgs, flags );
00710 if (!(flags & HideProgressInfo)) {
00711 KIO::JobPrivate::emitMounting(job, dev, point);
00712 }
00713 return job;
00714 }
00715
00716 SimpleJob *KIO::unmount( const QString& point, JobFlags flags )
00717 {
00718 KIO_ARGS << int(2) << point;
00719 SimpleJob *job = special( KUrl("file:/"), packedArgs, flags );
00720 if (!(flags & HideProgressInfo)) {
00721 KIO::JobPrivate::emitUnmounting(job, point);
00722 }
00723 return job;
00724 }
00725
00726
00727
00729
00730 class KIO::StatJobPrivate: public SimpleJobPrivate
00731 {
00732 public:
00733 inline StatJobPrivate(const KUrl& url, int command, const QByteArray &packedArgs)
00734 : SimpleJobPrivate(url, command, packedArgs), m_bSource(true), m_details(2)
00735 {}
00736
00737 UDSEntry m_statResult;
00738 KUrl m_redirectionURL;
00739 bool m_bSource;
00740 short int m_details;
00741 void slotStatEntry( const KIO::UDSEntry & entry );
00742 void slotRedirection( const KUrl &url);
00743
00750 virtual void start( Slave *slave );
00751
00752 Q_DECLARE_PUBLIC(StatJob)
00753
00754 static inline StatJob *newJob(const KUrl& url, int command, const QByteArray &packedArgs,
00755 JobFlags flags )
00756 {
00757 StatJob *job = new StatJob(*new StatJobPrivate(url, command, packedArgs));
00758 job->setUiDelegate(new JobUiDelegate);
00759 if (!(flags & HideProgressInfo)) {
00760 KIO::getJobTracker()->registerJob(job);
00761 emitStating(job, url);
00762 }
00763 return job;
00764 }
00765 };
00766
00767 StatJob::StatJob(StatJobPrivate &dd)
00768 : SimpleJob(dd)
00769 {
00770 }
00771
00772 StatJob::~StatJob()
00773 {
00774 }
00775
00776 void StatJob::setSide( bool source )
00777 {
00778 d_func()->m_bSource = source;
00779 }
00780
00781 void StatJob::setSide( StatSide side )
00782 {
00783 d_func()->m_bSource = side == SourceSide;
00784 }
00785
00786 void StatJob::setDetails( short int details )
00787 {
00788 d_func()->m_details = details;
00789 }
00790
00791 const UDSEntry & StatJob::statResult() const
00792 {
00793 return d_func()->m_statResult;
00794 }
00795
00796 void StatJobPrivate::start(Slave *slave)
00797 {
00798 Q_Q(StatJob);
00799 m_outgoingMetaData.insert( "statSide", m_bSource ? "source" : "dest" );
00800 m_outgoingMetaData.insert( "details", QString::number(m_details) );
00801
00802 q->connect( slave, SIGNAL( statEntry( const KIO::UDSEntry& ) ),
00803 SLOT( slotStatEntry( const KIO::UDSEntry & ) ) );
00804 q->connect( slave, SIGNAL( redirection(const KUrl &) ),
00805 SLOT( slotRedirection(const KUrl &) ) );
00806
00807 SimpleJobPrivate::start(slave);
00808 }
00809
00810 void StatJobPrivate::slotStatEntry( const KIO::UDSEntry & entry )
00811 {
00812
00813 m_statResult = entry;
00814 }
00815
00816
00817 void StatJobPrivate::slotRedirection( const KUrl &url)
00818 {
00819 Q_Q(StatJob);
00820 kDebug(7007) << url;
00821 if (!KAuthorized::authorizeUrlAction("redirect", m_url, url))
00822 {
00823 kWarning(7007) << "Redirection from " << m_url << " to " << url << " REJECTED!";
00824 q->setError( ERR_ACCESS_DENIED );
00825 q->setErrorText( url.prettyUrl() );
00826 return;
00827 }
00828 m_redirectionURL = url;
00829 if (m_url.hasUser() && !url.hasUser() && (m_url.host().toLower() == url.host().toLower()))
00830 m_redirectionURL.setUser(m_url.user());
00831
00832 emit q->redirection(q, m_redirectionURL);
00833 }
00834
00835 void StatJob::slotFinished()
00836 {
00837 Q_D(StatJob);
00838 if ( d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid())
00839 {
00840
00841 SimpleJob::slotFinished();
00842 } else {
00843
00844 if (queryMetaData("permanent-redirect")=="true")
00845 emit permanentRedirection(this, d->m_url, d->m_redirectionURL);
00846 d->m_url = d->m_redirectionURL;
00847 d->m_redirectionURL = KUrl();
00848 d->m_packedArgs.truncate(0);
00849 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
00850 stream << d->m_url;
00851
00852
00853 d->slaveDone();
00854 Scheduler::doJob(this);
00855 }
00856 }
00857
00858 void StatJob::slotMetaData( const KIO::MetaData &_metaData)
00859 {
00860 Q_D(StatJob);
00861 SimpleJob::slotMetaData(_metaData);
00862 storeSSLSessionFromJob(d->m_redirectionURL);
00863 }
00864
00865 StatJob *KIO::stat(const KUrl& url, JobFlags flags)
00866 {
00867
00868 return stat( url, StatJob::SourceSide, 2, flags );
00869 }
00870
00871 StatJob *KIO::stat(const KUrl& url, bool sideIsSource, short int details, JobFlags flags )
00872 {
00873
00874 KIO_ARGS << url;
00875 StatJob * job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
00876 job->setSide( sideIsSource ? StatJob::SourceSide : StatJob::DestinationSide );
00877 job->setDetails( details );
00878 return job;
00879 }
00880
00881 StatJob *KIO::stat(const KUrl& url, KIO::StatJob::StatSide side, short int details, JobFlags flags )
00882 {
00883
00884 KIO_ARGS << url;
00885 StatJob * job = StatJobPrivate::newJob(url, CMD_STAT, packedArgs, flags);
00886 job->setSide( side );
00887 job->setDetails( details );
00888 return job;
00889 }
00890
00891 SimpleJob *KIO::http_update_cache( const KUrl& url, bool no_cache, time_t expireDate)
00892 {
00893 assert( (url.protocol() == "http") || (url.protocol() == "https") );
00894
00895 KIO_ARGS << (int)2 << url << no_cache << qlonglong(expireDate);
00896 SimpleJob * job = SimpleJobPrivate::newJob(url, CMD_SPECIAL, packedArgs);
00897 job->