27 #include <sys/types.h>
40 #include <QtCore/QTimer>
41 #include <QtCore/QFile>
65 #define MAX_READ_BUF_SIZE (64 * 1024) // 64 KB at a time seems reasonable...
73 #define REPORT_TIMEOUT 200
107 SLOT(slotSpeed(
KJob*,ulong)));
109 if (
ui() && job->
ui()) {
126 qMakePair(
i18nc(
"The source of a file operation",
"Source"), src.
pathOrUrl()),
127 qMakePair(
i18nc(
"The destination of a file operation",
"Destination"), dest.
pathOrUrl()));
133 qMakePair(
i18nc(
"The source of a file operation",
"Source"), src.
pathOrUrl()),
134 qMakePair(
i18nc(
"The destination of a file operation",
"Destination"), dest.
pathOrUrl()));
158 qMakePair(
i18nc(
"The source of a file operation",
"Source"), url.
pathOrUrl()));
164 qMakePair(
i18n(
"Device"), dev),
165 qMakePair(
i18n(
"Mountpoint"), point));
171 qMakePair(
i18n(
"Mountpoint"), point));
209 q_func()->emitSpeed( speed );
214 #ifndef KDE_NO_DEPRECATED
237 Q_ASSERT(d->m_parentJob == 0L);
239 d->m_parentJob = job;
244 return d_func()->m_parentJob;
249 return d_func()->m_incomingMetaData;
254 return d_func()->m_incomingMetaData.value(key,
QString());
260 d->m_outgoingMetaData = _metaData;
265 d_func()->m_outgoingMetaData.insert(key, value);
272 for(;it != values.end(); ++it)
273 d->m_outgoingMetaData.insert(it.key(), it.value());
280 for(;it != values.end(); ++it)
282 if ( !d->m_outgoingMetaData.contains( it.key() ) )
283 d->m_outgoingMetaData.insert( it.key(), it.value() );
288 return d_func()->m_outgoingMetaData;
294 d_func()->simpleJobInit();
300 if (!
m_url.isValid())
304 QTimer::singleShot(0, q, SLOT(slotFinished()) );
319 kWarning(7007) <<
this <<
"This is overkill.";
328 d->m_slave->suspend();
336 d->m_slave->resume();
342 return d_func()->m_url;
348 Q_ASSERT( d->m_slave );
354 Q_ASSERT(!d->m_slave);
365 return d_func()->m_redirectionHandlingEnabled;
371 d->m_redirectionHandlingEnabled = handle;
378 if (d->m_schedSerial) {
379 kDebug(7007) <<
"Killing job" <<
this <<
"in destructor!" << kBacktrace();
396 SLOT(slotError(
int,
QString)) );
398 q->connect( slave, SIGNAL(warning(
QString)),
401 q->connect( slave, SIGNAL(infoMessage(
QString)),
404 q->connect( slave, SIGNAL(connected()),
407 q->connect( slave, SIGNAL(finished()),
408 SLOT(slotFinished()) );
418 q->connect( slave, SIGNAL(speed(ulong)),
422 if (
ui() &&
ui()->window())
427 if (
ui() &&
ui()->userTimestamp())
486 QDataStream str( d->m_packedArgs );
511 emit
warning(
this, errorText );
516 emit q_func()->infoMessage( q_func(), msg );
521 emit q_func()->connected( q_func() );
543 q_func()->emitSpeed( speed );
553 m_url = *redirectionUrl;
554 redirectionUrl->clear();
563 QMapIterator<QString,QString> it (_metaData);
564 while (it.hasNext()) {
566 if (it.key().startsWith(QLatin1String(
"{internal~"), Qt::CaseInsensitive))
567 d->m_internalMetaData.insert(it.key(), it.value());
569 d->m_incomingMetaData.insert(it.key(), it.value());
575 if (!d->m_internalMetaData.isEmpty()) {
582 Q_UNUSED(redirectionURL);
590 MkdirJobPrivate(
const KUrl& url,
int command,
const QByteArray &packedArgs)
593 KUrl m_redirectionURL;
594 void slotRedirection(
const KUrl &url);
602 virtual void start(
Slave *slave );
606 static inline
MkdirJob *newJob(const
KUrl& url,
int command, const QByteArray &packedArgs)
608 MkdirJob *job =
new MkdirJob(*
new MkdirJobPrivate(url, command, packedArgs));
626 q->connect( slave, SIGNAL(redirection(
KUrl)),
627 SLOT(slotRedirection(
KUrl)) );
633 void MkdirJobPrivate::slotRedirection(
const KUrl &url)
639 kWarning(7007) <<
"Redirection from" << m_url <<
"to" << url <<
"REJECTED!";
641 q->setErrorText( url.pathOrUrl() );
644 m_redirectionURL = url;
646 emit q->redirection(q, m_redirectionURL);
653 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() )
659 if ( d->m_redirectionHandlingEnabled )
663 QDataStream istream( d->m_packedArgs );
664 istream >> dummyUrl >> permissions;
666 d->m_packedArgs.truncate(0);
667 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
668 stream << d->m_redirectionURL << permissions;
670 d->restartAfterRedirection(&d->m_redirectionURL);
735 KIO_ARGS << int(1) << qint8( ro ? 1 : 0 )
736 << QString::fromLatin1(fstype) << dev << point;
761 inline StatJobPrivate(
const KUrl& url,
int command,
const QByteArray &packedArgs)
766 KUrl m_redirectionURL;
770 void slotRedirection(
const KUrl &url);
778 virtual void start(
Slave *slave );
782 static inline
StatJob *newJob(const
KUrl& url,
int command, const QByteArray &packedArgs,
785 StatJob *job =
new StatJob(*
new StatJobPrivate(url, command, packedArgs));
789 emitStating(job, url);
804 #ifndef KDE_NO_DEPRECATED
807 d_func()->m_bSource = source;
818 d_func()->m_details = details;
823 return d_func()->m_statResult;
828 if (!
url().isLocalFile()) {
829 const UDSEntry& udsEntry = d_func()->m_statResult;
840 m_outgoingMetaData.insert(
"statSide", m_bSource ?
"source" :
"dest" );
845 q->connect( slave, SIGNAL(redirection(
KUrl)),
846 SLOT(slotRedirection(
KUrl)) );
851 void StatJobPrivate::slotStatEntry(
const KIO::UDSEntry & entry )
854 m_statResult = entry;
858 void StatJobPrivate::slotRedirection(
const KUrl &url)
861 kDebug(7007) << m_url <<
"->" << url;
864 kWarning(7007) <<
"Redirection from " << m_url <<
" to " << url <<
" REJECTED!";
866 q->setErrorText( url.pathOrUrl() );
869 m_redirectionURL = url;
871 emit q->redirection(q, m_redirectionURL);
878 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() )
884 if ( d->m_redirectionHandlingEnabled )
886 d->m_packedArgs.truncate(0);
887 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
888 stream << d->m_redirectionURL;
890 d->restartAfterRedirection(&d->m_redirectionURL);
916 QTimer::singleShot(0, job, SLOT(slotFinished()));
922 #ifndef KDE_NO_DEPRECATED
948 KIO_ARGS << (int)2 << url << no_cache << qlonglong(expireDate);
973 if (d->m_command ==
CMD_GET && !d->m_isMimetypeEmitted) {
974 kWarning(7007) <<
"mimeType() not emitted when sending first data!; job URL ="
975 << d->m_url <<
"data size =" << _data.size();
978 d->m_isMimetypeEmitted =
true;
980 if (d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() ||
error()) {
981 emit
data(
this, _data);
997 kWarning(7007) <<
"Redirection from " << d->m_url <<
" to " << url <<
" REJECTED!";
1004 if (d->m_redirectionList.count(url) > 5)
1006 kDebug(7007) <<
"CYCLIC REDIRECTION!";
1012 d->m_redirectionURL =
url;
1013 d->m_redirectionList.append(url);
1014 d->m_outgoingMetaData[
"ssl_was_in_use"] = d->m_incomingMetaData[
"ssl_in_use"];
1024 kDebug(7007) << d->m_url;
1025 if (!d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid()) {
1031 if (d->m_redirectionHandlingEnabled) {
1036 d->staticData.truncate(0);
1037 d->m_incomingMetaData.clear();
1040 d->m_internalSuspended =
false;
1044 QDataStream istream( d->m_packedArgs );
1045 switch( d->m_command ) {
1047 d->m_packedArgs.truncate(0);
1048 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1049 stream << d->m_redirectionURL;
1054 qint8 iOverwrite, iResume;
1055 istream >> dummyUrl >> iOverwrite >> iResume >> permissions;
1056 d->m_packedArgs.truncate(0);
1057 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1058 stream << d->m_redirectionURL << iOverwrite << iResume << permissions;
1063 istream >> specialcmd;
1064 if (specialcmd == 1)
1066 d->m_outgoingMetaData.remove(QLatin1String(
"content-type"));
1068 d->m_packedArgs.truncate(0);
1069 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1070 stream << d->m_redirectionURL;
1076 d->restartAfterRedirection(&d->m_redirectionURL);
1090 d->m_extraFlags &= ~
JobPrivate::EF_TransferJobAsync;
1098 d->m_slave->send(
MSG_DATA, dataForSlave );
1106 d->m_extraFlags &= ~
JobPrivate::EF_TransferJobNeedData;
1109 #ifndef KDE_NO_DEPRECATED
1116 d->m_extraFlags &= ~
JobPrivate::EF_TransferJobDataSent;
1120 #ifndef KDE_NO_DEPRECATED
1129 return d_func()->m_mimetype;
1136 QByteArray dataForSlave;
1140 if (!d->staticData.isEmpty())
1142 dataForSlave = d->staticData;
1143 d->staticData.clear();
1147 emit
dataReq(
this, dataForSlave);
1153 static const int max_size = 14 * 1024 * 1024;
1154 if (dataForSlave.size() > max_size)
1156 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";
1157 d->staticData = QByteArray(dataForSlave.data() + max_size , dataForSlave.size() - max_size);
1158 dataForSlave.truncate(max_size);
1166 d->internalSuspend();
1167 d->m_subJob->d_func()->internalResume();
1174 d->m_mimetype = type;
1175 if (d->m_command ==
CMD_GET && d->m_isMimetypeEmitted) {
1176 kWarning(7007) <<
"mimetype() emitted again, or after sending first data!; job URL ="
1179 d->m_isMimetypeEmitted =
true;
1203 if ( d->m_internalSuspended )
1204 d->internalSuspend();
1210 return d_func()->m_errorPage;
1218 q->connect( slave, SIGNAL(data(QByteArray)),
1219 SLOT(slotData(QByteArray)) );
1222 q->connect( slave, SIGNAL(dataReq()),
1225 q->connect( slave, SIGNAL(dataReq()),
1226 SLOT(slotDataReq()) );
1228 q->connect( slave, SIGNAL(redirection(
KUrl)),
1229 SLOT(slotRedirection(
KUrl)) );
1231 q->connect( slave, SIGNAL(mimeType(
QString)),
1232 SLOT(slotMimetype(
QString)) );
1234 q->connect( slave, SIGNAL(errorPage()),
1237 q->connect( slave, SIGNAL(needSubUrlData()),
1270 m_subJob->d_func()->internalSuspend();
1289 emit q->canResume(q, offset);
1296 QByteArray dataForSlave;
1303 if (dataForSlave.isEmpty())
1305 emit q->dataReq(q, dataForSlave);
1310 q->sendAsyncData(dataForSlave);
1316 m_subJob->d_func()->internalResume();
1324 Q_ASSERT(job == d->m_subJob);
1328 if (!
error() && job == d->m_subJob)
1331 d->internalResume();
1337 addMetaData(
"modified", mtime.toString( Qt::ISODate ) );
1345 QByteArray(), flags);
1354 StoredTransferJobPrivate(
const KUrl& url,
int command,
1355 const QByteArray &packedArgs,
1356 const QByteArray &_staticData)
1360 StoredTransferJobPrivate(
const KUrl& url,
int command,
1361 const QByteArray &packedArgs,
1370 void slotStoredData(
KIO::Job *job,
const QByteArray &data );
1371 void slotStoredDataReq(
KIO::Job *job, QByteArray &data );
1376 const QByteArray &packedArgs,
1377 const QByteArray &staticData, JobFlags flags)
1380 *
new StoredTransferJobPrivate(url, command, packedArgs, staticData));
1388 const QByteArray &packedArgs,
1392 *
new StoredTransferJobPrivate(url, command, packedArgs, ioDevice));
1394 if (!(flags & HideProgressInfo))
1405 PostErrorJob(
int _error,
const QString& url,
const QByteArray &packedArgs,
const QByteArray &postData)
1409 setErrorText( url );
1412 PostErrorJob(
int _error,
const QString& url,
const QByteArray &packedArgs,
QIODevice* ioDevice)
1416 setErrorText( url );
1426 static const int bad_ports[] = {
1488 if (url.port() != 80)
1490 const int port = url.port();
1491 for (
int cnt=0; bad_ports[cnt] && bad_ports[cnt] <= port; ++cnt)
1492 if (port == bad_ports[cnt])
1501 static bool override_loaded =
false;
1503 if( !override_loaded ) {
1507 override_loaded =
true;
1509 for( QList< int >::ConstIterator it = overriden_ports->constBegin();
1510 it != overriden_ports->constEnd();
1512 if( overriden_ports->contains( url.port())) {
1536 PostErrorJob * job =
new PostErrorJob(_error, url.
pathOrUrl(), packedArgs, ioDevice);
1538 if (!(flags & HideProgressInfo)) {
1556 PostErrorJob * job =
new PostErrorJob(_error, url.
pathOrUrl(), packedArgs, postData);
1558 if (!(flags & HideProgressInfo)) {
1570 bool redirection =
false;
1572 if (_url.
path().isEmpty())
1583 KIO_ARGS << (int)1 << _url << static_cast<qint64>(postData.size());
1587 QTimer::singleShot(0, job, SLOT(slotPostRedirection()) );
1594 bool redirection =
false;
1596 if (_url.
path().isEmpty())
1610 size = ((ioDevice && !ioDevice->isSequential()) ? ioDevice->size() : -1);
1613 KIO_ARGS << (int)1 << _url << size;
1617 QTimer::singleShot(0, job, SLOT(slotPostRedirection()) );
1627 QByteArray(), flags);
1634 if (_url.
path().isEmpty())
1644 KIO_ARGS << (int)1 << _url << static_cast<qint64>(postData.size());
1652 if (_url.
path().isEmpty())
1665 size = ((ioDevice && !ioDevice->isSequential()) ? ioDevice->size() : -1);
1668 KIO_ARGS << (int)1 << _url << size;
1679 kDebug(7007) <<
"TransferJob::slotPostRedirection(" <<
m_url <<
")";
1681 emit q->redirection(q,
m_url);
1697 SLOT(slotStoredData(
KIO::Job*,QByteArray)) );
1699 SLOT(slotStoredDataReq(
KIO::Job*,QByteArray&)) );
1709 Q_ASSERT( d->m_data.isNull() );
1710 Q_ASSERT( d->m_uploadOffset == 0 );
1717 return d_func()->m_data;
1720 void StoredTransferJobPrivate::slotStoredData(
KIO::Job *,
const QByteArray &data )
1723 if ( data.size() == 0 )
1725 unsigned int oldSize = m_data.size();
1726 m_data.resize( oldSize + data.size() );
1727 memcpy( m_data.data() + oldSize, data.data(), data.size() );
1730 void StoredTransferJobPrivate::slotStoredDataReq(
KIO::Job *, QByteArray &data )
1734 const int MAX_CHUNK_SIZE = 64*1024;
1735 int remainingBytes = m_data.size() - m_uploadOffset;
1736 if( remainingBytes > MAX_CHUNK_SIZE ) {
1738 data = QByteArray( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
1739 m_uploadOffset += MAX_CHUNK_SIZE;
1744 data = QByteArray( m_data.data() + m_uploadOffset, remainingBytes );
1745 m_data = QByteArray();
1775 MimetypeJobPrivate(
const KUrl& url,
int command,
const QByteArray &packedArgs)
1781 static inline
MimetypeJob *newJob(const
KUrl& url,
int command, const QByteArray &packedArgs,
1786 if (!(flags & HideProgressInfo)) {
1788 emitStating(job, url);
1812 kDebug(7007) <<
"It is in fact a directory!";
1813 d->m_mimetype = QString::fromLatin1(
"inode/directory");
1818 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && !
error() )
1824 if (d->m_redirectionHandlingEnabled)
1826 d->staticData.truncate(0);
1827 d->m_internalSuspended =
false;
1828 d->m_packedArgs.truncate(0);
1829 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
1830 stream << d->m_redirectionURL;
1832 d->restartAfterRedirection(&d->m_redirectionURL);
1852 DirectCopyJobPrivate(
const KUrl& url,
int command,
const QByteArray &packedArgs)
1862 virtual void start(
Slave *slave);
1896 FileCopyJobPrivate(
const KUrl& src,
const KUrl& dest,
int permissions,
1897 bool move, JobFlags flags)
1898 : m_sourceSize(
filesize_t(-1)), m_src(src), m_dest(dest), m_moveJob(0), m_copyJob(0), m_delJob(0),
1899 m_chmodJob(0), m_getJob(0), m_putJob(0), m_permissions(permissions),
1900 m_move(move), m_mustChmod(0), m_flags(flags)
1907 QByteArray m_buffer;
1917 bool m_resumeAnswerSent:1;
1921 void startBestCopyMethod();
1922 void startCopyJob();
1923 void startCopyJob(
const KUrl &slave_url);
1924 void startRenameJob(
const KUrl &slave_url);
1925 void startDataPump();
1929 void slotData(
KIO::Job *,
const QByteArray &data);
1930 void slotDataReq(
KIO::Job *, QByteArray &data);
1937 void slotProcessedSize(
KJob *job, qulonglong size );
1943 void slotTotalSize(
KJob *job, qulonglong size );
1949 void slotPercent(
KJob *job,
unsigned long pct );
1964 *
new FileCopyJobPrivate(src, dest, permissions, move, flags));
1965 job->setProperty(
"destUrl", dest.url());
1967 if (!(flags & HideProgressInfo))
1984 QTimer::singleShot(0,
this, SLOT(slotStart()));
1987 void FileCopyJobPrivate::slotStart()
1998 if ((m_src.protocol() == m_dest.protocol()) &&
1999 (m_src.host() == m_dest.host()) &&
2000 (m_src.port() == m_dest.port()) &&
2001 (m_src.user() == m_dest.user()) &&
2002 (m_src.pass() == m_dest.pass()) &&
2003 !m_src.hasSubUrl() && !m_dest.hasSubUrl())
2005 startRenameJob(m_src);
2010 startRenameJob(m_dest);
2015 startRenameJob(m_src);
2020 startBestCopyMethod();
2023 void FileCopyJobPrivate::startBestCopyMethod()
2025 if ((m_src.protocol() == m_dest.protocol()) &&
2026 (m_src.host() == m_dest.host()) &&
2027 (m_src.port() == m_dest.port()) &&
2028 (m_src.user() == m_dest.user()) &&
2029 (m_src.pass() == m_dest.pass()) &&
2030 !m_src.hasSubUrl() && !m_dest.hasSubUrl())
2036 startCopyJob(m_dest);
2041 startCopyJob(m_src);
2056 d->m_sourceSize = size;
2064 d->m_modificationTime = mtime;
2069 return d_func()->m_src;
2074 return d_func()->m_dest;
2077 void FileCopyJobPrivate::startCopyJob()
2079 startCopyJob(m_src);
2082 void FileCopyJobPrivate::startCopyJob(
const KUrl &slave_url)
2088 if (m_move && m_modificationTime.isValid()) {
2089 m_copyJob->addMetaData(
"modified", m_modificationTime.toString( Qt::ISODate ) );
2091 q->addSubjob( m_copyJob );
2092 connectSubjob( m_copyJob );
2097 void FileCopyJobPrivate::startRenameJob(
const KUrl &slave_url)
2103 if (m_move && m_modificationTime.isValid()) {
2104 m_moveJob->addMetaData(
"modified", m_modificationTime.toString( Qt::ISODate ) );
2106 q->addSubjob( m_moveJob );
2107 connectSubjob( m_moveJob );
2110 void FileCopyJobPrivate::connectSubjob(
SimpleJob * job )
2113 q->connect( job, SIGNAL(totalSize(
KJob*,qulonglong)),
2114 SLOT(slotTotalSize(
KJob*,qulonglong)) );
2116 q->connect( job, SIGNAL(processedSize(
KJob*,qulonglong)),
2117 SLOT(slotProcessedSize(
KJob*,qulonglong)) );
2119 q->connect( job, SIGNAL(percent(
KJob*,ulong)),
2120 SLOT(slotPercent(
KJob*,ulong)) );
2128 d->m_moveJob->suspend();
2131 d->m_copyJob->suspend();
2134 d->m_getJob->suspend();
2137 d->m_putJob->suspend();
2147 d->m_moveJob->resume();
2150 d->m_copyJob->resume();
2153 d->m_getJob->resume();
2156 d->m_putJob->resume();
2162 void FileCopyJobPrivate::slotProcessedSize(
KJob *, qulonglong size )
2168 void FileCopyJobPrivate::slotTotalSize(
KJob*, qulonglong size )
2177 void FileCopyJobPrivate::slotPercent(
KJob*,
unsigned long pct )
2180 if ( pct > q->percent() ) {
2181 q->setPercent( pct );
2185 void FileCopyJobPrivate::startDataPump()
2190 m_canResume =
false;
2191 m_resumeAnswerSent =
false;
2193 m_putJob =
put( m_dest, m_permissions, (m_flags | HideProgressInfo) );
2195 if ( m_modificationTime.isValid() ) {
2196 m_putJob->setModificationTime( m_modificationTime );
2203 q->connect( m_putJob, SIGNAL(dataReq(
KIO::Job*,QByteArray&)),
2204 SLOT(slotDataReq(
KIO::Job*,QByteArray&)));
2205 q->addSubjob( m_putJob );
2211 if ( job == m_putJob || job == m_copyJob )
2223 res = ui()->askFileRename(
2224 job,
i18n(
"File Already Exists"),
2228 m_sourceSize, offset );
2231 if ( res ==
R_OVERWRITE || (m_flags & Overwrite) )
2235 if ( job == m_putJob ) {
2237 q->removeSubjob(m_putJob);
2241 q->removeSubjob(m_copyJob);
2250 m_resumeAnswerSent =
true;
2252 if ( job == m_putJob )
2256 m_getJob->addMetaData(
"errorPage",
"false" );
2257 m_getJob->addMetaData(
"AllowCompressedPage",
"false" );
2260 m_getJob->setTotalAmount(
KJob::Bytes, m_sourceSize);
2266 m_getJob->addMetaData(
"resume",
KIO::number(offset) );
2274 m_putJob->d_func()->internalSuspend();
2275 q->addSubjob( m_getJob );
2276 connectSubjob( m_getJob );
2277 m_getJob->d_func()->internalResume();
2279 q->connect( m_getJob, SIGNAL(data(
KIO::Job*,QByteArray)),
2280 SLOT(slotData(
KIO::Job*,QByteArray)) );
2289 else if ( job == m_getJob )
2298 kWarning(7007) <<
"unknown job=" << job
2299 <<
"m_getJob=" << m_getJob <<
"m_putJob=" << m_putJob;
2302 void FileCopyJobPrivate::slotData(
KIO::Job * ,
const QByteArray &data)
2306 if (!m_putJob)
return;
2307 m_getJob->d_func()->internalSuspend();
2308 m_putJob->d_func()->internalResume();
2313 if (!m_resumeAnswerSent)
2315 m_resumeAnswerSent =
true;
2321 void FileCopyJobPrivate::slotDataReq(
KIO::Job * , QByteArray &data)
2325 if (!m_resumeAnswerSent && !m_getJob) {
2328 q->setErrorText(
"'Put' job did not send canResume or 'Get' job did not send data!" );
2330 q->removeSubjob(m_putJob);
2337 m_getJob->d_func()->internalResume();
2338 m_putJob->d_func()->internalSuspend();
2341 m_buffer = QByteArray();
2344 void FileCopyJobPrivate::slotMimetype(
KIO::Job*,
const QString& type )
2347 emit q->mimetype( q, type );
2361 d->startBestCopyMethod();
2370 else if (job == d->m_getJob)
2379 else if (job == d->m_putJob)
2397 if (d->m_permissions != -1)
2399 d->m_chmodJob =
chmod(d->m_dest, d->m_permissions);
2401 d->m_mustChmod =
false;
2404 if (job == d->m_moveJob)
2409 if (job == d->m_copyJob)
2414 d->m_delJob =
file_delete( d->m_src, HideProgressInfo );
2419 if (job == d->m_getJob)
2424 d->m_putJob->d_func()->internalResume();
2427 if (job == d->m_putJob)
2435 d->m_getJob->d_func()->internalResume();
2439 d->m_delJob =
file_delete( d->m_src, HideProgressInfo );
2444 if (job == d->m_delJob)
2449 if (job == d->m_chmodJob)
2461 return FileCopyJobPrivate::newJob(src, dest, permissions,
false, flags);
2467 return FileCopyJobPrivate::newJob(src, dest, permissions,
true, flags);
2481 ListJobPrivate(
const KUrl& url,
bool _recursive,
2483 bool _includeHidden)
2485 recursive(_recursive), includeHidden(_includeHidden),
2486 m_prefix(prefix), m_displayPrefix(displayPrefix), m_processedEntries(0)
2492 unsigned long m_processedEntries;
2493 KUrl m_redirectionURL;
2501 virtual void start(
Slave *slave );
2504 void slotRedirection(
const KUrl &url );
2509 static inline
ListJob *newJob(const
KUrl& u,
bool _recursive,
2511 bool _includeHidden, JobFlags flags = HideProgressInfo)
2513 ListJob *job =
new ListJob(*
new ListJobPrivate(u, _recursive, prefix, displayPrefix, _includeHidden));
2515 if (!(flags & HideProgressInfo))
2519 static inline ListJob *newJobNoUi(
const KUrl& u,
bool _recursive,
2521 bool _includeHidden)
2523 return new ListJob(*
new ListJobPrivate(u, _recursive, prefix, displayPrefix, _includeHidden));
2533 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
2545 m_processedEntries += list.count();
2546 slotProcessedSize( m_processedEntries );
2549 UDSEntryList::ConstIterator it = list.begin();
2550 const UDSEntryList::ConstIterator
end = list.end();
2552 for (; it != end; ++it) {
2566 Q_ASSERT(!fileName.isEmpty());
2573 if (displayName.isEmpty())
2574 displayName = filename;
2576 if (filename !=
".." && filename !=
"." && (includeHidden || filename[0] !=
'.')) {
2579 m_prefix + filename +
'/',
2580 m_displayPrefix + displayName +
'/',
2594 if (m_prefix.isNull() && includeHidden) {
2595 emit q->entries(q, list);
2600 UDSEntryList::const_iterator it = list.begin();
2601 const UDSEntryList::const_iterator end = list.end();
2602 for (; it != end; ++it) {
2608 if (displayName.isEmpty())
2609 displayName = filename;
2612 if ( (m_prefix.isNull() || (filename !=
".." && filename !=
".") )
2613 && (includeHidden || (filename[0] !=
'.') ) )
2618 newlist.append(newone);
2622 emit q->entries(q, newlist);
2630 emit q->entries(q, list);
2640 emit
subError(
this, static_cast<KIO::ListJob*>(job));
2647 void ListJobPrivate::slotRedirection(
const KUrl & url )
2652 kWarning(7007) <<
"ListJob: Redirection from " << m_url <<
" to " << url <<
" REJECTED!";
2655 m_redirectionURL = url;
2656 emit q->redirection( q, m_redirectionURL );
2669 d->m_redirectionURL = d->m_url;
2670 d->m_redirectionURL.setProtocol( proto );
2677 if ( !d->m_redirectionURL.isEmpty() && d->m_redirectionURL.isValid() && !
error() ) {
2683 if ( d->m_redirectionHandlingEnabled ) {
2684 d->m_packedArgs.truncate(0);
2685 QDataStream stream( &d->m_packedArgs, QIODevice::WriteOnly );
2686 stream << d->m_redirectionURL;
2688 d->restartAfterRedirection(&d->m_redirectionURL);
2720 d->m_extraFlags &= ~
JobPrivate::EF_ListJobUnrestricted;
2727 !(m_extraFlags & EF_ListJobUnrestricted))
2730 q->setErrorText( m_url.url() );
2731 QTimer::singleShot(0, q, SLOT(slotFinished()) );
2738 q->connect( slave, SIGNAL(redirection(
KUrl)),
2739 SLOT(slotRedirection(
KUrl)) );
2746 return d_func()->m_redirectionURL;
2754 MultiGetJobPrivate(
const KUrl& url)
2759 GetRequest(
long _id,
const KUrl &_url,
const MetaData &_metaData)
2760 : id(_id), url(_url), metaData(_metaData) { }
2765 inline bool operator==(
const GetRequest& req )
const
2766 {
return req.id == id; }
2768 typedef QLinkedList<GetRequest> RequestQueue;
2770 RequestQueue m_waitQueue;
2771 RequestQueue m_activeQueue;
2772 GetRequest m_currentEntry;
2773 bool b_multiGetActive;
2781 virtual void start(
Slave *slave);
2783 bool findCurrentEntry();
2784 void flushQueue(QLinkedList<GetRequest> &queue);
2808 MultiGetJobPrivate::GetRequest entry(
id, url, metaData);
2810 d->m_waitQueue.append(entry);
2813 void MultiGetJobPrivate::flushQueue(RequestQueue &queue)
2817 RequestQueue::iterator wqit = m_waitQueue.begin();
2818 const RequestQueue::iterator wqend = m_waitQueue.end();
2819 while ( wqit != wqend )
2821 const GetRequest& entry = *wqit;
2822 if ((m_url.protocol() == entry.url.protocol()) &&
2823 (m_url.host() == entry.url.host()) &&
2824 (m_url.port() == entry.url.port()) &&
2825 (m_url.user() == entry.url.user()))
2827 queue.append( entry );
2828 wqit = m_waitQueue.erase( wqit );
2837 RequestQueue::const_iterator qit = queue.begin();
2838 const RequestQueue::const_iterator qend = queue.end();
2839 for( ; qit != qend; ++qit )
2841 stream << (*qit).url << (*qit).metaData;
2843 m_packedArgs = packedArgs;
2845 m_outgoingMetaData.clear();
2851 GetRequest entry = m_waitQueue.takeFirst();
2852 m_activeQueue.append(entry);
2856 if (!entry.url.protocol().startsWith(QLatin1String(
"http")))
2860 m_packedArgs = packedArgs;
2861 m_outgoingMetaData = entry.metaData;
2863 b_multiGetActive =
false;
2867 flushQueue(m_activeQueue);
2868 b_multiGetActive =
true;
2874 bool MultiGetJobPrivate::findCurrentEntry()
2876 if (b_multiGetActive)
2878 long id = m_incomingMetaData[
"request-id"].toLong();
2879 RequestQueue::const_iterator qit = m_activeQueue.begin();
2880 const RequestQueue::const_iterator qend = m_activeQueue.end();
2881 for( ; qit != qend; ++qit )
2883 if ((*qit).id ==
id)
2885 m_currentEntry = *qit;
2889 m_currentEntry.id = 0;
2894 if ( m_activeQueue.isEmpty() )
2896 m_currentEntry = m_activeQueue.first();
2904 if (!d->findCurrentEntry())
return;
2907 kWarning(7007) <<
"MultiGetJob: Redirection from " << d->m_currentEntry.url <<
" to " << url <<
" REJECTED!";
2910 d->m_redirectionURL =
url;
2911 get(d->m_currentEntry.id, d->m_redirectionURL, d->m_currentEntry.metaData);
2918 if (!d->findCurrentEntry())
return;
2919 if (d->m_redirectionURL.isEmpty())
2922 emit
result(d->m_currentEntry.id);
2924 d->m_redirectionURL =
KUrl();
2926 d->m_incomingMetaData.clear();
2927 d->m_activeQueue.removeAll(d->m_currentEntry);
2928 if (d->m_activeQueue.count() == 0)
2930 if (d->m_waitQueue.count() == 0)
2942 d->m_url = d->m_waitQueue.first().url;
2953 if(d->m_redirectionURL.isEmpty() || !d->m_redirectionURL.isValid() ||
error())
2954 emit
data(d->m_currentEntry.id, _data);
2960 if (d->b_multiGetActive)
2962 MultiGetJobPrivate::RequestQueue newQueue;
2963 d->flushQueue(newQueue);
2964 if (!newQueue.isEmpty())
2966 d->m_activeQueue += newQueue;
2967 d->m_slave->send( d->m_command, d->m_packedArgs );
2970 if (!d->findCurrentEntry())
return;
2971 emit
mimetype(d->m_currentEntry.id, _mimetype);
2977 job->
get(
id, url, metaData);
2983 SpecialJobPrivate(
const KUrl& url,
int command,
2984 const QByteArray &packedArgs,
2985 const QByteArray &_staticData)
3002 d->m_packedArgs =
data;
3007 return d_func()->m_packedArgs;
3012 CacheInfo::CacheInfo(
const KUrl &url)
3017 QString CacheInfo::cachedFileName()
3019 const QChar separator =
'_';
3023 int p = CEF.find(
'/');
3028 p = CEF.find(
'/', p);
3031 QString host = m_url.host().toLower();
3032 CEF = host + CEF +
'_';
3035 if (dir[dir.length()-1] !=
'/')
3038 int l = m_url.host().length();
3039 for(
int i = 0; i < l; i++)
3041 if (host[i].isLetter() && (host[i] !=
'w'))
3047 if (dir[dir.length()-1] ==
'/')
3050 unsigned long hash = 0x00000000;
3051 QString u = m_url.url().toLatin1();
3052 for(
int i = u.length(); i--;)
3054 hash = (hash * 12211 + u[i]) % 2147483563;
3058 hashString.sprintf(
"%08lx", hash);
3060 CEF = CEF + hashString;
3062 CEF = dir +
'/' + CEF;
3067 QFile *CacheInfo::cachedFile()
3070 const char *mode = (readWrite ?
"rb+" :
"rb");
3072 const char *mode = (readWrite ?
"r+" :
"r");
3083 if (ok && (!fgets(buffer, 400, fs)))
3089 time_t currentDate = time(0);
3092 if (ok && (!fgets(buffer, 400, fs)))
3096 int l = strlen(buffer);
3099 if (m_.url.url() != buffer)
3106 if (ok && (!fgets(buffer, 400, fs)))
3110 date = (time_t) strtoul(buffer, 0, 10);
3111 if (m_maxCacheAge && (difftime(currentDate, date) > m_maxCacheAge))
3113 m_bMustRevalidate =
true;
3114 m_expireDate = currentDate;
3119 m_cacheExpireDateOffset = KDE_ftell(fs);
3120 if (ok && (!fgets(buffer, 400, fs)))
3126 date = (time_t) strtoul(buffer, 0, 10);
3128 if (!date || difftime(currentDate, date) >= 0)
3129 m_bMustRevalidate =
true;
3130 m_expireDate = date;
3135 if (ok && (!fgets(buffer, 400, fs)))
3139 m_etag =
QString(buffer).trimmed();
3143 if (ok && (!fgets(buffer, 400, fs)))
3147 m_lastModified =
QString(buffer).trimmed();
3155 unlink( QFile::encodeName(CEF) );
3160 void CacheInfo::flush()
3162 cachedFile().remove();
3165 void CacheInfo::touch()
3169 void CacheInfo::setExpireDate(
int);
3170 void CacheInfo::setExpireTimeout(
int);
3173 int CacheInfo::creationDate();
3174 int CacheInfo::expireDate();
3175 int CacheInfo::expireTimeout();
3178 #include "jobclasses.moc"
3179 #include "job_p.moc"